I'm trying to ucreate a timer function that runs in the background of my code and make it so I can use/check the time. What I mean by use/check, I'm trying to make it so I can call upon that timer function and use it as integer.
This is the code I currently have:
def timer():
for endtime in range(0, 15):
print(15 - endtime)
time.sleep(1)
def hall():
timer()
while (timer > 0):
do something
Currently only using print(15 - endtime) for confirmation it is counting down.
But what the code does now is execute the countdown and that's it, it never touches the while loop. And of course the last issue is I can't set a function to an int. So I'm looking for some way where I can check where the timer is at and use it in that while loop.
The way you do it, you'll going to have to use multithread.
Here is another, simpler approach :
On your script beginning, set a time_start variable with the number of seconds since the epoch using time.time()
Then when you need the number of elapsed seconds, use time.time() - time_start :
t_start = time.time()
# do whatever you'd like
t_current = int(time.time()-t_start) # this way you get the number of seconds elapsed since start.
You can put that in a function as well, defining t_start as a global variable.
import time
t_start = time.time()
def timer():
global t_start
print(str(int(time.time()-t_start)))
print('start')
time.sleep(2)
timer()
time.sleep(3)
timer()
import time
def timer(tim):
time.sleep(1)
print tim
def hall():
tim = 15
while (tim > 0):
print 'do something'
timer(tim)
tim-=1
Not the cleanest solution, but it will do what you need.
The problem with your code is that when you run hall(), Python first executes the whole of timer() (i.e. the whole for loop), and then moves on with the rest of the code (it can only do one thing at a time). Thus, by the time it reaches the while loop in hall(), timer is already 0.
So, you're going to have to do something about that timer so that it counts down once, and then it moves on to the do something part.
Something that you can do is this:
def hall():
for a in range(0, 15):
print(15 - a)
# do something
time.sleep(1)
This should work just fine (if you're only executing hall 15 times), and condenses your code to just one function.
Related
I am trying to make a python script that works in a loop mode with iteration through a text file to run for periods of one hour and make 30minute pauses between each hour loop .
After some searching I found this piece of code :
import datetime
import time
delta_hour = 0
while:
now_hour = datetime.datetime.now().hour
if delta_hour != now_hour:
# run your code
delta_hour = now_hour
time.sleep(1800) # 1800 seconds sleep
# add some way to exit the infinite loop
This code has a few issues though :
It does not consider one hour periods since the script starts running
It does not seem to work continuously for periods over one hour
Considering what I am trying to achieve (running script 1hour before each time it pauses for 30mins) what is the best approach to this ? Cron is not an option here .
For clarification :
1hour run -- 30min pause -- repeat
Thanks
Here is a so simple code, I have written for teaching purposes, which is very clear
from datetime import datetime
class control_process():
def __init__(self, woking_period, sleeping_period):
self.woking_period = woking_period # working period in minutes
self.sleeping_period = sleeping_period # sleeping period in minutes
self.reset()
def reset(self):
self.start_time = datetime.utcnow() # set starting point
def manage(self):
m = (datetime.utcnow() - self.start_time).seconds / 60 # how long since starting point
if m >= self.woking_period: # if exceeded the working period
time.sleep(self.sleeping_period * 60) # time to sleep in seconds
self.reset() # then reset time again
return # go to continue working
cp = control_process(60, 30) # release for 60 minutes and sleep for 30 minutes
while True: # you code loop
cp.manage()
'''
your code
'''
in which 'control_processobject - I calledcp- callscp.manage()` inside your executing loop.
you reset time via cp.reset() before going in the loop or whenever you want
Based on Comments
The simplicity I mean is to add this class to your general library so you can use it whenever you want by instantiation of cp then one or two controlling functions 'cp.manage()` which control the working cycles, and cp.reset() if you want to use it in another location of the code. I believe that use a function is better than a long condition statement.
Using the default library you could do something like call the script itself using subprocess. By checking whether conditions are met the process could do a task and call itself. Extending the logic with a kill pill would make it stop (I leave that up to you).
import argparse, time
from subprocess import call
DELAY = 60 * 30 # minutes
WORK_TIME = 60 * 60 # minutes
parser = argparse.ArgumentParser()
parser.add_argument("-s",
help = "interval start time",
type = float,
default = time.time())
parser.add_argument("-t",
help = "interval stop time",
type = float,
default = time.time() + WORK_TIME)
def do_task():
# implement task
print("working..")
return
if __name__ == "__main__":
args = parser.parse_args()
start = args.s
stop = args.t
# work
if start < time.time() < stop:
do_task()
# shift target
else:
start = time.time() + DELAY
stop = start + WORK_TIME
call(f"python test.py -t {stop} -s {start}".split())
The simplest solution I could come up with was the following piece of code, which I added inside my main thread :
start_time = int(time())
... #main thread code
#main thread code end
if int(time() - start_time >= 60 * 60):
print("pausing time")
sleep(30 * 60)
start_time = int(time())
From the moment the script starts this will pause every hour for 30mins and resume afterwards .
Simple yet effective !
I just wrote a function that looked like this:
def block_for(seconds):
"""Wait at least seconds, this function should not be affected by the computer sleeping."""
end_time = datetime.datetime.now() + datetime.timedelta(seconds)
while datetime.datetime.now() < end_time:
pass
Can anything bad come of this? Should there ideally be something inside the while loop?
time.sleep(seconds) seconds does just that without burning through CPU cycles. your loop keeps the CPU fully busy. i do not know for you but i consider this bad.
maybe putting time.sleep(1) in the while loop will require less cycles? Or
def block_for(seconds):
"""Wait at least seconds, this function should not be affected by the computer sleeping."""
end_time = datetime.datetime.now() + datetime.timedelta(seconds=seconds)
while datetime.datetime.now() < end_time - datetime.timedelta(seconds=1):
time.sleep(1)
while datetime.datetime.now() < end_time:
pass
matches = []
done = []
for item in matches:
dofunctioneveryloop()
done.extent(item)
dofunctiononce5min()
How can I execute dofunctiononce5min() inside this loop once 5 minute? This is backup to file function is this possible?
Not sure I understood the question. I'll assume that you want this function to be executed only once every five minutes, no matter how often it is really called.
This might be overkill, but why not use a decorator? This will create a new function for the 'decorated' function that will execute the original function if X seconds have passed since the last execution. This will make sure the function is not executed more than once every 5 minutes (or whateer time interval in seconds you pass to the decorator), no matter whether it's called in that loop or elsewhere.
import time
def onceEveryXSeconds(seconds): # this creates the decorator
def wrapper(f): # decorator for given 'seconds'
f.last_execution = 0 # memorize last execution time
def decorated(*args, **kwargs): # the 'decorated' function
if f.last_execution < time.time() - seconds:
f.last_execution = time.time()
return f(*args, **kwargs)
return decorated
return wrapper
Usage:
#onceEveryXSeconds(3)
def function(foo):
print foo
while True:
print "loop"
function("Hello again")
time.sleep(1)
Output, with #onceEveryXSeconds(3)
loop
Hello again
loop
loop
loop
Hello again
loop
...
Assuming the loop takes longer than five minutes, you could use time.time() to determine when 5 minutes has been up.
import time
matches = []
done = []
starttime = time.time()
for item in matches:
dofunctioneveryloop()
done.extent(item)
if time.time() - starttime > 300:
dofunctiononce5min()
starttime = time.time()
It is not recommended that you do this way. Perhaps the best approach could be to schedule it on operation system, and it run it task periodically.
Anyway, if want to run a statement every x time, here is an example
import time
for i in range(5):
print i
time.sleep(3) # seconds
Time as parameter should be fractioned like 0.5 seconds.
I've got this program:
import multiprocessing
import time
def timer(sleepTime):
time.sleep(sleepTime)
fooProcess.terminate()
fooProcess.join() #line said to "cleanup", not sure if it is required, refer to goo.gl/Qes6KX
def foo():
i=0
while 1
print i
time.sleep(1)
i
if i==4:
#pause timerProcess for X seconds
fooProcess = multiprocessing.Process(target=foo, name="Foo", args=())
timer()
fooProcess.start()
And as you can see in the comment, under certain conditions (in this example i has to be 4) the timer has to stop for a certain X time, while foo() keeps working.
Now, how do I implement this?
N.B.: this code is just an example, the point is that I want to pause a process under certain conditions for a certain amount of time.
I am think you're going about this wrong for game design. Games always (no exceptions come to mind) use a primary event loop controlled in software.
Each time through the loop you check the time and fire off all the necessary events based on how much time has elapsed. At the end of the loop you sleep only as long as necessary before you got the next timer or event or refresh or ai check or other state change.
This gives you the best performance regarding lag, consistency, predictability, and other timing features that matter in games.
roughly:
get the current timestamp at the time start time (time.time(), I presume)
sleep with Event.wait(timeout=...)
wake up on an Event or timeout.
if on Event: get timestamp, subtract initial on, subtract result from timer; wait until foo() stops; repeat Event.wait(timeout=[result from 4.])
if on timeout: exit.
Here is an example, how I understand, what your Programm should do:
import threading, time, datetime
ACTIVE = True
def main():
while ACTIVE:
print "im working"
time.sleep(.3)
def run(thread, timeout):
global ACTIVE
thread.start()
time.sleep(timeout)
ACTIVE = False
thread.join()
proc = threading.Thread(target = main)
print datetime.datetime.now()
run(proc, 2) # run for 2 seconds
print datetime.datetime.now()
In main() it does a periodic task, here printing something. In the run() method you can say, how long main should do the task.
This code producess following output:
2014-05-25 17:10:54.390000
im working
im working
im working
im working
im working
im working
im working
2014-05-25 17:10:56.495000
please correct me, if I've understood you wrong.
I would use multiprocessing.Pipe for signaling, combined with select for timing:
#!/usr/bin/env python
import multiprocessing
import select
import time
def timer(sleeptime,pipe):
start = time.time()
while time.time() < start + sleeptime:
n = select.select([pipe],[],[],1) # sleep in 1s intervals
for conn in n[0]:
val = conn.recv()
print 'got',val
start += float(val)
def foo(pipe):
i = 0
while True:
print i
i += 1
time.sleep(1)
if i%7 == 0:
pipe.send(5)
if __name__ == '__main__':
mainpipe,foopipe = multiprocessing.Pipe()
fooProcess = multiprocessing.Process(target=foo,name="Foo",args=(foopipe,))
fooProcess.start()
timer(10,mainpipe)
fooProcess.terminate()
# since we terminated, mainpipe and foopipe are corrupt
del mainpipe, foopipe
# ...
print 'Done'
I'm assuming that you want some condition in the foo process to extend the timer. In the sample I have set up, every time foo hits a multiple of 7 it extends the timer by 5 seconds while the timer initially counts down 10 seconds. At the end of the timer we terminate the process - foo won't finish nicely at all, and the pipes will get corrupted, but you can be certain that it'll die. Otherwise you can send a signal back along mainpipe that foo can listen for and exit nicely while you join.
So I have a script where it measures how fast a person can press the keyboard 100 times. I have used the time module to set the start and the end of the measuring:
import time
import os
start = time.time()
pause() * 100 #defined the definition to os.system("pause")
end = time.time()
How do I make it so python can compare the elapsed time so if the time taken is >20seconds, it performs commands, and if it is equal or less than 20 seconds then preforms other commands?
You mean like this?
elapsed_time = end - start
if elapsed_time > 20:
# code
else:
# other code