COMPUTER PROGRAMMING 1 (PYTHON) • PROBLEM SOLVING & MINI-PROJECTS

Building To-Do List — I can build a menu-based to-do list using a list with add/remove/display actions.

Learn to combine lists, loops, and conditionals into an interactive program that manages tasks from the command line.

Historical Context & Motivation

Long before apps like Todoist or Apple Reminders existed, programmers solved the problem of task management with simple text-based programs. These early programs ran entirely in a terminal window, presenting users with numbered menus and responding to their keyboard input. The concept of organizing data into a list structure and letting users interact with it through a menu is one of the oldest and most fundamental patterns in software development.

Understanding this pattern matters because nearly every application you use daily—from social media feeds to shopping carts—relies on the same core idea: storing a collection of items and providing the user with actions to create, read, update, or delete them. Building a to-do list is the simplest way to practice this universal concept.

1960s
Text-Based Menus Emerge
Early mainframe computers used text-only interfaces. Users selected numbered options from menus printed on terminals to interact with programs.
1991
Python Is Released
Guido van Rossum releases Python, a language designed for readability and rapid prototyping. Its built-in list data type makes collection management straightforward.
2000s
CRUD Pattern Dominates Web Apps
The Create-Read-Update-Delete (CRUD) pattern becomes the standard model for web applications, from blogs to e-commerce. A to-do list is the simplest CRUD app.
2010s
To-Do Apps Go Mobile
Apps like Wunderlist, Todoist, and Apple Reminders bring task management to smartphones, but the underlying logic—add, remove, display—remains identical to the text-based originals.

The question our project addresses is deceptively simple: how do you write a program that keeps running, responds to user choices, and modifies a collection of data in real time? By the end of this lesson, you will have built a fully functional, menu-driven to-do list in Python that answers that question.

Core Principles & Definitions

Before writing any code, you need to understand the four building blocks that power every menu-based program. Each one maps directly to a Python feature you have already learned, and combining them is the key to creating interactive software.

1

The List

A Python list stores an ordered, mutable collection of items. It supports .append() to add items and .remove() to delete them. This is where your tasks live.
2

The Loop

A while True loop keeps the program running until the user explicitly chooses to quit. This is often called the main loop or event loop.
3

The Menu & Input

A printed menu shows numbered options. The input() function captures the user's choice as a string. This is the program's user interface (UI).
4

Conditional Branching

An if/elif/else chain checks the user's input and routes the program to the correct action—add, remove, display, or quit.
✦ KEY TAKEAWAY
Think of your to-do list program like a drive-through restaurant. The menu board (printed options) tells customers what they can order. The speaker box (input()) collects their choice. The kitchen staff (if/elif) decides what to do. And the order list (Python list) keeps track of everything. The drive-through stays open (the loop) until the last car leaves.

Visual Explanation — Program Flow

The diagram below shows the overall flow of a menu-based to-do list program. Notice how the main loop wraps around the entire decision structure. The program only exits when the user selects "Quit," which triggers a break statement that escapes the loop.

The flowchart shows the main loop (yellow), the decision diamond (pink), and each action branch: Add, Remove, Display, and Quit. All branches except Quit loop back to the menu.

Every action in the diagram maps to a small block of Python code. The Add branch prompts the user for a task name and calls tasks.append(task). The Remove branch asks which task to delete and calls tasks.remove(task). The Display branch iterates through the list with a for loop and prints each item. The Quit branch uses break to exit the loop and end the program.

How It Works — The Code Structure

Let's break the to-do list program into its three main code regions. Understanding how these regions interact is more important than memorizing any single line of code.

Region 1 — Initialization

Before the loop begins, you create an empty list to store tasks. This is a single line: tasks = []. The empty square brackets tell Python to create a mutable (changeable) list with zero items. Every action inside the loop will modify this same list.

Region 2 — The Main Loop & Menu

The while True loop is an infinite loop — it will run forever unless you explicitly break out of it. Inside the loop, you first print the menu options using several print() statements, then capture the user's response with choice = input("Enter choice: "). Remember that input() always returns a string, so you compare it to string values like "1", "2", and so on.

Region 3 — The Action Branches

An if/elif/else chain inspects the user's choice. Each branch contains a small, focused block of logic. The add branch calls input() again to get the task name, then appends it. The remove branch should include error handling — what if the user tries to remove a task that doesn't exist? You can use if task in tasks to check before calling .remove(). The display branch uses enumerate() to print each task with a number. Finally, the else clause handles invalid input by printing an error message.

⚠️ Common Bug Alert
If you forget to include a break in the Quit branch, your program will run forever! Always test the Quit option first when debugging.

Detailed Breakdown — List Operations in Action

The diagram below traces the state of the tasks list through a sample session. Watch how the list changes after each user action. This is called tracing — stepping through your program's data changes one operation at a time — and it is one of the most powerful debugging techniques you can learn.

This trace table follows seven interactions with the to-do list. Green borders mark add operations, orange marks remove, blue marks display, and red marks quit.
Key Python list methods and functions used in the to-do list
MethodWhat It DoesExample
.append(item)Adds item to the end of the listtasks.append("Essay")
.remove(item)Removes the first occurrence of item; raises ValueError if not foundtasks.remove("Essay")
enumerate(list, start)Returns pairs of (index, item), starting index at startenumerate(tasks, 1)
len(list)Returns the number of items currently in the listlen(tasks)
item in listReturns True if item exists in the list; useful for validation"Essay" in tasks

Worked Example — Building the Complete Program

Let's build the entire to-do list program step by step. Each step adds a new region of code. By the end, you will have a complete, working program that you can run in any Python environment.

Building a Menu-Based To-Do List
1
Step 1 — Initialize the ListStart by creating an empty list to hold tasks. This line goes at the very top of your program, before the loop.
tasks = []
2
Step 2 — Create the Main Loop and MenuWrap everything in a while True loop. Inside, print the menu options and capture the user's choice. Use print() for each option and input() to read the selection.
while True: print("\n--- To-Do List ---") print("1. Add task") print("2. Remove task") print("3. Display tasks") print("4. Quit") choice = input("Enter choice (1-4): ")
3
Step 3 — Add the Add-Task BranchIf the user enters "1", prompt for a task description and append it to the list. Print a confirmation message so the user knows the task was added.
if choice == "1": task = input("Enter task: ") tasks.append(task) print(f"'{task}' added!")
4
Step 4 — Add the Remove-Task Branch with ValidationIf the user enters "2", ask which task to remove. Before calling .remove(), check if the task actually exists using if task in tasks. If it doesn't exist, print an error message instead of crashing.
elif choice == "2": task = input("Enter task to remove: ") if task in tasks: tasks.remove(task) print(f"'{task}' removed!") else: print("Task not found.")
5
Step 5 — Add the Display BranchIf the user enters "3", check whether the list is empty first. If it is, print a friendly message. Otherwise, use enumerate(tasks, 1) to print each task with a number starting at 1.
elif choice == "3": if not tasks: print("No tasks yet!") else: for i, task in enumerate(tasks, 1): print(f"{i}. {task}")
6
Step 6 — Add the Quit Branch and Invalid Input HandlerIf the user enters "4", print a goodbye message and use break to exit the loop. The else clause catches any input that isn't 1–4 and tells the user to try again.
elif choice == "4": print("Goodbye!") break else: print("Invalid choice. Please enter 1-4.")
🚀 Try It Yourself
Copy all six steps into a single Python file, making sure each if/elif/else block is indented under the while True loop. Run it and test every menu option, including entering invalid choices like "5" or "hello".

Strengths, Limitations & Comparisons

Our to-do list is a great first project, but like any program, it has both strengths and limitations. Understanding these helps you think critically about your code and plan improvements.

Evaluating our to-do list program
Strengths ✅Limitations ⚠️
Simple and easy to understand — great for learning fundamentalsData is lost when the program closes (no file saving)
Demonstrates core Python concepts: lists, loops, conditionals, inputRemove requires exact text match (case-sensitive)
Handles invalid input gracefully with else clauseNo way to edit an existing task — only add or remove
Easy to extend with new featuresNo priority levels or due dates
Validates that task exists before removingText-only interface — no graphical UI
✦ KEY TAKEAWAY
Every real-world application started as a simple version like this. Instagram began as a single-feature photo app. The to-do list you just built is a minimum viable product (MVP) — the smallest working version of your idea. Professional developers build MVPs first, test them, and then add features one at a time. You can do the same by adding file saving, task editing, or priority sorting to your to-do list.

Connection to Advanced Concepts

The to-do list you built in this lesson is a simplified version of patterns used in professional software development. The table below shows how each part of your program connects to more advanced concepts you may encounter in future courses.

From beginner project to professional patterns
Your To-Do ListAdvanced VersionWhere You'll See It
tasks = []Database table (SQL, MongoDB)Web development, AP CS Principles
while True menu loopEvent-driven GUI loop or web server request handlerDesktop apps, Flask/Django web frameworks
if/elif/else branchingURL routing, command pattern, state machinesSoftware engineering, game development
.append() / .remove()CRUD operations (Create, Read, Update, Delete)Every web app, mobile app, and API
input() for user interactionHTML forms, REST API endpoints, voice inputFull-stack development

If you want to challenge yourself right away, try saving the task list to a text file using Python's open() function so that tasks survive after the program closes. This introduces data persistence, a concept that bridges the gap between simple scripts and real applications. You could also explore using functions to organize each action into its own reusable block, which is the first step toward writing clean, maintainable code.

Practice Problems

PROBLEM 1 — CONCEPTUAL
Why do we use while True instead of for i in range(10) for the main loop of the to-do list? What would happen if you used a for loop instead?
PROBLEM 2 — BASIC CALCULATION
Trace the state of the tasks list after each line of code below. What does tasks contain at the end? tasks = [] tasks.append("Grocery shopping") tasks.append("Call dentist") tasks.append("Study for quiz") tasks.remove("Call dentist") tasks.append("Walk dog")
PROBLEM 3 — INTERMEDIATE
A student wrote the remove branch without validation: elif choice == "2": task = input("Enter task to remove: ") tasks.remove(task) What happens if the user types a task name that isn't in the list? How would you fix the code to handle this situation gracefully?
PROBLEM 4 — APPLIED
You want to add a fifth menu option: "5. Mark task as done." When the user selects this option, they type a task name, and the program should change it from, say, "Math HW" to "✓ Math HW" in the list. Using only list methods you already know (.index(), indexing with []), write the code for this new branch.
PROBLEM 5 — CRITICAL THINKING
Right now, the remove feature requires the user to type the exact task name. Redesign the remove branch so that the program first displays numbered tasks (like the display option), and then asks the user to enter the number of the task to remove instead of the name. What advantages does this approach have? Write the code and explain your reasoning.

Lesson Summary

In this lesson, you built a complete menu-based to-do list in Python by combining four fundamental concepts. A Python list stores your tasks as an ordered, mutable collection. A while True loop keeps the program running until the user chooses to quit. The input() function captures user choices from the keyboard, and an if/elif/else chain routes each choice to the correct action: add (append), remove, display (enumerate), or quit (break).

You also learned the importance of input validation — checking that a task exists before removing it and handling invalid menu choices with an else clause. This project is a minimum viable product (MVP) that mirrors the CRUD pattern (Create, Read, Update, Delete) used in professional software. From here, you can extend it with file saving, task editing, priority levels, or even a graphical interface.

Varsity Tutors • Computer Programming 1 (Python) • Building To-Do List