5

I have a program (temptrack) where I need to download weather data every x minutes for x amount of hours. I have figured out how to download every x minutes using time.sleep(x*60), but I have no clue how to repeat this process for a certain amount of hours.

UPDATE: Thank you to everyone who posted a solution. I marked the example using "datetime.datetime.now() + datetime.timedelta(hours=x)" as the best answer because I could understand it the best and it seems like it will work very well for my purpose.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ErikT
  • 606
  • 8
  • 15

5 Answers5

5

Compute the time you want to stop doing whatever it is you're doing, and check each time that the time limit hasn't expired. Like this:

finish_time = datetime.datetime.now() + datetime.timedelta(hours=6)
while datetime.datetime.now() < finish_time:
    do_something()
    sleep_for_a_bit()
  • This is exactly what I was looking for, even though I didn't know it. Thank you very much. – ErikT Apr 18 '10 at 16:57
4

I've just found sched in the Python standard library.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dzen
  • 6,923
  • 5
  • 28
  • 31
3

You are looking for a scheduler.

Check this thread.

Community
  • 1
  • 1
Macarse
  • 91,829
  • 44
  • 175
  • 230
0

May be a bit of overkill, but for running background tasks, especially if you need a GUI, I'd recommend checking out the PyQt route with QSystemTrayIcon and QTimer

-2

Maybe I'm misunderstanding you, but just put it in a loop that runs a sufficient number of times. For example, to download every 5 minutes for 2 hours you need to download 24 times, so:

for i in range(24):
    download()
    sleep(5*60)

If you need it to be parameterizable, it's just:

from __future__ import division
from math import ceil
betweenDLs = 5 # minutes
totalTime = 2*60 # minutes
for i in range(int(ceil(totalTime/betweenDLs))):
    download()
    sleep(betweenDLs*60)
Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
  • 2
    This is a simple solution, but it might not be quite what is wanted if the time to execute the function is similar in magnitude to the time between executions. – Mark Byers Apr 17 '10 at 21:45
  • Thank you. Your first example works well. I'll just use "for i in range(totalTime/frequency)" and that should work well. I know it will round (as I'm using integers, not floating point) but it does not have to be very accurate. – ErikT Apr 17 '10 at 21:47
  • 1
    Try to avoid using range() unless you are needing for a real list. If you just need to run a for use xrange instead. This will optimize your code, because range() allocs a whole list, while xrange() is just an iterator. NOTE: in python3 there's only range() and behaves like xrange() – Dacav Apr 17 '10 at 22:22
  • I would use select() for doing this :p – dzen Apr 18 '10 at 10:00
  • UPDATE: nevermind, using "for i in range(totalTime/frequency)" does not appear to work that well (meaning it is too inaccurate to use). Thanks, I'll check out xrange() and select(). – ErikT Apr 18 '10 at 16:54