npb_data_viz_demo / translate.py
patrickramos's picture
Update app
f101223
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)