Build a Budget App - Percentages Calculation

Tell us what’s happening:

Hi all :waving_hand: I’ve got a bit of trouble with my code.
Tests not passed: 13, 15, 16, 19, 23 and 24

Things to note:

  • No errors come up in the console.
  • The spacing is exact, but it’s the calculations that seem incorrect.
  • My assumption was to calculate the percent of the total balance that are considered withdrawals (deposits < 0)
  • Unsure about the withdraw function’s return value.

Your code so far

class Category:
    def __init__(self, name):
        self.name = name
        self.ledger = []
    
    def deposit(self, amount, desc=""):
        new_deposit = {'amount': amount, 'description': desc}
        self.ledger.append(new_deposit)
    
    def withdraw(self, amount, desc=""):
        if self.get_balance() < amount:
            return False

        current_ledger_len = len(self.ledger)
        new_deposit = {'amount': -amount, 'description': desc}
        self.ledger.append(new_deposit)
        return True
    
    def get_balance(self):
        current_sum = 0
        for current_deposit in self.ledger:
            current_sum += current_deposit["amount"]
        return current_sum
    
    def transfer(self, amount, category):
        if amount < 0:
            return False

        other_balance = category.get_balance()
        self.withdraw(amount, f"Transfer to {category.name}")
        category.deposit(amount, f"Transfer from {self.name}")
        if other_balance != category.get_balance():
            return True
        else:
            return False
    
    def check_funds(self, amount):
        return amount < self.get_balance()
    
    def __str__(self):
        result = ""
        num_astericks = 30 - len(self.name)

        if num_astericks % 2 == 0:
            currStr = '*' * (num_astericks//2) + self.name + '*' * (num_astericks//2) + "\n"
            result += currStr
        else:
            currStr = '*' * (num_astericks//2) + self.name + '*' * ((num_astericks//2)+1) + "\n"
            result += currStr
        
        num_spaces = 0
        for current_deposit in self.ledger:
            if str(current_deposit['amount']).find(".") != -1:
                num_spaces = len(current_deposit['description'][:23]) + len(str(current_deposit['amount']))

                result += current_deposit['description'][:23] + (" " * (30 - num_spaces)) + str(current_deposit['amount']) + "\n"

            else:
                num_spaces = len(current_deposit['description'][:21]) + len(str(current_deposit['amount'])+".00")
                result += current_deposit['description'][:21] + (" " * (30 - num_spaces)) + str(current_deposit['amount'])+".00" + "\n"
        
        total_string = f"Total: {self.get_balance()}"
        if total_string.find(".") != -1:
            result += f"Total: {self.get_balance()}"
        else:
            result += f"Total: {self.get_balance()}.00"
        return result

def create_spend_chart(categories):
    final_string = "Percentage spent by category\n"
    chart_data = {}

    for category in categories:
        withdrawals = 0
        for transfer in category.ledger:
            if transfer["amount"] < 0:
                withdrawals += -(transfer["amount"])
        
        percent = (withdrawals/category.get_balance()) * 100
        chart_data[category.name] = round(percent, -1)

    bottom_line = "    " + ("---" * len(categories))

    for i in range(10, -1, -1):
        curr_y_num = i*10
        e = f"{curr_y_num}| ".rjust(5)
        for key in chart_data:
            val = chart_data[key]
            if curr_y_num <= val:
                e += "o  "
            else:
                e += " ".ljust(3)
        
        final_string += e + "\n"

    final_string += bottom_line + "-\n"

    categoryNames = [c.name for c in categories]
    categoryNames.sort(key=len)
    longest_len = len(categoryNames[-1])
    for j in range(longest_len):
        n = "     "
        for name in categoryNames:
            try:
                n += f"{name[j]}  "
            except IndexError:
                n += "   "

        if j == longest_len-1:
            final_string += n
        else:
            final_string += n + "\n"

    return final_string

# `create_spend_chart` function output (with dots representing spaces)

# 100|.......
# .90|.......
# .80|.......
# .70|.......
# .60|.......
# .50|.......
# .40|.......
# .30|.......
# .20|.......
# .10|.o.....
# ..0|.o..o..
# ....-------
# .....F..C..
# .....o..l..
# .....o..o..
# .....d..t..
# ........h..
# ........i..
# ........n..
# ........g..

# testing #
food = Category('Food')
food.deposit(1000, 'initial deposit')
food.withdraw(10.15, 'groceries')
food.withdraw(15.89, 'restaurant and more food for dessert')
clothing = Category('Clothing')
food.transfer(50, clothing)
print(food)

categories = [food, clothing]
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/147.0.0.0 Safari/537.36

Challenge Information:

Build a Budget App - Build a Budget App

Hi @xsussicax,

Please review the user story related to the check_funds method. And where are you using that method? In which methods do you need to check the funds?

Happy coding!