#! /usr/bin/env python3
# -*- coding: utf-8 -*-

# Autor : František Bártík (www.frantisekbartik.cz)
# Vytvořeno pro magazín Linuxexpres (www.linuxexpres.cz)
# Správné použití:  první argument - umístění vstupního souboru, druhý argument - umístění výstupního souboru

"""
V současnosti se používá jak starší Python 2.x, tak novější Python 3.x. Poznámky k skriptu z hlediska kompatibility řad 2.x a 3.x:

   * Python 3.x chápe print jako funkci. Python 3.x vyžaduje uzávorkování argumentu print. Python 2.x nechápe print jako funkci, neuzávorkovává argument.
   * Python 3.x chápe filter jako konstruktor iterátoru. Python 2.x rovnou stanoví prvky, jež poskytuje iterátor z Pythonu 3.x.
   * Python 3.x zná jen řetězce v UTF-kódování. Python 2.x rozeznává mezi UTF-řetězce jako speciální typ vyznačený prefixem u. Řetězec u"ů" chápe jako jednoznakový UTF-řetězec obsahující písmeno ů, neprefixovaný řetězec "ů" chápe jako bytestring s hodnotami bytů 192 a 172, tedy dvouznakový řetězec. (Česká spřežka ch se kóduje v obou případech dvěma znaky.)
   * Funkce codecs.open a codecs.write se podobají impelementacím klíčových slov open a write pouze v Pythonu 3.x. Funkce open a write z Pythonu 2.x lze úspěšně užít jen u binárních a ASCI souborů. 

Ke konverzi kódu mezi oběma verzemi slouží známé utility (např. py2to3).
"""

# Přečtení argumentů z příkazové řádky
import sys
try:
 vstup = sys.argv[1]
 vystup = sys.argv[2]
except:
 print("Správné použití:")
 print("   první argument - umístění vstupního souboru")
 print("   druhý argument - umístění výstupního souboru")
 print("Nezapisujte cestu do domovského adresáře vlnovkou \"~\".")
 sys.exit()

import codecs
f = codecs.open(vstup, encoding="utf-8")
text = ""
# Funkce print vypisuje řetězec do standardního výstupu. (Není-li výstup přesměrovaný, vypisuje se na terminál.)
print("Čtu vstupní soubor...")
for radka in f:
 text = text + " " + radka
f.close()
print("Vstupní soubor přečten (celkem " + str(len(text)) + " znaků).")

import re
print("Převádím na malá písmena...")
text = text.lower()
print("Odstraňuji nepísmenné znaky...")
text = re.sub("[^a-záčďéěíňóřšťúůýž]", " ", text)
print("Rozděluji text na jednotlivá slova...")
slova = text.split(" ")
print("Text byl rozdělen na jednotlivá slova (celkem " + str(len(slova)) + " slov),...")
slova = set(slova)
print("...z toho je " + str(len(slova)) + " slov jedinečných,...")
slova = filter(lambda x: len(x)>4, slova)
#Bez přetypování iterátoru na množinu nelze vypsat počet slov (výraz len(slova)). V Pythonu 2.x není přetypování potřeba.
slova = set(slova)
print("...z toho je " + str(len(slova)) + " slov alespoň pětiznakových.")

print("Konstruuji slovník s \"žolíkovými\" řetězci,...")
retezce = {}
for slovo in slova:
 for x in range(len(slovo) + 1):
  retezce[slovo[0:x] + " " + slovo[x:]] = set(["prazdny_retezec"])
print("...hotovy všechny substituce prázdným řetězcem (celkem " + str(len(retezce)) + " klíčů),...")
for x in [1,2,3,4,5]:
 for a in slova:
  for y in range(len(a) + 1 - x):
   try:
    retezce[a[0:y] + " " + a[y+x:]].add(a[y:y+x])
   except:
    retezce[a[0:y] + " " + a[y+x:]] = set([a[y:y+x]])
 print("...hotovy všechny substituce řetězců do délky " + str(x) + " (celkem " + str(len(retezce)) + " klíčů),...")
print("...slovník je zkonstruovaný.")

print("Počítám četnost morfů...")
cetnost_morfu = {}
for vyraz in retezce:
 if len(retezce[vyraz]) > 1:
  for morf in retezce[vyraz]:
   try:
    cetnost_morfu[morf] = cetnost_morfu[morf] + 1
   except:
    cetnost_morfu[morf] = 1
print("Vybírám dvě stě nejčetnějších morfů...")
nejcetnejsi_morfy = sorted(cetnost_morfu, key = lambda x: -cetnost_morfu[x])[0:200]

print("Otevírám výstupní soubor...")
f = codecs.open(vystup, "w", encoding="utf-8")
print("Zapisuji do výstupního souboru...")
for klic in retezce:
 vybrane = retezce[klic].intersection(nejcetnejsi_morfy)
 for x in vybrane:
  for y in vybrane:
   if x>y:
    f.write(x + "," + y + "\n")
f.close()
print("Zpracování úspěšně dokončeno.")
