-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPaymentBuilder.py
More file actions
134 lines (109 loc) · 4.27 KB
/
Copy pathPaymentBuilder.py
File metadata and controls
134 lines (109 loc) · 4.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import re
from decimal import Decimal
def filer(file):
f = open(file, 'r')
lines = []
for line in f.readlines():
lines.append(line.strip())
return lines
def parse_lines(lines, **kwargs):
compilers = kwargs.get('keys', ['money', 'name', 'bill'])
parses = []
for line in lines:
l1 = Parser(line, keys=compilers)
parses.append(l1.get_dict())
return parses
class Parser(object):
patterns = {'name_pattern':'^([\w\-]+)','money_pattern':'(\d+.?\d*)','bill_pattern':"[\w'-]+\.$"}
keys = ['money', 'name', 'bill']
def __init__(self, line, **kwargs):
if 'patterns' in kwargs:
self.patterns.update(kwargs.get('patterns'))
del kwargs['patterns']
self.__dict__.update(kwargs)
for key in self.keys:
key_str = key+'_pattern'
parser = re.compile(self.patterns[key_str])
value = parser.search(line)
setattr(self, key, value.group(0))
def get_dict(self):
rtn = {}
for key in self.keys:
rtn[key] = getattr(self, key)
return rtn
class Payments(object):
def __init__(self, **kwargs):
self.people = {}
self.formatter = "{from} pays {currency}{amount} to {to}."
self.currency = '$'
self.__dict__.update(kwargs)
def add_person(self, person):
self.people[str(person.name)] = person
def add_payment(self, payment):
person = self.people[payment['name']]
person.add_to(payment)
def get_liabilities(self):
liabilities = []
for name, person in self.people.items():
person.set_share(len(self.people.items()))
for name, person in self.people.items():
"""gets share & sets it against each person in the group"""
person.set_liability(self.people, self.currency)
liabilities += person.liabilities
return liabilities
def print_liabilities(self):
liabilities = []
for liability in self.get_liabilities():
liabilities.append(self.formatter.format(**liability))
return liabilities
class Person(object):
def __init__(self, **kwargs):
self.name = ""
self.items = []
self.paid = 0
self.share = 0
self.liabilities = []
self.__dict__.update(kwargs)
def add_to(self, payment):
""" payment must have keys: 'name', 'money'"""
if payment['name'] == self.name:
self.items.append(payment)
def _get_paid(self):
balance = 0
for item in self.items:
amount = Decimal(item['money'],2)
balance += amount
return Decimal(balance, 2)
def set_share(self, total_people):
"""total amount paid is divided by the number of
people to get the liabilities of each person"""
self.paid = self._get_paid()
self.share = round(self.paid/Decimal(total_people), 2)
def _set_extras(self, liability, keys):
"""sets extra properties"""
for key in keys:
if hasattr(self, key):
liab_dict[key] = getattr(self, key)
def set_liability(self, people, currency):
"""if owed is share is greater than owed, name needs to pay this"""
for name, person in people.items():
if self.name != name:
"""if owed is greater than what I have paid then add to liabilities"""
diff = self.share - person.share
if diff < 0:
liab_dict = {'from':self.name,'to': name,'amount':-diff, 'currency':currency }
self.liabilities.append(liab_dict)
class PaymentBuilder(object):
people = []
def __init__(self, **kwargs):
transactions = kwargs.get('transaction_file','./transactions.txt')
names = kwargs.get('names_file','./names.txt')
self.payments = Payments()
self.trans = parse_lines(filer(transactions))
self.names = filer(names)
for name in self.names:
self.payments.add_person(Person(name=name))
for tran in self.trans:
self.payments.add_payment(tran)
def liabilities(self):
return [ liability for liability in self.payments.print_liabilities()]