setting up route march script

This commit is contained in:
Khalim Conn-Kowlessar 2024-11-05 13:54:14 +00:00
parent 1e80656904
commit cb4b597272
5 changed files with 136 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="Fastapi-backend" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Route-March" 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="Fastapi-backend" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Route-March" project-jdk-type="Python SDK" />
<component name="PyCharmProfessionalAdvertiser">
<option name="shown" value="true" />
</component>

View file

@ -2,6 +2,7 @@ import os
import time
import re
from urllib.parse import urlencode
import usaddress
import pandas as pd
import numpy as np
@ -257,6 +258,8 @@ class SearchEpc:
params = {"address": self.address1, "postcode": self.postcode}
url = os.path.join(self.client.domestic.host, "search")
if size:
url += "?" + urlencode({k: v for k, v in {"size": size}.items() if v})
for retry in range(self.max_retries):
try:

View file

@ -0,0 +1,122 @@
import os
import pandas as pd
import numpy as np
from dotenv import load_dotenv
from urllib.parse import urlencode
from epc_api.client import EpcClient
load_dotenv(dotenv_path="backend/.env")
EPC_AUTH_TOKEN = os.getenv("EPC_AUTH_TOKEN")
CONFIG = [
{
"filepath": "/Users/khalimconn-kowlessar/Documents/hestia/Route Marches/Surveyors Sites for Week Commencing "
"11.11.2024.xlsx",
"tab": "SETTLE GBIS x 242 ",
"postcode_column": "Postcode",
},
{
"filepath": "/Users/khalimconn-kowlessar/Documents/hestia/Route Marches/Surveyors Sites for Week Commencing "
"11.11.2024.xlsx",
"tab": "ACIS GBIS x 76",
"postcode_column": "Postcode",
},
{
"filepath": "/Users/khalimconn-kowlessar/Documents/hestia/Route Marches/Surveyors Sites for Week Commencing "
"11.11.2024.xlsx",
"tab": "SOUTHERN GBIS x 150",
"postcode_column": "Postcode",
},
{
"filepath": "/Users/khalimconn-kowlessar/Documents/hestia/Route Marches/Surveyors Sites for Week Commencing "
"11.11.2024.xlsx",
"tab": "COMMUNITY HOUSING GBIS x 199",
"postcode_column": "Postcode",
},
{
"filepath": "/Users/khalimconn-kowlessar/Documents/hestia/Route Marches/Surveyors Sites for Week Commencing "
"11.11.2024.xlsx",
"tab": "EASTLIGHT GBIS x 42",
"postcode_column": "Postcode",
},
]
CAVITY_WALL_DESCRIPTIONS = [
"Cavity wall, as built, no insulation (assumed)",
"Cavity wall, as built, partial insulation (assumed)",
"Cavity wall, as built, insulated (assumed)",
"Cavity wall, with internal insulation",
"Cavity wall, with external insulation",
]
ROOF_DESCRIPTIONS = [
"Pitched, no insulation",
"Pitched, no insulation (assumed)",
"Pitched, 25 mm loft insulation",
"Pitched, 50 mm loft insulation",
"Pitched, 75 mm loft insulation",
"Pitched, 100 mm loft insulation",
"Pitched, 150 mm loft insulation",
"Pitched, limited insulation (assumed)",
"Pitched, insulated (assumed)",
]
SOCIAL_TENURES = ["Rented (social)", "rental (social)"]
def main():
"""
This application is used to identify additional units that are private rentals or owner occupies that can be
included in the route marches
Required inputs are the following:
- An excel file that contains one or many tabs that include the addresses to be visited
"""
for config in CONFIG:
# Read in the data
route_march_addresses = pd.read_excel(
config["filepath"],
sheet_name=config["tab"],
engine="openpyxl"
)
postcodes = route_march_addresses[config["postcode_column"]].unique()
epcs = []
for postcode in postcodes:
# Get the EPCs in this postcode
params = {"postcode": postcode}
client = EpcClient(auth_token=EPC_AUTH_TOKEN)
url = os.path.join(client.domestic.host, "search")
url += "?" + urlencode({k: v for k, v in {"size": 1000}.items() if v})
response = client.domestic.call(method="get", url=url, params=params)
postcode_epcs = pd.DataFrame(response["rows"])
# Get the newest EPC, per UPRN
postcode_epcs["uprn"] = np.where(
pd.isnull(postcode_epcs["uprn"]),
postcode_epcs["address"],
postcode_epcs["uprn"]
)
postcode_epcs = postcode_epcs.sort_values("lodgement-date", ascending=False)
postcode_epcs = postcode_epcs.drop_duplicates("uprn", keep="first")
postcode_epcs["Is Cavity Property"] = postcode_epcs["walls-description"].isin(
CAVITY_WALL_DESCRIPTIONS
) & (postcode_epcs["current-energy-efficiency"].astype(int) <= 72)
postcode_epcs["Solar and Loft"] = (postcode_epcs["roof-description"].isin(ROOF_DESCRIPTIONS)) & (
postcode_epcs["photo-supply"].isin(["0", "", "0.0"])) & (
postcode_epcs["current-energy-efficiency"].astype(int) <= 68
)
postcode_epcs = postcode_epcs[postcode_epcs["Is Cavity Property"] | postcode_epcs["Solar and Loft"]]
# Remove any social properties
postcode_epcs = postcode_epcs[~postcode_epcs["tenure"].isin(SOCIAL_TENURES)]
epcs.append(postcode_epcs)
epcs = pd.concat(epcs)

View file

@ -0,0 +1,9 @@
openpyxl
epc-api-python==1.0.2
numpy==2.1.2
pandas==2.2.3
usaddress==0.5.11
fuzzywuzzy==0.18.0
boto3==1.35.44
python-dotenv
tqdm