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 :

DEBUGGING et valeur de retour de fonction - Comment faites-vous ?


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2006
    Messages : 35
    Par défaut DEBUGGING et valeur de retour de fonction - Comment faites-vous ?
    Bonjour,

    Je voudrais ouvrir une discution sur la façon dont vous traiter les erreurs en retour d'une fonctions. Je ne parle pas d'erreurs avec sortie du programme mais juste des cas où votre fonction ne peut retourner un résultat du type attendu.

    Par exemple, vous avez une fonction qui cherche un mot dans un texte mais le mot n'y figure pas... Il faut alors que la fonction signale au programme ce cas particulier.
    Comment traitez-vous ce problème ?


    Le soucis classique avec une fonction, c'est lors du retour des résultats. La fonction retourne normalement une valeur mais il est possible qu'elle retourne aussi une valeur d'échec. Et cette valeur d'échec n'a pas forcément le même type que la valeur de retour.

    Exemple de fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    def inv(n):
        data=1.0/n
        return data
     
    print inv(2.0)
    >0.5
     
    print inv(0.0)
    >Traceback (most recent call last):
      File "debugging01.py", line 10, in <module>
        print inv(0.0)
      File "debugging01.py", line 5, in inv
        data=1.0/n
    ZeroDivisionError: float division
    Le soucis de cette fonction c'est qu'elle ne traite pas le cas où n=0...
    On écrira donc pour le traiter:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def inv(n):
        if n!=0.0:
            data=1.0/n
        else:
            data=False
        return data
     
    print inv(2.0)
    >0.5
     
    print inv(0.0)
    >False
    Ou avec le traitement des erreurs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    retValue=inv(2.0)
    if retValue!=False:
        print retValue
    >0.5
     
    retValue=inv(0.0)
    if retValue!=False:
        print retValue
    >
    Note: J'ai conscience que dans certains cas, il est possible de recourir à des astuces. Par exemple, une fonction qui recherche la position d'un mot dans un texte, fournira une valeur entière en retour et en cas d'échec une valeur négative comme -1. La valeur d'une position ne pouvant jamais être négative, l'astuce ne limite en rien la fonction. Dans une tel cas la fonction retourne toujours des nombres entiers.
    Cependant, il n'est pas toujours possible de réserver une valeur spécifique de même type.


    On peut alors imaginer de retourner systématiquement un tableau de deux valeurs.
    La première donnée est le résultat de la fonction: a-t-elle fonctionné oui ou non.
    La seconde donnée est la valeur retournée elle-même, du moins si elle existe.
    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 inv(n):
        state=False
        data=0.0
        if n!=0.0:
            state=True
            data=1.0/n
        return [state,data]
     
    retValue=inv(2.0)
    if retValue[0]:
        print retValue[1]
    >0.5
     
    retValue=inv(0.0)
    if retValue[0]:
        print retValue[0]
    >
    Ici l'avantage est de pouvoir séparer clairement les données retournées et le traitement des erreurs. Les valeurs ne sont plus mélangées, ce qui est mieux dans l'absolu pour le traitement des erreurs.

    Par contre, la récupération des données oblige à passer par des indices de tableau et il y a risque de confusion.
    J'ai volontairement introduit une erreur dans le code ci-dessus: le dernier 'print retValue[0]' n'a pas le bon indice (1 est correct). On voit qu'il est facile de se tromper.



    Donc voilà j'aurai aimé savoir comment vous faites dans vos programmes pour gérer ces cas particulier.

    Existe-t-il des techniques connues ou c'est la débrouille au cas par cas ?

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Toutes les réponses à tes questions sur la doc officielle

  3. #3
    Membre chevronné
    Profil pro
    Ingénieur sécurité
    Inscrit en
    Février 2007
    Messages
    574
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 574
    Par défaut
    Salut,
    Deux cas pour moi,
    Soit la chaîne indiquée n'est pas dans le texte et dans ce cas la fonction retourne None (type null python)
    Soit, dans le cas de la division par zero, je considère qu'il est de la responsabilité du programmeur d'inclure l'appel à la fonction dans un bloc et dans ce cas dans le corps de la fonction je lève une exception avec dans le cas d'une division par zero.
    Tout dépend si c'est une erreur de logique (de division) qui interromp le programme ou une absence de résultat (pas le mot dans la chaîne) qui n'est pas vraiment une erreur.
    J'espère que je suis pas trop obscur

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2006
    Messages : 35
    Par défaut
    Oui oui vous êtes clairs mais en fait je me rend compte que mon exemple avec la division par zéro était un peu malheureux... C'est vrai que ça se traite par les exceptions du langage lui-même. Mauvais exemple donc. Sorry.

    Non les cas qui m'intéressent, ce n'est pas ceux-là, c'est tous les autres quand une fonction retourne habituellement un résultat d'un certain type mais que dans certains cas elle ne peut pas le retourner pour une raison x. C'est pas une erreur à proprement parler, juste des cas spéciaux de retour de fonction. Après le programme doit intercepter ça sans pour autant recourrir à un try...

    Prenons plutot l'exemple avec le mot pas trouvé. Si je retourne None. Je dois après créer un test pour savoir si la valeur retournée par la fonction est None ou une chaine de caractères. C'est ces cas-là qui m'intéressent. Parce que dans ce cas là, la fonction retourne des valeurs avec des types différents.

  5. #5
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Dans ce cas utiliser isinstance

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    isinstance(None, str)
    >>>False
    isinstance("bonjour", str)
    >>>True
    avec des if...else, on s'en sort très bien.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2006
    Messages : 35
    Par défaut
    Oui voilà c'est plus ce genre de traitement qui m'intéresse.
    Donc toi tu proposes isinstance pour tester le type et puis un if/else.


    Sinon voici un meilleur exemple de programme pour servir de base à la discution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def nextWord(theSentence,theWord):
    	array=theSentence.split()
    	retValue=None
    	if theWord in array:
    		idx=array.index(theWord)
    		idx+=1
    		if idx<len(array):
    			retValue=array[idx]
    	return retValue
    Il s'agit d'un programme qui donne le mot qui suit un mot clé dans une phrase

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    theSentence='Un petit exemple pour illustrer le truc'
    theWord='petit'
    print nextWord(theSentence,theWord)
    >exemple
     
    theWord='truc'
    print nextWord(theSentence,theWord)
    >None
     
    theWord='machin'
    print nextWord(theSentence,theWord)
    >None
    Trois cas possibles:
    1) le mot clé existe et le mot qui suit aussi, on retourne du texte
    2) le mot clé existe mais il n'y a pas de mot qui suit (dernier mot de la phrase)
    3) le mot clé n'existe pas, il n'y a donc pas de réponse non plus

    EDIT: on dit aussi que pour créer un programme avec le moins de bugs possible une fonction devrait toujours retourner un résultat du même type.
    Mais dans cet exemple, on voit bien que ça semble difficile dans la pratique...

    A moins peut être de passer par un tableau ? (comme expliqué dans le post original).
    Si vous avez d'autres idées que le tableau ou autre pour traiter ça, n'hésitez pas

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    105
    Détails du profil
    Informations personnelles :
    Âge : 57
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2007
    Messages : 105
    Par défaut
    Bonjour,

    Il te suffit de tester la valeur retournée par ta fonction, si la valeur retournée est None le test échouera.
    Ce qui donne dans ton exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    theSentence='Un petit exemple pour illustrer le truc'
    for theWord in ['petit','truc','machin']:
        result = nextWord(theSentence,theWord)
        if result: print result
    La seule réponse que tu obtient est exemple.

    Salutations.

Discussions similaires

  1. Valeur de retour pour fonction
    Par oufou dans le forum Débuter
    Réponses: 7
    Dernier message: 19/09/2014, 16h02
  2. Réponses: 3
    Dernier message: 27/02/2012, 17h52
  3. Comment faites-vous pour récupérer la valeur d'une liste dynamique ?
    Par Cvbdev dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 03/06/2010, 09h01
  4. Réponses: 8
    Dernier message: 14/12/2007, 17h12
  5. [Struts]comment faites-vous pour enregistrer..
    Par pouss dans le forum Struts 1
    Réponses: 7
    Dernier message: 30/09/2005, 12h55

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