Can't get Arithmetic formatter to pass

Tell us what’s happening:
This is the Repl.it : https://repl.it/@PhotoCoog/boilerplate-arithmetic-formatter-1#arithmetic_arranger.py
From what I can tell, my output strings are formatted correctly. I put in some print functions there for each case so I can see how it actually looks and it looks right but when the test module looks at it, I think it’s seeing something else. I’ve been staring at this for 3 hours so my eyes and mind are shot so any help is appreciated.

Your code so far


def arithmetic_arranger(problems, optionalSolve=False):
    listLength = len(problems)
    #these vars will hold the temporary parsed oprands from each object
    augend = ""
    addend = ""
    operation = ""
    answer=0
    lengthMaxOpperand=0
    #these vars will be the strings that will print out once we are done
    firstLine=""
    secondLine=""
    dashLine=""
    answerLine=""
    arrangedProblems=""


    # check for maximum of 5 problems
    if listLength > 5:
      return ("Error: Too many problems.")

    
    #parse the list
    for i in problems:
      #apparently split is a little different in Python than in Javascript
      augend, operation, addend = i.split()

      #check to see if input is number
      if augend.isnumeric() == False or addend.isnumeric()== False:
        return ("Error: Numbers must only contain digits.")

      #check to make sure numbers aren't more than 4 digits
      if int(augend)>9999 or int(addend)>9999:
        return("Error: Numbers cannot be more than four digits.")

      #check to ensure + or - and do operation
      if operation =="+":
        answer= int(augend)+int(addend)
      elif operation =="-":
        answer = int(augend)-int(addend)
      else:
        return ("Error: Operator must be '+' or '-'.")
      
      #Now we build each line using rjust() and max()
      #first we find out the length of the larger of the two numbers
      lengthMaxOpperand = len(max(augend,addend))
      firstLine = firstLine + augend.rjust(lengthMaxOpperand+2) + "    "
      secondLine = secondLine + operation + " " + addend.rjust(lengthMaxOpperand) + "    "
      dashLine = dashLine + '-'*(lengthMaxOpperand+2) + "    "
      answerLine = answerLine + str(answer).rjust(lengthMaxOpperand+2) + "    "
  
    #Before we splice everything together, we need to check to see if we need to solve or not
    #leaving print in there for debugging
    if optionalSolve == True: 
      arrangedProblems=firstLine + "\n" + secondLine + "\n" + dashLine + "\n" + answerLine 
      print (optionalSolve)
      print(arrangedProblems)
    else:
      arrangedProblems=firstLine + "\n" + secondLine + "\n" + dashLine
      print (optionalSolve)
      print(arrangedProblems)
   
    return (arrangedProblems)

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36.

Challenge: Arithmetic Formatter

Link to the challenge:

check the output for each test, with a sectoom that shows the difference between the expected output and your code: the lines starting with - is your wrong line, the lines starting with + is the expected line, and the lines with ? show the difference between the two

1 Like

Thanks it looks like the last problem is off by a space for some reason… This is fun lol

-     3      3801      45     123    
?                                ----
+     3      3801      45      123
?                        +
- + 855    -    2    + 43    + 49    
?                                ----
+ + 855    -    2    + 43    +  49
?                             +
- -----    ------    ----    ----    ?                                ^^^^
+ -----    ------    ----    -----?        

and

-    32         1      45     123    
?                                ----
+    32         1      45      123
?                        +
- - 698    - 3801    + 43    + 49    
?                                ----
+ - 698    - 3801    + 43    +  49
?                             +
- -----    ------    ----    ----    
?                                ^^^^
+ -----    ------    ----    -----
?                                ^
-  -666     -3800      88     172    ?                                ----
+  -666     -3800      88      172?        

After more debugging, it appears that in the last iteration of the list, the max function gives the incorrect answer to which is the largest operand and picks the shorter one. Any help would be appreciated!

OK, so I figured out why Max was not working correctly. Apparently when comparing strings, it doesn’t go by length and goes by value. I changed it to

lengthMaxOperand = len(max(addend,augend, key=len))

and now it gets the correct value…it still doesn’t pass but I am on the right track! Also fixed the spelling of operand

OK, I give up. My output looks identical to the test output but it doesn’t pass the two solutions. I redid the code a little so it’s a little more intuitive to follow so please take a look. I’ll also post the output. Can anybody tell me why it’s not passing? Is a spacing wrong somewhere? the + and - look the same to me.

def arithmetic_arranger(problems, optionalSolve=False):
  
    #these vars will hold the temporary parsed oprands from each object
    operand1 = ""
    operand2 = ""
    operation = ""
    answer=0
    lengthMaxOperand=0
    #these vars will be the strings that will print out once we are done
    firstLine=""
    secondLine=""
    dashLine=""
    answerLine=""
    arrangedProblems=""


    # check for maximum of 5 problems
    if len(problems) > 5:
      return ("Error: Too many problems.")

    
    #parse the list
    for i in problems:
      #apparently split is a little different in Python than in Javascript
      operand1, operation, operand2 = i.split()

      #check to see if input is number
      if operand1.isnumeric() == False or operand2.isnumeric()== False:
        return ("Error: Numbers must only contain digits.")

      #check to make sure numbers aren't more than 4 digits
      if int(operand1)>9999 or int(operand2)>9999:
        return("Error: Numbers cannot be more than four digits.")

      #check to ensure + or - and do operation
      if operation =="+":
        answer= int(operand1)+int(operand2)
      elif operation =="-":
        answer = int(operand1)-int(operand2)
      else:
        return ("Error: Operator must be '+' or '-'.")
      
      #Now we build each line using rjust() and max()
      #first we find out the length of the larger of the two numbers

      lengthMaxOperand = len(max(operand2,operand1, key=len))

   
      firstLine = firstLine + operand1.rjust(lengthMaxOperand+2) + "    "
      secondLine = secondLine + operation + " " + operand2.rjust(lengthMaxOperand) + "    "
      dashLine = dashLine + '-'*(lengthMaxOperand+2) + "    "
      answerLine = answerLine + str(answer).rjust(lengthMaxOperand+2) + "    "
    
      
  
    #Before we splice everything together, we need to check to see if we need to solve or not
    #leaving print in there for debugging
    if optionalSolve == True: 
      arrangedProblems=firstLine + "\n" + secondLine + "\n" + dashLine + "\n" + answerLine
    else:
      arrangedProblems=firstLine + "\n" + secondLine + "\n" + dashLine
    return (arrangedProblems)
    
    

This is the output when I run it:

 python main.py
   32      3801      45      123    
+ 698    -    2    + 43    +  49    
-----    ------    ----    -----    
F..F..
======================================================================
FAIL: test_arrangement (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/boilerplate-arithmetic-formatter-1/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: '    [23 chars]  123    \n+ 855    -    2    + 43    +  49   [35 chars]    ' != '    [23 chars]  123\n+ 855    -    2    + 43    +  49\n-----[23 chars]----'
-     3      3801      45      123    
?                                 ----
+     3      3801      45      123
- + 855    -    2    + 43    +  49    
?                                 ----
+ + 855    -    2    + 43    +  49
- -----    ------    ----    -----    ?                                 ----
+ -----    ------    ----    ----- : Expected different output when calling "arithmetic_arranger()" with ["3 + 855", "3801 - 2", "45 + 43", "123 + 49"]

======================================================================
FAIL: test_solutions (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/boilerplate-arithmetic-formatter-1/test_module.py", line 39, in test_solutions
    self.assertEqual(actual, expected, 'Expected solutions to be correctly displayed in output when calling "arithmetic_arranger()" with arithemetic problems and a second argument of `True`.')
AssertionError: '   3[23 chars]  123    \n- 698    - 3801    + 43    +  49   [73 chars]    ' != '   3[23 chars]  123\n- 698    - 3801    + 43    +  49\n-----[57 chars] 172'
-    32         1      45      123    
?                                 ----
+    32         1      45      123
- - 698    - 3801    + 43    +  49    
?                                 ----
+ - 698    - 3801    + 43    +  49
- -----    ------    ----    -----    
?                                 ----
+ -----    ------    ----    -----
-  -666     -3800      88      172    ?                                 ----
+  -666     -3800      88      172 : Expected solutions to be correctly displayed in output when calling "arithmetic_arranger()" with arithemetic problems and a second argument of `True`.

----------------------------------------------------------------------
Ran 6 tests in 0.061s

FAILED (failures=2)
 

Those ? lines with the four - indicate your lines has 4 extra spaces. compared to the expected output because every time through the loop (even the last time) you add 4 spaces to the end of each line. Luckily, there is an easy fix to remove white space at the end of a line.

1 Like

Thank you! I did not know what those dashes meant but now that I look at the code and have that info, I see where the issue is. Still not sure how to fix it but I’ll mull it over a bit and probably come back and ask for help :wink: … Oh rstrip() to the rescue…I swear python has a method for everything.

to make it even better, make the logic not add the spaces, instead of adding them and then removing them

Yeah my old assembly language teacher would absolutely kill me if I ever did that in his class where every bit mattered and efficiency was rewarded but for now everything passes by me stripping the white space after adding them.

I am curious about what I could do about leaving the 4 spaces from being added to the end of very last problem that would be less expensive. I suppose I could put in a conditional to check to see if we’re doing the last one and if so, not add it but the way I’m thinking would be pretty ugly and I’m not sure if it will save much if any computing.

firstLine = firstLine + operand1.rjust(lengthMaxOperand+2) + "    "
      secondLine = secondLine + operation + " " + operand2.rjust(lengthMaxOperand) + "    "
      dashLine = dashLine + '-'*(lengthMaxOperand+2) + "    "
      answerLine = answerLine + str(answer).rjust(lengthMaxOperand+2) + "    "

if optionalSolve == True: 
      arrangedProblems=firstLine.rstrip() + "\n" + secondLine.rstrip() + "\n" + dashLine.rstrip() + "\n" + answerLine.rstrip()
    else:
      arrangedProblems=firstLine.rstrip() + "\n" + secondLine.rstrip() + "\n" + dashLine.rstrip()
    return (arrangedProblems)
    

This is basically your answer right here. You join the elements (of a list perhaps) together with a \n to make a string. Just because you want firstLine to be a string at the end doesn’t mean it has to be a string in the beginning; it could just be a list of parts of the final string.

Google around on python’s join and the first/last line different problem and you’ll find plenty of examples.

I appreciate the insight and it makes sense that I don’t need to keep things as a string the whole way. I wish they had finished solutions with how a python expert would do things so one could look at it as a review to see where they are and where they need to be. I hate to develop bad habits or resorting to lower level language tactics when starting off with Python and defeating the purpose of its use.

there is not a single solution, plus as first thing the most important thing is that you are able to create stuff that works, after that you can keep polishing your coding style

you could practice on places like codewars.com, there after you solve something you can confront your solution with many others and learn a lot of methods and tricks