It’s time for another project! We’ve spent the last several posts exploring Python’s most versatile data structure, the list. We’ve learned how to create them, add to them, remove from them, and loop through them like a pro. Now, we will combine all of that knowledge to build a useful, interactive program: a command-line to-do list application.
Our program will be able to view all current tasks, add new tasks, remove completed tasks, and exit. It’s a perfect example of how the concepts we’ve learned can come together to create something functional.
Step 1: The Setup
Let’s start by creating a new file named todo.py
. The core of our application will be a while
loop that keeps the program running and a list that stores our tasks. We’ll start with an empty list.
# Our list to store the to-do items
tasks = []
print("--- Welcome to your To-Do List ---")
# The main application loop
while True:
# Display the menu and get user input
print("\n--- To-Do List Menu ---")
print("1. View all tasks")
print("2. Add a task")
print("3. Remove a task")
print("4. Exit")
choice = input("Enter your choice (1-4): ")
# We will add the logic for our choices here
if choice == '4':
break
print("Goodbye!")
This code sets up our main application loop using the while True
and break
pattern from Post #38. Now, let’s fill in the logic for our other choices.
Step 2: Implementing the Menu Choices
We will use an if-elif-else
chain (from Post #27) inside our while
loop to handle the user’s input.
Choice 1: View Tasks
If the user chooses “1”, we should show them all their tasks in a numbered list. We’ll use enumerate()
(from Post #56) to make this easy. We should also handle the case where the list is empty.
if choice == '1':
print("\n--- Your Tasks ---")
if not tasks: # A Falsy check from Post #24
print("Your to-do list is empty.")
else:
for index, task in enumerate(tasks, start=1):
print(f"{index}. {task}")
Choice 2: Add a Task
If the user chooses “2”, we need to ask them for the task and use .append()
(from Post #50) to add it to our list.
elif choice == '2':
new_task = input("What task would you like to add? ")
tasks.append(new_task)
print(f"'{new_task}' has been added to your list.")
Choice 3: Remove a Task
This is our most complex step. We need to show the user the tasks, ask which one to remove by number, and then use .pop()
(from Post #51) to remove it. We must also validate their input to make sure the number is in a valid range.
elif choice == '3':
if not tasks:
print("Your to-do list is empty, nothing to remove.")
else:
print("\n--- Current Tasks ---")
for index, task in enumerate(tasks, start=1):
print(f"{index}. {task}")
task_num_str = input("Enter the number of the task to remove: ")
task_num = int(task_num_str)
# Check if the number is valid
if 1 <= task_num <= len(tasks):
# Adjust for zero-based indexing
removed_task = tasks.pop(task_num - 1)
print(f"Removed task: '{removed_task}'")
else:
print("Invalid task number.")
Handling Invalid Input
Finally, we add an else
block to catch any input that isn’t one of our valid choices.
else:
print("Invalid choice. Please enter a number between 1 and 4.")
The Complete Program
Here is the full, commented script for our to-do list application.
# Our list to store the to-do items
tasks = []
print("--- Welcome to your To-Do List ---")
# The main application loop
while True:
# Display the menu and get user input
print("\n--- To-Do List Menu ---")
print("1. View all tasks")
print("2. Add a task")
print("3. Remove a task")
print("4. Exit")
choice = input("Enter your choice (1-4): ")
if choice == '1': # View Tasks
print("\n--- Your Tasks ---")
if not tasks:
print("Your to-do list is empty.")
else:
for index, task in enumerate(tasks, start=1):
print(f"{index}. {task}")
elif choice == '2': # Add Task
new_task = input("What task would you like to add? ")
tasks.append(new_task)
print(f"'{new_task}' has been added to your list.")
elif choice == '3': # Remove Task
if not tasks:
print("Your to-do list is empty, nothing to remove.")
else:
print("\n--- Current Tasks ---")
for index, task in enumerate(tasks, start=1):
print(f"{index}. {task}")
task_num_str = input("Enter the number of the task to remove: ")
task_num = int(task_num_str)
if 1 <= task_num <= len(tasks):
removed_task = tasks.pop(task_num - 1)
print(f"Removed task: '{removed_task}'")
else:
print("Invalid task number.")
elif choice == '4': # Exit
break
else: # Handle invalid menu choices
print("Invalid choice. Please enter a number between 1 and 4.")
print("Goodbye!")
What’s Next?
You’ve successfully built a functional to-do list manager! This project combines loops, conditionals, user input, and a wide array of list methods. You are now able to create interactive command-line applications that manage collections of data.
Our to-do list is a great example of using a mutable, or changeable, collection of data. But sometimes, you need a collection of items that should never change after it’s created. For this, Python provides an immutable version of a list. In Post #58, we will be introduced to tuples.
Author

Experienced Cloud & DevOps Engineer with hands-on experience in AWS, GCP, Terraform, Ansible, ELK, Docker, Git, GitLab, Python, PowerShell, Shell, and theoretical knowledge on Azure, Kubernetes & Jenkins. In my free time, I write blogs on ckdbtech.com