FA-70866 / Weather index computation / Open access
Wind chill from km/h anemometer: anemometer unit conversion · case 01
Wind chill is several degrees too cold for every windy reading.
ROOT CAUSE
Kilometres per hour are multiplied by 1.609344 instead of divided, overstating the wind in mph.
VERIFIED REPAIR
Convert with wind_kmh / 1.609344.
Unsuccessful approach: Dividing by 1.852 treats the anemometer as knots and still misstates the wind.
Case contract
Input temperature in degF and wind in km/h. Convert wind to mph (divide by 1.609344). If T > 50 degF or wind below 3 mph, return T rounded to 0.1. Otherwise return 35.74 + 0.6215T - 35.75V^0.16 + 0.4275T*V^0.16 rounded to 0.1.
Why this case matters
Cold-weather advisories and frostbite timing use the wind chill index.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(t_f, wind_kmh):
mph = wind_kmh * 1.609344
if t_f > 50 or mph < 3:
return round(t_f, 1)
v = mph ** 0.16
wc = 35.74 + 0.6215 * t_f - 35.75 * v + 0.4275 * t_f * v
return round(wc, 1)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['-40F with 0 km/h wind', [-40, 0], -40], ['-40F with 3 km/h wind', [-40, 3], -40], ['-40F with 4 km/h wind', [-40, 4], -40], ['-40F with 4.8 km/h wind', [-40, 4.8], -40], ['-40F with 5 km/h wind', [-40, 5], -52.5], ['-40F with 8 km/h wind', [-40, 8], -57.4], ['-40F with 16 km/h wind', [-40, 16], -65.4], ['-40F with 32 km/h wind', [-40, 32], -74.4]], [['-40F with 5 km/h wind', [-40, 5], -52.5], ['-40F with 32 km/h wind', [-40, 32], -74.4], ['-40F with 64 km/h wind', [-40, 64], -84.4], ['-40F with 100 km/h wind', [-40, 100], -91.4], ['-20F with 0 km/h wind', [-20, 0], -20], ['-20F with 3 km/h wind', [-20, 3], -20], ['-20F with 4 km/h wind', [-20, 4], -20], ['-20F with 5 km/h wind', [-20, 5], -29.8]], [['-40F with 32 km/h wind', [-40, 32], -74.4], ['-20F with 5 km/h wind', [-20, 5], -29.8], ['-20F with 8 km/h wind', [-20, 8], -33.9], ['-20F with 16 km/h wind', [-20, 16], -40.7], ['-20F with 32 km/h wind', [-20, 32], -48.2], ['-20F with 64 km/h wind', [-20, 64], -56.5], ['-20F with 100 km/h wind', [-20, 100], -62.5], ['-5F with 0 km/h wind', [-5, 0], -5]], [['-20F with 3 km/h wind', [-20, 3], -20], ['-5F with 3 km/h wind', [-5, 3], -5], ['-5F with 4 km/h wind', [-5, 4], -5], ['-5F with 4.8 km/h wind', [-5, 4.8], -5], ['-5F with 5 km/h wind', [-5, 5], -12.8], ['-5F with 8 km/h wind', [-5, 8], -16.3], ['-5F with 16 km/h wind', [-5, 16], -22.1], ['-5F with 64 km/h wind', [-5, 64], -35.7]], [['-20F with 5 km/h wind', [-20, 5], -29.8], ['-5F with 64 km/h wind', [-5, 64], -35.7], ['-5F with 100 km/h wind', [-5, 100], -40.7], ['0F with 0 km/h wind', [0, 0], 0], ['0F with 3 km/h wind', [0, 3], 0], ['0F with 4 km/h wind', [0, 4], 0], ['0F with 4.8 km/h wind', [0, 4.8], 0], ['0F with 32 km/h wind', [0, 32], -21.9]]]
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 |
|---|---|---|---|
| -40F with 0 km/h wind | -40 | -40 | Passed |
| -40F with 3 km/h wind | -57.1 | -40 | Failed |
| -40F with 4 km/h wind | -60.3 | -40 | Failed |
| -40F with 4.8 km/h wind | -62.4 | -40 | Failed |
| -40F with 5 km/h wind | -62.9 | -52.5 | Failed |
| -40F with 8 km/h wind | -68.7 | -57.4 | Failed |
| -40F with 16 km/h wind | -78.0 | -65.4 | Failed |
| -40F with 32 km/h wind | -88.4 | -74.4 | Failed |
SHA-256 / 0e6b6fe689763e00076956b7c3c5749a25547b0d2668c1aad238aad55dbbac76
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(t_f, wind_kmh):
mph = wind_kmh / 1.852
if t_f > 50 or mph < 3:
return round(t_f, 1)
v = mph ** 0.16
wc = 35.74 + 0.6215 * t_f - 35.75 * v + 0.4275 * t_f * v
return round(wc, 1)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['-40F with 0 km/h wind', [-40, 0], -40], ['-40F with 3 km/h wind', [-40, 3], -40], ['-40F with 4 km/h wind', [-40, 4], -40], ['-40F with 4.8 km/h wind', [-40, 4.8], -40], ['-40F with 5 km/h wind', [-40, 5], -52.5], ['-40F with 8 km/h wind', [-40, 8], -57.4], ['-40F with 16 km/h wind', [-40, 16], -65.4], ['-40F with 32 km/h wind', [-40, 32], -74.4]], [['-40F with 5 km/h wind', [-40, 5], -52.5], ['-40F with 32 km/h wind', [-40, 32], -74.4], ['-40F with 64 km/h wind', [-40, 64], -84.4], ['-40F with 100 km/h wind', [-40, 100], -91.4], ['-20F with 0 km/h wind', [-20, 0], -20], ['-20F with 3 km/h wind', [-20, 3], -20], ['-20F with 4 km/h wind', [-20, 4], -20], ['-20F with 5 km/h wind', [-20, 5], -29.8]], [['-40F with 32 km/h wind', [-40, 32], -74.4], ['-20F with 5 km/h wind', [-20, 5], -29.8], ['-20F with 8 km/h wind', [-20, 8], -33.9], ['-20F with 16 km/h wind', [-20, 16], -40.7], ['-20F with 32 km/h wind', [-20, 32], -48.2], ['-20F with 64 km/h wind', [-20, 64], -56.5], ['-20F with 100 km/h wind', [-20, 100], -62.5], ['-5F with 0 km/h wind', [-5, 0], -5]], [['-20F with 3 km/h wind', [-20, 3], -20], ['-5F with 3 km/h wind', [-5, 3], -5], ['-5F with 4 km/h wind', [-5, 4], -5], ['-5F with 4.8 km/h wind', [-5, 4.8], -5], ['-5F with 5 km/h wind', [-5, 5], -12.8], ['-5F with 8 km/h wind', [-5, 8], -16.3], ['-5F with 16 km/h wind', [-5, 16], -22.1], ['-5F with 64 km/h wind', [-5, 64], -35.7]], [['-20F with 5 km/h wind', [-20, 5], -29.8], ['-5F with 64 km/h wind', [-5, 64], -35.7], ['-5F with 100 km/h wind', [-5, 100], -40.7], ['0F with 0 km/h wind', [0, 0], 0], ['0F with 3 km/h wind', [0, 3], 0], ['0F with 4 km/h wind', [0, 4], 0], ['0F with 4.8 km/h wind', [0, 4.8], 0], ['0F with 32 km/h wind', [0, 32], -21.9]]]
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 |
|---|---|---|---|
| -40F with 0 km/h wind | -40 | -40 | Passed |
| -40F with 3 km/h wind | -40 | -40 | Passed |
| -40F with 4 km/h wind | -40 | -40 | Passed |
| -40F with 4.8 km/h wind | -40 | -40 | Passed |
| -40F with 5 km/h wind | -40 | -52.5 | Failed |
| -40F with 8 km/h wind | -55.9 | -57.4 | Failed |
| -40F with 16 km/h wind | -63.7 | -65.4 | Failed |
| -40F with 32 km/h wind | -72.5 | -74.4 | Failed |
SHA-256 / 7eb16ba7aa054ce28ce48ca03dde6053fc6bf7ba8c145543147315aeb84c587e
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(t_f, wind_kmh):
mph = wind_kmh / 1.609344
if t_f > 50 or mph < 3:
return round(t_f, 1)
v = mph ** 0.16
wc = 35.74 + 0.6215 * t_f - 35.75 * v + 0.4275 * t_f * v
return round(wc, 1)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['-40F with 0 km/h wind', [-40, 0], -40], ['-40F with 3 km/h wind', [-40, 3], -40], ['-40F with 4 km/h wind', [-40, 4], -40], ['-40F with 4.8 km/h wind', [-40, 4.8], -40], ['-40F with 5 km/h wind', [-40, 5], -52.5], ['-40F with 8 km/h wind', [-40, 8], -57.4], ['-40F with 16 km/h wind', [-40, 16], -65.4], ['-40F with 32 km/h wind', [-40, 32], -74.4]], [['-40F with 5 km/h wind', [-40, 5], -52.5], ['-40F with 32 km/h wind', [-40, 32], -74.4], ['-40F with 64 km/h wind', [-40, 64], -84.4], ['-40F with 100 km/h wind', [-40, 100], -91.4], ['-20F with 0 km/h wind', [-20, 0], -20], ['-20F with 3 km/h wind', [-20, 3], -20], ['-20F with 4 km/h wind', [-20, 4], -20], ['-20F with 5 km/h wind', [-20, 5], -29.8]], [['-40F with 32 km/h wind', [-40, 32], -74.4], ['-20F with 5 km/h wind', [-20, 5], -29.8], ['-20F with 8 km/h wind', [-20, 8], -33.9], ['-20F with 16 km/h wind', [-20, 16], -40.7], ['-20F with 32 km/h wind', [-20, 32], -48.2], ['-20F with 64 km/h wind', [-20, 64], -56.5], ['-20F with 100 km/h wind', [-20, 100], -62.5], ['-5F with 0 km/h wind', [-5, 0], -5]], [['-20F with 3 km/h wind', [-20, 3], -20], ['-5F with 3 km/h wind', [-5, 3], -5], ['-5F with 4 km/h wind', [-5, 4], -5], ['-5F with 4.8 km/h wind', [-5, 4.8], -5], ['-5F with 5 km/h wind', [-5, 5], -12.8], ['-5F with 8 km/h wind', [-5, 8], -16.3], ['-5F with 16 km/h wind', [-5, 16], -22.1], ['-5F with 64 km/h wind', [-5, 64], -35.7]], [['-20F with 5 km/h wind', [-20, 5], -29.8], ['-5F with 64 km/h wind', [-5, 64], -35.7], ['-5F with 100 km/h wind', [-5, 100], -40.7], ['0F with 0 km/h wind', [0, 0], 0], ['0F with 3 km/h wind', [0, 3], 0], ['0F with 4 km/h wind', [0, 4], 0], ['0F with 4.8 km/h wind', [0, 4.8], 0], ['0F with 32 km/h wind', [0, 32], -21.9]]]
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 |
|---|---|---|---|
| -40F with 0 km/h wind | -40 | -40 | Passed |
| -40F with 3 km/h wind | -40 | -40 | Passed |
| -40F with 4 km/h wind | -40 | -40 | Passed |
| -40F with 4.8 km/h wind | -40 | -40 | Passed |
| -40F with 5 km/h wind | -52.5 | -52.5 | Passed |
| -40F with 8 km/h wind | -57.4 | -57.4 | Passed |
| -40F with 16 km/h wind | -65.4 | -65.4 | Passed |
| -40F with 32 km/h wind | -74.4 | -74.4 | Passed |
SHA-256 / cfc5dff7556c6e8582557638adf36ad115b342a37d5e4808a7eca400aa398185
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:24.634695+00:00.
Case digest / ac3c3fc07d7d8069343043feb77c9eeb2bc8aa95e6861313083c8770ffe6048c