Exercice 05 - Compréhension de scripts Python
Table des matières
Mise en situation
Pour comprendre un nouveau langage de programmation, on doit souvent regarder des exemples. Des codes qu'un collègue à fait et qui n'est pas toujours bien commenté s'il jugeait cela simple.
Mais, bien sûr, quand on commence rien n'est simple! À vous de jouer pour comprendre le fonctionnement des scripts!
Modalités
- Exercice individuel
- Réaliser durant le cours
- Durée approximative le reste du cours
- Cet exercice doit être zippé et remis dans Exercice 05 sur Léa pour la fin de la journée.
À faire (étapes)
Premier script à analyser
- Copier le script complet dans un fichier nommé fib.py
- Ouvrir le script dans VS Code
- Lire au complet le script à analyser
- Commenter chacune des lignes avec ce que vous pensez que la ligne fait
Ex: # Boucle qui permet de... - À quoi pensez vous que le script sert concrètement?
Code Python
def fib(n):
a = 0
b = 1
c = 0
while c < n:
t = b
b = a + b
a = t
c = c + 1
return a
if __name__ == "__main__":
position = int(input("Enter the position you seek: "))
rep = fib(position)
print("The value at position (" + str(position) + ") is: " + str(rep))
Deuxième script à analyser
Cet exercice couvre les concepts suivants :
- Importation de modules (random)
- Définition de fonction
- Variables et types de données (int, string)
- Génération de nombres aléatoires
- Boucles (while)
- Conditions (if, elif, else)
- Conversion de types (int())
- Entrées utilisateur (input())
- Affichage (print())
- Opérateurs de comparaison
- F-strings pour le formatage de chaînes
Pour réaliser cet exercice :
- Copiez ce code dans un fichier Python (par exemple, devinette.py).
- Exécutez le script et jouez au jeu.
- Essayez de comprendre comment chaque partie du code fonctionne.
- Mettez un commentaire pour chaque concepts numérotés précédant
Ex:# 1. Importation de modules (random) import random
MODE EXPERT
Ensuite, vous pourriez essayer de modifier le code pour : - Changer la plage de nombres (par exemple, de 1 à 200)
- Modifier le nombre maximum de tentatives
- Ajouter un système de score basé sur le nombre de tentatives utilisées
Code Python
import random
def deviner_nombre():
# Générer un nombre aléatoire entre 1 et 100
nombre_secret = random.randint(1, 100)
tentatives = 0
max_tentatives = 7
print("Bienvenue dans le jeu de devinette !")
print(f"Devinez un nombre entre 1 et 100. Vous avez {max_tentatives} tentatives.")
while tentatives < max_tentatives:
# Demander à l'utilisateur de deviner
essai = input("Entrez votre guess : ")
# Vérifier si l'entrée est un nombre valide
if not essai.isdigit():
print("Veuillez entrer un nombre valide.")
continue
essai = int(essai)
tentatives += 1
# Vérifier si le guess est correct
if essai == nombre_secret:
print(f"Bravo ! Vous avez deviné le nombre en {tentatives} tentatives.")
return
elif essai < nombre_secret:
print("Le nombre est plus grand.")
else:
print("Le nombre est plus petit.")
# Afficher le nombre de tentatives restantes
restantes = max_tentatives - tentatives
print(f"Il vous reste {restantes} tentative(s).")
print(f"Désolé, vous avez épuisé vos {max_tentatives} tentatives. Le nombre était {nombre_secret}.")
if __name__ == "__main__":
# Lancer le jeu
deviner_nombre()
Troisième script à corriger (10 erreurs)
Mise en situation
Tu reçois un petit utilitaire censé vérifier rapidement si une adresse IPv4 est valide et si elle appartient à un espace privé. Problème : le script contient 10 erreurs. À toi de les repérer et de les corriger.
Concepts couverts
- Fonctions et paramètres
- Chaînes, listes, boucles et conditions
- Conversions de types (
int(...)
) - F-strings
- Gestion d’erreurs courantes (NameError, TypeError, ValueError, SyntaxError)
- Module standard
random
À faire (étapes)
- Copier le script ci-dessous dans un fichier nommé
ip_checker.py
. - Ouvrir dans VS Code.
- Exécuter et corriger les erreurs une à une (l’interpréteur s’arrête à la première erreur).
- Pour chaque correction, ajouter un commentaire expliquant le problème.
- Quand le programme tourne, tester avec quelques adresses (ex.:
192.168.1.10
,10.0.0.5
,172.20.3.4
,256.1.1.1
,abc.def.ghi.jkl
).
Code Python
# ip_checker.py
import random
def valider_ipv4(adresse) # 1) <- erreur
octets = adresse.split('.')
if len(octets) != 5: # 2) <- erreur
return False
for i in range(1, len(octets)): # 3) <- erreur
octet = octets[i]
if octet == "":
print("Octet vide détecté")
if int(octet) < 0 or int(octet) > "255": # 4) <- erreur
return False
return True
def est_prive(ip):
o = ip.split('.')
if int(o[0]) == 10:
return True
elif int(o[0]) == 172 and 16 <= int(o[1]) <= 31:
return True
elif o[0] == 192 and o[1] == 168: # 5) <- erreur
return True
else:
return False
def main():
adresse = input("Entrez une adresse IPv4: ")
if not valider_ip(adresse): # 6) <- erreur
print("Adresse IPv4 invalide")
else:
if est_prive(adress): # 7) <- erreur
print("Adresse privée")
else:
print(f"Adresse publique: {adresse") # 8) <- erreur
tentative = random.randint(100, 1) # 9) <- erreur
print("Nombre aléatoire: " + tentative) # 10) <- erreur
if __name__ == "__main__":
main()
(Optionnel) Améliorations “MODE EXPERT”
- Validation plus robuste : refuser les octets avec des zéros de tête non désirés (
"01"
), ou imposer0–255
+isdigit()
. - Gestion des cas limites :
''
, espaces, caractères non numériques → retournerFalse
proprement. -
Module standard
ipaddress
: pour valider et classifier les adresses sans réécrire la roue.import ipaddress def est_valide(adresse): try: ip = ipaddress.IPv4Address(adresse) return True except ipaddress.AddressValueError: return False def est_prive_ipaddress(adresse): return ipaddress.IPv4Address(adresse).is_private
Solution
-
Deux-points manquant après la définition de fonction
Ligne fautive :def valider_ipv4(adresse)
Problème :
SyntaxError
— en Python, un bloc de fonction doit se terminer par:
.
Correction :def valider_ipv4(adresse):
-
Mauvaise longueur d’adresse IPv4
Ligne fautive :if len(octets) != 5:
Problème : Une IPv4 doit avoir 4 octets, pas 5. C’est une erreur logique.
Correction :if len(octets) != 4: return False
-
Boucle qui saute le premier octet (off-by-one)
Ligne fautive :for i in range(1, len(octets)):
Problème : En partant à 1, on ignore l’octet d’indice 0.
Correction (par indices) :for i in range(0, len(octets)):
ou, plus Pythonique :
for octet in octets:
-
Comparaison entre
int
etstr
Ligne fautive :if int(octet) < 0 or int(octet) > "255":
Problème :
"255"
est une chaîne. Comparerint
àstr
lèveTypeError
.
Correction :if int(octet) < 0 or int(octet) > 255:
Bonus robustesse : vérifier que
octet
ne contient que des chiffres avant leint(octet)
:if not octet.isdigit(): return False
-
Comparaison de chaînes avec des entiers dans
est_prive
Ligne fautive :elif o[0] == 192 and o[1] == 168:
Problème :
o[0]
eto[1]
sont des chaînes. Comparées à des entiers, l’expression est toujours fausse → erreur logique.
Correction (convertir avant) :elif int(o[0]) == 192 and int(o[1]) == 168: return True
-
Appel d’une fonction qui n’existe pas (
valider_ip
vsvalider_ipv4
)
Ligne fautive :if not valider_ip(adresse):
Problème :
NameError
— faute de frappe dans le nom de fonction.
Correction :if not valider_ipv4(adresse):
-
Variable mal orthographiée (
adress
vsadresse
)
Ligne fautive :if est_prive(adress):
Problème :
NameError
— variable inexistante.
Correction :if est_prive(adresse):
-
F-string mal fermée (parenthèse/accolade manquante)
Ligne fautive :print(f"Adresse publique: {adresse")
Problème :
SyntaxError
— il manque la}
(et la parenthèse deprint
se ferme trop tôt).
Correction :print(f"Adresse publique: {adresse}")
-
Bornes inversées dans
random.randint
Ligne fautive :tentative = random.randint(100, 1)
Problème :
ValueError
— pourrandint(a, b)
, on doit avoira <= b
.
Correction :tentative = random.randint(1, 100)
-
Concaténation
str
+int
Ligne fautive :
print("Nombre aléatoire: " + tentative)
Problème : TypeError
— on ne peut pas concaténer une chaîne et un entier.
Correction (deux options) :
print("Nombre aléatoire: " + str(tentative))
# ou
print(f"Nombre aléatoire: {tentative}")