refactoring
This commit is contained in:
133
core/runner_classifier.py
Normal file
133
core/runner_classifier.py
Normal file
@@ -0,0 +1,133 @@
|
||||
"""
|
||||
core/runner_classifier.py — 주루 이벤트 분류
|
||||
|
||||
네이버 리포트의 주루 이벤트를 분석하여 관리자 사이트에서
|
||||
선택해야 할 라디오 버튼 라벨을 결정합니다.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from core.config_loader import runner_event_map
|
||||
|
||||
|
||||
def classify_runner_event(event_type: str) -> str | None:
|
||||
"""주루 이벤트 타입 → 사이트 라벨 (기본 매핑)"""
|
||||
return runner_event_map().get(event_type or "")
|
||||
|
||||
|
||||
def infer_runner_action_label(
|
||||
event: dict[str, Any],
|
||||
runner_event: dict[str, Any],
|
||||
) -> str | None:
|
||||
"""주루 이벤트를 종합적으로 추론하여 사이트 라벨 반환
|
||||
|
||||
리포트 action_label, event_type, event_text, result_type 등을 모두 분석.
|
||||
"""
|
||||
# 0. 리포트에 명시된 라벨이 있으면 최우선
|
||||
if "action_label" in runner_event:
|
||||
return runner_event["action_label"]
|
||||
|
||||
event_type = runner_event.get("type") or ""
|
||||
event_text = runner_event.get("text") or ""
|
||||
result_type = ((event.get("result") or {}).get("type") or "")
|
||||
result_text = ((event.get("result") or {}).get("text") or "")
|
||||
|
||||
# 이중도루 실패 + 진루
|
||||
if "이중도루 실패" in event_text and "진루" in event_text:
|
||||
return "기타 진루"
|
||||
if "도루" in event_text and "실패" in event_text and "진루" in event_text:
|
||||
return "기타 진루"
|
||||
|
||||
# 견제 아웃
|
||||
if event_type == "pickoff_out" or "견제사" in event_text:
|
||||
return "견제 아웃"
|
||||
|
||||
# 도루 실패
|
||||
if event_type == "steal_fail":
|
||||
return "도루시도 아웃"
|
||||
if "이중도루 실패" in event_text and "아웃" in event_text:
|
||||
return "도루시도 아웃"
|
||||
|
||||
# 도루 + 실책 진루
|
||||
if "도루" in event_text and "실책" in event_text and ("진루" in event_text or event_type == "error_advance"):
|
||||
return "도루성공&실책"
|
||||
|
||||
# 도루
|
||||
if "도루" in event_text:
|
||||
if "실패" in event_text:
|
||||
return "도루시도 아웃"
|
||||
return "도루성공"
|
||||
|
||||
# 낫아웃 + 폭투/포일
|
||||
if "낫아웃" in result_text and event_type == "wild_pitch_advance":
|
||||
return "폭투 낫아웃 진루"
|
||||
if "낫아웃" in result_text and event_type == "passed_ball_advance":
|
||||
return "포일 낫아웃 진루"
|
||||
|
||||
# 포일 진루
|
||||
if "포일" in event_text and ("진루" in event_text or event_type == "passed_ball_advance"):
|
||||
return "포일-진루성공"
|
||||
|
||||
# 실책으로 진루
|
||||
if "실책으로" in event_text:
|
||||
return "수비 실책"
|
||||
|
||||
# 안타/아웃 상황 → 일반 진루
|
||||
play_types = {
|
||||
"single", "double", "triple", "home_run", "out", "strikeout",
|
||||
"play", "sacrifice_fly", "sacrifice_bunt", "ground_out", "fly_out",
|
||||
}
|
||||
if result_type in play_types and event_type in {"advance", "score"}:
|
||||
return "일반 진루"
|
||||
|
||||
# 볼넷 상황 → 볼넷 진루
|
||||
walk_types = {"walk", "intentional_walk", "hit_by_pitch"}
|
||||
if result_type in walk_types and event_type in {"advance", "score"}:
|
||||
return "볼넷 진루"
|
||||
|
||||
# 기본: 일반 진루
|
||||
if event_type in {"advance", "score"}:
|
||||
return "일반 진루"
|
||||
|
||||
# 최종 폴백: config 매핑
|
||||
return classify_runner_event(event_type)
|
||||
|
||||
|
||||
def get_runner_area_type(event: dict[str, Any], runner_event: dict[str, Any]) -> int:
|
||||
"""주루 이벤트의 입력 영역 타입 결정
|
||||
|
||||
1 = 진루 영역 (일반 진루, 볼넷 진루 등)
|
||||
2 = 액션 영역 (도루, 견제, 폭투, 포일 등)
|
||||
"""
|
||||
event_text = runner_event.get("text") or ""
|
||||
action_keywords = ["도루", "견제", "폭투", "포일", "태그아웃", "포스아웃"]
|
||||
if any(k in event_text for k in action_keywords):
|
||||
return 2
|
||||
return 1
|
||||
|
||||
|
||||
def split_complex_runner_event(
|
||||
runner_event: dict[str, Any],
|
||||
) -> tuple[dict[str, Any], dict[str, Any] | None]:
|
||||
"""복합 주루 이벤트를 두 개로 분리
|
||||
|
||||
예: '도루성공 후 수비실책 진루' → (도루, 실책진루)
|
||||
"""
|
||||
text = runner_event.get("text") or ""
|
||||
|
||||
if "실책" not in text and "/" not in text:
|
||||
return runner_event, None
|
||||
|
||||
# '도루성공&실책' 같은 패턴
|
||||
if "도루" in text and "실책" in text and "진루" in text:
|
||||
first = dict(runner_event)
|
||||
first["type"] = "steal"
|
||||
first["text"] = text
|
||||
|
||||
second = dict(runner_event)
|
||||
second["type"] = "error_advance"
|
||||
second["text"] = text
|
||||
return first, second
|
||||
|
||||
return runner_event, None
|
||||
Reference in New Issue
Block a user