Arithmetic Formatter (Scientific computing with python)

I wrote the code for the arithmetic formatter and the results shown by the print statement seem to be in order with the rules stated. However, my code is failing all the tests except for the ones which require raising an error.
Can someone please tell me the reason behind this?

#Helper func to check for requirements
def req_check(elements:list) -> None:
  #Raises exception if digits>4
  if len(a := elements[0])>4 or len(b := elements[2])>4:
    raise Exception("Error: Numbers cannot be more than four digits.")
  #Raises exception if numbers contain non-digits
  if not a.isdigit() or not b.isdigit():
    raise Exception("Error: Numbers must only contain digits.")
  #Raises exception if invalid operation
  if elements[1] not in ('+','-'):
    raise Exception ("Error: Operator must be '+' or '-'.")
  return

def arithmetic_arranger(problems, results=False):
  #Raises error if more then 5 problems.
  if len(problems)>5:
    raise Exception("Error: Too many problems.")

  #A list for each line
  line_1=[]
  line_2=[]
  line_3=[]
  line_res=[]

  for ind, problem in enumerate(problems):
    elements=problem.split()
    #checking reqs
    req_check(elements)

    #Assinging vars
    a=elements[0]
    b=elements[2]
    operator=elements[1]
    n=max(len(a), len(b)) #len of largest number
    
    if operator=='+':
      answer=str(int(a)+int(b))
    else:
      answer=str(int(a)-int(b))

    #This is to ensure that there isn't an extra space at the end
    if problems[ind]!=problems[-1]:
      spc=" "*4
    else:
      spc=''
    line_1.append(f"{a:>{n+2}}{spc}")
    line_2.append(f"{operator} {b:>{n}}{spc}")
    line_3.append(f"{'_'*(n+2)}{spc}")
    line_res.append(f"{answer:>{n+2}}{spc}")

  #converting lists to strings
  line_1=''.join(line_1)
  line_2=''.join(line_2)
  line_3=''.join(line_3)
  line_res=''.join(line_res)

  #Creating final result
  arranged_problems=f"{line_1}\n{line_2}\n{line_3}"
  if results:
    arranged_problems+=f"\n{line_res}"
  print (arranged_problems)
  return arranged_problems

What error/fail specifically are you getting?

I’m getting an assertion error, ie, the output is not the expected output for all problems except the ones that ask you to raise an error due to requirements not being met.
The console result is as follows:

 python main.py
   32      3801      45      123
+ 698    -    2    + 43    +  49
_____    ______    ____    _____
   32      3801      45      123
+ 698    -    2    + 43    +  49
_____    ______    ____    _____
======================= test session starts =======================
platform linux -- Python 3.8.13, pytest-7.1.1, pluggy-1.0.0 -- /nix/store/06c55y0c5yzx5gx4l6k0pp6071zf1y5i-python3-3.8.13/bin/python
cachedir: .pytest_cache
rootdir: /home/runner/boilerplate-arithmetic-formatter
collected 10 items                                                

test_module.py::test_template[test_two_problems_arrangement1] FAILED [ 10%]
test_module.py::test_template[test_two_problems_arrangement2] FAILED [ 20%]
test_module.py::test_template[test_four_problems_arrangement] FAILED [ 30%]
test_module.py::test_template[test_five_problems_arrangement] FAILED [ 40%]
test_module.py::test_template[test_too_many_problems] FAILED [ 50%]
test_module.py::test_template[test_incorrect_operator] FAILED [ 60%]
test_module.py::test_template[test_too_many_digits] FAILED  [ 70%]
test_module.py::test_template[test_only_digits] FAILED      [ 80%]
test_module.py::test_template[test_two_problems_with_solutions] FAILED [ 90%]
test_module.py::test_template[test_five_problems_with_solutions] FAILED [100%]

============================ FAILURES =============================
__________ test_template[test_two_problems_arrangement1] __________

arguments = [['3801 - 2', '123 + 49']]
expected_output = '  3801      123\n-    2    +  49\n------    -----'
fail_message = 'Expected different output when calling "arithmetic_arranger()" with ["3801 - 2", "123 + 49"]'

    @pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
    def test_template(arguments, expected_output, fail_message):
        actual = arithmetic_arranger(*arguments)
>       assert actual == expected_output, fail_message
E       AssertionError: Expected different output when calling "arithmetic_arranger()" with ["3801 - 2", "123 + 49"]
E       assert '  3801      123\n-    2    +  49\n______    _____' == '  3801      123\n-    2    +  49\n------    -----'
E             3801      123
E           -    2    +  49
E         - ------    -----
E         + ______    _____

test_module.py:77: AssertionError
---------------------- Captured stdout call -----------------------
  3801      123
-    2    +  49
______    _____
__________ test_template[test_two_problems_arrangement2] __________

arguments = [['1 + 2', '1 - 9380']]
expected_output = '  1         1\n+ 2    - 9380\n---    ------'
fail_message = 'Expected different output when calling "arithmetic_arranger()" with ["1 + 2", "1 - 9380"]'

    @pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
    def test_template(arguments, expected_output, fail_message):
        actual = arithmetic_arranger(*arguments)
>       assert actual == expected_output, fail_message
E       AssertionError: Expected different output when calling "arithmetic_arranger()" with ["1 + 2", "1 - 9380"]
E       assert '  1         1\n+ 2    - 9380\n___    ______' == '  1         1\n+ 2    - 9380\n---    ------'
E             1         1
E           + 2    - 9380
E         - ---    ------
E         + ___    ______

test_module.py:77: AssertionError
---------------------- Captured stdout call -----------------------
  1         1
+ 2    - 9380
___    ______
__________ test_template[test_four_problems_arrangement] __________

arguments = [['3 + 855', '3801 - 2', '45 + 43', '123 + 49']]
expected_output = '    3      3801      45      123\n+ 855    -    2    + 43    +  49\n-----    ------    ----    -----'
fail_message = 'Expected different output when calling "arithmetic_arranger()" with ["3 + 855", "3801 - 2", "45 + 43", "123 + 49"]'

    @pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
    def test_template(arguments, expected_output, fail_message):
        actual = arithmetic_arranger(*arguments)
>       assert actual == expected_output, fail_message
E       AssertionError: Expected different output when calling "arithmetic_arranger()" with ["3 + 855", "3801 - 2", "45 + 43", "123 + 49"]
E       assert ('    3      3801      45      123\n'\n '+ 855    -    2    + 43    +  49\n'\n '_____    ______    ____    _____') == ('    3      3801      45      123\n'\n '+ 855    -    2    + 43    +  49\n'\n '-----    ------    ----    -----')
E               3      3801      45      123
E           + 855    -    2    + 43    +  49
E         - -----    ------    ----    -----
E         + _____    ______    ____    _____

test_module.py:77: AssertionError
---------------------- Captured stdout call -----------------------
    3      3801      45      123
+ 855    -    2    + 43    +  49
_____    ______    ____    _____
__________ test_template[test_five_problems_arrangement] __________

arguments = [['11 + 4', '3801 - 2999', '1 + 2', '123 + 49', '1 - 9380']]
expected_output = '  11      3801      1      123         1\n+  4    - 2999    + 2    +  49    - 9380\n----    ------    ---    -----    ------'
fail_message = 'Expected different output when calling "arithmetic_arranger()" with ["11 + 4", "3801 - 2999", "1 + 2", "123 + 49", "1 - 9380"]'

    @pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
    def test_template(arguments, expected_output, fail_message):
        actual = arithmetic_arranger(*arguments)
>       assert actual == expected_output, fail_message
E       AssertionError: Expected different output when calling "arithmetic_arranger()" with ["11 + 4", "3801 - 2999", "1 + 2", "123 + 49", "1 - 9380"]
E       assert ('  11      3801      1      123         1\n'\n '+  4    - 2999    + 2    +  49    - 9380\n'\n '____    ______    ___    _____    ______') == ('  11      3801      1      123         1\n'\n '+  4    - 2999    + 2    +  49    - 9380\n'\n '----    ------    ---    -----    ------')
E             11      3801      1      123         1
E           +  4    - 2999    + 2    +  49    - 9380
E         - ----    ------    ---    -----    ------
E         + ____    ______    ___    _____    ______

test_module.py:77: AssertionError
---------------------- Captured stdout call -----------------------
  11      3801      1      123         1
+  4    - 2999    + 2    +  49    - 9380
____    ______    ___    _____    ______
______________ test_template[test_too_many_problems] ______________

arguments = [['44 + 815', '909 - 2', '45 + 43', '123 + 49', '888 + 40', '653 + 87']]
expected_output = 'Error: Too many problems.'
fail_message = 'Expected calling "arithmetic_arranger()" with more than five problems to return "Error: Too many problems."'

    @pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
    def test_template(arguments, expected_output, fail_message):
>       actual = arithmetic_arranger(*arguments)

test_module.py:76: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

problems = ['44 + 815', '909 - 2', '45 + 43', '123 + 49', '888 + 40', '653 + 87']
results = False

    def arithmetic_arranger(problems, results=False):
      #Raises error if more then 5 problems.
      if len(problems)>5:
>       raise Exception("Error: Too many problems.")
E       Exception: Error: Too many problems.

arithmetic_arranger.py:17: Exception
_____________ test_template[test_incorrect_operator] ______________

arguments = [['3 / 855', '3801 - 2', '45 + 43', '123 + 49']]
expected_output = "Error: Operator must be '+' or '-'."
fail_message = 'Expected calling "arithmetic_arranger()" with a problem that uses the "/" operator to return "Error: Operator must be \'+\' or \'-\'."'

    @pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
    def test_template(arguments, expected_output, fail_message):
>       actual = arithmetic_arranger(*arguments)

test_module.py:76: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
arithmetic_arranger.py:28: in arithmetic_arranger
    req_check(elements)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

elements = ['3', '/', '855']

    def req_check(elements:list) -> None:
      #Raises exception if digits>4
      if len(a := elements[0])>4 or len(b := elements[2])>4:
        raise Exception("Error: Numbers cannot be more than four digits.")
      #Raises exception if numbers contain non-digits
      if not a.isdigit() or not b.isdigit():
        raise Exception("Error: Numbers must only contain digits.")
      #Raises exception if invalid operation
      if elements[1] not in ('+','-'):
>       raise Exception ("Error: Operator must be '+' or '-'.")
E       Exception: Error: Operator must be '+' or '-'.

arithmetic_arranger.py:11: Exception
_______________ test_template[test_too_many_digits] _______________

arguments = [['24 + 85215', '3801 - 2', '45 + 43', '123 + 49']]
expected_output = 'Error: Numbers cannot be more than four digits.'
fail_message = '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."'

    @pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
    def test_template(arguments, expected_output, fail_message):
>       actual = arithmetic_arranger(*arguments)

test_module.py:76: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
arithmetic_arranger.py:28: in arithmetic_arranger
    req_check(elements)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

elements = ['24', '+', '85215']

    def req_check(elements:list) -> None:
      #Raises exception if digits>4
      if len(a := elements[0])>4 or len(b := elements[2])>4:
>       raise Exception("Error: Numbers cannot be more than four digits.")
E       Exception: Error: Numbers cannot be more than four digits.

arithmetic_arranger.py:5: Exception
_________________ test_template[test_only_digits] _________________

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

    @pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
    def test_template(arguments, expected_output, fail_message):
>       actual = arithmetic_arranger(*arguments)

test_module.py:76: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
arithmetic_arranger.py:28: in arithmetic_arranger
    req_check(elements)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

elements = ['98', '+', '3g5']

    def req_check(elements:list) -> None:
      #Raises exception if digits>4
      if len(a := elements[0])>4 or len(b := elements[2])>4:
        raise Exception("Error: Numbers cannot be more than four digits.")
      #Raises exception if numbers contain non-digits
      if not a.isdigit() or not b.isdigit():
>       raise Exception("Error: Numbers must only contain digits.")
E       Exception: Error: Numbers must only contain digits.

arithmetic_arranger.py:8: Exception
_________ test_template[test_two_problems_with_solutions] _________

arguments = [['3 + 855', '988 + 40'], True]
expected_output = '    3      988\n+ 855    +  40\n-----    -----\n  858     1028'
fail_message = 'Expected solutions to be correctly displayed in output when calling "arithmetic_arranger()" with ["3 + 855", "988 + 40"] and a second argument of `True`.'

    @pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
    def test_template(arguments, expected_output, fail_message):
        actual = arithmetic_arranger(*arguments)
>       assert actual == expected_output, fail_message
E       AssertionError: Expected solutions to be correctly displayed in output when calling "arithmetic_arranger()" with ["3 + 855", "988 + 40"] and a second argument of `True`.
E       assert '    3      988\n+ 855    +  40\n_____    _____\n  858     1028' == '    3      988\n+ 855    +  40\n-----    -----\n  858     1028'
E               3      988
E           + 855    +  40
E         - -----    -----
E         + _____    _____
E             858     1028

test_module.py:77: AssertionError
---------------------- Captured stdout call -----------------------
    3      988
+ 855    +  40
_____    _____
  858     1028
________ test_template[test_five_problems_with_solutions] _________

arguments = [['32 - 698', '1 - 3801', '45 + 43', '123 + 49', '988 + 40'], True]
expected_output = '   32         1      45      123      988\n- 698    - 3801    + 43    +  49    +  40\n-----    ------    ----    -----    -----\n -666     -3800      88      172     1028'
fail_message = 'Expected solutions to be correctly displayed in output when calling "arithmetic_arranger()" with five arithmetic problems and a second argument of `True`.'

    @pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
    def test_template(arguments, expected_output, fail_message):
        actual = arithmetic_arranger(*arguments)
>       assert actual == expected_output, fail_message
E       AssertionError: Expected solutions to be correctly displayed in output when calling "arithmetic_arranger()" with five arithmetic problems and a second argument of `True`.
E       assert ('   32         1      45      123      988\n'\n '- 698    - 3801    + 43    +  49    +  40\n'\n '_____    ______    ____    _____    _____\n'\n ' -666     -3800      88      172     1028') == ('   32         1      45      123      988\n'\n '- 698    - 3801    + 43    +  49    +  40\n'\n '-----    ------    ----    -----    -----\n'\n ' -666     -3800      88      172     1028')
E              32         1      45      123      988
E           - 698    - 3801    + 43    +  49    +  40
E         - -----    ------    ----    -----    -----
E         + _____    ______    ____    _____    _____
E            -666     -3800      88      172     1028

test_module.py:77: AssertionError
---------------------- Captured stdout call -----------------------
   32         1      45      123      988
- 698    - 3801    + 43    +  49    +  40
_____    ______    ____    _____    _____
 -666     -3800      88      172     1028
===================== short test summary info =====================
FAILED test_module.py::test_template[test_two_problems_arrangement1]
FAILED test_module.py::test_template[test_two_problems_arrangement2]
FAILED test_module.py::test_template[test_four_problems_arrangement]
FAILED test_module.py::test_template[test_five_problems_arrangement]
FAILED test_module.py::test_template[test_too_many_problems] - E...
FAILED test_module.py::test_template[test_incorrect_operator] - ...
FAILED test_module.py::test_template[test_too_many_digits] - Exc...
FAILED test_module.py::test_template[test_only_digits] - Excepti...
FAILED test_module.py::test_template[test_two_problems_with_solutions]
FAILED test_module.py::test_template[test_five_problems_with_solutions]
======================= 10 failed in 0.32s ========================

Take a closer look at the test output:

E       AssertionError: Expected different output when calling "arithmetic_arranger()" with ["3801 - 2", "123 + 49"]
E       assert '  3801      123\n-    2    +  49\n______    _____' == '  3801      123\n-    2    +  49\n------    -----'
E             3801      123
E           -    2    +  49
E         - ------    -----
E         + ______    _____

Specific difference is shown by the two last lines. Line starting with - is what was expected by test, line starting with + is what function returned.

1 Like

-----
_____

:grinning:

Ahh I see
I used _ instead of - for the line separation.
I didn’t know about the thing with given and expected output, so thanks for telling me about that.
Though now I’m failing tests for raising errors where I was supposed to raise errors ;-;. All its telling me is ‘exception’. Is this happening because I did something wrong or is this normal?

Here is one for example:

___________ test_template[test_too_many_digits] ____________

arguments = [['24 + 85215', '3801 - 2', '45 + 43', '123 + 49']]
expected_output = 'Error: Numbers cannot be more than four digits.'
fail_message = '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."'

    @pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
    def test_template(arguments, expected_output, fail_message):
>       actual = arithmetic_arranger(*arguments)

test_module.py:76: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
arithmetic_arranger.py:28: in arithmetic_arranger
    req_check(elements)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

elements = ['24', '+', '85215']

    def req_check(elements:list) -> None:
      #Raises exception if digits>4
      if len(a := elements[0])>4 or len(b := elements[2])>4:
>       raise Exception("Error: Numbers cannot be more than four digits.")
E       Exception: Error: Numbers cannot be more than four digits.

arithmetic_arranger.py:5: Exception

Small detail - function is not expected to raise such error, but to return the text as a string.

1 Like

You’re right!
Its all in order now.
TYSM for the quick and effective assist <3

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.