Version: 1.0 Date: 2025-10-15 Author: CLI Interface Architect
- System Overview
- CLI Menu Structure
- State Machine Design
- Module Coordination
- Input/Output Patterns
- Error Handling Strategy
- Integration Requirements
- Sample Interaction Flows
- Implementation Roadmap
An interactive command-line educational platform for teaching binary mathematics, logic gates, and computational thinking through guided lessons and practice problems.
- Progressive Learning: Start simple, build complexity gradually
- Immediate Feedback: Real-time validation with educational explanations
- Adaptive Difficulty: Scale challenges to user skill level
- Session Persistence: Save/resume learning progress
- Minimal Cognitive Load: Clear UI, intuitive navigation
- Language: Python 3.8+
- CLI Framework:
clickorargparsefor command parsing - Display Enhancement:
richfor colored output and formatting - State Management: JSON-based session files
- Testing: pytest with MVP-level coverage
βββββββββββββββββββββββββββββββββββββββββββββββ
β Binary Math Interactive Tutor β
β β
β 1. Start New Lesson β
β 2. Resume Lesson β
β 3. Practice Problems β
β 4. View Progress β
β 5. Settings β
β 6. Help β
β 7. Exit β
β β
β Current Level: Beginner | Progress: 45% β
βββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββ
β Select Your Lesson β
β β
β 1. Binary Basics β
β ββ Introduction to Base-2 Numbers β
β Status: ββββββββββ 60% Complete β
β β
β 2. Logic Gates β
β ββ AND, OR, NOT, XOR Operations β
β Status: ββββββββββ 30% Complete β
β β
β 3. Truth Tables β
β ββ Building and Reading Truth Tables β
β Status: ββββββββββ Not Started β
β β
β 4. Binary Arithmetic β
β ββ Addition, Subtraction, Overflow β
β Status: ββββββββββ Locked (Complete #3) β
β β
β B. Back to Main Menu β
βββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββ
β Choose Difficulty Level β
β β
β 1. Beginner β
β - Step-by-step guidance β
β - Detailed explanations β
β - Unlimited hints β
β β
β 2. Intermediate β
β - Moderate guidance β
β - Standard explanations β
β - 3 hints per problem β
β β
β 3. Advanced β
β - Minimal guidance β
β - Concise explanations β
β - 1 hint per problem β
β β
β Current: Beginner β
βββββββββββββββββββββββββββββββββββββββββββββββ
During Lesson:
- 'n' or 'next' : Next question
- 'p' or 'prev' : Previous question
- 'h' or 'hint' : Get a hint
- 'e' or 'explain' : Detailed explanation
- 's' or 'save' : Save progress
- 'q' or 'quit' : Return to main menu
- 'help' : Show all commands
ββββββββββββββββ
β STARTUP β
ββββββββ¬ββββββββ
β
v
ββββββββββββββββ ββββββββββββββββ
β MAIN_MENU βββββ>β SETTINGS β
ββββββββ¬ββββββββ ββββββββββββββββ
β
ββββββ> LESSON_SELECT ββββ> DIFFICULTY_SELECT
β β β
β v v
β ββββββββββββββββββββββββββββββββ
β β IN_LESSON_ACTIVE β
β β ββββββββββββββββββββββββββ β
β β β - READING_CONTENT β β
β β β - ANSWERING_QUESTION β β
β β β - VIEWING_HINT β β
β β β - VIEWING_EXPLANATION β β
β β ββββββββββββββββββββββββββ β
β ββββββββββββββββ¬ββββββββββββββββ
β β
ββββββ> PRACTICE_MODE β
β β β
β v v
ββββββ> PROGRESS_VIEW ββ
class LessonState:
"""Represents the current state of a lesson session"""
# Core State
lesson_id: str # e.g., "binary_basics"
section_index: int # Current section (0-based)
question_index: int # Current question within section
difficulty: str # "beginner", "intermediate", "advanced"
# Progress Tracking
completed_sections: List[str]
completed_questions: List[str]
total_attempts: int
correct_attempts: int
# Session Management
started_at: datetime
last_active: datetime
hints_used: int
current_streak: int
# User Responses
answer_history: List[Dict] # All Q&A pairs
hint_requests: List[str] # Hints viewed
# State Flags
is_paused: bool
needs_save: bool
lesson_complete: bool# Valid state transitions
TRANSITIONS = {
"MAIN_MENU": ["LESSON_SELECT", "PRACTICE_MODE", "PROGRESS_VIEW", "SETTINGS", "EXIT"],
"LESSON_SELECT": ["DIFFICULTY_SELECT", "MAIN_MENU"],
"DIFFICULTY_SELECT": ["IN_LESSON_ACTIVE", "LESSON_SELECT"],
"IN_LESSON_ACTIVE": ["MAIN_MENU", "PRACTICE_MODE", "PROGRESS_VIEW"],
"PRACTICE_MODE": ["MAIN_MENU", "PROGRESS_VIEW"],
"PROGRESS_VIEW": ["MAIN_MENU", "LESSON_SELECT"],
"SETTINGS": ["MAIN_MENU"],
}
# State transition validator
def validate_transition(current_state: str, next_state: str) -> bool:
return next_state in TRANSITIONS.get(current_state, [])βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β interactive_tutor.py β
β (CLI Orchestrator) β
ββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββΌβββββββββββββ
β β β
v v v
βββββββββββββ ββββββββββββ ββββββββββββ
β CLI β β State β β Session β
β Display β β Manager β β Manager β
βββββββββββββ ββββββββββββ ββββββββββββ
β β β
ββββββββββββββΌβββββββββββββ
β
ββββββββββββββΌβββββββββββββ¬βββββββββββ
β β β β
v v v v
ββββββββββββββββ ββββββββββ βββββββββββ ββββββββββ
β binary_basicsβ β logic_ β β truth_ β βpracticeβ
β β β gates β β tables β β_engine β
ββββββββββββββββ ββββββββββ βββββββββββ ββββββββββ
β β β β
ββββββββββββββ΄βββββββββββββ΄βββββββββββ
β
v
ββββββββββββββββββ
β Validators β
β & Feedback β
ββββββββββββββββββ
from abc import ABC, abstractmethod
from typing import Dict, List, Optional
class LessonModule(ABC):
"""Base interface for all lesson modules"""
@abstractmethod
def get_metadata(self) -> Dict:
"""
Returns:
{
"id": "binary_basics",
"title": "Binary Basics",
"description": "Introduction to base-2 numbers",
"difficulty_levels": ["beginner", "intermediate", "advanced"],
"estimated_duration_minutes": 30,
"prerequisites": [],
"sections": ["intro", "conversion", "practice"]
}
"""
pass
@abstractmethod
def get_section_content(self, section_id: str, difficulty: str) -> Dict:
"""
Returns section content adapted to difficulty level
Returns:
{
"section_id": "conversion",
"title": "Decimal to Binary Conversion",
"content": "...", # Educational content
"questions": [...] # List of question objects
}
"""
pass
@abstractmethod
def validate_answer(self, question_id: str, user_answer: str) -> Dict:
"""
Returns:
{
"is_correct": True,
"feedback": "Correct! You successfully converted...",
"explanation": "The process works because...",
"points_earned": 10
}
"""
pass
@abstractmethod
def generate_hint(self, question_id: str, hint_level: int) -> str:
"""
Returns progressively detailed hints
hint_level: 1 (gentle nudge), 2 (more detail), 3 (step-by-step)
"""
pass
@abstractmethod
def get_practice_problem(self, difficulty: str, topic: Optional[str] = None) -> Dict:
"""
Generate a practice problem
Returns:
{
"question_id": "binary_basics_practice_001",
"question_text": "Convert 42 to binary",
"expected_answer": "101010",
"difficulty": "intermediate",
"topic": "conversion"
}
"""
passclass StateManager:
"""Manages application and lesson state"""
def __init__(self):
self.current_state: str = "MAIN_MENU"
self.lesson_state: Optional[LessonState] = None
self.user_profile: UserProfile = None
def transition_to(self, next_state: str) -> bool:
"""Validate and execute state transition"""
if validate_transition(self.current_state, next_state):
self._on_exit_state(self.current_state)
self.current_state = next_state
self._on_enter_state(next_state)
return True
return False
def start_lesson(self, lesson_id: str, difficulty: str):
"""Initialize a new lesson session"""
self.lesson_state = LessonState(
lesson_id=lesson_id,
difficulty=difficulty,
started_at=datetime.now()
)
def update_progress(self, question_id: str, is_correct: bool):
"""Update lesson progress"""
self.lesson_state.total_attempts += 1
if is_correct:
self.lesson_state.correct_attempts += 1
self.lesson_state.current_streak += 1
else:
self.lesson_state.current_streak = 0
def save_state(self) -> bool:
"""Persist current state to disk"""
pass
def load_state(self, session_id: str) -> bool:
"""Restore state from disk"""
passclass SessionManager:
"""Handles session persistence and history"""
def __init__(self, base_dir: str = "~/.binary_tutor"):
self.base_dir = Path(base_dir).expanduser()
self.sessions_dir = self.base_dir / "sessions"
self.progress_file = self.base_dir / "progress.json"
def create_session(self, lesson_id: str) -> str:
"""
Create a new session file
Returns: session_id (UUID)
"""
pass
def save_session(self, session_id: str, state: LessonState) -> bool:
"""Persist session state to JSON file"""
pass
def load_session(self, session_id: str) -> Optional[LessonState]:
"""Load session from JSON file"""
pass
def list_active_sessions(self) -> List[Dict]:
"""
Returns list of active sessions
[
{
"session_id": "...",
"lesson_id": "binary_basics",
"last_active": "2025-10-15T10:30:00",
"progress_percent": 45
}
]
"""
pass
def get_overall_progress(self) -> Dict:
"""
Returns aggregated progress across all lessons
{
"total_lessons": 4,
"completed_lessons": 1,
"in_progress_lessons": 2,
"total_questions_answered": 47,
"accuracy_rate": 0.85,
"current_streak": 12,
"achievements": [...]
}
"""
passclass ModuleLoader:
"""Dynamic lesson module loader"""
def __init__(self, modules_dir: str = "lessons"):
self.modules_dir = Path(modules_dir)
self.loaded_modules: Dict[str, LessonModule] = {}
def discover_modules(self) -> List[str]:
"""
Scan modules directory for lesson modules
Expects: binary_basics.py, logic_gates.py, etc.
"""
modules = []
for file in self.modules_dir.glob("*.py"):
if file.name.startswith("_"):
continue
module_name = file.stem
modules.append(module_name)
return modules
def load_module(self, module_id: str) -> LessonModule:
"""
Dynamically import and instantiate lesson module
"""
if module_id in self.loaded_modules:
return self.loaded_modules[module_id]
# Dynamic import
module = importlib.import_module(f"lessons.{module_id}")
# Instantiate the lesson class
lesson_class = getattr(module, "Lesson")
lesson_instance = lesson_class()
self.loaded_modules[module_id] = lesson_instance
return lesson_instance
def get_all_lessons_metadata(self) -> List[Dict]:
"""Get metadata from all available lesson modules"""
metadata_list = []
for module_id in self.discover_modules():
module = self.load_module(module_id)
metadata_list.append(module.get_metadata())
return metadata_listfrom rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.progress import Progress
from rich.markdown import Markdown
class DisplayRenderer:
"""Handles all CLI output rendering"""
def __init__(self):
self.console = Console()
def show_main_menu(self, user_profile: UserProfile):
"""Render main menu with user status"""
menu_table = Table(show_header=False, box=None)
menu_table.add_column("Option", style="cyan")
menu_table.add_column("Description", style="white")
menu_table.add_row("1", "Start New Lesson")
menu_table.add_row("2", "Resume Lesson")
menu_table.add_row("3", "Practice Problems")
menu_table.add_row("4", "View Progress")
menu_table.add_row("5", "Settings")
menu_table.add_row("6", "Help")
menu_table.add_row("7", "Exit")
panel = Panel(
menu_table,
title="[bold blue]Binary Math Interactive Tutor[/bold blue]",
subtitle=f"Level: {user_profile.level} | Progress: {user_profile.overall_progress}%"
)
self.console.print(panel)
def show_question(self, question: Dict, question_num: int, total: int):
"""Render a question with context"""
self.console.print(f"\n[bold cyan]Question {question_num}/{total}[/bold cyan]")
self.console.print(f"\n{question['question_text']}\n")
if question.get('example'):
self.console.print(f"[dim]Example: {question['example']}[/dim]\n")
def show_feedback(self, is_correct: bool, feedback: str, explanation: str = None):
"""Render answer feedback"""
if is_correct:
self.console.print(f"\n[bold green]β Correct![/bold green]")
self.console.print(f"[green]{feedback}[/green]\n")
else:
self.console.print(f"\n[bold red]β Incorrect[/bold red]")
self.console.print(f"[red]{feedback}[/red]\n")
if explanation:
self.console.print(Panel(
Markdown(explanation),
title="[bold yellow]Explanation[/bold yellow]",
border_style="yellow"
))
def show_hint(self, hint: str, hint_level: int, max_hints: int):
"""Render a hint"""
self.console.print(Panel(
hint,
title=f"[bold yellow]Hint {hint_level}/{max_hints}[/bold yellow]",
border_style="yellow"
))
def show_progress_bar(self, current: int, total: int, label: str = "Progress"):
"""Render a progress bar"""
with Progress() as progress:
task = progress.add_task(f"[cyan]{label}", total=total)
progress.update(task, completed=current)
def show_error(self, message: str):
"""Render error message"""
self.console.print(f"[bold red]Error:[/bold red] {message}")
def show_success(self, message: str):
"""Render success message"""
self.console.print(f"[bold green]Success:[/bold green] {message}")
def show_info(self, message: str):
"""Render info message"""
self.console.print(f"[bold blue]Info:[/bold blue] {message}")class InputHandler:
"""Handles all user input with validation"""
def __init__(self):
self.console = Console()
def get_menu_choice(self, valid_options: List[str], prompt: str = "Enter choice") -> str:
"""
Get validated menu choice
Args:
valid_options: List of valid inputs (e.g., ['1', '2', '3', 'q'])
prompt: Prompt text to display
Returns:
Validated user choice
"""
while True:
choice = self.console.input(f"\n[bold cyan]{prompt}:[/bold cyan] ").strip().lower()
if choice in valid_options:
return choice
self.console.print(
f"[red]Invalid choice. Please enter one of: {', '.join(valid_options)}[/red]"
)
def get_answer(self, question_type: str = "text") -> str:
"""
Get answer with type-specific validation
question_type: "text", "number", "binary", "boolean"
"""
prompt_text = {
"text": "Your answer",
"number": "Enter number",
"binary": "Enter binary (e.g., 1010)",
"boolean": "True or False"
}.get(question_type, "Your answer")
while True:
answer = self.console.input(f"\n[bold green]{prompt_text}:[/bold green] ").strip()
if not answer:
self.console.print("[red]Answer cannot be empty. Try again.[/red]")
continue
# Type-specific validation
if question_type == "binary":
if not all(c in '01' for c in answer):
self.console.print("[red]Binary numbers can only contain 0 and 1.[/red]")
continue
elif question_type == "number":
try:
int(answer)
except ValueError:
self.console.print("[red]Please enter a valid number.[/red]")
continue
return answer
def confirm_action(self, message: str) -> bool:
"""
Get yes/no confirmation
"""
choice = self.get_menu_choice(['y', 'n', 'yes', 'no'], f"{message} (y/n)")
return choice in ['y', 'yes']
def get_command(self, valid_commands: List[str]) -> str:
"""
Get in-lesson command (hint, next, quit, etc.)
"""
command = self.console.input(
f"\n[dim]Commands: {', '.join(valid_commands)}[/dim]\n[bold cyan]>[/bold cyan] "
).strip().lower()
return commandβββββββββββββββββββ
β Display Prompt β
ββββββββββ¬βββββββββ
β
v
βββββββββββββββββββ
β Await Input β
ββββββββββ¬βββββββββ
β
v
βββββββββββββββββββ ββββββββββββββββ
β Validate Input ββββββ>β Show Error & β
ββββββββββ¬βββββββββ NO β Retry Input β
β YES ββββββββββββββββ
v
βββββββββββββββββββ
β Process Input β
ββββββββββ¬βββββββββ
β
v
βββββββββββββββββββ
β Display Result β
βββββββββββββββββββ
class TutorError(Exception):
"""Base exception for tutor errors"""
pass
class StateError(TutorError):
"""Invalid state transition or state corruption"""
pass
class ModuleLoadError(TutorError):
"""Failed to load lesson module"""
pass
class SessionError(TutorError):
"""Session save/load failure"""
pass
class ValidationError(TutorError):
"""Input validation failure"""
pass
class ConfigError(TutorError):
"""Configuration file issue"""
passdef load_lesson_module(module_id: str) -> Optional[LessonModule]:
"""
Load lesson with fallback handling
"""
try:
return module_loader.load_module(module_id)
except ModuleNotFoundError:
logger.error(f"Lesson module '{module_id}' not found")
display.show_error(f"Lesson '{module_id}' is not available")
return None
except Exception as e:
logger.exception(f"Failed to load lesson '{module_id}'")
display.show_error("An error occurred loading the lesson. Please try again.")
return Nonedef safe_state_transition(next_state: str) -> bool:
"""
Attempt state transition with recovery
"""
try:
# Save current state before transition
backup_state = state_manager.get_snapshot()
if state_manager.transition_to(next_state):
return True
# Invalid transition
display.show_error(f"Cannot navigate to {next_state} from current location")
return False
except StateError as e:
# Restore backup state
state_manager.restore_snapshot(backup_state)
logger.error(f"State transition failed: {e}")
display.show_error("Navigation error. Returning to previous screen.")
return Falsedef save_session_safe(session_id: str, state: LessonState) -> bool:
"""
Save with retry and fallback
"""
max_retries = 3
for attempt in range(max_retries):
try:
session_manager.save_session(session_id, state)
display.show_success("Progress saved successfully")
return True
except PermissionError:
logger.error(f"Permission denied saving session: {session_id}")
display.show_error("Cannot save progress: Permission denied")
return False
except IOError as e:
if attempt < max_retries - 1:
logger.warning(f"Save attempt {attempt + 1} failed: {e}")
time.sleep(0.5) # Brief delay before retry
continue
else:
logger.error(f"Failed to save session after {max_retries} attempts")
display.show_error("Cannot save progress. Your session may be lost.")
return False
return FalseERROR_MESSAGES = {
"module_not_found": "This lesson is not yet available. Please choose another lesson.",
"session_corrupt": "Your session file is corrupted. Starting a fresh session.",
"invalid_answer_format": "Please enter your answer in the correct format.",
"save_failed": "Unable to save your progress. You may need to retry later.",
"load_failed": "Unable to load your previous session. Starting fresh.",
"network_unavailable": "Network features are unavailable in offline mode.",
}
def get_user_friendly_error(error_code: str) -> str:
"""Get user-friendly error message"""
return ERROR_MESSAGES.get(error_code, "An unexpected error occurred. Please try again.")import logging
from logging.handlers import RotatingFileHandler
def setup_logging():
"""Configure application logging"""
log_dir = Path.home() / ".binary_tutor" / "logs"
log_dir.mkdir(parents=True, exist_ok=True)
# Rotating file handler (5MB max, 3 backups)
handler = RotatingFileHandler(
log_dir / "tutor.log",
maxBytes=5_000_000,
backupCount=3
)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
handler.setFormatter(formatter)
logger = logging.getLogger("binary_tutor")
logger.setLevel(logging.INFO)
logger.addHandler(handler)
return loggerEach lesson module must implement the LessonModule interface:
# lessons/binary_basics.py
from lesson_interface import LessonModule
from typing import Dict, List, Optional
class Lesson(LessonModule):
"""Binary Basics lesson implementation"""
def __init__(self):
self.lesson_id = "binary_basics"
self.questions = self._load_questions()
def get_metadata(self) -> Dict:
return {
"id": "binary_basics",
"title": "Binary Basics",
"description": "Introduction to base-2 number system",
"difficulty_levels": ["beginner", "intermediate", "advanced"],
"estimated_duration_minutes": 30,
"prerequisites": [],
"sections": ["introduction", "conversion", "practice"],
"learning_objectives": [
"Understand binary representation",
"Convert decimal to binary",
"Convert binary to decimal"
]
}
def get_section_content(self, section_id: str, difficulty: str) -> Dict:
# Load section content from questions database
content = self._get_content_for_section(section_id)
questions = self._get_questions_for_section(section_id, difficulty)
return {
"section_id": section_id,
"title": content["title"],
"content": content["text"],
"questions": questions
}
def validate_answer(self, question_id: str, user_answer: str) -> Dict:
question = self._get_question(question_id)
is_correct = self._check_answer(question, user_answer)
return {
"is_correct": is_correct,
"feedback": self._generate_feedback(is_correct, question, user_answer),
"explanation": question.get("explanation", ""),
"points_earned": 10 if is_correct else 0
}
def generate_hint(self, question_id: str, hint_level: int) -> str:
question = self._get_question(question_id)
hints = question.get("hints", [])
if hint_level <= len(hints):
return hints[hint_level - 1]
return "No more hints available."
def get_practice_problem(self, difficulty: str, topic: Optional[str] = None) -> Dict:
# Generate or retrieve practice problem
return self._generate_practice_question(difficulty, topic)// ~/.binary_tutor/config.json
{
"user_profile": {
"name": "Student",
"created_at": "2025-10-15T10:00:00",
"current_level": "beginner",
"preferred_difficulty": "beginner"
},
"display_settings": {
"use_colors": true,
"show_hints_auto": false,
"explanation_detail": "standard"
},
"session_settings": {
"auto_save_interval_seconds": 300,
"max_hint_requests": 3,
"enable_achievements": true
},
"paths": {
"lessons_dir": "lessons",
"sessions_dir": "~/.binary_tutor/sessions",
"progress_file": "~/.binary_tutor/progress.json"
}
}// ~/.binary_tutor/sessions/session_uuid.json
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"lesson_id": "binary_basics",
"difficulty": "beginner",
"created_at": "2025-10-15T10:00:00",
"last_active": "2025-10-15T10:45:00",
"current_section": "conversion",
"section_index": 1,
"question_index": 3,
"completed_sections": ["introduction"],
"completed_questions": [
"binary_basics_intro_q1",
"binary_basics_intro_q2",
"binary_basics_conv_q1",
"binary_basics_conv_q2"
],
"progress": {
"total_questions": 15,
"completed_questions": 4,
"correct_answers": 3,
"total_attempts": 5,
"accuracy_rate": 0.75,
"current_streak": 2
},
"answer_history": [
{
"question_id": "binary_basics_intro_q1",
"user_answer": "8",
"is_correct": true,
"timestamp": "2025-10-15T10:05:00",
"hints_used": 0
}
],
"hints_used": 2,
"achievements_earned": [],
"is_complete": false
}// ~/.binary_tutor/progress.json
{
"user_id": "user_001",
"overall_stats": {
"total_time_minutes": 450,
"lessons_completed": 2,
"lessons_in_progress": 1,
"total_questions_answered": 127,
"total_correct_answers": 98,
"overall_accuracy": 0.77,
"longest_streak": 15,
"current_streak": 8
},
"lesson_progress": {
"binary_basics": {
"status": "completed",
"completed_at": "2025-10-10T15:30:00",
"final_score": 92,
"time_spent_minutes": 35,
"questions_answered": 20,
"accuracy": 0.85
},
"logic_gates": {
"status": "in_progress",
"started_at": "2025-10-12T09:00:00",
"progress_percent": 45,
"questions_answered": 15,
"accuracy": 0.73
}
},
"achievements": [
{
"id": "first_lesson_complete",
"name": "Getting Started",
"description": "Complete your first lesson",
"earned_at": "2025-10-10T15:30:00"
},
{
"id": "perfect_score",
"name": "Perfect Score",
"description": "Get 100% on a lesson section",
"earned_at": "2025-10-10T14:20:00"
}
],
"difficulty_history": [
{
"changed_at": "2025-10-10T10:00:00",
"from": null,
"to": "beginner"
}
]
}βββββββββββββββββββββββββββββββββββββββββββ
β Welcome to Binary Math Tutor! β
β β
β Let's set up your profile. β
βββββββββββββββββββββββββββββββββββββββββββ
> What should we call you? John
> What's your experience level?
1. Beginner (New to binary)
2. Intermediate (Some experience)
3. Advanced (Experienced with binary)
> Enter choice: 1
βββββββββββββββββββββββββββββββββββββββββββ
β Great! Welcome, John! β
β β
β Your profile has been created. β
β Level: Beginner β
β β
β Press Enter to continue... β
βββββββββββββββββββββββββββββββββββββββββββ
[Main menu displays]
βββββββββββββββββββββββββββββββββββββββββββ
β Select Your Lesson β
β β
β 1. Binary Basics β
β ββββββββββ 50% Complete β
β β
β 2. Logic Gates β
β ββββββββββ Not Started β
β β
β B. Back to Main Menu β
βββββββββββββββββββββββββββββββββββββββββββ
> Enter choice: 2
βββββββββββββββββββββββββββββββββββββββββββ
β Logic Gates β
β β
β Learn about AND, OR, NOT, and XOR β
β operations - the building blocks of β
β digital circuits. β
β β
β Estimated time: 45 minutes β
β Difficulty: Beginner β
β β
β Ready to start? (y/n) β
βββββββββββββββββββββββββββββββββββββββββββ
> y
βββββββββββββββββββββββββββββββββββββββββββ
β Section 1: Introduction to Logic Gates β
β β
β Logic gates are the fundamental β
β building blocks of digital circuits... β
β β
β [Educational content continues...] β
β β
β Press Enter when ready for questions β
βββββββββββββββββββββββββββββββββββββββββββ
[User presses Enter]
Question 1/5
What does an AND gate output when both inputs are 1?
Your answer: 1
β Correct!
The AND gate outputs 1 only when both inputs are 1.
Points earned: +10 | Streak: 1
Commands: n=next, h=hint, q=quit
>
Question 3/5
Convert the binary number 1011 to decimal.
Your answer: 12
β Incorrect
12 is not the correct decimal value for 1011.
Commands: n=next, h=hint, e=explain, r=retry, q=quit
> h
βββββββββββββββββββββββββββββββββββββββββββ
β Hint 1/3 β
β β
β Remember: Each position in binary β
β represents a power of 2, starting β
β from the right with 2^0. β
βββββββββββββββββββββββββββββββββββββββββββ
> r
Your answer: 10
β Incorrect
Still not quite right. Would you like another hint?
> h
βββββββββββββββββββββββββββββββββββββββββββ
β Hint 2/3 β
β β
β Break it down position by position: β
β 1011 = (1Γ2Β³) + (0Γ2Β²) + (1Γ2ΒΉ) + (1Γ2β°)β
β β
β Calculate each term then add them up. β
βββββββββββββββββββββββββββββββββββββββββββ
> r
Your answer: 11
β Correct!
Excellent! 1011 in binary equals 11 in decimal.
βββββββββββββββββββββββββββββββββββββββββββ
β Explanation β
β β
β 1011 = (1Γ8) + (0Γ4) + (1Γ2) + (1Γ1) β
β = 8 + 0 + 2 + 1 β
β = 11 β
β β
β Each position represents a power of 2, β
β and we multiply by 1 or 0 depending β
β on the bit value. β
βββββββββββββββββββββββββββββββββββββββββββ
Points earned: +7 (2 hints used) | Streak: 1
>
[During a lesson]
Commands: n=next, h=hint, s=save, q=quit
> s
βββββββββββββββββββββββββββββββββββββββββββ
β Saving your progress... β
β β
β β Session saved successfully β
β β
β Lesson: Logic Gates β
β Progress: 3/5 questions (60%) β
β Accuracy: 67% β
β Streak: 1 β
β β
β You can resume anytime from the β
β main menu. β
βββββββββββββββββββββββββββββββββββββββββββ
> q
[Returns to main menu]
---
[Later session - User returns]
βββββββββββββββββββββββββββββββββββββββββββ
β Binary Math Interactive Tutor β
β β
β 1. Start New Lesson β
β 2. Resume Lesson β
β 3. Practice Problems β
β 4. View Progress β
β 5. Settings β
β 6. Help β
β 7. Exit β
β β
β Level: Beginner | Progress: 35% β
βββββββββββββββββββββββββββββββββββββββββββ
> Enter choice: 2
βββββββββββββββββββββββββββββββββββββββββββ
β Resume Lesson β
β β
β Active Sessions: β
β β
β 1. Logic Gates β
β Last active: 2 hours ago β
β Progress: 60% (3/5 questions) β
β Accuracy: 67% β
β β
β B. Back to Main Menu β
βββββββββββββββββββββββββββββββββββββββββββ
> Enter choice: 1
βββββββββββββββββββββββββββββββββββββββββββ
β Resuming: Logic Gates β
β β
β Welcome back! You left off at β
β question 4 of 5. β
β β
β Press Enter to continue... β
βββββββββββββββββββββββββββββββββββββββββββ
[Lesson resumes at question 4]
βββββββββββββββββββββββββββββββββββββββββββ
β Your Progress β
β β
β Overall Statistics β
β ββββββββββββββββββββββββββββββββ β
β Total Time: 2h 15m β
β Questions Answered: 47 β
β Accuracy: 77% β
β Current Streak: 5 β
β Longest Streak: 12 β
β β
β Lesson Progress β
β ββββββββββββββββββββββββββββββββ β
β β Binary Basics [100%] β
β Completed: Oct 10, 2025 β
β Score: 92/100 β
β β
β β Logic Gates [60%] β
β In Progress β
β Current Score: 67/100 β
β β
β β Truth Tables [0%] β
β Not Started β
β Requires: Logic Gates β
β β
β Achievements β
β ββββββββββββββββββββββββββββββββ β
β π Getting Started β
β Complete your first lesson β
β β
β π― Perfect Score β
β Get 100% on a lesson section β
β β
β Press Enter to return to main menu β
βββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββ
β Practice Problems β
β β
β Choose a topic: β
β β
β 1. Binary Conversion β
β 2. Logic Gates β
β 3. Truth Tables β
β 4. Mixed Topics β
β β
β Difficulty: Beginner β
β (Change in Settings) β
β β
β B. Back to Main Menu β
βββββββββββββββββββββββββββββββββββββββββββ
> Enter choice: 1
βββββββββββββββββββββββββββββββββββββββββββ
β Practice: Binary Conversion β
β β
β How many problems? (1-20): 5 β
βββββββββββββββββββββββββββββββββββββββββββ
> 5
Practice Problem 1/5
Convert 25 to binary.
Your answer: 11001
β Correct!
Points: +10 | Session Score: 10/10
[Next problem appears...]
---
[After completing all problems]
βββββββββββββββββββββββββββββββββββββββββββ
β Practice Session Complete! β
β β
β Results: β
β ββββββββββββββββββββββββββββββββ β
β Correct: 4/5 (80%) β
β Total Points: 40/50 β
β Time: 3m 45s β
β Avg. Time per Question: 45s β
β β
β Great job! Keep practicing to improve. β
β β
β 1. Practice Again β
β 2. Review Mistakes β
β 3. Return to Main Menu β
βββββββββββββββββββββββββββββββββββββββββββ
Deliverables:
- Project structure and basic CLI framework
- State management system
- Session persistence (save/load)
- Basic display rendering (no colors, plain text)
- Input handling with validation
Files to Create:
interactive_tutor.py- Main orchestratorstate_manager.py- State machine implementationsession_manager.py- Session persistencedisplay_renderer.py- Output renderinginput_handler.py- Input processingconfig.py- Configuration management
Test Coverage:
- State transitions (valid/invalid)
- Session save/load with corrupted data
- Input validation edge cases
Deliverables:
- Lesson module interface definition
- Module loader system
- First lesson implementation (Binary Basics)
- Answer validation engine
- Hint generation system
Files to Create:
lesson_interface.py- Base class for lessonsmodule_loader.py- Dynamic module loadinglessons/binary_basics.py- First lessonvalidators.py- Answer validationfeedback_engine.py- Feedback generation
Test Coverage:
- Module loading (success/failure)
- Answer validation (correct/incorrect/edge cases)
- Hint progression (3 levels)
Deliverables:
- Full menu system with navigation
- Progress tracking and visualization
- Enhanced display with colors (using
rich) - Help system
- Settings management
Files to Create:
menu_system.py- Menu navigationprogress_tracker.py- Progress calculationhelp_system.py- Context-sensitive help
Test Coverage:
- Navigation flows (forward/backward)
- Progress calculation accuracy
- Settings persistence
Deliverables:
- Logic Gates lesson
- Truth Tables lesson
- Practice problem generator
- Achievement system
Files to Create:
lessons/logic_gates.pylessons/truth_tables.pypractice_engine.py- Practice problem generationachievements.py- Achievement tracking
Test Coverage:
- Each lesson's validation logic
- Practice problem generation
- Achievement unlock conditions
Deliverables:
- Error handling refinement
- User experience improvements
- Performance optimization
- Documentation
- Integration testing
Artifacts:
- User manual
- Developer documentation
- Video walkthrough (optional)
Test Coverage:
- End-to-end user flows
- Error recovery scenarios
- Performance benchmarks
binary_math_tutor/
βββ interactive_tutor.py # Main entry point
βββ config.py # Configuration management
βββ state_manager.py # State machine
βββ session_manager.py # Session persistence
βββ display_renderer.py # Output rendering
βββ input_handler.py # Input handling
βββ module_loader.py # Dynamic module loading
βββ progress_tracker.py # Progress tracking
βββ menu_system.py # Menu navigation
βββ help_system.py # Help content
βββ feedback_engine.py # Feedback generation
βββ validators.py # Answer validation
βββ achievements.py # Achievement system
βββ practice_engine.py # Practice problems
β
βββ lesson_interface.py # Base lesson interface
βββ lessons/
β βββ __init__.py
β βββ binary_basics.py # Lesson 1
β βββ logic_gates.py # Lesson 2
β βββ truth_tables.py # Lesson 3
β βββ binary_arithmetic.py # Lesson 4
β
βββ tests/
β βββ test_state_manager.py
β βββ test_session_manager.py
β βββ test_validators.py
β βββ test_lessons.py
β βββ test_integration.py
β
βββ requirements.txt # Dependencies
βββ README.md # Project documentation
βββ ARCHITECTURE.md # This document
# requirements.txt
# CLI Framework
click>=8.1.0 # Command-line interface creation
rich>=13.0.0 # Terminal formatting and colors
# Data Management
pydantic>=2.0.0 # Data validation
# Testing
pytest>=7.4.0 # Test framework
pytest-cov>=4.1.0 # Coverage reporting
pytest-mock>=3.11.0 # Mocking utilities
# Development
black>=23.0.0 # Code formatting
ruff>=0.0.290 # Linting
mypy>=1.5.0 # Type checking| Command | Description | Example |
|---|---|---|
start |
Start a new lesson | User selects from menu |
resume |
Resume previous session | User selects from active sessions |
practice |
Enter practice mode | User selects topic and count |
progress |
View progress report | Displays stats and achievements |
settings |
Modify settings | Change difficulty, display options |
help |
Display help information | Context-sensitive help |
exit |
Exit the program | Saves state before exit |
| Command | Shortcut | Description |
|---|---|---|
next |
n |
Next question |
previous |
p |
Previous question (if allowed) |
hint |
h |
Request a hint |
explain |
e |
Show detailed explanation |
retry |
r |
Retry current question |
save |
s |
Save progress |
quit |
q |
Return to main menu |
help |
? |
Show command list |
- Menu rendering: < 50ms
- Question display: < 100ms
- Answer validation: < 200ms
- Session save: < 500ms
- Session load: < 300ms
- Memory footprint: < 50MB
- Session file size: < 100KB
- Config file size: < 10KB
- Log file rotation: 5MB max
- Support 50+ lessons without degradation
- Handle 1000+ questions per lesson
- Maintain sub-second response with 10+ active sessions
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0 | 2025-10-15 | CLI Interface Architect | Initial architecture design |
End of Document