Perform action every once in a while - python

I am currently trying (Python 2.7) to set an action to be performed with a fixed sampling frequency (i.e. every x milliseconds). However, I am facing inaccurate results. With the code bellow (sampling frequency of 1000Hz, code running for 5 seconds) I would expect to have 5 * 10000 samples. Instead, I'm getting lower values. I would like to have a sampling frequency of 5000Hz at best, but I would also be happy with 1000Hz.
Can anyone help me?
import datetime
count = 0
loop_start_time = start_time = datetime.datetime.now()
while datetime.datetime.now() - loop_start_time <= datetime.timedelta(0,5,0): #loop for 5 seconds
if datetime.datetime.now() - start_time >= datetime.timedelta(0,0,1000): #perform an action every 1000 microseconds (1 millisecond, 0.1 seconds)
start_time = datetime.datetime.now()
count = count + 1
print count
Best regards,
T2

Would something like this work?
import time
import threading
total_time = 5
increment_time = .1
is_running = False
count = 0
def incrementCounter():
global count
global is_running
is_running = True
threading.Timer(increment_time, incrementCounter).start()
count += 1
# Any additional code should be put here
end_time = time.time() + total_time
while time.time() < end_time:
if not is_running:
incrementCounter()
print count
Output for this I am getting ~50.

Related

How do I ensure that a timed loop performs the same number of iterations from trial to trial when the same duration is specified?

from datetime import datetime, timedelta
ntrials = 3 # specify number of trials
duration = 1 # specify duration (in seconds)
for i in range(1,ntrials+1):
count = 0 # (re)initialize count to zero
end_time = datetime.now() + timedelta(seconds=duration) # set trial duration
while datetime.now() < end_time: # check if duration has elapsed
count += 1 # count number of iterations
print("trial: ",i,"\tcount: ",count) # display results

python - printing something in a for loop every n seconds

I have a for loop that iterates over a number and performs some simple calculations. I am trying to figure out how to print out ( or log to file) the current value of 'val' every .5 to 1 second with out having to pause or sleep during the loop. Here is a super simple example
val_list = []
for i in xrange(iterations):
val = (i*(1/2)) * pi
val2 = np.linalg.pinv(val)
# print or write to log val2 after every half second (or 1 second)
val_list.append(val2)
Just use time.time to capture the time before starting, then check how long it's been after you calculate val2:
import time
val_list = []
prev_time = time.time()
for i in xrange(iterations):
val = (i*(1/2)) * pi
val2 = np.linalg.pinv(val)
# print or write to log val2 after every half second (or 1 second)
dt = time.time() - prev_time
if dt > 1:
# print or write to log here
prev_time = time.time()
val_list.append(val2)
You can use time.time():
from time import time as t
val_list = []
nowTime = t()
for i in xrange(iterations):
val = (i*(1/2)) * pi
val2 = np.linalg.pinv(val)
curTime = t()
if curTime - nowTime >= 0.5:
#Do your stuff
nowTime = curTime
val_list.append(val2)
You can achieve this using Threads.
Here's a documentation on how to utilize Threads : https://docs.python.org/3/library/threading.html ( If you're using Python2.7 then change the 3 in the url to a 2 )
Here's a link which is similar to what you want and should also point you in the right direction : Python threading.timer - repeat function every 'n' seconds
Basically you have to create a Thread that will only execute ever n number of seconds. On each iteration it will print the value. The above link should suffice for that. Good luck !

How would I format inputted minutes/seconds into datetime.now() format?

I have created a program which requires the user to input a given TimeType (Seconds/Minutes) and an objectivetime (integer) (e.g. if the user inputs Seconds and then 5, then the objective time is 5 Secs). In addition, the program also checks the time at the start and then checks the time after to work out the elapsed_time. I then wanted to check if the elapsed_time is more than or equal to the objective time. The code i have written is shown below (minus the other irrelevant code in between a and b)
import time, sys, os, random
a = datetime.datetime.now().replace(microsecond=0)
#random code...
b = datetime.datetime.now().replace(microsecond=0)
timetype = input("Enter time type: ")#Either Seconds or Minutes
objectivetime = input("Enter objective time: ")#This will be an integer
if timetype == 'Seconds':
#convert objectivetime to seconds and present in same format as a or b
else:
#convert objectivetime into minutes and present in same format as a or b
elapsed_time = b-a
if objectivetime<=elapsed_time:
'Well done'
else:
'You have exceeded the objective time'
Is there any way that the code could be edited to get the objective time to be formatted in the same way as a and b (start_time and end_time)??
Update--------------------------------------------------------------------------
How would I work out which time is bigger (elapsed_time or objtime)??
See updated code:
import time, sys, os, random
import datetime
a = datetime.datetime.now().replace(microsecond=0)
print(a)
#random code...
time.sleep(3)
b = datetime.datetime.now().replace(microsecond=0)
timetype = input("Enter time type: ")#Either Seconds or Minutes
objectivetime = input("Enter objective time: ")#This will be an integer
objectivetime = int(objectivetime) # I noticed you didn't do this in your code
delta = None
if timetype == 'Seconds':
delta = datetime.timedelta(seconds = objectivetime)
else:
delta = datetime.timedelta(minutes = objectivetime)
objtime = a + delta
print(objtime)
#How would I work out which time is greater?? (elapsed_time or objtime)
elapsed_time = b-a
print(elapsed_time-objtime)
objectivetime = int(objectivetime) # I noticed you didn't do this in your code
delta = None
if timetype == 'Seconds':
delta = datetime.timedelta(seconds = objectivetime)
else:
delta = datetime.timedelta(minutes = objectivetime)
objtime = a + delta
This will give you a datetime object like datetime.now()
To compare the datetime object, you can simply use the comparison operators. For example,
b <= objtime # Finished before (or on) the objective time
b > objtime # Finished after the objective time
You don't even need to subtract a from b! If you still want to, then compare the time deltas instead
elapsed_time <= delta # Finished before (or on) the objective time
elapsed_time > delta # Finished after the objective time

Algorithm timing in Python

I want to compute how many times my computer can do counter += 1 in one second. A naive approach is the following:
from time import time
counter = 0
startTime = time()
while time() - startTime < 1:
counter += 1
print counter
The problem is time() - startTime < 1 may be considerably more expensive than counter += 1.
Is there a way to make a less "clean" 1 sec sample of my algorithm?
The usual way to time algorithms is the other way around: Use a fixed number of iterations and measure how long it takes to finish them. The best way to do such timings is the timeit module.
print timeit.timeit("counter += 1", "counter = 0", number=100000000)
Note that timing counter += 1 seems rather pointless, though. What do you want to achieve?
Why don't you infer the time instead? You can run something like:
from datetime import datetime
def operation():
counter = 0
tbeg = datetime.utcnow()
for _ in range(10**6):
counter += 1
td = datetime.utcnow() - tbeg
return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6)/10.0**6
def timer(n):
stack = []
for _ in range(n):
stack.append(operation()) # units of musec/increment
print sum(stack) / len(stack)
if __name__ == "__main__":
timer(10)
and get the average elapsed microseconds per increment; I get 0.09 (most likely very inaccurate). Now, it is a simple operation to infer that if I can make one increment in 0.09 microseconds, then I am able to make about 11258992 in one second.
I think the measurements are very inaccurate, but maybe is a sensible approximation?
I have never worked with the time() library, but according to that code I assume it counts seconds, so what if you do the /sec calculations after ctrl+C happens? It would be something like:
#! /usr/bin/env python
from time import time
import signal
import sys
#The ctrl+C interruption function:
def signal_handler(signal, frame):
counts_per_sec = counter/(time()-startTime)
print counts_per_sec
exit(0)
signal.signal(signal.SIGINT, signal_handler)
counter = 0
startTime = time()
while 1:
counter = counter + 1
Of course, it wont be exact because of the time passed between the last second processed and the interruption signal, but the more time you leave the script running, the more precise it will be :)
Here is my approach
import time
m = 0
timeout = time.time() + 1
while True:
if time.time() > timeout:
break
m = m + 1
print(m)

Calculating Time Difference

at the start and end of my program, I have
from time import strftime
print int(strftime("%Y-%m-%d %H:%M:%S")
Y1=int(strftime("%Y"))
m1=int(strftime("%m"))
d1=int(strftime("%d"))
H1=int(strftime("%H"))
M1=int(strftime("%M"))
S1=int(strftime("%S"))
Y2=int(strftime("%Y"))
m2=int(strftime("%m"))
d2=int(strftime("%d"))
H2=int(strftime("%H"))
M2=int(strftime("%M"))
S2=int(strftime("%S"))
print "Difference is:"+str(Y2-Y1)+":"+str(m2-m1)+":"+str(d2-d1)\
+" "+str(H2-H1)+":"+str(M2-M1)+":"+str(S2-S1)
But when I tried to get the difference, I get syntax errors.... I am doing a few things wrong, but I'm not sure what is going on...
Basically, I just want to store a time in a variable at the start of my program, then store a 2nd time in a second variable near the end, then at the last bit of the program, compute the difference and display it. I am not trying to time a function speed. I am trying to log how long it took for a user to progress through some menus. What is the best way to do this?
The datetime module will do all the work for you:
>>> import datetime
>>> a = datetime.datetime.now()
>>> # ...wait a while...
>>> b = datetime.datetime.now()
>>> print(b-a)
0:03:43.984000
If you don't want to display the microseconds, just use (as gnibbler suggested):
>>> a = datetime.datetime.now().replace(microsecond=0)
>>> b = datetime.datetime.now().replace(microsecond=0)
>>> print(b-a)
0:03:43
from time import time
start_time = time()
...
end_time = time()
seconds_elapsed = end_time - start_time
hours, rest = divmod(seconds_elapsed, 3600)
minutes, seconds = divmod(rest, 60)
You cannot calculate the differences separately ... what difference would that yield for 7:59 and 8:00 o'clock? Try
import time
time.time()
which gives you the seconds since the start of the epoch.
You can then get the intermediate time with something like
timestamp1 = time.time()
# Your code here
timestamp2 = time.time()
print "This took %.2f seconds" % (timestamp2 - timestamp1)
Both time.monotonic() and time.monotonic_ns() are correct. Correct as in monotonic.
>>> import time
>>>
>>> time.monotonic()
452782.067158593
>>>
>>> t0 = time.monotonic()
>>> time.sleep(1)
>>> t1 = time.monotonic()
>>> print(t1 - t0)
1.001658110995777
Regardless of language, monotonic time is the right answer, and real time is the wrong answer. The difference is that monotonic time is supposed to give a consistent answer when measuring durations, while real time isn't, as real time may be adjusted – indeed needs to be adjusted – to keep up with reality. Monotonic time is usually the computer's uptime.
As such, time.time() and datetime.now() are wrong ways to do this.
Python also has time.perf_counter() and time.perf_counter_ns(), which are specified to have the highest available resolution, but aren't guarranteed to be monotonic. On PC hardware, though, both typically have nanosecond resolution.
Here is a piece of code to do so:
def(StringChallenge(str1)):
#str1 = str1[1:-1]
h1 = 0
h2 = 0
m1 = 0
m2 = 0
def time_dif(h1,m1,h2,m2):
if(h1 == h2):
return m2-m1
else:
return ((h2-h1-1)*60 + (60-m1) + m2)
count_min = 0
if str1[1] == ':':
h1=int(str1[:1])
m1=int(str1[2:4])
else:
h1=int(str1[:2])
m1=int(str1[3:5])
if str1[-7] == '-':
h2=int(str1[-6])
m2=int(str1[-4:-2])
else:
h2=int(str1[-7:-5])
m2=int(str1[-4:-2])
if h1 == 12:
h1 = 0
if h2 == 12:
h2 = 0
if "am" in str1[:8]:
flag1 = 0
else:
flag1= 1
if "am" in str1[7:]:
flag2 = 0
else:
flag2 = 1
if flag1 == flag2:
if h2 > h1 or (h2 == h1 and m2 >= m1):
count_min += time_dif(h1,m1,h2,m2)
else:
count_min += 1440 - time_dif(h2,m2,h1,m1)
else:
count_min += (12-h1-1)*60
count_min += (60 - m1)
count_min += (h2*60)+m2
return count_min

Categories