Sun, 17 Sep 2017 20:50:07 +0300
Pöö 2
#!/usr/bin/env python3 from configparser import ConfigParser replacements = { "ylioppilaskylä-itä": "ylioppilaskylä", "ylioppilaskylä-länsi": "ylioppilaskylä", "jokila": "lieto", "piispala": "lieto", 'saaro': 'ruissalo', 'silvola': 'vahto', 'hemmola': 'vahto', 'paasniittu': 'ruskon keskusta', 'kahari': 'ruskon keskusta', 'kemiö': 'kemiönsaari', 'kasnäs': 'kemiönsaari', 'pernon telakka': 'perno', 'paimion sairaala': 'paimio', 'hanhijoki': 'paimio', } # nimiä joista voidaan joustaa tarvittaessa abbreviations = { 'raision keskusta': 'raisio', 'ruskon keskusta': 'rusko', 'naantalin keskusta': 'naantali', 'kaarinan keskusta': 'kaarina', 'kauppakeskus mylly': 'mylly', } region_info = ConfigParser() region_info.read('regions.ini') municipalities = set(region_info.sections()) municipalities_per_region = {} for municipality in municipalities: for region in region_info[municipality].keys(): municipalities_per_region[region] = municipality for place_from, place_to in replacements.items(): municipalities_per_region[place_to] = municipalities_per_region[place_from] def simplify_name(name): name = replacements.get(name, name) name = abbreviations.get(name, name) return name def reduce_schedule(reitti, trip_length, whole = False): length = ((trip_length / 600) * 3 + len(reitti) * 2) / 5 if not reitti: return '' 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 priorities = { 'ihala': 150, 'kauppakeskus mylly': 200, 'kuninkoja': 80, 'moikoinen': 80, 'raision keskusta': 150, 'kukola': 50, 'kaistarniemi': 50, 'papinsaari': 50, 'oriniemi': 50, 'pikisaari': 50, 'häppilä': 20, 'haarla': 80, 'ylioppilaskylä': 50, 'halinen': 70, 'kakskerta': 200, 'pansio': 50, 'räntämäki': 10, 'verkahovi': 20, 'skanssi': 200, 'vaala': 20, 'varissuo': 60, 'kohmo': 80, 'kupittaa': 70, 'kupittaa as': 120, 'kauppatori': 1e15, 'lentoasema': 50, 'runosmäki': 50, 'lieto': 100, 'lieto as': 200, 'ilmarinen': 50, 'vahto': 50, 'ruskon keskusta': 200, 'oriketo': 60, 'harittu': 40, 'jäkärlä': 80, 'moisio': 100, 'paattinen': 100, 'kaarinan keskusta': 200, 'naantalin keskusta': 200, 'uittamo': 50, 'piikkiö': 100, 'paimio': 100, 'pargas': 100, 'nagu': 100, 'yli-maaria': 60, '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, #'rautatieasema': 50, 'logomo': 100, 'rymättylä': 50, "sauvo": 500, "kemiönsaari": 500, 'suovuori': 300, 'eerikvalla': 50, 'petäsmäki': 50, 'tortinmäki': 50, 'aura': 100, 'friskala': -1, 'merimasku': 50, 'turkuhalli': 100, 'messukeskus': 100, 'naantalin pikatie': 150, 'helsingin valtatie': 500, } if 'kauppatori' not in reitti: priorities['länsikeskus'] = priorities['skanssi'] = priorities['kauppatori'] from_place = reitti[0] destination = reitti[-1] reitti_arvot = {} f = lambda i: i**-0.3 factor = 1 / max(f(i + 1) for i in range(len(reitti))) while priorities.get(reitti[-1], 0) < 0: del reitti[-1] destination = reitti[-1] for i, stop in enumerate(reitti): # muunna indeksi siten että myöhemmät alueet korostuvat i = f(i + 1) * factor # ota prioriteetti huomioon, jotkin alueet ovat tärkeämpiä kyltissä kuin toiset i *= priorities.get(stop, 1) reitti_arvot[stop] = i # nollaa lähtöpaikan arvo ettei se mitenkään tule kylttiin if from_place in reitti_arvot: reitti_arvot[from_place] = 0 # varmista että destination tulee kylttiin reitti_arvot[destination] = 1e10 # muodosta sign-tiedot järjestettynä reittiarvon mukaan weights = sorted([ (stop, reitti_arvot[stop], i) \ for i, stop in enumerate(reitti) \ if reitti_arvot[stop] >= 1 ], key = lambda stop: -stop[1]) # enintään neljä tulee kylttiin weights = weights[:3] # jos kolmas kylttiarvo ei ole tarpeeksi merkittävä suhteessa reitin pituuteen niin otetaan se pois try: if weights[2][0] != destination and weights[2][1] < (725 / length ** 0.8): del weights[2] except IndexError: pass try: if weights[1][0] != destination and weights[1][1] < (500 / length ** 1.15): del weights[1] except IndexError: pass # lajitellaan painoarvot uudestaan reittijärjestykseen jotta sign tulee oikeinpäin weights = sorted(weights, key = lambda weight_data: weight_data[2]) # muodostetaan sign.. sign = [paino[0] for paino in weights] to_place = sign[-1] nearby_municipalities = {'Turku', 'Raisio', 'Naantali', 'Kaarina', 'Lieto'} if from_place != to_place: municipality_from = municipalities_per_region.get(from_place) municipality_to = municipalities_per_region.get(to_place) if municipality_from and municipality_to and municipality_from not in nearby_municipalities | {municipality_to} and municipality_to not in nearby_municipalities: def convert_region(region): municipality = municipalities_per_region.get(region, region) if municipality != municipality_from: return municipality else: return region sign = [convert_region(region) for region in sign] # supista nimet tarvittaessa if len(' - '.join(sign)) > 20: sign = [abbreviations.get(place, place) for place in sign] old_sign = sign.copy() sign = [] for place in old_sign: if place not in sign: sign.append(place) if whole: sign = [from_place] + sign if not sign: sign = [destination] return sign