initial commit

This commit is contained in:
Djalim Simaila 2023-10-20 16:18:07 +02:00
commit 29de3039f7
30 changed files with 1104 additions and 0 deletions

View File

@ -0,0 +1,8 @@
[codestyle]
indentation = True
edge_line = True
edge_line_columns = 79
[main]
version = 0.2.0

View File

@ -0,0 +1,5 @@
[codestyle]
indentation = True
edge_line = True
edge_line_columns = 79

View File

@ -0,0 +1,3 @@
[encoding]
text_encoding = utf-8

View File

@ -0,0 +1,4 @@
[vcs]
use_version_control = False
version_control_system =

View File

@ -0,0 +1,6 @@
[workspace]
restore_data_on_startup = True
save_data_on_exit = True
save_history = True
save_non_project_files = False

View File

@ -0,0 +1,6 @@
[encoding]
text_encoding = utf-8
[main]
version = 0.2.0

7
.spyproject/config/vcs.ini Executable file
View File

@ -0,0 +1,7 @@
[vcs]
use_version_control = False
version_control_system =
[main]
version = 0.2.0

View File

@ -0,0 +1,10 @@
[workspace]
restore_data_on_startup = True
save_data_on_exit = True
save_history = True
save_non_project_files = False
[main]
version = 0.2.0
recent_files = ['../../../../../../../../../../home/djalim/.config/spyder-py3/temp.py', 'fonctions.py']

145
CahierDesCharges.ipynb Executable file
View File

@ -0,0 +1,145 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cahier des charges\n",
"\n",
"\n",
"donc notre projet de site \"d'entrainement cerebrale sur le theme des operation mathematique\" plus communement appelé \"calcul mental\" par le commun des mortels\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Taches à effectuer + %\n",
"\n",
"## Priorité - Haute\n",
"\n",
"> 1) la fonction generation de chiffre/calcul aleatoire - 100%\n",
"- docstring tres explicite\n",
"- prends en parametre une difficulté.\n",
"- sa range() doit etre modulable celon la difficulté ( par exemple en facile on obtient des nombres entre 0 et 10 et en difficile entre 25 et 75)\n",
"- si le calcul est une division, elle doit tomber juste, donc soit les chiffre \"3\" \"6\" \"9\" sont a banir ou bien verifier que le diviseur et le divisé partagent une table\n",
"- si le calcul est une soustraction, le resultat doir etre positif, donc verifier que le premier nombre est plus grand que le second\n",
"\n",
"> 2) la fonction verifiant la reponse - 100 %\n",
"- docstring explicite\n",
"- prends en parametre le calcul generé precedement\n",
"- doit etre fiable a 100%\n",
"\n",
"> des test unitaire - 0 %\n",
"\n",
"## Priorité - Moyenne\n",
"\n",
"> 3) Interface Homme - machine html / css - 80%\n",
"- Belle, minimale et efficace\n",
"- les pages principales sont:\n",
" * le menu principale (ou l'utilisateur choisis un mode de jeu : qcm ou classique, une difficulté)\n",
" * les pages de calcul (ou l'utilisateur reponds aux calcul qui lui sont proposés)\n",
" * la page finale (ou l'utilisateur obtiens la correction des calculs, son score et peut choisir ou non d'enregistrer son score dans le classement dans ce cas il devra entrer un pseudonyme)\n",
" * la page de classement ( qui affiche tout les score enregistrés dans le classement)\n",
"\n",
">4) la fonction generation de reponse pour qcm - 100%\n",
"- docstring explicite\n",
"- prends en parametre le calcul generé precedement et sa difficulté\n",
"- genere des 3 fausses reponses en plus de la vrai reponse\n",
"- plus la difficulté est basse plus la similarité entre la reponse juste et les reponses fausses est basse \n",
"\n",
"> 5) fonction attribuant un score a calcul - 0%\n",
"- prends en parametre un calcul et sa difficulté\n",
"- renvoie un score entre 0 et 10 celon la perfomance de l'utilisateur ( on peut prendre par exemple la vitesse a la quelle l'utilisateur a repondu a la question pour quantifier la perfomance )\n",
"\n",
"## Priorité - Basse / optionel\n",
"\n",
"> Ajouter un classement des meilleurs perfomances\n",
"\n",
"> Ajouter la possiblilité a l'utilisateur de se chronometrer\n",
"\n",
"> Donnez la possiblilité a l'utilisateur de choisir le nombre de calculs\n",
"ex: 10, 30, 50 et peut etre integrer un systeme de difficulté croissante\n",
"\n",
"> Ajouter des effets sonores /des musiques libre de droit\n",
"\n",
"> Ajouter un mode marathon ou il n'y a pas de limite sur le nombre de question, la partie s'arette a la premiere mauvaise reponse, le but et donc d'enchainer le plus de bonne reponse avec des calculs a difficulté croissante\n",
"\n",
"# Reparition des Taches\n",
"\n",
"\n",
"\n",
"| Fonction | Developpeur | Progression |\n",
"| :------------ |: -------------: | ------------: |\n",
"| 1) | Clément | 100% |\n",
"| 2) | Clément | 100% |\n",
"| 3) | Djalim | 80% |\n",
"| 4) | Djalim | 100% |\n",
"| 5) | . | 0% |\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Exemple visuel du site"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![image](https://cdn.discordapp.com/attachments/561585323616763924/707153314214838292/Menu.png)\n",
"![image](https://cdn.discordapp.com/attachments/561585323616763924/707153302386900992/class.png)\n",
"![image](https://cdn.discordapp.com/attachments/561585323616763924/707153317574344754/qcm.png)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.4"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
"autoclose": false,
"autocomplete": true,
"bibliofile": "biblio.bib",
"cite_by": "apalike",
"current_citInitial": 1,
"eqLabelWithNumbers": true,
"eqNumInitial": 1,
"hotkeys": {
"equation": "Ctrl-E",
"itemize": "Ctrl-I"
},
"labels_anchors": false,
"latex_user_defs": false,
"report_style_numbering": false,
"user_envs_cfg": false
}
},
"nbformat": 4,
"nbformat_minor": 2
}

14
README.md Normal file
View File

@ -0,0 +1,14 @@
# Site d'enrichissement cerebral sur le theme des matematique communement appel{} : Calcul Mental
##
## Prerequis
- python3
- flask
## usage
> python3 index.py

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

280
fonctions.py Executable file
View File

@ -0,0 +1,280 @@
import random
import csv
def creer_calcul(difficulte:int )->str:
"""
Cette fonction crée un calcul au hasard entre une addition, soustrction, multiplication et division euclidienne.
Elle prend en compte la difficulté, choisie par l'utilisateur.
En difficulté facile (difficulté = 0), les - sont positives, les nombres sont des entiers positifs, les * et les / sont les tables de 1 à 10.
En difficulté normale (difficulté = 1), les - peuvent être négatives, il y a des nombre entiers positifs et négatifs pour les + et les -, les * et / sont : un chiffre * un nombre compris entre -99 et 99.
En difficulté difficile (difficulté = 2), pour les - et +, les nombres sont relatifs avec 2 chiffres max après la virgule, les * et / sont : un nombre compris entre -99 et 99 * un nombre compris entre -99 et 99.
:param difficulte: La difficulte du calcul mental. C'est un entier compris entre 0 et 2.
:return: Un calcul mental, sous forme de str.
:return: L'operation liée au calcul, sous forme de str.
"""
try:
assert type(difficulte) == int
assert difficulte >= 0 and difficulte < 3
except:
return None
calcul = ''
if difficulte == 0 :
n1 = random.randint(0, 10)
n2 = random.randint(0, 10)
operation = random.choice(['+', '-', '*', '/'])
if operation == '-' :
while n1 < n2 :
n1 = random.randint(0, 10)
n2 = random.randint(0, 10)
calcul = str(n1) + '-' + str(n2)
if operation == '/' :
n1 = random.randint(1, 10)
dividende = n1*n2
calcul = str(dividende) + '/' + str(n1)
elif operation == '+' or operation == '*' :
calcul = str(n1) + operation + str(n2)
if difficulte == 1 :
n1 = random.randint(-99, 99)
n2 = random.randint(-99, 99)
operation = random.choice(['+', '-', '*', '/'])
if operation == '/' :
while n1 == 0 :
n1 = random.randint(-99, 99)
n2 = random.randint(2, 10)
dividende = n1*n2
calcul = str(dividende) + '/' + str(n1)
if operation == '*' :
n1 = random.randint(2, 10)
if n2 < 0 :
calcul = str(n1) + '*' + '(' + str(n2) + ')'
else :
calcul = str(n1) + '*' + str(n2)
elif operation == '+' or operation == '-' :
if n2 < 0 :
calcul = str(n1) + operation + '(' + str(n2) + ')'
else :
calcul = str(n1) + operation + str(n2)
if difficulte == 2 :
n1 = random.randint(-100, 99) + round(random.random(), 2)
n2 = random.randint(-100, 99) + round(random.random(), 2)
operation = random.choice(['+', '-', '*', '/'])
if operation == '*' :
n1 = random.randint(-99, 99)
n2 = random.randint(-99, 99)
if n2 < 0 :
calcul = str(n1) + '*' + '(' + str(n2) + ')'
else :
calcul = str(n1) + '*' + str(n2)
if operation == '/' :
n1 = random.randint(-99, 99)
while n1 == 0 :
n1 = random.randint(-99, 99)
n2 = random.randint(-99, 99)
dividende = n1*n2
calcul = str(dividende) + '/' + str(n1)
else :
if n2 < 0 :
calcul = str(n1) + operation + '(' + str(n2) + ')'
else :
calcul = str(n1) + operation + str(n2)
return calcul, operation
def reponses_qcm(calcul:str, difficulte:int, operation:str)-> list :
"""
Cette fonction genere les reponses a affichier dans le mode qcm.
Elle genere 3 reponses fausses en plus de la vrai reponse.
Selon la difficulté les fausses reponses sont plus ou moins eloignés de la vrai reponse
:param calcul: un calul generé aleatoirement
:param difficulte: La difficulte du calcul mental, peut être difficile, normal, facile
:return: une liste de reponces (melangé afin que la bonne reponse ne soit pas toujours au meme index)
"""
try:
assert type(calcul) == str
assert type(difficulte) == int
assert difficulte >= 0 and difficulte <= 3
except:
return None
bonne_reponse = round(eval(calcul), 2)
reponses = [bonne_reponse]
if difficulte == 0:
fausse_minimale = eval(calcul) - 10
fausse_maximale = eval(calcul) + 10
fausses = [round(random.uniform(fausse_minimale , fausse_maximale),0) for i in range (3)]
if difficulte == 1:
fausse_minimale = eval(calcul) - 30
fausse_maximale = eval(calcul) + 30
fausses = [round(random.uniform(fausse_minimale , fausse_maximale),0) for i in range (3)]
if difficulte == 2:
fausse_minimale = eval(calcul) - 50
fausse_maximale = eval(calcul) + 50
if operation == "+" or operation == "-" :
fausses = [round(random.uniform(fausse_minimale , fausse_maximale),2) for i in range(3)]
else :
fausses = [round(random.uniform(fausse_minimale, fausse_maximale),0) for i in range(3)]
for i in range(3) :
while fausses[i] == bonne_reponse or fausses[0] == fausses[1] or fausses[0] == fausses[2] or fausses[1] == fausses[2] :
if difficulte == 2:
if operation == "+" or operation == "-" :
fausses = [round(random.uniform(fausse_minimale , fausse_maximale),2) for i in range(3)]
else :
fausses = [round(random.uniform(fausse_minimale, fausse_maximale),0) for i in range(3)]
else :
fausses = [round(random.uniform(fausse_minimale , fausse_maximale),0) for i in range (3)]
reponses.extend(fausses)
random.shuffle(reponses)
try:
assert len(reponses) == 4
except:
return None
return reponses
def verifier_reponse(reponse_utilisateur:str, calcul:str)-> str:
"""
Cette fonction vérifie la réponse donnée par l'utilisateur.
:param reponse_utilisateur: La réponse donnée.
:param calcul: Le calcul mental auquel l'utilisaateur a repondu.
:return: True si la reponse est juste, sinon la bonne réponse.
"""
try:
assert type(reponse_utilisateur) == str
assert type(calcul) == str
bonne_reponse = round(eval(calcul),2)
except:
return None
try :
if round(float(reponse_utilisateur), 2) == round(bonne_reponse, 2) :
return "Bravo !"
elif round(float(reponse_utilisateur), 2) != round(bonne_reponse, 2) :
return "Raté, la bonne réponse était : " + str(bonne_reponse)
except :
return "Ecrivez juste un nombre"
def enregistrer_score(nom:str, score:str) :
"""
Cette fonction enregistre les scores des joueurs dans un fichier csv score.csv.
Si le joueur a fait un meilleur score, la ligne du tableau correspondant à son pseudo est modifiée.
Si le joueur donne un pseudo inconnu, une nouvelle ligne est créée à la fin du tableau.
:param nom: Le nom entré par l'utilisateur
:param score: Le score obtenue par l'utilisateur
"""
"""
try:
assert type(nom) == str
assert type(score) == str
except:
return
"""
fichier_r = open('static/Score.csv', 'r', encoding = 'utf-8')
modifier = False
new = ""
print(nom)
nom = nom.replace(','," ") # dans le cas ou des malin mettent des vigules dans leur nom et ruinent le classement
for ligne in fichier_r :
if nom in ligne :
score_ligne = ligne.split(',')[1]
if int(score) > int(score_ligne) :
ligne = ligne.replace(str(score_ligne), str(score)) + "\n"
new = new + ligne
modifier = True
else :
new = new + ligne
modifier = True
elif nom not in ligne :
new = new + ligne
if modifier == False :
ligne = "\n" + nom + ',' + str(score)
new = new + ligne
fichier_r.close()
fichier_w = open('static/Score.csv', 'w', encoding = 'utf-8')
fichier_w.write(new)
fichier_w.close()
return
def meilleur_score(nom:str)->str :
"""
Cette fonction trouve le meileur score d'un joueur dans le tableau score.csv.
:param nom: Le nom entré par l'utilisateur
:return: Le meilleur score detenu par l'utilisateur
"""
try:
assert type(nom) == str
except:
return
fichier_r = open('static/Score.csv', 'r', encoding = 'utf-8')
for ligne in fichier_r :
nom_ligne = ligne.split(',')[0]
if nom == nom_ligne :
return "Votre meilleur score est : " + ligne.split(',')[1]
return 'Vous êtes anonyme'
def trier_csv() :
"""
Cette fonction écrit les 10 meilleurs scores de Score.csv dans Score_classement.csv, en les triant par ordre décoissant.
"""
fichier_r = open('static/Score.csv', 'r', encoding = 'utf-8')
fichier_reader = csv.reader(fichier_r)
table = []
comptage_ligne = 0
for ligne in fichier_reader :
comptage_ligne += 1
table.append(ligne)
for i in range(len(table)) :
m = i
for j in range(i+1, len(table)) :
if int(table[j][1]) < int(table[m][1]) :
m = j
x = table[i]
table[i] = table[m]
table[m] = x
table.reverse()
if len(table) > 10 :
table = [table[i] for i in range(10)]
fichier_w = open('static/Score_classement.csv', 'w', encoding = 'utf-8')
fichier_writer = csv.writer(fichier_w)
for i in range(len(table)) :
fichier_writer.writerow(table[i])

94
index.py Executable file
View File

@ -0,0 +1,94 @@
from flask import Flask, render_template, request
from fonctions import *
app = Flask(__name__)
@app.route("/")
def index():
return render_template("Acceuil.html")
@app.route("/commencer_classique/", methods = ['POST'])
def commencer():
difficulte = int(request.form['radio'])
calcul_entier = creer_calcul(difficulte)
calcul = calcul_entier[0]
operation = calcul_entier[1]
numero = 1
calcul_juste = 0
return render_template("Calcul.html",difficulte=difficulte, calcul=calcul, numero = numero,calcul_juste=calcul_juste)
@app.route("/commencer_qcm/", methods = ['POST'])
def commencer_qcm():
difficulte = int(request.form['radio'])
calcul_entier = creer_calcul(difficulte)
calcul = calcul_entier[0]
operation = calcul_entier[1]
reponces = reponses_qcm(calcul,difficulte,operation)
numero = 1
calcul_juste = 0
rep1 = float(reponces[0])
rep2 = float(reponces[1])
rep3 = float(reponces[2])
rep4 = float(reponces[3])
return render_template("Calcul_qcm.html", calcul=calcul,difficulte=difficulte, rep1=rep1, rep2=rep2, rep3=rep3, rep4=rep4, numero=numero,calcul_juste=calcul_juste, operation=operation)
@app.route("/suivant/", methods = ['POST'])
def suivant():
try:
reponse = request.form['resultat']
except:
reponse = ''
calcul = request.form['calcul']
operation = request.form['operation']
verification = verifier_reponse(reponse, calcul)
calcul_juste = int(request.form['calcul_juste'])
if verification == "Bravo !" :
calcul_juste += 1
difficulte = int(request.form['difficulte'])
calcul_entier = creer_calcul(difficulte)
calcul = calcul_entier[0]
operation = calcul_entier[1]
mode = request.form['type']
numero = int(request.form['numero'])
if verification == "Ecrivez juste un nombre" :
numero -= 1
calcul = request.form['calcul']
operation = request.form['operation']
while numero < 2 :
if mode == "qcm":
numero += 1
reponces = reponses_qcm(calcul,difficulte,operation)
rep1 = float(reponces[0])
rep2 = float(reponces[1])
rep3 = float(reponces[2])
rep4 = float(reponces[3])
return render_template("Calcul_qcm_suivant.html",difficulte=difficulte, calcul=calcul,verification=verification, rep1=rep1, rep2=rep2, rep3=rep3, rep4=rep4,numero = numero,calcul_juste=calcul_juste)
else :
numero += 1
return render_template("Calcul_suivant.html",difficulte=difficulte, calcul=calcul, verification=verification, numero=numero, calcul_juste=calcul_juste)
return render_template("Resultat.html",calcul_juste=calcul_juste)
@app.route('/resultat/', methods=['POST'])
def resultat():
score = int(request.form['score'])
nom = request.form['nom']
nom = nom.strip()
if len(nom) > 10 :
erreur = 'Trop de caractères'
calcul_juste = request.form['score']
return render_template("Resultat.html",calcul_juste=calcul_juste, erreur=erreur)
if len(nom) > 0 :
print(nom)
enregistrer_score(nom, score)
ms = meilleur_score(str(nom))
return render_template('Classement.html', nom=nom, ms=ms)
@app.route('/classement', methods=['GET', 'POST'])
def classement() :
trier_csv()
return render_template('Classement.html')
if __name__ == "__main__":
app.run(host="localhost", port = 5002,debug=True)

12
static/Score.csv Executable file
View File

@ -0,0 +1,12 @@
Clement,9
Djalim,9
Test,9
c,6
12,6
TOTO,10
Test2,2
Paul,2
lol,2
Test3,2
Test4,2
Paul2,2
1 Clement 9
2 Djalim 9
3 Test 9
4 c 6
5 12 6
6 TOTO 10
7 Test2 2
8 Paul 2
9 lol 2
10 Test3 2
11 Test4 2
12 Paul2 2

10
static/Score_classement.csv Executable file
View File

@ -0,0 +1,10 @@
TOTO,10
Djalim,9
Clement,9
Test,9
12,6
c,6
Paul2,2
Test4,2
Test3,2
lol,2
1 TOTO 10
2 Djalim 9
3 Clement 9
4 Test 9
5 12 6
6 c 6
7 Paul2 2
8 Test4 2
9 Test3 2
10 lol 2

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

163
static/style.css Executable file
View File

@ -0,0 +1,163 @@
* {
box-sizing: border-box;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-kerning: auto;
}
html {
font-family: sans-serif;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
background-color: greenyellow; /* a changer j'aime pas trop cette couleur en vrai*/
background-image: url(./licence_free_background.jpg);
}
ul {
list-style-type: none;
}
li{
font-size: 20px;
}
h1 {
text-align:center;
font-size: 54px;
}
h2 {
text-align:center;
font-size: 60px;
opacity: 1.0;
}
h3 {
text-align:center;
font-size: 30px;
opacity: 1.0;
}
#principale {
width: 951px;
margin: auto;
display: flex;
}
.secondaires {
width: 425px;
margin-left: 25px;
margin-right: 25px;
border: 0px solid black;
border-radius: 40px;
padding: 15px;
background-color: greenyellow;
opacity: 0.7;
}
.secondaires:hover {
opacity: 1.0;
}
.checkboxes {
width: 200px;
margin: auto;
opacity: 1.0;
}
#calcul {
width: 301px;
margin: auto;
}
.start {
margin-top: 25px;
}
#boite_qcm {
width: 525px;
margin: auto;
}
#liste_qcm_reponces {
display: flex;
flex-wrap: wrap;
}
.qcm_reponses {
width: 200px;
margin: 10px;
font-size: 30px;
text-align: center;
}
#titre {
border: 3px solid black;
border-radius: 12px;
width: 508px;
margin-left: auto;
margin-right: auto;
}
#accueil {
border: 3px solid black;
border-radius: 12px;
width: fit-content;
margin: auto;
padding: 25px;
margin-top: 25px;
margin-bottom: 25px;
}
p {
text-align:center;
}
table {
border-collapse: collapse;
border: 2px black solid;
font: 12px sans-serif;
}
td {
border: 1px black solid;
padding: 10px;
font-size: 28px;
text-align: center;
width: calc(100% + 5px);
}
#classement {
margin:0 auto;
display: table;
}
#entete {
width: auto;
background-color: #00701a;
display: flex;
}
a {
text-decoration: none;
font-size: 16px;
color: black;
}
.bouton {
width: 120px;
text-align: center;
margin-left: 10px;
margin-right: 10px;
height: 55px;
padding: 18px;
background-color: #43a047;
}
.bouton:hover{
background-color: #76d275;
}

6
static/test_score.csv Executable file
View File

@ -0,0 +1,6 @@
Clement,9
Djalim,9
Test,9
c,6
12,6
TOTO,10
1 Clement 9
2 Djalim 9
3 Test 9
4 c 6
5 12 6
6 TOTO 10

52
templates/Acceuil.html Executable file
View File

@ -0,0 +1,52 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Calcul mental</title>
<meta name="description" content="The HTML5 Herald">
<meta name="author" content="SitePoint">
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="entete">
<div class="bouton"><a href="/">Accueil</a></div>
<div class="bouton"><a href="{{ url_for('classement') }}">Classement</a></div>
</div>
<h1 id="acceuil">Bienvenue sur notre site de calcul mental</h1>
<div id="principale">
<div class=secondaires>
<h2>Classique</h2>
<h3>Difficulté</h3>
<form action="/commencer_classique/" method="POST">
<div class="checkboxes">
<ul>
<!-- je prefere utiliser des valeur numerique dans le cas ou on devrais les utiliser pour des calculs de difficulté -->
<li><input type="radio" name="radio" id="difficulte" value="0" checked> facile</li>
<li><input type="radio" name="radio" id="difficulte" value="1"> normal</li>
<li><input type="radio" name="radio" id="difficulte" value="2"> difficile</li>
<li><input class=start type="submit" name="commencer_classique" value="commencer"></li>
</ul>
</div>
</form>
</div>
<div class=secondaires>
<h2>QCM</h2>
<h3>Difficulté</h3>
<form action="commencer_qcm/" method="POST">
<div class="checkboxes">
<ul>
<li><input type="radio" name="radio" id="difficulte" value="0" checked > facile</li>
<li><input type="radio" name="radio" id="difficulte" value="1"> normal</li>
<li><input type="radio" name="radio" id="difficulte" value="2"> difficile</li>
<input class=start type="submit" name="commencer_qcm" value="commencer">
</ul><!-- voir si il a pas un moyer de fusioner les 2 methodes post-->
</div>
</form>
</div>
</div>
</body>
</html>

34
templates/Calcul.html Executable file
View File

@ -0,0 +1,34 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Calcul mental</title>
<meta name="description" content="The HTML5 Herald">
<meta name="author" content="SitePoint">
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="entete">
<div class="bouton"><a href="/">Accueil</a></div>
<div class="bouton"><a href="{{ url_for('classement') }}">Classement</a></div>
</div>
<h1 id="titre"><a href="{{ url_for('static', filename='Accueil.html') }}"></a>Calcul Mental</h1>
<p>Calcul {{ numero }} sur 10 </p>
<h1>{{ calcul }}</h1>
<div id="calcul">
<form action="/suivant/" method="POST">
<input type="text" id="resultat" name="resultat" autofocus>
<input type="hidden" name="difficulte" value="{{ difficulte }}">
<input type="hidden" name="calcul" value="{{ calcul }}">
<input type="hidden" name="operation" value="{{ operation }}">
<input type="hidden" name="type" value="classique">
<input type="hidden" name="numero" value="{{ numero }}">
<input type="hidden" name="calcul_juste" value="{{ calcul_juste }}">
<input type="submit" name="suivant" value="suivant">
</form>
</div>
</body>
</html>

39
templates/Calcul_qcm.html Executable file
View File

@ -0,0 +1,39 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Calcul mental</title>
<meta name="description" content="The HTML5 Herald">
<meta name="author" content="SitePoint">
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="entete">
<div class="bouton"><a href="/">Accueil</a></div>
<div class="bouton"><a href="{{ url_for('classement') }}">Classement</a></div>
</div>
<h1 id="titre"><a href="/"></a>Calcul Mental</h1>
<p>Calcul {{ numero }} sur 10 </p>
<h1>{{ calcul }}</h1>
<form action="/suivant/" method="POST">
<div id="boite_qcm">
<ul id="liste_qcm_reponces">
<li class=qcm_reponses><input type="radio" name="resultat" id="resultat" value="{{ rep1 }}"> {{ rep1 }}</li>
<li class=qcm_reponses><input type="radio" name="resultat" id="resultat" value="{{ rep2 }}"> {{ rep2 }}</li>
<li class=qcm_reponses><input type="radio" name="resultat" id="resultat" value="{{ rep3 }}"> {{ rep3 }}</li>
<li class=qcm_reponses><input type="radio" name="resultat" id="resultat" value="{{ rep4 }}"> {{ rep4 }}</li>
</ul>
<input type="hidden" name="difficulte" value="{{ difficulte }}">
<input type="hidden" name="type" value="qcm">
<input type="hidden" name="calcul" value="{{ calcul }}">
<input type="hidden" name="operation" value="{{ operation }}">
<input type="hidden" name="numero" value="{{ numero }}">
<input type="hidden" name="calcul_juste" value="{{ calcul_juste }}">
<input type="submit" name="suivant" value="suivant">
</div>
</form>
</body>
</html>

View File

@ -0,0 +1,40 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Calcul mental</title>
<meta name="description" content="The HTML5 Herald">
<meta name="author" content="SitePoint">
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="entete">
<div class="bouton"><a href="/">Accueil</a></div>
<div class="bouton"><a href="{{ url_for('classement') }}">Classement</a></div>
</div>
<h1 id="titre"><a href="{{ url_for('static', filename='Accueil.html') }}"></a>Calcul Mental</h1>
<p>Calcul {{ numero }} sur 10 </p>
<h1>{{verification}}</h1>
<h1>{{ calcul }}</h1>
<form action="/suivant/" method="POST">
<div id="boite_qcm">
<ul id="liste_qcm_reponces">
<li class=qcm_reponses><input type="radio" name="resultat" id="resultat" value="{{ rep1 }}"> {{ rep1 }}</li>
<li class=qcm_reponses><input type="radio" name="resultat" id="resultat" value="{{ rep2 }}"> {{ rep2 }}</li>
<li class=qcm_reponses><input type="radio" name="resultat" id="resultat" value="{{ rep3 }}"> {{ rep3 }}</li>
<li class=qcm_reponses><input type="radio" name="resultat" id="resultat" value="{{ rep4 }}"> {{ rep4 }}</li>
</ul>
<input type="hidden" name="difficulte" value="{{ difficulte }}">
<input type="hidden" name="type" value="qcm">
<input type="hidden" name="calcul" value="{{ calcul }}">
<input type="hidden" name="operation" value="{{ operation }}">
<input type="hidden" name="numero" value="{{ numero }}">
<input type="hidden" name="calcul_juste" value="{{ calcul_juste }}">
<input type="submit" name="suivant" value="suivant">
</div>
</form>
</body>
</html>

34
templates/Calcul_suivant.html Executable file
View File

@ -0,0 +1,34 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Calcul mental</title>
<meta name="description" content="The HTML5 Herald">
<meta name="author" content="SitePoint">
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="entete">
<div class="bouton"><a href="/">Accueil</a></div>
<div class="bouton"><a href="{{ url_for('classement') }}">Classement</a></div>
</div>
<h1 id="titre"><a href="{{ url_for('static', filename='Accueil.html') }}"></a>Calcul Mental</h1>
<p>Calcul {{ numero }} sur 10 </p>
<h1>{{verification}}</h1>
<h1>{{ calcul }}</h1>
<div id="calcul">
<form action="/suivant/" method="POST">
<input type="text" id="resultat" name="resultat" autofocus>
<input type="hidden" name="difficulte" value="{{ difficulte }}">
<input type="hidden" name="calcul" value="{{ calcul }}">
<input type="hidden" name="operation" value="{{ operation }}">
<input type="hidden" name="type" value="classique">
<input type="hidden" name="numero" value="{{ numero }}">
<input type="hidden" name="calcul_juste" value="{{ calcul_juste }}">
<input type="submit" name="suivant" value="suivant">
</form>
</div>
</body>
</html>

42
templates/Classement.html Executable file
View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="entete">
<div class="bouton"><a href="/">Accueil</a></div>
<div class="bouton"><a href="{{ url_for('classement') }}">Classement</a></div>
</div>
<h1 id="titre"><a href="/"></a>Calcul Mental</h1>
<h1>{{ms}}</h1>
<h1>Top 10</h1>
<div id="classement">
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<!--<script src="d3.min.js?v=3.2.8"></script> -->
<script type="text/javascript"charset="utf-8">
d3.text("{{ url_for('static',filename='Score_classement.csv')}}", function(data) {
var parsedCSV = d3.csv.parseRows(data);
var container = d3.select("#classement")
.append("table")
.selectAll("tr")
.data(parsedCSV).enter()
.append("tr")
.selectAll("td")
.data(function(d) { return d; }).enter()
.append("td")
.text(function(d) { return d; });
});
</script>
<form action="/classement/" method="POST">
</form>
</body>
</html>

30
templates/Resultat.html Executable file
View File

@ -0,0 +1,30 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Calcul mental</title>
<meta name="description" content="The HTML5 Herald">
<meta name="author" content="SitePoint">
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="entete">
<div class="bouton"><a href="/">Accueil</a></div>
<div class="bouton"><a href="{{ url_for('classement') }}">Classement</a></div>
</div>
<h1 id="titre"><a href="{{ url_for('static', filename='Accueil.html') }}"></a>Calcul Mental</h1>
<h2>{{ calcul_juste }} / 10</h2>
<form action="/resultat/" method="POST">
<div>
<h3>Vous pouvez vous enregistrer, pour cela entrez votre pseudo : </h3>
<input type="text" id="nom" name="nom" autofocus>
<input type="submit" name="suivant" value="Valider">
</div>
<input type="hidden" name="score" value="{{ calcul_juste }}">
</form>
</body>
</html>

60
test_fonctions.py Executable file
View File

@ -0,0 +1,60 @@
from fonctions import *
def test_cree_calcul_aleatoire_facile():
for i in range(10):
precedant = creer_calcul(0)
assert creer_calcul(0) != precedant
def test_cree_calcul_aleatoire_normal():
for i in range(10):
precedant = creer_calcul(1)
assert creer_calcul(1) != precedant
def test_cree_calcul_aleatoire_difficile():
for i in range(10):
precedant = creer_calcul(2)
assert creer_calcul(2) != precedant
def test_cree_calcul_difficulte_str():
assert creer_calcul("0") == None
def test_cree_calcul_difficulte_invalide():
assert creer_calcul(4) == None
#-----------------------------------------------------------------#
# Cette fonction est un peu chelou a test, si tu trouve des test a faire
# je suis preneur
#def test_reponces_qcm_simple()
# assert reponses_qcm("1+1",0,"+")
#-----------------------------------------------------------------#
def test_verifier_reponse_simple_juste():
assert verifier_reponse("2","1+1") == "Bravo !"
def test_verifier_reponse_simple_faux():
assert verifier_reponse("11","1+1") == "Raté, la bonne réponse était : 2"
def test_verifier_reponse_lettre():
assert verifier_reponse("deux","1+1") == "Ecrivez juste un nombre"
def test_verifier_reponse_reponse_type_int():
assert verifier_reponse(2,"1+1") == None
def test_verifier_reponse_calcul_incorrect():
assert verifier_reponse("2","1plus1") == None
#-----------------------------------------------------------------#
def test_enregistrer_score_nom_type_int():
assert enregistrer_score(123,"456") == None
def test_enregistrer_score_score_type_int():
assert enregistrer_score("test",123) == None
#-----------------------------------------------------------------#
def test_meilleur_score_type_int():
assert meilleur_score(123) == None