🎓 A1Learner
🔍

Python Project: To-Do List

A to-do app is a program that tracks jobs in a list. The app adds, shows, and finishes tasks.

A task is a small dict

A dict holds labelled values. Here the labels are task for the job and done for the flag.

task = {"task": "Buy milk", "done": False}
print(task["task"])
print(task["done"])

Hold tasks in a list

The list keeps the tasks in order. append() adds one task dict at the end.

tasks = []
tasks.append({"task": "Buy milk", "done": False})
tasks.append({"task": "Walk the dog", "done": False})
print(len(tasks))
print(tasks[0]["task"])

Mark a task done

You change the done value inside the dict. The job text stays the same.

task = {"task": "Buy milk", "done": False}
task["done"] = True
print(task["done"])

Save and load lines

Each task goes on its own line in the save file.

names = ["Buy milk", "Walk the dog"]
with open("tasks_demo.txt", "w") as file:
    for name in names:
        file.write(name + "\n")
with open("tasks_demo.txt") as file:
    for line in file:
        print(line.strip())

Example

import os


def load_tasks():
    tasks = []
    if not os.path.exists("tasks.txt"):
        return tasks
    with open("tasks.txt") as file:
        for line in file:
            done_text, name = line.strip().split("|", 1)
            tasks.append({"task": name, "done": done_text == "1"})
    return tasks


def save_tasks(tasks):
    with open("tasks.txt", "w") as file:
        for task in tasks:
            done_text = "1" if task["done"] else "0"
            file.write(done_text + "|" + task["task"] + "\n")


def show_tasks(tasks):
    if len(tasks) == 0:
        print("No tasks yet.")
    number = 1
    for task in tasks:
        mark = "x" if task["done"] else " "
        print(f"{number}. [{mark}] {task['task']}")
        number += 1


def main():
    tasks = load_tasks()
    while True:
        print("Menu: add, view, done, quit")
        choice = input("Choose: ")
        if choice == "add":
            name = input("Task name: ")
            tasks.append({"task": name, "done": False})
            print("Added.")
        elif choice == "view":
            show_tasks(tasks)
        elif choice == "done":
            number = int(input("Task number: "))
            tasks[number - 1]["done"] = True
            print("Marked done.")
        elif choice == "quit":
            save_tasks(tasks)
            print("Saved. Bye!")
            break


main()

Key points

  • Task: one dict that holds the job text and a done flag
  • Use a list to hold all the task dicts in order
  • Use open() with with to read or write the save file
  • Use one line per task in the save file, like 1|Buy milk
  • Use os.path.exists() so a first run, with no save file yet, starts empty

In this example, the app runs on scripted input. With this input, one value per line: add, Buy milk, add, Walk the dog, view, done, 1, view, quit. load_tasks finds no save file, so the list starts empty. The two add rounds append one task dict each. View shows both tasks as open. The done round marks task 1, so the next view shows an x for Buy milk. Quit calls save_tasks, which writes one line per task. The saved file holds 1|Buy milk and 0|Walk the dog. On a later start, load_tasks cuts each line at the first | sign. The left part rebuilds the done flag, and the right part rebuilds the job text.

Note

The save file holds plain text lines.

Python reads them back and rebuilds each dict by hand.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Python Playground

Exercise

How does the program store one task?