-
Notifications
You must be signed in to change notification settings - Fork 0
/
statisticsOfDrunk.py
130 lines (110 loc) · 3.36 KB
/
statisticsOfDrunk.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import random
"""
Using Simulation to find out how far does the drunk reach from it's starting
point (0,0)
Using three abstractions
1) Location
2) Drunk (UsualDrunk, BiasedDrunk)
3) Field
"""
class Location(object):
"""
docstring for Location
"""
def __init__(self, x, y):
"""
used as blueprint to make the Location object
"""
self.x = x
self.y = y
def getX(self):
return self.x
def getY(self):
return self.y
def move(self, deltaX, deltaY):
"""
deltaX -> move on x-axis by deltaX
deltaY -> move on x-axis by deltaY
returns a Location object with new Location
this function makes each location unique and hence
this class is immutable
"""
return Location(deltaX + self.x , deltaY + self.y)
def distBetween(self, other):
"""
returns the distance b/w two locations
"""
return ((self.x - other.getX())**2 +(self.y - other.getY())**2)**0.5
def __str__(self):
return '<' + str(self.x) + ', ' + str(self.y) + '>'
class Drunk(object):
"""
issabase class
"""
def __init__(self,name = None):
self.name = name
def getName(self):
return self.name
def __str__(self):
if self is not None:
return self.name
return 'Anonymous'
class UsualDrunk(Drunk):
def takeStep(self):
x, y = random.choice([ (1,0), (-1,0) , (0,1) , (0,-1) ])
return (x,y)
class MasochistDrunk(Drunk):
def takeStep(self):
stepChoices = [(0.0,1.1), (0.0,-0.9),(1.0, 0.0), (-1.0, 0.0)]
return random.choice(stepChoices)
class Field(object):
"""
The main field where the drunk moves
this has to be mutable because the location
of the drunk changes
"""
def __init__(self):
self.drunks = {}
def addDrunk(self, drunk, loc):
"""
self -> object Field
drunk -> the drunk
loc -> the location where the drunk has to be placed
"""
if drunk in self.drunks:
raise ValueError("Occupied")
else:
self.drunks[drunk] = loc
def getLoc(self, drunk):
if drunk not in self.drunks:
raise ValueError('Drunk not in field')
else:
return self.drunks[drunk]
def moveDrunk(self, drunk):
if drunk not in self.drunks:
raise ValueError("No such Drunk")
else:
x,y = drunk.takeStep()
self.drunks[drunk] = self.drunks[drunk].move(x,y)
def walk(f, d, numSteps):
start = f.getLoc(d)
for step in range(numSteps):
f.moveDrunk(d)
return start.distBetween(f.getLoc(d))
def simWalks(numSteps , numTrials, dClass):
homer = dClass()
origin = Location(0,0)
distances = []
for step in range(numTrials):
f = Field()
f.addDrunk(homer, origin)
distances.append(round(walk(f, homer, numSteps), 1))
return distances
def drunkTest(walkLengths, numTrials, dClass):
for numSteps in walkLengths:
distances = simWalks(numSteps, numTrials,dClass)
print(dClass.__name__, 'random walk of',numSteps, 'steps')
print(' Mean =',round(sum(distances)/len(distances), 4))
print(' Max =', max(distances),'Min =', min(distances))
if __name__ == '__main__':
drunkTest((10, 100, 1000, 10000), 100, UsualDrunk)