Cycle Vitesse/Relais

Professeurs référents :

M FAURY (ISN)

M VERDIER (EPS)

Présentation de l’équipe projet

NOM Prénom Classe Année Scolaire
PELGER Pierre TS5 2017-2018
MERESSE Marc TS5 2017-2018

Présentation du projet

Dans le cadre du cycle de course, plus particulièrement les épreuves de relai, dans les cours d’EPS, on souhaite avoir accès à un outil facile d’utilisation permettant la saisie des performances des élèves et de certaines statistiques qui y sont liées. L’application doit pouvoir être utilisée facilement par le professeur comme les élèves, qui pourront modifier de nombreux paramètres, ajouter des groupes, des élèves,… Elle doit aussi permettre à l’utilisateur de rechercher les performances des élèves selon différents critères (classe, groupe,…).

 

Cahier des charges

Description détaillée :

Étapes Avancement
Squelette graphique (pages/boutons/zones d’entrée de texte) [Méresse] Terminé
Design [Méresse] En cours
Ergonomie [Méresse] Terminé
Textes de l’app [Méresse] Terminé
Fonction de calcul des performances [Pelger] En cours
Création des objets [Pelger] Terminé
Recherche des élèves (optionnel)  Non commencé
Fichier XML [Pelger] Terminé
Manipulation de la base de données En cours
Mot de passe administrateur (optionnel) Non commencé

Répartition des tâches

PELGER Pierre Statistiques, données, fichiers
MERESSE Marc Interface graphique, textes

Suivi collectif du projet

Date Tâche Remarques
07/02/2018 Début de réflexion sur le projet  Cahier des charges précisé après entretien avec M.Verdier.
28/02/2018 Découverte des modules et des outils de programmation

Début des manipulations sur différents petits projets de test

04/04/2018 Création des objets classes, groupes et élèves (programmation orientée objet)

Après apprentissage de Tkinter, début de la création du squelette de l’app.

25/04/2018 Squelette de l’application terminé. Nous relevons un ensemble de problèmes d’ergonomie à régler.

 

Choix d’un fichier XML pour stocker les données.

Pour le design nécessité d’implémenter un système de frames ou canvas.
02/05/2018 Amélioration du design. L’app est lisible -grâce aux frames– et le design satisfaisant. Remplacement intégral des méthodes .pack() par des .grid() pour afficher correctement les barres de défilement des diverses listes de la base de données.

 

Ressources documentaires et documentation du projet

Liste des références consultées pour le projet :


Marc Méresse :

http://apprendre-python.com/page-tkinter-interface-graphique-python-tutoriel

http://effbot.org/tkinterbook/

http://tkinter.fdex.eu/index.html


Pierre Pelger :

Programmation Orientée Objet


Objectif

Proposer un logiciel renseignant et calculant pour chaque élève ses performances individuelles et collectives dans les épreuves de Vitesse et Relai en EPS.

 

Cahier des charges

Exemples :

  • Sur une course de 30m, Jean met 6″  et Paul  5″.
  • Le temps additionné de ces 2 coureurs est 5+6=11″
  • Ensuite, ils réalisent un relais sur 60m. Leur temps est alors de 10″78c

Le logiciel doit permettre :

La saisie des noms des « athlètes »

  • La saisie des différentes performances réalisées par chacun d’entre eux, pour différents types d’épreuves.
  • Les calculs pertinents pour évaluer leurs performances « globales », leur évolution, leurs points faibles, …
    • additions de temps (par exemple sur 30 m pour Paul et Jean 5″ + 6″ = 11″)
    • comparaison de leurs performances individuelles avec leur performance collective (individuel : 11″ / 60m ; collectif 10″78c)
  • Le réglage de nombreux paramètres : nombre d’élèves par groupe de relais, …
  • Des analyse statistiques, sur la classe, d’autres classe, dans le temps, …

[reveal heading= »%image% Programme »]

### textes

#page1

texteTuto= """Cycle Vitesse et Relai ! 

Les règles sont simples : 

-Formez vos groupes de trois élèves.
-Chronométrez-vous individuellement sur la distance prévue.
-En groupe, courrez en relai sur la somme des distances individuelles comme vous l'indique votre professeur.
-Utilisez l'onglet "Renseigner mes performances" pour sauvegarder vos résultats individuels et collectifs.

Pour tout problème, renseignez-vous auprès de votre professeur ou consultez la page "Infos" dans la barre de menu."""

texteCredits="""Ce logiciel est Open-Source.
Développé dans le cadre de la spécialité ISN du lycée Blaise Pascal de Clermont-Ferrand, 2017-2018.
Interface graphique : Marc Méresse
CÅ“ur : Pierre Pelger
Professeurs référents : M. Faury (ISN) ; M.Verdier(EPS)
"""

###imports, fenêtre, génération aléatoire des effectifs
print('hello world')
from tkinter import *
from tkinter import ttk
 
from random import *
nombre_de_classes=randint(1,5)
liste_nombre_groupes=[0]*nombre_de_classes
for i in range(nombre_de_classes):
    liste_nombre_groupes[i]=randint(1,13)
groupes_total=0
for i in range(nombre_de_classes):
    groupes_total+=liste_nombre_groupes[i]
eleves_total=randint(1,250)

accueil = Tk()
accueil.title('Cycle Vitesse et Relai')
accueil.minsize(width=700, height=300)

### 
 
# messages pop-up
from tkinter.messagebox import *

def pierre():
    showwarning('Partie de Pierre Pelger','!!à implémenter!!')

    
def marc():
    showwarning('Partie de Marc Méresse','!!à implémenter!!')
    
def fenetreCredits():
    showwarning('Crédits',texteCredits)
    
# gérer classe

def gerer_classes():
    gestion_classes = Toplevel()
    gestion_classes.title("Gestion des Classes")
    gestion_classes.geometry('400x370')
    
    
    cadreTexte1 = Frame(gestion_classes, background = 'PeachPuff', bd = 10)
    cadreTexte1.pack(side=TOP)
    separateur1 = Frame(gestion_classes, height=3, bd=1, relief=SUNKEN)
    separateur1.pack(fill=X, padx=5, pady=5)
    cadreAjouter1 = Frame(gestion_classes, background = 'PeachPuff', bd=10)
    cadreAjouter1.pack(side=LEFT)
    cadreSupprimer1 = Frame(gestion_classes, background = 'PeachPuff', bd=10)
    cadreSupprimer1.pack(side = RIGHT)
    
    #texte
    texte1 = Label(cadreTexte1, text='Ajouter ou supprimer des classes.\nAvant d\'enregistrer une nouvelle classe, assurez-vous d\'avoir créé la fiche de chaque groupe de cette classe dans la rubrique "Gérer groupes".', height=5, width=150)
    texte1.pack(fill=BOTH, expand = 1)
    
    listeClasses = Listbox(cadreSupprimer1)
    for i in range(nombre_de_classes):
        nomclasseexemple='classe'+str(i)
        listeClasses.insert(i, nomclasseexemple)
    listeClasses.grid(row=0,column=0)
    boutonSupprimerClasse=Button(cadreSupprimer1, text="Supprimer la classe selectionnée", command=pierre)
    boutonSupprimerClasse.grid(row=1,column=0)
    
    classe = StringVar()
    inviteClasse=Label(cadreAjouter1, text='Nom de la classe')
    inviteClasse.grid(row=0,column=0)
    entreeClasse = Entry(cadreAjouter1, textvariable=classe, width=20)
    entreeClasse.grid(row=1,column=0)
    listeGroupes = Listbox(cadreAjouter1, selectmode = MULTIPLE)
    for i in range(groupes_total):
        nomgroupeexemple='groupe'+str(i)
        listeGroupes.insert(i,nomgroupeexemple)
    listeGroupes.grid(row=2,column=0)
    #barre ajouter
    barre1=Scrollbar(cadreAjouter1)
    barre1.grid(row=2,column=1)
    barre1.config(command = listeGroupes.yview)
    listeGroupes.config(yscrollcommand=barre1.set)
    #barre supprimer
    barre2=Scrollbar(cadreSupprimer1)
    barre2.grid(row=0,column=1)
    barre2.config(command = listeClasses.yview)
    listeClasses.config(yscrollcommand=barre1.set)
    
    ajouterClasse=Button(cadreAjouter1, text="Créer la classe", cursor='plus',command=pierre)
    ajouterClasse.grid(row=3,column=0)
    
    
    
# gérer groupes

def gerer_groupes():
    gestion_groupes = Toplevel()
    gestion_groupes.title("Gestion des Groupes d'élèves")
    gestion_groupes.geometry('400x375')
    
    cadreTexte12 = Frame(gestion_groupes, background = 'PeachPuff', bd = 10)
    cadreTexte12.pack(side=TOP)
    separateur2 = Frame(gestion_groupes, height=3, bd=1, relief=SUNKEN)
    separateur2.pack(fill=X, padx=5, pady=5)
    cadreAjouter12 = Frame(gestion_groupes, background = 'PeachPuff', bd=10)
    cadreAjouter12.pack(side=LEFT)
    cadreSupprimer12 = Frame(gestion_groupes, background = 'PeachPuff', bd=10)
    cadreSupprimer12.pack(side = RIGHT)
    
    texte1 = Label(cadreTexte12, text='Formez vos groupes de trois.\nAvant de créer un nouveau groupe, assurez-vous d\'avoir créé chaque profil d\'élève de ce groupe dans la rubrique "Gérer élèves".', height=5, width=150)
    texte1.pack()
    
    listeGroupes = Listbox(cadreSupprimer12)
    for i in range(groupes_total):
        nomgroupeexemple='Groupe '+str(i)
        listeGroupes.insert(i,nomgroupeexemple)
    listeGroupes.pack()
    supprimerGroupe=Button(cadreSupprimer12, text="Supprimer le groupe sélectionné", command=pierre)
    supprimerGroupe.pack()
    
    groupe = StringVar()
    inviteGroupe=Label(cadreAjouter12, text='Nom du groupe')
    inviteGroupe.pack()
    entreeGroupe = Entry(cadreAjouter12, textvariable=groupe, width=20)
    entreeGroupe.pack()
    check=StringVar()
    listeEleves=Listbox(cadreAjouter12, selectmode=MULTIPLE)
    for i in range(eleves_total):
        nomeleveexemple='Eleve '+str(i)
        listeEleves.insert(i, nomeleveexemple)
    listeEleves.pack()
    ajouterGroupe=Button(cadreAjouter12, text="Créer Groupe", cursor='plus', command=pierre)
    ajouterGroupe.pack()

    
# gérer élèves

def gerer_eleves():
   
    gestion_eleves = Toplevel()
    gestion_eleves.title("Gestion des Groupes d'élèves")
    gestion_eleves.geometry('400x400')
    
    cadreTexte3 = Frame(gestion_eleves, background = 'PeachPuff', bd = 10)
    cadreTexte3.pack(side=TOP)
    separateur3 = Frame(gestion_eleves, height=3, bd=1, relief=SUNKEN)
    separateur3.pack(fill=X, padx=5, pady=5)
    cadreAjouter3 = Frame(gestion_eleves, background = 'PeachPuff', bd=10)
    cadreAjouter3.pack(side=LEFT)
    cadreSupprimer3 = Frame(gestion_eleves, background = 'PeachPuff', bd=10)
    cadreSupprimer3.pack(side = RIGHT)
    
    texte1 = Label(cadreTexte3, text='Créez un nouveau profil d\'élève à partir de son nom.', height=5, width=60)
    texte1.pack()
    texte2 = Label(cadreTexte3, text='Ou supprimez un profil d\'élève.', height=5, width=60)
    texte2.pack()
    
    
    prenom = StringVar()
    textePrenom=Label(cadreAjouter3, text='Prénom de l\'élève :')
    textePrenom.pack()
    entreePrenom = Entry(cadreAjouter3, textvariable=prenom, width=20)
    entreePrenom.pack()
    nom = StringVar()
    texteNom=Label(cadreAjouter3, text='Nom de l\'élève :')
    texteNom.pack()
    entreeNom = Entry(cadreAjouter3, textvariable=nom, width=20)
    entreeNom.pack()
    listeEleves=Listbox(cadreSupprimer3)
    for i in range(eleves_total):
        nomeleveexemple='Eleve '+str(i)
        listeEleves.insert(i, nomeleveexemple)
    listeEleves.pack()
    
    ajouterEleve=Button(cadreAjouter3, text="Ajouter",cursor='plus', command=pierre)
    ajouterEleve.pack()
    supprimerEleve=Button(cadreSupprimer3, text="Supprimer un élève", command=pierre)
    supprimerEleve.pack()


#cascade de choix de classe / groupe & entrée perfs
    
def choisir_classe():
    
    #cascade groupe
    def maclasse_sesgroupes():

        try:
            indiceClasse=int(listeClasses.get(ACTIVE)[-2]+listeClasses.get(ACTIVE)[-1])
        except:
            indiceClasse=int(listeClasses.get(ACTIVE)[-1])
        
        def mongroupe_seseleves():
            
            try:
                indiceGroupe=int(listeGroupes.get(ACTIVE)[-2]+listeGroupes.get(ACTIVE)[-1])
            except:
                indiceGroupe=int(listeGroupes.get(ACTIVE)[-1])
            
            titreajuste2=titreajuste+'Groupe '+str(indiceGroupe)
            perfs = Toplevel()
            perfs.title(titreajuste2)
            perfs.geometry('400x370')
            ###ici compléter la fenetre avec perf eleve1,2,3 et perf groupe
            
            choix_groupe.destroy()
                    
        titreajuste='Classe '+str(indiceClasse)+' '
        choix_groupe = Toplevel()
        choix_groupe.title(titreajuste)
        choix_groupe.geometry('400x370')


        cadreTexteGroupe = Frame(choix_groupe, background = 'PeachPuff', bd = 10)
        cadreTexteGroupe.pack(side=TOP)
        separateur1bis = Frame(choix_groupe, height=3, bd=1, relief=SUNKEN)
        separateur1bis.pack(fill=X, padx=5, pady=5)
        cadrelisteGroupes = Frame(choix_groupe, background = 'PeachPuff', bd=10)
        cadrelisteGroupes.pack()

        #texte
        texte1bis = Label(cadreTexteGroupe, text='Sélectionnez votre groupe.', height=5, width=150)
        texte1bis.pack(fill=BOTH, expand = 1)

        listeGroupes = Listbox(cadrelisteGroupes)
        for i in range(liste_nombre_groupes[indiceClasse]):
            nomclasseexemple=titreajuste+'Groupe '+str(i)
            listeGroupes.insert(i, nomclasseexemple)
        listeGroupes.grid(row=0,column=0)

        boutonSelectionGroupe=Button(cadrelisteGroupes, text="OK", command=mongroupe_seseleves)
        boutonSelectionGroupe.grid(row=1,column=0)

        #barre choix
        barre=Scrollbar(cadrelisteGroupes)
        barre.grid(row=0,column=1)
        barre.config(command = listeGroupes.yview)
        listeGroupes.config(yscrollcommand=barre.set)
        
        choix_classe.destroy()
        
    choix_classe = Toplevel()
    choix_classe.title("Sélection de la Classe")
    choix_classe.geometry('400x370')
    
    
    cadreTexte = Frame(choix_classe, background = 'PeachPuff', bd = 10)
    cadreTexte.pack(side=TOP)
    separateur1 = Frame(choix_classe, height=3, bd=1, relief=SUNKEN)
    separateur1.pack(fill=X, padx=5, pady=5)
    cadrelisteClasses = Frame(choix_classe, background = 'PeachPuff', bd=10)
    cadrelisteClasses.pack()
    
    #texte
    texte1 = Label(cadreTexte, text='Sélectionnez votre classe.', height=5, width=150)
    texte1.pack(fill=BOTH, expand = 1)
    
    listeClasses = Listbox(cadrelisteClasses)
    for i in range(nombre_de_classes):
        nomclasseexemple='Classe '+str(i)
        listeClasses.insert(i, nomclasseexemple)
    listeClasses.grid(row=0,column=0)
    
    boutonSelectionClasse=Button(cadrelisteClasses, text="OK", command=maclasse_sesgroupes)
    boutonSelectionClasse.grid(row=1,column=0)
    
    #barre choix
    barre=Scrollbar(cadrelisteClasses)
    barre.grid(row=0,column=1)
    barre.config(command = listeClasses.yview)
    listeClasses.config(yscrollcommand=barre.set)
    
    
#cascade de choix de classe / groupe & consultation resultats
    
def choisir_classe2():
    
    #cascade groupe
    def maclasse_sesgroupes2():

        try:
            indiceClasse=int(listeClasses.get(ACTIVE)[-2]+listeClasses.get(ACTIVE)[-1])
        except:
            indiceClasse=int(listeClasses.get(ACTIVE)[-1])
    
        
        def mongroupe_seseleves2():
        
            try:
                indiceGroupe=int(listeGroupes.get(ACTIVE)[-2]+listeGroupes.get(ACTIVE)[-1])
            except:
                indiceGroupe=int(listeGroupes.get(ACTIVE)[-1])
            
        
            titreajustebis2=titreajustebis+'Groupe test '+str(indiceGroupe)
            resultats = Toplevel()
            resultats.title(titreajustebis2)
            resultats.geometry('400x370')
            
            cadreEleve1=Label(resultats, text='Eleve 1')
            cadreEleve1.grid(row=0,column=0)
            entreeEleve1 = Entry(resultats, textvariable='1', width=20)
            entreeEleve1.grid(row=0,column=1)  
            cadreEleve2=Label(resultats, text='Eleve 2')
            cadreEleve2.grid(row=1,column=0)
            entreeEleve2 = Entry(resultats, textvariable='2', width=20)
            entreeEleve2.grid(row=1,column=1)
            cadreEleve3=Label(resultats, text='Eleve 3')
            cadreEleve3.grid(row=2,column=0)
            entreeEleve2 = Entry(resultats, textvariable='3', width=20)
            entreeEleve2.grid(row=2,column=1)         
                     
            choix_groupe2.destroy()

                
        titreajustebis='Classe '+str(indiceClasse)+' '
        choix_groupe2 = Toplevel()
        choix_groupe2.title(titreajustebis)
        choix_groupe2.geometry('400x370')


        cadreTexteGroupe = Frame(choix_groupe2, background = 'PeachPuff', bd = 10)
        cadreTexteGroupe.pack(side=TOP)
        separateur1bis = Frame(choix_groupe2, height=3, bd=1, relief=SUNKEN)
        separateur1bis.pack(fill=X, padx=5, pady=5)
        cadrelisteGroupes = Frame(choix_groupe2, background = 'PeachPuff', bd=10)
        cadrelisteGroupes.pack()

        #texte
        texte1bis = Label(cadreTexteGroupe, text='Sélectionnez votre groupe.', height=5, width=150)
        texte1bis.pack(fill=BOTH, expand = 1)

        listeGroupes = Listbox(cadrelisteGroupes)
        for i in range(liste_nombre_groupes[indiceClasse]):
            nomclasseexemple=titreajustebis+'Groupe '+str(i)
            listeGroupes.insert(i, nomclasseexemple)
        listeGroupes.grid(row=0,column=0)

        boutonSelectionGroupe=Button(cadrelisteGroupes, text="OK", command=mongroupe_seseleves2)
        boutonSelectionGroupe.grid(row=1,column=0)

        #barre choix
        barre=Scrollbar(cadrelisteGroupes)
        barre.grid(row=0,column=1)
        barre.config(command = listeGroupes.yview)
        listeGroupes.config(yscrollcommand=barre.set)
        
        choix_classe2.destroy()

        
    choix_classe2 = Toplevel()
    choix_classe2.title("Sélection de la Classe")
    choix_classe2.geometry('400x370')
    
    
    cadreTexte = Frame(choix_classe2, background = 'PeachPuff', bd = 10)
    cadreTexte.pack(side=TOP)
    separateur1 = Frame(choix_classe2, height=3, bd=1, relief=SUNKEN)
    separateur1.pack(fill=X, padx=5, pady=5)
    cadrelisteClasses = Frame(choix_classe2, background = 'PeachPuff', bd=10)
    cadrelisteClasses.pack()
    
    #texte
    texte1 = Label(cadreTexte, text='Sélectionnez votre classe.', height=5, width=150)
    texte1.pack(fill=BOTH, expand = 1)
    
    listeClasses = Listbox(cadrelisteClasses)
    for i in range(nombre_de_classes):
        nomclasseexemple='Classe '+str(i)
        listeClasses.insert(i, nomclasseexemple)
    listeClasses.grid(row=0,column=0)
    
    boutonSelectionClasse=Button(cadrelisteClasses, text="OK", command=maclasse_sesgroupes2)
    boutonSelectionClasse.grid(row=1,column=0)
    
    #barre choix
    barre=Scrollbar(cadrelisteClasses)
    barre.grid(row=0,column=1)
    barre.config(command = listeClasses.yview)
    listeClasses.config(yscrollcommand=barre.set)
 
###pages

 
# grille pour les onglets et positionnement en haut à gauche
onglets = ttk.Notebook(accueil)
onglets.grid(row = 1, column = 0, columnspan = 3, sticky = W)


# pages 
page1 = ttk.Frame(onglets)
onglets.add(page1, text='Le cycle Course et Relai')
page2 = ttk.Frame(onglets)
onglets.add(page2, text='Renseigner mes performances')
page3 = ttk.Frame(onglets)
onglets.add(page3, text='Résultats')

###page 1

# texte page 1
#page1.grid_columnconfigure(0, weight=1)
#page1.grid_rowconfigure(0, weight=1)
#texte = Label(page1,text=texteTuto)
#texte.pack(expand=1, fill=Y)
#texte.configure(font=("Times New Roman", 18, "italic"))

texteaccueil = Label(page1, text=texteTuto)
texteaccueil.pack(fill=BOTH)


### page 2

cadreTexte = Frame(page2, background = 'PeachPuff', bd = 10)
cadreTexte.pack(side=TOP)
separateur = Frame(page2, height=3, bd=1, relief=SUNKEN)
separateur.pack(fill=X, padx=5, pady=5)
cadre = Frame(page2, background = 'PeachPuff', bd=10)
cadre.pack()

texte = Label(cadreTexte, text='Une fois vos performances effectuées et chronométrées, cliquez ci-dessous et suivez les instructions.', height=5, width=60)
texte.pack()


boutonPerfClasse=Button(cadre, text="Renseigner mes performances individuelles et de groupe",cursor='plus', command=choisir_classe)
boutonPerfClasse.pack()

###page 3

cadreTexte = Frame(page3, background = 'PeachPuff', bd = 10)
cadreTexte.pack(side=TOP)
separateur = Frame(page3, height=3, bd=1, relief=SUNKEN)
separateur.pack(fill=X, padx=5, pady=5)
cadre = Frame(page3, background = 'PeachPuff', bd=10)
cadre.pack()

texte = Label(cadreTexte, text='Ici consultez vos performances archivées.', height=5, width=60)
texte.pack()

boutonRechercheClasse=Button(cadre, text="Renseigner mes performances individuelles et de groupe",cursor='man', command=choisir_classe2)
boutonRechercheClasse.pack()

###barre de menu


# barre de menu

barremenu = Menu(accueil)

menu1 = Menu(barremenu, tearoff=0)
menu1.add_command(label="Gérer classes", command=gerer_classes)
menu1.add_command(label="Gérer groupes", command=gerer_groupes)
menu1.add_command(label="Gérer élèves", command=gerer_eleves)
barremenu.add_cascade(label="Gestion", menu=menu1)

menu2 = Menu(barremenu, tearoff=0)
menu2.add_command(label="Aide", command=marc)
menu2.add_separator()
menu2.add_command(label="Crédits", command=fenetreCredits)
barremenu.add_cascade(label="Infos", menu=menu2)


accueil.config(menu=barremenu)



### mainloop
accueil.mainloop()

 

[/reveal]

vitesserelaiMERESSE

 

 

<?xml version="1.0" encoding="UTF-8">
<classe>
  <groupe id="1">
     <name>...</name>
     <collectif>...</collectif>
     <eleve id="54"/>
     <eleve id="2">
     <id>54</id>
     </eleve>
        <eleve id="3">
        <nom>...</nom>
        <prenom>...</prenom>
        <individuel>...</individuel>
     </eleve>
  </groupe>
</classe>

 

Vous aimerez aussi...

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *