Python's print statement followed by sleep(...) function gives unexpected output - python

Here's my Python 3 code:
from time import sleep
s='what is your name'
for x in s:
print(x,end='')
sleep(1)
What I expect is that, each letter will be printed one by one after a delay of one second. But when I run this program, it takes a time of len(s) seconds and then prints the value of s.
Can anyone explain to me what is actually happening.

Use flush argument to print function:
print(x, end='', flush=True)
From docs:
Whether output is buffered is usually determined by file, but if the
flush keyword argument is true, the stream is forcibly flushed.

Related

Why isn't python printing statement above infinite loop?

The output of this code is just bb. I want to know why cc is not printed, meaning that the third line is not executed which is print("cc").
This is the link - https://ideone.com/M7LyS3
print("bb")
s2=input()
print("cc")
while 0>-50:
pass
print("qq")
Input = 5
print does not flush by default. Here, your first print in queued, and then flushed when you call input(). The second print is queued, but is never flushed.
If you add the optional flush argument, you'll get the behavior you expect:
print("bb", flush = True)
s2=input()
print("cc"", flush = True)
while 0>-50:
pass
print("qq"", flush = True) # Will never happen because of the infinite loop, though
Try copying your code in this online compiler here:
https://www.onlinegdb.com/online_python_compiler
It works as you expected.
The reason it's not printing cc on your machine might be because of some issues or race condition of the buffer that prints output. The program gets busy in that infinite loop and is holding the buffer to be written to the terminal/console.
The code is running fine:
print("bb")
s2=input()
print("cc")
while 0>-50:
pass
print("qq")
Output:
bb
my_input
cc

printing every thing slowly (Simulate typing)

[printing slowly (Simulate typing)
I got my answer from the link above but it only works when you put the string as a parameter when calling function.
I want the code to print slowly every time when I use print().
is it possible?
Yes, you can do it like this, however, I think it's not a good idea:
import time
def dprint(string):
for letter in string:
__builtins__.print(letter,end = '', flush=True)
time.sleep(.1)
__builtins__.print("")
print = dprint
print("something")
Yes, you can do it using the stdout version as below.
import sys, time
def print(s):
for letter in s:
sys.stdout.write(letter)
time.sleep(.1)
print("Foo")
Changing the default behaviour of print() is not recommended and was only introduced for purpose of porting Python 2 programs easily. Moreover overloading the print function without a special parameter will make the default functionality of print() moot.
Create another function with adds a delay to the prints. Also remember that you cannot use print() because it appends a new line. You’ll have to you sys.stdout.write()
So a basic function would look like:
def typrint(x):
for i in len(x):
sys.stdout.write(x[i])
sleep(0.05)
sys.stdout.write(“\n”)
Check this article to see why Python updated print() to a function
I am using this as the solution for the problem,
import sys,time
def delay(str):
for i in str:
sys.stdout.write(i)
sys.stdout.flush()
time.sleep(0.04)
Note: You need to add in every print statement or here "delay" statement "\n".

Dynamically call and print a function's return-value within a loop, overwrite previous outputs

I'm looking for the cleanest way to print a variable dynamically in python 3.
I want to repeatedly call psutil.virtual_memory() and print its return-value in place.
Something like this:
import psutil
import time
memory = psutil.virtual_memory()
while True:
print(f"Memory: {memory}")
time.sleep(0.5)
Ofcourse that wouldn't be dynamic. I want "memory" to update every 0.5 seconds on the same line.
I couldn't seem to find a clean example of how to do this in this manner.
UPDATE: I'm also wanting to learn how I can do this with multi-line print statements.
Like this
Memory: 500MB
CPU Usage: 25%
Just add print(..., end='\r') to the end of your printing statement.
This brings the cursor to the beginning of the line, so subsequent prints will overwrite it.
f-strings allow you to directly print a function call or expression in the first place, so do that. (No need to store the stale return value to a variable, in the first place)
while True:
print(f"Memory: {psutil.virtual_memory()}")
time.sleep(0.5)
UPDATE: after you accepted an answer, we infer that when you say "print the value in-place", you actually mean "overwrite the output (on console) from previous print"
"in-place" is actually a different term that usually refers to "variable assignment without allocating new memory". Better to say "overwrite on the console".
Add carriage return with flush for print.
import psutil
import time
def memory():
return psutil.virtual_memory()
while True:
print(f"Memory: {memory()}", end="\r", flush=True)
time.sleep(0.5)

Strange print behavior with time.sleep in python [duplicate]

This question already has an answer here:
Why doesn't print output show up immediately in the terminal when there is no newline at the end?
(1 answer)
Closed last month.
I was trying to create a progress-like thing by printing a dot every second on the same line. Something like "Fishing.....". This is what I used:
import time
print('Fishing', end='')
for i in range(5):
time.sleep(1)
print('.', end='')
But it waits for 5 seconds and prints Fishing..... all at once. But when I don't use the end='', it prints dots every second, but on separate lines like so
Fishing.
.
.
.
.
My questions:
Why does print behave this way?
How can I print a dot every second, but on the same line?
Why does print behave this way?
This has less to do with print and more with your terminal. For performance reasons, the text only gets "flushed" everytime there's a newline character, and not one character at a time.
How can I print a dot every second, but on the same line?
By "flushing" the standard output manually everytime you printed something:
import time
import sys
print('Fishing', end='')
sys.stdout.flush()
for i in range(5):
time.sleep(1)
print('.', end='', flush=True) # another way
If you need this all the time, you could define a seperate flushing print function:
from functools import partial
myprint = partial(print, end='', flush=True)
myprint('Fishing')
for i in range(5):
time.sleep(1)
myprint('.')
This is because print is considered to be an expensive operation: it will usually wait until it has to print a lot of data, or until a new line is encountered (usually only if output is written to a terminal):
Output buffering is determined by file. Use file.flush() to ensure, for instance, immediate appearance on a screen.
Evidently it is not expensive in the sense that it takes minutes: but asking the terminal operator to print new content, or the operating system to write data to a file (in case of I/O redirection) is still not "lightning fast".
You can force to print all data that is still in the queue, by using a flush on the standard output channel.
use
print('.', end="", flush=True)

Python: time.sleep functions unexpectedly?

I'm trying to make a simple function that will type out a string letter by letter, such as in a game, where text scrolls.
Here's what my code looks like:
import time
def ScrollingText(s):
s=str(s)
for letter in s:
print(letter, end="")
time.sleep(.05)
print("") # newline at the end
if __name__=='__main__':
ScrollingText("Hello World!")
However when I run, it waits, then dumps out the whole string at once. I'm new to python (and this forum as well) so if anyone can point me in the right direction and show me what I'm missing here in time.sleep I'd greatly appreciate it. Thanks!
As you do not have a newline in your string, python will buffer it. You have to explicitly flush the output after each character like this:
import sys
import time
def ScrollingText(s):
s=str(s)
for letter in s:
print(letter, end="")
sys.stdout.flush()
time.sleep(.05)
print("") # newline at the end
For better performance, I/O is usually buffered, that is, python will collect the data you print until it can send it out as a large block (this also goes for file I/O by the way). By calling flush() on sys.stdout (which is the file object where print writes to by default), you force python to send your data to the operating system (and that will send it to your terminal).

Categories

Resources