Ciao lotto_tom75
ottimo Script, come sempre.
Mi sono permesso di fare un piccolo Python che stampa direttamente, su 5 file diversi, le 5 posizioni:
# -*- coding: utf-8 -*-
# Raggruppa i numeri estratti in una determinata posizione su tutte le ruote
# e verifica il gruppo nei colpi successivi (script by lotto_tom75 - conversione da VBScript)
# Interessante per generare gruppi base estremamente ridotti per ulteriori sviluppi
# Legge storico.txt (TAB: AAAA/MM/GG, sigla ruota, 5 numeri)
# Chiede sorte (Invio = 2), colpi (Invio = 16)
# e il periodo: data di inizio (i) oppure ultime estrazioni (u)
# Analizza tutte le posizioni (1-5) e scrive un report per ognuna in risultati_posizione_N.html
import os
from datetime import datetime
# Ruote del gruppo e della verifica: le 10 ruote piu' la Nazionale
RUOTE = ["BA", "CA", "FI", "GE", "MI", "NA", "PA", "RM", "TO", "VE", "RN"]
# Posizioni analizzate: tutte e 5
POSIZIONI = [1, 2, 3, 4, 5]
# Valori di default delle richieste iniziali
SORTE_DEFAULT = 2
COLPI_DEFAULT = 16
ULTIME_DEFAULT = 180
DATA_INIZIO_DEFAULT = "01/01/2026"
# Nomi delle sorti (numero di numeri usciti insieme sulla stessa ruota)
NOMI_SORTE = {1: "Estratto", 2: "Ambo", 3: "Terno", 4: "Quaterna", 5: "Cinquina"}
def cartella_script():
# Cartella dello script; se __file__ non esiste (es. Thonny) usa la cartella corrente
try:
return os.path.dirname(os.path.abspath(__file__))
except NameError:
return os.getcwd()
def carica_storico(percorso):
# Restituisce una lista di (data, {sigla: [5 numeri]}) in ordine cronologico
estrazioni = {}
with open(percorso, "r", encoding="utf-8", errors="ignore") as f:
for riga in f:
campi = riga.split()
if len(campi) < 7:
continue
data, sigla = campi[0], campi[1]
try:
numeri = [int(x) for x in campi[2:7]]
except ValueError:
continue
estrazioni.setdefault(data, {})[sigla] = numeri
return [(d, estrazioni[d]) for d in sorted(estrazioni)]
def formatta_data(data):
# AAAA/MM/GG -> GG/MM/AAAA
p = data.split("/")
return "{}/{}/{}".format(p[2], p[1], p[0]) if len(p) == 3 else data
def chiedi_intero(domanda, default, minimo=1, massimo=None):
# Chiede un numero intero nell'intervallo indicato; Invio = valore di default
while True:
testo = input("{} (Invio = {}): ".format(domanda, default)).strip()
if not testo:
return default
try:
n = int(testo)
if n >= minimo and (massimo is None or n <= massimo):
return n
except ValueError:
pass
print("Valore non valido, riprova.")
def chiedi_data(domanda, default):
# Chiede una data GG/MM/AAAA; restituisce AAAA/MM/GG
while True:
testo = input("{} (GG/MM/AAAA, Invio = {}): ".format(domanda, default)).strip() or default
try:
return datetime.strptime(testo, "%d/%m/%Y").strftime("%Y/%m/%d")
except ValueError:
print("Data non valida, riprova.")
def chiedi_modo():
# i = a partire da una data, u = ultime estrazioni; Invio = i
while True:
testo = input("Data di inizio (i) o ultime estrazioni (u) (Invio = i): ").strip().lower() or "i"
if testo in ("i", "u"):
return testo
print("Valore non valido, riprova.")
def raccogli_gruppo(ruote_es, posizione):
# Numero estratto nella posizione voluta su ogni ruota: [(sigla, numero)]
gruppo = []
for sigla in RUOTE:
if sigla in ruote_es:
gruppo.append((sigla, ruote_es[sigla][posizione - 1]))
return gruppo
def verifica_gruppo(estrazioni, idx, numeri, sorte, colpi):
# Primo colpo in cui almeno 'sorte' numeri del gruppo escono insieme su una ruota
# Restituisce (colpo, data, [(ruota, numeri usciti)]) oppure (None, None, [])
giocati = set(numeri)
disponibili = min(colpi, len(estrazioni) - 1 - idx)
for k in range(1, disponibili + 1):
data_k, ruote_k = estrazioni[idx + k]
trovati = []
for sigla in RUOTE:
presenti = sorted(giocati & set(ruote_k.get(sigla, [])))
if len(presenti) >= sorte:
trovati.append((sigla, presenti))
if trovati:
return k, data_k, trovati
return None, None, []
def main():
cartella = cartella_script()
estrazioni = carica_storico(os.path.join(cartella, "storico.txt"))
print("Archivio letto: {} estrazioni, dal {} al {}".format(
len(estrazioni), formatta_data(estrazioni[0][0]), formatta_data(estrazioni[-1][0])))
sorte = chiedi_intero("Sorte di verifica (1=estratto, 2=ambo, 3=terno, 4=quaterna, 5=cinquina)",
SORTE_DEFAULT, 1, 5)
colpi = chiedi_intero("Colpi di verifica", COLPI_DEFAULT)
modo = chiedi_modo()
if modo == "i":
data_da = chiedi_data("Data di inizio", DATA_INIZIO_DEFAULT)
idx_inizio = next((i for i, (d, _) in enumerate(estrazioni) if d >= data_da), len(estrazioni))
descrizione = "a partire dal {}".format(formatta_data(data_da))
else:
n_ultime = chiedi_intero("Quante ultime estrazioni analizzare", ULTIME_DEFAULT)
# Come EstrazioneFin - quanteultimeestrazionianalizzare nello script originale
idx_inizio = max(0, len(estrazioni) - 1 - n_ultime)
descrizione = "le ultime {} estrazioni".format(n_ultime)
if idx_inizio >= len(estrazioni):
print("Nessuna estrazione nel periodo scelto.")
return
# Un report per ogni posizione (es. risultati_posizione_1.html)
for posizione in POSIZIONI:
casi = []
for idx in range(idx_inizio, len(estrazioni)):
data, ruote_es = estrazioni[idx]
gruppo = raccogli_gruppo(ruote_es, posizione)
numeri = [n for _, n in gruppo]
colpo, data_hit, trovati = verifica_gruppo(estrazioni, idx, numeri, sorte, colpi)
casi.append({
"data": data, "gruppo": gruppo, "numeri": sorted(set(numeri)),
"colpo": colpo, "data_hit": data_hit, "trovati": trovati,
"disponibili": min(colpi, len(estrazioni) - 1 - idx),
})
nome_report = "risultati_posizione_{}.html".format(posizione)
scrivi_html(os.path.join(cartella, nome_report), casi,
posizione, sorte, colpi, descrizione)
positivi = sum(1 for c in casi if c["colpo"] is not None)
print("Posizione {}: estrazioni analizzate: {} - esiti positivi: {} - report: {}".format(
posizione, len(casi), positivi, nome_report))
def scrivi_html(percorso, casi, posizione, sorte, colpi, descrizione):
positivi = [c for c in casi if c["colpo"] is not None]
in_corso = [c for c in casi if c["colpo"] is None and c["disponibili"] < colpi]
negativi = [c for c in casi if c["colpo"] is None and c["disponibili"] >= colpi]
colpo_massimo = max([c["colpo"] for c in positivi], default=0)
conclusi = len(positivi) + len(negativi)
perc = (100.0 * len(positivi) / conclusi) if conclusi else 0.0
h = []
h.append("<!DOCTYPE html><html lang='it'><head><meta charset='utf-8'>")
h.append("<title>Numeri in posizione {} su tutte le ruote</title><style>".format(posizione))
h.append("body{background:#14161a;color:#e0e0e0;font-family:Segoe UI,Arial,sans-serif;margin:20px}")
h.append("h1{color:#f0c040}table{border-collapse:collapse;width:100%;margin-top:14px}")
h.append("th,td{border:1px solid #333;padding:5px 8px;font-size:13px;text-align:left;vertical-align:top}")
h.append("th{background:#23262d;color:#f0c040;position:sticky;top:0}")
h.append("td.ko{background:#4d1d1d;color:#f0a0a0}")
h.append("td.wait{background:#4d4120;color:#f0d890}")
h.append(".esito{display:block;margin:2px 0;padding:3px 6px;border-radius:4px;background:#1d4d2b;color:#9cf0b0}")
h.append(".box{display:inline-block;background:#23262d;padding:8px 14px;margin:4px 8px 4px 0;border-radius:6px}")
h.append(".num{color:#f0c040;font-weight:bold}")
h.append(".calc{font-size:12px;color:#b0b0b0}")
h.append("footer{margin-top:20px;text-align:center;color:#f0c040;letter-spacing:2px}")
h.append("</style></head><body>")
h.append("<h1>Numeri estratti in posizione {} su tutte le ruote - {} entro {} colpi</h1>".format(
posizione, NOMI_SORTE[sorte].lower(), colpi))
h.append("<p>Range temporale analizzato: {}</p>".format(descrizione))
h.append("<div class='box'>Posizione di raccolta: <b>{}</b></div>".format(posizione))
h.append("<div class='box'>Colpo massimo: <b>{}</b></div>".format(colpo_massimo))
h.append("<div class='box'>Esiti positivi: <b>{}</b></div>".format(len(positivi)))
h.append("<div class='box'>Esiti negativi: <b>{}</b></div>".format(len(negativi)))
h.append("<div class='box'>In corso: <b>{}</b></div>".format(len(in_corso)))
h.append("<div class='box'>% positivi sui conclusi: <b>{:.2f}</b></div>".format(perc))
h.append("<table><tr><th>N°</th><th>Data</th><th>Gruppo ({}° posizione)</th><th>Esito</th></tr>".format(posizione))
for i, c in enumerate(casi, 1):
h.append("<tr><td>{}</td><td>{}</td>".format(i, formatta_data(c["data"])))
h.append("<td><span class='num'>{}</span><br><span class='calc'>{}</span></td>".format(
" ".join("{:02d}".format

for n in c["numeri"]),
" ".join("{} {:02d}".format(s, n) for s, n in c["gruppo"])))
if c["colpo"] is not None:
dove = ", ".join("{} {}".format(s, ".".join("{:02d}".format

for n in nn))
for s, nn in c["trovati"])
h.append("<td><span class='esito'><b>{}</b> al {}° colpo ({}) - {}</span></td></tr>".format(
NOMI_SORTE[sorte], c["colpo"], formatta_data(c["data_hit"]), dove))
elif c["disponibili"] < colpi:
h.append("<td class='wait'>In corso ({}/{} colpi)</td></tr>".format(c["disponibili"], colpi))
else:
h.append("<td class='ko'>Nessun esito</td></tr>")
h.append("</table>")
h.append("<footer>NESSUNA CERTEZZA SOLO POCA PROBABILITÀ<br>SCRIPT BY LOTTO_TOM75</footer></body></html>")
with open(percorso, "w", encoding="utf-8") as f:
f.write("\n".ioin(h) if False else "\n".join(h))
if __name__ == "__main__":
main()
mega.nz
Piccola modifica ho aggiunto un foglio:
Serve solo se avete convergenze, prché i casi negativi sono circa il 31%