🐍 Waking up Python…

Downloading the Python engine (~10 MB, first load only)…
keep reading the course anyway (code boxes stay read-only)
🐍 David's Python Foundationsinteractive beginner course · runs 100% in your browser

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.

ModuleWhat you learnWhat you build
0 · Start herehow the course worksyour first program
1 · Variables & typesdata, operators, strings, inputtip calculator (exercises)
2 · Control flowif/else, loops, debugging🎮 number guessing game
3 · Data structureslists, tuples, dicts, sets📝 to‑do list manager
4 · Functions & modulesreusable code, math, random🧮 calculator
5 · Objects & classesOOP from scratchbank accounts, pets, students
6 · Files & errorssaving data, surviving crashescrash‑proof programs
7 · Projectseverything together🏰 text adventure + 📔 journal
8 · Ecosystempip, numpy, JSON, APIsfetch 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.
⚠️ How the browser version differs from desktop 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 an EOFError — 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 no break) will freeze the tab — if that happens, just reload the page (your code is saved).
✅ How to actually learn (not just read)
  • 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 = 5 then x * 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:

  1. 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."
  2. 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.)
  3. 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").

✅ Stuck at the ... 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 >>>.
This is exactly how a real terminal Python behaves too — the prompt switch and the blank-line ending are standard CPython shell conventions, so what you learn here transfers directly.
✅ One superpower worth knowing The console shares variables with the lesson code boxes. Set 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.

💡 Why comments matter Code tells the computer what to do; comments tell people why. Six months from now, "why did I divide by 60 here?" is the question comments answer. Good code + good comments = readable code.

1.2Variables — labelling data

A variable is a name that refers to a value. Create one with = (read it as "gets", not "equals"):

🍪 Analogy A variable is a labelled box: 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, print is allowed but confusing.
  • Style: snake_case, lowercase, descriptive — user_score beats us.

🎯 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:

TypeNameExamplesUsed for
intinteger42, -7, 1000000counting things
floatfloating point3.14, -0.5, 2.0measurements, money, science
strstring"hello", 'a', ""text
boolbooleanTrue, Falsedecisions (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().

🐞 Break it on purpose — your first traceback Run this, type a number, and read the last line of the red error: 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 toExampleResult
int()int("42")42
float()float("3.5")3.5
str()str(99)"99"
bool()bool("")False (empty = falsey)

1.6Arithmetic operators

OperatorNameExampleResult
+ - *the classics7 * 321
/true division7 / 23.5 (always float)
//floor division7 // 23 (chops the fraction)
%remainder ("mod")7 % 21
**power2 ** 101024
💡 Why % 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.

⚠️ The classic bug: = 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.

🛤️ Analogy An 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.
💡 Why order matters With 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.
✅ Change the values Edit 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.

💡 When do I use a loop? Any time you hear "for each…" or "repeat … times" or "do this to every item" — that's a loop. Humans get bored; loops don't.

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".

⚠️ Infinite loops (read this!) If the condition can never become False, the loop runs forever — and in the browser that means a frozen tab (just reload if it happens; your code is saved). Every 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

KeywordEffectAnalogy
breakexits the whole loopleave the table
continueskips 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
✅ The debugger's creed
  • 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

  1. Import random and generate secret = random.randint(1, 100).
  2. Read one guess with int(input(...)) and compare: too low / too high / correct.
  3. Wrap step 2 in while True: — you don't know how many guesses the player needs!
  4. 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 += 1 every 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
🚀 Extensions (optional) Limit to 7 attempts ("You ran out of guesses — it was 73!"), let the player choose the difficulty range, or ask "Play again? (y/n)" to wrap everything in one more loop.

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.

💡 Why start counting at 0? An index is really an offset: how far from the start. The first item is 0 steps away. Every serious language does this — you'll be fluent within a week.

3.2List methods — your toolbox

MethodDoes
.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/lenbuiltins 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.

📖 Analogy A dictionary is an actual dictionary: look up a word (the key), get its definition (the value) — instantly, no matter how many words there are.
🐞 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.

⚠️ Empty set is set() {} creates an empty dict, not a set. Write set() for an empty set.

3.6Choosing the right container

ListTupleDictSet
Ordered✓ (insertion order)
Changeable
Duplicateskeys: ✗
Access bypositionpositionkeymembership
Use when…a collection that grows/shrinksfixed group of valueslabelled records, lookupsuniqueness / overlaps
💡 Real programs mix them freely A contact book: a list of dicts. A game board: a dict mapping coordinates to sets of items. Choosing containers well is half of good design — you'll practice it in the projects.

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

  1. Start with tasks = [] and a while True loop reading a command.
  2. Handle quit first (with break) so you can always escape!
  3. Add add (ask for the task, append), then list (number with enumerate).
  4. done: ask for a number, check it's in range (1 to len(tasks)), then pop(number - 1) — humans count from 1, lists from 0.
💡 Hints
  • Always build the quit branch before anything else — otherwise you can't escape your own loop.
  • int(input("Task number: ")) gives the human number; the list index is n - 1.
  • Check if 1 <= n <= len(tasks): before popping — be kind to your user.
Show solution
🚀 Extensions Priorities (store tuples like ("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.

💡 Why functions Reuse (write once, call forever), organization (small named pieces beat one giant script), and testing (check each piece alone). "Don't Repeat Yourself" — DRY — is the programmer's prime directive.

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.

⚠️ printreturn 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.

🏢 Analogy Globals are the company-wide signage on the walls; locals are the sticky notes inside one office. Anyone can read the wall signs, but you can't rearrange the building from inside a single office.
✅ Style advice Avoid 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.

✅ Run it twice! The random results change on every run — that's the point. Games, simulations, and sampling all start here. Deterministic code + randomness = 🎲.

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.

💡 This is how real projects are organized One file per concern — 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
🚀 Extensions Add ** (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.

🍪 Analogy A class is a cookie cutter — the shape, the blueprint. Each object (instance) is a cookie stamped from it: same shape, but each has its own sprinkles (attribute values). One cutter, many cookies.
💡 Why OOP exists When programs model things — users, products, monsters, bank accounts — OOP keeps each thing's data and rules together. It's how almost every large codebase (and every GUI, game, and API you'll ever touch) is organized. You only need the basics — that's exactly what this module teaches.

5.2Defining a class — __init__ and self

  • __init__ (double underscore = "dunder") is the constructor: it receives the arguments from Dog("Rex", 3) and sets up the new object.
  • self is the object being worked on. self.name = name means "store this argument on this dog". Every method's first parameter is self — 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.

💡 Why inheritance matters Write the common part once (Animal), specialize per kind (Cat, Duck). The loop at the bottom shows the payoff: code that works on the parent works on every child — one loop, many behaviours.

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.

⚠️ Browser note (last one, promise) Python here writes to a virtual file system inside the page — the code is identical to desktop Python; the files just disappear when you close the tab. Everything you learn transfers 1:1.
ModeMeaningIf file exists / doesn't
"r"read (default)reads / raises FileNotFoundError
"w"writeerases it / creates it
"a"appendadds 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.

🧹 Analogy 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.

🛡️ Analogy 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.

✅ Error-handling etiquette
  • Catch specific exceptions (except ValueError:), not a bare except: 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 take and hurt.
  • 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 is cmd[3:].strip().
  • Check direction in room["exits"] before changing current.
  • Removing an item from a room: room["items"].pop(0) — but only if room.get("items") isn't empty!
Show solution
🚀 Extensions A locked door that needs the torch; a 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
🚀 The perfect final extension After Module 8, replace the 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):

💡 Why this matters Web apps (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.

💡 Why numpy exists A Python loop over a million numbers takes seconds; numpy's compiled array math takes milliseconds. Same reason pandas, image processing, and machine learning all build on it.

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.

🍽️ Analogy You (your code) don't walk into the kitchen (the server); you tell the waiter (the API) what you want, and dishes arrive in standard takeout boxes (JSON) any kitchen can pack.

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 libraryos (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)
✅ The one habit that matters Build a small thing every week. A tip calculator became a journal became…? Ideas: a quiz game, a pomodoro timer, a script that renames your downloads, a birthday reminder that saves to a file. Every finished project teaches more than ten tutorials.

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.

ErrorMeansTypical fix
SyntaxErrorPython can't even parse the linemissing :, unclosed quote or bracket
IndentationErrorinconsistent indentationalign the block (4 spaces per level)
NameErrorname used before it existstypo? define before use? scope? (4.4)
TypeErrorwrong type for the operationconvert: int("5"), str(5)
ValueErrorright type, impossible valuevalidate input (6.3)
IndexErrorlist position doesn't existcheck len(); remember counting from 0
KeyErrordict key doesn't existuse .get(key, default)
AttributeErrorno such method/attributetypo (.upcase.upper)? wrong type?
ZeroDivisionErrordivided by zeroguard with if b != 0
ModuleNotFoundErrorno such modulespelling; on a real machine: pip install it
FileNotFoundErrorno such fileright name? create it first? try/except
EOFErrorinput 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:

RequirementWhere you got it
Starts with the very basicsModule 0–1: print, variables, types, operators — nothing assumed
Logical, building-block progressionEach module uses only what came before (files→exceptions→projects→APIs)
Plenty of exercises19 exercises with hidden solutions + 30 quiz questions + "try it" boxes in every lesson
Projects5 guided projects: guessing game, to‑do list, calculator, text adventure, journal
Explains why, not just how💡 "Why this matters" callouts throughout
Teaches debuggingLesson 2.6, deliberate 🐞 crash boxes, Appendix A error zoo
No overwhelming advanced topicsComprehensions, decorators, metaclasses deferred to "what's next"
Tools to keep learningLesson 8.4: docs, help(), search technique, editors, pip workflow
REPL habitBuilt-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. 🐍

🐍 Python Console Enter to run · ↑/↓ history · auto-indent after “:” · empty Enter ends a block · Ctrl+C cancels · Esc closes
>>>