Skip to content

sanzgiri/fermi

Repository files navigation

🎯 Fermi — estimate anything

A web app for practicing Fermi estimation: the art of getting within an order of magnitude of any quantity by breaking it into a chain of guessable factors. Named for Enrico Fermi, who famously estimated the number of piano tuners in Chicago.

Unlike a typical "guess the number" quiz, Fermi scores your reasoning, not just your final answer — it tells you which factor in your chain sent you off course, and trains your calibration (how well your confidence matches reality) over time.

No build step. No dependencies. Open the file and play.


Quick start

# Option A — just open it
open index.html            # macOS  (or double-click the file)

# Option B — run the tiny dev server (better; enables localStorage cleanly)
python3 server.py          # then visit http://localhost:8000
# or
npm start

Run the tests:

npm test          # engine + units tests + headless UI smoke test
# or
node test.js
node test_units.js
node smoke.js

The six features

1. Reasoning-chain scoring (the differentiator)

Build your estimate as a chain of factors that combine with real operators (× ÷ + −), each carrying an optional unit. The app keeps a live running total (with units) and compares your chain — factor by factor — against a reference decomposition. It highlights the single biggest divergence:

"Your factor 'fraction owning a piano' (5 × 10⁻¹) was about 10× too high versus the reference (5 × 10⁻²). Fixing just this step would move your answer by ~1.0 orders of magnitude."

Worksheet rows are colour-coded green / amber / red by how far each factor is from the reference.

Operations & grouping without brackets. Rows multiply/divide by default. When you need a sum-then-multiply like (a + b) × c, add a group: a tidy sub-calculation whose rows all share one operator (sum / difference / product / quotient). The group's result drops into the main chain as a single factor — so you get real grouping with no bracket soup. (One level of nesting; the calculator handles arbitrarily complex ( ) expressions for power users.)

Units via dropdowns (magnitude × unit). Each factor has two dropdowns: a magnitude (×1, thousand, million, billion, percent, kilo, milli, micro…) and a unit (grouped: length, area, volume, mass, time, speed, count, …), plus an “Other…” escape for anything exotic (BTU, parsec). Picking magnitude = million on a 20 makes the factor 2×10⁷ — no more silently dropping the word “million”. The engine tracks SI dimensions, converts where needed (a chain that works out to metres is compared against an answer stated in km), and shows an advisory warning if your factors combine to the wrong dimension — it never blocks you from submitting. Casing is forgiving for words (Million, KMkm) but strict for ambiguous symbols (m=metre stays distinct from M=mega, t=tonne from T=tera).

2. Calibration mode

Instead of a point estimate, give a 90% confidence interval. You're scored with a log-scale interval score: tight intervals that still contain the truth score best; overconfident-and-wrong scores worst. Your hit rate is tracked on a calibration curve in Stats — a well-calibrated estimator contains the answer in ~90% of their intervals.

3. Order-of-magnitude calculator (now unit-aware)

A floating 🧮 dock that understands estimation-friendly notation and units:

  • Math: 3e6, 3×10^6, 3 x 10^6, 5k, 2.5M, 2B, pi, sqrt(), log() (base 10), ln(), and ordinary + − × ÷ ( ).
  • Convert: 12 ft to m, 3 m^3 in L, 100 km/h to m/s, 1 mile -> km.
  • Unit products: 12 ft * 8 ft * 9 ft → result in m³ (with the dimension shown).

Results show both scientific and human-readable forms, with a reusable tape. A 📚 button drops reference values straight into the calculator.

📚 Reference lookups (estimation cheat-sheet)

Stuck on "how big is a marble?" or "what's the population of India?" Hit 📚 Lookups (on the worksheet or the calculator) for a searchable library of ~90 common reference quantities — object sizes, room/building dimensions, the human body, populations, time, speeds, physics constants, money. Click any entry to insert it as a worksheet factor (value and unit) or into the calculator.

4. Procedural generation → endless practice

Practice mode serves an unlimited stream of generated problems from parameterized templates (packing, per-capita services, daily consumption, line-ups), each with its own reference chain and hints. The generator is seedable, which powers…

5. Daily Fermi + spoiler-free sharing

Daily mode gives everyone the same problem each day (deterministically generated from the date). After solving, copy a Wordle-style result:

Daily Fermi 2026-06-19 🟢
Within 0.4 orders of the answer
Hints used: 💡
Streak: 5🔥

6. Reference solutions, streaks, stats & history

Every problem reveals a full worked decomposition with notes and a source (Fermi, Weinstein's Guesstimation, Mahajan, Santos…). Daily wins build a 🔥 streak; Stats tracks accuracy, calibration, best streak and recent results. All progress persists in localStorage.


Project layout

File Purpose
index.html App shell (loads the scripts in order).
styles.css Dark, mobile-first theme.
units.js Dimensional-analysis engine: parse/convert units, combine dimensions.
references.js Searchable library of ~90 common reference quantities (the cheat-sheet).
problems.js Hand-curated bank of classic problems with reference steps.
generator.js Seedable procedural generator (templates → problems).
engine.js Pure logic: OOM math, unit-aware grouped chain scoring, calibration, storage, share text.
app.js UI controller wiring all views and modes (no framework).
server.py Zero-dependency static dev server.
test.js Unit tests for the engine + generator.
test_units.js Unit tests for units, conversions, grouped chains, and lookups.
smoke.js Headless DOM harness that drives app.js to catch runtime errors.

Data model

Each problem (static or generated) has the same shape. The key part is steps, where every input factor is tagged with an op:

{
  id, title, question, unit, category, difficulty, answer, tolerance,
  hints: [ "…", "…", "…" ],
  steps: [
    { label: "Population of Chicago", value: 3e6,  unit: "people", op: "mul" },
    { label: "People per household",  value: 3,    unit: "",       op: "div" },
    { label: "Households",            value: 1e6,  unit: "",       op: "sub" }, // subtotal
    { label: "Fraction owning a piano", value: 0.05, unit: "",     op: "mul" },
    // …
    { label: "Piano tuners",          value: 125,  unit: "tuners", op: "sub" }, // final
  ],
  sources: [ "Enrico Fermi (classic), University of Chicago" ],
}
  • op: "mul" — an input factor multiplied into the chain.
  • op: "div" — an input factor divided into the chain.
  • op: "sub" — a subtotal / intermediate (shown to the reader, excluded from the factor product).

The reference answer is reconstructed by combining the mul/div inputs, which is also what the unit tests assert (engine.referenceProduct).


Adding your own problems

Append an object to the array in problems.js. Make sure the mul/div inputs multiply out to your stated answer (the test suite checks this). Then:

node test.js   # confirms every reference chain reproduces its answer

The books these problems are drawn from, if you want more:

  • Guesstimation & Guesstimation 2.0 — Lawrence Weinstein
  • Street-Fighting Mathematics & The Art of Insight in Science and Engineering — Sanjoy Mahajan (free PDFs from MIT)
  • How Many Licks? — Aaron Santos

Notes & limitations

  • The calculator evaluates expressions in a whitelisted scope (only known math names; rejects anything else) — fine for local/single-user use. If you deploy this multi-tenant, consider a dedicated expression parser.
  • smoke.js ships a tiny purpose-built DOM (not a real browser); it exists to catch runtime wiring errors in CI without a heavyweight dependency.
  • State lives in localStorage, so progress is per-browser.

MIT licensed. Have fun estimating.

About

Fermi-problem trainer: generate estimation problems and score the reasoning chain factor-by-factor. Zero-build static SPA.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors