Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why time() below 0.25 skips animation in Python?

This code works as expected. Output:

Loading 
Loading.
Loading..
Loading...

Code:

done = False
count = 0

while not done:
    print '{0}\r'.format("Loading"),
    time.sleep(0.25)
    print '{0}\r'.format("Loading."),
    time.sleep(0.25)
    print '{0}\r'.format("Loading.."),
    time.sleep(0.25)
    print '{0}\r'.format("Loading..."),
    time.sleep(0.25)
    count += 1
    if count == 5:
        done = True

And this code doesn't. Output:

Loading.
Loading...

Code:

done = False
count = 0

while not done:
    print '{0}\r'.format("Loading"),
    time.sleep(0.125)
    print '{0}\r'.format("Loading."),
    time.sleep(0.125)
    print '{0}\r'.format("Loading.."),
    time.sleep(0.125)
    print '{0}\r'.format("Loading..."),
    time.sleep(0.125)
    count += 1
    if count == 5:
        done = True

Why does the time function seem to skip every second print statement if it is lower than 0.25?

like image 373
Gunnm Avatar asked Jan 06 '16 12:01

Gunnm


1 Answers

Reason

Depending on the platform, Python buffers the output to different degrees. For example, on Mac OSX there is no output at all even for your version with 0.25 seconds sleep.

Flushing manually

Flushing manually should work:

import sys
import time

done = False
count = 0

while not done:
    for n in range(4):
        print '{0}\r'.format("Loading" + n * '.'),
        sys.stdout.flush()
        time.sleep(0.125)
    print ' ' * 20 + '\r',
    count += 1
    if count == 5:
        done = True

You need to flush the output with sys.stdout.flush(). You also need to print empty spaces to make the dots "going back and forth":

print ' ' * 20 + '\r',

More minimal and cleaned up

This is shortened and a bit more general in terms of the shown text:

import sys
import time


text = 'Loading'
for _ in range(5):
    for n in range(4):
        print '{0}\r'.format(text + n * '.'),
        sys.stdout.flush()
        time.sleep(0.25)
    nspaces = len(text) + n
    print ' ' * nspaces + '\r',

Running unbuffered from the commandline

You can remove the line:

sys.stdout.flush()

if you run your script with the -u option:

python -u script_name.py

Note: This will have an effect on all print statements.

like image 132
Mike Müller Avatar answered Nov 17 '22 09:11

Mike Müller