Skip to content

Instantly share code, notes, and snippets.

@royvandam
Last active November 30, 2015 15:40
Show Gist options
  • Save royvandam/c7c992a8d785baf9c2f4 to your computer and use it in GitHub Desktop.
Save royvandam/c7c992a8d785baf9c2f4 to your computer and use it in GitHub Desktop.
Interpolate car milage to month boundaries for use with ERP systems.
#!/usr/bin/python
import sys
import re
import calendar
from datetime import date
from dateutil.relativedelta import relativedelta
date_format = '%Y/%m/%d'
s = re.compile('/|\s');
p = re.compile('[0-9]{4}/[0-1][0-9]/[0-3][0-9] [0-9]+')
def next_month(d):
d += relativedelta(months = 1)
return d.replace(day = 1)
while 1:
start = raw_input('Enter milage at start (yyyy/mm/dd milage): ')
if p.match(start):
break
print("Invalid input.")
while 1:
end = raw_input('Enter milage at the end (yyyy/mm/dd milage): ')
if p.match(end):
break
print("Invalid input.")
start = s.split(start)
end = s.split(end)
if int(start[3]) > int(end[3]):
print("Milage at the beginning higher than at the end.")
sys.exit(1)
start_date = date(int(start[0]), int(start[1]), int(start[2]))
end_date = date(int(end[0]), int(end[1]), int(end[2]))
if start_date > end_date:
print("End date is earlier than the start date.")
sys.exit(1)
delta = end_date - start_date
milage_delta = int(end[3]) - int(start[3])
milage_avg = milage_delta / float(delta.days)
print('Delta: \n - Milage: {0}\n - Days: {1}').format(milage_delta, delta.days)
print('Average milage per day: {0}\n').format(milage_avg)
d = start_date
milage = int(start[3])
while 1:
# Determine the end of the month
end_of_month = d.replace(day = calendar.monthrange(d.year, d.month)[1])
# Start input on end of the month, simply print the milage and continue
if (d == end_of_month):
print('\t\t\t{0} - {1}').format(d.strftime(date_format), int(milage))
d = next_month(d)
continue;
# Print the milage at the start of the month
print('{0} - {1}\t').format(d.strftime(date_format), int(milage)),
# Input ends in the middel of a month, calculate up to that specific date.
if (end_date <= end_of_month):
days_to_end = (end_date - d).days
milage_at_end = milage + (milage_avg * (days_to_end + 1))
print('{0} - {1}').format(end_date.strftime(date_format), int(milage_at_end))
break
# Calculate milage at end of the month and increment to next month
days_to_eom = (end_of_month - d).days + 1
milage_at_eom = milage + (milage_avg * days_to_eom)
print('{0} - {1}').format(end_of_month.strftime(date_format), int(milage_at_eom))
milage = milage_at_eom
d = next_month(d)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment