Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does "time.sleep()" not work inside a for loop with a print function using the "end" attribute?

So, I'm just recently learning python and I was playing with some code. I wanted to print the some character without line breaks over a loop with some delay. I used the time.sleep() function inside the for loop. But, all it does is delay the output for the total time it would have taken in the loop, all at once and, then print out the character.

I did try it without the "end" attribute and it worked perfectly. But, I didn't want the line break.

from time import sleep
print("starting the progress bar")


for i in range(50):
    sleep(0.1)
    print("#", end = '')

I expected the output to print a character and with a delay, print another character. But, the script delays for 0.1 seconds for 50 times and then prints out all the characters at once

like image 595
thesuzan Avatar asked Jul 05 '19 04:07

thesuzan


People also ask

What a time sleep () does in Python?

Python time sleep function is used to add delay in the execution of a program. We can use python sleep function to halt the execution of the program for given time in seconds.

How do I print sleep time in Python?

Example 1: Python sleep() import time print("Printed immediately.") time.sleep(2.4) print("Printed after 2.4 seconds.") Here's how this program works: "Printed immediately" is printed.

Is time sleep blocking Python?

The reason you'd want to use wait() here is because wait() is non-blocking, whereas time.sleep() is blocking. What this means is that when you use time.sleep() , you'll block the main thread from continuing to run while it waits for the sleep() call to end. wait() solves this problem.

How do you sleep while looping in Python?

sleep() is a method that causes Python to pause for a specified number of seconds. Give sleep() the number of seconds that you want it to pause for in its parenthesis, and it will stall the execution of your program. It's fairly common to see sleep() in loops, especially infinite ones.


4 Answers

As python is linebuffered it will wait for a newline before printing the stdout.

Solution 1:

Add PYTHONUNBUFFERED=1 to your env.var:

export PYTHONUNBUFFERED=1

This will allow the output to be immediately dumped

Solution 2:

As you are using python >= 3 you can use the flush=True

for i in range(50):
    sleep(0.1)
    print("#", end="", flush=True)
like image 142
Nic Laforge Avatar answered Oct 03 '22 11:10

Nic Laforge


I just found a solution on reddit.

reddit comment on why it doesn't work and how beginners fall into the same pitfall

So, it has something to do with buffering.

Here's the code that would work;

from time import sleep
print("starting the progress bar")


for i in range(50):
    sleep(0.1)
    print("#", end = '', flush = True)
like image 32
thesuzan Avatar answered Oct 03 '22 10:10

thesuzan


By default, Python is linebuffered. As long as you print without a newline, output is collected but not shown. You must forcefully flush the output.

from time import sleep
print("starting the progress bar")


for i in range(50):
    sleep(0.1)
    print("#", end = '', flush=True)

Note in that whatever you use to view the output might be linebuffered as well. This cannot be changed from within your script.

like image 36
MisterMiyagi Avatar answered Oct 03 '22 12:10

MisterMiyagi


You can use the -u option when running your program.

$ man python3


PYTHON(1)                                                            PYTHON(1)

...

       -u     Force  the  stdout  and  stderr  streams to be unbuffered.  This
              option has no effect on the stdin stream.

Run like this: python3 -u file.py


Alternatively, you can set the PYTHONUNBUFFERED environment variable in your shell

       PYTHONUNBUFFERED
              If this is set to a non-empty string it is equivalent to  speci-
              fying the -u option.

Like so: PYTHONUNBUFFERED="yes" python3 file.py


Lastly, you can use flush=True as other answers have mentioned.

like image 34
xrisk Avatar answered Oct 03 '22 10:10

xrisk