Build a Budget App - Step 22

Tell us what’s happening:

I’m stuck at Step 22: create_spend_chart chart should not have new line character at the end.

The output on Console doesn’t show any error, though using F12 show me this line:

'Perc[364 chars]         m  \n           e  \n           n  \n           t  \n'!='Perc[364 chars]         m  \n           e  \n           n  \n           t  '


Including an error on line 24, which is part of the __str__ function. Except writing my code in any other way doesn’t work. I don’t know how to fix what I did.

Your code so far

import math

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

    def __str__(self):
        title = len(self.name)
        stars = ((30 - title)//2)*"*"
        header =  f'{stars}{self.name}{stars}\n'
        line_ = ""
        for i in self.ledger:
            price = f"{i['amount']:.2f}"
            if len(i["description"]) <= 23:
                space = 30 - len(i["description"]) - len(price) 
                line_ = i["description"] + (space * ' ') + price + "\n"
                header += line_
            else:
                space = 30 - 24 - (len(price))
                #print(f"{i['description']} {len(price)}")
                line_ = f"{i['description'][:23]} {(space * ' ')}{price[:7]}\n"
                header += line_
        total_ = f"Total: {self.get_balance():.2f}"
        header += total_
        return (header)
        

    def deposit(self,amount,descr=''):
        self.balance += amount
        self.ledger.append({'amount': amount,'description': descr})
     
    def withdraw(self,amount,descr=''):
        if self.check_funds(amount) == True:
            self.ledger.append({'amount': -abs(amount),'description': descr})
            self.balance -= amount
            self.spent += amount
            return True
        else:
            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}")
            dest.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 create_spend_chart(categories):
    # add variable for string, starting with the chart title.
    chart_ = "Percentage spent by category\n"
    # add variables for:
    # > amount spent in each ledger
    cats_spent = []
    # > Total amount spent across all ledger
    total_spent = 0.0
    # > calculated percentage for each ledger
    percent = 0
    # > rounded values of percentage to use them for the chart
    indice_ = []

    for category in categories:
        cat_spent = 0
        for i in category.ledger:
            if i['amount'] < 0:
                cat_spent += abs(i['amount'])
        cats_spent.append(cat_spent)
        
        # verify amount spent per category
        # print(f"{cat_spent} {category.name}")

        total_spent += cat_spent
    
    # print (f"\nTotal spent: {total_spent}\n")
    
    nb_cats = len(cats_spent)
    j=0    
    while j < nb_cats:
        percent = round(cats_spent[j]*100/(total_spent),2)
        # print(f"{cats_spent[j]} is {percent} % of {total_spent}")
        j+=1

        indice_.append(round(percent))

    # cats_spent.sort()
    # indice_.sort()
    # print(f"\n{cats_spent}\n{indice_}\n")

    for data in range(100,-1,-10):
        bar = f"{data:3}| "
        for i in range(len(indice_)):
            if indice_[i] >= data:
                bar += "o"
            else:
                bar += " "
            bar += "  "
        chart_ += f"{bar}\n"

    chart_ += "    " + "-"*len(indice_)*3+'-\n'
    
    longest_name = 0
    for category in categories:
        if len(category.name) > longest_name:
            longest_name = len(category.name)
        else:
            continue
    
    for i in range (longest_name):
        chart_ += " "*5
        for category in categories:
            if i < len(category.name):
                chart_ += f"{category.name[i]}  "
            else:
                chart_ += "   "
        chart_ += "\n"
    return chart_

food = Category('Food')
clothing = Category('Clothing')
auto = Category('Auto')

food.deposit(1000, 'deposit')
food.deposit(900, 'deposit')
food.withdraw(45.67, 'milk, cereal, eggs, bacon, bread')
food.withdraw(10.15,'groceries')
food.withdraw(15.89, 'restaurant and more food for dessert')
food.transfer(50,clothing)
auto.deposit(15000,'initial deposit')
food.transfer(10,auto)
clothing.withdraw(40,'new shirts')
auto.withdraw(80,'car repair')

accounts = [food,clothing,auto]

# print(food)
# print(clothing)
print(create_spend_chart(accounts))
# print(f"{food.ledger}\n")
# print(food.get_balance())
# print(food.transfer(1000,clothing))
# print(clothing.get_balance())
# print(food.get_balance())

# print(f"{food.ledger}\n")
# print(f"{clothing.ledger}\n")

Your browser information:

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

Challenge Information:

Build a Budget App - Build a Budget App

GitHub Link: freeCodeCamp/curriculum/challenges/english/blocks/lab-budget-app/5e44413e903586ffb414c94e.md at main · freeCodeCamp/freeCodeCamp · GitHub

Welcome to the forum @Vanael,

Have you considered checking the length of the longest category name to make sure there is no new line character after the last letter in it?

Happy coding

I hadn’t though of looking for this, no. Thanks!

I did fix the problem, but I think my solution is very crude:

    for i in range (longest_name):
        chart_ += " "*5
        for category in categories:
            if i < len(category.name):
                chart_ += f"{category.name[i]}  "
            else:
                chart_ += "   "
#added the if statement here.
        if i in range (longest_name-1):
            chart_ += "\n"
    return chart_

is there a way I could have make it neater? Or even for the rest of my code? Maybe even just tips to follow to better organize my code?

Have a good day ~

I would not worry about that at this stage.

You are a beginner learning programming. You don’t even know enough to evaluate if this is “crude” or not.

Just get it done and move on.