FA-70881 / Weather index computation / Open access
Wind chill from km/h anemometer: temperature-wind interaction term · case 01
Wind chill no longer converges as wind changes; values are off by several degrees.
ROOT CAUSE
The interaction term drops the V^0.16 factor.
VERIFIED REPAIR
Use 0.4275*T*V^0.16.
Unsuccessful approach: Keeping V^0.16 but dropping T removes the temperature dependence of the interaction.
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
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 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 4.8 km/h wind', [-20, 4.8], -20], ['-20F with 5 km/h wind', [-20, 5], -29.8]], [['-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], ['-5F with 3 km/h wind', [-5, 3], -5]], [['-20F with 32 km/h wind', [-20, 32], -48.2], ['-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]], [['-5F with 5 km/h wind', [-5, 5], -12.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 | -49.1 | -52.5 | Failed |
| -40F with 8 km/h wind | -52.4 | -57.4 | Failed |
| -40F with 16 km/h wind | -57.8 | -65.4 | Failed |
| -40F with 32 km/h wind | -63.9 | -74.4 | Failed |
SHA-256 / f8b9fda78e9bf7ce9d450cfa47929fff7613e39cb87701ecddfa425a9945a72b
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.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 * 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 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 4.8 km/h wind', [-20, 4.8], -20], ['-20F with 5 km/h wind', [-20, 5], -29.8]], [['-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], ['-5F with 3 km/h wind', [-5, 3], -5]], [['-20F with 32 km/h wind', [-20, 32], -48.2], ['-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]], [['-5F with 5 km/h wind', [-5, 5], -12.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 | -31.5 | -52.5 | Failed |
| -40F with 8 km/h wind | -34.8 | -57.4 | Failed |
| -40F with 16 km/h wind | -40.1 | -65.4 | Failed |
| -40F with 32 km/h wind | -46.1 | -74.4 | Failed |
SHA-256 / 1994af3f71d7ed21c39d2cf675893a6ca0a926d565cf32acb27c544247ab9759
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 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 4.8 km/h wind', [-20, 4.8], -20], ['-20F with 5 km/h wind', [-20, 5], -29.8]], [['-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], ['-5F with 3 km/h wind', [-5, 3], -5]], [['-20F with 32 km/h wind', [-20, 32], -48.2], ['-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]], [['-5F with 5 km/h wind', [-5, 5], -12.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 / 9764b6260218d210f6dfbad67a67b3af3fefc0ce364a3985c9336a1ee6509801
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.778514+00:00.
Case digest / 9d7f481ddd9e90207e980f4a124b6b0c6ed0151f3c8f22710e98cd111b32af6d