Build a Budget App Project - Build a Budget App Project

Tell us what’s happening:

I have been stuck on this spot for God knows how long. It keeps failing the last two tests. I don’t know what else to do at this point. I have attached screenshots of my output and errors from the browser console. Please kindly help. Thank you

Your code so far

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

    def deposit(self, amount, description=""):
        """Adds a deposit with the given amount and description to the ledger."""
        self.ledger.append({'amount': amount, 'description': description})

    def withdraw(self, amount, description=""):
        """Withdraws an amount from the category and stores as negative if there are sufficient funds."""
        if self.check_funds(amount):
            self.ledger.append({'amount': -amount, 'description': description})
            return True
        return False

    def get_balance(self):
        """Returns the current balance in the category."""
        return sum(entry['amount'] for entry in self.ledger)

    def transfer(self, amount, category):
        """Transfers an amount from this category to another category."""
        if self.check_funds(amount):
            self.withdraw(amount, f"Transfer to {category.name}")
            category.deposit(amount, f"Transfer from {self.name}")
            return True
        return False

    def check_funds(self, amount):
        """Checks if the amount is available in the category's balance."""
        return self.get_balance() >= amount

    def __str__(self):
        """Returns a string representation of the category with the ledger and total balance."""
        title = f"{self.name:*^30}"
        ledger_lines = []
        for entry in self.ledger:
            description = entry['description'][:23]  # Limit description to 23 characters
            amount = f"{entry['amount']:.2f}".rjust(30 - len(description))
            ledger_lines.append(f"{description}{amount}")
        
        total = f"Total: {self.get_balance():.2f}"
        return "\n".join([title] + ledger_lines + [total])


def create_spend_chart(categories):
    """Creates a bar chart of percentages spent by each category."""
    
    # Calculate total spent for each category
    total_spent = sum(
        sum(entry['amount'] for entry in category.ledger if entry['amount'] < 0)
        for category in categories
    )
    
    if total_spent == 0:
        return "Percentage spent by category\n    ----------\n"
    
    # Calculate percentage spent for each category and round down to the nearest 10
    percentages = []
    for category in categories:
        category_spent = sum(entry['amount'] for entry in category.ledger if entry['amount'] < 0)
        percentage = category_spent / total_spent * 100
        rounded_percentage = (percentage // 10) * 10  # Round down to the nearest 10
        percentages.append(rounded_percentage)
    
    # Create the bar chart
    chart = "Percentage spent by category\n"
    
    # Chart rows (percentages from 100 to 0)
    for i in range(100, -1, -10):
        chart += f"{i:3}| "  # Add percentage on the left side
        for percentage in percentages:
            chart += "o  " if percentage >= i else "   "  # Add 'o' or empty space depending on the percentage
        chart += "\n"  # New line after each row
    
    # Add the horizontal line
    chart += "    " + "-" * (len(categories) * 3 + 1) + "\n"
    
    # Add the category names vertically below the bars
    max_name_length = max(len(category.name) for category in categories)
    
    # Add category names vertically
    for i in range(max_name_length):
        chart += "     "  # Add spaces for alignment
        for j, category in enumerate(categories):
            # Add character from the category name or a space if index exceeds name length
            chart += category.name[i] if i < len(category.name) else " "
            
            # Only add space between categories if it's not the last one
            if j < len(categories) - 1:
                chart += "  "
        
        # After printing all categories in this row, add a newline
        chart += "\n"
    
    # Remove any unnecessary trailing spaces from the final chart
    return chart.strip()




# Example usage

# Creating categories and performing operations
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')
clothing.deposit(500, 'initial deposit')
clothing.withdraw(50, 'pants')
clothing.withdraw(75.50, 'shirt')

entertainment = Category('Entertainment')
entertainment.deposit(300, 'initial deposit')
entertainment.withdraw(120, 'movie tickets')
entertainment.withdraw(50, 'arcade')

# Transfer funds
food.transfer(50, clothing)

# Print category details
print(food)
print(clothing)
print(entertainment)

# Create and print the spend chart
categories = [food, clothing, entertainment]
print(create_spend_chart(categories))

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) 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

Generally in the test output:

  • line starting with - shows line returned from function
  • line starting with + shows expected line
  • line starting with ? shows where exactly is the difference
1 Like

Thank you for your response. I’m still unable to resolve the issue.

Try to check if all rows match the max length of the separator row and try to check if the columns max length is also always as the max length of the longest category name
Basically what I’m saying is check all empty spaces are there

1 Like

Let’s take a look at the Assertion Error

AssertionError: 'Perc[225 chars] F  E\n     u  o  n\n     s  o  t\n     i  d  [123 chars]   t' 
             != 'Perc[225 chars] F  E  \n     u  o  n  \n     s  o  t  \n     [149 chars] t  '

the first line is yours, the second is the expected. If you look at where the lines stat having differencies, you have the new line character immediately after the E, but the expected is that there are two more spaces before the new line character

Below is my new assert error. I think I’m very close. The issue I have now is that once I use the strip function (either rstrip or strip) on the chart that is to be returned it completely removes the required space as in the attached assertion error.

self.assertEqual(actual, expected, 'Expected different chart representation. Check that all spacing is exact.')
AssertionError: 'Perc[362 chars]           m  \n           e  \n           n  \n           t' 
             != 'Perc[362 chars]           m  \n           e  \n           n  \n           t  '

you are almost there, you are missing the two spaces at the end of the string

I figured it out and it worked. Thanks for the help