Review CE1/CE2 content: fix 'le arbre', g/ge/gu rule, elision guard on filled sentences (0.8.3)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Denis Defolie
2026-10-12 12:40:55 +02:00
parent a91d9e528c
commit bf180eea01
9 changed files with 80 additions and 24 deletions
@@ -7,11 +7,17 @@
"difficulty": 3, "difficulty": 3,
"type": "multiple_choice", "type": "multiple_choice",
"instruction": "Choisis le bon déterminant.", "instruction": "Choisis le bon déterminant.",
"question": "... arbre est grand.", "question": "... fromage est délicieux.",
"answers": ["Le", "La"], "answers": [
"Le",
"La"
],
"correct_answer": 0, "correct_answer": 0,
"hint": "« Arbre » se termine par un -e, mais il est masculin.", "hint": "« Fromage » se termine par un -e, mais il est masculin.",
"explanation": "« Arbre » est un nom masculin, même s'il se termine par -e : il faut le déterminant masculin « Le ».", "explanation": "« Fromage » est un nom masculin, même s'il se termine par -e : il faut le déterminant masculin « Le ».",
"review_tags": ["genre", "accord_determinant"], "review_tags": [
"genre",
"accord_determinant"
],
"review_status": "draft" "review_status": "draft"
} }
+1 -1
View File
@@ -14,7 +14,7 @@
"ai" "ai"
], ],
"correct_answer": 2, "correct_answer": 2,
"hint": "Avec « je », le verbe « avoir » s'écrit « ai ».", "hint": "Avec « je », le verbe « avoir » est très court et ne finit pas par -s.",
"explanation": "Avec « je », on écrit « ai » : j'ai.", "explanation": "Avec « je », on écrit « ai » : j'ai.",
"review_tags": [ "review_tags": [
"verbes_present", "verbes_present",
@@ -7,14 +7,14 @@
"difficulty": 3, "difficulty": 3,
"type": "multiple_choice", "type": "multiple_choice",
"instruction": "Choisis le bon mot.", "instruction": "Choisis le bon mot.",
"question": "Les grands ... volent haut.", "question": "Les grands ... se balancent dans le vent.",
"answers": [ "answers": [
"oiseau", "arbres",
"oiseaux" "arbre"
], ],
"correct_answer": 1, "correct_answer": 0,
"hint": "Cherche le déterminant, même si un autre mot s'intercale avant le nom.", "hint": "Cherche le déterminant, même si un autre mot s'intercale avant le nom.",
"explanation": "« Les » indique le pluriel, même si l'adjectif « grands » s'intercale avant le nom : il faut écrire « oiseaux ».", "explanation": "« Les » indique le pluriel, même si l'adjectif « grands » s'intercale avant le nom : il faut écrire « arbres ».",
"review_tags": [ "review_tags": [
"pluriel", "pluriel",
"pluriel_nom" "pluriel_nom"
+1 -1
View File
@@ -7,7 +7,7 @@
"difficulty": 3, "difficulty": 3,
"type": "multiple_choice", "type": "multiple_choice",
"instruction": "Choisis le bon mot.", "instruction": "Choisis le bon mot.",
"question": "La ... du volcan a duré trois jours.", "question": "L'... du volcan a duré trois jours.",
"answers": [ "answers": [
"érussion", "érussion",
"érupsion", "érupsion",
+1 -1
View File
@@ -3,7 +3,7 @@
"level": "CE2", "level": "CE2",
"domain": "orthographe", "domain": "orthographe",
"skill": "lettres_et_mots", "skill": "lettres_et_mots",
"statement": "Devant a, o et u, on écrit « ge » pour garder le son doux [ʒ] (nous mangeons). Devant e et i, on écrit « gu » pour le son dur [g] (une guitare).", "statement": "Devant a et o, on écrit « ge » pour garder le son doux [ʒ] (nous mangeons). Devant e et i, on écrit « gu » pour le son dur [g] (une guitare).",
"example": "Nous mangeons. Une guitare. Un garage.", "example": "Nous mangeons. Une guitare. Un garage.",
"review_status": "draft" "review_status": "draft"
} }
+10 -10
View File
@@ -141,11 +141,11 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
- Indice : Le nom « fleur » est féminin. - Indice : Le nom « fleur » est féminin.
- Explication : « Fleur » est un nom féminin : il faut le déterminant féminin « une ». - Explication : « Fleur » est un nom féminin : il faut le déterminant féminin « une ».
- Statut : draft - Statut : draft
- **ce1_accord_determinant_qcm_07** (difficulte 3) : ... arbre est grand. - **ce1_accord_determinant_qcm_07** (difficulte 3) : ... fromage est délicieux.
- Reponses : Le, La - Reponses : Le, La
- Reponse attendue : Le - Reponse attendue : Le
- Indice : « Arbre » se termine par un -e, mais il est masculin. - Indice : « Fromage » se termine par un -e, mais il est masculin.
- Explication : « Arbre » est un nom masculin, même s'il se termine par -e : il faut le déterminant masculin « Le ». - Explication : « Fromage » est un nom masculin, même s'il se termine par -e : il faut le déterminant masculin « Le ».
- Statut : draft - Statut : draft
- **ce1_accord_determinant_qcm_08** (difficulte 3) : ... cabane est grande. - **ce1_accord_determinant_qcm_08** (difficulte 3) : ... cabane est grande.
- Reponses : Le, La - Reponses : Le, La
@@ -1213,7 +1213,7 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
## regle_g_ge_gu (CE2, orthographe) ## regle_g_ge_gu (CE2, orthographe)
**Enonce** : Devant a, o et u, on écrit « ge » pour garder le son doux [ʒ] (nous mangeons). Devant e et i, on écrit « gu » pour le son dur [g] (une guitare). **Enonce** : Devant a et o, on écrit « ge » pour garder le son doux [ʒ] (nous mangeons). Devant e et i, on écrit « gu » pour le son dur [g] (une guitare).
**Exemple** : Nous mangeons. Une guitare. Un garage. **Exemple** : Nous mangeons. Une guitare. Un garage.
@@ -2652,11 +2652,11 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
- Indice : Le déterminant « la » indique une seule porte. - Indice : Le déterminant « la » indique une seule porte.
- Explication : « La » indique un seul objet : le nom reste au singulier, sans -s : « porte ». - Explication : « La » indique un seul objet : le nom reste au singulier, sans -s : « porte ».
- Statut : draft - Statut : draft
- **ce1_pluriel_nom_qcm_07** (difficulte 3) : Les grands ... volent haut. - **ce1_pluriel_nom_qcm_07** (difficulte 3) : Les grands ... se balancent dans le vent.
- Reponses : oiseau, oiseaux - Reponses : arbres, arbre
- Reponse attendue : oiseaux - Reponse attendue : arbres
- Indice : Cherche le déterminant, même si un autre mot s'intercale avant le nom. - Indice : Cherche le déterminant, même si un autre mot s'intercale avant le nom.
- Explication : « Les » indique le pluriel, même si l'adjectif « grands » s'intercale avant le nom : il faut écrire « oiseaux ». - Explication : « Les » indique le pluriel, même si l'adjectif « grands » s'intercale avant le nom : il faut écrire « arbres ».
- Statut : draft - Statut : draft
- **ce1_pluriel_nom_qcm_08** (difficulte 3) : Les belles ... brillent dans le ciel. - **ce1_pluriel_nom_qcm_08** (difficulte 3) : Les belles ... brillent dans le ciel.
- Reponses : étoile, étoiles - Reponses : étoile, étoiles
@@ -3117,7 +3117,7 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
- Indice : Ce mot a deux s : -ssion. - Indice : Ce mot a deux s : -ssion.
- Explication : Le mot « impression » s'écrit avec -ssion. - Explication : Le mot « impression » s'écrit avec -ssion.
- Statut : draft - Statut : draft
- **cm2_tion_sion_qcm_07** (difficulte 3) : La ... du volcan a duré trois jours. - **cm2_tion_sion_qcm_07** (difficulte 3) : L'... du volcan a duré trois jours.
- Reponses : érussion, érupsion, éruption - Reponses : érussion, érupsion, éruption
- Reponse attendue : éruption - Reponse attendue : éruption
- Indice : Le son [sjɔ̃] s'écrit ici avec -ption. - Indice : Le son [sjɔ̃] s'écrit ici avec -ption.
@@ -3177,7 +3177,7 @@ Genere automatiquement depuis `data/` par `tools/generate_content_review.py`. Ne
- **ce1_avoir_qcm_01** (difficulte 1) : J'... une grande trousse. - **ce1_avoir_qcm_01** (difficulte 1) : J'... une grande trousse.
- Reponses : a, as, ai - Reponses : a, as, ai
- Reponse attendue : ai - Reponse attendue : ai
- Indice : Avec « je », le verbe « avoir » s'écrit « ai ». - Indice : Avec « je », le verbe « avoir » est très court et ne finit pas par -s.
- Explication : Avec « je », on écrit « ai » : j'ai. - Explication : Avec « je », on écrit « ai » : j'ai.
- Statut : draft - Statut : draft
- **ce1_avoir_qcm_02** (difficulte 1) : Tu ... mal à la tête. - **ce1_avoir_qcm_02** (difficulte 1) : Tu ... mal à la tête.
+9
View File
@@ -416,3 +416,12 @@ Volume : 6 tableaux, 18 règles, 144 QCM, 72 corrections, 54 dictées (voix Pipe
- **Énoncé de règle incomplet** : « travail → travaux » ajouté à la règle des pluriels en -aux. - **Énoncé de règle incomplet** : « travail → travaux » ajouté à la règle des pluriels en -aux.
**Non vérifié** : lecture faite par Claude, pas par un enseignant ; l'ambiguïté résiduelle possible (ex. « marron » parfois accordé dans l'usage) est assumée au profit de la norme. **Non vérifié** : lecture faite par Claude, pas par un enseignant ; l'ambiguïté résiduelle possible (ex. « marron » parfois accordé dans l'usage) est assumée au profit de la norme.
**Relecture CE1/CE2 (0.8.3)** — même audit que pour les CM, sur les 6 tableaux CE1 et CE2 (QCM, corrections, dictées, règles). Trouvé et corrigé :
- **« Le arbre » (CE1, accord du déterminant)** : l'énoncé « ... arbre est grand. » avec les réponses Le/La n'avait aucune bonne réponse (il faut « l'arbre »). Remplacé par « ... fromage est délicieux. ». Même défaut, de la même famille, dans « La ... du volcan » (CM2, éruption) devenu « L'... du volcan ». Le garde-fou d'élision ne lisait pas les phrases à trous : il reconstitue maintenant la phrase correcte (blanc rempli, mot fautif corrigé) avant de la contrôler.
- **Règle g/ge/gu inexacte** : on écrit « ge » devant a et o (pas u) pour garder le son doux ; énoncé corrigé.
- **Pluriel en -x dans la règle du pluriel en -s** (CE1) : « oiseaux » remplacé par « arbres » (les pluriels en -aux/-eaux sont l'objet du CM1).
- **Indice qui donnait la réponse** (« avoir » avec « je ») reformulé.
Les corrections et les dictées CE1/CE2 n'ont pas révélé d'autre problème ; les tests de doublons, quasi-doublons et de position de la bonne réponse sont verts. **Non vérifié** : relecture par un enseignant.
+1 -1
View File
@@ -11,7 +11,7 @@ config_version=5
[application] [application]
config/name="Les Aventuriers des mots" config/name="Les Aventuriers des mots"
config/version="0.8.2" config/version="0.8.3"
run/main_scene="res://scenes/boot/boot.tscn" run/main_scene="res://scenes/boot/boot.tscn"
config/features=PackedStringArray("4.6", "Forward Plus") config/features=PackedStringArray("4.6", "Forward Plus")
config/icon="res://icon.svg" config/icon="res://icon.svg"
+41
View File
@@ -61,6 +61,28 @@ func test_no_missing_elision_in_game_texts() -> void:
assert_eq(_problems.size(), 0, "Elisions manquantes : %s" % "\n".join(_problems)) assert_eq(_problems.size(), 0, "Elisions manquantes : %s" % "\n".join(_problems))
func test_no_missing_elision_once_the_blank_or_the_error_is_filled_in() -> void:
# Une phrase a trous ou a corriger n'est pas verifiable mot a mot : on
# reconstitue la phrase correcte (« ... arbre » + « Le » = « Le arbre »).
_problems.clear()
for path in _json_files("res://data/exercises"):
var data := _read(path)
var sentence := ""
if data.get("type", "") == "multiple_choice":
var answers: Array = data["answers"]
sentence = str(data["question"]).replace(
"...", str(answers[int(data["correct_answer"])])
)
elif data.get("type", "") == "sentence_correction":
var words: Array[String] = []
for token: Dictionary in data["tokens"]:
words.append(token["text"] if token["correct"] else token["expected"])
sentence = " ".join(words)
if not sentence.is_empty():
_check_text(sentence, "%s (phrase reconstituee)" % data["id"])
assert_eq(_problems.size(), 0, "Elisions manquantes : %s" % "\n".join(_problems))
func test_detector_catches_a_missing_elision() -> void: func test_detector_catches_a_missing_elision() -> void:
_problems.clear() _problems.clear()
_check_text("le arbre est grand", "exemple") _check_text("le arbre est grand", "exemple")
@@ -110,3 +132,22 @@ func _check_text(text: String, where: String) -> void:
if NO_ELISION_WORDS.has(next_word): if NO_ELISION_WORDS.has(next_word):
continue continue
_problems.append("%s : « %s »" % [where, match.get_string(0)]) _problems.append("%s : « %s »" % [where, match.get_string(0)])
func _json_files(path: String) -> Array[String]:
var found: Array[String] = []
var dir := DirAccess.open(path)
if dir == null:
return found
for sub in dir.get_directories():
found.append_array(_json_files(path.path_join(sub)))
for file_name in dir.get_files():
if file_name.ends_with(".json"):
found.append(path.path_join(file_name))
return found
func _read(path: String) -> Dictionary:
var file := FileAccess.open(path, FileAccess.READ)
var parsed: Variant = JSON.parse_string(file.get_as_text())
return parsed if typeof(parsed) == TYPE_DICTIONARY else {}