Browse Source

interface fonctionnelle ; correction d'erreurs dans knn

master
bollet.c 4 months ago
parent
commit
0081543cfb
  1. 66
      ihm.py
  2. 8
      knn.py
  3. 12
      lecture.py
  4. 148
      selection.py
  5. 11
      test.py

66
ihm.py

@ -1,46 +1,76 @@
import tkinter as tk import tkinter as tk
from test import lancerTest from test import lancerTest
from tkinter import ttk
from selection import DateSelection, TemperatureSelection, VoisinSelection
class Interface(tk.Frame): class Interface(tk.Frame):
def __init__(self, master): def __init__(self, master):
"""initialisation de l'interface""" """initialisation de l'interface"""
self.master = master self.master = master
tk.Frame.__init__(self, master) tk.Frame.__init__(self, master)
self.create_menu_bar() self.create_menu_bar()
self.tabs = ttk.Notebook(self.master)
self.create_tabs()
nb_voisins_proches = tk.Entry(self.master)
nb_voisins_proches.pack(fill="both")
btn_entrer = tk.Button(frame_saisie, text='entrer')
btn_entrer.pack()
def create_menu_bar(self): def create_menu_bar(self):
"""crée la barre de menu""" """crée la barre de menu"""
menu_bar = tk.Menu(self) menu_bar = tk.Menu(self)
menu_file = tk.Menu(menu_bar, tearoff=0) menu_file = tk.Menu(menu_bar, tearoff=0)
menu_file.add_command(label="Quitter", command=self.master.destroy) menu_file.add_command(label="Quitter", command=self.master.destroy)
menu_bar.add_cascade(label="Fichier", menu=menu_file) menu_bar.add_cascade(label="Fichier", menu=menu_file)
menu_affichage = tk.Menu(menu_bar, tearoff=0) self.master['menu']=menu_bar
menu_mode = tk.Menu(menu_bar, tearoff=0) def create_tabs(self):
menu_affichage.add_command(label="préfixe (polonaise)") """crée les onglets et les widgets à l'intérieur"""
menu_affichage.add_command(label="infixe")
menu_mode.add_command(label="mode interactif") tabAccueil = tk.Frame(self.tabs)
menu_mode.add_command(label="mode expression") tabTest = tk.Frame(self.tabs)
menu_affichage.add_cascade(label="postfixe (polonaise inversée)", menu=menu_mode) tabRes = tk.Frame(self.tabs)
menu_bar.add_cascade(label="Notation", menu=menu_affichage) self.tabs.add(tabAccueil, text="Accueil")
self.tabs.add(tabTest, text="Données")
self.tabs.add(tabRes, text="Résultats")
self.tabs.pack(expand=1, fill='both')
#accueil
tk.Label(tabAccueil, text="Vizion", font=("Magneto", 70)).pack()
tk.Label(tabAccueil, text="Aɴᴀʟʏsᴇs - Pʀᴇᴅɪᴄᴛɪᴏɴs", font=("arial", 10)).pack()
menu_help = tk.Menu(menu_bar, tearoff=0) tk.Button(tabAccueil, text='Commencer un nouveau test', padx=10, pady=10, command=lambda :self.tabs.select(tabTest)).pack(pady=50)
menu_help.add_command(label="Aide") #test
menu_help.add_command(label="À propos") self.nb_voisins_proches = VoisinSelection(tabTest)
menu_bar.add_cascade(label="Aide", menu=menu_help)
self.master['menu']=menu_bar param = tk.LabelFrame(tabTest, text="Paramètres", padx=20, pady=20)
param.pack()
self.choix_date = DateSelection(param)
self.choix_temp_moy = TemperatureSelection(param, "Température moyenne")
self.choix_temp_ref = TemperatureSelection(param, "Température de référence")
btn_entrer = tk.Button(tabTest, text='Tester', command=lambda : self.affResTest(tabRes))
btn_entrer.pack()
#res
tk.Label(tabRes, text="Résultat", font=(42)).pack()
self.affichage_resultats = tk.Label(tabRes, text="", font=("Courier", 15))
self.affichage_resultats.pack()
def affResTest(self, tab):
"""affiche le résultat du test dans le label
self.affichage_resultats dans l'onglet TabRes"""
k = self.nb_voisins_proches.get()
date_choisie = self.choix_date.get()
temperature_moyenne = self.choix_temp_moy.get()
temperature_ref = self.choix_temp_ref.get()
res = str(lancerTest(k, (date_choisie, temperature_moyenne, temperature_ref)))
self.affichage_resultats['text'] = "La consommation électrique \nprévue est de " + res + " MW."
self.tabs.select(tab)
if __name__ == "__main__": if __name__ == "__main__":
root = tk.Tk() root = tk.Tk()

8
knn.py

@ -12,6 +12,7 @@ def distance(point1, point2):
(Date du jour, Température moyenne, température de référence) (Date du jour, Température moyenne, température de référence)
et qui renvoie un nombre réel représentant et qui renvoie un nombre réel représentant
la distance euclidienne au carré entre ces deux points""" la distance euclidienne au carré entre ces deux points"""
duree = ecartDate(point1[0], point2[0]) duree = ecartDate(point1[0], point2[0])
delta_T_moy = (point1[1]-point2[1])**2 delta_T_moy = (point1[1]-point2[1])**2
delta_T_ref = (point1[2]-point2[2])**2 delta_T_ref = (point1[2]-point2[2])**2
@ -25,8 +26,9 @@ def kPlusProches(point_a_verifier, tableau, k):
et un tableau au format (Numéro du jour, Température moyenne, Température de référence). et un tableau au format (Numéro du jour, Température moyenne, Température de référence).
Renvoie un tableau trié avec les k plus proches Renvoie un tableau trié avec les k plus proches
points de `point_a_verifier`, au format (distance, indice du tableau original)""" points de `point_a_verifier`, au format (distance, indice du tableau original)"""
dist = [] dist = []
for i, point in enumerate(tableau): for i, point in enumerate(tableau):
dist.append(distance(point_a_verifier, point), i) dist.append((distance(point_a_verifier, point[0]), i))
sorted(dist, key=lambda t: t[0]) dist = sorted(dist, key=lambda t: t[0])
return dist[:k+1] return dist[:k]

12
lecture.py

@ -3,10 +3,18 @@ import csv
def lecture(fichier): def lecture(fichier):
"""renvoie tableau pour """renvoie tableau pour
traitement par d'autres programmes""" traitement par d'autres programmes"""
tableau = [] tableau = []
with open(fichier, newline='') as csvfile: with open(fichier, newline='') as csvfile:
lecteur = csv.reader(csvfile) lecteur = csv.reader(csvfile)
next(lecteur)
for ligne in lecteur: for ligne in lecteur:
tableau.append([(ligne[0], ligne[2], ligne[3]), ligne[1]]) date = ligne[0]
return tableau[1:] pic_journalier_consommation = float(ligne[1])
temperature_moyenne = float(ligne[2])
temperature_reference = float(ligne[3])
tableau.append([(date, temperature_moyenne, temperature_reference), \
pic_journalier_consommation])
return tableau

148
selection.py

@ -0,0 +1,148 @@
import tkinter as tk
from datetime import date
from tkinter import messagebox
class DateSelection:
def __init__(self, master):
"""initialise le widget"""
self.master = master
self.value = "0001-01-01"
frame_btn_date = tk.LabelFrame(self.master, text="Date", font=(25), fg="gray")
frame_btn_date.pack()
self.button = tk.Button(frame_btn_date, text="Choisir une date", command=self.select)
self.button.pack(padx=10, pady=2, side="left")
self.aff_date = tk.Label(frame_btn_date, text=self.value, padx=10, pady=2, font=(25), fg="gray")
self.aff_date.pack(padx=10, pady=2, side="left")
def select(self):
"""permet de choisir une date au format isoformat"""
self.popup = tk.Toplevel(padx=15, pady=15)
self.popup.wm_title("Veuillez choisir une date")
frame_choix = tk.LabelFrame(self.popup, text="jour / mois / année", font=(50), fg="gray")
frame_choix.pack()
self.jour = tk.Spinbox(frame_choix, from_=1, to=31, font=(100), width=2)
self.jour.pack(side="left", padx=10, pady=10)
tk.Label(frame_choix, text="/", font=(100)).pack(side="left")
self.mois = tk.Spinbox(frame_choix, from_=1, to=12, font=(100), width=2)
self.mois.pack(side="left", padx=10, pady=10)
tk.Label(frame_choix, text="/", font=(100)).pack(side="left")
self.annee = tk.Spinbox(frame_choix, from_=1, to=9999, font=(100), width=4)
self.annee.pack(side="left", padx=10, pady=10)
ok_btn = tk.Button(self.popup, text="OK", command=self.update)
ok_btn.pack()
def update(self):
"""assigne la date choisie (si elle est valide) à self.valeur,
sinon, ne change rien"""
val = self.format2iso()
if self.est_valide(val):
self.value = val
self.aff_date['text'] = self.value
self.popup.destroy()
else:
messagebox.showerror("Erreur", "La date n'est pas valide")
def format2iso(self):
"""renvoie une chaine de caractère avec
la date au format iso"""
aaaa = "0"*(4-len(self.annee.get())) + self.annee.get()
mm = "0"*(2-len(self.mois.get())) + self.mois.get()
jj = "0"*(2-len(self.jour.get())) + self.jour.get()
res = aaaa + "-" + mm + "-" + jj
return res
def est_valide(self, d):
"""renvoie True si la date d est valide,
False sinon"""
try:
date.fromisoformat(d)
return True
except ValueError:
return False
def get(self):
"""renvoie la date choisie"""
return self.value
class TemperatureSelection:
def __init__(self, master, nom):
"""initialise le widget"""
self.master = master
self.value = 0
frame_choix = tk.LabelFrame(self.master, text=nom, font=(25), fg="gray")
frame_choix.pack()
self.choix_tmp = tk.Entry(frame_choix, fg="black")
self.choix_tmp.insert("end", self.value)
self.choix_tmp.pack(side="left", padx=(10,5), pady=10)
self.choix_tmp.bind("<KeyRelease>", lambda e : self.isCorrect())
tk.Label(frame_choix, text="°C", font=(50), fg="gray").pack(side="left")
def isCorrect(self):
"""vérifie que la température entrée est correcte"""
val = self.choix_tmp.get()
if is_float(val) and float(val) > -273.15:
self.choix_tmp['bg'] = 'lightgreen'
self.choix_tmp['fg'] = 'black'
return True
else:
self.choix_tmp['bg'] = 'red'
self.choix_tmp['fg'] = 'white'
return False
def get(self):
"""renvoie la température choisie"""
if self.isCorrect():
return float(self.choix_tmp.get())
else:
return 0 #valeur par défaut
class VoisinSelection:
def __init__(self, master):
"""initialise le widget"""
self.master = master
frame_choix = tk.LabelFrame(self.master, text="Nombre de voisins (k)", font=(25), fg="gray")
frame_choix.pack()
self.choix_k = tk.Entry(frame_choix, font=(100), width=3)
self.choix_k.insert("end", "1")
self.choix_k.pack(pady=10)
def get(self):
"""renvoie le nombre de voisins"""
c = self.choix_k.get()
return int(c) if c.isdigit() and int(c) != 0 else 1
#fonction axiliaire
def is_float(element):
if element is None:
return False
try:
float(element)
return True
except ValueError:
return False

11
test.py

@ -3,9 +3,16 @@ from lecture import lecture
def lancerTest(nombre_voisins, point_a_verifier): def lancerTest(nombre_voisins, point_a_verifier):
"""effectue prédiction""" """effectue prédiction"""
fichier_apprentissage = lecture("data/pic-journalier-consommation.csv") fichier_apprentissage = lecture("data/pic-journalier-consommation.csv")
k_plus_proches = kPlusProches(point_a_verifier, \ k_plus_proches = kPlusProches(point_a_verifier, \
fichier_apprentissage, \ fichier_apprentissage, \
nombre_voisins) nombre_voisins)
conso_prevue = sum(k_plus_proches) / len(k_plus_proches)
return conso_prevue conso_prevue = 0
liste_indices = [elem[1] for elem in k_plus_proches]
for indice in liste_indices:
pic_conso = fichier_apprentissage[indice][1]
conso_prevue += pic_conso
return conso_prevue / len(k_plus_proches)

Loading…
Cancel
Save