from time import time  # -*- coding: utf-8 -*-


##  Name:           soundex_2025.py
##  Modifications:   CFV (2014-2024) + Pauline Collon (2025)
##  Date: 	        janvier 2014
##  Description:    aplication de l'algorithme du soundex sur un annuaire de noms

def formater(nom):
    """

    @param nom:     nom propre à convertir
    @return:        nom sans espaces à gauche et en majuscules
    """

    # on enlève les blancs à gauche
    nom = nom.lstrip()

    # on met en majuscules et on retourne le résultat
    return nom.upper()


def elaguer(nom):
    """

    @param nom:     nom propre "nettoyé" (fc formater) sans espace à gauche
                    et en majuscules
    @return:        retourne le nom sans les lettres muettes
    """

    # on conserve la 1ère lettre
    nom_code = nom[0]

    # on élimine les lettres muettes parmi les lettres autres que la 1ère
    for let in nom[1:]:
        if let not in "AEHIOUWY":
            # let n'est pas dans la liste des lettres muettes
            # on l'ajoute au mot codé
            nom_code += let

    return nom_code


def elaguer_V2(nom):
    """

    @param nom:     nom propre "nettoyé" sans esapce à gauche et en majuscules
    @return:        retourne le nom sans les lettres muettes
                    version avec l'itération principale sur la liste des lettres muettes
                    les deux versions sont à peu près équivalentes
    """

    nom_code = nom[1:]
    # on élimine chaque lettre muette sur toutes les lettres du mot sauf la 1ère
    for l in "AEHIOUWY":
        nom_code = nom_code.replace(l, "")

    # on remet la 1ère lettre en place
    return nom[0] + nom_code


def coder(nom, codage):
    """

    Pauline : Version plus efficace car evite un double "for"
    @param nom:     nom propre nettoyé et élagué sans les lettres muettes
    @param codage:    dictionnaire des lettres se prononçant de la même façon
    exemple de dictionnaire = {'Z': '8', 'X': '8', 'V': '9', 'T': '3', 'R': '6',
                        'S': '8', 'P': '1', 'Q': '2', 'N': '5', 'L': '4',
                        'M': '5', 'J': '7', 'K': '2', 'F': '9', 'G': '7',
                        'D': '3', 'B': '1', 'C': '2'}
    @return:        nom codé selon soundex
    """

    # codage pour le français
    if codage == 1:
        dico = {'Z': '8', 'X': '8', 'V': '9', 'T': '3', 'R': '6', 'S': '8',
                'P': '1', 'Q': '2', 'N': '5', 'L': '4', 'M': '5', 'J': '7',
                'K': '2', 'F': '9', 'G': '7', 'D': '3', 'B': '1', 'C': '2'}

    else:  # dico anglais
        dico = {'Z': '2', 'X': '2', 'R': '6', 'S': '2', 'P': '1', 'Q': '2',
                'V': '1', 'T': '3', 'J': '2', 'K': '2', 'N': '5', 'L': '4',
                'M': '5', 'B': '1', 'C': '2', 'F': '1', 'G': '2', 'D': '3'}

    # on conserve la 1ère lettre
    nom_code = nom[0]

    # on remplace les autres lettres par le codage associé
    for car in nom[1:]:
        nom_code += dico[car]

    return nom_code


def coder_V2(nom, codage):
    """

    Pauline : version que je pense peu efficace car realise de multiples parcours
    @param nom:     nom propre nettoyé et élagué sans les lettres muettes
    @param codage:   liste des lettres se prononçant de la même façon
                    exemple de liste = ['PB', 'QKC', 'TD', 'L', 'NM', 'R', 'JG', 'ZXS', 'VF']
    """
    if codage==1:
        liste_codage = ['PB', 'QKC', 'TD', 'L', 'NM', 'R', 'JG', 'ZXS', 'VF']
    else : #code anglais
        liste_codage = ['PVBF', 'ZXSQJKCG', 'TD', 'L', 'NM', 'R']

    # on conserve la 1ère lettre
    nom_code = nom[0]

    # on remplace les autres lettres par le codage associé qu'on recherche dans la liste
    for car in nom[1:]:
        # on recherche le code associé
        for i in range(len(liste_codage)):
            if car in liste_codage[i]:
                nom_code += str(i + 1)
                break #evite de continuer a chercher alors qu'on a trouve

    return nom_code



def dedoublonner(nom):
    """

    @param nom: nom codé formaté, nettoyé des lettres muettes et codé, exemple : J66982
    @return:    nom codé dont on a enlevé les chiffres qui se répètent consécutivement
    """

    # on conserve la première lettre
    nom_code = nom[0]

    # on repère les répétitions dans le reste de nom
    for car in nom[1:]:
        # on ajoute le caractère car s'il n'est pas répété
        # c'est à dire s'il n'est pas égal à la dernière lettre ajoutée dans nom_code
        if car != nom_code[-1]:
            nom_code += car

    return nom_code


def raccourcir(nom):
    """

    @param nom:     str - nom codé avec la 1ère lettre du nom et les autres lettres codées par un code numérique
    @return:        str - ramène le nom codé à une chaîne de 4 caractères
    """

    nom = nom + '0' * 3 #on rajoute 3 0 pour etre surs que le code fait au moins 4 elements

    return nom[:4] #on renvoie les 4 premiers caracteres


def soundex(nom, code):
    """
    @param nom: str - nom à coder selon la méthode soundex
    @param code : int - type de dico d'encodage (entier si 1: francais, 2: anglais)
    @return: str - nom transformé après l'application de toutes les étapes de l'algorithme
    """

    # on enleve blancs et on met en majuscules
    nom = formater(nom)
    # on enleve les lettres "muettes"
    nom = elaguer(nom)
    # on code avec le type de codage choisi (1: francais, 2: anglais)
    nom = coder(nom, code)
    # on enleve les répétitions
    nom = dedoublonner(nom)
    # on se ramène à 4 lettres
    nom = raccourcir(nom)

    return nom


if __name__ == '__main__':

    # l'annuaire des employés est représenté par une liste de chaînes de caractères
    annuaire_employes = ["Jurafsky", "Robert", "Jarofsky", "Jarovsky", "Rupert",
                         "Jarovski", " Baragwanath", "Woolcock"]

    # Saisie des Donnees utilisateur
    #nom_recherche = "Woolcock"
    #type_codage = 2
    nom_recherche = input("Entrez le nom a rechercher dans l'annuaire: ")
    type_codage = int(
        input("Choisissez le type d'encodage (1: Francais, 2: Anglais): "))
    # si mauvaise valeur entree, alors on impose le codage francais
    if (type_codage != 1 and type_codage != 2):
        type_codage = 1

    # encodage du nom recherché
    nom_phonetique = soundex(nom_recherche, type_codage)
    print('le code soundex de ce nom est: ', nom_phonetique)

    # recherche de noms equivalents
    lcandidats = []  # liste des candidats à la sélection selon le nom recherché
    for employe in annuaire_employes:
        # on regarde la prononciation de chaque employe dans l'annuaire
        if soundex(employe, type_codage) == nom_phonetique:
            # on ajoute l'employe à la liste des candidats
            lcandidats.append(employe)

    print("La liste des employes pouvant correspondre à ", nom_recherche, " est : ")
    print(lcandidats)

    # version avec liste en compréhension
    lcandidats = [employe for employe in annuaire_employes if
                  soundex(employe, type_codage) == nom_phonetique]
    print("version avec liste en compréhension : ", lcandidats)
