Created
March 6, 2015 01:43
-
-
Save brianbruggeman/797f18fecf021b7414d9 to your computer and use it in GitHub Desktop.
Revisions
-
brianbruggeman created this gist
Mar 6, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,152 @@ #!/usr/bin/env python """ Calculates return on investment over time. Usage: calc_roi [options] Options: -h, --help This message -u, --unit-cost <uc> Cost per panel (USD) [Default: 750] -i, --initial <ic> Initial investment cost (USD) [Default: 9000] -i, --units <units> Initial units purchased [Default: 15] -d, --degradation <deg> Efficiency degradation per year % [Default: 0.007] -y, --years <years> Years to calculate [Default: 25] -r, --return <return> Annual return per unit (USD) [Default: 90] -p, --purchase Purchase new units with profit [Default: True] -s, --sunset <year> When to sunset a panel [Default: 100] -m, --margin <margin> Percentage of revenue kept [Default: 80%] -c, --cease <year> Year to cease purchasing new units [Default: 100] """ class Panel(object): """ Solar Panel used for calculating roi per unit """ @property def break_even(self): """ Year when this panel will break even """ investment_return = 0 for year in xrange(100): coeff = 1.0 - (self.degradation) margin = self.profit_margin revenue = self.annual_revenue investment_return += coeff * revenue * margin if investment_return >= self.investment: return year @property def age(self): """ age of panel """ return self.start + self.year @property def roi(self): """ return on investment (%) """ return self.investment / self.generated_revenue @property def degraded_revenue(self): """ degradation of panel in revenue """ value = 0 if self.age < self.sunset: coefficient = (1.0 - self.degradation * self.age) value = coefficient * self.annual_revenue * self.profit_margin return value def __init__(self, cost=750, year=0, revenue=2250 / 25, degradation=0.007, margin=0.8, sunset=100): """ Creates a unit which can be updated """ self.investment = cost self.start = year self.year = 0 self.profit_margin = 0.8 self.degradation = degradation self.annual_revenue = revenue self.generated_revenue = 0 self.sunset = sunset def update(self): """ Increments unit for this year """ self.generated_revenue += self.degraded_revenue self.year += 1 def __repr__(self): """ Panel at any point in time """ args = { "years": self.years, "capital": self.investment, "return": self.generated_revenue, "roi": self.roi, } string = "<Panel age:{years}, capital:{investment}, "\ "return:{revenue}, roi:{roi}>" return string.format(args) def calculate(args): unit_cost = args.get("--unit-cost") initial_cost = args.get("--initial") units_purchased = args.get("--units") degradation = args.get("--degradation") years = args.get("--years") annual_return = args.get("--return") purchase_new_units = args.get("--purchase", False) sunset = args.get("--sunset") margin = args.get("--margin") cease = args.get("--cease") cpu = initial_cost / units_purchased units = [Panel(cost=cpu, revenue=annual_return, degradation=degradation, margin=margin, sunset=sunset) for unit in xrange(units_purchased)] titles = ["year", "units", "monthly", "roi", "investment", "return"] print "{0:>4}: {1:>10} | {2:>16} | {3:<15} | ({4:>19}/{5:>19})".format(*titles) cumulative = 0 for year in xrange(years): profit = sum(u.degraded_revenue for u in units) cumulative += profit if purchase_new_units and year < cease: while cumulative > unit_cost: panel = Panel(cost=unit_cost, year=year, revenue=annual_return, degradation=degradation, margin=margin, sunset=sunset) units.append(panel) cumulative = cumulative - unit_cost data = { "units": sum(1 for u in units), "year": year, "cost": sum(u.investment for u in units), "profit": sum(u.generated_revenue for u in units), "monthly": sum(u.degraded_revenue/12.0 for u in units), } data["roi"] = data["profit"] / data["cost"] print("{year:>4}: {units:>10} | ${monthly:>15,} | {roi:<15} | (${cost:>18,}/${profit:>18,})".format(**data)) for unit in units: unit.update() if __name__ == "__main__": import docopt args = docopt.docopt(__doc__) for k, v in args.iteritems(): try: if "." not in v: v = int(v) args[k] = v else: v = float(v) args[k] = v except: pass calculate(args)