Build a Budget App - Build a Budget App

Tell us what’s happening:

Why are my tests 16, 20, 23, 24 going wrong? everything seems to be working correctly even with more categories

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):
        balance = 0
        
        for n in self.ledger:
            balance += n['amount']
        return balance

    def transfer(self, amount, target):
        if self.check_funds(amount):
            self.withdraw(amount, f'Transfer to {target.name}')
            target.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):
        title = f'{"*" * ( 15 - int(len(self.name) // 2))}{self.name}{"*" * ( 15 - int(len(self.name) // 2))}'
        lines = [title]
        for x in self.ledger:
            lines.append((f'{x["description"].ljust(23, " ")[:23]}{str(x["amount"]).rjust(7, " ")}'))
        lines.append(f'Total: {self.get_balance()}')
        return '\n'.join(lines)

def writehr(m, y='', z='', p=''):
    lines = []
    
    for a, b, c, d in zip_longest(m.name, y.name if isinstance(y, Category) else "", z.name if isinstance(z, Category) else '', p.name if isinstance(p, Category) else '', fillvalue = ' '):
        lines.append(f' {a if a != ("", None) else " "} ' + f' {b if b != ("", None) else " "} ' + f' {c if c != ("", None) else " "} ' + f' {d if d != ("", None) else " "} ')
    
    return '    ' + '\n    '.join(lines)

def create_spend_chart(categories):
        x = 100
        totalSpent = 0
        eachSpent = []
        perSpent = []
        for i in categories:
            spent = 0

            ## Calcula o total gasto e adiciona o valor x gasto pela categoria a uma lista
            for s in i.ledger:
                if s['amount'] < 0:
                    totalSpent += -s['amount']
                    spent += -s['amount']
                else:
                    totalSpent += 0
            eachSpent.append(spent)
        
            ## Divide o valor da lista por 100 e ve quantos % ele gastou
        for g in eachSpent:
            perSpent.append(g / totalSpent * 100)
        lines = []
        lines.append('Percentage spent by category')
        while x >= 0:
            string = f'{str(x).rjust(3, " ")}|'
            for y in perSpent:
                string = string + f' {"o" if y >= x else " "} '
            lines.append(string)
            x -= 10
        lines.append('-'.rjust(5, " ") + f'{"---" * len(perSpent)}')
        lines.append(writehr(*categories))
        return '\n'.join(lines)
        

clothes = Category('Clothes')
food = Category('Food')
food.deposit(1000, 'deposit')
food.withdraw(10.15, 'groceries')
food.withdraw(15.89, 'restaurant and more food for dessert')
food.transfer(100, clothes)
clothes.withdraw(100)
groceries = Category('Groceries')
groceries.deposit(1000, 'deposit')
groceries.withdraw(900, 'groceries')


print(food)
print(create_spend_chart([food, clothes, groceries]))



Your browser information:

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

Challenge Information:

Build a Budget App - Build a Budget App

Welcome to the forum @gabrielwmariuzza

What does 70 + 10 + 0 equal?

Happy coding

Oh wait I didnt notice that, but now that I fixed it (atleast I think) making it

perSpent.append(round(g / totalSpent * 100, -1))

my test 19 is now going wrong, besides whats wrong with test 16?

(just figured it is “rounded down” but then it should give an error when summing up things no?)

can you post your updated code?

from itertools import zip_longest
from math import floor
from math import ceil

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):
        balance = 0
        
        for n in self.ledger:
            balance += n['amount']
        return balance

    def transfer(self, amount, target):
        if self.check_funds(amount):
            self.withdraw(amount, f'Transfer to {target.name}')
            target.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):

        left_padding = (15 - ceil(len(self.name) / 2))
        right_padding = (15 - floor(len(self.name) / 2))
        print(left_padding)
        print(right_padding)
        title = f'{"*" * left_padding}{self.name}{"*" * right_padding}'
        lines = [title]
        for x in self.ledger:
            lines.append((f'{x["description"].ljust(23, " ")[:23]}{str(x["amount"]).rjust(7, " ")}'))
        lines.append(f'Total: {self.get_balance()}')
        return '\n'.join(lines)

def writehr(m, y='', z='', p=''):
    lines = []
    
    for a, b, c, d in zip_longest(m.name, y.name if isinstance(y, Category) else "", z.name if isinstance(z, Category) else '', p.name if isinstance(p, Category) else '', fillvalue = ' '):
        line = f' {a if a != ("", None) else " "} ' + f'{f" {b} " if b != ("", None) else " "}' + f'{f" {c} " if c != ("", None) else " "}' + f'{f" {d} " if d != ("", None) else ""}'
        lines.append(line)
        print(line)
    
    return '    ' + '\n    '.join(lines)

def create_spend_chart(categories):
        x = 100
        totalSpent = 0
        eachSpent = []
        perSpent = []
        for i in categories:
            spent = 0

            ## Calcula o total gasto e adiciona o valor x gasto pela categoria a uma lista
            for s in i.ledger:
                if s['amount'] < 0:
                    totalSpent += -s['amount']
                    spent += -s['amount']
                else:
                    totalSpent += 0
            eachSpent.append(spent)
        
            ## Divide o valor da lista por 100 e ve quantos % ele gastou
        
        for g in eachSpent:
            result = g / totalSpent * 100
            print(result)
            perSpent.append(floor(result / 10) * 10)
        lines = []
        lines.append('Percentage spent by category')
        print(perSpent)
        while x >= 0:
            string = f'{str(x).rjust(3, " ")}|'
            for y in perSpent:
                string = string + f' {"o" if y >= x else " "} '
            string = string + ' '
            lines.append(string)
            x -= 10
        print(perSpent)
        lines.append('-'.rjust(5, " ") + f'{"---" * len(perSpent)}')
        lines.append(writehr(*categories))
        return '\n'.join(lines)
        

clothes = Category('Clothes')
food = Category('Food')
food.deposit(1000, 'deposit')
food.withdraw(10.15, 'groceries')
food.withdraw(15.89, 'restaurant and more food for dessert')
food.transfer(100, clothes)
clothes.withdraw(100)
groceries = Category('Groceries')
groceries.deposit(1000, 'deposit')
groceries.withdraw(900, 'groceries')


print(food)
print(clothes)
print(create_spend_chart([food, clothes, groceries]))

(Was working on fixing some thigs so somethings may look really wrong) now only tests 16, 23, 24 are getting wrong

are you familiar how to read the output from unittest? this lab has the tests written with unittest, and the output can be found in the brower console

for test 16

AssertionError: '****[47 chars]        900\nmilk, cereal, eggs, bac -45.67\nT[40 chars]4.33' 
             != '****[47 chars]     900.00\nmilk, cereal, eggs, bac -45.67\nT[40 chars]4.33'

first actual second expected. all numbers need their decimals

for test 24

AssertionError: '     F  E       \n     o  n       \n     o  t       [176 chars]    ' 
             != '     F  E  \n     o  n  \n     o  t  \n     d  e  \n[111 chars] t  '

you have extra spaces on the lines

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