You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
3.1 KiB
Python

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]