How do I make a timer in python? - 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)

Related

Optimizing a Function that Returns "ON" Every Second [duplicate]

This question already has answers here:
How to repeatedly execute a function every x seconds?
(22 answers)
Closed 5 days ago.
I'm very new to python, and I'm trying to make a sort of idle game. I'm having a little bit of trouble optimizing a function I wrote that flashes "ON" and then "OFF" every time a second passes.
While it works fine, it checks to see if a second has passed so many times that it peaks my CPU. The code is below:
import time
def timer():
oldtime = int(time.time())
#grabs the time on initiation
while True:
if oldtime < int(time.time()):
return 'ON'
#flashes on
return 'OFF'
#makes everything that checks if it's on only proc once
oldtime += int(time.time()) - oldtime
#makes oldtime advance one second ahead of time.time(),
#even if more than one second passes at a time
timer()
while timer() == "ON":
print('lorem ipsum')
#output: lorem ipsum every second and a peaking CPU
How would one go about optimizing something like this?
Here I have written a while loop that calls a function that will check the previous state of a variable and depending on whether it was ON or OFF it will sleep for 1 second and change to the other state.
import time
def repeat():
isOn = True
if(isOn):
time.sleep(1)
isOn = False
return 'OFF'
if(isOn != True):
time.sleep(1)
isOn = True
return 'ON'
while True:
#You could always take the return value of repeat() to do something else
#in your code
repeat()
I'm not sure if this is actually what you want as I feel like you are likely looking to do "something else" in the pause.
However, looking at your code, I think this will give you the result you are currently working towards. The key to not using up resources is to sleep()
import time
def timer():
time.sleep(1)
return ["On ", "Off"][int(time.time() % 2)]
while True:
print(timer(), end="\r", flush=True)

python schedule module to periodically run a function

Goal: run a function every day at a randomized time between two times.
So, I wrote this function to randomly generate a time (please offer feedback on how to streamline. Couldn't find this in an existing package - it MUST already exist...)
def gen_rand_time(low, high):
hour = np.random.randint(low, high)
minute = np.random.randint(1,59)
if minute < 10:
time = str(hour)+':'+str(0)+str(minute)
return time
else:
time = str(hour) + ':' + str(minute)
return time
Next I define the function I would like to run. Keeping it nice and simple.
def test(a):
print('TEST: ' + str(a))
Now I want to run this runction on a periodic basis. I use the schedule package.
def run_bot():
time1 = str(gen_rand_time(18,19))
print(time1)
schedule.every(1).days.at(time1).do(test('TEST WORKED'))
while True:
schedule.run_pending()
time.sleep(1)
run_bot()
when I run run_bot() and put in a time in the immediate future (say, 1 minute into the future), the test() function returns "TEST: TEST WORKED" without waiting for the specified random time.
You should probably try ... do(test,'TEST WORKED')
instead of ... do(test('TEST WORKED')), see this.
Besides, it seems that you cannot use the same value for low and high (I wonder if you actually tried what you posted).

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

How to make a time sensitive loop in 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.

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

Categories