4

I've seen a question on justifying a 'print' right, but could I have text left and right on the same line, for a --help? It'd look like this in the terminal:

|                                                     |
|Left                                            Right|
|                                                     |
tkbx
  • 15,602
  • 32
  • 87
  • 122

3 Answers3

4

I think you can use sys.stdout for this:

import sys

def stdout(message):
    sys.stdout.write(message)
    sys.stdout.write('\b' * len(message))   # \b: non-deleting backspace

def demo():
    stdout('Right'.rjust(50))
    stdout('Left')
    sys.stdout.flush()
    print()

demo()

You can replace 50 with the exact console width, which you can get from https://stackoverflow.com/a/943921/711085

Community
  • 1
  • 1
Blender
  • 289,723
  • 53
  • 439
  • 496
  • couldn't you use `print message,` (note trailing comma)? – andrew cooke Mar 09 '12 at 20:06
  • nifty. I've commented it, and edited it so it works in the interactive python prompt, and in both python2 and python3. Replace `50` with the value you'd get from http://stackoverflow.com/a/943921/711085 for exact accuracy. – ninjagecko Mar 09 '12 at 20:06
  • @andrewcooke: The `\b` "rewinds: the cursor to the beginning of the line, so I'm actually overwriting the line when I print out `Left`. You could use `print`, though. @FJ did. – Blender Mar 09 '12 at 20:21
  • 1
    right, but there's no need to mess around with sys.stdout, you can still use idiomatic python print (there's nothing special about \b that requires sys.stdout). – andrew cooke Mar 09 '12 at 20:29
3

Here is a pretty simple method:

>>> left, right = 'Left', 'Right'
>>> print '|{}{}{}|'.format(left, ' '*(50-len(left+right)), right)
|Left                                         Right|

As a function:

def lr_justify(left, right, width):
    return '{}{}{}'.format(left, ' '*(width-len(left+right)), right)

>>> lr_justify('Left', '', 50)
'Left                                              '
>>> lr_justify('', 'Right', 50)
'                                             Right'
>>> lr_justify('Left', 'Right', 50)
'Left                                         Right'
>>> lr_justify('', '', 50)
'                                                  '
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
1

I know this is an old thread but I'd like to propose a more elegant solution that "fails gracefully" when the combined text's length exceeds the desired length.

def align_left_right(left: str, right: str, total_len: int = 80) -> str:
    left_size = max(0, total_len - len(right) - 1)  # -1 to account for the space
    return format(left, f"<{left_size}") + " " + right


def main():
    print("1.", align_left_right("|left", "right|"))
    print("2.", align_left_right("|", "right|"))
    print("3.", align_left_right("|left", "|"))
    print("4.", align_left_right("|left", "right|", total_len=20))
    print("5.", align_left_right("|left", "a longer text that doesn't fit|", total_len=20))


if __name__ == "__main__":
    main()

output :

1. |left                                                                     right|
2. |                                                                         right|
3. |left                                                                          |
4. |left         right|
5. |left a longer text that doesn't fit|

You could make a more full-fledged version using textwrap.shorten to keep the total size constant even when one or both strings are too long.

dedebenui
  • 11
  • 1