import tkinter as tk from math import sqrt def transfoEnFloat(groupe): """Prend en parametre un tuple ou une liste de réels de type str et renvoie une liste de réels de type float""" lst = [] for element in groupe: lst.append(float(element)) return lst def lecture(nomFichier): """Prend en parametre le nom du fichier csv à lire et renvoie un tableau.""" with open(nomFichier, 'r') as fichier: fichier_nettoye = [] tableau = [] for ligne in fichier: fichier_nettoye.append(ligne.strip()) for donnees in fichier_nettoye: tableau.append(tuple(donnees.split(","))) return tableau def estBissextile(annee): """prend en compte une annee à verifier si elle est bissextile et renvoie True si elle l'est et False sinon""" return annee%4 == 0 and annee%100 != 0 or annee%400 == 0 def numeroJour(date): """Prend en parametre une date au format aaaa-mm-jj et renvoie un entier correspondant au numero du jour correspondant (de 1 à 365)""" dateSeparee = transfoEnFloat(date.split('-')) totalJours = 0 JoursMois = [31,28,30,31,30,31,31,30,31,30,31] #Nombre de jours de chaques mois for i in range(int(dateSeparee[1])-1): totalJours += JoursMois[i] if estBissextile(dateSeparee[0]) and totalJours + dateSeparee[2] >= 60 and dateSeparee[1] > 2: #regarde si on est dans une année bissextile et apres fevrier totalJours += 1 return totalJours + dateSeparee[2] def distance(Tuple1 , Tuple2): """prend en parametre 2 tuples avec (Numéro du jour, Température moyenne, température de référence) et renvoie la distance **euclidienne**""" lst1 = transfoEnFloat(Tuple1) lst2 = transfoEnFloat(Tuple2) minJours = min([lst1[0],lst2[0]]) maxJours = max([lst1[0],lst2[0]]) DiffJours = min([maxJours-minJours,365-maxJours+minJours]) return sqrt(DiffJours**2 + (lst1[1]-lst2[1])**2+(lst1[2]-lst2[2])**2) def kPlusProches(point,lstRepre,k): #je ne sais pas si il faut mettre k ce n'est pas demandé dans l'ennoncé mais cela ne servirait à rien d'en mettre plus """Prend en parametre un tuple avec (Numéro du jour, Température moyenne, température de référence) correspondant au point à verifier, une liste de tuples de meme type et la consommation electrique Renvoie une liste triée en fonction de la distance avec le tuple dont les elements sont des tuple avec (distance, indice du tableau original)""" lstvoisins = [] if k > len(lstRepre): k = len(lstRepre) for i in range(len(lstRepre)): d = distance(point,lstRepre[i]) lstvoisins.append((d,i)) lstvoisins.sort() return [lstvoisins[i] for i in range(k)] def puissanceMoyenne(listeTriee, tableau): """Prend une liste triée de tuple avec (distance, indice du tableau initial) et un tableau de donnée et renvoie la moyenne de la puissance electrique des k plus proches voisins""" PuissanceTotale = 0.0 for donnee in listeTriee: distance,indice = donnee PuissanceTotale += float(tableau[indice][1]) return PuissanceTotale/len(listeTriee) def listeTuples(fichier): """Prend une liste de tuples de type (date,pic journalier consommation, temperature moyenne, temperature reference) et renvoie une liste de tuples de type (numero jour, temperature moyenne, temperature de reference)""" tableau = [] for i in range(1,len(fichier)): date, picJournalier, tempMoy, tempRef = fichier[i] tableau.append((numeroJour(date),tempMoy,tempRef)) return tableau def lancerTest(): """Utilise les valeurs données par l'utilisateur et le fichier pic journaliser pour afficher la moyenne de consommation electrique""" nombreK = int(valeurk.get()) date = numeroJour(valeurdate.get()) temp = valeurtemp.get().split(" ") temp = transfoEnFloat(temp) tempMoy, tempRef = temp fichier = lecture('pic-journalier-consommation-brute-2023.csv') listeVoisins = kPlusProches((date,tempMoy,tempRef),(listeTuples(fichier)), nombreK) listeVoisins ConsoMoy = round(puissanceMoyenne(listeVoisins,fichier),2) affichageResultats.configure(text="La consommation électrique devrait être d'environ " + str(ConsoMoy) +"MW") fenetre = tk.Tk() fenetre['bg'] = "lavender" fenetre.title("Outil de prévision énergétique") fenetre.geometry('357x236') fenetre.resizable(False,False) #Un truc comme gestionnaire du transport d'electricité non ? ou je pense que sur tkinter tu peux faire disparaitre #le dessus (mais faut rajouter un bouton pour fermer la fenetre et tout c'est galere) canva = tk.Canvas(fenetre, bg = "lavender", highlightthickness = 0, width = 10, height = 13.5) canva.grid() # Boutons valeur de k valeurk = tk.StringVar() labelk = tk.Label(fenetre, text = "choisir le nombre de k plus proches voisin voulus : ", width = 50, bg = "lavender") labelk.grid(row = 1, column = 0) entreek = tk.Entry(fenetre, textvariable = valeurk, width = 30) entreek.grid(row = 2, column = 0) # Boutons date canvadate = tk.Canvas(fenetre, bg = "lavender", width = 350, height = 20, highlightthickness = 0) canvadate.create_line(0, 10, 350, 10, fill = "black") canvadate.grid(row = 3) valeurdate = tk.StringVar() labeldate = tk.Label(fenetre, text = "choisir la date au format aaaa-mm-jj : ", width = 50, bg = "lavender") labeldate.grid(row = 4, column = 0) entreedate=tk.Entry(fenetre, textvariable = valeurdate, width = 30) entreedate.grid(row = 5, column = 0) # Boutons température canvatemp = tk.Canvas(fenetre, bg = "lavender", width = 350, height = 20, highlightthickness = 0) canvatemp.create_line(0, 10, 350, 10, fill = "black") canvatemp.grid(row = 6) valeurtemp = tk.StringVar() labeltemp = tk.Label(fenetre, text = "La température moyenne et de référence avec un espace: ", width = 50, bg = "lavender") labeltemp.grid(row = 7, column = 0) entreetemp=tk.Entry(fenetre, textvariable = valeurtemp, width = 30) entreetemp.grid(row = 8, column = 0) canvaRecup = tk.Canvas(fenetre, bg='lavender', width = 1, height = 10, highlightthickness = 0) canvaRecup.grid(row = 9) boutonRecup = tk.Button(fenetre, command = lancerTest, bg = 'lavender',text='Valider', cursor='hand2') boutonRecup.grid(row = 10) affichageResultats = tk.Label(fenetre, bg='lavender', text='',font='TkDefaultFont 8 bold') #J'ai du chercher parce qu'on ne peut affichageResultats.grid() fenetre.mainloop()