Arithmetic Arranger - Works in PyCharm, doesn't pass in replit

Hey guys, been working on this for a couple days. Gives me the result I want in the console in PyCharm, doesn’t pass the replit test. Any help would be appreciated!


def arithmetic_arranger(problems, result=True):
    final_first_line = ""
    final_second_line = ""
    final_barrier = ""
    final_total = ""
    if len(problems) > 5:
        return "Error: Too many problems."

    for problem in problems:

        first_number = problem.split()[0]
        second_number = problem.split()[2]
        if not first_number.isdigit() or not second_number.isdigit():
            return "Error: Numbers must only contain digits."
        if len(first_number) > 4 or len(second_number) > 4:
            return "Error: Numbers cannot be more than four digits."
        operator = problem.split()[1]
        if operator != "+" and operator != "-":
            return "Error: Operator must be '+' or '-'."
        total = eval(problem)

        if max(len(first_number), len(second_number)) == 1 or max(len(first_number), len(second_number)) == 2:
            barrier = "-" * 4
            length = 4
        elif max(len(first_number), len(second_number)) == 3:
            barrier = "-" * 5
            length = 5
        elif max(len(first_number), len(second_number)) == 4:
            barrier = "-" * 6
            length = 6

        display_total = str(total).rjust(length)

        first_line = str(first_number).rjust(length)
        second_line = str(operator.ljust(length - len(second_number)) + second_number).rjust(length)

        final_first_line += f"{first_line}    "
        final_second_line += f"{second_line}    "
        final_barrier += f"{barrier}    "
        if result:
            final_total += f"{display_total}    "

        arranged_problems = f"{final_first_line}\n" \
                            f"{final_second_line}\n" \
                            f"{final_barrier}\n" \
                            f"{final_total}\n"

    return arranged_problems


print(arithmetic_arranger(["32 + 8", "1 - 3801", "9999 + 9999", "523 - 49"], True))


Edit: Jeez sorry about how messy this came out, haven’t used a forum with this kind of layout before :sweat_smile:

I’ve edited your code 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 (').

1 Like

Please post the errors you are seeing.

1 Like

No errors in the console, this error repeatedly in replit;

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

If you see the series of pluses in the output, these indicate the presence of extra spaces.
These spaces are unexpected (and probably invisible to you in the console) but detected by the test.
You will need to remove them.

1 Like

Any advice? .rstrip() doesn’t seem to be helping, and that should remove all of the white space, correct?

You need to detect when you are at the last problem so you don’t end up adding the spaces to its right to begin with?

1 Like
def arithmetic_arranger(problems, result=False):
    final_first_line = ""
    final_second_line = ""
    final_barrier = ""
    final_total = ""
    if len(problems) > 5:
        return "Error: Too many problems."

    for problem in problems:

        first_number = problem.split()[0]
        second_number = problem.split()[2]
        if not first_number.isdigit() or not second_number.isdigit():
            return "Error: Numbers must only contain digits."
        if len(first_number) > 4 or len(second_number) > 4:
            return "Error: Numbers cannot be more than four digits."
        operator = problem.split()[1]
        if operator != "+" and operator != "-":
            return "Error: Operator must be '+' or '-'."
        total = eval(problem)

        if max(len(first_number), len(second_number)) == 1 or max(len(first_number), len(second_number)) == 2:
            barrier = "-" * 4
            length = 4
        elif max(len(first_number), len(second_number)) == 3:
            barrier = "-" * 5
            length = 5
        elif max(len(first_number), len(second_number)) == 4:
            barrier = "-" * 6
            length = 6

        display_total = str(total).rjust(length)

        first_line = str(first_number).rjust(length)
        second_line = str(operator.ljust(length - len(second_number)) + second_number).rjust(length)

        final_first_line += f"{first_line}    "
        final_second_line += f"{second_line}    "
        final_barrier += f"{barrier}    "
        if result:
            final_total += f"{display_total}    "

        arranged_problems = f"{final_first_line.rstrip()}\n" \
                            f"{final_second_line.rstrip()}\n" \
                            f"{final_barrier.rstrip()}\n" \
                            f"{final_total.rstrip()}"

    return arranged_problems

The whitespace is stripped before anything is returned, is there a way to alter the loop so it performs differently in its final iteration?

Hi, you could create a simple counter variable and increment it on each loop till you get to the final one.
There is probably more than one way to do this but I am curious about how the spaces are getting added and then stripped and yet still somehow end up in the final result. (I would try to log all that)

1 Like

It seems the whitespace problem was sorted somewhere in my tinkering, now it’s just failing the initial 4 tests (display sums without totals) and passing the final 6 (error testing and sums displaying totals)

Current error message:

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 '-----    ------    ----    -----\n'\n '  858      3799      88      172') == ('    3      3801      45      123\n'\n '+ 855    -    2    + 43    +  49\n'\n '-----    ------    ----    -----')
E               3      3801      45      123
E           + 855    -    2    + 43    +  49
E         - -----    ------    ----    -----
E         + -----    ------    ----    -----
E         ?                                 +
E         +   858      3799      88      172

Back to being lost again :sweat_smile: thanks for your help so far!

Edit:
Current code

def arithmetic_arranger(problems, result=True):
    final_first_line = ""
    final_second_line = ""
    final_barrier = ""
    final_total = ""
    if len(problems) > 5:
        return "Error: Too many problems."

    for problem in problems:

        first_number = problem.split()[0]
        second_number = problem.split()[2]
        if not first_number.isdigit() or not second_number.isdigit():
            return "Error: Numbers must only contain digits."
        if len(first_number) > 4 or len(second_number) > 4:
            return "Error: Numbers cannot be more than four digits."
        operator = problem.split()[1]
        if operator != "+" and operator != "-":
            return "Error: Operator must be '+' or '-'."
        total = eval(problem)

        if max(len(first_number), len(second_number)) == 1 or max(len(first_number), len(second_number)) == 2:
            barrier = "-" * 4
            length = 4
        elif max(len(first_number), len(second_number)) == 3:
            barrier = "-" * 5
            length = 5
        elif max(len(first_number), len(second_number)) == 4:
            barrier = "-" * 6
            length = 6

        display_total = str(total).rjust(length)

        first_line = str(first_number).rjust(length)
        second_line = str(operator.ljust(length - len(second_number)) + second_number).rjust(length)

        final_first_line += f"{first_line}    "
        final_second_line += f"{second_line}    "
        final_barrier += f"{barrier}    "
        if result:
            final_total += f"{display_total}    "

        arranged_problems = f"{final_first_line.rstrip()}\n" \
                            f"{final_second_line.rstrip()}\n" \
                            f"{final_barrier.rstrip()}\n" \
                            f"{final_total.rstrip()}"


    return arranged_problems

The error says you have one extra space at the end of the line of dashes. (See the plus sign pointing it out?)

Edit: it could also mean you have an extra hidden character there that is not a space (it just looks like a space to us but could be any hidden character like a newline)

1 Like

I’m so stumped. Any hidden characters I remove make it completely wrong. Using strip and rstrip doesn’t seem to help. Should I not be using an f-string at all?

Just seems like semantics at this point :cry:

To be honest, the way you wrote the last line that puts all the strings together looks weird to me (I don’t even understand how it is working).

Do you want to share your replit? I am a python beginner myself and I need to play with the code to see what it is doing.

(To share the replit, enclose its link inside angled brackets or the link will not display properly here)

1 Like

https://replit.com/@riddywhey/boilerplate-arithmetic-formatter-1#arithmetic_arranger.py

It’s a multi-line formatted string with the white space stripped at the end of each line. Works perfectly fine aesthetically, replit just doesn’t seem to like it.

Edit: Also genuinely confused how it works fine solving the problems with solutions, but doesn’t work without. It’s the exact same code.

i’m glad you shared that because when I ran it I noticed something else that may be the actual issue you are having. One of the errors shows this:

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     ?                      +                   +

Notice how you have an extra space in front of the 1 on the top line and the 2 on the bottom line? (in the 3rd set?)

This would explain why (maybe) things are getting shifted sideways.
You also have an extra dash in that same set (there should be a total of 3)

Edit: here is where I think your logic is wrong


        if max(len(first_number), len(second_number)) == 1 or max(len(first_number), len(second_number)) == 2:
            barrier = "-" * 4
            length = 4

You are treating an expression of 1 + 2 as if it needs 4 spaces but it only needs 3.

1 Like

Got it!

I needed to adjust the dashes/whitespace. I also needed to ad an extra boolean condition only adding the final line if the condition was set to True. Thanks so much for your help!

1 Like