From e14d37d40fda3394a1f8c5d340e4c5a4e8e4c182 Mon Sep 17 00:00:00 2001 From: areza-blocpower Date: Wed, 29 Mar 2017 16:27:14 -0400 Subject: [PATCH 1/3] Add report generator for CBRA --- bpeng/reports/cbra_diag.py | 263 +++++++++++++++++++++++++++++++++++++ requirements.txt | 2 + 2 files changed, 265 insertions(+) create mode 100644 bpeng/reports/cbra_diag.py diff --git a/bpeng/reports/cbra_diag.py b/bpeng/reports/cbra_diag.py new file mode 100644 index 0000000..cec460f --- /dev/null +++ b/bpeng/reports/cbra_diag.py @@ -0,0 +1,263 @@ +""" + Code is designed to take template for CBRA EEDR and fill in engineering data, charts, graphs + for easy presentation creation. +""" + +import os +import sys +from datetime import datetime +from sys import version_info + +import openpyxl as op +import pandas as pd +from pptx import Presentation +from pptx.chart.data import ChartData +from pptx.dml.color import RGBColor +from pptx.enum.chart import (XL_CHART_TYPE, XL_LABEL_POSITION, + XL_LEGEND_POSITION, XL_TICK_LABEL_POSITION) +from pptx.enum.shapes import MSO_SHAPE +from pptx.enum.text import MSO_AUTO_SIZE, PP_ALIGN +from pptx.util import Inches, Pt + + +class CbraDiagnostic: + + def _generate_report(input_file): + """ + Generate powerpoint file + + Args: + + input_file (str): The path of the report content + + Returns: + + Presentation: the presenation generated + + """ + file_input = pd.ExcelFile(input_file) + sheet_input = file_input.parse("Inputs", header=None) + + input_list = sheet_input[0] + input_values = sheet_input[1] + + # Define presentation to edit as the finished template + prs = Presentation('./templates/EEDR_CBRA.pptx') + + # Slide 1: cover slide + cover_slide_layout = prs.slide_layouts[0] + cover_slide = prs.slides[0] + cover_title = cover_slide.shapes.title + cover_subtitle = cover_slide.placeholders[1] + + client_name = sheet_input.loc[1, 1] + project_address = sheet_input.loc[2, 1] + + cover_title.text = "{} - {}".format(client_name, project_address) + cover_subtitle.text = "Energy Efficiency Diagnostic Report" + cover_report_date = cover_subtitle.text_frame.add_paragraph() + cover_report_date.text = str(datetime.now().strftime('%B %Y')) + + # Slide 2: Executive Summary + Table of Contents + # shapes[0] = slide #, 1 = executive summary text box, 2 = title , 3 = table of contents + exec_summary_slide = prs.slides[1] + exec_results_box = exec_summary_slide.shapes[1] + exec_results_box.text_frame.auto_size = MSO_AUTO_SIZE.SHAPE_TO_FIT_TEXT + exec_results_box.text_frame.alignment = PP_ALIGN.LEFT + exec_title_run = exec_results_box.text_frame.paragraphs[0].add_run() + exec_title_run.text = "Executive Summary:" + exec_title_run.alignment = PP_ALIGN.LEFT + exec_title_run.font.name = 'Arial' + exec_title_run.font.size = Pt(20) + exec_title_run.font.underline = True + + exec_results_box.text_frame.add_paragraph() + exec_results_box.text_frame.add_paragraph() + + crnyc_intro_run = exec_results_box.text_frame.paragraphs[2].add_run() + exec_results_box.text_frame.paragraphs[2].alignment = PP_ALIGN.LEFT + crnyc_intro_run.text = "Community Retrofit NYC’s engineering feasibility study provides a cost effective and energy efficient solution for {}. Implementation of the recommended ECMs would result in the following:".format(project_address) + crnyc_intro_run.font.name = 'Arial' + crnyc_intro_run.font.size = Pt(14) + exec_results_box.text_frame.add_paragraph() + + annual_energy_percent = int(sheet_input.loc[3,1]) + annual_dollar_save = int(sheet_input.loc[4,1]) + co2_tonnage = int(sheet_input.loc[5,1]) + jobs_created = int(sheet_input.loc[6,1]) + + exec_energy_savings_line = exec_results_box.text_frame.add_paragraph() + exec_energy_savings_run = exec_energy_savings_line.add_run() + exec_energy_savings_run.text = "{}\N{PERCENT SIGN} decrease in energy consumption".format(annual_energy_percent) + exec_results_box.text_frame.paragraphs[4].alignment = PP_ALIGN.LEFT + exec_energy_savings_run.font.name = 'Arial' + exec_energy_savings_run.font.size = Pt(14) + exec_energy_savings_run.font.bold = True + exec_results_box.text_frame.add_paragraph() + + exec_dollar_savings_Line = exec_results_box.text_frame.add_paragraph() + exec_dollar_savings_run = exec_dollar_savings_Line.add_run() + exec_dollar_savings_run.text = "Estimated annual savings of \N{DOLLAR SIGN}{}".format(annual_dollar_save) + exec_results_box.text_frame.paragraphs[6].alignment = PP_ALIGN.LEFT + exec_dollar_savings_run.font.name = 'Arial' + exec_dollar_savings_run.font.size = Pt(14) + exec_dollar_savings_run.font.bold = True + exec_results_box.text_frame.add_paragraph() + + exec_emissions_Line = exec_results_box.text_frame.add_paragraph() + exec_emissions_run = exec_emissions_Line.add_run() + exec_emissions_run.text = "{} less tonnes of CO\u2082 generated".format(co2_tonnage) + exec_results_box.text_frame.paragraphs[8].alignment = PP_ALIGN.LEFT + exec_emissions_run.font.name = 'Arial' + exec_emissions_run.font.size = Pt(14) + exec_emissions_run.font.bold = True + exec_results_box.text_frame.add_paragraph() + + exec_job_add_line = exec_results_box.text_frame.add_paragraph() + exec_job_add_run = exec_job_add_line.add_run() + exec_job_add_run.text = "{} jobs created".format(jobs_created) + exec_results_box.text_frame.paragraphs[10].alignment = PP_ALIGN.LEFT + exec_job_add_run.font.name = 'Arial' + exec_job_add_run.font.size = Pt(14) + exec_job_add_run.font.bold = True + exec_results_box.text_frame.add_paragraph() + + # Slide 3: Energy Analysis, includes heatload pie chart + image from BlocMaps (might be static) + # + efficiency % from BlocMaps + + heat_load_slide = prs.slides[2] + energy_analyze_box = heat_load_slide.shapes[3] + #BlocMaps Efficiency Comparison + blocmaps_est = sheet_input.loc[7, 1] + eab_run = energy_analyze_box.text_frame.paragraphs[0].add_run() + eab_run.text = "Your building is {}\N{PERCENT SIGN} less efficient than buildings of similar age, size, and type.".format(blocmaps_est) + eab_run.font.name = 'Arial' + eab_run.font.size = Pt(14) + eab_run.font.color.rgb = RGBColor(0xff, 0xff, 0xff) + + # For using w/ input file + heat_loss_cat = input_list[9:15] + heat_loss_val = input_values[9:15] + + total_heat_loss = sum(heat_loss_val) + heat_loss_break = [hl_frac/total_heat_loss for hl_frac in heat_loss_val] + + heat_load_pie_data = ChartData() + heat_load_pie_data.categories = heat_loss_cat + heat_load_pie_data.add_series('Heat Load Breakdown', heat_loss_break) + + # Set chart location and formatting + chart_horz_pos, chart_vert_pos, chart_width, chart_height = Inches(4.2), Inches(1.3), Inches(5.27), Inches(3.47) + heat_load_pie = heat_load_slide.shapes.add_chart(XL_CHART_TYPE.PIE, chart_horz_pos, chart_vert_pos, chart_width, chart_height, heat_load_pie_data).chart + + heat_load_pie.has_legend = True + heat_load_pie.legend.include_in_layout = False + + heat_load_pie.plots[0].has_data_labels = True + heat_loss_labels = heat_load_pie.plots[0].data_labels + heat_loss_labels.number_format = '0%' + heat_loss_labels.font.size = Pt(22) + + # Slide 4: Potential Savings, includes utility expenses stacked bar charts for pre+post-retrofit, + # ECM table w/ names, savings for elec and gas, and total savings + + # Slide 4: Utility breakdown (chart is in bottom right corner) + utilityProjectionSlide = prs.slides[3] + + # Define stacked bar chart data + util_cat = ["Existing", "Projected"] + util_break_sh = sheet_input.loc[16:17,1] + util_break_dhw = sheet_input.loc[16:17,2] + util_break_light = sheet_input.loc[16:17,3] + util_break_plug = sheet_input.loc[16:17,4] + util_break_h2o = sheet_input.loc[16:17,5] + + + util_break_data = ChartData() + util_break_data.categories = util_cat + util_break_data.add_series("Space Heating", util_break_sh) + util_break_data.add_series("DHW", util_break_dhw) + util_break_data.add_series("Lighting", util_break_light) + util_break_data.add_series("Plug Load", util_break_plug) + util_break_data.add_series("Water", util_break_h2o) + + # Set chart location and formatting + chart_horz_pos, chart_vert_pos, chart_width, chart_height = Inches(0.05), Inches(2.4), Inches(3.5), Inches(2.5) + util_break_chart = utilityProjectionSlide.shapes.add_chart(XL_CHART_TYPE.COLUMN_STACKED, chart_horz_pos, chart_vert_pos, chart_width, chart_height, util_break_data).chart + + # Formatting for chart + #Legend + util_break_chart.has_legend = True + util_break_chart.legend.include_in_layout = False + util_break_chart.legend.position = XL_LEGEND_POSITION.LEFT + util_break_chart.legend.font.size = Pt(11) + util_break_chart.legend.font.color.rgb = RGBColor(0xff, 0xff, 0xff) + #Data Labels + util_break_chart.plots[0].has_data_labels = True + util_labels = util_break_chart.plots[0].data_labels + util_labels.number_format = '$0' + util_labels.font.size = Pt(8) + #Axis + util_break_chart.has_axis = True + util_break_chart.has_axis_title = True + util_break_chart.category_axis.tick_labels.font.size = Pt(11) + util_break_chart.value_axis.has_major_gridlines = False + util_break_chart.value_axis.tick_label_position = XL_TICK_LABEL_POSITION.NONE + + # Create ECM summary table + ecm_count = input_values.str.contains('Y').sum() + ecm_table = utilityProjectionSlide.shapes.add_table(ecm_count+2,3, Inches(3.81), Inches(0.25), Inches(5.83), Inches(3.76)) + ecm_table.last_row = True + ecm_table.horz_banding = False + ecm_table_head = ['ECM', "Heating Savings [%]", "Electricity Savings [%]"] + + for j in range(len(ecm_table_head)): + ecm_table.table.cell(0,j).text = ecm_table_head[j] + + + ecm_list = [] + ecm_heat_save = [] + ecm_elec_save = [] + + for j in range(len(input_values)): + if input_values[j] == 'Y': + ecm_list.append(input_list[j]) + ecm_heat_save.append(input_values[j+1]) + ecm_elec_save.append(input_values[j+2]) + + for k,j in zip(ecm_list,range(len(ecm_list))): + ecm_table.table.cell(j+1,0).text = k + ecm_table.table.cell(j+1,1).text = str(ecm_heat_save[j]) + ecm_table.table.cell(j+1,2).text = str(ecm_elec_save[j]) + + + # Slides 5-end: removing slides based on recommendations + counter = 0 + for j in range(len(input_values)): + if input_values[j] == 'N': + slide_idx = int(((j-6)/3) - counter) + prs.slides.delete_slide(prs,slide_idx) + counter = counter + 1 + + + return project_address, prs + + + @staticmethod + def generate_report_save(input_path): + """ + + Args: + input_path (str) The path of the input + """ + project_address, prs = CbraDiagnostic._generate_report(input_path) + prs.save('EEDR {}.pptx'.format(project_address)) + + @staticmethod + def generate_report(): + """ + Generate report with finding file in current working directory + """ + BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + file_name = input('Enter File Name (with .xlsx extension): ') + CbraDiagnostic.generate_report_save(os.path.join(BASE_DIR, file_name)) diff --git a/requirements.txt b/requirements.txt index 0b8b968..03ebee4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ numpy==1.12.0 +openpyxl==2.4.5 pandas==0.19.2 xlrd==1.0.0 +git+ssh://git@github.com/Blocp/python-pptx.git -- GitLab From 807fbb940e7c87bc1faf31dea4d1ef7fba338469 Mon Sep 17 00:00:00 2001 From: areza-blocpower Date: Thu, 30 Mar 2017 18:36:43 -0400 Subject: [PATCH 2/3] Format code for python conventions and format ECM table --- bpeng/reports/cbra_diag.py | 47 ++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/bpeng/reports/cbra_diag.py b/bpeng/reports/cbra_diag.py index cec460f..88c5a68 100644 --- a/bpeng/reports/cbra_diag.py +++ b/bpeng/reports/cbra_diag.py @@ -15,7 +15,6 @@ from pptx.chart.data import ChartData from pptx.dml.color import RGBColor from pptx.enum.chart import (XL_CHART_TYPE, XL_LABEL_POSITION, XL_LEGEND_POSITION, XL_TICK_LABEL_POSITION) -from pptx.enum.shapes import MSO_SHAPE from pptx.enum.text import MSO_AUTO_SIZE, PP_ALIGN from pptx.util import Inches, Pt @@ -81,10 +80,10 @@ class CbraDiagnostic: crnyc_intro_run.font.size = Pt(14) exec_results_box.text_frame.add_paragraph() - annual_energy_percent = int(sheet_input.loc[3,1]) - annual_dollar_save = int(sheet_input.loc[4,1]) - co2_tonnage = int(sheet_input.loc[5,1]) - jobs_created = int(sheet_input.loc[6,1]) + annual_energy_percent = int(sheet_input.loc[3, 1]) + annual_dollar_save = int(sheet_input.loc[4, 1]) + co2_tonnage = int(sheet_input.loc[5, 1]) + jobs_created = int(sheet_input.loc[6, 1]) exec_energy_savings_line = exec_results_box.text_frame.add_paragraph() exec_energy_savings_run = exec_energy_savings_line.add_run() @@ -95,8 +94,8 @@ class CbraDiagnostic: exec_energy_savings_run.font.bold = True exec_results_box.text_frame.add_paragraph() - exec_dollar_savings_Line = exec_results_box.text_frame.add_paragraph() - exec_dollar_savings_run = exec_dollar_savings_Line.add_run() + exec_dollar_savings_line = exec_results_box.text_frame.add_paragraph() + exec_dollar_savings_run = exec_dollar_savings_line.add_run() exec_dollar_savings_run.text = "Estimated annual savings of \N{DOLLAR SIGN}{}".format(annual_dollar_save) exec_results_box.text_frame.paragraphs[6].alignment = PP_ALIGN.LEFT exec_dollar_savings_run.font.name = 'Arial' @@ -104,8 +103,8 @@ class CbraDiagnostic: exec_dollar_savings_run.font.bold = True exec_results_box.text_frame.add_paragraph() - exec_emissions_Line = exec_results_box.text_frame.add_paragraph() - exec_emissions_run = exec_emissions_Line.add_run() + exec_emissions_line = exec_results_box.text_frame.add_paragraph() + exec_emissions_run = exec_emissions_line.add_run() exec_emissions_run.text = "{} less tonnes of CO\u2082 generated".format(co2_tonnage) exec_results_box.text_frame.paragraphs[8].alignment = PP_ALIGN.LEFT exec_emissions_run.font.name = 'Arial' @@ -166,11 +165,11 @@ class CbraDiagnostic: # Define stacked bar chart data util_cat = ["Existing", "Projected"] - util_break_sh = sheet_input.loc[16:17,1] - util_break_dhw = sheet_input.loc[16:17,2] - util_break_light = sheet_input.loc[16:17,3] - util_break_plug = sheet_input.loc[16:17,4] - util_break_h2o = sheet_input.loc[16:17,5] + util_break_sh = sheet_input.loc[16:17, 1] + util_break_dhw = sheet_input.loc[16:17, 2] + util_break_light = sheet_input.loc[16:17, 3] + util_break_plug = sheet_input.loc[16:17, 4] + util_break_h2o = sheet_input.loc[16:17, 5] util_break_data = ChartData() @@ -206,13 +205,14 @@ class CbraDiagnostic: # Create ECM summary table ecm_count = input_values.str.contains('Y').sum() - ecm_table = utilityProjectionSlide.shapes.add_table(ecm_count+2,3, Inches(3.81), Inches(0.25), Inches(5.83), Inches(3.76)) + ecm_table = utilityProjectionSlide.shapes.add_table(ecm_count+2, 3, Inches(3.81), Inches(0.25), Inches(5.83), Inches(3.76)) ecm_table.last_row = True ecm_table.horz_banding = False - ecm_table_head = ['ECM', "Heating Savings [%]", "Electricity Savings [%]"] + ecm_table_head = ['ECM', "Heating Savings *", "Electricity Savings *"] for j in range(len(ecm_table_head)): - ecm_table.table.cell(0,j).text = ecm_table_head[j] + ecm_table.table.cell(0, j).text_frame.paragraphs[0].font.size = Pt(12) + ecm_table.table.cell(0, j).text = ecm_table_head[j] ecm_list = [] @@ -225,10 +225,13 @@ class CbraDiagnostic: ecm_heat_save.append(input_values[j+1]) ecm_elec_save.append(input_values[j+2]) - for k,j in zip(ecm_list,range(len(ecm_list))): - ecm_table.table.cell(j+1,0).text = k - ecm_table.table.cell(j+1,1).text = str(ecm_heat_save[j]) - ecm_table.table.cell(j+1,2).text = str(ecm_elec_save[j]) + for k, j in zip(ecm_list, range(len(ecm_list))): + ecm_table.table.cell(j+1, 0).text_frame.paragraphs[0].font.size = Pt(10) + ecm_table.table.cell(j+1, 0).text = k + ecm_table.table.cell(j+1, 1).text_frame.paragraphs[0].font.size = Pt(10) + ecm_table.table.cell(j+1, 1).text = str(ecm_heat_save[j]) + ecm_table.table.cell(j+1, 2).text_frame.paragraphs[0].font.size = Pt(10) + ecm_table.table.cell(j+1, 2).text = str(ecm_elec_save[j]) # Slides 5-end: removing slides based on recommendations @@ -236,7 +239,7 @@ class CbraDiagnostic: for j in range(len(input_values)): if input_values[j] == 'N': slide_idx = int(((j-6)/3) - counter) - prs.slides.delete_slide(prs,slide_idx) + prs.slides.delete_slide(prs, slide_idx) counter = counter + 1 -- GitLab From 0140f6529682c29dff10e4472e00db4071fa19d5 Mon Sep 17 00:00:00 2001 From: Alessandro DiMarco Date: Mon, 3 Apr 2017 22:47:31 -0400 Subject: [PATCH 3/3] Fix pep8 issues --- bpeng/reports/__init__.py | 1 + bpeng/reports/cbra_diag.py | 108 ++++++++++++++++++++----------------- requirements-dev.txt | 2 +- requirements.txt | 1 - 4 files changed, 61 insertions(+), 51 deletions(-) create mode 100644 bpeng/reports/__init__.py diff --git a/bpeng/reports/__init__.py b/bpeng/reports/__init__.py new file mode 100644 index 0000000..7bf4756 --- /dev/null +++ b/bpeng/reports/__init__.py @@ -0,0 +1 @@ +from .cbra_diag import CbraDiagnostic diff --git a/bpeng/reports/cbra_diag.py b/bpeng/reports/cbra_diag.py index 88c5a68..6348315 100644 --- a/bpeng/reports/cbra_diag.py +++ b/bpeng/reports/cbra_diag.py @@ -3,12 +3,8 @@ for easy presentation creation. """ -import os -import sys from datetime import datetime -from sys import version_info -import openpyxl as op import pandas as pd from pptx import Presentation from pptx.chart.data import ChartData @@ -20,8 +16,12 @@ from pptx.util import Inches, Pt class CbraDiagnostic: + """ + Download template file from https://s3.amazonaws.com/bp-dev-assets/EEDR_CBRA.pptx + """ - def _generate_report(input_file): + @staticmethod + def _generate_report(template_file, input_file): """ Generate powerpoint file @@ -41,7 +41,7 @@ class CbraDiagnostic: input_values = sheet_input[1] # Define presentation to edit as the finished template - prs = Presentation('./templates/EEDR_CBRA.pptx') + prs = Presentation(template_file) # Slide 1: cover slide cover_slide_layout = prs.slide_layouts[0] @@ -75,7 +75,12 @@ class CbraDiagnostic: crnyc_intro_run = exec_results_box.text_frame.paragraphs[2].add_run() exec_results_box.text_frame.paragraphs[2].alignment = PP_ALIGN.LEFT - crnyc_intro_run.text = "Community Retrofit NYC’s engineering feasibility study provides a cost effective and energy efficient solution for {}. Implementation of the recommended ECMs would result in the following:".format(project_address) + + crnyc_intro_run.text = 'Community Retrofit NYC’s engineering feasibility study provides ' \ + 'a cost effective and energy efficient solution for {}. ' \ + 'Implementation of the recommended ECMs would ' \ + 'result in the following:'.format(project_address) + crnyc_intro_run.font.name = 'Arial' crnyc_intro_run.font.size = Pt(14) exec_results_box.text_frame.add_paragraph() @@ -87,7 +92,10 @@ class CbraDiagnostic: exec_energy_savings_line = exec_results_box.text_frame.add_paragraph() exec_energy_savings_run = exec_energy_savings_line.add_run() - exec_energy_savings_run.text = "{}\N{PERCENT SIGN} decrease in energy consumption".format(annual_energy_percent) + + exec_energy_savings_run.text = '{}\N{PERCENT SIGN} decrease in energy ' \ + 'consumption'.format(annual_energy_percent) + exec_results_box.text_frame.paragraphs[4].alignment = PP_ALIGN.LEFT exec_energy_savings_run.font.name = 'Arial' exec_energy_savings_run.font.size = Pt(14) @@ -96,7 +104,8 @@ class CbraDiagnostic: exec_dollar_savings_line = exec_results_box.text_frame.add_paragraph() exec_dollar_savings_run = exec_dollar_savings_line.add_run() - exec_dollar_savings_run.text = "Estimated annual savings of \N{DOLLAR SIGN}{}".format(annual_dollar_save) + exec_dollar_savings_run.text = 'Estimated annual savings of ' \ + '\N{DOLLAR SIGN}{}'.format(annual_dollar_save) exec_results_box.text_frame.paragraphs[6].alignment = PP_ALIGN.LEFT exec_dollar_savings_run.font.name = 'Arial' exec_dollar_savings_run.font.size = Pt(14) @@ -121,15 +130,17 @@ class CbraDiagnostic: exec_job_add_run.font.bold = True exec_results_box.text_frame.add_paragraph() - # Slide 3: Energy Analysis, includes heatload pie chart + image from BlocMaps (might be static) - # + efficiency % from BlocMaps + # Slide 3: Energy Analysis, includes heatload pie chart + image from + # BlocMaps (might be static) + efficiency % from BlocMaps heat_load_slide = prs.slides[2] energy_analyze_box = heat_load_slide.shapes[3] - #BlocMaps Efficiency Comparison + + # BlocMaps Efficiency Comparison blocmaps_est = sheet_input.loc[7, 1] eab_run = energy_analyze_box.text_frame.paragraphs[0].add_run() - eab_run.text = "Your building is {}\N{PERCENT SIGN} less efficient than buildings of similar age, size, and type.".format(blocmaps_est) + eab_run.text = 'Your building is {}\N{PERCENT SIGN} less efficient than buildings of ' \ + 'similar age, size, and type.'.format(blocmaps_est) eab_run.font.name = 'Arial' eab_run.font.size = Pt(14) eab_run.font.color.rgb = RGBColor(0xff, 0xff, 0xff) @@ -146,8 +157,11 @@ class CbraDiagnostic: heat_load_pie_data.add_series('Heat Load Breakdown', heat_loss_break) # Set chart location and formatting - chart_horz_pos, chart_vert_pos, chart_width, chart_height = Inches(4.2), Inches(1.3), Inches(5.27), Inches(3.47) - heat_load_pie = heat_load_slide.shapes.add_chart(XL_CHART_TYPE.PIE, chart_horz_pos, chart_vert_pos, chart_width, chart_height, heat_load_pie_data).chart + chart_horz_pos, chart_vert_pos = Inches(4.2), Inches(1.3) + chart_width, chart_height = Inches(5.27), Inches(3.47) + heat_load_pie = heat_load_slide.shapes.add_chart(XL_CHART_TYPE.PIE, chart_horz_pos, + chart_vert_pos, chart_width, chart_height, + heat_load_pie_data).chart heat_load_pie.has_legend = True heat_load_pie.legend.include_in_layout = False @@ -157,13 +171,13 @@ class CbraDiagnostic: heat_loss_labels.number_format = '0%' heat_loss_labels.font.size = Pt(22) - # Slide 4: Potential Savings, includes utility expenses stacked bar charts for pre+post-retrofit, - # ECM table w/ names, savings for elec and gas, and total savings + # Slide 4: Potential Savings, includes utility expenses stacked bar charts for + # pre+post-retrofit, ECM table w/ names, savings for elec and gas, and total savings # Slide 4: Utility breakdown (chart is in bottom right corner) utilityProjectionSlide = prs.slides[3] - # Define stacked bar chart data + # Define stacked bar chart data util_cat = ["Existing", "Projected"] util_break_sh = sheet_input.loc[16:17, 1] util_break_dhw = sheet_input.loc[16:17, 2] @@ -180,32 +194,40 @@ class CbraDiagnostic: util_break_data.add_series("Plug Load", util_break_plug) util_break_data.add_series("Water", util_break_h2o) - # Set chart location and formatting - chart_horz_pos, chart_vert_pos, chart_width, chart_height = Inches(0.05), Inches(2.4), Inches(3.5), Inches(2.5) - util_break_chart = utilityProjectionSlide.shapes.add_chart(XL_CHART_TYPE.COLUMN_STACKED, chart_horz_pos, chart_vert_pos, chart_width, chart_height, util_break_data).chart - - # Formatting for chart - #Legend + # Set chart location and formatting + chart_horz_pos, chart_vert_pos = Inches(0.05), Inches(2.4) + chart_width, chart_height = Inches(3.5), Inches(2.5) + util_break_chart = utilityProjectionSlide.shapes.add_chart(XL_CHART_TYPE.COLUMN_STACKED, + chart_horz_pos, chart_vert_pos, + chart_width, chart_height, + util_break_data).chart + + # Formatting for chart + # Legend util_break_chart.has_legend = True util_break_chart.legend.include_in_layout = False util_break_chart.legend.position = XL_LEGEND_POSITION.LEFT util_break_chart.legend.font.size = Pt(11) util_break_chart.legend.font.color.rgb = RGBColor(0xff, 0xff, 0xff) - #Data Labels + + # Data Labels util_break_chart.plots[0].has_data_labels = True util_labels = util_break_chart.plots[0].data_labels util_labels.number_format = '$0' util_labels.font.size = Pt(8) - #Axis + + # Axis util_break_chart.has_axis = True util_break_chart.has_axis_title = True util_break_chart.category_axis.tick_labels.font.size = Pt(11) util_break_chart.value_axis.has_major_gridlines = False util_break_chart.value_axis.tick_label_position = XL_TICK_LABEL_POSITION.NONE - # Create ECM summary table + # Create ECM summary table ecm_count = input_values.str.contains('Y').sum() - ecm_table = utilityProjectionSlide.shapes.add_table(ecm_count+2, 3, Inches(3.81), Inches(0.25), Inches(5.83), Inches(3.76)) + ecm_table = utilityProjectionSlide.shapes.add_table(ecm_count+2, 3, Inches(3.81), + Inches(0.25), Inches(5.83), + Inches(3.76)) ecm_table.last_row = True ecm_table.horz_banding = False ecm_table_head = ['ECM', "Heating Savings *", "Electricity Savings *"] @@ -214,7 +236,6 @@ class CbraDiagnostic: ecm_table.table.cell(0, j).text_frame.paragraphs[0].font.size = Pt(12) ecm_table.table.cell(0, j).text = ecm_table_head[j] - ecm_list = [] ecm_heat_save = [] ecm_elec_save = [] @@ -226,13 +247,12 @@ class CbraDiagnostic: ecm_elec_save.append(input_values[j+2]) for k, j in zip(ecm_list, range(len(ecm_list))): - ecm_table.table.cell(j+1, 0).text_frame.paragraphs[0].font.size = Pt(10) - ecm_table.table.cell(j+1, 0).text = k - ecm_table.table.cell(j+1, 1).text_frame.paragraphs[0].font.size = Pt(10) - ecm_table.table.cell(j+1, 1).text = str(ecm_heat_save[j]) - ecm_table.table.cell(j+1, 2).text_frame.paragraphs[0].font.size = Pt(10) - ecm_table.table.cell(j+1, 2).text = str(ecm_elec_save[j]) - + ecm_table.table.cell(j+1, 0).text_frame.paragraphs[0].font.size = Pt(10) + ecm_table.table.cell(j+1, 0).text = k + ecm_table.table.cell(j+1, 1).text_frame.paragraphs[0].font.size = Pt(10) + ecm_table.table.cell(j+1, 1).text = str(ecm_heat_save[j]) + ecm_table.table.cell(j+1, 2).text_frame.paragraphs[0].font.size = Pt(10) + ecm_table.table.cell(j+1, 2).text = str(ecm_elec_save[j]) # Slides 5-end: removing slides based on recommendations counter = 0 @@ -245,22 +265,12 @@ class CbraDiagnostic: return project_address, prs - - @staticmethod - def generate_report_save(input_path): - """ - - Args: - input_path (str) The path of the input - """ - project_address, prs = CbraDiagnostic._generate_report(input_path) - prs.save('EEDR {}.pptx'.format(project_address)) - @staticmethod def generate_report(): """ Generate report with finding file in current working directory """ - BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + template_file = input('Enter Template Name (with .pptx extension): ') file_name = input('Enter File Name (with .xlsx extension): ') - CbraDiagnostic.generate_report_save(os.path.join(BASE_DIR, file_name)) + project_address, prs = CbraDiagnostic._generate_report(template_file, file_name) + prs.save('EEDR {}.pptx'.format(project_address)) diff --git a/requirements-dev.txt b/requirements-dev.txt index eba0caa..9213341 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,6 +1,6 @@ -r requirements.txt autopep8==1.3 -matplotlib==1.5.3 +matplotlib==2.0.0 prospector==0.12.4 pycodestyle==2.0.0 pydocstyle==1.0.0 diff --git a/requirements.txt b/requirements.txt index 03ebee4..f39d074 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ numpy==1.12.0 -openpyxl==2.4.5 pandas==0.19.2 xlrd==1.0.0 git+ssh://git@github.com/Blocp/python-pptx.git -- GitLab