Build a Budget App - Build a Budget App

Tell us what’s happening:

My code seems to be producing the exact expected output as shown. When I run the tests however, 8/24 have failed.

I can’t understand where the problem in the code is.

Your code so far

class Category:
    def __init__(self, name):
        self.name = name
        self.ledger = []
        self.balance = 0

    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.balance -= amount
            self.ledger.append({'amount': -amount, 'description': description})
            return True
        return False

    def get_balance(self):
        return self.balance

    def transfer(self, amount, category):
        if self.check_funds(amount):
            self.balance -= amount
            self.ledger.append({'amount': -amount, 'description': f'Transfer to {category.name}'})
            category.deposit(amount, f'Transfer from {self.name}')
            return True
        return False

    def check_funds(self, amount):
        if amount <= self.balance:
            return True
        return False

    def __str__(self):
        category_repr = ''
        number_of_stars = 30 - len(self.name)
        if(number_of_stars%2 == 1):
            left_stars = '*' * (number_of_stars // 2)
            right_stars = '*' * (number_of_stars // 2 + 1)
            title = left_stars + self.name + right_stars + '\n'
        else:
            left_stars = '*' * (number_of_stars // 2)
            right_stars = '*' * (number_of_stars // 2)
            title = left_stars + self.name + right_stars + '\n'

        category_repr += 'initial deposit        ' + str('{:.2f}'.format(self.ledger[0]['amount'])) + '\n'
        for item in self.ledger[1:]:
            if len(item['description']) >= 23:
                description_column = item['description'][0:23]
            else:
                description_column = item['description'] + (' '*(23-len(item['description'])))
            if len(str(item['amount'])) >= 7:
                price_column = str('{:.2f}'.format(item['amount']))
            else:
                price_column = ' '*(7-len(str('{:.2f}'.format(item['amount'])))) + str('{:.2f}'.format(item['amount']))
            category_repr += description_column + price_column + '\n'
        return title + category_repr + f'Total: {"{:.2f}".format(self.balance)}\n'

def create_spend_chart(categories):
    print("Percentage spent by category")
    scale_strings = ['  '+str(num)+'| ' if num==0 else ' '+str(num)+'| ' if num>0 and num<100 else str(num)+'| ' for num in range(0,110,10)]
    scale_strings.reverse()
    category_names = [category.name for category in categories]
    category_names_lengths = [len(category_name) for category_name in category_names]
    max_category_name_length = max(category_names_lengths)
    category_names_lists = [list(category_name+(' '*(max_category_name_length - len(category_name)))) for category_name in category_names]

    deductions_per_category = [[item['amount'] for item in category.ledger if item['amount'] < 0] for category in categories]
    total_expense_per_category = [-round(sum(sublist)) for sublist in deductions_per_category]
    total_expense_all_categories = sum(total_expense_per_category)

    percentages_per_category = [int(round((num/total_expense_all_categories)*100, -1))//10 for num in total_expense_per_category]
    
    nested_os = []
    
    for num in percentages_per_category:
            nested_os.append([char+'  'for char in' '*(11-num) + '0'*num])
    
    nested_os.insert(0, scale_strings)

    final = ''

    for i in range(11):
        for j in range(len(categories)+1):
            final += f'{nested_os[j][i]}'
        final += '\n'

    final += f'    -{"---"*len(categories)}\n'


    for i in range(max_category_name_length):
        final += '     '
        for j in range(len(categories)):
            final += f'{category_names_lists[j][i]}  '
        final += '\n'
    return final

food = Category('Food')
food.deposit(1000, 'deposit')
food.withdraw(100.15, 'groceries')
food.withdraw(159.89, 'restaurant and more food for dessert')

clothing = Category('Clothing')
clothing.deposit(1000, 'deposit')

clothing.withdraw(245.23, 'new hand bag')
clothing.withdraw(222.19, 'sport shoes')

auto = Category('Auto')
auto.deposit(1000, 'deposit')

auto.withdraw(128.99, 'rear mirror')
auto.withdraw(98.32, 'car wash')

stationary = Category('Stationary')
stationary.deposit(1000, 'deposit')
stationary.withdraw(233.22, 'pens and paper')
stationary.withdraw(178.58, 'books and colors')

print(food)
print(clothing)
print(auto)
print(stationary)
print(create_spend_chart((food, clothing, auto ,stationary)))

print(create_spend_chart((food, clothing)))

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36

Challenge Information:

Build a Budget App - Build a Budget App

Did you open your browser’s console to check the assertion errors there?

1 Like

I did. Below is the screenshot of my output and the browser console:

And these are the string representations of the objects:

those AssertionErro in the console, and the diffs, are useful.

Click here to learn how to read the diff

The assertion error and diff gives you a lot of information to track down a problem. For example:

AssertionError: 'Year' != 'Years'
- Year
+ Years
?     +

Your output comes first, and the output that the test expects is second.

AssertionError: ‘Year’ != ‘Years’

Your output: Year does not equal what’s expected: Years

This is called a diff, and it shows you the differences between two files or blocks of code:

- Year
+ Years
?     +

- Dash indicates the incorrect output
+ Plus shows what it should be
? The Question mark line indicates the place of the character that’s different between the two lines. Here a + is placed under the missing s .

Here’s another example:

E       AssertionError: Expected different output when calling "arithmetic_arranger()" with ["3801 - 2", "123 + 49"]
E       assert '  3801      123    \n   - 2     + 49    \n------    -----    \n' == '  3801      123\n-    2    +  49\n------    -----'
E         -   3801      123
E         +   3801      123    
E         ?                ++++
E         - -    2    +  49
E         +    - 2     + 49    
E         - ------    -----
E         + ------    -----    
E         ?                +++++

The first line is long, and it helps to view it as 2 lines in fixed width characters, so you can compare it character by character:

'  3801      123    \n   - 2     + 49    \n------    -----    \n'
'  3801      123\n-    2    +  49\n------    -----'

Again, your output is first and the expected output is second. Here it’s easy to see extra spaces or \n characters.

E         -   3801      123
E         +   3801      123    
E         ?                ++++

Here the ? line indicates 4 extra spaces at the end of a line using four + symbols. Spaces are a little difficult to see this way, so it’s useful to use both formats together.

I hope this helps interpret your error!

There is this for the printing of Categories:

AssertionError: '****[23 chars]***\ninitial deposit        900.00\nmilk, cere[65 chars]33\n' != '****[23 chars]***\ndeposit                 900.00\nmilk, cer[64 chars]4.33'

Why is initial deposit appearing there? Are you asked to do that?

And then there is this

AssertionError: '100|          \n 90|          \n 80|     [355 chars]  \n'
             != 'Percentage spent by category\n100|       [383 chars] t  '

the first line is your code, the second is the expected. Aren’t you missing something? Then there is a difference at the end.

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.