If you have any questions, comments or issues with this project please post them here!
For anyone who gets an unexpected EOF error with the Day 51 example code and are strugglingā¦
The file you are trying to write to needs to be populated with an empty list []
beforehand.
Thought Iād post the solution here to hopefully help someone out.
For file auto-saves: why donāt we use āa+ā instead of āwā? It seems like weāre trying to append items to the list, not rewrite the whole list. I know it works, just curious as to why it does.
Autosave is designed to use as little code as possible, if we used a+ it would append after the []
of the list. Originally Iād used this as a quick way for students to memorise code snippets to use in exams but itās a neat way of dumping the contents of a list and being able to use things like .remove
and have the changes propogate.
Hi,
I have a problem with the auto-save trick.
The file doesnāt get updated in the first loop but gets updated with the first task after the second loop. I printed the list to test that everything works. But I still donāt understand why the file doesnāt get updated on the first go ?
I will keep scratching my mind to understand whatās going on, but I would be open to some help from the community. Thanks !
import os, time
todo = []
#f = open("todo.txt", 'r')
#todo = eval(f.read())
#f.close()
def prettyprint(sublist):
print(f"""
{'Task':<10}{'->':^10}{sublist[0]:>10}
{'Due time':<10}{'->':^10}{sublist[1]:>10}
{'Priority':<10}{'->':^10}{sublist[2]:>10}""")
while True:
#os.system('clear')
title = "YOUR TODO LIST"
print(f"{title:^6}")
print()
menu = input('add, view, edit or remove an item ? > ').strip().lower()
if menu == "add":
item = input("what to do ? > ").strip().lower()
due = input("when is it due ? > ").strip().lower()
priority = input(
"is the priority high, medium or low ? > ").strip().lower()
todo.append([item, due, priority])
print('the task has been added to the list, select view to check it out')
time.sleep(3)
elif menu == "view":
type_of_view = input(
"Do you want to view high, medium or low priority, or all items ? > "
).strip().lower()
print()
if type_of_view[0] == 'a':
print("ALL YOUR TASKS")
for task_number in range(len(todo)):
prettyprint(todo[task_number])
elif type_of_view[0] == 'h':
print("HIGH PRIORITY TASKS")
for task_number in range(len(todo)):
if todo[task_number][2] == 'high':
prettyprint(todo[task_number])
elif type_of_view[0] == 'm':
print("MEDIUM PRIORITY TASKS")
for task_number in range(len(todo)):
if todo[task_number][2] == 'medium':
prettyprint(todo[task_number])
elif type_of_view[0] == 'l':
print("LOW PRIORITY TASKS")
for task_number in range(len(todo)):
if todo[task_number][2] == 'low':
prettyprint(todo[task_number])
print()
input("press any key to return to the menu >")
elif menu == "edit":
item_to_edit = input("which task do you want to edit ? > ").strip().lower()
for sub_todo in range(len(todo)):
if item_to_edit == todo[sub_todo][0]:
print(
f"the task you selected is to {todo[sub_todo][0]} before {todo[sub_todo][1]} with a {todo[sub_todo][2]} priority."
)
info_to_edit = input(
"do you want to change the task, the time or priority ? > ").strip(
).lower()
if info_to_edit == 'task':
new_task = input("what's the new task ? > ").strip().lower()
todo[sub_todo][0] = new_task
elif info_to_edit == 'time':
new_time = input("what's the new due time ? > ").strip().lower()
todo[sub_todo][1] = new_time
elif info_to_edit == 'priority':
new_priority = input("what's the new priority ? > ").strip().lower()
todo[sub_todo][2] = new_priority
print("the information has been changed, returning to the menu")
time.sleep(2.5)
elif menu == "remove":
item_to_remove = input("which task did you finish ? > ").strip().lower()
for sub_todo in range(len(todo)):
if todo[sub_todo][0] == item_to_remove:
todo.pop(sub_todo)
print("Well done ! The list is updated, select view to check it out.")
time.sleep(3)
break
else:
print("instruction unclear, please input add, view, edit or remove")
time.sleep(3)
print(todo) # test: the todo list is up to date
f = open("to.do", "w")
f.write(str(todo))
f.close
Well, I still canāt figure out whatās wrong.
To be clear let me give an example.
1/ I select add from the menu and enter the task > run, tomorrow, high.
2/ The program runs and my empty list todo is now printed [[run, tomorrow, high]]
3/ Here comes the issue, the f.write(str(todo)) does not write anything to the file ?!
4/ The loop is done and I add another task > read, today, medium.
5/ Now the todo is printed [[run, tomorrow, high], [read, today, medium]]
6/ And in the file appear the first task only [run, tomorrow, high]
I think it has to do with how I constructed my add block but still donāt get whatās wrong.
If you could give it a go and tell me if you encounter the same issue. Thanks !
The problem might be that you can not saving the list to the file and also the flie name is to.do
but it is meant to be a .txt
file.
This is my code that saves the tasks.
import os, time
todo = []
#f = open("todo.txt", 'r')
#todo = eval(f.read())
#f.close()
def prettyprint(sublist):
print(f"""
{'Task':<10}{'->':^10}{sublist[0]:>10}
{'Due time':<10}{'->':^10}{sublist[1]:>10}
{'Priority':<10}{'->':^10}{sublist[2]:>10}""")
while True:
#os.system('clear')
title = "YOUR TODO LIST"
print(f"{title:^6}")
print()
menu = input('add, view, edit or remove an item ? > ').strip().lower()
if menu == "add":
item = input("what to do ? > ").strip().lower()
due = input("when is it due ? > ").strip().lower()
priority = input(
"is the priority high, medium or low ? > ").strip().lower()
todo.append([item, due, priority])
print('the task has been added to the list, select view to check it out')
f = open("todo.txt", "w")
f.write(str(todo))
f.close
time.sleep(3)
elif menu == "view":
type_of_view = input(
"Do you want to view high, medium or low priority, or all items ? > "
).strip().lower()
print()
if type_of_view[0] == 'a':
print("ALL YOUR TASKS")
for task_number in range(len(todo)):
prettyprint(todo[task_number])
elif type_of_view[0] == 'h':
print("HIGH PRIORITY TASKS")
for task_number in range(len(todo)):
if todo[task_number][2] == 'high':
prettyprint(todo[task_number])
elif type_of_view[0] == 'm':
print("MEDIUM PRIORITY TASKS")
for task_number in range(len(todo)):
if todo[task_number][2] == 'medium':
prettyprint(todo[task_number])
elif type_of_view[0] == 'l':
print("LOW PRIORITY TASKS")
for task_number in range(len(todo)):
if todo[task_number][2] == 'low':
prettyprint(todo[task_number])
print()
input("press any key to return to the menu >")
elif menu == "edit":
item_to_edit = input("which task do you want to edit ? > ").strip().lower()
for sub_todo in range(len(todo)):
if item_to_edit == todo[sub_todo][0]:
print(
f"the task you selected is to {todo[sub_todo][0]} before {todo[sub_todo][1]} with a {todo[sub_todo][2]} priority."
)
info_to_edit = input(
"do you want to change the task, the time or priority ? > ").strip(
).lower()
if info_to_edit == 'task':
new_task = input("what's the new task ? > ").strip().lower()
todo[sub_todo][0] = new_task
elif info_to_edit == 'time':
new_time = input("what's the new due time ? > ").strip().lower()
todo[sub_todo][1] = new_time
elif info_to_edit == 'priority':
new_priority = input("what's the new priority ? > ").strip().lower()
todo[sub_todo][2] = new_priority
print("the information has been changed, returning to the menu")
f = open("todo.txt", "w")
f.write(str(todo))
f.close
time.sleep(2.5)
elif menu == "remove":
item_to_remove = input("which task did you finish ? > ").strip().lower()
for sub_todo in range(len(todo)):
if todo[sub_todo][0] == item_to_remove:
todo.pop(sub_todo)
print("Well done ! The list is updated, select view to check it out.")
time.sleep(3)
break
else:
print("instruction unclear, please input add, view, edit or remove")
time.sleep(3)
print(todo) # test: the todo list is up to date
f = open("todo.txt", "w")
f.write(str(todo))
f.close
Thanks a lot !
My understanding was that the extension of the file doesnāt matter, but I apparently does !
Cheers
I donāt know, but itās possible itās because Python doesnāt know that that file extension should be read as text (since different files are read differently depending on their extension).
because f.close() is missing brackets. so the file never gets properly closed and the change remains in limbo until the 2nd loop.
Hello All,
Please help me figure out print statement in the ādeleteā function. I want to add if input is not in list element - print something. I am not sure how to structure the if-else. I tried multiple ways.
import random, os, time
myEvents = []
f = open("calendar.txt", "r")
myEvents = eval(f.read())
f.close()
def inputIdea():
os.system("clear")
idea = input("Input your idea: ")
row = [idea]
myEvents.append(row)
print(idea, "added!")
print()
time.sleep(2)
os.system("clear")
def generateIdea():
os.system("clear")
idea = random.choice(myEvents)
print()
print("Your random idea is: ", *idea)
time.sleep(2)
os.system("clear")
def deleteIdea():
os.system("clear")
idea_to_delete = input("What idea you would like to delete?: ")
#I want to add an "else" statement if idea_to_delete is not in the list and print something, but if I add it, it will not find my idea_to_delete if it is not the first item in list as it starts to loop one by one - please help where to put else statemnt
for row in myEvents:
if idea_to_delete in row:
myEvents.remove(row)
print()
print(idea_to_delete, "is removed form your idea list.")
time.sleep(2)
os.system("clear")
while True:
print("Idea Storage")
print()
usr_choice = input("'1' Enter your idea. \n'2' Display a random idea. \n'3' Delete idea. \n > ")
if usr_choice == "1":
inputIdea()
elif usr_choice == "2":
generateIdea()
elif usr_choice == "3":
deleteIdea()
f = open("calendar.txt", "w")
f.write(str(myEvents))
f.close()
Iām not very sure about it myself - but i suppose you could try checking the ideea user is inputting against the list you are trying to remove it from. But here ⦠iāve checked your code and iāve made a few modifications:
for the first at the beginning we check if the file is empty or not ⦠so you wonāt get errors. If it exists or not you should add try, except - but i donāt know what operators have you worked with until now.
then i have removed the row = [ideea] line - that was unnecessary!
then the for loop was really making a mess in your list :)) so iāve removed it!
there are a few commented lines - about os.system(āclearā) - but those are not working properly on my spyder IDE and i usually donāt use it.
Iām a beginner too - so donāt know a lot yet ⦠but started to realize how little i actually know :)))
Here is your code sort of updated:
# -*- coding: utf-8 -*-
"""
Created on Wed Feb 15 09:44:53 2023
@author: soreen
"""
import random, os, time
myEvents = []
f = open("calendar.txt", "r")
contents = f.read()
if len(contents) > 0:
myEvents = eval(contents)
f.close()
def inputIdea():
# os.system("clear")
idea = input("Input your idea: ")
# row = [idea]
myEvents.append(idea)
print(idea, "added!")
print()
time.sleep(2)
# os.system("clear")
def generateIdea():
# os.system("clear")
idea = random.choice(myEvents)
print()
print("Your random idea is: ", *idea)
time.sleep(2)
# os.system("clear")
def deleteIdea():
# os.system("clear")
idea_to_delete = input("What idea you would like to delete?: ")
#I want to add an "else" statement if idea_to_delete is not in the list and print something, but if I add it, it will not find my idea_to_delete if it is not the first item in list as it starts to loop one by one - please help where to put else statemnt
if idea_to_delete not in myEvents:
print("No way Jose, you need to first have that ideea!")
elif idea_to_delete in myEvents:
myEvents.remove(idea_to_delete)
print()
print(idea_to_delete, "is removed form your idea list.")
time.sleep(2)
# os.system("clear")
while True:
print("Idea Storage")
print()
usr_choice = input("'1' Enter your idea. \n'2' Display a random idea. \n'3' Delete idea. \n'4' Exit > ")
if usr_choice == "1":
inputIdea()
elif usr_choice == "2":
generateIdea()
elif usr_choice == "3":
deleteIdea()
elif usr_choice == "4":
f = open("calendar.txt", "w")
f.write(str(myEvents))
f.close()
break
Well I hope you manage Iām struggling myself!
Thank you very much
In the solution suddenly David uses the eval() function (ātodo = eval(f.read())ā).
It is unclear to me what exactly that does? Iāve tried searching, but didnāt found an explanation Iāve comprehend⦠Perhaps someone here can explain this?
Thx in advance!
To be honest I would advise you not to do that and use Eval on files. It is a lazy to load files into lists and alike, and it is a serious security risk.
Why is it a security risk?
Because when you use eval on a file, the command will evaluate the file. This can actually be a program itself ā¦
Hello, everyone!
Iām almost finished with this project, but I donāt understand why my if-statement under prettyprintremove(): isnāt working. If the āelseā isnāt there it works fine and deletes the task, but if the else is there it skips the āifā even when the tasks is in the list.
import os, time
todolist = []
f = open("todo.txt", "r")
todolist = eval(f.read())
f.close
def prettyprintadd():
os.system('clear')
title = "\033[1;34m \033[4m𤯠Adding To The List! š¤Æ\033[0m"
print()
print(f"{title:^20}")
print()
task = input("\033[1;37mWhat is the activity -\033[1;34m ").capitalize()
print()
date = input("\033[1;37mDue Date -\033[1;34m ")
print()
critical = input("\033[1;37mPriority - [High(H), Medium(M) or Low(L)] -\033[1;34m ").upper()
print()
row = [task, date, critical]
todolist.append(row)
print("Task has been added!")
os.system('clear')
return
def prettyprintview():
os.system('clear')
title = "\033[1;32m \033[4mPresent To-Do list\033[0m"
print(f"{title:^20}")
print()
for row in todolist:
for item in row:
print(item, end=" | ")
print()
print()
last_sen = "\033[1;32mEnd of the list\033[0m"
print(f"{last_sen:>47}")
time.sleep(15)
os.system("clear")
return
#problem area
def prettyprintremove():
os.system('clear')
print("\033[1;31m \033[4mRemoving Some Tasks!\033[0m")
print()
for row in todolist:
for item in row:
print(item, end=" | ")
print()
print()
task = input("\033[1;31mWhat do you want to remove?\033[0m ").capitalize()
print()
for row in todolist:
if task in row:
todolist.remove(row)
print("\033[1;31mTask removed!")
time.sleep(2)
os.system('clear')
return
else:
print("\033[1;31mTask not in list")
time.sleep(2)
os.system('clear')
return
#end of problem area
def prettyprintedit():
os.system("clear")
print("\033[1;35m \033[4mEditing the list!\033[0m")
print()
for row in todolist:
for item in row:
print(item, end=" | ")
print()
print()
find = input("\033[1;35mWhat do you want to change?\033[0m ").capitalize()
print()
found = False
for row in todolist:
if find in row:
found = True
if not found:
print("\033[1;35mThat task is not in the list")
time.sleep(4)
print()
os.system('clear')
return
for row in todolist:
if find in row:
todolist.remove(row)
task = input("\033[1;35mThe new activity -\033[0m ").capitalize()
print()
date = input("\033[1;35mDue Date -\033[0m ")
print()
critical = input("\033[1;35mPriority - [High(H), Medium(M) or Low(L)] - \033[0 ").upper()
print()
new_row = [task, date, critical]
todolist.append(new_row)
print("\033[1;35mTask has been changed!\033[0m ")
print()
os.system("clear")
for row in todolist:
for item in row:
print(item, end=" | ")
print()
time.sleep(20)
os.system("clear")
return
while True:
title = "\033[1;35m \033[4mš To Do List š\033[0m"
print(f"{title:^20}")
print()
options = int(input("\033[1;34m Add -> 1\n \033[1;32mView -> 2\n \033[1;31mRemove -> 3\n \033[0;37mEdit -> 4\n\n \033[1;35mWhat Would You Like To Do - "))
print()
if options == 1:
prettyprintadd()
elif options == 2:
prettyprintview()
elif options == 3:
prettyprintremove()
elif options == 4:
prettyprintedit()
else:
print("Goodbye !āŗļø")
exit()
f = open("todo.txt", "w")
f.write(str(todolist))
f.close()
Why do you print something and then return it all in one function?
I thought the return had to be on the bottom. Even when I remove them the if- statement still doesnāt work.