Browse Source

Refactoring

master
Maximilian Stiefel 3 years ago
parent
commit
fcc2b6330f
  1. 148
      .gitignore
  2. 14
      ecar.json
  3. 133
      ecar.py

148
.gitignore

@ -0,0 +1,148 @@
# Created by https://www.toptal.com/developers/gitignore/api/python
# Edit at https://www.toptal.com/developers/gitignore?templates=python
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# End of https://www.toptal.com/developers/gitignore/api/python
*.swp

14
ecar.json

@ -3,26 +3,26 @@
"kwh_price_commercial": 0.5,
"petrol_litre_price": 1.75,
"kilometers_per_year": 20000.0,
"years": 3,
"years": 6,
"ecar": {
"label": "Nissan Leaf",
"label": "Nissan Leaf 2013",
"price": 7600,
"taxes": 0,
"insurance": 354,
"kwh_per_kilometer": 0.16,
"maintenance": 200,
"charging_behaviour": {
"percent_free_charges": 80,
"percent_home_charges": 10,
"percent_commercial_charges": 10
"percent_free_charges": 90,
"percent_home_charges": 5,
"percent_commercial_charges": 5
}
},
"ccar": {
"label": "Suzuki Grand Vitara",
"label": "Suzuki Grand Vitara 2008",
"price": 7000,
"taxes": 350,
"insurance": 362,
"litre_per_kilometer": 0.08,
"litres_per_kilometer": 0.08,
"maintenance": 1000
}
}

133
ecar.py

@ -1,44 +1,103 @@
import matplotlib.pyplot as plt
import numpy as np
import json
import sys
import argparse
__author__ = 'm3x1m0m'
with open("ecar.json", "r") as rf:
settings = json.load(rf)
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
kilometer_price = np.array( [settings["ecar"]["kwh_per_kilometer"] * settings["kwh_price_home"],
settings["ccar"]["litre_per_kilometer"] * settings["petrol_litre_price"]])
labels = [settings["ecar"]["label"], settings["ccar"]["label"]]
price = np.array([settings["ecar"]["price"], settings["ccar"]["price"]])
taxes = np.array([settings["ecar"]["taxes"], settings["ccar"]["taxes"]])
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
driving = np.array([kilometer_price_ecar * settings["kilometers_per_year"], kilometer_price[1] * settings["kilometers_per_year"]])
maintenance = np.array([settings["ecar"]["maintenance"], settings["ecar"]["maintenance"]])
width = 0.3
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
fig, ax = plt.subplots()
ax.bar(labels, price, width, label = "Price", color = "gray")
currenty = price
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()
for i in range(settings["years"]):
#while currenty[0] > currenty[1]:
ax.bar(labels, taxes, width, bottom = currenty, label = "Taxes".format(y), color = "darkgreen")
currenty = currenty + taxes
ax.bar(labels, insurance, width, bottom = currenty, label = "Insurance".format(y), color = "royalblue")
currenty = currenty + insurance
ax.bar(labels, driving, width, bottom = currenty, label = "Driving".format(y), color = "midnightblue")
currenty = currenty + driving
ax.bar(labels, maintenance, width, bottom = currenty, label = "Maintenance".format(y), color = "lavender")
currenty = currenty + maintenance
y += 1
ecar_top = currenty[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"], currenty[0], currenty[1]))
plt.show()
if __name__ == "__main__":
main()

Loading…
Cancel
Save