待办清单应用
开发实用的命令行任务管理工具
项目概述
功能需求
- 添加任务
- 查看任务列表
- 标记任务完成
- 删除任务
- 数据持久化保存
技能点
- CRUD操作
- 文件读写
- JSON数据处理
- 面向对象设计
版本1:基础版
# todo_v1.py
"""待办清单 - 基础版"""
todos = []
def add_task():
task = input("请输入任务:").strip()
if task:
todos.append({"task": task, "done": False})
print(f"✓ 任务已添加")
else:
print("任务不能为空")
def show_tasks():
if not todos:
print("暂无任务")
return
print("\n===== 待办清单 =====")
for i, todo in enumerate(todos, 1):
status = "✓" if todo["done"] else "○"
print(f"{i}. [{status}] {todo['task']}")
def complete_task():
show_tasks()
if not todos:
return
try:
index = int(input("完成第几个任务:")) - 1
if 0 <= index < len(todos):
todos[index]["done"] = True
print("✓ 任务已完成")
else:
print("无效编号")
except ValueError:
print("请输入数字")
def delete_task():
show_tasks()
if not todos:
return
try:
index = int(input("删除第几个任务:")) - 1
if 0 <= index < len(todos):
removed = todos.pop(index)
print(f"✓ 已删除:{removed['task']}")
else:
print("无效编号")
except ValueError:
print("请输入数字")
def main():
print("===== 待办清单 v1.0 =====")
while True:
print("\n1.添加 2.查看 3.完成 4.删除 5.退出")
choice = input("请选择:")
if choice == "1":
add_task()
elif choice == "2":
show_tasks()
elif choice == "3":
complete_task()
elif choice == "4":
delete_task()
elif choice == "5":
print("再见!")
break
else:
print("无效选择")
if __name__ == "__main__":
main()
版本2:增加数据持久化
# todo_v2.py
"""待办清单 - 数据持久化版"""
import json
from datetime import datetime
class TodoList:
def __init__(self, filename="todos.json"):
self.filename = filename
self.todos = []
self.load()
def load(self):
"""从文件加载数据"""
try:
with open(self.filename, "r", encoding="utf-8") as f:
self.todos = json.load(f)
except FileNotFoundError:
self.todos = []
def save(self):
"""保存数据到文件"""
with open(self.filename, "w", encoding="utf-8") as f:
json.dump(self.todos, f, ensure_ascii=False, indent=2)
def add(self, task):
"""添加任务"""
todo = {
"id": len(self.todos) + 1,
"task": task,
"done": False,
"created_at": datetime.now().strftime("%Y-%m-%d %H:%M")
}
self.todos.append(todo)
self.save()
print(f"✓ 已添加:{task}")
def show(self, show_all=True):
"""显示任务列表"""
if not self.todos:
print("暂无任务")
return
print("\n" + "=" * 40)
print(" 待办清单")
print("=" * 40)
for i, todo in enumerate(self.todos, 1):
if not show_all and todo["done"]:
continue
status = "✓" if todo["done"] else "○"
print(f"{i}. [{status}] {todo['task']}")
print(f" 创建于:{todo['created_at']}")
# 统计
total = len(self.todos)
done = sum(1 for t in self.todos if t["done"])
print(f"\n共 {total} 个任务,完成 {done} 个")
def complete(self, index):
"""标记任务完成"""
if 0 <= index < len(self.todos):
self.todos[index]["done"] = True
self.todos[index]["completed_at"] = datetime.now().strftime("%Y-%m-%d %H:%M")
self.save()
print(f"✓ 完成:{self.todos[index]['task']}")
else:
print("无效编号")
def delete(self, index):
"""删除任务"""
if 0 <= index < len(self.todos):
removed = self.todos.pop(index)
self.save()
print(f"✓ 删除:{removed['task']}")
else:
print("无效编号")
def clear_done(self):
"""清除已完成任务"""
count = len([t for t in self.todos if t["done"]])
self.todos = [t for t in self.todos if not t["done"]]
self.save()
print(f"✓ 已清除 {count} 个完成的任务")
def main():
todo_list = TodoList()
print("=" * 40)
print(" 待办清单 v2.0")
print("=" * 40)
while True:
print("\n命令:add/list/done/del/clear/quit")
cmd = input("> ").strip().lower()
if cmd == "add":
task = input("任务内容:").strip()
if task:
todo_list.add(task)
elif cmd == "list":
todo_list.show()
elif cmd == "done":
todo_list.show()
try:
index = int(input("完成第几个:")) - 1
todo_list.complete(index)
except ValueError:
print("请输入数字")
elif cmd == "del":
todo_list.show()
try:
index = int(input("删除第几个:")) - 1
todo_list.delete(index)
except ValueError:
print("请输入数字")
elif cmd == "clear":
todo_list.clear_done()
elif cmd == "quit":
print("再见!")
break
else:
print("未知命令")
if __name__ == "__main__":
main()
版本3:增加优先级和分类
# todo_v3.py
"""待办清单 - 完整版"""
import json
from datetime import datetime
class Task:
def __init__(self, content, priority="中", category="默认"):
self.id = None
self.content = content
self.priority = priority # 高/中/低
self.category = category
self.done = False
self.created_at = datetime.now().strftime("%Y-%m-%d %H:%M")
self.completed_at = None
def to_dict(self):
return {
"id": self.id,
"content": self.content,
"priority": self.priority,
"category": self.category,
"done": self.done,
"created_at": self.created_at,
"completed_at": self.completed_at
}
@classmethod
def from_dict(cls, data):
task = cls(data["content"], data["priority"], data["category"])
task.id = data["id"]
task.done = data["done"]
task.created_at = data["created_at"]
task.completed_at = data.get("completed_at")
return task
class TodoApp:
PRIORITY_ORDER = {"高": 0, "中": 1, "低": 2}
def __init__(self, filename="todos_v3.json"):
self.filename = filename
self.tasks = []
self.next_id = 1
self.load()
def load(self):
try:
with open(self.filename, "r", encoding="utf-8") as f:
data = json.load(f)
self.tasks = [Task.from_dict(t) for t in data["tasks"]]
self.next_id = data.get("next_id", len(self.tasks) + 1)
except FileNotFoundError:
self.tasks = []
def save(self):
data = {
"tasks": [t.to_dict() for t in self.tasks],
"next_id": self.next_id
}
with open(self.filename, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def add_task(self, content, priority="中", category="默认"):
task = Task(content, priority, category)
task.id = self.next_id
self.next_id += 1
self.tasks.append(task)
self.save()
print(f"✓ 已添加任务 #{task.id}")
def list_tasks(self, filter_category=None, show_done=True):
tasks = self.tasks
if filter_category:
tasks = [t for t in tasks if t.category == filter_category]
if not show_done:
tasks = [t for t in tasks if not t.done]
# 按优先级排序
tasks = sorted(tasks, key=lambda t: self.PRIORITY_ORDER.get(t.priority, 1))
if not tasks:
print("暂无任务")
return
print("\n" + "=" * 50)
for task in tasks:
status = "✓" if task.done else "○"
priority_mark = {"高": "🔴", "中": "🟡", "低": "🟢"}.get(task.priority, "")
print(f"#{task.id} [{status}] {priority_mark} {task.content}")
print(f" 分类:{task.category} | 创建:{task.created_at}")
print("=" * 50)
def complete_task(self, task_id):
for task in self.tasks:
if task.id == task_id:
task.done = True
task.completed_at = datetime.now().strftime("%Y-%m-%d %H:%M")
self.save()
print(f"✓ 任务 #{task_id} 已完成")
return
print("未找到任务")
def delete_task(self, task_id):
for i, task in enumerate(self.tasks):
if task.id == task_id:
self.tasks.pop(i)
self.save()
print(f"✓ 任务 #{task_id} 已删除")
return
print("未找到任务")
def get_categories(self):
return list(set(t.category for t in self.tasks))
def stats(self):
total = len(self.tasks)
done = sum(1 for t in self.tasks if t.done)
print(f"\n📊 统计:共{total}个任务,完成{done}个,剩余{total-done}个")
def main():
app = TodoApp()
print("=" * 50)
print(" 待办清单 v3.0")
print("=" * 50)
while True:
print("\n命令: add | list | done | del | stats | quit")
cmd = input("> ").strip().lower()
if cmd == "add":
content = input("任务内容:").strip()
if not content:
continue
print("优先级 (高/中/低,默认中):", end="")
priority = input().strip() or "中"
print("分类(默认:默认):", end="")
category = input().strip() or "默认"
app.add_task(content, priority, category)
elif cmd == "list":
app.list_tasks()
elif cmd == "done":
app.list_tasks(show_done=False)
try:
task_id = int(input("完成任务ID:"))
app.complete_task(task_id)
except ValueError:
print("请输入数字")
elif cmd == "del":
app.list_tasks()
try:
task_id = int(input("删除任务ID:"))
app.delete_task(task_id)
except ValueError:
print("请输入数字")
elif cmd == "stats":
app.stats()
elif cmd == "quit":
print("再见!")
break
if __name__ == "__main__":
main()
本章小结
通过这个项目,你学会了:
- CRUD操作:增删改查
- JSON存储:数据持久化
- 类的设计:面向对象封装
- 数据结构:列表和字典的使用
- 用户交互:命令行界面设计
下一步
完成待办清单,下一章学习数据分析入门。
→ 继续阅读:29-数据分析入门项目