Spaces:
Running
Running
import re | |
import unicodedata | |
jp_pos_to_en_pos = { | |
'投': 'P', | |
'捕': 'C', | |
'一': '1B', | |
'二': '2B', | |
'三': '3B', | |
'遊': 'SS', | |
'左': 'LF', | |
'中': 'CF', | |
'右': 'RF', | |
'右中': 'RCF', | |
'左中': 'LCF' | |
} | |
def translate_pa_outcome(outcome): | |
partial_outcomes = { | |
'ファウルフライ': 'FF', | |
'ファウルライナー': 'FL', | |
'ゴロ': 'GB', | |
'フライ': 'FB', | |
'ライナー': 'LD', | |
'安打': '1B', | |
'2塁打': '2B', | |
'3塁打': '3B', | |
'ランニング本塁打': 'IHR', # inside-the-park home run | |
'本塁打': 'HR', | |
'犠打': 'SH', | |
'犠飛': 'SF', | |
'併殺打': 'DP', # what about triple plays? | |
'エラー': 'E', | |
'犠打野選': 'SH FC', | |
'野選': 'FC' | |
} | |
if outcome.endswith('三振'): | |
if outcome.startswith('空振り'): | |
return 'K' | |
elif outcome.startswith('見逃し'): | |
return 'inv_K' | |
elif outcome == '四球': | |
return 'BB' | |
elif outcome == '死球': | |
return 'HBP' | |
elif outcome == '敬遠(申告敬遠)': | |
return 'IBB' | |
elif outcome == 'スリーバント失敗': | |
return 'bunt_K' # have to confirm | |
elif outcome == '犠打失': | |
return 'failed_SH' # have to confirm | |
elif outcome == '犠飛失': | |
return 'failed_SF' #have to confirm | |
elif outcome.endswith('走塁妨害'): | |
return 'obstruction' | |
elif outcome.endswith('走塁妨害'): | |
return 'dropped_K_safe' | |
elif outcome == '振り逃げ' or '暴投' in outcome: | |
return 'WP' # reached base on WP; on another search, 振り逃げ is an uncaught third strike | |
elif outcome.endswith('塁けん制 アウト'): | |
return outcome.replace('塁けん制 アウト', 'B PK') | |
elif 'けん制アウト' in outcome: | |
return 'XB PK' # pickoff at unknown base | |
elif outcome == '守備妨害': | |
return 'defensive_interference' | |
elif '盗塁失敗' in outcome: | |
return 'CS' | |
elif tag_search:= re.search(r'[123本](・[123本])*塁(間|上)タッチアウト', outcome): | |
outcome = unicodedata.normalize('NFKC', tag_search.group(0)) | |
outcome = outcome.replace('本', 'H') | |
bases = re.findall(r'\d|H', outcome) | |
return ' '.join(bases) + 'TO' # tag out | |
elif '捕逸' in outcome: | |
return 'PB' # reached base on passed ball | |
for _outcome in partial_outcomes.keys(): | |
if outcome.endswith(_outcome): | |
return f'{jp_pos_to_en_pos[outcome.removesuffix(_outcome)]} {partial_outcomes[_outcome]}' | |
return outcome | |
jp_pitch_to_en_pitch = { | |
# fastballs | |
'ストレート': '4-Seam Fastball', | |
'ツーシーム': '2-Seam Fastball', | |
'カットボール': 'Cutter', | |
'ワンシーム': '1-Seam Fastball', | |
'シンカー': 'Sinker', | |
'シュート': 'Shootball', | |
# breaking balls | |
'スライダー': 'Slider', | |
'縦スライダー': 'Vertical Slider', | |
'高速スライダー': 'Hard Slider', | |
'スラーブ': 'Slurve', | |
'カーブ': 'Curveball', | |
'ナックルカーブ': 'Knuckle Curve', | |
'スローカーブ': 'Slow Curve', | |
'パワーカーブ': 'Power Curve', | |
'スクリュー': 'Screwball', | |
# off speed | |
'チェンジアップ': 'Changeup', | |
'スプリット': 'Splitter', | |
'フォーク': 'Forkball', | |
'パーム': 'Palmball', | |
# other | |
'スローボール': 'Eephus', | |
} | |
jp_pitch_to_pitch_code = { | |
# fastballs | |
'ストレート': 'FF', | |
'ツーシーム': 'FT', | |
'カットボール': 'FC', | |
'ワンシーム': 'FE', | |
'シンカー': 'SI', | |
'シュート': 'SH', | |
# breaking balls | |
'スライダー': 'SL', | |
'縦スライダー': 'VS', | |
'高速スライダー': 'HS', | |
'スラーブ': 'SV', | |
'カーブ': 'CU', | |
'ナックルカーブ': 'KC', | |
'スローカーブ': 'CS', | |
'パワーカーブ': 'PC', | |
'スクリュー': 'SC', | |
# off speed | |
'チェンジアップ': 'CH', | |
'スプリット': 'FS', | |
'フォーク': 'FO', | |
'パーム': 'PA', | |
# other | |
'スローボール': 'EP', | |
} | |
def translate_pitch_outcome(outcome): | |
partial_outcomes = { | |
'失': 'E', | |
'犠打': 'SH', | |
'犠飛': 'SF', | |
'邪直': 'FLD', # foul line drive | |
'邪飛': 'FF', | |
'ゴロ': 'GB', | |
'飛': 'FB', | |
'直': 'LD', | |
'安': '1B', | |
'2': '2B', | |
'3': '3B', | |
'走本': 'IHR', # inside-the-park home run, should confirm | |
'本': 'HR', | |
'併打': 'DP', | |
'犠野': 'SH FC', | |
'野選': 'FC' | |
} | |
if outcome == 'ボール': | |
return 'B' | |
elif outcome == 'ファウル': | |
return 'F' | |
elif outcome == '空振り': | |
return 'SS' # swinging strike | |
elif outcome == '見逃し': | |
return 'LS' # swinging strike | |
elif outcome == '空三振': | |
return 'K' | |
elif outcome == '見三振': | |
return 'inv_K' | |
elif outcome == 'バ三振': | |
return 'bunt_K' | |
elif outcome == '四球': | |
return 'BB' | |
elif outcome == '死球': | |
return 'HBP' | |
elif outcome == '犠打失': | |
return 'SH_E' # or SBE? sac hit error | |
elif outcome == '犠飛失': | |
return 'SF_E' # sac fly error | |
elif outcome == '走妨': | |
return 'obstruction' | |
elif outcome == '反則投球': | |
return 'illegal_pitch' | |
elif outcome == '守妨': | |
return 'defensive_interference' | |
elif outcome == '暴振逃': | |
return 'WP_S' | |
elif outcome == '逸振逃': | |
return 'PB_S' | |
for _outcome in partial_outcomes.keys(): | |
if outcome.endswith(_outcome): | |
return f'{jp_pos_to_en_pos[outcome.removesuffix(_outcome)]} {partial_outcomes[_outcome]}' | |
return outcome | |
max_pitch_types = len(jp_pitch_to_en_pitch) | |