0

I want to print a number of math operations (additions or subtractions) next to each other. All numbers should be right-aligned.

Below is my current code, which prints each math operation on consecutive lines (vertical output) instead of on the same lines (horizontal output).

I am not sure what method I should use here. How can I do this?

def arithmetic_arranger(problems, solution):
    problems = ["32 + 698", "3801 - 2", "45 + 43", "123 + 49"]
    if len(problems) > 5:
        return print("Error: Too many problems.")
    try:
        for p in problems:
            p1 = p.split(" ")
            x = int(p1[0])
            d = (p1[1])
            y = int(p1[2])
            if x > y:
                e = "-" * len(str(x)) + "--"
            else:
                e = "-" * len(str(y)) + "--"
            if len(str(x)) > 4 or len(str(y)) > 4:
                return print("Error: Numbers cannot be more than four digits.")
            if d == "+":
                sol = x + y
            elif d == "-":
                sol = x - y
            else:
                return print("Error: Operator must be '+' or '-'.")
            if solution is True:
                sol = sol
            elif solution is False:
                sol = ""
            math = ("{}\n{}" + " " + "{}\n{}\n"+" "+"{}").format(x, d, y, e, sol)
            print(math)
            print("====================")
    except ValueError:
        return print("Error: Numbers must only contain digits.")
arithmetic_arranger(["32 + 698", "3801 - 2", "45 + 43", "123 + 49"], True)

Expected output:

   32      3801      45      123
+ 698    -    2    + 43    +  49
-----    ------    ----    -----
wovano
  • 4,543
  • 5
  • 22
  • 49

2 Answers2

1

Printing (using print) is done line by line. There's an option to not print the end-of-line character (so you could do multiple "prints" on the same line), as already answered here. You wrote in a comment that this solution didn't help, but below I will show you that you can use this to solve your problem.

However, the main problem is that you want to print 3 or 4 related lines, each of which contains a certain part of the arithmetic operation: On the first line you want to have all the first arguments of the operations, on the second line the second arguments, and you want to have them properly aligned, so you'll need to know the width of each argument before you can start.

I think the easiest method is to first perform all arithmetic operations and determine the width for each operation (where the width is determined by the "longest" number, which is not necessary the largest number, since -1 takes more space than 1). When you know the width for each operation, you could use string formatting to create the "columns".

There are many ways to write this code, but the following is an example. It uses list comprehension and str.join() to create and print each line at once. For simplicity, I left out the error handling, which is not really relevant for the question, and the input restrictions are not mentioned in the question anyway.

def arithmetic_arranger(problems, calculate_solution):
    solutions = []
    for problem in problems:
        x, op, y = problem.split(' ')
        z = ""
        if op == "+":
            z = str(int(x) + int(y))
        if op == "-":
            z = str(int(x) - int(y))
        width = max(map(len, [x, y, z]))
        solutions.append([op, x, y, z, width])
    print('    '.join('  %*s' % (width, x) for (op, x, y, z, width) in solutions))
    print('    '.join('%s %*s' % (op, width, y) for (op, x, y, z, width) in solutions))
    print('    '.join('-' * (2 + width) for (op, x, y, z, width) in solutions))
    if calculate_solution:
        print('    '.join('  %*s' % (width, z) for (op, x, y, z, width) in solutions))


arithmetic_arranger(["32 + 698", "3801 - 2", "45 + 43", "123 + 49"], True)

This has the following output:

   32      3801      45      123
+ 698    -    2    + 43    +  49
-----    ------    ----    -----
  730      3799      88      172

Alternative solution using simple for loops and the end parameter of print():

In above code, replace the print-statements with the following code, which will result in the same output:

    # print first line
    for i, s in enumerate(solutions):
        if i > 0:
            print('    ', end='')
        print('  %*s' % (s.width, s.x), end='')
    print('')
    # print second line
    for i, s in enumerate(solutions):
        if i > 0:
            print('    ', end='')
        print('%s %*s' % (s.op, s.width, s.y), end='')
    print('')
    # print third line
    for i, s in enumerate(solutions):
        if i > 0:
            print('    ', end='')
        print('-' * (2 + s.width), end='')
    print('')
    # optionally, print fourth line
    if calculate_solution:
        for i, s in enumerate(solutions):
            if i > 0:
                print('    ', end='')
            print('  %*s' % (s.width, s.z), end='')
        print('')
wovano
  • 4,543
  • 5
  • 22
  • 49
-1

First, do not return a 'print' statement. simply send the string back and print the function. (print(my_function())
Second, I've 'fixed' your code, and removed the return statements for you to be able to run your code and see what happens without a function or a function call.

problems = ["32 + 698", "3801 - 2", "45 + 43", "123 + 49"]
if len(problems) > 5:
    print("Error: Too many problems.")
try:
    for p in problems:
        solution = True # Add this as your boolean check
        p1 = p.split(" ")
        x = int(p1[0])
        d = (p1[1])
        y = int(p1[2])
        if x > y:
            e = "-" * len(str(x)) + "--"
        else:
            e = "-" * len(str(y)) + "--"
        if len(str(x)) > 4 or len(str(y)) > 4:
            print("Error: Numbers cannot be more than four digits.")
        if d == "+":
            sol = x + y
        elif d == "-":
            sol = x - y
        else:
            print("Error: Operator must be '+' or '-'.")  # use return statement directly. I've used print to visualize for you.
            sol = ""
        math = ("{}\n{}" + " " + "{}\n{}\n"+" "+"{}").format(x, d, y, e, sol)
        print(math)
        print("====================")
except ValueError:
    print("Error: Numbers must only contain digits.")

edit
OK, so initiate an empty string at the. start and append your output to it-

my_str = ""
for p in problems:
.
.
.
my_str = my_str + ("{}\n{}" + " " + "{}\n{}\n"+" "+"{}").format(x, d, y, e, sol)
wovano
  • 4,543
  • 5
  • 22
  • 49
Bar Ifrah
  • 80
  • 7