Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature may not be available in some browsers.
import tkinter as tk
from tkinter import filedialog, messagebox, ttk, scrolledtext
from threading import Thread
from queue import Queue
import numpy as np
from collections import defaultdict
import time
class SequenzaSpiaApp:
def __init__(self, root):
self.root = root
self.root.title("Predittore Bit Lotto")
self.setup_variables()
self.create_ui()
self.queue = Queue()
self.check_queue()
self.tabella_valori = [] # For storing table buttons
self.decimal_results = {} # Store decimal results for each column
self.binary_filename = None # Store the name of the binary file
def setup_variables(self):
self.dati = []
self.carrello = [None] * 7
self.pattern_ricerca = []
self.filename = None
self.pattern_cache = {}
self.soglia_var = tk.IntVar(value=50) # Default threshold 50%
self.bit_var = tk.IntVar(value=0) # Add bit_var for analysis
def create_ui(self):
main_frame = ttk.Frame(self.root, padding="10")
main_frame.pack(fill=tk.BOTH, expand=True)
# Binary preview section
preview_frame = ttk.LabelFrame(main_frame, text="Anteprima Binaria", padding="5")
preview_frame.pack(fill=tk.X, pady=5)
self.binary_preview = scrolledtext.ScrolledText(preview_frame, height=5, width=50)
self.binary_preview.pack(fill=tk.X, pady=5)
# 1-3: File loading and binary conversion section
conversion_frame = ttk.LabelFrame(main_frame, text="Conversione File", padding="5")
conversion_frame.pack(fill=tk.X, pady=5)
# File loading
ttk.Button(conversion_frame, text="Carica estrazioni.txt",
command=self.carica_file).pack(side=tk.LEFT, padx=5)
self.nome_file_label = ttk.Label(conversion_frame, text="Nessun file caricato")
self.nome_file_label.pack(side=tk.LEFT, padx=5)
# Column selection with checkboxes
self.column_vars = []
for i in range(5):
var = tk.BooleanVar()
self.column_vars.append(var)
ttk.Checkbutton(conversion_frame, text=f"Col {i+1}",
variable=var).pack(side=tk.LEFT, padx=2)
ttk.Button(conversion_frame, text="Converti Colonne",
command=self.convert_selected_columns).pack(side=tk.LEFT, padx=5)
# 4-7: Pattern analysis section
analysis_frame = ttk.LabelFrame(main_frame, text="Analisi Pattern", padding="5")
analysis_frame.pack(fill=tk.X, pady=5)
ttk.Button(analysis_frame, text="Carica File Binario",
command=self.load_binary_file).pack(side=tk.LEFT, padx=5)
# Label to display the name of the loaded binary file
self.binary_file_label = ttk.Label(analysis_frame, text="Nessun file binario caricato")
self.binary_file_label.pack(side=tk.LEFT, padx=5)
# Pattern creation controls
ttk.Label(analysis_frame, text="Righe:").pack(side=tk.LEFT, padx=5)
self.righe_input = ttk.Entry(analysis_frame, width=5)
self.righe_input.pack(side=tk.LEFT, padx=2)
ttk.Label(analysis_frame, text="Colonne:").pack(side=tk.LEFT, padx=5)
self.colonne_input = ttk.Entry(analysis_frame, width=5)
self.colonne_input.pack(side=tk.LEFT, padx=2)
ttk.Button(analysis_frame, text="Crea Pattern",
command=self.crea_tabella).pack(side=tk.LEFT, padx=5)
ttk.Button(analysis_frame, text="Carica Pattern",
command=self.carica_pattern).pack(side=tk.LEFT, padx=5)
# 8-9: Cart management section
cart_frame = ttk.LabelFrame(main_frame, text="Gestione Carrello", padding="5")
cart_frame.pack(fill=tk.X, pady=5)
self.carrello_label = ttk.Label(cart_frame, text=self._format_carrello())
self.carrello_label.pack(side=tk.LEFT, padx=5)
ttk.Button(cart_frame, text="Svuota Carrello",
command=self.svuota_carrello).pack(side=tk.LEFT, padx=5)
ttk.Button(cart_frame, text="Converti in Decimale",
command=self.esporta_carrello).pack(side=tk.LEFT, padx=5)
# Add table frame for pattern creation
self.table_frame = ttk.Frame(main_frame)
self.table_frame.pack(fill=tk.BOTH, expand=True, pady=5)
# Add progress bar
self.progress = ttk.Progressbar(main_frame, mode='determinate')
self.progress.pack(fill=tk.X, pady=5)
# Add pattern display and analysis section
pattern_control_frame = ttk.LabelFrame(main_frame, text="Controllo Pattern", padding="5")
pattern_control_frame.pack(fill=tk.X, pady=5)
self.pattern_display = ttk.Label(pattern_control_frame, text="Pattern: Nessun pattern caricato")
self.pattern_display.pack(side=tk.LEFT, padx=5)
ttk.Button(pattern_control_frame, text="Analizza Dataset",
command=self.start_analysis).pack(side=tk.LEFT, padx=5)
# Add bit position selector
bit_frame = ttk.LabelFrame(main_frame, text="Selezione Bit", padding="5")
bit_frame.pack(fill=tk.X, pady=5)
ttk.Label(bit_frame, text="Posizione bit (0-6):").pack(side=tk.LEFT, padx=5)
self.bit_position = ttk.Spinbox(bit_frame, from_=0, to=6, width=5)
self.bit_position.pack(side=tk.LEFT, padx=5)
self.bit_position.set(0)
# Add extraction range selector
range_frame = ttk.LabelFrame(main_frame, text="Range Analisi", padding="5")
range_frame.pack(fill=tk.X, pady=5)
ttk.Label(range_frame, text="Ultime N estrazioni (0=tutte):").pack(side=tk.LEFT, padx=5)
self.n_estrazioni = ttk.Entry(range_frame, width=6)
self.n_estrazioni.pack(side=tk.LEFT, padx=5)
self.n_estrazioni.insert(0, "0")
# Add results frame
self.results_frame = ttk.LabelFrame(main_frame, text="Risultati Analisi", padding="5")
self.results_frame.pack(fill=tk.BOTH, expand=True, pady=5)
# Add buttons to copy and clear results
button_frame = ttk.Frame(self.results_frame)
button_frame.pack(fill=tk.X, pady=5)
ttk.Button(button_frame, text="Copia Risultati",
command=self.copy_results).pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text="Cancella Risultati",
command=self.clear_results).pack(side=tk.LEFT, padx=5)
self.results_text = scrolledtext.ScrolledText(self.results_frame, height=10, width=50)
self.results_text.pack(fill=tk.BOTH, expand=True, pady=5)
# Add decimal results section
decimal_frame = ttk.LabelFrame(main_frame, text="Risultati Decimali per Colonna", padding="5")
decimal_frame.pack(fill=tk.X, pady=5)
self.decimal_text = scrolledtext.ScrolledText(decimal_frame, height=5, width=50)
self.decimal_text.pack(fill=tk.X, pady=5)
def carica_file(self):
"""Load and process file"""
try:
filename = filedialog.askopenfilename(filetypes=[("Text files", "*.txt")])
if filename:
self.filename = filename
self.nome_file_label.config(text=f"File: {filename.split('/')[-1]}")
Thread(target=self.load_data, daemon=True).start()
except Exception as e:
self.queue.put(("error", f"Errore caricamento: {str(e)}"))
def load_data(self):
"""Process file data removing dots"""
try:
with open(self.filename, 'r') as file:
self.dati = [line.strip().replace('.', '') for line in file.readlines()]
print(f"Dati caricati: {self.dati[:5]}...") # Debug first 5 lines
self.queue.put(("update", f"Totale righe: {len(self.dati)}"))
except Exception as e:
self.queue.put(("error", f"Errore lettura: {str(e)}"))
def _format_carrello(self):
"""Format cart display"""
return "Carrello: " + " ".join(str(b) if b is not None else "_" for b in self.carrello)
def check_queue(self):
"""Process queue messages"""
while not self.queue.empty():
msg = self.queue.get()
if isinstance(msg, tuple):
msg_type, content = msg
if msg_type == "error":
messagebox.showerror("Errore", content)
elif msg_type == "update":
self.nome_file_label.config(text=content)
self.root.after(100, self.check_queue)
def start_analysis(self):
"""Start pattern analysis"""
if not self.dati:
messagebox.showwarning("Attenzione", "Caricare prima un file binario")
return
if not self.pattern_ricerca:
messagebox.showwarning("Attenzione", "Caricare prima un pattern")
return
Thread(target=self.analizza_dataset, daemon=True).start()
def esporta_carrello(self):
"""Export cart results"""
if None in self.carrello:
messagebox.showwarning("Avviso", "Completare il carrello")
return
val = int("".join(map(str, self.carrello)), 2)
messagebox.showinfo("Risultato", f"Valore decimale: {val}")
# Save the decimal result and associated information
bit_pos = self.binary_filename # Use the binary filename as the position
n_estrazioni = self.n_estrazioni.get().strip()
if n_estrazioni.isdigit():
n_estrazioni = int(n_estrazioni)
else:
n_estrazioni = 0
self.decimal_results[bit_pos] = (val, n_estrazioni)
# Update the results label
self.update_results_label()
def crea_tabella(self):
"""Create dynamic pattern table"""
try:
righe = int(self.righe_input.get())
colonne = int(self.colonne_input.get())
# Clear existing table
for widget in self.table_frame.winfo_children():
widget.destroy()
self.tabella_valori = []
for i in range(righe):
row = []
for j in range(colonne):
btn = ttk.Button(self.table_frame, text="0", width=2,
command=lambda r=i, c=j: self.toggle_bit(r, c))
btn.grid(row=i, column=j, padx=2, pady=2)
row.append(btn)
self.tabella_valori.append(row)
self.queue.put(("update", "Tabella pattern creata"))
except ValueError:
self.queue.put(("error", "Inserire valori numerici validi"))
def toggle_bit(self, riga, colonna):
"""Toggle bit value in pattern table"""
button = self.tabella_valori[riga][colonna]
current = button.cget("text")
new_value = "1" if current == "0" else "0"
button.config(text=new_value)
def carica_pattern(self):
"""Load pattern from table"""
try:
pattern = []
for row in self.tabella_valori:
pattern_row = []
for button in row:
pattern_row.append(int(button.cget("text")))
pattern.append(pattern_row)
self.pattern_ricerca = pattern
pattern_str = "\n".join(" ".join(str(bit) for bit in row) for row in pattern)
self.pattern_display.config(text=f"Pattern:\n{pattern_str}")
messagebox.showinfo("Pattern Caricato", "Pattern pronto per l'analisi")
except Exception as e:
messagebox.showerror("Errore", f"Errore caricamento pattern: {str(e)}")
def analizza_dataset(self):
"""Analyze dataset with selected pattern - starting from oldest data"""
try:
if not self.pattern_ricerca:
messagebox.showwarning("Attenzione", "Caricare prima un pattern")
return
self.progress['value'] = 0
reversed_data = list(reversed(self.dati))
# Get number of extractions to analyze
n = self.n_estrazioni.get().strip()
if n and n.isdigit():
n = int(n)
if 0 < n < len(reversed_data):
reversed_data = reversed_data[:n]
print(f"\nAnalisi limitata alle ultime {n} estrazioni")
total_rows = len(reversed_data)
bit_pos = int(self.bit_position.get())
zeros = 0
ones = 0
matches = 0
print("\n====== ANALISI DETTAGLIATA PATTERN ======")
print(f"Posizione bit analizzata: {bit_pos}")
print("\nPattern di ricerca:")
for row in self.pattern_ricerca:
print("".join(str(bit) for bit in row))
print("\n=== SEQUENZE TROVATE ===")
pattern_height = len(self.pattern_ricerca)
pattern_width = len(self.pattern_ricerca[0]) if self.pattern_ricerca else 0
for i in range(len(reversed_data) - pattern_height):
match = True
current_sequence = []
# Check pattern match
for row_idx in range(pattern_height):
data_row = reversed_data[i + row_idx].split() # Split the binary string into parts
if not data_row: # Skip empty rows
match = False
break
current_sequence.append(reversed_data[i + row_idx])
# Ensure the data row has enough columns
if len(data_row) * 7 < pattern_width: # Each part is 7 bits
match = False
break
# Convert the row to a continuous binary string
binary_row = ''.join(data_row).replace('.', '') # Remove dots
# Check each bit in the pattern
for col_idx, pattern_bit in enumerate(self.pattern_ricerca[row_idx]):
if col_idx >= len(binary_row):
match = False
break
try:
if int(binary_row[col_idx]) != pattern_bit:
match = False
break
except ValueError as e:
print(f"Errore di conversione: {e} in riga {i + row_idx}, colonna {col_idx}")
match = False
break
if not match:
break
if match:
matches += 1
next_row_idx = i + pattern_height
if next_row_idx < total_rows:
next_row = reversed_data[next_row_idx].split()
if next_row and bit_pos < len(''.join(next_row)):
binary_next_row = ''.join(next_row).replace('.', '') # Remove dots
try:
next_bit = int(binary_next_row[bit_pos])
except ValueError as e:
print(f"Errore di conversione: {e} in riga {next_row_idx}, posizione bit {bit_pos}")
continue
print(f"\n--- Match #{matches} ---")
print(f"Riga iniziale: {total_rows - i}")
print("Sequenza trovata:")
for seq_row in current_sequence:
print(seq_row)
print(f"Bit successivo in pos {bit_pos}: {next_bit}")
if next_bit == 0:
zeros += 1
else:
ones += 1
# Add match result to the results text
self.results_text.insert(tk.END, f"Posizione bit analizzata: {bit_pos}\n")
self.results_text.insert(tk.END, f"Match #{matches}: Bit {bit_pos} trovato in riga {total_rows - i}\n")
self.progress['value'] = (i / (total_rows - pattern_height)) * 100
self.root.update_idletasks()
# Calculate and display results
total_matches = zeros + ones
zero_percent = (zeros / total_matches * 100) if total_matches > 0 else 0
one_percent = (ones / total_matches * 100) if total_matches > 0 else 0
result_text = (
f"\nRisultati Analisi:\n"
f"Totale match: {total_matches}\n"
f"Zeri: {zeros} ({zero_percent:.1f}%)\n"
f"Uni: {ones} ({one_percent:.1f}%)"
)
print("\n====== RIEPILOGO FINALE ======")
print(result_text)
self.queue.put(("update", result_text))
self.results_text.insert(tk.END, result_text + "\n")
# Update cart based on majority
if ones > zeros:
self.carrello[bit_pos] = 1
else:
self.carrello[bit_pos] = 0
self.carrello_label.config(text=self._format_carrello())
# Update the final summary
self.update_final_summary()
except ValueError as e:
error_msg = f"Errore durante l'analisi: {str(e)}"
print(f"\nERRORE: {error_msg}")
self.queue.put(("error", error_msg))
except Exception as e:
error_msg = f"Errore generico durante l'analisi: {str(e)}"
print(f"\nERRORE: {error_msg}")
self.queue.put(("error", error_msg))
finally:
self.progress['value'] = 100
self.root.update_idletasks()
def convert_selected_columns(self):
"""Convert selected columns to binary files"""
try:
if not self.filename:
messagebox.showwarning(
"Attenzione", "Caricare prima estrazioni.txt")
return
for i, var in enumerate(self.column_vars):
if var.get():
output_file = f"b{i + 1}.txt"
self.convert_column_to_binary_file(i + 1, output_file)
except Exception as e:
messagebox.showerror(
"Errore", f"Errore nella conversione: {str(e)}")
def convert_column_to_binary_file(self, column_index, output_file):
"""Convert single column to binary file"""
try:
with open(self.filename, 'r') as f:
lines = f.readlines()
transformed_lines = []
for line in lines:
numbers = line.strip().split(".")
if column_index - 1 < len(numbers):
binary = f"{int(numbers[column_index - 1]):07b}"
binary_with_dots = ".".join(binary)
transformed_lines.append(binary_with_dots)
with open(output_file, 'w') as f:
f.write("\n".join(transformed_lines))
except Exception as e:
raise Exception(f"Errore colonna {column_index}: {str(e)}")
def load_binary_file(self):
"""Load binary file for analysis"""
try:
filename = filedialog.askopenfilename(filetypes=[("Text files", "*.txt")])
if filename:
self.binary_filename = filename.split('/')[-1] # Store only the filename
self.binary_file_label.config(text=f"File binario: {self.binary_filename}")
with open(filename, 'r') as file:
self.dati = [line.strip().replace('.', '') for line in file.readlines()]
preview_text = '\n'.join(self.dati[:5]) + "\n..."
self.binary_preview.delete('1.0', tk.END)
self.binary_preview.insert('1.0', preview_text)
self.queue.put(("update", f"File binario caricato: {len(self.dati)} righe"))
except Exception as e:
self.queue.put(("error", f"Errore caricamento file binario: {str(e)}"))
def svuota_carrello(self):
"""Clear cart"""
self.carrello = [None] * 7
self.carrello_label.config(text=self._format_carrello())
def update_results_label(self):
"""Update the results label with decimal results and associated information"""
result_text = "Risultati Analisi:\n"
for bit_pos, (decimal_value, n_estrazioni) in self.decimal_results.items():
result_text += f"Decimale ricostruito: {decimal_value}\n"
result_text += f"rilevato {decimal_value} in posizione {bit_pos} con ultime {n_estrazioni} estrazioni\n"
self.results_text.insert(tk.END, result_text + "\n")
def update_final_summary(self):
"""Update the final summary with all decimal results"""
final_summary = "\nREPORT FINALE \"pulito\"\n\n"
for bit_pos, (decimal_value, n_estrazioni) in self.decimal_results.items():
final_summary += f"Decimale ricostruito: {decimal_value}\n"
final_summary += f"rilevato {decimal_value} in posizione {bit_pos} con ultime {n_estrazioni} estrazioni\n"
self.results_text.insert(tk.END, final_summary + "\n")
def copy_results(self):
"""Copy the content of the results text area to the clipboard"""
self.root.clipboard_clear()
self.root.clipboard_append(self.results_text.get("1.0", tk.END))
messagebox.showinfo("Copiato", "Contenuto copiato negli appunti")
def clear_results(self):
"""Clear the content of the results text area"""
self.results_text.delete("1.0", tk.END)
if __name__ == "__main__":
root = tk.Tk()
app = SequenzaSpiaApp(root)
root.mainloop()