In Step 10.3 we built a menu-driven To-Do list with options to add, view, and exit.
But a real list isn’t useful unless you can manage it: some tasks must be marked done ✅, others should be removed 🗑️.
In this lesson we extend the program with functions to:
- mark a task as completed,
- delete a task from the list.
You’ll learn how to:
- work with indexes (numeric positions) in a list,
- update values inside a list (modify a field),
- remove elements using
delorpop().
🎯 Goal
Extend the menu with:
- [A] Add task
- [V] View tasks
- [M] Mark task as completed
- [D] Delete task
- [X] Exit
📝 Updated code
# todo_edit_remove.py
tasks = [] # Each task is a dict: {"text": "...", "done": False}
def show_menu():
print("\n=== TO-DO MENU ===")
print("[A] Add task")
print("[V] View tasks")
print("[M] Mark task as complete")
print("[D] Delete task")
print("[X] Exit")
def add_task():
text = input("Write the new task: ").strip()
if text:
tasks.append({"text": text, "done": False})
print(f"✅ '{text}' added to the list!")
else:
print("⚠️ You didn't write anything, task not added.")
def view_tasks():
if not tasks:
print("📭 No tasks available.")
return
print("\n📋 Your tasks:")
for i, t in enumerate(tasks, start=1):
status = "✅" if t["done"] else "⭕"
print(f"{i}. {status} {t['text']}")
def mark_task():
view_tasks()
if not tasks:
return
try:
num = int(input("Which number do you want to mark as complete? "))
if 1 <= num <= len(tasks):
tasks[num-1]["done"] = True
print(f"🎉 '{tasks[num-1]['text']}' marked as complete!")
else:
print("❌ Invalid number.")
except ValueError:
print("⚠️ You must enter a number.")
def delete_task():
view_tasks()
if not tasks:
return
try:
num = int(input("Which number do you want to delete? "))
if 1 <= num <= len(tasks):
removed = tasks.pop(num-1)
print(f"🗑️ '{removed['text']}' removed from the list.")
else:
print("❌ Invalid number.")
except ValueError:
print("⚠️ You must enter a number.")
def main():
print("Welcome to your To-Do List!")
while True:
show_menu()
choice = input("Choose an option: ").strip().lower()
if choice == "a":
add_task()
elif choice == "v":
view_tasks()
elif choice == "m":
mark_task()
elif choice == "d":
delete_task()
elif choice == "x":
print("Goodbye! 👋")
break
else:
print("❌ Invalid command, try again.")
if __name__ == "__main__":
main()
🔍 How it works
tasks = []→ the list now stores dictionaries, each withtextanddone.mark_task()→ shows tasks, asks for a number, setsdone = True.delete_task()→ shows tasks, asks for a number, removes withpop().enumerate(..., start=1)numbers tasks for humans (1-based).- Invalid input is handled with
try/except.
💡 Possible improvements
- Add an option to unmark a task (undo “completed”).
- Save tasks to a file (next step).
- Add colors (e.g., with
colorama).
🧪 Exercises
- Add an option to mark all tasks as completed.
- Change
mark_task()to toggle state (completed ↔ not completed). - Add a
[C] Clear allcommand that empties the list after confirmation.
🚫 Common mistakes
- Forgetting to check if the list is empty before asking for a number.
- Not converting input to
int, causing type errors. - Using wrong indexes (remember Python is 0-based, while we display from 1).
📌 Key takeaways
- With indexes you can target and manage individual list items.
- Dictionaries make each task’s state clear (text + completed).
- We added essential features: mark as done and delete.
Closing – Python vs PHP and a first look at large data
After building a To-Do list in Python and a similar app in PHP, you might think they’re the same. Both handle lists, input/output, saving, and logic.
In reality, Python and PHP have different histories, goals, and usage contexts.
✅ Similarities
- Both are interpreted languages.
- Both can build interactive applications and manipulate data.
- Both can be used for web and local scripts.
🚦 Key differences
| Aspect | Python | PHP |
|---|---|---|
| Origin / philosophy | 1991, general-purpose scripting. Today: data science, ML, automation, backend. | 1995, dynamic web pages. Dominant in classic web (WordPress, Drupal). |
| Typical environment | Desktop, servers, Jupyter notebooks, APIs, automation. | Web servers (Apache/Nginx). Most shared hostings support it by default. |
| Data handling | Libraries like Pandas and NumPy to analyze very large datasets in memory. | Often paired with SQL databases (MySQL, PostgreSQL) to display dynamic website data. |
| Community | Data scientists, researchers, backend developers. | Web developers, CMS maintainers, full-stack web. |
| Distribution | Scripts, CLI apps, APIs, microservices, machine learning. | Web apps and CMS. |
🤔 When to use Python vs PHP?
Choose Python if…
- You need to analyze or process large amounts of data.
- You’re into AI, machine learning, or automation.
- You want a multi-purpose language beyond the web.
Choose PHP if…
- You want to create/manage a dynamic website quickly.
- You use CMSs like WordPress or Drupal.
- You need to connect web interfaces to SQL databases for real users.
📦 First look at large-data work
Scenario: a CSV with 1 million sales rows.
Python → direct analysis with Pandas
import pandas as pd
df = pd.read_csv("vendite.csv")
print("Row count:", len(df))
print("Total sales:", df["totale"].sum())
df2025 = df[df["anno"] == 2025]
print("Rows for 2025:", len(df2025))
👉 In a few lines, Python loads and analyzes millions of records.
PHP → presentation via SQL database
<?php
$conn = new mysqli("localhost", "user", "password", "database");
$sql = "SELECT COUNT(*) as rows FROM vendite";
$res = $conn->query($sql)->fetch_assoc();
echo "Total rows: " . $res["rows"];
$sql = "SELECT SUM(totale) as total FROM vendite WHERE anno = 2025";
$res = $conn->query($sql)->fetch_assoc();
echo "Total sales 2025: " . $res["total"];
?>
👉 PHP doesn’t analyze in memory; it queries the database and presents results.
🔍 Two useful metaphors
- Python is a scientific lab: it ingests data, transforms it, computes statistics, finds patterns.
- PHP is a web storefront: it takes prepared data and shows it to users dynamically.
🧪 Reflection exercises
- Write a Python script to compute the average of a numeric field in a large CSV.
- Write a PHP script that shows the same aggregates, but from a MySQL database.
- Compare the experience: where do you need analysis, and where presentation?
📌 Final takeaways
- Python and PHP aren’t competitors; they serve different purposes.
- Python → analysis, automation, large data, AI.
- PHP → dynamic web, user interfaces, CMS, databases.
- Together they shine: Python processes data, PHP exposes it to users.
