88
""
,adPPYb,d8 88 88 88 888888888
a8" `Y88 88 88 88 a8P"
8b 88 88 88 88 ,d8P'
"8a ,d88 "8a, ,a88 88 ,d8"
`"YbbdP'88 `"YbbdP'Y8 88 888888888
88
88
100 Days of Code — Day 17
A terminal-based True/False trivia quiz, built twice: once as the original course exercise and once as a fully rebuilt, modular application with multiple game modes and a polished CLI experience.
This project is part of my 100 Days of Code journey. Day 17 introduced object-oriented programming through a quiz game — a Question class, a Quiz class, and a simple game loop. After completing the course version, I rebuilt it from scratch with clean architecture, separated concerns, and an interactive terminal UI.
Both versions are launchable from a single root menu.
Requirements: Python 3.10+ · No external dependencies (standard library only)
git clone https://github.com/YOUR_USERNAME/quiz-game.git
cd quiz-game
python menu.pySelect [1] Original for the course version or [2] Advanced for the rebuilt version.
quiz-game/
│
├── menu.py # Root launcher — version selector
├── art.py # Shared ASCII logo (imported by all versions)
├── questions.py # Question bank — edit this to add/change questions
├── requirements.txt
│
├── docs/
│ └── COURSE_NOTES.md # Original course exercise brief
│
├── original/ # Course-state version
│ └── main.py # All logic in one file: data, models, game loop
│
└── advanced/ # Rebuilt version
├── main.py # Orchestrator: menu loop + mode dispatcher
├── quiz.py # Pure logic layer: Question, Quiz, QuizResult
├── display.py # All terminal UI: colors, typewriter, input, output
└── config.py # Constants: timing, dimensions, game settings
The course exercise, preserved close to its original state. Everything lives in one file: the Question model, the Quiz class, the question data, and the game loop. Procedural style, minimal abstraction — exactly what was taught on Day 17.
python menu.py → [1] Original
A full rebuild with strict separation of concerns:
| Layer | File | Responsibility |
|---|---|---|
| Logic | quiz.py |
Question, Quiz, QuizResult — zero UI, zero print() |
| Display | display.py |
All terminal output: colors, layout, animation, input |
| Config | config.py |
Every constant and setting in one place |
| Orchestration | main.py |
Collects input → calls logic → calls display |
python menu.py → [2] Advanced
| Mode | Description |
|---|---|
| Classic | All questions in random order. Wrong answers are OK — finish the set. |
| Sudden Death | One wrong answer ends the game immediately. Survive as long as you can. |
| Lightning | 5 random questions. Your total time is tracked and shown at the end. |
| Key | Action |
|---|---|
T |
Answer True |
F |
Answer False |
↑ (up arrow) |
Return to menu from anywhere |
Enter |
Play again after a round |
Open questions.py at the root. Each question is a dict with two keys:
{"text": "Your question here.", "answer": "True"}, # or "False"Add as many as you like — the game picks them up automatically. The advanced version shuffles and samples from the full list each round.
The original/ folder is a snapshot of what the course teaches — useful as a reference for how far the rebuild has come. The advanced/ folder is what I'd actually ship.
art.py and questions.py live at the root and are shared across both versions. Each subdirectory script adds the project root to sys.path at runtime so the import works regardless of working directory.
quiz.py has zero awareness of the terminal. It takes inputs, updates state, and returns QuizResult dataclasses. display.py owns everything the user sees. main.py is the only place that touches both — it reads user input, passes it to quiz.py, and passes the result to display.py.
This means the quiz logic could be dropped into a web app, a Discord bot, or a GUI with no changes to quiz.py.
The advanced version uses termios/tty to read individual keypresses without requiring the user to press Enter after every answer. Arrow key detection is handled by reading the ANSI escape sequence (ESC [ A for up arrow).
- Object-oriented programming: classes, instances, encapsulation
- Separating data, models, logic, and UI into distinct layers
- Dataclasses and type hints
- Terminal control: ANSI color codes, raw keypress input,
clear() - Typewriter animation with
sys.stdout.write subprocessfor launching child scripts from a menusys.pathmanipulation for shared imports across a nested project- Git branching:
originalbranch preserves the course starting point
| Branch | Contents |
|---|---|
main |
Current working version — all restructuring applied |
original |
Untouched course starter code — reference only |