Si certains exercices n'ont pas pu être terminés dans le cadre de cette séance, il est fortement conseillé de les terminer par vous-même chez vous ou en salle libre service.
Le but de ce TP est d'approfondir votre maîtrise des :
for
»,
et de découvrir le débogueur de Python.
Un « débogueur » est un outil permettant de ... chercher des bogues dans un programme. Une fonctionnalité intéressante est la possibilité d'exécuter le programme pas à pas en regardant les valeurs des variables à chaque étape.
Pour activer le débogueur de Idle, il suffit de cocher D
ebugger
dans le menu D
ebug
de l'interpréteur. (Pour le désactiver, il faut décocher D
ebugger
...)
Une fois activé, le débogueur ouvrira une fenêtre supplémentaire ressemblant à celle ci :
Pour notre utilisation, il est préférable de décocher la case "Stack" et de cocher la case "Source".
Positionnez ensuite les trois fenêtre (fichier, interpréteur et débogueur) cote à cote, comme par exemple :
Lorsque que l'interpréteur évalue une expression, il procède pas à pas : il faut cliquer sur le bouton "Over" (ou "Step") du débogueur pour passer à la ligne suivante. D'autre part, la ligne que l'interpréteur s'apprête à exécuter est surlignée dans le fichier et la valeur des variables locales est affichée dans le débogueur. Par exemple, après quelques pas, on peut obtenir
Les boutons ont les significations suivantes :
Run Module
du menu R
un
), les définitions passent elles-même dans le débogueur. Il convient donc de cliquer sur le bouton "Go" pour évaluer tout le fichier et reprendre la main dans l'interpréteur.
Reprenez le code de la fonction compte_triangle
du TP précédent :
def compte_triangle(n): r = 0 for i in range(1, n+1, 1): r = r+i return r
Activez le débogueur et évaluez l'expression compte_triangle(15)
. Vérifiez les choses suivantes :
range(...)
,
Utilisez le débogueur pour répondre aux questions suivantes :
for i in range(debut, fin, 1)
, est-ce que la variable i
prend la valeur fin
?
Nous utiliserons maintenant le code suivant, qui permet de compter combien de "6" ont étés obtenus lors de n
lancers d'un dé à 6 faces : (vous pouvez faire un copier/coller ou télécharger le fichier exemple-tp3.py contenant cette fonction et la suivante).
from random import randint def compte_6(n): """compte combien de "6" sont obtenus lors de n tirages aléatoires entre 1 et 6.""" compteur = 0 for i in range(0, n, 1): resultat = randint(1, 6) # tirage aléatoire d'un nombre entre 1 et 6 if resultat == "6": compteur = compteur + 1 return compteur
La première ligne nous permettra d'utiliser la fonction randint(a,b)
qui permet d'obtenir un nombre entier aléatoire entre a
et b
.
compte_6(600)
. Quel est le résultat attendu ? Quel est le résultat constaté ?
compte_6(600)
. Utilisez le mode pas à pas :
compte_6
,
6
et, lorsque vous avez trouvé l'erreur, appuyez sur la touche "Go" pour finir l'exécution.
Activez le débogueur et lancez l'évaluation de l'expression compte_6(35)
.
compte_6
,
randint
, le débogueur détaille le calcul de la fonction randint
, en ouvrant le code de cette fonction dans une nouvelle fenêtre,
randint
, il passe tout de suite à la ligne suivant l'appel en question, dans la fonction compte_6
, (vous pouvez alors refermer la fenêtre contenant le code de la fonction randint
)
randint
, le débogueur passe directement à la ligne suivante,
Lorsque l'on recherche des bogues, il est parfois utile d'arrêter une fonction à un endroit précis. Pour cela, on peut insérer des points d'arrêt dans le programme. Avec Idle, il suffit de faire un clique droit sur la ligne et de cliquer sur la commande Set Breakpoint
. La ligne sera alors surlignée en jaune.
Le bouton "Go" du débogueur permet de continuer l'exécution sans détails, jusqu'au point d'arrêt suivant.
On regardera maintenant le code suivant (vous pouvez faire un copier/coller ou télécharger le fichier exemple-tp3.py contenant cette fonction et la précédente)
from random import randint def compare_lancers(n): """compare les résultats obtenus en tirant 2n fois : - sur les n premiers tirages, en tirant un nombre entre 2 et 12, - sur les n tirages suivant, en tirant deux nombres indépendants entre 1 et 6 et en les additionnant. À chaque fois, les nombres sont ajoutés Le résultat sera la moyenne des tirages pour le type de tirage meilleur. Par exemple, on pourra obtenir (pour n=4) les tirages suivants - 7, 10, 2, 3 pour un total de 22, - 1+3, 2+2, 5+2, 6+4 pour un total de 25. La meilleure moyenne est donc 25/4 soit 6.25.""" resultat1 = 0 # total des tirages avec un nombre entre 2 et 12 for i in range(0, n, 1): nb = randint(2, 12) resultat1 = resultat1 + nb resultat2 = 0 # total des tirages avec deux nombres entre 1 et 6 for j in range(0, n, 1): nb1 = randint(1,6) nb2 = randint(1,6) resultat1 = resultat2 + nb1 + nb2 if resultat1 > resultat2: moyenne = resultat1 / n else: moyenne = resultat2 / n return moyenne
Désactivez le débogueur et évaluez l'expression compare_lancers(1000)
. Quel est le résultat attendu ? Quel est le résultat obtenu ?
Réactivez le débogueur et insérez un point d'arrêt sur la déclaration de resultat2
.
Lancez l'évaluation de compare_lancers(1000)
puis :
resultat1
.
i
et resultat
.
resultat2
. Lorsque que vous avez trouvé le bogue, terminez l'évaluation avec le bouton "Go".
Pourquoi est-il préférable de mettre le point d'arrêt sur la ligne précédent la boucle ? Refaites les mêmes opérations avec le point d'arrêt sur la ligne for j in range(1, n, 0)
.
Insérez un point d'arrêt sur la ligne contenant le return
et lancez l'évaluation de compare_lancers(1000)
. Arrêtez le débogueur sur la ligne contenant le return
et comparez les valeurs des variables resultat1
et resultat2
. Quel type de lancers est plus avantageux ?
Programmez deux versions de la fonction renverse
qui renvoie le « renversé » d'une chaîne de caractères :
...
resultat = s[i] + resultat
...
return resultat
...
resultat = resultat + s[i]
...
return resultat
Vérifiez que les deux versions donnent bien le même résultat et utilisez le débogueur pour regarder l'évolution de la variable resultat
dans les deux cas.
Programmez toutes les fonctions restantes de la feuille de TD3.