Arithmetic Formatter code problems

Seeking help on the arithmetic formatter project. In my mind this logic should work but reality says otherwise. Any glaring errors?

def arithmetic_arranger(problems, solve=False):

    if len(problems) > 5:
        return "Error: Too many problems."
  
    for problem in problems:
      
        individual = problem.split()

        firstoperand = individual[0]
        secondoperand = individual[2]
        operator = individual[1]
        
        if len(firstoperand) > 4:
          return "Error: Numbers cannot be more than four digits."
        if len(secondoperand) > 4:
          return "Error: Numbers cannot be more than four digits."
      
        if operator == ("*"):
            return "Error: Operator must be '+' or '-'."
        elif operator == ("/"):
            return "Error: Operator must be '+' or '-'."

        if not firstoperand.isdigit():
            return "Error: Numbers must only contain digits."
        elif not secondoperand.isdigit():
            return "Error: Numbers must only contain digits."
      
        if operator == ("+"):
            result = int(firstoperand) + int(secondoperand)
            result = str(result)
        elif operator == ("-"):
            result = int(firstoperand) - int(secondoperand)
            result = str(result)
      
              
        firstline = []
        secondline = []
        thirdline = []
        fourthline = []

        length = max(len(firstoperand), len(secondoperand))+2
       
        thirdline = ("-"*length)

        firstline = firstoperand.rjust(length)

        secondline = operator + secondoperand.rjust(length-1)

        fourthline = result.rjust(length)

    if solve:   

        arranged_problems = "    ".join(firstline) + "\n" + "    ".join(secondline) + "\n" + "    ".join(thirdline) + "\n" + "    ".join(fourthline)
   
    else:
    
        arranged_problems = "    ".join(firstline) + "\n" + "    ".join(secondline) + "\n" + "    ".join(thirdline)  
  

    return arranged_problems

Sometimes I’m good enough to look at code and guess what the problem is, but would you mind sharing the error messages?

 python main.py
          1    2    3
+              4    9
-    -    -    -    -
============================= 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-11
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 '          1 ...  -    -    -' == '  3801      ...----    -----'
E         -   3801      123
E         - -    2    +  49
E         - ------    -----
E         +           1    2    3
E         + +              4    9
E         + -    -    -    -    -

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         ...---    ------'
E         -   1         1
E         - + 2    - 9380
E         - ---    ------
E         +                          1
E         + -         9    3    8    0
E         + -    -    -    -    -    -

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 '          1 ...  -    -    -' == '    3      3...----    -----'
E         -     3      3801      45      123
E         - + 855    -    2    + 43    +  49
E         - -----    ------    ----    -----
E         +           1    2    3
E         + +              4    9
E         + -    -    -    -    -

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...---    ------'
E         -   11      3801      1      123         1
E         - +  4    - 2999    + 2    +  49    - 9380
E         - ----    ------    ---    -----    ------
E         +                          1
E         + -         9    3    8    0
E         + -    -    -    -    -    -

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 '          9 ...  0    2    8' == '    3      9... 858     1028'
E         -     3      988
E         ?     -
E         +           9    8    8
E         ?            ++++ ++++
E         - + 855    +  40
E         - -----    -----
E         -   858     1028...
E         
E         ...Full output truncated (4 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 '          9 ...  0    2    8' == '   32       ... 172     1028'
E         -    32         1      45      123      988
E         - - 698    - 3801    + 43    +  49    +  40
E         - -----    ------    ----    -----    -----
E         -  -666     -3800      88      172     1028
E         +           9    8    8
E         + +              4    0
E         + -    -    -    -    -...
E         
E         ...Full output truncated (2 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...
========================= 6 failed, 4 passed in 0.20s ==========================

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 (’).

-   3801      123
- -    2    +  49
- ------    -----
+           1    2    3
+ +              4    9
+ -    -    -    -    -

It looks like you are producing completely different output than is requested. You have a ton of extra spaces in your output and you deleted an entire problem!

-     3      3801      45      123
- + 855    -    2    + 43    +  49
- -----    ------    ----    -----
+           1    2    3
+ +              4    9
+ -    -    -    -    -

Here you only have the last problem!

Wow, ok thanks for taking a look, and thanks for the posting tip. Clearly I’ve got some work to do, but that helps give me an idea of where to start at least. Sorry for the newbie mistakes!

It takes practice to be able to read those error messages!

So I don’t understand why the join function was resulting in 4 spaces between characters instead of preceding the strings, but this version seems to solve that. Now I just need to figure out how to get it to iterate instead of just returning one problem, with 4 spaces between entries but not after the final entry.

def arithmetic_arranger(problems, solve=False):

if len(problems) > 5:
    return "Error: Too many problems."

for problem in problems:
  
    individual = problem.split()

    firstoperand = individual[0]
    secondoperand = individual[2]
    operator = individual[1]
    
    if len(firstoperand) > 4:
      return "Error: Numbers cannot be more than four digits."
    if len(secondoperand) > 4:
      return "Error: Numbers cannot be more than four digits."
  
    if operator == ("*"):
        return "Error: Operator must be '+' or '-'."
    elif operator == ("/"):
        return "Error: Operator must be '+' or '-'."

    if not firstoperand.isdigit():
        return "Error: Numbers must only contain digits."
    elif not secondoperand.isdigit():
        return "Error: Numbers must only contain digits."
  
    if operator == ("+"):
        result = int(firstoperand) + int(secondoperand)
        result = str(result)
    elif operator == ("-"):
        result = int(firstoperand) - int(secondoperand)
        result = str(result)
  
          
    length = max(len(firstoperand), len(secondoperand))+2
   
    thirdline = ("-"*length)

    firstline = firstoperand.rjust(length)

    secondline = operator + secondoperand.rjust(length-1)

    fourthline = result.rjust(length)

    if solve:   

        arranged_problems = (firstline) + "\n" + (secondline) + "\n" + (thirdline) + "\n" + (fourthline)

    else:

        arranged_problems = (firstline) + "\n" + (secondline) + "\n" + (thirdline)  


return arranged_problems

It looks like this completely replaces the arranged problem… But are the lines complete yet at this point?

Ah, the lines are where I need to iterate through the for loop and append rather than overwrite each time I guess. Hopefully I can figure that out this evening when I get some time to sit down and work on it. Thanks again.

So, it’s perhaps an inefficient, inelegant kludge but I got it to work!

def arithmetic_arranger(problems, solve=False):

    if len(problems) > 5:
        return "Error: Too many problems."
   
    firstlinelong = ""
    secondlinelong = ""
    thirdlinelong = ""
    fourthlinelong = ""
  
    for problem in problems:
      
        individual = problem.split()

        firstoperand = individual[0]
        secondoperand = individual[2]
        operator = individual[1]
        
        if len(firstoperand) > 4:
          return "Error: Numbers cannot be more than four digits."
        if len(secondoperand) > 4:
          return "Error: Numbers cannot be more than four digits."
      
        if operator == ("*"):
            return "Error: Operator must be '+' or '-'."
        elif operator == ("/"):
            return "Error: Operator must be '+' or '-'."

        if not firstoperand.isdigit():
            return "Error: Numbers must only contain digits."
        elif not secondoperand.isdigit():
            return "Error: Numbers must only contain digits."
      
        if operator == ("+"):
            result = int(firstoperand) + int(secondoperand)
            result = str(result)
        elif operator == ("-"):
            result = int(firstoperand) - int(secondoperand)
            result = str(result)
      
            
        length = max(len(firstoperand), len(secondoperand))+2
       
        thirdline = ("-"*length)

        firstline = firstoperand.rjust(length)

        secondline = operator + secondoperand.rjust(length-1)

        fourthline = result.rjust(length)

        firstlinelong = firstlinelong + ((firstline)+"    ")
        secondlinelong = secondlinelong + ((secondline)+"    ")
        thirdlinelong = thirdlinelong + ((thirdline)+"    ")
        fourthlinelong = fourthlinelong + ((fourthline)+"    ")

    if solve:   

        firstlinelong = firstlinelong[:-4]
        secondlinelong = secondlinelong[:-4]
        thirdlinelong = thirdlinelong[:-4]
        fourthlinelong = fourthlinelong[:-4]
      
        arranged_problems = (firstlinelong) + "\n" + (secondlinelong) + "\n" + (thirdlinelong) + "\n" + (fourthlinelong)

    else:

        firstlinelong = firstlinelong[:-4]
        secondlinelong = secondlinelong[:-4]
        thirdlinelong = thirdlinelong[:-4]
        fourthlinelong = fourthlinelong[:-4]

        arranged_problems = (firstlinelong) + "\n" + (secondlinelong) + "\n" + (thirdlinelong)  
  

    return arranged_problems

Good work! Working code is the first step in getting good code!

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