I am trying to make a simple program in komodo edit using python that when it runs will print out 10 seconds worth of time in the command output.
The code is as follows:
import time
seconds = 0
while seconds != 10:
time.sleep(1)
seconds += 1
print(">", seconds)
When I run this in komodo edit, it doesn't print out the numbers as wanted.
I want the number 1 to be printed after one second of time, the number 2 to be printed after two seconds of time, and etc.
Instead, it prints out all the numbers (1-10) after 10 seconds of time.
I have run this exact same program in the python IDLE and it works as it should, printing one number per second.
What am I doing wrong or what do I not understand/know about?
The program is likely running in an environment where it does not believe its output is connected to a terminal, so stdout defaults to block buffering, not line buffering. Since you're outputting very little data, the buffer never fills, and is only flushed just before the program exits.
The simplest fix is to add the flush=True argument to your print call, so the buffer is explicitly flushed after each print:
print(">", seconds, flush=True)
Related
I have done a little function that acts as a timer, updating the line as minutes go (put a second here for test.
I wanted to use the KeyboardInterrupt to exit this part of my program so used the try/except method, but something odd happens.
With the try/except, nothing prints on the screen. When i do the Ctrl-C, then all the statements print together (one after the other) and the input statement appears fine.
Like this :
ou have been working for 0 minutesYou have been working for 1 minutesYou have been working for 2 minutesYou have been working for 3 minutesYou have been working for 4 minutesYou have been working for 5 minutesYou have been working for 6 minutesYou have been working for 7 minutesYou have been working for 8 minutesYou have been working for 9 minutesYou have been working for 10 minutesYou have been working for 11 minutesAre you sure you want to finish your working session ? (y/n)
Here is my code:
def timer():
minutes = 0
startDateTime = datetime.datetime.now()
stringDateTime = startDateTime.strftime('%m/%d/%Y, at %H:%M:%S' )
while True:
try:
time.sleep(1)
print('You have been working for {} minutes'.format(minutes), end='')
minutes += 1
except KeyboardInterrupt:
choice = input('Are you sure you want to finish your working session ? (y/n)')
if choice == 'y':
log_time(stringDateTime, minutes)
elif choice == 'n':
pass
pass
Is this behavior is inherent to try/except ?
If it is, what other solutions could I use ?
Best !
By default Python will use buffered output. Since sys.stdout is a text stream, debuffering usually takes place when a newline is emitted, but your code isn't emitting any.
If you left your program to run for a while I suspect you would eventually see a huge splurge of output as the buffer filled up.
To force debuffering, simply use
sys.stdout.flush()
when you want to be sure everything printed so far is emitted.
As #wjandrea points out in a comment to another answer, adding flush=True to print's arguments is a simpler solution.
#holdenweb has explained it. I am just adding this for better clarity.
If you try to print like this then it will be saved in the buffer and all will be outputted after the loop exits. which in this case will take 13s for the string of length 13.
import time
strn = "StackOverflow"
for i in range(0, len(strn)):
print(strn[i], end ="")
time.sleep(1)
but with the flush, it will output one character after every second.
import time
import sys
strn = "StackOverflow"
for i in range(0, len(strn)):
print(strn[i], end ="")
sys.stdout.flush()
time.sleep(1)
Since you're not printing a newline at the end of your print statement, it's not getting flushed to output. Try calling sys.stdout.flush() after every print.
I'm using the Enthought Canopy IDE to write Python and the the output of print commands do not reach the ipython output window at the time when I would expect them to. The clearest way to explain is to give an example:
import time
print 1
print 2
time.sleep(1)
print 3
for i in range(10):
print i
time.sleep(0.5)
The initial 1, 2 and 3 are displayed simultaneously after a second, and then there is a half second delay before the next 0 is displayed.
(as opposed to the expected instantaneous and simultaneous display of 1 and 2, then a 1 second delay before a simultaneous display of 3 and 0, then half second delays)
This is causing me issues as I am looking to get readouts of variables before a time consuming portion of script runs, and I cannot get it to display these readouts without terminating the program after calling the print command.
Any ideas/solutions?
I'm on Windows 7, let me know if you need any other specs/config details...
Thanks!
You can start the Python interpreter with an additional -u parameter, which gives you unbuffered output (i.e. instant).
Or you can call sys.stdout.flush() after every print. Maybe even wrapping it in a function like this:
from __future__ import print_function
import sys
def print_flush(*args):
print(*args)
sys.stdout.flush()
Short version: I have a program that prints to the terminal successive integer numbers in an infinite loop. At some point, the terminal became black, and no output is visible, but I can still execute commands.
Details:
I read this answer in PCG and wanted to try it in Python. Here it is:
#!/bin/python2
class Dier(object):
def __init__(self):
global ct
ct += 1
print ct
def __del__(self):
Dier()
ct = 0
Dier()
This program loops indefinitely, printing the number of iterations on each step. Left overnight (we get to the tenths of millions in a matter of minutes) executed from an Ubuntu gnome terminal, the terminall just shows black. The program is still running, and new lines appear, but nothing is visible. I killed the program, but the terminal, including the command prompt, is black. I can input commands, and they work, but no output is visible.
Why is this happening?
Some information I provided in the comments:
The memory used by the program (reported by top) remains constant and low.
I can print absurdly large numbers to the terminal without getting this behaviour. The largest number I have printed has 10^10^6 digits (of course, the terminal has forgotten the beginning of it, and only shows the last digits, but its log10 is 1246124). My program couldn't have gone that far, that would take millions of times the age of the universe.
On an added note, if I try to print something ever bigger than that, it just seems to freeze, using the CPU but without any output (while the original output was there, but invisible).
Seems like the output is being buffered. You should try and change the print to
print ct, "\n"
or
print ct
sys.stdout.flush()
alternatively you can tell python to not buffer the output by calling it with -u parameter (see https://docs.python.org/2/using/cmdline.html#cmdoption-u) or setting PYTHONUNBUFFERED=1 env variable (see https://docs.python.org/2/using/cmdline.html#envvar-PYTHONUNBUFFERED)
What does sys.stdout.flush() do?
Python's standard out is buffered (meaning that it collects some of the data "written" to standard out before it writes it to the terminal). Calling sys.stdout.flush() forces it to "flush" the buffer, meaning that it will write everything in the buffer to the terminal, even if normally it would wait before doing so.
Here's some good information about (un)buffered I/O and why it's useful:
http://en.wikipedia.org/wiki/Data_buffer
Buffered vs unbuffered IO
Consider the following simple Python script:
import time
import sys
for i in range(5):
print(i),
#sys.stdout.flush()
time.sleep(1)
This is designed to print one number every second for five seconds, but if you run it as it is now (depending on your default system buffering) you may not see any output until the script completes, and then all at once you will see 0 1 2 3 4 printed to the screen.
This is because the output is being buffered, and unless you flush sys.stdout after each print you won't see the output immediately. Remove the comment from the sys.stdout.flush() line to see the difference.
As per my understanding, When ever we execute print statements output will be written to buffer. And we will see the output on screen when buffer get flushed(cleared). By default buffer will be flushed when program exits. BUT WE CAN ALSO FLUSH THE BUFFER MANUALLY by using "sys.stdout.flush()" statement in the program. In the below code buffer will be flushed when value of i reaches 5.
You can understand by executing the below code.
chiru#online:~$ cat flush.py
import time
import sys
for i in range(10):
print i
if i == 5:
print "Flushing buffer"
sys.stdout.flush()
time.sleep(1)
for i in range(10):
print i,
if i == 5:
print "Flushing buffer"
sys.stdout.flush()
chiru#online:~$ python flush.py
0 1 2 3 4 5 Flushing buffer
6 7 8 9 0 1 2 3 4 5 Flushing buffer
6 7 8 9
import sys
for x in range(10000):
print "HAPPY >> %s <<\r" % str(x),
sys.stdout.flush()
As per my understanding sys.stdout.flush() pushes out all the data that has been buffered to that point to a file object.
While using stdout, data is stored in buffer memory (for some time or until the memory gets filled) before it gets written to terminal. Using flush() forces to empty the buffer and write to terminal even before buffer has empty space.
You can see the differences b/w these two
import sys
for i in range(1,10 ):
sys.stdout.write(str(i))
sys.stdout.flush()
for i in range(1,10 ):
print i
In the first case, the characters are output one by one after each is written, because of the flush. In the second case, the characters are buffered by Python until it thinks it's got something worth the effort to write, and then written all in a batch.
If you add, say, a time.sleep(0.2) in the loops, this becomes more obvious.
Imagine you have a toy box where you keep all your toys. When you want to play with a toy, you usually take it out of the box, right?
In a similar way, when you write something on the computer, it gets stored in a temporary place called a buffer. Think of it like a toy box for computer data. The computer waits until the toy box is full before it takes the data out of the box and shows it to you on the screen.
However, sometimes you might want to play with a toy right away, without waiting for the toy box to fill up with other toys. This is like when you call sys.stdout.flush() in Python. It tells the computer to take the data out of the buffer and show it to you on the screen right away, without waiting for the buffer to fill up.
I have the following script 186.py:
S=[]
study=set([524287])
tmax=10**7
D={}
DF={}
dudcount=0
callcount=0
def matchval(t1,t2):
if t1==t2:
global dudcount
dudcount+=1
else:
global callcount
callcount+=1
D.setdefault(t1,set([]))
D.setdefault(t2,set([]))
D[t1].add(t2)
if t1 in D[t2]:
DF.setdefault(t1,set([]))
DF[t1].add(t2)
DF.setdefault(t2,set([]))
DF[t2].add(t1)
for k in xrange(27):
t1=(100003 - 200003*(2*k+1) + 300007*(2*k+1)**3)%(1000000)
S.append(t1)
t2=(100003 - 200003*(2*k+2) + 300007*(2*k+2)**3)%(1000000)
S.append(t2)
matchval(t1,t2)
t1=(100003 - 200003*(55) + 300007*(55)**3)%(1000000)
S.append(t1)
t2=(S[31]+S.pop(0))%(1000000)
S.append(t2)
matchval(t1,t2)
for k in xrange(29,tmax+1):
t1=(S[31]+S.pop(0))%(1000000)
S.append(t1)
t2=(S[31]+S.pop(0))%(1000000)
S.append(t2)
matchval(t1,t2)
D.setdefault(524287,set([]))
DF.setdefault(524287,set([]))
print D[524287]
print DF[524287]
print dudcount,callcount
print "Done"
The last line prints "Done" but python doesn't exit when this happens. I type the following command:
$ time python 186.py
And get the results:
set([810528L, 582178L, 49419L, 214483L, 974071L, 651738L, 199163L, 193791L])
set([])
11 9999989
Done
But I have to ctrl+C to get the time:
real 34m18.642s
user 2m26.465s
sys 0m11.645s
After the program outputs "Done" python CPU usage is very little... but the memory usage continues to grow... I used ctrl+C once it got to 80% of my system memory (its an old system).
What is going on here? What is the program doing after Done is printed? Shouldn't it be done?
Thanks,
Dan
I ran the same code on my 2 GHz dual-core laptop with 2GB RAM and it took about 1 1/2 minutes in Cygwin. The memory usage got up over 600 MB before the program quit and it took about 2-4 seconds after Done appeared for the prompt to come up and the memory to be released. However, I didn't see any memory increase after the Done appeared.
My guess is it has to do with memory management. After the Done appears, Python is working on freeing all of the memory which might take quite a while on an older machine with less RAM. I'm not sure why the memory actually increases unless there is just a delay in whatever is telling you how much memory is being used.
There are no indications in what you've posted that match the described symptoms. Perhaps the indentation in the executed code is stuffed and you are really about to run another loop around the whole pile. Note that only brave people are going to bother trying to reproduce your problem when it takes 34 minutes to run. Can you reproduce this problem in a shorter time?
When you did Control-C, what did the traceback say?
In any case, I'd strongly advise not having hard-coded constants(?) all over the place e.g. 524287 .... give it a meaningful name and do meaningful_name = 524287 at the start. Or if it's really a variable, feed it in via sys.argv.