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)
Related
How can i stop a while loop after a certain time in which the sleep function is used. The condition inside a while loop does not work correctly because the sleep function pauses the execution of the code.
In this case i have delay for 40 seconds before a while loop stops:
# timeout for 10 minutes
timeout = time.time() + 60*10
while True:
if time.time() >= timeout:
break
# do something
sleep(20)
# do something
sleep(20)
you may use the code below.
import datetime
import time
timeout = datetime.datetime.now() + datetime.timedelta(seconds=20) # define here!
while True:
now = datetime.datetime.now()
if now >= timeout:
print('time is up !')
break
else:
print('do something')
time.sleep(5) # define here!
continue
Looks like you need a variable sleep duration.
Something like this:
from time import time, sleep
timeout = time() + 10 * 60
while time() < timeout:
# do some work
sleep_duration = min(20, timeout - time())
sleep(sleep_duration)
This means that the sleep will be at most 20s
Probably, the fastest solution will be to set the certain amount of sleep.
timeout = time.time() + 60*10
while time.time() < timeout:
# do something
# added clipping negative numbers too
time_left = max(0,min(20, timeout - time.time()))
sleep(time_left)
if time_left == 0:
break
time_left = max(0,min(20, timeout - time.time()))
# do something
sleep(time_left)
Not the most elegant solution. But should work
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
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)
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.
I have five loops in my code and I want to stop each loop by the time I set. My code is:
nw=1000
for i in range(nw):
w_list.append(-3+0.006*i)
chi_1=0
chi_2=0
k=1
while k<10:
now_1=time.time()
l=1
while l<10:
now_2=time.time()
n_1=0
while n_1<10:
now_3=time.time()
n_2=0
while n_2<5:
now_4=time.time()
chi_2+=(e1_vecs[n_1,0]*e1_vecs[n_1,k]*e_vecs[2*n_2,0]*e_vecs[2*n_2,l])**2*(1.0/(w_list[i]+(E0-e_vals[l]-k*w_b+b*w_b)-0.001j))+(e1_vecs[n_1,0]*e1_vecs[n_1,k]*e_vecs[2*n_2+1,0]*e_vecs[2*n_2+1,l])**2*(1.0/(w_list[i]-(E0-e_vals[l]-k*w_b+b*w_b)+0.001j))
n_2+=1
stop_4=time.time()-now_4
time.sleep(1.0-stop_4)
n_1+=1
stop_3=time.time()-now_3
time.sleep(1.0-stop_3)
l+=1
stop_2=time.time()-now_2
time.sleep(1.0-stop_2)
k+=1
stop_1=time.time()-now_1
time.sleep(1.0-stop_2)
chi_on.append(chi_2.imag)
But my method does not work... Do you have any good suggestion? I am a beginner on Programming...
time.sleep is the wrong method to use, sleep takes in a number of seconds and then forces your program to wait for that amount of time. Instead, you just want your while loops to not run if you have taken too long.
Try something like:
MAX_TIMEOUT = 100 # Max seconds before we abort
stop_time = time.time() + MAX_TIMEOUT
nw=1000
abort = False
for i in range(nw):
w_list.append(-3+0.006*i)
chi_1=0
chi_2=0
k=1
while k<10 and not abort:
l=1
while l<10 and not abort:
n_1=0
while n_1<10 and not abort:
n_2=0
while n_2<5 and not abort:
chi_2+=(e1_vecs[n_1,0]*e1_vecs[n_1,k]*e_vecs[2*n_2,0]*e_vecs[2*n_2,l])**2*(1.0/(w_list[i]+(E0-e_vals[l]-k*w_b+b*w_b)-0.001j))+(e1_vecs[n_1,0]*e1_vecs[n_1,k]*e_vecs[2*n_2+1,0]*e_vecs[2*n_2+1,l])**2*(1.0/(w_list[i]-(E0-e_vals[l]-k*w_b+b*w_b)+0.001j))
n_2+=1
# We check here if we need to abort
if time.time() >= stop_time:
abort = True # This will force the while loops to end
print 'Aborted because we took too long!' #Probably a good idea to log this somewhere
n_1+=1
l+=1
k+=1
chi_on.append(chi_2.imag)
if abort:
break #No point staying in the forloop if we need to abort
try using
delay = 100 # some time in seconds
start_time = time.time()
while True:
if start_time + (delay * 5) >= time.time():
break
while True:
if start_time + (delay * 4) >= time.time():
break
while True:
...
...