import matplotlib.pyplot as plt

#### 1) Liste des mots du fichier :

fichier = 'mots.txt' # remplacer les ... par le nom du dossier contenant le fichier
f = open(fichier)
mots = f.read().split(';')
f.close()

# Combien y a-t-il de mots dans le fichier ?

print(len(mots))


#### 2) Quel est le mot le plus long et combien a-t-il de lettres ?

mot_max = mots[0]
longueur_max = len(mots[0])
for mot in mots:
    if len(mot) > longueur_max:
        longueur_max = len(mot)
        mot_max = mot
print(mot_max, longueur_max)

# ou :

mot_max = max(mots, key=len)
print(mot_max, len(mot_max))


##### 3) Combien de mots de 1 lettre, de 2 lettres, etc. ?

# Dans cette question et les suivantes, on construit des tableaux d'occurrences.
# Cette méthode permet de ne parcourir la liste des mots qu'une seule fois.

nb = [0]*25  # nb[i-1] = nombre de mots de i lettres
for mot in mots:
    nb[len(mot)-1] += 1
for i in range(1, 26):
    print('Il y a', nb[i-1], 'mots de', i, 'lettres')

plt.bar(list(range(1, 26)), nb)
plt.show()

# Avec un dictionnaire :

longueurs = {}
for i in range(1, 26):
    longueurs[i] = 0
for mot in mots:
    longueurs[len(mot)] += 1
print(longueurs)


#### 4) Combien de mots commençant par 'a', par 'b', etc. ?

# Dans cette question et les suivantes, on utilisera ord et chr.

nb = [0]*26  # nb[i] = nombre de mots commençant par la (i+1)ème lettre de l'alphabet
for mot in mots:
    nb[ord(mot[0])-97] += 1
for i in range(26):
    print('Il y a', nb[i], 'mots qui commencent par', chr(i+97))

plt.bar(list('abcdefghijklmnopqrstuvwxyz'),nb)
plt.show()


#### 5) Fréquences des lettres

nb = [0] * 26
for mot in mots:
    for lettre in mot:
        nb[ord(lettre)-97] += 1
for i in range(26):
    print('Fréquence de la lettre', chr(i+97), ':', nb[i]/sum(nb) * 100, '%')

plt.bar(list('abcdefghijklmnopqrstuvwxyz'),nb)
plt.show()


#### 6) Proportions de mots qui contiennent un a, un b, etc.

alphabet = 'abcdefghijklmnopqrstuvwxyz'
nbs = []
n = len(mots)
for lettre in alphabet:
    nb = 0
    for mot in mots:
        if lettre in mot:
            nb += 1
    nbs.append(nb)
    print(nb/n * 100, '% des mots contiennent un', lettre)

plt.bar(list('abcdefghijklmnopqrstuvwxyz'),nbs)
plt.show()


#### 7) Mots contenant un q non suivi d'un u

for mot in mots:
    n = len(mot)
    for i in range(n):
        if mot[i] == 'q' and (i == n-1 or mot[i+1] != 'u'):  # attention aux mots finissant par q
            print(mot)

# Ce qui suit est plus simple mais discutable car il pourrait exister un mot
# contenant à la fois un 'q' sans 'u' et un 'qu'

for mot in mots:
    if 'q' in mot and 'qu' not in mot:
        print(mot)


#### 8) Mots contenant toutes les voyelles

for mot in mots:
    if 'y' in mot and 'u' in mot and 'o' in mot and 'i' in mot and 'a' in mot and 'e' in mot:
        print(mot)

# Il vaut mieux commencer par tester les voyelles les moins fréquentes.

# Autre méthode, avec all qui permet de tester une liste de conditions :

for mot in mots:
    if all(voyelle in mot for voyelle in 'yuoiae'):
        print(mot)

            
#### 9) Mots contenant quatre lettres consécutives

for mot in mots:
    for i in range(len(mot)-3):
        if ord(mot[i+3]) == ord(mot[i+2])+1 == ord(mot[i+1])+2 == ord(mot[i])+3:
            print(mot)

# ou avec un slicing :
    
alphabet = 'abcdefghijklmnopqrstuvwxyz'
for mot in mots:
    for i in range(23):
        if alphabet[i:i+4] in mot:
            print(mot)


#### 10) Mots finissant par ... :

def mots_finissant_par(chaine):
    n = len(chaine)
    L = []
    for mot in mots:
        if mot[-n:] == chaine:  # le slicing est très pratique ici
            L.append(mot)
    return L

# Ou avec une liste par compréhension :

def mots_finissant_par(chaine):
    n = len(chaine)
    return [mot for mot in mots if mot[-n:] == chaine]


#### 11) Compléter un mot :

def completer(modele):
    n = len(modele)
    positions = [k for k in range(len(modele)) if modele[k] != '*']  # positions des lettres connues
    for mot in mots:
        if len(mot) == n:
            ok = True
            for i in positions:
                if mot[i] != modele[i]:
                    ok = False
                    break
            if ok:
                print(mot)
                    
# Ou avec all (très pratique ici) :

def completer(modele):
    n = len(modele)
    positions = [k for k in range(len(modele)) if modele[k]!='*']
    for mot in mots:
        if len(mot) == n and all(mot[i] == modele[i] for i in positions):
            print(mot)


#### 12) Voisins :

def voisins(mot):
    L = []
    n = len(mot)
    for m in mots:
        if len(m) == n:
            nb = 0  # nombre de lettres identiques dans m et mot
            for i in range(n):
                if m[i] == mot[i]:
                    nb += 1
            if nb == n-1:
                L.append(m)
    return L
