Build a Budget App Project

Hi I’ve completed this test few days ago but I had trouble signing in to the forum.

One fail I’m getting to pass the test is the last term, “create_spend_chart” should print a different chart representation. Check that all spacing is exact.

I’ve tested both print() and repr() to check the spacing, but I cannot find what’s failing me to pass. They both look fine to me even after I calculated the number of spaces and unnecessary spaces.

Below is my code.

class Category:
    def __init__(self, name):
        self.ledger = []
        self.balance = 0
        self.name = name
        self.percent = 0
        self.spending = 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) == True:
            self.balance -= amount
            self.spending += amount
            self.ledger.append({"amount" : -amount, "description" : description})
            return True
        return False

                
    def get_balance(self):
        return self.balance
    
    def transfer(self, amount, dest):
        if self.check_funds(amount) == True:
            self.withdraw(amount, f'Transfer to {dest.name}')
            self.spending -= amount
            dest.deposit(amount, f'Transfer from {self.name}')
            return True
        return False

    def check_funds(self, amount):
        return self.balance >= amount
    
    def __str__(self):
        title = ''
        title += self.name.center(30, '*')
        res = ''
        res += title + '\n'
        total = 0
        for i in self.ledger:
            d = i["description"][:23]
            if not 'deposit' in res:
                if 'Transfer' in i["description"]:
                    d = i["description"]
            a = f'{i["amount"]:.2f}'
            l = f'{d}' + a.rjust(len(title) - len(d)) + '\n'
            total += i["amount"]
            res += l
        t = f'Total: {total:.2f}'
        res += t
        return res

            
def create_spend_chart(categories):
    line = [''] * 13
    line[0] = 'Percentage spent by category'
    line[12] = '    -'
    n = [i.name for i in categories]
    lth = len(max(n, key = len))
    line += ['     '] * lth
    res = ''
    a = list(range(110, -10, -10))
    ts = sum([round(i.spending,2) for i in categories])
    per = []
    for i in range(1,12):
        line[i] += str(a[i]).rjust(3) + '| '
    for i in categories:
        line[12] += '-' * 3
        i.name = i.name + ' ' * (lth - len(i.name))
        i.per = int(round(i.spending / ts * 100, -1))
        per.append(i.per)
        for b in range(0,lth):
            line[13 + b] += i.name[b] + '  '
    for x in per: # per = [20, 20, 60]
        for i in range(11, 0, -1):
            if x >= 0:
                line[i] += 'o' + '  '
                x -= 10
            else: 
                line[i] += '   '

    for lines in line:
        lines = lines.rstrip(' ')
        res += '\n' + lines

    res = (res.replace('\n', '', 1))
    return res
    
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")
auto = Category("Auto")
food.transfer(50, clothing)
food.transfer(100, auto)
clothing.withdraw(30.50, 't-shirt')
auto.withdraw(70.30, "engine")

print(food)
# create_spend_chart([food, clothing, auto])
print(
    (create_spend_chart([food, clothing, auto])))


Below is the output I get.

*************Food*************
deposit                1000.00
groceries               -10.15
restaurant and more foo -15.89
Transfer to Clothing    -50.00
Transfer to Auto       -100.00
Total: 823.96
Percentage spent by category
100|
 90|
 80|
 70|
 60|       o
 50|       o
 40|       o
 30|       o
 20| o  o  o
 10| o  o  o
  0| o  o  o
    ----------
     F  C  A
     o  l  u
     o  o  t
     d  t  o
        h
        i
        n
        g

Below is the link to the test.

Blockquote

Hey, I didnt dig very deep into the project or your code, but seems to me like spacing is correct. A good way to check that is substituting them for symbols like $ or %, which I did and it looked all good. I would advice double checking the percentages and their rounding.

Press F12 to open the browser console. You should be able to see the difference between your output and the expected one.

I checked and it’s quite difficult to compare with the browser console as there’s no example codes to call. The locations of ‘o’ to indicate the bars are different to the brower console’s.

Would there be another way to check or solve this issue?

In the browser console (f12) you will see output like this:

I suggest using the AssertionError. Copy it and put it into a fixed width font notepad and compare the lines like this:

AssertionError: 
'Perc[25 chars]n100|\n 90|\n 80|\n 70|    o\n 60|    o\n 50| [262 chars]   t' != 
'Perc[25 chars]n100|          \n 90|          \n 80|         [349 chars] t  '

You can clearly see the difference between your output (first line) and the expected output (second line).

To see your output in this format in the preview use repr()

print(repr(create_spend_chart([food, clothing, auto])))

I’ve changed the spacings to go like the bottom line.
Also changed the withdraw amounts to make the bars have exactly the same number of 'o’s for bar graph as below.

Percentage spent by category\n100|          \n 90|          \n 80|          \n 70|          \n 60| o        \n 50| o        \n 40| o        \n 30| o        \n 20| o  o     \n 10| o  o  o  \n  0| o  o  o  \n    ----------\n     F  C  A  \n     o  l  u  \n     o  o  t  \n     d  t  o  \n        h     \n        i     \n        n     \n        g     '

But on the browser console I still get below.
And I have no idea how to read that, and why it says there’s 3 'o’s in the 100| section.
And why there’s a t at the very end.

Can you help me with this?

AssertionError: 
'Perc[170 chars] 10| o  o  o  \n  0| o  o  o  \n    ----------[204 chars] t  ' !=
'Perc[170 chars] 10|    o  o  \n  0| o  o  o  \n    ----------[204 chars] t  '

The test is inputting it’s own data, the t at the end I believe is the end of “Entertainment”.

Your spacing looks good now, that’s fixed :white_check_mark:

The only problem is that your chart is missing an o in the first column there. That’s likely a calculation or rounding error. Since it’s just that one o it’s probably a rounding error.

The height of each bar should be rounded down to the nearest 10.

Please share your updated code.

Thanks for your confirm.

I’ve just added temporary print() in the middle of the codes for converting into percentage to check that I was using the round() function which goes up for numbers above >= 5.

I wasn’t sure if I could use the math module or not, so I divided the percentages by 10 to make them into decimals, then used int() to get only the first integer then multiplied them by 10 to put them in to the nearest 10s.

eg)
i.per = int(i.per / 10) * 10

This worked, thank you for all your helps.

1 Like