Skip to content

Instantly share code, notes, and snippets.

@Roguelazer
Created January 18, 2023 17:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Roguelazer/faecd8a0ad58e2df9233f5efa4e4fd9d to your computer and use it in GitHub Desktop.
Save Roguelazer/faecd8a0ad58e2df9233f5efa4e4fd9d to your computer and use it in GitHub Desktop.
import argparse
import collections
import csv
import datetime
import functools
import os
import subprocess
import sys
data = []
def aggregate_by_field(f):
by_date = collections.defaultdict(collections.Counter)
for row in data:
cost = row["Price Per Unit ($)"] * row["Quantity"] * row["Multiplier"]
date = datetime.datetime.strptime(row["Date"], "%Y-%m-%d").date()
by_date[date][row[f]] += cost
return by_date
def dump_table(table, field, filename_base):
keys = functools.reduce(set.union, [set(i.keys()) for i in table.values()])
columns = sorted(keys)
start_date = min(table.keys())
end_date = max(table.keys())
with open(filename_base + ".csv", "w") as f:
out = csv.writer(f)
out.writerow(["date"] + columns)
while start_date <= end_date:
this_row = table.get(start_date, {})
row = [start_date.strftime("%Y-%m-%d")] + [str(this_row.get(c, "")) for c in columns]
out.writerow(row)
start_date += datetime.timedelta(days=1)
gnuplot_file = filename_base + ".gnuplot"
with open(gnuplot_file, "w") as f:
f.write('set term png enhanced font "Berkeley Mono" 16 size 1000,800\n')
f.write(f'set out "{filename_base}.png"\n')
f.write('set datafile separator ","\n')
f.write('set timefmt "%Y-%m-%d"\n')
f.write("set xdata time\n")
f.write('set ylabel "Cost ($)"\n')
f.write('set xlabel "Date"\n')
f.write("set key below\n")
f.write("set pointsize 1\n")
f.write(f'set title "Spend By {field}"\n')
plot = []
for i, label in enumerate(columns):
plot.append(f'"{filename_base}.csv" using 1:{i+2} with points title "{label.replace("_", "-")}"')
plot = ", ".join(plot)
f.write(f"plot {plot}\n")
subprocess.check_call(["gnuplot", gnuplot_file])
os.unlink(gnuplot_file)
def dump_table_by_field(field, filename_base):
dump_table(aggregate_by_field(field), field, filename_base)
_TRANSFORMS = {"Quantity": float, "Price Per Unit ($)": float, "Multiplier": float}
def transform(row):
return dict((k, _TRANSFORMS.get(k, str)(v)) for (k, v) in row.items())
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input", type=argparse.FileType("r"), default=sys.stdin)
args = parser.parse_args()
r = csv.DictReader(args.input)
for row in r:
data.append(transform(row))
dump_table_by_field("Owner", "by_owner")
dump_table_by_field("Repository Slug", "by_repo")
dump_table_by_field("Username", "by_user")
dump_table_by_field("SKU", "by_sku")
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment