From 9f897ea4a042bd42f8040065d4b822b7934a5621 Mon Sep 17 00:00:00 2001 From: gahusb Date: Sun, 31 May 2026 17:04:35 +0900 Subject: [PATCH] =?UTF-8?q?feat(lotto):=20point=5Fin=5Ftime=5Fdraws=20?= =?UTF-8?q?=ED=97=AC=ED=8D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- lotto/app/backtest.py | 6 ++++++ lotto/tests/test_backtest.py | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/lotto/app/backtest.py b/lotto/app/backtest.py index 132ebe5..b0c838b 100644 --- a/lotto/app/backtest.py +++ b/lotto/app/backtest.py @@ -85,6 +85,12 @@ def random_null_tickets(k: int, seed: Optional[int] = None) -> List[List[int]]: return out +def point_in_time_draws(draws: List[Tuple[int, List[int]]], + target_draw_no: int) -> List[Tuple[int, List[int]]]: + """target 회차 추첨 '직전' 시점의 데이터 — target_draw_no 미만만.""" + return [(d, nums) for d, nums in draws if d < target_draw_no] + + def coverage_tickets(k: int, seed: Optional[int] = None) -> List[List[int]]: """greedy 커버리지 — 아직 덜 쓰인 번호를 우선 배치해 번호를 넓게 분산. (휠링/보장설계는 향후. 현재는 distinct + 번호 사용 균등화)""" diff --git a/lotto/tests/test_backtest.py b/lotto/tests/test_backtest.py index 9eee498..0972492 100644 --- a/lotto/tests/test_backtest.py +++ b/lotto/tests/test_backtest.py @@ -60,6 +60,14 @@ def test_random_null_and_coverage_distinct(): assert len(flat) >= 40 # 커버리지 전략은 번호를 넓게 퍼뜨림 +def test_point_in_time_excludes_target_draw(): + draws = _toy_draws(50) # drw_no 1..50 + pit = bt.point_in_time_draws(draws, target_draw_no=30) + assert all(d < 30 for d, _ in pit) # 30 이상 제외 + assert max(d for d, _ in pit) == 29 + assert len(pit) == 29 + + def test_generate_pool_partial_fill(monkeypatch): """weighted_sample_6이 항상 같은 조합만 반환하도록 패치 → cap에 먼저 걸려 len < n — 예외 없이 반환.""" import random as _r