读取tasks.txt生成统计报告的Python代码问题求助
Python代码问题:统计字典无法更新求助
我是Python新手,写了一段当用户输入"gr"时触发的代码,需求如下:读取tasks.txt文件,把内容处理后存入reports列表,再用这个列表更新两个统计字典(stat_dict_task_overview、stat_dict_user_overview),最终将统计信息写入task_overview.txt和user_overview.txt文件。但代码里从reports = task.readlines()之后的部分完全没法更新字典,求帮忙解决。
tasks.txt内容
user;Task;description of task;due date;entered date;completed sam;asdfgg;gfdsa;2024-12-12;2024-03-09;No admin;werty;ytrew;2024-12-12;2024-03-09;No sam;plkju;ujklp;2024-02-12;2024-03-09;No admin;qwaszx;xzsawq;2023-12-12;2024-03-09;No sam;finish cap2;make the code more user friendly;2024-03-16;2024-03-11;No
原代码
elif menu == 'gr': # 创建task_overview文件用的统计字典 stat_dict_task_overview = { "Tasks": 0, "Completed": 0, "Uncompleted": 0, "Overdue": 0, "Percentage Incomplete": 0, "Percentage Overdue": 0 } # 创建user_overview文件用的统计字典 stat_dict_user_overview = { "Users": 0, "Tasks": 0, "Name": 0, } reports = [] with open("tasks.txt", "r") as task: # 这段代码能正常更新字典 for line in enumerate(task): stat_dict_task_overview["Tasks"] += 1 # 从这里开始,字典再也更新不了 reports = task.readlines() for line in task: reports.append(line.strip().split(";")) for line in task: if reports[-1] == "Yes": stat_dict_task_overview["Completed"] += 1 else: stat_dict_task_overview["Uncompleted"] += 1 if reports[3] < str(datetime.today()): stat_dict_task_overview["Overdue"] += 1 print(reports) print(stat_dict_task_overview)
问题原因
- 文件指针耗尽:第一次
for line in enumerate(task)已经把文件所有内容读完,文件指针移到了末尾。之后的task.readlines()和for line in task都读不到任何内容,自然无法更新字典。 - 逻辑错误:就算读到内容,你的循环逻辑也有问题:
reports[-1]取的是整个列表的最后一个元素,不是当前行的完成状态;reports[3]是列表的第四个元素,不是当前行的截止日期;- 日期用字符串比较存在风险,应该转成
datetime对象再做判断。
修正后的代码
from datetime import datetime elif menu == 'gr': # 创建task_overview文件用的统计字典 stat_dict_task_overview = { "Tasks": 0, "Completed": 0, "Uncompleted": 0, "Overdue": 0, "Percentage Incomplete": 0, "Percentage Overdue": 0 } # 重构用户统计字典,用嵌套结构存储每个用户的详细数据 stat_dict_user_overview = { "Total Users": 0, "Total Tasks": 0, "User Details": {} } reports = [] with open("tasks.txt", "r") as task: # 读取所有行并跳过表头 lines = task.readlines()[1:] for line in lines: # 处理每行数据,拆分并跳过空行 parts = line.strip().split(";") if not parts[0]: continue reports.append(parts) # 更新总任务数 stat_dict_task_overview["Tasks"] += 1 stat_dict_user_overview["Total Tasks"] += 1 # 更新完成/未完成统计 completed_status = parts[-1].strip() if completed_status == "Yes": stat_dict_task_overview["Completed"] += 1 else: stat_dict_task_overview["Uncompleted"] += 1 # 未完成任务才检查逾期 due_date = datetime.strptime(parts[3].strip(), "%Y-%m-%d").date() today = datetime.today().date() if due_date < today: stat_dict_task_overview["Overdue"] += 1 # 更新用户个人统计 username = parts[0].strip() if username not in stat_dict_user_overview["User Details"]: stat_dict_user_overview["User Details"][username] = { "Total Tasks": 0, "Completed Tasks": 0, "Uncompleted Tasks": 0, "Overdue Tasks": 0 } user_stats = stat_dict_user_overview["User Details"][username] user_stats["Total Tasks"] += 1 if completed_status == "Yes": user_stats["Completed Tasks"] += 1 else: user_stats["Uncompleted Tasks"] += 1 if due_date < today: user_stats["Overdue Tasks"] += 1 # 计算百分比(避免除以0) total_tasks = stat_dict_task_overview["Tasks"] if total_tasks > 0: stat_dict_task_overview["Percentage Incomplete"] = round( (stat_dict_task_overview["Uncompleted"] / total_tasks) * 100, 2 ) stat_dict_task_overview["Percentage Overdue"] = round( (stat_dict_task_overview["Overdue"] / total_tasks) * 100, 2 ) # 更新总用户数 stat_dict_user_overview["Total Users"] = len(stat_dict_user_overview["User Details"]) # 打印测试结果 print(reports) print("\n任务统计:") for k, v in stat_dict_task_overview.items(): print(f"{k}: {v}") print("\n用户统计:") print(f"总用户数: {stat_dict_user_overview['Total Users']}") print(f"总任务数: {stat_dict_user_overview['Total Tasks']}") for user, stats in stat_dict_user_overview["User Details"].items(): print(f"\n{user}:") for k, v in stats.items(): print(f" {k}: {v}") # 写入task_overview.txt with open("task_overview.txt", "w") as f: for k, v in stat_dict_task_overview.items(): f.write(f"{k}: {v}\n") # 写入user_overview.txt with open("user_overview.txt", "w") as f: f.write(f"Total Users: {stat_dict_user_overview['Total Users']}\n") f.write(f"Total Tasks: {stat_dict_user_overview['Total Tasks']}\n") for user, stats in stat_dict_user_overview["User Details"].items(): f.write(f"\n{user}:\n") for k, v in stats.items(): f.write(f" {k}: {v}\n")
关键修改说明
- 一次性读取所有行并跳过表头,避免文件指针耗尽的问题;
- 逐行处理数据,实时更新统计字典,同时填充reports列表;
- 把日期字符串转成
datetime对象后比较,确保逾期判断准确; - 重构用户统计字典结构,用嵌套字典存储每个用户的详细数据,更符合实际需求;
- 补充百分比计算逻辑,处理了任务数为0的边界情况;
- 完成了写入统计文件的代码,满足最初需求。
内容的提问来源于stack exchange,提问作者SamWestlake-Cann
相关产品推荐
相关产品推荐

