#!/usr/bin/python
from sys import *

usage = '''
usage: %s chargeTime totalMilage [ x1=40 y1=145 x2=55 y2=100 x3=70 y3=80 ]

recharge time should be hours, and can include fraction of hour

assumptions: you start with full SOC, travel at constant speed until empty,
             and fully recharge (if the final leg is, e.g, 28%% of a full leg,
             assumes you only recharge to 28%%)
             
             Default three data points are:
               mph   range
               ---   -----
                40    145
                55    100
                70     80

Note: none of these assumptions reflect "real life;" this is very much 
      a back-of-the-envelope investigation to attempt to gain some insight 
      regarding riding efficiency

The parameters x1, y1, x2, y2, x3, y3 are optional; they're provided
in case you want to plug in other values. The x1,y1,x2,y2 defaults are 
from Zero's specs for my 2016 SR; x3 and y3 are a guess on my part ...
If you specify x and y values you can specify any or all, and ordering
doesn't matter. Just ensure the first two params are chargeTime and
totalMilage

I used info from this site: http://www.mathcelebrity.com/3ptquad.php
to fit a curve to the three points to estimate ranges for other speeds
   
CAUTION: this code is not well error-checked. 
         Ensure your input params are correct!
''' % argv[0]

#=========================================================================
'''
Given the input (x,y) points, returns the coefficients (A, B, C) for the
equation of a quadratic curve that fits the points. The equation is:
y = Ax^2 + Bx + C
'''
def computeQuadraticCoefficients(x1,y1,x2,y2,x3,y3) :
  b = x1; a = x1*x1; c = 1; d = y1
  f = x2; e = x2*x2; g = 1; h = y2
  j = x3; i = x3*x3; k = 1; l = y3

  denominator = float((a*f*k) + (b*g*i) + (c*e*j) - (c*f*i) - (a*g*j) - (b*e*k))
  numerator_a = float((d*f*k) + (b*g*l) + (c*h*j) - (c*f*l) - (d*g*j) - (b*h*k))
  numerator_b = float((a*h*k) + (d*g*i) + (c*e*l) - (c*h*i) - (a*g*l) - (d*e*k))
  numerator_c = float((a*f*l) + (b*h*i) + (d*e*j) - (d*f*i) - (a*h*j) - (b*e*l))

  A = numerator_a / denominator
  B = numerator_b / denominator
  C = numerator_c / denominator

  return (A, B, C)

#=========================================================================
if len(argv) < 3 :
  print usage
  exit(9)

total_miles = float(argv[2])
recharge_time = float(argv[1])

#default three data points
x1 = 40; y1 = 145
x2 = 55; y2 = 100
x3 = 70; y3 = 80

#parse cmd line for optional data points
for j in range(len(argv)) :
  x = argv[j]
  if x.find('=') != -1 :
    t = x.split('=')
    if t[0] == 'x1' : x1 = int(t[1])
    elif t[0] == 'x2' : x2 = int(t[1])
    elif t[0] == 'x3' : x3 = int(t[1])
    elif t[0] == 'y1' : y1 = int(t[1])
    elif t[0] == 'y2' : y2 = int(t[1])
    elif t[0] == 'y3' : y3 = int(t[1])
    else :
      print 'something seems wrong with this entry in you cmd line:', x
      exit(9)


(A,B,C) = computeQuadraticCoefficients(x1, y1, x2, y2, x3, y3)

for speed in range(40,105,5) :
  milage_per_leg = speed*speed*A + B*speed + C
  num_legs = total_miles / milage_per_leg
  riding_time_per_leg = milage_per_leg / speed
  num_recharges = num_legs - 1
  total_time = num_legs*riding_time_per_leg + num_recharges*recharge_time
  miles_per_hour = total_miles/total_time

  print 'mph: %d legs: %0.1f mpl: %3d avg mph: %d time %4.1f rideTm: %4.1f chargeTm: %4.1f' % (speed, num_legs, round(milage_per_leg), round(miles_per_hour), total_time, num_legs*riding_time_per_leg, num_recharges*recharge_time)

