IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

problème sur une fonction python


Sujet :

Python

  1. #1
    Candidat au Club
    Homme Profil pro
    responsable maintenance véhicule et matériel
    Inscrit en
    Décembre 2020
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : responsable maintenance véhicule et matériel

    Informations forums :
    Inscription : Décembre 2020
    Messages : 3
    Points : 4
    Points
    4
    Par défaut problème sur une fonction python
    Bonjour à tous,

    Actuellement débutant dans le monde du codage informatique, je suis en train de suivre un mooc python afin d'avoir les premières bases.

    actuellement je coince sur un exercice. Voir consigne ci-dessous.

    **********
    Joao vient d’arriver dans notre pays depuis le Portugal. Il a encore du mal avec la langue française. Malgré ses efforts considérables, il fait une faute d’orthographe quasi à chaque mot. Son souci est qu’il n’arrive pas toujours à écrire un mot correctement sans se tromper à une lettre près. Ainsi pour écrire « bonjour », il peut écrire « binjour ». Pour remédier à ce problème, Joao utilise un correcteur orthographique. Malheureusement, Joao a un examen aujourd’hui et il a oublié son petit correcteur.

    Afin de l’aider, nous vous demandons d’écrire une fonction correcteur(mot, liste_mots) où mot est le mot que Joao écrit et liste_mots est une liste qui contient les mots (ayant la bonne orthographe) que Joao est susceptible d’utiliser.

    Cette fonction doit retourner le mot dont l’orthographe a été corrigée.

    Exemple 1
    L’appel suivant de la fonction :

    correcteur("bonvour", ["chien", "chat", "train", "voiture", "bonjour", "merci"])
    doit retourner :

    "bonjour"

    ***********

    voici le code que j'ai écris et que je vais essayé d'expliquer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    def distance_mots(mot_1, mot_2):
     
        d = 0                           #incrémentation des distances
     
        for i in range(len(mot_1)):     # boucle pour interroger chaque caractère
     
            if mot_1[i] != mot_2[i]:    # si les caractères sont différent
     
                d = d + 1               # incrémentation de +1 a d
     
        return d                        # a la fin de la boucle retourner le résultat de d
     
    def correcteur(mot, liste_mots):            # fonction correcteur
     
        num = 0                                 # variable num
     
        iteration = 0                           # variable itération
     
        while iteration != len(liste_mots):      # création d'une boucle en fonction du nombre d'élément dans la liste de mots
     
            iteration += 1                        # incrémenter + 1 a la variable iteration
     
            if len(mot) == len(liste_mots[num]):            # rechercher les mots avec le même nombres de caractère
     
                distance_mots(mot, liste_mots[num])         # une fois trouver faire appel a la fonction distance_mots
     
                res = distance_mots(mot, liste_mots)        # variable du résultat de la fonction distance_mots
     
                if res == 1:                                #si le résultat de distance_mot est égale à 1
     
                    return liste_mots[num]                      # retourner le mot correspondant la liste de mots
     
                    iteration = len(liste_mots)             # arrêt de la boucle en changeant la valeur d'itération
     
                elif res == 0:                              # si le résultat de distance_mot est égale à 0
     
                    return mot                              # retourner le mot si l'ortographe est correcte
     
                    iteration = len(liste_mots)             # arrêt de la boucle en changeant la valeur d'itération
     
                else:
     
                    num += 1                                # incrémenter + 1 a num
    Dans mon code j'ai une première fonction qui me permet de comparer chaque caractère de deux chaîne de caractère en entrée et retourne un résultat D, si le résultat de D est égale à 0 donc tout les caractères sont identiques donc il n'y a pas de faite d'orthographe, en revanche si D = 1 il y a une faute.

    Ensuite j'ai une deuxième fonction nommée correcteur qui reçoit en entrée un mot et une liste de mots.

    j'ai choisi l'option d'utilisé une boucle while car je part du principe qu'on ne sait pas de combien d'élément sera composer la liste de mots.

    je créer 2 variables:

    une nommée "num", l'autre "iteration"

    iteration va me servir a stopper la boucle while et num a interroger chaque chaîne de caractère présente dans la liste de mot.

    "je rappel que dans la consigne il est dit qu'il ne peut y avoir qu'une seul faute donc une lettre de différente sa permet de simplifier la chose"

    Dans ma boucle while je recherche si la première entrée qui est une chaine de caractère a le même nombre de caractère que le num dans la liste de mots.

    Malheureusement lors de mes tests a aucun moment le programme rentre dans la fonction if afin d'interroger la première question qui va me permettre de savoir si les deux chaînes de caractères qui sont en comparaison sont soit identique et donc pas de faute d'orthographe, soit 1 caractère différent et donc sans ce cas il s'agit du bon mot mais avec une faute ou bien si il y a plus d'un caractère de différent ce sont deux mots totalement différent.

    Pouvez-vous me dire ce qui coince dans mon code?

    Merci d'avance pour votre aide

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 300
    Points : 36 798
    Points
    36 798
    Par défaut
    Salut,

    Citation Envoyé par juju510 Voir le message
    Pouvez-vous me dire ce qui coince dans mon code?
    Plutôt que de vous prendre les pieds avec un Python que vous ne maîtrisez pas encore, commencez par écrire ce que vous voulez faire en français un peu "algorithmique" sans vous préoccuper de Python.

    Quand ça marche sur le "papier", vous traduisez en Python en respectant ce que vous avez écrit en français.

    Côté code, c'est pas compliqué, parcourir une liste L avec un index qui va de 0 à len(L) signifie qu'à chaque itération on va travailler sur L[index] (comparer sa longueur avec mot, éventuellement tester si la distance est <=1).

    - W

  3. #3
    Membre actif
    Homme Profil pro
    Animateur Numérique
    Inscrit en
    Février 2013
    Messages
    140
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Animateur Numérique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2013
    Messages : 140
    Points : 208
    Points
    208
    Par défaut
    Salut,

    Comme dit par @wiztricks, tu te compliques la vie, comme l'erreur ne peut qu’être que sur une seule lettre, ton code devrait plutôt ressembler à ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def correcteur(mot, liste_mots):
        occurence = 0
        for mot_correct in liste_mots: 
            if len(mot) == len(mot_correct): 
                for i in range(len(mot_correct)): 
                    if mot[i] == mot_correct[i]: 
                        occurence += 1
                    if occurence == len(mot_correct) - 1:
                        return mot_correct
     
    print(correcteur("bonvour", ["chien", "chat", "train", "voiture", "bonjour", "merci"]))

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 300
    Points : 36 798
    Points
    36 798
    Par défaut
    Citation Envoyé par Diablo76 Voir le message
    ton code devrait plutôt ressembler à ceci:
    Essayez avec print(correcteur("axae", ["aaaa", "adaf", "acae"])), vous aurez la surprise de voir sortir adaf au lieu de acae.

    - W

  5. #5
    Membre actif
    Homme Profil pro
    Animateur Numérique
    Inscrit en
    Février 2013
    Messages
    140
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Animateur Numérique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2013
    Messages : 140
    Points : 208
    Points
    208
    Par défaut
    Ha bon ça appartient à la langue française tes trucs...
    Trouve moi autre chose...

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 042
    Points
    31 042
    Billets dans le blog
    1
    Par défaut
    SAlut
    Citation Envoyé par juju510 Voir le message
    je suis en train de suivre un mooc python afin d'avoir les premières bases.
    Ah je l'ai fait aussi (pour le fun) mais je l'ai trouve extra, avec des exos super bien faits. Ensuite j'ai fait le mooc avancé et lui je ne l'ai pas aimé (aucun exo, que des questions du style "différence entre itérateur et itérable").

    Citation Envoyé par juju510 Voir le message
    voici le code que j'ai écris et que je vais essayé d'expliquer.
    Ta fonction "distance" est pas mal. Bon elle ne fonctionnera que si mot_2 a au-moins autant de lettres que mot_1 mais c'est un bon début.
    Ensuite ta fonction "correcteur" elle, chie un peu dans la colle. Par exemple pourquoi utiliser un while (qui t'oblige à gérer l'incrément) alors que (et tu as bien montré que tu le connaissais dans la première fonction) le for peut faire ça tout seul ?
    Et pourquoi tu appelles deux fois la fonction "distance()" (dont une fois pour rien) ?

    L'algo de cette fonction est beaucoup plus simple que ce que tu as fait : tu parcours la liste de mots et si la distance entre le mot parcouru et le mot à tester est de 1 alors tu affiches le mot parcouru et tu peux quitter la boucle (et pour ça le break est plus simple que mettre ton indice à la valeur max).

    Ensuite (imaginons qu'il n'y ait pas de mot avec une distance de 1) on peut faire plus évolué. Par exemple tu peux trier la liste de mots selon leur distance avec le mot de base puis tu affiches le mot de la liste qui a la distance la plus faible.

    Citation Envoyé par Diablo76 Voir le message
    ton code devrait plutôt ressembler à ceci:
    Pas d'accord. Son approche est plus carrée. Il découpe son problème en différentes étapes et affecte une fonction dédiée à chaque étape. Ok il se mélange un peu à certains moments mais ça c'est du détail qui disparaitra avec l'expérience.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 300
    Points : 36 798
    Points
    36 798
    Par défaut
    Citation Envoyé par Diablo76 Voir le message
    Ha bon ça appartient à la langue française tes trucs...
    Trouve moi autre chose...
    On s'en fout de la langue française: c'est juste des chaines de caractères... et un contre-exemple qui montre que votre code ne marche pas dans tous les cas.

    - W

  8. #8
    Invité
    Invité(e)
    Par défaut
    Bonjour !
    Liste des mots français : https://www.freelang.com/dictionnaire/dic-francais.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    from string import ascii_lowercase
    from unidecode import unidecode as delete_accent
     
    file = open("liste_francais.txt")
    dicofr = file.read().splitlines()
    file.close()
     
    def correcteur(mot):
        MOT = delete_accent(mot.lower())
        length = len(mot)
        words = []
        for word in dicofr:
            WORD = delete_accent(word)
            if length != len(word):
                continue
     
            errors = []
            for i in range(length):            
                if WORD[i] != MOT[i]:
                    if errors:
                        break
                    errors.append(i)
     
            else:
                try:
                    distance = abs(ascii_lowercase.index(MOT[errors[0]])-ascii_lowercase.index(WORD[errors[0]]))
                    words.append((distance,word))
                except IndexError:
                    words.append((0,word))
        try:   
            return sorted(words)[0][1]
        except IndexError:
            print('No word found.')
    L'énoncé explique bien qu'il n'y a qu'une erreur par mot donc inutile de calculer la distance pour chaque lettre, surtout que ça me paraît être assez compliqué d'un point de vu algorithme !
    Imaginons que Joao tape : "zbri", la distance avec "abri" est de 25 mais celle avec "taro" (une plante tropicale) n'est que de 13, sauf qu'on change trois lettres dans ce second exemple.

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 042
    Points
    31 042
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    L'énoncé explique bien qu'il n'y a qu'une erreur par mot donc inutile de calculer la distance pour chaque lettre
    Ce n'est pas "une distance pour chaque lettre" mais "une distance entre deux mots" (ce qu'on nomme, pour des mots de même longueur, une distance de Hamming). Et "une erreur" implique donc une distance de 1.

    Citation Envoyé par LeNarvalo Voir le message
    surtout que ça me paraît être assez compliqué d'un point de vu algorithme !
    Euh... quand-même pas (itérer sur chaque lettre de chaque mot et compter quand ça diffère). La fonction du PO, toute bricolage qu'elle est, fait le job.

    Citation Envoyé par LeNarvalo Voir le message
    Imaginons que Joao tape : "zbri", la distance avec "abri" est de 25
    Je pense que tu n'as pas bien compris la notion de "distance entre deux mots"...

  10. #10
    Candidat au Club
    Homme Profil pro
    responsable maintenance véhicule et matériel
    Inscrit en
    Décembre 2020
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : responsable maintenance véhicule et matériel

    Informations forums :
    Inscription : Décembre 2020
    Messages : 3
    Points : 4
    Points
    4
    Par défaut
    bonjour à tous,

    J'ai lu vos différentes réponses, et comme on me la suggéré wiztricks j'ai reposé le problème sur papier et j'ai effectuer des tests sur pycharm en créant 2 variables une mot et une autre avec une liste de mots, j'ai ensuite écrit mon code avec un print afin qu'il m'affiche le résultat.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    def correcteur(mot, liste_mots):                                # fonction correcteur
     
        for elem in liste_mots:                                     # lit le mot de la liste
     
            if len(mot) == len(elem):                               # compare la longueur de chaîne de caractère
     
                erreur = 0                                          # variable erreur
     
                for caractère in range(len(mot)):                   # comparaison de chaque caractère individuellement
     
                    if mot[caractère] != elem[caractère]:           # si un caractère est différent
     
                        erreur += 1                                 # ajouter 1 a la variable erreur
     
                if erreur <= 1:                                     # si le nombre d'erreur est inférieur ou égale a 1
     
                    return(elem)                                     # affiche le mot de la liste correspondant
    Je précise que avec ce code, je répond correctement à l'exercice qui a été validé sur le upylab du mooc.

    je suis toujours preneur de conseil pour amélioré mon code.

    Merci à tous

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 300
    Points : 36 798
    Points
    36 798
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Je pense que tu n'as pas bien compris la notion de "distance entre deux mots"...
    Si je relis l'énoncé, notre portugais "arrive pas toujours à écrire un mot correctement sans se tromper à une lettre près".
    Ce qu'on cherche n'est pas une "distance" mais une égalité à une lettre près entre 2 mots de même "longueur".
    => compter le nombre de lettres différentes devrait suffire.

    - W

  12. #12
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ce n'est pas "une distance pour chaque lettre" mais "une distance entre deux mots" (ce qu'on nomme, pour des mots de même longueur, une distance de Hamming). Et "une erreur" implique donc une distance de 1.


    Euh... quand-même pas (itérer sur chaque lettre de chaque mot et compter quand ça diffère). La fonction du PO, toute bricolage qu'elle est, fait le job.


    Je pense que tu n'as pas bien compris la notion de "distance entre deux mots"...
    Ah ok, un truc aussi basique à un nom ! Il s'est pas foulé M. Hamming !
    N'empêche on est pas plus avancé pour choisir entre "taux" et "tour" s'il tape "taur".
    J'ai proposé un truc arbitraire... L'idéal aurait peut-être été de se baser sur la fréquence des mots dans la langue française :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    from string import ascii_lowercase
    from unidecode import unidecode as delete_accent
     
    file = open("liste_francais.txt")
    dicofr = file.read().splitlines()
    file.close()
     
    file = open("roman.txt",encoding='utf8')
    roman = file.read().lower().split()
    file.close()
     
    frequences = {}
    for word in dicofr:
        frequences[word]=roman.count(word)
     
    def correcteur(mot):
        MOT = delete_accent(mot.lower())
        length = len(mot)
        words = []
        for word in dicofr:
            WORD = delete_accent(word)
            if length != len(word):
                continue
     
            errors = []
            for i in range(length):            
                if WORD[i] != MOT[i]:
                    if errors:
                        break
                    errors.append(i)
     
            else:
                try:
                    frequence = frequences[word]
                    words.append((frequence,word))
                except IndexError:
                    words.append((0,word))
        try:   
            return sorted(words, reverse=True)[0][1]
        except IndexError:
            print('No word found.')

  13. #13
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 042
    Points
    31 042
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Ah ok, un truc aussi basique à un nom ! Il s'est pas foulé M. Hamming !
    Il n'a pas fait que ça. Par exemple le "code de Hamming" est un mécanisme assez intelligent permettant, en cas d'erreur de transmission sur un bit, de repérer le bit en erreur et le corriger. Il se base sur les puissances de 2. Chaque bit correcteur est placé à une puissance parfaite de 2 ex 1, 2, 4, 8, 16 etc ce qui fait qu'en binaire son numéro d'ordre s'écrit avec un seul "1", et il ne contrôle que les bits ayant un "1" sur la même colonne que la sienne. Par exemple le bit "1" ne contrôle que les bits chiffres impairs. Le bit 2 (10) ne contrôle que que les bits 3 (11), 6 (110), 7 (111), 10 (1010) etc.
    Ainsi si un bit change de valeur, la différence entre le nouveau calcul et l'ancien exprimé en binaire donne immédiatement le numéro du bit ayant changé.

    Citation Envoyé par LeNarvalo Voir le message
    N'empêche on est pas plus avancé pour choisir entre "taux" et "tour" s'il tape "taur".
    Là tu marques un point (moi j'avais pensé à comment choisir entre "cheveux" et "chevaux" par rapport à "cheviux"). Mais rappelons qu'il s'agit d'un simple exercice de débutant destiné à apprendre à faire évaluer une suite d'éléments par une fonction, et apprendre à distinguer les différents retours de l'évaluation et non pas recréer le traducteur universel de Star Trek. Donc dans cette optique, l'examinateur n'ira pas poser ce genre de piège.

    Citation Envoyé par LeNarvalo Voir le message
    L'idéal aurait peut-être été de se baser sur la fréquence des mots dans la langue française
    Remettons donc les choses dans leur contexte (cf ma précédente remarque)...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème sur une fonction logique
    Par Crack1986 dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 16/03/2012, 16h51
  2. problème sur une Fonction récursive
    Par bernie74 dans le forum Développement
    Réponses: 4
    Dernier message: 21/11/2011, 12h45
  3. probléme sur une fonction
    Par titeufdev dans le forum PL/SQL
    Réponses: 3
    Dernier message: 11/01/2011, 09h36
  4. [String]Problème sur une fonction de récurrence
    Par hibou107 dans le forum Débuter avec Java
    Réponses: 9
    Dernier message: 13/04/2010, 15h53
  5. [PostgreSQL] [PostGreSQL] problème sur une fonction avec connexion
    Par roblescriso dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 04/06/2008, 18h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo