Created
May 12, 2024 03:39
-
-
Save lawrence910426/ee7294b992ec8475b95855316c726788 to your computer and use it in GitHub Desktop.
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
import sys | |
class Record: | |
"""Represents a financial record with a category, description, and amount.""" | |
def __init__(self, category, description, amount): | |
self._category = category | |
self._description = description | |
self._amount = float(amount) | |
@property | |
def category(self): | |
return self._category | |
@property | |
def description(self): | |
return self._description | |
@property | |
def amount(self): | |
return self._amount | |
class Records: | |
"""Manages a collection of Record instances and overall financial balance.""" | |
def __init__(self): | |
try: | |
with open('records.txt', 'r') as file: | |
self._initial_money = float(file.readline().strip()) | |
self._records = [Record(*line.strip().split(', ')) for line in file.readlines()] | |
except FileNotFoundError: | |
self._initial_money = float(input("How much money do you have? ")) | |
self._records = [] | |
def add(self, entry, categories): | |
cat, desc, amt = entry.split(" ") | |
if categories.is_category_valid(cat): | |
self._records.append(Record(cat, desc, float(amt))) | |
self._initial_money += float(amt) | |
else: | |
print(f"The specified category '{cat}' is not in the category list.") | |
def view(self): | |
print("Here's your expense and income records:") | |
print("Category Description Amount") | |
print("=============== ==================== ======") | |
for record in self._records: | |
print(f"{record.category:15} {record.description:20} {record.amount:5.2f}") | |
print("===========================================") | |
print(f"Now you have {self._initial_money:.2f} dollars.") | |
def delete(self, index): | |
try: | |
index = int(index) - 1 | |
if 0 <= index < len(self._records): | |
self._initial_money -= self._records[index].amount | |
del self._records[index] | |
else: | |
print("Invalid record number.") | |
except ValueError: | |
print("Please enter a valid number.") | |
def find(self, subcategories): | |
print("Category Description Amount") | |
print("=============== ==================== ======") | |
total = 0 | |
for record in self._records: | |
if record.category in subcategories: | |
print(f"{record.category:15} {record.description:20} {record.amount:5.2f}") | |
total += record.amount | |
print("===========================================") | |
print(f"The total amount above is {total:.2f}.") | |
def save(self): | |
with open('records.txt', 'w') as file: | |
file.write(f"{self._initial_money}\n") | |
for record in self._records: | |
file.write(f"{record.category}, {record.description}, {record.amount}\n") | |
class Categories: | |
"""Manages categories and validates them against a predefined list.""" | |
def __init__(self): | |
self._categories = [ | |
'expense', [ | |
'food', [ | |
'meal', | |
'snack', | |
'drink' | |
], | |
'transportation', [ | |
'bus', | |
'railway' | |
] | |
], | |
'income', [ | |
'salary', | |
'bonus' | |
] | |
] | |
def view(self, categories=None, level=0): | |
if categories is None: | |
categories = self._categories | |
if isinstance(categories, list): | |
for category in categories: | |
self.view(category, level + 1) | |
else: | |
print(' ' * level + '- ' + categories) | |
def is_category_valid(self, category, categories=None): | |
if categories is None: | |
categories = self._categories | |
if isinstance(categories, list): | |
for subcat in categories: | |
if self.is_category_valid(category, subcat): | |
return True | |
return category == categories | |
def find_subcategories(self, category, categories=None): | |
if categories is None: | |
categories = self._categories | |
if isinstance(categories, list): | |
for i in range(0, len(categories), 2): | |
print(categories[i], category == categories[i]) | |
if categories[i] == category: | |
return [category] + self._flatten(categories[i + 1]) | |
result = self.find_subcategories(category, categories[i + 1]) | |
if result: | |
return result | |
return [category] if category == categories else [] | |
def _flatten(self, categories): | |
if isinstance(categories, list): | |
flat_list = [] | |
for element in categories: | |
flat_list.extend(self._flatten(element)) | |
return flat_list | |
else: | |
return [categories] | |
categories = Categories() | |
records = Records() | |
while True: | |
command = input('\nWhat do you want to do (add / view / delete / view categories / find / exit)? ') | |
if command == 'add': | |
entry = input('Add some expense or income records with category, description, and amount (separate by spaces):\n') | |
records.add(entry, categories) | |
elif command == 'view': | |
records.view() | |
elif command == 'delete': | |
delete_record = input("Which record number do you want to delete? ") | |
records.delete(delete_record) | |
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() | |
print("Changes saved. Exiting.") | |
break | |
else: | |
sys.stderr.write('Invalid command. Try again.\n') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment