from collections import namedtuple SummaryValues = namedtuple('SummaryValues', ['total_weight', 'max_psf', 'avg_psf', 'anchors', 'ballast', 'max_weight', 'ballast_weight']) class SummaryValuesCalculator(object): def __init__(self, user_values): self.values = user_values self.constants = self.values.module_system_constants() def summary_values(self, panels, subarrays, c_p_matrix, q_z, seismic_interval, ballast_calculator): summary_values = self.compute_summary(panels, subarrays, c_p_matrix, q_z, ballast_calculator) return [ {'label': 'Total System Weight (lbs)', 'value': summary_values.total_weight}, {'label': 'Max PSF', 'value': summary_values.max_psf}, {'label': 'Avg PSF', 'value': summary_values.avg_psf}, {'label': 'Total Anchors', 'value': summary_values.anchors}, {'label': 'Total Ballast', 'value': summary_values.ballast}, {'label': 'Max Possible System Weight', 'value': summary_values.max_weight}, {'label': 'Max System Weight Ballast Block', 'value': summary_values.ballast_weight}, {'label': 'Seismic Anchor Max. Spacing', 'value': seismic_interval} ] def documentation_summary_values(self, panels, subarrays, c_p_matrix, q_z, seismic_interval, ballast_calculator): summary_values = self.compute_summary(panels, subarrays, c_p_matrix, q_z, ballast_calculator) return { 'total_system_weight': summary_values.total_weight, 'max_psf': summary_values.max_psf, 'ave_psf': summary_values.avg_psf, 'total_anchors': summary_values.anchors, 'total_ballast': summary_values.ballast, 'max_possible_system_weight': summary_values.max_weight, 'max_system_weight_ballast_block': summary_values.ballast_weight, 'seismic_anchor_max_spacing': seismic_interval } def compute_summary(self, panels, subarrays, c_p_matrix, q_z, ballast_calculator): total_weight, avg_psf = self.system_weight_and_pressure(panels) max_psf = 0 wind_anchors = 0 total_ballast = 0 for panel in panels: max_psf = panel.pressure if panel.pressure > max_psf else max_psf wind_anchors += panel.wind_anchors total_ballast += panel.ballast required_seismic_anchors = sum(subarray.required_seismic_anchors for subarray in subarrays) total_anchors = int(wind_anchors + required_seismic_anchors) max_weight, ballast_weight = self.find_max_system_weight(panels, c_p_matrix, q_z, ballast_calculator) return SummaryValues( total_weight=round(total_weight), max_psf=round(max_psf, 2), avg_psf=round(avg_psf, 2), anchors=total_anchors, ballast=int(total_ballast), max_weight=round(max_weight, 0), ballast_weight=ballast_weight ) def system_weight_and_pressure(self, panels): constants = self.values.module_system_constants() effective_area = constants.surface_area / constants.ground_coverage_ratio psf_sum = sum(panel.pressure for panel in panels) return psf_sum * effective_area, psf_sum / len(panels) def find_max_system_weight(self, panels, c_p_matrix, q_z, ballast_calculator): copied_panels = list(panels) max_weight = 0 ballast_block_weight_for_max_weight = 0 for weight in range(12, 19): ballast_matrix = ballast_calculator.ballast_and_trays_matrix(c_p_matrix, q_z, copied_panels, ballast_block_weight=weight) total_weight, _ = self.system_weight_and_pressure(ballast_matrix) if total_weight > max_weight: max_weight = total_weight ballast_block_weight_for_max_weight = weight return max_weight, ballast_block_weight_for_max_weight