Arithmetic arranger Problems that I don't understand

I think I have found a possible solution to Arithmetic arranger. However, there are some errors I don’t clearly understand and I can’t solve.

In my code I return the elements as a string, but the following errors appear:

 python main.py
   32      3801      45      123    
+ 698    -    2    + 43    +  49    
-----    ------    ----    -----    
============================= test session starts ==============================
platform linux -- Python 3.8.12, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/runner/boilerplate-arithmetic-formatter
collected 10 items                                                             

test_module.py FFFF....FF                                                [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      ...    -----    ' == '  3801      ...----    -----'
E         -   3801      123
E         +   3801      123    
E         ?                ++++
E         - -    2    +  49
E         + -    2    +  49    
E         ?                ++++
E         - ------    -----...
E         
E         ...Full output truncated (3 lines hidden), use '-vv' to show

test_module.py:77: AssertionError
________________ 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         ...---    ------'
E         -   1         1
E         +   1         1    
E         ?              ++++
E         - + 2    - 9380
E         + + 2    - 9380    
E         ?              ++++
E         - ---    ------...
E         
E         ...Full output truncated (3 lines hidden), use '-vv' to show

test_module.py:77: AssertionError
________________ 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      3...    -----    ' == '    3      3...----    -----'
E         -     3      3801      45      123
E         +     3      3801      45      123    
E         ?                                 ++++
E         - + 855    -    2    + 43    +  49
E         + + 855    -    2    + 43    +  49    
E         ?                                 ++++
E         - -----    ------    ----    -----...
E         
E         ...Full output truncated (3 lines hidden), use '-vv' to show

test_module.py:77: AssertionError
________________ 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      38...   ------    ' == '  11      38...---    ------'
E         -   11      3801      1      123         1
E         +   11      3801      1      123         1    
E         ?                                         ++++
E         - +  4    - 2999    + 2    +  49    - 9380
E         + +  4    - 2999    + 2    +  49    - 9380    
E         ?                                         ++++
E         - ----    ------    ---    -----    ------...
E         
E         ...Full output truncated (3 lines hidden), use '-vv' to show

test_module.py:77: AssertionError
_______________ 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      9...     1028    ' == '    3      9... 858     1028'
E         -     3      988
E         +     3      988    
E         ?               ++++
E         - + 855    +  40
E         + + 855    +  40    
E         ?               ++++
E         - -----    -----...
E         
E         ...Full output truncated (6 lines hidden), use '-vv' to show

test_module.py:77: AssertionError
_______________ 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       ...     1028    ' == '   32       ... 172     1028'
E         -    32         1      45      123      988
E         +    32         1      45      123      988    
E         ?                                          ++++
E         - - 698    - 3801    + 43    +  49    +  40
E         + - 698    - 3801    + 43    +  49    +  40    
E         ?                                          ++++
E         - -----    ------    ----    -----    -----...
E         
E         ...Full output truncated (6 lines hidden), use '-vv' to show

test_module.py:77: AssertionError
=========================== short test summary info ============================
FAILED test_module.py::test_template[test_two_problems_arrangement1] - Assert...
FAILED test_module.py::test_template[test_two_problems_arrangement2] - Assert...
FAILED test_module.py::test_template[test_four_problems_arrangement] - Assert...
FAILED test_module.py::test_template[test_five_problems_arrangement] - Assert...
FAILED test_module.py::test_template[test_two_problems_with_solutions] - Asse...
FAILED test_module.py::test_template[test_five_problems_with_solutions] - Ass...

The following is my code:

def arithmetic_arranger(problems, validator=False):
    # List to store one list for each operation
    listOfProblems = list()
    results = list()
    result = 0
    moreDigits = 0
    # Elements of the operation to print
    element1 = element2 = separationLine = total = ""
    # Temporary tuples to store the values that will be converted into str to
    # be stored in the previous variables (line 8)
    tupleElement1 = tupleElement2 = sepLineTup = ""
    tupleTotal = ""
    separationSpace = "    "

    # Verify that the number of operations is no greater than 5 operations
    if len(problems) > 5:
        return "Error: Too many problems."

    for problem in problems:
        # Add each operation into a listOfProbles for further validation
        listOfProblems.append([problem])

    # Loop through listOfProblems, and then Loop throug each operation for
    # further validations
    for operation in listOfProblems:
        for operationElement in operation:
            # Verify if the operation is addition or subtraction only
            if ("*" in operationElement or "/" in operationElement):
                return "Error: Operator must be '+' or '-'."
            # Split each element of the operation to get individual values and
            # validate that the numbers have no more than 4 digits
            operationElement = operationElement.split()
            if len(operationElement[0]) > 4 or len(operationElement[2]) > 4:
                return "Error: Numbers cannot be more than four digits."

            # Verify if the numbers in the operation are only digits and not
            # letters or other characters
            try:
                operationElement[0] = int(operationElement[0])
                operationElement[2] = int(operationElement[2])
            except:
                return "Error: Numbers must only contain digits."

            # Develop the mathematical operation and store the elements into
            # the results list with each result
            if operationElement[1] == "+":
                result = operationElement[0] + operationElement[2]
            else:
                result = operationElement[0] - operationElement[2]

            # Store the length of the element with more digits in each
            # operation
            if len(str(operationElement[0])) > len(str(operationElement[2])):
                moreDigits = len(str(operationElement[0]))
            elif len(str(operationElement[0])) < len(str(operationElement[2])):
                moreDigits = len(str(operationElement[2]))
            else:
                moreDigits = len(str(operationElement[0]))

            # Append the elements of the operation to a list
            results.append([operationElement[0], operationElement[1],
                            operationElement[2], result, moreDigits])

    for element in results:
        # When the number of digits of the element 0 is less than the
        # number of digits of the element 2, print white spaces ahead
        # of the number to align the element to the right when
        # displaying.
        if len(str(element[0])) < len(str(element[2])):
            # Store each value in a tuple and then convert all values in
            # a single str called element1
            tupleElement1 = " " * \
                (element[-1] - len(str(element[0]))
                 ), "  ", element[0], separationSpace
            for i in tupleElement1:
                element1 += str(i)

        # The opposite case of if the elements 0 and 2 have the same
        # number of digits
        else:
            # Store each value in a tuple and then convert all values in
            # a single str called element1
            tupleElement1 = "  ", element[0], separationSpace
            for i in tupleElement1:
                element1 += str(i)

    for element in results:
        # When the number of digits of the element 0 is greater than
        # the number of digits of the element 2, print the operation
        # symbol (element[1]), and then white spaces ahead of the
        # number to align the element to the right when displaying.
        if len(str(element[0])) < len(str(element[2])):
            tupleElement2 = element[1], " ", element[2], separationSpace
            for i in tupleElement2:
                element2 += str(i)
        # The opposite case
        elif len(str(element[0])) > len(str(element[2])):
            tupleElement2 = element[1], " " * (len(str(element[0])) - len(
                str(element[2]))-1), "  ", element[2], separationSpace
            for i in tupleElement2:
                element2 += str(i)
        # If the elements 0 and 2 have the same number of digits
        else:
            tupleElement2 = element[1], " ", element[2], separationSpace
            for i in tupleElement2:
                element2 += str(i)

    # Print the divisory line between operation and result adding the
    # same number  of dashes as the number of digits of the larger
    # number plus two additional dashes.
    for element in results:
        sepLineTup = "-" * (element[-1] + 2), separationSpace
        for i in sepLineTup:
            separationLine += i

    # Determine if the output will display or not the result element of the
    # operation
    if validator is True:
        for element in results:
            # If the result has more digits than the largest element
            if len(str(element[3])) > element[-1]:
                tupleTotal = " ", element[3], separationSpace
                for i in tupleTotal:
                    total += str(i)
            # If the result has less digits than the largest element
            elif len(str(element[3])) < element[-1]:
                tupleTotal = "   ", element[3], separationSpace
                for i in tupleTotal:
                    total += str(i)
            # If the result has the same digits the largest element has
            else:
                tupleTotal = "  ", element[3], separationSpace
                for i in tupleTotal:
                    total += str(i)
        return element1 + "\n" + element2 + "\n" + separationLine + "\n" + total  
    else:
      return element1 + "\n" + element2 + "\n" + separationLine

Can anyone can help me to understand and solve this problem?

The error message is trying to communicate that you have four extra spaces at the end of each line.

1 Like

Thank you Jeremy. The solution was as simple as to add an rstrip() to each of the elements to be passed in. Here is my new functional code…

def arithmetic_arranger(problems, validator=False):
    # List to store one list for each operation
    listOfProblems = list()
    results = list()
    result = 0
    moreDigits = 0
    # Elements of the operation to print
    element1 = element2 = separationLine = total = ""
    # Temporary tuples to store the values that will be converted into str to
    # be stored in the previous variables (line 8)
    tupleElement1 = tupleElement2 = sepLineTup = ""
    tupleTotal = ""
    separationSpace = "    "

    # Verify that the number of operations is no greater than 5 operations
    if len(problems) > 5:
        return "Error: Too many problems."

    for problem in problems:
        # Add each operation into a listOfProbles for further validation
        listOfProblems.append([problem])

    # Loop through listOfProblems, and then Loop throug each operation for
    # further validations
    for operation in listOfProblems:
        for operationElement in operation:
            # Verify if the operation is addition or subtraction only
            if ("*" in operationElement or "/" in operationElement):
                return "Error: Operator must be '+' or '-'."
            # Split each element of the operation to get individual values and
            # validate that the numbers have no more than 4 digits
            operationElement = operationElement.split()
            if len(operationElement[0]) > 4 or len(operationElement[2]) > 4:
                return "Error: Numbers cannot be more than four digits."

            # Verify if the numbers in the operation are only digits and not
            # letters or other characters
            try:
                operationElement[0] = int(operationElement[0])
                operationElement[2] = int(operationElement[2])
            except:
                return "Error: Numbers must only contain digits."

            # Develop the mathematical operation and store the elements into
            # the results list with each result
            if operationElement[1] == "+":
                result = operationElement[0] + operationElement[2]
            else:
                result = operationElement[0] - operationElement[2]

            # Store the length of the element with more digits in each
            # operation
            if len(str(operationElement[0])) > len(str(operationElement[2])):
                moreDigits = len(str(operationElement[0]))
            elif len(str(operationElement[0])) < len(str(operationElement[2])):
                moreDigits = len(str(operationElement[2]))
            else:
                moreDigits = len(str(operationElement[0]))

            # Append the elements of the operation to a list
            results.append([operationElement[0], operationElement[1],
                            operationElement[2], result, moreDigits])

    for element in results:
        # When the number of digits of the element 0 is less than the
        # number of digits of the element 2, print white spaces ahead
        # of the number to align the element to the right when
        # displaying.
        if len(str(element[0])) < len(str(element[2])):
            # Store each value in a tuple and then convert all values in
            # a single str called element1
            tupleElement1 = " " * \
                (element[-1] - len(str(element[0]))
                 ), "  ", element[0], separationSpace
            for i in tupleElement1:
                element1 += str(i)

        # The opposite case of if the elements 0 and 2 have the same
        # number of digits
        else:
            # Store each value in a tuple and then convert all values in
            # a single str called element1
            tupleElement1 = "  ", element[0], separationSpace
            for i in tupleElement1:
                element1 += str(i)

    for element in results:
        # When the number of digits of the element 0 is greater than
        # the number of digits of the element 2, print the operation
        # symbol (element[1]), and then white spaces ahead of the
        # number to align the element to the right when displaying.
        if len(str(element[0])) < len(str(element[2])):
            tupleElement2 = element[1], " ", element[2], separationSpace
            for i in tupleElement2:
                element2 += str(i)
        # The opposite case
        elif len(str(element[0])) > len(str(element[2])):
            tupleElement2 = element[1], " " * (len(str(element[0])) - len(
                str(element[2]))-1), "  ", element[2], separationSpace
            for i in tupleElement2:
                element2 += str(i)
        # If the elements 0 and 2 have the same number of digits
        else:
            tupleElement2 = element[1], " ", element[2], separationSpace
            for i in tupleElement2:
                element2 += str(i)

    # Print the divisory line between operation and result adding the
    # same number  of dashes as the number of digits of the larger
    # number plus two additional dashes.
    for element in results:
        sepLineTup = "-" * (element[-1] + 2), separationSpace
        for i in sepLineTup:
            separationLine += i

    # Remove the final separationSpace of each element to avoid errors
    element1 = element1.rstrip(" ")
    element2 = element2.rstrip(" ")
    separationLine = separationLine.rstrip(" ")
    
    # Determine if the output will display or not the result element of the
    # operation
    if validator is True:
        for element in results:
            # If the result has more digits than the largest element
            if len(str(element[3])) > element[-1]:
                tupleTotal = " ", element[3], separationSpace
                for i in tupleTotal:
                    total += str(i)
            # If the result has less digits than the largest element
            elif len(str(element[3])) < element[-1]:
                tupleTotal = "   ", element[3], separationSpace
                for i in tupleTotal:
                    total += str(i)
            # If the result has the same digits the largest element has
            else:
                tupleTotal = "  ", element[3], separationSpace
                for i in tupleTotal:
                    total += str(i)
        # Remove the final separationSpace of the total to avoid errors
        total = total.rstrip(" ")
        return element1 + "\n" + element2 + "\n" + separationLine + "\n" + total  
    else:
      return element1 + "\n" + element2 + "\n" + separationLine

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