import matplotlib.pyplot as plt import numpy as np import json import sys import argparse __author__ = 'm3x1m0m' class c_settings_extractor: def __init__(self, fname): with open(fname, "r") as rf: settings = json.load(rf) kilometer_price_ccar = settings["ccar"]["litres_per_kilometer"] * settings["petrol_litre_price"] self.labels = [settings["ecar"]["label"], settings["ccar"]["label"]] self.purchase = np.array([settings["ecar"]["price"], settings["ccar"]["price"]]) self.taxes = np.array([settings["ecar"]["taxes"], settings["ccar"]["taxes"]]) self.insurance = np.array([settings["ecar"]["insurance"], settings["ccar"]["insurance"]]) kilometer_price_ecar = ( settings["ecar"]["charging_behaviour"]["percent_home_charges"] * settings["kwh_price_home"] + settings["ecar"]["charging_behaviour"]["percent_commercial_charges"] * settings["kwh_price_commercial"]) / 100.0 self.driving = np.array([kilometer_price_ecar * settings["kilometers_per_year"], kilometer_price_ccar * settings["kilometers_per_year"]]) self.maintenance = np.array([settings["ecar"]["maintenance"], settings["ecar"]["maintenance"]]) def get_labels(self): return self.labels def get_purchase(self): return self.purchase def get_taxes(self): return self.taxes def get_insurance(self): return self.insurance def get_driving(self): return self.driving def get_maintenance(self): return self.maintenance class c_ecar_comparator: def __init__(self, fname): self.settings_extractor = c_settings_extractor(fname) def calculate_costs_a_year(self): taxes = self.settings_extractor.get_taxes() insurance = self.settings_extractor.get_insurance() driving = self.settings_extractor.get_driving() maintenance = self.settings_extractor.get_maintenance() return taxes + insurance + driving + maintenance def calculate_costs(self, years, months): months_a_year = 12.0 costs_a_year = self.calculate_costs_a_year() return costs_a_year * (years + months/months_a_year) def calculate_break_even(self): total_costs = self.settings_extractor.get_purchase() months_a_year = 12.0 increment = self.calculate_costs_a_year() / months_a_year months = 0 while total_costs[0] > total_costs[1]: total_costs += increment months += 1 return [months/months_a_year, months%months_a_year] # years, months def main(): parser = argparse.ArgumentParser(description='This script allows to calculate if an electric car makes sense financially for you') parser.add_argument('-a','--settings', help='Settings file', required=True, metavar=('FILENAME')) parser.add_argument('-b','--break_even', help='Calculate the break even point. (When does the EV become cheaper)', action='store_true') parser.add_argument('-c','--savings_per_year', help='Calculate savings per year', action='store_true') parser.add_argument('-d','--savings_per_month', help='Calculate savings per month', action='store_true') parser.add_argument('-e','--plot', help='Visualize costs over one or multiple years', type=int, metavar=('YEARS')) args = parser.parse_args() if not args.break_even and not args.savings_per_year and not args.savings_per_month and not args.plot: sys.exit("Please choose one or multiple options") comparator = c_ecar_comparator(args.settings) extractor = c_settings_extractor(args.settings) if args.plot: width = 0.3 labels = extractor.get_labels() purchase = extractor.get_purchase() taxes = extractor.get_taxes() insurance = extractor.get_insurance() driving = extractor.get_driving() maintenance = extractor.get_maintenance() fig, ax = plt.subplots() ax.bar(labels, purchase, width, label = "Price", color = "gray") current_y = extractor.get_purchase() y = 0 for i in range(args.plot): ax.bar(labels, taxes, width, bottom = current_y, label = "Taxes".format(y), color = "darkgreen") current_y = current_y + taxes ax.bar(labels, insurance, width, bottom = current_y, label = "Insurance".format(y), color = "royalblue") current_y = current_y + insurance ax.bar(labels, driving, width, bottom = current_y, label = "Driving".format(y), color = "midnightblue") current_y = current_y + driving ax.bar(labels, maintenance, width, bottom = current_y, label = "Maintenance".format(y), color = "lavender") current_y = current_y + maintenance y += 1 ecar_top = current_y[0] #ax.plot(np.linspace(-0.2, 1.2, 10), [ecar_top]*10, "--", color = "firebrick", label = "Break even") #ax.text(0.3, ecar_top * 0.95, "Break even: {} years, {} kilometers".format(y, y*settings["kilometers_per_year"])) ax.set_ylabel("CHF") ax.set_title("Comparision of economics electric vs. combustion car") ax.legend(["Price", "Taxes", "Insurance", "Driving", "Maintenance"]) ax.grid(axis = "y") #print("Break even after {} years and {} kilometers. {}".format(y, y*settings["kilometers_per_year"], current_y[0]-current_y[1])) plt.show() if __name__ == "__main__": main()