Sat, 10 Jun 2017 20:56:38 +0300
Lisätty bussipysäkkien ryhmittely
#!/usr/bin/env python3 def supista_reitti(reitti, kokonainen = False): def abstract_sign(sign): abstractions = { 'Moikoinen': 'Hirvensalo', 'Maanpää': 'Hirvensalo', 'Papinsaari': 'Hirvensalo', 'Häppilä': 'Hirvensalo', 'Friskala': 'Hirvensalo', 'Kukola': 'Hirvensalo', 'Oriniemi': 'Hirvensalo', 'Haarla': 'Hirvensalo', 'Lauttasaari': 'Hirvensalo', 'Pikisaari': 'Hirvensalo', 'Vienola': 'Pahaniemi', 'Takakirves': 'Kärsämäki', 'Liljalaakso': 'Länsinummi', 'Pernon telakka': 'Perno', } try: start = sign.index('Kauppatori') except ValueError: return sign result = [] for i, place in enumerate(sign): if i >= start: abstract_place = abstractions.get(place, place) if abstract_place not in result: result.append(abstract_place) else: result.append(place) return result if not reitti: return '' kunnat = {'Turku', 'Naantali', 'Lieto', 'Aura', 'Kaarina', 'Pargas', 'Marttila', 'Somero', 'Koski Tl', 'Tarvasjoki'} replacements = { "Ylioppilaskylä-Itä": "Ylioppilaskylä", "Ylioppilaskylä-Länsi": "Ylioppilaskylä", "Caribia": "Ylioppilaskylä", "Jokila": "Lieto", "Piispala": "Lieto", 'Saaro': 'Ruissalo', 'Silvola': 'Vahto', 'Hemmola': 'Vahto', 'Paasniittu': 'Ruskon keskusta', 'Kahari': 'Ruskon keskusta', } have_already = set() i = 0 while i < len(reitti): if reitti[i] in replacements: reitti[i] = replacements[reitti[i]] if reitti[i] in have_already: del reitti[i] else: have_already.add(reitti[i]) i += 1 prioriteetit = { 'Ihala': 150, 'Kauppakeskus Mylly': 200, 'Kuninkoja': 80, 'Moikoinen': 50, 'Raision keskusta': 100, 'Friskala': 20, 'Kukola': 50, 'Kaistarniemi': 50, 'Papinsaari': 50, 'Oriniemi': 50, 'Pikisaari': 50, 'Häppilä': 50, 'Haarla': 50, 'Ylioppilaskylä': 50, 'Halinen': 70, 'Kakskerta': 50, 'Pansio': 50, 'Räntämäki': 10, 'Verkahovi': 20, 'Skanssi': 200, 'Vaala': 20, 'Varissuo': 60, 'Kohmo': 80, 'Kupittaa': 70, 'Kauppatori': 1e15, 'Lentoasema': 50, 'Runosmäki': 50, 'Lieto': 100, 'Liedon asemanseutu': 200, 'Ilmarinen': 50, 'Vahto': 50, 'Ruskon keskusta': 200, 'Oriketo': 30, 'Harittu': 40, 'Jäkärlä': 50, 'Paattinen': 100, 'Kaarinan keskusta': 200, 'Naantalin keskusta': 200, 'Uittamo': 50, 'Piikkiö': 100, 'Paimio': 100, 'Pargas': 50, 'Yli-Maaria': 50, 'Saramäki': 50, 'Tarvasjoki': 100, 'Marttila': 100, 'Koski Tl': 100, 'Katariina': 50, 'Länsikeskus': 50, 'Kaanaa': 100, 'Satava': 50, 'Suikkila': 50, 'Raunistula': 50, 'Räntämäki': 50, 'Moisio': 25, 'Pääskyvuori': 100, } if 'Kauppatori' not in reitti: prioriteetit['Länsikeskus'] = prioriteetit['Skanssi'] = prioriteetit['Kauppatori'] # nimiä joista voidaan joustaa tarvittaessa helpot_supistukset = { 'Raision keskusta': 'Raisio', 'Ruskon keskusta': 'Rusko', 'Naantalin keskusta': 'Naantali', 'Kaarinan keskusta': 'Kaarina', 'Liedon asemanseutu': 'Lieto as.', 'Kauppakeskus Mylly': 'Mylly', } # jos ei nyt millään vaan mahdu muuten... vakavat_supistukset = { 'Kauppatori': 'Tori', 'Ylioppilaskylä': 'Yo-kylä', } lähtö = reitti[0] määränpää = reitti[-1] reitti_arvot = {} f = lambda i: i**-0.6 jakaja = max(f(i + 1) for i in range(len(reitti))) for i, pysäkki in enumerate(reitti): # muunna indeksi siten että myöhemmät alueet korostuvat i = f(i + 1) / jakaja # ota prioriteetti huomioon, jotkin alueet ovat tärkeämpiä kyltissä kuin toiset i *= prioriteetit.get(pysäkki, 1) reitti_arvot[pysäkki] = i # nollaa lähtöpaikan arvo ettei se mitenkään tule kylttiin if lähtö in reitti_arvot: reitti_arvot[lähtö] = 0 # varmista että määränpää tulee kylttiin reitti_arvot[määränpää] = 1e10 # muodosta kyltti-tiedot järjestettynä reittiarvon mukaan painot = sorted([ (pysäkki, reitti_arvot[pysäkki], i) \ for i, pysäkki in enumerate(reitti) \ if reitti_arvot[pysäkki] >= 1 ], key = lambda pysäkki: -pysäkki[1]) # enintään neljä tulee kylttiin painot = painot[:4] # jos neljäs kylttiarvo ei ole tarpeeksi merkittävä suhteessa reitin pituuteen niin otetaan neljäs pois if len(painot) == 4 and painot[3][0] != määränpää and painot[3][1] < (4000 / len(reitti) ** 1.5): del painot[3] # sama kolmannelle if len(painot) == 3 and painot[2][0] != määränpää and painot[2][1] < (500 / len(reitti) ** 1.5): del painot[2] if len(painot) == 2 and painot[1][0] != määränpää and painot[1][1] < (150 / len(reitti) ** 1.5): del painot[1] # lajitellaan painoarvot uudestaan reittijärjestykseen jotta kyltti tulee oikeinpäin painot = sorted(painot, key = lambda paino: paino[2]) # muodostetaan kyltti.. kyltti = [paino[0] for paino in painot] kyltti = abstract_sign(kyltti) # supista nimet jos mahdollista def viimeistele(kyltti, supistus_taso = 0): if supistus_taso > 0: kyltti = [helpot_supistukset.get(paikka, paikka) for paikka in kyltti] if supistus_taso > 1: kyltti = [vakavat_supistukset.get(paikka, paikka) for paikka in kyltti] return kyltti tulos = viimeistele(kyltti) if len(' - '.join(kyltti)) > 20: tulos = viimeistele(kyltti, supistus_taso = 1) if len(' - '.join(kyltti)) > 70: tulos = viimeistele(kyltti, supistus_taso = 2) if kokonainen: tulos = [lähtö] + tulos lyhyt_lähtö = replacements.get(lähtö, lähtö) if lyhyt_lähtö != tulos[-1] and helpot_supistukset.get(lyhyt_lähtö, lyhyt_lähtö) in kunnat | {'Kauppatori'} and tulos[-1] in kunnat | {'Kauppatori'}: tulos = ['Turku' if k == 'Kauppatori' else k for k in tulos] return tulos