From 621db11d423b545a5e885f89b7559202385c3e99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= <vaclav.volhejn@gmail.com>
Date: Mon, 4 Jan 2021 12:36:23 +0100
Subject: [PATCH] Okomentovat

---
 bin/shorten-schools | 102 +++++++++++++++++++++++++-------------------
 1 file changed, 59 insertions(+), 43 deletions(-)

diff --git a/bin/shorten-schools b/bin/shorten-schools
index 62ebc343..6f19ce36 100755
--- a/bin/shorten-schools
+++ b/bin/shorten-schools
@@ -1,10 +1,28 @@
 #!/usr/bin/env python3
-# Zkrátí v databázi oficiální dlouhá jména škol na něco čitelnějšího, uloží
-# do sloupce places.name
+"""
+Zkrátí v databázi oficiální dlouhá jména škol na něco čitelnějšího, uloží
+do sloupce places.name.
+
+Algoritmus se jména snaží dostat do podoby ZKRÁCENÉ_JMÉNO, kde
+ZKRÁCENÉ_JMÉNO = NÁZEV MÍSTO
+NÁZEV = např. "SŠ", "ZŠ T. G. Masaryka", "SPŠ strojnická a SOŠ profesora Švejcara"
+MÍSTO = MĚSTO [ULICE [Č.P.]]
+  např. "Slatinice", "Praha 7", "Olomouc, Svatoplukova"
+
+Může existovat víc možností zkrácení, např.
+    ZŠ a MŠ Olomouc, Svatoplukova 11
+    ZŠ a MŠ Olomouc, Svatoplukova
+    ZŠ a MŠ Olomouc
+Algoritmus vytvoří všechny varianty jmen a pak kontroluje, jestli při použití
+nejkratší varianty ("ZŠ a MŠ Olomouc") nenastane konflikt jmen s jinou školou.
+Pokud ano, zkusí použít pro obě školy delší variantu názvu. Toto se opakuje,
+dokud se konflikty nevyřeší.
+"""
 
 import copy
 import random
 import re
+import sys
 
 from sqlalchemy.orm import aliased
 
@@ -26,10 +44,11 @@ schools = []
 
 for school, place, parent_place in schools_q:
 
+    # Parent má být škola
     assert parent_place.level == 3
-    n = place.name
-    on = school.official_name
-    # assert n == on
+
+    # Toto platí před prvním spuštením skriptu, pak už ne (změníme place.name)
+    # assert place.name == school.official_name
 
     schools.append(
         {
@@ -40,7 +59,8 @@ for school, place, parent_place in schools_q:
         }
     )
 
-schools_orig = copy.deepcopy(schools)
+def eprint(*args, **kwargs):
+    print(*args, file=sys.stderr, **kwargs)
 
 
 def sorted_by_length(schools):
@@ -52,33 +72,32 @@ def sorted_by_length(schools):
 def summarize(schools, k=5):
     lens = [len(sc["names"][-1]) for sc in schools]
     avg_len = sum(lens) / len(schools)
-    print("Average length:", avg_len)
-    print("Maximum length:", max(lens))
+    eprint("Average length:", avg_len)
+    eprint("Maximum length:", max(lens))
 
     names_by_lens = sorted_by_length(schools)
 
-    print()
-    print(f"{k} longest:")
+    eprint()
+    eprint(f"{k} longest:")
     for sc in names_by_lens[::-1][:k]:
-        print(f'{sc["names"][-1]} (@{sc["city"]})')
+        eprint(f'{sc["names"][-1]} (@{sc["city"]})')
 
     random.shuffle(names_by_lens)
-    print()
-    print(f"{k} random:")
+    eprint()
+    eprint(f"{k} random:")
     for sc in names_by_lens[:k]:
-        print(f'Old: {sc["names"][0]}')
-        print(f'{sc["names"][-1]}')
-        print()
+        eprint(f'Old: {sc["names"][0]}')
+        eprint(f'{sc["names"][-1]}')
+        eprint()
 
 
 city_rules = [
-    (r"(\w)-(\w)", r"\1 - \2"),
+    (r"(\w)-(\w)", r"\1 - \2"),  # Mezery kolem pomlček jsou někdy nekonzistentní
     ("Praha", "v Praze"),
     ("v Praze 4", "v Praze 12"),
-    ("v Praze 4", "v Praze 12"),
     (r"v Praze [0-9]+", "v Praze"),
     ("v Praze", "Praha"),
-    None,  # Dummy at the end
+    None,  # Dummy
 ]
 
 school_kinds = [
@@ -119,14 +138,18 @@ def shorten_name(name):
 
 
 def partition(name, city):
+    """Rozdělí název školy na část před názvem města a část po názvu města"""
+
+    # Zkouší drobné úpravy názvu města
     for rule in city_rules:
-        # Eat up rest of the word for cases like "Táborské"
+        # Pro slova jako "Táborské" chceme odstranit i zbytek slova, nejen "Tábor"
         pat = r"\b{}\w*\b".format(city)
+
         if re.search(pat, name) is not None:
             parts = re.split(pat, name)
 
             if len(parts) != 2:
-                # Multiple occurrences of city - what to do?
+                # Název města se vyskytuje víckrát, není jasné, co dělat
                 return None
             else:
                 ok = True
@@ -135,7 +158,8 @@ def partition(name, city):
                         ok = False
 
                 if not ok:
-                    # Part of the school kind follows after city name
+                    # Názvová část školy pokračuje i po názvu města (např. "Táborské gymnázium"),
+                    # nelze automaticky vyřešit
                     return None
                 else:
                     return parts
@@ -143,19 +167,13 @@ def partition(name, city):
         if rule is not None:
             city = re.sub(rule[0], rule[1], city)
 
-    # Failed to find match
+    # Nenašli jsme název města
     return [name]
 
 
-def shorten_in_city(city, schools):
-    for sc in schools:
-        name_p, place_p = sc["parts"]
-        sc["name"] = "|".join([name_p, city, place_p])
-
-
 def remove_house_number(name):
     name, n = re.subn(r"(, ([^\W\d_]| |\.)+) [0-9/]+[a-z]?$", r"\1", name)
-    # True if changed, False if not
+    # True, pokud se název změnil
     return name, n > 0
 
 
@@ -177,7 +195,7 @@ def shorten_all(schools):
         sc["names"].append(remove_formalities(sc["names"][-1]))
         sc["parts"] = partition(sc["names"][-1], sc["city"])
 
-    print("Total schools: {}".format(len(schools)))
+    eprint("Total schools: {}".format(len(schools)))
 
     n_split = 0
 
@@ -185,9 +203,11 @@ def shorten_all(schools):
         sc["names"].append(shorten_name(sc["names"][-1]))
         if sc["parts"] is not None:
             if len(sc["parts"]) == 1:
-                # City name not found in school name
+                # Název města nenalezen v názvu školy
                 sc["names"].append(f"{sc['names'][-1]}, {sc['city']}")
             else:
+                # Když máme rozdělení, můžeme zkusit odstanit číslo popisné
+                # a případně i celý název ulice
                 n_split += 1
                 assert len(sc["parts"]) == 2
 
@@ -206,26 +226,21 @@ def shorten_all(schools):
 
                 sc["names"].append(f"{p_name} {sc['city']}")
 
-    print(f"Successfully split up {n_split} schools")
+    eprint(f"Successfully split up {n_split} schools")
 
     return schools
 
-
-schools = copy.deepcopy(schools_orig)
-shortened = shorten_all(schools)
-
-
 def is_conflict(names1, names2):
     return any([(name in names1) for name in names2])
 
 
 def remove_conflicts(shortened):
-    n_conflicts = 0
+    """Vrátí se k delším variantám jmen, pokud se vyskytly konflikty"""
     again = True
 
     while again:
         shortened.sort(key=lambda sc: sc["names"][-1])
-        print("----------------------------")
+        eprint("----------------------------")
         n_conflicts = 0
         again = False
 
@@ -244,15 +259,16 @@ def remove_conflicts(shortened):
                 assert len(sc["names"]) > 1
                 sc["names"].pop()
 
-        print(f"Found {n_conflicts} conflicts")
+        eprint(f"Found {n_conflicts} conflicts")
 
-    # Hack - fix false positives, we always want to do these changes
+    # Hack - tato zkrácení vždy chceme aplikovat, předpokládáme, že nevzniknou konflikty
     for sc in shortened:
         sc["names"].append(remove_formalities(shorten_name(sc["names"][-1])))
 
-    print("Done (possible unremovable conflicts)")
+    eprint("Done (possible unremovable conflicts)")
 
 
+shortened = shorten_all(schools)
 remove_conflicts(shortened)
 
 summarize(shortened, k=10)
-- 
GitLab