đ”ïžââïž Trace dâexĂ©cution
Lorsqu'on a un morceau de code, on peut souhaiter savoir dans quel ordre les instructions sont exécutées.
On veut spécifier précisément :
- Quelles lignes de code s'exécutent dans quel ordre.
- Les effets de chaque ligne de code :
- quelles variables sont créées/modifiées,
- quelles valeurs elles contiennent,
- ce qui est affiché (si on a des
print).
- La portée des variables.
- Si on a des fonctions :
- la pile d'appels (quelles fonctions sont en cours d'exécution),
- quelle fonction est appelée,
- quelle valeur elle retourne (si elle en retourne une).
đ Vous pouvez imprimer ce tableau de trace d'exĂ©cution pour pratiquer vos traces Ă la main.
- Exemple simple
- Avec fonction
- Avec condition
- Avec boucle
- Valider une trace
Dans le cas d'une séquence d'instructions, on peut voir que les instructions sont exécutées dans l'ordre de lecture du code. Simple!
Codeâ
Si on a le code suivant :
def carre(n):
return n * n
def affiche_resultat():
a = 2
b = 3
total = carre(a) + carre(b)
print(f'La somme des carrés est : {total}')
z = 42
affiche_resultat()
Traceâ
On aura la trace suivante :
| portée globale | portée de affiche_resultat | portée de carre | |||||||
|---|---|---|---|---|---|---|---|---|---|
| #ligne | z | a | b | total | n | affichage | pile d'appels | fonction appelée | valeur retournée |
| 10 | 42 | ||||||||
| 11 | 42 | affiche_resultat() | |||||||
| 5 | 42 | 2 | affiche_resultat | ||||||
| 6 | 42 | 2 | 3 | affiche_resultat | |||||
| 7 | 42 | 2 | 3 | affiche_resultat | carre(2) | ||||
| 2 | 42 | 2 | carreaffiche_resultat | 4 | |||||
| 7 | 42 | 2 | 3 | affiche_resultat | carre(3) | ||||
| 2 | 42 | 3 | carreaffiche_resultat | 9 | |||||
| 7 | 42 | 2 | 3 | 13 | affiche_resultat | ||||
| 8 | 42 | 2 | 3 | 13 | La somme des carrés est : 13 | affiche_resultat | |||
Explicationsâ
On indique la portée des variables en les regroupant par portée (premiÚre ligne).
Ici, on a la portée globale (variables définies en dehors de toute fonction), la portée de affiche_resultat et la portée de carre.
On remarque que la variable n n'existe que dans la portée de la fonction carre, et que les variables a, b et total n'existent que dans la portée de la fonction affiche_resultat.
La variable z est dans la portée globale, c'est pourquoi elle est visible dans toute la trace.
On indique aussi la fonction appelée (avant son exécution) et la valeur qu'elle retourne (aprÚs son exécution) (derniÚres colonnes).
On indique aussi la pile d'appels, c'est-à -dire les fonctions en cours d'exécution (3e colonne à partir de la droite).
Ce genre de code fait souvent appel à plusieurs appels de fonctions imbriqués.
On peut donc visualiser la pile d'appels comme un empilement temporaire oĂč chaque appel sâajoute en haut de la pile, et disparaĂźt dĂšs quâil est terminĂ©.
Voici maintenant un petit exemple qui dĂ©montre l'importantce de spĂ©cifier la portĂ©e des variables, oĂč on a une variable x dans la portĂ©e globale et une autre variable nommĂ©e x dans la portĂ©e de la fonction ma_fonction.
Codeâ
def ma_fonction(y):
x = 3 + y
print(f'dans ma_fonction, x vaut {x}')
x = 5
print(f'dans main, x vaut {x}')
ma_fonction(100)
print(f'dans main, x vaut toujours {x}')
Traceâ
| portée globale | portée de ma_fonction | ||||||
|---|---|---|---|---|---|---|---|
| #ligne | x | y | x | affichage | pile d'appels | fonction appelée | valeur retournée |
| 5 | 5 | ||||||
| 6 | 5 | dans main, x vaut 5 | |||||
| 7 | 5 | ma_fonction(100) | |||||
| 2 | 5 | 100 | 103 | ma_fonction | |||
| 3 | 5 | 100 | 103 | dans ma_fonction, x vaut 103 | ma_fonction | ||
| 8 | 5 | dans main, x vaut toujours 5 | |||||
On voit que la variable x dans la portée de ma_fonction n'a rien à voir avec la variable x dans la portée globale.
Cette derniÚre n'est pas modifiée par l'exécution de ma_fonction, malgré le fait qu'on ait une instruction x = 3 + y dans ma_fonction et que la variable globale x soit aussi accessible dans ma_fonction (car elle est globale).
La raison est que l'instruction x = 3 + y cr ée une nouvelle variable x dans la portée de ma_fonction, qui masque la variable globale x.
Si on voulait modifier la variable globale x dans ma_fonction, il faudrait utiliser le mot-clé global (ce qui est déconseillé en général).
- Certaines lignes ne s'exécutent pas, c'est le principe de la condition!
- On indique les lignes qui testent une condition :
if,elif,match,case(mais paselse).
Codeâ
Si on a le code suivant :
a = 42
if a > 100:
print('a est grand')
elif a > 10:
print('a est moyen')
elif a > 1:
print('a est petit')
else:
print('a est trĂšs petit')
print('a est nul') if a == 0 else print('fin')
Traceâ
On aura la trace suivante :
| portée globale | |||||
|---|---|---|---|---|---|
| #ligne | a | affichage | pile d'appels | fonction appelée | valeur retournée |
| 1 | 42 | ||||
| 2 | 42 | ||||
| 4 | 42 | ||||
| 5 | 42 | a est moyen | |||
| 11 | 42 | fin | |||
Codeâ
Si on a le code suivant :
a = 42
match a:
case 6:
print('a est égal à 6')
case 7:
print('a est égal à 7')
case 42:
print('a est égal à 42')
case 420:
print('a est égal à 42')
case _:
print("a n'est pas 6, 7 ou 42")
Traceâ
On aura la trace suivante :
| portée globale | |||||
|---|---|---|---|---|---|
| #ligne | a | affichage | pile d'appels | fonction appelée | valeur retournée |
| 1 | 42 | ||||
| 2 | 42 | ||||
| 3 | 42 | ||||
| 5 | 42 | ||||
| 7 | 42 | ||||
| 8 | 42 | a est égal à 42 | |||
- Certaines lignes s'exécutent plusieurs fois, c'est le principe de la boucle!
- On indique les lignes qui testent une condition (
whileetfor).
Traceâ
On aura la trace suivante :
| portée globale | |||||
|---|---|---|---|---|---|
| #ligne | i | affichage | pile d'appels | fonction appelée | valeur retournée |
| 1 | 0 | ||||
| 2 | 0 | ||||
| 3 | 0 | i vaut 0 | |||
| 4 | 1 | ||||
| 2 | 1 | ||||
| 3 | 1 | i vaut 1 | |||
| 4 | 2 | ||||
| 2 | 2 | ||||
Afin de valider une trace :
- Placer un point d'arrĂȘt sur la premiĂšre ligne qui s'exĂ©cute.
- Lancer l'exécution en mode débogage.
- Sauter de ligne en ligne pour voir si la trace est correcte.
Si on se rend à la fin de l'exécution et que toutes tes valeurs étaient bonnes, on a bien compris ce que fait le code.