51 lines
2.1 KiB
Python
51 lines
2.1 KiB
Python
"""큐레이션 직전 호출 — review 1건 + 추세 3건 → 컨텍스트 dict."""
|
|
import json
|
|
from typing import Optional, Dict, Any
|
|
from .. import service_proxy
|
|
|
|
|
|
def _detect_bias(reviews: list) -> str:
|
|
"""3주↑ 같은 방향 패턴 편향이 유지되면 한 줄로."""
|
|
deltas = [r.get("pattern_delta") or "" for r in reviews if r.get("pattern_delta")]
|
|
if len(deltas) < 2:
|
|
return ""
|
|
# 단순 휴리스틱 — 같은 키워드("저번호" 등)가 2회 이상이면 지속 편향
|
|
keywords = ["저번호", "고번호", "합계", "홀짝"]
|
|
persistent = []
|
|
for kw in keywords:
|
|
cnt = sum(1 for d in deltas if kw in d)
|
|
if cnt >= max(2, len(deltas) - 1):
|
|
persistent.append(kw)
|
|
return " · ".join(persistent)
|
|
|
|
|
|
async def build_retrospective(target_draw_no: int) -> Optional[Dict[str, Any]]:
|
|
"""target_draw_no(이번 주) 직전 회차의 review + 그 앞 3회 추세."""
|
|
last = await service_proxy.lotto_review_by_draw(target_draw_no - 1)
|
|
if not last:
|
|
return None
|
|
|
|
history = await service_proxy.lotto_reviews_history(limit=4)
|
|
# history 는 desc 정렬 → last 와 그 이전 3건 분리
|
|
others = [r for r in history if r["draw_no"] < target_draw_no - 1][:3]
|
|
series = [last] + others
|
|
|
|
cur_avgs = [r["curator_avg_match"] for r in series if r.get("curator_avg_match") is not None]
|
|
usr_avgs = [r["user_avg_match"] for r in series if r.get("user_avg_match") is not None]
|
|
|
|
return {
|
|
"last_draw": {
|
|
"draw_no": last["draw_no"],
|
|
"curator_avg": last.get("curator_avg_match"),
|
|
"curator_best_tier": last.get("curator_best_tier"),
|
|
"user_avg": last.get("user_avg_match"),
|
|
"user_5plus": last.get("user_5plus_prizes"),
|
|
"pattern_delta": last.get("pattern_delta") or "",
|
|
},
|
|
"trend_4w": {
|
|
"curator_avg_4w": round(sum(cur_avgs) / len(cur_avgs), 2) if cur_avgs else None,
|
|
"user_avg_4w": round(sum(usr_avgs) / len(usr_avgs), 2) if usr_avgs else None,
|
|
"user_persistent_bias": _detect_bias(series),
|
|
},
|
|
}
|