timeout for 10 seconds while loop in python [duplicate] - python

This question already has answers here:
How would I stop a while loop after n amount of time?
(11 answers)
Closed 9 months ago.
What is the best way to timeout while loop in python
say:
while not buff.endswith('/abc #'):
After 10 secs, if it does not match, break the loop.
Thanks

You can record the time before the loop, then inside the while loop you can compare the current time, and if it's > 10 seconds, you can break out of the while loop.
Something like:
from datetime import datetime
start_time = datetime.now()
print(start_time)
while not buff.endswith('/abc #'):
print('waiting')
time_delta = datetime.now() - start_time
print(time_delta)
if time_delta.total_seconds() >= 10:
break

If your only concern is to end the loop after 10 seconds, try the below code.
from datetime import datetime
t1 = datetime.now()
while (datetime.now()-t1).seconds <= 10:
#do something
print(datetime.now())
Else check for the time difference inside the loop and break it. Like,
t1 = datetime.now()
while not buff.endswith('/abc #'):
if (datetime.now()-t1).seconds > 10:
break

You can use interrupting cow package and put you code inside a with management statement.
import interruptingcow
TIME_WAIT=20 #time in seconds
class TimeOutError(Exception):
"""InterruptingCow exceptions cause by timeout"""
pass
with interruptingcow.timeout(TIME_WAIT, exception=TimeOutError):
while not buff.endswith('/abc #'):
pass #do something or just pass
As long you don't use interruptingcow with another systems that implements SIGALARM eg. stopit, python-rq. It will work

Related

Python how to freeze program? [duplicate]

This question already has an answer here:
How to start/stop a Python function within a time period (ex. from 10 am to 12:30pm)?
(1 answer)
Closed 2 years ago.
Note: read my comments on the provided answer, it doesn't work
I have a python program which runs every 5 seconds like this:
def main():
start_time = time.time()
while True:
if not execute_data():
break
time.sleep(5.0 - ((time.time() - start_time) % 5.0))
The question is how can I make it run from 7:00 to 23:00 only? I don't want to use my computer resources at times where I'm sure my program won't be helpful...
You can use datetime.datetime.strptime() and datetime.datetime.strftime():
from datetime import datetime
import time
def str_to_time(string):
return datetime.strptime(string, "%H:%M")
def main():
start = '7:00'
end = '23:00'
while True:
now = str_to_time(datetime.now().strftime("%H:%M"))
if str_to_time(end) > now > str_to_time(start) or str_to_time(end) < now < str_to_time(start):
print('Working...')
time.sleep(5)
main()

How to set python to sleep till a particular time? [duplicate]

This question already has answers here:
In Python, how can I put a thread to sleep until a specific time?
(14 answers)
Closed 2 years ago.
I have a list which contains times like this ['13:45','12:30','11:40'] in string format. So, the script should pick the earliest time in the string format list and wait till that time occurs. The first part of code, picking the minimum can be done with min function. How to make it wait till that time?
And also, if the time mentioned the least one already completed(past) then it should pick the next lowest.
There is a nuance in this problem: when the least time from the list is smaller than the current time. In this case, the most reasonable way is to sleep until the smallest time in the list tomorrow. E.g., let's consider current time 23:59 and tl = [00:10, 01:30], then the script should sleep until 00:10 (tomorrow).
Here is the solution:
import time
from datetime import datetime
from datetime import timedelta
from dateutil import parser
now = datetime.now()
def parse_times(tl):
for t in tl:
parsed_time = parser.parse(t)
if parsed_time > now:
yield parsed_time
else:
yield parsed_time + timedelta(days=1)
tl = ['13:45', '12:30', '11:40']
parsed_times = parse_times(tl)
next_time = min(parsed_times)
time.sleep((next_time - now).total_seconds())
What about something like:
from time import sleep
from datetime import datetime
tl = ['13:45','12:30','11:40']
## remove times less or equal current time, then get minimum
t = min(el for el in tl if el > datetime.now().strftime('%H:%M'))
## sleep until we pass the minimum time
## we check this every second
while t > datetime.now().strftime('%H:%M'):
sleep(1)

Problems with python alarm at specified hours

I'm trying to make a "alarm" for my classes and it does that when a certain hour comes it does something (in this case it just prints, and i will change that when the code works) and it repeats until next alarm.The problem here is that when i run the code 1 min before it prints it's time , and then it reaches the alarm time and it still prints the same and not not yet.
I want the code to keep running after the if statements. Here's the code:
from datetime import datetime
import time
now = datetime.now()
current_time = now.strftime("%H:%M")
today = now.strftime("%A")
cn = "22:14"
ing ="21:23"
day = {0:"Monday", 1:"Tuesday", 2:"Wednesday"
, 3:"Thursday", 4:"Friday", 5:"Saturday", 6:"Sunday"}
def mday():
if (today == day[0]) and (current_time == cn):
print("its time")
time.sleep(1)
mday()
else:
print("not yet")
time.sleep(1)
mday()
mday()
The main problem with your code (why it does not work at all), is that you do not update the values of the today and current_time variables. That you sleep for one second in each call to mday() does not affect these variables. You need to update them right at the entry to mday.
The second problem is that you have infinite recursion here. Infinite loops run forever, which is what you want, I guess. Infinite recursion, on the other hand, simply uses up the stack, and crashes you application. You would need to convert the recursive function mday to one with an infinite loop. To do that, place all the if statement from inside mday inside a forever loop: (while True:), and
also remove the two recursive calls from the end of the branches. You can also take the sleep calls out of the if - remove one of them, and place the other after the the content of the else block:
from datetime import datetime
import time
cn = "22:14"
ing ="21:23"
day = {
0:"Monday",
1:"Tuesday",
2:"Wednesday",
3:"Thursday",
4:"Friday",
5:"Saturday",
6:"Sunday"
}
def mday():
while True:
# Update current time values
now = datetime.now()
current_time = now.strftime("%H:%M")
today = now.strftime("%A")
# Print alarm/no-alarm message
if (today == day[0]) and (current_time == cn):
print("its time")
else:
print("not yet")
time.sleep(1)
mday()
There are many ways this code can be optimized, but the above will produce roughly the result you want.

Python - Print index of for loop only once every five minutes

I'm trying to get a for loop to print the value of 'i' every 5 minutes
import threading
def f(i):
print(i)
threading.Timer(600, f).start()
for i in range(1,1000000000000):
f(i=i)
However, this method results in the code printing the value of i instantly since it calls 'f' as soon as it finds 'i'.
I know this is not the first time someone will ask, nor the last, but I can't get it to work on a for loop nested within a function.
I'm fairly new to Python and I'd appreciate any help.
How about just keeping track of how long has passed in the loop?
from timeit import default_timer as timer
start = timer()
freq = 5 * 60 # Time in seconds
last_time = 0.0
for i in range(int(1e8)):
ctime = timer()
if ctime - last_time > freq:
print(i)
last_time = ctime
I imagine you can make this more efficient by only checking the time every N iterations rather than every time. You may also want to look into using progressbar2 for a ready-made solution.
I prefer using datetime, as I think it's more intuitive and looks a bit cleaner. Otherwise, using more or less the same approach as Paul:
from datetime import datetime, timedelta
print_interval = timedelta(minutes=5)
# Initialize the next print time. Using now() will print the first
# iteration and then every interval. To avoid printing the first
# time, just add print_interval here (i.e. uncomment).
next_print = datetime.now() # + print_interval
for i in range(int(1e8)):
now = datetime.now()
if now >= next_print:
next_print = now + print_interval
print(i)
Also note that before python 3.x xrange would be preferable over range.

Trigger function periodic by datetime but not time interval

I want to make my function trigger at 0 second,30second every minute.
Rather than use time.sleep(30) because the script will run for months and have some blocking system call,
I want to make it happens on specific time like 12:00:00, 12:00:30, 12:01:00
How could I do it on Python 2.7
Not sure how your function works but if there is any sort of a loop you could use an if statement.
t = time.time()
while/for loop:
...
if time.time() > t + 30:
yourFunction()
t = time.time()
...
EDIT:
My fault, misread that. Similar method but you can use date time, probably better off looking into chrontab though. This method is a little hacky and if your script is small and can cycle every second this will work, otherwise go chrontab.
import datetime
t = datetime.datetime
run = True
while/for loop:
...
if t.now().second % 30 == 0 and run == True:
yourFunction()
run = False
if t.now().second % 30 == 1:
run = True
...

Categories

Resources