Build a Budget App - Build a Budget App

Tell us what’s happening:

All tests relating to the bar chart are failing - code all seems to work as intended so not sure what I’m missing. Have checked spacings and F12 doesn’t seem to shed any light. Works with 1-4 categories, pls help

Your code so far

```
categ = {}
categories = []

class Category:
    def __init__(self, name):
        self.name = name
        self.ledger = []
        self.balance = 0
        self.account_string = ""
        self.total_withdrawals = 0
        self.withdrawal_statement = []
        self.iterable_name = list(self.name.capitalize())
    
    def deposit(self, amount, description=""):
        amount_chars = len(str(amount))
        desc_chars = len(description)
        total_chars = desc_chars + amount_chars
        string_chars = 30 - total_chars
        self.ledger.append({'amount': amount, 'description': description}) 
        self.balance += amount
        self.account_string += f'{description[0:23]:<23}{amount:>7.2f}\n'

    def withdraw(self, amount, description=""):
        amount_chars = len(str(amount))
        desc_chars = len(description)
        total_chars = desc_chars + amount_chars
        string_chars = 30 - total_chars
        if amount <= self.balance:
            self.ledger.append({'amount': -abs(amount), 'description': description})
            self.balance += -abs(amount)
            self.account_string += f'{description[0:23]:<23}{-abs(amount):>7.2f}\n'
            self.total_withdrawals += amount
            if self.name not in categ:    
                categ[self.name.capitalize()] = self
            elif self.name in categ:
                pass
            if self.name.capitalize() not in categories:
                categories.append(self.name.capitalize())
            elif list(self.name.capitalize())  in categories or len(categories) == 4:
                pass
            return True
        else:
            return False
            
    def get_balance(self):
        return self.balance

    def transfer(self, amount, account):
        self.withdraw(amount, f'Transfer to {account.name}')
        account.ledger.append({'amount': amount, 'description': f'Transfer from {self.name}'})
        account.balance += amount
        if amount <= self.balance:
            return True
        else:
            return False

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

    def __str__(self):
        stars = "*" * int(15 - (len(self.name) * 0.5))
        return(f'{stars}{self.name}{stars}\n{self.account_string}Total: {self.balance}')

food = Category('Food')
clothing = Category('Clothing')
clothing.deposit(1000, 'deposit')
food.deposit(1000, 'deposit')
food.withdraw(10.15, 'groceries')
food.withdraw(15.89, 'restaurant and more food for dessert')
food.transfer(50, clothing)

clothing.withdraw(50, 'wedding suit')

auto = Category('Auto')
auto.deposit(1000, 'loan refund')
auto.withdraw(150, 'mechanic')

# school = Category('School')
# school.deposit(10000, 'tuition funds')
# school.withdraw(50, 'tuition')


def create_spend_chart(categories):
    def round_down10(number):
        diff = number % 10
        new_num = number - diff
        return new_num

# total withdrawals sum
    total_withdrawals = 0
    for i in categ.values():
        total_withdrawals += i.total_withdrawals

    chart = ''

# bar chart
    chart += 'Percentage spent by category'
    chart += '\n'
    for i in range(100, -1, -10):
        chart += (f'{i:>3}| ')
        for cat in categ:
            perc = categ[cat].total_withdrawals / total_withdrawals * 100
            bar_height = round_down10(perc)
            if bar_height >= i:
                chart += f'o  '
            else:
                chart += '   '
        chart += '\n'
    chart_width = len(categ) * 3
    one_sep = '-'
    separator = one_sep * chart_width + one_sep
    separator = f'    {separator:>{chart_width}}'
    chart += separator
    chart += '\n'
    max_length = (len(max(categories, key=len)))
    for i in range(max_length):
        row = '     '
        for name in categories:
            if i < len(name):
                row += name[i] + '  '
            else:
                row += '   '
        row += '\n'
        chart += row
    print(chart.rstrip('\n'))
    return(chart.rstrip('\n'))

create_spend_chart(categories)
```

Your browser information:

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

Challenge Information:

Build a Budget App - Build a Budget App

Hey there,

Please update the message to include your code. The code was too long to be automatically inserted by the help button.

When you enter a code, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

sorry about that - done so now

You have several tests that are failing at the same line of code. In the browser’s console, I see:

thank you for replying - I’ve now amended the code so that it’s as follows:

def create_spend_chart(categories):
    def round_down10(number):
        diff = number % 10
        new_num = number - diff
        return new_num

# total withdrawals sum
    total_withdrawals = 0
    for i in categ.values():
        total_withdrawals += i.total_withdrawals

    chart = ''

# bar chart
    chart += 'Percentage spent by category'
    chart += '\n'
    for i in range(100, -1, -10):
        chart += (f'{i:>3}| ')
        for cat in categ:
            perc = categ[cat].total_withdrawals / total_withdrawals * 100
            bar_height = round_down10(perc)
            if bar_height >= i:
                chart += f'o  '
            else:
                chart += '   '
        chart += '\n'
    chart_width = len(categ) * 3
    one_sep = '-'
    separator = one_sep * chart_width + one_sep
    separator = f'    {separator:>{chart_width}}'
    chart += separator
    chart += '\n'
    max_length = 0
    for c in categories:
        if len(c) > max_length:
            max_length = (len(c))
    for i in range(max_length):
        row = '     '
        for name in categories:
            if i < len(name):
                row += name[i] + '  '
            else:
                row += '   '
        row += '\n'
        chart += row
    print(chart.rstrip('\n'))
    return(chart.rstrip('\n'))

create_spend_chart(categories)

I’m getting a similar error for ‘if len(c) > max_length:’ when F12ing, even though i’m iterating through a list of strings, and the category names are capitalised so they shouldn’t be trying to call the objects as far as I’m aware?

Test your code with the example for setting up categories.

You have a syntax error that needs to be resolved first.

food = Category('Food')
food.deposit(1000, 'deposit')
food.withdraw(10.15, 'groceries')
food.withdraw(15.89, 'restaurant and more food for dessert')
clothing = Category('Clothing')
food.transfer(50, clothing)
print(food)
Traceback (most recent call last):
  File "main.py", line 49, in <module>
NameError: name 'Category' is not defined

EDIT: Sorry just saw that was not your complete code. I’ll have another look

1 Like

Please do not use global variables. Your create_spend_chart function takes a categories parameter, but you are using both categ and categories inside the function.

2 Likes

thank you! got muddled up with arguments used in create_spend_chart(), but removed global variables and restructured code and it passed