import tkinter as tk
from tkinter import messagebox, filedialog
import pandas as pd
from scipy.stats import binom
import requests
from io import StringIO
import threading
import time
def carica_dati(url, start_date=None, end_date=None):
try:
response = requests.get(url)
response.raise_for_status() # Verifica se la richiesta ha avuto successo
data = StringIO(response.text)
df = pd.read_csv(data, sep='\t', header=None, names=['Data', 'Ruota', 'Numero1', 'Numero2', 'Numero3', 'Numero4', 'Numero5'])
df['Data'] = pd.to_datetime(df['Data'], errors='coerce')
df = df.dropna(subset=['Data'])
if start_date and end_date:
df = df[(df['Data'] >= start_date) & (df['Data'] <= end_date)]
for colonna in ['Numero1', 'Numero2', 'Numero3', 'Numero4', 'Numero5']:
df[colonna] = df[colonna].apply(lambda x: str(int(x)).zfill(2) if pd.notna(x) and str(x).isdigit() else None)
return df
except requests.exceptions.RequestException as e:
messagebox.showerror("Errore di Rete", f"Errore durante il recupero dei dati dall'URL: {e}")
return None
except ValueError as e:
messagebox.showerror("Errore di Formattazione", f"Errore nel file scaricato: {e}")
return None
def calcola_statistiche_numeri_successivi(df, numero):
df_numeri = df[['Numero1', 'Numero2', 'Numero3', 'Numero4', 'Numero5']]
filtro_successivi = df_numeri.shift(1).apply(lambda x: x == numero).any(axis=1)
numeri_successivi = df[filtro_successivi].iloc[:, 2:].values.flatten()
numeri_successivi = pd.Series(numeri_successivi).dropna()
filtro_precedenti = df_numeri.shift(-1).apply(lambda x: x == numero).any(axis=1)
numeri_precedenti = df[filtro_precedenti].iloc[:, 2:].values.flatten()
numeri_precedenti = pd.Series(numeri_precedenti).dropna()
if numeri_successivi.empty and numeri_precedenti.empty:
return None, f"Il numero {numero} non ha seguito né preceduto immediato sulla ruota."
statistiche = {}
if not numeri_successivi.empty:
conteggio_numeri_successivi = numeri_successivi.value_counts()
numeri_top_successivi = conteggio_numeri_successivi.head(4)
percentuali_successivi = (numeri_top_successivi / len(numeri_successivi)) * 100
media_successivi = numeri_successivi.astype(int).mean()
deviazione_standard_successivi = numeri_successivi.astype(int).std()
statistiche['successivi'] = {
'numeri_top': numeri_top_successivi,
'percentuali': percentuali_successivi,
'media': media_successivi,
'deviazione_standard': deviazione_standard_successivi,
'dati': numeri_successivi
}
if not numeri_precedenti.empty:
conteggio_numeri_precedenti = numeri_precedenti.value_counts()
numeri_top_precedenti = conteggio_numeri_precedenti.head(4)
percentuali_precedenti = (numeri_top_precedenti / len(numeri_precedenti)) * 100
media_precedenti = numeri_precedenti.astype(int).mean()
deviazione_standard_precedenti = numeri_precedenti.astype(int).std()
statistiche['precedenti'] = {
'numeri_top': numeri_top_precedenti,
'percentuali': percentuali_precedenti,
'media': media_precedenti,
'deviazione_standard': deviazione_standard_precedenti,
'dati': numeri_precedenti
}
freq_uscita_numero = (df.iloc[:, 2:] == numero).sum().sum() / (len(df) * 5)
def calcola_estrazioni_necessarie(probabilita, freq):
estrazioni = 1
while True:
probabilita_attuale = 1 - binom.cdf(0, estrazioni, freq)
if probabilita_attuale >= probabilita:
return estrazioni
estrazioni += 1
estrazioni_50_percento = calcola_estrazioni_necessarie(0.50, freq_uscita_numero)
estrazioni_90_percento = calcola_estrazioni_necessarie(0.90, freq_uscita_numero)
return (statistiche, freq_uscita_numero, estrazioni_50_percento, estrazioni_90_percento), None
def scegli_miglior_ruota(risultati):
miglior_ruota = None
miglior_valutazione = -float('inf')
for ruota, risultato in risultati:
statistiche, freq_uscita_numero, estrazioni_50_percento, estrazioni_90_percento = risultato
valutazione = 0
if 'successivi' in statistiche:
valutazione += statistiche['successivi']['media'] - statistiche['successivi']['deviazione_standard']
if 'precedenti' in statistiche:
valutazione += statistiche['precedenti']['media'] - statistiche['precedenti']['deviazione_standard']
if valutazione > miglior_valutazione:
miglior_valutazione = valutazione
miglior_ruota = (ruota, risultato)
return miglior_ruota
def cerca_numeri():
ruote_selezionate = listbox_ruote.curselection()
if not ruote_selezionate:
messagebox.showinfo("Nessuna Ruota Selezionata", "Seleziona almeno una ruota.")
return
numeri_spia = [entry.get().zfill(2) for entry in entry_numeri if entry.get().isdigit() and 1 <= int(entry.get()) <= 90]
if not numeri_spia:
messagebox.showinfo("Numeri Spia Invalidi", "Inserisci numeri spia validi (1-90).")
return
try:
start_date = pd.to_datetime(start_date_entry.get(), format='%Y-%m-%d')
end_date = pd.to_datetime(end_date_entry.get(), format='%Y-%m-%d')
except ValueError:
messagebox.showinfo("Date Invalidi", "Inserisci date valide nel formato YYYY-MM-DD.")
return
risultati = []
messaggi_errore = []
for ruota_index in ruote_selezionate:
ruota = listbox_ruote.get(ruota_index)
file_ruota = file_ruote.get(ruota)
if file_ruota:
df = carica_dati(file_ruota, start_date, end_date)
if df is not None:
for numero in numeri_spia:
risultato, errore = calcola_statistiche_numeri_successivi(df, numero)
if errore:
messaggi_errore.append(errore)
if risultato is not None:
risultati.append((ruota, risultato))
if risultati:
miglior_ruota = scegli_miglior_ruota(risultati)
if miglior_ruota:
ruota, risultato = miglior_ruota
statistiche, freq_uscita_numero, estrazioni_50_percento, estrazioni_90_percento = risultato
messaggio = f"Per la ruota di {ruota}, le statistiche dei numeri spia sono:\n"
if 'successivi' in statistiche:
messaggio += "Numeri successivi:\n"
for num, freq in statistiche['successivi']['numeri_top'].items():
percentuale = statistiche['successivi']['percentuali'][num]
messaggio += f"- Numero: {num}, Frequenza: {freq}, Percentuale: {percentuale:.2f}%\n"
messaggio += f"Media dei numeri successivi: {statistiche['successivi']['media']:.2f}\n"
messaggio += f"Deviazione standard dei numeri successivi: {statistiche['successivi']['deviazione_standard']:.2f}\n"
if 'precedenti' in statistiche:
messaggio += "Numeri precedenti:\n"
for num, freq in statistiche['precedenti']['numeri_top'].items():
percentuale = statistiche['precedenti']['percentuali'][num]
messaggio += f"- Numero: {num}, Frequenza: {freq}, Percentuale: {percentuale:.2f}%\n"
messaggio += f"Media dei numeri precedenti: {statistiche['precedenti']['media']:.2f}\n"
messaggio += f"Deviazione standard dei numeri precedenti: {statistiche['precedenti']['deviazione_standard']:.2f}\n"
messaggio += f"Frequenza di uscita del numero spia: {freq_uscita_numero:.2f}\n"
messaggio += f"Numero stimato di estrazioni necessarie per avere il numero spia con probabilità del 50%: {estrazioni_50_percento}\n"
messaggio += f"Numero stimato di estrazioni necessarie per avere il numero spia con probabilità del 90%: {estrazioni_90_percento}\n"
messaggio += "\n"
risultato_text.delete(1.0, tk.END)
risultato_text.insert(tk.END, messaggio)
else:
risultato_text.delete(1.0, tk.END)
if messaggi_errore:
risultato_text.insert(tk.END, "\n".join(messaggi_errore))
else:
risultato_text.insert(tk.END, "Nessun risultato trovato.")
def salva_risultati():
results = risultato_text.get(1.0, tk.END)
if not results.strip():
messagebox.showinfo("Nessun Risultato", "Non ci sono risultati da salvare.")
return
file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")])
if file_path:
with open(file_path, "w") as file:
file.write(results)
messagebox.showinfo("Salvataggio", "I risultati sono stati salvati correttamente.")
def ottieni_data_ultima_estrazione(url):
try:
response = requests.get(url)
response.raise_for_status()
data = StringIO(response.text)
df = pd.read_csv(data, sep='\t', header=None, names=['Data', 'Ruota', 'Numero1', 'Numero2', 'Numero3', 'Numero4', 'Numero5'])
df['Data'] = pd.to_datetime(df['Data'], errors='coerce')
df = df.dropna(subset=['Data'])
if not df.empty:
ultima_estrazione = df.iloc[-1]['Data']
return ultima_estrazione.strftime('%Y/%m/%d')
else:
return "Data non disponibile"
except requests.exceptions.RequestException as e:
return f"Errore di rete: {e}"
except ValueError as e:
return f"Errore di formato: {e}"
def aggiorna_data_estrazione():
global ultima_estrazione_label
# URL del file da cui prelevare la data (es. BARI)
url_bari = 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d99d8a5925b875da1b/BARI.txt'
data_ultima_estrazione = ottieni_data_ultima_estrazione(url_bari)
ultima_estrazione_label.config(text=f"Aggiornato alla data del: {data_ultima_estrazione}")
root.after(60000, aggiorna_data_estrazione) # Aggiorna ogni 60 secondi
# Definizione della finestra principale
root = tk.Tk()
root.title("Analisi dei Numeri Spia")
root.geometry("1200x700")
# Definisci gli URL dei file delle ruote
file_ruote = {
'BA': 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d99d8a5925b875da1b/BARI.txt',
'CA': 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d99d8a5925b875da1b/CAGLIARI.txt',
'FI': 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d99d8a5925b875da1b/FIRENZE.txt',
'GE': 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d99d8a5925b875da1b/GENOVA.txt',
'MI': 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d99d8a5925b875da1b/MILANO.txt',
'NA': 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d8a5925b875da1b/NAPOLI.txt',
'PA': 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d8a5925b875da1b/PALERMO.txt',
'RM': 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d8a5925b875da1b/ROMA.txt',
'TO': 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d8a5925b875da1b/TORINO.txt',
'VE': 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d8a5925b875da1b/VENEZIA.txt',
'NZ': 'https://raw.githubusercontent.com/Lottopython/estrazioni/56f992301c37511d75bd79d8a5925b875da1b/NAZIONALE.txt'
}
frame = tk.Frame(root, padx=10, pady=10)
frame.pack(expand=True, fill=tk.BOTH)
# Etichetta per l'ultima estrazione (box aggiunto)
ultima_estrazione_label = tk.Label(frame, text="Caricamento data...", font=("Helvetica", 14))
ultima_estrazione_label.place(relx=0.05, rely=0.01, relwidth=0.9, relheight=0.1)
label_ruote = tk.Label(frame, text="Seleziona Ruota:", font=("Helvetica", 14))
label_ruote.place(relx=0.05, rely=0.15, relwidth=0.15, relheight=0.05)
listbox_ruote = tk.Listbox(frame, font=("Helvetica", 12), selectmode=tk.MULTIPLE)
for ruota in file_ruote.keys():
listbox_ruote.insert(tk.END, ruota)
listbox_ruote.place(relx=0.05, rely=0.2, relwidth=0.15, relheight=0.35)
label_numeri_spia = tk.Label(frame, text="Numeri Spia:", font=("Helvetica", 14))
label_numeri_spia.place(relx=0.25, rely=0.15, relwidth=0.2, relheight=0.05)
entry_numeri = []
for i in range(5):
entry_numero = tk.Entry(frame, font=("Helvetica", 12))
entry_numero.place(relx=0.25, rely=0.2 + i * 0.07, relwidth=0.2, relheight=0.05)
entry_numeri.append(entry_numero)
start_date_label = tk.Label(frame, text="Data Inizio:", font=("Helvetica", 14))
start_date_label.place(relx=0.55, rely=0.15, relwidth=0.15, relheight=0.05)
start_date_entry = tk.Entry(frame, font=("Helvetica", 12))
start_date_entry.place(relx=0.55, rely=0.2, relwidth=0.2, relheight=0.05)
end_date_label = tk.Label(frame, text="Data Fine:", font=("Helvetica", 14))
end_date_label.place(relx=0.55, rely=0.3, relwidth=0.15, relheight=0.05)
end_date_entry = tk.Entry(frame, font=("Helvetica", 12))
end_date_entry.place(relx=0.55, rely=0.35, relwidth=0.2, relheight=0.05)
button_cerca = tk.Button(frame, text="Cerca", font=("Helvetica", 14), command=cerca_numeri)
button_cerca.place(relx=0.8, rely=0.2, relwidth=0.15, relheight=0.1)
button_salva = tk.Button(frame, text="Salva Risultati", font=("Helvetica", 14), command=salva_risultati)
button_salva.place(relx=0.8, rely=0.35, relwidth=0.15, relheight=0.1)
risultato_text = tk.Text(frame, font=("Helvetica", 12))
risultato_text.place(relx=0.05, rely=0.6, relwidth=0.9, relheight=0.35)
# Avvia l'aggiornamento iniziale delle estrazioni e il loop
aggiorna_data_estrazione()
root.mainloop()