NSI - Première - Projet : algorithmes de parcours séquentiel d’un tableau
Algorithmes de parcours séquentiel d’un tableau
Cliquez sur le lien du chapitre de cours à consulter:
Les exceptions
Une exception est une interruption de l’exécution du programme qui peut être prévue par le développeur ou décidée par l’interpréteur python notamment quand une donnée n’est pas conforme au code qui la manipule et dans beaucoup d’autres situations.
Lorqu’une exception est levée, un message d’erreur s’affiche dans la console avec le type d’exception. Les exceptions courantes sont:
- NameError : Accès à une variable qui n’existe pas.
- IndexError : Accès à un indice de tableau qui n’existe pas
- TypeError : opération appliquée à des valeurs incompatibles.
Il est possible de déclencher une exception avec le mot clé raise
def indice_du_minimum_tableau(t):
# EXCEPTION LEVEE SI tableau t vide
if len(t) == 0 :
raise ValueError('cette fonction n’accepte pas les tableaux vides')
try :
# ici un code à risque: on demande un nombre à l'utilisateur du logiciel
nombre = int(input( "entrez votre nombre de notes:"))
if nombre <= 0 :
# si l'utilisateur saisit un nombre nul ou négatif, on lève une exception:
raise ValueError('veuillez entrer un nombre entier naturel supérieur à 0')
except:
'''si l'utilisateur n'a pas saisi des caractères qui peuvent se convertir
en nombre, une exception est levée lorsque la fonction int
essaie de convertir la donnée transmise par input,
le bloc de code du try est interrompu et le bloc de code du
except s'exécute:'''
print("la donnée saisie n’est pas valide")
Pré-conditions - Post-conditions
L’instruction assert , combine un test de condition et déclenche une exception de type AssertionError avec un affichage personnalisé, exemple :
assert len(t) > 0, "le tableau ne doit pas être vide"

On distinguera deux types d'utilisation d'assert:
Les pré-conditions
On peut utiliser assert comme précondition à l’exécution d’un bloc de code. Si l’assertion s’avère fausse le code s’interrompt et une exception de type AssertionError est levée.
Exemple de code:
def indice_du_minimum_tableau(t: List[int]) -> int:
""" Cette fonction renvoie l’indice du plus petit des nombres
d’un tableau non vide d’entiers """
indice_minimum = 0
# avant l'exécution de la boucle, on vérifie que le tableau n'est pas vide
assert len(t) > 0, "le tableau ne doit pas être vide"
for i in range(len(t)):
if t[i] < t[indice_minimum]:
indice_minimum = i
return indice_minimum
L’instruction assert peut être combinée avec la fonction isinstance(une_donnée, un_type) pour vérifier que la donnée une_donnée est du type un_type. La fonction isinstance(..) renvoie True si le premier argument (une_donnée) est du type donné en second argument (un_type), exemples:
isinstance( 5, int ) : renvoie True parce que 5 est bien un objet de type int
isinstance( 5.0, int ) : renvoie False parce que 5.0 est un objet de type float
Exemple de code:
def indice_du_minimum_tableau(t: List[int]) -> int:
""" Cette fonction renvoie l’indice du plus petit des nombres
d’un tableau non vide d’entiers """
indice_minimum = 0
# avant l'exécution de la boucle, on vérifie que le tableau n'est pas vide:
assert len(t) > 0, "le tableau ne doit pas être vide"
for i in range(len(t)):
# avant de comparer l'élément du tableau, on vérifie son type:
assert isinstance( t[i], int ) , " le tableau ne doit contenir que des nombres entiers"
if t[i] < t[indice_minimum]:
indice_minimum = i
return indice_minimum
Les post-conditions
On peut utiliser des assertions comme post-conditions, dans ce cas l’assertion permet de vérifier la correction du code (si le programme donne bien les résultats attendus).
Exemple de code:
Par exemple pour la fonction indice_du_minimum_tableau, si l'argument est:
[ 1, 2, 3, -4, 5] alors elle doit renvoyer l’indice 3
[ 1, 2, 3, 4, 5] elle doit renvoyer l’indice 0
On codera ces deux tests ainsi:
def indice_du_minimum_tableau(t: List[int]) -> int:
""" Cette fonction renvoie l’indice du plus petit des nombres
d’un tableau non vide d’entiers """
indice_minimum = 0
# avant l'exécution de la boucle, on vérifie que le tableau n'est pas vide:
assert len(t) > 0, "le tableau ne doit pas être vide"
for i in range(len(t)):
# avant de comparer l'élément du tableau, on vérifie son type:
assert isinstance( t[i], int ) , " le tableau ne doit contenir que des nombres entiers"
if t[i] < t[indice_minimum]:
indice_minimum = i
return indice_minimum
# les deux post-conditions
assert indice_du_minimum_tableau([ 1, 2, 3, -4, 5]) == 3
assert indice_du_minimum_tableau([ 1, 2, 3, 4, 5]) == 0
Il est difficile d’être exhaustif (prévoir tous les cas possibles).
Voici quelques points qu’il convient de vérifier.
- Si le programme traite plusieurs cas, chacun des cas doit être testé.
- Si une fonction renvoie une valeur booléenne ( True, False), il faut tester que les deux valeurs soient bien obtenues.
- Si le programme manipule un tableau il faut tester pour un tableau vide.
- Si le programme manipule un nombre entier, il faut tester pour une valeur négative et nulle.
- Si le programme manipule un intervalle, il faut tester les valeurs limites de cet intervalle. Cas très fréquent dans les boucles range(min, max).
Programmation défensive
Les assertions décrites précédemment servent en phase de tests. Un code qui doit être en "production" doit intégrer une programmation défensive, c'est à dire anticiper les situations non conformes et donner un résultat en adéquation avec les données manipulées. Dans le cas d'une fonction qui doit renvoyer l'indice du plus petit nombre d'une liste, l'objet None peut être renvoyé pour signifier que le code ne peut pas donner de résultat cohérent quand la liste est vide ou si les données sont de types différents et donc incomparables par exemple.
On peut utiliser des tests et la fonction isinstance() mais pas d'assertions.
def indice_du_minimum_tableau(t: List[int]) -> int:
""" Cette fonction renvoie l’indice du plus petit des nombres
d’un tableau non vide d’entiers """
# avant l'exécution de la boucle, on vérifie que le tableau n'est pas vide:
if len(t) == 0:
return None
indice_minimum = 0
for i in range(len(t)):
# on teste la nature de la donnée avant le test:
if isinstance(t[i],int ):
if t[i] < t[indice_minimum]:
indice_minimum = i
# si if est False, on renvoie None
else:
return None
# à la fin de la boucle, on renvoie l'indice
return indice_minimum