Python Budget App create_spend_chart categories

Hi folks, maybe someone can help me with the following.

I’m on the Scientific Computing with Python Budget App project. My program has passed all the tests except the chart. However, I’m coming across a problem with the chart in the tests.

Whenever I try to run the test, my chart is made using the print(create_spend_chart([food, clothing, auto])) line in ‘main.py’.
However, the test is looking for a chart created by the line:
actual = create_spend_chart([self.business, self.food, self.entertainment])

My chart is therefore different from the expected result:

Is there a reason why the test would be creating a different chart from the one it expects?

My code:

class Category:

    def __init__(self, category):
        self.category = category
        self.ledger = list()
        self.balance = 0
        self.total_spend = float()
        self.percentage_total = 0
        self.percent_points = []

    def deposit(self, amount, description = ""):
        self.ledger.append({"amount": round(float(amount),2), "description": description})
        self.balance = self.balance + amount


    def withdraw(self, amount, description = ""):
        if self.check_funds(amount) is True:
            self.ledger.append({"amount": -1 * round(float(amount),2), "description": description})
            self.balance = self.balance - amount
            self.total_spend = self.total_spend + amount
            return True
        else:
            return False
    def get_balance(self):
        return self.balance

    def transfer(self, amount, target_cat):
        if self.check_funds(amount) is True:
            self.withdraw(amount, "Transfer to " + target_cat.category)
            target_cat.deposit(amount, "Transfer from " + self.category)
            return True
        else:
            return  False

    def check_funds(self, amount):
        check_amount = amount
        if self.balance >= check_amount:
            return True
        else:
            return False
    def round_to_ten(self,number):
        if number < 10:
            return 0
        else:
            return  int(number)

    def get_withdrawals(self):
        total = 0
        for item in self.ledger:
            if item["amount"] < 0:
                total += item["amount"]
        return total



    def __str__(self):
        ledger_print = """"""
        for entry in self.ledger:
            ledger_print += str(entry["description"][:23]).ljust(23) + str(format(entry["amount"], '.2f')).rjust(7) + "\n"

        return  (str(self.category).center(30,"*") + "\n" + ledger_print + 'Total: ' + str(self.balance))


def total_spend(categories):
    all_total_spend = float()
    # work out total spend
    for category in categories:
        cat_spend = category.get_withdrawals()
        all_total_spend = all_total_spend + cat_spend
    return all_total_spend

def cat_percent(categories, all_total_spend):
    # % total spend for each category
    percent_by_cat = []
    for category in categories:
        category.percentage_total = (-1 * (category.total_spend / all_total_spend)) * 100
        category.percent_points = int(category.percentage_total)
        percent_by_cat.append(category.percent_points)

    return percent_by_cat


def create_spend_chart(cats):

    # works out longest name
    name_length = 0
    for category in cats:
        if len(category.category) > name_length:
            name_length = len(category.category)

    # setting up output string dimensions
    output = ""
    num_cats = 0
    spaces = 7
    for category in cats:
        num_cats +=1
        spaces += 2

    # calculate no of dashes
    dashes = ("-" * (spaces-4)).rjust(spaces)

    # calculates total spend and percentage per category, puts percentages into dictionary
    all_total_spend = total_spend(cats)
    percent_by_cat = cat_percent(cats, all_total_spend)

    #adds bars to output string
    y_axis = 100
    cat_spaces = str()
    filler = str()
    output_line = ""
    while y_axis > -1:
        filler = list()
        lister_iter = 0
        for x in percent_by_cat:
            if x >= y_axis:
                filler.append('{}'.format("o  "))
            else:
                filler.append('{}'.format("   "))
        lister_iter += 1
        filler_str = "".join(filler)
        output += str(y_axis).rjust(3) + "| " + filler_str + "\n"
        y_axis -= 10
    

    output += dashes



    return output









Your browser information:

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

Challenge: Budget App

Link to the challenge:

Any solutions would be appreciated!

Welcome to the forums.

When I test your code, I get the following report

    self.assertEqual(actual, expected, 'Expected different chart representation. Check that all spacing is exact.')
AssertionError: '100|          \n 90|          \n 80|     [144 chars]----' != 'Percentage spent by category\n100|       [383 chars] t  '
+ Percentage spent by category
  100|          
   90|          
   80|          
   70|    o     
   60|    o     
   50|    o     
   40|    o     
   30|    o     
   20|    o  o  
   10|    o  o  
    0| o  o  o  
-     ---------+     ----------
?              ++
+      B  F  E  
+      u  o  n  
+      s  o  t  
+      i  d  e  
+      n     r  
+      e     t  
+      s     a  
+      s     i  
+            n  
+            m  
+            e  
+            n  
+            t   : Expected different chart representation. Check that all spacing is exact.

The test is importing your code and running your create_spend_chart() function in both the print() call and the test. The error is telling you that the output of your code does not match what it expects. Further, the lines beginning with + (green) indicate lines that are missing in your output. The - lines (red) show lines that are present but different from expected.

So according to the output your function is not producing the chart title and the categories and the line between the chart and categories is not exactly right.

set MaxDiff=None in the test_module.py so you see what lines you need to fix like so:

class UnitTests(unittest.TestCase):
maxDiff=None
def setUp(self):
self.food = budget.Category(“Food”)
self.entertainment = budget.Category(“Entertainment”)
self.business = budget.Category(“Business”)

Thanks so much for the help! Fully understanding the feedback and setting maxDiff got me where I needed to be.

Thanks!