mirror of
https://github.com/deunix-educ/aventuriers-des-mots.git
synced 2026-10-13 02:11:58 +02:00
Tolerate missing terminal punctuation in dictée answers
Manual test: the Piper voice (previous commit) is now intelligible,
but typing exactly what's heard ("Les petits chats dorment", no
period) was rejected. The provisional audio never vocalizes
punctuation, so nothing tells the child to add it — penalizing its
absence punishes information they were never given.
DictationAnalyzer now strips terminal punctuation (. ! ? …) from both
sides before comparing, in the exact-match/variant check and before
word alignment, without touching punctuation elsewhere in the
sentence. A real error on the last word is still caught (added test).
A scene-level test reproducing the exact reported interaction
(tests/exercises/test_exercise_host_dictation.gd) failed before the
fix and passes after.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,13 @@ extends RefCounted
|
||||
## ni hasard. L'explication complete (texte de la regle) est composee par la
|
||||
## couche d'affichage a partir des rule_id retournes, pas ici.
|
||||
|
||||
## Ponctuation de fin de phrase ignoree a la comparaison : l'audio provisoire
|
||||
## (point 19/20 de docs/specs/decisions.md) ne la fait pas entendre, donc rien
|
||||
## dans ce que l'enfant ecoute ne lui indique qu'il faut l'ecrire. L'exiger
|
||||
## serait sanctionner une information qu'il n'a pas recue (CLAUDE.md : une
|
||||
## erreur declenche une explication, jamais une punition).
|
||||
const TERMINAL_PUNCTUATION := ".!?…"
|
||||
|
||||
|
||||
static func analyze(dictation: Dictionary, submitted_text: String) -> CorrectionResult:
|
||||
var normalized_submitted := TextNormalizer.normalize(submitted_text)
|
||||
@@ -16,8 +23,10 @@ static func analyze(dictation: Dictionary, submitted_text: String) -> Correction
|
||||
if _matches_target_or_variant(dictation, normalized_submitted, normalized_target):
|
||||
return CorrectionResult.correct(_build_explanation(0))
|
||||
|
||||
var target_words := TextNormalizer.split_words(normalized_target)
|
||||
var submitted_words := TextNormalizer.split_words(normalized_submitted)
|
||||
var target_words := TextNormalizer.split_words(_strip_terminal_punctuation(normalized_target))
|
||||
var submitted_words := TextNormalizer.split_words(
|
||||
_strip_terminal_punctuation(normalized_submitted)
|
||||
)
|
||||
var words_meta: Array = dictation["words"]
|
||||
|
||||
# L'alignement se fait insensible a la casse : une majuscule manquante est
|
||||
@@ -74,14 +83,27 @@ static func analyze(dictation: Dictionary, submitted_text: String) -> Correction
|
||||
static func _matches_target_or_variant(
|
||||
dictation: Dictionary, normalized_submitted: String, normalized_target: String
|
||||
) -> bool:
|
||||
if normalized_submitted == normalized_target:
|
||||
var stripped_submitted := _strip_terminal_punctuation(normalized_submitted)
|
||||
if stripped_submitted == _strip_terminal_punctuation(normalized_target):
|
||||
return true
|
||||
for variant: String in dictation.get("accepted_variants", []):
|
||||
if normalized_submitted == TextNormalizer.normalize(variant):
|
||||
if stripped_submitted == _strip_terminal_punctuation(TextNormalizer.normalize(variant)):
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
## Retire les signes de ponctuation terminale (un ou plusieurs, ex. "?!") en
|
||||
## fin de texte. N'affecte pas la ponctuation interne a la phrase.
|
||||
static func _strip_terminal_punctuation(text: String) -> String:
|
||||
var result := text
|
||||
while (
|
||||
not result.is_empty()
|
||||
and TERMINAL_PUNCTUATION.find(result.substr(result.length() - 1)) != -1
|
||||
):
|
||||
result = result.substr(0, result.length() - 1)
|
||||
return result.strip_edges()
|
||||
|
||||
|
||||
static func _classify_error(words_meta: Array, target_index: int, found: String) -> Dictionary:
|
||||
var meta: Dictionary = words_meta[target_index] if target_index < words_meta.size() else {}
|
||||
var expected: String = meta.get("text", "")
|
||||
|
||||
Reference in New Issue
Block a user