|  | @ -2,6 +2,7 @@ import matplotlib | 
			
		
	
		
		
			
				
					|  |  | matplotlib.use('Qt5Agg')  # or 'Qt5Agg', depending on your setup |  |  | matplotlib.use('Qt5Agg')  # or 'Qt5Agg', depending on your setup | 
			
		
	
		
		
			
				
					|  |  | import matplotlib.pyplot as plt |  |  | import matplotlib.pyplot as plt | 
			
		
	
		
		
			
				
					|  |  | import numpy as np |  |  | import numpy as np | 
			
		
	
		
		
			
				
					|  |  |  |  |  | from numpy_da import DynamicArray | 
			
		
	
		
		
			
				
					|  |  | import json |  |  | import json | 
			
		
	
		
		
			
				
					|  |  | import sys |  |  | import sys | 
			
		
	
		
		
			
				
					|  |  | import argparse |  |  | import argparse | 
			
		
	
	
		
		
			
				
					|  | @ -13,23 +14,20 @@ class JsonSettingsExtractor: | 
			
		
	
		
		
			
				
					|  |  |         with open(fname, "r") as rf: |  |  |         with open(fname, "r") as rf: | 
			
		
	
		
		
			
				
					|  |  |             settings = json.load(rf) |  |  |             settings = json.load(rf) | 
			
		
	
		
		
			
				
					|  |  |             self._currency = settings["currency"] |  |  |             self._currency = settings["currency"] | 
			
		
	
		
		
			
				
					|  |  |             self._legend = settings["legend"] |  |  |  | 
			
		
	
		
		
			
				
					|  |  |             # Kind of inefficient code. Does not matter only runs once at startup |  |  |             # Kind of inefficient code. Does not matter only runs once at startup | 
			
		
	
		
		
			
				
					|  |  |             _technologies = settings["technologies"] |  |  |             _technologies = settings["technologies"] | 
			
		
	
		
		
			
				
					|  |  |             self._label = [technology["label"] for technology in _technologies] |  |  |             self._label = [technology["label"] for technology in _technologies] | 
			
		
	
		
		
			
				
					|  |  |             self._installation_price = [technology["installation_price"] 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_expenditure = [technology["kwh_expenditure"] for technology in _technologies] | 
			
		
	
		
		
			
				
					|  |  |             self._kwh_price = [technology["kwh_price"] 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._percent_inflation = [technology["percent_inflation"] for technology in _technologies] | 
			
		
	
		
		
			
				
					|  |  |             self._years_lifespan = [technology["years_lifespan"] for technology in _technologies] |  |  |             self._years_lifespan = [technology["years_lifespan"] for technology in _technologies] | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             self._amount_of_technologies = len(self.label) | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     @property |  |  |     @property | 
			
		
	
		
		
			
				
					|  |  |     def currency(self): |  |  |     def currency(self): | 
			
		
	
		
		
			
				
					|  |  |         return self._currency |  |  |         return self._currency | 
			
		
	
		
		
			
				
					|  |  |      |  |  |  | 
			
		
	
		
		
			
				
					|  |  |     @property |  |  |  | 
			
		
	
		
		
			
				
					|  |  |     def legend(self): |  |  |  | 
			
		
	
		
		
			
				
					|  |  |         return self._legend |  |  |  | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     @property |  |  |     @property | 
			
		
	
		
		
			
				
					|  |  |     def label(self): |  |  |     def label(self): | 
			
		
	
	
		
		
			
				
					|  | @ -37,56 +35,114 @@ class JsonSettingsExtractor: | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     @property |  |  |     @property | 
			
		
	
		
		
			
				
					|  |  |     def installation_price(self): |  |  |     def installation_price(self): | 
			
		
	
		
		
			
				
					
					|  |  |         return self._installation_price |  |  |         return np.array(self._installation_price) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |      | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     @property | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     def reinstallation_price(self): | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         return np.array(self._reinstallation_price) | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     @property |  |  |     @property | 
			
		
	
		
		
			
				
					|  |  |     def kwh_expenditure(self): |  |  |     def kwh_expenditure(self): | 
			
		
	
		
		
			
				
					
					|  |  |         return self._kwh_expenditure |  |  |         return np.array(self._kwh_expenditure) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |      |  |  |      | 
			
		
	
		
		
			
				
					|  |  |     @property |  |  |     @property | 
			
		
	
		
		
			
				
					|  |  |     def percent_inflation(self): |  |  |     def percent_inflation(self): | 
			
		
	
		
		
			
				
					
					|  |  |         self._percent_inflation |  |  |         return np.array(self._percent_inflation) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     @property |  |  |     @property | 
			
		
	
		
		
			
				
					|  |  |     def years_lifespan(self): |  |  |     def years_lifespan(self): | 
			
		
	
		
		
			
				
					
					|  |  |         self._years_lifespan |  |  |         return self._years_lifespan | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     @property | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     def amount_of_technologies(self): | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         return self._amount_of_technologies | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | def main(): |  |  | def main(): | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     parser = argparse.ArgumentParser(description='This script allows to calculate which heating technology makes sense financially for you.') |  |  |     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('-a','--settings', help='Settings file.', required=True, metavar=('FILENAME')) | 
			
		
	
		
		
			
				
					
					|  |  |     parser.add_argument('-g','--plot', help='Visualize costs over one or multiple years.', type=int, metavar=('YEARS')) |  |  |     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() |  |  |     args = parser.parse_args() | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     input_data = JsonSettingsExtractor(args.settings) |  |  |     input_data = JsonSettingsExtractor(args.settings) | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     print("Inflations: {}".format(input_data.percent_inflation)) |  |  |     # Basic settings | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     print("Expend: {}".format(input_data.kwh_expenditure)) |  |  |     currency = input_data.currency | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  |     # Initializations | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     # if args.plot != None: |  |  |     year = 0 #first year | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     # Basic settings |  |  |     #grand_total = DynamicArray(shape=(0, input_data._amount_of_technologies)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     width = 0.3 |  |  |     grand_total = np.empty((0, input_data.amount_of_technologies)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     plt_colors = ["#8ecae6", "#219ebc", "#023047", "#ffb703", "#fb8500"]; |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     fig, ax = plt.subplots() |  |  |     # Iteration for years in service | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     ax.bar(input_data.label, input_data.installation_price, width, label = "Installation price", color = plt_colors[0]) |  |  |     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 | 
			
		
	
		
		
			
				
					|  |  |          |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |     #     current_y = input_data.installation_price |  |  |         # Calculate increase | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     years = 0 #first year |  |  |         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 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     # Iteration for years in service |  |  |         increase_total = increase_installation + increase_expenditure | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     for i in range(args.plot): |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #         inflation_factor = 1.0 + (input_data.percent_inflation * years) / 100.0 |  |  |         # Safe the yearly costs for plotting | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #         increase = input_data.kwh_expenditure * inflation_factor |  |  |         if year > 0: | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #         ax.bar(input_data.label, increase, width, bottom = current_y, label = "Expenditure".format(y), color = plt_colors[1]) |  |  |             grand_total = np.vstack((grand_total, increase_total + grand_total[year - 1])) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #         years += 1 |  |  |         elif year == 0: | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #         current_y += increase |  |  |             grand_total = np.vstack((grand_total, increase_total)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     ax.set_ylabel(input_data.currency) |  |  |         # Output data every year | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     ax.set_title("Comparision of economics w/ different heating technologies") |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     ax.legend(input_data.legend) |  |  |         # Rounding | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  |         increase_total = np.round(increase_total, decimals=0) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     #     plt.show() |  |  |         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__": |  |  | if __name__ == "__main__": | 
			
		
	
		
		
			
				
					|  |  |     main() |  |  |     main() | 
			
		
	
	
		
		
			
				
					|  | 
 |