Skip to content

Instantly share code, notes, and snippets.

@aahung
Last active August 29, 2015 14:25
Show Gist options
  • Save aahung/5e8d33750e4911c213d3 to your computer and use it in GitHub Desktop.
Save aahung/5e8d33750e4911c213d3 to your computer and use it in GitHub Desktop.
AA Pay Calculator
X 38 #July 1st Taxi
$ (0, []),
T 6.74 #July 7th Super Fresh Asian Market
$ (0, []),
T 37.922 #July 7th Superstore
$ (10.85, [M, C, W]), (0, []),
M 20 #July 9th 711
$ (0, []),
C 52.48 #July 9th Superstore
$ (0, []),
Z 30 #July 13th Parking Ticket
$ (0, [M, C, W, X, Z]),
X 61.52 #July 15th Super Store
$ (0, []),
$
Please paste the raw record here, end with single $ in seperate line,
[RAW RECORD HERE]
%%%%%%%%%%%%%%%%%%%%
%% HERE WE GO!!!
%%%%%%%%%%%%%%%%%%%%
%% W spent 43.919 paid 0.000 should pay 43.90
%% M spent 43.919 paid 20.000 should pay 23.90
%% T spent 34.302 paid 44.662 should receive 10.35
%% X spent 40.302 paid 99.520 should receive 59.20
%% Z spent 40.302 paid 30.000 should pay 10.30
%% C spent 43.919 paid 52.480 should receive 8.55
%% error = -0.000
%%%%%%%%%%%%%%%%%%%%
%% HERE WE DONE!!!
%%%%%%%%%%%%%%%%%%%%
#! /usr/bin/env python3
from enum import Enum
class Calculator(object):
"""docstring for Calculator"""
@staticmethod
def round_005(x):
b = 0.05
dr = x // 0.05
frac = x - dr * b
if frac >= b / 2:
return x - frac + b
else:
return x - frac
class Status(Enum):
Ground = 0
Intermediate = 1
# initial status and str
status = Status.Ground
str = ''
last_paid = 0
# datas
# Please do change these to the people's symbol
all = ['W', 'M', 'T', 'X', 'Z', 'C']
paids = {}
spents = {}
def __init__(self):
for who in self.all:
self.paids[who] = 0.0
self.spents[who] = 0.0
def add_quote(self, spent_str):
for who in self.all:
spent_str = spent_str.replace(who, '\'%s\'' % (who,))
return spent_str
def add_paid(self, who, amount):
if who not in self.all:
print('invalid person: %s' % (who,))
exit()
self.paids[who] = self.paids[who] + amount
def add_spent(self, who, amount):
if who not in self.all:
print('invalid person: %s' % (who,))
exit()
self.spents[who] = self.spents[who] + amount
def process_spent(self, spent_str):
spent_str = self.add_quote(spent_str)
spent_list = eval(spent_str)
bill_whos = set()
bill_special_spent = 0.0
for spent_item in spent_list:
amount = spent_item[0]
whos = spent_item[1]
if len(whos) == 0:
whos = self.all
number_who = len(whos)
for who in whos:
self.add_spent(who, amount / number_who)
bill_whos.add(who)
bill_special_spent = bill_special_spent + amount
common_spent = self.last_paid - bill_special_spent
for bill_who in bill_whos:
self.add_spent(bill_who, common_spent / len(bill_whos))
def process(self):
if self.str == '':
return
tokens = self.str.split()
if len(tokens) < 2:
print('invalid line: %s' % (str,))
exit()
if self.status == self.Status.Ground:
# read overall money
# and add to paids
who = tokens[0]
amount = float(tokens[1])
self.add_paid(who, amount)
self.last_paid = amount
# switch status
self.status = self.Status.Intermediate
else:
# read detail money
if tokens[0] != '$':
print('invalid line: %s' % (str,))
exit()
# deal with each spent
spent_str = self.str[1:].strip()
self.process_spent(spent_str)
# switch status
self.status = self.Status.Ground
def print_result(self):
print('%' * 20)
print('%% HERE WE GO!!!')
print('%' * 20)
error = 0
for who in self.all:
balance = Calculator.round_005(self.paids[who] - self.spents[who])
error = error + balance
behaviour = 'receive'
if balance < 0:
behaviour = 'pay'
balance = 0 - balance
print('%%%% %s \tspent %.3f\tpaid %.3f\tshould %s %.2f'
% (who,
self.spents[who],
self.paids[who],
behaviour,
balance))
print('%%%% error = %.3f' % (error,))
print('%' * 20)
print('%% HERE WE DONE!!!')
print('%' * 20)
def calculate(self):
print('Please paste the raw record here, '
'end with single $ in seperate line, \n[RAW RECORD HERE]')
while True:
self.str = input('').strip()
if self.str == '$':
break
self.process()
self.print_result()
calculator = Calculator()
calculator.calculate()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment