mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
56 lines
2.4 KiB
Python
56 lines
2.4 KiB
Python
"""Map a Landlord-Override enum *value* to the gov-EPC API *code* space.
|
|
|
|
The `property_overrides` fact layer stores resolved overrides as enum-value
|
|
strings ("House", "Detached"); the EPC-API cohort certs carry numeric codes
|
|
("0", "2") — `EpcPropertyData.property_type = str(schema.property_type)`. EPC
|
|
Prediction filters `comparable.epc.property_type == target.property_type`, so a
|
|
target attribute sourced from overrides must be translated into the code space
|
|
or no comparable ever matches (ADR-0031, the wiring-handover "every cohort
|
|
comes back empty" gotcha).
|
|
|
|
Codes are the gov RdSAP/SAP table values in `datatypes/epc/domain/epc_codes.csv`.
|
|
This module owns "unresolvable": a value that maps to no code returns None.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Optional
|
|
|
|
# property_type codes (epc_codes.csv, `property_type` rows — stable across the
|
|
# RdSAP/SAP schemas that carry each member). "Park home" exists only from
|
|
# SAP-17.0 / RdSAP-17.0 onward; the code itself is stable where present.
|
|
_PROPERTY_TYPE_CODES: dict[str, str] = {
|
|
"House": "0",
|
|
"Bungalow": "1",
|
|
"Flat": "2",
|
|
"Maisonette": "3",
|
|
"Park home": "4",
|
|
}
|
|
|
|
# built_form codes (epc_codes.csv, `built_form` rows). "Not Recorded" lodges as
|
|
# the non-numeric "NR", but cohort comparables carry `str(int)` for built_form,
|
|
# so an "NR" target could never match — and built_form is the SOFT filter, so a
|
|
# non-match only widens the cohort. We therefore treat "Not Recorded" (and the
|
|
# classifier "Unknown") as "no usable built-form signal" → None.
|
|
_BUILT_FORM_CODES: dict[str, str] = {
|
|
"Detached": "1",
|
|
"Semi-Detached": "2",
|
|
"End-Terrace": "3",
|
|
"Mid-Terrace": "4",
|
|
"Enclosed End-Terrace": "5",
|
|
"Enclosed Mid-Terrace": "6",
|
|
}
|
|
|
|
|
|
def property_type_to_code(override_value: str) -> Optional[str]:
|
|
"""The gov-EPC `property_type` code for a Landlord-Override value, or None
|
|
when it has no code ("Unknown", or any unmapped value) — which gates the
|
|
Property out of prediction, as `property_type` is the hard cohort filter."""
|
|
return _PROPERTY_TYPE_CODES.get(override_value)
|
|
|
|
|
|
def built_form_to_code(override_value: str) -> Optional[str]:
|
|
"""The gov-EPC `built_form` code for a Landlord-Override value, or None when
|
|
it has no usable code ("Unknown", "Not Recorded", or any unmapped value).
|
|
built_form is the soft filter, so None simply leaves it unconditioned."""
|
|
return _BUILT_FORM_CODES.get(override_value)
|