VaultBy ENSAMIENParrainage
Notebook

Expressions régulières:

correction.ipynb

TDP 06
Expressions régulières, Math

Répondez aux questions et envoyez à votre classe room le fichier
ayant comme nom le format suivant

  • TDP_05_Python_NOM_PRENOM.ipynb

    </ul>
    

Nom Prénom : CHOUBIK Houssam

  • Écrire une fonction ERpair(nb) qui vérifie si le nombre écrit en binaire est pair (retourne 1, sinon retourne 0)
import re

def ERpair(nb):
    if re.fullmatch(r'[01]*0', nb):
        return 1
    else:
        return 0
print(ERpair('0101')) 
print(ERpair('0101 0000'))  
0
0
  • Appliquer les fonctions relatives aux expressions régulières à un texte pour :
    • Extraire tous les nombres entiers.
    • Extraire tous les nombres décimaux (ex: 9.99).
# Exemple:
ph = "Prix: 41$, Convert: 35.67€, Promo: 12$ | 10€"

entiers = re.findall(r'(?<!\.)\b\d+\b(?!\.)', ph)
decimaux = re.findall(r'\b\d+\.\d+\b', ph)

print("Entiers :", entiers)
print("Décimaux :", decimaux)
Entiers : ['41', '12', '10']
Décimaux : ['35.67']
  • Écrire une fonction mailVal(ch) qui vérifie si une chaine ch correspond à un email valide
emails = [
    "alice@gmail.com",
    "bob@ensam.ac.ma",
    "john.doe@company.org",
    "wrong.email@com",
    "no-at-symbol.com"
]
def mailVal(ch):
    pattern = r'^[\w\.-]+@[\w\.-]+\.\w{2,}$'
    return bool(re.fullmatch(pattern, ch))
for e in emails:
    print(e, "->", mailVal(e))
alice@gmail.com -> True
bob@ensam.ac.ma -> True
john.doe@company.org -> True
wrong.email@com -> False
no-at-symbol.com -> False
  • Écrire une fonction validImm(h) qui vérifie si la chaîne h correspond à une plaque d'immatriculation marocaine:
    • Exemples:
      • "7688 | A | 1" est valide
      • "0042 | B | 05" est invalide
def validImm(h):
    pattern = r'^[1-9]\d{0,3}\s*\|\s*[A-Z]\s*\|\s*[1-9]\d?$'
    return bool(re.fullmatch(pattern, h))
print(validImm("7688 | A | 1"))
print(validImm("0042 | B | 05"))
True
False
  • Écrire une fonction validHeure(h) qui vérifie si la chaîne h est une heure valide au format HH:MM:SS (de 00:00:00 à 23:59:59)
def validHeure(h):
    import re
    pattern = r'^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$'
    return bool(re.fullmatch(pattern, h))
h='24:33:55'
print(validHeure(h))
False
  • Écrire une fonction validTel(PN) qui vérifie si la chaîne PN est un numéro de téléphone valide
def validTel(PN):
    pattern = r'^(?:\+212|0)(6|7)\d{8}$'
    return bool(re.fullmatch(pattern, PN))
print(validTel("0612345678"), validTel("+212712345678"), validTel("0512345678"))
True True False
  • Écrire une fonction qui supprime tous les caractères spéciaux, ponctuations ... d’un texte :
  • Exemple :
    texte = "Bonjour!!! Python@@@ est*** magnifique..."
    Résultat attendu : "Bonjour Python est magnifique"
text = "Bonjour!!! Python@@@ est*** magnifique..."
n_text = re.sub(r'[^A-Za-zÀ-ÖØ-öø-ÿ0-9\s]', '', text)
print(n_text)
Bonjour Python est magnifique

Créer un fichier text qui contient des enregistrements comme :

...
[INFO] 2025-11-02 10:45:23 - User Alice connected
[ERROR] 2025-11-02 10:46:01 - Connection timeout
[WARNING] 2025-11-02 10:47:15 - Low disk space
[INFO] 2025-11-02 10:48:05 - User Bob disconnected
...

Taches à réaliser : - lire le fichier ligne par ligne, - Extraire et ranger dans une liste puis afficher (en utilisant les expressions régulières): - tous les timestamps (formats YYYY-MM-DD HH:MM:SS), - toutes les dates (formats YYYY-MM-DD), - toutes les heures (formats HH:MM:SS), - tous les niveaux de log (INFO, ERROR, WARNING), - si c'est [Info] tous les noms d’utilisateur (après le mot User). - Diviser le fichier par niveaux de log : 3 fichiers résultants : INFO.txt , ERROR.txt , WARNING.txt

  • Exemple:
    • Timestamps: ['2025-11-02 10:45:23', '2025-11-02 10:46:01', '2025-11-02 10:47:15', '2025-11-02 10:48:05']
    • Levels: ['INFO', 'ERROR', 'WARNING', 'INFO']
    • Users: ['Alice', 'Bob']
logs="""[INFO] 2025-11-02 10:45:23 - User Alice connected
[ERROR] 2025-11-02 10:46:01 - Connection timeout
[WARNING] 2025-11-02 10:47:15 - Low disk space
[INFO] 2025-11-02 10:48:05 - User Bob disconnected
[INFO] 2025-11-02 25:00:00 - User Eve connected
[ERROR] 2025-02-30 12:00:00 - Invalid date
"""

with open("logs.txt", "w") as f:
    f.write(logs)
import re
fichier = "logs.txt"

timestamps = []
dates = []
heures = []
niveaux = []
utilisateurs = []

fichiers_logs = {
    "INFO": [],
    "ERROR": [],
    "WARNING": []
}

regex_timestamp = r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'
regex_date = r'\d{4}-\d{2}-\d{2}'
regex_heure = r'\d{2}:\d{2}:\d{2}'
regex_niveau = r'\[(INFO|ERROR|WARNING)\]'
regex_user = r'User (\w+)'

def heure_valide(h):
    motif = r'^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$'
    return bool(re.fullmatch(motif, h))

def date_valide(d):
    motif = r'^(?:[12]\d{3})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$'
    m = re.fullmatch(motif, d)
    if not m:
        return False
    annee, mois, jour = map(int, d.split('-'))
    if mois in [4, 6, 9, 11] and jour > 30:
        return False
    if mois == 2 and jour > 29:
        return False
    return True

with open(fichier, "r") as f:
    for ligne in f:
        ligne = ligne.strip()
        
        
        ts_match = re.search(regex_timestamp, ligne)
        if ts_match:
            ts = ts_match.group()
            date_part, heure_part = ts.split(' ')
            if date_valide(date_part) and heure_valide(heure_part):
                timestamps.append(ts)
                dates.append(date_part)
                heures.append(heure_part)
        
        n = re.search(regex_niveau, ligne)
        if n:
            niveau = n.group(1)
            niveaux.append(niveau)
            fichiers_logs[niveau].append(ligne)
            
            if niveau == "INFO":
                u = re.search(regex_user, ligne)
                if u:
                    utilisateurs.append(u.group(1))

print("Timestamps :", timestamps)
print("Dates :", dates)
print("Heures :", heures)
print("Niveaux :", niveaux)
print("Utilisateurs (INFO) :", utilisateurs)

for niveau, lignes in fichiers_logs.items():
    nom_fichier = f"{niveau}.txt"
    with open(nom_fichier, "w") as f:
        for l in lignes:
            f.write(l + "\n")
Timestamps : ['2025-11-02 10:45:23', '2025-11-02 10:46:01', '2025-11-02 10:47:15', '2025-11-02 10:48:05']
Dates : ['2025-11-02', '2025-11-02', '2025-11-02', '2025-11-02']
Heures : ['10:45:23', '10:46:01', '10:47:15', '10:48:05']
Niveaux : ['INFO', 'ERROR', 'WARNING', 'INFO', 'INFO', 'ERROR']
Utilisateurs (INFO) : ['Alice', 'Bob', 'Eve']

Optionnel :

  • Écrire une fonction MultTrois(nb) qui vérifie si le nombre écrit en binaire est multiple de 3 (retourne 1, sinon retourne 0)
def MultTrois(nb):
    return int(int(nb, 2) % 3 == 0) 
print(MultTrois('110'), MultTrois('111'))
1 0

Vecteurs propres, Valeurs propores:

  • Soit la matrice M = [[2, 1], [1, 2]].
    • Calcule ses valeurs propres et vecteurs propres avec numpy.
import numpy as np

M = np.array([[2, 1], [1, 2]])
valeurs_propres, vecteurs_propres = np.linalg.eig(M)

print("Valeurs propres :", valeurs_propres)
print("Vecteurs propres :\n", vecteurs_propres)
Valeurs propres : [3. 1.]
Vecteurs propres :
 [[ 0.70710678 -0.70710678]
 [ 0.70710678  0.70710678]]
  • Vérifie que pour chaque vecteur propre v et valeur propre λ de M, on a M @ v = λ * v.
for i in range(len(valeurs_propres)):
    v = vecteurs_propres[:, i]
    λ = valeurs_propres[i]
    print(np.allclose(M @ v, λ * v))
True
True

POO : héritage

  1. Créer une classe Forme avec une méthode surface() qui retourne 0.
  1. Créer une classe Rectangle qui hérite de Forme et possède les attributs longueur et largeur. Implémente la méthode surface() pour calculer l’aire du rectangle.
class Forme:
    def surface(self):
        pass

class Rectangle(Forme):
    def __init__(self, longueur, largeur):
        self.longueur = longueur
        self.largeur = largeur
    
    def surface(self):
        return self.longueur * self.largeur
  1. Créer une classe Carre qui hérite de Rectangle. Son constructeur prend un seul paramètre cote et utilise le constructeur du rectangle en fixant longueur = largeur = cote.
class Carre(Rectangle):
    def __init__(self, cote):
        super().__init__(cote, cote)
  1. Créer une classe Triangle qui hérite de Forme avec les attributs base et hauteur. Implémente la méthode surface() pour calculer l’aire du triangle (base * hauteur / 2).
class Triangle(Forme):
    def __init__(self, base, hauteur):
        self.base = base
        self.hauteur = hauteur
    
    def surface(self):
        return (self.base * self.hauteur) / 2
  1. Créer des objets de chaque type (Rectangle, Carre, Triangle) et affiche leur surface.
r = Rectangle(8, 4)
c = Carre(8)
t = Triangle(7, 3)
print("Surface rectangle:", r.surface())
print("Surface carré:", c.surface())
print("Surface triangle:", t.surface())
Surface rectangle: 32
Surface carré: 64
Surface triangle: 10.5

Exercice :

Un professeur a enregistré les notes de 5 étudiants dans 3 matières différentes dans une matrice NumPy :

notes = np.array([[12, 15, 14],
                  [10, 13, 11],
                  [14, 16, 15],
                  [9,  12, 10],
                  [13, 14, 13]])

  • Calculer la moyenne de chaque étudiant
import numpy as np

notes = np.array([
    [12, 15, 14],
    [10, 13, 11],
    [14, 16, 15],
    [9, 12, 10],
    [13, 14, 13]
])
moyenne_individuelle = notes.mean(axis=1)
for idx, moyenne in enumerate(moyenne_individuelle, start=1):
    print(f"Moyenne de l'étudiant {idx} : {moyenne:.2f}")
Moyenne de l'étudiant 1 : 13.67
Moyenne de l'étudiant 2 : 11.33
Moyenne de l'étudiant 3 : 15.00
Moyenne de l'étudiant 4 : 10.33
Moyenne de l'étudiant 5 : 13.33
  • Calculer la moyenne de chaque matière
moy_matiere = np.mean(notes, axis=0)
for idx, moyenne in enumerate(moy_matiere, start=1):
    print(f"Moyenne de la matière {idx} : {moyenne:.2f}")
Moyenne de la matière 1 : 11.60
Moyenne de la matière 2 : 14.00
Moyenne de la matière 3 : 12.60
  • calculer la variation des notes pour chaque matière (écart-type par colonne)
ecart_type = np.std(notes, axis=0)
print("Écart type par matière :")
for idx, ec in enumerate(ecart_type, start=1):
    print(f"Matière {idx} : {ec:.2f}")
Écart type par matière :
Matière 1 : 1.85
Matière 2 : 1.41
Matière 3 : 1.85

    Type at least 2 letters. ↑ ↓ to move, Enter to open.