Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
| Download

📚 The CoCalc Library - books, templates and other resources

Views: 96165
License: OTHER
1
#!/usr/bin/python
2
3
"""This file contains code for use with "Think Bayes",
4
by Allen B. Downey, available from greenteapress.com
5
6
Copyright 2013 Allen B. Downey
7
License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
8
"""
9
10
import csv
11
import json
12
import numpy
13
import os
14
import sys
15
import redis
16
import urllib2
17
18
from datetime import datetime, time
19
20
from time import sleep
21
22
23
class Redis(object):
24
"""Provides access to a Redis instance on Redis To Go"""
25
26
host = 'dory.redistogo.com'
27
port = 10534
28
29
def __init__(self):
30
try:
31
password = os.environ['REDIS_AUTH']
32
except KeyError:
33
print 'Environment variable REDIS_AUTH is not set.'
34
sys.exit()
35
36
self.r = redis.StrictRedis(host=self.host,
37
port=self.port,
38
password=password,
39
db=0)
40
41
def WriteTrainSpotting(self, timestamp, tripid, seconds, live=True):
42
"""Writes a trainspotting event to the database.
43
44
timestamp: int seconds since epoch
45
tripid: string unique id
46
seconds: int how many seconds away the train is
47
live: boolean, whether to actually write the data
48
"""
49
dt = datetime.fromtimestamp(timestamp)
50
day = dt.date().isoformat()
51
52
print dt, tripid, seconds, timestamp
53
54
if live:
55
self.r.sadd('days', day)
56
self.r.sadd(day, tripid)
57
self.r.zadd(tripid, seconds, timestamp)
58
59
def FindArrivals(self, start_hour=16, end_hour=18):
60
"""For each trip, find the best estimate of the arrival time.
61
62
start_hour: int 0-24, beginning of observation window
63
end_hour: int 0-24, end of window
64
65
Returns: map from string day to unsorted list of arrival datetimes
66
"""
67
days = self.r.smembers('days')
68
print days
69
70
start_time = time(hour=start_hour)
71
end_time = time(hour=end_hour)
72
73
arrival_map = {}
74
75
for day in days:
76
tripids = self.r.smembers(day)
77
78
for tripid in tripids:
79
pred_dt = self.GetPredictedArrival(tripid)
80
pred_time = pred_dt.time()
81
82
if start_time < pred_time < end_time:
83
arrival_map.setdefault(day, []).append(pred_dt)
84
85
return arrival_map
86
87
def GetPredictedArrival(self, tripid):
88
"""Gets the best predicted arrival time for a given trip.
89
90
tripid: string TripID like R98313D88
91
"""
92
pair = self.r.zrange(tripid, 0, 1, withscores=True)
93
timestamp, seconds = pair[0]
94
pred_ts = float(timestamp) + seconds
95
pred_dt = datetime.fromtimestamp(pred_ts)
96
return pred_dt
97
98
class TrainSpotting(object):
99
"""Represents one observation of a train."""
100
101
def __init__(self, t):
102
self.timestamp = int(t[0])
103
self.tripid = t[2]
104
self.seconds = int(t[6])
105
106
107
def ReadCsv(url = 'http://developer.mbta.com/lib/rthr/red.csv'):
108
"""Reads data from the red line.
109
110
Returns: list of TrainSpotting objects
111
"""
112
fp = urllib2.urlopen(url)
113
reader = csv.reader(fp)
114
115
tss = []
116
for t in reader:
117
if t[5] != 'Kendall/MIT': continue
118
if t[3] != 'Braintree': continue
119
120
ts = TrainSpotting(t)
121
tss.append(ts)
122
123
fp.close()
124
return tss
125
126
127
def ReadJson():
128
url = 'http://developer.mbta.com/lib/rthr/red.json'
129
json_text = urllib2.urlopen(url).read()
130
json_obj = json.loads(json_text)
131
print json_obj
132
133
134
def ReadAndStore(red):
135
"""Read data from the MBTA and put it in the database.
136
137
red: Redis object
138
"""
139
tss = ReadCsv()
140
for ts in tss:
141
red.WriteTrainSpotting(ts.timestamp, ts.tripid, ts.seconds)
142
143
144
def Loop(red, start_time, end_time, delay=60):
145
"""Collects data from start_time until end_time.
146
147
red: Redis object to store data
148
start_time: datetime
149
end_time: datetime
150
delay: time to sleep between collections, in seconds
151
"""
152
if datetime.now() < start_time:
153
diff = start_time - datetime.now()
154
print 'Sleeping', diff
155
sleep(diff.total_seconds())
156
157
while datetime.now() < end_time:
158
print 'Collecting'
159
ReadAndStore(red)
160
sleep(delay)
161
162
163
def TodayAt(hour):
164
"""Makes a datetime object with today's date and the given time.
165
166
hour: int 0-24
167
"""
168
now = datetime.now()
169
return datetime.combine(now, time(hour=hour))
170
171
172
def GetInterarrivals(arrival_map):
173
"""Finds all interarrival times in the arrival map.
174
175
arrival_map: map from string day to unsorted list of arrival datetimes
176
177
Returns: list of float interarrival times in seconds
178
"""
179
interarrival_seconds = []
180
for day, arrivals in sorted(arrival_map.iteritems()):
181
print day, len(arrivals)
182
arrivals.sort()
183
diffs = numpy.diff(arrivals)
184
diffs = [diff.total_seconds() for diff in diffs]
185
interarrival_seconds.extend(diffs)
186
187
return interarrival_seconds
188
189
190
def main(script, command='collect'):
191
red = Redis()
192
193
if command == 'collect':
194
start = TodayAt(16)
195
end = TodayAt(18)
196
197
print start, end
198
Loop(red, start, end)
199
200
elif command == 'report':
201
arrival_map = red.FindArrivals()
202
interarrivals = GetInterarrivals(arrival_map)
203
print repr(interarrivals)
204
205
206
if __name__ == '__main__':
207
main(*sys.argv)
208
209