Build a Budget App Project - Build a Budget App Project

Tell us what’s happening:

Hello world!

I’d like to know how to return the last function (last test) exactly what I see on print(). I’ve tried many ways, but nothing seems to work properly.

Your code so far

class Category:

    total_expenses = []

    def __init__(self, name):

        self.name = name
        self.ledger = []
            


###################DEPOSIT#####
    def deposit(self, amount, description=""):
        
        self.ledger.append({"amount": amount, "description": description})

        

####################WITHDRAW###
    def withdraw(self, amount, description=""):

        if self.check_funds(amount):

            self.ledger.append({"amount": -amount, "description": description})

            return True
            
        else:
            return False



###############GET_BALANCE#####
    def get_balance(self):

        total = 0

        for amount in self.ledger:
            total += float(amount['amount'])

        return total



#############TRANSFER##########
    def transfer(self, amount, another_category):

        if self.check_funds(amount):
            self.withdraw(amount, f'Transfer to {another_category.name}')
            
            another_category.deposit(amount, f'Transfer from {self.name}')

            return True

        else:
            return False



##################CHECK_FUNDS##
    def check_funds(self, amount):

        #se o dinheiro para retirar ou para transferir for maior que o total disponível:
        
        if float(amount) > self.get_balance():
            return False
        else:
            return True


##############PERCENTAGE#######
    def get_percentage(self):
        
        expenses = 0

        for x in self.ledger:
            val = x["amount"]
            if val < 0:
                expenses += -val
        expenses = round(expenses, 2)

        Category.total_expenses.append(expenses)
        
        return Category.total_expenses



######################STRING###
    def __str__(self):

        amount = ''
        description = ''
        output = f'{self.name.center(30, "*")}\n'

        for q in self.ledger:
            amount = "{:.2f}".format(q["amount"])[:7]
            description = q["description"][:23]

            #if description == "deposit":
                #description = "initial deposit"

            output += f'{description.ljust(23)[:23]}{amount.rjust(7)[:7]}\n'

        
        return output + f'Total: {"{:.2f}".format(self.get_balance())}'


####################MAGIC######
    def __repr__(self):
        
        return f'\n\nTotal Expenses: {self.get_percentage()}\n'
        

###############################

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(23.44, "pants")
clothing.withdraw(18.22, "blouse")
entertainment = Category("Entertainment")
entertainment.deposit(500, "deposit for fun")
entertainment.withdraw(12.05, "cinema")
entertainment.withdraw(24.55, "meeting")
entertainment.transfer(120, clothing)
print(food)
print(clothing)
print(entertainment)


###############################

def create_spend_chart(categories):

    if len(categories) > 4:
        return "\n\nUp to four!!!\n\n"

    
    try:

        chart = ''
        calculate = 0
        calcs = []
        
        #print(f'\nTotal expenses in all categories: ${"{:.2f}".format(sum(Category.total_expenses))}\n')

        for i in range(len(categories)):
            #print(f'{Category(categories[i]).name} expenses: ${"{:.2f}".format(Category(categories[i]).get_percentage()[i])}')
        
            calculate = (Category(categories[i]).get_percentage()[i]/sum(Category.total_expenses)) * 100
        
            calculate = round(calculate)

            #print(f'{calculate}%\n')


            if calculate == 100:
                pass
            elif calculate < 100 and calculate >= 90:
                calculate = 90
        
            elif calculate < 90 and calculate >= 80:
                calculate = 80
            
            elif calculate < 80 and calculate >= 70:
                calculate = 70
            
            elif calculate < 70 and calculate >= 60:
                calculate = 60
            
            elif calculate < 60 and calculate >= 50:
                calculate = 50
        
            elif calculate < 50 and calculate >= 40:
                calculate = 40
        
            elif calculate < 40 and calculate >= 30:
                calculate = 30
            
            elif calculate < 30 and calculate >= 20:
                calculate = 20
        
            elif calculate < 20 and calculate >= 10:
                calculate = 10
    
            elif calculate < 10:
                calculate = 0

            
            #other variables
            first_calc = '' 
            second_calc = '' 
            third_calc = '' 
            fourth_calc = ''
            
        
            #first item
            if i == 0:
                first_calc = calculate
                calcs.append(first_calc)
                #print(categories[0], first_calc)
            
            #second item
            elif i == 1:
                second_calc = calculate
                calcs.append(second_calc)
                #print(categories[1], second_calc)

            #third item
            elif i == 2:
                third_calc = calculate
                calcs.append(third_calc)
                #print(categories[2], third_calc)
            
            #fourth item
            elif i == 3:
                fourth_calc = calculate
                calcs.append(fourth_calc)
                #print(categories[3], fourth_calc)
        

        #print(calcs)
        
        chart = "Percentage spent by category\n"


###### https://github.com/ZnarKhalil/BudgetApp/blob/main/budget.py
        for i in range(100, -1, -10):
            #start,stop,step
            chart += str(i).rjust(3) + "| "
            #print(chart)
            #print(calcs)
            for c in calcs:
                chart += "o" if c >= i else " "
                chart += "  "
            chart += "\n"
            
        #print(chart)
###############################
        
        # --- => three for each category and one more -
        chart += "    " + "---" * len(categories) + "-"
        
        c_names = []
        #print(chart)
        for cat in categories:
            c_names.append(cat)


        max_length = max(c_names, key=len)

        c_names = [name.ljust(len(max_length)) for name in c_names]

        lala = ""
        chart.rstrip("\n")

        print(chart)

        for x in zip(*c_names):
            
            lala = "  ".join(x).rjust(6)

            if len(categories) == 2:
                lala = "  ".join(x).rjust(9)

            elif len(categories) == 3:
                lala = "  ".join(x).rjust(12)
                
            elif len(categories) == 4:
                lala = "  ".join(x).rjust(15)
            
            print(lala)
            
        
        #chart += "\n"
        #for i in range(len(c_names)):
            #chart += c_names[i]
            #chart += "  "

        #chart += "\n"
        #for name in c_names:
            #chart += name[0]
            #chart += "  "

        #chart += "\n"
        #for name in c_names:
            #chart += name[1]
            #chart += "  "

    except:
        print("!!!")
    
    finally:
        pass



#####CALLING THE FUNCTION######
print(repr(create_spend_chart(['Food', 'Clothing'])
))


#####RASCUNHO CÁLCULO:#########

# 274.30 é o total de gastos de todas as categorias

# Food category, for example:

# 100% =========> 274.30
#  x%  =========>  76.04

# (274.30)x = 76.04 * 100
# (274.30)x = 7604
#     x     = 7604 / (274.30)
#     x     = 27.72% aprox.
#     x     = 28%

# "The height of each bar should be rounded down to the nearest 10."

# 28% ========> 20


# Clothing category:

# 100% ==========> 274.30
#  x % ==========>  41.66

# (274.30)x = 41.66 * 100
# (274.30)x = 4166
#         x = 4166 / (274.30)
#         x = 15.19% aprox.
#         x = 15%

# 15% ==========> 10


# Entertainment category:

# (274.30)x = 156.60 * 100
#         x = 15660 / (274.30)
#         x = 57% aprox.

# 57% ===========> 50

Your browser information:

User Agent is: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Mobile Safari/537.36

Challenge Information:

Build a Budget App Project - Build a Budget App Project

That function should return not print

Check the browser console (f12 and select the console tab) for a more detailed error

FAIL: test_create_spend_chart (test_module.UnitTests.test_create_spend_chart) 
---------------------------------------------------------------------- 
    self.assertEqual(actual, expected, 'Expected different chart representation. Check that all spacing is exact.')

AssertionError: None != 'Percentage spent by category\n100|      [384 chars] t  ' : 
Expected different chart representation. Check that all spacing is exact. 

Your function is returning None

I know it returns “None”, I could see it before going here… but what I want to know is how to return my print response ==> I want to return the same picture, the same elements’ position and chart’s design; because whenever I return that function, I cannot pass the test!

I think I understand. First though, your function needs to return and not print, or it will never pass the test.

If you want to see the chart form, when you call the function, don’t use repr()

Thank you for your help!

Well, I discovered that the issue is worse than I thought:

when I change the category’s position inside calling function, the percentage’s position doesn’t change.

Let me explain it better: if I call the function with “Food” and “Entertainment”, the “Entertainment” receives “Clothing” percentage, not the correct one. So, I have to call “Food”, “Clothing”, “Entertainment”, all in that order, to receive the correct percentage’s position.

I have to write all, starting at zero in the last test.

Very boring, because I’ve been “pulling out my hair” because of this Budget App (last test).

It can feel like a setback, but try to look at it as an opportunity to learn, practice your skills and write a better program! You’ll be a stronger programmer when it’s done.