Build a Budget App Project - Build a Budget App Project

Tell us what’s happening:

I have problems with the create_spend_chart function.
I truly don’t know what I’m missging, I don’t know if it is an spacing problem or if it is a problem with how I calculated the percentages.
I would gladly appreciate some help.

Your code so far

class Category:
    def __init__(self, category_name):
        self.category_name = category_name
        self.ledger = [] 

    #Method for printing the category
    def __str__(self):
        category_str = ''
        
        #Making the title
        asterix = ''.join(['*' for i in range((30-len(self.category_name))//2)])
        title = asterix + self.category_name + asterix
        if (30-len(self.category_name))%2 != 0:
            title += '*'
        category_str += title 

        #Adding the transactions
        for transaction in self.ledger:
            #Getting the description for each transaction (only the first 23 characters)
            description = transaction['description'][0:23]
    
            #Getting the amount of each transaction and adding the decimals if needed
            amount = str(transaction['amount'])
            if type(transaction['amount']) is int:
                amount +='.00'
    
            #Spaces to align the amount to the right
            spaces = ''.join([' ' for i in range(30-len(amount)-len(description))]) 
            transaction_str = '\n' + description + spaces + amount
            category_str += transaction_str
        
        #Adding the total
        total = '\nTotal: ' + str(self.get_balance()) 
        category_str += total

        return category_str   
    
    def deposit(self, amount, description = ''):
        deposit = {'amount': amount, 'description': description}
        return self.ledger.append(deposit)

    def get_balance(self):
        balance = 0
        for transaction in self.ledger:
            balance += transaction['amount']
        return balance

    def check_funds(self, amount):
        return amount <= self.get_balance()

    def withdraw(self, amount, description = ''):
        if self.check_funds(amount):
            withdrawal = {'amount': -amount, 'description': description}
            self.ledger.append(withdrawal)
            return True
        return False

    def transfer(self, amount, other_category):
        if self.check_funds(amount) == True:
            self.withdraw(amount, f'Transfer to {other_category.category_name}')
            other_category.deposit(amount, f'Transfer from {self.category_name}')
            return True
        return False
    
    #Creating a method that will help the function to create the bar char of withdrawals
    def total_of_withdrawals(self):
        total_withdrawals = 0
        for transaction in self.ledger:
            if transaction['amount'] < 0:
                total_withdrawals += transaction['amount']
        return total_withdrawals*(-1)


#Creating a function to calculate and round the percentage of withdrawals of each category
def calculate_category_percentage(categories):
    #Getting the total of withdrawals and the name of the categories
    overall_total = 0
    category_names = []
    category_totals = []
    for category in categories:
        total_by_category = category.total_of_withdrawals()
        category_totals.append(total_by_category)
        overall_total += total_by_category

        category_name = category.category_name
        category_names.append(category_name)
    
    #Calculating the percentages and rounding them
    category_percentages = [(i/overall_total)*100 for i in category_totals]
    category_percentages_rounded = [round(i/10)*10 for i in category_percentages]

    #Creating a dictionary to store the categories and their percentages
    dictionary = {'categories' : category_names, 'percentages': category_percentages_rounded }
    return dictionary


def create_spend_chart(categories):
    #Get the names and percentages of the categories 
    catgories_list = calculate_category_percentage(categories)['categories']
    percentages_list = calculate_category_percentage(categories)['percentages']

    #Making the title
    bar_chart = 'Percentage spent by category' 
    
    #Making each row of the chart
    for number in range(100,-1,-10):
        bars = '  '.join(['o' if p >= number else ' ' for p in percentages_list])
        if number == 100:
            row = f'{number}| {bars}  '
        else:
            row = f'{number:3}| {bars}  '    
        bar_chart += '\n' + row

    #Making the lines that go below
    lines = ''.join(['-' for i in range(len(row)-4)])
    bar_chart += '\n    ' + lines
    

    #Adding the titles of each category vertically
    max_length = max(len(name) for name in catgories_list)
    for i in range(max_length):
        vertical_names = '  '.join([category[i] if i < len(category) else ' ' for category in catgories_list])
        bar_chart += '\n     ' + vertical_names + '  '

    print(bar_chart)


    
    
#For testing my code...
food = Category('Food')
food.deposit(1000, 'deposit')
food.withdraw(180.15, 'groceries')
food.withdraw(150.89, 'restaurant and more food for dessert')

clothing = Category('Clothing')
food.transfer(50, clothing)
clothing.deposit(1200,'deposit')
clothing.withdraw(400.56, 'blouse')
clothing.withdraw(599.99, 'socks')
clothing.withdraw(800, 'jacket')

auto = Category('Auto')
auto.deposit(7000,'initial deposit')
auto. withdraw(399.47,'gas')
auto. withdraw(2000, 'wheels')


create_spend_chart([food, clothing, auto])

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

1 Like

Check the browser console for more a more detailed message. Press F12 and look for where it says “console”. Here’s how to interpret the message:

1 Like

An assertion error gives you a lot of information to track down a problem. For example:

AssertionError: 'Year' != 'Years'
- Year
+ Years
?     +

Your output comes first, and the output that the test expects is second.

AssertionError: ‘Year’ != ‘Years’

Your output: Year does not equal what’s expected: Years

- Year
+ Years
?     +

- Dash indicates the incorrect output
+ Plus shows what it should be
? The Question mark line indicates the place of the character that’s different between the two lines. Here a + is placed under the missing s .

Here’s another example:

E       AssertionError: Expected different output when calling "arithmetic_arranger()" with ["3801 - 2", "123 + 49"]
E       assert '  3801      123    \n   - 2     + 49    \n------    -----    \n' == '  3801      123\n-    2    +  49\n------    -----'
E         -   3801      123
E         +   3801      123    
E         ?                ++++
E         - -    2    +  49
E         +    - 2     + 49    
E         - ------    -----
E         + ------    -----    
E         ?                +++++

The first line is long, and it helps to view it as 2 lines in fixed width characters, so you can compare it character by character:

'  3801      123    \n   - 2     + 49    \n------    -----    \n'
'  3801      123\n-    2    +  49\n------    -----'

Again, your output is first and the expected output is second. Here it’s easy to see extra spaces or \n characters.

E         -   3801      123
E         +   3801      123    
E         ?                ++++

Here the ? line indicates 4 extra spaces at the end of a line using four + symbols. Spaces are a little difficult to see this way, so it’s useful to use both formats together.

I hope this helps interpret your error!

1 Like

Hi this is what the console says. I´ll also try and do what you told me in the other comment

See where it says "AssertionError: None != 'Percentage" ?

This means your function is returning None because you print() your chart. You need to return() the chart.

If you want to print the chart to see it, call your function like this:

print(create_spend_chart([food, clothing, auto]))
2 Likes

thanks for the info
I looked up a problem I was having and this helped me also.

1 Like

Thank you so much, that was my problem, and also that I wasn’t rounding down. Thanksssss!

1 Like