Médaille
N°1 pour apprendre & réviser du collège au lycée.

Mise au point logicielle

Déjà plus de

1 million

d'inscrits !

Effets de bord

  • Python étant un langage à typage dynamique, il n'impose pas de spécifier le type d'une donnée, et on peut à loisir changer le type de donnée d'une variable.
  • Le typage dynamique nous permet d'envisager un même traitement applicable à plusieurs types (mutables ou non mutables) de données.
  • Le choix du type de structure de donnée doit s'effectuer en fonction des besoins et des caractéristiques désirées, notamment d'ordre et de mutabilité.
  • Les types mutables autorisent l'affectation ou la suppression d'éléments mais ce n'est pas le cas des types non mutables qui génèrent une erreur si on tente une affectation ou une suppression d'élément.
  • Certaines structures de données ont été conçues avec la caractéristique d'être mutables, c'est-à-dire modifiables.
  • Il est nécessaire d'être vigilant·e sur cette caractéristique en programmation fonctionnelle : une fonction ne doit pas créer d'effet de bord, c'est-à-dire qu'elle ne doit pas modifier d'éléments extérieurs à son environnement local.
  • La copie de structures de données mutables avec la méthode copy() consiste en une copie superficielle des données (shallow copy). Si ces structures de données mutables contiennent elles-mêmes des données mutables, il est nécessaire d'effectuer ce qu'on appelle une deep copy.
  • La bibliothèque copy faisant partie de la bibliothèque standard de Python, elle propose les méthodes correspondantes.
  • La notion de débordement est associée à la notion de pile.
  • Avec une pile on ne peut retirer que le dernier élément empilé. Si on veut accéder à des éléments situés en-dessous, il faut d'abord dépiler un par un ceux qui se trouvent au-dessus.
  • Des débordements peuvent survenir dans deux cas :
  • débordement positif quand la pile, limitée en taille, est pleine et qu'on tente d'ajouter un nouvel élément ;
  • débordement négatif quand la pile est vide et qu'on tente de retirer un élément.
  • En Python on peut assez facilement modéliser une pile en s'appuyant sur une liste.
  • On peut constater un débordement négatif sur une liste si on appelle la méthode pop() sans nous assurer au préalable que la liste contient au moins un élément.
  • Un test préalable est donc nécessaire pour s'assurer que la liste n'est pas complètement vide avant de tenter de la dépiler.
  • Les effets de bord peuvent perturber la mise au point logicielle. Il est important de les connaître afin d'éviter de les subir de manière involontaire.

Instructions conditionnelles

  • Les instructions conditionnelles permettent à nos algorithmes d'effectuer des traitements distincts en fonction de conditions particulières.
  • Ces instructions conditionnelles sont articulées en Python autour d'au moins un if, optionnellement associé à un ou plusieurs elif et optionnellement à un else.
  • Voici quatre cas de figures d'erreurs fréquemment commises avec des instructions conditionnelles :
  • Séquence incomplète
  • Séquence complète avec ordre incorrect des conditions
  • Traitement conditionnel d'égalités
  • Gestion de la sécurité
  • Pour ce dernier cas : si on cherche à déterminer si un mot de passe est, ou non, conforme à un certain nombre de critères, on commencera par considérer qu'il n'est pas conforme.
  • Les traitements conditionnels nécessitent une vigilance particulière afin de s'assurer que tous les cas de figure possibles sont traités, et que les traitements prévus pour chaque cas spécifique sont bien effectués comme prévu.

Comparaisons

  • De nombreux algorithmes nécessitent de comparer des valeurs entre elles.
  • Si l'ordre n'a pas d'importance pour les égalités simples, la notion même d'égalité doit être nuancée.

Égalité des nombres réels

  • La comparaison d'entiers (type int) ne pose pas de problèmes particuliers.
  • Il convient en revanche d'être prudent avec les nombres flottants (type float).
  • Dans le cas des nombres flottants, certaines valeurs sont seulement des valeurs approchées.
  • Les tests d'égalité stricte sont à éviter lorsqu'on manipule des nombres réels. On passera par des arrondis ou par des comparaisons prenant en compte un faible écart que l'on aura choisi de tolérer.
  • La bibliothèque de tests unitaires unittest, incluse dans la bibliothèque standard, comporte une méthode d'assertion de quasi-égalité appelée AssertAlmostEqual reposant sur ce principe.
  • Cette méthode permet de préciser un ordre de grandeur de l'écart (appelé conventionnellement delta) acceptable pour la comparaison.
  • Lorsqu'on compare deux variables, il est important de comprendre sur quoi porte la comparaison, on distingue deux notions :
  • l'égalité structurelle, qui indique si le contenu des objets est identique ;
  • l'égalité physique, qui indique s'il s'agit ou non du même objet.
  • Exemple : toute modification effectuée sur liste1 affectera obligatoirement liste2 puisqu'il s'agit d'un seul et même objet. En revanche liste3 étant un objet distinct, il pourra être modifié de manière indépendante.
  • En fonction de l'objectif recherché, on vérifiera soit l'identité soit l'équivalence entre deux objets comparés.
  • La connaissance des sources d'erreur évoquées précédemment permet au·à la programmeur·se d'anticiper ses erreurs.
  • Cependant, on n'échappera pas forcément à la manifestation d'un bug.

Démarche de correction d'un bug

  • Lorsqu'un bug apparaît, il importe, dans un premier temps, de procéder à son identification.
  • Cette identification se fait en trois étapes :
  • être en mesure de reproduire le bug (identification des circonstances d’apparition)
  • bien cerner le résultat normalement attendu
  • localiser le bug, c'est-à-dire la partie de code fautive
  • Une fois le bug identifié on procède en quatre étapes pour le corriger :
  • corriger le bug
  • enrichir le jeu de tests du programme pour couvrir le cas qui a généré le bug
  • profiter de son intervention dans le code pour l'améliorer, le rendre plus clair
  • tester la correction du bug et vérifier également que l'on n'a pas commis de régression, c'est-à-dire engendré d'autres bugs.