mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
Prefer a MAIN-bearing prediction template so EPC-less dwellings predict 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fc7cfc70e8
commit
abb822c1c7
1 changed files with 28 additions and 0 deletions
|
|
@ -9,6 +9,7 @@ from datetime import date
|
|||
from typing import Optional, Union
|
||||
|
||||
from datatypes.epc.domain.epc_property_data import (
|
||||
BuildingPartIdentifier,
|
||||
EpcPropertyData,
|
||||
MainHeatingDetail,
|
||||
SapBuildingPart,
|
||||
|
|
@ -32,6 +33,7 @@ from domain.epc_prediction.prediction_target import PredictionTarget
|
|||
def _epc(
|
||||
*,
|
||||
building_parts: int = 1,
|
||||
identifier: BuildingPartIdentifier = BuildingPartIdentifier.MAIN,
|
||||
floor_area: float = 80.0,
|
||||
wall_construction: Union[int, str] = 1,
|
||||
wall_insulation_type: Union[int, str] = 1,
|
||||
|
|
@ -57,6 +59,7 @@ def _epc(
|
|||
parts: list[SapBuildingPart] = []
|
||||
for _ in range(building_parts):
|
||||
part: SapBuildingPart = object.__new__(SapBuildingPart)
|
||||
part.identifier = identifier
|
||||
part.wall_construction = wall_construction
|
||||
part.wall_insulation_type = wall_insulation_type
|
||||
part.construction_age_band = construction_age_band
|
||||
|
|
@ -148,6 +151,31 @@ def test_template_is_the_member_closest_to_the_cohort_median_size() -> None:
|
|||
assert predicted.total_floor_area_m2 == 80.0
|
||||
|
||||
|
||||
def test_template_skips_a_main_less_member_so_the_prediction_has_a_main_part() -> None:
|
||||
# Arrange — the size-median member is OTHER-only (the gov API lodged its part
|
||||
# with a null identifier), but the cohort holds MAIN-bearing neighbours at
|
||||
# other sizes. The structural template must be a MAIN-bearing member so the
|
||||
# predicted dwelling presents a main dwelling — else the modelling handler's
|
||||
# MAIN-part guard rejects an otherwise-rich cohort as "not predictable".
|
||||
cohort = _cohort(
|
||||
_epc(floor_area=80.0, identifier=BuildingPartIdentifier.OTHER),
|
||||
_epc(floor_area=30.0, identifier=BuildingPartIdentifier.MAIN),
|
||||
_epc(floor_area=200.0, identifier=BuildingPartIdentifier.MAIN),
|
||||
)
|
||||
|
||||
# Act
|
||||
predicted: EpcPropertyData = EpcPrediction().predict(
|
||||
PredictionTarget(postcode="LS6 1AA", property_type="2"), cohort
|
||||
)
|
||||
|
||||
# Assert — the predicted dwelling has a MAIN part (seeded from a MAIN-bearing
|
||||
# neighbour), not the OTHER-only median member.
|
||||
assert any(
|
||||
part.identifier is BuildingPartIdentifier.MAIN
|
||||
for part in predicted.sap_building_parts
|
||||
)
|
||||
|
||||
|
||||
def test_sets_main_wall_construction_to_the_cohort_mode() -> None:
|
||||
# Arrange — the template (members[0]) is solid brick (2), but the cohort
|
||||
# majority is cavity (1). The homogeneous categorical should follow the mode,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue