Les conteneurs Python
💻 Travail n° 1 Jours de la semaine
🎯 Travail à faire :
-
Constituer une liste
semainecontenant les 7 jours de la semaine. -
À partir de cette liste, donner les expressions permettant de récupérer seulement les 5 premiers jours de la semaine d’une part, et ceux du week-end d’autre part en utilisant le slicing avec des indices positifs.
-
Même question en utilisant des indices négatifs.
-
Trouver 2 expressions différentes permettant d’accéder au dernier jour de la semaine.
-
Inverser les jours de la semaine en une seule expression.
💻 Travail n° 2 Nombre de voyelles et de consonnes d’une phrase
🎯 Travail à faire :
On vous donne une expression Python qui permet d’initialiser une liste avec toutes les lettres minuscules de l’alphabet :
alphabet = [chr(lettre) for lettre in range(ord('a'), ord('z') + 1)]
Explication détaillée de cette expression :
Cette expression — qui utilise une compréhension de liste — évite d’avoir à écrire manuellement toutes les lettres de l’alphabet, ce qui la rend plus flexible et moins sujette aux erreurs.
-
ord('a')etord('z'):
La fonctionord()renvoie la valeur Unicode d’un caractère. Ainsi,ord('a')renvoie 97 (la valeur Unicode de 'a') etord('z')renvoie 122 (la valeur Unicode de 'z'). -
range(ord('a'), ord('z') + 1):
Cette partie crée une séquence de nombres allant de 97 à 122 inclus. Le+ 1est nécessaire carrange()n’inclut pas la borne supérieure. -
chr(lettre):
La fonctionchr()est l’inverse deord(). Elle prend une valeur Unicode et renvoie le caractère correspondant. Ici, elle convertit chaque nombre de la séquence en sa lettre correspondante. -
[chr(lettre) for lettre in …]:
C’est une compréhension de liste. Elle parcourt chaque nombre de la séquence créée parrange(), convertit ce nombre en lettre avecchr(), et ajoute cette lettre à la nouvelle liste.
Le résultat final est une liste contenant toutes les lettres minuscules de 'a' à 'z'.
Faire un script qui :
-
demande à l’utilisateur de saisir une phrase
-
détermine et affiche le nombre de voyelles et de consonnes contenues dans cette phrase
Vous utiliserez pour cela 2 listes : voyelles et consonnes.
La liste consonnes sera initialisée obligatoirement à partir d’une compréhension de liste sachant que l’alphabet comporte 6 voyelles (→ '‘a’, ‘e’, ‘i’, ‘o’, ‘u’, ‘y’) et qu’une consonne est une lettre de l’alphabet … qui n’est pas une voyelle !
Une fois les 2 listes voyelles et consonnes initialisées, l’algorithme consiste uniquement à tester l’appartenance de chaque lettre de la phrase à une des ces 2 listes et à incrémenter un compteur le cas échéant.
Vous veillerez au fait que la phrase saisie par l’utilisateur peut contenir des majuscules : il faudra donc la convertir en minuscules avant son traitement (→ consulter Text Sequence Type — str pour trouver un moyen de le faire).
Saisir une phrase : HELLO world !
La phrase :
"HELLO world !"
contient 3 voyelles et 7 consonnes
💻 Travail n° 3 Palindrômes
🕮 Problématique :
On désire connaître le nombre de palindrômes présents dans une œuvre littéraire.
Un palindrôme est un mot ou une phrase pouvant se lire dans les 2 sens.
Exemples : kayak, radar, rotor, ressasser, “Et la marine va venir à Malte” (Victor Hugo)…
On vous demande de relever les palindrômes d’au moins 3 lettres contenus dans l’œuvre “Alice au pays des merveilles” dont le contenu intégral en ASCII vous est fourni.
Palindromes et leurs fréquences dans le fichier :
did : 50
pop : 1
eye : 4
non : 1
🎯 Travail à faire :
Compléter le code suivant pour qu’il affiche les palindrômes d’au moins 3 lettres contenus dans l’œuvre Alice au pays des merveilles et leur fréquence.
import sys
def est_palindrome(mot: str) -> bool: (1)
'''Retourne True si le mot est un palindrome d'au moins
3 lettres), False sinon.''' (2)
# **A COMPLETER**
pass (3)
def compter_palindromes_avec_frequence() -> dict:
'''Compte les palindromes dans un fichier texte
et retourne un dictionnaire {palindrome: fréquence}.'''
# initialisations :
# . fichier à traiter
nom_fichier = "./alice-au-pays-des-merveilles.txt"
# . dictionnaire des palindromes et de leur fréquence
dictionnaire = {}
# lecture du fichier
try: (5)
with open(nom_fichier, 'r', encoding='ascii') as fichier : (4)
# Repérer les palindrômes par ligne en testant chaque mot qui la compose
# puis comptabiliser leur fréquence dans un dictionnaire
# **A COMPLETER**
for ligne in fichier :
# Découper 'ligne' en mots
# POUR chaque mot de 'ligne' FAIRE :
# | SI mot est un palindrome ALORS :
# | | SI mot n'est pas dans 'dictionnaire' ALORS :
# | | | Ajouter mot comme clé dans 'dictionnaire' et lui donner la valeur 1
# | | SINON
# | | | Incrémenter la valeur de la clé du mot déjà présent dans 'dictionnaire'
# | | FINSI
# | FINSI
# FINPOUR
pass
except FileNotFoundError: (5)
print(f"Erreur : Le fichier '{fichier}' est introuvable.", file=sys.stderr)
return dictionnaire
# POINT D'ENTRÉE DU SCRIPT
if __name__ == "__main__": (6)
# Comptage des palindromes dans le fichier
palindromes = compter_palindromes_avec_frequence()
# Affichage des palindromes et de leur fréquence
if( palindromes ) :
print("Palindromes et leurs fréquences dans le fichier :")
# **A COMPLETER**
| 1 | Annotation de type voir détails ci-dessous |
| 2 | Docstring voir détails ci-dessous |
| 3 | pass voir détails ci-dessous |
| 4 | with voir détails ci-dessous |
| 5 | try…except… voir détails ci-dessous |
| 6 | if name == "main": voir détails ci-dessous |
Détails :
-
Annotation de type :
C’est une nouvelle façon de déclarer une fonction depuis Python v3.5.
On spécifie le type des arguments (icistrpourmot) et celui de la valeur retournée (icibool).
L’annotation de type n’est pas requise par l’interpréteur mais peut être utilisée par des outils (IDE, analyseurs de code…) pour détecter/signaler des erreurs. -
Docstring :
Une chaîne de caractère délimitée par'''…'''ou"""…"""qui suit la définition d’une fonction constitue sa documentation.
Elle est utilisée notamment par la fonctionhelp()de PythonExemple du résultat dehelp()appliqué au fichier :$ python >>> import palindrome_eleve >>> help(palindrome_eleve) Help on module palindrome_eleve: NAME palindrome_eleve FUNCTIONS compter_palindromes_avec_frequence() -> dict Compte les palindromes dans un fichier texte et retourne un dictionnaire {palidrome: fréquence}. est_palindrome(mot: str) -> bool Retourne True si le mot est un palindrome (au moins 3 lettres), False sinon. FILE d:\enseignement\bts-ciel-codebase\d2\python\palindrome_eleve.py -
pass:
L’instructionpassde Python est utilisée pour marquer un morceau de code pas encore implémenté en évitant le signalement d’erreur par l’interpréteur -
with:
withest une instruction qui facilite la gestion des ressources en garantissant que les opérations d’initialisation et de finalisation sont effectuées de manière cohérente et fiable.
C’est la façon recommandée pour ouvrir un fichier en Python. Celle-ci permet en effet de le fermer automatiquement dès qu’on sort du bloc.L’argument
'r'dansopen()signifie qu’on ouvre le fichier en lecture seuleL’argument
encoding='ascii'signifie que le fichier est censé être encodé en ASCII. Si ce n’est pas le cas (exemple utf-8), l’ouverture échouera.with open()retourne un objet itérable : on peut le parcourir avecin. Ici, l’expressionfor ligne in f :permettra d’accéder à chaque ligne du fichier. -
try…except…:
En Python, mettre du code dans un bloctry … exceptpermet de gérer les situations d’erreurs. Ici, on traite le cas où le fichier n’est pas accessible dans le chemin fourni àopen() -
if name == "main"::
Regrouper le code principal du script dans le blocif name == "main":est une pratique courante.
Avec cette construction, le code sera évalué lorsqu’on exécute le script et pas quand on l’importe.
Ceci permet d’écrire des modules Python que l’on peut malgré tout exécuter comme des scripts normaux (pour les tester, par exemple).
💻 Travail n° 4 Analyse de log
🕮 Problématique :
On désire exploiter le fichier journal d’un serveur web pour en extraire des métriques mais également pour déceler les connexions suspectes.
On met à votre disposition le fichier contenant toutes les requêtes HTTP qui ont eu lieu le 1er Août 1995 sur le serveur web du centre spatial Kennedy de la NASA situé en Floride.
Ce fichier est au format CLF .
Il est contenu dans une archive au format .gz (→ gzip)
🎯 Travail à faire :
-
Télécharger localement le fichier journal NASA_access_log_1Aug95.txt.gz
-
Ouvrir et analyser manuellement le fichier journal dans un éditeur de texte pour retrouver les informations du format CLF
.
-
Lire le fichier de logs en utilisant le module
gzipet “parser” chaque ligne depuis une fonctionparserLog(log_gz)d’un script Python.Extraire au moins :
-
L’adresse IP ou le host
-
Le code de réponse HTTP (200, 404, etc.)
-
La ressource demandée
Exemple d’utilisation du modulegzip:# Ouvrir l'archive .gz with gzip.open("dummy-file.gz", 'rt', encoding='utf-8', errors='ignore') as f: # POUR chaque ligne du fichier FAIRE for ligne in f: # Parser la ligne passLa fonction
split()peut suffire à décomposer chaque ligne du fichier.La fonction retournera une liste de tuples :
Prototype de la fonctionparserLog()avec annotation de type :def parserLog(log_gz : str) -> list[tuple[str, str, str]] : pass
-
-
Définir une fonction
compterErreurs()qui retournera dans un dictionnaire pour chaque IP/host le nombre d’erreurs HTTP (erreurs : 401, 403, 404, 500) relevées -
Lister les IPs/hosts suspects ayant plus de 20 erreurs
-
Définir une fonction
trouverTop5Ressources()qui retourne un dictionnaire contenant le top 5 des ressources disponibles demandées (celles pour lesquelles la requête GET retourne le code 200)Pour trier un dictionnaire, on pourra utiliser la fonction
sorted()de Python.Exemple de tri d’un dictionnaire pour récupérer les formations par effectif décroissant :>>> formations = {'BTS CIEL 1 ER' : 14, 'BTS CIEL 2 ER': 7, 'BTS CIEL 1 IR' : 16 , 'BTS CIEL 2 IR': 11} >>> sorted(formations.items(), key=lambda x : x[1], reverse=True) [('BTS CIEL 1 IR', 16), ('BTS CIEL 1 ER', 14), ('BTS CIEL 2 IR', 11), ('B TS CIEL 2 ER', 7)]
💻 Travail n° 5 Scanner IP basique
On vous demande de coder en Python un scanner IP basique qui va tester chacune des adresses IP de notre réseau (→ 192.168.4.0/22) avec la commande ping pour voir si un hôte y est joignable.
🎯 Travail à faire :
-
Constituer une liste
hostsqui contiendra — sous forme de chaînes de caractères — toutes les adresses IP du réseau 192.168.4.0/22 (→ ['192.168.4.1'… '192.168.7.254']).Vous pouvez procéder en plusieurs étapes en constituant une liste pour chaque plage (→ 192.168.4.X, 192.168.5.Y, 192.168.6.Z, 192.168.7.T) puis en les ajoutant chacune dans la liste
hosts. -
Pinger chaque IP contenue dans la liste
hostspour voir si l’hôte correspondant est joignable puis l’ajouter dans une listereachableHostsle cas échéant.Voici une portion de code Python qui permet de pinger une adresse IP en utilisant la commande
pingde Windows :import subprocess hostIP = '192.168.4.1' (1) command = ['ping', '-w', '2000', '-n', '2', hostIP] (2) ping_response = subprocess.run(command , capture_output=True , text=True , encoding='cp437' , timeout=10 , check=False ) (3) if f"Réponse de {hostIP}" in ping_response.stdout : (4) print(f"ping {hostIP} : OK") else: print(f"ping {hostIP} : NOK")1 adresse IP à pinger 2 définition de la commande ping(avec ses options) à faire exécuter par Python3 exécution du pingpar Python. La fonctionsubprocess.run(…)peut nécessiter de nombreux paramètres. Ici, on spécifie essentiellement que l’on veut capturer (→capture_output=True)sous forme de texte (→text=True) la sortie “écran” des commandesping, encodée par défaut encp437dans la console Windows (→encoding='cp437'). Cette sortie “écran” est ensuite utilisée pour déterminer si le ping a abouti ou pas.4 test de réussite ou d’échec du ping en inspectant sa sortie “écran”. Sous Windows, on ne peut pas se contenter de tester le code de sortie de la commande ping pour déterminer si un hôte réseau est joignable ou pas. En effet, cette commande peut retourner un code OK même lorsqu’elle indique sur sa sortie écran qu’un hôte n’est pas joignable.
-
Que signifient les options “-n 2” et “-w 2000” passées à
pingdans l’exemple ci-dessus ? -
Afficher pour finir la liste des hôtes joignables sur le réseau.
SCANNING hosts in range [192.168.4.1 -> 192.168.4.6] ...
Attempt to join 192.168.4.1 -> OK
Attempt to join 192.168.4.2 -> OK
Attempt to join 192.168.4.3 -> NOK
Attempt to join 192.168.4.4 -> OK
Attempt to join 192.168.4.5 -> OK
Attempt to join 192.168.4.6 -> NOK
SCAN RESULT for range [192.168.4.1 -> 192.168.4.6] :
reachable hosts are :
192.168.4.1
192.168.4.2
192.168.4.4
192.168.4.5
Bye !
💻 Travail n° 6 Calculateur valeur de résistance
On désire faire un script Python qui donne la valeur d’une résistance électrique en Ohms à partir de la couleur des anneaux figurant dessus, un peu à la manière de ce calculateur disponible sur ce site internet
🎯 Travail à faire :
On vous donne le code partiel du script :
def getOhmsFromColors(a, b, c, d) :
pass
# Point d'entrée du script
if __name__ == "__main__":
a = "red"
b = "blue"
c = "black"
d = "brown"
# Appel de la fonction qui détermine la valeur d'une résistance
# en fonction de la couleur de ces anneaux
getOhmsFromColors(a, b, c, d)
Compléter le code de la fonction getOhmsFromColors() de façon à ce qu’elle retourne la valeur en Ohms de la résistance dont les couleurs sont passées en paramètre :
-
a= couleur du 1er anneau qui indique le 1er digit de la valeur de la résistance -
b= couleur du 2ème anneau qui indique le 1er digit de la valeur de la résistance -
c= couleur du 3ème anneau qui détermine la valeur du facteur de multiplication -
d= couleur du 4ème anneau qui donne la tolérance
Les couleurs seront spécifiées en anglais.
Vous utiliserez des dictionnaires Python pour associer les couleurs aux valeurs numériques auxquelles elles correspondent.
Vous servirez du Calculateur de code couleur des résistances à 4 anneaux mis à disposition par le distributeur de composants Digikey pour vérifier les valeurs retournées par votre script en fonction des couleurs saisies.
Le script doit également signaler une erreur si une couleur non prise en charge est fournie à la fonction getOhmsFromColors()
Resistor value (red|blue|black|brown) = 26 Ω +/-1.00% (25.74 Ω -> 26.26 Ω)
🞄 🞄 🞄
