Stop the loop in time in Python. - python

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:
...
...

Related

Break a while loop with the sleep function inside after a certain period of time

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

Why my thread doesn't stop after function finished?

So I wrote this script, which counts income packets on certain port, and in case if there are to many packets script has to do something. On the first received packet is has to start timer, and if timer reaches 60 sec, packet count should start from 0 again. It works, but only for first timer call, in any case, if script has to start timer again I get the error:
raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once"`
It's clear, that this thread still running, but i don't understand why. I mean, in case if timer reaches 60 secs, timer loop is finished, and function should be finished too, so i can use timer again? Clearly i don't understand something here, can you guys explain it? Thanks for answers
My code:
from scapy.all import *
from threading import Thread
import time
global count
count = 0
def timer():
global count
i = 0
while i < 60:
if count > 0:
time.sleep(1)
i = i + 1
print(str(count))
else:
print("count is 0, timer turning off...")
break
else:
count = 0
print("60 seconds, timer is off")
background_thread = Thread(target=timer)
def pkt_callback(pkt):
global count
packet_limit = 10
if pkt.haslayer(UDP) and pkt.getlayer(UDP).dport == 5160 and pkt.haslayer(Raw):
raw = pkt.getlayer(Raw).load
s = str(raw)
if 'REGISTER' in s:
count += 1
print(count)
if count == 1:
if background_thread.is_alive() is False:
background_thread.start()
print("Register packet detected, timer is on")
if count >= packet_limit:
print("PACKETLIMIT reached, do smth")
count = 0
sniff(iface='ens160', filter="", prn=pkt_callback)
I think you have to use the return function not break, and either way you have only used it once, also you can change your code a bit, try this:
def timer():
global count
i = 0
while i < 60:
if count != 0:
time.sleep(1)
i += 1
print(str(count))
else:
return "count is 0, timer turning off..."
else:
count = 0
return "60 seconds, timer is off"

I am trying to execute an alarm function in tkinter but it is not working properly

I am trying to Execute the function in tkinter as I want function to run in background I have done following code. Also I am trying to execute it inside a while loop but its not looping through.
t1 = dt.time(hour = 13, minute= 24)
t2 = dt.time(hour= 13, minute= 4)
timetable = [t1, t2]
root = Tk()
def Alarm():
current_time = now_time.strftime("%H:%M:%S")
print(current_time)
print(timetable[0])
while True:
if timetable[0] <= dt.datetime.now().time():
print("Its time")
break
Alarm()
root.mainloop()
print statements are only for testing. The logic I am using in alarm clock is also not executing properly as it tells ""Its time" even after time has passed. I have tried following methods before.
method 1:
for i in reversed(timetable):
i_time = i
#print (i_time)
#print(now_time.strftime("%H:%M"))
while True:
if dt.datetime.now().time() < i_time:
#if i_time <= dt.datetime.now().time():
print("Its Time")
break
method 2:
for i in timetable:
current_time = dt.datetime.now().time()
alarm_time = i
while True:
if current_time < alarm_time:
if current_time <= alarm_time:
print("its time", alarm_time)
Using for loop was my first goal but for loop isn't executing properly. It only gets 1st element and doesn't go to 2nd element even if first element has passed so I have decided to go with if,elif,else statement
You can use the after method to run a function after a certain amount of time has elapsed. You should use it rather than creating a loop.
You simply need to convert the alarm time to a number of milliseconds, then use that to ring the alarm at the given time. For example, to ring an alarm in one hour you would do this:
def ring_alarm():
print("Its time")
delay = 60 * 60 * 1000 # 60 min/hour, 60 secs/min, 1000ms/sec
root.after(delay, ring_alarm)
I am going with if..else response for executing alarm as
current_time = dt.datetime.now().time()
if timetable[0] == current_time:
print("Its time")
break
I was breaking While loop in wrong place as well an typo from my end.

Creating a counter which resets itself every 30 seconds

I want to create a function that counts till 30, but when it reaches 30 I want to reset it to starting point.
def countdown():
global countDown
countDown = int(time.time() - start_time)
return countDown % 30
And then I want to print it like that.
print("You have " + str(30 - countdown()) + " time")
It works but when it reaches 0, it keeps counting below 0 like -1,-2 and it is not doing modula operation. So it doesn't reset itself. What can I do in this case ?
Desired case: 30 29.... 3 2 1 0 30 29 28
Recent case: 30 29 ... 2 1 0 -1 -2
The counter is not being reset using the modulo operator (countDown % 30). Try,
import time
def countdown(i):
counter = i
while True:
if (counter == i):
counter = 0
print(counter)
counter = counter + 1
time.sleep(1)
countdown(30)
What I got from your code
import time
start_time = time.time()
def countdown():
global countDown
countDown = int(time.time() - start_time)
return countDown % 30
print("You have " + str(30 - countdown()) + " time")
is working perfectly on https://www.python.org/shell/
Can't reproduce your problem. Or it's not with the code in your question!
Try to avoid using global variables. Also, use 4 space indentations.
I would use length of time as an input.
from time import time
def do_something():
pass
def get_time(start_time):
# returns how much time did it pass from event that started at start_time
return time() - start_time
def countdown(countDown):
start_time = time()
# this is counter that attains consecutive values [0, 1, ..., countDown]
current_count = 0
while current_count < countDown:
print(countDown - current_count, end=' ')
while get_time(start_time) - current_count < 1:
do_something()
#warning: if do_something takes significant anount of
#time forthcoming print won't be correct
current_count += 1
print(countDown - current_count, end=' ')
return current_count
countdown(7)
countdown(5)
Also the purpose of
print("You have " + str(30 - countdown()) + " time")
is not clear to me. Use it wherever you want in your script.
Due to the question being quite unclear, it is hard to create exactly what you're looking for. However, this code should work for you no matter how you intend it to be used.
This code allows you to:
Make a timer
Get the time left
Run code while the timer is counting down
Run code once the timer has ended.
You can also reset the timer
Code:
import time
class countdown():
def start(self):
self.t = time.time()
def remaining(self):
return 30 - int(time.time()-self.t)
timer = countdown()
timer.start()
while True:
print(30 - countdown(), "seconds remaining") #Still time left code
if timer.remaining() <= 0:
pass #30 seconds over code
timer.reset() #Starts timer again
As others pointed out, your function is not resetting your counter.
Try the following little modification:
def countdown():
global countDown
countDown = int(time.time() - start_time) % 30
return countDown
Firstly, I want to apologize from everyone for not explaining my question clearly because this is my first question. Secondly, as shown in example , I saw that I did not made any mistake about my code. First part is correct but when it prints ("You have " + str(5 - countdown()) + " time") showing me the negative ones because of I take the modula of 30 but showing it in print func " 5 - countdown()" . So when it becomes 15 it will return 15 but 5 - 15 = -10. Thanks for everyone who tried to help.

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