Python loop to run for certain amount of seconds

Question:

I have a while loop, and I want it to keep running through for 15 minutes. it is currently:

while True:
    #blah blah blah

(this runs through, and then restarts. I need it to continue doing this except after 15 minutes it exits the loop)

Thanks!

Asked By: oam811

||

Answers:

Try this:

import time

t_end = time.time() + 60 * 15
while time.time() < t_end:
    # do whatever you do

This will run for 15 min x 60 s = 900 seconds.

Function time.time returns the current time in seconds since 1st Jan 1970. The value is in floating point, so you can even use it with sub-second precision. In the beginning the value t_end is calculated to be “now” + 15 minutes. The loop will run until the current time exceeds this preset ending time.

Answered By: DrV

If I understand you, you can do it with a datetime.timedelta

import datetime

endTime = datetime.datetime.now() + datetime.timedelta(minutes=15)
while True:
  if datetime.datetime.now() >= endTime:
    break
  # Blah
  # Blah
Answered By: Elliott Frisch

try this:

import time
import os

n = 0
for x in range(10): #enter your value here
    print(n)
    time.sleep(1) #to wait a second
    os.system('cls') #to clear previous number
                     #use ('clear') if you are using linux or mac!
    n = n + 1
Answered By: anonmak9
import time
delay = 60*15 # For 15 minutes delay 
close_time = time.time()+delay
while True:
    # ...
    if time.time() > close_time:
        break
Answered By: Hasan Latif

I was looking for an easier-to-read time-loop when I encountered this question here. Something like:

for sec in max_seconds(10):
      do_something()

So I created this helper:

# allow easy time-boxing: 'for sec in max_seconds(42): do_something()'
def max_seconds(max_seconds, *, interval=1):
    interval = int(interval)
    start_time = time.time()
    end_time = start_time + max_seconds
    yield 0
    while time.time() < end_time:
        if interval > 0:
            next_time = start_time
            while next_time < time.time():
                next_time += interval
            time.sleep(int(round(next_time - time.time())))
        yield int(round(time.time() - start_time))
        if int(round(time.time() + interval)) > int(round(end_time)): 
            return

It only works with full seconds which was OK for my use-case.

Examples:

for sec in max_seconds(10) # -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
for sec in max_seconds(10, interval=3) # -> 0, 3, 6, 9
for sec in max_seconds(7): sleep(1.5) # -> 0, 2, 4, 6
for sec in max_seconds(8): sleep(1.5) # -> 0, 2, 4, 6, 8

Be aware that interval isn’t that accurate, as I only wait full seconds (sleep never was any good for me with times < 1 sec). So if your job takes 500 ms and you ask for an interval of 1 sec, you’ll get called at: 0, 500ms, 2000ms, 2500ms, 4000ms and so on. One could fix this by measuring time in a loop rather than sleep() …

Answered By: Sascha N.

For those using asyncio, an easy way is to use asyncio.wait_for():

async def my_loop():
    res = False
    while not res:
        res = await do_something()

await asyncio.wait_for(my_loop(), 10)
Answered By: Sam Bull

The best solution for best performance is to use @DrV answer and the suggestion from @jfs to use time.monotonic():

    import time
    from datetime import datetime, timedelta

    count = 0
    end_time = time.monotonic() + 10
    while time.monotonic() < end_time:
        count += 1
    print(f'10 second result: {count=:,}')
    # 10 second result: count=185,519,745

    count = 0
    end_time = time.time() + 10
    while time.time() < end_time:
        count += 1
    print(f'10 second result: {count=:,}')
    # 10 second result: count=158,219,172

    count = 0
    end_time = datetime.now() + timedelta(seconds=10)
    while datetime.now() < end_time:
        count += 1
    print(f'10 second result: {count=:,}')
    # 10 second result: count=39,168,578
Answered By: Jan Lněnička
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.