This is the HowToFit tutorial lecture series for PyAutoFit, a Python probabilistic
programming library for Bayesian model fitting. Tutorials teach new users how to compose, fit, and
interpret probabilistic models from first principles. It is the teaching companion to
../autofit_workspace. These are the canonical, agent-agnostic instructions for this repo.
scripts/— Runnable Python tutorial scripts:chapter_1_introduction/— Models, fitting data, non-linear searches, results and sampleschapter_2_scientific_workflow/— Reserved stub for future material (empty except README)chapter_3_graphical_models/— Individual / graphical / hierarchical models, Expectation Propagationsimulators/— Simulator scripts that generate the tutorial 1D datasets at runtime
notebooks/— Jupyter versions, generated fromscripts/(do not edit directly)config/— PyAutoFit configuration YAMLdataset/— Empty in the repo; written at runtime by the simulator scriptsoutput/— Model-fit results (generated at runtime, not committed)
Scripts are run from the repo root so relative paths to dataset/ and output/ resolve. A
tutorial that needs a dataset invokes scripts/simulators/simulators.py via subprocess if the
dataset folder is absent — no manual simulate-then-run step.
python scripts/chapter_1_introduction/tutorial_1_models.pyFast mode for integration: PYAUTO_TEST_MODE=1 skips sampling (=2 also bypasses; combine with
PYAUTO_SKIP_FIT_OUTPUT=1 PYAUTO_SKIP_VISUALIZATION=1 PYAUTO_SKIP_CHECKS=1 for a fast smoke run).
Most tutorials use the af.ex namespace for example components (af.ex.Gaussian, af.ex.Analysis)
and the generic af.Model / af.Collection API.
On CI, every PR is gated on Python 3.12 and 3.13 by smoke_tests.yml (runs
python .github/scripts/run_smoke.py, driven by smoke_tests.txt + config/build/env_vars.yaml —
the definition of green), navigator_check.yml (PyAutoBuild's reusable navigator-catalogue check;
see Notebooks vs Scripts), and url_check.yml (link checking). The smoke and navigator jobs check
out PyAutoBuild as a sibling and run the PyAuto* libraries from the same-named branch of each
source repo, so a HowToFit PR is validated against matching library branches.
If numba or matplotlib cannot write to the default cache locations, point them at writable dirs:
NUMBA_CACHE_DIR=/tmp/numba_cache MPLCONFIGDIR=/tmp/matplotlib python scripts/chapter_1_introduction/tutorial_1_models.pyNotebooks in notebooks/ are generated from the .py scripts via PyAutoBuild. Always edit the
.py scripts, never the .ipynb directly. The # %% marker alternates code and markdown cells.
Regenerate from the repo root:
PYTHONPATH=../PyAutoBuild/autobuild python3 ../PyAutoBuild/autobuild/generate.py howtofitThe howtofit project target is registered in PyAutoBuild (run_all.py, navigator.py, config/).
The navigator catalogue — llms-full.txt + workspace_index.json — is what navigator_check.yml
gates; it is rebuilt by the same PyAutoBuild generate/merge flow that builds the notebooks. Commit
regenerated notebooks and catalogue alongside the script changes.
When editing the same region across many scripts in one pass, only rewrite the targeted region. Never produce a whole-file write unless you have read the entire current file — a whole-file write from a header skim silently deletes every section below the header.
../PyAutoFit— source library.../autofit_workspace— the user-facing workspace (tutorials point here as the next destination).../PyAutoBuild— notebook generation + CI tooling.
[API Update] issues: find every renamed/moved/removed/changed public API, update each tutorial
script (preserving the teaching prose), run python .github/scripts/run_smoke.py, and fix [FAIL]
entries until the summary passes; regenerate notebooks + catalogue after. General issues: edit
only files in scripts/ (never notebooks/), preserve docstrings and explanations, test, then
regenerate. Flag any change that affects autofit_workspace or PyAutoFit in your PR.
Never rewrite history on a repo with a remote (no git init over a tracked tree, no force-push to
main, no rebasing pushed shared branches). To reset a dirty tree the only correct sequence is:
git fetch origin
git reset --hard origin/main
git clean -fd