05/23 update codes, add build scripts
LottoSight CI / Syntax Check & Tests (push) Has been cancelled

This commit is contained in:
2026-05-23 18:16:56 -04:00
parent c61c09db94
commit c05867a642
10 changed files with 674 additions and 29 deletions
+22 -8
View File
@@ -6,27 +6,41 @@ Each function takes game_id and returns structured Python data
(dicts / lists) — no UI concerns here.
"""
import math
from collections import Counter
from itertools import combinations
from db.models import get_all_draws_numbers, get_game_by_id
def frequency_analysis(game_id, last_n=None):
def frequency_analysis(game_id, last_n=None, decay: float = 0.0):
"""
Count appearances of each main ball.
Count (or weight) appearances of each main ball.
last_n: restrict to the most recent N draws (None = all).
Returns {number: count} sorted high → low.
decay: exponential recency weight per draw step (0 = uniform / off).
With decay=0.01 the draw 69 steps back carries ~50% of the
latest draw's weight; draws >300 steps back are near-zero.
Returns {number: count_or_weight} sorted high → low.
"""
draws = get_all_draws_numbers(game_id) # ASC order
draws = get_all_draws_numbers(game_id) # ASC order, oldest first
if last_n and last_n > 0:
draws = draws[-last_n:]
counter = Counter()
for draw in draws:
counter.update(draw["numbers"])
if not decay:
counter = Counter()
for draw in draws:
counter.update(draw["numbers"])
return dict(sorted(counter.items(), key=lambda kv: kv[1], reverse=True))
return dict(sorted(counter.items(), key=lambda kv: kv[1], reverse=True))
# Decayed path: newest draw (i = n-1) gets weight 1.0; older draws decay
n = len(draws)
freq: dict[int, float] = {}
for i, draw in enumerate(draws):
w = math.exp(-decay * (n - 1 - i))
for num in draw["numbers"]:
freq[num] = freq.get(num, 0.0) + w
return dict(sorted(freq.items(), key=lambda kv: kv[1], reverse=True))
def gap_analysis(game_id):