Build a Budget App Project - Build a Budget App Project

Tell us what’s happening:

I am failing my last test. My output appears to be ok but I am obviously getting my chart printout wrong. I still have to deal with this error:

AssertionError: 'Perc[77 chars]|          \n 60|          \n 50|          \n [299 chars]  \n' != 'Perc[77 chars]|    o     \n 60|    o     \n 50|    o     \n [297 chars] t  '

I am not getting something right which I need help to spot.

Your code so far

class Category:

    def __init__(self, category):
        self.category = category
        self.ledger = []
        self.balance = 0

    def display_category(self):
        display = ""
        display += f"{self.category.center(30, '*')}\n"
        for expense in self.ledger:
            display += expense["description"][:23].ljust(23) + str("%.2f" % expense["amount"])[:7].rjust(7)
            display += "\n"
        display += f"Total: " + str(self.balance)
        return display

    def __str__(self):
        return self.display_category()

    def check_funds(self, amount):
        if amount > self.balance:
            return False
        else:
            return True
    
    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):
            self.ledger.append(
                {
                "amount" : amount * -1,
                "description" : description
                }
                )
            self.balance -=amount
            return True
        else:
            return False

    def transfer(self, amount, cate):
        if self.check_funds(amount):
            self.withdraw(amount, f"Transfer to {cate.category}")
            cate.deposit(amount, f"Transfer from {self.category}")
            return True
        else: return False

    def get_balance(self):
        return self.balance
    
      

def create_spend_chart(categories):
    chart = ""
    def get_percentage_spent(category):
        total_amount_spent = 0
        total_deposit = 0
        for i in range(len(category.ledger)):
                if category.ledger[i]["amount"] < 0:
                    total_amount_spent += category.ledger[i]["amount"]
                else:
                    total_deposit += category.ledger[i]["amount"]
        percentage_spent = int(round((abs(total_amount_spent) * 100) / total_deposit, -1))
        return percentage_spent

    def print_bar(dictionary, percentage):
        line = ""
        for item in dictionary:
            if percentage > dictionary[item]:
                line += "   "
            elif percentage <= dictionary[item]:
                line += "o  "
        return line


    percentage_spent = {
        cat.category: get_percentage_spent(cat) for cat in categories
    }


    chart += "Percentage spent by category\n"
    for percentage in range(100, -10, -10):
        chart += (str(percentage) + "|").rjust(4) + " " + print_bar(percentage_spent, percentage) + "\n"
    dash_length = (len(categories) * 3) + 1 
    dashes = "    "
    for _ in range(dash_length):
        dashes += "-" 
    chart += dashes + "\n"


    index = 0
    cat = [len(item.category) for item in categories]
    
    while index < max(cat):
        line = "     "
        for item in categories:
            if item.category[-1] == item.category[0] and len(item.category) == 1:
                if item.category == "_":
                    line += " "
                else:
                    line += item.category[index]
                    item = "_" 
            else:
                try: 
                   line += item.category[index] + "  "
                except IndexError:
                    line += "   "
        index += 1
        chart += line + "\n"
    #print(percentage_spent)
    return chart
        



categories = []
food = Category("Food")
clothing = Category("Clothing")
home = Category("Hommie")
edu = Category("Educationiskey")

food.deposit(1000, "deposit")
food.withdraw(10.15, "groceries")
food.withdraw(15.89, "restaurant and more food for dessert")
food.transfer(50, clothing)
food.transfer(150, home)

home.deposit(200, "deposit")
home.withdraw(20, "furniture")
home.withdraw(30, "kitchenware")
home.transfer(40, edu)

edu.deposit(300, "initial deposit")
edu.withdraw(150, "books")
edu.withdraw(20, "sch uniform")
edu.transfer(20, clothing)

clothing.withdraw(15, "shoes")

categories.append(food)
categories.append(clothing)
categories.append(home)
categories.append(edu)

print(food)
print(create_spend_chart(categories))





Your browser information:

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

Challenge Information:

Build a Budget App Project - Build a Budget App Project

AssertionError: 'Perc[77 chars]|          \n 60|          \n 50|          \n [299 chars]  \n'
             != 'Perc[77 chars]|    o     \n 60|    o     \n 50|    o     \n [297 chars] t  '

first line is yours, the second is the expected. Start from removing differences from the visible characters, in this case the missing o and the end where you have an extra \n

you may get more information from the one that shows all the output, it’s right below the AssertionError you copied. Maybe you have thee columns in the wrong order, or you are calculating the percentages wrong, from that one you can see it

Hi, Thanks for your swift reply. The order of my category is correct. the percentage calculation is also correct but it appears the rounding is off since it expects a bar to be printed where mine did not print. But increasing the length of the my bars would also increase the total number of characters expected. It expects 297 characters but mine already exceeds that number by 2. This is my issue.

The percentage calculation is not correct, considering this:

You seem to have overlooked this line

The percentage spent should be calculated only with withdrawals and not with deposits.

ok.

def create_spend_chart(categories):
    chart = ""
    def get_percentage_spent(category):
        total_amount_spent = 0
        total_deposit = 0
        for i in range(len(category.ledger)):
                if category.ledger[i]["amount"] < 0: # takes care of only withdrawals right?
                    total_amount_spent += category.ledger[i]["amount"]
                else:
                    total_deposit += category.ledger[i]["amount"]
        percentage_spent = int(round((abs(total_amount_spent) * 100) / total_deposit, -1))
        return percentage_spent

I was thinking my if statements takes care of the “only withdraws requirement” sinece only withdrawals would have a negavtive value. I shall look into that method critically. Many thanks.

you are using deposits in your calculation, you should not use deposits at all

1 Like

Hang on. Is the percentage spent required the percentage spent by each category of the total withdrawal of all categories??

Yes, that’s correct

… adding characters to fufill char limit.

Many thanks, my chart is now Sorted.
Now I have to find a way to remove the last new line character somewhere.

    chart = ""
    def get_withdrawal(category):
        withdrawal = 0
        for i in range(len(category.ledger)):
                if category.ledger[i]["amount"] < 0:
                    withdrawal += category.ledger[i]["amount"]
        return abs(withdrawal)

    def print_bar(dictionary, percentage):
        line = ""
        for item in dictionary:
            if percentage > dictionary[item]:
                line += "   "
            elif percentage <= dictionary[item]:
                line += "o  "
        return line


    withdrawal_dict = {
        cat.category: get_withdrawal(cat) for cat in categories
    }

    percentage_spent = {
        key: (value * 100) / sum(withdrawal_dict.values()) for key, value in withdrawal_dict.items()
    }

It is still complaining about a new line character lol, but the chart is fine now. I should be able to troubleshoot this on my own. Many thanks @pkdvalis and @ILM

1 Like

Finally done and dusted. I must confess, this was fun but challenging and i think i enjoyed every bit of it. Understanding is key. I was suck on the chart issue for days before i decided to cry for help. It came down to basic understanding. I think the project requirement should be reworded to avoid ambiguity like it happend to me. I had fun no doubt.

2 Likes

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