1

The question how to overwrite your last printed line has been asked before and answered (e.g. here), but it seems all the answers assume you overwrite your last line with something of similar length, for example in a progress indicator where "2 % done" overwrites "1 % done".

However, I'd like to print variable length statements, such as "Now reading file path/to/xxx/file.ext...", where the next filename may be shorter. If I use the simple approach, and first print "Now reading ./path/with/many/long-named/subdirectories/version/LongFileNameAsWell.ext...", followed by "Now reading ./file.ext...", the result is a line that says

Now reading ./file.ext... ng-named/subdirectories/version/LongFileNameAsWell.ext

A workaround would be to append all my print-strings with spaces, but then I'd need to make sure I don't wrap around to a newline, while still having enough spaces to cover the entire filename. This all adds a lot of overhead, room for bugs, etc.

Is there a Pythonic way to do this?

For the record, I'm using Python 3.7 on Spyder with the IPython Console, on Windows

Emil Bode
  • 1,784
  • 8
  • 16
  • 1
    @MrFuppes I wasn't sure what part of the environment was/is important here, thanks for the suggestion (edited now) – Emil Bode Nov 29 '19 at 12:39
  • had to make an edit to my answer: the line width setting returned by `get_terminal_size().columns` doesn't seem to apply to very long strings, at least in my version of IPython / Spyder... (IPython 7.9.0 in Spyder 4.0.0rc3) – FObersteiner Nov 29 '19 at 14:01

2 Answers2

1

Building on Sayandip Dutta's answer, you could also use get_terminal_size from shutil to get the current line length setting, then write the new line and append spaces if it is shorter than that.

import time
from shutil import get_terminal_size

l = ["1st statment is long",
     "2nd short",
     "3rd statement is much longer...",
     "done."]

sz = get_terminal_size().columns
for i in l:
    print('\r', end=i.ljust(sz, ' '))
    time.sleep(1)

EDIT: I just realized that this might not work for very long lines... so you will have to use something like

lines = ["1st statment is long",
         "2nd short",
         "3rd statement is much longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer longer...",
         "more lines",
         "done."]

widths = [0] + [len(l) for l in lines][:-1]
for l, w in zip(lines, widths):
    print('\r', end=l.ljust(w, ' '))
    time.sleep(1)
FObersteiner
  • 22,500
  • 8
  • 42
  • 72
0

You can try this:

lst = ["Now reading file path/to/xxx/file.ext...","Now reading ./path/with/many/long-named/subdirectories/version/LongFileNameAsWell.ext...","Now reading ./file.ext..."]
maxlen = 0

for l in lst:
    maxlen = max(maxlen,len(l))
    print('\r',end = l.ljust(maxlen,' '))

Of course instead of lst it will be your directory, and instead of l there will be filenames.

Sayandip Dutta
  • 15,602
  • 4
  • 23
  • 52