Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import io | |
| import contextlib | |
| import traceback | |
| # ---------- Python runner ---------- | |
| def run_python(code: str) -> str: | |
| """ | |
| Execute user-provided Python code and capture stdout / errors. | |
| NOTE: This is for teaching demos; do NOT use this pattern in | |
| a multi-user production environment without sandboxing. | |
| """ | |
| stdout_buffer = io.StringIO() | |
| try: | |
| # Provide a very simple, mostly empty environment | |
| local_env = {} | |
| global_env = {"__builtins__": __builtins__} | |
| with contextlib.redirect_stdout(stdout_buffer): | |
| exec(code, global_env, local_env) | |
| output = stdout_buffer.getvalue() | |
| if not output.strip(): | |
| output = "[No output produced]" | |
| return output | |
| except Exception: | |
| error_text = stdout_buffer.getvalue() | |
| error_text += "\n" + traceback.format_exc() | |
| return error_text | |
| # ---------- Course content ---------- | |
| lessons = [ | |
| { | |
| "title": "Lesson 1: Setup & Simple Apps", | |
| "description": """ | |
| ### Lesson 1: Setting Up Python and Developing a Simple Application | |
| **Topics** | |
| - Topic A: Set Up the Development Environment | |
| - Topic B: Write Python Statements | |
| - Topic C: Create a Python Application | |
| - Topic D: Prevent Errors | |
| **You’ll practice:** | |
| - Using `print()` and variables | |
| - Reading user input with `input()` | |
| - Building a tiny interactive console app | |
| **Mini-project idea:** | |
| Create a **“Profile Card”** script that asks for your name, age, and hobby, then prints a nicely formatted profile. | |
| """, | |
| "starter_code": '''# Lesson 1: Simple Hello & Input | |
| print("👋 Welcome to Lesson 1: Setup & Simple Apps") | |
| name = input("What is your name? ") | |
| age = input("How old are you? ") | |
| print(f"Hello, {name}! You are {age} years old.") | |
| # Try: | |
| # 1. Ask for a favorite color and food and add them to the message. | |
| # 2. Create a small "profile card" printed with multiple lines, e.g.: | |
| # Name: ... | |
| # Age: ... | |
| # Favorite color: ... | |
| ''' | |
| }, | |
| { | |
| "title": "Lesson 2: Simple Data Types", | |
| "description": """ | |
| ### Lesson 2: Processing Simple Data Types | |
| **Topics** | |
| - Topic A: Process Strings and Integers | |
| - Topic B: Process Decimals, Floats, and Mixed Number Types | |
| **You’ll practice:** | |
| - Combining strings | |
| - Doing arithmetic with integers and floats | |
| - Using `round()` and basic numeric conversions | |
| **Mini-project idea:** | |
| Create a **BMI & Health Stats** script that asks for height, weight, and age, calculates BMI, and prints a short health summary. | |
| """, | |
| "starter_code": '''# Lesson 2: Strings, Integers, Floats | |
| print("✨ Lesson 2: Simple Data Types") | |
| first_name = "Alice" | |
| last_name = "Smith" | |
| age = 30 | |
| height_m = 1.70 | |
| weight_kg = 65.0 | |
| full_name = first_name + " " + last_name | |
| bmi = weight_kg / (height_m ** 2) | |
| print("Full name:", full_name) | |
| print("Age next year:", age + 1) | |
| print("BMI (unrounded):", bmi) | |
| print("BMI (rounded to 2 decimals):", round(bmi, 2)) | |
| # Try: | |
| # 1. Ask the user for their name and birth year; compute their age. | |
| # 2. Convert a temperature from Fahrenheit to Celsius: | |
| # celsius = (f - 32) * 5/9 | |
| # 3. Ask for two prices and print the subtotal, tax, and total. | |
| ''' | |
| }, | |
| { | |
| "title": "Lesson 3: Data Structures", | |
| "description": """ | |
| ### Lesson 3: Processing Data Structures | |
| **Topics** | |
| - Topic A: Process Ordered Data Structures (lists, tuples) | |
| - Topic B: Process Unordered Data Structures (sets, dictionaries) | |
| **You’ll practice:** | |
| - Storing groups of values in lists and tuples | |
| - Using sets to deduplicate data | |
| - Using dictionaries to store labeled data | |
| **Mini-project idea:** | |
| Build a tiny **“Student Gradebook”** using a dictionary of names and scores. Compute averages and print a report. | |
| """, | |
| "starter_code": '''# Lesson 3: Lists, Tuples, Sets, Dictionaries | |
| print("📚 Lesson 3: Data Structures") | |
| # Ordered: lists and tuples | |
| fruits = ["apple", "banana", "cherry"] | |
| scores = (88, 92, 79) | |
| print("Fruits:", fruits) | |
| print("First fruit:", fruits[0]) | |
| print("Scores:", scores) | |
| print("Average score:", sum(scores) / len(scores)) | |
| # Unordered: sets and dictionaries | |
| numbers_with_duplicates = [1, 2, 2, 3, 3, 3] | |
| unique_numbers = set(numbers_with_duplicates) | |
| print("Original numbers:", numbers_with_duplicates) | |
| print("Unique numbers:", unique_numbers) | |
| student = { | |
| "name": "Alice", | |
| "age": 20, | |
| "grade": "A" | |
| } | |
| print("Student name:", student["name"]) | |
| print("\nAll student key/value pairs:") | |
| for key, value in student.items(): | |
| print(f"{key}: {value}") | |
| # Try: | |
| # 1. Add a new key "major" to the student dictionary, then print it. | |
| # 2. Create a list of 5 movies and print the first and last. | |
| # 3. Create a "gradebook" dict: student_name -> list of scores, | |
| # then print each student's average. | |
| ''' | |
| }, | |
| { | |
| "title": "Lesson 4: Conditionals & Loops", | |
| "description": """ | |
| ### Lesson 4: Writing Conditional Statements and Loops | |
| **Topics** | |
| - Topic A: Write a Conditional Statement (`if`, `elif`, `else`) | |
| - Topic B: Write a Loop (`for`, `while`) | |
| **You’ll practice:** | |
| - Making decisions in code | |
| - Repeating actions until some condition is met | |
| - Combining `if` with loops for basic logic | |
| **Mini-project idea:** | |
| Create a **“Number Guessing Game”** that picks a random number and gives the user several attempts with hints (too high / too low). | |
| """, | |
| "starter_code": '''# Lesson 4: Conditionals & Loops | |
| print("🔁 Lesson 4: Conditionals and Loops") | |
| # Conditional example | |
| score = int(input("Enter a score between 0 and 100: ")) | |
| if score >= 90: | |
| grade = "A" | |
| elif score >= 80: | |
| grade = "B" | |
| elif score >= 70: | |
| grade = "C" | |
| elif score >= 60: | |
| grade = "D" | |
| else: | |
| grade = "F" | |
| print(f"Your grade is: {grade}") | |
| # Loop example: print even numbers 2-20 | |
| print("\nEven numbers from 2 to 20:") | |
| for n in range(2, 21, 2): | |
| print(n, end=" ") | |
| print() # newline | |
| # Try: | |
| # 1. Use a while loop to ask for a password until it is 'secret'. | |
| # 2. Write an if/elif/else to classify a number as positive, negative, or zero. | |
| # 3. (Challenge) Make a number guessing game (1-20) that tells the user if | |
| # their guess is too high or too low. | |
| ''' | |
| }, | |
| { | |
| "title": "Lesson 5: Functions, Classes, Modules", | |
| "description": """ | |
| ### Lesson 5: Structuring Code for Reuse | |
| **Topics** | |
| - Topic A: Define and Call a Function | |
| - Topic B: Define and Instantiate a Class | |
| - Topic C: Import and Use a Module | |
| **You’ll practice:** | |
| - Creating functions with parameters and return values | |
| - Creating simple classes with attributes and methods | |
| - Using built-in modules like `math`, `random` | |
| **Mini-project idea:** | |
| Create a **“Banking Simulator”** with a `BankAccount` class that supports deposit, withdraw, and showing balance. | |
| """, | |
| "starter_code": '''# Lesson 5: Functions, Classes, and Modules | |
| print("🧩 Lesson 5: Reusable Code") | |
| # --- Functions --- | |
| def add(a, b): | |
| """Return the sum of a and b.""" | |
| return a + b | |
| result = add(10, 5) | |
| print("10 + 5 =", result) | |
| # --- Classes --- | |
| class Car: | |
| def __init__(self, make, model, year): | |
| self.make = make | |
| self.model = model | |
| self.year = year | |
| def description(self): | |
| return f"{self.year} {self.make} {self.model}" | |
| my_car = Car("Toyota", "Corolla", 2022) | |
| print("My car:", my_car.description()) | |
| # --- Modules --- | |
| import math | |
| import random | |
| print("Square root of 16:", math.sqrt(16)) | |
| print("Random integer from 1 to 6:", random.randint(1, 6)) | |
| # Try: | |
| # 1. Write a function is_even(n) that returns True if n is even. | |
| # 2. Create a BankAccount class with deposit and withdraw methods, | |
| # and test it with a few transactions. | |
| # 3. Use random.randint to simulate rolling two dice and print their sum. | |
| ''' | |
| }, | |
| { | |
| "title": "Lesson 6: Files & Directories", | |
| "description": """ | |
| ### Lesson 6: Writing Code to Process Files and Directories | |
| **Topics** | |
| - Topic A: Write to a Text File | |
| - Topic B: Read from a Text File | |
| - Topic C: Get the Contents of a Directory | |
| - Topic D: Manage Files and Directories | |
| ⚠️ In a hosted environment, file access is temporary and sandboxed, | |
| but the patterns you learn here transfer directly to your local machine. | |
| **You’ll practice:** | |
| - Creating directories and files | |
| - Reading and writing text data | |
| - Listing directory contents | |
| **Mini-project idea:** | |
| Create a simple **“Log Writer”** that appends timestamped messages to a log file, then reads and prints the last N lines. | |
| """, | |
| "starter_code": '''# Lesson 6: Files & Directories | |
| print("📂 Lesson 6: Files and Directories") | |
| from pathlib import Path | |
| # Create a folder | |
| folder = Path("demo_folder") | |
| folder.mkdir(exist_ok=True) | |
| # Write to a file | |
| file_path = folder / "example.txt" | |
| file_path.write_text("Hello from Lesson 6!\\nThis is a test file.") | |
| print("Wrote file:", file_path) | |
| # Read from a file | |
| content = file_path.read_text() | |
| print("\\nFile contents:") | |
| print(content) | |
| # List directory contents | |
| print("\\nContents of demo_folder:") | |
| for item in folder.iterdir(): | |
| print(" -", item.name) | |
| # Try: | |
| # 1. Add another file with different text. | |
| # 2. Read both files and print their contents. | |
| # 3. Add a timestamp to each line you write into a 'log.txt' file. | |
| ''' | |
| }, | |
| { | |
| "title": "Lesson 7: Exceptions", | |
| "description": """ | |
| ### Lesson 7: Dealing with Exceptions | |
| **Topics** | |
| - Topic A: Handle Exceptions | |
| - Topic B: Raise Exceptions | |
| **You’ll practice:** | |
| - Wrapping risky code in `try/except` | |
| - Catching specific errors like `ValueError` and `ZeroDivisionError` | |
| - Raising your own exceptions when inputs are invalid | |
| **Mini-project idea:** | |
| Create a **“Safe Calculator”** that: | |
| - Accepts user input for operations | |
| - Handles invalid inputs gracefully | |
| - Prevents divide-by-zero errors | |
| """, | |
| "starter_code": '''# Lesson 7: Exceptions | |
| print("⚠️ Lesson 7: Exceptions") | |
| def safe_divide(a, b): | |
| try: | |
| return a / b | |
| except ZeroDivisionError: | |
| print("Error: cannot divide by zero!") | |
| return None | |
| x = float(input("Enter numerator: ")) | |
| y = float(input("Enter denominator: ")) | |
| result = safe_divide(x, y) | |
| print("Result:", result) | |
| # Raising your own exception | |
| def set_age(age): | |
| if age < 0 or age > 120: | |
| raise ValueError("Age must be between 0 and 120.") | |
| return age | |
| try: | |
| age_value = int(input("Enter an age (0-120): ")) | |
| print("Valid age:", set_age(age_value)) | |
| except ValueError as e: | |
| print("Invalid age:", e) | |
| # Try: | |
| # 1. Wrap more user input in try/except to catch ValueError. | |
| # 2. Write a function that raises ValueError if a discount is | |
| # not between 0 and 100. | |
| # 3. Build a small "safe calculator" that handles bad input gracefully. | |
| ''' | |
| }, | |
| ] | |
| appendix_markdown = """ | |
| ## 📎 References & Appendices | |
| This tab consolidates extra reference material for the course. | |
| --- | |
| ### Appendix A: Major Differences Between Python 2 and 3 | |
| Modern development uses **Python 3**, but here are some historical differences: | |
| - `print` | |
| - Python 2: `print "Hello"` | |
| - Python 3: `print("Hello")` | |
| - Integer division | |
| - Python 2: `5/2` → `2` (integer when both are ints) | |
| - Python 3: `5/2` → `2.5`, use `5//2` for integer division. | |
| - Text and bytes | |
| - Python 2: `str` (bytes) vs `unicode`. | |
| - Python 3: `str` is Unicode by default; `bytes` is a separate type. | |
| - `input()` | |
| - Python 2: `input()` evaluates, `raw_input()` returns string. | |
| - Python 3: `input()` always returns a string. | |
| - Standard library layout | |
| - Some modules reorganized (e.g., `urllib` family). | |
| If you’re starting now, you almost never need Python 2, but you might see old code in the wild. | |
| --- | |
| ### Appendix B: Mini Python Style Guide (PEP 8 Highlights) | |
| Follow these conventions to keep your code clean and readable: | |
| **Indentation** | |
| - Use **4 spaces** per indentation level. | |
| - Avoid mixing tabs and spaces. | |
| **Naming** | |
| - Variables / functions: `snake_case` (e.g., `total_price`, `calculate_bmi`). | |
| - Classes: `CapWords` (e.g., `BankAccount`). | |
| - Constants: `UPPER_CASE` (e.g., `PI = 3.14159`). | |
| **Spacing** | |
| - Around operators: `x = a + b`, not `x=a+b`. | |
| - After commas: `func(a, b, c)`. | |
| **Imports** | |
| - At the **top** of the file. | |
| - One import per line is preferred. | |
| **Comments & Docstrings** | |
| - Use `#` for short explanations above a line or block. | |
| - Use triple-quoted strings for docstrings, for example: | |
| `\"\"\"This is a multi-line docstring.\"\"\"`. | |
| **Structure** | |
| - Break large scripts into functions and classes. | |
| - For larger programs, use: | |
| ```python | |
| if __name__ == "__main__": | |
| main() | |
| with gr.Tabs(): | |
| # Main lesson tabs | |
| for lesson in lessons: | |
| with gr.Tab(lesson["title"]): | |
| gr.Markdown(lesson["description"]) | |
| code = gr.Code( | |
| value=lesson["starter_code"], | |
| language="python", | |
| label="✏️ Edit and run your Python code here", | |
| interactive=True, | |
| ) | |
| with gr.Row(): | |
| run_button = gr.Button("▶️ Run code", variant="primary") | |
| clear_button = gr.Button("🧹 Clear output") | |
| output = gr.Textbox( | |
| label="📤 Output (stdout and errors)", | |
| lines=14, | |
| show_copy_button=True, | |
| ) | |
| # Bind buttons | |
| run_button.click(run_python, inputs=code, outputs=output) | |
| clear_button.click(lambda: "", outputs=output) | |
| # References / Appendices tab | |
| with gr.Tab("References & Appendices"): | |
| gr.Markdown(appendix_markdown) | |
| gr.Markdown( | |
| """ | |