You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
566 lines
28 KiB
566 lines
28 KiB
from tkinter import*
|
|
import csv
|
|
|
|
|
|
"""
|
|
Projet Estimation de Puissance Consommée
|
|
Yanis DE-OLIVEIRA et Loïc JEAN-OPHOVEN 1G1 06/2022
|
|
Version intégrant le choix du type de calcul de distance et la possibilité de calculer sur plusieurs points
|
|
|
|
"""
|
|
|
|
|
|
|
|
######################################################################################################
|
|
#OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO Fonctions OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
|
|
######################################################################################################
|
|
|
|
"""""""""""""""""""""""""""
|
|
III-2 Fonctions utiles pour la lecture du fichier d'apprentissage : lecture, numeroJour, estBissextile
|
|
"""""""""""""""""""""""""""
|
|
|
|
def lecture(FileName):
|
|
"""
|
|
1. Fonction lecture qui :
|
|
- prend en paramètre le chemin du fichier csv à lire et qui renvoie un tableau
|
|
- lit le fichier csv dont le nom est passé en paramètre (attention : séparateur = ";")
|
|
- appelle la fonction de transformation d'une date en "Nombre de jours correspondant dans l'année"
|
|
- et renvoie un tableau "liste" contenant le tuple
|
|
(numéro de jours de chaque date, la température moyenne, la température de référence)
|
|
et la valeur associée du pic de consommation
|
|
"""
|
|
|
|
date_mes = 'aaaa-mm-jj'
|
|
lst_Jour = []
|
|
lst_pic_jour_conso = []
|
|
lst_tempe_moy = []
|
|
lst_tempe_ref = []
|
|
liste = [(lst_Jour,lst_tempe_moy,lst_tempe_ref,),lst_pic_jour_conso] # variable de sortie
|
|
|
|
with open(FileName, 'r') as fichierApp:
|
|
fichierApp.readline() # on fait en sorte d'ignorer la première ligne contenant les titres
|
|
for ligne in fichierApp:
|
|
date_mes, pic_jour_conso, tempe_moy, tempe_ref = ligne.split(';')
|
|
# Transformation du jour :
|
|
Jour = numeroJour(date_mes)
|
|
# Ajout des données de chaque ligne du fichier + le nombre de jour calculé dans les listes:
|
|
lst_Jour.append(Jour)
|
|
lst_tempe_moy.append(float(tempe_moy))
|
|
lst_tempe_ref.append(float(tempe_ref))
|
|
lst_pic_jour_conso.append(float(pic_jour_conso))
|
|
# mise en liste unique :
|
|
liste = [(lst_Jour, lst_tempe_moy, lst_tempe_ref), lst_pic_jour_conso]
|
|
return liste
|
|
|
|
def numeroJour(d):
|
|
"""
|
|
2. Fonction numeroJour qui prend en paramètre la date d (au format string "aaaa-mm-jj")
|
|
et qui renvoie un entier correspondant au numéro du jour correspondant dans une année (entre 1 et 365)
|
|
Remarque : comme demandé, on force le 31/12 à 365j même en cas d'année bissextile, afin de simplifier
|
|
le calcul de différence de jours entre 2 dates qui ne seraient pas de la même année.
|
|
"""
|
|
date_tab = []
|
|
date_tab = d.split('-')
|
|
a = int(date_tab[0])
|
|
m = int(date_tab[1])
|
|
j = int(date_tab[2])
|
|
|
|
if estBissextile(a):
|
|
return (0,31,60,91,121,152,182,213,244,274,305,335,365)[m-1] + j # on ajoute le "cumul de jours depuis le début d'année jusqu'à m-1" avec le jour "j" du mois en cours
|
|
else:
|
|
return (0,31,59,90,120,151,181,212,243,273,304,334,365)[m-1] + j # idem mais en comptant 28j en février au lieu de 29 (cas bissextile précédent)
|
|
|
|
|
|
def estBissextile(a):
|
|
"""
|
|
3. Fonction estBissextile qui prend en paramètre l'année à vérifier "a" et qui renvoie True si elle est bissextile, False sinon
|
|
"""
|
|
if a%4!=0:
|
|
return False
|
|
if a%100==0 and a%400!=0:
|
|
return False
|
|
return True
|
|
|
|
|
|
|
|
|
|
"""""""""""""""""""""""""""
|
|
III-3 Fonctions utiles pour l'algorithme des k plus proches voisins
|
|
Cette partie du projet va calculer la distance entre un point à vérifier et tous les enregistrements. Ces distances
|
|
seront stockées dans une nouvelle liste qu'il faudra trier dans l'ordre croissant des distances afin de ne garder que les k premiers termes.
|
|
On calculera aussi la puissance moyenne consommée sur les k résultats "plus proches voisins" de la date étudiée.
|
|
Trois fonctions : distance (calcule la distance euclidienne carrée ou de Manhattan), kPlusProches, PuissanceMoyenne
|
|
|
|
Ajout de la fonction "Check_Date_Choix" qui vérifie :
|
|
- le contenu de la date (pour éviter le " 35/02/2021" par exemple,
|
|
- et le choix de type de calcul de distance (doit être 0 ou 1)
|
|
|
|
"""""""""""""""""""""""""""
|
|
|
|
|
|
def distance(Tuple_point, Tuple_tab_data, Choix_calcul):
|
|
"""
|
|
1. Fonction distance qui prend en paramètre 2 tuples, chacun contenant (Numéro du jour, Température moyenne, température de référence)
|
|
et qui renvoie un nombre réel représentant la distance euclidienne ou de Manhattan selon la valeur de "Choix_calcul"
|
|
• Paramètres d'entrée :
|
|
• Tuple_point : le tuple "jour, température moyenne, température de référence" saisi par l'utilisateur (ou du fichier Excel en contenant plusieurs)
|
|
• Tuple_tab_data : le tuple "jour, température moyenne, température de référence" d'une ligne appartenant à la liste de mesures
|
|
• Choix_calcul : si égal à 0 (ou autre entier) : somme euclidienne, si égal à 1 : comme de Manhattan
|
|
• Sortie : La fonction renvoie un float = la distance au carré entre le Tuple_point étudié et chaque triplettes de valeurs du Tuple_tab_data, c'est-à-dire la
|
|
distance euclidienne "au carré" incluant écart de jours, écart de température moyenne, écart de température de référence.
|
|
Si Choix_Calcul est égal 1, le calcul de distance se fait par la méthode de Manhattan
|
|
• Note : si la date du point étudié et la date du tableau de données sont espacés de plusieurs années, ce n'est pas grave car nous étudions des phénomènes
|
|
saisonniers et que le calcul prend aussi en compte la distance avec les températures moyennes et de référence.
|
|
"""
|
|
|
|
# gestion de la différence de jours (rappel : le nombre total de jours d'une année est fixé à 365j quel que soit le nombre d'années d'écart entre deux dates.
|
|
d1 = abs(Tuple_point[0] - Tuple_tab_data[0])
|
|
d2 = 365-d1 # remarque : d1 est forcément inférieur ou égal à 365j
|
|
|
|
if Choix_calcul==1 : # alors calcul de Manhattan
|
|
return (min(d1, d2)) + abs(Tuple_point[1] - Tuple_tab_data[1]) + abs(Tuple_point[2] - Tuple_tab_data[2])
|
|
else : # sinon, quelle que soit la valeur de Choix_calcul (entier), alors calcul Euclidien (même si on teste la valeur de Choix_calcul par ailleurs)
|
|
return (min(d1, d2))**2 + (Tuple_point[1] - Tuple_tab_data[1])**2 + (Tuple_point[2] - Tuple_tab_data[2])**2
|
|
|
|
|
|
def kPlusProches(Tuple_point_local, Tab_Data_local, k_local, Choix_local):
|
|
"""
|
|
2. Fonction kPlusProches :
|
|
• Paramètres d'entrée :
|
|
Tuple_point_local : tuple de 3 valeurs "jour, température moyenne, température de référence" : tuple étudié
|
|
Tab_Data_local : liste de référence dont chaque ligne comprend un tuple situé en Tab_Data_local[0] = (jour, température moyenne, température de référence)
|
|
ET une valeur de consommation : Tab_Data_local[1] = pic_jour_conso
|
|
k_local : le nombre de voisins à prendre en compte
|
|
Choix_local : le choix de calcul de distance
|
|
• Sortie : ListeVoisinsProches
|
|
Liste des distances et indices des k points de la liste 'Tab_Data_local' les plus proches du point représenté par Tuple_point_local.
|
|
Donc une liste de tuples à 2 valeurs (distance, indice du tableau original), triée en fonction de la distance avec le point étudié
|
|
"""
|
|
voisins = [] # la liste des des k voisins : chaque ligne contiendra indice d'un des k voisins, et la distance correspondante en Jours
|
|
d=0.0 # init de la variable distance utilisée dans la fonction
|
|
|
|
if k_local > len(Tab_Data_local[0][0]): # Par sécurité, si on demande plus de voisin qu'il n'y a de points dans le tableau csv de référence (nbre de points de "NbreJours", indice[0] du tuple se trouvant à l'indice [0] de Tab_Data_Local...
|
|
k_local = len(Tab_Data_local[0][0]) # ... alors on réduit k
|
|
|
|
Tuple_Tab_Data_local = Tab_Data_local[0] # on récupère la liste de tuple de 3 valeurs (jour, température moyenne, température de référence)
|
|
|
|
# pour chaque indice de Tuple_Tab_Data_local, on calcule la distance avec le point étudié + enregistrement dans "voisins" :
|
|
for i_tab_data in range(len(Tuple_Tab_Data_local[0])):
|
|
Tuple_Tab_Data_local_i = (Tuple_Tab_Data_local[0][i_tab_data],Tuple_Tab_Data_local[1][i_tab_data],Tuple_Tab_Data_local[2][i_tab_data]) # récupération du tuple (de 3 valeurs) stocké en indice i_tab_data du Tuple_Tab_Data_local
|
|
d = distance(Tuple_point_local, Tuple_Tab_Data_local_i, Choix_local)
|
|
voisins.append((d, i_tab_data))
|
|
# tri croissant sur la distance :
|
|
voisins.sort() # Pour un couple, sort trie d'abord en fonction de la première valeur, donc la distance dans notre cas, c'est ce que nous voulons
|
|
|
|
ListeVoisinsProches=[]
|
|
for i in range(int(k_local)):
|
|
ListeVoisinsProches.append(voisins[i])
|
|
|
|
|
|
return ListeVoisinsProches # on renvoie la liste ordonnée des k premiers points voisins, chaque ligne contenant un tuple (d,i_tab_data)
|
|
|
|
|
|
|
|
def PuissanceMoyenne(Liste_k_voisins, Tab_Data_local):
|
|
"""
|
|
3. Fonction PuissanceMoyenne : Calcule et renvoie la puissance électrique moyenne des k plus proches voisins.
|
|
• Paramètre d'entrée :
|
|
Liste_k_voisins : La liste triée en fonction de la distance dont les éléments sont des tuples (distance, indice du tableau original)
|
|
La liste Tab_Data_local = "tuple (distance, température moyenne, température de référence) en indice 0 ; et pic_jour_conso en indice 1"
|
|
• Paramètre de sortie :
|
|
Puissance électrique moyenne des k plus proches voisins (dont on a les indices dans Liste_k_Voisins, et qui se trouvent en [1] de Tab_Data_Local)
|
|
"""
|
|
consoElecPrevue=0
|
|
for i in range(len(Liste_k_voisins)):
|
|
consoElecPrevue=consoElecPrevue+Tab_Data_local[1][Liste_k_voisins[i][1]] # on additionne la valeur en indice 1 de la Liste_k_voisins correspondante à l'indice stocké en Liste_k_voisins[i]
|
|
|
|
return consoElecPrevue/len(Liste_k_voisins)
|
|
|
|
|
|
def Check_Date_Choix(date,choix):
|
|
"""
|
|
Fonction qui teste les saisies de date et de choix de calcul de distance, seules saisies qui doivent respecter des règles particulières
|
|
date doit respecter les critères d'une date réelle (pour éviter les 32ème jour, 13ème mois, choix autre que 0 ou 1)
|
|
Entrées : date (format string 'aaaa-mm-dd') et choix (integer)
|
|
Sortie : booléen True si test ok, False sinon
|
|
"""
|
|
|
|
date_local = []
|
|
date_local = date.split('-')
|
|
a = int(date_local[0])
|
|
m = int(date_local[1])
|
|
j = int(date_local[2])
|
|
|
|
Jours_mois = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
|
if estBissextile(a):
|
|
Jours_mois[2] = 29
|
|
|
|
if (1 <= m <= 12 and 1 <= j <= Jours_mois[m]) and (choix==0 or choix==1):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
|
|
|
|
"""""""""""""""""""""""""""""""""""""""
|
|
III-4 Exécution du test sur un point
|
|
"""""""""""""""""""""""""""""""""""""""
|
|
|
|
def lancerTest():
|
|
'''
|
|
Cette fonction a pour rôles :
|
|
• Récupérer les diverses entrées de l'utilisateur (nombre de voisins k, paramètres du point à vérifier, jour, température moyenne) puis de les mettre en forme
|
|
• Lancer la lecture du fichier d'apprentissage (fichier de données de référence)
|
|
• Lancer l'algorithme de k plus proches voisins
|
|
• Calculer la consommation électrique prévue en effectuant la moyenne des consommations des k proches voisins
|
|
• Afficher le résultat sur l'IHM (mise à jour de la variable labelRep)
|
|
• intègre la prise en compte du choix de calcul de distance
|
|
|
|
Ajout : si une erreur survient durant le calcul, ou si la date ou le choix ne respectent pas les critères basiques,
|
|
alors : afficher un message demandant à l'utilisateur de vérifier ses saisies.
|
|
'''
|
|
consoElecPrevue=0.0 # initialisation de résultat final
|
|
Test_saisies=True # variable servant à tester si une erreur survient durant les calculs
|
|
Test_date_choix=True # variable servant à tester les caractéristiques de la date et du choix
|
|
|
|
while Test_saisies==True:
|
|
try:
|
|
|
|
# 1. récupération des données saisies et du chemin de fichier de données :
|
|
FileName=Chemin_Fichier.get()
|
|
k_local= k.get()
|
|
DatePoint_local = DatePoint.get()
|
|
tempMoyenne_local = tempMoyenne.get()
|
|
tempRef_local = tempRef.get()
|
|
ChoixCalcul_local = Choix.get()
|
|
# remarque : si une affectation d'un .get dans une variable renvoie une erreur, elle est "attrapée" par le try / except
|
|
|
|
# 2. teste les critères spécifiques de la date et du choix de calcul des distances et si ok lance les calculs :
|
|
Test_date_choix = Check_Date_Choix(DatePoint_local, ChoixCalcul_local)
|
|
|
|
if Test_date_choix == True:
|
|
|
|
# 2.1 récupération du point à étudier sous forme de tuple :
|
|
Tuple_Point_local = (numeroJour(DatePoint_local), tempMoyenne_local, tempRef_local)
|
|
|
|
# 2.2 récupération des points du tableau de données de référence enregistrées :
|
|
Tab_Data_local = lecture(FileName)
|
|
|
|
# 2.3 Calculs :
|
|
Liste_k_Voisins_local = kPlusProches(Tuple_Point_local, Tab_Data_local, k_local, ChoixCalcul_local)
|
|
consoElecPrevue = PuissanceMoyenne(Liste_k_Voisins_local, Tab_Data_local)
|
|
|
|
# 2.4 Affichage du résultat de consommation prévisionnelle (variable labelRep:
|
|
labelRep.configure(text = str(consoElecPrevue)+ ' MW')
|
|
|
|
else: # alors on ne fait pas les calculs et on affiche un message explicite :
|
|
labelRep.configure(text = 'La date ou le choix de calcul de distance ne va pas : veuillez vérifier vos saisies !')
|
|
|
|
break
|
|
|
|
# si exception durant le test, nous passons la variable Test_saisies à False et affichons un message +/- explicite ...
|
|
except (RuntimeError, TypeError, NameError, OSError, ValueError, ConnectionError, BaseException):
|
|
Test_saisies=False
|
|
labelRep.configure(text = 'Ca plante ! Vérifiez vos saisies, ou engueulez les développeurs !')
|
|
|
|
return True
|
|
|
|
|
|
|
|
"""""""""""""""""""""""""""""""""""""""""""""""""""
|
|
Bonus Exécution du test sur un fichier de points :
|
|
Deux fonctions additionnelles :
|
|
|
|
1. lancerTestsPlusieursPoints qui éxécute un code similaire à celui pour un point
|
|
mais sur l'ensemble des points listés dans un fichier "source" (jeuTests.csv)
|
|
|
|
2. NewCsv qui permet de créer un fichier csv cible dans lequel on mettra les données "sources" + les résultats de simulations
|
|
|
|
"""""""""""""""""""""""""""""""""""""""""""""""""""
|
|
def lancerTestsPlusieursPoints():
|
|
"""
|
|
fonction qui ouvre un fichier contenant plusieurs points à simuler,
|
|
lance i fois le calcul comme dans "lancerTests" (où i est le nombre de points contenus dans le fichier),
|
|
et stocke chaque résultats dans Tab_estimations
|
|
puis copie les résultats dans un autre fichier csv avec les données du premier fichier et les résultats dans une 5ème colonne
|
|
|
|
"""
|
|
Tab_estimations=['Estimation de puissance consommée :'] # tableau de string pour mettre en csv à la fin ... première ligne = entête du futur csv
|
|
Test_saisies=True # variable servant à tester si une erreur survient durant les calculs
|
|
|
|
while Test_saisies==True:
|
|
try:
|
|
# 1. récupération des données saisie, du chemin de fichier de points à tester + les options de calculs (k et méthode de cacul de distance)
|
|
FileName=Chemin_Fichier.get()
|
|
Tab_Data_local = lecture(FileName)
|
|
FileNameTests=Chemin_Fichier_Tests.get()
|
|
Tab_Points_local = lecture(FileNameTests) # rappel : Tab_Points_local[0] contient le tuple NbreJours, tempe, Tab_Points_local[1] les consommations du fichier
|
|
k_local= k.get()
|
|
ChoixCalcul_local = Choix.get()
|
|
# remarque : si un .get renvoie une erreur, elle est "attrapée" par le try / except
|
|
# remarque additionnelle : si Excel contient jj/mm/aaaa, Python convertit en aaa-mm-jj automatiquement (sans quoi la fonction "lecture" planterait)
|
|
|
|
# 2. Boucle sur chaque point du fichier Tests : calcul comme pour un point
|
|
# on considère que les données du fichiers sont "bonnes" (simplification : on ne teste pas le format des dates)
|
|
# si ce n'est pas le cas, l'IHM affichera un message d'erreur de saisie, mais on teste le choix quand même :
|
|
|
|
if (ChoixCalcul_local==0 or ChoixCalcul_local==1) : # si "Choix" est 0 ou 1
|
|
|
|
for i in range(len(Tab_Points_local[0][0])): # nbre de points de "NbreJours", indice[0] du tuple se trouvant à l'indice [0] de Tab_Points
|
|
|
|
# 2.1 Constitution du Tuple du point à étudier, cette fois on récupère non pas la valeur de l'IHM mais celle du point étudié dans le fichier
|
|
Tuple_Point_local = (Tab_Points_local[0][0][i],Tab_Points_local[0][1][i],Tab_Points_local[0][2][i])
|
|
|
|
# 2.2 Calculs et préparation du tableau de sortie :
|
|
Liste_k_Voisins_local = kPlusProches(Tuple_Point_local, Tab_Data_local, k_local, ChoixCalcul_local)
|
|
Consommation_calculee = PuissanceMoyenne(Liste_k_Voisins_local, Tab_Data_local)
|
|
|
|
Tab_estimations.append(Consommation_calculee)
|
|
|
|
# 2.3 on génère un nouveau fichier csv avec les données du tableau de tests + les estimations calculées en dernière colonne :
|
|
FileNameSortieTests=Chemin_Sortie_Tests.get()
|
|
NewCsv(FileNameTests,FileNameSortieTests,Tab_estimations)
|
|
|
|
labelRep.configure(text = 'Vous pouvez ouvrir votre fichier ...')
|
|
|
|
else: # alors on ne fait pas les calculs et on affiche un message explicite :
|
|
labelRep.configure(text = 'Le choix de calcul de distance ne va pas : il faut 0 ou 1 !')
|
|
|
|
break
|
|
|
|
except (RuntimeError, TypeError, NameError, OSError, ValueError, ConnectionError, BaseException):
|
|
Test_saisies=False
|
|
labelRep.configure(text = 'Ca plante ! Vérifiez vos saisies, fermez le fichier cible, ou engueulez les développeurs !')
|
|
|
|
return True
|
|
|
|
|
|
|
|
def NewCsv(FileNameTestsLocal,FileNameSortieTestsLocal,Tab_estimationsLocal):
|
|
"""
|
|
Fonction inspirée de "lecture" mais utilisée pour :
|
|
- lire un csv "FileNameTestsLocal",
|
|
- remplir un tableau avec les données lues
|
|
- ajouter les résultats de calculs "Tab_estimationsLocal"
|
|
- et écrire le tableau obtenu dans un autre csv : "FileNameSortieTestsLocal"
|
|
|
|
Paramètres :
|
|
FileNameTestsLocal : chemin du fichier contenant les données de tests
|
|
FileNameSortieTestsLocal : chemin du fichier de sortie
|
|
Tab_estimationsLocal : tableau contenant les résultats de simulation
|
|
Sortie : le fichier csv qui contiendra la variable liste_col, transposée en colonne de la liste de l'ensemble des données
|
|
|
|
"""
|
|
|
|
date_mes = 'aaaa-mm-jj'
|
|
lst_Date = []
|
|
lst_pic_jour_conso = []
|
|
lst_tempe_moy = []
|
|
lst_tempe_ref = []
|
|
liste = [lst_Date,lst_pic_jour_conso,lst_tempe_moy,lst_tempe_ref,[]]
|
|
liste_col = [] # variable qui contiendra la transposée de liste
|
|
|
|
with open(FileNameTestsLocal, 'r') as fichierTests:
|
|
# Cette fois, on n'ignore pas la première ligne contenant les titres
|
|
|
|
for ligne in fichierTests:
|
|
|
|
date_mes, pic_jour_conso, tempe_moy, tempe_ref = ligne.split(';')
|
|
tempe_ref = tempe_ref.strip('\n') #tempe_ref sort avec un \n de trop en fin de chaine : à supprimer !
|
|
|
|
# Ajout des données dans les listes :
|
|
lst_Date.append(date_mes)
|
|
lst_pic_jour_conso.append(pic_jour_conso)
|
|
lst_tempe_moy.append(tempe_moy)
|
|
lst_tempe_ref.append(tempe_ref)
|
|
|
|
# mise en liste unique format string avant écriture en csv :
|
|
liste = [lst_Date, lst_pic_jour_conso, lst_tempe_moy, lst_tempe_ref, Tab_estimationsLocal]
|
|
|
|
# Ecriture de "liste" en colonne dans un csv :
|
|
|
|
F_Out = open (FileNameSortieTestsLocal, 'w', newline='')
|
|
writer=csv.writer(F_Out,delimiter=';')
|
|
|
|
# Transposition des lignes en colonnes :
|
|
for i in range(len(liste[0])):
|
|
row =[]
|
|
for item in liste:
|
|
row.append(item[i])
|
|
liste_col.append(row)
|
|
|
|
# Ecriture :
|
|
for item in liste_col:
|
|
writer.writerow(item)
|
|
|
|
return liste_col
|
|
|
|
|
|
######################################################################################################
|
|
#OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO Fin des fonctions OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
|
|
######################################################################################################
|
|
|
|
|
|
|
|
"""""""""""""""""""""""""""
|
|
III-1 L'interface Homme Machine (IHM)
|
|
On utilisera la bibliothèque Tkinter. L'IHM devra permettre à l'utilisateur :
|
|
• De choisir le fichier de données de référence
|
|
• Choisir le nombre de voisins (k)
|
|
• Choisir la méthode de calcul de distance (euclidienne ou de Manhattan)
|
|
• POUR FAIRE UNE ESTIMATION SUR UN POINT :
|
|
• D'entrer les paramètres date, température moyenne, température de référence du point à vérifier
|
|
• De lancer le test par appui sur un bouton
|
|
• D'afficher la consommation prévue
|
|
• POUR FAIRE UNE ESTIMATION SUR UN FICHIER DE POINTS :
|
|
• de choisir le fichier de points à traiter
|
|
• de choisir le fichier à créer
|
|
• de lancer le test par appui sur un bouton
|
|
• d'enregistrer les résultats
|
|
"""""""""""""""""""""""""""
|
|
|
|
# créer une première fenêtre
|
|
window = Tk()
|
|
|
|
# personnaliser la fenêtre
|
|
window.title('Qui va payer ? ')
|
|
window.geometry("800x800")
|
|
window.minsize(1000, 900)
|
|
window.iconbitmap("Flash.ico") # fichier à poser à côté du .py
|
|
window.config(background = '#88cffa')
|
|
|
|
# créer la frame
|
|
frame = Frame(window, bg = '#19191a')
|
|
|
|
##############################################################
|
|
# Données générales :
|
|
##############################################################
|
|
|
|
# Lien fichier de données :
|
|
label_subtitle = Label(frame, text = "Saisissez le chemin du fichier de données de référence : ", font = ('Arial', 20), bg = '#19191a', fg = 'white')
|
|
label_subtitle.pack()
|
|
|
|
Chemin_Fichier = StringVar()
|
|
Chemin_Fichier.set('pic-journalier-consommation.csv')
|
|
chemin = Entry(frame, textvariable = Chemin_Fichier, width = 50)
|
|
chemin.pack()
|
|
|
|
# Choix de la valeur de k, nombre de voisins
|
|
label_subtitle = Label(frame, text = 'Veuillez enter le nombre de plus proches voisins :', font = ('Arial', 16), bg = '#19191a', fg = 'white')
|
|
label_subtitle.pack()
|
|
|
|
k = IntVar()
|
|
k.set(1)
|
|
entree = Entry(frame, textvariable = k, width=15)
|
|
entree.pack()
|
|
|
|
# Ajout du choix du type de calcul : Choix =1 => calcul de Manhattan, Choix =0 => calcul Euclidien
|
|
label_subtitle = Label(frame, text = 'Option de méthode de calcul : 0 pour méthode Euclidienne / 1 pour Manhattan :', font = ('Arial', 16), bg = '#19191a', fg = 'white')
|
|
label_subtitle.pack()
|
|
Choix = IntVar()
|
|
# Par défaut si Choix est égal à 0, ce sera un calcul Euclidien
|
|
entree = Entry(frame, textvariable = Choix, width=5)
|
|
entree.pack()
|
|
|
|
|
|
##############################################################
|
|
# Pour plusieurs points :
|
|
##############################################################
|
|
|
|
label_subtitle = Label(frame, text = "Pour lancer le calcul sur un fichier de points : ", font = ('Arial', 20), bg = '#19191a', fg = 'red')
|
|
label_subtitle.pack(pady=5)
|
|
|
|
# Lien fichier de Tests sur plusieurs points :
|
|
label_subtitle = Label(frame, text = "Saisissez le chemin du fichier de points à tester si vous voulez en faire plusieurs : ", font = ('Arial', 16), bg = '#19191a', fg = 'white')
|
|
label_subtitle.pack()
|
|
|
|
Chemin_Fichier_Tests = StringVar()
|
|
Chemin_Fichier_Tests.set('jeuTests.csv')
|
|
chemin = Entry(frame, textvariable = Chemin_Fichier_Tests, width = 50)
|
|
chemin.pack()
|
|
|
|
# Lien fichier de sortie pour calcul sur plusieurs points :
|
|
label_subtitle = Label(frame, text = "Saisissez le chemin du fichier de sortie pour plusieurs points : ", font = ('Arial', 16), bg = '#19191a', fg = 'white')
|
|
label_subtitle.pack()
|
|
|
|
Chemin_Sortie_Tests = StringVar()
|
|
Chemin_Sortie_Tests.set('monFichier.csv')
|
|
chemin = Entry(frame, textvariable = Chemin_Sortie_Tests, width = 50)
|
|
chemin.pack()
|
|
|
|
##############################################################
|
|
# Sur un seul point :
|
|
##############################################################
|
|
|
|
label_subtitle = Label(frame, text = 'Saisies pour le calcul sur un seul point :', font = ('Arial', 20), bg = '#19191a', fg = 'red')
|
|
label_subtitle.pack(pady = 20)
|
|
|
|
##############################################################
|
|
|
|
# Choix de la date dont on veut estimer la puissance consommée
|
|
label_subtitle = Label(frame, text = 'Veuillez entrer la date dont on doit estimer la consommation (format : aaaa-mm-dd) :', font = ('Arial', 16), bg = '#19191a', fg = 'white')
|
|
label_subtitle.pack()
|
|
|
|
DatePoint = StringVar()
|
|
DatePoint.set('2000-01-01')
|
|
entree = Entry(frame, textvariable = DatePoint, width=15)
|
|
entree.pack()
|
|
|
|
|
|
##############################################################
|
|
|
|
# Choix de la température moyenne
|
|
label_subtitle = Label(frame, text = 'Veuillez entrer la température moyenne :', font = ('Arial', 16), bg = '#19191a', fg = 'white')
|
|
label_subtitle.pack()
|
|
|
|
tempMoyenne = DoubleVar()
|
|
tempMoyenne.set(21)
|
|
entree = Entry(frame, textvariable = tempMoyenne, width=15)
|
|
entree.pack()
|
|
|
|
##############################################################
|
|
|
|
# Choix de la température de référence
|
|
label_subtitle = Label(frame, text = 'Veuillez entrer la température de référence du point à vérifier :', font = ('Arial', 16), bg = '#19191a', fg = 'white')
|
|
label_subtitle.pack()
|
|
|
|
tempRef = DoubleVar()
|
|
tempRef.set(20)
|
|
entree = Entry(frame, textvariable = tempRef, width=15)
|
|
entree.pack()
|
|
|
|
##############################################################
|
|
# Résultat pour un point :
|
|
|
|
label_subtitle = Label(frame, text="Votre consommation estimée en MW est de :", font = ('Arial', 16), bg = '#19191a', fg = 'white')
|
|
label_subtitle.pack()
|
|
|
|
# Zone d'affichage du résultat :
|
|
labelRep = Label(frame, text=" ", font = ("Arial", 18), bg = 'white', fg = 'red')
|
|
labelRep.pack(pady=10)
|
|
frame.pack(expand = YES, pady = 20)
|
|
|
|
|
|
|
|
##############################################################
|
|
# Zone de boutons pour lancer les calculs :
|
|
##############################################################
|
|
|
|
# lance le test
|
|
boutonTest = Button(window, text = 'Lancer le calcul pour le point saisi !', font = ("Arial", 18), bg = 'white', fg = 'blue', command = lancerTest)
|
|
boutonTest.pack(pady = 5)
|
|
|
|
# lance le test sur le fichier contenant plusieurs points
|
|
boutonTest = Button(window, text = 'Lancer le calcul sur le fichier contenant plusieurs points !', font = ("Arial", 18), bg = 'white', fg = 'blue', command = lancerTestsPlusieursPoints)
|
|
boutonTest.pack(pady = 5)
|
|
|
|
# bouton quitter
|
|
boutonLeave = Button(window, text = 'Quitter le logiciel', font = ("Arial", 15), bg = 'white', fg = '#19191a', command = window.destroy)
|
|
boutonLeave.pack(pady = 30)
|
|
|
|
|
|
window.mainloop()
|
|
##############################################################
|
|
# FIN D'IHM
|
|
##############################################################
|
|
|