diff --git a/module3/avare_vincent_dargaud.html b/module3/avare_vincent_dargaud.html new file mode 100644 index 0000000000000000000000000000000000000000..8a6fce7e7ed950ed4149614dca55cbb813505652 --- /dev/null +++ b/module3/avare_vincent_dargaud.html @@ -0,0 +1,13753 @@ + + + + +exercice_fr + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
In [1]:
+
+
+
with open("moliere_avare.txt", "r", encoding="utf-8") as f:
+    texte = f.read()
+
+print(texte[:500])  # affiche les 500 premiers caractères pour vérifier
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
---
+identifier: moliere_avare  
+creator: Molière.  
+date: 1668  
+title: L'Avare. Comédie  
+---
+
+
+L'AVARE,
+
+COMÉDIE.
+
+Par J.B.P. MOLIÈRE.
+
+À PARIS, Chez JEAN RIBOU, au Palais, vis à vis la Porte de l'Église de la Sainte Chapelle, à l'Image Saint-Louis. M. DC. LXIX. *AVEC PRIVILÈGE DU ROI*
+
+
+
+# ACTEURS.
+ – Harpagon, Père de Cléante et d'Élise, et Amoureux de Mariane.
+ – Cléante, Fils d'Harpagon, Amant de Mariane.
+ – Élise, Fille d'Harpagon, Amante de Valère.
+ – Valère, Fils d'Anselme, et Amant d'É
+
+
+
+ +
+
+ +
+
+
+
In [2]:
+
+
+
import re
+import unicodedata
+from collections import defaultdict, Counter
+
+import pandas as pd
+import numpy as np
+import matplotlib.pyplot as plt
+
+plt.rcParams["figure.figsize"] = (9, 5)
+
+def strip_accents(s: str) -> str:
+    return ''.join(c for c in unicodedata.normalize('NFD', s)
+                   if unicodedata.category(c) != 'Mn')
+
+def normalize_name(raw: str) -> str:
+    s = raw.strip()
+    s = s.replace('’', "'")
+    s = s.replace('ſ', 's')  # vieilles ligatures éventuelles
+    s = strip_accents(s).upper()
+    s = re.sub(r'[^A-Z\- ]+', '', s)  # garde lettres/espaces/tirets
+    s = re.sub(r'\s+', ' ', s).strip()
+    return s
+
+def word_count(text: str) -> int:
+    # enlève didascalies [ ... ] ( ... ) et tirets de réplique
+    text = re.sub(r'\[[^\]]*\]', ' ', text)
+    text = re.sub(r'\([^)]*\)', ' ', text)
+    text = text.replace('–', ' ')
+    tokens = re.findall(r"[A-Za-zÀ-ÖØ-öø-ÿ']+", text)
+    return len(tokens)
+
+ +
+
+
+ +
+
+
+
In [3]:
+
+
+
with open("moliere_avare.txt", "r", encoding="utf-8") as f:
+    raw = f.read()
+
+# normalisation minimale
+raw = raw.replace('\r\n', '\n').replace('\r', '\n')
+
+ +
+
+
+ +
+
+
+
In [5]:
+
+
+
acte = "INCONNU"
+scene = "INCONNUE"
+
+# compte global par personnage
+wc_by_char = Counter()
+
+# compte par personnage ET par scène
+wc_by_char_scene = defaultdict(int)
+
+lines = raw.split('\n')
+i = 0
+while i < len(lines):
+    line = lines[i].strip()
+
+    # titres d'acte / scène (markdown)
+    m_acte = re.match(r'^\s*##+\s*Acte\b\s*(.*)$', line, flags=re.I)
+    m_scene = re.match(r'^\s*###+\s*Sc[eè]ne\b\s*(.*)$', line, flags=re.I)
+    if m_acte:
+        suffix = m_acte.group(1).strip()
+        acte = f"ACTE {suffix or '?'}"
+        i += 1
+        continue
+    if m_scene:
+        suffix = m_scene.group(1).strip()
+        scene = f"SCENE {suffix or '?'}"
+        i += 1
+        continue
+
+    # ligne de locuteur (MAJUSCULES + point)
+    m_speaker = re.match(r"^([A-ZÉÈÀÂÎÔÛÄËÏÖÜÇŒÆ'\- ]+)\.\s*$", line)
+    if m_speaker:
+        raw_name = m_speaker.group(1)
+        name = normalize_name(raw_name)
+
+        # récupérer la réplique (lignes suivantes jusqu'à ligne vide ou nouveau locuteur/titre)
+        i += 1
+        speech_lines = []
+        while i < len(lines):
+            nxt = lines[i]
+            if not nxt.strip():
+                break
+            if re.match(r'^\s*##+', nxt):  # nouveau titre acte/scène
+                break
+            if re.match(r"^([A-ZÉÈÀÂÎÔÛÄËÏÖÜÇŒÆ'\- ]+)\.\s*$", nxt.strip()):
+                break
+            speech_lines.append(nxt)
+            i += 1
+
+        speech = "\n".join(speech_lines)
+        n = word_count(speech)
+        if n > 0:
+            wc_by_char[name] += n
+            key_scene = f"{acte}{scene}"
+            wc_by_char_scene[(name, key_scene)] += n
+        continue
+
+    i += 1
+
+# DataFrames
+df_total = pd.DataFrame(list(wc_by_char.items()), columns=["personnage", "mots"])\
+             .sort_values("mots", ascending=False).reset_index(drop=True)
+
+df_scene = pd.DataFrame(list(wc_by_char_scene.items()), columns=["pair", "mots"])
+df_scene[["personnage", "scene"]] = pd.DataFrame(df_scene["pair"].tolist(), index=df_scene.index)
+df_scene = df_scene.drop(columns=["pair"])
+
+ +
+
+
+ +
+
+
+
In [6]:
+
+
+
print(type(wc_by_char), len(wc_by_char))
+print(list(wc_by_char.items())[:5])  # aperçu des 5 premiers
+
+ +
+
+
+ +
+
+ + +
+ +
+ + +
+
<class 'collections.Counter'> 13
+[('VALERE', 2516), ('ELISE', 874), ('CLEANTE', 3120), ('HARPAGON', 5158), ('LA FLECHE', 1405)]
+
+
+
+ +
+
+ +
+
+
+
In [7]:
+
+
+
topN = 10  # nombre de personnages à afficher
+ax = df_total.head(topN).iloc[::-1].plot(
+    kind="barh",
+    x="personnage",
+    y="mots",
+    color="cornflowerblue",
+    legend=False
+)
+ax.set_xlabel("Nombre de mots prononcés")
+ax.set_ylabel("")
+ax.set_title(f"L'Avare — Top {topN} orateurs")
+plt.tight_layout()
+plt.savefig("avare_top_orateurs.png", dpi=150)
+plt.show()
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + + +
+ +
+ +
+ +
+
+ +
+
+
+
In [8]:
+
+
+
main_chars = set(df_total.head(5)["personnage"])
+tmp = df_scene.copy()
+tmp["perso_grp"] = np.where(tmp["personnage"].isin(main_chars), tmp["personnage"], "AUTRES")
+
+pivot = tmp.pivot_table(index="scene", columns="perso_grp", values="mots", aggfunc="sum").fillna(0)
+pivot = pivot.reindex(sorted(pivot.index), axis=0)
+
+pivot.plot(kind="bar", stacked=True, figsize=(12,6))
+plt.xlabel("Scènes")
+plt.ylabel("Mots prononcés")
+plt.title("Répartition par scène (personnages principaux)")
+plt.tight_layout()
+plt.savefig("avare_par_scene.png", dpi=150)
+plt.show()
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + + +
+ +
+ +
+ +
+
+ +
+
+
+
In [9]:
+
+
+
idx = df_scene.groupby("scene")["mots"].idxmax()
+df_winner = df_scene.loc[idx, ["scene", "personnage", "mots"]].sort_values("scene")
+df_winner.head(20)
+
+ +
+
+
+ +
+
+ + +
+ +
Out[9]:
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
scenepersonnagemots
14ACTE II. • SCENE II.MAITRE SIMON180
19ACTE II. • SCENE III.HARPAGON21
20ACTE II. • SCENE IV.LA FLECHE274
13ACTE II. • SCENE Première.LA FLECHE852
23ACTE II. • SCENE V.FROSINE1223
32ACTE III. • SCENE II.MAITRE JACQUES185
33ACTE III. • SCENE III.FROSINE19
36ACTE III. • SCENE IV.FROSINE183
50ACTE III. • SCENE IX.HARPAGON74
25ACTE III. • SCENE Première.MAITRE JACQUES737
37ACTE III. • SCENE V.HARPAGON100
41ACTE III. • SCENE VI.HARPAGON65
43ACTE III. • SCENE VII.CLEANTE539
48ACTE III. • SCENE VIII.HARPAGON21
57ACTE IV. • SCENE II.HARPAGON52
61ACTE IV. • SCENE III.CLEANTE386
63ACTE IV. • SCENE IV.CLEANTE160
56ACTE IV. • SCENE Première.FROSINE401
65ACTE IV. • SCENE V.CLEANTE154
68ACTE IV. • SCENE VI.LA FLECHE33
+
+
+ +
+ +
+
+ +
+
+
+
+

Analyse des dialogues dans L’Avare de Molière

Ce document propose une exploration computationnelle du texte de L’Avare, en s’appuyant sur les données disponibles sur le site de l’OBVIL. +L’objectif est d’analyser la répartition de la parole entre les personnages — en particulier la quantité de mots prononcés, leur distribution selon les scènes, et la dynamique d’interlocution implicite.

+

Cette approche vise à relier les structures littéraires visibles (le texte, les dialogues) à des structures invisibles : rapports de pouvoir, densité psychologique des scènes, et hiérarchie dramatique implicite.

+ +
+
+
+
+
+
+

Préparation des données

Le texte brut est issu du projet OBVIL. +Nous avons téléchargé la version au format texte brut (.txt) et l’avons placée dans notre environnement Jupyter. +Chaque ligne contenant le nom d’un personnage suivi de ses répliques a été extraite à l’aide d’une expression régulière.

+ +
+
+
+
+
+
In [10]:
+
+
+
import re, pandas as pd, numpy as np, matplotlib.pyplot as plt
+# (et tout ton parsing jusqu’à la création de df_total et df_scene)
+
+ +
+
+
+ +
+
+
+
+

Résultats : distribution globale de la parole

Le premier graphique illustre la quantité totale de mots prononcés par chaque personnage dans l’ensemble de la pièce. +On observe que Harpagon domine nettement la parole, suivi de Cléante et de Frosine.
+Cette hiérarchie reflète déjà une logique dramatique : Harpagon, figure de l’avarice incarnée, occupe l’espace verbal comme il occupe l’espace matériel.

+ +
+
+
+
+
+
In [11]:
+
+
+
plt.imshow(plt.imread("avare_top_orateurs.png"))
+plt.axis("off")
+plt.show()
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + + +
+ +
+ +
+ +
+
+ +
+
+
+
+

Répartition par scène

Le graphique suivant montre, pour chaque scène, la proportion de mots prononcés par les personnages principaux.
+Cette visualisation permet de détecter les bascules de tension : certaines scènes sont dominées par Frosine, d’autres par Cléante ou Élise, révélant la mécanique d’équilibre typique de Molière.

+

On perçoit aussi une alternance rythmique : la parole circule comme un bien disputé — signe que, chez Molière, le langage lui-même devient monnaie d’échange.

+ +
+
+
+
+
+
In [12]:
+
+
+
plt.imshow(plt.imread("avare_par_scene.png"))
+plt.axis("off")
+plt.show()
+
+ +
+
+
+ +
+
+ + +
+ +
+ + + + +
+ +
+ +
+ +
+
+ +
+
+
+
+

Interprétation synthétique

L’analyse computationnelle des dialogues de L’Avare révèle un ordre latent : celui de la parole comme capital symbolique. +Plus un personnage parle, plus il contrôle la scène ; mais certains, comme Frosine, dominent sans posséder le pouvoir matériel, tandis que d’autres, comme Élise, sont souvent présents par le silence. +Ce contraste entre parole et pouvoir forme la véritable tension du texte.

+

Ainsi, derrière l’économie de l’argent se joue une économie du verbe — où parler, c’est dépenser, et se taire, c’est accumuler.

+ +
+
+
+
+
+
In [ ]:
+
+
+
 
+
+ +
+
+
+ +
+
+
+ + + + + +