Projet : Mathématiques et BODMAS
([Link]
Dans ce projet, nous allons écrire un programme qui teste notre compréhension
de la règle de calcul arithmétique BODMAS (
B Brackets first
O Orders (i.e. Powers and Square Roots, etc.)
DM Division and Multiplication (left-to-right)
AS Addition and Subtraction (left-to-right)
Notre programme définira au hasard une question arithmétique à laquelle nous
devons répondre. Si nous obtenons une mauvaise réponse, le programme
affichera la bonne réponse et demandera si nous voulons essayer une nouvelle
question.
De plus, le programme gardera une trace de nos tentatives et enregistrera les
tentatives dans un fichier texte externe.
Après chaque question, nous pouvons taper « -1 » pour terminer le programme.
Travail à faire
Partie 1 : [Link]
Nous allons écrire deux fichiers pour nos programmes. Le premier fichier est
[Link] et le 2éme est [Link].
La partie 1 se concentrera sur l'écriture du code pour [Link].
Pour commencer, créons d'abord le fichier [Link]. Nous allons
définir trois fonctions dans ce fichier.
Tâche 1 : Importation de modules
Nous devons importer deux modules pour [Link]: random et os.
1/8
Nous utiliserons la fonction randint() du module random. La fonction randint()
génère un entier aléatoire dans la plage fournie. Nous allons l'utiliser pour
générer les chiffres des entiers pour nos questions plus tard.
Nous utiliserons, également, les fonctions remove() et rename() du module os.
Tâche 2 : Obtenir le score de l'utilisateur
Ici, nous allons définir notre première fonction. Appelons-la getUserPoint().
Cette fonction accepte un seul paramètre le nom d'utilisateur. Elle ouvre alors le
fichier '[Link]' en mode « r ». [Link] ressemble à quelque chose
comme ça :
A, 100
B, 102
C, 214
D, 129
Chaque ligne enregistre les informations d'un utilisateur. La première valeur est
le nom d'utilisateur et le deuxième est le score de l'utilisateur.
Ensuite, la fonction lit le fichier ligne par ligne à l'aide d'une boucle for. Chaque
ligne est ensuite fractionnée à l'aide de la fonction split() et stocker les résultats
dans une liste.
Ensuite, la fonction vérifie si l'une des lignes a le même nom d'utilisateur que la
valeur transmise comme paramètre. Si le nom existe, la fonction ferme le fichier
et renvoie le score à côté de celui-ci (Nom d'utilisateur). Si le nom d’utilisateur
n’existe pas dans la liste, la fonction ferme le fichier et renvoie la chaîne '-1'.
Tâche 3 : Mettre à jour le score de l'utilisateur
Nous allons définir une autre fonction appelée updateUserPoints(), qui prend
trois paramètres : newUser, userName et score.
newUser peut être soit True ou False. Si newUser est True, la fonction ouvrira
le fichier [Link] en mode ajout pour ajouter l’utilisateur userName et
score au fichier quand il ou elle quitte le jeu.
Si newUser est False, la fonction mettra à jour le score de l'utilisateur dans le
fichier. Cependant, il n'y a pas de fonction en Python (ou dans la plupart des
langages de programmation d'ailleurs) qui nous permet de mettre à jour un
fichier texte. Nous ne pouvons que créer ou ajouter, mais pas mettre à jour.
2/8
Par conséquent, nous devons créer un fichier temporaire. C'est une pratique
assez courante en programmation. Appelons ce fichier [Link] et
ouvrez-le en mode « w ». Maintenant, nous aurons besoin de parcourir
[Link] et copier les données ligne par ligne dans [Link].
Cependant, avant copie, nous vérifierons si le Nom d'utilisateur sur cette ligne
est le même que celui fourni comme paramètre. Si c'est le même, nous
changerons le score par le nouveau score avant de l'écrire dans le fichier
temporaire.
Après avoir fini d'écrire dans [Link], nous allons fermer les deux fichiers
et supprimer [Link]. Enfin, nous renommerons [Link] à
[Link].
Tâche 4 : Génération des questions
Nous arrivons maintenant à la partie la plus importante du programme, générer
les questions.
Pour générer les questions, déclarons d'abord trois variables : deux listes et un
dictionnaire.
Nous nommerons les deux listes operandList et operatorList.
operandList doit stocker cinq nombres, avec 0 comme valeur initiale.
operatorList devra stocker quatre chaînes, avec "" comme valeur initiale.
Le dictionnaire se compose de 4 paires, avec des nombres entiers de 1 à 4
comme clés du dictionnaire, et « + », « - », « * », « ** » comme données.
Appelons ça operatorDict.
Action 4.1 : Mise à jour d’operandList avec des nombres aléatoires
Nous devons d'abord remplacer les valeurs initiales de notre operandList avec
des nombres aléatoires généré par la fonction randint().
Pour mettre à jour notre operandList avec des nombres aléatoires, nous pouvons
le faire un par une boucle for.
Action 4.2 : Mise à jour liste operatorList avec des symboles mathématiques
Maintenant que nous avons les nombres sur lesquels opérer, nous devons
générer aléatoirement les symboles mathématique (+, -, *, **) pour nos
3/8
questions. Pour ce faire, nous utiliserons le la fonction randint() et le
dictionnaire operatorDict.
randint() générera la clé du dictionnaire, qui sera ensuite mappée sur le bon
opérateur en utilisant le dictionnaire operatorDict. Par exemple, pour affecter le
symbole à operatorList[0], nous écrivons :
operatorList[0] = operatorDict[randint(1, 4)]
Semblable à l’Action 4.1, vous devez utiliser une boucle for pour terminer cette
tâche. Cependant, il y a un problème qui rend cette Action plus difficile que 4.1.
Rappelez-vous qu'en Python, ** signifie exposant (c'est-à-dire 2**3 = 2^3) ?
Le problème est que, lorsque nous avons deux opérateurs exposants consécutifs
en Python, tels que 2**3**2, Python l'interprète comme 2**(3**2) au lieu de
(2**3)**2. Dans le premier cas, la réponse est 2 au puissance de 9 (c'est-à-dire
29) qui vaut 512. Dans le second cas, la réponse est 8 puissance 2 (c'est-à-dire
82) qui est 64. Par conséquent, lorsque nous présentons une question comme
2**3**2, l'utilisateur aura une mauvaise réponse s'il l'interprète comme
(2**3)**2.
Pour éviter ce problème, nous allons modifier notre code afin de ne pas avoir
deux signes ** consécutifs. En d'autres termes, OperatorList = ['+', '+', '-', '**']
c'est bien mais OperatorList = ['+', '-', '**', '**'] n'est pas.
Action 4.3 : Générer une expression mathématique
Maintenant que nous avons nos opérateurs et opérandes, nous allons essayer de
générer l’expression mathématique sous forme de chaîne. Cette expression
utilise les cinq nombres de notre operandList et les quatre symboles
mathématiques de notre OperatorList pour former une question.
Nous devons déclarer une autre variable appelée questionString et assigner la
l’expression mathématique à questionString.
Exemples de questionString :
6 – 2*3 – 2**1
4 + 5 – 2*6 + 1
8 – 0*2 + 5 – 8
4/8
Action 4.4 : Évaluation du résultat
Nous devrions maintenant avoir une expression mathématique sous forme de
chaîne, affectée à la variable questionString. Pour évaluer le résultat de cette
expression, nous allons utiliser la fonction intégrée qui vient avec Python,
eval().
eval() interprète une chaîne comme un code et exécute le code. Par exemple, si
nous écrivons eval ("1+2+4"), nous obtiendrons la valeur 7.
Par conséquent, pour évaluer le résultat de notre expression mathématique, nous
passons questionString à la fonction eval() et affectez le résultat à une nouvelle
variable nommée result.
Action 4.5 : Interagir avec l'utilisateur
Enfin, nous allons interagir avec notre utilisateur selon les étapes suivantes :
Étape 1 : Affichage de la question à l'utilisateur
Étape 2 : inviter l'utilisateur à répondre
Étape 3 : Évaluation de la réponse, affichage du message approprié et retour du
score de l'utilisateur
Pour l'étape 1, nous devons utiliser une fonction intégrée pour manipuler les
chaînes. Comme mentionné précédemment, dans Python, le symbole ** signifie
exposant. C'est-à-dire 2**3 = 8. Cependant, pour la plupart des utilisateurs, **
n'a pas de sens. Par conséquent, si nous affichons une question sous la forme
2**3 + 8 -5, l'utilisateur sera probablement confus. Pour éviter cela, nous
remplacerons tout symbole ** dans questionString avec le symbole ^.
Pour ce faire, nous utiliserons la fonction intégrée replace(). Son utilisation est
assez simple, il suffit d’écrire questionString = [Link]("**",
"^"). Vous pouvez maintenant afficher l'expression résultante à l'utilisateur.
Pour l'étape 2, vous pouvez utiliser la fonction input() pour accepter l'entrée de
l'utilisateur.
Pour l'étape 3, vous devez utiliser un énoncé if pour évaluer la réponse et
afficher le bon message. Si l'utilisateur répond correctement, nous
complimenterons l'utilisateur et renverrons la valeur 1. Si le l'utilisateur se
trompe, nous afficherons la bonne réponse et renverrons la valeur 0.
5/8
Rappelons que la fonction input() renvoie l'entrée utilisateur sous forme de
chaîne ? Par conséquent, lorsque vous comparez l'entrée de l'utilisateur avec la
bonne réponse (obtenue dans la partie 4.4), vous devez faire un certain type
casting pour changer l'entrée de l'utilisateur en un entier. Lorsque vous modifiez
l'entrée utilisateur en nombre entier, vous devrait utiliser un try, except pour
vérifier si l'utilisateur a tapé un nombre. Si l'utilisateur a tapé une chaîne à la
place, le programme doit informer l'utilisateur de l'erreur et inviter l'utilisateur à
taper de nouveau un nombre.
Vous pouvez utiliser une boucle while True pour continuer à demander à
l'utilisateur un numéro tant qu'il/elle ne parvient pas à le faire. L'écriture while
True équivaut à écrire quelque chose comme while 1==1. Puisque 1 est toujours
égal à 1 (donc toujours Vrai), la boucle s'exécutera indéfiniment.
Voici une suggestion sur la façon dont vous pouvez utiliser une boucle while
True pour cette partie.
while True:
try:
convertir la réponse de l'utilisateur en un entier et évaluer la réponse
renvoyer le score de l'utilisateur en fonction de la réponse
except:
afficher un message d'erreur si la conversion échoue
inviter l'utilisateur à saisir à nouveau un nombre
6/8
Partie 2: [Link]
La partie 2 va être simple car nous appellerons principalement les fonctions que
nous avons définies précédemment.
Programme principal
Tout d'abord, plaçons notre programme principal dans une déclaration try,
except pour gérer toutes erreurs imprévues lors de l'exécution du programme
principal.
Commençons par écrire le code du bloc try.
Premièrement, nous devons importer le module myPythonFonctions. Ensuite,
demandons à l'utilisateur son nom et attribuez la valeur à la variable userName.
Passez cette variable en tant que paramètre à la fonction getUserScore().
getUserScore() renverra soit le score de l'utilisateur, soit '-1' (si l'utilisateur n'est
pas trouvé). Convertissons ce résultat en un entier et affectons-le à la variable
userScore.
Maintenant, nous devons définir la valeur d'une autre variable newUser. Si
l'utilisateur n'est pas trouvé, newUser = True, sinon newUser = False. Si
newUser = True, nous devons changer userScore de -1 à 0.
La prochaine partie de notre programme comprend une boucle while. Plus
précisément, notre programme demandera une entrée utilisateur pour déterminer
s'il doit terminer le programme ou faire autre chose.
Étape 1:
Vous devez déclarer une autre variable userChoice et donnez-lui une valeur
initiale de 0.
Étape 2:
Ensuite, à l'aide d'une boucle while, comparer userChoice avec une chaîne de
votre choix, dites « -1 ». Si userChoice n'est pas la même chose que "-1",
appelez la fonction generateQuestion() pour générer une nouvelle question.
Étape 3:
generateQuestion() renverra le score que l'utilisateur a obtenu pour cette
question. Utiliser ce résultat pour mettre à jour la variable userScore.
7/8
Étape 4:
Enfin, afin d'éviter une boucle infinie, nous devons utiliser input() à nouveau
dans la boucle while pour accepter l'entrée de l'utilisateur et l'utiliser pour mettre
à jour la valeur de userChoice.
Enfin, après la fin de la boucle while, l'étape suivante consiste à mettre à jour le
[Link] en appelant simplement la fonction updateUserPoints().
C'est tout pour le bloc try. Maintenant pour le bloc except, nous informons
simplement l'utilisateur qu'une erreur s'est produite et le programme se
terminera.
8/8