How to make a time sensitive loop in Python? - python

I want to make a function that prints a statement every 2 minutes. I'm really new to Python and don't fully understand the time library. This is the code I have so far:
from datetime import datetime
import time
now = datetime.now()
print now.second
print "start"
while True:
print "while loop started"
if (now % 2 == 0):
print "Hello"
else:
break
How can I do this?

You can use time.sleep here. Since you want a timer for 2 minutes, pass 120 (seconds) as the argument value.
Basically, this translates into something like below:
while True:
time.sleep(120)
print "Hello"
This will print "Hello" every 2 minutes.
Note that time.sleep is not entirely accurate, and may be off by a small but arbitrary amount of time because of OS scheduling of other processes etc and execution of the code itself.

Use the sched module
import sched, time
s = sched.scheduler(time.time, time.sleep)
def do_something(sc):
print "Doing stuff..."
# do your stuff
sc.enter(60, 1, do_something, (sc,))
s.enter(60, 1, do_something, (s,))
s.run()
take a look here.

Related

How do I make a timer in python?

I want a timer, but I want it to just affect one function, so it can't just be
sleep().
For example:
def printSomething():
print("Something")
def functionWithTheTimer():
for i in range(0, 5):
#wait for 1 second
print("Timer ran out")
Say the first function is called when a button is clicked, and the second function should print something out every second, both should act independently.
If I used sleep(), I couldn't execute the first function within that one second, and that's a problem for me. How do I fix this?
For your timer function, you may want to do something like this:
def functionWithTheTimer():
for i in reversed(range(1, 6)):
print(i)
time.sleep(1)
print("finished")
This will print the range backwards (like a countdown), one number every second.
EDIT: To run a function during that time, you can just duplicate and shorten the wait time. Example:
def functionWithTheTimer():
for i in reversed(range(1, 6)):
print(i)
time.sleep(0.5)
YourFunctionHere()
time.sleep(0.5)
print("finished")
You can play with the timings a little so you can get your appropriate output.
You can use the datetime library like this:
from datetime import datetime
def functionwithtimer():
start_time = datetime.now()
# code stuff you have here
print("This function took: ", datetime.now() - start_time)

Run repeatedly two different functions every n seconds

I have two functions: foo() should start every 5 seconds and bar() should start every 10 seconds.
code below:
import threading
import time
def foo():
while True:
time.sleep(5)
print("Call every 5 seconds")
time.sleep(5)
def bar():
while True:
time.sleep(10)
print("Call every 10 seconds")
tr1 = threading.Thread(target=foo)
tr1.start()
tr2 = threading.Thread(target=bar)
tr2.start()
But I think that this is not a good solution.
What is the best way to do this?
And yes, I think that I have memory leak, should I use garbage collector or anything else?
P.S. I hope you could understand what i wrote, because I am not native speaker.
Using the link posted by depperm in the comments
import sched, time
s = sched.scheduler(time.time, time.sleep)
def foo(s):
print("Call every 5 seconds")
s.enter(5, 1, foo, (s,))
def bar(s):
print("Call every 10 seconds")
s.enter(10, 1, bar, (s,))
s.enter(5, 1, foo, (s,))
s.enter(10, 1, bar, (s,))
s.run()
Your code with minor changes, plus some print statements that suggest that this works alright. The 'good' thing about this code is that sleep will raise an exception if the argument to it is negative. Thus, if the codes expected to take less than five or ten seconds respectively take longer then then script will die.
import threading
import time
from datetime import timedelta, datetime
def foo(delay=5):
while True:
t_start = time.time()
print("Call every %s seconds" % delay, datetime.now().strftime('%H.%M.%S'))
t_end = time.time()
time.sleep(delay-(t_end-t_start))
def bar(delay=10):
while True:
t_start = time.time()
print("Call every %s seconds" % delay, datetime.now().strftime('%H.%M.%S'))
t_end = time.time()
time.sleep(delay-(t_end-t_start))
tr1 = threading.Thread(target=foo)
tr1.start()
tr2 = threading.Thread(target=bar)
tr2.start()
Here's the output.
>pythonw -u "temp1.py"
Call every 5 seconds 17.09.51
Call every 10 seconds 17.09.51
Call every 5 seconds 17.09.56
Call every 5 seconds 17.10.01
Call every 10 seconds 17.10.01
Call every 5 seconds 17.10.06
Call every 5 seconds 17.10.11
Call every 10 seconds 17.10.11
Call every 5 seconds 17.10.16
Call every 5 seconds 17.10.21
Call every 10 seconds 17.10.21
Call every 5 seconds 17.10.26
Call every 10 seconds 17.10.31
Call every 5 seconds 17.10.31
Call every 5 seconds 17.10.36
>Process failed to respond; forcing abrupt termination...
>Exit code: 1
I cannot say whether this is the 'best' way of doing this. At least the contents of the functions begin at more or less regular time intervals.

Time based for loop in Python

I have a program which includes execution of time based while loop. Some thing like..
import time
endtime=time.time()+60.0 #1minute
while (time.time()<endtime):
do something
I was just wondering if this is possible using for loop? Can I build a time based for loop in python?
From https://wiki.python.org/moin/ForLoop
When do I use for loops?
For loops are traditionally used when you have a piece of code which you want to repeat n number of times. As an alternative, there is the WhileLoop, however, while is used when a condition is to be met, or if you want a piece of code to repeat forever, for example -
The while loop feels more natural for this task, because the for needs an enumerable or a generator.
But if you really want to do it with a for loop, I guess you can construct a generator that yields something until time.time()<endtime:
def there_is_more_time(e)
while time.time() < e:
yield True
for i in there_is_more_time(endtime):
do something
But as you see, you are again using while behind the scenes.
Perhaps someone can manage to not use the while inside the generator, but what's the point of doing so?
Sure. Here's an iterator that gives you the time since start over and over until it reaches the end:
def time_counter(seconds):
starttime = time.time()
while True:
now = time.time()
if now > starttime + seconds:
break
yield now - starttime
for t in time_counter(20):
print(t)
time.sleep(3)
When I run this, it outputs:
9.5367431640625e-07
3.002220869064331
6.0040669441223145
9.004395961761475
12.006848812103271
15.009617805480957
18.011652946472168
If you need some different value, just change the yield expression.
If you don't need any value… then you don't need a for statement; your existing code is already perfectly readable, and a for loop that iterates over and discards some meaningless values is just going to make it confusing.
Perhaps you want to create a scheduler object?
https://docs.python.org/2/library/sched.html
import sched, time
s = sched.scheduler(time.time, time.sleep)
def print_time():
print "From print_time", time.time()
def print_some_times():
print time.time()
s.enter(1, 1, print_time, ())
s.enter(2, 1, print_time, ())
s.enter(3, 1, print_time, ())
s.enter(4, 1, print_time, ())
s.enter(5, 1, print_time, ())
s.run()
print time.time()
Output:
1430392956.35
From print_time 1430392957.35
From print_time 1430392958.35
From print_time 1430392959.35
From print_time 1430392960.35
From print_time 1430392961.35
1430392961.35

Python: Stop at desired time

I have some problem here. I want to stop the print command at desired time. I figured out some codes and it still keep looping. Here the code,
import time
t = time.strftime("%H%M%S")
while ti:
print(time.strftime("%H%M%S"))
time.sleep(1)
if t = ("140000"): #just example of time to stop print
break
Thanks
t = time.strftime("%H%M%S")
is only executed once before the loop, so t's value doesn't ever change.
Your approach is the worst method of checking time difference; python's datetime framework allows for subtraction of timestamps and thus, you can check the time since something else happened easily without doing any string comparisons...
This will work
import time
t = time.strftime("%H%M%S")
while t:
t = time.strftime("%H%M%S")
print(time.strftime("%H%M%S"))
time.sleep(1)
if t == ("140000"): #just example of time to stop print
break
You had some bugs in your code
while ti: -- > while t:
if t = ("140000"): --> if t== ("140000"):
and you were missing this line t = time.strftime("%H%M%S")
time.sleep(1) may sleep less or more than a second therefore t == "140000" is not enough.
To stop a loop at a given local time:
import time
from datetime import datetime
stop_dt = datetime.combine(datetime.now(), datetime.strptime("1400", "%H%M").time())
stop_time = time.mktime(stop_dt.timetuple())
while time.time() < stop_time:
print(time.strftime("%H%M%S"))
time.sleep(max(1, (stop_time - time.time()) // 2))
time.time() returns "seconds since the epoch" -- unlike strings comparison it works across a midnight.
The sleep interval is a half of the remaining time or one second (whatever larger).
time.mktime() may return a wrong result if stop time is during an end-of-DST transition ("fall back") when the local time is ambiguous (the string-based solution may stop twice in this case).
Try this:
import time
while ti:
t = time.strftime("%H%M%S")
print(time.strftime("%H%M%S"))
time.sleep(1)
if t = ("140000"): #just example of time to stop print
break

How do I get python code to loop every x mins between the times y and z?

This might be incredibly easy but how do I get python code to loop every x mins between the times y and z?
For example if I wanted my script to run between midnight (00:00) through to 10 pm (22:00) looping every 5 minutes.
Try the sched module in the standard library. Here's an example of calling a function once per second, starting five seconds in the future, and ending ten seconds in the future:
from sched import scheduler
from time import time, sleep
s = scheduler(time, sleep)
def run_periodically(start, end, interval, func):
event_time = start
while event_time < end:
s.enterabs(event_time, 0, func, ())
event_time += interval
s.run()
if __name__ == '__main__':
def say_hello():
print 'hello'
run_periodically(time()+5, time()+10, 1, say_hello)
Alternatively, you can work with threading.Timer, but you need to do a little more work to get it to start at a given time, run every five minutes, and stop at a fixed time.

Categories