Build out all 27 modules + capstone (#1)

Co-authored-by: claude <claude@jpaul.io>
Co-committed-by: claude <claude@jpaul.io>
This commit was merged in pull request #1.
This commit is contained in:
2026-06-22 12:19:01 -04:00
committed by Claude (agent)
parent 4bd586bbd0
commit 2684095e2f
117 changed files with 15131 additions and 1 deletions
@@ -0,0 +1,62 @@
"""Tiny command-line front end for the demo task app.
Run it:
python cli.py add "write the lesson"
python cli.py list
python cli.py done 0
State is kept in tasks.json next to this file. The `done` command turns a bad index into a
clean error message and a non-zero exit code — note that behavior before you review the AI
change, so you can tell if the change quietly alters it.
"""
import json
import sys
from pathlib import Path
from tasks import Task, TaskList
STATE = Path(__file__).parent / "tasks.json"
def load() -> TaskList:
if not STATE.exists():
return TaskList()
raw = json.loads(STATE.read_text())
return TaskList(tasks=[Task(**t) for t in raw])
def save(tlist: TaskList) -> None:
STATE.write_text(json.dumps([t.__dict__ for t in tlist.tasks], indent=2))
def main(argv: list[str]) -> int:
tlist = load()
if not argv:
print("usage: python cli.py [add <title> | list | done <index>]")
return 1
command = argv[0]
if command == "add":
title = " ".join(argv[1:])
tlist.add(title)
save(tlist)
print(f"added: {title}")
elif command == "list":
print(tlist.render())
elif command == "done":
try:
tlist.complete(int(argv[1]))
except IndexError as exc:
print(f"error: {exc}")
return 1
save(tlist)
print("updated")
else:
print(f"unknown command: {command}")
return 1
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv[1:]))
@@ -0,0 +1,42 @@
"""Core task logic for the demo app.
Same running example as Modules 1 and 2, with one addition: `complete` now validates the
index and raises a clear error for a bad one. That explicit edge-case handling is here on
purpose — it's the kind of thing an AI "refactor" likes to quietly remove. This is the
known-good base you'll review an AI change against in Module 10.
"""
from dataclasses import dataclass, field
@dataclass
class Task:
title: str
done: bool = False
@dataclass
class TaskList:
tasks: list[Task] = field(default_factory=list)
def add(self, title: str) -> Task:
task = Task(title=title)
self.tasks.append(task)
return task
def complete(self, index: int) -> None:
if not 0 <= index < len(self.tasks):
raise IndexError(f"no task at index {index}")
self.tasks[index].done = True
def pending(self) -> list[Task]:
return [t for t in self.tasks if not t.done]
def render(self) -> str:
if not self.tasks:
return "(no tasks yet)"
lines = []
for i, task in enumerate(self.tasks):
box = "[x]" if task.done else "[ ]"
lines.append(f"{i}. {box} {task.title}")
return "\n".join(lines)