-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathledgerParser.py
More file actions
167 lines (146 loc) · 6.05 KB
/
ledgerParser.py
File metadata and controls
167 lines (146 loc) · 6.05 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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import csv
from dataStructures import generateTransactions, Entity
from datetime import datetime
class Ledger:
"""
A class representation of the ledger.
Attributes
----------
entities : list
a list of Entity types that are allowed to make payments.
ledgerFile : str
the name of the entity.
Methods
----------
getEntityByName(name)
retrieves an entity from the entities list of this object by its name.
parseRandomLedger(entitiesFile, ledgerFile, number, startDate)
creates a new ledger of randomized transactions in csv format and parses it.
parseLedger(ledgerFile)
parses a ledger of transactions in csv format.
getBalanceAtDate(date,format)
gets the balance for all entities at the specified date in JSON format.
printBalanceAtDate(date,format)
prints the balance for all entities at the specified date.
"""
def __init__(self):
"""
Initializes the ledger object.
"""
self.entities = None
self.ledgerFile = None
def getEntityByName(self,name):
"""
Retrieves an entity from the entities list of this object by its name.
Parameters
----------
name : str
The name to look for in the entities list.
Returns
----------
Entity or None
The entity located in the entities array or None if no entity was found.
"""
for entity in self.entities:
if entity.name.lower() == name.lower():
return entity
return None
def parseRandomLedger(self,entitiesFile = 'entities.csv', ledgerFile = 'transactions.csv', number = 5000, startDate='2021-04-01'):
"""
Creates a new ledger of randomized transactions in csv format and parses it.
Parameters
----------
entitiesFile : str
The entities csv filename to parse and create the entities list for the random generation of transactions.
ledgerFile : str
The ledger csv filename to be created.
number : int
The number of transactions to be generated.
startdate : str
The date of the first transaction.
"""
generateTransactions(entitiesFile, ledgerFile, number, startDate)
self.ledgerFile = ledgerFile
self.entities = Entity.parseEntities(entitiesFile)
def parseLedger(self,ledgerFile = 'transactions.csv'):
"""
Parses a ledger of transactions in csv format.
Parameters
----------
ledgerFile : str
The ledger csv filename to be parsed.
"""
self.ledgerFile = ledgerFile
self.entities = Entity.parseEntities(None,ledgerFile)
def getBalanceAtDate(self,date,format='%Y-%m-%d'):
"""
Gets the balance for all entities at the specified date in JSON format.
Parameters
----------
date : str
The date to search for in string format.
format : str
The format of the date provided, default format is '%Y-%m-%d'.
Returns
----------
json
The list of balances for all entities in JSON format.
Raises
----------
Exception
If the date is not provided or sender, receiver, date and/or amount is not present in the ledger csv.
ValueError
If the format specified does not match the date's format.
IOError
If a file specified could not be found or opened.
"""
if date is None:
raise Exception('No date was provided.')
try:
date = datetime.strptime(date,format)
except:
raise
try:
with open(self.ledgerFile) as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
for rowIndex,row in enumerate(csv_reader):
if rowIndex == 0:
headers = row
if 'sender' not in headers or 'receiver' not in headers or 'date' not in headers or 'amount' not in headers :
raise Exception('sender, receiver, date and amount must be contained as headers in the ledger CSV.')
else:
sender = self.getEntityByName(row[headers.index('sender')])
receiver = self.getEntityByName(row[headers.index('receiver')])
currentDate = datetime.strptime(row[headers.index('date')],'%Y-%m-%d')
amount = float(row[headers.index('amount')])
if currentDate <= date:
sender.pay(receiver,amount)
else:
return {date.strftime(format):[{'name':entity.name,'balance':entity.balance} for entity in self.entities]}
except:
raise
def printBalanceAtDate(self,date,format='%Y-%m-%d'):
"""
Prints the balance for all entities at the specified date.
Parameters
----------
date : str
The date to search for in string format.
format : str
The format of the date provided, default format is '%Y-%m-%d'.
Raises
----------
Exception
If the date is not provided.
ValueError
If the format specified does not match the date's format.
IOError
If a file specified could not be found or opened.
"""
try:
balance = self.getBalanceAtDate(date,format)
print('Balances on '+str(list(balance.keys())[0])+':')
for entity in balance[list(balance.keys())[0]]:
print(entity['name'].capitalize()+' has a balance of §'+"{:.2f}".format(entity['balance'])+'.')
except:
raise