Build a Budget App Project - Build a Budget App Project

Tell us what’s happening:

Hi everyone.
I’ve worked on the Python project called Build a Budget App.
Once finished, my code passes all the tests except for this one:
“16. Printing a Category instance should give a different string representation of the object.”
I acknowledge I don’t understand the instructions here. Could someone explain in other words what is required?

Your code so far

# returns a string composed of n times of a character. Used both inside and outside of Category class
def repeat_char(char, n):
    return ''.join([char for i in range(n)])

class Category:
    list = []

    def __init__(self, category):
        self.category = category
        self.ledger = []
        Category.list.append(self) 

    def __str__(self):
        result_str = self.center_title(self.category, 30) + '\n'
        for entry in self.ledger:
            result_str += self.display_line(entry['description'], entry['amount'], 30, 23) + '\n'
        result_str += self.display_total() + '\n'
        return result_str

    # returns the title of the category's edition
    def center_title(self, category, line_size):
        chars_to_fill = line_size - len(category)
        left_side = repeat_char('*', chars_to_fill // 2)
        right_side = left_side if chars_to_fill % 2 == 0 else left_side + '*'
        return left_side + category + right_side

    # returns a category line item
    def display_line(self, description, amount, line_size, desc_size):
        left_side = description if len(description) <= 23 else description[:23]
        right_side = '{:.2f}'.format(float(amount))
        chars_to_fill = line_size - len(left_side) - len(right_side)
        center = repeat_char(' ', chars_to_fill)
        return left_side + center + right_side

    def display_total(self):
        return 'Total: ' + str('{:.2f}'.format(self.get_balance()))

    # expenses are all negative entries not including transfers 
    def total_expenses(self):
        return round(-sum([entry['amount'] for entry in self.ledger if (entry['amount'] < 0 and entry['description'][:8] != 'Transfer')]), 2)

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

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

    def get_balance(self):        
        return sum([entry['amount'] for entry in self.ledger])

    def transfer(self, amount, other_instance):
        if self.check_funds(amount):
            self.withdraw(amount, 'Transfer to ' + other_instance.category)
            other_instance.deposit(amount, 'Transfer from ' + self.category)
            return True
        return False
    
    def check_funds(self, amount):
        if amount <= self.get_balance():
            return True
        return False    

# returns column header
def draw_top_left(level):
    chars_to_fill = 3 - len(str(level))
    return repeat_char(' ', chars_to_fill) + str(level) + '|'

# returns ' o ' to fill the bars when relevant
def draw_top_col(level, share):
    return repeat_char(' ', 3) if level > share else ' o ' 

# returns a seperate line between bars and corresponding names
def draw_sep_line(no_of_cat):
    line = '    '
    for i in range(no_of_cat):
        line += '---'
    return line + '-\n'    

# lines below the separate line all start with '    '
def draw_low_left():
    return repeat_char(' ', 4)

# returns the letter at index row of the name of the category at col index 
def draw_low_col(categories, row, col):
    if row >= len(categories[col].category):
        res_str = repeat_char(' ', 3)
    else:
        category = categories[col].category
        res_str = ' ' + category[row] + ' '
    return res_str

# gets the length of the longest category name
def max_len(categories):
    return max([len(category.category) for category in categories])

# builds a bar chart based on expenses in each category
def create_spend_chart(categories):
    total = round(sum([category.total_expenses() for category in categories]), 2)
    shares = []
    for category in categories: 
        share = int (100 * category.total_expenses() // total)
        shares.append(share)
    result_str = 'Percentage spent by category' + '\n'
    for level in range(100, -1, -10):
        result_str += draw_top_left(level)
        print(f'')
        for col_no in range(len(shares)):
            result_str += draw_top_col(level, shares[col_no])
        result_str += ' \n'
    result_str += draw_sep_line(len(shares))
    for row_no in range(0, max_len(categories)):
        result_str += draw_low_left()
        for col_no in range(len(categories)):
            result_str += draw_low_col(categories, row_no, col_no)
        if row_no < max_len(categories) - 1:
            result_str +=  ' \n'
        else:
            result_str +=  ' '
    return result_str

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(30.25, 'shirts')
auto = Category('Auto')
auto.deposit(150, 'deposit')
auto.withdraw(25, 'gas')
auto.withdraw(20, 'overhaul')
clothing.withdraw(15.25, 't-shirts')
food.withdraw(125, 'office cafeteria')
print(food)
print(clothing)
print(auto)
print(create_spend_chart(Category.list))

Your browser information:

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

Challenge Information:

Build a Budget App Project - Build a Budget App Project

There is an example, if you print the food category with the example data

print(food)

It should look just like this:

*************Food*************
initial deposit        1000.00
groceries               -10.15
restaurant and more foo -15.89
Transfer to Clothing    -50.00
Total: 923.96

What does your output look like?

Ok, I got it. I had an extra ‘\n’ after displaying the result and that was not expected in the example.
Thanks a lot for your help.

1 Like