Tooling reference

Python basics

How Python spells the things you already know, for the subset the early builds use. A read-once orientation, not a course.

Who this is for. This page assumes you can already program in some language and shows you how Python spells it, for the subset the early Build Track milestones use (up to about B5). It does not teach programming from scratch and is not a general Python course. It is an optional reference. If you have never programmed, use a dedicated beginner Python resource first, then come back.
Last reviewed: 2026. The examples here are short and illustrative; exact output depends on your Python version and setup. For anything beyond this subset, the official Python tutorial is the durable source.

Variables and assignment

No declarations or types up front. You assign and the name exists.

x = 5
name = "grid"
rate = 0.1

Basic types

The ones the builds use: integers, floats, strings, booleans, and None for absence.

n = 5          # int
lr = 0.95      # float
s = "goal"     # str
done = True    # bool
nothing = None # absence of a value

Lists

An ordered, mutable sequence. Python's default container.

xs = [1, 2, 3]
xs.append(4)
first = xs[0]
how_many = len(xs)

Tuples

Like a list but fixed once made. Handy for a pair such as a grid cell.

cell = (4, 0)
row, col = cell      # unpack into two names

Dictionaries

Key to value lookup. Useful for mapping or counting.

scores = {"a": 1, "b": 2}
scores["c"] = 3
val = scores["a"]

Sets

An unordered collection of unique items. Fast membership tests.

obstacles = {(1, 1), (2, 2)}
blocked = (1, 1) in obstacles   # True

Indexing

Square brackets read one element. Indexing starts at 0; negatives count from the end.

xs = [10, 20, 30]
xs[0]    # 10
xs[-1]   # 30

Slicing

A range of elements with start:stop (stop is excluded).

xs = [0, 1, 2, 3, 4]
xs[1:3]   # [1, 2]
xs[:2]    # [0, 1]
xs[2:]    # [2, 3, 4]

Conditionals

if, elif, else. The colon and indentation mark the block.

if x > 0:
    sign = 1
elif x < 0:
    sign = -1
else:
    sign = 0

for loops

Iterate over a sequence directly, or over a number range. enumerate gives index and item.

for v in xs:
    print(v)

for i in range(5):     # 0,1,2,3,4
    print(i)

for i, v in enumerate(xs):
    print(i, v)

while loops

Repeat until a condition is false. Make sure something changes inside.

steps = 0
while not done:
    steps = steps + 1
    if steps > 100:
        break

Functions

def names a function. Arguments can have defaults.

def step(cell, action, gamma=0.95):
    # ... do something ...
    return cell

Returning multiple values

Return a tuple and unpack it at the call site.

def env_step(cell, a):
    return next_cell, reward, done

nxt, r, done = env_step(cell, a)

Imports

Bring in a module, optionally under a short alias.

import numpy as np
import random
from math import sqrt

f-strings

Put values straight into a string with f"...{value}...".

ep = 12
print(f"episode {ep}: reward {total:.2f}")

List comprehensions

Build a list in one line from a loop. Optional condition filters.

squares = [v * v for v in range(5)]
evens = [v for v in xs if v % 2 == 0]

Simple file reading

Open a file with with, so it closes itself. Read all text or loop lines. Pass encoding="utf-8" so non-English characters load correctly rather than turning into garbage.

with open("corpus.txt", encoding="utf-8") as f:
    text = f.read()

with open("corpus.txt", encoding="utf-8") as f:
    for line in f:
        print(line.strip())

Strings, characters, and adjacent pairs

A string loops one character at a time, and you join characters back with "".join(...). To walk adjacent pairs (the core move in a BPE tokenizer), zip a sequence against itself shifted by one. To pick the dictionary key with the largest value, pass key=d.get to max.

for ch in "hello":    # 'h', 'e', 'l', 'l', 'o'
    print(ch)
text = "".join(["h", "i"])   # 'hi'

syms = ["l", "o", "w", "e", "r"]
for a, b in zip(syms, syms[1:]):   # ('l','o'), ('o','w'), ('w','e'), ('e','r')
    print(a, b)

counts = {"lo": 5, "ow": 2, "er": 9}
best = max(counts, key=counts.get)   # 'er' (the key with the highest count)

If you would rather not build the count dict by hand, collections.Counter does it for you:

from collections import Counter
counts = Counter(zip(syms, syms[1:]))   # {('l','o'): 1, ('o','w'): 1, ...}
best, n = counts.most_common(1)[0]      # the most frequent pair and its count

A debugging mindset

When something is wrong, look rather than guess. Print the value and, for arrays, the shape; read the bottom line of any traceback first; check you are in the right folder and that your imports succeeded.

print("Q row:", Q[s])
print("shape:", Q.shape)

numpy basics

numpy gives you fast arrays. The handful the early builds use:

import numpy as np

a = np.zeros((5, 4))      # a 5 by 4 array of zeros
a.shape                   # (5, 4)
a[0, 1]                   # one element (row 0, col 1)
a[0]                      # a whole row

a + b                     # elementwise add (same shapes)
a * 2                     # multiply every element by 2

np.argmax(a[0])           # index of the largest value in row 0
np.max(a[0])              # the largest value in row 0
a.sum()                   # add everything up (also np.sum(a))

a @ b                     # dot product / matrix multiply (also np.dot(a, b))
np.linalg.norm(v)         # length of a vector
M.mean(axis=0)            # average down the rows, one value per column
M @ q                     # score a (D,) vector q against every row of an (N, D) matrix
np.argsort(scores)        # indices that would sort the array (ascending)

X, Y = np.meshgrid(xs, ys)   # a 2D grid of coordinates from two 1D arrays
Z = f(X, Y)                  # evaluate a surface at every grid point (vectorised)

matplotlib: a quick plot

The plotting builds (B3 onward) use matplotlib for a scatter, a line, or a contour map. The handful you need:

import matplotlib.pyplot as plt

plt.scatter(xs, ys)       # points; xs and ys are equal-length arrays
plt.plot(xs, ys)          # a line instead of points
plt.contour(X, Y, Z, levels=30)   # contour lines of a surface Z over a grid
plt.contourf(X, Y, Z)     # filled version (optional)
plt.colorbar()            # a scale beside the plot (optional)
plt.xlabel("dim 1")       # axis labels
plt.ylabel("dim 2")
plt.title("2D projection")
plt.savefig("plot.png")   # write the figure to a file
plt.show()                # open a window (skip this if you only save)
That is the whole subset the early builds need. Keep the Python cheatsheet open while you build for quick recall. Anything past this (classes, objects, decorators, generators, framework APIs) is not needed for the early milestones and is left out on purpose.