What does this AssertionError mean in the context of my code? FAIL: test_arrangement (test_module.UnitTests)

I’m working on an arithmetic arranger problem.

The program arranges and returns the problem as shown below in the console output. It is a function that accepts two parameters: a list where each item is an addition or subtraction problem, and an optional second argument that, when true, displays each answer beneath the dashes under each problem.

To me, it looks like the program is failing 1 out of the 6 tests in the test_module file.

Here’s the console output when I run the program, the error is shown here:

python main.py
   32      3801      50      123        12
+ 698    -    2    + 50    -  49    + 3600
-----    ------    ----    -----    ------
  730      3799     100       74      3612
F.....
======================================================================
FAIL: test_arrangement (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/boilerplate-arithmetic-formatter-4/test_module.py", line 10, in test_arrangement
    self.assertEqual(actual, expected, 'Expected different output when calling "arithmetic_arranger()" with ["3 + 855", "3801 - 2", "45 + 43", "123 + 49"]')
AssertionError: '    [68 chars]-    ------    ----    -----\n  858      3799      88      172' != '    [68 chars]-    ------    ----    -----'
      3      3801      45      123
  + 855    -    2    + 43    +  49
- -----    ------    ----    -----
?                                 -
+ -----    ------    ----    ------   858      3799      88      172 : Expected different output when calling "arithmetic_arranger()" with ["3 + 855", "3801 - 2", "45 + 43", "123 + 49"]

----------------------------------------------------------------------
Ran 6 tests in 0.006s

FAILED (failures=1)

The contents of my main.py file:

# This entrypoint file to be used in development. Start by reading README.md
from arithmetic_arranger import arithmetic_arranger
from unittest import main


print(arithmetic_arranger(["32 + 698", "3801 - 2", "50 + 50", "123 - 49", "12 + 3600"], True))


# Run unit tests automatically
main(module='test_module', exit=False)

The contents of my arithmetic_arranger.py file:

def arithmetic_arranger(problems, results):
  if len(problems) > 5:
    return 'Error: Too many problems.'
  
  top = []
  bottom = []
  dashes = []
  spaces = '    '
  answers = []

# ["32 + 698", "3801 - 2", "50 + 50", "123 - 49", "12 + 3600"]

  for problem in problems:
    first = '  ' + problem.split()[0]
    second = problem.split(' ', 1)[1]
    length_first = len(first)
    length_second = len(second)
    difference_first = length_first - length_second
    difference_second = length_second - length_first

    width_first = len(problem.split()[0])
    width_second = len(problem.split()[2])

    if width_first > 4 or width_second > 4:
      return "Error: Numbers cannot be more than four digits."
      
    if second[0] != '+' and second[0] != '-':
      return "Error: Operator must be '+' or '-'."
    
    if first.lstrip().isdigit() != True or second[2:].isdigit() != True:
      return 'Error: Numbers must only contain digits.'
    
    if difference_first > 0:
      second = second[0] + ' ' * (difference_first + 1) + second[2:]
    elif difference_second > 0:
      first = ' ' * difference_second + first

    # Optional condition to display answers under problems:
    if results:
      if second[0] == '+':
        answer = int(first) + int(second[2:])
      else:
        answer = int(first) - int(second[2:])

      answer_to_string = str(answer)
      length_result = len(answer_to_string)
      answer_to_string = '  ' + answer_to_string
      length_maximum = max([len(first.lstrip()), len(second[1:].lstrip())])

      if length_maximum > length_result:
        answer_to_string = ' ' * (length_maximum - length_result) + answer_to_string
      elif length_maximum < length_result:
        answer_to_string = answer_to_string[1:]

      answers.append(answer_to_string)

  # Append variables to lists
    top.append(first)
    bottom.append(second)
    dashes.append('-' * len(second))

  # Set spacing
    spaced_top = spaces.join(top)
    spaced_bottom = spaces.join(bottom)
    spaced_dashes = spaces.join(dashes)
    spaced_answers = spaces.join(answers)
  
  return spaced_top + '\n' + spaced_bottom + '\n' + spaced_dashes + '\n' + spaced_answers

The contents of my test_module.py file:

import unittest
from arithmetic_arranger import arithmetic_arranger


# the test case
class UnitTests(unittest.TestCase):
    def test_arrangement(self):
        actual = arithmetic_arranger(["3 + 855", "3801 - 2", "45 + 43", "123 + 49"], True)
        expected = "    3      3801      45      123\n+ 855    -    2    + 43    +  49\n-----    ------    ----    -----"
        self.assertEqual(actual, expected, 'Expected different output when calling "arithmetic_arranger()" with ["3 + 855", "3801 - 2", "45 + 43", "123 + 49"]')

        actual = arithmetic_arranger(["11 + 4", "3801 - 2999", "1 + 2", "123 + 49", "1 - 9380"], True)
        expected = "  11      3801      1      123         1\n+  4    - 2999    + 2    +  49    - 9380\n----    ------    ---    -----    ------"
        self.assertEqual(actual, expected, 'Expected different output when calling "arithmetic_arranger()" with ["11 + 4", "3801 - 2999", "1 + 2", "123 + 49", "1 - 9380"]')

    def test_too_many_problems(self):
        actual = arithmetic_arranger(["44 + 815", "909 - 2", "45 + 43", "123 + 49", "888 + 40", "653 + 87"], True)
        expected = "Error: Too many problems."
        self.assertEqual(actual, expected, 'Expected calling "arithmetic_arranger()" with more than five problems to return "Error: Too many problems."')

    def test_incorrect_operator(self):
        actual = arithmetic_arranger(["3 / 855", "3801 - 2", "45 + 43", "123 + 49"], True)
        expected = "Error: Operator must be '+' or '-'."
        self.assertEqual(actual, expected, '''Expected calling "arithmetic_arranger()" with a problem that uses the "/" operator to return "Error: Operator must be '+' or '-'."''')
        
    def test_too_many_digits(self):
        actual = arithmetic_arranger(["24 + 85215", "3801 - 2", "45 + 43", "123 + 49"], True)
        expected = "Error: Numbers cannot be more than four digits."
        self.assertEqual(actual, expected, 'Expected calling "arithmetic_arranger()" with a problem that has a number over 4 digits long to return "Error: Numbers cannot be more than four digits."')

    def test_only_digits(self):
        actual = arithmetic_arranger(["98 + 3g5", "3801 - 2", "45 + 43", "123 + 49"], True)
        expected = "Error: Numbers must only contain digits."
        self.assertEqual(actual, expected, 'Expected calling "arithmetic_arranger()" with a problem that contains a letter character in the number to return "Error: Numbers must only contain digits."')

    def test_solutions(self):
        actual = arithmetic_arranger(["32 - 698", "1 - 3801", "45 + 43", "123 + 49"], True)
        expected = "   32         1      45      123\n- 698    - 3801    + 43    +  49\n-----    ------    ----    -----\n -666     -3800      88      172"
        self.assertEqual(actual, expected, 'Expected solutions to be correctly displayed in output when calling "arithmetic_arranger()" with arithmetic problems and a second argument of `True`.')


if __name__ == "__main__":
    unittest.main()

Any help on why I’m getting this error is appreciated, thank you!

Answer returned by function is not matching expected one. It is returning answer with results of calculated problems, but this test isn’t (shouldn’t) requiring that. Looking at the test_module.py, test function calls were modified, to always require calculated problems.

I’m not sure I understand what you’re saying. What should I change to fix the problem?

I’d suggest starting with reverting test_module.py to the original version, otherwise tests may give results more strange than they should or seemingly incorrect.

Here is the output when I revert test_module.py to the original version:

 python main.py
   32      3801      50      123        12
+ 698    -    2    + 50    -  49    + 3600
-----    ------    ----    -----    ------
  730      3799     100       74      3612
EEE.EE
======================================================================
ERROR: test_arrangement (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/boilerplate-arithmetic-formatter-4/test_module.py", line 8, in test_arrangement
    actual = arithmetic_arranger(["3 + 855", "3801 - 2", "45 + 43", "123 + 49"])
TypeError: arithmetic_arranger() missing 1 required positional argument: 'results'

======================================================================
ERROR: test_incorrect_operator (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/boilerplate-arithmetic-formatter-4/test_module.py", line 22, in test_incorrect_operator
    actual = arithmetic_arranger(["3 / 855", "3801 - 2", "45 + 43", "123 + 49"])
TypeError: arithmetic_arranger() missing 1 required positional argument: 'results'

======================================================================
ERROR: test_only_digits (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/boilerplate-arithmetic-formatter-4/test_module.py", line 32, in test_only_digits
    actual = arithmetic_arranger(["98 + 3g5", "3801 - 2", "45 + 43", "123 + 49"])
TypeError: arithmetic_arranger() missing 1 required positional argument: 'results'

======================================================================
ERROR: test_too_many_digits (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/boilerplate-arithmetic-formatter-4/test_module.py", line 27, in test_too_many_digits
    actual = arithmetic_arranger(["24 + 85215", "3801 - 2", "45 + 43", "123 + 49"])
TypeError: arithmetic_arranger() missing 1 required positional argument: 'results'

======================================================================
ERROR: test_too_many_problems (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/boilerplate-arithmetic-formatter-4/test_module.py", line 17, in test_too_many_problems
    actual = arithmetic_arranger(["44 + 815", "909 - 2", "45 + 43", "123 + 49", "888 + 40", "653 + 87"])
TypeError: arithmetic_arranger() missing 1 required positional argument: 'results'

----------------------------------------------------------------------
Ran 6 tests in 0.002s

FAILED (errors=5)

Function is defined as always requiring two arguments, while the second one should be optional per specification.

This is really helpful, I see what you’re saying. However I’m unsure how to define the function so that the second argument is optional.

Here is how my function is currently written:

def arithmetic_arranger(problems, results)

Inside the function, I run a conditional if results is true. I thought this would make it optional. What am I missing?

Thank you!

Check in function can be done for what that optional parameter is exactly, but that will not be enough to allow calling function without that parameter. For that it needs to be made as optional in the signature.

For example, the following function accepts name parameter and if it’s passed it will use it in print. If function would be called without any argument - greet() it will use the optional, default value of name, which is 'stranger' in this case.

def greet(name='stranger'):
     print('Hello', name)
1 Like

Thank you! I will try this!