FA-96996 / Recipe scaling and nutrition / Open access
Atwater energy calculator: kilojoule rounding stage · case 01
kJ disagrees with the exact energy because it is converted from the rounded kcal.
ROOT CAUSE
Kilojoules are computed from the already rounded kilocalories.
VERIFIED REPAIR
Convert the exact kcal to kJ and round once.
Unsuccessful approach: Floor-dividing the rounded kcal compounds two rounding steps.
Case contract
Gram amounts as strings. Total carbohydrate includes fiber and polyols; available carb = max(0, carb - fiber - polyol). kcal = 4*protein + 9*fat + 4*available + 2*fiber + 7*alcohol + 2.4*polyol. Return [kcal, kJ, fat_energy_pct]: kcal half-up integer of the exact energy, kJ half-up integer of exact kcal * 4.184, fat pct = half-up of 9*fat/exact kcal*100 (0 if energy is 0).
Why this case matters
Recipe energy totals use factor systems where fiber and sugar alcohols are not full carbohydrate.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(protein, fat, carb, fiber, alcohol, polyol):
p, fat, carb, fib, alc, poly = (Fraction(v) for v in (protein, fat, carb, fiber, alcohol, polyol))
avail = carb - fib - poly
avail = max(avail, Fraction(0))
exact = 4 * p + 9 * fat + 4 * avail + 2 * fib + 7 * alc + Fraction(12, 5) * poly
def r(x):
return math.floor(x + Fraction(1, 2))
kj = r(r(exact) * Fraction(4184, 1000))
pct_fat = r(9 * fat * 100 / exact) if exact else 0
return [r(exact), kj, pct_fat]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['all zero', ['0', '0', '0', '0', '0', '0'], [0, 0, 0]],
['fat only', ['0', '10', '0', '0', '0', '0'], [90, 377, 100]],
['fiber heavier than carb', ['5', '1', '3', '6', '0', '0'], [41, 172, 22]],
['regression: kilojoule rounding stage', ['17', '20', '13', '5', '0', '4'], [284, 1187, 63]],
['repair check: kilojoule rounding stage', ['2', '11', '10', '2', '0', '4'], [137, 572, 72]],
['generated control 1', ['32', '85/4', '53', '3', '0', '4'], [519, 2171, 37]],
['generated control 2', ['39', '0', '20', '3', '14', '10'], [312, 1305, 0]],
['generated control 3', ['31', '21/2', '31', '5', '14', '4'], [424, 1774, 22]]],
[['fat only', ['0', '10', '0', '0', '0', '0'], [90, 377, 100]],
['fiber heavier than carb', ['5', '1', '3', '6', '0', '0'], [41, 172, 22]],
['sugar-free candy', ['0', '5', '30', '1', '0', '20'], [131, 548, 34]],
['regression: kilojoule rounding stage', ['36', '51/4', '19', '3', '0', '0'], [329, 1375, 35]],
['repair check: kilojoule rounding stage', ['40', '5/2', '59', '8', '14', '0'], [501, 2094, 4]],
['generated control 1', ['37', '11', '23', '1', '5', '0'], [372, 1556, 27]],
['generated control 2', ['21', '2', '0', '2', '5', '4'], [151, 630, 12]],
['generated control 3', ['8', '4', '18', '1', '14', '10'], [220, 920, 16]]],
[['fiber heavier than carb', ['5', '1', '3', '6', '0', '0'], [41, 172, 22]],
['sugar-free candy', ['0', '5', '30', '1', '0', '20'], [131, 548, 34]],
['cocktail', ['0', '0', '12', '0', '14', '0'], [146, 611, 0]],
['regression: kilojoule rounding stage', ['18', '13', '33', '1', '14', '4'], [411, 1718, 28]],
['repair check: kilojoule rounding stage', ['34', '51/2', '31', '33', '5', '4'], [476, 1992, 48]],
['generated control 1', ['23', '14', '45', '47', '5', '10'], [371, 1552, 34]],
['generated control 2', ['31', '16', '4', '1', '0', '10'], [294, 1230, 49]],
['generated control 3', ['21', '26', '0', '5', '0', '0'], [328, 1372, 71]]],
[['sugar-free candy', ['0', '5', '30', '1', '0', '20'], [131, 548, 34]],
['cocktail', ['0', '0', '12', '0', '14', '0'], [146, 611, 0]],
['all zero', ['0', '0', '0', '0', '0', '0'], [0, 0, 0]],
['regression: kilojoule rounding stage', ['2', '6', '0', '8', '0', '4'], [88, 367, 62]],
['repair check: kilojoule rounding stage', ['20', '23', '57', '59', '0', '0'], [405, 1695, 51]],
['generated control 1', ['31', '6', '40', '0', '14', '0'], [436, 1824, 12]],
['generated control 2', ['24', '2', '46', '3', '0', '0'], [292, 1222, 6]],
['generated control 3', ['8', '18', '15', '2', '0', '0'], [250, 1046, 65]]],
[['cocktail', ['0', '0', '12', '0', '14', '0'], [146, 611, 0]],
['all zero', ['0', '0', '0', '0', '0', '0'], [0, 0, 0]],
['fat only', ['0', '10', '0', '0', '0', '0'], [90, 377, 100]],
['regression: kilojoule rounding stage', ['26', '9', '59', '0', '5', '4'], [450, 1881, 18]],
['repair check: kilojoule rounding stage', ['11', '23', '15', '8', '5', '0'], [330, 1381, 63]],
['generated control 1', ['8', '6', '0', '1', '14', '10'], [210, 879, 26]],
['generated control 2', ['36', '10', '7', '0', '5', '0'], [297, 1243, 30]],
['generated control 3', ['4', '26', '7', '9', '14', '10'], [390, 1632, 60]]]]
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 |
|---|---|---|---|
| all zero | [0, 0, 0] | [0, 0, 0] | Passed |
| fat only | [90, 377, 100] | [90, 377, 100] | Passed |
| fiber heavier than carb | [41, 172, 22] | [41, 172, 22] | Passed |
| regression: kilojoule rounding stage | [284, 1188, 63] | [284, 1187, 63] | Failed |
| repair check: kilojoule rounding stage | [137, 573, 72] | [137, 572, 72] | Failed |
| generated control 1 | [519, 2171, 37] | [519, 2171, 37] | Passed |
| generated control 2 | [312, 1305, 0] | [312, 1305, 0] | Passed |
| generated control 3 | [424, 1774, 22] | [424, 1774, 22] | Passed |
SHA-256 / ce1ce982ffd46381ad0bd09202df1caa1d1085ec34619194f594897b0f292667
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(protein, fat, carb, fiber, alcohol, polyol):
p, fat, carb, fib, alc, poly = (Fraction(v) for v in (protein, fat, carb, fiber, alcohol, polyol))
avail = carb - fib - poly
avail = max(avail, Fraction(0))
exact = 4 * p + 9 * fat + 4 * avail + 2 * fib + 7 * alc + Fraction(12, 5) * poly
def r(x):
return math.floor(x + Fraction(1, 2))
kj = r(exact) * 4184 // 1000
pct_fat = r(9 * fat * 100 / exact) if exact else 0
return [r(exact), kj, pct_fat]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['all zero', ['0', '0', '0', '0', '0', '0'], [0, 0, 0]],
['fat only', ['0', '10', '0', '0', '0', '0'], [90, 377, 100]],
['fiber heavier than carb', ['5', '1', '3', '6', '0', '0'], [41, 172, 22]],
['regression: kilojoule rounding stage', ['17', '20', '13', '5', '0', '4'], [284, 1187, 63]],
['repair check: kilojoule rounding stage', ['2', '11', '10', '2', '0', '4'], [137, 572, 72]],
['generated control 1', ['32', '85/4', '53', '3', '0', '4'], [519, 2171, 37]],
['generated control 2', ['39', '0', '20', '3', '14', '10'], [312, 1305, 0]],
['generated control 3', ['31', '21/2', '31', '5', '14', '4'], [424, 1774, 22]]],
[['fat only', ['0', '10', '0', '0', '0', '0'], [90, 377, 100]],
['fiber heavier than carb', ['5', '1', '3', '6', '0', '0'], [41, 172, 22]],
['sugar-free candy', ['0', '5', '30', '1', '0', '20'], [131, 548, 34]],
['regression: kilojoule rounding stage', ['36', '51/4', '19', '3', '0', '0'], [329, 1375, 35]],
['repair check: kilojoule rounding stage', ['40', '5/2', '59', '8', '14', '0'], [501, 2094, 4]],
['generated control 1', ['37', '11', '23', '1', '5', '0'], [372, 1556, 27]],
['generated control 2', ['21', '2', '0', '2', '5', '4'], [151, 630, 12]],
['generated control 3', ['8', '4', '18', '1', '14', '10'], [220, 920, 16]]],
[['fiber heavier than carb', ['5', '1', '3', '6', '0', '0'], [41, 172, 22]],
['sugar-free candy', ['0', '5', '30', '1', '0', '20'], [131, 548, 34]],
['cocktail', ['0', '0', '12', '0', '14', '0'], [146, 611, 0]],
['regression: kilojoule rounding stage', ['18', '13', '33', '1', '14', '4'], [411, 1718, 28]],
['repair check: kilojoule rounding stage', ['34', '51/2', '31', '33', '5', '4'], [476, 1992, 48]],
['generated control 1', ['23', '14', '45', '47', '5', '10'], [371, 1552, 34]],
['generated control 2', ['31', '16', '4', '1', '0', '10'], [294, 1230, 49]],
['generated control 3', ['21', '26', '0', '5', '0', '0'], [328, 1372, 71]]],
[['sugar-free candy', ['0', '5', '30', '1', '0', '20'], [131, 548, 34]],
['cocktail', ['0', '0', '12', '0', '14', '0'], [146, 611, 0]],
['all zero', ['0', '0', '0', '0', '0', '0'], [0, 0, 0]],
['regression: kilojoule rounding stage', ['2', '6', '0', '8', '0', '4'], [88, 367, 62]],
['repair check: kilojoule rounding stage', ['20', '23', '57', '59', '0', '0'], [405, 1695, 51]],
['generated control 1', ['31', '6', '40', '0', '14', '0'], [436, 1824, 12]],
['generated control 2', ['24', '2', '46', '3', '0', '0'], [292, 1222, 6]],
['generated control 3', ['8', '18', '15', '2', '0', '0'], [250, 1046, 65]]],
[['cocktail', ['0', '0', '12', '0', '14', '0'], [146, 611, 0]],
['all zero', ['0', '0', '0', '0', '0', '0'], [0, 0, 0]],
['fat only', ['0', '10', '0', '0', '0', '0'], [90, 377, 100]],
['regression: kilojoule rounding stage', ['26', '9', '59', '0', '5', '4'], [450, 1881, 18]],
['repair check: kilojoule rounding stage', ['11', '23', '15', '8', '5', '0'], [330, 1381, 63]],
['generated control 1', ['8', '6', '0', '1', '14', '10'], [210, 879, 26]],
['generated control 2', ['36', '10', '7', '0', '5', '0'], [297, 1243, 30]],
['generated control 3', ['4', '26', '7', '9', '14', '10'], [390, 1632, 60]]]]
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 |
|---|---|---|---|
| all zero | [0, 0, 0] | [0, 0, 0] | Passed |
| fat only | [90, 376, 100] | [90, 377, 100] | Failed |
| fiber heavier than carb | [41, 171, 22] | [41, 172, 22] | Failed |
| regression: kilojoule rounding stage | [284, 1188, 63] | [284, 1187, 63] | Failed |
| repair check: kilojoule rounding stage | [137, 573, 72] | [137, 572, 72] | Failed |
| generated control 1 | [519, 2171, 37] | [519, 2171, 37] | Passed |
| generated control 2 | [312, 1305, 0] | [312, 1305, 0] | Passed |
| generated control 3 | [424, 1774, 22] | [424, 1774, 22] | Passed |
SHA-256 / 46e1ce965e9690b29a2399d3c3c435adcedf6ff0f2d0e635ae7a42ffe868dc84
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(protein, fat, carb, fiber, alcohol, polyol):
p, fat, carb, fib, alc, poly = (Fraction(v) for v in (protein, fat, carb, fiber, alcohol, polyol))
avail = carb - fib - poly
avail = max(avail, Fraction(0))
exact = 4 * p + 9 * fat + 4 * avail + 2 * fib + 7 * alc + Fraction(12, 5) * poly
def r(x):
return math.floor(x + Fraction(1, 2))
kj = r(exact * Fraction(4184, 1000))
pct_fat = r(9 * fat * 100 / exact) if exact else 0
return [r(exact), kj, pct_fat]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['all zero', ['0', '0', '0', '0', '0', '0'], [0, 0, 0]],
['fat only', ['0', '10', '0', '0', '0', '0'], [90, 377, 100]],
['fiber heavier than carb', ['5', '1', '3', '6', '0', '0'], [41, 172, 22]],
['regression: kilojoule rounding stage', ['17', '20', '13', '5', '0', '4'], [284, 1187, 63]],
['repair check: kilojoule rounding stage', ['2', '11', '10', '2', '0', '4'], [137, 572, 72]],
['generated control 1', ['32', '85/4', '53', '3', '0', '4'], [519, 2171, 37]],
['generated control 2', ['39', '0', '20', '3', '14', '10'], [312, 1305, 0]],
['generated control 3', ['31', '21/2', '31', '5', '14', '4'], [424, 1774, 22]]],
[['fat only', ['0', '10', '0', '0', '0', '0'], [90, 377, 100]],
['fiber heavier than carb', ['5', '1', '3', '6', '0', '0'], [41, 172, 22]],
['sugar-free candy', ['0', '5', '30', '1', '0', '20'], [131, 548, 34]],
['regression: kilojoule rounding stage', ['36', '51/4', '19', '3', '0', '0'], [329, 1375, 35]],
['repair check: kilojoule rounding stage', ['40', '5/2', '59', '8', '14', '0'], [501, 2094, 4]],
['generated control 1', ['37', '11', '23', '1', '5', '0'], [372, 1556, 27]],
['generated control 2', ['21', '2', '0', '2', '5', '4'], [151, 630, 12]],
['generated control 3', ['8', '4', '18', '1', '14', '10'], [220, 920, 16]]],
[['fiber heavier than carb', ['5', '1', '3', '6', '0', '0'], [41, 172, 22]],
['sugar-free candy', ['0', '5', '30', '1', '0', '20'], [131, 548, 34]],
['cocktail', ['0', '0', '12', '0', '14', '0'], [146, 611, 0]],
['regression: kilojoule rounding stage', ['18', '13', '33', '1', '14', '4'], [411, 1718, 28]],
['repair check: kilojoule rounding stage', ['34', '51/2', '31', '33', '5', '4'], [476, 1992, 48]],
['generated control 1', ['23', '14', '45', '47', '5', '10'], [371, 1552, 34]],
['generated control 2', ['31', '16', '4', '1', '0', '10'], [294, 1230, 49]],
['generated control 3', ['21', '26', '0', '5', '0', '0'], [328, 1372, 71]]],
[['sugar-free candy', ['0', '5', '30', '1', '0', '20'], [131, 548, 34]],
['cocktail', ['0', '0', '12', '0', '14', '0'], [146, 611, 0]],
['all zero', ['0', '0', '0', '0', '0', '0'], [0, 0, 0]],
['regression: kilojoule rounding stage', ['2', '6', '0', '8', '0', '4'], [88, 367, 62]],
['repair check: kilojoule rounding stage', ['20', '23', '57', '59', '0', '0'], [405, 1695, 51]],
['generated control 1', ['31', '6', '40', '0', '14', '0'], [436, 1824, 12]],
['generated control 2', ['24', '2', '46', '3', '0', '0'], [292, 1222, 6]],
['generated control 3', ['8', '18', '15', '2', '0', '0'], [250, 1046, 65]]],
[['cocktail', ['0', '0', '12', '0', '14', '0'], [146, 611, 0]],
['all zero', ['0', '0', '0', '0', '0', '0'], [0, 0, 0]],
['fat only', ['0', '10', '0', '0', '0', '0'], [90, 377, 100]],
['regression: kilojoule rounding stage', ['26', '9', '59', '0', '5', '4'], [450, 1881, 18]],
['repair check: kilojoule rounding stage', ['11', '23', '15', '8', '5', '0'], [330, 1381, 63]],
['generated control 1', ['8', '6', '0', '1', '14', '10'], [210, 879, 26]],
['generated control 2', ['36', '10', '7', '0', '5', '0'], [297, 1243, 30]],
['generated control 3', ['4', '26', '7', '9', '14', '10'], [390, 1632, 60]]]]
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 |
|---|---|---|---|
| all zero | [0, 0, 0] | [0, 0, 0] | Passed |
| fat only | [90, 377, 100] | [90, 377, 100] | Passed |
| fiber heavier than carb | [41, 172, 22] | [41, 172, 22] | Passed |
| regression: kilojoule rounding stage | [284, 1187, 63] | [284, 1187, 63] | Passed |
| repair check: kilojoule rounding stage | [137, 572, 72] | [137, 572, 72] | Passed |
| generated control 1 | [519, 2171, 37] | [519, 2171, 37] | Passed |
| generated control 2 | [312, 1305, 0] | [312, 1305, 0] | Passed |
| generated control 3 | [424, 1774, 22] | [424, 1774, 22] | Passed |
SHA-256 / 4fa56a0fa42b301e8ea1ec0b548ffe0cab6e36813bbcb295cee049eb3af5ef8c
Verification & scope
A deterministic toy contract stated in full here; it is a bounded teaching model, not an authoritative reference or standards implementation. 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:52:27.825014+00:00.
Case digest / 8e88b62f5429872eebc196a1815d48568f624c930714dbf6fbf509a0ade28939