refactoring

This commit is contained in:
2026-05-02 16:24:42 +09:00
parent 296adf3073
commit 859c39fe0c
194 changed files with 5267 additions and 0 deletions

85
core/change_parser.py Normal file
View File

@@ -0,0 +1,85 @@
"""
core/change_parser.py — 선수 교체 이벤트 파싱
교체 텍스트에서 선수명, 포지션, 교체 유형 등을 추출합니다.
"""
from __future__ import annotations
import re
from typing import Any
from core.config_loader import position_to_defense_no
def extract_change_actor(text: str) -> tuple[str | None, int | None, str]:
"""교체 텍스트의 왼쪽(actor)에서 역할, 타순, 이름 추출
'5번타자 문보경' → ('batter', 5, '문보경')
'투수 임찬규' → ('투수', None, '임찬규')
"""
lhs = (text or "").split(" : ", 1)[0].strip()
batter_match = re.search(r"(\d+)번타자\s+(.+)$", lhs)
if batter_match:
return "batter", int(batter_match.group(1)), batter_match.group(2).strip()
roles = (
"대타", "대주자",
"1루주자", "2루주자", "3루주자", "주자",
"투수", "포수", "1루수", "2루수", "3루수",
"유격수", "좌익수", "중견수", "우익수",
)
for role in roles:
if lhs.startswith(role + " "):
return role, None, lhs[len(role):].strip()
return None, None, lhs
def is_merged_pitcher_substitution(actor_role: str | None, in_role: str | None) -> bool:
"""야수→투수 교체인지 확인 (투수가 DH로 전환되는 병합 교체)"""
field_roles = {"포수", "1루수", "2루수", "3루수", "유격수", "좌익수", "중견수", "우익수"}
return actor_role in field_roles and in_role == "투수"
def normalize_change_event(change_event: dict[str, Any]) -> dict[str, Any]:
"""교체 이벤트를 정규화
텍스트 파싱 → actor_name, out_player, in_player, change_type 등 추출
"""
if change_event.get("actor_name") or change_event.get("player_name"):
return change_event
text = change_event.get("text") or ""
normalized = dict(change_event)
normalized["change_type"] = "position_change" if "수비위치 변경" in text else "substitution"
actor_role, bat_order, actor_name = extract_change_actor(text)
normalized["actor_role"] = actor_role
normalized["actor_name"] = actor_name
if bat_order is not None:
normalized["bat_order"] = bat_order
if normalized["change_type"] == "position_change":
rhs = text.split(" : ", 1)[1] if " : " in text else ""
normalized["player_name"] = actor_name
normalized["to_position"] = rhs.split("(으)로", 1)[0].strip()
return normalized
rhs = text.split(" : ", 1)[1] if " : " in text else ""
rhs = rhs.split("(으)로 교체", 1)[0].strip()
in_role, _, in_name = extract_change_actor(rhs)
normalized["out_player"] = actor_name
normalized["in_player"] = in_name
normalized["in_role"] = in_role
pos_defense = position_to_defense_no()
if is_merged_pitcher_substitution(actor_role, in_role):
normalized["change_type"] = "merged_pitcher_substitution"
normalized["player_name"] = actor_name
normalized["to_position"] = "지명타자"
normalized["pitcher_in_player"] = in_name
return normalized
if in_role in pos_defense:
normalized["to_position"] = in_role
return normalized