Python To-Do Application

In the previous lesson, Python Named Tuples, we finished the advanced Python section. Now we will use the Python concepts we have learned to build a complete to-do application.

In this tutorial, we will build a Python To-Do application from scratch using VS Code. This is a beginner-friendly project that teaches lists, dictionaries, loops, functions, JSON file handling, and user input. By the end, we will have a working task manager that can add, view, complete, and delete tasks, with all data saved to a file.

What Is a To-Do Application?

A To-Do application is a program that helps us keep track of tasks we need to do. We can add new tasks, view all tasks, mark tasks as done, and delete tasks we no longer need.

Think of it like a digital notebook. Instead of writing on paper, we type our tasks into the program. And the program remembers them for us.

To-Do apps are everywhere. Our phones have them. Our computers have them. Even big companies use them to manage projects. They are simple but very useful.

Features of Our Python To-Do Application

Our To-Do app will have these features:

  • Add a new task
  • View all tasks
  • Mark a task as done
  • Delete a task
  • Save tasks to a file
  • Load tasks when the program starts

Project Folder Structure

We will create a folder for our project. Inside it, we will have one Python file and one data file.

todo_app/
todo.py
tasks.json

The tasks.json file stores our tasks. It will be created automatically when we save our first task.

Let us set up the project in VS Code.

Setting Up the Project in VS Code

Step 1: Open VS Code

If we do not have VS Code installed, we can download it from code.visualstudio.com. It is free.

Once installed, open VS Code.

Step 2: Create a New Folder

  • Click on File in the top menu.
  • Click Open Folder.
  • Navigate to where we want to keep our project (like Desktop or Documents).
  • Click New Folder.
  • Name it todo_app.
  • Click Select Folder.

Now VS Code is open with our new empty folder.

Step 3: Create the Python File

  • In the left sidebar, we see our folder name todo_app.
  • Right-click on the folder name.
  • Click New File.
  • Name it todo.py.
  • Press Enter.

Now we have an empty todo.py file ready for code.

Step 4: Open the Integrated Terminal

  • Click on Terminal in the top menu.
  • Click New Terminal.

A terminal panel opens at the bottom. It is already inside our todo_app folder. So we do not need to cd anywhere.

Now we are ready to write code.

How to Create the To-Do App in Python (Step by Step)

We will write the code in small steps. Before each step, we will explain what we are doing and why. We will mention which file we are editing (always todo.py in this project).

Step 1: Import Required Modules

We need two modules. json for saving and loading tasks, and os for checking if the file exists.

todo.py
import json
import os

Step 2: Define the Tasks File

We will store tasks in a file called tasks.json. Let us define it as a constant.

todo.py
TASKS_FILE = "tasks.json"

Step 3: Create a Function to Load Tasks

When the program starts, we want to show the user their existing tasks. So we read the file and convert it back into a Python list of dictionaries.

todo.py
def load_tasks():
if not os.path.exists(TASKS_FILE):
return []
with open(TASKS_FILE, "r") as file:
return json.load(file)

Step 4: Create a Function to Save Tasks

Whenever we add, mark, or delete a task, we save the changes so they are not lost.

todo.py
def save_tasks(tasks):
with open(TASKS_FILE, "w") as file:
json.dump(tasks, file, indent=4)

Step 5: Create a Function to Add a Task

The user types a task, and we add it to our list. We also save the updated list to the file.

todo.py
def add_task(tasks):
title = input("Enter task: ").strip()
if not title:
print("Task cannot be empty")
return
task = {
"title": title,
"done": False
}
tasks.append(task)
save_tasks(tasks)
print(f"Task added: {title}")

Step 6: Create a Function to View All Tasks

The user needs to see what tasks they have. We loop through the list and print each task with its status.

todo.py
def view_tasks(tasks):
if not tasks:
print("No tasks yet")
return
print("\nYour Tasks:")
print("-" * 40)
for i, task in enumerate(tasks, 1):
status = "Done" if task["done"] else "Pending"
print(f"{i}. [{status}] {task['title']}")
print("-" * 40)

Step 7: Create a Function to Mark a Task as Done

The user wants to track completed tasks. We show the tasks, ask for a number, and update the done flag.

todo.py
def mark_done(tasks):
view_tasks(tasks)
if not tasks:
return
try:
number = int(input("Enter task number to mark as done: "))
if 1 <= number <= len(tasks):
tasks[number - 1]["done"] = True
save_tasks(tasks)
print("Task marked as done")
else:
print("Invalid task number")
except ValueError:
print("Please enter a valid number")

Step 8: Create a Function to Delete a Task

Sometimes tasks are no longer needed. The user should be able to remove them.

todo.py
def delete_task(tasks):
view_tasks(tasks)
if not tasks:
return
try:
number = int(input("Enter task number to delete: "))
if 1 <= number <= len(tasks):
removed = tasks.pop(number - 1)
save_tasks(tasks)
print(f"Deleted: {removed['title']}")
else:
print("Invalid task number")
except ValueError:
print("Please enter a valid number")

Step 9: Create the Main Menu Function

This is the control center. It shows the options to the user and calls the right function based on their choice.

todo.py
def main():
tasks = load_tasks()
while True:
print("\n===== TO-DO APP =====")
print("1. Add task")
print("2. View tasks")
print("3. Mark task as done")
print("4. Delete task")
print("5. Exit")
choice = input("Enter your choice: ").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!")
break
else:
print("Invalid choice")

Step 10: Run the To-Do App Program

Finally, let us add the program entry point.

todo.py
if __name__ == "__main__":
main()

Complete Python To-Do App Code

Now our complete todo.py file looks like this.

import json
import os
TASKS_FILE = "tasks.json"
def load_tasks():
if not os.path.exists(TASKS_FILE):
return []
with open(TASKS_FILE, "r") as file:
return json.load(file)
def save_tasks(tasks):
with open(TASKS_FILE, "w") as file:
json.dump(tasks, file, indent=4)
def add_task(tasks):
title = input("Enter task: ").strip()
if not title:
print("Task cannot be empty")
return
task = {
"title": title,
"done": False
}
tasks.append(task)
save_tasks(tasks)
print(f"Task added: {title}")
def view_tasks(tasks):
if not tasks:
print("No tasks yet")
return
print("\nYour Tasks:")
print("-" * 40)
for i, task in enumerate(tasks, 1):
status = "Done" if task["done"] else "Pending"
print(f"{i}. [{status}] {task['title']}")
print("-" * 40)
def mark_done(tasks):
view_tasks(tasks)
if not tasks:
return
try:
number = int(input("Enter task number to mark as done: "))
if 1 <= number <= len(tasks):
tasks[number - 1]["done"] = True
save_tasks(tasks)
print("Task marked as done")
else:
print("Invalid task number")
except ValueError:
print("Please enter a valid number")
def delete_task(tasks):
view_tasks(tasks)
if not tasks:
return
try:
number = int(input("Enter task number to delete: "))
if 1 <= number <= len(tasks):
removed = tasks.pop(number - 1)
save_tasks(tasks)
print(f"Deleted: {removed['title']}")
else:
print("Invalid task number")
except ValueError:
print("Please enter a valid number")
def main():
tasks = load_tasks()
while True:
print("\n===== TO-DO APP =====")
print("1. Add task")
print("2. View tasks")
print("3. Mark task as done")
print("4. Delete task")
print("5. Exit")
choice = input("Enter your choice: ").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!")
break
else:
print("Invalid choice")
if __name__ == "__main__":
main()

How to Run the To-Do App in VS Code

We have two ways to run the program.

Way 1: Using the Terminal

In the VS Code terminal, type:

Terminal window
python todo.py

Way 2: Using the Run Button

  • Open todo.py in the editor.
  • Look at the top right corner. There is a small play button (triangle).
  • Click it. VS Code will run the file in the terminal.

Both ways work. Use whichever we prefer.

Example Output

===== TO-DO APP =====
1. Add task
2. View tasks
3. Mark task as done
4. Delete task
5. Exit
Enter your choice: 1
Enter task: Buy groceries
Task added: Buy groceries
===== TO-DO APP =====
...
Enter your choice: 2
Your Tasks:
----------------------------------------
1. [Pending] Buy groceries
----------------------------------------

That is our To-Do app. It is simple but complete. And we built it entirely in VS Code.

Exercises for Practice

Try these exercises to improve the To-Do app.

  1. Add a due date field to each task.
  2. Add a priority level (high, medium, low) to each task.
  3. Add a category (work, personal, shopping) to each task.
  4. Add a search feature to find tasks by keyword.
  5. Add a “clear completed” option that removes all done tasks.
  6. Add an option to edit an existing task’s title.
  7. Add sorting: show tasks by priority or due date.

Now let us build the next project: the Expense Tracker. We will also use VS Code for that.

Next, we will build a Python Calculator Application and practice functions, input, loops, and file handling in another complete project.