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('C:/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('C:/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('C:/Users/sylva/Desktop/Documents/00 Mes documents/08 Loic/Lycée/1G1/NSI/projet knn puissance electrique/DEV/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 ##############################################################