NEW QUESTION:
Hi, I submitted my Budget.py app on Replit and I have 2 errors I just can’t seem to solve. Can you help, please?
My output seems to be spot on, except, when the test module runs the 2nd (hidden) test, the test module manages to add an errant (.) period just before the spend_chart. Why?
Here’s the error descriptions (there are 2):
973.96
Food
initial deposit 1000.00
groceries -10.15
restaurant and more foo -15.89
Transfer to Clothing -50.00
Total: 923.96
Clothing
Transfer from Food 50.00
-25.55
Total: 24.45
Percentage spent by category
100|
90|
80|
70|
60| o
50| o
40| o
30| o
20| o o
10| o o o
0| o o o
----------
F C A
o l u
o o t
d t o
h
i
n
g
None
.Percentage spent by category
100|
90|
80|
70| o
60| o
50| o
40| o
30| o
20| o o
10| o o
0| o o o
----------
B F E
u o n
s o t
i d e
n r
e t
s a
s i
n
m
e
n
t
F…F…
FAIL: test_create_spend_chart (test_module.UnitTests)
Traceback (most recent call last):
File “/home/runner/boilerplate-budget-app-1/test_module.py”, line 102, in test_create_spend_chart
self.assertEqual(actual, expected, ‘Expected different chart representation. Check that all spacing is exact.’)
AssertionError: None != 'Percentage spent by category\n100| [384 chars] t ’ : Expected different chart representation. Check that all spacing is exact.
======================================================================
FAIL: test_to_string (test_module.UnitTests)
Traceback (most recent call last):
File “/home/runner/boilerplate-budget-app-1/test_module.py”, line 91, in test_to_string
self.assertEqual(actual, expected, ‘Expected different string representation of object.’)
AssertionError: ‘[92 chars]Transfer to Entertainme -20.00\nTotal: 834.33 ’ != '[92 chars]Transfer to Entertainme -20.00\nTotal: 834.33’
Food
deposit 900.00
milk, cereal, eggs, bac -45.67
Transfer to Entertainme -20.00
- Total: 834.33 + Total: 834.33 : Expected different string representation of object.
Ran 11 tests in 0.009s
FAILED (failures=2)
KeyboardInterrupt
And here’s the code I submitted:
# Budget App
class Category:
def __init__(self, name):
self.name = name
self.balance = 0
self.ledger = []
def __str__(self):
s = f"{self.name:*^30}\n"
# Here’s the grammar of a format specifier: [[fill]align][sign][#][0][width][grouping_option][.precision][type]
for n in self.ledger:
descriptions = (n['description'])[0:23] # each character of the string up until the 23rd.
amounts = str(n['amount']) # entire amount as a string.
d = (f"{descriptions: <23}")
a = (f"{float(amounts): >#7.2f}\n")
s += d
s += (a)[0:7] + "\n"
s += (f"Total: {self.balance:<#23.2f}\n")[0:30]
#s += "\n"
return s
# DEFINE METHODS = FUNCTIONS (with self-contained variables)
def get_balance(self):
return self.balance
def check_funds(self, amount): # per category
self.amount = amount
if self.amount <= self.balance:
return True
else:
return False
def deposit(self, amount, description=""):
self.balance += amount
self.ledger.append({"amount": amount, "description": description}) # can take ONE argument
return True
def withdraw(self, amount, description=""):
if self.check_funds(amount):
self.balance -= amount
self.ledger.append({"amount": -abs(amount), "description": description})
return True
else:
amount = 0
return False
def transfer(self, amount, instance):
if self.check_funds(amount):
description_transfer = f"Transfer ${amount} from {self.name} to {instance.name}."
self.withdraw(amount, f"Transfer to {instance.name}")
instance.deposit(amount, f"Transfer from {self.name}")
return True
else:
return False
def print_ledger(self):
print(self.__str__())
def get_withdrawls(self):
global cat_total
cat_total = 0
for item in self.ledger[0:]:
if int(item['amount']) < 0:
cat_total += item['amount']
return cat_total
# -------------------OUTSIDE OF CLASS------------------- #
def get_totals(names):
total = 0
totals = []
for each in names:
total += Category.get_withdrawls(self=each)
totals.append(Category.get_withdrawls(self=each))
rounded = list(map(lambda x: math_reduce(x / total), totals)) # x is each in totals list, x/grand total for each.
return rounded
def math_reduce(n):
multiplier = 10
return int(n * multiplier) / multiplier
# ***********************************^^^WORKS^^^*********************************** #
def create_spend_chart(categories):
p = "Percentage spent by category\n"
percentages = []
names_list = []
nums_list = []
padded = []
for cat in categories: # use.method
names_list.append(cat.name)
nums_list.append(cat.get_withdrawls())
height = (len(max(names_list, key=len)))
padded = [name.ljust(height) for name in names_list]
percentages.append(get_totals(categories))
# PERCENTAGES FOR CHART
percentages_big = []
for i in percentages[0]:
multiplied = i * 100
percentages_big.append(multiplied)
# THE CHART
for n in range(100, -1, -10):
p += f"{n:>3}" + "| "
for percent in percentages_big:
if percent >= n:
p += "o "
else:
p += " "
p += "\n"
p += f"{' ' + '-' + (('-' * 3) * len(categories))}\n"
for name in zip(*padded):
p += (' ' + (' '.join(name))) + ' \n'
print(p)