Aller au contenu
English

Conditions et répétitions

  • Leçon 6
  • 45 min
  • Module 2 : Valeurs et flux de contrôle
Leçon 6 sur 18 · Python pour l'ingénierie de l'IA en pratiqueConditions et répétitions

Ce que vous saurez faire

Écrivez la première vraie partie de ticket-cleaner : un script qui garde seulement les billets de soutien ayant un statut donné. Il les compte ensuite par catégorie. Il doit aussi donner une réponse correcte quand il n’y a aucun billet, car les données réelles sont parfois vides.

Carnet JupyterFaites cette leçon dans un carnet JupyterColab · Kaggle · GitHub · en anglais

Le carnet (notebook) Jupyter contient tous les exemples, exercices et vérifications de cette leçon, avec les consignes. Sa première cellule crée un dossier ticket-cleaner pour count_tickets.py. Il fonctionne donc sans votre projet local. Aucune installation n’est nécessaire. Lisez les explications ici et exécutez le code dans le carnet.

Le carnet est en anglais. Colab et Kaggle ouvrent votre propre copie. Il faut un compte Google ou Kaggle gratuit. Vous êtes bloqué ? Consultez le carnet de solution.

Avant de commencerCe qu’il faut savoir et avoir sous la mainEnviron 45 minutes

Ce que vous devez savoir

Ce qu’il vous faut sur votre ordinateur (seulement pour travailler localement; le carnet et les encadrés de cette page n’en ont pas besoin)

Testé avec Python 3.14 (terminal) et Pyodide 314.0 (navigateur). Le carnet a été testé dans Jupyter.

Une instruction if exécute certaines lignes seulement quand une condition vaut True (vrai). Ici, le numéro de priorité de chaque billet devient une étiquette :

if priority == 1:
label = "urgent"
elif priority == 2:
label = "normal"
else:
label = "low"

Python vérifie les conditions à partir du haut. Il exécute le bloc sous la première condition qui vaut True et ignore tous les autres. elif signifie « sinon, si ». Le bloc else s’exécute seulement quand aucune condition ne vaut True. Vous pouvez avoir plusieurs blocs elif. elif et else sont tous deux facultatifs.

Chaque ligne qui commence un bloc (if, elif, else, for) se termine par :. Les lignes du bloc ont un retrait de quatre espaces. Python utilise ce retrait pour savoir où un bloc se termine. Le retrait fait donc partie du code, pas seulement de sa présentation.

Une condition n’est pas forcément une comparaison. Python considère certaines valeurs comme fausses : 0, "", None, ainsi qu’une liste, un dictionnaire ou un ensemble vide. Toutes les autres valeurs comptent comme vraies. Ainsi, if not selected: signifie « si selected est vide ».

Dans la leçon précédente, une boucle affichait chaque élément. En général, une boucle construit un résultat. Ce modèle a trois parties : créer un résultat vide avant la boucle, le compléter dans la boucle, puis l’utiliser après.

Cette boucle garde seulement les billets ouverts :

selected = [] # 1. an empty result
for ticket in tickets:
if ticket["status"] == "open":
selected.append(ticket) # 2. add to it
print(len(selected)) # 3. use it

Exemple détaillé : compter les billets par catégorie

Section intitulée « Exemple détaillé : compter les billets par catégorie »

La tâche : compter les billets pour chaque catégorie. Le résultat est un dictionnaire : chaque clé est une catégorie et chaque valeur est un nombre de billets.

category_counts = {}
for ticket in tickets:
category = ticket["category"]
category_counts[category] = category_counts.get(category, 0) + 1

La dernière ligne fait le travail. category_counts.get(category, 0) donne le nombre actuel, ou 0 quand une catégorie apparaît pour la première fois. Ensuite, + 1 ajoute ce billet, et le résultat retourne dans le dictionnaire.

Une trace de boucle montre l’état après chaque étape de la boucle. Voici celle des six billets :

Étape ticket["id"] category category_counts après l’étape
1 T-1001 billing {'billing': 1}
2 T-1002 login {'billing': 1, 'login': 1}
3 T-1003 login {'billing': 1, 'login': 2}
4 T-1004 billing {'billing': 2, 'login': 2}
5 T-1005 billing {'billing': 3, 'login': 2}
6 T-1006 shipping {'billing': 3, 'login': 2, 'shipping': 1}

Aux étapes 1 et 6, la catégorie est nouvelle, donc .get() donne 0. Aux autres étapes, il donne le nombre obtenu à une étape précédente.

Exécutez du Python dans votre navigateur

Tracez vous-même la boucle

Le print dans la boucle produit la même trace que le tableau. Modifiez la boucle pour compter par "status" (statut) plutôt que par "category" (catégorie). Prédisez d’abord le résultat.

Parfois, vous n’avez pas besoin de tous les éléments. Deux instructions changent le déroulement d’une boucle :

  • break termine la boucle immédiatement. Utilisez-le quand vous avez trouvé ce que vous cherchiez.
  • continue termine seulement l’étape actuelle et passe à l’élément suivant. Utilisez-le pour sauter des éléments.

Cette boucle trouve le premier billet ouvert de priorité 1 et s’arrête là :

Exécutez du Python dans votre navigateur

Arrêtez à la première correspondance

Combien de lignes checking (vérification) prévoyez-vous? Exécutez le code. Ensuite, supprimez la ligne break et exécutez-le de nouveau. Qu’est-ce qui change? La réponse est-elle toujours correcte?

first_urgent commence avec la valeur None. Après la boucle, None signifie « la boucle n’en a pas trouvé ». C’est un usage courant de None. Vérifiez is None après la boucle. Ne supposez pas que la boucle a trouvé un billet.

La boucle de filtrage ci-dessus est si courante que Python propose une forme plus courte, la compréhension de liste :

open_ids = [ticket["id"] for ticket in tickets if ticket["status"] == "open"]
# ['T-1001', 'T-1003', 'T-1005']

Lisez-la en trois parties : quoi mettre dans la nouvelle liste (ticket["id"]), pour chaque élément de quelle collection, et si quelle condition. La partie if est facultative. Le résultat est le même qu’avec une boucle et append.

Utilisez une compréhension si elle tient sur une ligne et se lit clairement. Si la boucle comporte plusieurs étapes ou utilise break, écrivez la boucle complète.

Écrivez maintenant le script dans votre projet. Il garde les billets ayant un statut donné et les compte par catégorie.

  1. Dans VS Code, ouvrez le dossier ticket-cleaner. Créez un fichier, count_tickets.py.

  2. Copiez les six billets de l’encadré ci-dessus dans le fichier, de tickets = [ à ].

  3. Sous la liste, ajoutez le statut voulu et la boucle de filtrage :

    count_tickets.py
    wanted_status = "open"
    # Keep only the tickets with the wanted status.
    selected = []
    for ticket in tickets:
    if ticket["status"] == wanted_status:
    selected.append(ticket)
  4. Ajoutez la boucle de comptage. Elle utilise selected, pas tickets :

    count_tickets.py (continued)
    # Count the selected tickets in each category.
    category_counts = {}
    for ticket in selected:
    category = ticket["category"]
    category_counts[category] = category_counts.get(category, 0) + 1
  5. Ajoutez le rapport. sorted() place les catégories en ordre alphabétique, pour que la sortie soit identique chaque fois :

    count_tickets.py (continued)
    print(f"Tickets with status '{wanted_status}': {len(selected)}")
    for category, count in sorted(category_counts.items()):
    print(f" {category}: {count}")
  6. Enregistrez le fichier. Dans le terminal, activez l’environnement et exécutez le script :

    Fenêtre de terminal
    python count_tickets.py
    Sortie
    Tickets with status 'open': 3
    billing: 2
    login: 1

Changez wanted_status pour "resolved" (résolu). Aucun billet n’a ce statut. Avant d’exécuter le script, prédisez la sortie. Exécutez-le ensuite.

Le script affiche Tickets with status 'resolved': 0 (billets au statut « résolu » : 0) et rien d’autre. C’est correct, mais le lecteur ne sait pas si le script a fonctionné ou s’est arrêté trop tôt. Ajoutez une condition pour que la sortie l’indique clairement :

Expected output
Tickets with status 'resolved': 0
No tickets to count.

Ajoutez ensuite une ligne au rapport : la priorité moyenne des billets sélectionnés, arrondie à une décimale. Pour "open" (ouvert), elle vaut 2.0. Pour "resolved", votre script ne doit pas s’arrêter avec une erreur.

Afficher une réponse possible
count_tickets.py (the report)
print(f"Tickets with status '{wanted_status}': {len(selected)}")
if not selected:
print("No tickets to count.")
else:
for category, count in sorted(category_counts.items()):
print(f" {category}: {count}")
total_priority = 0
for ticket in selected:
total_priority = total_priority + ticket["priority"]
average_priority = total_priority / len(selected)
print(f"Average priority: {round(average_priority, 1)}")

La moyenne est dans le bloc else. La division s’exécute donc seulement quand selected contient au moins un billet. L’erreur courante ci-dessous montre ce qui se passe sans cette condition.

Erreur courante

ZeroDivisionError avec des données d'entrée vides

Symptôme : le script fonctionne pour "open", mais s’arrête pour "resolved" :

ZeroDivisionError: division by zero

Cause : la moyenne est total / len(selected). Quand aucun billet ne correspond, len(selected) vaut 0, et la division par zéro est impossible. Le code a été testé seulement avec des données qui avaient des correspondances. Des données d’entrée vides sont un cas normal, pas un cas rare. Une nouvelle journée sans billets donne une liste vide. Un filtre avec une faute de frappe peut aussi donner ce résultat.

Correction :

  1. Décidez de la bonne réponse quand les données d’entrée sont vides. Ici : un message clair, sans moyenne.
  2. Vérifiez si les données sont vides avant la division : if not selected:.
  3. Testez le script avec des données sans correspondance chaque fois que vous le modifiez.

Vérifiez votre compréhension

Prédisez la sortie : for n in [3, 0, 5, 1]: if n == 0: continue; if n == 5: break; print(n). (Chaque partie est sur sa propre ligne, avec les retraits habituels.)

Afficher la réponse

Seulement 3. La première étape affiche 3. La deuxième étape (0) utilise continue, donc elle saute le print. La troisième étape (5) utilise break, donc la boucle se termine et 1 n’est jamais vérifié.

Vérifiez votre compréhension

Réécrivez avec une compréhension de liste : ids = []; for t in tickets : if t[« priority »] == 1: ids.append(t[« id »])

Afficher la réponse

ids = [t["id"] for t in tickets if t["priority"] == 1]. Avec les six billets, le résultat est ['T-1003', 'T-1006'].

Vérifiez votre compréhension

Vérification du module : donnez à wanted_status la valeur « closed ». Prédisez la sortie complète de count_tickets.py, puis exécutez-le. Choisissez ensuite un statut qui n'existe pas et exécutez-le de nouveau.

Afficher la réponse

Pour "closed" (fermé), la sortie est Tickets with status 'closed': 2 (billets au statut « fermé » : 2). Viennent ensuite login: 1 (connexion : 1), shipping: 1 (expédition : 1) et Average priority: 2.0 (priorité moyenne : 2,0). Les billets T-1002 et T-1006 ont les priorités 3 et 1. Pour un statut inexistant, la sortie donne le nombre 0 et No tickets to count. (aucun billet à compter), sans erreur. Si votre prédiction était différente, faites une trace de boucle pour la partie qui vous a surpris.

Récapitulatif

  • if, elif et else exécutent le bloc de la première condition vraie. Un retrait de quatre espaces marque chaque bloc.
  • Une boucle qui construit un résultat a trois parties : un résultat vide avant, des ajouts pendant, une utilisation après.
  • dict.get(key, 0) + 1 compte les éléments par clé.
  • break termine une boucle. continue passe à l’élément suivant. Initialisez une variable de recherche à None et vérifiez-la après la boucle.
  • Une compréhension de liste est un filtre court : [what for item in items if condition].
  • Testez toujours avec des données d’entrée vides. Vérifiez ce cas avant de diviser par un nombre d’éléments.

Vous pouvez maintenant filtrer et compter des données dans un script. Dans le prochain module, vous diviserez count_tickets.py en fonctions ayant chacune une tâche, pour pouvoir tester chaque partie.

Leçon suivante : Le contrat d'une fonction