Beginner’s Guide: To-Do List App in Python
Are you ready to take your first big step in Python programming? Building a to-do list app is the perfect beginner project to combine learning with productivity. I still remember the thrill of seeing my own tasks appear and disappear as I checked them off-there’s something truly satisfying about coding a tool you’ll actually use every day. In this guide, I’ll share my personal experience and walk you through every step of creating your own to-do list app in Python, from the basics to adding extra features.

Introduction
A to-do list app helps you organize your day, boost productivity, and track your progress. For beginners, it’s a fantastic way to master Python essentials: lists, functions, user input, file handling, and even GUI programming if you’re feeling adventurous. The best part? You’ll finish with an app you’ll actually use-just like I did when I started my coding journey.
- Reinforces core programming concepts
- Teaches user input and file management
- Introduces GUI programming with Tkinter (optional)
- Results in a practical, real-world tool
Required Libraries
The beauty of this project is its simplicity. You don’t need any fancy external libraries-just Python’s built-in modules. If you want to make a graphical app, we’ll use Tkinter, which comes pre-installed with Python 3.x.
- Command-line app: No external libraries needed
- GUI app: Tkinter (bundled with Python)
Open your favorite code editor (I’m partial to VS Code for its clean interface, but any editor will do) and create a new file called todo_app.py
.
Step-by-Step Coding
1. Command-Line To-Do List App
Let’s start with a simple command-line version. This is how I built my first to-do list app, and it’s a great way to learn the basics.
a. Displaying the Menu
def display_menu(): print("\nMenu:") print("1. Add Task") print("2. View Tasks") print("3. Mark as Done") print("4. Exit")
b. Managing the Task List
tasks = []
def add_task():
description = input("Enter task description: ")
tasks.append({"description": description, "completed": False})
print("Task added!")
def view_tasks():
if not tasks:
print("No tasks found.")
return
for idx, task in enumerate(tasks, 1):
status = "✔️" if task["completed"] else "❌"
print(f"{idx}. {task['description']} [{status}]")
def mark_done():
view_tasks()
if not tasks:
return
try:
idx = int(input("Enter task number to mark as done: ")) - 1
tasks[idx]["completed"] = True
print("Task marked as completed!")
except (ValueError, IndexError):
print("Invalid input. Please try again.")
c. Saving and Loading Tasks
import json import os
FILENAME = "tasks.json"
def save_tasks():
with open(FILENAME, "w") as f:
json.dump(tasks, f)
def load_tasks():
global tasks
if os.path.exists(FILENAME):
with open(FILENAME, "r") as f:
tasks.extend(json.load(f))
d. Main Application Loop
def main(): load_tasks() while True: display_menu() choice = input("Choose an option: ") if choice == "1": add_task() save_tasks() elif choice == "2": view_tasks() elif choice == "3": mark_done() save_tasks() elif choice == "4": save_tasks() print("Goodbye!") break else: print("Invalid choice. Please try again.")
if name == "main":
main()
Personal tip: When I first built this, I’d often forget to save my tasks. Automating saves after each change means you’ll never lose your progress!
2. GUI To-Do List App with Tkinter
Once you’re comfortable with the command-line version, try building a graphical version. The first time I saw my app with clickable buttons and a listbox, it felt like magic!
a. Setting Up Tkinter
import tkinter as tk from tkinter import messagebox
tasks = []
def add_task():
task = entry_task.get()
if task != "":
listbox_tasks.insert(tk.END, task)
tasks.append({"description": task, "completed": False})
entry_task.delete(0, tk.END)
save_tasks()
else:
messagebox.showwarning("Warning", "You must enter a task.")
def delete_task():
try:
selected_index = listbox_tasks.curselection()
listbox_tasks.delete(selected_index)
del tasks[selected_index]
save_tasks()
except IndexError:
messagebox.showwarning("Warning", "You must select a task.")
def mark_completed():
try:
selected_index = listbox_tasks.curselection()
tasks[selected_index]["completed"] = True
listbox_tasks.delete(selected_index)
listbox_tasks.insert(selected_index, tasks[selected_index]["description"] + " ✔️")
save_tasks()
except IndexError:
messagebox.showwarning("Warning", "You must select a task.")
def save_tasks():
with open(FILENAME, "w") as f:
json.dump(tasks, f)
def load_tasks():
if os.path.exists(FILENAME):
with open(FILENAME, "r") as f:
loaded = json.load(f)
for task in loaded:
tasks.append(task)
desc = task["description"] + (" ✔️" if task.get("completed") else "")
listbox_tasks.insert(tk.END, desc)
window = tk.Tk()
window.title("Python To-Do List App")
frame_tasks = tk.Frame(window)
frame_tasks.pack()
listbox_tasks = tk.Listbox(frame_tasks, height=15, width=50)
listbox_tasks.pack(side=tk.LEFT)
scrollbar_tasks = tk.Scrollbar(frame_tasks)
scrollbar_tasks.pack(side=tk.RIGHT, fill=tk.Y)
listbox_tasks.config(yscrollcommand=scrollbar_tasks.set)
scrollbar_tasks.config(command=listbox_tasks.yview)
entry_task = tk.Entry(window, width=52)
entry_task.pack()
button_add_task = tk.Button(window, text="Add Task", width=48, command=add_task)
button_add_task.pack()
button_delete_task = tk.Button(window, text="Delete Task", width=48, command=delete_task)
button_delete_task.pack()
button_mark_completed = tk.Button(window, text="Mark as Completed", width=48, command=mark_completed)
button_mark_completed.pack()
load_tasks()
window.mainloop()
Personal tip: GUI apps can seem intimidating at first, but breaking them down into small functions (add, delete, mark complete) makes them much more manageable. I found it helpful to sketch my app layout on paper before coding.
Adding Features (e.g., Save to File)
One of the best parts about building your own to-do list app is customizing it. Here are some features you can add:
- Save to File: Use JSON to save and load tasks so your list persists between sessions.
- Mark as Completed: Visually indicate completed tasks (I like adding a checkmark or changing the color).
- Delete Tasks: Remove tasks you no longer need.
- Edit Tasks: Allow users to update task descriptions.
- Due Dates: Add an optional due date for each task.
- Priorities: Let users set task priorities (e.g., high, medium, low).
Personal experience: After using my app for a few weeks, I realized I wanted to sort tasks by priority. Adding that feature made my app even more useful-and taught me more about Python lists and sorting!
Final Thoughts
Building a to-do list app in Python is a fantastic beginner project. You’ll learn about lists, functions, user input, file handling, and even GUIs with Tkinter. More importantly, you’ll end up with a tool that helps you stay organized and productive.
When I first started, I was just hoping to get the basics working. But as I added features and polished the interface, I found myself using the app every day. That’s the magic of coding-turning ideas into reality, one line at a time.
Ready to build your own to-do list app in Python? Start simple, experiment with new features, and don’t be afraid to make mistakes. Every bug is a learning opportunity. And who knows? You might just build the next great productivity tool!