I want to print random data ranging from -1 to 1 in csv file for each millisecond using Python. I started with to print for each second and it worked. But, I am facing difficulty with printing random data for each millisecond. I want the timestamp to be in UNIX epoch format like "1476449030.55676" (for milliseconds, decimal point is not required)
tstep = datetime.timedelta(milliseconds=1)
tnext = datetime.datetime.now() + tstep
NumberOfReadings = 10; # 10 values ( 1 value for 1 millisecond)
i = 0;
f = open(sys.argv[1], 'w+')
try:
writer = csv.writer(f)
while i < NumberOfReadings:
writer.writerow((random.uniform(-1, 1), time.time()))
tdiff = tnext - datetime.datetime.now()
time.sleep(float(tdiff.total_seconds()/1000))
tnext = tnext + tstep
i =i+1;
finally:
f.close()
UPD: time.sleep() accepts argument in seconds, so you don't need to divide it by 1000. After fixing this, my output looks like this:
0.18153176446804853,1476466290.720721
-0.9331178681567136,1476466290.721784
-0.37142653326337327,1476466290.722779
0.1397040393287503,1476466290.723766
0.7126280853504974,1476466290.724768
-0.5367844384018245,1476466290.725762
0.44284645253432786,1476466290.726747
-0.2914685960956531,1476466290.727744
-0.40353712249981943,1476466290.728778
0.035369003158632895,1476466290.729771
Which is as good as it gets, given the precision of time.sleep and other time functions.
Here's a stripped down version, which outputs timestamps into stdout every second:
import time
tstep = 0.001
tnext = time.time() + tstep
NumberOfReadings = 10; # 10 values ( 1 value for 1 millisecond)
for i in range(NumberOfReadings):
now = time.time()
print(now)
time.sleep(tnext - now)
tnext += tstep
================================================
This is the problem:
float(tdiff.total_seconds()/1000)
You use integer division, and then convert result to float.
Instead, you need to use float division:
tdiff.total_seconds()/1000.0
Related
For Python 3, is there a possibility to find the highest possible calculated number in a function under a specific time span?
For example if something would take almost 'forever', is there a way to find out the highest possible number to be calculated under 1 minute?
Here is the code:
def fibonacci5(n):
f1, f2 = 1, 0
while n > 0:
f1, f2 = f1 + f2, f1
n -= 1
return f2
I am trying to use the possible solution for finding the number that takes 1 second via timeit.
repeats = 10
t = timeit.Timer("fibonacci5(500000)", globals=globals())
time = t.timeit(repeats)
print ("average execution time:", time/repeats)
But 500.000 takes on average 2,6s, while 250.000 takes on average 0,6s - so that solution can't work.
you could add a timer to your function to make it stop after a given time:
from datetime import datetime, timedelta
max_runtime = timedelta(seconds=1)
def fibonacci5(n):
stop_time = datetime.now() + max_runtime
f1, f2 = 1, 0
while n > 0:
f1, f2 = f1 + f2, f1
n -= 1
if datetime.now() > stop_time:
return f2, 'timelimit reached'
return f2
note that if it returns when the time has run out that it will not just return a number, but a tuple with the number and the string 'timelimit reached'. that way you can differentiate between normal termination and timeout (there may be better ways to handle that...).
the caveat here is that the if line (at least as long as your ints are still very small) is probably the line of the function that takes up the most amount of time... the results will therefore not represent the actual run-times very exactly...
also note that there are way more efficient ways to calculate fibonacci numbers.
if we write Fibonacci sequence generator like
def fibonacci():
a, b = 0, 1
while True:
yield b
a, b = b, a + b
it looks naive but works fast enough, e.g. if you need 500000th Fibonacci number we can use itertools.islice
from itertools import islice
fibonacci_500000 = next(islice(fibonacci(), 500000, 500001))
print(fibonacci_500000)
which took about 5 seconds on my old machine, output is too big to insert, but it looks like
47821988144175...more digits here...2756008390626
but if you really need to find out which value we've calculated after some time – we can use timedelta and datetime objects like
from datetime import datetime, timedelta
def fibonacci():
a, b = 0, 1
while True:
yield b
a, b = b, a + b
if __name__ == '__main__':
duration = timedelta(seconds=5)
fibonacci_numbers = fibonacci()
stop = datetime.now() + duration
for index, number in enumerate(fibonacci_numbers, start=1):
if datetime.now() >= stop:
break
print(index)
which gives us 505352th Fibonacci number calculated after approximately 5 seconds (we can also print number, but it is too long)
I am trying to write a program that writes my hyp_ft variable (continuously streamed once every second) to a text file, waits until 60 lines (1 minute) have been written, averages those 60 values, and then clears the text file and repeats.
I found some code from another post here and tried to incorporate this into mine, with an added if statement.
Calculating average of the numbers in a .txt file using Python
Can someone look at this for me and tell me if this is correct? Thank you!
hyp_ft = (hyp_m*3.2800839) #hyp_ft is the value that is constantly publishing
f = open( 'hyp_ft.txt', 'a' )
f.write(str(hyp_ft) + '\n' )
f.close()
while 1:
with open('hyp_ft.txt') as fh:
sum = 0 # initialize here, outside the loop
count = 0 # and a line counter
for line in fh:
count += 1 # increment the counter
if count == 59
sum += float(line) #convert the lines to floats
average = sum / count
print average
fh.truncate()
fh.close()
You are missing time.sleep() function that might be the issue to your problem, try as:
import time
f = open( 'hyp_ft.txt', 'a' )
count = 0
while True:
#hyp_ft is the value that is constantly publishing
hyp_ft = (hyp_m*3.2800839)
# first time creating the file if it doesnt exists
f.write(str(hyp_ft) + '\n' )
count += 1
if count == 60:
f.close()
with open('hyp_ft.txt') as fh:
total = 0 # initialize here, outside the loop
for line in fh:
total += float(line) #convert the lines to floats
average = total / (count) # as your count is still 59 not 60 what you actually want
print average
fh.truncate()
fh.close()
count = 0
f = open( 'hyp_ft.txt', 'a' )
Here is the updated solution where you are continuously updating the value to the file updating the count value and as soon as you reach 60 if calculates the average and prints the value and continue doing the same.
And assuming you don't need the usage of this file outside of this code there is no need to create one, you can simply do something like:
def calc_distance(gps1, gps2):
count = 0
total = 0
while True:
gps1_lat = round(gps1.latitude, 6)
gps1_lon = round(gps1.longitude, 6)
gps2_lat = round(gps2.latitude, 6)
gps2_lon = round(gps2.longitude, 6)
delta_lat = (gps1_lat*(108000) - gps2_lat*(108000))
delta_lon = (gps1_lon*(108000) - gps2_lon*(108000))
hyp_m = (delta_lat**2 + delta_lon**2)**0.5
hyp_ft = (hyp_m*3.2800839)
total += hyp_ft
pub = rospy.Publisher("gps_dist", Float32, queue_size=10)
rate = rospy.Rate(1)
rospy.loginfo("Distance is %s in ft.", hyp_ft)
# rospy.loginfo(hyp_ft)
pub.publish(hyp_ft)
rate.sleep()
count += 1
if(count == 60):
print (total/count)
total = 0
count = 0
this is much efficient, check if this helps
#warl0ck here is the entire function. What's happening here is that I'm trying to get GPS latitude and longitude values to calculate the distance between two GPS coordinates. It makes one calculation once every second and gives me the hyp_ft value. I'm trying to write 60 hyp_ft values, take the average of those 60 values, then clear the file and continue doing that for the next 60 values, repeatedly. As for the rospy lines, those are from the Robot Operating System (ROS) framework that this code uses to help it run.
When I run the code, it only saves the hyp_ft value, then after 60 seconds it gives me this error.
The error that I'm getting is:
fh.truncate()
"I/O operation on closed file"
def calc_distance(gps1, gps2):
while 1:
gps1_lat = round(gps1.latitude, 6)
gps1_lon = round(gps1.longitude, 6)
gps2_lat = round(gps2.latitude, 6)
gps2_lon = round(gps2.longitude, 6)
delta_lat = (gps1_lat*(108000) - gps2_lat*(108000))
delta_lon = (gps1_lon*(108000) - gps2_lon*(108000))
hyp_m = (delta_lat**2 + delta_lon**2)**0.5
hyp_ft = (hyp_m*3.2800839)
f = open( 'hyp_ft.txt', 'a' )
try:
f.write(str(hyp_ft) + '\n' )
finally:
f.close()
pub = rospy.Publisher("gps_dist", Float32, queue_size=10)
rate = rospy.Rate(1)
rospy.loginfo("Distance is %s in ft.", hyp_ft)
# rospy.loginfo(hyp_ft)
pub.publish(hyp_ft)
rate.sleep()
while True:
time.sleep(60)
with open('hyp_ft.txt') as fh:
sum = 0 # initialize here, outside the loop
count = 0 # and a line counter
for line in fh:
count += 1 # increment the counter
if count == 60:
sum += float(line) #convert the lines to floats
break # to come out of the for loop
average = sum / count
print average
fh.truncate()
fh.close()``
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 !
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
I found this python script which seems to do the job, but I don't know if it is really correct and I can't explain myself that 100- in the last lines.
Theory behind it is clear: you sum up user,system and i/o time spent by the cpu, and you divide it for the same sum plus the idle time. This would give you a % of the cpu load.
I don't need a 100% accurate measurement, but just some hint about the real %cpu usage.
import time
TIMEFORMAT = "%m/%d/%y %H:%M:%S"
INTERVAL = 2
def getTimeList():
statFile = file("/proc/stat", "r")
timeList = statFile.readline().split(" ")[2:6]
statFile.close()
for i in range(len(timeList)) :
timeList[i] = int(timeList[i])
return timeList
def deltaTime(interval) :
x = getTimeList()
time.sleep(interval)
y = getTimeList()
for i in range(len(x)) :
y[i] -= x[i]
return y
if __name__ == "__main__" :
while True :
dt = deltaTime(INTERVAL)
timeStamp = time.strftime(TIMEFORMAT)
cpuPct = 100 - (dt[len(dt) - 1] * 100.00 / sum(dt)) #why 100 - ?
print timeStamp + "\t" + str('%.4f' %cpuPct)
The 100 is 100%. The expression yields time idle, you want time busy. Subtract from 100.