Tell us what’s happening:
My create_spend_chart(categories) function is failing your tests, and I cannot figure out why. Running the code from the command line is working as you can see in the figure below.
Please help. Thanks.
Your code so far
class Category:
def __init__(self, name):
self.name = 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):
self.ledger.append({'amount' : -amount, 'description': description})
return True
return False
def get_balance(self):
balance = 0
for entry in self.ledger:
# ignore withdrawals that make balance < 0
amount, description = list(entry.keys())
if entry[amount] >= 0 or balance + entry[amount] >= 0:
balance += entry[amount]
return balance
def transfer(self, amount, category):
if self.check_funds(amount):
entry = {'amount' : -amount, 'description': f'Transfer to {category.name}'}
self.ledger.append(entry)
entry = {'amount' : amount, 'description': f'Transfer from {self.name}'}
category.ledger.append(entry)
return self.check_funds(amount)
def check_funds(self, amount):
balance = self.get_balance()
return balance >= amount
def __str__(self):
title_len = 30
title_head_len = (title_len - len(self.name)) // 2
title_tail_len = title_len - title_head_len - len(self.name)
title = f"{'*' * title_head_len}{self.name}{'*' * title_tail_len}"
result = title
for entry in self.ledger:
amount, description = list(entry.keys())
description_str = entry[description][:23]
amount_str = f"{entry[amount]:.2f}"
spaces_str = ' ' * (title_len - len(description_str) - len(amount_str))
entry_str = f"\n{description_str}{spaces_str}{amount_str}"
result += entry_str
result += f"\nTotal: {self.get_balance()}"
return result
def create_spend_chart(categories):
# Sort withdrawals in descending order
withdrawals = []
for entry in categories.ledger:
amount, description = list(entry.keys())
if entry[amount] < 0:
if not len(withdrawals):
withdrawals.append((-entry[amount], entry[description]))
else:
for i in range(len(withdrawals)):
if (-entry[amount] > withdrawals[i][0]):
withdrawals.insert(i, (-entry[amount], entry[description]))
break
else:
withdrawals.append((-entry[amount], entry[description]))
total = 0
for w in withdrawals:
total += w[0]
total = round(total)
chart = []
for w in withdrawals:
chart.append(((round(100 * w[0] / total) // 10) * 10, w[1]))
result = 'Percentage spent by category\n'
line_width = 4 + len(chart) * 3 + 1
chart_lines = []
for p in range(100, -1, -10):
percentage_prefix_str = '' if p == 100 else (' ' if p == 0 else ' ')
line = f"{percentage_prefix_str}{p}|"
first_o = True
for percentage, _ in chart:
if percentage >= p:
if first_o:
line += ' o'
first_o = False
else:
line += ' o'
if len(line) < line_width:
line += f"{' ' * (line_width - len(line))}"
chart_lines.append(line)
for line in chart_lines:
result += f"{line}\n"
horiz_line = f"{' ' * 4}{'-' * (3 * len(chart) + 1)}\n"
result += horiz_line
descriptions = []
descriptions_lines_lens = []
for w in withdrawals:
descriptions.append([c for c in w[1]])
descriptions_lines_lens.append(len(w[1]))
description_suffix = f"{' ' * (line_width - len(horiz_line))}"
description_lines_num = max(*descriptions_lines_lens)
for i in range(description_lines_num):
description_line = f"{' ' * 5}"
for j, d in enumerate(descriptions):
description_prefix = f"{' ' if j > 0 else ''}"
description_line += f"{description_prefix}{d[i] if i < len(d) else ' '}"
result += f"{description_line}{description_suffix} \n"
result = result[:-1]
return result
food = Category('Food')
food.deposit(1000, 'initial deposit')
food.withdraw(10.15, 'groceries')
food.withdraw(15.89, 'restaurant and more food for dessert')
clothing = Category('Clothing')
food.transfer(50, clothing)
print(create_spend_chart(food))
Lesson URL is https://www.freecodecamp.org/learn/python-v9/lab-budget-app/build-a-budget-app
