Build a Budget App - error in test 17

Tell us what’s happening:

I am seeing this error message at step 17:
Title at the top of create_spend_chart chart should say Percentage spent by category.

I have tried running this code in my laptop, and even inspected the error messages shown in the browser’s console window. I can see that the line “Percentage spent by category” is being displayed at the top of the chart

Your code so far

from itertools import zip_longest


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):
        return sum([entry["amount"] for entry in self.ledger])

    def transfer(self, amount, category):
        if self.check_funds(amount):
            self.withdraw(amount, f"Transfer to {category.name}")
            category.deposit(amount, f"Transfer from {self.name}")
            return True
        else:
            return False

    def check_funds(self, amount):
        if amount > self.get_balance():
            return False
        else:
            return True

    def __str__(self):
        display_string = self.name.center(30, "*") + "\n"
        for entry in self.ledger:
            amount_str = f"{entry['amount']:.2f}"[:7]
            display_string += f"{entry['description'][:23]:23}{' ' * (7 - len(amount_str))}{amount_str}\n"
        display_string += f"Total: {self.get_balance():.2f}"
        return display_string


def create_spend_chart(categories: list[Category]):
    expense_per_category = {}
    total_expenses = 0

    for category in categories:
        expense_per_category[category.name] = -sum([entry["amount"] for entry in category.ledger if entry["amount"] < 0])
        total_expenses += expense_per_category[category.name]

    horizontal_line = "    -"
    for category_expense in expense_per_category:
        expense_per_category[category_expense] = int(round((expense_per_category[category_expense] / total_expenses) * 100, -1))
        horizontal_line += "---"

    print("Percentage spent by category")
    for percentage in range(100, -1, -10):
        single_graph_line = f"{percentage:>3}| "
        for category_expense in expense_per_category:
            single_graph_line += "   " if expense_per_category[category_expense] < percentage else "o  "
        print(single_graph_line)
    print(horizontal_line)

    single_line = ""
    category_names = [category.name for category in categories]
    for letters in zip_longest(*category_names, fillvalue=" "):
        single_line += "     " + "  ".join(letters) + "\n"
    single_line.rstrip()
    print(single_line, end="")

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36

Challenge Information:

Build a Budget App - Build a Budget App

GitHub Link: freeCodeCamp/curriculum/challenges/english/blocks/lab-budget-app/5e44413e903586ffb414c94e.md at main · freeCodeCamp/freeCodeCamp · GitHub

I have changed the create_spend_chart() function to return the chart display string, but I am still seeing the same error message

The updated code for the function:

def create_spend_chart(categories: list[Category]):
    expense_per_category = {}
    total_expenses = 0

    for category in categories:
        expense_per_category[category.name] = -sum([entry["amount"] for entry in category.ledger if entry["amount"] < 0])
        total_expenses += expense_per_category[category.name]

    horizontal_line = "    -"
    for category_expense in expense_per_category:
        expense_per_category[category_expense] = int(round((expense_per_category[category_expense] / total_expenses) * 100, -1))
        horizontal_line += "---"

    chart = "Percentage spent by category"
    for percentage in range(100, -1, -10):
        single_graph_line = f"{percentage:>3}| "
        for category_expense in expense_per_category:
            single_graph_line += "   " if expense_per_category[category_expense] < percentage else "o  "
        chart += single_graph_line + "\n"
    chart += horizontal_line + "\n"

    x_axis_titles = ""
    category_names = [category.name for category in categories]
    for letters in zip_longest(*category_names, fillvalue=" "):
        x_axis_titles += "     " + "  ".join(letters) + "\n"
    chart += x_axis_titles.rstrip("\n")

    return chart

I have fixed that issue with step 17. I am now getting an error in tests 23 and 24:

create_spend_chart chart should have each category name written vertically below the bar. Each line should have the same length, each category should be separated by two spaces, with additional two spaces after the final category.

This is the latest code for the create_spend_chart function:

def create_spend_chart(categories: list[Category]):
    expense_per_category = {}
    total_expenses = 0

    for category in categories:
        expense_per_category[category.name] = -sum([entry["amount"] for entry in category.ledger if entry["amount"] < 0])
        total_expenses += expense_per_category[category.name]

    horizontal_line = "    -"
    for category_expense in expense_per_category:
        expense_per_category[category_expense] = math.floor(((expense_per_category[category_expense] / total_expenses) * 100) / 10) * 10
        horizontal_line += "---"

    chart = "Percentage spent by category\n"
    for percentage in range(100, -1, -10):
        single_graph_line = f"{percentage:>3}| "
        for category_expense in expense_per_category:
            single_graph_line += "   " if expense_per_category[category_expense] < percentage else "o  "
        chart += single_graph_line + "\n"
    chart += horizontal_line + "\n"

    x_axis_titles = ""
    category_names = [category.name for category in categories]
    for letters in zip_longest(*category_names, fillvalue=" "):
        x_axis_titles += "     " + "  ".join(letters) + "\n"
    chart += x_axis_titles.rstrip("\n")

    return chart

Welcome to the forum @giri.sarthak1,

I’m seeing this error message in the console:

Traceback (most recent call last):
  File "main.py", line 92, in <module>
  File "main.py", line 55, in create_spend_chart
NameError: name 'math' is not defined

Happy coding

I forgot to add the import statement with the function when I posted my latest reply.
Here is the entire code, with the Category class:

from itertools import zip_longest
import math


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):
        return sum([entry["amount"] for entry in self.ledger])

    def transfer(self, amount, category):
        if self.check_funds(amount):
            self.withdraw(amount, f"Transfer to {category.name}")
            category.deposit(amount, f"Transfer from {self.name}")
            return True
        else:
            return False

    def check_funds(self, amount):
        if amount > self.get_balance():
            return False
        else:
            return True

    def __str__(self):
        display_string = self.name.center(30, "*") + "\n"
        for entry in self.ledger:
            amount_str = f"{entry['amount']:.2f}"[:7]
            display_string += f"{entry['description'][:23]:23}{' ' * (7 - len(amount_str))}{amount_str}\n"
        display_string += f"Total: {self.get_balance():.2f}"
        return display_string


def create_spend_chart(categories: list[Category]):
    expense_per_category = {}
    total_expenses = 0

    for category in categories:
        expense_per_category[category.name] = -sum([entry["amount"] for entry in category.ledger if entry["amount"] < 0])
        total_expenses += expense_per_category[category.name]

    horizontal_line = "    -"
    for category_expense in expense_per_category:
        expense_per_category[category_expense] = math.floor(((expense_per_category[category_expense] / total_expenses) * 100) / 10) * 10
        horizontal_line += "---"

    chart = "Percentage spent by category\n"
    for percentage in range(100, -1, -10):
        single_graph_line = f"{percentage:>3}| "
        for category_expense in expense_per_category:
            single_graph_line += "   " if expense_per_category[category_expense] < percentage else "o  "
        chart += single_graph_line + "\n"
    chart += horizontal_line + "\n"

    x_axis_titles = ""
    category_names = [category.name for category in categories]
    for letters in zip_longest(*category_names, fillvalue=" "):
        x_axis_titles += "     " + "  ".join(letters) + "\n"
    chart += x_axis_titles.rstrip("\n")

    return chart

if __name__ == "__main__":
    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(283.44, clothing)
    clothing.withdraw(59.57, "yellow t-shirt")
    print(food)
    print(clothing)

    print(create_spend_chart([food, clothing]))

Did you check the assertion errors in your browser’s console?

This is the assertion error for test 23:
Expected different category names written vertically below the bar. Check that all spacing is exact.

python-test-evaluator.js:2 AssertionError: '     B  F  E\n     u  o  n\n     s  o  t\n     i  d  [123 chars]   t' != '     B  F  E  \n     u  o  n  \n     s  o  t  \n     [149 chars] t  '
python-test-evaluator.js:2 AssertionError: '     F  E\n     o  n\n     o  t\n     d  e\n      [87 chars]   t' != '     F  E  \n     o  n  \n     o  t  \n     d  e  [113 chars] t  '

This is the assertion error for test 24:
Expected different chart representation. Check that all spacing is exact.

AssertionError: 'Perc[225 chars] F  E\n     u  o  n\n     s  o  t\n     i  d  [123 chars]   t' != 'Perc[225 chars] F  E  \n     u  o  n  \n     s  o  t  \n     [149 chars] t  '

I finally figured out the error. I was missing the two additional spaces after each line in the x axis titles.

My code is working now, and I have successfully passed all the code tests