Project 3 — Calculator · Project 4 — Unit Converter · Project 5 — To-Do List App · Project 6 — Vocabulary Quiz
Build a command-line calculator that parses infix expressions (+, -, *, /, **, %) and handles division-by-zero and invalid input gracefully. Convert between common units (length, weight, temperature) using a menu-driven CLI. Extend the conversion table with new units without changing the core logic. Build a full-featured to-do list with priorities, due dates, categories, and JSON file persistence. Create an interactive vocabulary quiz that shuffles questions, tracks performance per word, and prioritizes words you get wrong (basic spaced repetition).
What you'll learn
- 1Parse and evaluate arithmetic expressions
- 2Handle errors gracefully (division by zero, invalid input)
- 3Store and display calculation history
- 4Support multi-step calculations (ANS reference)
- 5Store conversion factors in a dict-of-dict structure
- 6Write a generic convert(value, from_unit, to_unit) function
- 7Present a clean numbered menu
- 8Handle temperature as a special case (formula-based)
- 9Store tasks as dicts with id, title, priority, due_date, category
- 10Implement CRUD + filter + sort commands
- 11Persist to JSON on every write
- 12Display tasks in a clean tabular format
- 13Load vocabulary from a JSON or CSV file
- 14Randomize question order with random.shuffle
- 15Track correct/incorrect counts per word
- 16Implement basic spaced repetition (repeat wrong answers)
Project 3 — Calculator
Build a command-line calculator that parses infix expressions (+, -, *, /, **, %) and handles division-by-zero and invalid input gracefully.
Project Overview
- Evaluate expressions like: 3 + 4 * 2, (10 - 3) ** 2
- Commands: history, clear, quit
- ANS refers to the previous result
- Never use eval() — parse manually or use a safe alternative
Sample Session
Calculator (type 'quit' to exit)
> 3 + 4 * 2
= 11
> (10 - 3) ** 2
= 49
> ANS + 1
= 50
> 10 / 0
Error: division by zero
> history
3 + 4 * 2 = 11
(10 - 3) ** 2 = 49
ANS + 1 = 50Project 4 — Unit Converter
Convert between common units (length, weight, temperature) using a menu-driven CLI. Extend the conversion table with new units without changing the core logic.
Supported Units
| Category | Units |
|---|---|
| Length | mm, cm, m, km, in, ft, mi |
| Weight | mg, g, kg, lb, oz |
| Temperature | °C, °F, K |
Sample Session
Unit Converter
1) Length 2) Weight 3) Temperature 4) Quit
Choice: 1
From unit (mm/cm/m/km/in/ft/mi): km
To unit: mi
Value: 5
5 km = 3.1069 mi
Choice: 3
From unit (C/F/K): C
To unit: F
Value: 100
100°C = 212.0°FProject 5 — To-Do List App
Build a full-featured to-do list with priorities, due dates, categories, and JSON file persistence.
Commands
- add <title> [--priority high|medium|low] [--due YYYY-MM-DD] [--cat <category>]
- list [--filter done|pending] [--sort priority|due|id]
- done <id> — mark complete
- delete <id>
- search <keyword>
- stats — show counts by priority/category
Sample Output
> list --sort priority
ID P Due Category Title
3 H 2024-05-20 Work Write report
1 M 2024-05-22 Personal Buy groceries
2 L — Chores Clean garage
Done: 0/3Project 6 — Vocabulary Quiz
Create an interactive vocabulary quiz that shuffles questions, tracks performance per word, and prioritizes words you get wrong (basic spaced repetition).
Features
- Load word list from vocab.json: [{word, definition, example}]
- Multiple-choice (4 options) and fill-in-the-blank modes
- Track per-word accuracy across sessions
- End-of-session report: accuracy, time per question, weak words
- Save progress to progress.json
Sample Session
=== Vocabulary Quiz ===
[1/10] What does 'ubiquitous' mean?
A) rare and unusual
B) present everywhere
C) unclear in meaning
D) easily broken
Answer: B ✓ Correct!
[2/10] What does 'ephemeral' mean?
...💻 Examples
Run these examples and check the output yourself.
import re
def safe_eval(expr, ans):
expr = expr.replace("ANS", str(ans))
# Allow only numbers, operators, parens, spaces
if not re.fullmatch(r'[\d.+\-*/%(). \*\*]+', expr):
raise ValueError("Invalid characters in expression")
try:
return eval(compile(expr, "<string>", "eval"),
{"__builtins__": {}}, {})
except ZeroDivisionError:
raise ZeroDivisionError("division by zero")
history, ans = [], 0
print("Calculator (type 'quit' to exit)")
while True:
line = input("> ").strip()
if line.lower() in ("quit", "exit"): break
if line.lower() == "history":
for h in history: print(f" {h}")
continue
if line.lower() == "clear":
history.clear(); ans = 0; continue
try:
result = safe_eval(line, ans)
print(f"= {result}")
history.append(f"{line} = {result}")
ans = result
except Exception as e:
print(f"Error: {e}")
# All conversions to SI base unit (metre, gram, kelvin)
LENGTH = {"mm":1e-3,"cm":1e-2,"m":1,"km":1e3,"in":0.0254,"ft":0.3048,"mi":1609.344}
WEIGHT = {"mg":1e-3,"g":1,"kg":1e3,"lb":453.592,"oz":28.3495}
def convert_linear(value, from_u, to_u, table):
return value * table[from_u] / table[to_u]
def convert_temp(value, from_u, to_u):
# Convert to Kelvin first
if from_u == "C": k = value + 273.15
elif from_u == "F": k = (value - 32) * 5/9 + 273.15
else: k = value
if to_u == "C": return k - 273.15
if to_u == "F": return (k - 273.15) * 9/5 + 32
return k
while True:
print("\n1) Length 2) Weight 3) Temperature 4) Quit")
c = input("Choice: ").strip()
if c == "4": break
elif c == "1": tbl = LENGTH; cat = "Length"
elif c == "2": tbl = WEIGHT; cat = "Weight"
elif c == "3":
from_u = input(f"From (C/F/K): ").upper()
to_u = input(f"To (C/F/K): ").upper()
val = float(input("Value: "))
print(f"{val}°{from_u} = {convert_temp(val,from_u,to_u):.4f}°{to_u}")
continue
else: print("Invalid"); continue
units = list(tbl.keys())
from_u = input(f"From unit ({"/".join(units)}): ").lower()
to_u = input(f"To unit: ").lower()
val = float(input("Value: "))
result = convert_linear(val, from_u, to_u, tbl)
print(f"{val} {from_u} = {result:.6g} {to_u}")
📝 Exercises
Try them yourself first, then open the solution to compare.
Build the calculator
Goal: Implement expression evaluation, history, ANS, and error handling.
- Evaluate +, -, *, /, **, %
- ANS references previous result
- Division by zero handled gracefully
- history command shows calculation log
Build the unit converter
Goal: Implement the converter with length, weight, and temperature categories.
- Data-driven design (dicts for length and weight)
- Temperature handled via formula
- Handles unknown units gracefully
- Loop until quit
Build the to-do app
Goal: Implement all commands with JSON persistence.
- All CRUD operations
- Filter and sort options
- JSON file persistence
- stats command
- · CRUD works — 40%
- · Filter/sort — 20%
- · Persistence — 25%
- · Stats — 15%
Build the vocab quiz
Goal: Implement multiple-choice quiz with spaced repetition.
- Load from JSON file
- 4-option multiple choice
- Track per-word accuracy
- Repeat wrong answers twice
All lecture materials and example code are openly available on GitHub.
View on GitHub ↗Comments 0
No comments yet. Be the first.
Only members can comment.
Comments with ads, abuse, personal information or illegal content are hidden or removed. Comments are shown with your nickname. Privacy Policy