Build an Arithmetic Formatter Project: Stuck on how to format the output correctly

def check_input(problems):
    if len(problems) < 5:
        for p in problems:
            if p.find('+') != -1 or p.find('-') != -1:
                p_list = p.split(' ')

                if p_list[0].isdigit() and p_list[2].isdigit():
                    if len(p_list[0]) < 5 and len(p_list[2]) < 5:
                        return True
                    else:
                        raise ValueError('Error: Numbers cannot be more than four digits.')
                else:
                    raise ValueError("Error: Numbers must only contain digits.")
            else:
                raise ValueError("Error: Operator must be '+' or '-'.")
    else:
        raise ValueError('Error: Too many problems.')

def calculate_space(operand1, operand2):
    operand1_len = len(operand1)
    operand2_len = len(operand2)
    len_deference = abs(operand1_len - operand2_len)
    i = 0
    space = ''

    while i < len_deference:
        space += ' '
        i += 1

    return space


def check_longest(op1, op2):
    longest = 0
    op1_length = len(op1)
    op2_length = len(op2)

    if op1_length > op2_length: longest = op1
    elif op2_length > op1_length: longest = op2
    else: longest = op1

    return longest

def draw_line(op1, op2):
    i = 0
    line = '--'

    longest = check_longest(op1, op2)

    while i < len(longest):
        line += '-'
        i += 1

    return line

def arithmetic_arranger(problems, show_answers=False):
    if check_input(problems):
        top = []
        mid = []
        bottom= []

        for problem in problems:
            problem_list = problem.split(' ')
            operator = problem_list[1]
            operand1 = problem_list[0]
            operand2 = problem_list[2]
            operand1_len = len(operand1)
            operand2_len = len(operand2)
            result = 0

            space = calculate_space(operand1, operand2)
            line = draw_line(operand1, operand2)

            if operand1_len > operand2_len:
                print(f"  {operand1}\n{operator}{space} {operand2}\n{line} ")
            elif operand2_len > operand1_len:
                print(f"  {space}{operand1}\n{operator} {operand2}\n{line} ")
            else:
                print(f"  {operand1}\n{operator} {operand2}\n{line} ")

            if show_answers:
                if operator == '+':
                    result = int(operand1) + int(operand2)
                elif operator == '-':
                    result = int(operand1) - int(operand2)

                longest = check_longest(operand1, operand2)
                answer_space = calculate_space(longest, str(result))

                print(f'  {answer_space}{result}')

    return problems

print(f'\n{arithmetic_arranger(["32 + 698", "3801 - 2", "45 + 43", "123 + 49"], True)}')

Hello, so I can’t figure out to format the output correctly so that the problems are printed on the same line. I searched the forum for posts about the same issue and saw some people suggesting using a 2D array. I’m still unsure how to go about it or if it’s an optimal way to do it.

Please tell me if this is something I should figure out myself.
Sorry for the lack of comments, if they are needed to understand the code, please do tell.

Hi. Welcome to the forum. Can you please link to the challenge you are stuck on.

If you have a question about a specific challenge as it relates to your written code for that challenge and need some help, click the Help button located on the challenge. This button only appears if you have tried to submit an answer at least three times.

The Help button will create a new topic with all code you have written and include a link to the challenge also. You will still be able to ask any questions in the post before submitting it to the forum.

Thank you.

1 Like

Welcome to the forum @mmx8

Python is a versatile programming language, so there are many ways to implement code.

First, try and figure out what you need to do so that each line contains the first operand. Then, the second line contains the operator and the second operand. Finally, the dash lines (later: don’t forget to add the functionality for a solution option).

Treat each as a separate task - so three tasks.
Then implement code so that each set of arithmetic is correctly spaced.

Breaking down problems into smaller steps is one approach. Don’t worry too much about optimising code for now. Once you have the formatting, then review the code to see where you can make improvements, such as eliminating repeated steps, or simplifying a process.

Happy coding

1 Like

Thank you for the tip, I will keep that in mind next time I want to ask a question. Here’s the link to the challenge.

Thank you for taking the time. I noticed that I’ve already started something like what you’ve mentioned, about dividing the problem (creating 3 arrays for each section), but forgot about it (probably cheated by reading someone’s answer to a similar question).

Now, just need to figure out how to store each line content inside the array (mainly the 2nd line) and how to print them correctly.

I guess will keep trying and hopefully figure it our or stay stuck and come back here :smiley:

I couldn’t figure it out and gave up a while ago. Does anyone have any other tips or hints?

  if operand1_len > operand2_len:
                print(f"  {operand1}\n{operator}{space} {operand2}\n{line} ")
            elif operand2_len > operand1_len:
                print(f"  {space}{operand1}\n{operator} {operand2}\n{line} ")
            else:
                print(f"  {operand1}\n{operator} {operand2}\n{line} ")

        ...

    return problems

The biggest problem here is that you are sending each problem to print and then at the end, return an array:

  45
+ 43
---- 
  88
  123
+  49
----- 
  172

['32 + 698', '3801 - 2', '45 + 43', '123 + 49']

Instead of sending each problem to print you need to be adding everything to a long string formatted with newlines \n at appropriate points.

At the end you should return the string.

1 Like

Sorry for the late response and I should of updated with my progress since I posted last time. It’s been a while and last time I remember being stuck and losing hope.

I think I figured something out last time but got stuck again and after reviewing the code, I think I figured out how the solution should be or maybe not. Let me try again and get back to you (it may take a while)

1 Like

It turns out I wasn’t exactly on the right track. I was still trying to print the problems line by line.

I understand now what you mean by combining everything in one string, it’s also a requirement of the challenge which I have missed.

Here’s what the first line looks like:

first_line = ""
            while i < len(operand1):
                    if len(operand1[i]) > len(operand2[i]):
                        first_line += f"  {operand1[i]}    "
                    elif len(operand1[i]) > len(operand2[i]):
                        first_line += f"  {operand2[i]}    "
                    else:
                        first_line += f"  {operand1[i]}    "

Then I’m going to combine the 3-4 lines together and return it.

Thank you for the help, I appreciate it! I was going to give up.

Optional side question: Do you think it’s a problem that I wasn’t able to figure it on my own or that I was considering giving up?

No. You haven’t figured it out yet, and you didn’t give up. The battle ain’t over.

This is a tricky problem and there are lots of forum posts opened about it. I think it’s definitely a small leap in complexity from the previous lessons. It’s a challenge, it’s hard. That’s what the forum is here for.

Everyone needs guidance once in a while when they are learning something new and difficult. Don’t worry about it, just keep plugging away.

1 Like

Just to clarify, You mean I haven’t figured it out before asking again here, but the solution/code I posted in the last comment is correct (well not 100%, still need to work on a few things like spacing) but it solves the problem I had, am I correct?

I just meant the lab hadn’t been fully solved yet

1 Like

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