Could somebody please say what is wrong with my code? I cant pass the last test which is about creating spend chart. Withdrawal percentages calculated correctly, and all spacings seem to be in place. What is wrong here?
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
else:
return False
def get_balance(self):
balance = 0
for transaction in self.ledger:
balance += transaction['amount']
return balance
def check_funds(self, amount):
return amount <= self.get_balance()
def transfer(self, amount, destination_category):
if self.check_funds(amount):
self.withdraw(amount, f"Transfer to {destination_category.name}")
destination_category.deposit(amount, f"Transfer from {self.name}")
return True
else:
return False
def __str__(self):
# Customize the string representation to include more details
lines = [center_title(self.name)]
for transaction in self.ledger:
description = transaction['description'][:23]
amount = '{:.2f}'.format(transaction['amount'])
lines.append(f"{description.ljust(23)}{amount.rjust(7)}")
lines.append(f"Total: {self.get_balance()}")
return '\n'.join(lines)
def center_title(title, line_width=30):
title_length = len(title)
left_padding = (line_width - title_length) // 2
right_padding = line_width - title_length - left_padding
return '*' * left_padding + title + '*' * right_padding
def create_spend_chart(categories):
category_withdrawals = {}
# Calculate withdrawals for each category
for category in categories:
withdrawals = 0
for transaction in category.ledger:
amount = transaction['amount']
if amount < 0:
withdrawals += -amount # Add the amount spent (negative for withdrawals)
category_withdrawals[category.name] = withdrawals
# Calculate total withdrawals across all categories
total_withdrawals = sum(category_withdrawals.values())
# Calculate percentages spent for each category based on withdrawals
category_percentages = {}
for name, withdrawals in category_withdrawals.items():
category_percentages[name] = (withdrawals / total_withdrawals) * 100 if total_withdrawals > 0 else 0
# Generate the chart body
chart_str = "Percentage spent by category\n"
for i in range(100, -1, -10):
line = f"{i:3}| "
for name in category_percentages:
percent = category_percentages[name]
if percent >= i:
line += "o "
else:
line += " "
chart_str += line + "\n"
# Print the horizontal line at the bottom of the chart
chart_str += " " + "-" * (len(category_percentages) * 3 + 1) + "\n"
# Print category names vertically
max_name_length = max(len(name) for name in category_percentages)
for i in range(max_name_length):
line = " "
for name in category_percentages:
if i < len(name):
line += name[i] + " "
else:
line += " "
chart_str += line + "\n"
return chart_str
food = Category("Food")
food.deposit(1000, "deposit")
food.withdraw(500.00, "groceries")
clothing = Category("Clothing")
clothing.deposit(1000, "deposit")
clothing.withdraw(100.00, "buying new clothes")
auto = Category("Auto")
auto.deposit(1000, "deposit")
auto.withdraw(200.00, "fuel")
food.transfer(200, clothing)
categories = [food, clothing, auto]
chart_str = create_spend_chart(categories)
print(clothing)
print(chart_str)
I can’t figure out where to remove \n? If I remove in one of the functions, everything falls apart. Do I need to create an if statement with the condition adding \n everywhere but if it is the last line then don’t add \n?
I am having a similar issue. My output seems to be fine but I failed the last test. The only sense I could make from the assertion error was that the expected characters (297) are less than mine (299). I am definitely missing something which I need help to spot.
my code:
class Category:
def __init__(self, category):
self.category = category
self.ledger = []
self.balance = 0
def display_category(self):
display = ""
display += f"{self.category.center(30, '*')}\n"
for expense in self.ledger:
display += expense["description"][:23].ljust(23) + str("%.2f" % expense["amount"])[:7].rjust(7)
display += "\n"
display += f"Total: " + str(self.balance)
return display
def __str__(self):
return self.display_category()
def check_funds(self, amount):
if amount > self.balance:
return False
else:
return True
def deposit(self, amount, description = ""):
self.balance += amount
self.ledger.append(
{
"amount" : amount,
"description" : description
}
)
def withdraw(self, amount, description = ""):
if self.check_funds(amount):
self.ledger.append(
{
"amount" : amount * -1,
"description" : description
}
)
self.balance -=amount
return True
else:
return False
def transfer(self, amount, cate):
if self.check_funds(amount):
self.withdraw(amount, f"Transfer to {cate.category}")
cate.deposit(amount, f"Transfer from {self.category}")
return True
else: return False
def get_balance(self):
return self.balance
def create_spend_chart(categories):
chart = ""
def get_percentage_spent(category):
total_amount_spent = 0
total_deposit = 0
for i in range(len(category.ledger)):
if category.ledger[i]["amount"] < 0:
total_amount_spent += category.ledger[i]["amount"]
else:
total_deposit += category.ledger[i]["amount"]
percentage_spent = int(round((abs(total_amount_spent) * 100) / total_deposit, -1))
return percentage_spent
def print_bar(dictionary, percentage):
line = ""
for item in dictionary:
if percentage > dictionary[item]:
line += " "
elif percentage <= dictionary[item]:
line += "o "
return line
percentage_spent = {
cat.category: get_percentage_spent(cat) for cat in categories
}
chart += "Percentage spent by category\n"
for percentage in range(100, -10, -10):
chart += (str(percentage) + "|").rjust(4) + " " + print_bar(percentage_spent, percentage) + "\n"
dash_length = (len(categories) * 3) + 1
dashes = " "
for _ in range(dash_length):
dashes += "-"
chart += dashes + "\n"
index = 0
cat = [len(item.category) for item in categories]
while index < max(cat):
line = " "
for item in categories:
if item.category[-1] == item.category[0] and len(item.category) == 1:
if item.category == "_":
line += " "
else:
line += item.category[index]
item = "_"
else:
try:
line += item.category[index] + " "
except IndexError:
line += " "
index += 1
chart += line + "\n"
#print(percentage_spent)
return chart
categories = []
food = Category("Food")
clothing = Category("Clothing")
home = Category("Hommie")
edu = Category("Educationiskey")
food.deposit(1000, "deposit")
food.withdraw(10.15, "groceries")
food.withdraw(15.89, "restaurant and more food for dessert")
food.transfer(50, clothing)
food.transfer(150, home)
home.deposit(200, "deposit")
home.withdraw(20, "furniture")
home.withdraw(30, "kitchenware")
home.transfer(40, edu)
edu.deposit(300, "initial deposit")
edu.withdraw(150, "books")
edu.withdraw(20, "sch uniform")
edu.transfer(20, clothing)
clothing.withdraw(15, "shoes")
categories.append(food)
categories.append(clothing)
categories.append(home)
categories.append(edu)
print(food)
print(create_spend_chart(categories))
If you have a question about a specific challenge as it relates to your written code for that challenge and need some help, click the Ask for Help button located on the challenge (it looks like a question mark). This button only appears if you have tried to submit an answer at least three times.
The Ask for Help button will create a new topic with all code you have written and include a link to the challenge also. You will still be able to ask any questions in the post before submitting it to the forum.