File size: 3,841 Bytes
72c8410
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
"""Chargement et traitement des données FAQ à partir des fichiers CSV."""
import logging
from pathlib import Path
from typing import List, Tuple

import pandas as pd

logger = logging.getLogger(__name__)


class FAQEntry:
    """Représentation d'une entrée FAQ."""

    def __init__(self, formulation: str, theme: str, response: str) -> None:
        """
        Initialiser une entrée FAQ.

        Args:
            formulation: La question de la FAQ
            theme: Le thème/catégorie de la FAQ
            response: La réponse associée
        """
        self.formulation: str = formulation
        self.theme: str = theme
        self.response: str = response


def load_faq_data(
    formulations_path: str,
    responses_path: str,
    delimiter: str = ";"
) -> List[FAQEntry]:
    """
    Charger et fusionner les données FAQ à partir de deux fichiers CSV.

    Les fichiers sont joints via la colonne 'theme'.

    Args:
        formulations_path: Chemin vers faq_formulations.csv (colonnes: formulation, theme)
        responses_path: Chemin vers faq_responses.csv (colonnes: theme, response)
        delimiter: Délimiteur du CSV (par défaut: ";")

    Returns:
        Liste d'objets FAQEntry contenant formulation, theme et réponse

    Raises:
        FileNotFoundError: Si un fichier CSV n'existe pas
        ValueError: Si les fichiers sont vides ou mal formés
    """
    # Vérifier existence des fichiers
    if not Path(formulations_path).exists():
        raise FileNotFoundError(f"Fichier non trouvé: {formulations_path}")
    if not Path(responses_path).exists():
        raise FileNotFoundError(f"Fichier non trouvé: {responses_path}")

    try:
        # Charger les CSV
        logger.info(f"Chargement formulations depuis: {formulations_path}")
        df_formulations: pd.DataFrame = pd.read_csv(
            formulations_path,
            delimiter=delimiter,
            encoding="utf-8"
        )

        logger.info(f"Chargement réponses depuis: {responses_path}")
        df_responses: pd.DataFrame = pd.read_csv(
            responses_path,
            delimiter=delimiter,
            encoding="utf-8"
        )

        # Valider les colonnes
        required_cols_form = {"formulation", "theme"}
        required_cols_resp = {"theme", "response"}

        if not required_cols_form.issubset(df_formulations.columns):
            raise ValueError(
                f"Colonnes manquantes dans formulations. Attendu: {required_cols_form}, "
                f"Trouvé: {set(df_formulations.columns)}"
            )

        if not required_cols_resp.issubset(df_responses.columns):
            raise ValueError(
                f"Colonnes manquantes dans réponses. Attendu: {required_cols_resp}, "
                f"Trouvé: {set(df_responses.columns)}"
            )

        # Joindre les dataframes sur la colonne 'theme'
        logger.info("Fusion des données par theme...")
        df_merged: pd.DataFrame = df_formulations.merge(
            df_responses,
            on="theme",
            how="inner"
        )

        if df_merged.empty:
            raise ValueError("Aucune correspondance trouvée entre formulations et réponses")

        # Créer les objets FAQEntry
        faq_entries: List[FAQEntry] = [
            FAQEntry(
                formulation=row["formulation"].strip(),
                theme=row["theme"].strip(),
                response=row["response"].strip()
            )
            for _, row in df_merged.iterrows()
        ]

        logger.info(f"✓ {len(faq_entries)} entrées FAQ chargées avec succès")
        return faq_entries

    except pd.errors.ParserError as e:
        raise ValueError(f"Erreur lors du parsing du CSV: {e}")
    except Exception as e:
        logger.error(f"Erreur lors du chargement des FAQ: {e}")
        raise