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.
181 lines
7.7 KiB
181 lines
7.7 KiB
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 i in range(1,len(fichier_nettoye)):
|
|
tableau.append(tuple(fichier_nettoye[i].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 distanceEuclidienne(Tuple1 , Tuple2):
|
|
"""prend en parametre 2 tuples avec (Numéro du jour, Valeur1, Valeur2)
|
|
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 distanceManhattan(Tuple1, Tuple2):
|
|
"""prend en parametre 2 tuples avec (numero du jour, Valeur1, Valeur2)
|
|
et renvoie la distance de manhattan"""
|
|
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 DiffJours + abs(lst1[1]-lst2[1]) + abs(lst1[2]-lst2[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)):
|
|
if boolDistanceDeManhattan:
|
|
d = distanceManhattan(point,lstRepre[i])
|
|
else:
|
|
d = distanceEuclidienne(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][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)
|
|
ConsoMoy = round(puissanceMoyenne(listeVoisins,fichier),2)
|
|
affichageResultats.configure(text="La consommation électrique devrait être d'environ " + str(ConsoMoy) +"MW")
|
|
|
|
def changeDistance():
|
|
global boolDistanceDeManhattan
|
|
if boolDistanceDeManhattan:
|
|
boutonDistance.config(text='Distance de Manhattan')
|
|
else:
|
|
boutonDistance.config(text='Distance euclidienne')
|
|
boolDistanceDeManhattan = not boolDistanceDeManhattan
|
|
|
|
boolDistanceDeManhattan = False
|
|
|
|
fenetre = tk.Tk()
|
|
fenetre['bg'] = "snow"
|
|
fenetre.title("Outil de prévision énergétique")
|
|
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 = "snow", highlightthickness = 0, width = 10,
|
|
height = 13.5)
|
|
canva.grid( columnspan = 2)
|
|
# Boutons valeur de k
|
|
valeurk = tk.StringVar()
|
|
labelk = tk.Label(fenetre, text = "choisir le nombre de k plus proches voisin voulus : ",
|
|
width = 50, bg = "snow")
|
|
labelk.grid(row = 1, column = 0, columnspan = 2)
|
|
entreek = tk.Entry(fenetre, textvariable = valeurk, width = 30)
|
|
entreek.grid(row = 2, column = 0, columnspan = 2)
|
|
|
|
# Boutons date
|
|
canvadate = tk.Canvas(fenetre, bg = "snow", width = 350, height = 20,
|
|
highlightthickness = 0)
|
|
canvadate.create_line(0, 10, 350, 10, fill = "black")
|
|
canvadate.grid(row = 3, columnspan = 2)
|
|
valeurdate = tk.StringVar()
|
|
labeldate = tk.Label(fenetre, text = "choisir la date (au format aaaa-mm-jj) : ", width = 50, bg = "snow")
|
|
labeldate.grid(row = 4, column = 0, columnspan = 2)
|
|
entreedate=tk.Entry(fenetre, textvariable = valeurdate, width = 30)
|
|
entreedate.grid(row = 5, column = 0, columnspan = 2)
|
|
|
|
# Boutons température
|
|
canvatemp = tk.Canvas(fenetre, bg = "snow", width = 350, height = 20,
|
|
highlightthickness = 0)
|
|
canvatemp.create_line(0, 10, 350, 10, fill = "black")
|
|
canvatemp.grid(row = 6, columnspan = 2)
|
|
valeurtemp = tk.StringVar()
|
|
labeltemp = tk.Label(fenetre, text = "La température moyenne et de référence (avec un espace) : ",
|
|
width = 50, bg = "snow")
|
|
labeltemp.grid(row = 7, column = 0, columnspan = 2)
|
|
entreetemp=tk.Entry(fenetre, textvariable = valeurtemp, width = 30)
|
|
entreetemp.grid(row = 8, column = 0, columnspan = 2)
|
|
|
|
canvaRecup = tk.Canvas(fenetre, bg='snow', width = 1, height = 10, highlightthickness = 0)
|
|
canvaRecup.grid(row = 9, columnspan = 2)
|
|
|
|
labeldistance = tk.Label(fenetre, text = "choisir le mode de distance voulu :", bg = "snow")
|
|
labeldistance.grid(row = 10)
|
|
|
|
boutonRecup = tk.Button(fenetre, command = lancerTest, bg = 'snow',text='Valider',
|
|
cursor='hand2')
|
|
boutonRecup.grid(row = 11,column = 1)
|
|
|
|
boutonDistance = tk.Button(fenetre, command = changeDistance, text="Distance de Manhattan"
|
|
,bg='snow',cursor='hand2')
|
|
boutonDistance.grid(row=11, column=0)
|
|
|
|
affichageResultats = tk.Label(fenetre, bg='snow', text='',font='TkDefaultFont 8 bold') #J'ai du chercher parce qu'on ne peut
|
|
affichageResultats.grid(row=12)
|
|
|
|
fenetre.mainloop()
|