-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtodo_app.py
More file actions
194 lines (145 loc) · 4.94 KB
/
Copy pathtodo_app.py
File metadata and controls
194 lines (145 loc) · 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# To-Do List Application - Codveda Internship Level 2 Task 1
# Command-line task manager with JSON storage and filtering
import json
import os
from datetime import date
TASKS_FILE = "tasks.json"
def load_tasks():
"""Load tasks from the JSON file. Returns an empty list if the file doesn't exist yet."""
if not os.path.exists(TASKS_FILE):
return []
with open(TASKS_FILE, "r") as f:
try:
data = json.load(f)
except json.JSONDecodeError:
print("Warning: tasks file was corrupted. Starting fresh.")
data = []
return data
def save_tasks(tasks):
"""Write the full task list back to the JSON file."""
with open(TASKS_FILE, "w") as f:
json.dump(tasks, f, indent=2)
def next_id(tasks):
"""Figure out the next available ID based on what's already in the list."""
if not tasks:
return 1
return max(task["id"] for task in tasks) + 1
# ---- Add a task ----
def add_task(tasks):
title = input("Task title: ").strip()
if not title:
print("Title can't be empty.")
return
new_task = {
"id": next_id(tasks),
"title": title,
"status": "pending",
"created": str(date.today())
}
tasks.append(new_task)
save_tasks(tasks)
print(f"Added: \"{title}\"")
# ---- View tasks ----
def display_tasks(task_list):
"""Print a formatted list of tasks. Used by both view_all and filtered views."""
if not task_list:
print(" No tasks to show.")
return
# figure out the longest title so we can line things up
max_title = max(len(t["title"]) for t in task_list)
max_title = max(max_title, 5) # minimum width
print(f" {'ID':<5} {'Title':<{max_title + 2}} {'Status':<10} {'Created'}")
print(" " + "-" * (max_title + 32))
for t in task_list:
# put a checkmark next to completed tasks
status_display = "done" if t["status"] == "done" else "pending"
mark = " [x]" if t["status"] == "done" else " [ ]"
print(f"{mark} {t['id']:<5} {t['title']:<{max_title + 2}} {status_display:<10} {t['created']}")
def view_tasks(tasks):
if not tasks:
print("\nYour to-do list is empty. Add some tasks first!")
return
print("\n-- All Tasks --")
display_tasks(tasks)
# ---- Mark a task as done ----
def mark_done(tasks):
if not tasks:
print("No tasks to mark.")
return
# show pending tasks so the user knows what's available
pending = [t for t in tasks if t["status"] == "pending"]
if not pending:
print("All tasks are already completed!")
return
print("\nPending tasks:")
for t in pending:
print(f" ID {t['id']}: {t['title']}")
raw = input("Enter the task ID to mark as done: ").strip()
try:
task_id = int(raw)
except ValueError:
print("That's not a valid ID.")
return
# look for the task
for t in tasks:
if t["id"] == task_id:
if t["status"] == "done":
print(f"\"{t['title']}\" is already marked as done.")
else:
t["status"] = "done"
save_tasks(tasks)
print(f"Marked \"{t['title']}\" as done!")
return
print(f"No task found with ID {task_id}.")
# ---- Delete a task ----
def delete_task(tasks):
if not tasks:
print("Nothing to delete.")
return
print("\nCurrent tasks:")
for t in tasks:
status_tag = " (done)" if t["status"] == "done" else ""
print(f" ID {t['id']}: {t['title']}{status_tag}")
raw = input("Enter the task ID to delete: ").strip()
try:
task_id = int(raw)
except ValueError:
print("That's not a valid ID.")
return
# find and remove
for i, t in enumerate(tasks):
if t["id"] == task_id:
removed = tasks.pop(i)
save_tasks(tasks)
print(f"Deleted \"{removed['title']}\".")
return
print(f"No task found with ID {task_id}.")
# ---- Main menu loop ----
def main():
tasks = load_tasks()
print("\n===== To-Do List Manager =====")
while True:
# count pending for the menu header
pending_count = sum(1 for t in tasks if t["status"] == "pending")
total = len(tasks)
print(f"\n--- Menu --- ({pending_count} pending / {total} total)")
print("1. Add a task")
print("2. View tasks")
print("3. Mark task as done")
print("4. Delete a task")
print("5. Quit")
choice = input("\nPick an option (1-5): ").strip()
if choice == "1":
add_task(tasks)
elif choice == "2":
view_tasks(tasks)
elif choice == "3":
mark_done(tasks)
elif choice == "4":
delete_task(tasks)
elif choice == "5":
print("Goodbye! Your tasks are saved.")
break
else:
print("Not a valid option. Try 1 through 5.")
main()