-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathbudget.py
82 lines (69 loc) · 2.92 KB
/
budget.py
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
class Category:
def __init__(self, description):
self.description = description
self.ledger = []
self.__balance = 0.0
def __repr__(self):
header = self.description.center(30, "*") + "\n"
ledger = ""
for item in self.ledger:
# format description and amount
line_description = "{:<23}".format(item["description"])
line_amount = "{:>7.2f}".format(item["amount"])
# Truncate ledger description and amount to 23 and 7 characters respectively
ledger += "{}{}\n".format(line_description[:23], line_amount[:7])
total = "Total: {:.2f}".format(self.__balance)
return header + ledger + total
def deposit(self, amount, description=""):
self.ledger.append({"amount": amount, "description": description})
self.__balance += amount
def withdraw(self, amount, description=""):
if self.__balance - amount >= 0:
self.ledger.append({"amount": -1 * amount, "description": description})
self.__balance -= amount
return True
else:
return False
def get_balance(self):
return self.__balance
def transfer(self, amount, category_instance):
if self.withdraw(amount, "Transfer to {}".format(category_instance.description)):
category_instance.deposit(amount, "Transfer from {}".format(self.description))
return True
else:
return False
def check_funds(self, amount):
if self.__balance >= amount:
return True
else:
return False
def create_spend_chart(categories):
spent_amounts = []
# Get total spent in each category
for category in categories:
spent = 0
for item in category.ledger:
if item["amount"] < 0:
spent += abs(item["amount"])
spent_amounts.append(round(spent, 2))
# Calculate percentage rounded down to the nearest 10
total = round(sum(spent_amounts), 2)
spent_percentage = list(map(lambda amount: int((((amount / total) * 10) // 1) * 10), spent_amounts))
# Create the bar chart substrings
header = "Percentage spent by category\n"
chart = ""
for value in reversed(range(0, 101, 10)):
chart += str(value).rjust(3) + '|'
for percent in spent_percentage:
if percent >= value:
chart += " o "
else:
chart += " "
chart += " \n"
footer = " " + "-" * ((3 * len(categories)) + 1) + "\n"
descriptions = list(map(lambda category: category.description, categories))
max_length = max(map(lambda description: len(description), descriptions))
descriptions = list(map(lambda description: description.ljust(max_length), descriptions))
for x in zip(*descriptions):
footer += " " + "".join(map(lambda s: s.center(3), x)) + " \n"
return (header + chart + footer).rstrip("\n")