python How to loop a function [duplicate] - python

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

Related

How can I let a while loop pause for a specified time (datetime)?

I would like to let a while loop run, the stuff thats happening inside takes about 2 seconds to complete (it varies a small amount), so if I use time.sleep(60 or 58) it would still shift slightly. So what I would like to do is that the while loop starts for example at 16:00:00 (because I click run) and does its stuff, waits and then starts again at 16:01:00, so a minute later and so on. How can I do that?
Measure the time taken by the operation. Then subtract that from your loop period to get the amount of time to sleep.
import time
while True:
start = time.time()
# do your thing
time.sleep(60 - (time.time() - start))
Where are you putting time.sleep() in your code? Have you tried putting it at the end of the while loop when all of the processing is complete?
Calling the stop function will stop your while loop for the amount you pass. This works I tested it
def stop(t):
running = False
time.sleep(t)
running = True
while running:
# Do something

Creating a timer that runs in the background

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.

Python Scheduler vs loop + sleep

the following is:
python sched:
from time import time, sleep
from sched import scheduler
def daemon(local_handler):
print 'hi'
local_handler.enter(3, 1, daemon, (local_handler,))
if __name__ == '__main__':
handler = scheduler(time, sleep)
handler.enter(0, 1, daemon, (handler,))
handler.run()
python loop + sleep:
from time import sleep
while True:
print 'hello'
sleep(3)
What is the difference between sched and loop+sleep, and sched will stop when the system time is changed?
A big difference is that the delay between multiple tasks is calculated as necessary. That means your loop will take:
time it needs to print("hello") or do the task that you need to do
time it takes to sleep(3)
while if you change the order in your scheduler to:
local_handler.enter(3, 1, daemon, (local_handler,))
do_the_task
your next task will be run either after 3 seconds, or immediately after do_the_task if it took longer than 3 seconds.
So the decision really comes down to: do you want your task executed every X time units, or with X time units space between executions.
Assuming you're using the typical (time, sleep) parameters, if the system time is changed, you'll get the next task run after the expected amount of time (sleep takes care of this, unless some signals were received in the meantime), but your next scheduled task time will be shifted. I believe that the next execution time will not be what you'd normally expect.
The difference between the two is that scheduler is more pythonic than loop + sleep for two reasons: elegance and modularity.
Long loops easily become difficult to read and require a lot more code to be written within. However, with a scheduler, a specific function can be called on a delay, containing all of the code within. This makes code much more readable and allows for moving code into classes and modules to be called within the main loop.
Python knows what the current time is by checking the local system. If the local system's time is changed, then that will affect a currently running program or script.
Becaused the python sched is use system time for next iteration.
The sleep is use cpu time clock for next iteration.

How do i make a keypress display how long my program has been running?

import time
number = 1
while number > 0:
print "Testing"
time.sleep(5) #print every 5 seconds
That is just an example loop. I'm a semi-beginner and I'm not sure how to make a keypress(any key is fine) display how long the program has been running. This program will be running on Windows 7 and Linux.
Thank you very much.
Welcome to Stack Overflow and to Python! You'll like it here.
First, I'll show you how to print out the time your code has been running. The time module includes a time() function that gets the current time as a Unix timestamp (the number of seconds since January 1, 1970). If you assign it to a variable at the start of the function, you can simply call it each time through the loop and subtract it from the current time to get your runtime. With me so far?
(You can also remove your number variable and the number > 0 check and simply replace it with True.)
import time
start_time = time.time()
while True:
print "I've been running for %d seconds!" % (time.time() - start_time)
time.sleep(5) #print every 5 seconds
But you asked how to get it each time the user presses a key. If you just want 'enter', you can do:
import time
start_time = time.time()
while True:
print "I've been running for %d seconds!" % (time.time() - start_time)
raw_input("Press Enter...")
The raw_input() function will wait for the user to press Enter, then print out the runtime.
One problem at a time.
How do you find how long your program has been running at the point at which you want to calculate?
How do you detect a key-press?
How do you get the program to produce 1) when 2) happens?
Try each problem in turn, then ask if you need help.
There are a lot of complexities and approaches for a such a simple question.
If you are looking for up time of a currently running process, use the OS to query that process with the subprocess module to run a command line operation such as 'ps | grep "foo" '
Usually programs do only one thing at a time. For example, the code could either do work OR look for a keypress. If you need to run have to run two different sections of code concurrently, spawn (run) the code segments as separate threads . For your question you could spawn two threads (pieces of code), one to do work and one to query up time.
Use the threading module in python to wrap the worker function and create a query thread. However, when the worker thread is done, you will want the query thread to terminate also. One way to do this is to define it as a daemon thread. Daemon threads terminate when they are the only threads alive.
For example:
from time import sleep
import datetime
import threading
def do_someting():
MAX_RUN_TIME = 300 #Seconds
for i in xrange(MAX_RUN_TIME):
print i,
sleep (1)
class worker_thread(threading.Thread):
def run(self):
do_someting()
class keypress_daemon_thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self) # Initialize the parent class
self.daemon = True # Terminates if only daemon threads are left
def run(self):
startTime = datetime.datetime.now()
while True:
raw_input()
timeDelta = datetime.datetime.now() - startTime
print 'Up for', timeDelta
if __name__ == '__main__':
workerThread = worker_thread()
keyPressThread = keypress_daemon_thread()
workerThread.start()
keyPressThread.start()
workerThread.join()

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