lottery_特码: 每次分析入库 + 中奖对比 + CLI add/list/hits
新功能: 1. SQLite analysis 表 (id, period, candidates JSON, v_xg_state, actual_special, hit) 2. save_analysis() — 每次跑分析入库 3. check_hits() — 对比 draws 表 actual_special, 更新 hit 4. add_draw() — 手填真开彩 (lottery_特码.py add 083 27 1 2 3 4 5 6) - reset 该 period 所有 analysis.actual_special=NULL (重跑 check_hits) 5. list_analysis() — 列出最近 N 条分析 + hit 状态 bug 修: - check_hits 之前用 'hit IS NULL' 找未更新 (但 hit=0 是已检查过) - 改成 'actual_special IS NULL' (没填过) CLI: - 默认: 跑分析 - add <period> <special> [n1 n2 n3 n4 n5 n6]: 手填真开彩 - list [N]: 列最近 N 条分析 - hits: 单独跑 check_hits 使用方法: 1. 跑分析: lottery_特码.py 084 (自动入库) 2. 真开彩出来手填: lottery_特码.py add 083 27 1 2 3 4 5 6 3. 看历史: lottery_特码.py list 10
This commit is contained in:
@@ -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 <period> <special> [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))
|
||||
Reference in New Issue
Block a user