0

i have a quite complex problem, but here is the "simplest version" so you can better understand it.

import time
for i in range(10):
   time.sleep(1)
   print('{}\r'.format(i), end="")

and here everything works fine, the problem comes when i try to make a countdown

import time
for i in range(10):
   time.sleep(1)
   print('{}\r'.format(10-i), end="")

the output is 10... then 90... 80... 70 and so on, it seems like if the second cipher of the 10 is not cancelled. can someone tell me why?

Giuppox
  • 1,393
  • 9
  • 35

3 Answers3

4

\r moves the cursor to the beginning of the line, but it doesn't "clear" anything already printed unless you overwrite it (this may be platform-dependent). Thus, the 0 character will remain visible. You can deal with that by always printing a "fixed-width" column, so that empty spaces are printed to blank out anything left over from before. You can also just put the CR in the end param.
Thus:

import time
for i in range(10):
   time.sleep(1)
   print('{: <3}'.format(10-i), end='\r')

This uses a format specifier to indicate a space-filled, <left-aligned, 3-width column. You can change the 3 to any higher number depending on how many digits your counter needs.

tzaman
  • 46,925
  • 11
  • 90
  • 115
  • hi, thanks for your answer, i found it very useful. I found this ansi escape code on the internet... \x1b[2K\r can you explain what it does? thanks... really appreciated. alternatively, is there a method to know the width of the previous line? – Giuppox Aug 31 '20 at 10:16
  • @Giuppox That's a terminal escape sequence, you can read more about it [here](https://stackoverflow.com/questions/55192019/what-does-this-mean-in-python-x1b2k). But if you're trying to do more complex terminal stuff, I'd suggest just using a proper TUI library. `curses` is the most basic and included in the stdlib, but there are a ton of alternatives out there like `blessed` or `prompt-toolkit`. – tzaman Aug 31 '20 at 11:28
1

It's caused by a simple error, you are missing a space before the \r:

Your Code:

   print('{}\r'.format(10-i), end="")
   # > 10,90,80

Change it to:

   print('{} \r'.format(10-i), 
   #> 10, 9, 8
Manas Sambare
  • 1,158
  • 2
  • 11
  • 22
1

The issue is like old typewriters when you press \r carriage return it goes to line start and chages one character from there. so 10 will become 90 as the first character changes.

import time
for i in range(10):
    time.sleep(1)
    print('{:02d}'.format(10-i), end="\r")

So one potential solution is to fix the width. here I have made it 2 digit

Equinox
  • 6,483
  • 3
  • 23
  • 32