import re from typing import Dict, Union from model_data.BaseUtility import Definitions from model_data.epc_attributes.attribute_utils import extract_component_types, extract_thermal_transmittance class RoofAttributes(Definitions): ROOF_TYPES = ['pitched', 'roof room', 'loft', 'flat', 'thatched', 'at rafters', 'assumed'] DWELLING_ABOVE = ["another dwelling above", "other premises above"] WELSH_TEXT = { "ar oleddf, dim inswleiddio": "pitched, no insulation", } def __init__(self, description: str): """ :param description: Description of the roof. """ self.description: str = description.lower() self.nodata = not description or description in self.DATA_ANOMALY_MATCHES translation = self.WELSH_TEXT.get(self.description) if translation: self.nodata = False self.description = translation if not self.nodata and not any( rt in self.description for rt in self.ROOF_TYPES + self.DWELLING_ABOVE + ["average thermal transmittance"] ): raise ValueError('Invalid description') def process(self) -> Dict[str, Union[float, str, bool, None]]: result: Dict[str, Union[float, str, bool, None]] = {} if self.nodata: return result description = self.description # thermal transmittance result, description = extract_thermal_transmittance(result, description) # roof type result, description = extract_component_types(result, description, list_of_components=self.ROOF_TYPES) result["has_dwelling_above"] = ( "another dwelling above" in description or "other premises above" in description ) for dwelling_above in self.DWELLING_ABOVE: description = description.replace(dwelling_above, "") result["is_valid"] = "invalid" not in description description = description.replace("invalid", "") # insulation thickness thickness_map = { "ceiling insulated": "average", "insulated": "average", "limited": "below average", "no insulation": "none", "limited insulation": "below average", "additional insulation": "above average", } for key, value in thickness_map.items(): if key in description: result['insulation_thickness'] = value # Remove the match from the description # description = description.replace(key, "") break else: # Extract insulation thickness in mm, if present match = re.search(r'(\d+\+?)\s*mm', description) if match: result['insulation_thickness'] = match.group(1) if "insulation_thickness" not in result: result['insulation_thickness'] = None return result