Home > Back-end >  How to align strings properly when they are vertical?
How to align strings properly when they are vertical?

Time:06-23

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?

CodePudding user response:

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
  • Related