Créer des exercices de mathématiques avec des valeurs aléatoires

a marqué ce sujet comme résolu.

Bonjour à tous.

Je suis professeur de mathématiques et j'utilise latex depuis plusieurs années maintenant. Je profite de chaque grande vacances pour travailler de nouveaux projets, chose que je n'ai pas le temps de faire pendant l'année scolaire.

Cette année je souhaite créer des fiches d'exercices prenant des valeurs aléatoires, de façon à éviter la triche entre autre.

Mon premier objectif est de créer un exercice de calcul mental, donc une commande qui prendrait comme arguments le nombre de questions posées.

J'ai pu programmer quelque chose qui ressemble à mon objectif en Python, mais la traduction en latex me pose problème. Voici le code Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import random
i=1
listea=list()
listeb=list()
listec=list()
while i < 21:
    a=random.randint(1,100)
    b=random.randint(1,100)
    c=a+b
    listea.append(a)
    listeb.append(b)
    listec.append(c)
    print(i,")" ,a, "+", b, "=...")
    i+=1

print("CORRECTION")
i=0
while i<20:
    print (i+1,")", listea[i], "+", listeb[i], "=", listec[i])
    i+=1

J'ai trouvé comment générer des nombres aléatoires en latex, ce que je ne sais pas faire c'est générer des listes, puis mettre des valeurs dans des listes et enfin aller rechercher la n-ième valeur d'une liste dans latex.

Voilà les différentes questions que je me pose, je vous remercie si vous avez eu le courage de tout lire et d'avance de votre aide.

Salut,

C’est sûrement possible de faire ça avec LaTeX, mais sinon, tu peux le faire avec Python (en écrivant dans un fichier) que tu incluras ensuite dans ton fichier tex.

Si tu utilises LuaTeX, tu peux aussi utiliser les fonctionnalités de Lua pour le faire.

PS : si tu utilises la solution en Python, ton code peut être amélioré (boucle for plutôt que while par exemple).

+0 -0

Tu peux par exemple écrire un code de ce genre (je l’ai écrit rapidement et sans tester donc je ne sais pas s’il y a des erreurs).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from random import randint

(a, b, c) = ([], [], [])

fichier = open("exo.tex", "w")
fichier.write("\\subsection{Exercices}\n\n")

fichier.write("\\begin{itemize}\n")
for i in range(100):
    a.append(randint(1, 100))
    b.append(randint(1, 100))
    c.append(a[i] + b[i])
    fichier.write("\\item ${} + {} = \ldots$ ;\n".format(a[i], b[i]))
fichier.write("\\end{itemize}\n\n")

fichier.write("\\subsection{Correction}\n\n")

fichier.write("\\begin{itemize}\n")
for i in range(100):
    fichier.write("\\item ${} + {} = {}$ ;\n".format(a[i], b[i], c[i]))
fichier.write("\\end{itemize}")

fichier.close()

@Holosmos : toi tu lui conseilles d’écrire tout le préambule et tout avec Python ? Moi je préfère utiliser un code comme celui que je présente et avoir un fichier tex de ce genre écrit à la main.

1
2
3
4
5
6
7
8
\documentclass{article}
% Inclusion des packages

\begin{document}
% Des trucs avant
\input{exo.tex}
% Des trucs après
\end{document}

Je ne connais pas Luatex, qu'est ce que c'est ?

LuaTeX est un moteur de LateX. J’imagine que tu utilises PdfTeX (commande pdflatex pour compiler).

+0 -0

@Holosmos : toi tu lui conseilles d’écrire tout le préambule et tout avec Python ? Moi je préfère utiliser un code comme celui que je présente et avoir un fichier tex de ce genre écrit à la main.

Je préfère ce que tu proposes, c'est plus modulable.

Désolé mais tout n'est pas clair, je crois que ça va trop vite pour moi.

J'ai copié le code en Python, si j'ai bien compris, ce code devrai créer un document "exo.tex" qui contient ce que je veux, et je n'ai plus qu'à appeler ce document dans mon préambule latex habituel. J'ai donc deux documents, le premier avec le code en python, le second un document .tex. Je ne sais pas lequel je compile en premier, j'ai compilé le programme en python, mais j'ai eu ce message d'erreur: invalid syntaxe, or mes connaissances en Python sont trop minces pour trouver l'erreur.

mais j'ai eu ce message d'erreur: invalid syntaxe, or mes connaissances en Python sont trop minces pour trouver l'erreur.

Quel est le message d’erreur complet ? J’ai testé le programme et il fonctionne. Quelle version de Python utilises-tu ? Le mieux est de suivre rapidement un petit tutoriel sur Python. En quelques heures, tu devrais pouvoir comprendre le code que j’ai écrit.

+0 -0

Jinja c'est un moteur de template, qui génère des fichiers à partir de templates. Tu peux avoir du code Python dans le fichier de template, et Jinja produit le fichier final. Regarde des exemples de templates Jinja, l'idée c'est d'avoir des blocs du style {{une variable python}} dans ton fichier LaTeX et Jinja remplacera tout comme il faut.

+0 -0

En eTeX/LaTeX :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xstring}
\newcount\cntquestions
\newcommand*\genquestions[1]{% génère #1 additions
    \begin{enumerate}
        \let\questions\empty
        \global\cntquestions0
        \loop
            \ifnum\cntquestions<\numexpr#1\relax
                \global\advance\cntquestions1
                \edef\opa{\the\numexpr\pdfuniformdeviate99+1}\edef\opb{\the\numexpr\pdfuniformdeviate99+1}%
                \xdef\questions{\questions\opa+\opb=\the\numexpr\opa+\opb\relax,}%
                \item$\opa+\opb=\ldots$
        \repeat
    \end{enumerate}
}
\newcommand*\correction{%
    \begin{enumerate}
        \edef\numquestions{\the\cntquestions}%
        \cntquestions0
        \loop
            \ifnum\cntquestions<\numquestions\relax
            \advance\cntquestions1
            \StrCut\questions,\qquestion\questions
            \item$\qquestion$
        \repeat
    \end{enumerate}
}

\begin{document}
L'interrogation :
\genquestions{10}
\bigbreak

La correction :
\correction
\end{document}

Non, ça ne l'est pas. Je te propose d'étudier le code suivant, qui me semble suffisamment documenté vis-à-vis de ce que tu as proposé dans ton premier post.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# generer_exercice.py
# Importation du module d'aléa.
import random

# Définition des modèles LaTeX.
# On veut que les exercices soient de forme
#      12 + 24 = …
# et les corrigés
#      12 + 24 = 36
TEMPLATES = { "question": "\\item ${a} + {b} = \ldots$",
              "answer": "\\item ${a} + {b} = {c}$" }
# Plage pour les nombres
RANGE = (1,1000)
# Nombre de questions à générer
NQUESTIONS = 50
# Fichier de sortie
QUESTIONS = "ex0-que.tex"
ANSWERS = "ex0-ans.tex"

def generate_question():
    "Génère une question."
    # On génère deux nombres aléatoires.
    a, b = random.randint(RANGE[0], RANGE[1]), \
           random.randint(RANGE[0], RANGE[1])
    # Retourne une tuple (a, b, a+b)
    return a, b, a + b

def generate_questions():
    "Génère les 3-uplets des questions."
    # On génère une liste de questions d'une longueur correspondant
    # à QUESTIONS
    # C'est équivalent à
    # out = []
    # for _ in range(NQUESTIONS):
    #     out.append(generate_question())
    # return out
    return [generate_question() for _ in range(NQUESTIONS)]

# Génère une fois pour toute les questions qui seront 
# imprimées dans les fichiers `ex0-que.tex` et `ex0-ans.tex`.
questions = generate_questions()

# On ouvre le fichier `ex0-que.tex` avec le drapeau `w`, c'est-à-dire
# « écriture »
with open(QUESTIONS, 'w') as que:
    # On applique la fonction anonyme
    # \x -> TEMPLATES.format(a=x[0], b=x[1])
    # (c'est-à-dire formatter les réponses selon le modèle)
    # sur chaque élément de la liste `questions` (fonction map)
    # et les assemble par des sauts de ligne (fonction `join`, 
    #      et \n pour marquer les sauts de ligne).
    # La fonction `format` utilise un modèle et remplace certains
    # éléments par les valeurs fournies, par exemple ici `{a}` sera
    # remplacé par la valeur de x[0]
    #
    # C'est équivalent à 
    # for question in questions:
    #    a, b, c = question
    #    formatted = TEMPLATES["questions"].format(a=a,
    #                                              b=b)
    #    que.write("{}\n".format(formatted))
    que.write("\n".join(map(lambda x:
                            TEMPLATES["question"].format(a=x[0],
                                                         b=x[1]), questions)))

with open(ANSWERS, 'w') as ans:
   # Même chose
   ans.write("\n".join(map(lambda x:
                           TEMPLATES["answer"].format(a=x[0],
                                                      b=x[1],
                                                      c=x[2]), questions)))

Cela produira deux fichiers (ex0-que.tex et ex0-ans.tex), qui ressembleront à quelque chose comme ça:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
% ex0-que.tex
\item $226 + 391 = \ldots$
\item $519 + 693 = \ldots$
\item $659 + 595 = \ldots$
\item $713 + 483 = \ldots$
\item $862 + 581 = \ldots$
\item $276 + 665 = \ldots$
\item $407 + 751 = \ldots$
\item $601 + 667 = \ldots$
\item $239 + 76 = \ldots$
\item $124 + 297 = \ldots$
% …
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
% ex0-ans.tex
\item $226 + 391 = 617$
\item $519 + 693 = 1212$
\item $659 + 595 = 1254$
\item $713 + 483 = 1196$
\item $862 + 581 = 1443$
\item $276 + 665 = 941$
\item $407 + 751 = 1158$
\item $601 + 667 = 1268$
\item $239 + 76 = 315$
\item $124 + 297 = 421$
% …

Dans le fichier que tu utilises usuellement pour tes questions, qui ressemble probablement à quelque chose comme cela:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
% test.tex
\documentclass{article}
% suite du préambule…

\begin{document}
\chapter{Addition}
\section{Exercices}
\subsection{Questions}
\begin{itemize}
    \item $12 + 13 = \ldots$
    \item $42 + 11= \ldots$
    \item $113 + 22 = \ldots$
    % …
\end{itemize}
\subsection{Réponses}
\begin{itemize}
    \item $12 + 13 = 25$
    \item $42 + 11= 53$
    \item $113 + 22 = 135$
    % …
\end{itemize}
\end{document}

Par quelque chose comme ceci, en faisant usage de la commande \input{<fichier>} de LaTeX. Cette commande va alors aller lire le fichier et l'insérer dans le fichier LaTeX dans lequel la commande est appelée.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
% test.tex
\documentclass{article}
% suite du préambule…

\begin{document}
\chapter{Addition}
\section{Exercices}
\subsection{Questions}
\begin{itemize}
\input{exercices/ex0-que.tex}
\end{itemize}
\subsection{Réponses}
\begin{itemize}
\input{exercices/ex0-ans.tex}
\end{itemize}
\end{document}

Maintenant, en supposant que tu as une structure similaire à celle-ci,

1
2
3
test.tex
exercices/
    generer_exercice.py

Tu pourras lancer, dans le répertoire racine, un script comme suit,

1
2
3
4
#!/bin/sh

cd exercices && python generer_exercice.py && cd ..
pdflatex test.tex

Tu auras donc, en définitif,

1
2
3
4
5
6
test.tex
test.pdf
exercices/
    generer_exercice.py
    ex0-que.tex
    ex0-ans.tex

Edit: formattage LaTeX Edit: ajout de l'équivalence pour le join/map.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte