FAILURE MAP
← Case archive

FA-58321 / Double-entry ledger accounting / Open access

Straight-line depreciation journal: accumulated cap · case 01

Mid-month assets depreciate below salvage value in the final month.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

Accumulated depreciation is capped at cost instead of the depreciable base.

VERIFIED REPAIR

Cap accumulated depreciation at cost minus salvage.

Unsuccessful approach: Exempting mid_month from the cap leaves that convention able to overshoot.

Case contract

x = {'cost', 'salvage', 'life_months', 'start_month', 'convention': 'full_month'|'mid_month'|'next_month', 'through': last month to post}. Depreciable base = cost - salvage. The first charge month is start_month (start_month + 1 for next_month). Charges use cumulative rounding: target accumulated after the j-th charge month is round(base*j/life) or, for mid_month, round(base*(2j-1)/(2*life)), half-up and capped at base; each month posts target - accumulated. Posting stops after 'through' or once accumulated reaches base. Return {'schedule': [[month, amount]], 'accumulated', 'book_value': cost - accumulated}.

Why this case matters

Ledger software must keep debits equal to credits and apply normal-balance, period and cutoff rules exactly; small sign or boundary slips silently misstate financial statements.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    def rnd(n, d):
        q, r = divmod(n, d)
        return q + (1 if 2 * r >= d else 0)
    base = x['cost'] - x['salvage']
    life = x['life_months']
    conv = x['convention']
    first = x['start_month'] + (1 if conv == 'next_month' else 0)
    acc = 0
    rows = []
    month = first
    while month <= x['through'] and acc < base:
        j = month - first + 1
        if conv == 'mid_month':
            target = rnd(base * (2 * j - 1), 2 * life)
        else:
            target = rnd(base * j, life)
        target = min(target, x['cost'])
        rows.append([month, target - acc])
        acc = target
        month += 1
    return {'schedule': rows, 'accumulated': acc, 'book_value': x['cost'] - acc}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: accumulated cap', {'cost': 5000, 'salvage': 7, 'life_months': 7, 'start_month': 1, 'convention': 'mid_month', 'through': 40}, {'schedule': [[1, 357], [2, 713], [3, 713], [4, 714], [5, 713], [6, 713], [7, 713], [8, 357]], 'accumulated': 4993, 'book_value': 7}], ['control 1', {'cost': 5000, 'salvage': 0, 'life_months': 12, 'start_month': 1, 'convention': 'mid_month', 'through': 80}, {'schedule': [[1, 208], [2, 417], [3, 417], [4, 416], [5, 417], [6, 417], [7, 416], [8, 417], [9, 417], [10, 416], [11, 417], [12, 417], [13, 208]], 'accumulated': 5000, 'book_value': 0}], ['control 2', {'cost': 5000, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 5000}], ['control 3', {'cost': 120000, 'salvage': 7, 'life_months': 7, 'start_month': 10, 'convention': 'full_month', 'through': 80}, {'schedule': [[10, 17142], [11, 17142], [12, 17142], [13, 17141], [14, 17142], [15, 17142], [16, 17142]], 'accumulated': 119993, 'book_value': 7}], ['control 4', {'cost': 5000, 'salvage': 1000, 'life_months': 12, 'start_month': 1, 'convention': 'mid_month', 'through': 12}, {'schedule': [[1, 167], [2, 333], [3, 333], [4, 334], [5, 333], [6, 333], [7, 334], [8, 333], [9, 333], [10, 334], [11, 333], [12, 333]], 'accumulated': 3833, 'book_value': 1167}], ['control 5', {'cost': 36000, 'salvage': 0, 'life_months': 12, 'start_month': 3, 'convention': 'full_month', 'through': 3}, {'schedule': [[3, 3000]], 'accumulated': 3000, 'book_value': 33000}], ['control 6', {'cost': 5000, 'salvage': 1000, 'life_months': 36, 'start_month': 3, 'convention': 'mid_month', 'through': 12}, {'schedule': [[3, 56], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 111], [11, 111], [12, 112]], 'accumulated': 1056, 'book_value': 3944}]], [['regression: accumulated cap', {'cost': 99999, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'mid_month', 'through': 40}, {'schedule': [[10, 3667], [11, 7333], [12, 7333], [13, 7333], [14, 7334], [15, 7333], [16, 7333], [17, 7333], [18, 7334], [19, 7333], [20, 7333], [21, 7333], [22, 3667]], 'accumulated': 87999, 'book_value': 12000}], ['control 1', {'cost': 99999, 'salvage': 1000, 'life_months': 60, 'start_month': 3, 'convention': 'next_month', 'through': 40}, {'schedule': [[4, 1650], [5, 1650], [6, 1650], [7, 1650], [8, 1650], [9, 1650], [10, 1650], [11, 1650], [12, 1650], [13, 1650], [14, 1650], [15, 1650], [16, 1650], [17, 1650], [18, 1650], [19, 1650], [20, 1650], [21, 1650], [22, 1650], [23, 1650], [24, 1650], [25, 1650], [26, 1650], [27, 1650], [28, 1650], [29, 1650], [30, 1650], [31, 1650], [32, 1650], [33, 1650], [34, 1649], [35, 1650], [36, 1650], [37, 1650], [38, 1650], [39, 1650], [40, 1650]], 'accumulated': 61049, 'book_value': 38950}], ['control 2', {'cost': 36000, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'next_month', 'through': 40}, {'schedule': [[11, 2000], [12, 2000], [13, 2000], [14, 2000], [15, 2000], [16, 2000], [17, 2000], [18, 2000], [19, 2000], [20, 2000], [21, 2000], [22, 2000]], 'accumulated': 24000, 'book_value': 12000}], ['control 3', {'cost': 120000, 'salvage': 1000, 'life_months': 60, 'start_month': 10, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 120000}], ['control 4', {'cost': 36000, 'salvage': 0, 'life_months': 60, 'start_month': 10, 'convention': 'next_month', 'through': 80}, {'schedule': [[11, 600], [12, 600], [13, 600], [14, 600], [15, 600], [16, 600], [17, 600], [18, 600], [19, 600], [20, 600], [21, 600], [22, 600], [23, 600], [24, 600], [25, 600], [26, 600], [27, 600], [28, 600], [29, 600], [30, 600], [31, 600], [32, 600], [33, 600], [34, 600], [35, 600], [36, 600], [37, 600], [38, 600], [39, 600], [40, 600], [41, 600], [42, 600], [43, 600], [44, 600], [45, 600], [46, 600], [47, 600], [48, 600], [49, 600], [50, 600], [51, 600], [52, 600], [53, 600], [54, 600], [55, 600], [56, 600], [57, 600], [58, 600], [59, 600], [60, 600], [61, 600], [62, 600], [63, 600], [64, 600], [65, 600], [66, 600], [67, 600], [68, 600], [69, 600], [70, 600]], 'accumulated': 36000, 'book_value': 0}], ['control 5', {'cost': 100000, 'salvage': 7, 'life_months': 60, 'start_month': 1, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 100000}], ['control 6', {'cost': 36000, 'salvage': 7, 'life_months': 36, 'start_month': 3, 'convention': 'full_month', 'through': 3}, {'schedule': [[3, 1000]], 'accumulated': 1000, 'book_value': 35000}]], [['regression: accumulated cap', {'cost': 100000, 'salvage': 7, 'life_months': 7, 'start_month': 1, 'convention': 'mid_month', 'through': 80}, {'schedule': [[1, 7142], [2, 14285], [3, 14285], [4, 14285], [5, 14284], [6, 14285], [7, 14285], [8, 7142]], 'accumulated': 99993, 'book_value': 7}], ['control 1', {'cost': 36000, 'salvage': 0, 'life_months': 7, 'start_month': 3, 'convention': 'mid_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 36000}], ['control 2', {'cost': 100000, 'salvage': 12000, 'life_months': 7, 'start_month': 1, 'convention': 'next_month', 'through': 12}, {'schedule': [[2, 12571], [3, 12572], [4, 12571], [5, 12572], [6, 12571], [7, 12572], [8, 12571]], 'accumulated': 88000, 'book_value': 12000}], ['control 3', {'cost': 100000, 'salvage': 0, 'life_months': 12, 'start_month': 3, 'convention': 'next_month', 'through': 12}, {'schedule': [[4, 8333], [5, 8334], [6, 8333], [7, 8333], [8, 8334], [9, 8333], [10, 8333], [11, 8334], [12, 8333]], 'accumulated': 75000, 'book_value': 25000}], ['control 4', {'cost': 36000, 'salvage': 0, 'life_months': 60, 'start_month': 1, 'convention': 'next_month', 'through': 80}, {'schedule': [[2, 600], [3, 600], [4, 600], [5, 600], [6, 600], [7, 600], [8, 600], [9, 600], [10, 600], [11, 600], [12, 600], [13, 600], [14, 600], [15, 600], [16, 600], [17, 600], [18, 600], [19, 600], [20, 600], [21, 600], [22, 600], [23, 600], [24, 600], [25, 600], [26, 600], [27, 600], [28, 600], [29, 600], [30, 600], [31, 600], [32, 600], [33, 600], [34, 600], [35, 600], [36, 600], [37, 600], [38, 600], [39, 600], [40, 600], [41, 600], [42, 600], [43, 600], [44, 600], [45, 600], [46, 600], [47, 600], [48, 600], [49, 600], [50, 600], [51, 600], [52, 600], [53, 600], [54, 600], [55, 600], [56, 600], [57, 600], [58, 600], [59, 600], [60, 600], [61, 600]], 'accumulated': 36000, 'book_value': 0}], ['control 5', {'cost': 36000, 'salvage': 1000, 'life_months': 7, 'start_month': 3, 'convention': 'full_month', 'through': 40}, {'schedule': [[3, 5000], [4, 5000], [5, 5000], [6, 5000], [7, 5000], [8, 5000], [9, 5000]], 'accumulated': 35000, 'book_value': 1000}], ['control 6', {'cost': 99999, 'salvage': 7, 'life_months': 12, 'start_month': 3, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 99999}]], [['regression: accumulated cap', {'cost': 36000, 'salvage': 7, 'life_months': 7, 'start_month': 10, 'convention': 'mid_month', 'through': 80}, {'schedule': [[10, 2571], [11, 5142], [12, 5142], [13, 5142], [14, 5141], [15, 5142], [16, 5142], [17, 2571]], 'accumulated': 35993, 'book_value': 7}], ['control 1', {'cost': 36000, 'salvage': 7, 'life_months': 36, 'start_month': 1, 'convention': 'mid_month', 'through': 3}, {'schedule': [[1, 500], [2, 1000], [3, 1000]], 'accumulated': 2500, 'book_value': 33500}], ['control 2', {'cost': 120000, 'salvage': 12000, 'life_months': 36, 'start_month': 3, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 120000}], ['control 3', {'cost': 36000, 'salvage': 0, 'life_months': 7, 'start_month': 1, 'convention': 'next_month', 'through': 80}, {'schedule': [[2, 5143], [3, 5143], [4, 5143], [5, 5142], [6, 5143], [7, 5143], [8, 5143]], 'accumulated': 36000, 'book_value': 0}], ['control 4', {'cost': 100000, 'salvage': 7, 'life_months': 60, 'start_month': 3, 'convention': 'mid_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 100000}], ['control 5', {'cost': 36000, 'salvage': 12000, 'life_months': 60, 'start_month': 10, 'convention': 'full_month', 'through': 12}, {'schedule': [[10, 400], [11, 400], [12, 400]], 'accumulated': 1200, 'book_value': 34800}], ['control 6', {'cost': 5000, 'salvage': 1000, 'life_months': 36, 'start_month': 1, 'convention': 'mid_month', 'through': 3}, {'schedule': [[1, 56], [2, 111], [3, 111]], 'accumulated': 278, 'book_value': 4722}]], [['regression: accumulated cap', {'cost': 100000, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'mid_month', 'through': 80}, {'schedule': [[10, 3667], [11, 7333], [12, 7333], [13, 7334], [14, 7333], [15, 7333], [16, 7334], [17, 7333], [18, 7333], [19, 7334], [20, 7333], [21, 7333], [22, 3667]], 'accumulated': 88000, 'book_value': 12000}], ['control 1', {'cost': 120000, 'salvage': 12000, 'life_months': 60, 'start_month': 10, 'convention': 'mid_month', 'through': 3}, {'schedule': [], 'accumulated': 0, 'book_value': 120000}], ['control 2', {'cost': 5000, 'salvage': 0, 'life_months': 36, 'start_month': 3, 'convention': 'next_month', 'through': 12}, {'schedule': [[4, 139], [5, 139], [6, 139], [7, 139], [8, 138], [9, 139], [10, 139], [11, 139], [12, 139]], 'accumulated': 1250, 'book_value': 3750}], ['control 3', {'cost': 120000, 'salvage': 1000, 'life_months': 36, 'start_month': 1, 'convention': 'full_month', 'through': 40}, {'schedule': [[1, 3306], [2, 3305], [3, 3306], [4, 3305], [5, 3306], [6, 3305], [7, 3306], [8, 3305], [9, 3306], [10, 3306], [11, 3305], [12, 3306], [13, 3305], [14, 3306], [15, 3305], [16, 3306], [17, 3305], [18, 3306], [19, 3306], [20, 3305], [21, 3306], [22, 3305], [23, 3306], [24, 3305], [25, 3306], [26, 3305], [27, 3306], [28, 3306], [29, 3305], [30, 3306], [31, 3305], [32, 3306], [33, 3305], [34, 3306], [35, 3305], [36, 3306]], 'accumulated': 119000, 'book_value': 1000}], ['control 4', {'cost': 5000, 'salvage': 1000, 'life_months': 36, 'start_month': 1, 'convention': 'mid_month', 'through': 12}, {'schedule': [[1, 56], [2, 111], [3, 111], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 112], [11, 111], [12, 111]], 'accumulated': 1278, 'book_value': 3722}], ['control 5', {'cost': 100000, 'salvage': 1000, 'life_months': 7, 'start_month': 3, 'convention': 'full_month', 'through': 3}, {'schedule': [[3, 14143]], 'accumulated': 14143, 'book_value': 85857}], ['control 6', {'cost': 99999, 'salvage': 0, 'life_months': 60, 'start_month': 3, 'convention': 'full_month', 'through': 40}, {'schedule': [[3, 1667], [4, 1666], [5, 1667], [6, 1667], [7, 1666], [8, 1667], [9, 1667], [10, 1666], [11, 1667], [12, 1667], [13, 1666], [14, 1667], [15, 1666], [16, 1667], [17, 1667], [18, 1666], [19, 1667], [20, 1667], [21, 1666], [22, 1667], [23, 1667], [24, 1666], [25, 1667], [26, 1667], [27, 1666], [28, 1667], [29, 1667], [30, 1666], [31, 1667], [32, 1667], [33, 1666], [34, 1667], [35, 1666], [36, 1667], [37, 1667], [38, 1666], [39, 1667], [40, 1667]], 'accumulated': 63333, 'book_value': 36666}]]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'raised ' + type(exc).__name__
    check(label, actual, 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 fixtureActualExpectedOutcome
regression: accumulated cap{'accumulated': 5000, 'book_value': 0, 'schedule': [[1, 357], [2, 713], [3, 713], [4, 714], [5, 713], [6, 713], [7, 713], [8, 364]]}{'accumulated': 4993, 'book_value': 7, 'schedule': [[1, 357], [2, 713], [3, 713], [4, 714], [5, 713], [6, 713], [7, 713], [8, 357]]}Failed
control 1{'accumulated': 5000, 'book_value': 0, 'schedule': [[1, 208], [2, 417], [3, 417], [4, 416], [5, 417], [6, 417], [7, 416], [8, 417], [9, 417], [10, 416], [11, 417], [12, 417], [13, 208]]}{'accumulated': 5000, 'book_value': 0, 'schedule': [[1, 208], [2, 417], [3, 417], [4, 416], [5, 417], [6, 417], [7, 416], [8, 417], [9, 417], [10, 416], [11, 417], [12, 417], [13, 208]]}Passed
control 2{'accumulated': 0, 'book_value': 5000, 'schedule': []}{'accumulated': 0, 'book_value': 5000, 'schedule': []}Passed
control 3{'accumulated': 119993, 'book_value': 7, 'schedule': [[10, 17142], [11, 17142], [12, 17142], [13, 17141], [14, 17142], [15, 17142], [16, 17142]]}{'accumulated': 119993, 'book_value': 7, 'schedule': [[10, 17142], [11, 17142], [12, 17142], [13, 17141], [14, 17142], [15, 17142], [16, 17142]]}Passed
control 4{'accumulated': 3833, 'book_value': 1167, 'schedule': [[1, 167], [2, 333], [3, 333], [4, 334], [5, 333], [6, 333], [7, 334], [8, 333], [9, 333], [10, 334], [11, 333], [12, 333]]}{'accumulated': 3833, 'book_value': 1167, 'schedule': [[1, 167], [2, 333], [3, 333], [4, 334], [5, 333], [6, 333], [7, 334], [8, 333], [9, 333], [10, 334], [11, 333], [12, 333]]}Passed
control 5{'accumulated': 3000, 'book_value': 33000, 'schedule': [[3, 3000]]}{'accumulated': 3000, 'book_value': 33000, 'schedule': [[3, 3000]]}Passed
control 6{'accumulated': 1056, 'book_value': 3944, 'schedule': [[3, 56], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 111], [11, 111], [12, 112]]}{'accumulated': 1056, 'book_value': 3944, 'schedule': [[3, 56], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 111], [11, 111], [12, 112]]}Passed

SHA-256 / 0d23d7734954635c4bd1bde4a5a242314a42a13fcf96f4ce52d639fa92cbb1ec

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    def rnd(n, d):
        q, r = divmod(n, d)
        return q + (1 if 2 * r >= d else 0)
    base = x['cost'] - x['salvage']
    life = x['life_months']
    conv = x['convention']
    first = x['start_month'] + (1 if conv == 'next_month' else 0)
    acc = 0
    rows = []
    month = first
    while month <= x['through'] and acc < base:
        j = month - first + 1
        if conv == 'mid_month':
            target = rnd(base * (2 * j - 1), 2 * life)
        else:
            target = rnd(base * j, life)
        target = min(target, base) if conv != 'mid_month' else target
        rows.append([month, target - acc])
        acc = target
        month += 1
    return {'schedule': rows, 'accumulated': acc, 'book_value': x['cost'] - acc}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: accumulated cap', {'cost': 5000, 'salvage': 7, 'life_months': 7, 'start_month': 1, 'convention': 'mid_month', 'through': 40}, {'schedule': [[1, 357], [2, 713], [3, 713], [4, 714], [5, 713], [6, 713], [7, 713], [8, 357]], 'accumulated': 4993, 'book_value': 7}], ['control 1', {'cost': 5000, 'salvage': 0, 'life_months': 12, 'start_month': 1, 'convention': 'mid_month', 'through': 80}, {'schedule': [[1, 208], [2, 417], [3, 417], [4, 416], [5, 417], [6, 417], [7, 416], [8, 417], [9, 417], [10, 416], [11, 417], [12, 417], [13, 208]], 'accumulated': 5000, 'book_value': 0}], ['control 2', {'cost': 5000, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 5000}], ['control 3', {'cost': 120000, 'salvage': 7, 'life_months': 7, 'start_month': 10, 'convention': 'full_month', 'through': 80}, {'schedule': [[10, 17142], [11, 17142], [12, 17142], [13, 17141], [14, 17142], [15, 17142], [16, 17142]], 'accumulated': 119993, 'book_value': 7}], ['control 4', {'cost': 5000, 'salvage': 1000, 'life_months': 12, 'start_month': 1, 'convention': 'mid_month', 'through': 12}, {'schedule': [[1, 167], [2, 333], [3, 333], [4, 334], [5, 333], [6, 333], [7, 334], [8, 333], [9, 333], [10, 334], [11, 333], [12, 333]], 'accumulated': 3833, 'book_value': 1167}], ['control 5', {'cost': 36000, 'salvage': 0, 'life_months': 12, 'start_month': 3, 'convention': 'full_month', 'through': 3}, {'schedule': [[3, 3000]], 'accumulated': 3000, 'book_value': 33000}], ['control 6', {'cost': 5000, 'salvage': 1000, 'life_months': 36, 'start_month': 3, 'convention': 'mid_month', 'through': 12}, {'schedule': [[3, 56], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 111], [11, 111], [12, 112]], 'accumulated': 1056, 'book_value': 3944}]], [['regression: accumulated cap', {'cost': 99999, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'mid_month', 'through': 40}, {'schedule': [[10, 3667], [11, 7333], [12, 7333], [13, 7333], [14, 7334], [15, 7333], [16, 7333], [17, 7333], [18, 7334], [19, 7333], [20, 7333], [21, 7333], [22, 3667]], 'accumulated': 87999, 'book_value': 12000}], ['control 1', {'cost': 99999, 'salvage': 1000, 'life_months': 60, 'start_month': 3, 'convention': 'next_month', 'through': 40}, {'schedule': [[4, 1650], [5, 1650], [6, 1650], [7, 1650], [8, 1650], [9, 1650], [10, 1650], [11, 1650], [12, 1650], [13, 1650], [14, 1650], [15, 1650], [16, 1650], [17, 1650], [18, 1650], [19, 1650], [20, 1650], [21, 1650], [22, 1650], [23, 1650], [24, 1650], [25, 1650], [26, 1650], [27, 1650], [28, 1650], [29, 1650], [30, 1650], [31, 1650], [32, 1650], [33, 1650], [34, 1649], [35, 1650], [36, 1650], [37, 1650], [38, 1650], [39, 1650], [40, 1650]], 'accumulated': 61049, 'book_value': 38950}], ['control 2', {'cost': 36000, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'next_month', 'through': 40}, {'schedule': [[11, 2000], [12, 2000], [13, 2000], [14, 2000], [15, 2000], [16, 2000], [17, 2000], [18, 2000], [19, 2000], [20, 2000], [21, 2000], [22, 2000]], 'accumulated': 24000, 'book_value': 12000}], ['control 3', {'cost': 120000, 'salvage': 1000, 'life_months': 60, 'start_month': 10, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 120000}], ['control 4', {'cost': 36000, 'salvage': 0, 'life_months': 60, 'start_month': 10, 'convention': 'next_month', 'through': 80}, {'schedule': [[11, 600], [12, 600], [13, 600], [14, 600], [15, 600], [16, 600], [17, 600], [18, 600], [19, 600], [20, 600], [21, 600], [22, 600], [23, 600], [24, 600], [25, 600], [26, 600], [27, 600], [28, 600], [29, 600], [30, 600], [31, 600], [32, 600], [33, 600], [34, 600], [35, 600], [36, 600], [37, 600], [38, 600], [39, 600], [40, 600], [41, 600], [42, 600], [43, 600], [44, 600], [45, 600], [46, 600], [47, 600], [48, 600], [49, 600], [50, 600], [51, 600], [52, 600], [53, 600], [54, 600], [55, 600], [56, 600], [57, 600], [58, 600], [59, 600], [60, 600], [61, 600], [62, 600], [63, 600], [64, 600], [65, 600], [66, 600], [67, 600], [68, 600], [69, 600], [70, 600]], 'accumulated': 36000, 'book_value': 0}], ['control 5', {'cost': 100000, 'salvage': 7, 'life_months': 60, 'start_month': 1, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 100000}], ['control 6', {'cost': 36000, 'salvage': 7, 'life_months': 36, 'start_month': 3, 'convention': 'full_month', 'through': 3}, {'schedule': [[3, 1000]], 'accumulated': 1000, 'book_value': 35000}]], [['regression: accumulated cap', {'cost': 100000, 'salvage': 7, 'life_months': 7, 'start_month': 1, 'convention': 'mid_month', 'through': 80}, {'schedule': [[1, 7142], [2, 14285], [3, 14285], [4, 14285], [5, 14284], [6, 14285], [7, 14285], [8, 7142]], 'accumulated': 99993, 'book_value': 7}], ['control 1', {'cost': 36000, 'salvage': 0, 'life_months': 7, 'start_month': 3, 'convention': 'mid_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 36000}], ['control 2', {'cost': 100000, 'salvage': 12000, 'life_months': 7, 'start_month': 1, 'convention': 'next_month', 'through': 12}, {'schedule': [[2, 12571], [3, 12572], [4, 12571], [5, 12572], [6, 12571], [7, 12572], [8, 12571]], 'accumulated': 88000, 'book_value': 12000}], ['control 3', {'cost': 100000, 'salvage': 0, 'life_months': 12, 'start_month': 3, 'convention': 'next_month', 'through': 12}, {'schedule': [[4, 8333], [5, 8334], [6, 8333], [7, 8333], [8, 8334], [9, 8333], [10, 8333], [11, 8334], [12, 8333]], 'accumulated': 75000, 'book_value': 25000}], ['control 4', {'cost': 36000, 'salvage': 0, 'life_months': 60, 'start_month': 1, 'convention': 'next_month', 'through': 80}, {'schedule': [[2, 600], [3, 600], [4, 600], [5, 600], [6, 600], [7, 600], [8, 600], [9, 600], [10, 600], [11, 600], [12, 600], [13, 600], [14, 600], [15, 600], [16, 600], [17, 600], [18, 600], [19, 600], [20, 600], [21, 600], [22, 600], [23, 600], [24, 600], [25, 600], [26, 600], [27, 600], [28, 600], [29, 600], [30, 600], [31, 600], [32, 600], [33, 600], [34, 600], [35, 600], [36, 600], [37, 600], [38, 600], [39, 600], [40, 600], [41, 600], [42, 600], [43, 600], [44, 600], [45, 600], [46, 600], [47, 600], [48, 600], [49, 600], [50, 600], [51, 600], [52, 600], [53, 600], [54, 600], [55, 600], [56, 600], [57, 600], [58, 600], [59, 600], [60, 600], [61, 600]], 'accumulated': 36000, 'book_value': 0}], ['control 5', {'cost': 36000, 'salvage': 1000, 'life_months': 7, 'start_month': 3, 'convention': 'full_month', 'through': 40}, {'schedule': [[3, 5000], [4, 5000], [5, 5000], [6, 5000], [7, 5000], [8, 5000], [9, 5000]], 'accumulated': 35000, 'book_value': 1000}], ['control 6', {'cost': 99999, 'salvage': 7, 'life_months': 12, 'start_month': 3, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 99999}]], [['regression: accumulated cap', {'cost': 36000, 'salvage': 7, 'life_months': 7, 'start_month': 10, 'convention': 'mid_month', 'through': 80}, {'schedule': [[10, 2571], [11, 5142], [12, 5142], [13, 5142], [14, 5141], [15, 5142], [16, 5142], [17, 2571]], 'accumulated': 35993, 'book_value': 7}], ['control 1', {'cost': 36000, 'salvage': 7, 'life_months': 36, 'start_month': 1, 'convention': 'mid_month', 'through': 3}, {'schedule': [[1, 500], [2, 1000], [3, 1000]], 'accumulated': 2500, 'book_value': 33500}], ['control 2', {'cost': 120000, 'salvage': 12000, 'life_months': 36, 'start_month': 3, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 120000}], ['control 3', {'cost': 36000, 'salvage': 0, 'life_months': 7, 'start_month': 1, 'convention': 'next_month', 'through': 80}, {'schedule': [[2, 5143], [3, 5143], [4, 5143], [5, 5142], [6, 5143], [7, 5143], [8, 5143]], 'accumulated': 36000, 'book_value': 0}], ['control 4', {'cost': 100000, 'salvage': 7, 'life_months': 60, 'start_month': 3, 'convention': 'mid_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 100000}], ['control 5', {'cost': 36000, 'salvage': 12000, 'life_months': 60, 'start_month': 10, 'convention': 'full_month', 'through': 12}, {'schedule': [[10, 400], [11, 400], [12, 400]], 'accumulated': 1200, 'book_value': 34800}], ['control 6', {'cost': 5000, 'salvage': 1000, 'life_months': 36, 'start_month': 1, 'convention': 'mid_month', 'through': 3}, {'schedule': [[1, 56], [2, 111], [3, 111]], 'accumulated': 278, 'book_value': 4722}]], [['regression: accumulated cap', {'cost': 100000, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'mid_month', 'through': 80}, {'schedule': [[10, 3667], [11, 7333], [12, 7333], [13, 7334], [14, 7333], [15, 7333], [16, 7334], [17, 7333], [18, 7333], [19, 7334], [20, 7333], [21, 7333], [22, 3667]], 'accumulated': 88000, 'book_value': 12000}], ['control 1', {'cost': 120000, 'salvage': 12000, 'life_months': 60, 'start_month': 10, 'convention': 'mid_month', 'through': 3}, {'schedule': [], 'accumulated': 0, 'book_value': 120000}], ['control 2', {'cost': 5000, 'salvage': 0, 'life_months': 36, 'start_month': 3, 'convention': 'next_month', 'through': 12}, {'schedule': [[4, 139], [5, 139], [6, 139], [7, 139], [8, 138], [9, 139], [10, 139], [11, 139], [12, 139]], 'accumulated': 1250, 'book_value': 3750}], ['control 3', {'cost': 120000, 'salvage': 1000, 'life_months': 36, 'start_month': 1, 'convention': 'full_month', 'through': 40}, {'schedule': [[1, 3306], [2, 3305], [3, 3306], [4, 3305], [5, 3306], [6, 3305], [7, 3306], [8, 3305], [9, 3306], [10, 3306], [11, 3305], [12, 3306], [13, 3305], [14, 3306], [15, 3305], [16, 3306], [17, 3305], [18, 3306], [19, 3306], [20, 3305], [21, 3306], [22, 3305], [23, 3306], [24, 3305], [25, 3306], [26, 3305], [27, 3306], [28, 3306], [29, 3305], [30, 3306], [31, 3305], [32, 3306], [33, 3305], [34, 3306], [35, 3305], [36, 3306]], 'accumulated': 119000, 'book_value': 1000}], ['control 4', {'cost': 5000, 'salvage': 1000, 'life_months': 36, 'start_month': 1, 'convention': 'mid_month', 'through': 12}, {'schedule': [[1, 56], [2, 111], [3, 111], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 112], [11, 111], [12, 111]], 'accumulated': 1278, 'book_value': 3722}], ['control 5', {'cost': 100000, 'salvage': 1000, 'life_months': 7, 'start_month': 3, 'convention': 'full_month', 'through': 3}, {'schedule': [[3, 14143]], 'accumulated': 14143, 'book_value': 85857}], ['control 6', {'cost': 99999, 'salvage': 0, 'life_months': 60, 'start_month': 3, 'convention': 'full_month', 'through': 40}, {'schedule': [[3, 1667], [4, 1666], [5, 1667], [6, 1667], [7, 1666], [8, 1667], [9, 1667], [10, 1666], [11, 1667], [12, 1667], [13, 1666], [14, 1667], [15, 1666], [16, 1667], [17, 1667], [18, 1666], [19, 1667], [20, 1667], [21, 1666], [22, 1667], [23, 1667], [24, 1666], [25, 1667], [26, 1667], [27, 1666], [28, 1667], [29, 1667], [30, 1666], [31, 1667], [32, 1667], [33, 1666], [34, 1667], [35, 1666], [36, 1667], [37, 1667], [38, 1666], [39, 1667], [40, 1667]], 'accumulated': 63333, 'book_value': 36666}]]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'raised ' + type(exc).__name__
    check(label, actual, 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 fixtureActualExpectedOutcome
regression: accumulated cap{'accumulated': 5350, 'book_value': -350, 'schedule': [[1, 357], [2, 713], [3, 713], [4, 714], [5, 713], [6, 713], [7, 713], [8, 714]]}{'accumulated': 4993, 'book_value': 7, 'schedule': [[1, 357], [2, 713], [3, 713], [4, 714], [5, 713], [6, 713], [7, 713], [8, 357]]}Failed
control 1{'accumulated': 5208, 'book_value': -208, 'schedule': [[1, 208], [2, 417], [3, 417], [4, 416], [5, 417], [6, 417], [7, 416], [8, 417], [9, 417], [10, 416], [11, 417], [12, 417], [13, 416]]}{'accumulated': 5000, 'book_value': 0, 'schedule': [[1, 208], [2, 417], [3, 417], [4, 416], [5, 417], [6, 417], [7, 416], [8, 417], [9, 417], [10, 416], [11, 417], [12, 417], [13, 208]]}Failed
control 2{'accumulated': 0, 'book_value': 5000, 'schedule': []}{'accumulated': 0, 'book_value': 5000, 'schedule': []}Passed
control 3{'accumulated': 119993, 'book_value': 7, 'schedule': [[10, 17142], [11, 17142], [12, 17142], [13, 17141], [14, 17142], [15, 17142], [16, 17142]]}{'accumulated': 119993, 'book_value': 7, 'schedule': [[10, 17142], [11, 17142], [12, 17142], [13, 17141], [14, 17142], [15, 17142], [16, 17142]]}Passed
control 4{'accumulated': 3833, 'book_value': 1167, 'schedule': [[1, 167], [2, 333], [3, 333], [4, 334], [5, 333], [6, 333], [7, 334], [8, 333], [9, 333], [10, 334], [11, 333], [12, 333]]}{'accumulated': 3833, 'book_value': 1167, 'schedule': [[1, 167], [2, 333], [3, 333], [4, 334], [5, 333], [6, 333], [7, 334], [8, 333], [9, 333], [10, 334], [11, 333], [12, 333]]}Passed
control 5{'accumulated': 3000, 'book_value': 33000, 'schedule': [[3, 3000]]}{'accumulated': 3000, 'book_value': 33000, 'schedule': [[3, 3000]]}Passed
control 6{'accumulated': 1056, 'book_value': 3944, 'schedule': [[3, 56], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 111], [11, 111], [12, 112]]}{'accumulated': 1056, 'book_value': 3944, 'schedule': [[3, 56], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 111], [11, 111], [12, 112]]}Passed

SHA-256 / f82bd2aa57d88ffe7ae6610b4ad903684a98d0714717ac3f9550f7aab4b2fa83

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    def rnd(n, d):
        q, r = divmod(n, d)
        return q + (1 if 2 * r >= d else 0)
    base = x['cost'] - x['salvage']
    life = x['life_months']
    conv = x['convention']
    first = x['start_month'] + (1 if conv == 'next_month' else 0)
    acc = 0
    rows = []
    month = first
    while month <= x['through'] and acc < base:
        j = month - first + 1
        if conv == 'mid_month':
            target = rnd(base * (2 * j - 1), 2 * life)
        else:
            target = rnd(base * j, life)
        target = min(target, base)
        rows.append([month, target - acc])
        acc = target
        month += 1
    return {'schedule': rows, 'accumulated': acc, 'book_value': x['cost'] - acc}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: accumulated cap', {'cost': 5000, 'salvage': 7, 'life_months': 7, 'start_month': 1, 'convention': 'mid_month', 'through': 40}, {'schedule': [[1, 357], [2, 713], [3, 713], [4, 714], [5, 713], [6, 713], [7, 713], [8, 357]], 'accumulated': 4993, 'book_value': 7}], ['control 1', {'cost': 5000, 'salvage': 0, 'life_months': 12, 'start_month': 1, 'convention': 'mid_month', 'through': 80}, {'schedule': [[1, 208], [2, 417], [3, 417], [4, 416], [5, 417], [6, 417], [7, 416], [8, 417], [9, 417], [10, 416], [11, 417], [12, 417], [13, 208]], 'accumulated': 5000, 'book_value': 0}], ['control 2', {'cost': 5000, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 5000}], ['control 3', {'cost': 120000, 'salvage': 7, 'life_months': 7, 'start_month': 10, 'convention': 'full_month', 'through': 80}, {'schedule': [[10, 17142], [11, 17142], [12, 17142], [13, 17141], [14, 17142], [15, 17142], [16, 17142]], 'accumulated': 119993, 'book_value': 7}], ['control 4', {'cost': 5000, 'salvage': 1000, 'life_months': 12, 'start_month': 1, 'convention': 'mid_month', 'through': 12}, {'schedule': [[1, 167], [2, 333], [3, 333], [4, 334], [5, 333], [6, 333], [7, 334], [8, 333], [9, 333], [10, 334], [11, 333], [12, 333]], 'accumulated': 3833, 'book_value': 1167}], ['control 5', {'cost': 36000, 'salvage': 0, 'life_months': 12, 'start_month': 3, 'convention': 'full_month', 'through': 3}, {'schedule': [[3, 3000]], 'accumulated': 3000, 'book_value': 33000}], ['control 6', {'cost': 5000, 'salvage': 1000, 'life_months': 36, 'start_month': 3, 'convention': 'mid_month', 'through': 12}, {'schedule': [[3, 56], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 111], [11, 111], [12, 112]], 'accumulated': 1056, 'book_value': 3944}]], [['regression: accumulated cap', {'cost': 99999, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'mid_month', 'through': 40}, {'schedule': [[10, 3667], [11, 7333], [12, 7333], [13, 7333], [14, 7334], [15, 7333], [16, 7333], [17, 7333], [18, 7334], [19, 7333], [20, 7333], [21, 7333], [22, 3667]], 'accumulated': 87999, 'book_value': 12000}], ['control 1', {'cost': 99999, 'salvage': 1000, 'life_months': 60, 'start_month': 3, 'convention': 'next_month', 'through': 40}, {'schedule': [[4, 1650], [5, 1650], [6, 1650], [7, 1650], [8, 1650], [9, 1650], [10, 1650], [11, 1650], [12, 1650], [13, 1650], [14, 1650], [15, 1650], [16, 1650], [17, 1650], [18, 1650], [19, 1650], [20, 1650], [21, 1650], [22, 1650], [23, 1650], [24, 1650], [25, 1650], [26, 1650], [27, 1650], [28, 1650], [29, 1650], [30, 1650], [31, 1650], [32, 1650], [33, 1650], [34, 1649], [35, 1650], [36, 1650], [37, 1650], [38, 1650], [39, 1650], [40, 1650]], 'accumulated': 61049, 'book_value': 38950}], ['control 2', {'cost': 36000, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'next_month', 'through': 40}, {'schedule': [[11, 2000], [12, 2000], [13, 2000], [14, 2000], [15, 2000], [16, 2000], [17, 2000], [18, 2000], [19, 2000], [20, 2000], [21, 2000], [22, 2000]], 'accumulated': 24000, 'book_value': 12000}], ['control 3', {'cost': 120000, 'salvage': 1000, 'life_months': 60, 'start_month': 10, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 120000}], ['control 4', {'cost': 36000, 'salvage': 0, 'life_months': 60, 'start_month': 10, 'convention': 'next_month', 'through': 80}, {'schedule': [[11, 600], [12, 600], [13, 600], [14, 600], [15, 600], [16, 600], [17, 600], [18, 600], [19, 600], [20, 600], [21, 600], [22, 600], [23, 600], [24, 600], [25, 600], [26, 600], [27, 600], [28, 600], [29, 600], [30, 600], [31, 600], [32, 600], [33, 600], [34, 600], [35, 600], [36, 600], [37, 600], [38, 600], [39, 600], [40, 600], [41, 600], [42, 600], [43, 600], [44, 600], [45, 600], [46, 600], [47, 600], [48, 600], [49, 600], [50, 600], [51, 600], [52, 600], [53, 600], [54, 600], [55, 600], [56, 600], [57, 600], [58, 600], [59, 600], [60, 600], [61, 600], [62, 600], [63, 600], [64, 600], [65, 600], [66, 600], [67, 600], [68, 600], [69, 600], [70, 600]], 'accumulated': 36000, 'book_value': 0}], ['control 5', {'cost': 100000, 'salvage': 7, 'life_months': 60, 'start_month': 1, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 100000}], ['control 6', {'cost': 36000, 'salvage': 7, 'life_months': 36, 'start_month': 3, 'convention': 'full_month', 'through': 3}, {'schedule': [[3, 1000]], 'accumulated': 1000, 'book_value': 35000}]], [['regression: accumulated cap', {'cost': 100000, 'salvage': 7, 'life_months': 7, 'start_month': 1, 'convention': 'mid_month', 'through': 80}, {'schedule': [[1, 7142], [2, 14285], [3, 14285], [4, 14285], [5, 14284], [6, 14285], [7, 14285], [8, 7142]], 'accumulated': 99993, 'book_value': 7}], ['control 1', {'cost': 36000, 'salvage': 0, 'life_months': 7, 'start_month': 3, 'convention': 'mid_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 36000}], ['control 2', {'cost': 100000, 'salvage': 12000, 'life_months': 7, 'start_month': 1, 'convention': 'next_month', 'through': 12}, {'schedule': [[2, 12571], [3, 12572], [4, 12571], [5, 12572], [6, 12571], [7, 12572], [8, 12571]], 'accumulated': 88000, 'book_value': 12000}], ['control 3', {'cost': 100000, 'salvage': 0, 'life_months': 12, 'start_month': 3, 'convention': 'next_month', 'through': 12}, {'schedule': [[4, 8333], [5, 8334], [6, 8333], [7, 8333], [8, 8334], [9, 8333], [10, 8333], [11, 8334], [12, 8333]], 'accumulated': 75000, 'book_value': 25000}], ['control 4', {'cost': 36000, 'salvage': 0, 'life_months': 60, 'start_month': 1, 'convention': 'next_month', 'through': 80}, {'schedule': [[2, 600], [3, 600], [4, 600], [5, 600], [6, 600], [7, 600], [8, 600], [9, 600], [10, 600], [11, 600], [12, 600], [13, 600], [14, 600], [15, 600], [16, 600], [17, 600], [18, 600], [19, 600], [20, 600], [21, 600], [22, 600], [23, 600], [24, 600], [25, 600], [26, 600], [27, 600], [28, 600], [29, 600], [30, 600], [31, 600], [32, 600], [33, 600], [34, 600], [35, 600], [36, 600], [37, 600], [38, 600], [39, 600], [40, 600], [41, 600], [42, 600], [43, 600], [44, 600], [45, 600], [46, 600], [47, 600], [48, 600], [49, 600], [50, 600], [51, 600], [52, 600], [53, 600], [54, 600], [55, 600], [56, 600], [57, 600], [58, 600], [59, 600], [60, 600], [61, 600]], 'accumulated': 36000, 'book_value': 0}], ['control 5', {'cost': 36000, 'salvage': 1000, 'life_months': 7, 'start_month': 3, 'convention': 'full_month', 'through': 40}, {'schedule': [[3, 5000], [4, 5000], [5, 5000], [6, 5000], [7, 5000], [8, 5000], [9, 5000]], 'accumulated': 35000, 'book_value': 1000}], ['control 6', {'cost': 99999, 'salvage': 7, 'life_months': 12, 'start_month': 3, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 99999}]], [['regression: accumulated cap', {'cost': 36000, 'salvage': 7, 'life_months': 7, 'start_month': 10, 'convention': 'mid_month', 'through': 80}, {'schedule': [[10, 2571], [11, 5142], [12, 5142], [13, 5142], [14, 5141], [15, 5142], [16, 5142], [17, 2571]], 'accumulated': 35993, 'book_value': 7}], ['control 1', {'cost': 36000, 'salvage': 7, 'life_months': 36, 'start_month': 1, 'convention': 'mid_month', 'through': 3}, {'schedule': [[1, 500], [2, 1000], [3, 1000]], 'accumulated': 2500, 'book_value': 33500}], ['control 2', {'cost': 120000, 'salvage': 12000, 'life_months': 36, 'start_month': 3, 'convention': 'next_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 120000}], ['control 3', {'cost': 36000, 'salvage': 0, 'life_months': 7, 'start_month': 1, 'convention': 'next_month', 'through': 80}, {'schedule': [[2, 5143], [3, 5143], [4, 5143], [5, 5142], [6, 5143], [7, 5143], [8, 5143]], 'accumulated': 36000, 'book_value': 0}], ['control 4', {'cost': 100000, 'salvage': 7, 'life_months': 60, 'start_month': 3, 'convention': 'mid_month', 'through': 1}, {'schedule': [], 'accumulated': 0, 'book_value': 100000}], ['control 5', {'cost': 36000, 'salvage': 12000, 'life_months': 60, 'start_month': 10, 'convention': 'full_month', 'through': 12}, {'schedule': [[10, 400], [11, 400], [12, 400]], 'accumulated': 1200, 'book_value': 34800}], ['control 6', {'cost': 5000, 'salvage': 1000, 'life_months': 36, 'start_month': 1, 'convention': 'mid_month', 'through': 3}, {'schedule': [[1, 56], [2, 111], [3, 111]], 'accumulated': 278, 'book_value': 4722}]], [['regression: accumulated cap', {'cost': 100000, 'salvage': 12000, 'life_months': 12, 'start_month': 10, 'convention': 'mid_month', 'through': 80}, {'schedule': [[10, 3667], [11, 7333], [12, 7333], [13, 7334], [14, 7333], [15, 7333], [16, 7334], [17, 7333], [18, 7333], [19, 7334], [20, 7333], [21, 7333], [22, 3667]], 'accumulated': 88000, 'book_value': 12000}], ['control 1', {'cost': 120000, 'salvage': 12000, 'life_months': 60, 'start_month': 10, 'convention': 'mid_month', 'through': 3}, {'schedule': [], 'accumulated': 0, 'book_value': 120000}], ['control 2', {'cost': 5000, 'salvage': 0, 'life_months': 36, 'start_month': 3, 'convention': 'next_month', 'through': 12}, {'schedule': [[4, 139], [5, 139], [6, 139], [7, 139], [8, 138], [9, 139], [10, 139], [11, 139], [12, 139]], 'accumulated': 1250, 'book_value': 3750}], ['control 3', {'cost': 120000, 'salvage': 1000, 'life_months': 36, 'start_month': 1, 'convention': 'full_month', 'through': 40}, {'schedule': [[1, 3306], [2, 3305], [3, 3306], [4, 3305], [5, 3306], [6, 3305], [7, 3306], [8, 3305], [9, 3306], [10, 3306], [11, 3305], [12, 3306], [13, 3305], [14, 3306], [15, 3305], [16, 3306], [17, 3305], [18, 3306], [19, 3306], [20, 3305], [21, 3306], [22, 3305], [23, 3306], [24, 3305], [25, 3306], [26, 3305], [27, 3306], [28, 3306], [29, 3305], [30, 3306], [31, 3305], [32, 3306], [33, 3305], [34, 3306], [35, 3305], [36, 3306]], 'accumulated': 119000, 'book_value': 1000}], ['control 4', {'cost': 5000, 'salvage': 1000, 'life_months': 36, 'start_month': 1, 'convention': 'mid_month', 'through': 12}, {'schedule': [[1, 56], [2, 111], [3, 111], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 112], [11, 111], [12, 111]], 'accumulated': 1278, 'book_value': 3722}], ['control 5', {'cost': 100000, 'salvage': 1000, 'life_months': 7, 'start_month': 3, 'convention': 'full_month', 'through': 3}, {'schedule': [[3, 14143]], 'accumulated': 14143, 'book_value': 85857}], ['control 6', {'cost': 99999, 'salvage': 0, 'life_months': 60, 'start_month': 3, 'convention': 'full_month', 'through': 40}, {'schedule': [[3, 1667], [4, 1666], [5, 1667], [6, 1667], [7, 1666], [8, 1667], [9, 1667], [10, 1666], [11, 1667], [12, 1667], [13, 1666], [14, 1667], [15, 1666], [16, 1667], [17, 1667], [18, 1666], [19, 1667], [20, 1667], [21, 1666], [22, 1667], [23, 1667], [24, 1666], [25, 1667], [26, 1667], [27, 1666], [28, 1667], [29, 1667], [30, 1666], [31, 1667], [32, 1667], [33, 1666], [34, 1667], [35, 1666], [36, 1667], [37, 1667], [38, 1666], [39, 1667], [40, 1667]], 'accumulated': 63333, 'book_value': 36666}]]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'raised ' + type(exc).__name__
    check(label, actual, 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 fixtureActualExpectedOutcome
regression: accumulated cap{'accumulated': 4993, 'book_value': 7, 'schedule': [[1, 357], [2, 713], [3, 713], [4, 714], [5, 713], [6, 713], [7, 713], [8, 357]]}{'accumulated': 4993, 'book_value': 7, 'schedule': [[1, 357], [2, 713], [3, 713], [4, 714], [5, 713], [6, 713], [7, 713], [8, 357]]}Passed
control 1{'accumulated': 5000, 'book_value': 0, 'schedule': [[1, 208], [2, 417], [3, 417], [4, 416], [5, 417], [6, 417], [7, 416], [8, 417], [9, 417], [10, 416], [11, 417], [12, 417], [13, 208]]}{'accumulated': 5000, 'book_value': 0, 'schedule': [[1, 208], [2, 417], [3, 417], [4, 416], [5, 417], [6, 417], [7, 416], [8, 417], [9, 417], [10, 416], [11, 417], [12, 417], [13, 208]]}Passed
control 2{'accumulated': 0, 'book_value': 5000, 'schedule': []}{'accumulated': 0, 'book_value': 5000, 'schedule': []}Passed
control 3{'accumulated': 119993, 'book_value': 7, 'schedule': [[10, 17142], [11, 17142], [12, 17142], [13, 17141], [14, 17142], [15, 17142], [16, 17142]]}{'accumulated': 119993, 'book_value': 7, 'schedule': [[10, 17142], [11, 17142], [12, 17142], [13, 17141], [14, 17142], [15, 17142], [16, 17142]]}Passed
control 4{'accumulated': 3833, 'book_value': 1167, 'schedule': [[1, 167], [2, 333], [3, 333], [4, 334], [5, 333], [6, 333], [7, 334], [8, 333], [9, 333], [10, 334], [11, 333], [12, 333]]}{'accumulated': 3833, 'book_value': 1167, 'schedule': [[1, 167], [2, 333], [3, 333], [4, 334], [5, 333], [6, 333], [7, 334], [8, 333], [9, 333], [10, 334], [11, 333], [12, 333]]}Passed
control 5{'accumulated': 3000, 'book_value': 33000, 'schedule': [[3, 3000]]}{'accumulated': 3000, 'book_value': 33000, 'schedule': [[3, 3000]]}Passed
control 6{'accumulated': 1056, 'book_value': 3944, 'schedule': [[3, 56], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 111], [11, 111], [12, 112]]}{'accumulated': 1056, 'book_value': 3944, 'schedule': [[3, 56], [4, 111], [5, 111], [6, 111], [7, 111], [8, 111], [9, 111], [10, 111], [11, 111], [12, 112]]}Passed

SHA-256 / 91c41cc80a462ec50cd0b1b508e6fc9ed5d649e9d3d2cff2a3158f0c1abb2806

Verification & scope

A deterministic bounded teaching model with stipulated toy bookkeeping rules stated in the contract; amounts are integer cents; it makes no claim of conformance to any accounting standard or product. 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:46:25.519849+00:00.

Case digest / c91e233e0d3e0e4504291c6f9ce2d6a78caa421701bad9d833dc8fdd5891efa0