Build a Budget App Project - Build a Budget App Project

Tell us what’s happening:

I am having trouble with test cases 19, 23, and 24. I’ve tried everything and read all the posts regarding this but it still won’t work.
For 19: My bars are rounded down but it still gives error.
For 23: All my lines are the same length, there are like three different loops that verify that.
For 24: Yeah, idek. I’ve lost hope in my program.
Ik my code sucks and is probably unreadable but if someone could please help me figure out what I am missing. Thanks.

Your code so far

# Budget App
class Category:
    def __init__(self,name):
        self.name = name
        self.ledger = []
        self.balance = 0
        self.spent_balance = 0
    def __str__(self):
        category_header = "*" * 30
        middle = len(category_header) // 2
        start_index = middle - (len(self.name) // 2)
        end_index = start_index + len(self.name)
        category_header = category_header[:start_index] + self.name + category_header[end_index:]

        return "{}\n{}\nTotal: {}".format(category_header,'\n'.join('{}{}{:.2f}'.format(dictionary['description'][:23], ' ' * (30 - len(dictionary['description'][:23]) - len("{:.2f}".format(float(dictionary['amount'])))), float(dictionary['amount'])) for dictionary in self.ledger), self.balance)        

    def __repr__(self):
        return self.name
    def deposit(self,amount,description=""):
        self.ledger.append({'amount': amount, 'description': description})
        self.balance += amount

    def withdraw(self,amount,description=""):
        if self.check_funds(amount):
            self.ledger.append({'amount': -amount, 'description': description})
            self.balance -= amount
            self.spent_balance += amount
            return True
        else:
            return False
        
    def get_balance(self):
        return self.balance

    def transfer(self, amount, category):
        if self.check_funds(amount):
            self.withdraw(amount,f"Transfer to {category.__repr__()}")
            category.deposit(amount,f"Transfer from {self.__repr__()}")
            category.ledger.append({'amount': amount})
            return True 
        return False
        
    def check_funds(self, amount):
        if amount <= self.balance:
            return True
        else:
            return False


#Return the percentage spending chart
def create_spend_chart(categories):
    spent = [category.spent_balance for category in categories]
    percentages = []
    lines = []
    for i in range(len(categories)):#Creates the percentages
        percent = ((((spent[i]/sum(spent)))*100)//10)*10
        percentages.append(percent)
    for i in range(11):#Initializes the bar chart
        lines.append(f"{(i*10):>3}"+"|")
    for i in range(len(percentages)):#Adds the o's to the bar chart
        level = percentages[i] / 10
        if level > 0:
            for j in range(int(level)):
                if lines[j][-1] == 'o':
                    lines[j] += "  o"
                else:
                    lines[j] += " o"
    maxh = "    "+("-"*3*len(categories)) + "-"#Divider
    maxc = max(len(category.name) for category in categories)
    name_lines = ['']*maxc


    for category in categories:#Vertical category names under line break
        name = category.name
        col = categories.index(category)
        for index, letter in enumerate(name):
            if len(name_lines[index]) == 0:
                if col == 0:
                    name_lines[index] += f"{letter:>6}"
                elif col == 1:
                    name_lines[index] += f"{letter:>9}"
                elif col == 2:
                    name_lines[index] += f"{letter:>12}"
                elif col == 3:
                    name_lines[index] += f"{letter:>15}"
                else:
                    print('-->Error')
            elif len(name_lines[index]) == 6:
                if col == 1:
                    name_lines[index] += f"{letter:>3}"
                elif col == 2:
                    name_lines[index] += f"{letter:>6}"
                elif col == 3:
                    name_lines[index] += f"{letter:>9}"
            elif len(name_lines[index]) == 9:
                if col == 2:
                    name_lines[index] += f"{letter:>3}"
                elif col == 3:
                    name_lines[index] += f"{letter:>6}"
            else:
                name_lines[index] += f"{letter:>3}"

    #Lines same length 1.0
    total_name_length = 4+(3*len(categories))+1
    for i in range(len(name_lines)):
        if len(name_lines[i]) != total_name_length:
            name_lines[i] = "{:<{}}".format(name_lines[i], total_name_length)

    #Lines same length 2.0
    for line in lines:
        if len(line) < len(maxh):
            index = lines.index(line)
            lines[index] = f"{line:<{len(maxh)}}"

    for line in name_lines:
        if len(line) < len(maxh):
            index = lines.index(line)
            name_lines[index] = f"{line:<{len(maxh)}}"
    
    return "Percentage spent by category\n{}\n{}\n{}".format(('\n'.join('{}'.format(line) for line in reversed(lines))),(maxh),('\n'.join('{}'.format(line) for line in name_lines))).rstrip()

food = Category("Food")
entertainment = Category("Entertainment")
business = Category("Business")
food.deposit(900, "deposit")
entertainment.deposit(900, "deposit")
business.deposit(900, "deposit")
food.withdraw(78)
entertainment.withdraw(22)
business.withdraw(8)

chart = create_spend_chart([food, entertainment])
print(chart)




# '    [101 chars]       n  \n        m  \n        e  \n        n  \n        t' 
# '    [101 chars]       n  \n        m  \n        e  \n        n  \n        t  '

Your browser information:

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

Challenge Information:

Build a Budget App Project - Build a Budget App Project

1 Like

Hi @philip04

The bar total needs to add up to 100%.

Happy coding

try this, this is what is being tested

food = Category("Food")
entertainment = Category("Entertainment")
business = Category("Business")
food.deposit(900, "deposit")
entertainment.deposit(900, "deposit")
business.deposit(900, "deposit")
food.withdraw(105.55)
entertainment.withdraw(33.40)
business.withdraw(10.99)
actual = create_spend_chart([business, food, entertainment])
expected = 'Percentage spent by category\n100|          \n 90|          \n 80|          \n 70|    o     \n 60|    o     \n 50|    o     \n 40|    o     \n 30|    o     \n 20|    o  o  \n 10|    o  o  \n  0| o  o  o  \n    ----------\n     B  F  E  \n     u  o  n  \n     s  o  t  \n     i  d  e  \n     n     r  \n     e     t  \n     s     a  \n     s     i  \n           n  \n           m  \n           e  \n           n  \n           t  '

Your code outputs this:

Percentage spent by category
100|          
 90|          
 80|          
 70|          
 60| o        
 50| o        
 40| o        
 30| o        
 20| o        
 10| o  o     
  0| o  o     
    ----------
     B  F  E  
     u  o  n  
     s  o  t  
     i  d  e  
     n     r  
     e     t  
     s     a  
     s     i  
           n  
           m  
           e  
           n  
           t

but the expected chart is this:

Percentage spent by category
100|          
 90|          
 80|          
 70|    o     
 60|    o     
 50|    o     
 40|    o     
 30|    o     
 20|    o  o  
 10|    o  o  
  0| o  o  o  
    ----------
     B  F  E  
     u  o  n  
     s  o  t  
     i  d  e  
     n     r  
     e     t  
     s     a  
     s     i  
           n  
           m  
           e  
           n  
           t 

Thanks for the help. I managed to fix #19 using this but 23 and 24 still give error. I will try fixing them on my own since I think that it just needs some small changes, but I’ll come back if I have any more questions.
Edit: Yes, just as I suspected, my return statement in create_spend_chart was using an unnecessary .rstrip() at the end.
Everything works fine now.
Thank you so much for making it clearer.