0.1Welcome — you're about to write real Python
This course teaches Python from absolute zero to confident beginner. Everything runs inside this page: the code boxes below are a real Python 3.12 interpreter (compiled to WebAssembly) running locally on your machine. Nothing is sent anywhere, nothing to install.
By the end you will have built five complete programs — a guessing game, a to‑do manager, a calculator, a text adventure, and a journal that saves to a file — and you'll know how to keep learning on your own.
| Module | What you learn | What you build |
|---|---|---|
| 0 · Start here | how the course works | your first program |
| 1 · Variables & types | data, operators, strings, input | tip calculator (exercises) |
| 2 · Control flow | if/else, loops, debugging | 🎮 number guessing game |
| 3 · Data structures | lists, tuples, dicts, sets | 📝 to‑do list manager |
| 4 · Functions & modules | reusable code, math, random | 🧮 calculator |
| 5 · Objects & classes | OOP from scratch | bank accounts, pets, students |
| 6 · Files & errors | saving data, surviving crashes | crash‑proof programs |
| 7 · Projects | everything together | 🏰 text adventure + 📔 journal |
| 8 · Ecosystem | pip, numpy, JSON, APIs | fetch live data from the web |
Your very first program
Click ▶ Run. Then change the text between the quotes and run it again. That's the whole workflow of this course: read → run → change → run again.
How the code boxes work
- ▶ Run executes the code; output appears below it.
- Edit anything — the course is yours to break. Ctrl+Enter (⌘ on Mac) runs from the keyboard.
- ↺ restores the original example; your edits are auto-saved in your browser.
- Python remembers variables between runs (like a session). If things get confusing, press ↻ Reset in the top bar for a fresh Python.
- First load only: the Python engine (~10 MB) downloads from a CDN once, then your browser caches it — after that everything runs locally, even offline.
input()appears as a small pop‑up dialog. Clicking Cancel raises anEOFError— you'll learn to handle that gracefully in Module 6.- Files you create live in a sandboxed in‑browser file system. The code is identical to real Python; files just vanish when you close the tab.
- A true infinite loop (
while True:with nobreak) will freeze the tab — if that happens, just reload the page (your code is saved).
- Type the examples instead of copy‑pasting — your fingers learn too.
- Predict the output before pressing Run. Wrong predictions teach the most.
- Break things on purpose — this course deliberately shows you crashes so you learn to read them.
- Use the Console (bottom‑right
>_button) to experiment with one-liners. - Do each exercise before opening the solution. Struggle is the point.
0.2The Python console — your laboratory
Programmers keep a REPL (Read‑Eval‑Print Loop) open at all times: type one line of Python, get the answer instantly. It's the fastest way to answer "wait, what does this do?" This course has one built in.
Single-line commands
Type the line, press Enter, read the answer. Try these one at a time:
2 + 2"py" + "thon"(strings glue together)10 ** 100(a googol — Python handles huge numbers)len("hello")x = 5thenx * 3(the console remembers)
Multi-line blocks (for, if, def, while…)
Anything ending in a colon : opens a block that needs an indented body before it can run. In the console, that's a three-step dance:
- Type the header and press Enter — e.g.
for i in range(3):. The prompt switches from>>>to...: Python is saying "I'm waiting for the body." - Type the body and press Enter — e.g.
print(i). (After any line ending in:the console auto-indents 4 spaces for you, so just keep typing.) - Press Enter once more, on the empty line. That's the signal "the block is finished — run it." Output appears, and the prompt returns to
>>>.
Exactly what you'll see — the >>> and ... are the prompt; you type only what follows them:
Once that works, try a function the same way: type def greet(name): ⏎ print(f"Hi, {name}!") ⏎ empty Enter — then call it with greet("Ada").
... prompt?
- Keep adding body lines — each one echoes with
.... - An empty Enter finishes the block and runs it.
- Ctrl+C cancels the half-typed block and returns to
>>>.
x = 5 in a lesson box, run it, then type x in the console to inspect it. On a real computer, running python in a terminal gives you the exact same >>> experience.1.1print() and comments
print() writes things to the output — it's how your program talks to you. You can print several values with commas; Python inserts spaces between them.
1.2Variables — labelling data
A variable is a name that refers to a value. Create one with = (read it as "gets", not "equals"):
age = 36 puts the number 36 in a box labelled age. Later you can look in the box (print(age)) or replace its contents (age = 37).Naming rules & style
- Letters, digits, underscores — but can't start with a digit:
player_1✓,1st_player✗ - No spaces or hyphens:
total score✗,total-score✗,total_score✓ - Can't be Python keywords like
if,for,class,printis allowed but confusing. - Style:
snake_case, lowercase, descriptive —user_scorebeatsus.
🎯 Exercise 1.1 — Swap!
Swap the values of a and b so the program prints tea coffee. (There's a beautiful one-line way you'll meet in Module 3 — for now, any way that works.)
Show solution
1.3Data types — the four essentials
Every value in Python has a type, which decides what you can do with it. The four you'll use constantly:
| Type | Name | Examples | Used for |
|---|---|---|---|
int | integer | 42, -7, 1000000 | counting things |
float | floating point | 3.14, -0.5, 2.0 | measurements, money, science |
str | string | "hello", 'a', "" | text |
bool | boolean | True, False | decisions (Module 2!) |
1.4Strings — text with superpowers
Strings are sequences of characters, so you can measure them, slice them, search them, and build new ones.
f-strings — the modern way to build text
Put an f before the quotes and anything inside { } is evaluated and inserted. It's a fill‑in‑the‑blank form for your program.
:.2f demystified
Inside an f-string, :.2f means "format as a fixed-point number with 2 decimals" — perfect for money. :x (hex), :, (thousands separators: f"{1234567:,}") are handy later.🎯 Exercise 1.2 — Reversal of fortune
The word "stressed" reversed is "desserts". Prove it with slicing, then build a username like ada.lovelace from first and last.
Show solution
1.5input() and type conversion
input() asks the user a question and gives you back their answer — always as a string, even if they type digits. To do math with it, convert with int() or float().
TypeError. input() handed you the string "25", and you can't add a string to a number. Conversion is your job.
The converters, for reference:
| Converts to | Example | Result |
|---|---|---|
int() | int("42") | 42 |
float() | float("3.5") | 3.5 |
str() | str(99) | "99" |
bool() | bool("") | False (empty = falsey) |
1.6Arithmetic operators
| Operator | Name | Example | Result |
|---|---|---|---|
+ - * | the classics | 7 * 3 | 21 |
/ | true division | 7 / 2 | 3.5 (always float) |
// | floor division | 7 // 2 | 3 (chops the fraction) |
% | remainder ("mod") | 7 % 2 | 1 |
** | power | 2 ** 10 | 1024 |
% is secretly amazing
"Is this number even?" (n % 2 == 0), "last digit" (n % 10), "wrap around every 7 days" (day % 7), "every 3rd item" (i % 3 == 0). Remainders show up everywhere in real programs.1.7Comparison and logic — the ingredients of decisions
Comparisons produce bool values (True/False). Logical operators combine them. Together, they're the fuel for every if and every loop you'll write in Module 2.
= vs ==
= assigns a value to a variable. == compares two values. Using = inside an if is a SyntaxError — Python protects you here, but many languages don't!1.8Comments, indentation & code structure
Many languages mark blocks of code with braces { }. Python uses indentation — and it's not cosmetic, it's law. A block (the body of an if, a loop, a function) is indented by 4 spaces, and everything at the same level belongs together.
The rules in short
- 4 spaces per level (never mix tabs and spaces — the editor inserts spaces for you with Tab).
- Blocks are introduced by a colon
:at the end of a line. - Blank lines and comments are free — use them to group related ideas.
🎯 Exercise 1.3 — Fix the broken program
This program has two bugs (one is a missing colon, one is bad indentation). Run it, read the errors, fix it until it prints all three lines.
Show solution
1.9Checkpoint — quiz & exercises
📝 Quiz 1
🎯 Exercises
🎯 Exercise 1.4 — Introduce yourself
Create variables name, age, city, hobby, then print one sentence with an f-string: "Hi, I'm Ada from London. I'm 36 and I love stargazing."
Show solution
🎯 Exercise 1.5 — Tip calculator
Ask for the bill and tip percentage, print the tip and grand total with 2 decimals. Example: bill 40, tip 15 → Tip: $6.00 Total: $46.00
Show solution
🎯 Exercise 1.6 — Time machine
5000 seconds is 83 minutes and 20 seconds. Use // and % to prove it.
Show solution
2.1if / elif / else — decisions
Up to now your programs ran straight top-to-bottom. if lets them choose a path: run this block only when a condition is True.
if is a fork in the road. The condition is the signpost. elif adds more forks, else is the "otherwise" road. Exactly one branch runs.score = 84, the first test score >= 90 fails, the second succeeds, and the rest are skipped entirely. If you put the easiest condition first (score >= 70), everyone would get a C. Arrange tests from most specific to least.temperature and score in the box above and rerun — watch the program take different paths. That's control flow.2.2for loops and range()
Want to greet 1000 users? You don't write 1000 lines — you write one line and a loop. for repeats a block, once per item. range() generates the numbers to loop over.
2.3Looping over strings, lists — and the accumulator pattern
for isn't just for numbers: it walks through any sequence — every letter of a string, every item of a list (lists get the full treatment in Module 3).
2.4while loops — repeat until further notice
for is for a known number of rounds. while repeats as long as a condition stays True — perfect when you don't know how many rounds you'll need, like "keep asking until the password is right".
while body must contain something that moves the condition toward False.for or while?
Know the number of rounds or have a collection? → for. Waiting for an event (user input, a condition to change)? → while. When in doubt, choose for — it can't run away from you.2.5break and continue — fine control
| Keyword | Effect | Analogy |
|---|---|---|
break | exits the whole loop | leave the table |
continue | skips to the next round | "not this one, next!" |
2.6🐞 Debugging — errors are teachers, not enemies
Sooner or later (today, probably) your code will crash. Professionals read error messages for a living. Here's the skill.
Anatomy of a traceback
Read a traceback bottom-up: the last line names the error type and explains it; the lines above point to where. Then fix, rerun, repeat. That loop — crash, read, fix — is 80% of programming.
print() debugging: the oldest trick, still the best
Show one way to fix it
- Read the last line of the traceback first.
- Put a temporary
print()right before the crash — inspect the actual values. - Suspect your assumptions: the data is never what you think it is.
- Full error reference table: Appendix A at the end of this course.
2.7Checkpoint — quiz & exercises
📝 Quiz 2
🎯 Exercises
🎯 Exercise 2.1 — FizzBuzz (the classic)
Print numbers 1–30, but: multiples of 3 → Fizz, multiples of 5 → Buzz, multiples of both → FizzBuzz.
Show solution
🎯 Exercise 2.2 — Sum of odd numbers
Add up every odd number from 1 to 100 with a loop (answer: 2500).
Show solution
🎯 Exercise 2.3 — PIN with 3 attempts
Ask for a PIN until correct — but lock the account after 3 wrong tries. (The flag pattern: a boolean that remembers whether you succeeded.)
Show solution
P1🎯 Guided project — Number Guessing Game
Your first complete program: the computer picks a secret number, you guess, it says "too high" or "too low" until you win.
You'll practice: random, while, if/elif/else, input(), break, a counter.
Build it in this order
- Import
randomand generatesecret = random.randint(1, 100). - Read one guess with
int(input(...))and compare: too low / too high / correct. - Wrap step 2 in
while True:— you don't know how many guesses the player needs! - Count attempts; on a correct guess, celebrate and
break.
💡 Hints
int(input("Your guess: "))gives you a number you can compare with<and>.- Remember to
attempts += 1every round — before or after asking, just be consistent. - Typing letters instead of numbers will crash it — that's fine for now! Exercise 6.1 makes it bullet-proof.
Show solution
3.1Lists — ordered, changeable collections
Programs juggle many values: 1000 temperatures, 50 usernames, 12 playlist tracks. A list keeps them together, in order, changeable at any time.
3.2List methods — your toolbox
| Method | Does |
|---|---|
.append(x) | add x at the end |
.insert(i, x) | add x at position i |
.remove(x) | delete first x (error if missing) |
.pop() / .pop(i) | remove and return an item |
.sort() / .reverse() | reorder the list itself |
sorted(list) | return a new sorted list |
sum/max/min/len | builtins for whole lists |
3.3Tuples — immutable cousins of lists
A tuple is written with parentheses and cannot be changed after creation. That sounds like a limitation — it's actually a feature: use tuples for data that shouldn't change (coordinates, RGB colors, a date).
3.4Dictionaries — data with labels
Lists find items by position; dictionaries find them by name. A dict stores key → value pairs — the single most useful container in real Python.
d[missing_key] vs d.get(missing_key)
Square brackets raise KeyError for a missing key; .get() returns None (or your default). Use [] when the key must exist, .get() when it might not.
The classic dict pattern: counting things
3.5Sets — unique, unordered
A set is a bag of items where duplicates simply can't exist, and membership checks are instant. Math operations (union, intersection) come free.
set()
{} creates an empty dict, not a set. Write set() for an empty set.3.6Choosing the right container
| List | Tuple | Dict | Set | |
|---|---|---|---|---|
| Ordered | ✓ | ✓ | ✓ (insertion order) | ✗ |
| Changeable | ✓ | ✗ | ✓ | ✓ |
| Duplicates | ✓ | ✓ | keys: ✗ | ✗ |
| Access by | position | position | key | membership |
| Use when… | a collection that grows/shrinks | fixed group of values | labelled records, lookups | uniqueness / overlaps |
3.7Checkpoint — quiz & exercises
📝 Quiz 3
🎯 Exercises
🎯 Exercise 3.1 — Dinner party
Start from the guest list: append two guests, remove one by name, check whether "Ada" is still coming, then print numbered invitations.
Show solution
🎯 Exercise 3.2 — Mutual friends
Given two friend sets, print the mutual friends and the combined circle.
Show solution
🎯 Exercise 3.3 — Gradebook
Each student maps to a list of scores. Print each student's average (1 decimal) — or a friendly note for a student with no grades.
Show solution
P2🎯 Guided project — To‑Do List Manager
A real, interactive app you operate with commands: add, list, done, quit. You'll run it for yourself right here in the browser.
You'll practice: lists, list methods, while + input, if/elif, enumerate, safe index handling.
Build it in this order
- Start with
tasks = []and awhile Trueloop reading a command. - Handle
quitfirst (withbreak) so you can always escape! - Add
add(ask for the task,append), thenlist(number withenumerate). done: ask for a number, check it's in range (1 tolen(tasks)), thenpop(number - 1)— humans count from 1, lists from 0.
💡 Hints
- Always build the
quitbranch before anything else — otherwise you can't escape your own loop. int(input("Task number: "))gives the human number; the list index isn - 1.- Check
if 1 <= n <= len(tasks):before popping — be kind to your user.
Show solution
("urgent", "email boss")), a clear command, or — after Module 6 — save the list to a file so it survives a rerun.4.1Defining functions
You've been calling functions all course (print, len, input…). Now write your own: a named, reusable block of code.
Vocabulary: parameters are the placeholders in the definition; arguments are the actual values you send. The definition does nothing until you call it.
4.2return — getting answers back
print() merely shows a value; return hands it back to the caller so it can be stored, combined, or passed onward. Printed values vanish; returned values live on.
print ≠ return
A function with no return gives back None. If you ever see None where you expected a number, you probably printed inside a function instead of returning. This is the #1 beginner bug.4.3Default and keyword arguments
Defaults make functions friendly: callers only specify what differs from the norm. You'll meet this constantly in real libraries — e.g. sorted(items, reverse=True).
4.4Scope — where variables live
Variables created inside a function are local: they exist only there. Variables at the top level are global and readable everywhere. This is how functions stay self-contained and predictable.
global where you can: pass values in as parameters and out via return. Functions that only touch their own inputs and outputs are easier to reason about, test, and reuse.4.5Modules — standing on shoulders
A module is a file of ready-made functions. import gives you the whole Python standard library: hundreds of battle-tested tools.
4.6Writing your own module
Any Python file can be imported. Create helpers.py on the (virtual) file system — then import it in a different code box. On a real computer, exactly the same story, just a real folder.
helpers.py, game.py, stats.py — imported by a main script. Modules keep thousand-line projects sane.4.7Checkpoint — quiz & exercises
📝 Quiz 4
🎯 Exercises
🎯 Exercise 4.1 — Palindrome detector
Write is_palindrome(word) that returns True for "Level" (case-insensitive). One line is possible with slicing!
Show solution
🎯 Exercise 4.2 — Dice roller
Write roll_dice(sides=6, count=1) that returns the total of count dice with sides faces.
Show solution
🎯 Exercise 4.3 — Temperature table
Write c_to_f(c), then print 0, 37, and 100 °C converted, with a loop.
Show solution
P3🎯 Guided project — Calculator
A four-function calculator with a menu loop, built the professional way: tiny functions, a thin main() on top.
You'll practice: functions with returns, defaults, while + if/elif, float(input()), graceful handling of dividing by zero.
💡 Hints
- Handle
q(quit) first, and reject unknown operations with a message +continue. - Keep the math in functions and the conversation in
main()— that separation is the whole lesson.
Show solution
** (power) and %, keep a history list and add a history command, or support full expressions like 3 + 4 * 2 (harder — look up eval and its dangers!).5.1Classes and objects — the big idea
Object-Oriented Programming bundles data and the behaviour that belongs to it into one thing: an object. Instead of a loose name variable here and a bark function there, a Dog owns both.
5.2Defining a class — __init__ and self
__init__(double underscore = "dunder") is the constructor: it receives the arguments fromDog("Rex", 3)and sets up the new object.selfis the object being worked on.self.name = namemeans "store this argument on this dog". Every method's first parameter isself— Python passes it automatically; you never supply it yourself.
5.3Methods — behaviour, and pretty printing
5.4Inheritance — building on what exists
class Cat(Animal) means Cat is a kind of Animal: it inherits Animal's attributes and methods, can override them, and can add its own. The parent's abilities come free.
5.5Checkpoint — quiz & exercises
📝 Quiz 5
🎯 Exercises
🎯 Exercise 5.1 — Bank account
Build BankAccount with deposit(amount), withdraw(amount) (refuse overdrafts with a message), and friendly printing via __str__.
Show solution
🎯 Exercise 5.2 — Rectangle
Rectangle(w, h) with methods area(), perimeter(), and a __str__ like Rectangle(4×5).
Show solution
🎯 Exercise 5.3 — Student inherits Person
Person has a name and an introduce(). Student adds a major, and its introduce() calls the parent's version first (via super()), then adds "... and I study X".
Show solution
6.1Reading and writing files
Variables vanish when a program ends. Files make data persist — settings, high scores, journals, anything.
| Mode | Meaning | If file exists / doesn't |
|---|---|---|
"r" | read (default) | reads / raises FileNotFoundError |
"w" | write | erases it / creates it |
"a" | append | adds to the end / creates it |
6.2The with statement — the modern way
Forgetting f.close() is a classic bug. with closes the file automatically — even if an error explodes mid-write. This is the recommended pattern; professionals write it exclusively.
with is like borrowing a library book with an auto-return chip: no matter how your day goes, the book goes back on the shelf.6.3try / except — graceful survival
Errors are normal: users type "abc" for ages, files don't exist, connections drop. try/except lets your program catch an error and respond calmly instead of crashing.
try is a tightrope walk; except ValueError is the safety net — you hope not to need it, but it catches exactly one kind of fall (and lets you get up and continue the show).The pattern you'll use forever: bullet-proof input
6.4Raising errors, and the full try shape
Your own functions can raise errors too — the polite way to say "these inputs make no sense", instead of returning a nonsense value.
- Catch specific exceptions (
except ValueError:), not a bareexcept:that swallows everything — including bugs you'd want to see. - Handle the error where you can actually do something about it; let it travel upward otherwise.
- Never fail silently — a message beats a mystery.
6.5Checkpoint — quiz & exercises
📝 Quiz 6
🎯 Exercises
🎯 Exercise 6.1 — Bullet-proof the guessing game
Return to Project 1 and make it survive anything: letters instead of numbers, cancelled dialogs. Write ask_int(prompt) that re-asks until it gets a whole number (and exits politely on cancel).
Show solution
🎯 Exercise 6.2 — Settings file
Write settings.txt as key=value lines, then read it back into a dict. (Notice: everything comes back as a string — converting is your job. Module 8 shows the pro tool: json.)
Show solution
🎯 Exercise 6.3 — safe_divide
Write safe_divide(a, b) that returns the result, or None (with a message) if b is zero.
Show solution
P4🎯 Project — Escape the Manor (text adventure)
A mini explorable world: rooms described by a dictionary, a player represented by a class, and a game loop reading commands. This is the biggest program yet — take it step by step and run it often.
You'll practice: dicts of dicts, a class with methods, the game-loop pattern, string methods, while + if/elif.
Design first — then code
- Each room: a description, exits (direction → room name), and optional items.
- The Player class: a name, HP, and an inventory; methods
takeandhurt. - The loop: describe the room, read a command (
go north,take,look,quit), update the world, repeat.
💡 Hints
cmd.startswith("go ")detects a move; the direction iscmd[3:].strip().- Check
direction in room["exits"]before changingcurrent. - Removing an item from a room:
room["items"].pop(0)— but only ifroom.get("items")isn't empty!
Show solution
Monster class in the cellar that calls player.hurt(20) each visit; a win condition (collect 3 coins); more rooms. Add one thing at a time and rerun.P5🎯 Capstone — Personal Journal with persistence
The final boss: a real application combining everything — functions, lists of dicts, the datetime module, file saving, and exception handling. Entries survive between runs (while the page stays open — that's your file system working!).
You'll practice: the whole course. Seriously: functions, dicts, loops, files, exceptions, modules, string methods.
Design
- An entry is a dict:
{"date": "...", "text": "..."}; the journal is a list of them. - Save format: one line per entry,
date|text— plain text you can read with any editor. load_entries()must survive a missing file (first run) and malformed lines.
💡 Hints
datetime.now().strftime("%Y-%m-%d %H:%M")→ e.g."2025-06-14 21:07".- When loading, guard against junk lines: only accept
len(parts) == 2. - Write
main()last — test each function alone in the Console first!
Show solution
date|text format with the json module — 3 lines instead of a parser (that contrast is the lesson). Then copy the whole program to a real computer and it saves permanently.8.1pip and the Python ecosystem
Python's superpower isn't the language — it's PyPI, a repository of 500,000+ free packages. pip installs them in one command.
The browser can't run raw pip, but Pyodide ships micropip — a tiny pip that installs real packages from real PyPI. One wrinkle: micropip itself is a package that isn't loaded into the session until it's requested, so the course runner auto-loads it for you the moment your code says import micropip (behind the scenes that's await pyodide.loadPackage("micropip") — exactly what Python's error message would suggest). Watch it work (internet needed for this one):
flask, fastapi), data science (pandas, numpy), games (pygame), automation (beautifulsoup4)… almost anything you'll ever want to build has a package that gets you 80% there. Programmers who can find and use libraries are 10× faster.8.2numpy — a taste of data science
numpy is the foundation of all scientific Python: fast arrays that do math on every element at once. This box will auto-download numpy (~9 MB) on your first Run — the same package, real PyPI wheel.
8.3JSON and APIs — talking to the web
An API is how programs fetch live data: weather, prices, GitHub repos. The universal data format is JSON — text that looks almost exactly like Python dicts and lists.
Step 1 — parse JSON
Step 2 — the real-world code (on your own computer)
Step 3 — fetch live data, right here
Browsers don't allow raw network sockets, so instead of requests we use pyfetch — same idea, browser-native. This really hits the internet (needs a connection):
🎯 Exercise 8.1 — Read a weather forecast
Parse the JSON below and print a forecast: Forecast for REYKJAVIK, Iceland, then one line per day like Mon: -2 to 4°C, snow.
Show solution
8.4Where to go next — becoming an independent Pythonista
You now have the complete foundation. The rest of your journey is projects + documentation. Here's the toolkit.
1. Install real Python
- Download from python.org/downloads (Windows: tick "Add Python to PATH" during install). macOS/Linux usually have it — check with
python3 --version. - Run a saved file from any terminal:
python3 journal.py. Yes — the journal project runs unchanged.
2. Pick a real editor
- VS Code + the Python extension (free, industry standard)
- Thonny — simple, made for beginners, includes a debugger
- PyCharm Community — full-featured, heavier
3. Read documentation (a meta-superpower)
The fastest help is already inside Python:
Beyond that: the official tutorial and reference live at docs.python.org/3, and the practical skill is a good search: "python 3 how to sort list of dicts" — including "python 3" and naming the exact operation. Stack Overflow, the official docs, and Automate the Boring Stuff with Python (free online book) will be your constant companions.
4. What to learn next (in rough order)
- List comprehensions — the idiomatic one-line transform:
[n*n for n in nums if n % 2] - More standard library —
os(files),csv,re(text patterns),sqlite3(real databases),datetime(you've started!) - Testing with
pytest, then a domain: web apps (Flask), games (pygame), data (pandas), automation (requests + BeautifulSoup)
A🐞 Appendix A — the error field guide
Every error below, you can (and should) meet in person. Uncomment ONE line at a time, run, read the last line of the traceback, then check the table.
| Error | Means | Typical fix |
|---|---|---|
SyntaxError | Python can't even parse the line | missing :, unclosed quote or bracket |
IndentationError | inconsistent indentation | align the block (4 spaces per level) |
NameError | name used before it exists | typo? define before use? scope? (4.4) |
TypeError | wrong type for the operation | convert: int("5"), str(5) |
ValueError | right type, impossible value | validate input (6.3) |
IndexError | list position doesn't exist | check len(); remember counting from 0 |
KeyError | dict key doesn't exist | use .get(key, default) |
AttributeError | no such method/attribute | typo (.upcase → .upper)? wrong type? |
ZeroDivisionError | divided by zero | guard with if b != 0 |
ModuleNotFoundError | no such module | spelling; on a real machine: pip install it |
FileNotFoundError | no such file | right name? create it first? try/except |
EOFError | input ran out (dialog cancelled) | catch it (6.3) or provide a default |
BAppendix B — one-screen cheat sheet
CAppendix C — the course checklist
The criteria a great beginner course must meet — and where this one delivers:
| Requirement | Where you got it |
|---|---|
| Starts with the very basics | Module 0–1: print, variables, types, operators — nothing assumed |
| Logical, building-block progression | Each module uses only what came before (files→exceptions→projects→APIs) |
| Plenty of exercises | 19 exercises with hidden solutions + 30 quiz questions + "try it" boxes in every lesson |
| Projects | 5 guided projects: guessing game, to‑do list, calculator, text adventure, journal |
| Explains why, not just how | 💡 "Why this matters" callouts throughout |
| Teaches debugging | Lesson 2.6, deliberate 🐞 crash boxes, Appendix A error zoo |
| No overwhelming advanced topics | Comprehensions, decorators, metaclasses deferred to "what's next" |
| Tools to keep learning | Lesson 8.4: docs, help(), search technique, editors, pip workflow |
| REPL habit | Built-in console sharing state with every lesson box |
Congratulations. You started with print("Hello, World!") and ended by fetching live data from an API. Go build something. 🐍