I want to run a part of my loop for a certain time: 60 seconds. Afterwards I set a boolean flag and continue at another point. Does Python have something like a stopwatch? Maybe this is OS specific: it's targeted against a Linux env.
Sleeping a couple of seconds is easy... no question. ;) I want the opposite.
You could use the time.time() method:
import time
endtime = time.time() + 60
while time.time() < endtime:
# do something
Note - you probably don't want to use time.clock() as this measures CPU time rather than wall time.
You could use time.time() to set the begin of the loop, and later check if the passed time is greater than 60 seconds. But then you'll have a problem if the clock changes during the loop (very rare case) - so you should check for negative differences, too.
import time
begin = time.time()
for something:
# do something
if not (begin <= time.time() <= begin + 60):
break
As far as I know, Python does not include a stop watch class like in C#, for example.
Related
I have made this code to make a Countdown:
import time
end = time.time() + 5.5
if time.time() == end:
print('Time\'s up')
That didn't work. It wasn't an error. It didn't happened anything.Has anybody an idea? Thanks!
You check time.time() again immediately after setting end, and you only check it once, so it is definitely not going to be 5.5 seconds later. If you want to do this by making minimal modifications to your code:
while time.time() < end:
pass
print('Time\'s up')
you don't want to check for == in case the exact microsecond is not returned by the call to time.time().
If you want to do this the right way, you should use time.sleep(5.5).
You're comparing for equality, but that assumes that the timestamp returned is exactly the same as the original one, plus 5.5 seconds. That won't happen unless you're very lucky. Additionally you're doing this check right after you've retrieved the previous time, and there is no chance that 5.5 seconds will pass between those two statements.
You can fix this by either using the appropriate way - or the naive way.
The correct way to handle this is to use time.sleep(5.5):
import time
time.sleep(5.5)
print("Time's up!")
The naive way to implement it like in your example:
import time
end = time.time() + 5.5
while time.time() < end:
pass
print("Time's up")
This will spin an empty loop until the requested time has passed. The reason why I'm calling this naive is because your program will be stuck spending all available CPU resources while doing nothing, except for checking the clock and the current time until 5.5 seconds has passed. In the first example it tells the operating system that "Hey, wake me up in 5.5 seconds" and other processes can use the CPU in between.
I have a Python algorithm that will not terminate on its own. I'm doing some profiling on it and would like to run it with a bunch of different settings for a set amount of time, terminating it after that time has elapsed and starting the next run. How do I do this from within Python?
for c in configs:
# what do I wrap this with do terminate it after a
# set amount of time and go to next loop iteration?
runalgorithm(config)
start = time.time()
endt = start + 30
while True:
now = time.time()
if now > endt:
return
else:
print end - start
Try something like this within your for loop!
I am thinking to implement a function like below:
timeout = 60 second
timer = 0
while (timer not reach timeout):
do somthing
if another thing happened:
reset timer to 0
My question is how to implement the timer stuff? Multiple thread or a particular lib?
I hope the solution is based on the python built-in lib rather than some third-part fancy package.
I don't think you need threads for what you have described.
import time
timeout = 60
timer = time.clock()
while timer + timeout < time.clock():
do somthing
if another thing happened:
timer = time.clock()
Here, you check every iteration.
The only reason you would need a thread is if you wanted to stop in the middle of an iteration if something was taking too long.
I use the following idiom:
from time import time, sleep
timeout = 10 # seconds
start_doing_stuff()
start = time()
while time() - start < timeout:
if done_doing_stuff():
break
print "Timeout not hit. Keep going."
sleep(1) # Don't thrash the processor
else:
print "Timeout elapsed."
# Handle errors, cleanup, etc
I need to wait for about 25ms in one of my functions. Sometimes this function is called when the processor is occupied with other things and other times it has the processor all to itself.
I've tried time.sleep(.25) but sometimes its actually 25ms and other times it takes much longer. Is there a way to sleep for an exact amount of time regardless of processor availability?
Because you're working with a preemptive operating system, there's no way you can guarantee that your process will be able to have control of the CPU in 25ms.
If you'd still like to try, it would be better to have a busy loop that polls until 25ms has passed. Something like this might work:
import time
target_time = time.clock() + 0.025
while time.clock() < target_time:
pass
0.25 seconds are 250 ms, not 25. Apart from this, there is no way to wait for exactly 25 ms on common operating systems – you would need some real-time operating system.
What system are you on? If you're on Windows you may want to do something like this for exact timing:
import ctypes
kernel32 = ctypes.windll.kernel32
# This sets the priority of the process to realtime--the same priority as the mouse pointer.
kernel32.SetThreadPriority(kernel32.GetCurrentThread(), 31)
# This creates a timer. This only needs to be done once.
timer = kernel32.CreateWaitableTimerA(ctypes.c_void_p(), True, ctypes.c_void_p())
# The kernel measures in 100 nanosecond intervals, so we must multiply .25 by 10000
delay = ctypes.c_longlong(.25 * 10000)
kernel32.SetWaitableTimer(timer, ctypes.byref(delay), 0, ctypes.c_void_p(), ctypes.c_void_p(), False)
kernel32.WaitForSingleObject(timer, 0xffffffff)
This code will pretty much guarentee your process will sleep .25 seconds. Watch out though- you may want to lower the priority to 2 or 3 unless it's absolutely critical that this sleeps for .25 seconds. Certainly don't change the priority too high for a user-end product.
Edit: in Windows 10 this nonsense seems unnecessary. Try it like so:
>>> from time import sleep
>>> import timeit
>>> '%.2f%% overhead' % (timeit.timeit('sleep(0.025)', number=100, globals=globals()) / 0.025 - 100)
'0.29% overhead'
.29%, or thereabout, is fairly low overhead, and usually more than accurate enough.
Previous Windows versions will by default have a sleep resolution of 55 msecs, which means your sleep call will take somewhere between 25 and 55 msecs. To get the sleep resolution down to 1 millisecond you need to set the resolution used by Windows by calling timeBeginPeriod:
import ctypes
winmm = ctypes.WinDLL('winmm')
winmm.timeBeginPeriod(1)
Another solution for accurate timings and delay is to use the perf_counter() function from module time. Especially useful in windows as time.sleep is not accurate in milliseconds. See below example where function accurate_delay creates a delay in millisecond.
import time
def accurate_delay(delay):
''' Function to provide accurate time delay in millisecond
'''
_ = time.perf_counter() + delay/1000
while time.perf_counter() < _:
pass
delay = 10
t_start = time.perf_counter()
print('Wait for {:.0f} ms. Start: {:.5f}'.format(delay, t_start))
accurate_delay(delay)
t_end = time.perf_counter()
print('End time: {:.5f}. Delay is {:.5f} ms'.
format(t_end, 1000*(t_end - t_start)))
sum = 0
ntests = 1000
for _ in range(ntests):
t_start = time.perf_counter()
accurate_delay(delay)
t_end = time.perf_counter()
print('Test completed: {:.2f}%'.format(_/ntests * 100), end='\r', flush=True)
sum = sum + 1000*(t_end - t_start) - delay
print('Average difference in time delay is {:.5f} ms.'.format(sum/ntests))
What you intend to do is a real time application. Python (and probably the OS you are using) is not intended to program this kind of applications, where time restriction is so strict.
In order for you to achieve what you are looking for you need a RTOS (Real Time Operating System) and develop your application using a suitable programming language (usually C) following RT best practises.
From the docs of the sleep method:
Suspend execution for the given number of seconds. The argument may be
a floating point number to indicate a more precise sleep time. The
actual suspension time may be less than that requested because any
caught signal will terminate the sleep() following execution of that
signal’s catching routine. Also, the suspension time may be longer
than requested by an arbitrary amount because of the scheduling of
other activity in the system.
The fact is that it depends on your underlying OS.
i have a loop that runs for up to a few hours at a time. how could I have it tell me how long it has been at a set interval?
just a generic...question
EDIT: it's a while loop that runs permutations, so can i have it print the time running every 10 seconds?
Instead of checking the time on every loop, you can use a Timer object
import time
from threading import Timer
def timeout_handler(timeout=10):
print time.time()
timer = Timer(timeout, timeout_handler)
timer.start()
timeout_handler()
while True:
print "loop"
time.sleep(1)
As noted, this is a little bit of a nasty hack, as it involves checking the time every iteration. In order for it to work, you need to have tasks that run for a small percentage of the timeout - if your loop only iterates every minute, it won't print out every ten seconds. If you want to be interrupted, you might consider multithreading, or preferably if you are on linux/mac/unix, signals. What is your platform?
import time
timeout = 10
first_time = time.time()
last_time = first_time
while(True):
pass #do something here
new_time = time.time()
if new_time - last_time > timeout:
last_time = new_time
print "Its been %f seconds" % (new_time - first_time)
Output:
Its been 10.016000 seconds
Its been 20.031000 seconds
Its been 30.047000 seconds
There's a very hacky way to do this by using time.asctime(). You store the asctime before entering the while loop and somewhere in the loop itself. Calculate the time difference between the stored time and the current time and if that difference is 10 seconds, then update the stored time to the current time and print that it's been running.
However, that's a very hacky way to do it as it requires some twisted and boring math.
If your aim is to check the runtime of a specific algorithm, then you're better off using the timeit module
Hope this Helps