LyonHPC LyonHPC

14. Recherche d’erreurs#

../_images/phd011406s.gif

d’après le site http://phdcomics.com/comics.php

%matplotlib inline
from IPython.core.display import HTML,display
/tmp/ipykernel_3746331/2753186412.py:2: DeprecationWarning: Importing display from IPython.core.display is deprecated since IPython 7.14, please import from IPython display
  from IPython.core.display import HTML,display

14.1. Historique#

Un bug informatique ou bogue est communément attribué au tout premier incident informatique qui a été causé par un insecte lors du développement du système informatique électromécanique à lampes Harvard Mark II en 1945.

Mark II Bug

Cependant, le terme bug était déja utiliser pour désigner un défaut de conception depuis Thomas Edison en 1878.

14.2. Méthodologie#

(voir aussi le cours MIT 6.00 « Introduction to computer science and programming » )

Les erreurs dans un programme (bogues ou bugs) sont introduites par le programmeur:

  • erreur de syntaxe

  • erreur de programmation

  • erreur algorithmique

14.2.1. objectifs du debugging#

  • essayer d’obtenir un programme avec le moins d’erreurs possible (bug-free program)

  • et non pas éliminer rapidement une erreur

  • le debugging est très fortement associé à la validation

Dans le développement d’applications, la partie debugging et validation représente la part la plus importante.

14.2.2. démarche du debugging#

  • démarche systématique basée sur la logique

  • outils d’aide au debugging = debugger OK

  • mais ce qui est le plus important est la méthode, plus que l’outil !

  • outil simple et efficace= insertion de print dans le code

14.2.3. méthode#

  • recherche de bugs par dichotomie (binary search)

  • avec pour objectif non pas de trouver pourquoi le programme ne donne pas le bon résultat, mais de comprendre pourquoi le programme fonctionne de cette façon pour ensuite le corriger.

  • approche scientifique:

    • on fait une hypothèse

    • on choisit des données, et on fait des expériences numériques reproductibles pour tenter d’invalider l’hypothèse

    • raisonnement par dichotomie

      • hypothèse: telle partie du programme donne le résultat attendu

      • insertion de print pour tester l’hypothèse

14.3. Exemple de debugging#

Voici un programme qui teste si la représentation base 2 d’un entier est un palindrome.

exemple:

  • n=9 en base 2 s’écrit 1001 et est donc un palindrome

  • n=12 en base 2 s’écrit 1100 et n’est pas un palindrome

14.3.1. principe de l’algorithme#

n entier positif
conversion de n en base 2 sous forme d'une liste de 0 et 1
   éléments de la liste = reste division successive de n par 2
test si la liste est un palindrome 
   comparaison avec la liste inversée

14.3.2. programme avec des bugs !!#

# digit en base 2
digit=['0','1']
def base2(n):
    """conversion base 2 d'un nombre n"""
    x = n  
    while x:
      digits=[]
      digits.append(digit[x%2])
      x = x // 2
    return digit

def TestPalindrome2(n):
    """test si la representation de n en base 2 est un palindrome"""
    L=base2(n)
    tmp=L
    L.reverse
    if (L == tmp) :
        return True
    else :
        return False
# test
res=TestPalindrome2(9)
print("pour n=9  1001  palindrome vraie:",res)
res=TestPalindrome2(12)
print("pour n=12 1100  palindrome faux :",res)
pour n=9  1001  palindrome vraie: True
pour n=12 1100  palindrome faux : True

14.3.3. instrumentation du programme#

utilisation de print en utilisant une méthode de dichotomie pour rechercher les bogues

# digit en base 2
digit=['0','1']
def base2(n):
    """conversion base 2 d'un nombre n"""
    x = n  
    while x:
      digits=[]
      digits.append(digit[x%2])
      x = x // 2
    print(n,digits)
    return digit

def TestPalindrome2(n):
    """test si la representation de n en base 2 est un palindrome"""
    L=base2(n)
    #print L
    tmp=L
    tmp.reverse
    #print tmp
    if (L == tmp) :
        return True
    else :
        return False
# test
res=TestPalindrome2(9)
print("pour n=9  1001  palindrome vraie:",res)
res=TestPalindrome2(12)
print("pour n=12 1100  palindrome faux :",res)
9 ['1']
pour n=9  1001  palindrome vraie: True
12 ['1']
pour n=12 1100  palindrome faux : True

14.3.4. programme correcte#

# digit en base 2
digit=['0','1']
def base2(n):
    """conversion base 2 d'un nombre n"""
    x = n
    digits=[]
    while x:
      digits.append(digit[x%2])
      x = x // 2
    digits.reverse()
    return digits

def TestPalindrome2(n):
    """test si la representation de n en base 2 est un palindrome"""
    L=base2(n)
    tmp=L[:]
    L.reverse()
    if (L == tmp) :
        return True
    else :
        return False
# test
res=TestPalindrome2(9)
print("pour n=9  1001  palindrome vraie:",res)
res=TestPalindrome2(12)
print("pour n=12 1100  palindrome faux :",res)
pour n=9  1001  palindrome vraie: True
pour n=12 1100  palindrome faux : False

14.4. Utilisation de assert#

L’instruction assert permet de vérifier si une condition cdt est vérifiée. Dans le cas contraire, génère une exception et affiche le message optionnel.

syntaxe

   assert cdt [, message ]
   
x=1
assert x>0,"x doit etre positif"
assert x<0,"x doit etre negatif"
 ---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-6-025a817daa31> in <module>
      1 x=1
      2 assert x>0,"x doit etre positif"
----> 3 assert x<0,"x doit etre negatif"

AssertionError: x doit etre negatif   

14.4.1. exemple d’utilisation#

test si l’argument d’une fonction est valide

from numpy import *

def F(x):
    assert x>0, "x doit etre >0"
    return log(x)/x
# test
print(F(1))
0.0
print(F(0))

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-9-925a00bbef87> in <module>()
      6 # test
      7 print(F(1))
----> 8 print(F(0))

<ipython-input-9-925a00bbef87> in F(x)
      2 
      3 def F(x):
----> 4     assert x>0, "x doit etre >0"
      5     return log(x)/x
      6 # test

AssertionError: x doit etre >0

application test si une entrée est valide

print("test")
x=float(input("entree un reel  #0: x="))
assert x!=0, "x doit etre non nul"
print("inverse ",1./x)

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-10-3fd3c58b39a5> in <module>()
      1 print("test")
      2 x=float(input("entree un reel  #0: x="))
----> 3 assert x!=0, "x doit etre non nul"
      4 print("inverse ",1./x)

AssertionError: x doit etre non nul

14.5. FIN de la leçon#