From ffbef2d0475a2700f32e3a83015c852e69bdebc5 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Wed, 1 Jul 2026 13:58:39 +0000 Subject: [PATCH] =?UTF-8?q?Re-map=20house-coal=20water-heating=20overrides?= =?UTF-8?q?=20onto=20faithful=20biomass=20and=20immersion=20archetypes=20?= =?UTF-8?q?=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- scripts/reclassify_water_heating.py | 12 ++++ .../scripts/test_reclassify_water_heating.py | 68 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 scripts/reclassify_water_heating.py create mode 100644 tests/scripts/test_reclassify_water_heating.py diff --git a/scripts/reclassify_water_heating.py b/scripts/reclassify_water_heating.py new file mode 100644 index 000000000..b79463ad6 --- /dev/null +++ b/scripts/reclassify_water_heating.py @@ -0,0 +1,12 @@ +"""One-time re-classification of water-heating overrides funnelled into house coal. + +Placeholder — decision function stubbed; filled in GREEN. +""" + +from __future__ import annotations + +from collections.abc import Iterable + + +def water_heating_corrections(stored: Iterable[tuple[str, str]]) -> dict[str, str]: + raise NotImplementedError diff --git a/tests/scripts/test_reclassify_water_heating.py b/tests/scripts/test_reclassify_water_heating.py new file mode 100644 index 000000000..f59e6d200 --- /dev/null +++ b/tests/scripts/test_reclassify_water_heating.py @@ -0,0 +1,68 @@ +"""The water-heating reclassify maps the house-coal dumping ground onto faithful +biomass / wood / dual-fuel / biodiesel / immersion archetypes, leaves genuine coal +and already-correct rows alone, and is idempotent (#1376 / ADR-0043).""" + +from __future__ import annotations + +from scripts.reclassify_water_heating import water_heating_corrections + + +def test_house_coal_bucket_rows_are_remapped_to_faithful_fuels() -> None: + # Arrange — the biomass/wood family + the "no system / immersion assumed" case + # all funnelled into house coal, plus a genuinely-coal row and a correctly- + # classified mains-gas row (descriptions arrive lower-cased from the query). + stored = [ + ("from main heating system: wood logs", "From main system, house coal"), + ( + "from main heating system: dual fuel: mineral and wood", + "From main system, house coal", + ), + ( + "hot-water only community scheme - boilers: biomass (community)", + "From main system, house coal", + ), + ( + "hot-water only community scheme - boilers: heat from boilers using " + "biodiesel from any source (community)", + "From main system, house coal", + ), + ( + "no hot water system present - electric immersion assumed: " + "no heating or hot water", + "From main system, house coal", + ), + # Genuinely coal — stays (guard resolves house coal, value unchanged). + ("from main heating system: house coal", "From main system, house coal"), + # Already correct — the guard does not claim it. + ("from main heating system: mains gas", "From main system, mains gas"), + ] + + # Act + corrections = water_heating_corrections(stored) + + # Assert — only the mis-scored rows move, each to its faithful archetype. + assert corrections == { + "from main heating system: wood logs": "From main system, wood logs", + "from main heating system: dual fuel: mineral and wood": ( + "From main system, dual fuel (mineral and wood)" + ), + "hot-water only community scheme - boilers: biomass (community)": ( + "From main system, biomass (community)" + ), + "hot-water only community scheme - boilers: heat from boilers using " + "biodiesel from any source (community)": ( + "From main system, biodiesel (community)" + ), + "no hot water system present - electric immersion assumed: " + "no heating or hot water": "Electric immersion, electricity", + } + + +def test_already_corrected_rows_need_no_change() -> None: + # Act / Assert — idempotent: a re-run against corrected data is a no-op. + assert ( + water_heating_corrections( + [("from main heating system: wood logs", "From main system, wood logs")] + ) + == {} + )