Capstone: Build a CLI Tool from Scratch
Eleven modules. Seventy lessons. Hundreds of lines typed by your own hands. Time to prove it: one original command-line tool, designed and built by you, from an empty file to a working program.
The brief
Build a command-line tool that manages some data with a menu. Requirements:
Ideas (pick one, or invent your own)
Pick the one you'd actually use. Boring and finished beats exciting and abandoned.
The architecture (start from this skeleton)
"""My Tool — manages ___ data, stored in data.json."""
import json
import os
DATA_FILE = "data.json"
def load_data():
if os.path.exists(DATA_FILE):
with open(DATA_FILE) as f:
return json.load(f)
return []
def save_data(data):
with open(DATA_FILE, "w") as f:
json.dump(data, f, indent=2)
def view_items(data):
...
def add_item(data):
...
def main():
data = load_data()
while True:
print("\n1. View 2. Add 3. Update 4. Delete 5. Quit")
choice = input("Choice: ")
if choice == "1":
view_items(data)
elif choice == "2":
add_item(data)
save_data(data)
# ... 3, 4
elif choice == "5":
save_data(data)
break
else:
print("Invalid choice")
if __name__ == "__main__":
main()That skeleton already satisfies requirements 1, 3, and 5. Your job: the CRUD functions, the class, the polish.
The build order (how professionals actually work)
Step 1 — The skeleton runs. Menu loop with placeholder functions that print "not implemented yet." Verify the loop quits cleanly.
Step 2 — Add and View. The core loop of value: put data in, see it come back out. Save after every change.
Step 3 — Update and Delete. Find-by-index or find-by-name, confirm before deleting.
Step 4 — Error-proofing. Letters where numbers go, empty inputs, deleting from an empty list. Try to break your own tool — every crash you find is a try/except you add.
Step 5 — The class. Wrap the data logic in a class (e.g., ContactBook with .add(), .search(), .remove()) and slim the menu functions down to thin wrappers.
Step 6 — One flourish. Search. Sorting. A summary line. One delight feature — not ten.
Self-review rubric
| Check | Question |
|---|---|
| Survives | Kill it mid-action — does data.json stay valid? |
| Survives fools | Type letters into every numeric prompt |
| Reads | Could a stranger understand each function in 30 seconds? |
| Persists | Restart the program — is everything still there? |
| Structure | Any function longer than ~25 lines? Split it |
When you finish
If you get stuck
Every bug you'll hit was taught: NameError (scope, Module 7), KeyError (dicts, Module 5), JSONDecodeError (Module 8), infinite loops (Module 6). The course is your search engine — every lesson you completed is now a reference manual.
This is the exam. Open book. Go build. 🚀