Build a Budget App - Build a Budget App

Tell us what’s happening:

I’ve reading and searching for serveral hints, but still didn’t passed for a few numbers. Can somebody tell me somthing wrong ?

Your code so far

class Category:
    def __init__(self, category):
        self.category = category
        self.total = 0
        self.ledger = list()

    def __repr__(self):
        header = self.category.center(30, '*')
        print(header)
        for item in self.ledger:
            amount = '%.2f' % item['amount']
            desc = (item['description'][:28 - (len(amount))] + '..') if len(item['description']) > 28 - (len(amount)) else item['description']
            spaces = " " * (30 - (len(desc) + len(amount)))
            txt = f'{desc:<}{spaces}{amount:>}'
            print(txt)
        print("Total: " + '%2f' %self.total)

    def deposit(self, amount, description = ""):
        self.total += amount
        self.ledger.append({'amount' : amount, 'description' : description})
    
    def withdraw(self, amount, description = ""):
        self.total -= amount
        self.ledger.append({'amount' : -amount, 'description' : description})
        return True
            
    def get_balance(self):
        return self.total
    
    def transfer(self, amount, instance):
        if self.check_funds(amount):
            self.total -= amount
            self.ledger.append({'amount' : -amount, 'description' : 'Transfer to ' + instance.category})
        
            instance.total += amount
            instance.ledger.append({'amount' : amount, 'description' : 'Transfer from ' + self.category})

            return True

        
        else:
            False



    def check_funds(self, amount):
        if amount < self.total:
            return True
        else:
            return False

food = Category("Food")
clothing = Category("Clothing")
food.deposit(100, "Initial deposit")
food.withdraw(10, "super deluxe coffee")
food.withdraw(50, "protein food")
clothing.deposit(60, "Initial deposit")
food.transfer(15, clothing)
clothing.withdraw(80, "all the clothes")


def create_spend_chart(categories):
    names_list = []
    withdraw_list = []
    for category in categories:
        names = category.category
        names_list.append(names)
        height = (len(max(names_list, key=len)))
        padded = [word.ljust(height) for word in names_list]

        w_total = 0
        for item in category.ledger:
            amount = item['amount']
            if amount < 0:
                w_total += amount
        withdraw_list.append(w_total)
    total = int(round(sum(withdraw_list)))
    percentages = []
    for x in withdraw_list:
        per = x * 100 / total
        per = round(per//10)*10
        percentages.append(per)

    chart = "Percentage spent by category\n"
    for x in reversed(range(0, 110, 10)):
        chart += f"{str(x) + '|':>4}"
        for percent in percentages:
            if percent >= x:
                chart += " o "
            else:
                chart += "   "
        chart += ' \n'
    chart += "   "+("-" * ((len(names_list) + 2) * 2)) + '\n'
    for row in zip(*padded):
        chart += ('    '+' '.join(row)) + '  \n'
    return chart.rstrip("\n")
    

Your browser information:

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

Challenge Information:

Build a Budget App - Build a Budget App

Hi @Fidelis_B_Codes,

Here are some debugging steps you can follow. Focus on one test at a time:

  1. Are there any errors or messages in the console?
  2. What is the requirement of the failing test?
  3. Check the related User Story and ensure it’s followed precisely.
  4. What line of code implements this?
  5. What is the result of the code and does it match the requirement? (Write the value of a variable to the console at that point in the code if needed.)

If this does not help you solve the problem, please reply with answers to these questions.

Happy coding!

my code has failed test in : no.13, 14, 15, 16, 21, 23, & 24

But, there’re no error messages at all at the terminal console.

I’m stuck at these 2 numbers, any hints for those ?

After you run the tests, open your browser’s console and look for errors generated by the tests:

image

Another updated code.

import math
class Category:
    def __init__(self, category):
        self.category = category
        self.total = 0
        self.ledger = []

    def __repr__(self):
        header = self.category.center(30, '*')
        print(header)
        for item in self.ledger:
            amount = '%.2f' % item['amount']
            desc = (item['description'][:28 - (len(amount))] + '..') if len(item['description']) > 28 - (len(amount)) else item['description']
            spaces = " " * (30 - (len(desc) + len(amount)))
            txt = f'{desc:<}{spaces}{amount:>}'
            print(txt)
        print("Total: " + '%2f' %self.total)

    def deposit(self, amount, description = ""):
        self.total += amount
        self.ledger.append({'amount' : amount, 'description' : description})
    
    def withdraw(self, amount, description = ""):
        if self.check_funds(amount):
            self.total -= amount
            self.ledger.append({'amount' : -1 * amount, 'description' : description})
            return True
        else:
            return False
        
            
    def get_balance(self):
        return self.total
    
    def transfer(self, amount, instance):
        if self.check_funds(amount):
            self.total -= amount
            self.ledger.append({'amount' : -amount, 'description' : 'Transfer to ' + instance.category})
            instance.total += amount
            instance.ledger.append({'amount' : amount, 'description' : 'Transfer from ' + self.category})
            return True
        
        else:
            return False


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



def create_spend_chart(categories):
    names_list = []
    withdraw_list = []
    for category in categories:
        names = category.category
        names_list.append(names)
        height = (len(max(names_list, key=len)))
        padded = [word.ljust(height) for word in names_list]

        w_total = 0
        for item in category.ledger:
            amount = item['amount']
            if amount < 0:
                w_total += amount
        withdraw_list.append(w_total)
    total = int(round(sum(withdraw_list)))
    percentages = []
    for x in withdraw_list:
        per = x * 100 / total
        per = round(per//10)*10
        percentages.append(per)

    chart = "Percentage spent by category\n"
    for x in reversed(range(0, 110, 10)):
        chart += f"{str(x) + '|':>4}"
        for percent in percentages:
            if percent >= x:
                chart += " o "
            else:
                chart += "   "
        chart += ' \n'
    chart += "    -"+ ("---" * (len(names_list))) + '\n'
    for row in zip(*padded):
        chart += ('     '+'  '.join(row)) + '  \n'
    return chart.rstrip("\n")

food = Category("Food")
clothing = Category('Clothing')
auto = Category('Auto')
food.deposit(900, "deposit")
food.withdraw(45.67, "milk, cereal, eggs, bacon, bread")
clothing.deposit(500, 'deposit')
clothing.withdraw(100, 'suit')
auto.deposit(10000, 'deposit')
auto.withdraw(50, 'maintainance')

categories = [food, clothing, auto]
bar_chart = create_spend_chart(categories)
bar_chart = bar_chart.replace(' ', ' ')
print(bar_chart)

It’s only step 16 left.

How to make a Category instance give a different string representation of the object ? Should I add the def __str__ method ?

Please review this theory lecture:
Classes and Objects - What Are Special Methods and What Are They Used For? | Learn | freeCodeCamp.org

Does your repr method return anything?

You are only calling your create_spend_chart function. To test how the categories print, try testing like this instead;

for cat in categories:
    print(cat)
print(create_spend_chart(categories))

But, where can I put the “for” ?

should the repr printed like this (blue arrow) ?

print(repr(create_spend_chart(categories)))

if it helps you, you can do that, does it give you useful information?

this lab has also additional output in the browser console, you can also take a look there

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!

I’ve changed the __repr__ inside, then no.16 passed. Surprise…

removed by moderator

Congratulations on solving the challenge! You should be proud of your achievement…we are! But we are removing your working solution, so it is not available to others who have not yet done the work to get there. Again, congrats!