65 self.cluster = None |
65 self.cluster = None |
66 self.pairs = set() # samannimiset lähellä olevat pysäkit |
66 self.pairs = set() # samannimiset lähellä olevat pysäkit |
67 self.involved_trips = set() |
67 self.involved_trips = set() |
68 def __repr__(self): |
68 def __repr__(self): |
69 return 'bus_stops[%r]' % self.reference |
69 return 'bus_stops[%r]' % self.reference |
70 def schedule(self, max_amount = 50): |
70 def schedule(self, *, max_amount = 50, arrivals = False): |
71 ''' |
71 ''' |
72 Hakee tämän pysäkin seuraavat `määrä` lähtöä. Päätepysäkille saapuvia busseja ei |
72 Hakee tämän pysäkin seuraavat `määrä` lähtöä. Päätepysäkille saapuvia busseja ei |
73 lasketa. Palauttaa pysähdykset listana jossa alkiot ovat muotoa (aika, halt), |
73 lasketa. Palauttaa pysähdykset listana jossa alkiot ovat muotoa (aika, halt), |
74 jossa: |
74 jossa: |
75 - `aika` on saapumishetki muotoa datetime ja |
75 - `aika` on saapumishetki muotoa datetime ja |
83 date = today() - timedelta(days = 1) |
83 date = today() - timedelta(days = 1) |
84 # Niin kauan kuin aikatauluja ei ole vielä tarpeeksi, |
84 # Niin kauan kuin aikatauluja ei ole vielä tarpeeksi, |
85 while len(result) < max_amount: |
85 while len(result) < max_amount: |
86 try: |
86 try: |
87 # hae nykyisen päivän aikataulut ja lisää ne, |
87 # hae nykyisen päivän aikataulut ja lisää ne, |
88 result += self.schedule_for_day(date) |
88 result += self.schedule_for_day(date, arrivals = arrivals) |
89 except ValueError: |
89 except ValueError: |
90 # paitsi jos mentiin kalenterin ulkopuolelle, jolloin lopetetaan, |
90 # paitsi jos mentiin kalenterin ulkopuolelle, jolloin lopetetaan, |
91 break |
91 break |
92 # ja siirry seuraavaan päivään. |
92 # ja siirry seuraavaan päivään. |
93 date += timedelta(1) |
93 date += timedelta(1) |
94 # Typistä lopputulos haluttuun tulosmäärään. |
94 # Typistä lopputulos haluttuun tulosmäärään. |
95 return result[:max_amount] |
95 return result[:max_amount] |
96 def schedule_for_day(self, date): |
96 def schedule_for_day(self, date, *, arrivals = False): |
97 ''' |
97 ''' |
98 Hakee pysäkin aikataulut tiettynä päivänä. |
98 Hakee pysäkin aikataulut tiettynä päivänä. |
99 ''' |
99 ''' |
100 # Jos päädyttiin aikataulukalenterin ulkopuolelle, niin tuotetaan virhe. Jos vain |
100 # Jos päädyttiin aikataulukalenterin ulkopuolelle, niin tuotetaan virhe. Jos vain |
101 # palautettaisiin tyhjä result, niin algoritmi jatkaisi etsintää loputtomiin. |
101 # palautettaisiin tyhjä result, niin algoritmi jatkaisi etsintää loputtomiin. |
107 # jos tämä ajovuoro ajetaan tänä päivänä |
107 # jos tämä ajovuoro ajetaan tänä päivänä |
108 if trip.is_served_at(date): |
108 if trip.is_served_at(date): |
109 # ja jos tämä trip pysähtyy tällä pysäkillä, ei kuitenkaan saapuen |
109 # ja jos tämä trip pysähtyy tällä pysäkillä, ei kuitenkaan saapuen |
110 # päätepysäkille, |
110 # päätepysäkille, |
111 stop = trip.contains_stop(self) |
111 stop = trip.contains_stop(self) |
112 if stop and not stop.is_arrival: # stop is not trip.schedule[-1]: |
112 if stop and (arrivals or not stop.is_arrival) and stop is not trip.schedule[-1]: |
113 # ja jos tämä halt on tulevaisuudessa, |
113 # ja jos tämä halt on tulevaisuudessa, |
114 stop_time = datetime.combine(date, time()) + stop.arrival_time |
114 stop_time = datetime.combine(date, time()) + stop.arrival_time |
115 if stop_time >= now(): |
115 if stop_time >= now(): |
116 # lisää halt listaan. |
116 # lisää halt listaan. |
117 result.append({ |
117 result.append({ |
292 for bus_stop in other.stops: |
292 for bus_stop in other.stops: |
293 bus_stop.cluster = self |
293 bus_stop.cluster = self |
294 self.stops |= other.stops |
294 self.stops |= other.stops |
295 other.stops = set() |
295 other.stops = set() |
296 other._center = None |
296 other._center = None |
297 def schedule(self, max_amount = 50): |
297 def schedule(self, *, max_amount = 50): |
298 result = [] |
298 result = [] |
299 for stop in self.stops: |
299 for stop in self.stops: |
300 result += stop.schedule(max_amount) |
300 result += stop.schedule(max_amount = max_amount) |
301 result.sort(key = lambda schedule_entry: schedule_entry['time']) |
301 result.sort(key = lambda schedule_entry: schedule_entry['time']) |
302 return result[:max_amount] |
302 return result[:max_amount] |
303 |
303 |
304 from collections import defaultdict |
304 from collections import defaultdict |
305 bus_stops_by_name = defaultdict(set) |
305 bus_stops_by_name = defaultdict(set) |