Sell no works to a dwelling already at the goal band 🟩

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-21 10:05:55 +00:00
parent 8548b8304b
commit bc2f6c8a82
2 changed files with 24 additions and 2 deletions

View file

@ -491,10 +491,17 @@ def _objective_for(
def _target_sap(scenario: Scenario) -> Optional[float]:
"""The SAP rating the Optimiser repairs toward — the floor of the goal
band for an INCREASING_EPC goal, else None (no SAP target)."""
band for an INCREASING_EPC goal, else None (no SAP target).
On the **continuous** scale, because that is the currency every figure the
Optimiser compares it against is in. The dwelling is in the goal band once
its *published* rating is, which happens half a point below the integer
floor target the integer and a dwelling publishing at the floor reads as a
fraction short, and the Optimiser buys works toward a band it is already in
(#1654)."""
if scenario.goal != PortfolioGoal.INCREASING_EPC.value:
return None
return float(Epc(scenario.goal_value).sap_lower_bound())
return Epc(scenario.goal_value).sap_lower_bound_continuous()
def _best_practice_key(option: MeasureOption) -> int:

View file

@ -40,3 +40,18 @@ def test_dwelling_published_at_the_goal_band_is_sold_no_works() -> None:
# Assert — nothing to buy: the goal is already met.
assert plan.measures == ()
assert plan.cost_of_works == 0.0
def test_dwelling_below_the_goal_band_is_still_taken_to_it() -> None:
# Arrange — the same cert with an uninsulated loft scores a continuous
# 37.349, published SAP 37: band F, genuinely short of band D. Lowering the
# target by half a point must not let the package stop short of the band.
below_band_d = _dwelling("loft_001431_before.pdf")
# Act
plan: Plan = run_modelling(below_band_d, goal_band="D", print_table=False)
# Assert — real works, and they carry the dwelling into band D.
assert plan.measures != ()
assert plan.cost_of_works > 0.0
assert plan.post_retrofit.sap_continuous >= 54.5