Dernier projet de l'année 2022.
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

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
##############################################################