Skip to content

Instantly share code, notes, and snippets.

@ericsong
Created January 22, 2016 15:16
Show Gist options
  • Save ericsong/7ce7d28e29ad8642a06b to your computer and use it in GitHub Desktop.
Save ericsong/7ce7d28e29ad8642a06b to your computer and use it in GitHub Desktop.
script used to calculate per person expenses from our Japan trip
import csv
CONVERSION_RATE = 117.3
class Trans:
def __init__(self, item, receiver, giver, amount):
self.item = item
self.receiver = receiver
self.giver = giver
self.amount = amount
people = ["eric", "adam", "vincent", "kristian", "todd", "nathan", "sandy", "jon"]
transactions = []
giveTransactions = {}
#process and add transactions
with open('expenses.csv', 'r') as f:
reader = csv.reader(f)
for row in reader:
item = row[0]
cost = row[1]
currency = row[2]
paidby = row[3].lower()
paidfor = row[4].lower()
processed = False
if currency.lower() == 'usd':
cost = float(cost) * CONVERSION_RATE
if(paidby == paidfor):
continue
if(paidfor == 'everyone'):
cost = float(cost) / len(people)
for giver in people:
if giver == paidby:
continue
transactions.append(Trans(item, paidby, giver, cost))
processed = True
elif ' ' in paidfor:
names = paidfor.strip().split(' ')
cost = float(cost) / len(names)
for giver in names:
if giver.lower() == paidby:
continue
transactions.append(Trans(item, paidby, giver, cost))
processed = True
else:
if not paidfor in people or not paidby in people:
continue
transactions.append(Trans(item, paidby, paidfor, cost))
processed = True
if not processed and paidby != "":
print(row)
print("not processed error")
# calculate totals per person
totals = {}
details = {}
for person in people:
totals[person] = 0
details[person] = []
for trans in transactions:
totals[trans.receiver] = totals[trans.receiver] + float(trans.amount)
details[trans.receiver].append((float(trans.amount), trans.item))
totals[trans.giver] = totals[trans.giver] - float(trans.amount)
details[trans.giver].append((float(trans.amount) * -1, trans.item))
# calculate venmo transactions
transferTransactions = {}
givers = []
receivers = []
for person in people:
transferTransactions[person] = []
for person in people:
if totals[person] > 0:
receivers.append((person, totals[person]))
else:
givers.append((person, totals[person]))
for giver in givers:
giveBalance = giver[1] * -1
while giveBalance > 0.0000001:
receiver = receivers.pop()
receiveBalance = receiver[1]
if giveBalance > receiveBalance:
transferTransactions[receiver[0]].append((giver[0], receiveBalance))
transferTransactions[giver[0]].append((receiver[0], receiveBalance * -1))
giveBalance = giveBalance - receiveBalance
receiveBalance = 0
else:
transferTransactions[receiver[0]].append((giver[0], giveBalance))
transferTransactions[giver[0]].append((receiver[0], giveBalance * -1))
receiveBalance = receiveBalance - giveBalance
giveBalance = 0
receivers.append((receiver[0], receiveBalance))
# print results
for person in people:
f = open(person + '_expenses.txt', 'w')
f.write("Total: " + str(totals[person]) + '\n')
f.write("Total: $" + str(totals[person] / CONVERSION_RATE) + ' USD\n')
f.write("\n*******Transfers*******\n\n")
for trans in transferTransactions[person]:
amount = trans[1] / CONVERSION_RATE
if amount > 0:
f.write("Receive $" + format(amount, '.2f') + " from " + trans[0] + '\n')
else:
f.write("Give $" + format(amount * -1, '.2f') + " to " + trans[0] + '\n')
f.write("\n*******Transactions*******\n\n")
for t in details[person]:
f.write(str(t[0]) + '\t' + str(t[1]) + '\n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment