#quote from 'introduction to computation and programming
#using Python, revised, MIT press'
import random
def stdDev(X):
mean = sum(X)/len(X)
tot = 0.0
for x in X:
tot += (x-mean)**2
return (tot/len(X))**0.5
def CV(X):
mean = sum(X)/len(X)
return stdDev(X)/mean
class Location(object):
def __init__(self, x, y):
"""x and y are floats"""
self.x = x
self.y = y
def move(self, deltaX, deltaY):
"""deltaX and deltaY are floats"""
return Location(self.x + deltaX, self.y + deltaY)
def getX(self):
return self.x
def getY(self):
return self.y
def distFrom(self, other):
ox = other.x
oy = other.y
xDist = self.x - ox
yDist = self.y - oy
return (xDist**2 + yDist**2)**0.5
def __str__(self):
return '<' + str(self.x) + ', ' + str(self.y) + '>'
class Field(object):
def __init__(self):
self.drunks = {}
def addDrunk(self, drunk, loc):
if drunk in self.drunks:
raise ValueError('Duplicate drunk')
else:
self.drunks[drunk] = loc
def moveDrunk(self, drunk):
if drunk not in self.drunks:
raise ValueError('Drunk not in field')
xDist, yDist = drunk.takeStep()
currentLocation = self.drunks[drunk]
#use move method of Location to get new location
self.drunks[drunk] = currentLocation.move(xDist, yDist)
def getLoc(self, drunk):
if drunk not in self.drunks:
raise ValueError('Drunk not in field')
return self.drunks[drunk]
class Drunk(object):
def __init__(self, name = None):
"""Assumes name is a str"""
self.name = name
def __str__(self):
if self != None:
return self.name
return 'Anonymous'
class UsualDrunk(Drunk):
def takeStep(self):
stepChoices = [(0.0, 1.0), (0.0, -1.0), (1.0, 0.0), (-1.0, 0.0)]
return random.choice(stepChoices)
def walk(f, d, numSteps):
"""Assumes: f a field, d a Drunk in f, and numSteps an int >= 0.
Moves d numSteps times, and returns the difference between
the final location and the location at the start of the walk."""
start = f.getLoc(d)
for s in range(numSteps):
f.moveDrunk(d)
return start.distFrom(f.getLoc(d))
def simWalks(numSteps, numTrials, dClass):
"""Assumes numSteps an int >= 0, numTrials an int > 0,
dClass a subclass of Drunk
Simulates numTrials walks of numSteps steps each.
Returns a list of the final distances for each trial"""
Homer = dClass()
origin = Location(0.0, 0.0)
distances = []
for t in range(numTrials):
f = Field()
f.addDrunk(Homer, origin)
distances.append(walk(f, Homer, numSteps))
return distances
def drunkTest(walkLengths, numTrials, dClass):
"""Assumes walkLengths a sequence of ints >= 0
numTrials and int > 0, dClass a subclass of Drunk
For each number of steps in walkLengths, runs simWalk with
numTrials walks and prints results"""
for numSteps in walkLengths:
distances = simWalks(numSteps, numTrials, dClass)
print dClass.__name__, 'random walk of', numSteps, 'steps'
print ' Mean =', sum(distances)/len(distances),\
'CV =', CV(distances)
print ' Max =', max(distances), 'Min =', min(distances)
drunkTest((10, 100, 1000, 10000), 100, UsualDrunk)
%run "C:\Users\Administrator\test.py"UsualDrunk random walk of 10 steps
Mean = 2.53406018714 CV = 0.606044622899
Max = 6.32455532034 Min = 0.0
UsualDrunk random walk of 100 steps
Mean = 9.1303520316 CV = 0.504488309002
Max = 20.0 Min = 0.0
UsualDrunk random walk of 1000 steps
Mean = 28.2648152173 CV = 0.48577238125
Max = 64.88451279 Min = 1.41421356237
UsualDrunk random walk of 10000 steps
Mean = 89.18140116 CV = 0.527296885645
Max = 232.206804379 Min = 13.0384048104