```python=
import sys
class Record:
"""Represent a record."""
def __init__(self, regimentation, action, amount):
self.regimentation = regimentation
self.action = action
self.amount = amount
class Records:
"""Maintain a list of all the 'Record's and the initial amount of money."""
def __init__(self):
self.findmy = 0
try:
fh = open('records.txt', 'r')
money = int(fh.readline())
fh.close()
self.money = money
except:
self.money = 0
try:
fh = open('data.txt', 'r')
dee = fh.readlines()
see = []
f = 0
for things in dee:
f = f + 1
drr = things.split(".")
see.append([str(f), drr[1], drr[2], drr[3]])
fh.close()
self.f = f
self.see = see
except:
self.f = 0
self.see = []
def add(self, action):
# 1. Define the formal parameter so that a string input by the user
# representing a record can be passed in.
# 2. Convert the string in to a Record instance.
# 3. Check if the category is valid. For this step, the predefined
# categories have to be passed in through the parameter.
# 4. Add the Record into self._records if the category is valid.
action_list = action.split(" ")
try:
spending_income = int(action_list[2])
self.money += spending_income
print(action_list[0], action_list[1], spending_income)
self.f += 1
self.see.append([str(self.f), action_list[0],
action_list[1], action_list[2]])
except ValueError:
print("insert money")
def view(self):
for item in self.see:
k = item
print(k)
print("now you have?", self.money)
def delete(self, R):
# 1. Define the formal parameter.
# 2. Delete the specified record from self._records.
try:
t = int(R)
del see[t-1]
self.money = self.money + int(input("amount"))
except ValueError:
print("inset numbers!")
except:
print("not found")
def find(self, target_categories):
for items in self.see:
L = []
g = filter(lambda n: items[1] in target_categories, items)
L.append(list(g))
for things in L:
print(things)
self.findmy += int(things[3])
print(f"there are {self.findmy}")
def save(self):
# 1. Write the initial money and all the records to 'records.txt'.
a_lot_thing = []
for thing in self.see:
alot = ".".join(thing)
a_lot_thing.append(alot)
with open("records.txt", "w", encoding="utf-8") as File:
stmoney = str(self.money)
File.write(stmoney)
with open("data.txt", "w", encoding="utf-8") as file:
for line in a_lot_thing:
file.write(line+"\n")
print("latest amount of money:", self.money)
class Categories:
"""Maintain the category list and provide some methods."""
L = ['expense', ['food', ['meal', 'snack', 'drink'], 'transportation',
['bus', 'railway']], 'income', ['salary', 'bonus']]
def __init__(self):
pass
def view(self, L=L, prefix=()):
# 1. Define the formal parameters so that this method
# can be called recursively.
# 2. Recursively print the categories with indentation.
# 3. Alternatively, define an inner function to do the recursion.
if type(L) in {list, tuple}:
i = 0
for v in L:
if type(v) not in {list, tuple}:
i += 1
self.view(v, prefix+(i,))
else:
s = ' ' * 4*(len(prefix)-1)
s += '.'.join(map(str, prefix))
s += '. ' + L
print(s)
def flatten(self, L):
if type(L) == list:
result = []
for child in L:
result.extend(self.flatten(child))
return result
else:
return [L]
def find_subcategories(self, category, categories=L):
if type(categories) == list:
for v in categories:
p = self.find_subcategories(category, v)
if p == True:
index = categories.index(v)
if index + 1 < len(categories) and \
type(categories[index + 1]) == list:
return self.flatten(categories[index: index + 2])
else:
# return only itself if no subcategories
return [v]
if p != []:
return p
return True if categories == category else []
categories = Categories()
records = Records()
while True:
command = input('\nWhat do you want to do (add / ...)? ')
if command == 'add':
action = input('Add an expense or income record with ...:\n')
records.add(action)
elif command == 'view':
records.view()
elif command == 'delete':
R = input("which one")
records.delete(R)
elif command == 'view categories':
categories.view()
elif command == 'find':
category = input('Which category do you want to find? ')
target_categories = categories.find_subcategories(category)
records.find(target_categories)
elif command == 'exit':
records.save()
break
else:
sys.stderr.write('Invalid command. Try again.\n')
```