One of the best ways to go from learning a programming language to truly knowing it is to build something. Theory is great, but practice is where you build confidence.
In this tutorial, we're going to build one of the most classic beginner projects: a Command-Line Interface (CLI) To-Do List app in Python.
Don't let "command-line" scare you. It just means we'll interact with our app through the terminal, not a fancy graphical interface. This lets us focus purely on the programming logic.
What You'll Learn
How to get user input
How to use data structures (Python lists and collections)
How to write and call Python functions
How to use while loops in Python
How to use
if/elif/elseto control your app's logic
Prerequisites
All you need is a basic understanding of Python fundamentals and to have Python 3 installed on your computer. That's it. Let's get started.
Step 1: Set Up Your Project
First, let's get organized.
Create a new folder for your project (e.g.,
todo-app).Inside that folder, create a new file named
todo.py.Open
todo.pyin your favorite code editor.
At the heart of our to-do list app is a place to store the tasks. We'll start by using a simple Python list. Add this one line of code to your todo.py file:
pythontasks = []
This list will live in memory, which means it will reset every time we restart the program. In a future tutorial, we'll cover file handling in Python so they persist.
Step 2: The Main Menu (The App's "Heartbeat")
We need our app to run continuously until the user decides to quit. To do this, we'll use a while True loop. This loop will be the "heartbeat" of our application, constantly running and waiting for user input.
Inside this loop, we'll print a menu of options for the user.
pythonwhile True: print("\n=== To-Do List ===") print("1. Add task") print("2. View tasks") print("3. Delete task") print("4. Quit") choice = input("Choose an option (1-4): ") if choice == '1': pass # We'll add functionality here elif choice == '2': pass elif choice == '3': pass elif choice == '4': print("Goodbye!") break else: print("Invalid choice. Please try again.")
You can actually run this file now! Save it and run it in your terminal:
bashpython todo.py
You'll see the menu, and you can type a choice. If you type 4, the program will print "Goodbye!" and exit. If you type 1, 2, or 3, it will do nothing (because of pass) and then show the menu again. This is our core app structure!
Step 3: Building the Features with Functions
Using pass isn't very useful. Let's make our app do things. To keep our code clean and reusable, we'll define a function for each feature.
Feature 1: Adding a Task
Let's create a function called add_task(). This function will ask the user for a task, add it to our tasks list, and print a confirmation.
Place this function definition above your while True loop:
pythondef add_task(task_list): task = input("Enter a new task: ") task_list.append(task) print(f"✓ Task '{task}' added!")
Now, let's "hook up" this function in our while loop. Replace the pass under if choice == '1': with a call to our new function:
pythonif choice == '1': add_task(tasks)
We pass our tasks list into the function so it can be modified.
Feature 2: Viewing Tasks
Next, let's build the view_tasks() function. This function will check if the list is empty. If it's not, it will loop through the list and print each task with a number.
Add this function definition below add_task():
pythondef view_tasks(task_list): if not task_list: print("No tasks yet. Your to-do list is empty!") else: print("\n=== Your Tasks ===") for index, task in enumerate(task_list, start=1): print(f"{index}. {task}")
Pro-Tip: We use enumerate(task_list, start=1) here. It's a clean way to get both the index (starting from 1) and the item from the list at the same time.
Now, let's hook this up in the while loop. Replace pass under if choice == '2'::
pythonelif choice == '2': view_tasks(tasks)
Feature 3: Deleting a Task
This is the most complex one, but we can handle it. The delete_task() function needs to:
Show the user all the tasks (hey, we can reuse
view_tasks()!).Ask them which task to delete (by number).
Validate their input.
Remove the correct task from the list.
Add this function definition:
pythondef delete_task(task_list): view_tasks(task_list) if task_list: try: task_num = int(input("Enter task number to delete: ")) if 1 <= task_num <= len(task_list): removed = task_list.pop(task_num - 1) print(f"✓ Deleted: '{removed}'") else: print("Invalid task number.") except ValueError: print("Please enter a valid number.")
Here, we used try...except for error handling to catch cases where the user types something that isn't a number. We also used the list pop() method, which removes an item at a specific index.
Finally, hook it into the while loop:
pythonelif choice == '3': delete_task(tasks)
Step 4: The Final Code
You're done! You've built a fully functional to-do list app. Here is the complete todo.py file so you can check your work:
pythontasks = [] def add_task(task_list): task = input("Enter a new task: ") task_list.append(task) print(f"✓ Task '{task}' added!") def view_tasks(task_list): if not task_list: print("No tasks yet. Your to-do list is empty!") else: print("\n=== Your Tasks ===") for index, task in enumerate(task_list, start=1): print(f"{index}. {task}") def delete_task(task_list): view_tasks(task_list) if task_list: try: task_num = int(input("Enter task number to delete: ")) if 1 <= task_num <= len(task_list): removed = task_list.pop(task_num - 1) print(f"✓ Deleted: '{removed}'") else: print("Invalid task number.") except ValueError: print("Please enter a valid number.") while True: print("\n=== To-Do List ===") print("1. Add task") print("2. View tasks") print("3. Delete task") print("4. Quit") choice = input("Choose an option (1-4): ") if choice == '1': add_task(tasks) elif choice == '2': view_tasks(tasks) elif choice == '3': delete_task(tasks) elif choice == '4': print("Goodbye!") break else: print("Invalid choice. Please try again.")
Next Steps: Challenge Yourself
Congratulations on building a real app! The best part of a project is adding your own features. Here are some ideas to challenge you:
Mark as Complete: Add a "Mark task as complete" option. You'll need to change your
taskslist. Instead of a list of strings, you could use Python dictionaries (e.g.,{'task': 'Buy milk', 'status': 'pending'}).Save & Load Tasks: As mentioned in Step 1, your list resets every time. Try using Python's file I/O capabilities to save the tasks list to a text file and load it when the app starts.
Build a GUI: Want to make it look professional? Try rebuilding this same logic in a graphical user interface (GUI). Start with Python basics for beginners and work your way up!
You just went from an empty file to a working program. By building small projects like this, you're building the most important skill a developer has: turning an idea into working code.
Explore more Python project ideas:
What project should we build next? Share your ideas and let's keep building!