Build a Budget App - Build a Budget App

Tell us what’s happening:

I keep failing test 19, “The height of each bar on the create_spend_chart should be rounded down to the nearest 10.”

I’m dividing the category’s spend by the total spend, giving me a float less than one, then multiplying that by ten and using int to discard the decimal, giving me a single digit integer rounded down and then multiplying THAT by ten to give me the percentage. Whenever I test it, with dummy data it works properly.

Your code so far

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 * -1, 'description': description})
            return True
        else:
            print('No dice')
            return False
    def get_balance(self):
        total_balance = 0
        for transactions in self.ledger:
            total_balance = total_balance + transactions['amount']
        return total_balance
    def check_funds(self, amount):
        if self.get_balance() - amount < 0:
            return False
        else:
            return True
    def transfer(self, amount, category):
        if not category:
            return False
        if self.check_funds(amount):
            self.withdraw(amount, f"Transfer to {category.name}")
            category.deposit(amount, f"Transfer from {self.name}")
            return True
        else:
            return False
    def __str__(self):
        output_string = f"*************{self.name}*************\n"
        title = self.name
        title_length = len(title)
        stars = int((30 - title_length) / 2)
        output_string = "*" * stars + title + "*" * stars
        if len(output_string) == 29:
            output_string = output_string + "*"
        output_string = output_string + "\n"
        
        for item in self.ledger:
            desc_len = len(item['description'])
            amt_preform = f"{item['amount']:.2f}"
            amt_len = len(str(amt_preform))
            remainder_len = 23
            amt_formatted = ""
            if amt_len < 8:
                leading_zeroes = 7 - amt_len
                amt_formatted = " " * leading_zeroes + f"{amt_preform}"
            this_string = ""
            if desc_len < remainder_len:
                this_string = f"{item['description']}" + " " * (remainder_len - desc_len) + f"{amt_formatted}"
                output_string = output_string + this_string + "\n"
            else: # desc_len > remainder_len:
                chopped = str(item['description'])
                chopped = chopped[:remainder_len]
                this_string = chopped + f"{amt_formatted}"
                output_string = output_string + this_string + "\n"
        output_string = output_string + f"Total: {self.get_balance()}"
        return output_string

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')
food.transfer(50, clothing)
clothing.withdraw(33, 'brand new dress')
#print(food)
business = Category('Business')
business.deposit(1000)
business.withdraw(355.00)


categories = [food, clothing, business]

def create_spend_chart(categories):
    bar_chart_string = "Percentage spent by category\n"
    category_totals = []
    for category in categories:
        total_withdrawals = 0
        for item in category.ledger:
            if (item['amount']) < 0:
                total_withdrawals = total_withdrawals + item['amount']
        category_withdrawals = [round(total_withdrawals,-1), category.name]
        category_totals.append(category_withdrawals)

    #print(category_totals)
    total_spend = 0
    category_percentages = []
    for item in category_totals:
        total_spend = total_spend + item[0]
    total_spend = total_spend * -1
    for item in category_totals:
        if item[0] != 0:
            this_percentage = int((item[0] / total_spend * -1) * 10)*10
            #this_percentage = (item[0] * -1) / total_spend * 100 
            category_percentages.append([this_percentage , item[1]])
        else:
            category_percentages.append([0, item[1]])
    #category_percentages is a list of lists, where each list is the percentage of the total spend for a category and the name of that category
    #print(category_percentages)
    bar_chart_string = bar_chart_string + "100| "
    for items in category_percentages:
        if items[0] > 90:
            bar_chart_string = bar_chart_string + "o  "
        else:
            bar_chart_string = bar_chart_string + "   "
    bar_chart_string = bar_chart_string + "\n 90| "
    for items in category_percentages:
        if items[0] > 80:
            bar_chart_string = bar_chart_string + "o  "
        else:
            bar_chart_string = bar_chart_string + "   "
    bar_chart_string = bar_chart_string + "\n 80| "
    for items in category_percentages:
        if items[0] > 70:
            bar_chart_string = bar_chart_string + "o  "
        else:
            bar_chart_string = bar_chart_string + "   "
    bar_chart_string = bar_chart_string + "\n 70| "
    for items in category_percentages:
        if items[0] > 60:
            bar_chart_string = bar_chart_string + "o  "
        else:
            bar_chart_string = bar_chart_string + "   "
    bar_chart_string = bar_chart_string + "\n 60| "
    for items in category_percentages:
        if items[0] > 50:
            bar_chart_string = bar_chart_string + "o  "
        else:
            bar_chart_string = bar_chart_string + "   "
    bar_chart_string = bar_chart_string + "\n 50| "
    for items in category_percentages:
        if items[0] > 40:
            bar_chart_string = bar_chart_string + "o  "
        else:
            bar_chart_string = bar_chart_string + "   "
    bar_chart_string = bar_chart_string + "\n 40| "
    for items in category_percentages:
        if items[0] > 30:
            bar_chart_string = bar_chart_string + "o  "
        else:
            bar_chart_string = bar_chart_string + "   "
    bar_chart_string = bar_chart_string + "\n 30| "
    for items in category_percentages:
        if items[0] > 20:
            bar_chart_string = bar_chart_string + "o  "
        else:
            bar_chart_string = bar_chart_string + "   "
    bar_chart_string = bar_chart_string + "\n 20| "
    for items in category_percentages:
        if items[0] > 10:
            bar_chart_string = bar_chart_string + "o  "
        else:
            bar_chart_string = bar_chart_string + "   "
    bar_chart_string = bar_chart_string + "\n 10| "
    for items in category_percentages:
        if items[0] > 0:
            bar_chart_string = bar_chart_string + "o  "
        else:
            bar_chart_string = bar_chart_string + "   "
    bar_chart_string = bar_chart_string + "\n  0| "
    for items in category_percentages:
        bar_chart_string = bar_chart_string + "o  "
    bar_chart_string = bar_chart_string + "\n    -"
    for items in category_percentages:
        bar_chart_string = bar_chart_string + "---"
    bar_chart_string = bar_chart_string + "\n"
    category_names = []
    longest_name = 0
    for items in category_percentages:
        category_names.append(items[1])
        if len(items[1]) > longest_name:
            longest_name = len(items[1])
    bar_chart_string = bar_chart_string + "     "
    for x in range(0, longest_name):
        for items in category_percentages:
            if len(items[1]) > x:
                #print('Bigger Enough' + str(x))
                bar_chart_string = bar_chart_string + items[1] [x] + "  "
            else:
                bar_chart_string = bar_chart_string + "   "
        if x < longest_name - 1:
            bar_chart_string = bar_chart_string + "\n     "
    print(bar_chart_string)
    return bar_chart_string

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/144.0.0.0 Safari/537.36

Challenge Information:

Build a Budget App - Build a Budget App

which part of your code is doing the rounding?
is what you are doing rounding down?

test your app with

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)
print("70/20")
print(create_spend_chart([food, entertainment]))
print("0/70/20")
print(create_spend_chart([business, food, entertainment]))

the 70/20 and 0/70/20 are the expected heights of the colums

The problem was in the line “category_withdrawals = [round(total_withdrawals,-1), category.name]” - I was for some reason trying to round to the nearest 10 before calculating the percentages, which meant it was using 80 rather than 78 as the amount, if that makes sense.

Changing it to “category_withdrawals = [total_withdrawals, category.name]” fixed it.

Thank you!