Adding data structure
To add a mark as done feature, we will need a data structure to store the todos. Up until now, we only store todo as a string.
With data structure, we can store more information about the todo, such as whether it is done or not.
Create the structure
A basic data structure is to imagine a table with 2 columns todo and done:
| todo | is_done |
|---|---|
| Buy milk | False |
| Wash shoes | False |
| Print assign | False |
Then, how do we represent this table in Python? We can use a list of dictionaries:
todos = [
{
"todo": "Buy milk",
"is_done": False
},
{
"todo": "Wash shoes",
"is_done": False
},
{
"todo": "Print assignment",
"is_done": False
}
]
A dictionary is a data structure that stores key-value pairs.
In this case, the keys are todo and is_done.The todo key stores the todo string,
and the is_done key stores a boolean value,
true means the todo is done, false means the todo is not done.
Implement the data structure
Let's update the add_todo function to use the new data structure.
Instead of stroing the todo as a string, we will store it as a dictionary.
And give a default value of False to is_done key.
# main.py
def main():
todos = []
todos = add_todo(todos, "Buy milk")
todos = add_todo(todos, "Wash shoes")
todos = add_todo(todos, "Print assignment")
print_todos(todos)
print("Removing todo at index 1")
todos = remove_todo(todos, 1)
print("----")
print_todos(todos)
def add_todo(todos: list, todo: str):
todos.append({
"todo": todo,
"is_done": False
})
return todos
def print_todos(todos: list):
for todo in todos:
print(f"- {todo}")
def remove_todo(todos: list, index: int):
todos.pop(index)
return todos
# this will run the `main` function when we run the program `python3 main.py`
if __name__ == "__main__":
main()
If you print the above code we will get the following output:
- {'todo': 'Buy milk', 'is_done': False}
- {'todo': 'Wash shoes', 'is_done': False}
- {'todo': 'Print assignment', 'is_done': False}
Removing todo at index 1
----
- {'todo': 'Buy milk', 'is_done': False}
- {'todo': 'Print assignment', 'is_done': False}
It will print the dictionary, we want to update the print_todos function
to format the output instead of the dictionary
# main.py
def main():
todos = []
todos = add_todo(todos, "Buy milk")
todos = add_todo(todos, "Wash shoes")
todos = add_todo(todos, "Print assignment")
print_todos(todos)
print("Removing todo at index 1")
todos = remove_todo(todos, 1)
print("----")
print_todos(todos)
def add_todo(todos: list, todo: str):
todos.append({
"todo": todo,
"is_done": False
})
return todos
def print_todos(todos: list):
for todo in todos:
print(f"- {todo['todo']}")
def remove_todo(todos: list, index: int):
todos.pop(index)
return todos
# this will run the `main` function when we run the program `python3 main.py`
if __name__ == "__main__":
main()
In above code, we are using todo['todo'] to get the value of todo key in the dictionary.
the ['todo']
Marking todo as done
Now, let's add a function mark_todo_done to mark a todo as done.
What we will do is change the value of is_done key to True.
We will use the index again to find the todo we want to mark as done.
# main.py
def main():
todos = []
todos = add_todo(todos, "Buy milk")
todos = add_todo(todos, "Wash shoes")
todos = add_todo(todos, "Print assignment")
print_todos(todos)
print("Removing todo at index 1")
todos = remove_todo(todos, 1)
print("----")
print_todos(todos)
print("Marking todo at index 0 as done")
todos = mark_todo_done(todos, 0)
print("----")
print_todos(todos)
def add_todo(todos: list, todo: str):
todos.append({
"todo": todo,
"is_done": False
})
return todos
def print_todos(todos: list):
for todo in todos:
print(f"- {todo['todo']}")
def remove_todo(todos: list, index: int):
todos.pop(index)
return todos
def mark_todo_done(todos: list, index: int):
todos[index]["is_done"] = True
return todos
# this will run the `main` function when we run the program `python3 main.py`
if __name__ == "__main__":
main()
If you run the above code, you will get the following output, there is no change in the output.
We also need to update the print_todos function to show the is_done value.
# main.py
def main():
todos = []
todos = add_todo(todos, "Buy milk")
todos = add_todo(todos, "Wash shoes")
todos = add_todo(todos, "Print assignment")
print_todos(todos)
print("Removing todo at index 1")
todos = remove_todo(todos, 1)
print("----")
print_todos(todos)
print("Marking todo at index 0 as done")
todos = mark_todo_done(todos, 0)
print("----")
print_todos(todos)
def add_todo(todos: list, todo: str):
todos.append({
"todo": todo,
"is_done": False
})
return todos
def print_todos(todos: list):
for todo in todos:
if todo["is_done"]:
print(f"- [x] {todo['todo']}")
else:
print(f"- [ ] {todo['todo']}")
def remove_todo(todos: list, index: int):
todos.pop(index)
return todos
def mark_todo_done(todos: list, index: int):
todos[index]["is_done"] = True
return todos
# this will run the `main` function when we run the program `python3 main.py`
if __name__ == "__main__":
main()
In the above code, we are using if statement to check if the is_done value is True or False
and print different output based on the is_done value.
If you run the above code, you will get the following output:
- [ ] Buy milk
- [ ] Wash shoes
- [ ] Print assignment
Removing todo at index 1
----
- [ ] Buy milk
- [ ] Print assignment
Marking todo at index 0 as done
---
- [x] Buy milk
- [ ] Print assignment