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 :

Empêcher une fonction de tester une variable


Sujet :

Python

  1. #1
    Candidat au Club
    Empêcher une fonction de tester une variable
    Bonjour à tous,

    Je suis en 1ère spé NSI et ma professeur nous a donné des exercices sur les tests et la spécification dans un fonction. L'objectif de l'exercice est de calculer la distance entre 2 points, de spécifier la fonction et d'afficher un message d'erreur du genre "Le nombre entré n'est pas valide etc". J'ai réussis le début (code + spécification)

    Voici mon code :
    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
     
    from math import sqrt #On importe la fonction racine carré depuis le module math
     
    def distance(x, y) : #On définie une fonction appelée distance et qui prend en compte les paramètre x et y
        '''
        Cette fonction calcule la distance d'un point de coordonnées x y à l'origine du repère
     
        @param x : (int) abscisse du point
        @param y : (int) ordonnée du point
     
        @return distance : (int) distance entre le point entré et l'origine du repère
        '''
        if x and y != float : #On vérifie que les valeurs entrées sont des nombres
            print("Le nombre entré n'est pas valide. Veuillez entrez un nombre entier ou decimal") #Si une des valeurs entrée n'est pas un nombre on affiche un message d'erreur
            return
     
        distance = sqrt(x**2 + y**2) #La distance entre 2 point se calcule par la formule sqrt(x2 - x1)**2 + (y2 - y1)**2)
                                     #mais x2 et y2 sont égaux a zéro on a donc la formule sqrt(x**2 + y**2)
        return distance #On renvoie la distance du point a l'origine


    Problème :
    Quand j'entre par exemple distance(a,b) je veux que la fonction m'affiche le message d'erreur "personnalisé" mais a la place j'ai le message d'erreur classique qui me dit que la variable n'est pas définie. Es ce que vous savez si il y a moyen "d'empêcher" la fonction de tester si l'entré est une variable ou pas ?

    Merci par avance de votre aide

  2. #2
    Modérateur

    Salut,

    Je n'ai peut être pas tout compris mais si vous écrivez def distance(*args), la fonction pourra être appelée avec un nombre indéfini d'argumenta à piocher (à l'intérieur de la fonction) dans la variable args. Un tuple qui est une sorte de liste.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Candidat au Club
    Merci de votre réponse je vais tester ça

    En gros je veux que quand je rentre par exemple "distance(a,b)" dans la console la fonction me renvoie "le nombre entré n'est pas valide" au lieu d'avoir comme erreur :
    Traceback (most recent call last):
    File "<interactive input>", line 1, in <module>
    NameError: name 'a' is not defined

  4. #4
    Membre émérite
    Salut,

    Citation Envoyé par Gal.o.u Voir le message

    En gros je veux que quand je rentre par exemple "distance(a,b)" dans la console la fonction me renvoie "le nombre entré n'est pas valide" au lieu d'avoir comme erreur :
    Traceback (most recent call last):
    File "<interactive input>", line 1, in <module>
    NameError: name 'a' is not defined
    Ben je ne suis pas sûr de comprendre...

    Si tu fais distance(a,b) et que la variable a n'est pas définie eh bien il est normal que tu ais ce message d'erreur...
    Alors soit tu définis a et b avant l'appel de la fonction, soit tu mets directement des nombres comme ça par exemple : distance(2.3,5)...

    -----------
    EDIT : Ah oui ton test ne fonctionne pas : if x and y != float :...

    Pour plusieurs raisons, déjà le "and" (et logique) ne fonctionne pas comme ça...

    Essaye pour commencer de tester une seule variable (donc sans le "and" )...
    Pour cela tu peux utiliser par exemple la fonction isinstance...
    Plus précisément pour vérifier si x est un float : isinstance(x, float )...

  5. #5
    Candidat au Club
    Merci de vos réponses
    Enfaite j’oubliais juste de mettre des guillemets a chaque fois c'est pour ça que ce que je voulais faire ne marchais pas
    Pour le if x and y != float : j'ai remplacé le and par un or pour que la fonction s'arrête si un des 2 n'est pas un nombre.

  6. #6
    Membre émérite
    Ah je m'en doutais un peu pour les guillemets...

    Citation Envoyé par Gal.o.u Voir le message

    Pour le if x and y != float : j'ai remplacé le and par un or pour que la fonction s'arrête si un des 2 n'est pas un nombre.
    Non ce n'est pas cela le problème...
    Pour commencer essaye avec une variable comme je te l'ai suggéré...

  7. #7
    Candidat au Club
    Ducoup avoir
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     if x != float : 
            print("Un des nombres entré n'est pas valide. Veuillez entrez un nombre entier ou decimal")
    if y != float :
            print("Un des nombres entré n'est pas valide. Veuillez entrez un nombre entier ou decimal")
            return


    ?

    ------------------------------
    EDIT :
    Pourquoi le or marche pas j'ai pas compris ?

  8. #8
    Membre émérite
    Citation Envoyé par Beginner. Voir le message

    Plus précisément pour vérifier si x est un float : isinstance(x, float )...
    Tu peux utiliser la fonction isinstance : if isinstance(x, float ):...

    Ou la fonction type : if type(x) == float...

  9. #9
    Membre émérite
    Citation Envoyé par Gal.o.u Voir le message
    Ducoup avoir
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     if x != float : 
            print("Un des nombres entré n'est pas valide. Veuillez entrez un nombre entier ou decimal")
    if y != float :
            print("Un des nombres entré n'est pas valide. Veuillez entrez un nombre entier ou decimal")
            return


    ?
    Non, car tu compares x avec float alors que tu dois comparer le type de x avec float...

    Regarde mon message précédent...

    Après tu peux regrouper les conditions avec un ou logique...

  10. #10
    Modérateur

    Salut,

    Citation Envoyé par Gal.o.u Voir le message
    En gros je veux que quand je rentre par exemple "distance(a,b)" dans la console la fonction me renvoie "le nombre entré n'est pas valide" au lieu d'avoir comme erreur :
    Traceback (most recent call last):
    File "<interactive input>", line 1, in <module>
    NameError: name 'a' is not defined
    L'interpréteur Python essaie d'accéder aux arguments pour appeler la fonction: dans la fonction il est trop tard. Pour attraper çà, l'appelant de la fonction doit éventuellement le faire via une gestion d'exception (try...except...).
    Mais entrer des instructions Python à la console suppose que l'utilisateur connaît un peu Python et sait quoi faire dans ce cas.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Candidat au Club
    Donc j'aurai
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    if isinstance(x,float) or isinstance(y,float) = False :
    print("Mon message d'erreur")

  12. #12
    Membre émérite
    Citation Envoyé par Gal.o.u Voir le message
    Donc j'aurai
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    if isinstance(x,float) or isinstance(y,float) = False :
    print("Mon message d'erreur")
    Ben la comparaison c'est avec == et non avec =.

    Et quand tu utilises un opérateur logique tu dois avoir deux opérandes logiques...

    En français tu veux tester : si x n'est pas un float ou si y n'est pas un float (mais toi tu ne fais que le deuxième test)...

    Si on traduit on devrait avoir : if isinstance(x, float) == False or isinstance(y, float) == False:...

    PS : Tu peux faire cela aussi : if type(x) != float or type(y) != float:

  13. #13
    Membre émérite
    Citation Envoyé par Beginner. Voir le message

    Si on traduit on devrait avoir : if isinstance(x, float) == False or isinstance(y, float) == False:...

    PS : Tu peux faire cela aussi : if type(x) != float or type(y) != float:
    Ah oui ça c'est un test pour le type float mais je crois que toi tu veux aussi tester le type entier...

    Alors là il faudra ajouter des choses car en l'état si x est un entier alors tu auras ton message d'erreur, ce que tu ne veux pas...

  14. #14
    Expert confirmé
    Bonjour Gal.o.u,

    Il y a plusieurs choses à corriger dans ta fonction distance :
    • La docstring affirme que x et y doivent être des entiers, ce qui est contradictoire avec le code qui essaie de vérifier si x et y sont des flottants. Si tu veux tester que x est un entier, il faut écrire isinstance(x, int). Si tu veux tester que c'est un flottant, il faut écrire isinstance(x, float). Si tu veux tester que c'est un entier ou bien un flottant, il faut écrire isinstance(x, (int, float)).
    • La docstring affirme que le type de retour est int, ce qui est contradictoire avec le code, car la fonction sqrt retourne un flottant.
    • Il faut corriger le commentaire qui évoque la formule "sqrt(x2 - x1)**2 + (y2 - y1)**2)" : ce sont x1 e y1 qui valent 0, pas x2 et y2.


    Il y a aussi d'autres soucis, mais qu'il ne faudra peut-être pas corriger :
    • La fonction distance est mal nommée. Quand on lit distance(a, b), l'interprétation normale est que l'on calcule la distance entre a et b. Il aurait été plus adapté de nommer la fonction hypot ou my_hypot, étant donné que cet exercice consiste à refaire la fonction math.hypot, mis à part qu'on fixe le nombre de paramètres à deux. Mais peut-être que c'est l'exercice qui t'oblige à appeler distance cette fonction.
    • Quand les paramètres ne sont pas du bon type, au lieu de faire un print suivi d'un return, il vaut mieux lever une exception de type TypeError. Mais, si tu n'as pas encore vu les exceptions en Python (avec les mots-clefs raise et except), alors tu peux ignorer cette remarque pour le moment.

  15. #15
    Membre émérite
    Salut,

    Citation Envoyé par Pyramidev Voir le message
    Si tu veux tester que c'est un entier ou bien un flottant, il faut écrire isinstance(x, (int, float)).
    Ah ça je ne savais pas, merci.

    C'est mieux que de faire : if (type(x) != float and type(x) != int) or (type(y) != float and type(y) != int):...

  16. #16
    Expert éminent sénior
    Bonjour
    Citation Envoyé par Beginner. Voir le message
    C'est mieux que de faire : if (type(x) != float and type(x) != int) or (type(y) != float and type(y) != int):...
    if not all(isinstance(v, (int, float)) for v in (x, y)).
    L'avantage, c'est que tu peux facilement rajouter une 3°, 4°, 5° variable...
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  17. #17
    Membre émérite
    Merci Sve@r c'est bon à savoir.