I want to basically update a variable value every 5 minutes by calling a function in python while doing other tasks if time is not 5 minutes. I tried to use strftime to keep time but got lost. Not sure what mistake I am making. Any help is much appreciated.
variable = 0
start_time = strftime("%M")
While True:
{do something here}
current_time = strftime("%M")
diff = int(start_time) - int(current_time)
if diff is 5 minutes:
function_call() #updates the variable
else:
Use the old variable value
If you want to an asynchronous function call take a look at: Timer Objects and use them as such (from the docs):
from threading import Timer
t = Timer(300.0, function_call)
t.start() # after 300 seconds, function_call will be called
Otherwise the simpler solution (without threads) is just to check the difference from time calls as such (as you were trying to do):
from time import time
start_time = time()
# do stuff
if time() - start_time > 300: # 300 secs
function_call()
So using the 2nd option your code could look like this:
from time import time
variable = 0
start_time = time()
While True:
{do something here}
current_time = time()
diff = current_time - start_time
if diff > 5*60:
function_call() #updates the variable
start_time = current_time
else:
Use the old variable value
Related
I am trying to print the current time at a specific time, how come it is not printing what I want it to do?
it is just exiting at code 0 when it get to the specific time(12:09)
from datetime import datetime as dt
now = dt.now()
current_time = now.strftime("%H:%M")
for i in range(500000000):
if current_time == "12:09":
print("The time is" + current_time)
You're only getting the time once. After you do current_time = now.strftime("%H:%M"), the current_time variable isn't going to change. If you want that, you need to move that code inside the loop so that they get run repeatedly:
for i in range(500000000):
now = dt.now() # move these lines
current_time = now.strftime("%H:%M") # inside the loop
if current_time == "12:09":
print("The time is" + current_time)
Note that this code is going to thrash your CPU pretty hard, since the loop doesn't take any significant amount of time, and will likely see the same time string thousands or more times in a row. You may want to call time.sleep or a similar function to delay 30+ seconds between checks of the time (since you only care about the minutes).
I need code that will do this:
def foo():
now = datetime.datetime.utcnow()
# Some code will run that takes a variable amount of time
# (less than 15 minutes)
# This code should run no sooner than 15 minutes after `now`
Note that this is not the same as using time.sleep! time.sleep would halt the entire process, but I need computation in foo() to happen and for foo() to return no sooner than 15 minutes after it begins.
You need to calculate the time between the current time and the desired restart time. Then sleep for that amount of time.
wait_time = 15 # minutes
restart_time = datetime.datetime.now() + datetime.timedelta(minutes=wait_time)
# execute code that takes a long time
# for example, let's just sleep for some time
random_time = random.randint(1, wait_time)
time.sleep(random_time * 60)
print("See you again at ", restart_time)
# Now, calculate how long you need to sleep to resume at restart_time
sleep_time = restart_time - datetime.datetime.now()
# Sleep for that amount of time
time.sleep(sleep_time.total_seconds())
print("Hi, I'm back ", datetime.datetime.now())
datetime is not needed, because we do not need to think in human clock terms (hours, minutes, seconds).
All we need is a number of seconds since any fixed moment in the past and time.monotonic does exactly that.
import time
DELAY = 900 # in seconds
start = time.monotonic()
# computation here
end = time.monotonic()
duration = end - start
time.sleep(DELAY - duration)
Last three lines can be written as time.sleep(start + DELAY - time.monotonic()), I split it for simplicity.
import time
import random
import datetime
wait = random.randint(1, 14)
now = datetime.datetime.utcnow()
print(now)
time.sleep(wait * 60)
now = datetime.datetime.utcnow()
print(now)
I think this solves it.
i need your help.
I need a non-bloking timer, that allows me, in the period it's still counting, doing other tasks.
I need this function for my bot and obviously I don't want to block it all times I call this type of function which requires these timers.
So, in the past i used to use in Arduino (c++) the function millis() that in the same configuration seems not working well like
int t0 =0
int t1
void loop(){
t1= millis()
while (t1-t0 < 6000){
Serial.print(Timer!);
t0 = millis();}}
Do you have any advice for me? A code where I can start from?
Thanks!
The following will print "Timer" for 6 seconds:
import time
start_time = time.time() # returns number of seconds passed since epoch
current_time = time.time()
max_loop_time = 6 # 6 seconds
while (current_time - start_time) <= max_loop_time:
# do stuff
print("Timer")
current_time = time.time()
Okay, i found the solution by myself, trying to remember what i previously did on Arduino.
I based this answer from Adam Minas's one, but mine is quite different
So the expected behavior had to be:
print(something) every 5 seconds so:
import time
start_time = time.time() # returns number of seconds passed since epoch
#current_time = time.time()
print(start_time)
max_loop_time = 20 # 6 seconds
while True:
while (time.time() - start_time) > max_loop_time:
print("Timer")
start_time = time.time()
Then you can stop your while loop with break and other functions like
if == smth :
break
I'm creating a loop which executes every 5 seconds, starting at the startTime variable and ending at the stopTime variable. However, the code below is disregarding the minutes within my startTime and endTime variables and only executing on the hour. For example, even though my startTime is '1130', the code is executing 11:05, rather than ending the loop. I have the same problem with the endTime variable. If the current time is 12:45, the code still executes even though the endTime variable is '1230'. The code will stop executing at '1300'.
frequency = 5
startTime = '1130'
endTime = '1230'
while True:
now = datetime.now().strftime('%H:%M:%S')
if startTime <= now <= endTime:
print('Loop is working. Time is: ',now)
time.sleep(frequency)
else:
print('Loop is stopped')
break
I live in Central Time, so I tried switching to Eastern timezone by modifying the "now" variable to:
now = datetime.now(timezone('US/Eastern')).strftime('%H:%M:%S.%f %Z')
but I still get the same problem when I substitute eastern times with startTime and endTime when using the eastern datetime.now().
Is executing code at a precise minute possible with strftime()?
EDIT: (this is now the answer to the real question (oops))
If you want to wait till for example 11:30 (which was the real question)
you can calculate the time (in seconds) the program should sleep (and let it sleep for that time):
def wait_till(hour, minute, second=0):
# get system time (and date)
now_time = datetime.datetime.now()
# create time point we are waiting for (this year, this month and this day)
wait_till_time = datetime.datetime(year=now_time.year, month=now_time.month, day=now_time.day, hour=hour, minute=minute, second=second)
# calculate time we want to wait for and convert to seconds
wait_for = (wait_till_time - now_time).total_seconds()
# check if it's going to be tomorrow (if we would sleep for a negative amount of seconds)
if wait_for < 0:
# add one day
wait_till_time = wait_till_time.replace(day=now_time.day+1)
# recalculate (not very beautiful, but i don't know a better way)
wait_for = (wait_till_time - now_time).total_seconds()
# printing this waiting time (in seconds)
print("waiting for",wait_for,"seconds")
# sleeping for that time
time.sleep(wait_for)
# printing the new now time, so we can see how accurate it is
print("its now",datetime.datetime.now())
and say for example:
wait_till(20, 24) # waiting till 20:24 (today)
and get:
waiting for 15.32297 seconds
its now 2019-03-11 20:24:00.003857
which is pretty darn close to what we wanted (20:24:00.000000) and this delay is probably only caused by the calculation lag of formatting the string.
(The old stuff ...)
if it's not important that it takes 100% 5s (but rather 100.04546642303467% --> it will get off a little bit every time) you can just do
import time
frequency = 5 #every 5 seconds
start_time = time.time()
while 1:
elspsed_time = time.time() - start_time
print(elspsed_time)
time.sleep(frequency)
but if you need the 100% you can try this autocorrecting solution:
import time
from threading import Timer
frequency = 5 #every 5 seconds
start_time = time.time()
def what_to_do_after_5s():
elapsed_time = time.time() - start_time
print(elapsed_time)
# next call
Timer(5.0 - (elapsed_time - int(elapsed_time)), what_to_do_after_5s, ()).start()
what_to_do_after_5s()
and we can see that it autocorrects:
0.0
5.000170707702637
10.000272989273071
15.000539064407349
20.001248836517334
25.00046443939209
30.000929355621338
35.00142860412598
40.0007688999176
45.00128436088562
50.00045442581177
55.000683069229126
60.00123882293701
65.00095415115356
70.0015127658844
I'm trying to execute a while loop only under a defined time like this, but the while loop continues its execution even when we are above the defined limit :
import datetime
import time
now = datetime.datetime.now()
minute = now.minute
while minute < 46 :
print "test"
time.sleep(5)
minute = now.minute
How can stop the loop once we cross the limit ?
Thanks
You're not updating the value of minute inside while loop properly. You should recalculate the value of now in loop and then assign the new now.minute to minute.
while minute < 46 :
print "test"
time.sleep(5)
now = datetime.datetime.now()
minute = now.minute
You need to determine the time anew in your loop. The minute variable is static, it does not update to reflect changing time.
If you want to loop for a certain amount of time, start with time.time() instead and then calculate elapsed time:
import time
start = time.time()
while time.time() - start < 300:
print 'test'
time.sleep(5)
will print 'test' every 5 seconds for 5 minutes (300 seconds).
You can do the same with datetime objects of course, but the time.time() call is a little simpler to work with.
To loop until a certain time datetime can be used like:
import datetime
while datetime.datetime.now().minute < 46:
print 'test'
time.sleep(5)
Again, note that the loop needs to call a method each time to determine what the current time is.
The loop's proposition should be datetime.datetime.now().minute - minute < 46 and the body of the loop shouldn't be updating minute.
You are storing the current time in now variable. Instead you should get the current time inside the loop everytime:
import datetime
import time
minute = datetime.datetime.now().minute
while minute < 46 :
print "test"
time.sleep(5)
minute = datetime.datetime.now().minute