Last active
May 23, 2025 12:51
-
-
Save clamytoe/1734faa46e4ab251c1d44bd8f1d2af10 to your computer and use it in GitHub Desktop.
Script for tracking fuel usage and efficiency. I use this on my iPhone within Pythonista so it's convenient to use right at after filling up.
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 characters
import csv | |
from datetime import datetime | |
from typing import Optional | |
STARTING_ODOMETER_READING = 188590 | |
LOG_FILE = "fuel_log.csv" | |
def log_fuel_efficiency( | |
current_miles: int, | |
gallons: float, | |
total_paid: float, | |
filename: str = LOG_FILE, | |
) -> tuple[Optional[float], Optional[float]]: | |
""" | |
Logs a fuel efficiency entry to a CSV file. | |
Parameters | |
---------- | |
current_miles : int | |
Current odometer reading. | |
gallons : float | |
Number of gallons of fuel purchased. | |
total_paid : float | |
Total amount paid in USD. | |
filename : str, optional | |
Name of the file to write to. | |
Returns | |
------- | |
tuple | |
A tuple of two values: the calculated MPG and price per gallon. | |
""" | |
try: | |
with open(filename, "r") as f: | |
reader = csv.DictReader(f) | |
rows = list(reader) | |
start_miles = ( | |
int(rows[-1]["End Miles"]) if rows else STARTING_ODOMETER_READING | |
) | |
except (FileNotFoundError, KeyError): | |
start_miles = STARTING_ODOMETER_READING | |
miles_driven = current_miles - start_miles | |
mpg = round(miles_driven / gallons, 1) if gallons else 0 | |
price_per_gallon = round(total_paid / gallons, 3) if gallons else 0 | |
# Get current month for cost tracking | |
now = datetime.now() | |
current_month = now.strftime("%Y-%m") | |
new_row = [ | |
now.strftime("%Y-%m-%d %H:%M:%S"), | |
start_miles, | |
current_miles, | |
gallons, | |
mpg, | |
price_per_gallon, | |
total_paid, | |
current_month, | |
] | |
try: | |
with open(filename, "a", newline="") as f: | |
writer = csv.writer(f) | |
if f.tell() == 0: | |
writer.writerow( | |
[ | |
"Timestamp", | |
"Start Miles", | |
"End Miles", | |
"Gallons", | |
"MPG", | |
"Price per Gallon", | |
"Total Paid", | |
"Month", | |
] | |
) | |
writer.writerow(new_row) | |
return mpg, price_per_gallon | |
except Exception as e: | |
print(f"Error saving data: {e}") | |
return None, None | |
def calculate_cost_stats(filename: str = LOG_FILE) -> tuple[float, float]: | |
""" | |
Calculates cost statistics for the current month. | |
Parameters | |
---------- | |
filename : str, optional | |
Name of the file to read from. | |
Returns | |
------- | |
tuple | |
A tuple of two values: the total cost for the month and the average cost per week. | |
""" | |
now = datetime.now() | |
current_month = now.strftime("%Y-%m") | |
day_of_month = now.day | |
weeks_in_month_so_far = max(1, (day_of_month - 1) // 7 + 1) | |
try: | |
with open(filename, "r") as f: | |
reader = csv.DictReader(f) | |
monthly_data = [row for row in reader if row.get("Month") == current_month] | |
total_cost = sum(float(row["Total Paid"]) for row in monthly_data) | |
avg_cost_per_week = total_cost / weeks_in_month_so_far | |
return round(total_cost, 2), round(avg_cost_per_week, 2) | |
except (FileNotFoundError, KeyError): | |
print("No historical data found") | |
return 0, 0 | |
def main(): | |
""" | |
Prompts user for odometer reading, gallons consumed, and cost. | |
Logs the fuel efficiency to a CSV file. | |
Calculates and prints the current MPG and price per gallon. | |
Calculates and prints the total cost for the month and average cost per week. | |
""" | |
odometer = int(input("Odometer: ")) | |
gallons = float(input(" Gallons: ")) | |
cost = float(input(" Cost: ")) | |
mpg, price_per_gallon = log_fuel_efficiency(odometer, gallons, cost) | |
print() | |
print(f" Current MPG: {mpg}") | |
print(f"Price per gallon: ${price_per_gallon:.2f}") | |
monthly_total, avg_weekly = calculate_cost_stats() | |
print(f"Total this month: ${monthly_total:.2f}") | |
print(f" Weekly average: ${avg_weekly}") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment