Creating a timer that runs in the background - python

I'm making a client/server program and on the client I want a clock on the GUI that displays the running time. Now there's plenty of tutorials on here on how to make a clock/timer and I think I have that part down.
The issue is making one that runs in the background while the rest of the code executes. At the moment I have a loop for my timer that the code doesn't move past, so it just starts counting the timer then doesn't do anything else after that. At least until the timer is stopped anyway.
I'm guessing I need to find a way to make it run in the background, but I don't know how and I can't find the answer. It has been suggested to me that I should use threading/multithreading, but that looks kinda complicated and I can't quite figure it out.
Is there a better way to do it or is threading the way to go?

You can keep track of time passed since a certain point by subtracting the start time from the current time. You can then update the timer value with this (if you have a lot of other code running in between this will become slower so you might want to round it).
import time
start = time.time()
while doing_stuff:
do_stuff()
GUI.update_timer(time.time() - start)

I don't see any reason why threading is not a good idea. For one, if you have complex computations to run in your code, threading will enhance the performance by running your code and the timer in the background in tandem. Here's something that may help illustrate my point with a simple function to square numbers:
import time
import threading
def square():
start_time = time.time()
x = int(input('Enter number: '))
squared = x*x
print('Square is: %s ' %squared)
print('Time elapsed: %s seconds' %(time.time() - start_time))
set_thread = threading.Thread(target=square) #set Thread() to run on square() function
set_thread.start()
#Output:
Enter number: 5
Square is: 25
Time elapsed: 1.4820027351379395 seconds
Of course, the simple function above may take only a few seconds. The timer begins when the function is called and stops when the code in the square() block has run. But imagine a situation where your code has much more complex computations such as insert multiple values into a database or sort a large list of data and write to a file at the same time.

Related

how to optimize script to have 1 second between spoken words using speech module

the problem is that when i run my script it takes longer than the expected time 1 second before it says the next command. i think this has something to do with the speech command. what can i do to optimize this?
edit: link to the sppech module https://pypi.python.org/pypi/speech/0.5.2
edit2: per request i measured the sleep time only using datetime.
2016-06-29 18:39:42.953000
2016-06-29 18:39:43.954000
i found that it was pretty accurate
edit3: i tried the build in import win32com.client and it didnt work either
import speech
import time
import os
def exercise1():
speech.say("exercise1")
time.sleep(0.5)
for n in range(0, rep*2):
speech.say("1")
t ime.sleep(1)
speech.say("2")
time.sleep(1)
speech.say("3")
time.sleep(1)
speech.say("switch")
Refer the post here How accurate is python's time.sleep()?
It says:
"The accuracy of the time.sleep function depends on the accuracy of
your underlying OS's sleep accuracy. For non-realtime OS's like a
stock Windows the smallest interval you can sleep for is about
10-13ms. I have seen accurate sleeps within several milliseconds of
that time when above the minimum 10-13ms."
As you say in the comments, sleep(1) is fairly accurately 1s.
What you want to do to make each part take 1s, is time the "say" call, and then wait the remaining time to fill out the second. Something like this:
start = time.time()
speech.say("whatever")
end = time.time()
sleep(1 - (end - start)) # Wait however long will bring the time up to 1 second total

simplest way to time output of function

I am accessing a web API that seems to mysteriously hang every once in a while. Right now I am using print to do some simple logging. I am not familiar with threads or anything like it, and I'm hoping that there's just a simple way to keep a check on how long it's been since a new print statement was returned and gracefully quit my function if a maximum time interval has been reached. Thanks for any input.
Use the time.time() module to get time in seconds; from doc
'time() -> floating point number\n\nReturn the current time in seconds
since the Epoch.\nFractions of a second may be present if the system
clock provides them.'
Use it in code as,
import time
tic = time.time() #start
while True:
do_big_job()
toc = time.time();
if ( toc - tic > timeout ):
break

python How to loop a function [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the best way to repeatedly execute a function every x seconds in Python?
Hi so here is the code I have:
client = myclient(info1,info2)
sellor()
Contractor()
It works perfectly but what I would like to do is to make python launch that code every 60 seconds indefinitely...
I don't actually understand how I have to put the code together with the time loop
Any help is appreciated
Thank's
If the 60 seconds ignores the time it takes to execute your code):
from time import sleep
while True:
sleep(60)
# your code here
but if the 60 seconds takes into account the time it takes to execute your code:
from time import sleep
from os import fork
while True:
sleep(60)
fork() # create child process
# your code here
Use the sleep method. Just create a loop (while, for, whatever) and sleep for 60 secs every iteration.
import time
while True:
client = myclient(info1,info2)
sellor()
Contractor()
time.sleep(10)
hope it works,all the best mate
import time
repeat_time = 3.0
while True:
start_time = time.time()
# Your code goes here
time.sleep(max(repeat_time - (time.time() - start_time), 0.0))
And your code will be executed exactly every "repeat_time"
You could use sleep as already mentioned. But because there may be a variable amount of time needed for your own functions to run, this wouldn't necessarily mean your functions are run every 60 seconds.
If it was important that the period between each start of your functions is closer to 60 seconds, you could use time. I haven't tried this but something like
import time
while True:
# Get the current time
startTime = time.time()
# Your functions
client = myclient(info1,info2)
sellor()
Contractor()
delay = True
while delay:
if time.time() - startTime > 60:
delay = False # Break the delay
You might also think of just scheduling the task through windows scheduler. The benefit here would end the script once run and then execute the script again after scheduled interval. In the second approach it seems that the script instance process would continually run and only use the sleep function to do nothing for the specified time. I take it this way if the scripts fails at any instance you might have to keep a check to restart the script. While as a scheduled activity the script will be executed in any case at that specified intervals.
You might also not want the process thread to be kept running for the python script executed. I will research on this and you might get to hear form our other folks in the mean while.
Regards,
Harshal

Python -- time.sleep() offset by code duration

I have a function that runs a tick() for all players and objects within my game server. I do this by looping through a set every .1 seconds. I need it to be a solid .1. Lots of timing and math depends on this pause being as exact as possible to .1 seconds. To achieve this, I added this to the tick thread:
start_time = time.time()
# loops and code and stuff for tick thread in here...
time_lapsed = time.time() - start_time # get the time it took to run the above code
if 0.1 - time_lapsed > 0:
time.sleep(0.1 - time_lapsed)
else:
print "Server is overloaded!"
# server lag is greater that .1, so don't sleep, and just eat it on this run.
# the goal is to never see this.
My question is, is this the best way to do this? If the duration of my loop is 0.01, then time_lapsed == 0.01 ... and then the sleep should only be for 0.09. I ask, because it doesn't seem to be working. I started getting the overloaded server message the other day, and the server was most definitely not overloaded. Any thoughts on a good way to "dynamically" control the sleep? Maybe there's a different way to run code every tenth of a second without sleeping?
It would be better to base your "timing and math" on the amount of time actually passed since the last tick(). Depending on "very exact" timings will be fragile at the best of times.
Update: what I mean is that your tick() method would take an argument, say "t", of the elapsed time since the last call. Then, to do movement you'd store each thing's position (say in pixels) and velocity (in "pixels/second") so the magnitude of its movement for that call to tick() becomes "velocity * t".
This has the additional benefit of decoupling your physics simulation from the frame-rate.
I see pygame mentioned below: their "pygame.time.Clock.tick()" method is meant to be used this way, as it returns the number of seconds since the last time you called it.
Other Python threads may run in between leaving your thread less time. Also time.time() is subject to system time adjustments; it can be set back.
There is a similar function Clock.tick() in pygame. Its purpose is to limit the maximum frame rate.
To avoid outside influence you could keep an independent frame/turn-based counter to measure the game time.

Run a python function every second

What I want is to be able to run a function every second, irrelevant of how long the function takes (it should always be under a second). I've considered a number of options but not sure which is best.
If I just use the delay function it isn't going to take into account the time the function takes to run.
If I time the function and then subtract that from a second and make up the rest in the delay it's not going to take into account the time calculations.
I tried using threading.timer (I'm not sure about the ins and outs of how this works) but it did seem to be slower than the 1s.
Here's the code I tried for testing threading.timer:
def update(i):
sys.stdout.write(str(i)+'\r')
sys.stdout.flush()
print i
i += 1
threading.Timer(1, update, [i]).start()
Is there a way to do this irrelevant of the length of the time the function takes?
This will do it, and its accuracy won't drift with time.
import time
start_time = time.time()
interval = 1
for i in range(20):
time.sleep(start_time + i*interval - time.time())
f()
The approach using a threading.Timer (see code below) should in fact not be used, as a new thread is launched at every interval and this loop can never be stopped cleanly.
# as seen here: https://stackoverflow.com/a/3393759/1025391
def update(i):
threading.Timer(1, update, [i+1]).start()
# business logic here
If you want a background loop it is better to launch a new thread that runs a loop as described in the other answer. Which is able to receive a stop signal, s.t. you can join() the thread eventually.
This related answer seems to be a great starting point to implement this.
if f() always takes less than a second then to run it on a one second boundary (without a drift):
import time
while True:
time.sleep(1 - time.monotonic() % 1)
f()
The idea is from #Dave Rove's answer to a similar question.
To understand how it works, consider an example:
time.monotonic() returns 13.7 and time.sleep(0.3) is called
f() is called around (±some error) 14 seconds (since time.monotonic() epoch)
f() is run and it takes 0.1 (< 1) seconds
time.monotonic() returns around 14.1 seconds and time.sleep(0.9) is called
Step 2. is repeated around 15 seconds (since time.monotonic() epoch)
f() is run and it takes 0.3 (< 1) seconds (note: the value is different from Step 2.)
time.monotonic() returns around 15.3 and time.sleep(0.7) is called
f() is called around 16 seconds and the loop is repeated.
At each step f() is called on a one second boundary (according to time.monotonic() timer). The errors do not accumulate. There is no drift.
See also: How to run a function periodically in python (using tkinter).
How about this: After each run, sleep for (1.0 - launch interval) seconds. You can change the terminate condition by changing while True:. Although if the your function takes more than 1 second to run, this will go wrong.
from time import time, sleep
while True:
startTime = time()
yourFunction()
endTime = time()-startTime
sleep(1.0-endTime)
Threading may be a good choice. The basic concept is as follows.
import threading
def looper():
# i as interval in seconds
threading.Timer(i, looper).start()
# put your action here
foo()
#to start
looper()
I would like to recommend the following code. You can replace the True with any condition if you want.
while True:
time.sleep(1) #sleep for 1 second
func() #function you want to trigger
Tell me if it works.

Categories

Resources