from __future__ import annotations class Category: def __init__(self, category_name) -> None: self.name = category_name self.ledger = [] self.balance = 0 def __repr__(self): ledger = self.name.center(30, "*") + "\n" for entry in self.ledger: ledger += entry["description"][:23].ljust(23) ledger += ("%0.2f" % entry["amount"]).rjust(7) + "\n" ledger += "Total: " ledger += "%0.2f"%self.balance return ledger def deposit(self, amount: float, description: str="") -> None: self.ledger.append({"amount": amount, "description": description}) self.balance += amount def check_funds(self, amount: float) -> bool: return amount <= self.balance def withdraw(self, amount: float, description: str="") -> bool: if self.check_funds(amount): self.ledger.append({"amount": -amount, "description": description}) self.balance -= amount return True else: return False def get_balance(self) -> float: return self.balance def transfer(self, amount: float, other: Category) -> bool: if self.check_funds(amount): self.ledger.append({"amount": -amount, "description": f'Transfer to {other.name}'}) self.balance -= amount other.deposit(amount, f"Transfer from {self.name}") return True else: return False def create_spend_chart(categories: list[Category]) -> str: chart = "Percentage spent by category\n" total_spending: float = 0 category_wise_spending: dict[str, float] = {} for category in categories: category_wise_spending[category.name] = 0 for entry in category.ledger: if entry["amount"] < 0 and not entry["description"].startswith("Transfer to "): category_wise_spending[category.name] += entry["amount"] for category in category_wise_spending: total_spending += category_wise_spending[category] category_wise_relative_spending: dict[str, float] = {} for category in category_wise_spending: # in multiple of 10 percent, rounded down to nearest 10 category_wise_relative_spending[category] = int((category_wise_spending[category]/total_spending)*10) bars: list[int] = [] category_names: list[str] = [] for cat_name, bar_height in category_wise_relative_spending.items(): bars.append(bar_height) category_names.append(cat_name) for i in range(10, -1, -1): chart += str(i*10).rjust(3) + "|" part_chart: list[str] = [] for bar in bars: part_chart.append( " " if bar < i else " o") chart += " ".join(part_chart) chart += " \n" chart += " "*4 + "-"*(len(bars)*3+1)+"\n" cat_name_loop = max([len(cat_name) for cat_name in category_names]) for i in range(cat_name_loop): chart += " "*4 part_chart: list[str] = [] for cat_name in category_names: part_chart.append(" "+cat_name[i] if len(cat_name) > i else " ") chart += " ".join(part_chart) chart += " \n" return chart[:-1]