import matplotlib matplotlib.use('Qt5Agg') # or 'Qt5Agg', depending on your setup import matplotlib.pyplot as plt import numpy as np from numpy_da import DynamicArray import json import sys import argparse __author__ = 'm3x1m0m' class JsonSettingsExtractor: def __init__(self, fname): with open(fname, "r") as rf: settings = json.load(rf) self._currency = settings["currency"] # Kind of inefficient code. Does not matter only runs once at startup _technologies = settings["technologies"] self._label = [technology["label"] for technology in _technologies] self._installation_price = [technology["installation_price"] for technology in _technologies] self._reinstallation_price = [technology["reinstallation_price"] for technology in _technologies] self._kwh_expenditure = [technology["kwh_expenditure"] for technology in _technologies] self._kwh_price = [technology["kwh_price"] for technology in _technologies] self._percent_inflation = [technology["percent_inflation"] for technology in _technologies] self._years_lifespan = [technology["years_lifespan"] for technology in _technologies] self._amount_of_technologies = len(self.label) @property def currency(self): return self._currency @property def label(self): return self._label @property def installation_price(self): return np.array(self._installation_price) @property def reinstallation_price(self): return np.array(self._reinstallation_price) @property def kwh_expenditure(self): return np.array(self._kwh_expenditure) @property def percent_inflation(self): return np.array(self._percent_inflation) @property def years_lifespan(self): return self._years_lifespan @property def amount_of_technologies(self): return self._amount_of_technologies def main(): parser = argparse.ArgumentParser(description='This script allows to calculate which heating technology makes sense financially for you.') parser.add_argument('-a','--settings', help='Settings file.', required=True, metavar=('FILENAME')) parser.add_argument('-b','--years', help='Amount of years for which to run the simulation.', required=True, type=int, metavar=('YEARS')) parser.add_argument('-c','--plot', help='Visualize the calculations done.', action='store_true') args = parser.parse_args() input_data = JsonSettingsExtractor(args.settings) # Basic settings currency = input_data.currency # Initializations year = 0 #first year #grand_total = DynamicArray(shape=(0, input_data._amount_of_technologies)) grand_total = np.empty((0, input_data.amount_of_technologies)) # Iteration for years in service for i in range(args.years): # Initializations increase_total = np.zeros(input_data.amount_of_technologies) increase_installation = np.zeros(input_data.amount_of_technologies) increase_expenditure = np.zeros(input_data.amount_of_technologies) # Handle possible replacement of heating system for j in range(len(input_data.years_lifespan)): if (year % input_data.years_lifespan[j]) == 0 and year == 0: increase_installation[j] = input_data.installation_price[j] elif (year % input_data.years_lifespan[j]) == 0 and year > 0: increase_installation[j] = input_data.reinstallation_price[j] else: increase_installation[j] = 0 # just to be clear # Calculate increase inflation_factor = np.array([1.0 + (x * year) / 100.0 for x in input_data.percent_inflation]) increase_expenditure = input_data.kwh_expenditure * inflation_factor increase_total = increase_installation + increase_expenditure # Safe the yearly costs for plotting if year > 0: grand_total = np.vstack((grand_total, increase_total + grand_total[year - 1])) elif year == 0: grand_total = np.vstack((grand_total, increase_total)) # Output data every year # Rounding increase_total = np.round(increase_total, decimals=0) increase_installation = np.round(increase_installation, decimals=0) increase_expenditure = np.round(increase_expenditure, decimals=0) print(f"Year {year:2.0f} \t\tInstallation [{currency}] \tExpenditure [{currency}] \tTotal [{currency}] \tGrand total [{currency}]") print("-------------------------------------------------------------------------------------------------------------") for j in range(input_data.amount_of_technologies): print(f"{input_data.label[j]} \t{increase_installation[j]:8.0f} \t\t{increase_expenditure[j]:8.0f} \t\t{increase_total[j]:8.0f} \t{grand_total[year][j]:8.0f}") print("\n") year += 1 if args.plot: # Define colors for each line plt_colors = ["#8ecae6", "#219ebc", "#023047", "#ffb703", "#fb8500"]; # Number of years and technologies years = grand_total.shape[0] technologies = grand_total.shape[1] # Create a figure and axis plt.figure(figsize=(10, 6)) # Generate line plots for each technology for i in range(technologies): plt.plot(range(years), grand_total[:, i], marker='o', color=plt_colors[i], label=f'Technology {i+1}') # Adding titles and labels plt.title('Economical comparision of different heating technologies') plt.xlabel('Year') plt.ylabel(f'Cost {currency}') # plt.xticks(range(years), [f'Year {j+1}' for j in range(years)]) # Customize x-ticks if needed plt.legend(input_data.label) plt.grid() # Show the plot plt.tight_layout() plt.show() if __name__ == "__main__": main()