访问.txt文件更新列表并对该列表执行操作
我有一段代码,如果用户输入“gr”,它就会运行。
我想做的是读取一个叫做tasks.txt的文件,把里面的内容处理一下,然后放到一个叫reports[]的列表里。这样我就可以根据需要访问这个列表的每一部分,来更新两个字典里的相关信息。最后,我还会把这些信息写入两个新的文本文件(task_overview.txt和user_overview.txt)。
如果这听起来有点复杂,我很抱歉,我已经为这个问题挣扎了很久,而且我也很新手。
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
gr代码:
elif menu == 'gr':
# creating dictionary with values for task_overview file
stat_dict_task_overview = {
"Tasks": 0,
"Completed": 0,
"Uncompleted": 0,
"Overdue": 0,
"Percentage Incomplete": 0,
"Percentage Overdue": 0
}
# creating dictionary with values for user_overview file
stat_dict_user_overview = {
"Users": 0,
"Tasks": 0,
"Name": 0,
}
reports = []
with open("tasks.txt", "r") as task:
# This code updates the dictionary as needed
for line in enumerate(task):
stat_dict_task_overview["Tasks"] += 1
# From this point on nothing gets updated to the dictionary
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)
我想做的是读取tasks.txt文件,把内容处理后放到reports[]列表里,这样我就能根据需要访问列表中的每一部分,来更新两个字典里的相关信息。然后我会把这些信息写入两个新的文本文件(task_overview.txt和user_overview.txt)。
1 个回答
0
我在这个回答上花了些时间,但我注意到这个问题出现过几次,虽然每次都有点不同。我在代码里加了很多注释,并把内容分成了几个不同的函数。
最重要的是,你在使用一个用分号分隔的CSV文件。使用标准的Python CSV模块,特别是csv.DictReader()
,会让你的工作轻松很多。这个方法基本上把CSV文件转换成一个字典(就像方法名所暗示的那样),这样处理起来就非常简单了。
import csv
from datetime import datetime
# pprint is only imported to make the ouput at the bottom look nice
from pprint import pprint
def loadfile(csvfilename: str) -> dict[list]:
users = {}
# easy reading of file as a CSV file
# it skips over empty lines, and uses the first line as the dict key names
with open(csvfilename) as csvfile:
reader = csv.DictReader(csvfile, delimiter=";")
for row in reader:
# remove the name and use it as a key in the users dict
name = row.pop("user")
if name not in users:
# add new user
users[name] = [row]
else:
# update existing user
users[name].append(row)
return users
def get_stat_user_overview(users: dict[list]) -> dict:
tasks = 0
name = 0 # no idea what this is supposed to be
for user in users:
# just count the length of the tasklist and add to tasks
tasks += len(user)
usercount = len(users)
# you can just generate and return a dict without assigning it
# to a variable first
return {
"Tasks": tasks,
"Users": usercount,
"Names": name
}
def get_stat_task_overview(users: dict[list]) -> dict:
# set initial dict to zeros
result = {
"Tasks": 0,
"Completed": 0,
"Uncompleted": 0,
"Overdue": 0,
}
today = datetime.now() # only set this once to reduce the function calls
for user in users.values():
for task in user:
# add task count
result['Tasks'] += 1
# check if task completed
if task['completed'] == 'No':
result['Uncompleted'] += 1
# only check for overdue for the uncompleted items
# it's also safer to turn the string into a datatime object
# and then do a comparison between datetime objects
if datetime.strptime(task['due date'], '%Y-%m-%d') < today:
result['Overdue'] += 1
else:
result['Completed'] += 1
# do the percentage calculations
result["Percentage Incomplete"] = result['Uncompleted'] / result['Tasks'] * 100
result["Percentage Overdue"] = result['Overdue'] / result['Tasks'] * 100
return result
csvfilename = "tasks.txt"
users = loadfile(csvfilename)
pprint(users, indent=4)
print('-----')
user_stats = get_stat_user_overview(users)
pprint(user_stats, indent=4)
print('-----')
task_stats = get_stat_task_overview(users)
pprint(task_stats, indent=4)
输出结果:
{ 'admin': [ { 'Task': 'werty',
'completed': 'No',
'description of task': 'ytrew',
'due date': '2024-12-12',
'entered date': '2024-03-09'},
{ 'Task': 'qwaszx',
'completed': 'No',
'description of task': 'xzsawq',
'due date': '2023-12-12',
'entered date': '2024-03-09'}],
'sam': [ { 'Task': 'asdfgg',
'completed': 'No',
'description of task': 'gfdsa',
'due date': '2024-12-12',
'entered date': '2024-03-09'},
{ 'Task': 'plkju',
'completed': 'No',
'description of task': 'ujklp',
'due date': '2024-02-12',
'entered date': '2024-03-09'},
{ 'Task': 'finish cap2',
'completed': 'No',
'description of task': 'make the code more user friendly',
'due date': '2024-03-16',
'entered date': '2024-03-11'}]}
-----
{'Names': 0, 'Tasks': 8, 'Users': 2}
-----
{ 'Completed': 0,
'Overdue': 3,
'Percentage Incomplete': 100.0,
'Percentage Overdue': 60.0,
'Tasks': 5,
'Uncompleted': 5}