import pandas as pd # Importa la libreria pandas per la gestione dei dati.
import numpy as np # Importa la libreria numpy per operazioni numeriche.
from sklearn.model_selection import KFold # Importa KFold per la validazione incrociata.
from sklearn.preprocessing import MinMaxScaler # Importa MinMaxScaler per la normalizzazione dei dati.
import tensorflow as tf # Importa tensorflow per la costruzione del modello di rete neurale.
from tensorflow.keras.models import Sequential # Importa Sequential per la costruzione del modello sequenziale.
from tensorflow.keras.layers import Dense, Dropout, BatchNormalization # Importa le classi di layer.
from tensorflow.keras.callbacks import EarlyStopping # Importa EarlyStopping per l'arresto anticipato.
import tkinter as tk # Importa tkinter per l'interfaccia grafica.
from tkinter import messagebox, ttk, scrolledtext, filedialog # Importa messagebox e ttk per widget specifici.
import os # Importa os per interazioni con il sistema operativo.
import random # Importa random per generare numeri casuali.
import matplotlib.pyplot as plt # Importa matplotlib per la visualizzazione dei grafici.
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # Importa FigureCanvasTkAgg per integrare matplotlib con tkinter.
import logging # Importa logging per il logging degli eventi.
import requests # Importa requests per effettuare richieste HTTP.
from io import StringIO # Importa StringIO per la gestione di stringhe come file.
import time # Importa time per la gestione del tempo.
# Configurazione del logger
logger = logging.getLogger(__name__) # Ottiene un logger con il nome del modulo.
logger.setLevel(logging.INFO) # Imposta il livello di logging a INFO.
# Crea un handler per il box di testo
class TextHandler(logging.Handler): # Definisce una classe per gestire il logging nel box di testo.
def __init__(self, text_widget): # Costruttore della classe.
logging.Handler.__init__(self) # Chiama il costruttore della classe base.
self.text_widget = text_widget # Memorizza il widget di testo.
def emit(self, record): # Metodo per emettere un messaggio di log.
msg = self.format(record) # Formatta il record di log.
self.text_widget.config(state=tk.NORMAL) # Abilita la modifica del widget di testo.
self.text_widget.insert(tk.END, msg + '\n') # Inserisce il messaggio di log.
self.text_widget.config(state=tk.DISABLED) # Disabilita la modifica del widget di testo.
self.text_widget.see(tk.END) # Fa scorrere il widget di testo fino alla fine.
# Imposta il seme per la riproducibilità
def set_seed(seed_value=42): # Definisce una funzione per impostare il seme per la riproducibilità.
os.environ['PYTHONHASHSEED'] = str(seed_value) # Imposta una variabile d'ambiente per il seme di hash.
random.seed(seed_value) # Imposta il seme per il generatore di numeri casuali di Python.
np.random.seed(seed_value) # Imposta il seme per il generatore di numeri casuali di numpy.
tf.random.set_seed(seed_value) # Imposta il seme per il generatore di numeri casuali di tensorflow.
set_seed() # Chiama la funzione per impostare il seme.
# Definizione dei link delle ruote
file_ruote = { # Definisce un dizionario con i link dei file delle ruote.
'BA': 'https://raw.githubusercontent.com/Lottopython/estrazioni/refs/heads/main/BARI.txt', # Link per BARI.
'CA': 'https://raw.githubusercontent.com/Lottopython/estrazioni/refs/heads/main/CAGLIARI.txt', # Link per CAGLIARI.
'FI': 'https://raw.githubusercontent.com/Lottopython/estrazioni/refs/heads/main/FIRENZE.txt', # Link per FIRENZE.
'GE': 'https://raw.githubusercontent.com/Lottopython/estrazioni/refs/heads/main/GENOVA.txt', # Link per GENOVA.
'MI': 'https://raw.githubusercontent.com/Lottopython/estrazioni/refs/heads/main/MILANO.txt', # Link per MILANO.
'NA': 'https://raw.githubusercontent.com/Lottopython/estrazioni/refs/heads/main/NAPOLI.txt', # Link per NAPOLI.
'PA': 'https://raw.githubusercontent.com/Lottopython/estrazioni/refs/heads/main/PALERMO.txt', # Link per PALERMO.
'RM': 'https://raw.githubusercontent.com/Lottopython/estrazioni/refs/heads/main/ROMA.txt', # Link per ROMA.
'TO': 'https://raw.githubusercontent.com/Lottopython/estrazioni/refs/heads/main/TORINO.txt', # Link per TORINO.
'VE': 'https://raw.githubusercontent.com/Lottopython/estrazioni/refs/heads/main/VENEZIA.txt', # Link per VENEZIA.
'NZ': 'https://raw.githubusercontent.com/Lottopython/estrazioni/refs/heads/main/NAZIONALE.txt' # Link per NAZIONALE.
}
# Funzione per caricare i dati della ruota selezionata
def carica_dati(ruota, start_date=None, end_date=None): # Definisce una funzione per caricare i dati.
file_name = file_ruote.get(ruota) # Ottiene il nome del file dalla ruota.
if not file_name: # Se il nome del file non esiste.
logger.error("Ruota non trovata.") # Logga un errore.
messagebox.showerror("Errore", "Ruota non trovata.") # Mostra un messaggio di errore.
return None, None, None, None # Restituisce None.
try: # Inizia un blocco try-except per la gestione degli errori.
response = requests.get(file_name) # Effettua una richiesta GET al link.
response.raise_for_status() # Solleva un'eccezione per errori HTTP.
data = pd.read_csv(StringIO(response.text), header=None, sep="\t", encoding='utf-8') # Legge i dati CSV.
data.iloc[:, 0] = pd.to_datetime(data.iloc[:, 0], format='%Y/%m/%d') # Converte la prima colonna in datetime.
if start_date and end_date: # Se sono state specificate date di inizio e fine.
mask = (data.iloc[:, 0] >= start_date) & (data.iloc[:, 0] <= end_date) # Crea una maschera per filtrare i dati.
data = data.loc[mask] # Applica la maschera ai dati.
if data.empty: # Se i dati sono vuoti.
logger.error("Nessun dato trovato nell'intervallo di date specificato.") # Logga un errore.
messagebox.showerror("Errore", "Nessun dato trovato nell'intervallo di date specificato. Controlla le date di inizio e fine.") # Mostra un messaggio di errore.
return None, None, None, None # Restituisce None.
numeri = data.iloc[:, 2:].values # Estrae i numeri dalle colonne.
if numeri.size == 0: # Se non ci sono numeri.
logger.error("Nessun numero trovato nel file.") # Logga un errore.
return None, None, None, None # Restituisce None.
scaler = MinMaxScaler(feature_range=(0, 1)) # Crea un oggetto MinMaxScaler.
numeri_normalizzati = scaler.fit_transform(numeri.astype(float)) # Normalizza i numeri.
X = numeri_normalizzati[:-1] # Crea i dati di input (X).
y = numeri[:-1] # Crea i dati di output (y).
return X, y, scaler, data # Restituisce X, y, scaler e data.
except requests.exceptions.RequestException as e: # Cattura le eccezioni di richiesta.
logger.error(f"Errore durante il download dei dati dal link: {e}") # Logga un errore.
messagebox.showerror("Errore", f"Errore nel download dei dati dal link: {e}") # Mostra un messaggio di errore.
return None, None, None, None # Restituisce None.
except Exception as e: # Cattura tutte le altre eccezioni.
logger.error(f"Errore durante il caricamento dei dati: {e}") # Logga un errore.
messagebox.showerror("Errore", f"Errore durante il caricamento dei dati: {e}") # Mostra un messaggio di errore.
return None, None, None, None # Restituisce None.
# Funzione di attivazione Swish
def swish(x): # Definisce la funzione di attivazione Swish.
return x * tf.keras.backend.sigmoid(x) # Calcola e restituisce il valore di Swish.
# Variabili globali
optimizer_choice = None # Inizializza la variabile per la scelta dell'ottimizzatore.
loss_function_choice = None # Inizializza la variabile per la scelta della funzione di perdita.
patience = 10 # Imposta il valore di patience per EarlyStopping.
min_delta = 0.01 # Imposta il valore di min_delta per EarlyStopping.
progress_bar = None # Inizializza la variabile per la barra di avanzamento.
fig = None # Inizializza la variabile per la figura del grafico.
ax = None # Inizializza la variabile per l'asse del grafico.
pulsanti_ruote = {} # Inizializza il dizionario per i pulsanti delle ruote
entry_info = None # Inizializza la variabile per il campo di input info
textbox = None # Inizializza la variabile per il textbox di output
# Funzione per costruire il modello
def build_model(X_shape, y_shape, dense_layers, dropout_rates): # Definisce la funzione per costruire il modello.
model = Sequential() # Crea un modello sequenziale.
model.add(tf.keras.Input(shape=(X_shape,))) # Aggiunge un layer di input.
for i, (neurons, dropout) in enumerate(zip(dense_layers, dropout_rates)): # Itera sui layer densi e sui dropout.
logger.info(f"Layer {i+1}: Neuroni = {neurons}, Dropout = {dropout}") # Logga le informazioni sul layer.
for neurons, dropout in zip(dense_layers, dropout_rates): # Itera sui layer densi e sui dropout.
model.add(Dense(neurons, activation=swish)) # Aggiunge un layer denso con attivazione Swish.
model.add(BatchNormalization()) # Aggiunge un layer di BatchNormalization.
model.add(Dropout(dropout)) # Aggiunge un layer di Dropout.
model.add(Dense(y_shape, activation=tf.keras.activations.relu)) # Aggiunge un layer denso di output.
return model # Restituisce il modello.
# Funzione per calcolare la prevedibilità delle ruote
def calcola_prevedibilita(history): # Definisce la funzione per calcolare la prevedibilità.
prevedibilita = {} # Inizializza un dizionario per la prevedibilità.
for ruota in history.keys(): # Itera sulle ruote.
data_perdita = history[ruota]['val_loss'] # Ottiene i dati di perdita di validazione.
if data_perdita: # Se ci sono dati di perdita.
prevedibilita[ruota] = np.mean(data_perdita) # Calcola la media della perdita.
else: # Altrimenti.
prevedibilita[ruota] = float('inf') # Imposta la prevedibilità a infinito.
return prevedibilita # Restituisce il dizionario della prevedibilità.
# Funzione per mostrare la prevedibilità delle ruote
def mostra_prevedibilita(prevedibilita): # Definisce la funzione per mostrare la prevedibilità.
for child in frame_prevedibilita.winfo_children(): # Itera sui figli del frame della prevedibilità.
child.destroy() # Distrugge i figli.
migliori_ruote = sorted(prevedibilita.items(), key=lambda x: x[1])[:2] # Ordina le ruote per prevedibilità.
ruote_string = ", ".join([ruota for ruota, _ in migliori_ruote]) # Crea una stringa con le migliori ruote.
textbox.insert(tk.END, f"Le migliori ruote per la previsione sono: {ruote_string}\n") # Inserisce il testo nel box di testo.
fig, ax = plt.subplots(figsize=(10, 5)) # Crea un grafico.
ax.bar(prevedibilita.keys(), prevedibilita.values()) # Crea un grafico a barre.
ax.set_title('Prevedibilità delle Ruote (media perdite)') # Imposta il titolo.
ax.set_xlabel('Ruota') # Imposta l'etichetta dell'asse x.
ax.set_ylabel('Prevedibilità (Media Perdita)') # Imposta l'etichetta dell'asse y.
ax.grid(True) # Aggiunge una griglia.
canvas = FigureCanvasTkAgg(fig, master=frame_prevedibilita) # Crea un canvas per il grafico.
canvas.draw() # Disegna il grafico.
canvas.get_tk_widget().pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # Inserisce il canvas nel frame.
# Funzione per aggiornare la barra di avanzamento e mostrare ogni selezione nel box di testo
def update_progress(value, max_value, text_to_append=None): # Definisce la funzione per aggiornare la barra di avanzamento.
if progress_bar: # Se la barra di avanzamento esiste.
progress_bar["maximum"] = max_value # Imposta il valore massimo della barra.
progress_bar["value"] = value # Imposta il valore corrente della barra.
root.update_idletasks() # Aggiorna l'interfaccia grafica.
if text_to_append and textbox: # Se c'è del testo da aggiungere e il textbox esiste.
textbox.insert(tk.END, text_to_append + "\n") # Inserisce il testo nel box di testo.
# Funzione per gestire la selezione della ruota
def on_seleziona_ruota(ruota): # Definisce la funzione per la selezione della ruota.
global optimizer_choice, loss_function_choice, progress_bar, fig, ax # Dichiara le variabili globali.
start_date_str = entry_start_date.get() # Ottiene la data di inizio.
end_date_str = entry_end_date.get() # Ottiene la data di fine.
try: # Inizia un blocco try-except.
epochs = int(entry_epochs.get()) # Ottiene il numero di epoche.
dense_layers = [ # Ottiene i layer densi.
int(entry_neurons_layer1.get()),
int(entry_neurons_layer2.get()),
int(entry_neurons_layer3.get())
]
dropout_rates = [ # Ottiene i tassi di dropout.
float(entry_dropout_layer1.get()),
float(entry_dropout_layer2.get()),
float(entry_dropout_layer3.get())
]
except ValueError: # Cattura le eccezioni di valore.
messagebox.showerror("Errore", "Inserisci valori validi per epoche, neuroni o dropout.") # Mostra un messaggio di errore.
return # Esce dalla funzione.
try: # Inizia un blocco try-except.
start_date = pd.to_datetime(start_date_str, format='%Y/%m/%d') # Converte la data di inizio.
end_date = pd.to_datetime(end_date_str, format='%Y/%m/%d') # Converte la data di fine.
except ValueError: # Cattura le eccezioni di valore.
messagebox.showerror("Errore", "Formato data non valido. Usa YYYY/MM/DD.") # Mostra un messaggio di errore.
return # Esce dalla funzione.
X, y, scaler, data = carica_dati(ruota, start_date, end_date) # Carica i dati.
if X is None or y is None or scaler is None or data is None: # Se c'è un errore nel caricamento dei dati.
return # Esce dalla funzione.
if X.size <= 0 or y.size <= 0: # Se i dati sono vuoti.
messagebox.showerror("Errore", "I dati caricati non contengono informazioni sufficienti per l'addestramento.") # Mostra un messaggio di errore.
return # Esce dalla funzione.
for btn in pulsanti_ruote.values(): # Itera sui pulsanti delle ruote.
btn["bg"] = "SystemButtonFace" # Imposta il colore di sfondo.
pulsanti_ruote[ruota]["bg"] = "lightgreen" # Imposta il colore di sfondo del pulsante selezionato.
entry_info.delete(0, tk.END) # Cancella il testo nel campo di input.
entry_info.insert(0, f"Ruota: {ruota}, Periodo: {start_date.date()} - {end_date.date()}") # Inserisce il testo nel campo di input.
logger.info(f"Dimensione X: {X.shape}, Dimensione y: {y.shape}") # Logga le dimensioni dei dati.
k = min(5, len(X)) # Calcola il numero di fold per la validazione incrociata.
kf = KFold(n_splits=k, shuffle=True, random_state=42) # Crea un oggetto KFold.
# Mostra informazioni di caricamento
textbox.insert(tk.END, f"Caricamento dati per {ruota}...\n") # Inserisce il testo nel box di testo.
model = build_model(X.shape[1], y.shape[1], dense_layers, dropout_rates) # Costruisce il modello.
logger.info(f"Configurazione del Modello: Epoche = {epochs}, Ottimizzatore = {optimizer_choice}, Funzione di perdita = {loss_function_choice}") # Logga la configurazione del modello.
# Modifica qui per correggere l'errore di sintassi
if optimizer_choice == '1':
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
elif optimizer_choice == '2':
optimizer = tf.keras.optimizers.RMSprop(learning_rate=0.001)
else:
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
# Fine modifica
model.compile(optimizer=optimizer, loss=loss_function_choice, metrics=["mae"]) # Compila il modello.
all_hist_loss = [] # Inizializza la lista per la perdita.
all_hist_val_loss = [] # Inizializza la lista per la perdita di validazione.
history_per_ruota = {} # Inizializza il dizionario per la cronologia.
# Mostra informazioni di addestramento
textbox.insert(tk.END, f"Addestramento per {ruota}...\n") # Inserisce il testo nel box di testo.
progress_bar = ttk.Progressbar(root, orient="horizontal", length=200, mode="determinate", style="blue.Horizontal.TProgressbar") # Crea la barra di avanzamento.
progress_bar.pack(pady=10) # Inserisce la barra di avanzamento.
style = ttk.Style() # Crea un oggetto Style.
style.theme_use('clam') # Usa il tema clam.
style.configure("blue.Horizontal.TProgressbar", foreground='blue', background='lightblue') # Configura la barra di avanzamento.
style.map("blue.Horizontal.TProgressbar",
background=[('active', 'blue')])
fold_count = k # Ottiene il numero di fold.
epoch_count = epochs # Ottiene il numero di epoche.
total_steps = fold_count * epoch_count # Calcola il numero totale di passi.
current_step = 0 # Inizializza il passo corrente.
for train_index, test_index in kf.split(X): # Itera sui fold.
X_train, X_test = X[train_index], X[test_index] # Ottiene i dati di addestramento e test.
y_train, y_test = y[train_index], y[test_index]
noise = np.random.normal(0, 0.01 * np.abs(X_train), X_train.shape) # Aggiunge rumore ai dati di addestramento.
X_train_noisy = X_train + noise
early_stopping = EarlyStopping(monitor='val_loss', patience=patience, min_delta=min_delta, restore_best_weights=True) # Crea un oggetto EarlyStopping.
history = model.fit(X_train_noisy, y_train, epochs=epochs, batch_size=64, validation_data=(X_test, y_test),
callbacks=[early_stopping], verbose=0) # Addestra il modello.
all_hist_loss.append(history.history['loss']) # Aggiunge la perdita alla lista.
all_hist_val_loss.append(history.history['val_loss']) # Aggiunge la perdita di validazione alla lista.
history_per_ruota[ruota] = history.history # Memorizza la cronologia.
logger.info(f"Fine addestramento fold, Con perdita train: {history.history['loss'][-1]}, Val: {history.history['val_loss'][-1]}") # Logga la fine dell'addestramento.
current_step += epoch_count # Incrementa il passo corrente.
update_progress(current_step, total_steps, f"Addestramento completato {current_step}/{total_steps}") # Aggiorna la barra di avanzamento.
y_pred = model.predict(X_test[-len(X_test):]) # Effettua la predizione.
scaler_output = MinMaxScaler(feature_range=(1, 90)) # Crea un oggetto MinMaxScaler.
y_pred_scaled = scaler_output.fit_transform(y_pred) # Scala la predizione.
numeri_interi = np.round(y_pred_scaled).astype(int) # Arrotonda i numeri.
# Mostra informazioni di predizione
textbox.insert(tk.END, f"Predizione per {ruota}...\n") # Inserisce il testo nel box di testo.
update_textbox(numeri_interi) # Aggiorna il box di testo con i numeri predetti.
mostra_numeri_predetti(numeri_interi) # Mostra i numeri predetti.
mostra_migliori_risultati(history) # Mostra i migliori risultati.
prevedibilita = calcola_prevedibilita(history_per_ruota) # Calcola la prevedibilità.
mostra_prevedibilita(prevedibilita) # Mostra la prevedibilità.
mostra_grafico(all_hist_loss, all_hist_val_loss) # Mostra il grafico.
if 'history' in locals(): # Controlla se la variabile history esiste.
loss_to_val_loss_ratio = [val_train / val_val if val_val != 0 else float('inf') # Calcola il rapporto tra perdita e perdita di validazione.
for val_train, val_val in zip(history.history['loss'], history.history['val_loss'])]
min_ratio_epoch = np.argmin(loss_to_val_loss_ratio) # Trova l'epoca con il rapporto minimo.
plt.figure(figsize=(12, 6)) # Crea un grafico.
plt.plot(history.history['loss'], label='Loss Train') # Disegna la perdita di addestramento.
plt.plot(history.history['val_loss'], label='Loss Val') # Disegna la perdita di validazione.
plt.plot(loss_to_val_loss_ratio, label='Ratio Loss/Val') # Disegna il rapporto tra perdita e perdita di validazione.
plt.scatter(min_ratio_epoch, loss_to_val_loss_ratio[min_ratio_epoch],
label='Optimal Solution (Early Stopping)', color='red') # Disegna il punto ottimale.
plt.title('Andamento della Perdita durante l\'Addestramento e Rapporto') # Imposta il titolo del grafico.
plt.xlabel('Epoche') # Imposta l'etichetta dell'asse x.
plt.ylabel('Perdita') # Imposta l'etichetta dell'asse y.
plt.axhline(0, color='black', linewidth=0.8, linestyle='--') # Disegna una linea orizzontale.
plt.legend() # Aggiunge una legenda.
plt.grid(True) # Aggiunge una griglia.
plt.show() # Mostra il grafico.
if progress_bar: # Se la barra di avanzamento esiste.
progress_bar.destroy() # Distrugge la barra di avanzamento.
progress_bar = None # Imposta la barra di avanzamento a None.
logger.info(f"Fine addestramento modello per {ruota}.") # Logga la fine dell'addestramento.
def mostra_grafico(all_hist_loss, all_hist_val_loss): # Definisce la funzione per mostrare il grafico.
global fig, ax # Dichiara le variabili globali.
for child in frame_grafico.winfo_children(): # Itera sui figli del frame del grafico.
child.destroy() # Distrugge i figli.
fig, ax = plt.subplots(figsize=(12, 10)) # Crea un grafico.
for fold_idx in range(len(all_hist_loss)): # Itera sui fold.
ax.plot(all_hist_loss[fold_idx], label=f'Fold {fold_idx + 1} - Loss Train', linestyle='-') # Disegna la perdita di addestramento.
ax.plot(all_hist_val_loss[fold_idx], label=f'Fold {fold_idx + 1} - Loss Val', linestyle='--') # Disegna la perdita di validazione.
ax.set_title('Andamento della Perdita durante l\'Addestramento (K-Fold)') # Imposta il titolo del grafico.
ax.set_xlabel('Epoche') # Imposta l'etichetta dell'asse x.
ax.set_ylabel('Perdita') # Imposta l'etichetta dell'asse y.
ax.grid(True) # Aggiunge una griglia.
canvas = FigureCanvasTkAgg(fig, master=frame_grafico) # Crea un canvas per il grafico.
canvas.draw() # Disegna il grafico.
canvas.get_tk_widget().pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # Inserisce il canvas nel frame.
legend = ax.legend(loc='center left', bbox_to_anchor=(1, 0.5), fontsize='small') # Aggiunge una legenda.
fig.canvas.draw() # Disegna il grafico.
plt.close(fig) # Chiude la figura.
def select_optimizer(opt): # Definisce la funzione per selezionare l'ottimizzatore.
global optimizer_choice # Dichiara la variabile globale.
optimizer_choice = opt # Imposta l'ottimizzatore.
logger.info(f"Ottimizzatore selezionato: {optimizer_choice}") # Logga l'ottimizzatore selezionato.
def select_loss_function(loss_func): # Definisce la funzione per selezionare la funzione di perdita.
global loss_function_choice # Dichiara la variabile globale.
loss_function_choice = 'mean_squared_error' if loss_func == 'mse' else 'mean_absolute_error' # Imposta la funzione di perdita.
logger.info(f"Funzione di perdita selezionata: {loss_function_choice}") # Logga la funzione di perdita selezionata.
def select_patience(patience_value): # Definisce la funzione per selezionare il valore di patience.
global patience # Dichiara la variabile globale.
patience = patience_value # Imposta il valore di patience.
logger.info(f"Patience impostato a: {patience}") # Logga il valore di patience.
def select_min_delta(min_delta_value): # Definisce la funzione per selezionare il valore di min_delta.
global min_delta # Dichiara la variabile globale.
min_delta = min_delta_value # Imposta il valore di min_delta.
logger.info(f"Min Delta impostato a: {min_delta}") # Logga il valore di min_delta.
def update_textbox(numeri): # Definisce la funzione per aggiornare il box di testo con i numeri predetti.
textbox.insert(tk.END, "Numeri Predetti:\n") # Inserisce il testo nel box di testo.
numeri_limitati = numeri.flatten()[:5] # Estrae i primi 5 numeri.
textbox.insert(tk.END, ", ".join(map(str, numeri_limitati)) + "\n") # Inserisce i numeri nel box di testo.
def mostra_numeri_predetti(numeri): # Definisce la funzione per mostrare i numeri predetti.
textbox.insert(tk.END, "Numeri Predetti:\n") # Inserisce il testo nel box di testo.
numeri_limitati = numeri.flatten()[:5] # Estrae i primi 5 numeri.
textbox.insert(tk.END, ", ".join(map(str, numeri_limitati)) + "\n") # Inserisce i numeri nel box di testo.
def mostra_migliori_risultati(history): # Definisce la funzione per mostrare i migliori risultati.
final_train_loss = history.history['loss'][-1] # Ottiene la perdita di addestramento finale.
final_val_loss = history.history['val_loss'][-1] # Ottiene la perdita di validazione finale.
textbox.insert(tk.END, f"Ultima Loss Train: {final_train_loss:.4f}\n") # Inserisce il testo nel box di testo.
textbox.insert(tk.END, f"Ultima Loss Val: {final_val_loss:.4f}\n") # Inserisce il testo nel box di testo.
def salva_grafico(nome_file='grafico.png'): # Definisce la funzione per salvare il grafico.
if fig: # Se la figura esiste.
fig.savefig(nome_file) # Salva la figura.
messagebox.showinfo("Successo", f"Grafico salvato come {nome_file}") # Mostra un messaggio di successo.
else: # Altrimenti.
messagebox.showerror("Errore", "Nessun grafico disponibile per il salvataggio.") # Mostra un messaggio di errore.
def salva_risultati(nome_file='risultati.txt'): # Definisce la funzione per salvare i risultati.
try: # Inizia un blocco try-except.
# Apre il file dialog per selezionare la posizione di salvataggio
file_path = filedialog.asksaveasfilename(defaultextension=".txt",
filetypes=[("Text files", "*.txt"), ("All files", "*.*")])
if file_path: # Se l'utente ha selezionato un file.
with open(file_path, 'w') as file: # Apre il file.
file.write(textbox.get(1.0, tk.END)) # Scrive il contenuto del box di testo nel file.
messagebox.showinfo("Successo", f"Risultati salvati in {file_path}") # Mostra un messaggio di successo.
else:
messagebox.showinfo("Info", "Salvataggio cancellato dall'utente.")
except Exception as e: # Cattura tutte le eccezioni.
messagebox.showerror("Errore", f"Errore nel salvataggio dei risultati: {e}") # Mostra un messaggio di errore.
# Creazione della finestra principale
root = tk.Tk() # Crea la finestra principale.
root.geometry("1200x1250") # Imposta la dimensione della finestra.
# Crea una cornice per contenere l'etichetta del titolo e altri elementi, se necessario.
title_frame = tk.Frame(root)
title_frame.pack(pady=10) # Aggiunge un po' di spazio verticale attorno alla cornice
# Crea l'etichetta del titolo con il colore desiderato.
title_label = tk.Label(title_frame, text="𝔼𝕞𝕡𝕒𝕥𝕙𝕚𝕩", fg="blue", font=("Arial", 24)) # Scegli il colore e il font
title_label.pack() # Posiziona l'etichetta all'interno della cornice
# Frame per i pulsanti di salvataggio
frame_salvataggio = tk.Frame(root) # Crea un frame per i pulsanti di salvat # Crea un frame per i pulsanti di salvataggio.
frame_salvataggio.pack(pady=10) # Inserisce il frame nella finestra.
# Pulsanti per il salvataggio
btn_salva_grafico = tk.Button(frame_salvataggio, text="Salva Grafico", command=lambda: salva_grafico('grafico.png'), bg="#FFDDC1") # Crea il pulsante per salvare il grafico.
btn_salva_grafico.pack(side=tk.LEFT, padx=10) # Inserisce il pulsante nel frame.
btn_salva_risultati = tk.Button(frame_salvataggio, text="Salva Risultati", command=lambda: salva_risultati('risultati.txt'), bg="#FFDDC1")
btn_salva_risultati.pack(side=tk.LEFT, padx=10)
# Creazione del frame per i pulsanti
frame_pulsanti = tk.Frame(root)
frame_pulsanti.pack(pady=20)
# Creazione dei pulsanti per la selezione delle ruote
pulsanti_ruote = {}
for ruota in file_ruote.keys():
btn = tk.Button(frame_pulsanti, text=ruota, command=lambda r=ruota: on_seleziona_ruota(r), bg="#ADD8E6", fg="black")
btn.pack(side=tk.LEFT, padx=5)
pulsanti_ruote[ruota] = btn
# Campo di input per la ruota selezionata e il periodo
entry_info = tk.Entry(frame_pulsanti, width=100, bg="#F0F0F0", fg="black")
entry_info.pack(pady=10)
# Campi di input per le date
frame_date = tk.Frame(frame_pulsanti)
frame_date.pack(pady=20)
label_start_date = tk.Label(frame_date, text="Data di Inizio (YYYY/MM/DD):", bg="#ADD8E6", fg="black")
label_start_date.pack(side=tk.LEFT)
entry_start_date = tk.Entry(frame_date, width=15, bg="#F0F0F0", fg="black")
entry_start_date.pack(side=tk.LEFT)
label_end_date = tk.Label(frame_date, text="Data di Fine (YYYY/MM/DD):", bg="#ADD8E6", fg="black")
label_end_date.pack(side=tk.LEFT)
entry_end_date = tk.Entry(frame_date, width=15, bg="#F0F0F0", fg="black")
entry_end_date.pack(side=tk.LEFT)
# Campo per specificare il numero di epoche
frame_epochs = tk.Frame(frame_pulsanti)
frame_epochs.pack(pady=20)
label_epochs = tk.Label(frame_epochs, text="Numero di Epoche:", bg="#ADD8E6", fg="black")
label_epochs.pack(side=tk.LEFT)
entry_epochs = tk.Entry(frame_epochs, width=5, bg="#F0F0F0", fg="black")
entry_epochs.insert(0, "100")
entry_epochs.pack(side=tk.LEFT)
# Sezione per le opzioni di Early Stopping
frame_early_stopping = tk.Frame(root)
frame_early_stopping.pack(pady=20)
label_early_stopping = tk.Label(frame_early_stopping, text="Opzioni Early Stopping:", bg="#ADD8E6", fg="black")
label_early_stopping.pack(side=tk.TOP)
btn_patience_5 = tk.Button(frame_early_stopping, text="Patience: 5", command=lambda: select_patience(5), bg="#C9E4CA")
btn_patience_5.pack(side=tk.LEFT, padx=5)
btn_patience_10 = tk.Button(frame_early_stopping, text="Patience: 10", command=lambda: select_patience(10), bg="#C9E4CA")
btn_patience_10.pack(side=tk.LEFT, padx=5)
btn_patience_15 = tk.Button(frame_early_stopping, text="Patience: 15", command=lambda: select_patience(15), bg="#C9E4CA")
btn_patience_15.pack(side=tk.LEFT, padx=5)
btn_min_delta_01 = tk.Button(frame_early_stopping, text="Min Delta: 0.01", command=lambda: select_min_delta(0.01), bg="#C9E4CA")
btn_min_delta_01.pack(side=tk.LEFT, padx=5)
btn_min_delta_05 = tk.Button(frame_early_stopping, text="Min Delta: 0.05", command=lambda: select_min_delta(0.05), bg="#C9E4CA")
btn_min_delta_05.pack(side=tk.LEFT, padx=5)
btn_min_delta_1 = tk.Button(frame_early_stopping, text="Min Delta: 0.10", command=lambda: select_min_delta(0.1), bg="#C9E4CA")
btn_min_delta_1.pack(side=tk.LEFT, padx=5)
# Aggiunta di campi per i neuroni e i tassi di dropout
frame_model_parameters = tk.Frame(frame_pulsanti)
frame_model_parameters.pack(pady=20)
label_layer1 = tk.Label(frame_model_parameters, text="Layer 1 Neuroni:", bg="#ADD8E6", fg="black")
label_layer1.pack(side=tk.LEFT)
entry_neurons_layer1 = tk.Entry(frame_model_parameters, width=5, bg="#F0F0F0", fg="black")
entry_neurons_layer1.insert(0, "512")
entry_neurons_layer1.pack(side=tk.LEFT)
label_dropout_layer1 = tk.Label(frame_model_parameters, text="Layer 1 Dropout:", bg="#ADD8E6", fg="black")
label_dropout_layer1.pack(side=tk.LEFT)
entry_dropout_layer1 = tk.Entry(frame_model_parameters, width=5, bg="#F0F0F0", fg="black")
entry_dropout_layer1.insert(0, "0.2")
entry_dropout_layer1.pack(side=tk.LEFT)
label_layer2 = tk.Label(frame_model_parameters, text="Layer 2 Neuroni:", bg="#ADD8E6", fg="black")
label_layer2.pack(side=tk.LEFT)
entry_neurons_layer2 = tk.Entry(frame_model_parameters, width=5, bg="#F0F0F0", fg="black")
entry_neurons_layer2.insert(0, "256")
entry_neurons_layer2.pack(side=tk.LEFT)
label_dropout_layer2 = tk.Label(frame_model_parameters, text="Layer 2 Dropout:", bg="#ADD8E6", fg="black")
label_dropout_layer2.pack(side=tk.LEFT)
entry_dropout_layer2 = tk.Entry(frame_model_parameters, width=5, bg="#F0F0F0", fg="black")
entry_dropout_layer2.insert(0, "0.2") # Valore predefinito
entry_dropout_layer2.pack(side=tk.LEFT)
label_layer3 = tk.Label(frame_model_parameters, text="Layer 3 Neuroni:", bg="#ADD8E6", fg="black")
label_layer3.pack(side=tk.LEFT)
entry_neurons_layer3 = tk.Entry(frame_model_parameters, width=5, bg="#F0F0F0", fg="black")
entry_neurons_layer3.insert(0, "128") # Valore predefinito
entry_neurons_layer3.pack(side=tk.LEFT)
label_dropout_layer3 = tk.Label(frame_model_parameters, text="Layer 3 Dropout:", bg="#ADD8E6", fg="black")
label_dropout_layer3.pack(side=tk.LEFT)
entry_dropout_layer3 = tk.Entry(frame_model_parameters, width=5, bg="#F0F0F0", fg="black")
entry_dropout_layer3.insert(0, "0.2") # Valore predefinito
entry_dropout_layer3.pack(side=tk.LEFT)
# Frame per i pulsanti di ottimizzazione
frame_optimizer = tk.Frame(frame_pulsanti)
frame_optimizer.pack(side=tk.RIGHT, padx=20)
btn_optimizer_1 = tk.Button(frame_optimizer, text=" 1 (Adam)", command=lambda: select_optimizer('1'), bg="#C9E4CA", fg="black")
btn_optimizer_1.pack(pady=5)
btn_optimizer_2 = tk.Button(frame_optimizer, text=" 2 (RMSprop)", command=lambda: select_optimizer('2'), bg="#C9E4CA", fg="black")
btn_optimizer_2.pack(pady=5)
btn_optimizer_3 = tk.Button(frame_optimizer, text=" 3 (SGD)", command=lambda: select_optimizer('3'), bg="#C9E4CA", fg="black")
btn_optimizer_3.pack(pady=5)
# Frame per i pulsanti della funzione di perdita
frame_loss_function = tk.Frame(frame_pulsanti)
frame_loss_function.pack(side=tk.RIGHT, padx=20)
btn_loss_mse = tk.Button(frame_loss_function, text="Loss: MSE", command=lambda: select_loss_function('mse'), bg="#C9E4CA", fg="black")
btn_loss_mse.pack(pady=5)
btn_loss_mae = tk.Button(frame_loss_function, text="Loss: MAE", command=lambda: select_loss_function('mae'), bg="#C9E4CA", fg="black")
btn_loss_mae.pack(pady=5)
# Frame principale per il box di testo e la scrollbar
text_frame = tk.Frame(root)
text_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10)
# Scrollbar verticale
scrollbar = ttk.Scrollbar(text_frame)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
# Scrollbar orizzontale
scrollbar_x = ttk.Scrollbar(text_frame, orient=tk.HORIZONTAL)
scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
# Creazione del box di testo con scrollbar
textbox = tk.Text(text_frame, height=10, width=90, wrap=tk.NONE, yscrollcommand=scrollbar.set, xscrollcommand=scrollbar_x.set)
textbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# Configura la scrollbar
scrollbar.config(command=textbox.yview)
scrollbar_x.config(command=textbox.xview)
# Frame per il grafico
frame_grafico = tk.Frame(root)
frame_grafico.pack(pady=10)
# Frame per la prevedibilità
frame_prevedibilita = tk.Frame(root)
frame_prevedibilita.pack(pady=10)
# Creazione e visualizzazione della finestra
root.mainloop()
# Apre il file di log alla chiusura
open_log_file()