diff --git a/lottery-hk/scripts/lottery_特码.py b/lottery-hk/scripts/lottery_特码.py index 628bb60..6cab1a1 100755 --- a/lottery-hk/scripts/lottery_特码.py +++ b/lottery-hk/scripts/lottery_特码.py @@ -9,10 +9,123 @@ """ import re import json +import sqlite3 import subprocess +import datetime +import os from collections import Counter +DB_PATH = os.path.expanduser('~/.hermes/trading/lottery.db') + + +def save_analysis(period, candidates, budget, v_xg_state): + """把分析结果存 SQLite, 用于历史回顾 + 中奖检查 + + candidates: list of dict [{'num':16,'weight':3,'amount':5},...] + v_xg_state: dict {'Qi':083,'Nq':084,'Week':'周二','Day':'04'} + """ + try: + conn = sqlite3.connect(DB_PATH) + c = conn.cursor() + c.execute('''INSERT INTO analysis + (period, candidates, budget, v_xg_qi, v_xg_nq, v_xg_week, v_xg_day) + VALUES (?, ?, ?, ?, ?, ?, ?)''', + (period, + json.dumps(candidates, ensure_ascii=False), + budget, + v_xg_state.get('Qi'), + v_xg_state.get('Nq'), + v_xg_state.get('Week'), + v_xg_state.get('Day'))) + conn.commit() + conn.close() + return True + except Exception as e: + print(f"[warn] save_analysis 失败: {e}", file=__import__('sys').stderr) + return False + + +def check_hits(): + """对所有未中奖的 analysis 行, 跟 draws 表真开彩对比, 更新 hit + actual_special + + 真开彩存在 = draws.special, analysis.period = draws.period + 用 actual_special IS NULL 找未更新行 (hit=0 是已检查, hit IS NULL 是没检查) + """ + try: + conn = sqlite3.connect(DB_PATH) + c = conn.cursor() + # 未更新 (actual_special IS NULL) 的 analysis + c.execute('''SELECT a.id, a.period, a.candidates + FROM analysis a + WHERE a.actual_special IS NULL''') + rows = c.fetchall() + for aid, period, candidates_json in rows: + # 查真开彩 + c.execute('SELECT special FROM draws WHERE period = ?', (period,)) + d = c.fetchone() + if d is None or d[0] is None or d[0] == 0: + continue # 还没开 或 special 未填 + actual = d[0] + # 查 candidates 里有没有 actual + candidates = json.loads(candidates_json) + hit = 1 if any(c.get('num') == actual for c in candidates) else 0 + c.execute('UPDATE analysis SET actual_special=?, hit=? WHERE id=?', + (actual, hit, aid)) + conn.commit() + conn.close() + except Exception as e: + print(f"[warn] check_hits 失败: {e}", file=__import__('sys').stderr) + + +def add_draw(period, special, n1=0, n2=0, n3=0, n4=0, n5=0, n6=0): + """手填真开彩: lottery_特码.py add 083 34 1 2 3 4 5 6 + + 先 INSERT/UPDATE draws, 再 reset 该 period 所有 analysis 的 actual_special=NULL + 这样 check_hits 会重新跑 (hit=0 也会被覆盖) + """ + try: + conn = sqlite3.connect(DB_PATH) + c = conn.cursor() + c.execute('''INSERT OR REPLACE INTO draws + (period, n1, n2, n3, n4, n5, n6, special) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)''', + (period, n1, n2, n3, n4, n5, n6, special)) + # reset 该 period 所有 analysis 的 actual_special=NULL + c.execute('UPDATE analysis SET actual_special=NULL, hit=NULL WHERE period = ?', + (period,)) + conn.commit() + conn.close() + # 立即 check_hits + check_hits() + return True + except Exception as e: + print(f"[ERR] add_draw 失败: {e}", file=__import__('sys').stderr) + return False + + +def list_analysis(limit=10): + """列出最近 N 条分析记录 + hit 状态""" + try: + conn = sqlite3.connect(DB_PATH) + c = conn.cursor() + c.execute('''SELECT id, period, candidates, budget, + v_xg_qi, v_xg_nq, actual_special, hit, created_at + FROM analysis ORDER BY id DESC LIMIT ?''', (limit,)) + print(f"{'ID':<4} {'期号':<6} {'Top候选':<35} {'¥':<3} {'v_xg':<10} {'真开':<6} {'中':<3} {'时间':<20}") + print("-" * 110) + for row in c.fetchall(): + aid, period, cands, budget, vq, vn, actual, hit, ts = row + c_list = json.loads(cands) + top = '/'.join(f"{c['num']}({c['weight']})" for c in c_list[:5]) + v_xg_s = f"Qi{vq}/Nq{vn}" if vq else '?' + hit_s = '✓' if hit == 1 else ('✗' if hit == 0 else '-') + actual_s = str(actual) if actual is not None else '-' + print(f"{aid:<4} {period:<6} {top[:35]:<35} {budget:<3} {v_xg_s:<10} {actual_s:<6} {hit_s:<3} {ts}") + conn.close() + except Exception as e: + print(f"[ERR] list_analysis 失败: {e}", file=__import__('sys').stderr) + def curl_url(url): try: result = subprocess.run( @@ -241,8 +354,46 @@ def format_te_ma_result(weights, period=None, budget=15, qi_week=None, qi_day=No if __name__ == '__main__': import sys - # 支持 CLI 参数: python3 lottery_特码.py [period] - period = sys.argv[1] if len(sys.argv) > 1 else None + cmd = sys.argv[1] if len(sys.argv) > 1 else None + + # CLI: add [n1 n2 n3 n4 n5 n6] + if cmd == 'add': + period = sys.argv[2] + special = int(sys.argv[3]) + nums = [int(x) for x in sys.argv[4:10]] # 最多 6 个平码 + while len(nums) < 6: + nums.append(0) + if add_draw(period, special, *nums): + print(f"✅ {period} 期真开彩: special={special} 平码={nums[:6]}") + # 显示对应该期的所有 analysis 是否中 + try: + conn = sqlite3.connect(DB_PATH) + c = conn.cursor() + c.execute('''SELECT id, candidates, hit FROM analysis + WHERE period = ? ORDER BY id DESC''', (period,)) + for aid, cands, hit in c.fetchall(): + cs = json.loads(cands) + hit_num = next((c2['num'] for c2 in cs if c2['num'] == special), None) + print(f" analysis #{aid}: hit={'✓' if hit==1 else '✗'} (猜 {special}: {'在Top' if hit_num else '不在Top'})") + conn.close() + except Exception: + pass + sys.exit(0) + + # CLI: list [N] + if cmd == 'list': + limit = int(sys.argv[2]) if len(sys.argv) > 2 else 10 + list_analysis(limit) + sys.exit(0) + + # CLI: hits (单独跑 check_hits) + if cmd == 'hits': + check_hits() + print("✅ check_hits 跑完") + sys.exit(0) + + # 默认: 跑分析 (period 第一个参数) + period = cmd if period is None: # 自动取 v_xg.json Qi try: @@ -265,6 +416,24 @@ if __name__ == '__main__': qi_week = v.get('Week', '?') qi_day = v.get('Day', '?') qi_nq = v.get('Nq', '?') + qi_xg = v.get('Qi', '?') + v_xg_state = {'Qi': qi_xg, 'Nq': qi_nq, 'Week': qi_week, 'Day': qi_day} except Exception: - qi_week = qi_day = qi_nq = '?' + qi_week = qi_day = qi_nq = qi_xg = '?' + v_xg_state = {} + + # Top 5 + 重点金额 (存 SQLite 用) + top5 = weights.most_common(5) + splits = [5, 4, 3, 2, 1] + candidates_for_db = [] + for i, (num, w) in enumerate(top5, 1): + amt = splits[i-1] if i <= len(splits) else 1 + candidates_for_db.append({'num': num, 'weight': w, 'amount': amt}) + + # 存 SQLite + save_analysis(period, candidates_for_db, 15, v_xg_state) + + # 对所有未中奖的 analysis 更新 hit (开彩后) + check_hits() + print(format_te_ma_result(weights, period, 15, qi_week, qi_day, qi_nq)) \ No newline at end of file