Phase 01 — Production Python Engineering

Difficulty: ⭐⭐⭐☆☆ Estimated Time: 2 weeks (30–40 hours) Roles Supported: every later phase — this is the engineering substrate the JD calls "expert-level programming skills in Python … enabling you to build scalable, production-grade systems"


Why This Phase Exists

Senior ML engineers are distinguished less by knowing more ML than by writing ML code that survives: typed interfaces other teams can build against, tests that catch regressions before the on-call does, and profiling instincts that find the real bottleneck. Every artifact in phases 02–13 is production-shaped Python; this phase sets the bar and the idioms once, so the rest of the track can assume them.

The flagship lab is a typed data-contract library — the kind of component that sits at every pipeline boundary in a real ML platform (and the reason tools like pydantic and pandera exist). Building one teaches the protocol/generic/dataclass machinery, error-design discipline, and property-style testing in one artifact.

Concepts

  • Static typing as API design: Protocol (structural typing), generics (TypeVar, parameterized containers), dataclasses (frozen, slots), Enum, exhaustiveness
  • Error design: exception hierarchies vs result types; collect-don't-raise validation; error messages as UX
  • Iterators/generators as pipeline primitives; itertools; laziness and its traps
  • Concurrency truthfully: the GIL, threads (I/O-bound) vs processes (CPU-bound) vs asyncio (many-waiting); what each buys for ML workloads
  • Testing discipline: pytest fixtures/parametrize, property-style tests, golden files, test doubles at boundaries
  • Profiling: cProfile/py-spy reading, the measure-first ethic
  • Packaging and reproducibility: pyproject, pinned deps, src layout

Labs

Lab 01 — Typed Data-Contract Library (flagship, implemented)

FieldValue
GoalBuild contracts: declare a schema (fields, types, constraints) as code, validate records against it with aggregated error reporting, and compose schemas — the boundary-guard component of every ML pipeline
ConceptsProtocols, generics, frozen dataclasses, collect-don't-raise, custom rules, property-style testing
Steps1. Field / Schema model; 2. built-in rules (type, range, regex, enum, nullability); 3. ValidationReport aggregating all failures with paths; 4. custom-rule protocol; 5. schema composition (extend/subset) + record coercion; 6. property-style round-trip tests
How to Testpytest test_lab.py — 14 tests: rule semantics, aggregation, paths, protocol extensibility, coercion round-trips
Talking PointsWhy collect-don't-raise at data boundaries? Protocol vs ABC? Why frozen dataclasses for schema objects?
Resume BulletBuilt a typed data-contract validation library with aggregated error reporting and protocol-based extensibility, used as the boundary guard across a multi-stage ML pipeline

→ Lab folder: lab-01-data-contracts/

Extension Project A — Concurrency Benchmark Harness (spec)

Measure the same workload (CPU-bound feature transform; I/O-bound URL fetch simulation) under threads / processes / asyncio; produce the table that demonstrates the GIL's consequences; write the one-page "which concurrency for which ML workload" memo.

Extension Project B — Profiling Kata (spec)

Take a deliberately slow data-prep script (pandas anti-patterns: row-wise apply, repeated concat, object dtypes); profile with cProfile + line-profiler; fix the top three; document each fix's mechanism and speedup. Target: 50×+ end-to-end.

Guides in This Phase

  • WARMUP.md — the full zero-to-expert guide for every concept above

Deliverables Checklist

  • Lab 01 implemented; all 14 tests pass
  • Extension A table + memo (or equivalent from your own work)
  • Extension B with before/after profiles saved