diff --git a/module3/exo3/exercice_fr.ipynb b/module3/exo3/exercice_fr.ipynb index f76a512105a08d3746399547541fc8eb9b112857..ef7096da4c16b3fee07e54a4802ab9dc1d4d565e 100644 --- a/module3/exo3/exercice_fr.ipynb +++ b/module3/exo3/exercice_fr.ipynb @@ -238,6 +238,15 @@ "# de la stocker dans un dictionnaire en parcourant ligne par ligne\n", "# un fichier texte passé en entrée.\n", "def fill_perso_dict(fileToAnalyse, emptyPersoDict):\n", + " \"\"\"\n", + " Fonction remplissant un dictionnaire d'entrée avec la liste\n", + " des personnages de la pièce de théâtre lue dans le fichier\n", + " passé en entrée.\n", + " \n", + " :param fileToAnalyse: pointeur obtenu par ouverture d'un fichier\n", + " :param emptyPersoDict: dictionnaire à remplir par la fonction\n", + " :return: aucun retour\n", + " \"\"\"\n", " currentLine = fileToAnalyse.readline()\n", " isStartPersoListLine = False\n", " while (currentLine and not isStartPersoListLine):\n", @@ -308,7 +317,130 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "# Fonction qui permet d'extraire la liste des personnages\n", + "# de la stocker dans un dictionnaire en parcourant ligne par ligne\n", + "# un fichier texte passé en entrée.\n", + "def generate_text_synthesis_data_table(fileToAnalyse, persoDict, emptyAnalysisDict):\n", + " \"\"\"\n", + " Fonction principale d'analyse du texte générant un dataframe pandas\n", + " de synthèse des informations permettant l'analyse globale.\n", + " \n", + " :param fileToAnalyse: pointeur obtenu par ouverture d'un fichier\n", + " :param persoDict: dictionnaire donnant la liste des personnages de la pièce\n", + " :param emptyAnalysisDict: dictionnaire à remplir par la fonction\n", + " :return: dataframe pandas dont le template est donné par le dictionnaire\n", + " \"\"\"\n", + " currentLine = fileToAnalyse.readline()\n", + " # Variable pour enregistrer le numéro de l'acte courant\n", + " actNum = 0\n", + " # Variable pour enregistrer le numéro de la scène courante\n", + " sceneNum = 0\n", + " # Variable indiquant si la ligne précédente déclare une scène\n", + " previousLineIsScene = False\n", + " \n", + " # Boucle principale de parcours du fichier texte\n", + " while (currentLine):\n", + " if currentLine.startswith('##'):\n", + " # Déclaration d'un acte de la pièce\n", + " # On incrémente le numéro d'acte\n", + " actNum += 1\n", + " # On remet à zéro le numéro de la scène\n", + " sceneNum = 0\n", + " elif currentLine.startswith('###'):\n", + " # Déclaration d'une scène de la pièce\n", + " # On incrémente le numéro de scène\n", + " sceneNum += 1\n", + " previousLineIsScene = True\n", + " scenePersoList = []\n", + " else:\n", + " # La ligne courante est une ligne autre,\n", + " # comme on a pu le voir dans l'exemple un peu plus haut\n", + " # elle peut être:\n", + " # - vide\n", + " # - une déclaration des personnages de la scène\n", + " # - une identification de l'auteur de la réplique qui va suivre\n", + " # - une ligne composant une réplique\n", + " if not previousLineIsScene:\n", + " pass\n", + " else:\n", + " # La ligne courante présente forcément les personnages de la scène\n", + " # car c'est la ligne qui suit la déclaration de scène.\n", + " # On peut donc récupérer réduire l'analyse du texte à ces seuls\n", + " # protagonistes.\n", + " # Boucle sur les clés du dictionnaire de personnage\n", + " # qui sont leur nom.\n", + " for namePerso in persoDict:\n", + " # On vérifie si namePerso fait partie des protagonistes\n", + " m = re.search(namePerso, currentLine)\n", + " if m is not None:\n", + " # Le résultat de la recherche n'est pas vide,\n", + " # le personnage fait partie des protagonistes\n", + " # on l'ajoute à la liste des personnages de la scène\n", + " scenePersoList.append(m.group(0))\n", + " previousLineIsScene = False\n", + " \n", + " \n", + " currentLine = fileToAnalyse.readline()\n", + "\n", + " \"\"\" \n", + " # La lecture s'est arrêtée car la ligne de début de définition de la liste des personnages a été rencontrée.\n", + " # Nous avons néanmoins lu la ligne suivante qui est obligatoirement un personnage.\n", + " # Nous devons maintenant lire ligne par ligne, la liste des personnages au format suivant:\n", + " # \"- NomPersonnage, lien, lien, ...\"\n", + " # Ainsi dès que la ligne ne commence plus par un tiret nous pouvons arrêter la lecture et le remplissage\n", + " # du dictionnaire.\n", + " isAPersoLine = True\n", + " # On extrait la chaîne de caractères qui nous intéresse\n", + " m = re.search('(?<=\\s–\\s)[A-ZÀ-Ÿ]{1}[a-zA-ZÀ-ÿ\\s,\\']+', persoLineExample)\n", + " extractedString = m.group(0)\n", + " while (currentLine and isAPersoLine):\n", + " # Traitement de la ligne courante qui est obligatoirement\n", + " # une ligne listant un personnage de la pièce.\n", + " # Comme le montre l'exemple au-dessus, le nom ainsi que\n", + " # les différents types de liens sont séparés par une virgule.\n", + " parts = extractedString.split(',')\n", + " # La ligne au-dessus crée une liste dont chaque élément\n", + " # est séparé par des virgules\n", + " # typiquement \"tata, titi, toto\".split(',') --> ['tata', ' titi', ' toto']\n", + " # Création d'un dictionnaire vide temporaire pour enregistrer les liens\n", + " # ainsi que la couleur à paramétrer\n", + " persoCaracs = {\"links\":[],\"color\":None}\n", + " # Le premier élément donne le nom du personnage, indice 0 de la liste\n", + " # Les éléments suivants donnent les liens avec les autres personnages\n", + " # On parcours le reste de ces derniers\n", + " for elt in parts[1:]:\n", + " # En regardant cette partie dans le fichier,\n", + " # on voit que soit les parties commencent\n", + " # par un espace et une lettre,\n", + " # soit un espace et un \"et\" que l'on ne\n", + " # souhaite pas capturer\n", + " # On vérifie si l'élément commence par \" et \" ou non\n", + " if elt.startswith(\" et \"):\n", + " # L'élément commence bien par \" et \"\n", + " # on enlève cette partie\n", + " currentLink = elt[4:]\n", + " else:\n", + " # Ce n'est pas le cas, on enlève juste\n", + " # l'espace\n", + " currentLink = elt[1:]\n", + " persoCaracs[\"links\"].append(currentLink)\n", + " # Fin de la boucle for\n", + " \n", + " # On enregistre le dictionnaire temporaire des caractéristiques\n", + " # du personnage courant rempli, dans le dictionnaire\n", + " # global des personnages\n", + " emptyPersoDict[parts[0]] = persoCaracs\n", + " currentLine = fileToAnalyse.readline()\n", + " m = re.search('(?<=\\s–\\s)[A-ZÀ-Ÿ]{1}[a-zA-ZÀ-ÿ\\s,\\']+', currentLine)\n", + " if m is not None:\n", + " extractedString = m.group(0)\n", + " else:\n", + " isAPersoLine = False\n", + " \n", + " # Fin de la boucle while\n", + "\"\"\"" + ] }, { "cell_type": "code", @@ -342,12 +474,17 @@ "with open(local_filename,'r') as avareFile:\n", " # On va commencer par parser le fichier afin de récupérer la liste des personnages\n", " fill_perso_dict(avareFile, avarePersoDict)\n", + " \n", " print(\"##################################################\")\n", " print(\"Contenu du dictionnaire des personnages initialisé\")\n", " print(\"##################################################\\n\")\n", " print(avarePersoDict)\n", " print(\"\\n##################################################\")\n", "\n", + " textDataSynthesisTableDf = generate_text_synthesis_data_table(avareFile, avarePersoDict, avareAnalysisDict)\n", + "\n", + "# Le tableau de données récapitulatif est maintenant prêt à être utilisé\n", + "\n", " " ] },