import React, { useState, useEffect, useCallback } from 'react';
import { useAppState, useAction } from './sdk';
import { Badge, Glass, Icon, Metric } from './components';
import {
BookOpen, Code, CheckCircle, Play, ChevronRight, ChevronDown,
Trophy, Award, Clock, Target, Lightbulb, FileCode,
ChevronLeft, Menu, X, Star, Zap, Brain, Terminal
} from 'lucide-react';
// ============================================================================
// CURRICULUM DATA - Complete 6-Week Python Bootcamp
// ============================================================================
const CURRICULUM = {
weeks: [
{
id: 1,
title: "Python Basics",
description: "Variables, data types, operators, and input/output",
icon: "terminal",
lessons: [
{
id: "1.1",
title: "Welcome to Python",
content: `Python is a powerful, easy-to-read programming language used for web development, data science, automation, and more.
**Why Python?**
- Clean, readable syntax
- Huge ecosystem of libraries
- Great for beginners and experts
- Used by Google, Netflix, NASA, and more
**Your First Program:**
\`\`\`python
print("Hello, World!")
\`\`\`
The \`print()\` function displays text on the screen. This is your first step into programming!`,
codeExample: 'print("Hello, World!")',
exercises: [
{
id: "ex-1.1.1",
type: "code",
instruction: "Print your name to the screen",
starter: "# Write your code here\n",
solution: 'print("Your Name")',
test: 'output.contains("name")',
hint: "Use print() with your name in quotes"
}
]
},
{
id: "1.2",
title: "Variables & Data Types",
content: `Variables store data that your program can use and manipulate.
**Basic Data Types:**
- \`int\` - Whole numbers (42, -17, 0)
- \`float\` - Decimal numbers (3.14, -0.5)
- \`str\` - Text strings ("hello", 'world')
- \`bool\` - True or False
**Creating Variables:**
\`\`\`python
name = "Alice" # string
age = 25 # integer
height = 5.9 # float
is_student = True # boolean
\`\`\`
**Naming Rules:**
- Start with letter or underscore
- No spaces (use underscores)
- Case-sensitive (age ≠ Age)`,
codeExample: `name = "Alice"
age = 25
height = 5.9
print(f"{name} is {age} years old")`,
exercises: [
{
id: "ex-1.2.1",
type: "code",
instruction: "Create variables for your favorite color and age, then print them",
starter: "# Create your variables here\n\n# Print them\n",
solution: `color = "blue"
age = 30
print(f"My favorite color is {color} and I am {age} years old")`,
hint: "Use f-strings to combine text and variables"
},
{
id: "ex-1.2.2",
type: "multiple-choice",
instruction: "Which is a valid variable name?",
options: [
"2name",
"my_variable",
"my variable",
"class"
],
correct: 1,
explanation: "Variable names can't start with numbers, can't have spaces, and can't be Python keywords like 'class'"
}
]
},
{
id: "1.3",
title: "Operators & Expressions",
content: `Operators perform operations on values and variables.
**Arithmetic Operators:**
- \`+\` Addition
- \`-\` Subtraction
- \`*\` Multiplication
- \`/\` Division (returns float)
- \`//\` Floor division (returns int)
- \`%\` Modulo (remainder)
- \`**\` Exponentiation
**Examples:**
\`\`\`python
x = 10
y = 3
print(x + y) # 13
print(x / y) # 3.333...
print(x // y) # 3
print(x % y) # 1
print(x ** y) # 1000
\`\`\``,
codeExample: `price = 29.99
quantity = 3
total = price * quantity
print(f"Total: ${total:.2f}")`,
exercises: [
{
id: "ex-1.3.1",
type: "code",
instruction: "Calculate the area of a rectangle with width=5 and height=8",
starter: "width = 5\nheight = 8\n# Calculate area\n",
solution: `width = 5
height = 8
area = width * height
print(f"Area: {area}")`,
hint: "Area = width × height"
}
]
},
{
id: "1.4",
title: "Input & Output",
content: `Get input from users and display results.
**Getting Input:**
\`\`\`python
name = input("What is your name? ")
age = input("How old are you? ")
print(f"Hello {name}, you are {age} years old!")
\`\`\`
**Important:** \`input()\` always returns a string. Convert to numbers:
\`\`\`python
age = int(input("Your age: "))
price = float(input("Price: $"))
\`\`\`
**Type Conversion:**
- \`int("42")\` → 42
- \`float("3.14")\` → 3.14
- \`str(100)\` → "100"`,
codeExample: `name = input("Enter your name: ")
birth_year = int(input("Enter birth year: "))
age = 2024 - birth_year
print(f"{name}, you are approximately {age} years old")`,
exercises: [
{
id: "ex-1.4.1",
type: "code",
instruction: "Create a tip calculator: get bill amount and tip percentage, calculate total",
starter: "# Get bill amount\n# Get tip percentage\n# Calculate total\n# Print result\n",
solution: `bill = float(input("Bill amount: $"))
tip_percent = float(input("Tip %: "))
tip = bill * (tip_percent / 100)
total = bill + tip
print(f"Tip: ${tip:.2f}, Total: ${total:.2f}")`,
hint: "Remember to convert input to float"
}
]
}
],
project: {
title: "Unit Converter",
description: "Build a program that converts between different units (temperature, length, weight)",
requirements: [
"Convert Celsius ↔ Fahrenheit",
"Convert miles ↔ kilometers",
"Convert pounds ↔ kilograms",
"User-friendly menu interface",
"Handle invalid input gracefully"
],
starterCode: `def celsius_to_fahrenheit(c):
return c * 9/5 + 32
def fahrenheit_to_celsius(f):
return (f - 32) * 5/9
# Add more conversion functions here
print("=== Unit Converter ===")
# Build your menu system`,
solution: `def celsius_to_fahrenheit(c):
return c * 9/5 + 32
def fahrenheit_to_celsius(f):
return (f - 32) * 5/9
def miles_to_km(m):
return m * 1.609
def km_to_miles(k):
return k / 1.609
def lbs_to_kg(l):
return l * 0.454
def kg_to_lbs(k):
return k / 0.454
while True:
print("\\n=== Unit Converter ===")
print("1. Celsius to Fahrenheit")
print("2. Fahrenheit to Celsius")
print("3. Miles to Kilometers")
print("4. Kilometers to Miles")
print("5. Pounds to Kilograms")
print("6. Kilograms to Pounds")
print("0. Exit")
choice = input("Choose conversion: ")
if choice == "0":
break
elif choice == "1":
c = float(input("Celsius: "))
print(f"{c}°C = {celsius_to_fahrenheit(c):.1f}°F")
# Add remaining cases...
else:
print("Invalid choice")`,
rubric: {
functionality: 40,
codeQuality: 30,
userExperience: 20,
errorHandling: 10
}
},
quiz: {
questions: [
{
question: "Which data type stores whole numbers?",
options: ["float", "int", "str", "bool"],
correct: 1
},
{
question: "What does 17 % 5 equal?",
options: ["3", "3.4", "2", "0"],
correct: 2
},
{
question: "How do you convert a string to an integer?",
options: ["integer()", "int()", "str()", "num()"],
correct: 1
}
]
}
},
{
id: 2,
title: "Control Flow",
description: "Conditionals, loops, and logic",
icon: "zap",
lessons: [
{
id: "2.1",
title: "If Statements",
content: `Make decisions in your code using if/elif/else.
**Basic Syntax:**
\`\`\`python
age = 18
if age >= 18:
print("You're an adult")
else:
print("You're a minor")
\`\`\`
**Comparison Operators:**
- \`==\` Equal to
- \`!=\` Not equal to
- \`>\` Greater than
- \`<\` Less than
- \`>=\` Greater than or equal
- \`<=\` Less than or equal
**Logical Operators:**
- \`and\` - Both conditions true
- \`or\` - At least one true
- \`not\` - Invert the condition`,
codeExample: `score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
else:
grade = "F"
print(f"Grade: {grade}")`,
exercises: [
{
id: "ex-2.1.1",
type: "code",
instruction: "Check if a number is positive, negative, or zero",
starter: "num = int(input('Enter a number: '))\n# Your code here\n",
solution: `num = int(input('Enter a number: '))
if num > 0:
print("Positive")
elif num < 0:
print("Negative")
else:
print("Zero")`,
hint: "Use if/elif/else structure"
}
]
},
{
id: "2.2",
title: "For Loops",
content: `Repeat code a specific number of times or iterate over sequences.
**Range Function:**
\`\`\`python
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(2, 6): # 2, 3, 4, 5
print(i)
for i in range(0, 10, 2): # 0, 2, 4, 6, 8
print(i)
\`\`\`
**Iterating Over Strings:**
\`\`\`python
for char in "hello":
print(char)
\`\`\``,
codeExample: `for i in range(1, 6):
print(f"{i} squared is {i**2}")`,
exercises: [
{
id: "ex-2.2.1",
type: "code",
instruction: "Print all even numbers from 1 to 20",
starter: "# Use a for loop with range\n",
solution: `for i in range(2, 21, 2):
print(i)`,
hint: "Use range with step of 2"
}
]
},
{
id: "2.3",
title: "While Loops",
content: `Repeat code while a condition is true.
**Basic Syntax:**
\`\`\`python
count = 0
while count < 5:
print(count)
count += 1
\`\`\`
**Infinite Loop (be careful!):**
\`\`\`python
while True:
user_input = input("Type 'quit' to exit: ")
if user_input == "quit":
break
\`\`\`
**Break & Continue:**
- \`break\` - Exit the loop immediately
- \`continue\` - Skip to next iteration`,
codeExample: `password = ""
while password != "secret123":
password = input("Enter password: ")
print("Access granted!")`,
exercises: [
{
id: "ex-2.3.1",
type: "code",
instruction: "Keep asking for input until user types 'done'",
starter: "# Use while loop\n",
solution: `while True:
user_input = input("Enter something (type 'done' to quit): ")
if user_input == "done":
break
print(f"You typed: {user_input}")`,
hint: "Use while True with break"
}
]
}
],
project: {
title: "Number Guessing Game",
description: "Create a game where the computer picks a random number and the player guesses it",
requirements: [
"Generate random number 1-100",
"Give hints (higher/lower) after each guess",
"Track number of attempts",
"Validate input (1-100 range)",
"Ask to play again"
],
starterCode: `import random
secret = random.randint(1, 100)
attempts = 0
print("I'm thinking of a number between 1 and 100")
# Build your game loop`,
solution: `import random
def play_game():
secret = random.randint(1, 100)
attempts = 0
print("I'm thinking of a number between 1 and 100")
while True:
try:
guess = int(input("Your guess: "))
attempts += 1
if guess < 1 or guess > 100:
print("Please guess between 1 and 100")
elif guess < secret:
print("Higher!")
elif guess > secret:
print("Lower!")
else:
print(f"Correct! You got it in {attempts} attempts!")
break
except ValueError:
print("Please enter a valid number")
while True:
play_game()
again = input("Play again? (yes/no): ")
if again.lower() != "yes":
break
print("Thanks for playing!")`,
rubric: {
functionality: 40,
codeQuality: 30,
userExperience: 20,
errorHandling: 10
}
},
quiz: {
questions: [
{
question: "What does range(3, 7) produce?",
options: ["3, 4, 5, 6, 7", "3, 4, 5, 6", "4, 5, 6, 7", "3, 5, 7"],
correct: 1
},
{
question: "Which keyword exits a loop immediately?",
options: ["stop", "exit", "break", "return"],
correct: 2
}
]
}
},
{
id: 3,
title: "Data Structures",
description: "Lists, tuples, dictionaries, and sets",
icon: "book-open",
lessons: [
{
id: "3.1",
title: "Lists",
content: `Lists store ordered collections of items.
**Creating Lists:**
\`\`\`python
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]
\`\`\`
**Accessing Items:**
\`\`\`python
fruits[0] # "apple"
fruits[-1] # "cherry" (last item)
fruits[1:3] # ["banana", "cherry"]
\`\`\`
**List Methods:**
- \`append(item)\` - Add to end
- \`insert(pos, item)\` - Insert at position
- \`remove(item)\` - Remove first occurrence
- \`pop()\` - Remove and return last item
- \`len(list)\` - Get length`,
codeExample: `numbers = [1, 2, 3, 4, 5]
numbers.append(6)
numbers.insert(0, 0)
print(numbers) # [0, 1, 2, 3, 4, 5, 6]
print(f"Length: {len(numbers)}")`,
exercises: [
{
id: "ex-3.1.1",
type: "code",
instruction: "Create a list of 5 colors, add one more, then print all",
starter: "colors = []\n# Your code here\n",
solution: `colors = ["red", "blue", "green", "yellow", "purple"]
colors.append("orange")
for color in colors:
print(color)`,
hint: "Use append() to add, for loop to print"
}
]
},
{
id: "3.2",
title: "Dictionaries",
content: `Dictionaries store key-value pairs.
**Creating Dictionaries:**
\`\`\`python
person = {
"name": "Alice",
"age": 30,
"city": "New York"
}
\`\`\`
**Accessing Values:**
\`\`\`python
person["name"] # "Alice"
person.get("age") # 30
person.get("job", "N/A") # "N/A" (default if key missing)
\`\`\`
**Dictionary Methods:**
- \`keys()\` - Get all keys
- \`values()\` - Get all values
- \`items()\` - Get key-value pairs
- \`update(dict)\` - Merge dictionaries`,
codeExample: `student = {"name": "Bob", "grade": "A"}
student["age"] = 20
student.update({"major": "CS"})
for key, value in student.items():
print(f"{key}: {value}")`,
exercises: [
{
id: "ex-3.2.1",
type: "code",
instruction: "Create a dictionary for a book with title, author, and year",
starter: "book = {}\n# Add keys and values\n",
solution: `book = {
"title": "Python Basics",
"author": "John Doe",
"year": 2024
}
print(f"'{book['title']}' by {book['author']} ({book['year']})")`,
hint: "Use string keys and appropriate value types"
}
]
}
],
project: {
title: "Contact Book",
description: "Build a digital address book to store and manage contacts",
requirements: [
"Add new contacts (name, phone, email)",
"Search contacts by name",
"Display all contacts",
"Delete contacts",
"Save/load from file (bonus)"
],
starterCode: `contacts = {}
def add_contact(name, phone, email):
# Implement this
pass
# Build your menu system`,
solution: `contacts = {}
def add_contact(name, phone, email):
contacts[name] = {"phone": phone, "email": email}
print(f"Added {name}")
def search_contact(name):
if name in contacts:
info = contacts[name]
print(f"Name: {name}, Phone: {info['phone']}, Email: {info['email']}")
else:
print("Contact not found")
def display_all():
for name, info in contacts.items():
print(f"{name}: {info['phone']}, {info['email']}")
def delete_contact(name):
if name in contacts:
del contacts[name]
print(f"Deleted {name}")
else:
print("Contact not found")
while True:
print("\\n=== Contact Book ===")
print("1. Add Contact")
print("2. Search Contact")
print("3. Display All")
print("4. Delete Contact")
print("5. Exit")
choice = input("Choose: ")
if choice == "1":
name = input("Name: ")
phone = input("Phone: ")
email = input("Email: ")
add_contact(name, phone, email)
elif choice == "2":
name = input("Name to search: ")
search_contact(name)
elif choice == "3":
display_all()
elif choice == "4":
name = input("Name to delete: ")
delete_contact(name)
elif choice == "5":
break`,
rubric: {
functionality: 40,
codeQuality: 30,
userExperience: 20,
errorHandling: 10
}
},
quiz: {
questions: [
{
question: "How do you access the last item in a list?",
options: ["list[0]", "list[-1]", "list[last]", "list.end()"],
correct: 1
},
{
question: "What method adds an item to a list?",
options: ["add()", "insert()", "append()", "push()"],
correct: 2
}
]
}
},
{
id: 4,
title: "Functions & Modules",
description: "Reusable code and imports",
icon: "code",
lessons: [
{
id: "4.1",
title: "Defining Functions",
content: `Functions are reusable blocks of code.
**Basic Function:**
\`\`\`python
def greet(name):
return f"Hello, {name}!"
message = greet("Alice")
print(message) # "Hello, Alice!"
\`\`\`
**Parameters & Return:**
\`\`\`python
def add(a, b):
return a + b
result = add(5, 3) # 8
\`\`\`
**Default Parameters:**
\`\`\`python
def greet(name="Guest"):
return f"Hello, {name}!"
\`\`\``,
codeExample: `def calculate_area(width, height):
return width * height
area = calculate_area(5, 10)
print(f"Area: {area}")`,
exercises: [
{
id: "ex-4.1.1",
type: "code",
instruction: "Write a function that returns the square of a number",
starter: "def square(n):\n # Your code here\n",
solution: `def square(n):
return n * n
print(square(5)) # 25`,
hint: "Multiply n by itself"
}
]
},
{
id: "4.2",
title: "Modules & Imports",
content: `Organize code into modules and reuse them.
**Importing Modules:**
\`\`\`python
import math
print(math.sqrt(16)) # 4.0
from math import sqrt, pi
print(sqrt(16)) # 4.0
print(pi) # 3.14159...
import random as rd
print(rd.randint(1, 10))
\`\`\`
**Common Modules:**
- \`math\` - Mathematical functions
- \`random\` - Random number generation
- \`datetime\` - Date and time
- \`os\` - Operating system functions
- \`json\` - JSON parsing`,
codeExample: `import random
import math
numbers = [random.randint(1, 100) for _ in range(5)]
print(f"Numbers: {numbers}")
print(f"Average: {sum(numbers)/len(numbers):.2f}")`,
exercises: [
{
id: "ex-4.2.1",
type: "code",
instruction: "Use the random module to simulate rolling a die 3 times",
starter: "import random\n# Roll die 3 times\n",
solution: `import random
for i in range(3):
roll = random.randint(1, 6)
print(f"Roll {i+1}: {roll}")`,
hint: "Use randint(1, 6) in a loop"
}
]
}
],
project: {
title: "Text Utility Library",
description: "Create a module with useful text manipulation functions",
requirements: [
"Function to reverse a string",
"Function to count vowels",
"Function to check palindrome",
"Function to capitalize words",
"Include docstrings for each function"
],
starterCode: `"""Text Utility Library"""
def reverse_string(text):
# Implement this
pass
# Add more functions`,
solution: `"""Text Utility Library"""
def reverse_string(text):
"""Return the reversed string"""
return text[::-1]
def count_vowels(text):
"""Count the number of vowels in text"""
vowels = "aeiouAEIOU"
return sum(1 for char in text if char in vowels)
def is_palindrome(text):
"""Check if text is a palindrome"""
cleaned = text.lower().replace(" ", "")
return cleaned == cleaned[::-1]
def capitalize_words(text):
"""Capitalize first letter of each word"""
return text.title()
# Test the functions
if __name__ == "__main__":
print(reverse_string("hello")) # olleh
print(count_vowels("beautiful")) # 5
print(is_palindrome("A man a plan a canal Panama")) # True`,
rubric: {
functionality: 40,
codeQuality: 30,
userExperience: 20,
errorHandling: 10
}
},
quiz: {
questions: [
{
question: "What keyword defines a function?",
options: ["function", "def", "func", "define"],
correct: 1
},
{
question: "How do you import the math module?",
options: ["include math", "using math", "import math", "require math"],
correct: 2
}
]
}
},
{
id: 5,
title: "Intermediate Python",
description: "OOP, file I/O, APIs, and libraries",
icon: "brain",
lessons: [
{
id: "5.1",
title: "Object-Oriented Programming",
content: `Classes and objects for organizing code.
**Defining a Class:**
\`\`\`python
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
return f"{self.name} says woof!"
dog = Dog("Buddy", 3)
print(dog.bark()) # "Buddy says woof!"
\`\`\`
**Key Concepts:**
- \`__init__\` - Constructor method
- \`self\` - Reference to instance
- Attributes - Instance variables
- Methods - Functions in class`,
codeExample: `class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hi, I'm {self.name}"
p = Person("Alice", 30)
print(p.greet())`,
exercises: [
{
id: "ex-5.1.1",
type: "code",
instruction: "Create a Rectangle class with area() method",
starter: "class Rectangle:\n def __init__(self, width, height):\n # Your code here\n",
solution: `class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
rect = Rectangle(5, 10)
print(rect.area()) # 50`,
hint: "Store width and height, return their product"
}
]
},
{
id: "5.2",
title: "File I/O",
content: `Read from and write to files.
**Reading Files:**
\`\`\`python
with open("file.txt", "r") as f:
content = f.read()
print(content)
\`\`\`
**Writing Files:**
\`\`\`python
with open("output.txt", "w") as f:
f.write("Hello, file!")
\`\`\`
**File Modes:**
- \`"r"\` - Read (default)
- \`"w"\` - Write (overwrites)
- \`"a"\` - Append
- \`"r+"\` - Read and write`,
codeExample: `# Write to file
with open("data.txt", "w") as f:
f.write("Line 1\\n")
f.write("Line 2\\n")
# Read from file
with open("data.txt", "r") as f:
for line in f:
print(line.strip())`,
exercises: [
{
id: "ex-5.2.1",
type: "code",
instruction: "Write a function that saves a list of names to a file",
starter: "def save_names(names, filename):\n # Your code here\n",
solution: `def save_names(names, filename):
with open(filename, "w") as f:
for name in names:
f.write(name + "\\n")
save_names(["Alice", "Bob", "Charlie"], "names.txt")`,
hint: "Use 'w' mode and write each name with newline"
}
]
}
],
project: {
title: "Weather API App",
description: "Build an app that fetches and displays weather data from an API",
requirements: [
"Fetch weather data from API",
"Parse JSON response",
"Display temperature, conditions, humidity",
"Handle errors gracefully",
"Allow multiple city lookups"
],
starterCode: `import requests
API_KEY = "your_key_here"
BASE_URL = "https://api.openweathermap.org/data/2.5/weather"
def get_weather(city):
# Implement API call
pass`,
solution: `import requests
API_KEY = "demo" # Use actual key in production
BASE_URL = "https://api.openweathermap.org/data/2.5/weather"
def get_weather(city):
params = {"q": city, "appid": API_KEY, "units": "metric"}
response = requests.get(BASE_URL, params=params)
if response.status_code == 200:
data = response.json()
return {
"temp": data["main"]["temp"],
"feels_like": data["main"]["feels_like"],
"humidity": data["main"]["humidity"],
"description": data["weather"][0]["description"]
}
else:
return None
while True:
city = input("Enter city (or 'quit'): ")
if city.lower() == "quit":
break
weather = get_weather(city)
if weather:
print(f"\\n{city}:")
print(f"Temperature: {weather['temp']}°C")
print(f"Feels like: {weather['feels_like']}°C")
print(f"Humidity: {weather['humidity']}%")
print(f"Conditions: {weather['description']}")
else:
print("City not found")`,
rubric: {
functionality: 40,
codeQuality: 30,
userExperience: 20,
errorHandling: 10
}
},
quiz: {
questions: [
{
question: "What is __init__ in a class?",
options: ["A variable", "The constructor", "A decorator", "An import"],
correct: 1
},
{
question: "Which mode opens a file for appending?",
options: ["r", "w", "a", "x"],
correct: 2
}
]
}
},
{
id: 6,
title: "Advanced Topics & Capstone",
description: "Error handling, testing, and final project",
icon: "trophy",
lessons: [
{
id: "6.1",
title: "Error Handling",
content: `Handle errors gracefully with try/except.
**Basic Exception Handling:**
\`\`\`python
try:
result = 10 / 0
except ZeroDivisionError:
print("Can't divide by zero!")
\`\`\`
**Multiple Exceptions:**
\`\`\`python
try:
value = int(input("Enter a number: "))
result = 10 / value
except ValueError:
print("That's not a number!")
except ZeroDivisionError:
print("Can't divide by zero!")
\`\`\`
**Finally Block:**
\`\`\`python
try:
f = open("file.txt")
except:
print("Error!")
finally:
f.close() # Always executes
\`\`\``,
codeExample: `def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
return "Error: Division by zero"
except TypeError:
return "Error: Invalid types"
print(safe_divide(10, 2)) # 5.0
print(safe_divide(10, 0)) # Error message`,
exercises: [
{
id: "ex-6.1.1",
type: "code",
instruction: "Write a function that safely converts input to integer",
starter: "def safe_int(value):\n # Handle errors\n",
solution: `def safe_int(value):
try:
return int(value)
except (ValueError, TypeError):
return None
print(safe_int("42")) # 42
print(safe_int("abc")) # None`,
hint: "Catch ValueError and TypeError"
}
]
},
{
id: "6.2",
title: "Testing Your Code",
content: `Write tests to ensure your code works correctly.
**Using assert:**
\`\`\`python
def add(a, b):
return a + b
assert add(2, 3) == 5
assert add(-1, 1) == 0
print("All tests passed!")
\`\`\`
**unittest Module:**
\`\`\`python
import unittest
class TestMath(unittest.TestCase):
def test_add(self):
self.assertEqual(add(2, 3), 5)
if __name__ == "__main__":
unittest.main()
\`\`\``,
codeExample: `def multiply(a, b):
return a * b
# Simple tests
assert multiply(2, 3) == 6
assert multiply(0, 5) == 0
assert multiply(-2, 3) == -6
print("✓ All tests passed!")`,
exercises: [
{
id: "ex-6.2.1",
type: "code",
instruction: "Write 3 tests for a function that checks if a number is even",
starter: "def is_even(n):\n return n % 2 == 0\n\n# Write tests\n",
solution: `def is_even(n):
return n % 2 == 0
# Tests
assert is_even(2) == True
assert is_even(3) == False
assert is_even(0) == True
print("✓ All tests passed!")`,
hint: "Test even, odd, and zero cases"
}
]
}
],
project: {
title: "Capstone Project",
description: "Build a portfolio-worthy project that demonstrates all your skills",
requirements: [
"Use functions and classes",
"Include file I/O or API integration",
"Implement error handling",
"Have a clear user interface",
"Include documentation",
"Add tests for core functionality"
],
ideas: [
"Personal budget tracker with CSV export",
"Quiz app with score tracking",
"Task manager with file persistence",
"API-based news aggregator",
"Data visualization dashboard"
],
starterCode: `"""
Capstone Project: [Your Project Name]
Author: [Your Name]
Description: [What does it do?]
"""
# Start building your project!`,
rubric: {
functionality: 30,
codeQuality: 25,
creativity: 20,
documentation: 15,
testing: 10
}
},
quiz: {
questions: [
{
question: "What block always executes in try/except?",
options: ["try", "except", "finally", "else"],
correct: 2
},
{
question: "Which exception is raised when dividing by zero?",
options: ["ValueError", "TypeError", "ZeroDivisionError", "RuntimeError"],
correct: 2
}
]
}
}
]
};
// ============================================================================
// MAIN APP COMPONENT
// ============================================================================
export default function App() {
const [activeWeek, setActiveWeek] = useState(1);
const [activeLesson, setActiveLesson] = useState(null);
const [completedLessons, setCompletedLessons] = useAppState('completedLessons', []);
const [completedExercises, setCompletedExercises] = useAppState('completedExercises', []);
const [completedQuizzes, setCompletedQuizzes] = useAppState('completedQuizzes', []);
const [showProject, setShowProject] = useState(false);
const [showQuiz, setShowQuiz] = useState(false);
const [sidebarOpen, setSidebarOpen] = useState(true);
const [codeSolution, setCodeSolution] = useState(null);
const [quizAnswers, setQuizAnswers] = useState({});
const [quizSubmitted, setQuizSubmitted] = useState(false);
const [quizScore, setQuizScore] = useState(null);
const dispatch = useAction();
// Calculate progress
const totalLessons = CURRICULUM.weeks.reduce((sum, week) => sum + week.lessons.length, 0);
const progressPercent = Math.round((completedLessons.length / totalLessons) * 100);
// Get current week data
const currentWeek = CURRICULUM.weeks.find(w => w.id === activeWeek);
const currentLesson = currentWeek?.lessons.find(l => l.id === activeLesson);
// Toggle lesson completion
const toggleLessonComplete = useCallback((lessonId) => {
setCompletedLessons(prev =>
prev.includes(lessonId)
? prev.filter(id => id !== lessonId)
: [...prev, lessonId]
);
}, [setCompletedLessons]);
// Mark exercise complete
const markExerciseComplete = useCallback((exerciseId) => {
if (!completedExercises.includes(exerciseId)) {
setCompletedExercises(prev => [...prev, exerciseId]);
}
}, [completedExercises, setCompletedExercises]);
// Submit quiz
const submitQuiz = useCallback(() => {
if (!currentWeek?.quiz) return;
let correct = 0;
currentWeek.quiz.questions.forEach((q, idx) => {
if (quizAnswers[idx] === q.correct) correct++;
});
const score = Math.round((correct / currentWeek.quiz.questions.length) * 100);
setQuizScore(score);
setQuizSubmitted(true);
if (score >= 80) {
if (!completedQuizzes.includes(`week-${activeWeek}`)) {
setCompletedQuizzes(prev => [...prev, `week-${activeWeek}`]);
}
}
}, [currentWeek, quizAnswers, activeWeek, completedQuizzes, setCompletedQuizzes]);
// Render code block with syntax highlighting simulation
const CodeBlock = ({ code, showLineNumbers = true }) => (
{code.split('\n').map((line, i) => (
{showLineNumbers && (
{i + 1}
)}
{line}
))}
);
// Render exercise component
const ExerciseCard = ({ exercise, onComplete }) => {
const [userCode, setUserCode] = useState(exercise.starter || '');
const [selectedAnswer, setSelectedAnswer] = useState(null);
const [showHint, setShowHint] = useState(false);
const [showSolution, setShowSolution] = useState(false);
const isComplete = completedExercises.includes(exercise.id);
const handleRunCode = () => {
// Simple validation - in real app would run actual Python
if (userCode.trim().length > 10) {
onComplete(exercise.id);
dispatch('toast', { message: 'Exercise completed!', type: 'success' });
}
};
const handleMCAnswer = (idx) => {
setSelectedAnswer(idx);
if (idx === exercise.correct) {
onComplete(exercise.id);
dispatch('toast', { message: 'Correct!', type: 'success' });
} else {
dispatch('toast', { message: 'Try again!', type: 'error' });
}
};
return (
Exercise: {exercise.instruction}
{isComplete && (
)}
{exercise.type === 'code' ? (
<>
);
};
// Render quiz component
const QuizModal = () => {
if (!showQuiz || !currentWeek?.quiz) return null;
return (
{ setShowQuiz(false); setQuizSubmitted(false); setQuizAnswers({}); setQuizScore(null); }}
>
e.stopPropagation()}
>
Week {activeWeek} Quiz
{quizSubmitted ? (
= 80 ? 'text-emerald-400' : quizScore >= 60 ? 'text-amber-400' : 'text-red-400'}`}>
{quizScore}%
{quizScore >= 80 ? '🎉 Great job! Quiz passed!' : quizScore >= 60 ? 'Good effort! Review and try again.' : 'Keep studying and try again!'}
{quizScore >= 80 && (
)}
) : (
<>
{currentWeek.quiz.questions.map((q, idx) => (
Q{idx + 1}: {q.question}
{q.options.map((opt, optIdx) => (
))}
))}
>
)}
);
};
// Render project modal
const ProjectModal = () => {
if (!showProject || !currentWeek?.project) return null;
return (
setShowProject(false)}
>
e.stopPropagation()}
>
{currentWeek.project.title}
{currentWeek.project.description}
Requirements
{currentWeek.project.requirements.map((req, idx) => (
-
{req}
))}
Starter Code
Grading Rubric
{Object.entries(currentWeek.project.rubric).map(([key, value]) => (
{key.replace(/([A-Z])/g, ' $1').trim()}
{value}%
))}
);
};
return (
{/* Header */}
Python Bootcamp
{/* Sidebar */}
{/* Main Content */}
{currentLesson ? (
{/* Lesson Header */}
Week {activeWeek}
{currentLesson.id}
{currentLesson.title}
{/* Lesson Content */}
{currentLesson.content.split('\n').map((paragraph, idx) => {
if (paragraph.startsWith('**') && paragraph.endsWith('**')) {
return
{paragraph.replace(/\*\*/g, '')}
;
}
if (paragraph.startsWith('```')) {
return null;
}
if (paragraph.startsWith('- ')) {
return (
{paragraph.replace(/`([^`]+)`/g, '$1').replace(/\*\*([^*]+)\*\*/g, '$1')}
);
}
return (
$1')
.replace(/\*\*([^*]+)\*\*/g, '$1')
}}
/>
);
})}
{/* Code Example */}
{currentLesson.codeExample && (
Example
)}
{/* Exercises */}
{currentLesson.exercises && currentLesson.exercises.length > 0 && (
Practice Exercises
{currentLesson.exercises.map((exercise) => (
))}
)}
{/* Navigation */}
{activeWeek > 1 || (activeLesson && currentWeek.lessons.indexOf(currentLesson) > 0) ? (
) :
}
{(activeLesson && currentWeek.lessons.indexOf(currentLesson) < currentWeek.lessons.length - 1) || activeWeek < 6 ? (
) : null}
) : (
Select a lesson to begin
Choose a week from the sidebar to get started
)}
{/* Modals */}
);
}