FA-92636 / HVAC thermostat control / Open access
Averaging holds a stale value when no occupied room is valid · case 01
With everyone out of the occupied rooms the thermostat stops tracking temperature.
ROOT CAUSE
There is no fallback to all valid sensors when no occupied sensor is valid.
VERIFIED REPAIR
Fall back to all valid readings.
Unsuccessful approach: Falling back to every non-missing reading reintroduces invalid sensors.
Case contract
Thermostat with remote room sensors; each sample is a list of [room, reading tenths F or None, occupied]. Readings outside 32.0-100.0 F or None are invalid. The control temperature is the mean of valid readings from occupied rooms, or of all valid readings if no occupied room has one, rounded half up to a tenth; if nothing is valid the previous control temperature is held (None initially). Return the control temperature per sample.
Why this case matters
Residential and light-commercial thermostats make these decisions sample by sample; each defect changes equipment calls in a way that shows up as short cycling, comfort complaints or equipment stress.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(samples):
last = None
out = []
for readings in samples:
valid = [(t, occ) for room, t, occ in readings if t is not None and 320 <= t <= 1000]
pool = [t for t, occ in valid if occ]
if pool:
last = (2 * sum(pool) + len(pool)) // (2 * len(pool))
out.append(last)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 611, False], ['bed', 799, True]],
[['living', 697, True]],
[['living', 697, False], ['bed', 609, True]],
[['living', 751, False], ['bed', 736, True], ['den', 616, True]],
[['living', 1100, False], ['bed', 686, True]],
[['living', 798, False], ['bed', 743, True], ['den', 646, False], ['office', 720, False]],
[['living', 668, False], ['bed', None, True], ['den', None, True], ['office', 795, False]]]],
[799, 697, 609, 676, 686, 743, 732]],
['regression: scenario 2',
[[[['living', 602, False], ['bed', 665, False], ['den', 790, False], ['office', 677, False]],
[['living', 638, False]],
[['living', 602, False], ['bed', 750, True]],
[['living', None, True], ['bed', 250, False], ['den', 250, True]],
[['living', 744, True], ['bed', 711, True], ['den', 676, False], ['office', 640, True]],
[['living', 771, False], ['bed', 646, True]],
[['living', 608, False]],
[['living', 663, True], ['bed', 793, True], ['den', 250, True], ['office', 743, False]]]],
[684, 638, 750, 750, 698, 646, 608, 728]],
['regression: scenario 3',
[[[['living', 677, True]],
[['living', 624, True], ['bed', 620, True]],
[['living', 605, True], ['bed', 250, False]],
[['living', 764, False]],
[['living', 612, False], ['bed', None, True], ['den', 664, True]],
[['living', None, True], ['bed', 250, False], ['den', 250, True]],
[['living', 745, True], ['bed', None, False]],
[['living', 665, True]]]],
[677, 622, 605, 764, 664, 664, 745, 665]],
['regression: scenario 4',
[[[['living', 600, True]],
[['living', 742, True], ['bed', 607, False], ['den', 638, True], ['office', 791, True]],
[['living', 710, False], ['bed', 602, True], ['den', 716, False]],
[['living', 607, False], ['bed', 735, True], ['den', 739, False], ['office', 723, True]],
[['living', 621, True], ['bed', 625, False], ['den', 688, True], ['office', 627, False]],
[['living', 677, False], ['bed', 775, True]],
[['living', 1100, False], ['bed', None, False], ['den', 687, False]]]],
[600, 724, 602, 729, 655, 775, 687]]],
[['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['regression: scenario 5',
[[[['living', 660, True], ['bed', 706, True], ['den', 697, False], ['office', None, False]],
[['living', 683, True], ['bed', None, False]],
[['living', 604, False], ['bed', None, False], ['den', 677, True]],
[['living', None, False], ['bed', 609, True], ['den', 696, True], ['office', 610, False]],
[['living', 712, False]],
[['living', 629, True]],
[['living', 250, True]],
[['living', 770, True], ['bed', 1100, False], ['den', 760, False]]]],
[683, 683, 677, 653, 712, 629, 629, 770]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 631, False], ['bed', None, True]],
[['living', 674, True], ['bed', 788, True]],
[['living', 629, False]],
[['living', 617, False], ['bed', 636, True], ['den', 622, True]],
[['living', 602, True], ['bed', 659, True], ['den', 604, False]],
[['living', 641, True], ['bed', 600, True]],
[['living', 781, True]],
[['living', 615, True], ['bed', 788, True], ['den', 658, True]]]],
[631, 731, 629, 629, 631, 621, 781, 687]],
['regression: scenario 2',
[[[['living', 675, True], ['bed', 724, False], ['den', 793, True]],
[['living', 711, False], ['bed', 720, False]],
[['living', 722, False], ['bed', 1100, False], ['den', 606, False], ['office', 625, True]],
[['living', 657, False], ['bed', 619, True], ['den', 800, True], ['office', 629, True]],
[['living', 765, True], ['bed', 726, True]],
[['living', 785, False], ['bed', 626, False]]]],
[734, 716, 625, 683, 746, 706]],
['regression: scenario 3',
[[[['living', 795, False]],
[['living', 769, False], ['bed', 675, False]],
[['living', 640, False]],
[['living', None, False]],
[['living', None, False], ['bed', 790, True], ['den', 684, False], ['office', 789, True]],
[['living', 722, True], ['bed', 750, True], ['den', 250, True]],
[['living', 663, True], ['bed', 670, True]],
[['living', 628, False], ['bed', 687, False], ['den', 635, False]]]],
[795, 722, 640, 640, 790, 736, 667, 650]]],
[['regression: scenario 1',
[[[['living', 627, False], ['bed', 693, True], ['den', 769, True], ['office', 704, True]],
[['living', 738, True], ['bed', 638, True]],
[['living', 760, True], ['bed', 696, True], ['den', 683, False]],
[['living', 771, False], ['bed', 1100, False]],
[['living', 686, True]],
[['living', 734, True]],
[['living', None, True], ['bed', 649, False], ['den', 767, False]],
[['living', 722, True]],
[['living', 686, True], ['bed', 715, False], ['den', 617, False], ['office', 250, False]],
[['living', 790, True]]]],
[722, 688, 728, 771, 686, 734, 708, 722, 686, 790]],
['regression: scenario 4',
[[[['living', 647, True], ['bed', 693, False]],
[['living', None, False], ['bed', 1100, False], ['den', None, True], ['office', None, False]],
[['living', 791, False], ['bed', 250, False], ['den', 778, True]],
[['living', 650, False], ['bed', None, True]],
[['living', 1100, True], ['bed', 680, False], ['den', 250, False]],
[['living', 700, True], ['bed', 1100, True], ['den', 712, False]],
[['living', 662, True], ['bed', 670, True]]]],
[647, 647, 778, 650, 680, 700, 666]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 2',
[[[['living', 663, False], ['bed', 781, True], ['den', 775, False], ['office', 722, True]],
[['living', 655, False]],
[['living', 777, False], ['bed', 790, True], ['den', 637, False], ['office', 682, False]],
[['living', 250, False], ['bed', 701, True], ['den', 745, True], ['office', 626, False]],
[['living', 619, False]],
[['living', 619, True], ['bed', 710, True]],
[['living', 732, False]],
[['living', 772, False]],
[['living', None, True], ['bed', 664, True], ['den', 728, True], ['office', 783, False]],
[['living', 1100, True], ['bed', 734, True], ['den', 657, False], ['office', 601, False]]]],
[752, 655, 790, 723, 619, 665, 732, 772, 696, 734]],
['regression: scenario 3',
[[[['living', 740, True], ['bed', None, False], ['den', 718, True], ['office', 628, True]],
[['living', 687, True]],
[['living', 766, True], ['bed', 604, False], ['den', 725, False], ['office', 735, False]],
[['living', 788, False], ['bed', 698, False], ['den', 700, False], ['office', None, True]],
[['living', None, False], ['bed', 607, True], ['den', 754, False]],
[['living', 250, False], ['bed', 649, True], ['den', 666, False]],
[['living', None, True], ['bed', 785, True]],
[['living', 715, True], ['bed', 699, False], ['den', 1100, True]],
[['living', 605, False], ['bed', 735, False]]]],
[695, 687, 766, 729, 607, 649, 785, 715, 670]]],
[['regression: scenario 3',
[[[['living', 687, True], ['bed', 761, True]],
[['living', 719, False], ['bed', None, False], ['den', 774, True]],
[['living', 723, False]],
[['living', 649, False]],
[['living', 649, False], ['bed', 705, True]],
[['living', 699, True]]]],
[724, 774, 723, 649, 705, 699]],
['regression: scenario 6',
[[[['living', 794, False], ['bed', 676, True], ['den', 708, False]],
[['living', 732, False], ['bed', 732, True]],
[['living', 729, True], ['bed', 788, True], ['den', 788, True], ['office', 250, True]],
[['living', 739, True]],
[['living', 690, False], ['bed', 658, True]],
[['living', 653, False]],
[['living', 666, False], ['bed', None, True]],
[['living', 250, False], ['bed', 777, False], ['den', 1100, False]],
[['living', 756, True], ['bed', 629, False], ['den', 678, True], ['office', 703, False]],
[['living', 601, False], ['bed', 643, False], ['den', 790, True]]]],
[676, 732, 768, 739, 658, 653, 666, 777, 717, 790]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 782, False], ['bed', 708, True], ['den', 678, True]],
[['living', 772, False], ['bed', 795, True]],
[['living', 744, True], ['bed', 616, True], ['den', 694, True]],
[['living', 790, False], ['bed', 733, True]],
[['living', 722, True], ['bed', 701, False]],
[['living', 699, False], ['bed', 636, False]]]],
[693, 795, 685, 733, 722, 668]],
['control: scenario 2',
[[[['living', 675, False], ['bed', 659, True], ['den', 738, False], ['office', 1100, False]],
[['living', 250, True], ['bed', 649, True]],
[['living', 604, True]],
[['living', 629, True], ['bed', None, True], ['den', 610, True]],
[['living', 633, False], ['bed', None, True], ['den', 778, True], ['office', 795, False]],
[['living', None, False]]]],
[659, 649, 604, 620, 778, 778]]],
[['regression: scenario 3',
[[[['living', None, True], ['bed', 631, True]],
[['living', 654, False], ['bed', 779, False], ['den', 716, True]],
[['living', 799, True]],
[['living', 664, True]],
[['living', 622, False]],
[['living', 697, False], ['bed', 685, False]],
[['living', 727, False], ['bed', 250, True], ['den', 737, False], ['office', 692, False]]]],
[631, 716, 799, 664, 622, 691, 719]],
['regression: scenario 4',
[[[['living', 1100, False], ['bed', 686, True], ['den', 660, False]],
[['living', 716, True], ['bed', 689, True], ['den', 723, False]],
[['living', 729, True]],
[['living', 660, False], ['bed', 657, True]],
[['living', 765, True]],
[['living', 250, False]],
[['living', None, True], ['bed', 707, True], ['den', 646, True]],
[['living', 766, False], ['bed', 703, False]],
[['living', 617, True], ['bed', 608, True], ['den', 250, True]],
[['living', 603, False], ['bed', 746, True], ['den', None, True], ['office', 695, False]]]],
[686, 703, 729, 657, 765, 765, 677, 735, 613, 746]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 1100, True]],
[['living', 634, False], ['bed', 740, False], ['den', None, True]],
[['living', 1100, True]],
[['living', 618, False], ['bed', 787, False], ['den', 754, False]],
[['living', 673, False], ['bed', 795, True], ['den', 612, False], ['office', 721, True]]]],
[None, 687, 687, 720, 758]],
['regression: scenario 2',
[[[['living', 733, True], ['bed', 629, True], ['den', 631, True], ['office', 649, True]],
[['living', 766, True]],
[['living', 727, False], ['bed', 610, False]],
[['living', None, True]],
[['living', 627, False]],
[['living', 689, True], ['bed', 635, True], ['den', 250, False]],
[['living', 613, False], ['bed', 717, False]],
[['living', 1100, True]]]],
[661, 766, 669, 669, 627, 662, 665, 665]]]]
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 |
|---|---|---|---|
| regression: occupancy and faults | [700, 700, 700, 702] | [700, 686, 686, 702] | Failed |
| regression: shorted sensor | [700, 700] | [700, 690] | Failed |
| control: first sample all invalid | [None, 700, 700] | [None, 700, 700] | Passed |
| control: single occupied room | [700, 706] | [700, 706] | Passed |
| regression: scenario 1 | [799, 697, 609, 676, 686, 743, 743] | [799, 697, 609, 676, 686, 743, 732] | Failed |
| regression: scenario 2 | [None, None, 750, 750, 698, 646, 646, 728] | [684, 638, 750, 750, 698, 646, 608, 728] | Failed |
| regression: scenario 3 | [677, 622, 605, 605, 664, 664, 745, 665] | [677, 622, 605, 764, 664, 664, 745, 665] | Failed |
| regression: scenario 4 | [600, 724, 602, 729, 655, 775, 775] | [600, 724, 602, 729, 655, 775, 687] | Failed |
SHA-256 / 9aed0c8659f382a47adeb2fbd2afb8ea3750983079899c09e5a688bacafc1c83
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(samples):
last = None
out = []
for readings in samples:
valid = [(t, occ) for room, t, occ in readings if t is not None and 320 <= t <= 1000]
pool = [t for t, occ in valid if occ] or [t for room, t, occ in readings if t is not None]
if pool:
last = (2 * sum(pool) + len(pool)) // (2 * len(pool))
out.append(last)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 611, False], ['bed', 799, True]],
[['living', 697, True]],
[['living', 697, False], ['bed', 609, True]],
[['living', 751, False], ['bed', 736, True], ['den', 616, True]],
[['living', 1100, False], ['bed', 686, True]],
[['living', 798, False], ['bed', 743, True], ['den', 646, False], ['office', 720, False]],
[['living', 668, False], ['bed', None, True], ['den', None, True], ['office', 795, False]]]],
[799, 697, 609, 676, 686, 743, 732]],
['regression: scenario 2',
[[[['living', 602, False], ['bed', 665, False], ['den', 790, False], ['office', 677, False]],
[['living', 638, False]],
[['living', 602, False], ['bed', 750, True]],
[['living', None, True], ['bed', 250, False], ['den', 250, True]],
[['living', 744, True], ['bed', 711, True], ['den', 676, False], ['office', 640, True]],
[['living', 771, False], ['bed', 646, True]],
[['living', 608, False]],
[['living', 663, True], ['bed', 793, True], ['den', 250, True], ['office', 743, False]]]],
[684, 638, 750, 750, 698, 646, 608, 728]],
['regression: scenario 3',
[[[['living', 677, True]],
[['living', 624, True], ['bed', 620, True]],
[['living', 605, True], ['bed', 250, False]],
[['living', 764, False]],
[['living', 612, False], ['bed', None, True], ['den', 664, True]],
[['living', None, True], ['bed', 250, False], ['den', 250, True]],
[['living', 745, True], ['bed', None, False]],
[['living', 665, True]]]],
[677, 622, 605, 764, 664, 664, 745, 665]],
['regression: scenario 4',
[[[['living', 600, True]],
[['living', 742, True], ['bed', 607, False], ['den', 638, True], ['office', 791, True]],
[['living', 710, False], ['bed', 602, True], ['den', 716, False]],
[['living', 607, False], ['bed', 735, True], ['den', 739, False], ['office', 723, True]],
[['living', 621, True], ['bed', 625, False], ['den', 688, True], ['office', 627, False]],
[['living', 677, False], ['bed', 775, True]],
[['living', 1100, False], ['bed', None, False], ['den', 687, False]]]],
[600, 724, 602, 729, 655, 775, 687]]],
[['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['regression: scenario 5',
[[[['living', 660, True], ['bed', 706, True], ['den', 697, False], ['office', None, False]],
[['living', 683, True], ['bed', None, False]],
[['living', 604, False], ['bed', None, False], ['den', 677, True]],
[['living', None, False], ['bed', 609, True], ['den', 696, True], ['office', 610, False]],
[['living', 712, False]],
[['living', 629, True]],
[['living', 250, True]],
[['living', 770, True], ['bed', 1100, False], ['den', 760, False]]]],
[683, 683, 677, 653, 712, 629, 629, 770]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 631, False], ['bed', None, True]],
[['living', 674, True], ['bed', 788, True]],
[['living', 629, False]],
[['living', 617, False], ['bed', 636, True], ['den', 622, True]],
[['living', 602, True], ['bed', 659, True], ['den', 604, False]],
[['living', 641, True], ['bed', 600, True]],
[['living', 781, True]],
[['living', 615, True], ['bed', 788, True], ['den', 658, True]]]],
[631, 731, 629, 629, 631, 621, 781, 687]],
['regression: scenario 2',
[[[['living', 675, True], ['bed', 724, False], ['den', 793, True]],
[['living', 711, False], ['bed', 720, False]],
[['living', 722, False], ['bed', 1100, False], ['den', 606, False], ['office', 625, True]],
[['living', 657, False], ['bed', 619, True], ['den', 800, True], ['office', 629, True]],
[['living', 765, True], ['bed', 726, True]],
[['living', 785, False], ['bed', 626, False]]]],
[734, 716, 625, 683, 746, 706]],
['regression: scenario 3',
[[[['living', 795, False]],
[['living', 769, False], ['bed', 675, False]],
[['living', 640, False]],
[['living', None, False]],
[['living', None, False], ['bed', 790, True], ['den', 684, False], ['office', 789, True]],
[['living', 722, True], ['bed', 750, True], ['den', 250, True]],
[['living', 663, True], ['bed', 670, True]],
[['living', 628, False], ['bed', 687, False], ['den', 635, False]]]],
[795, 722, 640, 640, 790, 736, 667, 650]]],
[['regression: scenario 1',
[[[['living', 627, False], ['bed', 693, True], ['den', 769, True], ['office', 704, True]],
[['living', 738, True], ['bed', 638, True]],
[['living', 760, True], ['bed', 696, True], ['den', 683, False]],
[['living', 771, False], ['bed', 1100, False]],
[['living', 686, True]],
[['living', 734, True]],
[['living', None, True], ['bed', 649, False], ['den', 767, False]],
[['living', 722, True]],
[['living', 686, True], ['bed', 715, False], ['den', 617, False], ['office', 250, False]],
[['living', 790, True]]]],
[722, 688, 728, 771, 686, 734, 708, 722, 686, 790]],
['regression: scenario 4',
[[[['living', 647, True], ['bed', 693, False]],
[['living', None, False], ['bed', 1100, False], ['den', None, True], ['office', None, False]],
[['living', 791, False], ['bed', 250, False], ['den', 778, True]],
[['living', 650, False], ['bed', None, True]],
[['living', 1100, True], ['bed', 680, False], ['den', 250, False]],
[['living', 700, True], ['bed', 1100, True], ['den', 712, False]],
[['living', 662, True], ['bed', 670, True]]]],
[647, 647, 778, 650, 680, 700, 666]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 2',
[[[['living', 663, False], ['bed', 781, True], ['den', 775, False], ['office', 722, True]],
[['living', 655, False]],
[['living', 777, False], ['bed', 790, True], ['den', 637, False], ['office', 682, False]],
[['living', 250, False], ['bed', 701, True], ['den', 745, True], ['office', 626, False]],
[['living', 619, False]],
[['living', 619, True], ['bed', 710, True]],
[['living', 732, False]],
[['living', 772, False]],
[['living', None, True], ['bed', 664, True], ['den', 728, True], ['office', 783, False]],
[['living', 1100, True], ['bed', 734, True], ['den', 657, False], ['office', 601, False]]]],
[752, 655, 790, 723, 619, 665, 732, 772, 696, 734]],
['regression: scenario 3',
[[[['living', 740, True], ['bed', None, False], ['den', 718, True], ['office', 628, True]],
[['living', 687, True]],
[['living', 766, True], ['bed', 604, False], ['den', 725, False], ['office', 735, False]],
[['living', 788, False], ['bed', 698, False], ['den', 700, False], ['office', None, True]],
[['living', None, False], ['bed', 607, True], ['den', 754, False]],
[['living', 250, False], ['bed', 649, True], ['den', 666, False]],
[['living', None, True], ['bed', 785, True]],
[['living', 715, True], ['bed', 699, False], ['den', 1100, True]],
[['living', 605, False], ['bed', 735, False]]]],
[695, 687, 766, 729, 607, 649, 785, 715, 670]]],
[['regression: scenario 3',
[[[['living', 687, True], ['bed', 761, True]],
[['living', 719, False], ['bed', None, False], ['den', 774, True]],
[['living', 723, False]],
[['living', 649, False]],
[['living', 649, False], ['bed', 705, True]],
[['living', 699, True]]]],
[724, 774, 723, 649, 705, 699]],
['regression: scenario 6',
[[[['living', 794, False], ['bed', 676, True], ['den', 708, False]],
[['living', 732, False], ['bed', 732, True]],
[['living', 729, True], ['bed', 788, True], ['den', 788, True], ['office', 250, True]],
[['living', 739, True]],
[['living', 690, False], ['bed', 658, True]],
[['living', 653, False]],
[['living', 666, False], ['bed', None, True]],
[['living', 250, False], ['bed', 777, False], ['den', 1100, False]],
[['living', 756, True], ['bed', 629, False], ['den', 678, True], ['office', 703, False]],
[['living', 601, False], ['bed', 643, False], ['den', 790, True]]]],
[676, 732, 768, 739, 658, 653, 666, 777, 717, 790]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 782, False], ['bed', 708, True], ['den', 678, True]],
[['living', 772, False], ['bed', 795, True]],
[['living', 744, True], ['bed', 616, True], ['den', 694, True]],
[['living', 790, False], ['bed', 733, True]],
[['living', 722, True], ['bed', 701, False]],
[['living', 699, False], ['bed', 636, False]]]],
[693, 795, 685, 733, 722, 668]],
['control: scenario 2',
[[[['living', 675, False], ['bed', 659, True], ['den', 738, False], ['office', 1100, False]],
[['living', 250, True], ['bed', 649, True]],
[['living', 604, True]],
[['living', 629, True], ['bed', None, True], ['den', 610, True]],
[['living', 633, False], ['bed', None, True], ['den', 778, True], ['office', 795, False]],
[['living', None, False]]]],
[659, 649, 604, 620, 778, 778]]],
[['regression: scenario 3',
[[[['living', None, True], ['bed', 631, True]],
[['living', 654, False], ['bed', 779, False], ['den', 716, True]],
[['living', 799, True]],
[['living', 664, True]],
[['living', 622, False]],
[['living', 697, False], ['bed', 685, False]],
[['living', 727, False], ['bed', 250, True], ['den', 737, False], ['office', 692, False]]]],
[631, 716, 799, 664, 622, 691, 719]],
['regression: scenario 4',
[[[['living', 1100, False], ['bed', 686, True], ['den', 660, False]],
[['living', 716, True], ['bed', 689, True], ['den', 723, False]],
[['living', 729, True]],
[['living', 660, False], ['bed', 657, True]],
[['living', 765, True]],
[['living', 250, False]],
[['living', None, True], ['bed', 707, True], ['den', 646, True]],
[['living', 766, False], ['bed', 703, False]],
[['living', 617, True], ['bed', 608, True], ['den', 250, True]],
[['living', 603, False], ['bed', 746, True], ['den', None, True], ['office', 695, False]]]],
[686, 703, 729, 657, 765, 765, 677, 735, 613, 746]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 1100, True]],
[['living', 634, False], ['bed', 740, False], ['den', None, True]],
[['living', 1100, True]],
[['living', 618, False], ['bed', 787, False], ['den', 754, False]],
[['living', 673, False], ['bed', 795, True], ['den', 612, False], ['office', 721, True]]]],
[None, 687, 687, 720, 758]],
['regression: scenario 2',
[[[['living', 733, True], ['bed', 629, True], ['den', 631, True], ['office', 649, True]],
[['living', 766, True]],
[['living', 727, False], ['bed', 610, False]],
[['living', None, True]],
[['living', 627, False]],
[['living', 689, True], ['bed', 635, True], ['den', 250, False]],
[['living', 613, False], ['bed', 717, False]],
[['living', 1100, True]]]],
[661, 766, 669, 669, 627, 662, 665, 665]]]]
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 |
|---|---|---|---|
| regression: occupancy and faults | [700, 686, 1200, 702] | [700, 686, 686, 702] | Failed |
| regression: shorted sensor | [700, 995] | [700, 690] | Failed |
| control: first sample all invalid | [None, 700, 700] | [None, 700, 700] | Passed |
| control: single occupied room | [700, 706] | [700, 706] | Passed |
| regression: scenario 1 | [799, 697, 609, 676, 686, 743, 732] | [799, 697, 609, 676, 686, 743, 732] | Passed |
| regression: scenario 2 | [684, 638, 750, 250, 698, 646, 608, 728] | [684, 638, 750, 750, 698, 646, 608, 728] | Failed |
| regression: scenario 3 | [677, 622, 605, 764, 664, 250, 745, 665] | [677, 622, 605, 764, 664, 664, 745, 665] | Failed |
| regression: scenario 4 | [600, 724, 602, 729, 655, 775, 894] | [600, 724, 602, 729, 655, 775, 687] | Failed |
SHA-256 / 92df8e8f25c6b1c844783c28d946b606a30ee1b2b6a1df9b664f9d667eabb779
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(samples):
last = None
out = []
for readings in samples:
valid = [(t, occ) for room, t, occ in readings if t is not None and 320 <= t <= 1000]
pool = [t for t, occ in valid if occ] or [t for t, occ in valid]
if pool:
last = (2 * sum(pool) + len(pool)) // (2 * len(pool))
out.append(last)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 611, False], ['bed', 799, True]],
[['living', 697, True]],
[['living', 697, False], ['bed', 609, True]],
[['living', 751, False], ['bed', 736, True], ['den', 616, True]],
[['living', 1100, False], ['bed', 686, True]],
[['living', 798, False], ['bed', 743, True], ['den', 646, False], ['office', 720, False]],
[['living', 668, False], ['bed', None, True], ['den', None, True], ['office', 795, False]]]],
[799, 697, 609, 676, 686, 743, 732]],
['regression: scenario 2',
[[[['living', 602, False], ['bed', 665, False], ['den', 790, False], ['office', 677, False]],
[['living', 638, False]],
[['living', 602, False], ['bed', 750, True]],
[['living', None, True], ['bed', 250, False], ['den', 250, True]],
[['living', 744, True], ['bed', 711, True], ['den', 676, False], ['office', 640, True]],
[['living', 771, False], ['bed', 646, True]],
[['living', 608, False]],
[['living', 663, True], ['bed', 793, True], ['den', 250, True], ['office', 743, False]]]],
[684, 638, 750, 750, 698, 646, 608, 728]],
['regression: scenario 3',
[[[['living', 677, True]],
[['living', 624, True], ['bed', 620, True]],
[['living', 605, True], ['bed', 250, False]],
[['living', 764, False]],
[['living', 612, False], ['bed', None, True], ['den', 664, True]],
[['living', None, True], ['bed', 250, False], ['den', 250, True]],
[['living', 745, True], ['bed', None, False]],
[['living', 665, True]]]],
[677, 622, 605, 764, 664, 664, 745, 665]],
['regression: scenario 4',
[[[['living', 600, True]],
[['living', 742, True], ['bed', 607, False], ['den', 638, True], ['office', 791, True]],
[['living', 710, False], ['bed', 602, True], ['den', 716, False]],
[['living', 607, False], ['bed', 735, True], ['den', 739, False], ['office', 723, True]],
[['living', 621, True], ['bed', 625, False], ['den', 688, True], ['office', 627, False]],
[['living', 677, False], ['bed', 775, True]],
[['living', 1100, False], ['bed', None, False], ['den', 687, False]]]],
[600, 724, 602, 729, 655, 775, 687]]],
[['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['regression: scenario 5',
[[[['living', 660, True], ['bed', 706, True], ['den', 697, False], ['office', None, False]],
[['living', 683, True], ['bed', None, False]],
[['living', 604, False], ['bed', None, False], ['den', 677, True]],
[['living', None, False], ['bed', 609, True], ['den', 696, True], ['office', 610, False]],
[['living', 712, False]],
[['living', 629, True]],
[['living', 250, True]],
[['living', 770, True], ['bed', 1100, False], ['den', 760, False]]]],
[683, 683, 677, 653, 712, 629, 629, 770]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 631, False], ['bed', None, True]],
[['living', 674, True], ['bed', 788, True]],
[['living', 629, False]],
[['living', 617, False], ['bed', 636, True], ['den', 622, True]],
[['living', 602, True], ['bed', 659, True], ['den', 604, False]],
[['living', 641, True], ['bed', 600, True]],
[['living', 781, True]],
[['living', 615, True], ['bed', 788, True], ['den', 658, True]]]],
[631, 731, 629, 629, 631, 621, 781, 687]],
['regression: scenario 2',
[[[['living', 675, True], ['bed', 724, False], ['den', 793, True]],
[['living', 711, False], ['bed', 720, False]],
[['living', 722, False], ['bed', 1100, False], ['den', 606, False], ['office', 625, True]],
[['living', 657, False], ['bed', 619, True], ['den', 800, True], ['office', 629, True]],
[['living', 765, True], ['bed', 726, True]],
[['living', 785, False], ['bed', 626, False]]]],
[734, 716, 625, 683, 746, 706]],
['regression: scenario 3',
[[[['living', 795, False]],
[['living', 769, False], ['bed', 675, False]],
[['living', 640, False]],
[['living', None, False]],
[['living', None, False], ['bed', 790, True], ['den', 684, False], ['office', 789, True]],
[['living', 722, True], ['bed', 750, True], ['den', 250, True]],
[['living', 663, True], ['bed', 670, True]],
[['living', 628, False], ['bed', 687, False], ['den', 635, False]]]],
[795, 722, 640, 640, 790, 736, 667, 650]]],
[['regression: scenario 1',
[[[['living', 627, False], ['bed', 693, True], ['den', 769, True], ['office', 704, True]],
[['living', 738, True], ['bed', 638, True]],
[['living', 760, True], ['bed', 696, True], ['den', 683, False]],
[['living', 771, False], ['bed', 1100, False]],
[['living', 686, True]],
[['living', 734, True]],
[['living', None, True], ['bed', 649, False], ['den', 767, False]],
[['living', 722, True]],
[['living', 686, True], ['bed', 715, False], ['den', 617, False], ['office', 250, False]],
[['living', 790, True]]]],
[722, 688, 728, 771, 686, 734, 708, 722, 686, 790]],
['regression: scenario 4',
[[[['living', 647, True], ['bed', 693, False]],
[['living', None, False], ['bed', 1100, False], ['den', None, True], ['office', None, False]],
[['living', 791, False], ['bed', 250, False], ['den', 778, True]],
[['living', 650, False], ['bed', None, True]],
[['living', 1100, True], ['bed', 680, False], ['den', 250, False]],
[['living', 700, True], ['bed', 1100, True], ['den', 712, False]],
[['living', 662, True], ['bed', 670, True]]]],
[647, 647, 778, 650, 680, 700, 666]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 2',
[[[['living', 663, False], ['bed', 781, True], ['den', 775, False], ['office', 722, True]],
[['living', 655, False]],
[['living', 777, False], ['bed', 790, True], ['den', 637, False], ['office', 682, False]],
[['living', 250, False], ['bed', 701, True], ['den', 745, True], ['office', 626, False]],
[['living', 619, False]],
[['living', 619, True], ['bed', 710, True]],
[['living', 732, False]],
[['living', 772, False]],
[['living', None, True], ['bed', 664, True], ['den', 728, True], ['office', 783, False]],
[['living', 1100, True], ['bed', 734, True], ['den', 657, False], ['office', 601, False]]]],
[752, 655, 790, 723, 619, 665, 732, 772, 696, 734]],
['regression: scenario 3',
[[[['living', 740, True], ['bed', None, False], ['den', 718, True], ['office', 628, True]],
[['living', 687, True]],
[['living', 766, True], ['bed', 604, False], ['den', 725, False], ['office', 735, False]],
[['living', 788, False], ['bed', 698, False], ['den', 700, False], ['office', None, True]],
[['living', None, False], ['bed', 607, True], ['den', 754, False]],
[['living', 250, False], ['bed', 649, True], ['den', 666, False]],
[['living', None, True], ['bed', 785, True]],
[['living', 715, True], ['bed', 699, False], ['den', 1100, True]],
[['living', 605, False], ['bed', 735, False]]]],
[695, 687, 766, 729, 607, 649, 785, 715, 670]]],
[['regression: scenario 3',
[[[['living', 687, True], ['bed', 761, True]],
[['living', 719, False], ['bed', None, False], ['den', 774, True]],
[['living', 723, False]],
[['living', 649, False]],
[['living', 649, False], ['bed', 705, True]],
[['living', 699, True]]]],
[724, 774, 723, 649, 705, 699]],
['regression: scenario 6',
[[[['living', 794, False], ['bed', 676, True], ['den', 708, False]],
[['living', 732, False], ['bed', 732, True]],
[['living', 729, True], ['bed', 788, True], ['den', 788, True], ['office', 250, True]],
[['living', 739, True]],
[['living', 690, False], ['bed', 658, True]],
[['living', 653, False]],
[['living', 666, False], ['bed', None, True]],
[['living', 250, False], ['bed', 777, False], ['den', 1100, False]],
[['living', 756, True], ['bed', 629, False], ['den', 678, True], ['office', 703, False]],
[['living', 601, False], ['bed', 643, False], ['den', 790, True]]]],
[676, 732, 768, 739, 658, 653, 666, 777, 717, 790]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 782, False], ['bed', 708, True], ['den', 678, True]],
[['living', 772, False], ['bed', 795, True]],
[['living', 744, True], ['bed', 616, True], ['den', 694, True]],
[['living', 790, False], ['bed', 733, True]],
[['living', 722, True], ['bed', 701, False]],
[['living', 699, False], ['bed', 636, False]]]],
[693, 795, 685, 733, 722, 668]],
['control: scenario 2',
[[[['living', 675, False], ['bed', 659, True], ['den', 738, False], ['office', 1100, False]],
[['living', 250, True], ['bed', 649, True]],
[['living', 604, True]],
[['living', 629, True], ['bed', None, True], ['den', 610, True]],
[['living', 633, False], ['bed', None, True], ['den', 778, True], ['office', 795, False]],
[['living', None, False]]]],
[659, 649, 604, 620, 778, 778]]],
[['regression: scenario 3',
[[[['living', None, True], ['bed', 631, True]],
[['living', 654, False], ['bed', 779, False], ['den', 716, True]],
[['living', 799, True]],
[['living', 664, True]],
[['living', 622, False]],
[['living', 697, False], ['bed', 685, False]],
[['living', 727, False], ['bed', 250, True], ['den', 737, False], ['office', 692, False]]]],
[631, 716, 799, 664, 622, 691, 719]],
['regression: scenario 4',
[[[['living', 1100, False], ['bed', 686, True], ['den', 660, False]],
[['living', 716, True], ['bed', 689, True], ['den', 723, False]],
[['living', 729, True]],
[['living', 660, False], ['bed', 657, True]],
[['living', 765, True]],
[['living', 250, False]],
[['living', None, True], ['bed', 707, True], ['den', 646, True]],
[['living', 766, False], ['bed', 703, False]],
[['living', 617, True], ['bed', 608, True], ['den', 250, True]],
[['living', 603, False], ['bed', 746, True], ['den', None, True], ['office', 695, False]]]],
[686, 703, 729, 657, 765, 765, 677, 735, 613, 746]],
['regression: occupancy and faults',
[[[['liv', 700, True], ['bed', 680, False]],
[['liv', None, True], ['bed', 681, False], ['den', 690, False]],
[['liv', 1200, True]],
[['liv', 701, True], ['bed', 702, True]]]],
[700, 686, 686, 702]],
['regression: shorted sensor',
[[[['a', 700, True], ['b', 5, True]], [['a', 1300, False], ['b', 690, False]]]],
[700, 690]],
['control: first sample all invalid',
[[[['a', None, True]], [['a', 700, True]], [['a', None, False]]]],
[None, 700, 700]],
['control: single occupied room',
[[[['a', 700, True], ['b', 650, False], ['c', 660, False]], [['a', 707, True], ['b', 704, True]]]],
[700, 706]],
['regression: scenario 1',
[[[['living', 1100, True]],
[['living', 634, False], ['bed', 740, False], ['den', None, True]],
[['living', 1100, True]],
[['living', 618, False], ['bed', 787, False], ['den', 754, False]],
[['living', 673, False], ['bed', 795, True], ['den', 612, False], ['office', 721, True]]]],
[None, 687, 687, 720, 758]],
['regression: scenario 2',
[[[['living', 733, True], ['bed', 629, True], ['den', 631, True], ['office', 649, True]],
[['living', 766, True]],
[['living', 727, False], ['bed', 610, False]],
[['living', None, True]],
[['living', 627, False]],
[['living', 689, True], ['bed', 635, True], ['den', 250, False]],
[['living', 613, False], ['bed', 717, False]],
[['living', 1100, True]]]],
[661, 766, 669, 669, 627, 662, 665, 665]]]]
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 |
|---|---|---|---|
| regression: occupancy and faults | [700, 686, 686, 702] | [700, 686, 686, 702] | Passed |
| regression: shorted sensor | [700, 690] | [700, 690] | Passed |
| control: first sample all invalid | [None, 700, 700] | [None, 700, 700] | Passed |
| control: single occupied room | [700, 706] | [700, 706] | Passed |
| regression: scenario 1 | [799, 697, 609, 676, 686, 743, 732] | [799, 697, 609, 676, 686, 743, 732] | Passed |
| regression: scenario 2 | [684, 638, 750, 750, 698, 646, 608, 728] | [684, 638, 750, 750, 698, 646, 608, 728] | Passed |
| regression: scenario 3 | [677, 622, 605, 764, 664, 664, 745, 665] | [677, 622, 605, 764, 664, 664, 745, 665] | Passed |
| regression: scenario 4 | [600, 724, 602, 729, 655, 775, 687] | [600, 724, 602, 729, 655, 775, 687] | Passed |
SHA-256 / 4e637f69a25f5c08b519fe4b0ee00ad89e9d5e4c338fcda7b9dbadaf5ead9ebb
Verification & scope
A deterministic bounded teaching model of one thermostat or HVAC controller decision evaluated per sample. Temperatures are integer tenths of a degree Fahrenheit unless stated otherwise. The contract is a stipulated toy convention, not a claim of conformance to any manufacturer, ASHRAE guideline or code. 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:51:47.669756+00:00.
Case digest / db52ab37708cfcd9e3d2377f120e28df19e1c84d454174677af9aca4856c64a1