Math and statistics
Select numeric representations and compute descriptive statistics safely.
The numeric standard library includes math for real-number algorithms, cmath for complex
numbers, decimal for configurable base-10 arithmetic, fractions for exact rational values,
random for simulation, and statistics for descriptive measures.
math essentials
import math
distance = math.hypot(3.0, 4.0)
rounded_up = math.ceil(2.1)
quotient, remainder = divmod(17, 5)
assert distance == 5.0
assert math.isclose(0.1 + 0.2, 0.3, rel_tol=1e-9, abs_tol=0.0)Binary floats cannot exactly represent many decimal fractions. Compare computed floats with
math.isclose(), choosing tolerances from the domain. An absolute tolerance matters near zero.
Other useful APIs:
math.fsum()reduces accumulated floating-point error;math.prod()multiplies an iterable;math.comb()andmath.perm()compute exact combinatorial counts;math.gcd()andmath.lcm()operate on integers;math.isnan(),math.isinf(), andmath.isfinite()classify special values;math.log1p(x)andmath.expm1(x)retain precision near zero.
import math
values = [1e16, 1.0, -1e16]
print(sum(values)) # commonly 0.0
print(math.fsum(values)) # 1.0Choose the number type
| Requirement | Type |
|---|---|
| Fast scientific approximations | float |
| Currency or contractual decimal rounding | decimal.Decimal |
| Exact ratios and small rational calculations | fractions.Fraction |
| Arbitrarily large whole numbers | int |
| Complex-domain calculations | complex / cmath |
Construct decimals from strings, not floats:
from decimal import Decimal, ROUND_HALF_UP, localcontext
price = Decimal("19.95")
tax_rate = Decimal("0.0825")
with localcontext() as context:
context.prec = 28
total = (price * (Decimal(1) + tax_rate)).quantize(
Decimal("0.01"),
rounding=ROUND_HALF_UP,
)Rounding is a business rule. State it explicitly. round() uses bankers' rounding for ties and
still operates on the underlying numeric representation.
Descriptive statistics
from statistics import fmean, median, pstdev, quantiles
samples = [12.0, 15.0, 16.0, 20.0, 22.0]
print(fmean(samples))
print(median(samples))
print(pstdev(samples))
print(quantiles(samples, n=4, method="inclusive"))Choose the formula that matches the data:
mean()preserves supported exact numeric types;fmean()returns a fast float;median()is robust to large outliers;mode()returns one most common value;multimode()returns all modes;stdev()/variance()use sample formulas;pstdev()/pvariance()use population formulas;correlation()measures linear association, not causation;linear_regression()fits a simple least-squares line.
Most functions require nonempty data and may raise StatisticsError. Filter or reject missing,
infinite, and NaN observations according to an explicit policy. NaN values have surprising
comparison behavior and can invalidate sorting-based statistics.
Randomness is not security
random is deterministic and appropriate for simulations and tests. Seed a dedicated
random.Random instance for reproducibility. Use secrets for tokens, password-reset links, and
security-sensitive choices.
import random
import secrets
rng = random.Random(42)
sample = rng.sample(range(100), k=5)
token = secrets.token_urlsafe(32)Common mistakes and practice
- Using float equality for calculated values.
- Mixing
Decimalandfloat. - Reporting a mean without sample size, spread, units, or missing-data policy.
- Using sample variance for a full population, or vice versa.
- Treating correlation as proof of causation.
Practice: summarize a CSV column with count, missing count, median, mean, sample standard
deviation, and quartiles. Reject non-finite values, document your quartile method, and explain
whether float or Decimal is appropriate for the dataset.
LEARNING RECORD
Finish this lesson
Mark it complete when you can explain the main decision without looking.
KNOWLEDGE CHECK