completed estimate windows function, though it needs more testing

This commit is contained in:
Khalim Conn-Kowlessar 2023-12-19 19:27:33 +00:00
parent c6c8de6dcf
commit 57f92e6060
4 changed files with 154 additions and 2 deletions

2
.idea/Model.iml generated
View file

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

2
.idea/misc.xml generated
View file

@ -3,7 +3,7 @@
<component name="Black">
<option name="sdkName" value="Python 3.10 (backend)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (backend)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (model_data)" project-jdk-type="Python SDK" />
<component name="PythonCompatibilityInspectionAdvertiser">
<option name="version" value="3" />
</component>

View file

@ -652,3 +652,64 @@ def esimtate_pitched_roof_area(floor_area: float, floor_height: float) -> float:
area = 2 * (slope * wall_width)
return area
def estimate_windows(
property_type, built_form, construction_age_band, floor_area, number_habitable_rooms, extension_count
):
# Base window count based on habitable rooms
window_count = number_habitable_rooms
# Additional windows for non-habitable rooms (e.g., kitchen, bathroom)
# Assuming most houses will have at least one kitchen and one bathroom
# Scale non-habitable windows with the number of habitable rooms
non_habitable_base = 2 # Base for kitchen and bathroom
extra_non_habitable = max(0, (number_habitable_rooms - 3) // 2) # Extra for large houses
window_count += non_habitable_base + extra_non_habitable
# Adjustments based on built form and property type
if property_type in ["House", "Bungalow"] and built_form in ["Semi-Detached", "Detached"]:
built_form_lookup = {
"Semi-Detached": 3,
"Detached": 4,
}
else:
# For Flats and Maisonettes, adjustments might be less
built_form_lookup = {
"Mid-Terrace": 0,
"End-Terrace": 1,
"Semi-Detached": 1,
"Detached": 2,
}
window_count += built_form_lookup.get(built_form, 0)
# Adjust for floor area (larger floor area might indicate more rooms/windows)
if floor_area < 85: # Small to medium properties
# Standard window count likely sufficient
pass
elif 85 <= floor_area <= 120: # Medium to large properties
# More rooms or larger rooms likely, potentially more windows
window_count += 1
elif floor_area > 120: # Very large properties
# Likely to have significantly more or larger rooms
window_count += 2
# Adjust for construction age band
if construction_age_band in ["England and Wales: before 1900", "England and Wales: 1900-1929"]:
# Older houses with smaller, more numerous windows
window_count += 1
# Adjust for extensions (each extension might add windows)
window_count += extension_count
# Adjustments for specific property types
if property_type in ["Flat", "Maisontte"]:
# Flats might have fewer windows due to shared walls
# Maisonettes might follow a similar pattern to flats or small houses
window_count -= 1
# Ensure window count is not negative
if window_count < 0:
raise ValueError("Window count cannot be negative.")
return window_count

View file

@ -427,3 +427,94 @@ def test_external_wall_area():
for num_floors, floor_height, perimeter, built_form, expected in test_cases:
result = recommendation_utils.estimate_external_wall_area(num_floors, floor_height, perimeter, built_form)
assert result == expected, f"Test failed for {built_form}: Expected {expected}, got {result}"
def test_estimate_windows():
# Based on data from an EPR that has 4 windows
windows_case_1 = recommendation_utils.estimate_windows(
property_type="Flat",
built_form="Semi-Detached",
construction_age_band="England and Wales: 1976-1982",
floor_area=37,
number_habitable_rooms=2,
extension_count=0,
)
assert windows_case_1 == 4, f"Expected 4 windows, got {windows_case_1}"
# Based on data from an EPR that has 7 winows, however two of the windows were very small, having areas of
# 0.21m^2 and 0.3m^2 respectively. We see 6 as a reasonable estimate for the number of windows
windows_case_2 = recommendation_utils.estimate_windows(
property_type="House",
built_form="Mid-Terrace",
construction_age_band="England and Wales: 1950-1966",
floor_area=69,
number_habitable_rooms=4,
extension_count=0,
)
assert windows_case_2 == 6, f"Expected 6 windows, got {windows_case_2}"
# Based on data from an EPR on a bungalow, that has 6 windows. Two of the windows are small, both have a 0.4m^2 area
# and so 5 windows is an acceptable estimate
windows_case_3 = recommendation_utils.estimate_windows(
property_type="Bungalow",
built_form="Mid-Terrace",
construction_age_band="England and Wales: 1967-1975",
floor_area=56,
number_habitable_rooms=3,
extension_count=0,
)
assert windows_case_3 == 5, f"Expected 5 windows, got {windows_case_3}"
# Based on data from an EPR on a end terrace house that has 8 windows. One of the windows is very small, with an
# area of 0.25 m^2 and so 7 windows is an acceptable estimate
windows_case_4 = recommendation_utils.estimate_windows(
property_type="House",
built_form="End-Terrace",
construction_age_band="England and Wales: 1967-1975",
floor_area=77.28,
number_habitable_rooms=4,
extension_count=0,
)
assert windows_case_4 == 7, f"Expected 7 windows, got {windows_case_4}"
# Based on data from an EPR on a Semi-detatched house that has 11 windows based on the associated condition report
# Right now, we estimate 12 windows for this property
windows_case_5 = recommendation_utils.estimate_windows(
property_type="House",
built_form="Semi-Detached",
construction_age_band="England and Wales: 1950-1966",
floor_area=88.4,
number_habitable_rooms=5,
extension_count=0,
)
assert windows_case_5 == 12, f"Expected 12 windows, got {windows_case_5}"
# Based on Khalim's flat which has 3 windows. There is no construction age band on the EPC. The windows are large
# so an estimate of 5 windows is a reasonable estimate
windows_case_6 = recommendation_utils.estimate_windows(
property_type="Flat",
built_form="",
construction_age_band="",
floor_area=100,
number_habitable_rooms=3,
extension_count=0,
)
assert windows_case_6 == 5, f"Expected 5 windows, got {windows_case_6}"
# Based on an EPR semi detatched house though we don't have the exact number of windows. We estimate 10
windows_case_7 = recommendation_utils.estimate_windows(
property_type="House",
built_form="Semi-Detached",
construction_age_band="England and Wales: 1967-1975",
floor_area=85,
number_habitable_rooms=4,
extension_count=0,
)
assert windows_case_7 == 10, f"Expected 10 windows, got {windows_case_7}"