refactoring recommendations

This commit is contained in:
Khalim Conn-Kowlessar 2023-07-20 18:02:17 +01:00
parent deda5bc025
commit 2a002c1faf
6 changed files with 92 additions and 60 deletions

2
.idea/Model.iml generated
View file

@ -6,7 +6,7 @@
<sourceFolder url="file://$MODULE_DIR$/model_data" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/open_uprn" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="Python 3.10 (hestia-data)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.10 (backend)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

2
.idea/misc.xml generated
View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (hestia-data)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (backend)" project-jdk-type="Python SDK" />
<component name="PythonCompatibilityInspectionAdvertiser">
<option name="version" value="3" />
</component>

View file

@ -102,18 +102,52 @@ async def trigger_plan(body: PlanTriggerRequest):
logger.info("Getting components and properties recommendations")
for p in input_properties:
recommendations = []
for property_id, p in enumerate(input_properties):
# For each property, classiy floor area decide
total_floor_area_group_decile = classify_decile_newvalues(
decile_boundaries=floors_decile_data["decile_boundaries"],
decile_labels=floors_decile_data["decile_labels"],
new_values=[float(p.data["total-floor-area"])],
)[0]
print("hey")
print(total_floor_area_group_decile)
for p in input_properties:
# Property recommendations
p.get_components(cleaned)
# floor_recommendations = FloorRecommendations(property_instance=p, uvalue_estimates=uvalue_estimates_floors)
# Floor recommendations
floor_recommender = FloorRecommendations(property_instance=p, uvalue_estimates=uvalue_estimates_floors)
floor_recommender.recommend()
floor_recommendations = floor_recommender.recommendations
# insert property id
for rec in floor_recommendations:
rec["property_id"] = property_id
# Wall recommendations
# We would make this u-value query directly to the database
total_floor_area_group_decile = classify_decile_newvalues(
decile_boundaries=walls_decile_data["decile_boundaries"],
decile_labels=walls_decile_data["decile_labels"],
new_values=[float(p.data["total-floor-area"])],
)[0]
# This
walls_u_value_estimate = [
x for x in uvalue_estimates_walls
if (x['local-authority'] == p.data["local-authority"]) &
(x['property-type'] == p.data["property-type"]) &
(x['built-form'] == p.data["built-form"]) &
(x['walls-energy-eff'] == p.data["walls-energy-eff"]) &
(x['walls-env-eff'] == p.data["walls-env-eff"]) &
(x['total-floor-area_group'] == total_floor_area_group_decile)
]
wall_recomendations = WallRecommendations(property_instance=p, uvalue_estimates=walls_u_value_estimate)
wall_recomendations.recommend()
wall_recomendations = wall_recomendations.recommendations
# insert property id
for rec in wall_recomendations:
rec["property_id"] = property_id
recommendations.extend(floor_recommendations)
return {"message": "Plan complete"}

View file

@ -341,20 +341,20 @@ def app():
)
# Production of sample data for land registry
address_meta = [
{
"postcode": x["postcode"].upper(),
"address1": x["address1"].upper(),
"address2": x["address2"].upper(),
"address3": x["address3"].upper(),
"address": x["address"],
"uprn": x["uprn"]
} for x in data
]
import pickle
with open("sample_addresses.pkl", "wb") as f:
pickle.dump(address_meta, f)
# address_meta = [
# {
# "postcode": x["postcode"].upper(),
# "address1": x["address1"].upper(),
# "address2": x["address2"].upper(),
# "address3": x["address3"].upper(),
# "address": x["address"],
# "uprn": x["uprn"]
# } for x in data
# ]
#
# import pickle
# with open("sample_addresses.pkl", "wb") as f:
# pickle.dump(address_meta, f)
# Incorporate input data into cleaning
cleaner = EpcClean(data)

View file

@ -88,7 +88,9 @@ class FloorRecommendations(BaseUtility):
"Ground": 0,
# We don't know what floor level, we just make sure it's not 0
"mid floor": 1,
"4th": 4
"4th": 4,
# We set
"00": 0,
}
def __init__(self, property_instance: Property, uvalue_estimates):
@ -253,7 +255,7 @@ class FloorRecommendations(BaseUtility):
self.recommend_floor_insulation(u_value=u_value, parts=solid_floor_insulation_parts)
def _get_floors_uvalue_estimate(self, total_floor_area_group_decile):
blah
"""
Wrapper function which contains the methodology to extract a property's walls u-value estimate
when we don't have a true value and if we can't base our assumption off of the material

View file

@ -1,5 +1,6 @@
import itertools
import math
from statistics import mean
from model_data.Property import Property
from model_data.BaseUtility import BaseUtility
@ -321,10 +322,12 @@ class WallRecommendations(BaseUtility):
if new_u_value <= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE:
lowest_selected_u_value = update_lowest_selected_u_value(lowest_selected_u_value, new_u_value)
recommendations.append({
"parts": [get_recommended_part(part, depth)],
"new_u_value": new_u_value,
})
recommendations.append(
{
"parts": [get_recommended_part(part, depth)],
"new_u_value": new_u_value,
}
)
return recommendations
@ -405,46 +408,39 @@ class WallRecommendations(BaseUtility):
:return:
"""
total_floor_area_group_decile = self.uvalue_estimates.classify_decile_newvalues(
decile_boundaries=self.uvalue_estimates.walls_decile_data["decile_boundaries"],
decile_labels=self.uvalue_estimates.walls_decile_data["decile_labels"],
new_values=[float(self.property.data["total-floor-area"])],
)[0]
u_value_estimate = self.uvalue_estimates.walls[
(self.uvalue_estimates.walls["local-authority"] == self.property.data["local-authority"]) &
(self.uvalue_estimates.walls["property-type"] == self.property.data["property-type"]) &
(self.uvalue_estimates.walls["built-form"] == self.property.data["built-form"]) &
(self.uvalue_estimates.walls["walls-energy-eff"] == self.property.data["walls-energy-eff"]) &
(self.uvalue_estimates.walls["walls-env-eff"] == self.property.data["walls-env-eff"]) &
(self.uvalue_estimates.walls["total-floor-area_group"] == total_floor_area_group_decile)
]
if u_value_estimate.empty:
if not self.uvalue_estimates:
raise ValueError("No U-value estimate found for the given property")
# Because of how spuriously populated the data is for number-habitable-rooms and number-heated-rooms,
# we will try and filter on these to see if we get a result
habitable_rooms_filter = (
self.uvalue_estimates.walls["number-habitable-rooms"] == self.property.data["number-habitable-rooms"]
habitable_rooms_filer = [
x for x in self.uvalue_estimates if
x["number-habitable-rooms"] == self.property.data["number-habitable-rooms"]
]
if not habitable_rooms_filer:
# Take a mean of all the u-value estimates
return mean(
[x["median_thermal_transmittance"] for x in self.uvalue_estimates if x["median_thermal_transmittance"]]
)
# Try perform a filter on heated rooms
heated_rooms_filter = [
x for x in habitable_rooms_filer if
x["number-heated-rooms"] == self.property.data["number-heated-rooms"]
]
if not heated_rooms_filter:
# Take a mean of all the u-value estimates
return mean(
[x["median_thermal_transmittance"] for x in habitable_rooms_filer if x["median_thermal_transmittance"]]
)
return mean(
[x["median_thermal_transmittance"] for x in heated_rooms_filter if x["median_thermal_transmittance"]]
)
if any(habitable_rooms_filter):
u_value_estimate = u_value_estimate[habitable_rooms_filter]
heated_rooms_filter = (
self.uvalue_estimates.walls["number-heated-rooms"] == self.property.data["number-heated-rooms"]
)
if any(heated_rooms_filter):
u_value_estimate = u_value_estimate[heated_rooms_filter]
# It's possible for us to have multiple rows if we didn't do a habitable/heated rooms filter so we
# average
return u_value_estimate["median_thermal_transmittance"].mean()
@staticmethod
def rvalue_per_mm(total_r_value: float, thickness_mm: float) -> float:
"""Return R-value per mm.