This repository was archived by the owner on Oct 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathloader.py
More file actions
196 lines (167 loc) · 7.01 KB
/
Copy pathloader.py
File metadata and controls
196 lines (167 loc) · 7.01 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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#! python3
#loader.py
#
import os
import csv
from datetime import datetime
import categorizer
class record (object):
'''This class handles each individual item in the budget.'''
def __init__(self, date, description, withdrawl, deposit, account, category='', tag='', split=''):
#gives values to withdrawl and deposit if NULL.
if not withdrawl:
withdrawl = '0'
if not deposit:
deposit = '0'
self.date = datetime.strptime(date, '%m/%d/%Y').date()
self.description = description
self.withdrawl = float(withdrawl) #convert, saved as strings.
self.deposit = float(deposit)
self.account = account
self.category = category
self.tag = tag
self.split = split
def recordValues (self):
return ('{:%m/%d/%Y}'.format(self.date),
self.description,
self.withdrawl,
self.deposit,
self.account,
self.category,
self.tag,
self.split)
def similarValues (self):
return ('{:%m/%d/%Y}'.format(self.date),
self.description,
self.withdrawl,
self.deposit,
self.account)
def __str__(self):
return ('Date: {:%A, %b %d, %Y}\n'
'Description: {}\n'
'Withdrawl: ${}\n'
'Deposit: ${}\n'
'Account: {}\n'
'Category: {}\n'
'Tag: {}\n'
'Split Status: {}\n\n'.format(self.date, self.description, self.withdrawl, self.deposit, self.account, self.category, self.tag, self.split))
def new_file_list ():
''' returns tuple of file .csv names in .//newdata directory '''
return tuple('.//newdata//{}'.format(file) for file in os.listdir('.//newdata') if file.endswith(".csv"))
def create_master_records (fileName):
"""
Create previously categorized records from raw files.
Parameter: .csv file name of categorized records.
Return: a list of record objects.
"""
with open (fileName, newline='') as f:
# createn tuple where each entry represents a record
rawData = tuple(row for row in csv.reader(f))
#rows represent: date, description, withdrawl, deposit, account, category,
#tag, and split.
return [record(row[0],row[1],row[2],row[3], row[4], row[5], row[6], row[7]) for row in rawData]
def create_new_records (fileName):
"""
Create new records from raw files.
Parameter: .csv file name of new records.
Return: a list of record objects.
"""
#read raw data from .csv file
with open (fileName, newline='') as f:
rawData = tuple(row for row in csv.reader(f))
#Check to see what account tag the new data has in it's name.
if fileName.startswith('.//newdata//credit'):
account = 'credit'
elif fileName.startswith('.//newdata//savings'):
account = 'savings'
elif fileName.startswith('.//newdata//debit'):
account = 'debit'
else:
print(fileName)
account = 'no account'
#rows represent: date, description, withdrawl, deposit, account.
return [record(row[0],row[1],row[2],row[3], account) for row in rawData]
def load_new_records ():
records = []
for file in new_file_list():
records.extend(create_new_records(file))
return records
def archive_records ():
for file in os.listdir('.//newdata'):
if file.endswith(".csv"):
#os.replace will write over any file with the same name.
os.replace(".//newdata//{}".format(file), ".//archive//{}".format(file))
def delete_duplicates(records):
uniqueRecords = set()
newRecords = []
for record in records:
if record.recordValues() in uniqueRecords:
continue
uniqueRecords.add(record.recordValues())
newRecords.append(record)
return newRecords
def save_similar_records(records, fileName):
"""
Save records that are almost duplicates for manual review.
Parameters:
records(list): list of record objects.
fileName(str): file to save the similar records to.
Returns:
the number of similar records found.
"""
similarRecords = set()
newRecords = []
#
for record in records:
#if record exists in the set, add to list of similar records.
if record.similarValues() in similarRecords:
newRecords.append(record)
continue
#if record is unique, add to similarRecords set.
similarRecords.add(record.similarValues())
#save similar records to file.
save_records(newRecords, fileName)
return len(newRecords)
def save_records (records, fileName):
'''Writes records to output.csv file'''
with open(fileName, 'w', newline='') as f:
file = csv.writer(f)
for record in records:
file.writerow(record.recordValues())
def main ():
"""
Main function of the loader module.
Calls:
load_new_records(): load new transaction records.
.categorize_records(): classify records into budget
categories.
.save_categories(): save categorization data to categories.py.
archive_records(): archive new input transaction files.
create_master_records(): load previously categorized records.
delete_duplicates(): delete any duplicate records.
save_similar_records(): save records that are very similar for
later manual review.
save_records(): save all records to master.csv file.
"""
print('Loading new records...')
records = load_new_records()
print('loaded')
newCategories = categorizer.categorizer(records)
newCategories.categorize_records()
print('\nSaving categories...')
newCategories.save_categories()
print('Saved')
print('archiving records')
archive_records()
#print('loading master records...')
#records.extend(create_master_records('master.csv'))
print('deleting duplicate records')
records = delete_duplicates(records)
print('Saving similar records for review...')
similar = save_similar_records(records, 'similar.csv')
print('***** {} possible duplicate records to review *****'.format(similar))
print('\nSaving records...')
save_records(records, 'master2.csv')
print('Records saved in master2.csv')
if __name__=='__main__':
main()