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.
Related
I want that a specific time of the day (for example 10:00:00), one of my if condition activates.
For example:
if time is 10:00:00:
print("Hello world")
Imortant: I already read this: Python script to do something at the same time every day
But I don't want to use a function!
If you do not one to use a function but need to run a simple script at certain times, you may use crons/job schedulers for this.
Windows and Linux both supports cron operations.
If you want to do this programmatically instead of relying on operating system tools you need to write a service or a long running process for it.
You could easy use datetime to help you with that.
import datetime
from time import sleep
timing = [10, 0, 0] # Hour, minute, second, in 24 hour time
while True: # Repeat forever
now = datetime.datetime.now()
data = [now.hour, now.minute, now.second]
if data == timing:
# Code to be executed
print("Hello World")
#######
sleep(1) # To ensure the command is not repeated again
# break # Uncomment this if you want to execute the command only once
Make sure that I indented it properly, because one space can tick python off :).
The way that it works:
import datetime and from time import sleep import the necessary modules and functions that you will need.
Modules needed:
datetime
time.sleep
Now we're set.
timing = [10,0,0] sets the time that you want to use (you'll see why later)
while True repeats the loop... on and on and on.
now = datetime.datetime.now() creates a shortcut for such a long piece of text.
data == timing makes sure the time matches the timing you asked.
Note that the timing is in UTC
Go to Getting the correct timezone offset in Python using local timezone to know how to find your offset.
An offset of UTC-0200 (Or -7200 seconds) means that you need to ADD 2 hours to your time to get UTC. Or, if your time zone is UTC+0200, SUBSTRACT 2 hours from your time.
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.
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
I want to generate square clock waveform to external device.
I use python 2.7 with Windows 7 32bit on an old PC with a LPT1 port.
The code is simple:
import parallel
import time
p = parallel.Parallel() # open LPT1
x=0
while (x==0):
p.setData(0xFF)
time.sleep(0.0005)
p.setData(0x00)
I do see the square wave (using scope) but with not expected time period.
I will be gratefull for any help
It gives an expected performance for a while... Continue to reduce times
import parallel
import time
x=0
while (x<2000):
p = parallel.Parallel()
time.sleep(0.01) # open LPT1
p.setData(0xFF)
p = parallel.Parallel() # open LPT1
time.sleep(0.01)
p.setData(0x00)
x=x+1
To generate signals like that is hard. To mention one reason why it is hard might be that the process gets interrupted returns when the sleep time is exceeded.
Found this post about sleep precision with an accepted answer that is great:
How accurate is python's time.sleep()?
another source of information: http://www.pythoncentral.io/pythons-time-sleep-pause-wait-sleep-stop-your-code/
What the information tells you is that Windows will be able to do a sleep for a minimum ~10ms, in Linux the time is approximately 1ms, but may vary.
Update
I made function that make possible to sleep less then 10ms. But the precision is very sketchy.
In the attached code I included a test that presents how the precision behaves. If you want higher precision, I strongly recommend you read the links I attached in my original answer.
from time import time, sleep
import timeit
def timer_sleep(duration):
""" timer_sleep() sleeps for a given duration in seconds
"""
stop_time = time() + duration
while (time() - stop_time) < 0:
# throw in something that will take a little time to process.
# According to measurements from the comments, it will take aprox
# 2useconds to handle this one.
sleep(0)
if __name__ == "__main__":
for u_time in range(1, 100):
u_constant = 1000000.0
duration = u_time / u_constant
result = timeit.timeit(stmt='timer_sleep({time})'.format(time=duration),
setup="from __main__ import timer_sleep",
number=1)
print('===== RUN # {nr} ====='.format(nr=u_time))
print('Returns after \t{time:.10f} seconds'.format(time=result))
print('It should take\t{time:.10f} seconds'.format(time=duration))
Happy hacking
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