diff --git a/ihm.py b/ihm.py index f16491d..99d3921 100644 --- a/ihm.py +++ b/ihm.py @@ -1,46 +1,76 @@ import tkinter as tk from test import lancerTest +from tkinter import ttk +from selection import DateSelection, TemperatureSelection, VoisinSelection class Interface(tk.Frame): def __init__(self, master): """initialisation de l'interface""" + self.master = master tk.Frame.__init__(self, master) 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): """crée la barre de menu""" + menu_bar = tk.Menu(self) menu_file = tk.Menu(menu_bar, tearoff=0) menu_file.add_command(label="Quitter", command=self.master.destroy) menu_bar.add_cascade(label="Fichier", menu=menu_file) - menu_affichage = tk.Menu(menu_bar, tearoff=0) + self.master['menu']=menu_bar + + def create_tabs(self): + """crée les onglets et les widgets à l'intérieur""" - menu_mode = tk.Menu(menu_bar, tearoff=0) - menu_affichage.add_command(label="préfixe (polonaise)") - menu_affichage.add_command(label="infixe") + tabAccueil = tk.Frame(self.tabs) + tabTest = tk.Frame(self.tabs) + tabRes = tk.Frame(self.tabs) + 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_mode.add_command(label="mode interactif") - menu_mode.add_command(label="mode expression") - menu_affichage.add_cascade(label="postfixe (polonaise inversée)", menu=menu_mode) - menu_bar.add_cascade(label="Notation", menu=menu_affichage) - - menu_help = tk.Menu(menu_bar, tearoff=0) - menu_help.add_command(label="Aide") - menu_help.add_command(label="À propos") - menu_bar.add_cascade(label="Aide", menu=menu_help) - - self.master['menu']=menu_bar + tk.Button(tabAccueil, text='Commencer un nouveau test', padx=10, pady=10, command=lambda :self.tabs.select(tabTest)).pack(pady=50) + #test + self.nb_voisins_proches = VoisinSelection(tabTest) + + 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__": root = tk.Tk() diff --git a/knn.py b/knn.py index 8c18f53..22e69c7 100644 --- a/knn.py +++ b/knn.py @@ -12,6 +12,7 @@ def distance(point1, point2): (Date du jour, Température moyenne, température de référence) et qui renvoie un nombre réel représentant la distance euclidienne au carré entre ces deux points""" + duree = ecartDate(point1[0], point2[0]) delta_T_moy = (point1[1]-point2[1])**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). Renvoie un tableau trié avec les k plus proches points de `point_a_verifier`, au format (distance, indice du tableau original)""" + dist = [] for i, point in enumerate(tableau): - dist.append(distance(point_a_verifier, point), i) - sorted(dist, key=lambda t: t[0]) - return dist[:k+1] \ No newline at end of file + dist.append((distance(point_a_verifier, point[0]), i)) + dist = sorted(dist, key=lambda t: t[0]) + return dist[:k] \ No newline at end of file diff --git a/lecture.py b/lecture.py index e5e56d5..f2bb1b6 100644 --- a/lecture.py +++ b/lecture.py @@ -3,10 +3,18 @@ import csv def lecture(fichier): """renvoie tableau pour traitement par d'autres programmes""" + tableau = [] with open(fichier, newline='') as csvfile: lecteur = csv.reader(csvfile) + next(lecteur) for ligne in lecteur: - tableau.append([(ligne[0], ligne[2], ligne[3]), ligne[1]]) - return tableau[1:] + date = ligne[0] + 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 diff --git a/selection.py b/selection.py new file mode 100644 index 0000000..698632a --- /dev/null +++ b/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("", 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 + + \ No newline at end of file diff --git a/test.py b/test.py index baf69f6..c789ac5 100644 --- a/test.py +++ b/test.py @@ -3,9 +3,16 @@ from lecture import lecture def lancerTest(nombre_voisins, point_a_verifier): """effectue prédiction""" + fichier_apprentissage = lecture("data/pic-journalier-consommation.csv") k_plus_proches = kPlusProches(point_a_verifier, \ fichier_apprentissage, \ nombre_voisins) - conso_prevue = sum(k_plus_proches) / len(k_plus_proches) - return conso_prevue \ No newline at end of file + + 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) +