feat: 新增 timer.py 计时器程序
This commit is contained in:
30
.gitignore
vendored
Normal file
30
.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.Python
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
.venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Virtual environment
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
107
test_calculator.py
Normal file
107
test_calculator.py
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
计算器功能测试
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
from calculator import add, subtract, multiply, divide, calculate
|
||||||
|
|
||||||
|
def test_basic_operations():
|
||||||
|
"""测试基本运算"""
|
||||||
|
print("测试基本运算...")
|
||||||
|
|
||||||
|
# 测试加法
|
||||||
|
assert add(5, 3) == 8
|
||||||
|
assert add(-2, 3) == 1
|
||||||
|
assert add(0, 0) == 0
|
||||||
|
|
||||||
|
# 测试减法
|
||||||
|
assert subtract(10, 4) == 6
|
||||||
|
assert subtract(3, 7) == -4
|
||||||
|
assert subtract(0, 5) == -5
|
||||||
|
|
||||||
|
# 测试乘法
|
||||||
|
assert multiply(4, 5) == 20
|
||||||
|
assert multiply(-3, 2) == -6
|
||||||
|
assert multiply(0, 100) == 0
|
||||||
|
|
||||||
|
# 测试除法
|
||||||
|
assert divide(10, 2) == 5
|
||||||
|
assert divide(7, 2) == 3.5
|
||||||
|
assert divide(-12, 3) == -4
|
||||||
|
|
||||||
|
print("基本运算测试通过!")
|
||||||
|
|
||||||
|
def test_divide_by_zero():
|
||||||
|
"""测试除零错误"""
|
||||||
|
print("测试除零错误...")
|
||||||
|
try:
|
||||||
|
divide(5, 0)
|
||||||
|
print("错误: 除零异常未触发")
|
||||||
|
return False
|
||||||
|
except ValueError as e:
|
||||||
|
assert str(e) == "除数不能为零"
|
||||||
|
print("除零错误测试通过!")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def test_calculate_function():
|
||||||
|
"""测试计算函数"""
|
||||||
|
print("测试calculate函数...")
|
||||||
|
|
||||||
|
# 测试有效表达式
|
||||||
|
assert calculate("5 + 3") == 8
|
||||||
|
assert calculate("10 - 4") == 6
|
||||||
|
assert calculate("4 * 5") == 20
|
||||||
|
assert calculate("10 / 2") == 5
|
||||||
|
assert calculate("7.5 + 2.5") == 10.0
|
||||||
|
assert calculate("-3 * 4") == -12
|
||||||
|
|
||||||
|
# 测试无效表达式
|
||||||
|
test_cases = [
|
||||||
|
("5 +", "表达式格式错误"),
|
||||||
|
("+ 3", "表达式格式错误"),
|
||||||
|
("5 + 3 4", "表达式格式错误"),
|
||||||
|
("5 & 3", "不支持的运算符"),
|
||||||
|
("abc + 3", "操作数必须是数字"),
|
||||||
|
("5 / 0", "除数不能为零"),
|
||||||
|
]
|
||||||
|
|
||||||
|
for expr, expected_error in test_cases:
|
||||||
|
try:
|
||||||
|
calculate(expr)
|
||||||
|
print(f"错误: 表达式 '{expr}' 应触发错误但未触发")
|
||||||
|
return False
|
||||||
|
except (ValueError, RuntimeError) as e:
|
||||||
|
if expected_error not in str(e):
|
||||||
|
print(f"错误: 表达式 '{expr}' 返回错误 '{e}',但期望包含 '{expected_error}'")
|
||||||
|
return False
|
||||||
|
|
||||||
|
print("calculate函数测试通过!")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""运行所有测试"""
|
||||||
|
print("开始计算器测试...")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
try:
|
||||||
|
test_basic_operations()
|
||||||
|
test_divide_by_zero()
|
||||||
|
test_calculate_function()
|
||||||
|
|
||||||
|
print("=" * 50)
|
||||||
|
print("所有测试通过!")
|
||||||
|
return 0
|
||||||
|
except AssertionError as e:
|
||||||
|
print(f"测试失败: {e}")
|
||||||
|
return 1
|
||||||
|
except Exception as e:
|
||||||
|
print(f"测试过程中出现未知错误: {e}")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
183
timer.py
Normal file
183
timer.py
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class Timer:
|
||||||
|
def __init__(self):
|
||||||
|
self.total_seconds = 0
|
||||||
|
self.remaining_seconds = 0
|
||||||
|
self.is_running = False
|
||||||
|
self.is_paused = False
|
||||||
|
self.thread = None
|
||||||
|
|
||||||
|
def set_timer(self, minutes, seconds):
|
||||||
|
"""设置倒计时时间"""
|
||||||
|
self.total_seconds = minutes * 60 + seconds
|
||||||
|
self.remaining_seconds = self.total_seconds
|
||||||
|
print(f"计时器设置为 {minutes} 分 {seconds} 秒")
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""开始倒计时"""
|
||||||
|
if self.total_seconds <= 0:
|
||||||
|
print("请先设置计时器时间!")
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.is_running and not self.is_paused:
|
||||||
|
print("计时器已经在运行中!")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.is_running = True
|
||||||
|
self.is_paused = False
|
||||||
|
|
||||||
|
if self.thread is None or not self.thread.is_alive():
|
||||||
|
self.thread = threading.Thread(target=self._countdown)
|
||||||
|
self.thread.daemon = True
|
||||||
|
self.thread.start()
|
||||||
|
print("计时器开始!")
|
||||||
|
|
||||||
|
def pause(self):
|
||||||
|
"""暂停计时器"""
|
||||||
|
if not self.is_running:
|
||||||
|
print("计时器未运行!")
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.is_paused:
|
||||||
|
print("计时器已经暂停!")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.is_paused = True
|
||||||
|
print("计时器已暂停")
|
||||||
|
|
||||||
|
def resume(self):
|
||||||
|
"""继续计时器"""
|
||||||
|
if not self.is_running:
|
||||||
|
print("计时器未运行!")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not self.is_paused:
|
||||||
|
print("计时器未暂停!")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.is_paused = False
|
||||||
|
print("计时器继续")
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
"""重置计时器"""
|
||||||
|
self.is_running = False
|
||||||
|
self.is_paused = False
|
||||||
|
self.remaining_seconds = self.total_seconds
|
||||||
|
print("计时器已重置")
|
||||||
|
|
||||||
|
def _countdown(self):
|
||||||
|
"""倒计时线程函数"""
|
||||||
|
while self.remaining_seconds > 0 and self.is_running:
|
||||||
|
if not self.is_paused:
|
||||||
|
mins, secs = divmod(self.remaining_seconds, 60)
|
||||||
|
time_format = f"{mins:02d}:{secs:02d}"
|
||||||
|
sys.stdout.write(f"\r剩余时间: {time_format}")
|
||||||
|
sys.stdout.flush()
|
||||||
|
time.sleep(1)
|
||||||
|
self.remaining_seconds -= 1
|
||||||
|
|
||||||
|
if self.remaining_seconds <= 0 and self.is_running:
|
||||||
|
print("\n时间到!计时器结束!")
|
||||||
|
self.is_running = False
|
||||||
|
else:
|
||||||
|
print("\n计时器已停止")
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""获取计时器状态"""
|
||||||
|
if self.is_running:
|
||||||
|
if self.is_paused:
|
||||||
|
status = "已暂停"
|
||||||
|
else:
|
||||||
|
status = "运行中"
|
||||||
|
else:
|
||||||
|
status = "未运行"
|
||||||
|
|
||||||
|
mins, secs = divmod(self.remaining_seconds, 60)
|
||||||
|
time_format = f"{mins:02d}:{secs:02d}"
|
||||||
|
return f"状态: {status}, 剩余时间: {time_format}"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数,提供命令行交互界面"""
|
||||||
|
timer = Timer()
|
||||||
|
|
||||||
|
print("=== Python 计时器 ===")
|
||||||
|
print("命令列表:")
|
||||||
|
print(" set <分钟> <秒> - 设置计时器时间")
|
||||||
|
print(" start - 开始计时器")
|
||||||
|
print(" pause - 暂停计时器")
|
||||||
|
print(" resume - 继续计时器")
|
||||||
|
print(" reset - 重置计时器")
|
||||||
|
print(" status - 查看状态")
|
||||||
|
print(" help - 显示帮助")
|
||||||
|
print(" quit - 退出程序")
|
||||||
|
print()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
command = input(">>> ").strip().lower().split()
|
||||||
|
|
||||||
|
if not command:
|
||||||
|
continue
|
||||||
|
|
||||||
|
cmd = command[0]
|
||||||
|
|
||||||
|
if cmd == "set":
|
||||||
|
if len(command) != 3:
|
||||||
|
print("用法: set <分钟> <秒>")
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
minutes = int(command[1])
|
||||||
|
seconds = int(command[2])
|
||||||
|
if minutes < 0 or seconds < 0:
|
||||||
|
print("时间不能为负数!")
|
||||||
|
continue
|
||||||
|
timer.set_timer(minutes, seconds)
|
||||||
|
except ValueError:
|
||||||
|
print("请输入有效的数字!")
|
||||||
|
|
||||||
|
elif cmd == "start":
|
||||||
|
timer.start()
|
||||||
|
|
||||||
|
elif cmd == "pause":
|
||||||
|
timer.pause()
|
||||||
|
|
||||||
|
elif cmd == "resume":
|
||||||
|
timer.resume()
|
||||||
|
|
||||||
|
elif cmd == "reset":
|
||||||
|
timer.reset()
|
||||||
|
|
||||||
|
elif cmd == "status":
|
||||||
|
print(timer.get_status())
|
||||||
|
|
||||||
|
elif cmd == "help":
|
||||||
|
print("命令列表:")
|
||||||
|
print(" set <分钟> <秒> - 设置计时器时间")
|
||||||
|
print(" start - 开始计时器")
|
||||||
|
print(" pause - 暂停计时器")
|
||||||
|
print(" resume - 继续计时器")
|
||||||
|
print(" reset - 重置计时器")
|
||||||
|
print(" status - 查看状态")
|
||||||
|
print(" help - 显示帮助")
|
||||||
|
print(" quit - 退出程序")
|
||||||
|
|
||||||
|
elif cmd == "quit":
|
||||||
|
print("退出计时器程序")
|
||||||
|
break
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(f"未知命令: {cmd},输入 'help' 查看帮助")
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n程序被中断")
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
print(f"发生错误: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user