# Guide de rédaction des questions — QCM v2 (modèles paramétriques) Ce guide explique le format YAML des questions de la v2. La grande nouveauté : les questions sont des **modèles génératifs**. Vous écrivez UNE question avec des variables et des expressions calculées, et la plateforme génère des **centaines de variantes** — valeurs tirées au hasard, propositions recalculées, 4 propositions affichées parmi votre pool. ## Table des matières 1. [L'idée en 30 secondes](#lidée-en-30-secondes) 2. [Structure d'un modèle](#structure-dun-modèle) 3. [Variables et expressions {{ }}](#variables-et-expressions--) 4. [Types de questions (A, K-Prim)](#types-de-questions) 5. [Le pool de propositions](#le-pool-de-propositions) 6. [Math inline (KaTeX)](#math-inline-katex) 7. [Schémas (Typst + CeTZ)](#schémas-typst--cetz) 8. [Import par lot](#import-par-lot) 9. [Erreurs fréquentes](#erreurs-fréquentes) ## L'idée en 30 secondes ```yaml id: distance_vitesse_temps subject: A type: A variables: v: [10, 20, 30, 40] # km/h — une valeur est tirée au hasard t: [1, 2, 3, 4] # h statement: "Une voiture roule à {{v}} km/h pendant {{t}} h. Quelle distance parcourt-elle ?" propositions: - { text: "{{ v * t }} km", correct: true } # la bonne formule - { text: "{{ v + t }} km", correct: false } # erreur classique - { text: "{{ v * t / 2 }} km", correct: false } - { text: "{{ v / t }} km", correct: false } # ... visez 12+ propositions, 4 seront affichées ``` À chaque affichage : le serveur tire `v` et `t`, recalcule toutes les `{{ }}`, choisit 4 propositions distinctes (type A : exactement 1 correcte), les mélange, et **n'envoie jamais** au navigateur laquelle est la bonne. ## Structure d'un modèle | Champ | Requis | Description | |---|---|---| | `id` | ✅ | Slug unique : minuscules, chiffres, `_` ou `-`. Ex : `chute_libre_h` | | `subject` | ✅ | Code du sujet (A, B, C…) | | `type` | ✅ | `A` ou `K-Prim` (voir plus bas) | | `statement` | ✅ | L'énoncé (math `$...$`, valeurs `{{ }}`) | | `propositions` | ✅ | Le pool de propositions (voir plus bas) | | `title` | — | Titre court pour les listes de l'admin | | `show` | — | Nombre de propositions affichées (défaut : 4) | | `variables` | — | Variables aléatoires ; omettre pour une question statique | | `correction` | — | Explication générale montrée après la réponse | | `diagram` | — | Source Typst/CeTZ du schéma (voir plus bas) | | `correction_diagram` | — | Source Typst/CeTZ d'un schéma affiché AVEC la correction générale (révélé seulement après soumission ; mêmes règles que `diagram` : symbolique, sans valeurs numériques) | Champs optionnels PAR PROPOSITION (en plus de `text`/`correct`/`explanation`) : | Champ | Rôle | |---|---| | `diagram` | Schéma Typst/CeTZ affiché DANS la carte de réponse, sous le texte (questions « quel schéma est correct ? »). Compact : il est limité en hauteur à l'affichage, dessiner petit et lisible | | `explanation_diagram` | Schéma affiché avec l'explication de la proposition, révélé après soumission | | `comment` | — | Note interne, jamais montrée aux étudiants | Une question **statique** (sans variables) est simplement un modèle sans champ `variables` — le format reste le même. ## Variables et expressions {{ }} ### Déclarer des variables ```yaml variables: v: [10, 20, 30, 40] # forme courte m: { values: [0.5, 1, 1.5], unit: "kg" } # forme longue (unit = documentation) ``` Chaque variable est une **liste de valeurs** ; une valeur est tirée au hasard par affichage. Choisissez des valeurs qui donnent des résultats « propres ». ### Utiliser des expressions `{{ ... }}` est recalculé à chaque affichage, dans l'énoncé, les propositions, les explications et la correction : - `{{ v }}` — la valeur de la variable - `{{ v * t }}` — n'importe quelle formule arithmétique : `+ - * / % ^ ( )`. Affichage par défaut : **3 chiffres significatifs** (3.0289 → « 3.03 », 0.004905 → « 0.00491 », 2443.2 → « 2440 ») ; les entiers exacts restent affichés tels quels, jamais de zéros de remplissage. Le calcul, lui, est toujours exact : l'arrondi n'existe qu'à l'affichage. - `{{ round(v / t, 1) }}` — force un nombre maximal de décimales quand le défaut ne convient pas (prix, pourcentages…). Les zéros finaux sont élagués : « 10 », jamais « 10.0 ». - `{{ sci(x, 4) }}` — notation scientifique en LaTeX (« 2.998 \times 10^{8} », ici 4 chiffres significatifs ; défaut 3). À n'utiliser QUE dans un contexte math (`$...$` ou `$$...$$`), jamais dans du texte brut. Fonctions disponibles : `round(x, n)`, `sqrt`, `abs`, `pow(a, b)`, `exp`, `ln`, `log10`, `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `floor`, `ceil`, `min(...)`, `max(...)`. Constantes : `pi`, `e`. Attention : `-v^2` se lit `-(v^2)`, comme en mathématiques. ⚠️ `{{v}}` (valeur calculée) et `$v$` (symbole mathématique) sont deux choses différentes : « roule à {{v}} km/h » affiche un nombre ; « la vitesse $\vec{v}$ » affiche le symbole. Les accolades LaTeX simples (`\vec{v}`) ne sont pas touchées — seules les **doubles** accolades sont interprétées. ## Types de questions - **Type A** — une seule bonne réponse. 4 propositions affichées : exactement 1 correcte + 3 distracteurs tirés du pool. Score : 1 ou 0. - **Type K-Prim** — l'étudiant juge chaque proposition affichée **vraie ou fausse**. Barème : tout juste → 1 point ; une seule erreur → 0.5 ; sinon → 0. (`type: K`, ancien alias, est accepté à l'import et normalisé en K-Prim.) ## Le pool de propositions ```yaml propositions: - text: "{{ v * t }} km" correct: true explanation: "$d = v \\cdot t$" # montrée dans la correction - text: "{{ v + t }} km" correct: false explanation: "Unités incompatibles." ``` Règles : - `correct` est **fixe** : la proposition correcte est la *bonne formule* (juste pour toute valeur des variables) ; les distracteurs sont des *formules fausses* (erreurs classiques d'étudiants). Pas de « correct si v > 20 » — c'est voulu. - **Type A : visez 12+ propositions** (1–3 correctes équivalentes, le reste en distracteurs). Plus le pool est grand, moins l'étudiant peut mémoriser. - Le serveur garantit que les propositions affichées ont des **textes distincts** : si deux formules donnent le même nombre pour un tirage, il retire les dés — d'où l'intérêt de valeurs de variables bien choisies. - Écrivez une `explanation` par proposition : c'est ce qui fait la valeur pédagogique de la correction. ## Math inline (KaTeX) La notation est le LaTeX habituel : `$\vec{v}$`, `$\frac{1}{2}mv^2$`, `$$...$$` pour le mode display. Le rendu est fait par **KaTeX** (plus de MathJax) : instantané, sans sauts de mise en page, y compris sur mobile. En YAML, utilisez des guillemets simples `'...'` ou un bloc `|` pour ne pas doubler les backslashs. ## Schémas (Typst + CeTZ) Les schémas sont écrits en **Typst + CeTZ** (plus de TikZ/PNG) et rendus en **SVG** — nets à tous les zooms. Règle d'or : gardez le schéma **symbolique** (étiquettes `$arrow(v)$`, points `A`, `B`), **pas de valeurs numériques** — ainsi le même SVG sert à toutes les variantes de la question. ```yaml diagram: | #import "@preview/cetz:0.4.2" #set page(width: auto, height: auto, margin: 6pt) #cetz.canvas(length: 1cm, { import cetz.draw: * circle((0,0), radius: 3) content((1, 0.2), $A$) content((2.5, 0.7), $B$) }) ``` Note : dans les étiquettes CeTZ, la math est en syntaxe **Typst** (`$arrow(v)$`, pas `\vec{v}`). ## Import par lot Un fichier peut contenir **un seul modèle** (comme ci-dessus) ou une **liste de modèles** : ```yaml - id: question_un subject: A type: A statement: "..." propositions: [...] - id: question_deux subject: B type: K-Prim statement: "..." propositions: [...] ``` Chaque modèle est validé à l'import (structure, expressions, variables déclarées, génération possible) ; les erreurs indiquent le champ fautif. **`id` unique, dans le fichier ET dans toute la banque.** Importer un `id` déjà en base ÉCRASE la question existante et la remet en attente de validation ; un `id` en double dans le fichier fait écraser la première occurrence par la seconde. La revue d'import signale ces deux cas (bandeau gris) et les rejette par défaut — mais la bonne pratique est en amont : lors d'une génération assistée par IA à partir de questions existantes, ne jamais réutiliser les `id` fournis en exemple ; pour une variante, suffixer (`chute_libre_h_v2`). **Essai gratuit.** Chaque carte de la revue d'import porte une case « Essai gratuit » : les questions cochées sont marquées pour l'essai au moment de l'import (même effet que la case de l'onglet Questions). Elle est pré-cochée quand l'`id` commence par `gratuit_`. La question n'est servie à l'essai qu'une fois validée. ## Erreurs fréquentes | Erreur | Cause | |---|---| | `Variable « x » utilisée mais non déclarée` | `{{x}}` dans un texte, mais pas de `x:` sous `variables:` | | `Division by zero` | Une valeur de variable rend un dénominateur nul — retirez-la de la liste | | `impossible de générer 4 propositions distinctes` | Des formules coïncident trop souvent (ex : `v*t` et `v+t` avec v=t=2) — choisissez des valeurs qui les séparent | | `Type A : il faut au moins une proposition correcte` | Aucun `correct: true` dans le pool | | Backslashs cassés | Utilisez `'...'` (guillemets simples) ou un bloc `\|` pour le LaTeX | Des exemples complets et validés se trouvent dans `qcm_bank/examples/` (le bouton « Télécharger l'exemple » de la console en fournit un).