mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
working on presentation and content
This commit is contained in:
parent
c0b1acef98
commit
35a75bc4e5
6 changed files with 85 additions and 31 deletions
|
|
@ -470,7 +470,7 @@ class Property:
|
|||
to_update[k] = None
|
||||
return to_update
|
||||
|
||||
def get_full_property_data(self):
|
||||
def get_full_property_data(self, current_valuation=None):
|
||||
"""
|
||||
This method extracts the data which is pushed to the database, containing core information, from the EPC
|
||||
about a property
|
||||
|
|
@ -492,6 +492,7 @@ class Property:
|
|||
"tenure": self.data["tenure"],
|
||||
"current_epc_rating": self.data["current-energy-rating"],
|
||||
"current_sap_points": self.data["current-energy-efficiency"],
|
||||
"current_valuation": current_valuation
|
||||
}
|
||||
|
||||
property_data = self._clean_upload_data(property_data)
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ class PropertyModel(Base):
|
|||
tenure = Column(Text)
|
||||
current_epc_rating = Column(Enum(Epc))
|
||||
current_sap_points = Column(Float)
|
||||
current_valuation = Column(Float)
|
||||
|
||||
|
||||
class FeatureRating(enum.Enum):
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ class Plan(Base):
|
|||
property_id = Column(BigInteger, ForeignKey(PropertyModel.id), nullable=False)
|
||||
created_at = Column(TIMESTAMP, nullable=False, server_default=func.now())
|
||||
is_default = Column(Boolean, nullable=False)
|
||||
valuation_increase_lower_bound = Column(Float)
|
||||
valuation_increase_upper_bound = Column(Float)
|
||||
valuation_increase_average = Column(Float)
|
||||
|
||||
|
||||
class PlanRecommendations(Base):
|
||||
|
|
|
|||
|
|
@ -291,27 +291,43 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
batch_properties = input_properties[i:i + BATCH_SIZE]
|
||||
|
||||
for p in batch_properties:
|
||||
recommendations_to_upload = recommendations.get(p.id, [])
|
||||
default_recommendations = [r for r in recommendations_to_upload if r["default"]]
|
||||
total_sap_points = sum([r["sap_points"] for r in default_recommendations])
|
||||
new_sap_points = float(p.data["current-energy-efficiency"]) + total_sap_points
|
||||
new_epc = sap_to_epc(new_sap_points)
|
||||
|
||||
valuations = PropertyValuation.estimate(property_instance=p, target_epc=new_epc)
|
||||
|
||||
# Your existing operations
|
||||
property_details_epc = p.get_property_details_epc(
|
||||
portfolio_id=body.portfolio_id, rating_lookup=rating_lookup
|
||||
portfolio_id=body.portfolio_id, rating_lookup=rating_lookup,
|
||||
)
|
||||
create_property_details_epc(session, property_details_epc)
|
||||
|
||||
update_or_create_property_spatial_details(session, p.uprn, p.spatial)
|
||||
|
||||
property_data = p.get_full_property_data()
|
||||
property_data = p.get_full_property_data(current_valuation=valuations["current_value"])
|
||||
update_property_data(
|
||||
session, property_id=p.id, portfolio_id=body.portfolio_id, property_data=property_data
|
||||
)
|
||||
|
||||
recommendations_to_upload = recommendations.get(p.id, [])
|
||||
if not recommendations_to_upload:
|
||||
continue
|
||||
|
||||
new_plan_id = create_plan(session, {
|
||||
"portfolio_id": body.portfolio_id,
|
||||
"property_id": p.id,
|
||||
"is_default": True
|
||||
"is_default": True,
|
||||
"valuation_increase_lower_bound": (
|
||||
valuations["lower_bound_increased_value"] - valuations["current_value"]
|
||||
),
|
||||
"valuation_increase_upper_bound": (
|
||||
valuations["upper_bound_increased_value"] - valuations["current_value"]
|
||||
),
|
||||
"valuation_increase_average": (
|
||||
valuations["average_increased_value"] - valuations["current_value"]
|
||||
),
|
||||
})
|
||||
|
||||
uploaded_recommendation_ids = upload_recommendations(session, recommendations_to_upload, p.id)
|
||||
|
|
@ -320,14 +336,6 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
session, plan_id=new_plan_id, recommendation_ids=uploaded_recommendation_ids
|
||||
)
|
||||
|
||||
# Get defaults
|
||||
default_recommendations = [r for r in recommendations_to_upload if r["default"]]
|
||||
total_sap_points = sum([r["sap_points"] for r in default_recommendations])
|
||||
new_sap_points = float(p.data["current-energy-efficiency"]) + total_sap_points
|
||||
new_epc = sap_to_epc(new_sap_points)
|
||||
|
||||
valuations = PropertyValuation.estimate(property_instance=p, target_epc=new_epc)
|
||||
|
||||
property_valuation_increases.append(
|
||||
valuations["average_increased_value"] - valuations["current_value"]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
from pptx.enum.text import PP_ALIGN
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
import matplotlib.pyplot as plt
|
||||
|
|
@ -148,26 +149,64 @@ def save_figure_as_image(figure, filename='temp_plot.png'):
|
|||
plt.close(figure) # Close the figure to prevent it from displaying in notebooks or Python environments
|
||||
|
||||
|
||||
def add_commentary_with_bullets(slide, commentary, top_inches, left_inches=Inches(1), width_inches=Inches(8),
|
||||
height_inches=Inches(2)):
|
||||
"""
|
||||
Adds commentary with bullet points to a slide.
|
||||
|
||||
:param slide: The slide object to add the commentary to.
|
||||
:param commentary: The commentary text, with sections separated by newlines for bullet points.
|
||||
:param top_inches: The top position of the commentary text box.
|
||||
:param left_inches: The left position of the commentary text box.
|
||||
:param width_inches: The width of the commentary text box.
|
||||
:param height_inches: The height of the commentary text box.
|
||||
"""
|
||||
txBox = slide.shapes.add_textbox(left_inches, top_inches, width_inches, height_inches)
|
||||
tf = txBox.text_frame
|
||||
|
||||
# Configure text frame
|
||||
tf.word_wrap = True
|
||||
tf.auto_size = True
|
||||
tf.paragraphs[0].alignment = PP_ALIGN.LEFT
|
||||
|
||||
# Split the commentary into sections for bullet points
|
||||
sections = commentary.split("\n")
|
||||
|
||||
for i, section in enumerate(sections):
|
||||
if i > 0:
|
||||
p = tf.add_paragraph() # Add a new paragraph for each section after the first
|
||||
else:
|
||||
p = tf.paragraphs[0] # Use the first paragraph for the first section
|
||||
p.text = section
|
||||
p.space_after = Pt(14) # Adjust space after each bullet point as needed
|
||||
p.font.size = Pt(14) # Adjust font size as needed
|
||||
p.level = 0 # Bullet level, can be adjusted for nested bullets
|
||||
p.space_before = Pt(0)
|
||||
|
||||
|
||||
def add_slide_with_image(prs, title, img_path=None, commentary=None):
|
||||
"""
|
||||
Adds a slide with an image and optional commentary.
|
||||
Adds a slide with an image (if provided) and optional commentary. If no image is provided,
|
||||
places the commentary text in the middle of the slide.
|
||||
"""
|
||||
slide_layout = prs.slide_layouts[5] # Title and Content layout
|
||||
slide = prs.slides.add_slide(slide_layout)
|
||||
title_placeholder = slide.shapes.title
|
||||
title_placeholder.text = title
|
||||
|
||||
# Add the image
|
||||
# Determine the position of the commentary text box based on whether an image is included
|
||||
if img_path:
|
||||
# Add the image
|
||||
slide.shapes.add_picture(img_path, Inches(1), Inches(1.5), Inches(8), Inches(4.5))
|
||||
# Position for commentary when image is present
|
||||
commentary_top = Inches(6)
|
||||
else:
|
||||
# Position for commentary when image is not present (centered vertically)
|
||||
commentary_top = Inches(3)
|
||||
|
||||
# Add commentary if provided
|
||||
if commentary:
|
||||
txBox = slide.shapes.add_textbox(Inches(1), Inches(6), Inches(8), Inches(1))
|
||||
tf = txBox.text_frame
|
||||
p = tf.add_paragraph()
|
||||
p.text = commentary
|
||||
p.font.size = Pt(14) # Adjust font size as needed
|
||||
add_commentary_with_bullets(slide, commentary, commentary_top)
|
||||
|
||||
|
||||
def create_powerpoint(data, save_location):
|
||||
|
|
|
|||
|
|
@ -104,16 +104,18 @@ def app():
|
|||
)
|
||||
|
||||
# Valuation: upper and lower bounds - TODO!
|
||||
min_valuation, max_valuation, average_valuation = 0, 0, 0
|
||||
min_valuation, max_valuation, average_valuation = (0, 0, 0)
|
||||
|
||||
recommendations_df.keys()
|
||||
|
||||
slide_1_commentary = (
|
||||
f"Floor areas range from {min_area} to {max_area} square meters, with an average of {average_area} square "
|
||||
f"meters. "
|
||||
f"meters. \n"
|
||||
f"Annual energy consumption ranges from {min_energy_consumption} to {max_energy_consumption} kWh, with an "
|
||||
f"average of {average_consumption} kWh. "
|
||||
f"CO2 emissions range from {min_co2} to {max_co2} tonnes, with an average of {average_co2} tonnes. "
|
||||
f"average of {average_consumption} kWh. \n"
|
||||
f"CO2 emissions range from {min_co2} to {max_co2} tonnes, with an average of {average_co2} tonnes. \n"
|
||||
f"Valuations range from £{min_valuation} to £{max_valuation} £, with an average of £"
|
||||
f"{average_valuation}."
|
||||
f"{average_valuation}.\n"
|
||||
)
|
||||
|
||||
############
|
||||
|
|
@ -154,13 +156,13 @@ def app():
|
|||
)
|
||||
|
||||
slide_2_commentary = (
|
||||
f"{n_units_to_target} expected to achieve EPC {EPC_TARGET} "
|
||||
f"Measures include: {measures}"
|
||||
f"{n_units_to_target} units expected to achieve EPC {EPC_TARGET} \n"
|
||||
f"Measures include: {measures}\n"
|
||||
f"Valuation increase per property: £{min_valuation_impact}-{max_valuation_impact}, average: £"
|
||||
f"{average_valuation_impact}"
|
||||
f"Bill savings per property: £{min_bill_savings}-{max_bill_savings}, average: £{average_bill_savings}"
|
||||
f"Total CO2 reduction: {min_co2_reduction}-{max_co2_reduction} tonnes, average: {average_co2_reduction}"
|
||||
f"tonnes, total for the {n_units_to_target} properties: {total_co2_reduction} tonnes"
|
||||
f"{average_valuation_impact}\n"
|
||||
f"Bill savings per property: £{min_bill_savings}-{max_bill_savings}, average: £{average_bill_savings}\n"
|
||||
f"Total CO2 reduction: {min_co2_reduction}-{max_co2_reduction} tonnes, average: {average_co2_reduction}\n"
|
||||
f"tonnes, total for the {n_units_to_target} properties: {total_co2_reduction} tonnes\n"
|
||||
)
|
||||
|
||||
############
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue