Eight short scripts that take the package apart one layer at a time, on synthetic data with a known answer.
This section runs wdm one piece at a time: the model alone, a synthetic record with a hidden truth, the two estimation phases, the tape measure, the backtest, and the controller, first losing and then holding. At every step you run a short script, compare its output with the one shown, read the code it points at, and try a change. Everything here uses the package’s Python API, so it also serves as a guide to using wdm as a library.
How to use it. From weight-dynamics/code, after Getting started:
cd weight-dynamics/code &&uv run python walkthrough/01_model.py
Each page gives the command, the script itself (folded), the output it printed when the page was written (2026-10-28), what to notice in that output, where the code lives (file.py:line, under src/wdm/), the assumptions made at that layer, and a “Try this” exercise.
All data are synthetic, with fixed seeds, so your numbers should match to the digits shown. Another JAX or SciPy version can change the last digits of the optimizer-driven results (steps 3 to 8).
Steps 2 to 8 share one subject and one episode: a 40-year-old man, 175 cm, starting at 100 kg and 30 % body fat, eating about 80 % of his maintenance for 120 days, with a metabolism set deliberately away from the prior (the same values wdm demo and the tests use). Each script rebuilds that episode from the same seed, so each runs on its own.
Everything runs on the CPU. Most of each step’s time is generating the synthetic episode, which steps one day at a time in Python.
Holding today’s tissue and a weight 3 lb below: intake near maintenance, a gentle correction
08_maintain.py
25 s
Runtimes are wall-clock on a 20-thread desktop CPU, including Python and JAX start-up.
The steps in the pipeline
flowchart LR
M("model<br/>step 1")
D["synthetic episode:<br/>weigh-ins, food, waist<br/>step 2"]
P1("phase 1<br/>noise of the scale<br/>step 3")
P2("phase 2<br/>state + metabolism<br/>steps 4, 5")
BT("backtest<br/>step 6")
PL("controller<br/>steps 7, 8")
D --> P1
P1 -->|"reading noise"| P2
D --> P2
P2 --> BT
P2 -->|"state, parameters"| PL
M -.-> D
M -.-> P2
M -.-> PL
Where each step sits in the pipeline. Rounded boxes are what wdm computes; the model (step 1) is used by the generator, the filter and the controller alike.