I'm currently reading physics in the university, and im learning python as a little hobby.
To practise both at the same time, i figured I'll write a little "physics engine" that calculates the movement of an object based on x,y and z coordinates. Im only gonna return the movement in text (at least for now!) but i want the position updates to be real-time.
To do that i need to update the position of an object, lets say a hundred times a second, and print it back to the screen. So every 10 ms the program prints the current position.
So if the execution of the calculations take 2 ms, then the loop must wait 8ms before it prints and recalculate for the next position.
Whats the best way of constructing a loop like that, and is 100 times a second a fair frequency or would you go slower, like 25 times/sec?
The basic way to wait in python is to
import time and use
time.sleep. Then the question is, how long to sleep? This depends on how you want to handle cases where your loop misses the desired timing. The following implementation tries to catch up to the target interval if it misses.
import time import random def doTimeConsumingStep(N): """ This represents the computational part of your simulation. For the sake of illustration, I've set it up so that it takes a random amount of time which is occasionally longer than the interval you want. """ r = random.random() computationTime = N * (r + 0.2) print("...computing for %f seconds..."%(computationTime,)) time.sleep(computationTime) def timerTest(N=1): repsCompleted = 0 beginningOfTime = time.clock() start = time.clock() goAgainAt = start + N while 1: print("Loop #%d at time %f"%(repsCompleted, time.clock() - beginningOfTime)) repsCompleted += 1 doTimeConsumingStep(N) #If we missed our interval, iterate immediately and increment the target time if time.clock() > goAgainAt: print("Oops, missed an iteration") goAgainAt += N continue #Otherwise, wait for next interval timeToSleep = goAgainAt - time.clock() goAgainAt += N time.sleep(timeToSleep) if __name__ == "__main__": timerTest()
Note that you will miss your desired timing on a normal OS, so things like this are necessary. Note that even with asynchronous frameworks like tulip and twisted you can't guarantee timing on a normal operating system.