basic unit tests for fireplace recommendations

This commit is contained in:
Khalim Conn-Kowlessar 2023-10-24 06:23:05 +11:00
parent 9346b82c2e
commit 57c8788a37
6 changed files with 151 additions and 4 deletions

View file

@ -130,6 +130,16 @@ async def trigger_plan(body: PlanTriggerRequest):
# with open("new_sap_dataset.pickle", "rb") as f:
# new_sap_dataset = pickle.load(f)
# import pickle
# with open("cleaned.pickle", "rb") as f:
# cleaned = pickle.dump(f)
# with open("sap_dataset.pickle", "rb") as f:
# sap_dataset = pickle.load(f)
# with open("materials_by_type", "rb") as f:
# materials_by_type = pickle.load(f)
recommendations = {}
recommendations_scoring_data = []

View file

@ -1,10 +1,10 @@
import math
from backend import Property
from backend.Property import Property
from typing import List
from datatypes.enums import QuantityUnits
from recommendations.recommendation_utils import (
get_roof_u_value, r_value_per_mm_to_u_value, calculate_u_value_uplift, is_diminishing_returns,
update_lowest_selected_u_value, get_recommended_part
update_lowest_selected_u_value, get_recommended_part, convert_thickness_to_numeric
)
@ -35,10 +35,13 @@ class RoofRecommendations:
def recommend(self):
u_value = self.property.roof["thermal_transmittance"]
insulation_thickness = self.property.walls["insulation_thickness"]
insulation_thickness = convert_thickness_to_numeric(self.property.roof["insulation_thickness"])
# We check if the roof is already insulated and if so, we exit
if insulation_thickness in ["average", "above average"]:
# Building regulations part L recommend installing at least 270mm of insulation, however generally we
# experience diminishing returns in terms of SAP once we go beyond around 150mm of insulation
if insulation_thickness < 270:
return
# If we have a u-value already, need to implement this

View file

@ -534,3 +534,29 @@ def calculate_r_value_per_mm(thickness_mm, thermal_conductivity_w_mK):
r_value_per_mm = r_value_m2k_w / thickness_mm
return r_value_per_mm
def convert_thickness_to_numeric(string_thickness):
"""
Roof insulation thickness could be a string like "None", "300mm+" or a numeric string.
This function will convert these strings to a number for easy usage
:param string_thickness: string measure of insulation thickness
:return: integer measure of insulation thickness
"""
lookup = {
"none": 0,
"below average": 50,
"average": 100,
"above average": 270
}
mapped = lookup.get(string_thickness)
if mapped is not None:
return mapped
if "+" in string_thickness:
return int(string_thickness.replace("+", ""))
return int(string_thickness)

View file

@ -0,0 +1,58 @@
from backend.Property import Property
from unittest.mock import Mock
from recommendations.FireplaceRecommendations import FireplaceRecommendations
class TestFirepaceRecommendations:
def test_no_fireplaces(self):
property_instance = Property(id=0, address1="fake", postcode="fake", epc_client=Mock())
property_instance.data = {
"number-open-fireplaces": 0
}
recommender = FireplaceRecommendations(
property_instance=property_instance
)
assert recommender.recommendation is None
recommender.recommend()
assert recommender.recommendation is None
def test_one_fireplace(self):
property_instance = Property(id=0, address1="fake", postcode="fake", epc_client=Mock())
property_instance.data = {
"number-open-fireplaces": 1
}
recommender = FireplaceRecommendations(
property_instance=property_instance
)
assert recommender.recommendation is None
recommender.recommend()
assert recommender.recommendation
assert recommender.recommendation[0]["type"] == "sealing_open_fireplace"
assert recommender.recommendation[0]["cost"] == 300
def test_multiple_fireplaces(self):
property_instance = Property(id=0, address1="fake", postcode="fake", epc_client=Mock())
property_instance.data = {
"number-open-fireplaces": 3
}
recommender = FireplaceRecommendations(
property_instance=property_instance
)
assert recommender.recommendation is None
recommender.recommend()
assert recommender.recommendation
assert recommender.recommendation[0]["type"] == "sealing_open_fireplace"
assert recommender.recommendation[0]["cost"] == 900

View file

@ -277,6 +277,17 @@ class TestRecommendationUtils:
insulation_thickness=None,
)
def test_convert_thickness_to_numeric(self):
assert recommendation_utils.convert_thickness_to_numeric("none") == 0
assert recommendation_utils.convert_thickness_to_numeric("below average") == 50
assert recommendation_utils.convert_thickness_to_numeric("average") == 100
assert recommendation_utils.convert_thickness_to_numeric("above average") == 270
assert recommendation_utils.convert_thickness_to_numeric("300+") == 300
assert recommendation_utils.convert_thickness_to_numeric("400+") == 400
assert recommendation_utils.convert_thickness_to_numeric("270") == 270
def test_estimate_perimeter_regular_inputs():
assert math.isclose(

View file

@ -0,0 +1,39 @@
from backend.Property import Property
from unittest.mock import Mock
from recommendations.RoofRecommendations import RoofRecommendations
loft_insulation_materials = [
{
'id': 18, 'type': 'loft_insulation', 'description': 'Iso Spacesaver Mineral Wool insulation',
'depths': [270, 300], 'depth_unit': 'mm', 'cost': [9, 10], 'cost_unit': 'gbp_sq_meter',
'r_value_per_mm': 0.022727273, 'r_value_unit': 'square_meter_kelvin_per_watt',
'thermal_conductivity': 0.044, 'thermal_conductivity_unit': 'watt_per_meter_kelvin',
'link': 'https://flooringwarehousedirect.co.uk/product/isover-spacesaver-roll-100mm-x-1160mm-x-12-18m-14-13m2/',
'is_active': True
}
]
class TestRoofRecommendations:
def test_loft_insulation_recommendation_no_insulation(self):
property_instance = Property(id=0, address1="fake", postcode="fake", epc_client=Mock())
property_instance.age_band = "F"
property_instance.floor_area = 100
property_instance.roof = {
'original_description': 'Pitched, no insulation (assumed)',
'clean_description': 'Pitched, no insulation',
'thermal_transmittance': None,
'thermal_transmittance_unit': None,
'is_pitched': True, 'is_roof_room': False, 'is_loft': False, 'is_flat': False, 'is_thatched': False,
'is_at_rafters': False, 'is_assumed': True, 'has_dwelling_above': False, 'is_valid': True,
'insulation_thickness': 'none', 'roof_thermal_transmittance': None, 'roof_insulation_thickness': 'none'
}
roof_recommender = RoofRecommendations(property_instance=property_instance, materials=loft_insulation_materials)
assert not roof_recommender.recommendations
roof_recommender.recommend()
assert len(roof_recommender.recommendations)