Part 0 · 2 chapters · ~12 min
Basics
Installing Python and virtual environments (venv, uv), names and objects, numbers, strings and bytes, lists, tuples, dicts and sets, control flow, functions with defaults and keyword arguments, comprehensions, generators, decorators and context managers, modules and packages, and the standard library tour.
1
Names, objects and the data model
code
uv venv && source .venv/bin/activate # or: python3 -m venv .venv
uv pip install django pytest
def fee(amount_kobo: int, *, rate_bps: int = 50, minimum: int = 1_000) -> int: # keyword-only after *
if amount_kobo <= 0:
raise ValueError(f"amount must be positive, got {amount_kobo}")
return max(amount_kobo * rate_bps // 10_000, minimum)
fees = [fee(a) for a in (100_000, 5_000_000)] # list comprehension → [1000, 25000]
by_owner = {t.owner: t for t in transfers} # dict comprehension
big = (t for t in transfers if t.amount > 10_000_000) # generator: lazy, one item at a timeEVERYTHING IS AN OBJECT
names point at objects; objects carry their type and a reference count
swipe the figure sideways, or tap expand for full screen
1/4
names and objects
Variables are names bound to objects, not boxes holding values. balance = 500_000 binds the name to an int object.
names bind to objectsnot boxes holding values
2
Generators, decorators and context managers
code
def read_statement(path): # a generator: constant memory over a huge file
with open(path, encoding="utf-8") as f: # context manager: closed even on exceptions
for line in f:
yield parse(line)
import functools, time
def timed(fn): # a decorator wraps a function
@functools.wraps(fn)
def wrapper(*args, **kwargs):
t = time.perf_counter()
try: return fn(*args, **kwargs)
finally: log.info("%s took %.1f ms", fn.__name__, (time.perf_counter() - t) * 1000)
return wrapper
@timed
def reconcile(day): ...money
Never use
float for money: 0.1 + 0.2 == 0.30000000000000004 in Python too. Use integer minor units, or decimal.Decimal with an explicit context and rounding mode (Computers part 7).