Revised question
Is there a way by using treading and sched to create a for loop where you run a script exactly every second jumping between 3 treads constantly for as long as you need it Like
for thread01 in schead:
run at 00:00:01.0000
else(thread02):
run at 00:00:02.0000
else(thread03):
run at 00:00:03.0000
and have it constantly loop does mitigating the drift and neg sleep value as each time the code runs on a tread it has 1000 milliseconds to execute before the next second
I have tested and the session_create runs between 480 and 530 milliseconds constantly to execute
Old Question old Code to help mitigate time drift
from main import session_create
import sched, datetime, threading
def timestamp():
next_call = time.time()
while True:
session_create()
print (datetime.datetime.now())
nextcall = next_call+1;
time.sleep(nextcall - time.time())
timerThread = threading.Thread(target=timestamp)
timerThread.daemon = True
timerThread.start()
This was the closest I could get to what i wanted as I knew that the code that needed tobe called and run every second, and I knew it takes between 500 to 600 milliseconds to run.
I used threading.Timer to run the code every 900 milliseconds and this causes the code to run at least once every second and bypassing the time drift i was experiencing.
from Sessions import session
import sched, time, threading
Event_scheduler = sched.scheduler(time.time, time.sleep)
##
start_time = time.time()
def run():
threading.Timer(0.9, run).start()
session()
run()
The down side of this is simple math every Nth second ill have a point where the code ran twice (example 23:59:01:0050 and again at 23:59:01:0950). But the extra data is easily removed by finding the duplicates 23:59:01 == 23:59:01 and removing one of the two
Related
So what I am trying to do is have a bit of code check the time and at a a given time do something, the current part I am working on is small but I want it to run as efficiently as possible because the program will be running for long amounts of time when its finished. I've noticed on on task manager when I run a file with only the bit of code I will show soon my cpu usage is over 15% with an i7 7700 cpu, is there any way to make this code more efficient?
import datetime
import webbrowser
#loop to run until desired time
while True:
#checks current time to see if it is the desired time
if str(datetime.datetime.now().time()) == "11:00:00":
#opens a link when its the desired time
webbrowser.open('https://www.youtube.com/watch?v=q05NxtGgNp4')
break
If your program can remain idle until calling the browser, you can use sleep, for the time difference between now and 11:00:00:
import datetime
import webbrowser
# loop to run until desired time
def find_time_between_now__and_11():
"""returns the time in ms between now and 11"""
return datetime.datetime.now().time() - 11 # pseudocode, you need to figure out how to do that
lag = find_time_between_now__and_11()
time.sleep(lag)
# opens a link when its the desired time
webbrowser.open('https://www.youtube.com/watch?v=q05NxtGgNp4')
15% imho means you have one core filled 100%, because you're continuously looping. You can sleep() for 1+ seconds so the CPU is not busy looping and you need to add a fuzzy comparison for:
str(datetime.datetime.now().time()) == "11:00:00"
I'd go for something like:
def run_task(alarm):
last_run = None
while True:
now = datetime.datetime.now()
if now > alarm && last_run != now:
last_run = now
# Do whatever you need
webbrowser.open('https://www.youtube.com/watch?v=q05NxtGgNp4')
time.sleep(10) # Sleep 10 seconds
It's a bit convoluted bout you can extend to support multiple alarm times and change the if logic to suit your needs.
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.
Is it possible make this .py script time out every 20 minutes and auto run again by it self?
Currently I'm using crontab to rerun it every 20 minutes but the thing is it's running multiple .py sometime and not actually rerunning the program. I just want it to rerun every 20 minutes not rerun another instance of it every 20 minutes.
#!/usr/bin/env python
from TwitterFollowBot import TwitterBot
my_bot = TwitterBot("/home/TwitterFollowBot/config.txt")
my_bot.sync_follows()
my_bot.auto_unfollow_nonfollowers()
my_bot.auto_rt("#RtwtKing", count=2000)
my_bot.auto_rt("#ShoutGamers", count=2000)
You have several ways to do this.
If you want to do it only with Python you can:
Use threads, it will work pretty well, but it's not really what threads are designed for.
Use Daemon (good example here)
Do a Python wrapper which will loop forever and call you script when needed. It's less clean, but less overkill too.
Example of the wrapper solution:
The goal is to create a new python script which will handle timer and so execute your Twitter code when needed.
1. Update your current code to encapsulate it in a method
let's say your current file is named core.py
core.py:
from datetime import datetime
from TwitterFollowBot import TwitterBot
def get_feed():
print "({}) LOG: get_feed starting".format(datetime.now())
my_bot = TwitterBot("/home/TwitterFollowBot/config.txt")
my_bot.sync_follows()
my_bot.auto_unfollow_nonfollowers()
my_bot.auto_rt("#RtwtKing", count=2000)
my_bot.auto_rt("#ShoutGamers", count=2000)
This just make your code in a function and add a logging line which print current time when function is executed.
2. Make a wrapper which handle timer and call your twitter code
wrapper.py:
import time
from datetime import datetime
# Import your twitter code, so you can use it by calling 'get_feed()'
from core import get_feed
# Define constants here because it's easier to find it on top of file
# Delta between the last call and the next one, bascially time between two calls: 20 minutes
DELTA = 20 * 60
# Time your wrapper will take between each verification: 5 minutes
SLEEP_TIME = 5 * 60
# Initialize timer and call for the first time your method
# last_run will store timestamp of the last time you called get_feed()
last_run = time.time()
get_feed()
# Start an inifinite loop
while True:
# Compute delta since last call
# last_run_delta will store the time in seconds between last call and now
last_run_delta = time.time() - last_run
# If last_run_delta is upper than DELTA so the number of seconds you want to separate two calls is reached.
if last_run_delta >= DELTA:
# Because time is reached you want to run again your code and reset timer to can handle next call
last_run = time.time()
get_feed()
# If you have not reach delta time yet, you want to sleep to avoid stack overflow and because you don't need to check each microseconds
else:
time.sleep(SLEEP_TIME)
Ouput with DELTA = 10 and SLEEP_TIME = 5 (core.py is called every 10 seconds and check is done each 5 seconds):
(2016-11-29 10:43:07.405750) LOG: get_feed starting
(2016-11-29 10:43:17.414629) LOG: get_feed starting
(2016-11-29 10:43:27.422033) LOG: get_feed starting
(2016-11-29 10:43:37.430698) LOG: get_feed starting
(2016-11-29 10:43:47.436595) LOG: get_feed starting
The only real good point with this method is you can't launch same process two times at once. Because it's not asynchronous, get_feed can't be called twice, but if get_feed take more time than SLEEP_TIME or DELTA you will miss some calls and so do not run it each 20min.
Last thing, because you are importing core.py in wrapper.py you have to create a __init__.py file in the same folder than the two others files. (/path/to/project/ should contains __init__.py (empty), core.py and wrapper.py).
The real good way will is to create a daemon, but it require more skills.
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()
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