#!/usr/bin/env python
# coding: utf-8

# In[ ]:


filename = input('Saisissez un fichier conll:\n> ')
patterns = input("Saisissez les motifs (séparés par une virgule): ")

# on récupère les patrons saisis et on initialise le dictionnaire
patterns_list = patterns.split(',')
pattern_dico = {}

# on crée une entrée pour chaque patron
for pattern in patterns_list:
    pattern_dico[pattern] = []

# on lit le fichier et on sépare les phrases
with open(filename, 'r', encoding = 'utf-8', newline = '\n') as fichier:
    contenu = fichier.read()
    
phrase_liste = contenu.split('\n\n')
phrase_liste.pop()

# on traite toujours phrase par phrase
for phrase in phrase_liste:
    lignes = phrase.split('\n')
    # on filtre les commentaires
    mots = list(filter(lambda x: x and x.startswith("#") is False, lignes))
    
    # on initialise les listes tokens et tags
    tokens = []
    tags = []
    
    # on analyse chaque ligne de tableau et on met à jour les listes
    for mot in mots:
        champs = mot.split('\t')
        tokens.append(champs[1])
        tags.append(champs[3])
        
    # on transforme la liste tags en une chaîne de caractères
    tags_str = " ".join(tags)
    
    # pour chaque patron enregistré dans patterns_list
    for pattern in patterns_list:
        # si on trouve une suite identique au patron
        if pattern in tags_str:
            # on calcule la longueur du patron
            num = len(pattern.split(" "))
            
            # on génère les listes de n-gram token (n_grams) et tag (n_pos) en fonction de la longueur du patron
            n_grams = []
            n_pos = []
            for i in range(0, len(tags) - num + 1):
                n_grams.append(" ".join(tokens[i:i+num]))
                n_pos.append(" ".join(tags[i:i+num]))

            # on initialise un compteur comme ancre de recherche
            start_i = 0
            
            while True:
                try:
                    # on récupère l'index du patron dans n_pos et on prend le n-gram correspondant dans n_grams
                    pos_i = n_pos.index(pattern, start_i)
                    pattern_dico[pattern].append(n_grams[pos_i])
                    start_i = pos_i + 2
                except:
                    break

# on écrit le résultat dans le fichier de sortie
with open('sortie_non_trie.txt', 'w', encoding = 'utf-8', newline = '\n') as sortie:
    for pattern, patrons in pattern_dico.items():
        tmp = list(map(lambda x: sortie.write(x + '\n'), patrons))
        sortie.write('\n\n')

# on initialise le compteur
# à noter qu'il compte le nombre total des patrons trouvés, sans distinction entre les patterns
countresult = 0

# pour chaque entrée dans patrons_dico
for pattern, patrons in pattern_dico.items():
    # on inisitalise un dictionnaire temporaire
    tmp = {}
    for patron in patrons:
        # on compte le nombre d'occurrences de chaque patron
        try:
            tmp[patron] += 1
        except KeyError:
            tmp[patron] = 1

    # on trie les entrées
    tmplist = sorted(tmp.items(), key=lambda x: x[1], reverse=True)
    # on met à jour le compteur
    countresult += len(patrons)
    # on met à jour le dictionnaire
    pattern_dico[pattern] = tmplist
    
with open('sortie_trie.txt', 'w', encoding = 'utf-8', newline = '\n') as sortie:
    sortie.write('{} éléments trouvés\n'.format(countresult))
    for pattern, patrons in pattern_dico.items():
        sortie.write("Type de pattern: {}\n".format(pattern))
        tmp = list(map(lambda x: sortie.write(x + '\n'), patrons))
        sortie.write('\n\n')
		
