Projet n°1 - ISN 2014

Préparé pour: élèves de la section Informatique et Sciences du Numérique

par:Thierry Krebs

 

13 janvier 2014

 

 

 

Training Data Management


But du projet

Objectif

L’objectif à atteindre est de stocker, trier et exploiter les données récupérées par les capteurs d’entrainement sportif tels que les montres gps, cardiofréquencemètres, et autres compteurs de vélo. De nombreuses marques existent sur le marché. Polar, Suntoo, Garmin sont les principales, mais il en existe de nombreuses autres. Chacune a développé son propre format d’encodage de données et les logiciels qu’elles ont développés sont adaptés à leur format propriétaire.

Il existe quelques solutions logicielles multi-plateformes dont la plupart sont payantes.

Buts

Nous allons donc développer un programme permettant de traiter ces données. C’est à dire un programme où, après connexion sécurisée, l’athlète pourra transférer les données de son appareil, les stocker de manière organisée, en tirer un ensemble de résultats consultables ultérieurement, notamment sous forme graphique (diagrammes, histogrammes,...).

Solution

Le programme sera réalisé en Python 3.2 et pourra être compilé pour être utilisé sur différents systèmes opérationnels: Windows, Linux et éventuellement OS X.

Prérequis :

On partira de fichiers convertis au format csv utilisé notamment par le tableur Excel. Le logiciel TCX converter (gratuit) permet de réaliser aisément une telle opération.

Les mini-projets accomplis préalablement par les élèves seront réinvestis (répertoire, chronomètre, grapheur de fonctions et agenda).

Données à exploiter :

Nous limiterons ici volontairement l’étude au données suivantes: Heure, Latitude, Longitude, Altitude, Distance, Rythme Cardiaque.

Moyens mis en oeuvre:

  Programmation en python 3.2 sous édupython (Windows) ou Eclipse (Linux et OSX).

  Utilisation de bases de données Sqlite3 qui sont supportées par édupython et qui présentent l’avantage de ne pas nécessiter de serveur SQL dédié.

  Remarque: la solution mise en oeuvre se présentera sous forme d’un logiciel indépendant, portable. Une évolution serait envisageable sous forme d’application web accessible par un portail installé sur un serveur LAMP.

 

Organisation du travail:

 

 

Organigramme et réparition du travail en groupes

 

 

Groupe 1

Groupe 2

Groupe 3

Groupe4

Tâches à accomplir

Connecteur, identification

Portail, enregistrement de données

Consultations, modifications de données

Exploitation graphique des données

Elèves concernés

Skarka, Gantier

Blot, Mauze

Ladjmi, Guizelin, Muceli

Watelet, Stephan

Planning prévisionnel

 

24 mars définitions des premières variables utiles, récupération des algorithmes de base, utilisés dans les mini-projets. Recherche de documentation.

 

31 mars premier point de coordination, début des écritures en Python. Recherche de documentation.

 

14 avril deuxième point de coordination, début des «assemblages» de parties de programme.

 

5 mai mise au point, incorporation du travail accompli dans le dossier pour l’examen.

 

 

Version 0.1 du code :

# Créé par thierry, le 08/05/2014 en Python 3.2

# -*-coding:utf-8 -*-

#---------------importation des bibliothèques-------------------

from __future__ import division

from lycee import *

from tkinter import *

import sqlite3

import os

import os.path

from os import chdir

import datetime

#---------------récupération répertoire de travail--------------

rep = os.getcwd()

print(rep)

#--------------création répertoire sqlite3----------------------

try:

    os.mkdir(rep + "/Sqlite3")

except:

    print("\Sqlite3 existe déjà")

rep=rep+"\Sqlite3"

#print(rep)

os.chdir(rep)

#---------------------------------------------définition des fonctions------------------------------------------------

 

#-----------création et connexion à la base de données BDNAME----------

def BdName():

    BDNAME =rep+"/BDNAME.sq3"

    #print(BDNAME)

    global con1

    con1=sqlite3.connect(BDNAME)

    try:

        con1.execute("CREATE TABLE membres (numero INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,prenom TEXT, nom TEXT, telephone TEXT, adresse TEXT, mail TEXT, age INTEGER, login TEXT, password TEXT, datereg DATETIME)")

    except:

        print("la table est déjà crée")

 

#-----------création et connexion à la base de données TIMEREG----------

def TimeReg(numero2):

    global timeregistred

    global tablename

    global con2

    tablename="T"+timeregistred

    print(tablename)

    TIMEREG =rep+"/TIMEREG"+str(numero2)+".sq3"

    print(TIMEREG)

    con2=sqlite3.connect(TIMEREG)

    try:

        con2.execute("CREATE TABLE %s (numero2 INTEGER, TIME TEXT, LAT TEXT, LONG TEXT, ALT TEXT, DIST TEXT, HR TEXT)" %tablename)

#        con2.execute("CREATE TABLE %s (numero2 INTEGER)" %tablename)

 

 

    except:

        print("la table est déjà crée")

 

def repondre(titre,parent,boutton):

    Fenetre = Tk()

    Fenetre.title(titre)

    Fenetre.configure(bg='grey')

    Fenetre.tk_focusFollowsMouse()

    nom = Label(Fenetre, text = parent, bg='grey')

    reponse=StringVar()

    lareponse = Entry(textvariable=reponse, bd=5,background='white',relief='sunken', width=50)

    valeur = Button(Fenetre, text = boutton,bg='grey',justify='left', command=Fenetre.quit)

    affichage = Label(Fenetre,bg='grey', width=50)

    nom.pack()

    lareponse.pack()

    valeur.pack()

    affichage.pack()

    Fenetre.mainloop()

    saisir=lareponse.get()

    Fenetre.destroy()

    return (saisir)

 

def afficher(nblignes,titre,parent,boutton):

    Fenetre = Tk()

    Fenetre.title(titre)

    Fenetre.configure(bg='grey')

    Fenetre.tk_focusFollowsMouse()

    nom=nblignes*[""]

    for i in range(0,nblignes):

        nom[i] = Label(Fenetre, text = parent[i], bg='grey')

        nom[i].pack()

        trait=Label(Fenetre, text = '_________________________________________________________________________', bg='grey')

        trait.pack()

    valeur = Button(Fenetre, text = boutton,bg='grey',justify='left', command=Fenetre.quit)

    affichage = Label(Fenetre,bg='grey', width=50)

 

    valeur.pack()

    affichage.pack()

    Fenetre.mainloop()

    Fenetre.destroy()

    return ()

 

def tablereg(tablename,champ):##enregistrement des données GPS dans la table "date" de la base de l'athlète

    global numero2

    global con2

    print(tablename)

    print(champ)

    TimeReg(numero2)

    con2.execute("insert into %s (numero2, TIME, LAT, LONG, ALT, DIST, HR) values (?,?,?,?,?,?,?)"%tablename,champ)

    con2.commit()

    return()

 

def enreg():##enregistrement nouvel athlète dans BDNAME

    global con1

#    fiche=7*['']

    fiche=GestionNouvContact()

    now=datetime.datetime.now()

    fiche.append(now)

    print(fiche)

    con1.execute("insert into membres (prenom, nom, telephone, adresse, mail, age, login, password, datereg) values (?,?,?,?,?,?,?,?,?)",fiche)

    con1.commit()

    return()

 

def GestionNouvContact():##gestion des nouveaux athlètes

    Fenetre = Tk()

    Fenetre.title("nouvel athlète")

    Fenetre.configure(bg='grey')

    Fenetre.tk_focusFollowsMouse()

    igt=0

    nomchp=['prenom','nom','numéro de mobile','adresse','mail','âge','login','password']

    labelchp = 8*['']

    reg = 8*['']

    registred = 8*['']

    saisi = 8*['']

    for igt in range(0,(8)):

        labelchp[igt] = Label(Fenetre, text = nomchp[igt], bg='grey')

        reg[igt]=StringVar()

        registred[igt] = Entry(textvariable=reg[igt], bd=5,background='white',relief='sunken', width=50)

        labelchp[igt].pack()

        registred[igt].pack()

    valeur = Button(Fenetre, text = "Valider",bg='grey',justify='left', command=Fenetre.quit)

    affichage = Label(Fenetre,bg='grey', width=50)

    valeur.pack()

    affichage.pack()

    Fenetre.mainloop()

    for igt in range(0,8):

        saisi[igt]=registred[igt].get()

    Fenetre.destroy()

    return saisi

 

def ShowChoice():  ##fonction de choix menu principal

    mod=v.get()

    return mod

 

def ShowChoice2():   ##fonction de choix menu connecté

    mod2=v2.get()

    return mod2

 

def Recherche():

    recherche=repondre('recherche','nom','suivant')

    t=(recherche,)

    index=0

    affprenom=[""]

    affnom=[""]

    affnumero=[""]

    cursor = con1.execute("SELECT * FROM membres WHERE nom=? order by nom , prenom",t)

    for j in cursor:

        index=index+1

    fiches=(index+1)*[""]

    k=0

    cursor = con1.execute("SELECT * FROM membres WHERE nom=? order by nom , prenom",t)

    for row in cursor:

       affprenom="Prenom: "+str(row[1])

       affnom="Nom: "+str(row[2])

       affnumero="adresse: "+str(row[4])

       fiches[k]=affprenom+"  |  "+affnom+"  |  "+affnumero+"  |  "

       k=k+1

    return(index,fiches)

 

def Connexion():  ##fonction de connexion de l'athlète

    Fenetre = Tk()

    Fenetre.title("Connexion")

    Fenetre.configure(bg='grey')

    Fenetre.tk_focusFollowsMouse()

    igt=0

    nomchp=['Login','Password']

    labelchp = 2*['']

    reg = 2*['']

    registred = 2*['']

    saisi = 2*['']

    for igt in range(0,(2)):

        labelchp[igt] = Label(Fenetre, text = nomchp[igt], bg='grey')

        reg[igt]=StringVar()

        registred[igt] = Entry(textvariable=reg[igt], bd=5,background='white',relief='sunken', width=50)

        labelchp[igt].pack()

        registred[igt].pack()

    valeur = Button(Fenetre, text = "Valider",bg='grey',justify='left', command=Fenetre.quit)

    affichage = Label(Fenetre,bg='grey', width=50)

    valeur.pack()

    affichage.pack()

    Fenetre.mainloop()

    for igt in range(0,2):

        saisi[igt]=registred[igt].get()

    Fenetre.destroy()

    return saisi

 

def datareg(login): ##fonction de lecture des données du fichier GPS

    print('yes')

    fichier=""

    global numero2

    global timeregistred

    global tablename

    global con2

    fichier=repondre('Ouvrir fichier de données','Nom du fichier ?','ouvrir')

#    rep2 = os.getcwd()

#    print(rep2)

    os.chdir("C:\\Users\\thierry\\Documents\\programmation\\Python\\ISN\\TDM")

    contenu = open(fichier, "r").read()

    contenu = contenu.split(";")

    print(contenu)

    timeregistred=contenu[10]

    timeregistred=timeregistred[:4]+timeregistred[5:7]+timeregistred[8:10]+timeregistred[11:13]

    print(timeregistred)

    cursor = con1.execute("SELECT * FROM membres WHERE login=? and password=?",login)

    for row in cursor:

        numero2=str(row[0])

    TimeReg(numero2)

    champ=7*['']

    k=int(len(contenu)/9)

    print(k)

#   print(tablename)

    for j in range(0,k-1):

        for i in range(11,16):

            champ[0]=int(numero2)

            champ[1]=str(contenu[10+9*j])

            champ[i-9]=contenu[i+9*j]

#       print(champ)

        tablereg(tablename,champ)

#        con2.execute("insert into %s (numero, TIME, LAT, LONG, ALT, DIST, HR) values (?,?,?,?,?,?,?)"%tablename,champ)

#        con2.commit

        con2.close()

    return(numero2)

 

 

 

def connect(login):      ##menu connecté

#   login.append('connecté !')

#   print(login)

    message2="login: "+login[0]+" password: "+login[1]+" est connecté"

    root2 = Tk()

    global v2

    v2= IntVar()

    v2.set(1)

    boutton2='suivant'

    mode2 = [

               ("Enregistrer des données",1),

               ("Lister les enregistrements",2),

               ("Effacer un enregistrement",3),

               ("Synthèse des enregistrements",4),

               ("Se déconnecter",5),

               ]

    Label(root2,text=message2,justify = LEFT,padx = 20).pack()

    for txt2, val in mode2:

        Radiobutton(root2,text=txt2,indicatoron = 0,width = 20,padx = 20,variable=v2,command=ShowChoice,value=val).pack(anchor=W)

    Button(root2, text = boutton2, command=root2.quit).pack()

    root2.mainloop()

    root2.destroy()

    mod2=ShowChoice2()

    print(mod2)

 

    while (mod2 != 5):

        mod=ShowChoice()

 

    #----------Gestion du mode enregistrement de données----------

        if mod2 == 1:

            numero2=datareg(login)

 

    #----------Gestion du mode lister les enregistrements----------

        if mod2 == 2:

            reglist()

##            index=0

##            affprenom=[""]

##            affnom=[""]

##            affnumero=[""]

##            cursor = con1.execute("select prenom, nom, adresse   from membres")

##            for j in cursor:

##                index=index+1

##            fiches=(index+1)*[""]

##            k=0

##            cursor = con1.execute("select prenom, nom, adresse  from membres order by nom , prenom")

##            for row in cursor:

##               affprenom="Prenom: "+str(row[0])

##               affnom="Nom: "+str(row[1])

##               affnumero="Adresse: "+str(row[2])

##               fiches[k]=affprenom+"  |  "+affnom+"  |  "+affnumero+"  |  "

##               k=k+1

##            afficher(index,'Liste des athlètes',fiches,'suivant')

 

 

#----------Gestion effacement d'enregistrements-----------------

        if mod2 == 3:

            regdel()

##            [index,fiches]=Recherche()

##            afficher(index,'Recherche nom contact à effacer',fiches,'suivant')

##            effacer=repondre('effacement','nom athlète à effacer','recherche')

##            effacer2=repondre('effacement','prénom athlète à effacer','recherche')

##            eff=[""]

##            eff[0]=effacer2+" "+effacer

##            t=(effacer,effacer2,)

##            cursor = con1.execute("DELETE FROM membres WHERE nom=? and prenom=?",t)

##            con1.commit()

##            afficher(1,'athlète éffacé: ',eff,'suivant')

    #-----------Synthèse--------------------------

        if mod2 == 4:

            synth()

 

 

 

 

    #----------menu boucle------------

        root2 = Tk()

        v2 = IntVar()

        v2.set(1)  # initializing the choice, i.e. Python

        boutton2='suivant'

        mode2 = [

                   ("Enregistrer des données",1),

                   ("Lister les enregistrements",2),

                   ("Effacer un enregistrement",3),

                   ("Synthèse des enregistrements",4),

                   ("Se déconnecter",5),

                   ]

        Label(root2,text=message2,justify = LEFT,padx = 20).pack()

        for txt2, val in mode2:

            Radiobutton(root2,text=txt2,indicatoron = 0,width = 20,padx = 20,variable=v2,command=ShowChoice,value=val).pack(anchor=W)

        Button(root2, text = boutton2, command=root2.quit).pack()

        root2.mainloop()

        root2.destroy()

        mod2=ShowChoice2()

        con2.close()

    #----------------------------------

 

 

 

 

#-------------------------------------------------------programme principal------------------------------------------------------

BdName()

#----------initialisation menu------------

root = Tk()

v = IntVar()

v.set(1)

boutton='suivant'

mode = [

               ("Nouvel athlète",1),

               ("Lister les athlètes",2),

               ("Rechercher un athlète",3),

               ("Supprimer un athlète",4),

               ("Se connecter",5),

               ("quitter",6)

               ]

#----------appel du menu----------

Label(root,text="""action à effectuer:""",justify = LEFT,padx = 20).pack()

for txt, val in mode:

    Radiobutton(root,text=txt,indicatoron = 0,width = 20,padx = 20,variable=v,command=ShowChoice,value=val).pack(anchor=W)

Button(root, text = boutton, command=root.quit).pack()

root.mainloop()

root.destroy()

mod=ShowChoice()

 

while (mod != 6):

    mod=ShowChoice()

 

#----------Gestion du mode enregistrement----------

    if mod == 1:

        enreg()

 

#----------Gestion du mode lister----------

    if mod == 2:

        index=0

        affprenom=[""]

        affnom=[""]

        affnumero=[""]

        cursor = con1.execute("select prenom, nom, adresse   from membres")

        for j in cursor:

            index=index+1

        fiches=(index+1)*[""]

        k=0

        cursor = con1.execute("select prenom, nom, adresse  from membres order by nom , prenom")

        for row in cursor:

           affprenom="Prenom: "+str(row[0])

           affnom="Nom: "+str(row[1])

           affnumero="Adresse: "+str(row[2])

           fiches[k]=affprenom+"  |  "+affnom+"  |  "+affnumero+"  |  "

           k=k+1

        afficher(index,'Liste des athlètes',fiches,'suivant')

 

#----------Gestion Recherche-----------------

    if mod == 3:

        [index,fiches]=Recherche()

        afficher(index,'Résultat de la recherche',fiches,'suivant')

 

#----------Gestion effacement-----------------

    if mod == 4:

        [index,fiches]=Recherche()

        afficher(index,'Recherche nom contact à effacer',fiches,'suivant')

        effacer=repondre('effacement','nom athlète à effacer','recherche')

        effacer2=repondre('effacement','prénom athlète à effacer','recherche')

        eff=[""]

        eff[0]=effacer2+" "+effacer

        t=(effacer,effacer2,)

        cursor = con1.execute("DELETE FROM membres WHERE nom=? and prenom=?",t)

        con1.commit()

        afficher(1,'athlète éffacé: ',eff,'suivant')

#-----------Connexion--------------------------

    if mod == 5:

        login=Connexion()

        print(login)

        try:

            cursor = con1.execute("SELECT * FROM membres WHERE login=? and password=?",login)

        except:

            afficher(1,'login ou password non reconnu',login,'essayer à nouveau')

        for row in cursor:

           identifiant=str(row[7])

           motdepasse=str(row[8])

        if identifiant==login[0] and motdepasse==login[1]:

            connect(login)

        else:

            afficher(1,'login ou password non reconnu',login,'essayer à nouveau')

 

 

 

 

#----------menu boucle------------

    root = Tk()

    v = IntVar()

    v.set(1)  # initializing the choice, i.e. Python

    boutton='suivant'

    mode = [

               ("Nouvel athlète",1),

               ("Lister les athlètes",2),

               ("Rechercher un athlète",3),

               ("Supprimer un athlète",4),

               ("Se connecter",5),

               ("quitter",6)

               ]

    Label(root,text="""action à effectuer:""",justify = LEFT,padx = 20).pack()

    for txt, val in mode:

        Radiobutton(root,text=txt,indicatoron = 0,width = 20,padx = 20,variable=v,command=ShowChoice,value=val).pack(anchor=W)

    Button(root, text = boutton, command=root.quit).pack()

    root.mainloop()

    root.destroy()

    mod=ShowChoice()

con1.commit()

con1.close()

 

 

#----------------------------------

#----------Gestion mise à jour-----------------

##    if mod == 5:

##        [index,fiches]=Recherche()

##        afficher(index,'Recherche nom athlète à mettre à jour',fiches,'suivant')

##        actu=repondre('Mise à jour','nom athlète à mettre à jour','recherche')

##        actu2=repondre('Mise à jour','prénom athlète à mettre à jour','recherche')

##        t=(actu,actu2,)

##        cursor = con.execute("SELECT * FROM membres WHERE nom=? and prenom=?",t)

##        for row in cursor:

##           numero='ancien numéro: '+str(row[2])

##        maj=repondre('nouveau numero',numero,'mise à jour')

##        nvnum=[""]

##        nvnum[0]=actu2+" "+actu+" "+str(maj)

##        r=(maj,actu,actu2)

##        cursor = con.execute("UPDATE membres SET numero=? WHERE nom=? and prenom=?",r)

##        con.commit()

##        afficher(1,'athlète mis à jour: ',nvnum,'suivant')