mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
handle no data for floors
This commit is contained in:
parent
4a1a3fec14
commit
1bd69e8c61
4 changed files with 21 additions and 8 deletions
|
|
@ -408,6 +408,7 @@ def handler():
|
||||||
# TODO: Add in the u-values for roofs rather than the description
|
# TODO: Add in the u-values for roofs rather than the description
|
||||||
# TODO: Add in the actual property features for walls, floors, roof, not just the u-value
|
# TODO: Add in the actual property features for walls, floors, roof, not just the u-value
|
||||||
# TODO: Think about how we use sap vs rdsap - should we add a feature in the model for transaction-type?
|
# TODO: Think about how we use sap vs rdsap - should we add a feature in the model for transaction-type?
|
||||||
|
# TODO: Remove cases where descriptions have no data or are error cases
|
||||||
#
|
#
|
||||||
# property type looks okay - we're definitely low on the number of bungalows
|
# property type looks okay - we're definitely low on the number of bungalows
|
||||||
# number-habitable-rooms & number-heated-rooms is unpopulated so pretty useless atm
|
# number-habitable-rooms & number-heated-rooms is unpopulated so pretty useless atm
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,26 @@ class FloorAttributes(BaseUtility):
|
||||||
DWELLING_BELOW = ["another dwelling below", "other premises below"]
|
DWELLING_BELOW = ["another dwelling below", "other premises below"]
|
||||||
FLOOR_TYPES = ["assumed", "to unheated space", "to external air", "suspended", "solid"]
|
FLOOR_TYPES = ["assumed", "to unheated space", "to external air", "suspended", "solid"]
|
||||||
|
|
||||||
|
# For the short term, while we are still exploring the data, we maintain a list of error cases which
|
||||||
|
# we want to ignore and consider as no data.
|
||||||
|
|
||||||
|
OBSERVED_ERRORS = ["Conservatory"]
|
||||||
|
|
||||||
def __init__(self, description: str):
|
def __init__(self, description: str):
|
||||||
self.description: str = description.lower()
|
self.description: str = description.lower()
|
||||||
|
|
||||||
self.nodata = not description or description in self.DATA_ANOMALY_MATCHES
|
self.nodata = not description or description in self.DATA_ANOMALY_MATCHES or description in self.OBSERVED_ERRORS
|
||||||
|
|
||||||
if not description or not any(
|
if not self.nodata and not any(
|
||||||
rt in self.description for rt in self.FLOOR_TYPES + self.DWELLING_BELOW + ["average thermal transmittance"]
|
rt in self.description for rt in
|
||||||
|
self.FLOOR_TYPES + self.DWELLING_BELOW + ["average thermal transmittance"]
|
||||||
):
|
):
|
||||||
raise ValueError('Invalid description')
|
raise ValueError('Invalid description')
|
||||||
|
|
||||||
def process(self) -> Dict[str, Union[str, bool, int, None]]:
|
def process(self) -> Dict[str, Union[str, bool, int, None]]:
|
||||||
|
|
||||||
if self.nodata:
|
if self.nodata:
|
||||||
return {}
|
return {"no_data": True}
|
||||||
|
|
||||||
result: Dict[str, Union[float, str, bool, None]] = {}
|
result: Dict[str, Union[float, str, bool, None]] = {}
|
||||||
description = self.description
|
description = self.description
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class RoofAttributes(BaseUtility):
|
||||||
|
|
||||||
self.description: str = description.lower()
|
self.description: str = description.lower()
|
||||||
self.nodata = not description or description in self.DATA_ANOMALY_MATCHES
|
self.nodata = not description or description in self.DATA_ANOMALY_MATCHES
|
||||||
|
|
||||||
if not self.nodata and not any(
|
if not self.nodata and not any(
|
||||||
rt in self.description for rt in self.ROOF_TYPES + self.DWELLING_ABOVE + ["average thermal transmittance"]
|
rt in self.description for rt in self.ROOF_TYPES + self.DWELLING_ABOVE + ["average thermal transmittance"]
|
||||||
):
|
):
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,10 @@ class TestCleanFloor:
|
||||||
assert floor_attr.description == valid_description.lower()
|
assert floor_attr.description == valid_description.lower()
|
||||||
|
|
||||||
# Test initialization with an empty description
|
# Test initialization with an empty description
|
||||||
with pytest.raises(ValueError):
|
empty = FloorAttributes('')
|
||||||
FloorAttributes('')
|
assert empty.nodata
|
||||||
|
output = empty.process()
|
||||||
|
assert output == {"no_data": True}
|
||||||
|
|
||||||
# Test initialization with a description that contains none of the keywords
|
# Test initialization with a description that contains none of the keywords
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
|
|
@ -33,7 +35,6 @@ class TestCleanFloor:
|
||||||
def test_invalid_description(self):
|
def test_invalid_description(self):
|
||||||
# Test that invalid descriptions raise a ValueError
|
# Test that invalid descriptions raise a ValueError
|
||||||
invalid_descriptions = [
|
invalid_descriptions = [
|
||||||
"",
|
|
||||||
"invalid description",
|
"invalid description",
|
||||||
"description with no known floor types or thermal transmittance",
|
"description with no known floor types or thermal transmittance",
|
||||||
]
|
]
|
||||||
|
|
@ -47,3 +48,8 @@ class TestCleanFloor:
|
||||||
invalid_description = 'description without keywords'
|
invalid_description = 'description without keywords'
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
FloorAttributes(invalid_description)
|
FloorAttributes(invalid_description)
|
||||||
|
|
||||||
|
def test_known_errors(self):
|
||||||
|
error_description = "Conservatory"
|
||||||
|
obj = FloorAttributes(error_description)
|
||||||
|
assert obj.nodata
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue