ramedde commited on
Commit
c3551ba
·
verified ·
1 Parent(s): 9625980

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -45
app.py CHANGED
@@ -24,12 +24,13 @@ try:
24
  _gb.client_utils.json_schema_to_python_type = _safe
25
  except Exception:
26
  pass
 
27
  try:
28
  from llama_cpp import Llama
29
  _LLAMA_AVAILABLE = True
30
  except ImportError:
31
  _LLAMA_AVAILABLE = False
32
- import os, json, time, tempfile, random, threading
33
  from gtts import gTTS
34
  from huggingface_hub import hf_hub_download
35
 
@@ -90,48 +91,37 @@ LESSONS = [
90
  "title": "Leçon 1 — Sources du droit et hiérarchie des normes",
91
  "text": """
92
  Cours de droit civil. Introduction aux sources du droit français.
93
-
94
  Première partie : Les sources formelles du droit.
95
-
96
  Le droit français repose sur plusieurs sources hiérarchisées.
97
  Au sommet se trouve la Constitution du 4 octobre 1958, loi fondamentale
98
  de la République française. Elle établit les règles d'organisation de
99
  l'État et garantit les droits fondamentaux des citoyens.
100
-
101
  Sous la Constitution, on trouve les traités internationaux et le droit
102
  de l'Union européenne. En vertu de l'article 55 de la Constitution,
103
  les traités régulièrement ratifiés ont une autorité supérieure à celle
104
  des lois ordinaires.
105
-
106
  Vient ensuite la loi, votée par le Parlement. La loi ordinaire est
107
  adoptée par l'Assemblée nationale et le Sénat selon la procédure
108
  législative prévue par la Constitution. Les lois organiques,
109
  quant à elles, complètent et précisent certaines dispositions
110
  constitutionnelles et bénéficient d'un statut intermédiaire.
111
-
112
  Le règlement constitue la quatrième source majeure. Il émane du
113
  pouvoir exécutif : décrets du Président de la République et du
114
  Premier ministre, arrêtés ministériels, préfectoraux et municipaux.
115
  L'article 37 de la Constitution confère au gouvernement un domaine
116
  réglementaire autonome.
117
-
118
  Deuxième partie : Les sources matérielles du droit.
119
-
120
  La jurisprudence, bien qu'elle ne soit pas officiellement reconnue
121
  comme source formelle, joue un rôle fondamental dans le système
122
  juridique français. Les décisions de la Cour de cassation et du
123
  Conseil d'État interprètent et précisent la portée des textes légaux.
124
  Le Conseil constitutionnel contrôle la constitutionnalité des lois.
125
-
126
  La doctrine regroupe l'ensemble des travaux des juristes :
127
  professeurs, avocats, magistrats. Sans force obligatoire, elle influence
128
  néanmoins la jurisprudence et le législateur.
129
-
130
  La coutume, source ancienne, est aujourd'hui d'application limitée.
131
  En droit commercial, les usages professionnels conservent une importance certaine.
132
-
133
  Troisième partie : Le principe de hiérarchie des normes.
134
-
135
  Hans Kelsen, juriste autrichien du vingtième siècle, a théorisé
136
  la pyramide des normes. Chaque norme tire sa validité d'une norme supérieure.
137
  En France, le Conseil constitutionnel assure le respect de cette hiérarchie.
@@ -151,34 +141,25 @@ En France, le Conseil constitutionnel assure le respect de cette hiérarchie.
151
  "title": "Leçon 2 — Le droit des contrats",
152
  "text": """
153
  Cours de droit civil. Le droit des contrats.
154
-
155
  Première partie : Définition et conditions de validité.
156
-
157
  Le contrat est un accord de volontés destiné à créer, modifier, transmettre
158
  ou éteindre des obligations. Le Code civil, issu de l'ordonnance du 10 février 2016,
159
  définit trois conditions de validité : le consentement des parties, leur capacité
160
  à contracter, et un contenu licite et certain.
161
-
162
  Le consentement doit être libre et éclairé. Il est vicié par l'erreur, le dol
163
  ou la violence. L'incapacité concerne les mineurs non émancipés et les majeurs
164
  protégés sous tutelle ou curatelle.
165
-
166
  Deuxième partie : Les effets du contrat.
167
-
168
  L'exécution obéit au principe de la force obligatoire : le contrat tient lieu
169
  de loi entre les parties. En cas d'inexécution : exécution forcée, résolution
170
  ou dommages et intérêts.
171
-
172
  L'effet relatif du contrat signifie que le contrat ne crée d'obligations qu'entre
173
  les parties contractantes. Les tiers ne peuvent en principe ni se prévaloir du contrat,
174
  ni se le voir opposer.
175
-
176
  Troisième partie : La formation du contrat.
177
-
178
  La formation du contrat passe par une offre et une acceptation. L'offre doit être
179
  précise et ferme. L'acceptation doit être pure et simple. Toute contre-proposition
180
  constitue une nouvelle offre.
181
-
182
  Les avant-contrats tels que la promesse unilatérale de vente ou le pacte de
183
  préférence permettent d'organiser la phase précontractuelle et d'encadrer
184
  les négociations entre les parties.
@@ -198,35 +179,26 @@ les négociations entre les parties.
198
  "title": "Leçon 3 — La responsabilité civile",
199
  "text": """
200
  Cours de droit civil. La responsabilité civile.
201
-
202
  Première partie : Distinction responsabilité civile et pénale.
203
-
204
  La responsabilité civile répare le préjudice causé à autrui, contrairement
205
  à la responsabilité pénale qui sanctionne l'auteur d'une infraction.
206
  La responsabilité civile vise à remettre la victime dans l'état où elle
207
  se trouvait avant le dommage, par l'octroi de dommages et intérêts.
208
-
209
  Deuxième partie : La responsabilité délictuelle.
210
-
211
  La responsabilité délictuelle repose sur trois conditions : faute, dommage
212
  et lien de causalité. L'article 1240 du Code civil dispose que tout fait
213
  de l'homme causant un dommage oblige son auteur à le réparer.
214
-
215
  La faute peut être intentionnelle ou non intentionnelle. Le dommage doit être
216
  certain, direct et personnel. Le lien de causalité entre la faute et le dommage
217
  doit être prouvé par la victime.
218
-
219
  Troisième partie : La responsabilité sans faute.
220
-
221
  La responsabilité sans faute couvre trois domaines principaux.
222
  Le fait des choses : on est responsable des dommages causés par les choses
223
  dont on a la garde. Le fait d'autrui : les parents sont responsables des dommages
224
  causés par leurs enfants mineurs ; les commettants répondent des fautes de leurs préposés.
225
  Les produits défectueux : le producteur est responsable du dommage causé
226
  par un défaut de son produit, sans que la victime ait à prouver une faute.
227
-
228
  Quatrième partie : La responsabilité contractuelle.
229
-
230
  Lorsque le dommage résulte de l'inexécution d'un contrat, la responsabilité
231
  contractuelle s'applique. Elle suppose un contrat valable, une inexécution
232
  et un préjudice. Le débiteur peut s'exonérer en prouvant la force majeure,
@@ -286,7 +258,6 @@ def evaluate_answer(question, answer, hint):
286
  score = min(10, round((hits / max(len(kw), 1)) * 10))
287
  return score, f"(Sans IA – mots-clés : {hits}/{len(kw)})"
288
 
289
- # Prompt format Qwen2.5
290
  prompt = (
291
  "<|im_start|>system\n"
292
  "Tu es un professeur de droit français strict et bienveillant. "
@@ -311,7 +282,6 @@ def evaluate_answer(question, answer, hint):
311
  )
312
  text = out["choices"][0]["text"].strip()
313
  print(f"[law-app] Réponse modèle : {text}")
314
- # Extraire le JSON
315
  start = text.find("{")
316
  end = text.rfind("}") + 1
317
  if start == -1 or end == 0:
@@ -320,7 +290,6 @@ def evaluate_answer(question, answer, hint):
320
  return max(0, min(10, int(data["score"]))), data.get("feedback", "")
321
  except Exception as e:
322
  print(f"[law-app] Erreur éval : {e}")
323
- # Fallback mots-clés
324
  kw = [w.strip().lower() for w in hint.split(",")]
325
  hits = sum(1 for k in kw if k in answer.lower())
326
  score = min(10, round((hits / max(len(kw), 1)) * 10))
@@ -385,15 +354,33 @@ def open_quiz(ss):
385
  "", LESSONS[lesson_idx]["questions"][idx]["q"], "", D(state),
386
  )
387
 
 
388
  def submit_answer(answer, ss):
389
  state = S(ss)
390
  lesson_idx = state.get("lesson_idx", 0)
 
391
  if state["phase"] != "quiz":
392
- return (
393
  gr.update(visible=True), gr.update(visible=False),
394
  gr.update(visible=False), gr.update(visible=False),
395
- "", "➡️ Leçon suivante", ss,
 
 
 
396
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
397
  q = LESSONS[lesson_idx]["questions"][state["question_idx"]]
398
  score, fb = evaluate_answer(q["q"], answer, q["hint"])
399
  total = len(LESSONS)
@@ -405,10 +392,7 @@ def submit_answer(answer, ss):
405
  f"## 🎉 Bravo ! Leçon {lesson_idx + 1}/{total} réussie.\n\n"
406
  f"**Score : {score}/10**\n\n**Commentaire :** {fb}"
407
  )
408
- if is_last:
409
- next_label = "🏆 Voir mon certificat"
410
- else:
411
- next_label = f"➡️ {LESSONS[lesson_idx + 1]['title']}"
412
  else:
413
  state["phase"] = "fail"
414
  result = (
@@ -419,10 +403,14 @@ def submit_answer(answer, ss):
419
  )
420
  next_label = "🔄 Réécouter la leçon"
421
 
422
- return (
 
423
  gr.update(visible=False), gr.update(visible=False),
424
  gr.update(visible=True), gr.update(visible=False),
425
- result, next_label, D(state),
 
 
 
426
  )
427
 
428
  def handle_next(ss):
@@ -480,7 +468,7 @@ with gr.Blocks(title="Cours de Droit", css=CSS) as demo:
480
  audio_out = gr.Audio(label="Cours audio (français)", autoplay=False, interactive=False)
481
  timer_info = gr.Markdown("")
482
  with gr.Row():
483
- start_btn = gr.Button("▶️ Démarrer l'écoute"+str(_LLAMA_OK), variant="primary")
484
  check_btn = gr.Button("🔄 Vérifier le temps", variant="secondary")
485
  quiz_btn = gr.Button("✅ Accéder au Quiz", variant="secondary", interactive=False)
486
 
@@ -511,8 +499,9 @@ with gr.Blocks(title="Cours de Droit", css=CSS) as demo:
511
  timer_info, question_md, answer_box, session]
512
  quiz_btn.click(open_quiz, [session], QUIZ_OUT)
513
 
 
514
  RES_OUT = [listen_col, quiz_col, result_col, cert_col,
515
- result_md, next_btn, session]
516
  submit_btn.click(submit_answer, [answer_box, session], RES_OUT)
517
  answer_box.submit(submit_answer, [answer_box, session], RES_OUT)
518
 
@@ -523,5 +512,4 @@ with gr.Blocks(title="Cours de Droit", css=CSS) as demo:
523
  threading.Thread(target=get_llm, daemon=True).start()
524
 
525
  if __name__ == "__main__":
526
- demo.launch(server_name="0.0.0.0", server_port=7860, show_error=True)
527
-
 
24
  _gb.client_utils.json_schema_to_python_type = _safe
25
  except Exception:
26
  pass
27
+
28
  try:
29
  from llama_cpp import Llama
30
  _LLAMA_AVAILABLE = True
31
  except ImportError:
32
  _LLAMA_AVAILABLE = False
33
+
34
  from gtts import gTTS
35
  from huggingface_hub import hf_hub_download
36
 
 
91
  "title": "Leçon 1 — Sources du droit et hiérarchie des normes",
92
  "text": """
93
  Cours de droit civil. Introduction aux sources du droit français.
 
94
  Première partie : Les sources formelles du droit.
 
95
  Le droit français repose sur plusieurs sources hiérarchisées.
96
  Au sommet se trouve la Constitution du 4 octobre 1958, loi fondamentale
97
  de la République française. Elle établit les règles d'organisation de
98
  l'État et garantit les droits fondamentaux des citoyens.
 
99
  Sous la Constitution, on trouve les traités internationaux et le droit
100
  de l'Union européenne. En vertu de l'article 55 de la Constitution,
101
  les traités régulièrement ratifiés ont une autorité supérieure à celle
102
  des lois ordinaires.
 
103
  Vient ensuite la loi, votée par le Parlement. La loi ordinaire est
104
  adoptée par l'Assemblée nationale et le Sénat selon la procédure
105
  législative prévue par la Constitution. Les lois organiques,
106
  quant à elles, complètent et précisent certaines dispositions
107
  constitutionnelles et bénéficient d'un statut intermédiaire.
 
108
  Le règlement constitue la quatrième source majeure. Il émane du
109
  pouvoir exécutif : décrets du Président de la République et du
110
  Premier ministre, arrêtés ministériels, préfectoraux et municipaux.
111
  L'article 37 de la Constitution confère au gouvernement un domaine
112
  réglementaire autonome.
 
113
  Deuxième partie : Les sources matérielles du droit.
 
114
  La jurisprudence, bien qu'elle ne soit pas officiellement reconnue
115
  comme source formelle, joue un rôle fondamental dans le système
116
  juridique français. Les décisions de la Cour de cassation et du
117
  Conseil d'État interprètent et précisent la portée des textes légaux.
118
  Le Conseil constitutionnel contrôle la constitutionnalité des lois.
 
119
  La doctrine regroupe l'ensemble des travaux des juristes :
120
  professeurs, avocats, magistrats. Sans force obligatoire, elle influence
121
  néanmoins la jurisprudence et le législateur.
 
122
  La coutume, source ancienne, est aujourd'hui d'application limitée.
123
  En droit commercial, les usages professionnels conservent une importance certaine.
 
124
  Troisième partie : Le principe de hiérarchie des normes.
 
125
  Hans Kelsen, juriste autrichien du vingtième siècle, a théorisé
126
  la pyramide des normes. Chaque norme tire sa validité d'une norme supérieure.
127
  En France, le Conseil constitutionnel assure le respect de cette hiérarchie.
 
141
  "title": "Leçon 2 — Le droit des contrats",
142
  "text": """
143
  Cours de droit civil. Le droit des contrats.
 
144
  Première partie : Définition et conditions de validité.
 
145
  Le contrat est un accord de volontés destiné à créer, modifier, transmettre
146
  ou éteindre des obligations. Le Code civil, issu de l'ordonnance du 10 février 2016,
147
  définit trois conditions de validité : le consentement des parties, leur capacité
148
  à contracter, et un contenu licite et certain.
 
149
  Le consentement doit être libre et éclairé. Il est vicié par l'erreur, le dol
150
  ou la violence. L'incapacité concerne les mineurs non émancipés et les majeurs
151
  protégés sous tutelle ou curatelle.
 
152
  Deuxième partie : Les effets du contrat.
 
153
  L'exécution obéit au principe de la force obligatoire : le contrat tient lieu
154
  de loi entre les parties. En cas d'inexécution : exécution forcée, résolution
155
  ou dommages et intérêts.
 
156
  L'effet relatif du contrat signifie que le contrat ne crée d'obligations qu'entre
157
  les parties contractantes. Les tiers ne peuvent en principe ni se prévaloir du contrat,
158
  ni se le voir opposer.
 
159
  Troisième partie : La formation du contrat.
 
160
  La formation du contrat passe par une offre et une acceptation. L'offre doit être
161
  précise et ferme. L'acceptation doit être pure et simple. Toute contre-proposition
162
  constitue une nouvelle offre.
 
163
  Les avant-contrats tels que la promesse unilatérale de vente ou le pacte de
164
  préférence permettent d'organiser la phase précontractuelle et d'encadrer
165
  les négociations entre les parties.
 
179
  "title": "Leçon 3 — La responsabilité civile",
180
  "text": """
181
  Cours de droit civil. La responsabilité civile.
 
182
  Première partie : Distinction responsabilité civile et pénale.
 
183
  La responsabilité civile répare le préjudice causé à autrui, contrairement
184
  à la responsabilité pénale qui sanctionne l'auteur d'une infraction.
185
  La responsabilité civile vise à remettre la victime dans l'état où elle
186
  se trouvait avant le dommage, par l'octroi de dommages et intérêts.
 
187
  Deuxième partie : La responsabilité délictuelle.
 
188
  La responsabilité délictuelle repose sur trois conditions : faute, dommage
189
  et lien de causalité. L'article 1240 du Code civil dispose que tout fait
190
  de l'homme causant un dommage oblige son auteur à le réparer.
 
191
  La faute peut être intentionnelle ou non intentionnelle. Le dommage doit être
192
  certain, direct et personnel. Le lien de causalité entre la faute et le dommage
193
  doit être prouvé par la victime.
 
194
  Troisième partie : La responsabilité sans faute.
 
195
  La responsabilité sans faute couvre trois domaines principaux.
196
  Le fait des choses : on est responsable des dommages causés par les choses
197
  dont on a la garde. Le fait d'autrui : les parents sont responsables des dommages
198
  causés par leurs enfants mineurs ; les commettants répondent des fautes de leurs préposés.
199
  Les produits défectueux : le producteur est responsable du dommage causé
200
  par un défaut de son produit, sans que la victime ait à prouver une faute.
 
201
  Quatrième partie : La responsabilité contractuelle.
 
202
  Lorsque le dommage résulte de l'inexécution d'un contrat, la responsabilité
203
  contractuelle s'applique. Elle suppose un contrat valable, une inexécution
204
  et un préjudice. Le débiteur peut s'exonérer en prouvant la force majeure,
 
258
  score = min(10, round((hits / max(len(kw), 1)) * 10))
259
  return score, f"(Sans IA – mots-clés : {hits}/{len(kw)})"
260
 
 
261
  prompt = (
262
  "<|im_start|>system\n"
263
  "Tu es un professeur de droit français strict et bienveillant. "
 
282
  )
283
  text = out["choices"][0]["text"].strip()
284
  print(f"[law-app] Réponse modèle : {text}")
 
285
  start = text.find("{")
286
  end = text.rfind("}") + 1
287
  if start == -1 or end == 0:
 
290
  return max(0, min(10, int(data["score"]))), data.get("feedback", "")
291
  except Exception as e:
292
  print(f"[law-app] Erreur éval : {e}")
 
293
  kw = [w.strip().lower() for w in hint.split(",")]
294
  hits = sum(1 for k in kw if k in answer.lower())
295
  score = min(10, round((hits / max(len(kw), 1)) * 10))
 
354
  "", LESSONS[lesson_idx]["questions"][idx]["q"], "", D(state),
355
  )
356
 
357
+ # ── Submit avec désactivation immédiate du bouton ────────────────────────────
358
  def submit_answer(answer, ss):
359
  state = S(ss)
360
  lesson_idx = state.get("lesson_idx", 0)
361
+
362
  if state["phase"] != "quiz":
363
+ yield (
364
  gr.update(visible=True), gr.update(visible=False),
365
  gr.update(visible=False), gr.update(visible=False),
366
+ "",
367
+ gr.update(value="📤 Soumettre", interactive=True),
368
+ gr.update(interactive=True),
369
+ ss,
370
  )
371
+ return
372
+
373
+ # ── Étape 1 : désactiver immédiatement bouton + textbox ──────────────────
374
+ yield (
375
+ gr.update(visible=False), gr.update(visible=True),
376
+ gr.update(visible=False), gr.update(visible=False),
377
+ "",
378
+ gr.update(value="⏳ Réponse soumise — Correction en cours…", interactive=False),
379
+ gr.update(interactive=False),
380
+ ss,
381
+ )
382
+
383
+ # ── Étape 2 : évaluation IA (peut prendre quelques secondes) ─────────────
384
  q = LESSONS[lesson_idx]["questions"][state["question_idx"]]
385
  score, fb = evaluate_answer(q["q"], answer, q["hint"])
386
  total = len(LESSONS)
 
392
  f"## 🎉 Bravo ! Leçon {lesson_idx + 1}/{total} réussie.\n\n"
393
  f"**Score : {score}/10**\n\n**Commentaire :** {fb}"
394
  )
395
+ next_label = "🏆 Voir mon certificat" if is_last else f"➡️ {LESSONS[lesson_idx + 1]['title']}"
 
 
 
396
  else:
397
  state["phase"] = "fail"
398
  result = (
 
403
  )
404
  next_label = "🔄 Réécouter la leçon"
405
 
406
+ # ── Étape 3 : afficher résultat, réactiver bouton, mettre à jour next_btn ─
407
+ yield (
408
  gr.update(visible=False), gr.update(visible=False),
409
  gr.update(visible=True), gr.update(visible=False),
410
+ result,
411
+ gr.update(value="📤 Soumettre", interactive=True),
412
+ gr.update(value="", interactive=True),
413
+ D(state),
414
  )
415
 
416
  def handle_next(ss):
 
468
  audio_out = gr.Audio(label="Cours audio (français)", autoplay=False, interactive=False)
469
  timer_info = gr.Markdown("")
470
  with gr.Row():
471
+ start_btn = gr.Button("▶️ Démarrer l'écoute" + str(_LLAMA_OK), variant="primary")
472
  check_btn = gr.Button("🔄 Vérifier le temps", variant="secondary")
473
  quiz_btn = gr.Button("✅ Accéder au Quiz", variant="secondary", interactive=False)
474
 
 
499
  timer_info, question_md, answer_box, session]
500
  quiz_btn.click(open_quiz, [session], QUIZ_OUT)
501
 
502
+ # ── submit_answer est un générateur → outputs inclut submit_btn et answer_box
503
  RES_OUT = [listen_col, quiz_col, result_col, cert_col,
504
+ result_md, submit_btn, answer_box, session]
505
  submit_btn.click(submit_answer, [answer_box, session], RES_OUT)
506
  answer_box.submit(submit_answer, [answer_box, session], RES_OUT)
507
 
 
512
  threading.Thread(target=get_llm, daemon=True).start()
513
 
514
  if __name__ == "__main__":
515
+ demo.launch(server_name="0.0.0.0", server_port=7860, show_error=True)