64 self.tunniste, self.nimi, self.sijainti = tunniste, nimi, sijainti |
64 self.tunniste, self.nimi, self.sijainti = tunniste, nimi, sijainti |
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 def __repr__(self): |
67 def __repr__(self): |
68 return 'pysäkit[%r]' % self.tunniste |
68 return 'pysäkit[%r]' % self.tunniste |
69 def aikataulu(self, määrä = 50): |
69 def schedule(self, max_amount = 50): |
70 ''' |
70 ''' |
71 Hakee tämän pysäkin seuraavat `määrä` lähtöä. Päätepysäkille saapuvia busseja ei |
71 Hakee tämän pysäkin seuraavat `määrä` lähtöä. Päätepysäkille saapuvia busseja ei |
72 lasketa. Palauttaa pysähdykset listana jossa alkiot ovat muotoa (aika, pysähdys), |
72 lasketa. Palauttaa pysähdykset listana jossa alkiot ovat muotoa (aika, pysähdys), |
73 jossa: |
73 jossa: |
74 - `aika` on saapumishetki muotoa datetime ja |
74 - `aika` on saapumishetki muotoa datetime ja |
75 - `pysähdys` on vastaava Pysähdys olio. |
75 - `pysähdys` on vastaava Pysähdys olio. |
76 |
76 |
77 Mikäli pysäkille ei ole määrätty riittävästi pysähdyksiä kalenterissa, tuloslista |
77 Mikäli pysäkille ei ole määrätty riittävästi pysähdyksiä kalenterissa, tuloslista |
78 jää alimittaiseksi, mahdollisesti jopa tyhjäksi. |
78 jää alimittaiseksi, mahdollisesti jopa tyhjäksi. |
79 ''' |
79 ''' |
80 class PäivätLoppuError(Exception): |
80 result = [] |
81 pass |
81 date = tänään() |
82 # Hakee pysäkin aikataulut tiettynä päivänä. |
|
83 def aikataulu_päivänä(päivä): |
|
84 # Jos päädyttiin aikataulukalenterin ulkopuolelle, niin tuotetaan virhe. Jos vain |
|
85 # palautettaisiin tyhjä tulos, niin algoritmi jatkaisi etsintää loputtomiin. |
|
86 if päivä > viimeinen_käyttöpäivä: |
|
87 raise PäivätLoppuError() |
|
88 taulu = [] |
|
89 # Jokaiselle ajovuorolle, |
|
90 for ajo in ajot.values(): |
|
91 # jos tämä ajovuoro ajetaan tänä päivänä |
|
92 if ajo.ajetaan_päivänä(päivä): |
|
93 # ja jos tämä ajo pysähtyy tällä pysäkillä, ei kuitenkaan saapuen |
|
94 # päätepysäkille, |
|
95 pysähdys = ajo.pysäkkiReitillä(self) |
|
96 if pysähdys and pysähdys is not ajo.reitti[-1]: |
|
97 # ja jos tämä pysähdys on tulevaisuudessa, |
|
98 aika = datetime.combine(päivä, time()) + pysähdys.saapumisaika |
|
99 if aika >= nyt(): |
|
100 # lisää pysähdys listaan. |
|
101 taulu.append((aika, pysähdys)) |
|
102 # Lajittele lopputulos saapumisajan mukaan. |
|
103 taulu.sort(key = lambda tietue: tietue[0]) |
|
104 return taulu |
|
105 taulu = [] |
|
106 päivä = tänään() |
|
107 # Niin kauan kuin aikatauluja ei ole vielä tarpeeksi, |
82 # Niin kauan kuin aikatauluja ei ole vielä tarpeeksi, |
108 while len(taulu) < määrä: |
83 while len(result) < max_amount: |
109 try: |
84 try: |
110 # hae nykyisen päivän aikataulut ja lisää ne, |
85 # hae nykyisen päivän aikataulut ja lisää ne, |
111 taulu += aikataulu_päivänä(päivä) |
86 result += self.schedule_for_day(date) |
112 except PäivätLoppuError: |
87 except ValueError: |
113 # paitsi jos mentiin kalenterin ulkopuolelle, jolloin lopetetaan, |
88 # paitsi jos mentiin kalenterin ulkopuolelle, jolloin lopetetaan, |
114 break |
89 break |
115 # ja siirry seuraavaan päivään. |
90 # ja siirry seuraavaan päivään. |
116 päivä += timedelta(1) |
91 date += timedelta(1) |
117 # Typistä lopputulos haluttuun tulosmäärään. |
92 # Typistä lopputulos haluttuun tulosmäärään. |
118 return taulu[:määrä] |
93 return result[:max_amount] |
|
94 def schedule_for_day(self, date): |
|
95 ''' |
|
96 Hakee pysäkin aikataulut tiettynä päivänä. |
|
97 ''' |
|
98 # Jos päädyttiin aikataulukalenterin ulkopuolelle, niin tuotetaan virhe. Jos vain |
|
99 # palautettaisiin tyhjä tulos, niin algoritmi jatkaisi etsintää loputtomiin. |
|
100 if date > viimeinen_käyttöpäivä: |
|
101 raise ValueError('tried to retrieve schedule for date %s which is outside schedule data' % date) |
|
102 result = [] |
|
103 # Jokaiselle ajovuorolle, |
|
104 for trip in ajot.values(): |
|
105 # jos tämä ajovuoro ajetaan tänä päivänä |
|
106 if trip.ajetaan_päivänä(date): |
|
107 # ja jos tämä ajo pysähtyy tällä pysäkillä, ei kuitenkaan saapuen |
|
108 # päätepysäkille, |
|
109 stop = trip.pysäkkiReitillä(self) |
|
110 if stop and stop is not trip.reitti[-1]: |
|
111 # ja jos tämä pysähdys on tulevaisuudessa, |
|
112 aika = datetime.combine(date, time()) + stop.saapumisaika |
|
113 if aika >= nyt(): |
|
114 # lisää pysähdys listaan. |
|
115 result.append((aika, stop)) |
|
116 # Lajittele lopputulos saapumisajan mukaan. |
|
117 result.sort(key = lambda entry: entry[0]) |
|
118 return result |
119 @property |
119 @property |
120 def linkki_karttaan(self): |
120 def linkki_karttaan(self): |
121 return 'http://www.openstreetmap.org/#map=19/%f/%f' % (self.sijainti.leveys, self.sijainti.pituus) |
121 return 'http://www.openstreetmap.org/#map=19/%f/%f' % (self.sijainti.leveys, self.sijainti.pituus) |
122 |
122 |
123 class Pysähdys: |
123 class Pysähdys: |