cassionData Analysis

Lesson 4 of 8

Unit · What travels with the number

The panel that caught a wrong number in this course

Two artefacts on this platform computed improved water coverage from the same file and got 82.3% and 79.7%. The technical documentation was right and the lesson was wrong, and nothing except a definition panel and a second computation would have found it.

PythonR135 minUNICEF indicator definitionsSphere StandardsSustainable Development Goals (SDG)OECD DAC evaluation criteria

What happened

The WASH project has carried an indicator definitions document since it was written. It states improved water coverage as 82.3% and basic service as 56.3%, with the numerator, the denominator and the standard for each.

The WASH course lesson, the committed figure and the first version of the project dashboard all said 79.7% and 54.7%.

# What the lesson had
IMPROVED = {
    "piped-into-dwelling", "piped-into-yard", "public-tap",
    "borehole", "protected-well", "protected-spring",
}
# What the JMP definition actually lists
improved <- c("piped-into-dwelling", "piped-into-yard", "public-tap",
              "borehole", "protected-well", "protected-spring",
              "tanker-truck")     # packaged or delivered water

The JMP improved list includes packaged or delivered water, which is tanker-truck in this dataset. The lesson omitted it — in a course that names the JMP ladder and SDG 6.1.1 explicitly — and understated improved coverage by 2.6 points and basic service by 1.6.

Nothing detected it for months. The lesson was internally consistent, the figure agreed with the lesson because it used the same set, the tests passed, and the number was plausible. It surfaced the day a second artefact computed the same indicator from the same file and disagreed.

Why the documentation was the one that was right

Because it stated the definition rather than implementing it.

### 2.1 Improved source

| Numerator   | Households whose main drinking water source is piped, borehole,
|             | protected well, protected spring, rainwater or packaged water
| Denominator | All surveyed households
| Value       | 0.823
| Valid at    | Household, community, district
| Standard    | WHO/UNICEF JMP service ladders

Writing “or packaged water” in prose made it checkable against the standard. A Python set of six strings does not read like anything; a numerator written as a sentence can be compared to the definition it claims to implement.

That is the whole argument for the panel. It is not documentation of the code — it is the specification the code is supposed to satisfy, written in a form a sector specialist can audit without reading Python.

What a definition entry contains

Six fields, and the last two are the ones usually missing.

Field Example
Numerator Households with an improved source and a round trip of 30 minutes or less
Denominator All surveyed households
Value 0.563
Valid at Household, community, district
Standard JMP service ladders; SDG 6.1.1
Decision informed Which communities receive rehabilitation

“Valid at” prevents the commonest misuse. A number computed at district level and quoted at community level is the same arithmetic answering a different question, and stating the level is what stops it.

“Decision informed” is what justifies the indicator existing. The WASH documentation writes “None. It is reported so the report can show what changed” against improved coverage — which is an unusually honest entry and exactly right: the figure is retained to quantify a gap, not to be used.

Where the panel lives

Three places, and they are not alternatives.

Where What it holds
On the dashboard One clause per tile — “improved and within 30 minutes”
In the technical documentation The full entry, six fields, per indicator
In the code A comment naming the standard and the reason
# The JMP improved list, which includes packaged or delivered water —
# `tanker-truck` here. Omitting it understates improved coverage by 2.6
# points and disagrees with the project's own indicator documentation.
IMPROVED = {...}
# The comment is what makes the next reader check rather than assume.

The tile clause is what a reader sees; the document is what a challenger reads; the comment is what the next analyst edits. All three, or the three drift.

The check the panel makes possible

Compute the indicator twice, from different code, and compare. That is what found the error here, and it is a check you can run deliberately rather than by accident.

from_pipeline = summary["basic_service"]
from_documentation = 0.563          # the value the definition panel states
assert abs(from_pipeline - from_documentation) < 0.001, (
    f"pipeline {from_pipeline:.3f} disagrees with the definition panel"
)
stopifnot(abs(basic_service - 0.563) < 0.001)

A stated value in the definition panel is a test fixture. Once the panel carries the number, any pipeline that computes it differently fails loudly — which is the workflows course’s rule arriving in a place nobody expects it.

And when they disagree, decide which is authoritative before changing either. Here the standard settled it: JMP lists delivered water, so the documentation was right and four other artefacts were corrected to match.

The argument this prevents every month

The indicator definition panel exists because of a specific recurring meeting.

“Coverage is 82%.” — “We reported 76% last quarter.” — “That was a different definition.” — “Which one is right?”

Both are right and they are different indicators. Without a panel that conversation takes twenty minutes every quarter and is never resolved; with one it takes as long as opening the document.

The commonest three disagreements in this sector, all of which a panel settles:

Source against service. Improved source, 82.3%. Basic service, 56.3%. Twenty-six points, and both are correct.

Numerator population against denominator population. Gross enrolment of 109.2% is a projected denominator, not more children than exist.

Screening against survey. A screening rate is not a prevalence estimate, and the nutrition dashboard here says so in its own “what this does not show” section.

Report it whole

Indicator definitions

  Full definitions in docs/indicator-definitions.md: numerator, denominator,
  the level it is valid at, the standard applied, and the decision it
  informs, for each of the nine indicators in this report.

  Each dashboard tile carries the definition compressed to one clause.

  The pipeline asserts its computed values against the values stated in the
  definitions document. A disagreement fails the build rather than reaching
  a report.

  Change log: 2026-07-29, improved source corrected from 79.7% to 82.3%.
  Delivered water (tanker truck) was omitted from the JMP improved list.
  The definitions document had it right; the analysis code did not.

The change log entry is the part worth copying. An indicator that changed definition needs a dated line saying what changed and which direction, or every comparison with an earlier report is silently wrong.

What comes next

The dashboard answers a question. The report is where the answer gets argued, and the next lesson is about writing one whose findings, limitations and recommendation can be read separately — because they will be.

Teach this lesson

The lesson as a slide deck, with the prose kept in the speaker notes rather than on the slide. Generated from this page, so it cannot fall out of step with it.

Start the slideshowRead the slides

The PDF needs no software and projects from any machine. The PowerPoint file is there to be edited — add your organisation's branding, cut a section for a shorter session, or merge two lessons into a workshop.