Alexander_M
Alexander_M

Reputation: 39

How to align strings properly when they are vertical?

I have a task to make a function in Python, which arranges a couple of arithmetic problems vertically, so my desired output is something like this:

  32         1      9999      523
+  8    - 3801    + 9999    -  49
----    ------    ------    -----
  40     -3800     19998      474

To produce an output like that, I wrote a "for" loop which goes through the argument (argument of this function is a list: ["32 + 698", "3801 - 2", "45 + 43", "123 + 49", "555 + 555"]), assigns them to variables and then it should print them out like in the desired output. To print it out, I wrote this:

    sol = \
(   f'  {first}'
    f'\n{oper}'
    f' {second}'
    f'\n{dash}'
    f'\n  {sum}')
    lst.append(sol)

{first} is the first number from the argument, {oper} is the operator, {second} is the second number, {dash} is the adjustable dashes, {sum} is the solution of the arithmetic problem. The last line appends the vertical arithmetic solutions to a list, from which I try to print them horizontally.

print(f'{lst[0]}    {lst[1]}    {lst[2]}    {lst[3]}')

But then, the output I get is this:

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

How to make the strings with solutions even and aligned properly?

Upvotes: 0

Views: 154

Answers (1)

001
001

Reputation: 13533

Here's a simplified version with no list comprehensions

problems = ["32 + 698", "3801 - 2", "45 + 43", "123 + 49", "555 + 555"]

width = 5
space = "    "

lst = []
for problem in problems:
    lst.append(problem.split(' '))

for problem in lst:
    print(problem[0].rjust(width), end=space)
print()

for problem in lst:
    print(f"{problem[1]}{problem[2].rjust(width-1)}", end=space)
print()

for problem in lst:
    print("-" * width, end=space)
print()

for problem in problems:
    print(str(eval(problem)).rjust(width), end=space)
print()

The only part that might need explaining is the first for loop that creates this list:

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

It has broken up each problem into a list [operand1, operator, operand2].


Here's the first (possible overly complex) version.

Do some pre-processing and make a list for each line then print each line.

problems = ["32 + 698", "3801 - 2", "45 + 43", "123 + 49", "555 + 555"]

width = 5

lst = list(zip(*[p.split(' ') for p in problems]))
lines = [[s.rjust(width) for s in lst[0]],
        [f"{op}{val.rjust(width-1)}" for op,val in zip(lst[1], lst[2])],
        ['-' * (width)] * len(lst[0]),
        [str(eval(p)).rjust(width) for p in problems]]

for l in lines: print('   '.join(l))

Output:

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

Explanation:

lst = list(zip(*[p.split(' ') for p in problems]))

  • Splits each problem into a list. Ex: "32 + 698" becomes ["32", "+", "698"]
  • Then it zips each part (operand 1, operator, operand 2) into their own lists. Ex: [('32', '3801', '45', '123', '555'), ('+', '-', '+', '+', '+'), ('698', '2', '43', '49', '555')]

[s.rjust(width) for s in lst[0]]

  • Creates line one with each value set to a fixed width
  • Ex: [" 32", " 3801", " 45", " 123", " 555"]

[f"{op}{val.rjust(width-1)}" for op,val in zip(lst[1], lst[2])]

  • Line 2. Joins the operators and the 2nd operands
  • Ex: ["+ 698", "- 2", "+ 43", "+ 49", "+ 555"]

['-' * (width)] * len(lst[0]),

  • Creates the 3rd line of dashes

[str(eval(p)).rjust(width) for p in problems]

  • Last line with all the sums at the correct width

Upvotes: 2

Related Questions