How to time the execution of code in a loop? - python

I want to make a programme who print "hey" every 5 seconds
mine is printing every 5 seconds but more than one time.
import datetime
now = datetime.datetime.today()
objectif = datetime.timedelta(seconds = 50)
later = objectif+now
inc = 0
while later > datetime.datetime.today():
if datetime.datetime.today().second%5==0 and later.microsecond == datetime.datetime.today().microsecond:
print "hey"
How can I print "hey" only one time per 5 seconds?

You can use time.sleep()
The following will print 'hey' ever 5 seconds to a limit of 50 seconds
import datetime
from time import sleep
end_time = datetime.datetime.now() + datetime.timedelta(seconds = 50)
while end_time > datetime.datetime.now():
print("hey")
sleep(5)

Related

How to make program sleep until next day

I need my code to stop and wait until the next day. The time does not matter, I just need it to continue when the date changes.
currentDate = datetime.datetime.now()
future = datetime.datetime(currentDate.year, currentDate.month,
(currentDate.day + 1))
time.sleep((future-currentDate).total_seconds())
The code pauses but does not continue after
Two options here with comments.
First do imports
import datetime
import time
one uses a while loop - probably not a good solution but highlights one way to wait for a condition to be met.
def loop_until_tomorrow():
""" Will use a while loop to iterate until tomorrow """
#get current date
currentDate = datetime.datetime.now().date()
# loop attempts
times = 0
# this will loop infiniatly if condition is never met
while True:
# increment by one each iteration
times += 1
#get date now
now = datetime.datetime.now().date()
if currentDate != now:
# return when condition met
print("\nDay has changed")
return
else:
# print attempts and sleep here to avoid program hanging
print(f"Attempt: {times}".ljust(13) + " - Not tomorrow yet!", end="\r")
time.sleep(5)
the other - sleeps for the amount of seconds from now till tomorrow
def sleep_until_tomorrow():
"""wait till tomorrow using time.sleep"""
#get date now
now = datetime.datetime.now()
#get tomorrows date
tomorrow_date = now.date() + datetime.timedelta(days=1)
#set to datetime
tomorrow_datetime = datetime.datetime(year=tomorrow_date.year, month=tomorrow_date.month, day=tomorrow_date.day, hour=0, minute=0, second=0)
#get seconds
seconds_til_tomorrow = (tomorrow_datetime-now).total_seconds()
#sleep
time.sleep(seconds_til_tomorrow)
You can use schedule for that purpose, which will give you the flexibility to refactore the code when needed without having to write a chunck of code.
from schedule import every, repeat, run_pending
import time
#just to give you the idea on how to implement the module.
#repeat(every().day.at("7:15"))
def remind_me_its_a_new_day():
print("Hey there it's a new day! ")
while True:
run_pending()
time.sleep(1)

milliseconds countdown timer in python

there was a lot of models available here of a countdown timer but almost all of them does not have a millisecond value
the model im using :
import time
def countdown(t):
while t:
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
print(timer, end="\r")
time.sleep(1)
t -= 1
print('Fire in the hole!!')
# input time in seconds
t = input("Enter the time in seconds: ")
# function call
countdown(int(t))
i understand the divmod() method but i still find it difficult to understand how to extract milliseconds from this
Your code does not keep track of any milliseconds. You sleep(1) - which should sleep at least 1000ms (maybe more - see here - it depends on what is going on on your PC elsewise).
To display any ms you need to capture the current time somehow:
from datetime import datetime, timedelta
import time
def countdown(seconds):
started = datetime.now()
ended = started + timedelta(seconds=seconds)
while datetime.now() < ended:
print(f"Waiting for {ended-datetime.now()}", flush=True)
time.sleep(1)
now = datetime.now()
if now > ended:
print(f'Sorry, I overslept: {now-ended}')
print('Fire in the hole!!')
# input time in seconds
t ="4"
# function call
countdown(int(t))
To get:
Waiting for 0:00:04
Waiting for 0:00:02.995686
Waiting for 0:00:01.995361
Waiting for 0:00:00.980077
Sorry, I overslept: 0:00:00.020248
Fire in the hole!!
You can format the timedelta to your conveniece - more solutions to that f.e. here: Formatting timedelta objects.
Sleeping for a calculated time like
while datetime.now() < ended:
remainder = ended-datetime.now()
print(f"Waiting for {remainder}", flush=True)
time.sleep(min(1, ( ended-datetime.now()).total_seconds()))
could try to minimize your over-sleep time on the last loop. You could also try to do this for every loop by calculating what you need to sleep if need better 1s precision.
But in the end your loops may still be off due to factors you can not influence.
fulldate = datetime.datetime.strptime(date + ' ' + time, "%Y-%m-%d %H:%M:%S.%f")
fulldate = fulldate + datetime.timedelta(milliseconds=500)
This should solve your problem,
https://docs.python.org/2/library/datetime.html#timedelta-objects

Run a function at the start of every round 5 minute interval

I want to run a function every 5 minutes, it must be at a "round" intervals, for example :
12:05:00, 12:10:00, 12:15:00...
It cannot be like this:
12:06:00, 12:11:00, 12:16:00...
Or like this:
12:05:14, 12:10:14, 12:15:14...
What is the most accurate way to do this in python?
You could use a threading.Timer. You have to do some math to calculate the next run time. datetime has a handy replace method for that.
from datetime import datetime, timedelta
from threading import Timer
from time import sleep
import random
def schedule_next_run():
sleep_time = get_sleep_time()
t = Timer(sleep_time, do_work)
t.daemon = True
t.start()
print(f'sleeping for {sleep_time} seconds')
def get_sleep_time():
now = datetime.now()
last_run_time = now.replace(minute=now.minute // 5 * 5, second=0, microsecond=0)
next_run_time = last_run_time + timedelta(minutes=5)
return (next_run_time - now).total_seconds()
def do_work():
now = datetime.now()
print('Doing some work at', now)
sleep(random.uniform(0, 29))
print('Work complete. Scheduling next run.')
schedule_next_run()
print('Starting work schedule')
schedule_next_run()
input('Doing work every 5 minutes. Press enter to exit:\n')
On my system, the function fires within a half millisecond of the target time
Note that the time calculation rounds down and then adds a timedelta to carefully wrap around the end of each hour. You would want to ponder how this will behave around daylight savings changes.
Suggestion: move all this logic to a class to clean it up.
You can use datetime and condition.
import datetime
while True:
current_time = datetime.datetime.now()
if current_time.second % 5 == 0 and current_time.minute % 1 == 0 and current_time.microsecond == 0:
print(current_time)
hope this helps.
import datetime, time
def some_function():
ran_once = True
while True:
current_time = datetime.datetime.now()
if current_time.minute % 5 == 0 and current_time.second % 60 == 0 and not ran_once:
print(current_time) # DO YOUR WORK HERE
ran_once = True
elif current_time.minute % 5 == 0 or current_time.second % 60 != 0:
if current_time.second % 60 == 0:
print("Time to wait:", 5 - (current_time.minute % 5), "minutes and 0 seconds")
else:
print("Time to wait:", 4 - (current_time.minute % 5), "minutes and ", end="")
print(60 - (current_time.second % 60), "seconds")
time.sleep( (4 -(current_time.minute % 5))*60 + 60 -(current_time.second % 60))
ran_once = False
The above code runs at intervals of 5 minutes. Initially, the main thread sleeps for the number of seconds required to reach the perfect timestamp. For example, if the program is started at 7:28:30 then it is going to sleep for 90 seconds and then start at 7:30:00. From then on it will wait for 5 minutes before it runs the required functionality again.
Also, I think the performance of firing up at the exact second really varies on how your system handles the threads.

How we can stop a program at certain time in a day#15:30pm everyday…?(It's running every 1 minute)

Anyone help me to get code for below conditions...
I would like to run job1 and job2 for every 2 and 3 seconds,
job1 and job2 should start#9:30am in a day..and should stop#17:30pm...!
job3 #17:31pm daily once only..
import schedule
import time
def job1():
print("I'm working...")
def job2():
print("I'm not working...")
def job3():
print("I'll not work...")
schedule.every(2).seconds.do(job1) #For Every 2 seconds
schedule.every(5).seconds.do(job2) #For Every 3 Seconds
schedule.every().day.at("17:28").do(job3) #Once in a day
while True:
schedule.run_pending()
time.sleep(1)
You can wrap this into a function and start it in a given time with a scheduler
schedule.every(2).seconds.do(job1) #For Every 2 seconds
schedule.every(5).seconds.do(job2) #For Every 3 Seconds
And you could do the same with canceling the job when you want. So you will have 2 extra job which starts and stops the other jobs.
Probably not the nicest way of doing this, but something like this should work. (You obviously can extend the if statement to incorporate only weekdays/exclude holidays etc.)
import datetime
import time
def job_a():
print('a')
def job_b():
print('b')
def job_3():
print('3')
start_a = datetime.datetime.now()
wait_time_a = 2
start_b = datetime.datetime.now()
wait_time_b = 5
start_time = 9.30
end_time = 17.31
do_job_3 = False
while True:
while datetime.datetime.now().hour + datetime.datetime.now().minute/100. > start_time \
and datetime.datetime.now().hour + datetime.datetime.now().minute/100. < end_time:
do_job_3 = True
if (datetime.datetime.now() - start_a).seconds > wait_time_a:
job_a()
start_a += datetime.timedelta(seconds=wait_time_a)
if (datetime.datetime.now() - start_b).seconds > wait_time_b:
job_b()
start_b += datetime.timedelta(seconds=wait_time_b)
time.sleep(1)
if do_job_3:
do_job_3 = False
job_3()
time.sleep(1)

python timer in minutes

I am trying to run the below code. It fails to run for 5 minutes, can you please let me know what the issue is here. I am trying to run this in background by saving as .pyw and alert me after finishing 1 hours, as per what is passed in timer arguments.
import time
import ctypes
def timer(minutes):
seconds = minutes * 60
start = time.time()
time.clock()
elapsed = 0
while elapsed < seconds:
elapsed = time.time() - start
time.sleep(1)
timer(5) #would want enter in hours not in seconds
ctypes.windll.user32.MessageBoxA(0,"DoneToday", "Dones", 0)
Your timer() function is infinitely looping.
After your while elapsed < seconds: loop, two lines down, you've put timer(5). So that just calls itself again, and again, again...
Once you remove this line, it will work as expected:
timer(5) #would want enter in hours not in seconds
And as #vermillon mentioned, any reason you're not just doing time.sleep(minutes * 60)? I'm assuming you plan to do something else in that loop, other than just counting time.
Edit: For the OP to see running code
>>> def timer(minutes):
... seconds = minutes * 60
... start = time.time()
... time.clock()
... elapsed = 0
... while elapsed < seconds:
... elapsed = time.time() - start
... time.sleep(1)
... ctypes.windll.user32.MessageBoxA(0,"DoneToday", "Dones", 0)
... print 'also printing Done so you can see it'
...
>>> timer(0.1)
also printing Done so you can see it
>>>
If you want a timer that shows minutes and seconds remaining, then here's the snippet for you:
import time
import sys
def run_timer(seconds):
for remaining in range(seconds, 0, -1):
sys.stdout.write("\r")
minutes = 0
seconds = remaining
if remaining > 60:
minutes = int(seconds/60)
seconds = int(seconds%60)
else:
seconds = remaining
sys.stdout.write("{:2d} minutes {:2d} seconds remaining.".format(minutes,seconds))
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write("Timer complete")
run_timer(120)

Categories

Resources