Skip to content

Project: To-Do List Manager

Build a small task manager with classes that add, complete, remove, and report tasks.

20 min read 10 quiz questions

Stage 1: Make a Task class

A class is a blueprint for objects. Each Task will store a title and whether it is done. Its __str__ method chooses the text shown by print().

Stage 1: Represent one task
class Task:
    def __init__(self, title):
        self.title = title
        self.done = False

    def __str__(self):
        status = "done" if self.done else "todo"
        return f"{self.title} [{status}]"

task = Task("Buy milk")
print(task)

The new task starts with done set to False. Python calls __str__ when the task is printed.

Stage 2: Store tasks in a TodoList

A second class can keep a list of Task objects. Its add method creates and stores a task.

Stage 2: Add tasks to a list
class Task:
    def __init__(self, title):
        self.title = title
        self.done = False

    def __str__(self):
        status = "done" if self.done else "todo"
        return f"{self.title} [{status}]"

class TodoList:
    def __init__(self):
        self.tasks = []

    def add(self, title):
        self.tasks.append(Task(title))

todo = TodoList()
todo.add("Write code")
todo.add("Read notes")
for task in todo.tasks:
    print(task)

self.tasks is a list of objects. Each call to add appends one new Task.

Stage 3: Complete and remove tasks

Methods can search the task list. Mark a matching task done, or build a new list that leaves a matching task out.

Stage 3: Complete and remove tasks
class Task:
    def __init__(self, title):
        self.title = title
        self.done = False

    def __str__(self):
        mark = "x" if self.done else " "
        return f"[{mark}] {self.title}"

class TodoList:
    def __init__(self):
        self.tasks = []

    def add(self, title):
        self.tasks.append(Task(title))

    def complete(self, title):
        for task in self.tasks:
            if task.title == title:
                task.done = True

    def remove(self, title):
        self.tasks = [task for task in self.tasks if task.title != title]

todo = TodoList()
todo.add("Write code")
todo.add("Read notes")
todo.add("Buy fruit")
todo.complete("Write code")
todo.remove("Buy fruit")
for task in todo.tasks:
    print(task)

Completing changes one task object's done value. Removing rebuilds the list without the matching task.

Stage 4: Finish the to-do list manager

Add a list_tasks method for the numbered view and a final report that counts completed tasks.

Stage 4: Complete to-do list manager
class Task:
    def __init__(self, title):
        self.title = title
        self.done = False

    def __str__(self):
        mark = "x" if self.done else " "
        return f"[{mark}] {self.title}"

class TodoList:
    def __init__(self):
        self.tasks = []

    def add(self, title):
        self.tasks.append(Task(title))

    def complete(self, title):
        for task in self.tasks:
            if task.title == title:
                task.done = True
                return

    def remove(self, title):
        self.tasks = [task for task in self.tasks if task.title != title]

    def list_tasks(self):
        print("To-do list:")
        for number, task in enumerate(self.tasks, start=1):
            print(f"{number}. {task}")

todo = TodoList()
todo.add("Write code")
todo.add("Read notes")
todo.add("Buy fruit")
todo.complete("Write code")
todo.remove("Buy fruit")
todo.list_tasks()
completed = sum(task.done for task in todo.tasks)
print(f"Completed: {completed} of {len(todo.tasks)}")

The final report lists the remaining Task objects and counts the ones marked done. The manager now adds, completes, removes, and lists tasks.

Key points

  • A class is a blueprint for objects with data and methods.
  • __str__ controls how an object appears when printed.
  • A TodoList can store Task objects in a list.
  • Methods can add, complete, remove, and list tasks.
  • sum() can count True done values in a task list.

Worked example

A tiny task manager: tasks are dictionaries in a list, so each carries a title AND a done flag.

Example
tasks = [
    {"title": "Math homework", "done": True},
    {"title": "Buy eggs", "done": False},
]
pending = [task["title"] for task in tasks if not task["done"]]
print(pending)

How it works, step by step

  1. Each task is a dict — fields accessed by name.
  2. The comprehension filters on the done flag.
  3. Only unfinished titles survive.

References & Further Reading

Related entries from PyLabs's own reference library.

  • append() (Add a single item to the end of the list.)
  • copy() (Make a shallow copy of a list.)
  • sort() (Sort the elements of the list in ascending or custom order.)

Your notes

Sign in to keep private notes alongside this lesson.

Sign in to take notes

Practice exercise

Not passed yet

Create a Task class with title, done, and __str__ that returns [x] title when done and [ ] title otherwise. Create a TodoList class with add and complete methods. Add Plan trip, complete it, and print exactly [x] Plan trip.

# Define Task and TodoList
# Add and complete the requested task
Want another challenge on this module? More coding practice

Check yourself

Project: To-Do List Manager quiz

10 questions. You get instant feedback per question, and the timer starts when you press the button.

Lesson incomplete

Not completed

Create an ID or sign in to save lesson completion across devices.

Create ID to save
Module lesson progress0/4 complete
Module cheat sheet