Numbers, math, and randomness
Integers, floats, the math module, rounding, and reproducible random numbers.
Why this matters in AI / ML / GenAI
Learning-rate schedules, softmax, log-loss, and cosine similarity are arithmetic. Random number generation drives weight initialisation, shuffling, dropout, and train/test splits — and it must be seeded, or your results are not reproducible.
1. Read
Understand the idea in plain English first.
2. Run
Load any example into the compiler and press Run.
3. Change
Edit one value, rerun, and learn from the output.
Numeric types and operators
Three built-in numeric types: int (unbounded — no overflow), float (64-bit IEEE 754), and complex (rare outside signal processing).
Operators: + - * / // % **. Remember / always gives a float and // floors toward negative infinity, so -7 // 2 is -4, not -3.
Useful built-ins: abs, round, min, max, sum, pow, divmod.
Readability helper: underscores in numeric literals. 1_000_000 is easier to scan than 1000000, and scientific notation 2e-5 is standard for learning rates.
The math module
import math for the functions that show up in ML formulas:
math.sqrt,math.exp,math.log(natural),math.log10,math.log2math.floor,math.ceil,math.truncmath.inf,-math.inf,math.nan,math.isnan,math.isclosemath.pi,math.e
math.inf is the correct initial value when tracking a minimum loss: any real loss is smaller than infinity.
math.nan never equals itself — nan == nan is False. Test with math.isnan(x). NaN appearing in your loss is the signature of a diverged training run, usually from too high a learning rate or a log of zero.
Random numbers and seeding
random covers shuffling and sampling: random.random(), randint, uniform, choice, sample, shuffle, gauss.
Always seed for reproducibility. random.seed(42) makes the sequence deterministic. In an ML project you seed Python's random, NumPy, and your framework, because each has its own generator.
The random module is not cryptographically secure. For tokens, API keys, or passwords use secrets.
Hands-on practice
Compiler on the left. Examples on the right.
On desktop, keep the compiler beside the examples. On mobile, the same blocks stack cleanly. Pick an example, try it in the compiler, then change one small thing.
Build a learning-rate schedule
Live Python compiler
Try it — in-browser Python
Change decay_rate to 0.5 and watch the learning rate fall faster.
Code editor
Output
Python runs in your browser. First run downloads the runtime.
Press Run (or Ctrl+Enter) to execute.
Runs CPython in your browser. NumPy, pandas, scikit-learn and Matplotlib load on demand. Charts appear below the output. No input(), no GPU, no network installs.
Clear code examples
Every example is copy-ready. Use Try in compiler when you want to experiment without scrolling around.
Example
Operators and integer behaviour
Python ints have no size limit — no overflow.
print("divide :", 7 / 2)
print("floor divide:", 7 // 2, "|", -7 // 2, "<- floors toward -inf")
print("remainder :", 7 % 2)
print("power :", 2 ** 10)
print("divmod :", divmod(17, 5))
print("big int :", 2 ** 200)
print("readable :", 1_000_000 + 2e-5)
print("abs/min/max :", abs(-4), min(3, 1, 2), max(3, 1, 2))Example
math functions used in ML
Sigmoid and log-loss written out longhand.
import math
def sigmoid(x):
return 1 / (1 + math.exp(-x))
def log_loss(y_true, y_pred, eps=1e-15):
y_pred = min(max(y_pred, eps), 1 - eps) # clip to avoid log(0)
return -(y_true * math.log(y_pred) + (1 - y_true) * math.log(1 - y_pred))
for z in [-2.0, 0.0, 2.0]:
print(f"sigmoid({z:5.1f}) = {sigmoid(z):.4f}")
print("loss when confident and right:", round(log_loss(1, 0.99), 4))
print("loss when confident and wrong:", round(log_loss(1, 0.01), 4))
print("sqrt / log / exp:", math.sqrt(16), round(math.log(math.e), 4), round(math.exp(1), 4))Example
Infinity and NaN
math.inf is the right starting value for tracking a best loss.
import math
best_loss = math.inf
for loss in [0.9, 0.7, 0.75, 0.6]:
if loss < best_loss:
best_loss = loss
print("new best:", loss)
print("final best:", best_loss)
nan = float("nan")
print("nan == nan :", nan == nan, "<- always False")
print("isnan :", math.isnan(nan))
print("isinf :", math.isinf(math.inf))Example
Seeded randomness
Same seed, same sequence — this is what makes an experiment repeatable.
import random
random.seed(42)
first = [round(random.random(), 4) for _ in range(3)]
random.seed(42)
second = [round(random.random(), 4) for _ in range(3)]
print("run 1:", first)
print("run 2:", second)
print("reproducible:", first == second)
random.seed(7)
data = list(range(10))
random.shuffle(data)
print("shuffled :", data)
print("sample 3 :", random.sample(range(100), 3))
print("choice :", random.choice(["adam", "sgd", "adamw"]))
print("gaussian :", round(random.gauss(0, 1), 4))Takeaways
- int is unbounded; / gives float and // floors toward negative infinity.
- math.inf initialises best-loss trackers; NaN never equals itself, use math.isnan.
- Seed random for reproducibility, and use secrets for anything security-related.