Chapter Summary
Chapter Summary
Key Points
- 1.
Type annotations are documentation that tools can check. Use built-in generics (
list[float],dict[str, np.ndarray]),Union/|for alternatives,Literalfor constrained strings, andTypeAliasfor domain-specific names likeChannelMatrix. Annotations have no runtime cost and dramatically improve IDE support and error detection. - 2.
Assert for invariants, raise for inputs.
assertstatements are for conditions that indicate bugs in your code — they are stripped bypython -O. Useraise ValueError/TypeErrorfor conditions caused by external input. Thebeartypelibrary bridges the gap by enforcing type hints at runtime with O(1) overhead. - 3.
Never compare floats with
==. Usenp.testing.assert_allclose(a, b, atol=..., rtol=...)for numerical tests. The tolerance should reflect the condition number of the computation. Seed random number generators withnp.random.default_rng(seed)(not the globalnp.random.seed) for reproducible stochastic tests. - 4.
Profile before optimizing. Run
python -m cProfile -s cumtime script.pyto find actual bottlenecks. Useline_profilerfor line-level timing andpy-spyfor production profiling with near-zero overhead. The bottleneck is rarely where intuition suggests. - 5.
Package with pyproject.toml and the src layout. A single
pyproject.tomlreplacessetup.py,setup.cfg, andrequirements.txt. Thesrclayout prevents import shadowing. Editable installs (pip install -e ".[dev]") enable rapid development. Entry points create installable CLI tools from your package.
Looking Ahead
With type-safe, tested, and properly packaged code, you are ready for the numerical computing chapters. Chapter 5 dives into NumPy's internals — memory layout, broadcasting rules, and advanced indexing — where type annotations and shape validation become indispensable for writing correct, high-performance array code.