mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
feat(modelling): Epc.sap_lower_bound() — band → minimum SAP (#1160)
Slice 3a. The inverse of Epc.from_sap_score: the minimum SAP rating in a band (C → 69, B → 81, …), used as the Optimiser's repair target for an INCREASING_EPC goal (goal_value "C" → target SAP 69). Keeps the band-target derivation in the domain rather than re-coupling to backend.app.utils.epc_to_sap_lower_bound. 8 tests incl. round-trip through from_sap_score; pyright strict clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
49e86344d2
commit
504f592a27
5 changed files with 41 additions and 0 deletions
|
|
@ -31,3 +31,18 @@ class Epc(Enum):
|
||||||
if score >= 21:
|
if score >= 21:
|
||||||
return cls.F
|
return cls.F
|
||||||
return cls.G
|
return cls.G
|
||||||
|
|
||||||
|
def sap_lower_bound(self) -> int:
|
||||||
|
"""The minimum SAP rating in this band — the inverse of
|
||||||
|
`from_sap_score` (A → 92, B → 81, C → 69, D → 55, E → 39, F → 21,
|
||||||
|
G → 1). Used as an optimisation target, e.g. "reach band C" → 69."""
|
||||||
|
bounds: dict["Epc", int] = {
|
||||||
|
Epc.A: 92,
|
||||||
|
Epc.B: 81,
|
||||||
|
Epc.C: 69,
|
||||||
|
Epc.D: 55,
|
||||||
|
Epc.E: 39,
|
||||||
|
Epc.F: 21,
|
||||||
|
Epc.G: 1,
|
||||||
|
}
|
||||||
|
return bounds[self]
|
||||||
|
|
|
||||||
0
tests/datatypes/__init__.py
Normal file
0
tests/datatypes/__init__.py
Normal file
0
tests/datatypes/epc/__init__.py
Normal file
0
tests/datatypes/epc/__init__.py
Normal file
0
tests/datatypes/epc/domain/__init__.py
Normal file
0
tests/datatypes/epc/domain/__init__.py
Normal file
26
tests/datatypes/epc/domain/test_epc.py
Normal file
26
tests/datatypes/epc/domain/test_epc.py
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
"""Behaviour of the Epc band enum's SAP mapping — the band a SAP rating falls
|
||||||
|
in, and the minimum SAP rating of a band (the inverse, used as an optimisation
|
||||||
|
target)."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from datatypes.epc.domain.epc import Epc
|
||||||
|
|
||||||
|
|
||||||
|
def test_sap_lower_bound_returns_the_band_floor() -> None:
|
||||||
|
# Act / Assert — the standard SAP10 band floors.
|
||||||
|
assert Epc.A.sap_lower_bound() == 92
|
||||||
|
assert Epc.B.sap_lower_bound() == 81
|
||||||
|
assert Epc.C.sap_lower_bound() == 69
|
||||||
|
assert Epc.D.sap_lower_bound() == 55
|
||||||
|
assert Epc.E.sap_lower_bound() == 39
|
||||||
|
assert Epc.F.sap_lower_bound() == 21
|
||||||
|
assert Epc.G.sap_lower_bound() == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("band", list(Epc))
|
||||||
|
def test_band_floor_round_trips_through_from_sap_score(band: Epc) -> None:
|
||||||
|
# Act / Assert — a band's floor scores back to that band.
|
||||||
|
assert Epc.from_sap_score(band.sap_lower_bound()) is band
|
||||||
Loading…
Add table
Reference in a new issue