FA-71176 / Weather index computation / Open access
Hargreaves reference evapotranspiration: radiation equivalent evaporation · case 01
Irrigation demand is about 2.5 times too high.
ROOT CAUSE
Radiation in MJ/m2/day is used without the 0.408 mm-equivalent conversion.
THE FAILURE
Radiation in MJ/m2/day is used without the 0.408 mm-equivalent conversion.
Unsuccessful approach: Dividing by 0.408 applies the conversion in the wrong direction.
Case contract
Daily tmax/tmin degC (tmax >= tmin) and extraterrestrial radiation Ra in MJ/m2/day. Convert Ra to mm/day with 0.408. ET0 = 0.0023*Ra_mm*(Tmean+17.8)*sqrt(tmax-tmin), Tmean=(tmax+tmin)/2; negative results clamp to 0; round to 0.01 mm.
Why this case matters
Irrigation scheduling uses ET0 where full meteorological data are unavailable.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(tmax, tmin, ra_mj):
tmean = (tmax + tmin) / 2
et = 0.0023 * ra_mj * (tmean + 17.8) * math.sqrt(tmax - tmin)
return round(max(et, 0.0), 2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['tmax 30 tmin 15 Ra 10.0', [30, 15, 10.0], 1.46], ['tmax 30 tmin 15 Ra 25.0', [30, 15, 25.0], 3.66], ['tmax 30 tmin 15 Ra 40.0', [30, 15, 40.0], 5.86], ['tmax 35 tmin 20 Ra 10.0', [35, 20, 10.0], 1.65], ['tmax 35 tmin 20 Ra 25.0', [35, 20, 25.0], 4.12], ['tmax 35 tmin 20 Ra 40.0', [35, 20, 40.0], 6.59], ['tmax 10 tmin -2 Ra 10.0', [10, -2, 10.0], 0.71], ['tmax 10 tmin -2 Ra 25.0', [10, -2, 25.0], 1.77]], [['tmax 35 tmin 20 Ra 10.0', [35, 20, 10.0], 1.65], ['tmax 10 tmin -2 Ra 10.0', [10, -2, 10.0], 0.71], ['tmax 10 tmin -2 Ra 25.0', [10, -2, 25.0], 1.77], ['tmax 10 tmin -2 Ra 40.0', [10, -2, 40.0], 2.83], ['tmax -10 tmin -25 Ra 10.0', [-10, -25, 10.0], 0.01], ['tmax -10 tmin -25 Ra 25.0', [-10, -25, 25.0], 0.03], ['tmax -10 tmin -25 Ra 40.0', [-10, -25, 40.0], 0.04], ['tmax -12 tmin -30 Ra 10.0', [-12, -30, 10.0], 0.0]], [['tmax 10 tmin -2 Ra 10.0', [10, -2, 10.0], 0.71], ['tmax -10 tmin -25 Ra 40.0', [-10, -25, 40.0], 0.04], ['tmax -12 tmin -30 Ra 40.0', [-12, -30, 40.0], 0.0], ['tmax 25 tmin 25 Ra 10.0', [25, 25, 10.0], 0.0], ['tmax 25 tmin 25 Ra 25.0', [25, 25, 25.0], 0.0], ['tmax 25 tmin 25 Ra 40.0', [25, 25, 40.0], 0.0], ['tmax 40 tmin 18 Ra 10.0', [40, 18, 10.0], 2.06], ['tmax 40 tmin 18 Ra 25.0', [40, 18, 25.0], 5.15]], [['tmax 30 tmin 15 Ra 10.0', [30, 15, 10.0], 1.46], ['tmax -10 tmin -25 Ra 10.0', [-10, -25, 10.0], 0.01], ['tmax 22 tmin 8 Ra 10.0', [22, 8, 10.0], 1.15], ['tmax 22 tmin 8 Ra 25.0', [22, 8, 25.0], 2.88], ['tmax 22 tmin 8 Ra 40.0', [22, 8, 40.0], 4.61], ['tmax -5 tmin -20 Ra 10.0', [-5, -20, 10.0], 0.19], ['tmax -5 tmin -20 Ra 25.0', [-5, -20, 25.0], 0.48], ['tmax -5 tmin -20 Ra 40.0', [-5, -20, 40.0], 0.77]], [['tmax 30 tmin 15 Ra 10.0', [30, 15, 10.0], 1.46], ['tmax 30 tmin 15 Ra 25.0', [30, 15, 25.0], 3.66], ['tmax 30 tmin 15 Ra 40.0', [30, 15, 40.0], 5.86], ['tmax 35 tmin 20 Ra 10.0', [35, 20, 10.0], 1.65], ['tmax 35 tmin 20 Ra 25.0', [35, 20, 25.0], 4.12], ['tmax 35 tmin 20 Ra 40.0', [35, 20, 40.0], 6.59], ['tmax 10 tmin -2 Ra 10.0', [10, -2, 10.0], 0.71], ['tmax 40 tmin 18 Ra 10.0', [40, 18, 10.0], 2.06]]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| tmax 30 tmin 15 Ra 10.0 | 3.59 | 1.46 | Failed |
| tmax 30 tmin 15 Ra 25.0 | 8.97 | 3.66 | Failed |
| tmax 30 tmin 15 Ra 40.0 | 14.36 | 5.86 | Failed |
| tmax 35 tmin 20 Ra 10.0 | 4.04 | 1.65 | Failed |
| tmax 35 tmin 20 Ra 25.0 | 10.09 | 4.12 | Failed |
| tmax 35 tmin 20 Ra 40.0 | 16.14 | 6.59 | Failed |
| tmax 10 tmin -2 Ra 10.0 | 1.74 | 0.71 | Failed |
| tmax 10 tmin -2 Ra 25.0 | 4.34 | 1.77 | Failed |
SHA-256 / 4c0ac98d1cd34503e01d6fc8737831d7aef0c09ce5a83183f94ad178ff474347
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(tmax, tmin, ra_mj):
tmean = (tmax + tmin) / 2
et = 0.0023 * ra_mj / 0.408 * (tmean + 17.8) * math.sqrt(tmax - tmin)
return round(max(et, 0.0), 2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['tmax 30 tmin 15 Ra 10.0', [30, 15, 10.0], 1.46], ['tmax 30 tmin 15 Ra 25.0', [30, 15, 25.0], 3.66], ['tmax 30 tmin 15 Ra 40.0', [30, 15, 40.0], 5.86], ['tmax 35 tmin 20 Ra 10.0', [35, 20, 10.0], 1.65], ['tmax 35 tmin 20 Ra 25.0', [35, 20, 25.0], 4.12], ['tmax 35 tmin 20 Ra 40.0', [35, 20, 40.0], 6.59], ['tmax 10 tmin -2 Ra 10.0', [10, -2, 10.0], 0.71], ['tmax 10 tmin -2 Ra 25.0', [10, -2, 25.0], 1.77]], [['tmax 35 tmin 20 Ra 10.0', [35, 20, 10.0], 1.65], ['tmax 10 tmin -2 Ra 10.0', [10, -2, 10.0], 0.71], ['tmax 10 tmin -2 Ra 25.0', [10, -2, 25.0], 1.77], ['tmax 10 tmin -2 Ra 40.0', [10, -2, 40.0], 2.83], ['tmax -10 tmin -25 Ra 10.0', [-10, -25, 10.0], 0.01], ['tmax -10 tmin -25 Ra 25.0', [-10, -25, 25.0], 0.03], ['tmax -10 tmin -25 Ra 40.0', [-10, -25, 40.0], 0.04], ['tmax -12 tmin -30 Ra 10.0', [-12, -30, 10.0], 0.0]], [['tmax 10 tmin -2 Ra 10.0', [10, -2, 10.0], 0.71], ['tmax -10 tmin -25 Ra 40.0', [-10, -25, 40.0], 0.04], ['tmax -12 tmin -30 Ra 40.0', [-12, -30, 40.0], 0.0], ['tmax 25 tmin 25 Ra 10.0', [25, 25, 10.0], 0.0], ['tmax 25 tmin 25 Ra 25.0', [25, 25, 25.0], 0.0], ['tmax 25 tmin 25 Ra 40.0', [25, 25, 40.0], 0.0], ['tmax 40 tmin 18 Ra 10.0', [40, 18, 10.0], 2.06], ['tmax 40 tmin 18 Ra 25.0', [40, 18, 25.0], 5.15]], [['tmax 30 tmin 15 Ra 10.0', [30, 15, 10.0], 1.46], ['tmax -10 tmin -25 Ra 10.0', [-10, -25, 10.0], 0.01], ['tmax 22 tmin 8 Ra 10.0', [22, 8, 10.0], 1.15], ['tmax 22 tmin 8 Ra 25.0', [22, 8, 25.0], 2.88], ['tmax 22 tmin 8 Ra 40.0', [22, 8, 40.0], 4.61], ['tmax -5 tmin -20 Ra 10.0', [-5, -20, 10.0], 0.19], ['tmax -5 tmin -20 Ra 25.0', [-5, -20, 25.0], 0.48], ['tmax -5 tmin -20 Ra 40.0', [-5, -20, 40.0], 0.77]], [['tmax 30 tmin 15 Ra 10.0', [30, 15, 10.0], 1.46], ['tmax 30 tmin 15 Ra 25.0', [30, 15, 25.0], 3.66], ['tmax 30 tmin 15 Ra 40.0', [30, 15, 40.0], 5.86], ['tmax 35 tmin 20 Ra 10.0', [35, 20, 10.0], 1.65], ['tmax 35 tmin 20 Ra 25.0', [35, 20, 25.0], 4.12], ['tmax 35 tmin 20 Ra 40.0', [35, 20, 40.0], 6.59], ['tmax 10 tmin -2 Ra 10.0', [10, -2, 10.0], 0.71], ['tmax 40 tmin 18 Ra 10.0', [40, 18, 10.0], 2.06]]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| tmax 30 tmin 15 Ra 10.0 | 8.8 | 1.46 | Failed |
| tmax 30 tmin 15 Ra 25.0 | 22.0 | 3.66 | Failed |
| tmax 30 tmin 15 Ra 40.0 | 35.19 | 5.86 | Failed |
| tmax 35 tmin 20 Ra 10.0 | 9.89 | 1.65 | Failed |
| tmax 35 tmin 20 Ra 25.0 | 24.73 | 4.12 | Failed |
| tmax 35 tmin 20 Ra 40.0 | 39.56 | 6.59 | Failed |
| tmax 10 tmin -2 Ra 10.0 | 4.26 | 0.71 | Failed |
| tmax 10 tmin -2 Ra 25.0 | 10.64 | 1.77 | Failed |
SHA-256 / d208ebb009d8fe9311a6826be4520d38ad55828b6a6ab6df21709ec7870a5ffb
HELD IN THE MEMBER ARCHIVE
The verified repair and its recorded checks are member-only.
This mechanism has 8 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.
Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.
Member access is invitation-based. Sign in with your invited account to inspect the repair.
Sign in to the archive ↗Verification & scope
Stipulated deterministic teaching model of an operational weather index; coefficients and thresholds are fixed by the contract and no claim of standards conformance is made. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:48:27.337948+00:00.
Case digest / 5b19ece7c145f3966b1bbae30049c87db8f0f6f94a9247e2079c17e5d738caea