Exercices RAG - Python pour Débutants

Approche Progressive du Projet d'Analyse Documentaire

📚 Introduction

Bienvenue dans les exercices RAG

Ce module vous guide pas à pas dans l'apprentissage des concepts nécessaires pour comprendre et utiliser le projet RAG (Retrieval Augmented Generation) dans le dossier PYTHON/rag.

Objectif du projet RAG

Le projet RAG permet de :

  • Lire des documents dans différents formats (PDF, HTML, Markdown)
  • Extraire le contenu texte de ces documents
  • Rechercher intelligemment dans ces documents

Approche pédagogique

Ce module est divisé en 4 niveaux :

  1. Niveau 1 : Bases de Python (variables, listes, fonctions)
  2. Niveau 2 : Gestion de fichiers
  3. Niveau 3 : Traitement de texte
  4. Niveau 4 : Concepts avancés (classes, bibliothèques externes)

💡 Conseil : Ne passez pas au niveau suivant tant que vous ne maîtrisez pas le niveau actuel. La progression est conçue pour être linéaire.

🐣 Niveau 1 - Bases de Python

Variables et Types de Données

Exercice 1.1 : Variables et Opérations

Créez des variables pour stocker les informations d'un document.

Solution

# Création de variables
nom_document = "rapport_annuel.pdf"
taille_document = 2.5  # en Mo
est_pdf = True
mots_cles = ["rapport", "finance", "2024"]

# Affichage des informations
print(f"Nom du document : {nom_document}")
print(f"Taille : {taille_document} Mo")
print(f"Est un PDF : {est_pdf}")
print(f"Mots clés : {', '.join(mots_cles)}")

# Calculs simples
taille_ko = taille_document * 1024
print(f"Taille en Ko : {taille_ko}")
                        
Exercice 1.2 : Listes et Boucles

Manipulez une liste de noms de fichiers.

Solution

# Liste de fichiers
fichiers = ["rapport.pdf", "notes.txt", "presentation.pptx", "data.csv"]

# Afficher tous les fichiers
print("Liste des fichiers :")
for fichier in fichiers:
    print(f"  - {fichier}")

# Compter les fichiers
print(f"\nNombre total de fichiers : {len(fichiers)}")

# Filtrer les fichiers PDF
pdfs = []
for fichier in fichiers:
    if fichier.endswith(".pdf"):
        pdfs.append(fichier)

print(f"Fichiers PDF trouvés : {pdfs}")
                        
Exercice 1.3 : Fonctions Simples

Créez des fonctions pour manipuler les noms de fichiers.

Solution

def extraire_extension(nom_fichier):
    """Extrait l'extension d'un nom de fichier"""
    parties = nom_fichier.split(".")
    if len(parties) > 1:
        return parties[-1]
    return ""

def est_document_texte(nom_fichier):
    """Vérifie si un fichier est un document texte"""
    extensions_texte = ["txt", "md", "html", "csv"]
    extension = extraire_extension(nom_fichier)
    return extension in extensions_texte

# Test des fonctions
fichier_test = "rapport_annuel.pdf"
print(f"Extension de {fichier_test} : {extraire_extension(fichier_test)}")
print(f"{fichier_test} est un document texte : {est_document_texte(fichier_test)}")

fichier_test2 = "notes.txt"
print(f"Extension de {fichier_test2} : {extraire_extension(fichier_test2)}")
print(f"{fichier_test2} est un document texte : {est_document_texte(fichier_test2)}")
                        

📄 Niveau 2 - Gestion de Fichiers

Lecture et Écriture de Fichiers

Exercice 2.1 : Création et Lecture de Fichiers Texte

Créez un fichier texte et lisez son contenu.

Solution

# Création d'un fichier texte
nom_fichier = "exemple.txt"
contenu = """Ceci est un exemple de fichier texte.
Il contient plusieurs lignes.
C'est utile pour tester la lecture de fichiers."""

# Écriture du fichier
with open(nom_fichier, "w", encoding="utf-8") as f:
    f.write(contenu)

print(f"Fichier {nom_fichier} créé avec succès.")

# Lecture du fichier
try:
    with open(nom_fichier, "r", encoding="utf-8") as f:
        contenu_lu = f.read()
    print("Contenu du fichier :")
    print(contenu_lu)
except FileNotFoundError:
    print(f"Le fichier {nom_fichier} n'existe pas.")
                        
Exercice 2.2 : Gestion des Erreurs

Gérez les erreurs lors de la lecture de fichiers.

Solution

def lire_fichier_surement(nom_fichier):
    """Lit un fichier avec gestion d'erreurs"""
    try:
        with open(nom_fichier, "r", encoding="utf-8") as f:
            return f.read()
    except FileNotFoundError:
        return f"Erreur : Le fichier '{nom_fichier}' n'a pas été trouvé."
    except PermissionError:
        return f"Erreur : Permission refusée pour lire '{nom_fichier}'."
    except Exception as e:
        return f"Erreur inattendue : {e}"

# Test avec un fichier existant
resultat = lire_fichier_surement("exemple.txt")
print(resultat)

# Test avec un fichier inexistant
resultat = lire_fichier_surement("fichier_inexistant.txt")
print(resultat)
                        
Exercice 2.3 : Liste des Fichiers dans un Dossier

Listez les fichiers dans un dossier spécifique.

Solution

import os

def lister_fichiers(dossier):
    """Liste tous les fichiers dans un dossier"""
    try:
        fichiers = os.listdir(dossier)
        # Filtrer pour ne garder que les fichiers (pas les dossiers)
        fichiers = [f for f in fichiers if os.path.isfile(os.path.join(dossier, f))]
        return fichiers
    except FileNotFoundError:
        return f"Erreur : Le dossier '{dossier}' n'existe pas."
    except PermissionError:
        return f"Erreur : Permission refusée pour accéder à '{dossier}'."
    except Exception as e:
        return f"Erreur inattendue : {e}"

# Créer un dossier de test
dossier_test = "dossier_test"
os.makedirs(dossier_test, exist_ok=True)

# Créer quelques fichiers de test
with open(os.path.join(dossier_test, "fichier1.txt"), "w") as f:
    f.write("Contenu du fichier 1")
    
with open(os.path.join(dossier_test, "fichier2.md"), "w") as f:
    f.write("# Contenu du fichier 2")

# Lister les fichiers
fichiers = lister_fichiers(dossier_test)
print(f"Fichiers dans '{dossier_test}' :")
for fichier in fichiers:
    print(f"  - {fichier}")
                        

📝 Niveau 3 - Traitement de Texte

Manipulation de Chaînes de Caractères

Exercice 3.1 : Comptage de Mots et Caractères

Comptez les mots et caractères dans un texte.

Solution

def analyser_texte(texte):
    """Analyse un texte et retourne des statistiques"""
    # Compter les caractères
    nb_caracteres = len(texte)
    nb_caracteres_sans_espaces = len(texte.replace(" ", ""))
    
    # Compter les mots
    mots = texte.split()
    nb_mots = len(mots)
    
    # Compter les lignes
    lignes = texte.split("\n")
    nb_lignes = len(lignes)
    
    return {
        "caracteres": nb_caracteres,
        "caracteres_sans_espaces": nb_caracteres_sans_espaces,
        "mots": nb_mots,
        "lignes": nb_lignes
    }

# Test
texte_exemple = """Python est un langage de programmation puissant.
Il est utilisé dans de nombreux domaines.
Le traitement de texte est l'un de ses points forts."""

resultats = analyser_texte(texte_exemple)
print("Analyse du texte :")
print(f"  Caractères : {resultats['caracteres']}")
print(f"  Caractères (sans espaces) : {resultats['caracteres_sans_espaces']}")
print(f"  Mots : {resultats['mots']}")
print(f"  Lignes : {resultats['lignes']}")
                        
Exercice 3.2 : Recherche de Mots dans un Texte

Recherchez des mots spécifiques dans un texte.

Solution

def rechercher_mots(texte, mots_recherches):
    """Recherche des mots dans un texte et retourne leurs positions"""
    # Convertir en minuscules pour une recherche insensible à la casse
    texte_min = texte.lower()
    resultats = {}
    
    for mot in mots_recherches:
        mot_min = mot.lower()
        positions = []
        debut = 0
        
        # Rechercher toutes les occurrences
        while True:
            pos = texte_min.find(mot_min, debut)
            if pos == -1:
                break
            positions.append(pos)
            debut = pos + 1
        
        resultats[mot] = positions
    
    return resultats

# Test
texte_exemple = """Python est un langage de programmation.
Python est facile à apprendre.
Beaucoup de développeurs utilisent Python."""

mots_a_chercher = ["Python", "langage", "développeurs"]

resultats = rechercher_mots(texte_exemple, mots_a_chercher)
for mot, positions in resultats.items():
    print(f"Mot '{mot}' trouvé {len(positions)} fois aux positions : {positions}")
                        
Exercice 3.3 : Extraction de Paragraphes

Divisez un texte en paragraphes.

Solution

def extraire_paragraphes(texte):
    """Extrait les paragraphes d'un texte"""
    # Diviser par double saut de ligne
    paragraphes_bruts = texte.split("\n\n")
    
    # Nettoyer chaque paragraphe
    paragraphes = []
    for paragraphe in paragraphes_bruts:
        # Supprimer les espaces au début et à la fin
        paragraphe_nettoye = paragraphe.strip()
        # Ne garder que les paragraphes non vides
        if paragraphe_nettoye:
            paragraphes.append(paragraphe_nettoye)
    
    return paragraphes

# Test
texte_exemple = """Ceci est le premier paragraphe.
Il contient plusieurs lignes.

Ceci est le deuxième paragraphe.
Il est séparé du premier par un saut de ligne vide.


Et voici le troisième paragraphe.
Il est séparé par deux sauts de ligne."""

paragraphes = extraire_paragraphes(texte_exemple)
print(f"Nombre de paragraphes trouvés : {len(paragraphes)}")
for i, paragraphe in enumerate(paragraphes, 1):
    print(f"\nParagraphe {i} :")
    print(paragraphe)
    print(f"(Longueur : {len(paragraphe)} caractères)")
                        

🚀 Niveau 4 - Concepts Avancés

Classes et Bibliothèques Externes

Exercice 4.1 : Classe Document Simple

Créez une classe pour représenter un document.

Solution

class Document:
    """Classe représentant un document"""
    
    def __init__(self, nom, contenu=""):
        """Initialise un document"""
        self.nom = nom
        self.contenu = contenu
        self.date_creation = None  # À implémenter plus tard
    
    def __str__(self):
        """Représentation sous forme de chaîne"""
        return f"Document('{self.nom}', {len(self.contenu)} caractères)"
    
    def __len__(self):
        """Retourne la longueur du contenu"""
        return len(self.contenu)
    
    def ajouter_contenu(self, nouveau_contenu):
        """Ajoute du contenu au document"""
        self.contenu += nouveau_contenu
    
    def nombre_mots(self):
        """Retourne le nombre de mots dans le document"""
        if not self.contenu:
            return 0
        return len(self.contenu.split())
    
    def mots_cles(self, nb_mots=5):
        """Retourne les mots les plus fréquents"""
        if not self.contenu:
            return []
        
        # Convertir en minuscules et séparer les mots
        mots = self.contenu.lower().split()
        
        # Compter les occurrences
        compteur = {}
        for mot in mots:
            # Supprimer la ponctuation simple
            mot_nettoye = ''.join(c for c in mot if c.isalnum())
            if mot_nettoye:
                compteur[mot_nettoye] = compteur.get(mot_nettoye, 0) + 1
        
        # Trier par fréquence
        mots_tries = sorted(compteur.items(), key=lambda x: x[1], reverse=True)
        
        # Retourner les nb_mots premiers
        return [mot for mot, _ in mots_tries[:nb_mots]]

# Test
doc = Document("test.txt", "Python est un langage de programmation. Python est facile à apprendre.")
print(doc)
print(f"Longueur : {len(doc)} caractères")
print(f"Nombre de mots : {doc.nombre_mots()}")
print(f"Mots clés : {doc.mots_cles()}")

# Ajouter du contenu
doc.ajouter_contenu(" Beaucoup de développeurs utilisent Python.")
print(f"Après ajout : {len(doc)} caractères")
print(f"Nombre de mots : {doc.nombre_mots()}")
                        
Exercice 4.2 : Utilisation de Pathlib

Utilisez pathlib pour manipuler les chemins de fichiers.

Solution

from pathlib import Path

def analyser_chemin(chemin):
    """Analyse un chemin de fichier"""
    p = Path(chemin)
    
    print(f"Chemin : {p}")
    print(f"Nom du fichier : {p.name}")
    print(f"Extension : {p.suffix}")
    print(f"Dossier parent : {p.parent}")
    print(f"Chemin absolu : {p.absolute()}")
    
    # Vérifier l'existence
    if p.exists():
        print("Le fichier/dossier existe")
        if p.is_file():
            print("C'est un fichier")
        elif p.is_dir():
            print("C'est un dossier")
    else:
        print("Le fichier/dossier n'existe pas")

def creer_structure_dossier():
    """Crée une structure de dossiers pour les tests"""
    # Créer la structure
    base = Path("projets") / "documents"
    base.mkdir(parents=True, exist_ok=True)
    
    # Créer des fichiers de test
    fichiers = [
        base / "rapport.pdf",
        base / "notes.txt",
        base / "presentation.pptx"
    ]
    
    for fichier in fichiers:
        fichier.touch()  # Crée un fichier vide
        print(f"Fichier créé : {fichier}")

# Test
print("=== Analyse de chemins ===")
analyser_chemin("exemple.txt")
analyser_chemin("/Users/marcfrenkel/Desktop/-/ALWAYS/__qoder/AJOUR2511241322/PYTHON/rag/rag.py")

print("\n=== Création de structure ===")
creer_structure_dossier()
                        
Exercice 4.3 : Introduction à BeautifulSoup (HTML)

Utilisez BeautifulSoup pour extraire le texte d'un document HTML.

Solution

# Note : Pour exécuter cet exercice, vous devez d'abord installer beautifulsoup4
# pip install beautifulsoup4

try:
    from bs4 import BeautifulSoup
    
    def extraire_texte_html(html_content):
        """Extrait le texte d'un document HTML"""
        # Parser le HTML
        soup = BeautifulSoup(html_content, 'html.parser')
        
        # Supprimer les scripts et styles
        for script in soup(["script", "style"]):
            script.decompose()
        
        # Extraire le texte
        texte = soup.get_text()
        
        # Nettoyer les espaces multiples
        lignes = (ligne.strip() for ligne in texte.splitlines())
        paragraphes = (phrase.strip() for ligne in lignes for phrase in ligne.split("  "))
        texte_nettoye = ' '.join(paragraphe for paragraphe in paragraphes if paragraphe)
        
        return texte_nettoye

    # Exemple d'utilisation
    html_exemple = """
    <!DOCTYPE html>
    <html>
    <head>
        <title>Exemple de Page</title>
        <script>console.log('script à ignorer');</script>
    </head>
    <body>
        <h1>Bienvenue sur notre site</h1>
        <p>Ceci est un <strong>paragraphe</strong> d'exemple.</p>
        <p>Il contient plusieurs <em>éléments</em> HTML.</p>
        <div>
            <h2>Sous-titre</h2>
            <p>Voici un autre paragraphe.</p>
        </div>
    </body>
    </html>
    """

    texte_extrait = extraire_texte_html(html_exemple)
    print("Texte extrait du HTML :")
    print(texte_extrait)
    
except ImportError:
    print("BeautifulSoup n'est pas installé. Pour l'installer :")
    print("pip install beautifulsoup4")
    print("\nCet exercice nécessite la bibliothèque BeautifulSoup pour fonctionner.")