Last active
August 29, 2015 14:25
-
-
Save aahung/5e8d33750e4911c213d3 to your computer and use it in GitHub Desktop.
AA Pay Calculator
This file contains 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
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, []), | |
$ |
This file contains 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
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!!! | |
%%%%%%%%%%%%%%%%%%%% |
This file contains 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
#! /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