from shiny import App, Inputs, Outputs, Session, reactive, render, req, ui import joblib import pandas as pd model = joblib.load('tjstuff_model_20240123.joblib') pitch_dict = { 'CH': 'Changeup', 'CU': 'Curveball', 'FC': 'Cutter', 'FF': '4-Seam', 'FS': 'Splitter', 'SI': 'Sinker', 'SL': 'Slider'} mean_pitch = {'CH': -0.0013655939837917683, 'CU': -0.002458133501932025, 'FC': -0.0027185615617781878, 'FF': -0.0009670561994425952, 'FS': -0.0016869144747033715, 'SI': -0.001226274762302637, 'SL': -0.005721894558519125} std_pitch = {'CH': 0.004674187447635245, 'CU': 0.004885933432519971, 'FC': 0.004347654738518598, 'FF': 0.006622014251851153, 'FS': 0.004842304855545382, 'SI': 0.004983958694693723, 'SL': 0.004805394304446709} app_ui = ui.page_fluid( ui.row( ui.column(4,ui.input_select("pitch_type", "Select Pitch Type", pitch_dict, selected='FF', width='700px')) ), ui.row( ui.column(4,ui.input_numeric("start_speed", "Pitch Velocity (mph)", value=95,width='700px')), ui.column(4,ui.input_numeric("spin_rate", "Pitch Spin Rate (rpm)", value=2500,width='700px')),width=6), ui.row( ui.column(4,ui.input_numeric("extension", "Extension (ft)", value=6.5,width='700px')), ui.column(4,ui.input_numeric("ivb", "Pitch Induced Vertical Break (in)", value=15,width='700px'))), ui.row( ui.column(4,ui.input_numeric("hb", "Pitch Horizontal Break (in) [-Glove,+Arm]", value=5,width='700px')), ui.column(4,ui.input_numeric("x0", "Pitch Horizontal Release Point (ft)", value=2,width='700px'))), ui.row( ui.column(4,ui.input_numeric("z0", "Pitch Vertical Release Height (mph)", value=6,width='700px')), ui.column(4,ui.input_numeric("fb_max_velo_diff", "Pitcher's Fastball Velocity (mph) [max if possible]", value=95,width='700px'))), ui.row( ui.column(4,ui.input_numeric("fb_max_ivb_diff", "Pitcher's Fastball iVB (in) [max if possible]", value=15,width='700px')), ui.column(4,ui.input_numeric("fb_max_hb_diff", "Pitcher's Fastball HB (in) [max if possible]", value=5,width='700px'))), ui.row( ui.column(6,ui.input_action_button("go", "Go!", class_="btn-success",width='700px'))), ui.row( ui.column( 6, ui.output_text_verbatim("verb_no_placeholder", placeholder=False))),) def server(input: Inputs, output: Outputs, session: Session): #@output @render.text # Use reactive.event() to invalidate the plot only when the button is pressed # (not when the slider is changed) @reactive.event(input.go, ignore_none=False) def verb_no_placeholder(): pred_pitch = pd.DataFrame(data={'start_speed':input.start_speed(), 'spin_rate':input.spin_rate(), 'extension':input.extension(), 'ivb':input.ivb(), 'hb':input.hb(), 'x0':input.x0(), 'z0':input.z0(), 'fb_max_velo_diff':input.start_speed() - input.fb_max_velo_diff(), 'fb_max_ivb_diff':input.ivb() - input.fb_max_ivb_diff(), 'fb_max_hb_diff':input.hb() - input.fb_max_hb_diff()}, index=[0]) #print('test') return (f'{pitch_dict[input.pitch_type()]}\n' + f'{round(100 + 12*-(model.predict(pred_pitch)[0] - mean_pitch[input.pitch_type()]) / std_pitch[input.pitch_type()])} Stuff+\n\n'+ f'Stuff+ of 100 is considered average for the pitch type.\n1 Standard Deviation is equal to 12.') # fig = plt.figure(figsize=(12, 12)) # fig.text(s='Please Select a Batter',x=0.5,y=0.5) # return app = App(app_ui, server)