Aperçu de Maths Trainer
Maths Trainer est un outil de révision 100 % local pour les lycéens de
Terminale. Il génère des exercices aléatoires à partir de modules écrits en JavaScript,
sans serveur ni connexion requise — il suffit d'ouvrir index.html.
Structure du projet
Maths trainer/
├── index.html ← L'application (ouvrir dans le navigateur)
├── wiki.html ← Cette documentation
├── import_module.py ← Script d'import graphique (Python)
├── assets/
│ ├── css/style.css
│ └── js/
│ ├── engine.js ← Utilitaires maths (randInt, gcd…)
│ ├── registry.js ← Arborescence sidebar (à modifier pour ajouter un chapitre)
│ └── app.js ← Logique Alpine.js
└── modules/
├── maths-spe/ ← Modules Terminale Spé
│ ├── pgcd.js
│ └── ...
└── maths-expertes/ ← Modules Maths Expertes
└── gauss-jordan.js
Outil d'import Python
C'est la méthode recommandée pour les professeurs — pas besoin de toucher au code. Le script Python affiche un formulaire graphique et effectue automatiquement les trois modifications nécessaires.
Le script Python fait partie du projet — il faut d'abord télécharger le projet sur GitHub et l'extraire sur ton ordinateur. Le script ne fonctionne pas sur la version en ligne.
Comment lancer le script
Double-clic sur import_module.py
(Python doit être installé avec Add to PATH coché)
Clic droit → Ouvrir avec → Python Launcher
ou dans le Terminal : python3 import_module.py
Dans le Terminal :python3 import_module.py
Le fichier import_module.py doit se trouver dans le dossier racine du projet
(le même dossier que index.html).
Les 3 étapes du formulaire
Clique sur Parcourir… et ouvre le fichier .js
généré par l'IA. Le script lit automatiquement l'identifiant, le titre du chapitre
et la notion.
Sélectionne dans la liste la spécialité cible. Si elle n'existe pas encore, clique sur + Nouvelle spécialité.
Sélectionne la section thématique (ex. Analyse, Algèbre…). Si elle n'existe pas, clique sur + Nouvelle section.
Clique enfin sur ⬇ Importer le module. Le script :
- Copie le fichier JS dans le bon sous-dossier de
modules/ - Ajoute l'entrée dans
assets/js/registry.js(sidebar) - Ajoute la balise
<script>dansindex.html
Créer une nouvelle classe / spécialité
Une spécialité (ou classe) est le premier niveau de l'arborescence : par exemple Maths Spé — Terminale, 1ère Spé, Tronc Commun… Elle apparaît comme un grand titre dans la barre latérale de l'appli.
Via le script Python (recommandé)
- Lance
import_module.py - À l'Étape 2, clique sur + Nouvelle spécialité
- Remplis les champs :
Champ Exemple Rôle Nom * 1ère SpéTitre affiché dans la sidebar Sous-titre Première — SpécialitéPetit texte gris sous le titre Icône (emoji) 📘Icône à gauche du titre - L'identifiant est généré automatiquement (ex.
1ere-spe) - Clique ✓ Créer la spécialité
Manuellement dans registry.js
Dans assets/js/registry.js, ajoute un bloc à la fin du tableau tree: :
// Dans registry.js → tree: [ ..., ← ajouter ici
{
id: '1ere-spe',
label: '1ère Spé',
sublabel: 'Première — Spécialité',
icon: '📘',
open: false,
sections: [], // on ajoutera des sections ensuite
},
L'id doit être unique, en minuscules sans accents ni espaces
(seuls les tirets sont autorisés).
Créer une nouvelle section
Une section est un regroupement thématique de chapitres à l'intérieur d'une spécialité — par exemple Analyse, Algèbre & Arithmétique, Probabilités…
Via le script Python (recommandé)
- Sélectionne d'abord la spécialité cible à l'Étape 2
- À l'Étape 3, clique sur + Nouvelle section
- Saisis le nom de la section (ex.
Probabilités) - L'ID est généré :
1ere-spe-probabilites - Clique ✓ Créer la section
Manuellement dans registry.js
// Dans la spécialité cible, dans son tableau sections: [ ..., ← ajouter ici
{
id: '1ere-spe-probabilites',
label: 'Probabilités',
open: true,
chapters: [], // les modules s'ajouteront ici
},
Étape 1 — Préparer son contenu
Avant de parler à l'IA, prépare ces 6 éléments sur papier ou dans un doc :
ex. : Calcul de limites — forme indéterminée ∞−∞
ex. : Lever une forme ∞−∞ en factorisant par le terme dominant
Sois précis : l'IA implémentera exactement ce que tu décris.
ex. : a : entier dans [2, 8], n : entier dans [2, 5]
L'IA est capable d'inventer une méthode correcte mais différente de la tienne. En fournissant un exemple complet, tu garantis que le code généré enseigne exactement ce que tu as prévu.
Étape 2 — Mega-prompt à donner à l'IA
Copie l'intégralité du texte ci-dessous dans ChatGPT, Claude ou toute
autre IA, puis remplace les parties entre [crochets] par ton contenu.
Utilise le bouton "Copier" en haut à droite du bloc de code, ou sélectionne tout le texte avec Ctrl+A dans la zone.
===========================================================================
Tu es un développeur JavaScript spécialisé en mathématiques de lycée (Terminale française).
Je veux que tu génères un module d'exercice pour un outil web de révision.
L'outil utilise les bibliothèques déjà chargées (KaTeX, Alpine.js).
Un objet global `Engine` est disponible avec ces utilitaires :
Engine.randInt(min, max) → entier aléatoire dans [min, max]
Engine.gcd(a, b) → PGCD de a et b
Engine.lcm(a, b) → PPCM de a et b
Engine.reduceFraction(num, den) → {num, den} fraction irréductible
Engine.latexFraction(num, den) → chaîne LaTeX : "\dfrac{n}{d}" ou "n"
Engine.randIntWhere(min, max, fn) → entier satisfaisant fn(v) === true
Engine.coprimePair(minQ, maxP) → {p, q} avec pgcd(p,q)=1 et p>q≥minQ
Engine.euclidSteps(a, b) → {steps, pgcd} de l'algorithme d'Euclide
Engine.shuffle(array) → copie mélangée du tableau
FORMAT OBLIGATOIRE — le fichier doit contenir exactement ceci :
MathsTrainer.register({
id: 'identifiant-sans-espaces-ni-accents',
chapitre: 'Titre affiché',
notion: 'Une phrase décrivant ce que l\'élève apprend à faire',
methode: [
'Étape 1 avec $LaTeX$ si besoin.',
'Étape 2...',
],
generate() {
const enonce = `...texte avec $LaTeX$ inline et $$LaTeX$$ en bloc...`;
const correction = `...HTML avec $LaTeX$ et $$LaTeX$$...`;
return { enonce, correction };
},
});
RÈGLES LATEX DANS LES CHAÎNES JAVASCRIPT :
- Formule inline : $formule$
- Bloc display centré : $$formule$$
- Tout \ LaTeX devient \\ en JS (ex: \frac → \\frac, \times → \\times)
- Saut de ligne dans aligned : \\\\ en JS
- Macros disponibles sans les redéfinir : \\pgcd \\ppcm \\N \\Z \\R \\Q \\C
HTML AUTORISÉ dans la correction :
<p>texte</p>
<strong>texte</strong>
<div class="my-4 overflow-x-auto">$$...$$</div> ← pour un bloc display
<div class="result-highlight">$$résultat final$$</div> ← encadre le résultat
IMPORTANT :
- N'invente PAS la méthode : implémente EXACTEMENT les étapes que je fournis
- Génère UNIQUEMENT le contenu du fichier JS, sans explications avant ni après
- L'id doit être en minuscules, sans espaces, sans accents (tirets autorisés)
VOICI LE CHAPITRE À IMPLÉMENTER :
CHAPITRE: [écrire le nom du chapitre ici]
NOTION: [une phrase]
MÉTHODE:
Étape 1 — [ta description]
Étape 2 — [ta description]
Étape 3 — [ta description]
(ajouter autant d'étapes que nécessaire)
VARIABLES:
[nom]: entier, plage [min, max]
[nom]: entier, plage [min, max], contrainte : [décrire]
ÉNONCÉ EXEMPLE (avec des vraies valeurs) :
[coller ici un exemple d'énoncé complet avec des valeurs concrètes]
CORRECTION EXEMPLE (de l'énoncé ci-dessus) :
[coller ici la correction complète, étape par étape]
===========================================================================
Exemple rempli
CHAPITRE: Suites géométriques — terme général
NOTION: Calculer un terme u_n connaissant u_0 et la raison q
MÉTHODE:
Étape 1 — Rappeler la formule : u_n = u_0 × q^n
Étape 2 — Substituer u_0, q et n
Étape 3 — Calculer q^n puis multiplier par u_0
VARIABLES:
u0 : entier dans [1, 10]
q : entier dans [2, 5]
n : entier dans [2, 5]
(contrainte : u0 × q^n ≤ 10 000 pour rester lisible)
ÉNONCÉ EXEMPLE :
Soit (u_n) une suite géométrique de premier terme u_0 = 3 et de raison q = 2.
Calculer u_4.
CORRECTION EXEMPLE :
On applique la formule : u_n = u_0 × q^n
Donc u_4 = 3 × 2^4 = 3 × 16 = 48
Étape 3 — Vérifier le code généré
Avant d'importer, vérifie rapidement que le module respecte le format :
| Vérification | À chercher dans le code |
|---|---|
| ✅ Commence bien | MathsTrainer.register({ |
| ✅ Champs présents | id:, chapitre:, notion:, methode:, generate() |
| ✅ Se termine bien | }); seul sur la dernière ligne |
| ✅ Méthode correcte | Les étapes correspondent à ce que tu as écrit |
| ✅ Retour valide | return { enonce, correction }; dans generate() |
Dis à l'IA : "Relance la génération en respectant exactement la méthode que j'ai fournie, et génère uniquement le code JS sans commentaires autour."
Étape 4 — Importer le module
Deux approches : le script Python (recommandé) ou la méthode manuelle.
Avec le script Python
- Sauvegarde le code généré par l'IA dans un fichier
.jsn'importe où sur ton ordinateur - Lance
import_module.py - Étape 1 → Parcourir… → sélectionne ton fichier
- Étape 2 → choisis la spécialité
- Étape 3 → choisis la section
- Clique ⬇ Importer le module
Manuellement
Voir la section Méthode manuelle ci-dessous.
Étape 5 — Tester le module
- Double-clique sur
index.html— il s'ouvre dans le navigateur - Dans la sidebar, trouve ton chapitre — il doit apparaître sans badge bientôt
- Clique dessus — l'exercice doit se générer
- Clique sur Nouvel exercice plusieurs fois (5–6 fois minimum) pour vérifier que toutes les valeurs produites sont correctes
- Vérifie la correction en cliquant sur Voir la correction
Génère ~10 exercices et vérifie : les valeurs sont-elles raisonnables ? Les calculs dans la correction sont-ils exacts ? La mise en forme est-elle propre ?
Méthode manuelle (VS Code)
Pour les utilisateurs à l'aise avec l'édition de code.
1. Créer le fichier JS
- Dans VS Code, ouvre le dossier Maths trainer (Fichier → Ouvrir un dossier)
- Dans l'arborescence, clic droit sur
modules/maths-spe/→ Nouveau fichier - Nomme-le avec l'
iddu module : ex.suites-geo.js - Colle le code généré par l'IA → Ctrl+S
2. Ajouter la balise script dans index.html
- Ouvre
index.html - Cherche (Ctrl+F) :
/MODULES - Juste avant la ligne
<!-- /MODULES -->, ajoute :
<script src="modules/maths-spe/suites-geo.js"></script>
<!-- /MODULES -->
3. Ajouter le chapitre dans registry.js
- Ouvre
assets/js/registry.js - Cherche la section cible (ex.
spe-analyse) - Dans son tableau
chapters:, ajoute une ligne :
chapters: [
// ... chapitres existants ...
{ id: 'suites-geo', label: 'Suites géométriques — terme général' },
],
L'id dans registry.js doit être exactement identique
à l'id: déclaré dans le fichier JS du module — casse, tirets compris.
Format du module JS — référence complète
MathsTrainer.register({
// ── Identifiant ────────────────────────────────────────────────────────
// Même valeur que l'entrée dans registry.js.
// Minuscules, sans espaces ni accents, tirets autorisés.
id: 'mon-module',
// ── Affiché dans l'interface ────────────────────────────────────────────
chapitre: 'Titre complet affiché en haut de la page',
notion: 'Une phrase décrivant ce que l\'élève s\'entraîne à faire.',
// ── Méthode ─────────────────────────────────────────────────────────────
// Tableau de strings. Chaque string = une étape numérotée.
// Supporte HTML inline et LaTeX entre $...$ (rendu par KaTeX).
methode: [
'Étape 1 — reconnaître le type de $f$ : polynôme, $\\sin$, $e^x$…',
'Étape 2 — trouver une primitive $F$ vérifiant $F\'(x) = f(x)$.',
'Étape 3 — calculer $F(b) - F(a)$ et simplifier.',
],
// ── Générateur d'exercice ────────────────────────────────────────────────
// Appelé à chaque "Nouvel exercice".
// Doit renvoyer EXACTEMENT { enonce, correction } (deux chaînes).
generate() {
// Variables aléatoires
const a = Engine.randInt(1, 5);
const n = Engine.randInt(2, 4);
// Énoncé — texte avec LaTeX inline $...$
const enonce = `Calculer $\\displaystyle\\int_0^1 ${a}x^{${n}}\\,dx$.`;
// Correction — HTML avec LaTeX $...$ et $$...$$
const correction =
`<p>La primitive de $f(x) = ${a}x^{${n}}$ est
$F(x) = ${Engine.latexFraction(a, n+1)}x^{${n+1}}$.</p>` +
`<div class="my-4 overflow-x-auto">
$$\\begin{aligned}
\\int_0^1 ${a}x^{${n}}\\,dx &= \\Bigl[F(x)\\Bigr]_0^1 \\\\
&= ${Engine.latexFraction(a, n+1)}
\\end{aligned}$$
</div>` +
`<div class="result-highlight">$$\\text{résultat} = ${Engine.latexFraction(a, n+1)}$$</div>`;
return { enonce, correction };
},
});
API Engine — référence
L'objet Engine est disponible globalement dans tous les modules.
| Méthode | Retour | Description |
|---|---|---|
Engine.randInt(min, max) |
number |
Entier aléatoire dans [min, max] inclus |
Engine.gcd(a, b) |
number |
PGCD de a et b (algorithme d'Euclide) |
Engine.lcm(a, b) |
number |
PPCM de a et b |
Engine.reduceFraction(num, den) |
{ num, den } |
Fraction irréductible |
Engine.latexFraction(num, den) |
string |
Renvoie "n" si den=1, sinon "\\dfrac{n}{d}" |
Engine.randIntWhere(min, max, fn) |
number |
Entier dans [min,max] satisfaisant fn(v) === true |
Engine.coprimePair(minQ, maxP) |
{ p, q } |
Paire première entre elle avec p > q ≥ minQ |
Engine.euclidSteps(a, b) |
{ steps, pgcd } |
Étapes de l'algorithme d'Euclide (voir pgcd.js) |
Engine.signedInt(n, isFirst) |
string |
"+3" ou "-3" selon le signe et la position |
Engine.shuffle(array) |
array |
Copie mélangée (Fisher-Yates) — utile pour les QCM |
Exemples d'usage
// Entier aléatoire
const a = Engine.randInt(2, 10); // ex. 7
// Fraction aléatoire irréductible
const { p, q } = Engine.coprimePair(2, 9); // ex. {p: 7, q: 3}
const frac = Engine.latexFraction(p, q); // "\\dfrac{7}{3}"
// Contrainte : a pair
const a = Engine.randIntWhere(2, 20, v => v % 2 === 0);
// Étapes Euclide
const { steps, pgcd } = Engine.euclidSteps(48, 18);
// steps[0] = { dividend: 48, divisor: 18, quotient: 2, remainder: 12 }
LaTeX dans les chaînes JavaScript
Dans une chaîne JS, chaque \ LaTeX s'écrit \\.
Donc \frac devient \\frac, et le saut de ligne LaTeX
\\ devient \\\\.
Tableau de conversion
| Tu veux écrire en LaTeX | Tu écris dans JS |
|---|---|
\frac{a}{b} | \\frac{a}{b} |
\dfrac{a}{b} | \\dfrac{a}{b} |
\times | \\times |
\sqrt{x} | \\sqrt{x} |
\int_a^b | \\int_a^b |
\begin{aligned} | \\begin{aligned} |
\\ (saut de ligne dans aligned) | \\\\ |
\displaystyle | \\displaystyle |
\operatorname{pgcd} | \\operatorname{pgcd} |
Modes d'affichage
| Mode | Syntaxe JS | Rendu |
|---|---|---|
| Inline (dans le texte) | `La valeur de $a^2$ est…` |
La valeur de a² est… |
| Bloc centré | `$$\\frac{a}{b}$$` |
Fraction centrée sur sa propre ligne |
| Bloc aligné | `$$\\begin{aligned} a &= b \\\\ c &= d \\end{aligned}$$` |
Calculs alignés sur le signe = |
Macros pré-définies
| Macro JS | Rendu | À utiliser pour |
|---|---|---|
\\pgcd | pgcd (romain) | PGCD de deux entiers |
\\ppcm | ppcm (romain) | PPCM de deux entiers |
\\N | ℕ | Entiers naturels |
\\Z | ℤ | Entiers relatifs |
\\R | ℝ | Réels |
\\Q | ℚ | Rationnels |
\\C | ℂ | Complexes |
Exemple de correction complète
const correction =
`<p>On développe le calcul :</p>` +
`<div class="my-4 overflow-x-auto">` +
`$$\\begin{aligned}` +
` ${a}^{${n}} &= ${Array(n).fill(a).join(' \\\\times ')} \\\\` +
` &= ${Math.pow(a, n)}` +
`\\end{aligned}$$` +
`</div>` +
`<div class="result-highlight">$$${a}^{${n}} = ${Math.pow(a, n)}$$</div>`;
Classes CSS disponibles dans la correction
| Classe | Usage | Aperçu |
|---|---|---|
result-highlight |
Encadre le résultat final avec un fond jaune | $$a^n = 8$$ |
my-4 overflow-x-auto |
Bloc display centré avec défilement horizontal si formule large | <div class="my-4 overflow-x-auto">$$...$$</div> |
mt-1 text-xs text-slate-500 |
Petite note grise sous un bloc de calcul | On utilise ln(e) = 1 et ln(1) = 0. |
L'application charge Tailwind CSS en CDN. Tu peux donc utiliser n'importe quelle
classe utilitaire Tailwind dans le HTML de ta correction :
font-bold, text-blue-600, border, etc.
Dépannage
Le chapitre apparaît avec le badge "bientôt"
L'id dans registry.js et l'id:
dans le fichier JS ne correspondent pas exactement. Vérifie les majuscules et les tirets.
// registry.js
{ id: 'pgcd', label: '...' } ← doit être identique ↓
// pgcd.js
MathsTrainer.register({ id: 'pgcd', ... })
Page blanche ou écran d'erreur au chargement
Ouvre la console du navigateur avec F12 → onglet Console. L'erreur rouge indique le fichier et la ligne problématiques. Copie ce message et donne-le à l'IA :
"J'ai ce message d'erreur dans la console du navigateur, corrige le fichier JS : [message d'erreur]"
Les formules n'apparaissent pas (tu vois le LaTeX brut)
KaTeX se charge via internet (CDN). Vérifie ta connexion internet et recharge la page. Si tu travailles hors-ligne, télécharge KaTeX localement.
Le script Python ne se lance pas
Python 3 n'est pas installé ou n'est pas dans le PATH.
- Télécharge Python 3 sur
python.org - Lors de l'installation Windows, coche "Add Python to PATH"
- Relance le script
Le script Python dit "Dossier incorrect"
Le fichier import_module.py doit se trouver
dans le même dossier que index.html.
Ne le déplace pas dans un sous-dossier.
Les valeurs générées sont parfois impossibles
L'IA a choisi des plages trop larges. Ouvre le fichier JS,
repère les Engine.randInt() et ajuste les bornes.
Utilise Engine.randIntWhere() pour ajouter une contrainte :
// Forcer un résultat ≤ 100
const n = Engine.randIntWhere(2, 5, v => u0 * Math.pow(q, v) <= 100);