Tell us what’s happening:
I don’t understand what is wrong with my output. Everything looks exactly the same, maybe it’s some trailing whitespace?
This is the FAIL output
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
.F.........
======================================================================
FAIL: test_create_spend_chart (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/runner/boilerplate-budget-app/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: 'Perc[364 chars] m \n e \n n \n t \n' != 'Perc[364 chars] m \n e \n n \n t '
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
? -
+ t : Expected different chart representation. Check that all spacing is exact.
----------------------------------------------------------------------
Ran 11 tests in 0.002s
FAILED (failures=1)
This is my code:
class Category:
def __init__(self, category_name):
self.category = category_name
self.ledger = []
def deposit(self, amount, description=""):
self.ledger.append({"amount": amount, "description": description})
def withdraw(self, amount, description=""):
if self.check_funds(amount) == True:
self.ledger.append({"amount": -amount, "description": description})
return True
else:
return False
def get_balance(self):
balance = 0
for box_values in self.ledger:
balance += box_values['amount']
return balance
def transfer(self, amount, amount_to_object):
if self.check_funds(amount) == True:
self.withdraw(amount, f"Transfer to {amount_to_object.category}")
amount_to_object.ledger.append({"amount": amount, "description": f"Transfer from {self.category}"})
return True
else:
return False
def check_funds(self, amount): #if/el could be replaced with: return self.get.balance()-amount < 0
if self.get_balance() -amount < 0: #eller return self.get_balance() >= amount //True om balance är större eller lika som amount!
return False
else:
return True
def __str__(self):
output = self.category.center(30, '*') + '\n'
for item in self.ledger:
desc = item['description'][:23]
amt = "{:.2f}".format(item['amount']).rjust(30 - len(desc))
output += desc + amt + '\n'
output += "Total: {:.2f}".format(self.get_balance())
return output
def create_spend_chart(list_of_category_objects):
list_of_total_withdraw_per_category = []
for the_number_of_instances in list_of_category_objects: #For the amount objects in list
total_category_expenditure = 0
for one_line_dicts in the_number_of_instances.ledger: #For the length of the ledger in the object
if one_line_dicts['amount'] < 0:
total_category_expenditure += -one_line_dicts['amount'] #it's a negative amount so - before it will make - - = +
#Saved as a list of dictionaries of
list_of_total_withdraw_per_category.append({"category": the_number_of_instances.category, "total" : total_category_expenditure})
grand_total = sum(d["total"] for d in list_of_total_withdraw_per_category) #d is a box, can be called anything, iterates over each (d)ictionary
#*** Look below to find a shorter more python-esque way of writing this code
#add a new key value pair to each dictionary in the list, percentage of total spending/withdraws
for the_number_of_dictionaries in list_of_total_withdraw_per_category:
pct_of_total = (the_number_of_dictionaries['total'] / grand_total) * 100
the_number_of_dictionaries['pct_of_total'] = pct_of_total
#Now for the printing!
output = "Percentage spent by category\n"
to_zero = 100 # Assuming to_zero starts at 100
max_padding = len(str(to_zero))
while to_zero >= 0:
current_padding = max_padding -len(str(to_zero))
output += " " * current_padding + f"{to_zero}| " # Print the current value of to_zero followed by a vertical bar
for x in range(len(list_of_total_withdraw_per_category)): # Iterate over the indices of the categories list
if list_of_total_withdraw_per_category[x]['pct_of_total'] >= to_zero:
output += "o " # Print 'o' with spaces, without a newline
else:
output += " " # Print spaces only, without a newline
output += "\n" # Print a newline character after the inner loop completes
to_zero -= 10 # Decrement to_zero by 10
#now print the "------" line
output += " -" #The start of it
for x in range(len(list_of_total_withdraw_per_category)):
output += "---" #The length based on the list length
output += "\n"
#Now we find which category name is the longest
longest_length = 0
for dictionaries in list_of_total_withdraw_per_category:
string_value = dictionaries['category']
longest_length = max(longest_length, len(string_value))
#and print!
for y in range(longest_length):
output += " "
for x in range(len(list_of_total_withdraw_per_category)):
try:
char = list_of_total_withdraw_per_category[x]['category'][y]
except IndexError:
char = " "
output += f"{char} "
output += "\n"
return output
#***Så här kan man också lösa det, föredras, faktiskt. Men skillz osv.
#def create_spend_chart(categories):
# totals_per_category = [
# {
# "category": category.category,
# "total": sum(-item['amount'] for item in category.ledger if item['amount'] < 0)
# }
# for category in categories
# ]
# grand_total = sum(d["total"] for d in totals_per_category)
Your browser information:
User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
Challenge Information:
Scientific Computing with Python Projects - Budget App