Please check if unit tests has a mistake

This is from: https://www.freecodecamp.org/learn/scientific-computing-with-python/scientific-computing-with-python-projects/budget-app

Hi there, it might be me missing something so i’m sorry if it’s my mistake.

This function is supposed to return the percentage of the spent amount, rounded to nearest 10 multiple, for example 55 rounds to 60, 54 to 50.

In this case we have 900$ initially and then spend 105.55$, so as I understood the percentage should be (105.55 / 900) * 100 = ~12% which would round to 10%.

And in the unit test it says the expected result in this one is for the spent percentage to be rounded to 70%…
There is also another case like this one, on the same test.

If you could check it I would be very grateful.

I will leave my code below, and after the unit test:


import math

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

  def getname(self):
    return self.name

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

  def get_balance(self):
    balance = 0
    for movement in self.getledger():
      balance += movement["amount"]
    return balance

  def get_spent_percentage(self):
    gain = 0
    for movement in self.getledger():
      gain += movement["amount"] if movement["amount"] > 0 else 0

    return math.floor( 10 - ((self.get_balance() / gain) * 10)) * 10
  
  
  def transfer(self, amount, other_budget):
    if self.check_funds(amount):
      self.withdraw(amount, f"Transfer to {other_budget.getname()}")
      other_budget.deposit(amount, f"Transfer from {self.getname()}")
      return True
    else:
      return False
  
  def check_funds(self, amount):
    if amount > self.get_balance():
      return False
    else: 
      return True

  def __str__(self):
    s = ''
    s += f"*************{self.getname()}*************\n"
    for move in self.getledger():
      desc = move["description"]
      amnt = move["amount"]
      
      #lim = 23 if len(move["description"]) > 23

      s += f"{desc[:23] :23}"
      s += f"{amnt :7.2f}\n"
    s += f"Total: {self.get_balance()}"
    return s
    
def create_spend_chart(categories):
  s = "Percentage spent by category\n"
  spent_percentages = [cat.get_spent_percentage() for cat in categories]
  sep = ' '
  for i in range(100, -1, -10):
    s += f"{i :>3}|"
    for z in range(0, len(categories)):
      s += sep
      s += "o" if spent_percentages[z] >= i else sep
      s += sep
    s += f'{sep}\n'
  s += f'    {"---" * len(categories)}--\n'
  
  for n in range(max([len(cat.getname()) for cat in categories])):
    s += f"{sep :>5}"
    
    for cat in categories:
      s += sep
      s += cat.getname()[n] if len(cat.getname()) - 1 >= n else sep
      s += sep
    s += f'\n'

  return s

This is the unit test (each of the self objects is a Category object):

def test_create_spend_chart(self):
        self.food.deposit(900, "deposit")
        self.entertainment.deposit(900, "deposit")
        self.business.deposit(900, "deposit")

        self.food.withdraw(105.55)
        self.entertainment.withdraw(33.40)
        self.business.withdraw(10.99)

        actual = create_spend_chart([self.business, self.food, self.entertainment])
        expected = "Percentage spent by category\n100|          \n 90|          \n 80|          \n 70|    o     \n 60|    o     \n 50|    o     \n 40|    o     \n 30|    o     \n 20|    o  o  \n 10|    o  o  \n  0| o  o  o  \n    ----------\n     B  F  E  \n     u  o  n  \n     s  o  t  \n     i  d  e  \n     n     r  \n     e     t  \n     s     a  \n     s     i  \n           n  \n           m  \n           e  \n           n  \n           t  "
        self.assertEqual(actual, expected, 'Expected different chart representation. Check that all spacing is exact.')

As you can see on the expected variable in the unit test, it has a ‘o’ on the 70, related to the food object. Which is the example i cited in the beginning.

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (’).

The unit test is correct. 70% of the money that was spent came from that category.

Oh i understand now.
Sorry I didn’t read it well.

Thanks a lot for the quickest answer I’ve ever got.

Cheers!

1 Like

Its a question I have seen a couple of times. Its a tricky explanation to make clear.

1 Like