From 6fb86bb09690ba436a0fed96ad4e5258674f3e68 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=BCnter=20Milde?= Date: Mon, 20 Apr 2020 10:22:57 +0200 Subject: [PATCH] =?utf8?q?Pr=C3=A4fixextratkion=20und=20Kommandozeilenopti?= =?utf8?q?onen=20f=C3=BCr=20expand=5Fteilwoerter.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * Anwender-Hilfe mit -h * erlaube Konfiguration (siehe -h) * Erstelle Liste von Präfixen * Zur Analyse hilfreiche Kommentare mit -v. --- skripte/python/edit_tools/abgleich_neueintraege.py | 44 ++-- skripte/python/edit_tools/expand_teilwoerter.py | 237 +++++++++++++++++---- 2 files changed, 222 insertions(+), 59 deletions(-) mode change 100644 => 100755 skripte/python/edit_tools/expand_teilwoerter.py diff --git a/skripte/python/edit_tools/abgleich_neueintraege.py b/skripte/python/edit_tools/abgleich_neueintraege.py index a3bcdec..6e2b3a3 100755 --- a/skripte/python/edit_tools/abgleich_neueintraege.py +++ b/skripte/python/edit_tools/abgleich_neueintraege.py @@ -79,7 +79,7 @@ from expand_teilwoerter import expand_words # # :: -def praefixabgleich(key, praefix, words, grossklein=False): +def praefixabgleich(key, praefix, words, grossklein=False, verbose=False): if key.istitle(): praefix = praefix.title() @@ -107,8 +107,9 @@ def praefixabgleich(key, praefix, words, grossklein=False): if wort: wort = '<'.join([praefix, wort.lower()]) entry.append(wort) - - entry.comment = praefix + '< ' + + if verbose: + entry.comment = repr(verbose) + praefix + '< ' return entry # praefixe @@ -431,18 +432,17 @@ praefixe = ['ab', 'über', ] -# Nach Länge sortieren, damit spezifischere zuerst Probiert werden: +# Nach Länge sortieren, damit spezifischere zuerst probiert werden: praefixe.sort(key = len) praefixe.reverse() -# praekeys = [join_word(praefix) for praefix in praefixe] -# + # endungsabgleich() # ~~~~~~~~~~~~~~~~~ # # Übertrag von Einträgen auf Wörter mit anderer Endung: # -# >>> print(endungsabgleich('Füllventile', 'l', '-le', bspwords)) +# >>> print(endungsabgleich('Füllventile', 'l', '-le', bspwords, verbose=True)) # Füllventile;Füll=ven-ti-le # "l"->"-le" # # Das Argument `grossklein` sucht nach Vorkommen mit anderer Großschreibung: @@ -450,19 +450,19 @@ praefixe.reverse() # >>> print(endungsabgleich('Logismus', 'tisch', 'mus', bspwords)) # None # >>> print(endungsabgleich('Logismus', 'tisch', 'mus', bspwords, -# ... grossklein=True)) +# ... grossklein=True, verbose=True)) # Logismus;-2-;Lo-gis-mus;Lo-gi-smus # "tisch"->"mus" # # Vorsicht mit ck und Abkürzungen (jährl. -> jährle); # -# >>> print(endungsabgleich('Achterdecken', 'ck', '-cken', bspwords)) +# >>> print(endungsabgleich('Achterdecken', 'ck', '-cken', bspwords, verbose=True)) # Achterdecken;-2-;Ach-ter=de{ck/k-k}en;Ach-ter=de-cken # "ck"->"-cken" # >>> print(endungsabgleich('jährle', 'l', '-le', bspwords)) # None # # :: -def endungsabgleich(key, alt, neu, words, grossklein=False): +def endungsabgleich(key, alt, neu, words, grossklein=False, verbose=False): if not key.endswith(join_word(neu)): return None @@ -503,7 +503,8 @@ def endungsabgleich(key, alt, neu, words, grossklein=False): return None entry.regelaenderungen() # Sprachabgleich - entry.comment = '"%s"->"%s" ' % (alt, neu) + if verbose: + entry.comment = '"%s"->"%s"' % (alt, neu) return entry @@ -775,7 +776,7 @@ def zerlege(s): # # :: -def trenne_key(key, words, grossklein = False): +def trenne_key(key, words, grossklein = False, verbose=False): entries = [] sep = '=' for k1, k2 in zerlege(key): @@ -818,7 +819,8 @@ def trenne_key(key, words, grossklein = False): entry.append(wort) # Eintrag zusammenfassen und anhängen entry.prune() - entry.comment += '%s + %s ' % (k1, k2) + if verbose: + entry.comment += '%s + %s ' % (k1, k2) entries.append(entry) # Teste auf 3-teilige Composita und entferne die Wichtung: @@ -870,6 +872,8 @@ if __name__ == '__main__': parser.add_option('-i', '--file', dest='wortliste', help='Vergleichsdatei, Vorgabe "%s"'%default_wortliste, default=default_wortliste) + parser.add_option('-v', '--verbose', action='store_true', + help='nur auskommentieren') (options, args) = parser.parse_args() wordfile = WordFile(options.wortliste) @@ -889,16 +893,24 @@ if __name__ == '__main__': # Zusätzliche Teilwörter und Kombinationen (siehe expand_teilwoerter.py) # entweder vom "cache", oder "live" generiert:: - cache = "wortliste-expandiert" + cache_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'cache') + cache = os.path.join(cache_dir, 'wortliste-teile') try: cache_mtime = os.path.getmtime(cache) except OSError: cache_mtime = 0 if os.path.getmtime(options.wortliste) <= cache_mtime: - words.update(WordFile(cache).asdict()) + print(os.path.getmtime(options.wortliste), cache_mtime) + constituents = WordFile(cache).asdict() else: - words.update(expand_words(words)) + constituents = expand_words(words, scope='teile') + cachefile = open(cache, 'w') + for entry in sorted(constituents.values(), key=sortkey_duden): + cachefile.write(str(entry) + '\n') + words.update(constituents) + # Aussortieren von (Teil-) Wörtern, die zu "false positives" führen:: diff --git a/skripte/python/edit_tools/expand_teilwoerter.py b/skripte/python/edit_tools/expand_teilwoerter.py old mode 100644 new mode 100755 index 90da8fe..625d07a --- a/skripte/python/edit_tools/expand_teilwoerter.py +++ b/skripte/python/edit_tools/expand_teilwoerter.py @@ -8,14 +8,17 @@ # Erweitern der Wortliste um Kombinationen von Teilwörtern # ======================================================== # -# Zerlegen von Composita an den Wortfugen und Übernahme der Teile als -# eigenständige Einträge. -# +# :: + +"""Zerlegen von Komposita an den Wortfugen und Übernahme der Teile als + eigenständige Einträge. +""" + # >>> from expand_teilwoerter import * # # :: -import os, re, sys, codecs, copy +import os, re, sys, codecs, copy, optparse from wortliste import (WordFile, WordEntry, join_word, sprachabgleich, toggle_case, sortkey_duden) @@ -54,7 +57,7 @@ from wortliste import (WordFile, WordEntry, join_word, # ['Be[t=t/{tt/tt=t}]uch'] # # Mit `only_new` wird das Eingangswort nicht mit ausgegeben: - +# # >>> list(multisplitter('test', '=', only_new=True)) # [] # >>> list(multisplitter('a=b', '=', True)) @@ -65,7 +68,7 @@ from wortliste import (WordFile, WordEntry, join_word, # ['a=b', 'c=de'] # >>> list(multisplitter('a=b==c=de', '===', True)) # [] - +# # :: def multisplitter(wort, sep, only_new=False): @@ -302,61 +305,71 @@ def split_entry(entry, only_new=False): return [entry] -# Gib ein Dictionary mit Teilwortkombinationen der Liste `entries` -# zurück. + +# Gib ein Dictionary mit Teilwortkombinationen der Liste oder des Dictionaries +# `entries` zurück. # -# Mit `cautious` werden Kombinationen aussortiert, die wahrscheinlich keine -# sinnvollen Einträge für die Wortliste sind: +# Das Argument `scope` bestimmt die Auswahl der gesammelten Wörter: # -# * kürzer als 3 Buchstaben, -# * eingeschobenes "zu" (gegen=zu=halten) -# * Kurzform ohne "-en" (z.B. Ablich, ...) -# * Bindungs-S (z.B. "Ablich, ...) +# * Bindungs-S (z.B. "Ab 1: # eingeschobenes "zu" (gegen=zu=halten) if key.startswith('zu=') or key.endswith('=zu'): continue @@ -373,36 +386,174 @@ def expand_words(entries, cautious=False, only_new=True): # Herkunft festhalten: e.comment = '< ' + str(entry) + e._duplicates = 0 # Entfernen des "Ungünstigkeitsmarkers" nach kurzen Vorsilben: for i in range(1, len(e)): if re.match('..<[.]', e[i]): e[i] = e[i][:3] + e[i][4:] newentries[key] = e + + for entry in newentries.values(): + if entry._duplicates: + entry.comment += ' +%s×' % entry._duplicates + return newentries # def exists(wort): # key = join_word(wort) # return (key.title() in words) or (key.lower() in words) or (len(wort)<4) # +# +# Präfixe bestimmen: +# +# >>> entries = [WordEntry('Vorsilbe;Vor>> for entry in entries: +# ... split_prefix(entry.get('de-1996')) +# 'vor' +# '' +# 'globale' +# 'au-to' +# '' +# +# :: + +def split_prefix(word): + first_word = word.split('=')[0] + parts = first_word.split('<') + if len(parts) == 1: + return '' # keine Vorsilbe + prefix = parts[0].lower() + if '[' in prefix: + return '' # Spezialtrennung/Alternatives -> unsicher + # Entferne Alternativtrennung nach §113 (verblasste Morphologie): + prefix = re.sub('[·-]([^aeiouäöüy])$', r'\1', prefix) + prefix = re.sub('[-]([aeiouäöüy])$', r'·\1', prefix) + return prefix + +# Präfixe sammeln: +# `scope`: +# * alle: alle Teile vom Wortanfang bis "<" +# * nichtwörter: keine Homonyme zu Einträgen in `entries`, +# * wörter: Homonyme zu Einträgen und Teilwörtern. + +# >>> for p in list_prefixes(entries): print(p) +# au-to # < au-to>> list_prefixes(entries, scope='nichtwörter') +# ['globale # < Globale<=vor>> list_prefixes(entries, scope='wörter') +# ['au-to # < au-to