<jupyter_start><jupyter_text>Contains functions to scrape data from various baseball data sites<jupyter_code># Import statements
import requests
import pandas as pd<jupyter_output><empty_output><jupyter_text>Function to find player IDs<jupyter_code>def id_lookup(player_name:str, id_type:str = "MLB") -> str:
    '''
    Return ID for given player_name corresponding to given id_type. Defaults to MLBID.
    NOTE: Only supports MLBID for now.
    >>> id_lookup("<NAME>","MLB")
    "477132"
    >>> id_lookup("<NAME>") # Defaults to MLBID
    "519242"
    '''
    # Load in player ID data
    id_df = pd.read_excel("..\Data\SFBB-Player-ID-Map.xlsx")
    
    # Extract player ID for given name and ID type
    raw_id = id_df.loc[id_df.PLAYERNAME==player_name,"MLBID"]
    
    # Convert raw_id to string and return
    return(str(int(raw_id)))<jupyter_output><empty_output><jupyter_text>Function to scrape Brooks Baseball data<jupyter_code>def scrape_brooksbb(player:str, pitcher_or_batter: str, season:int, table_type:str,
                    batter_hand:str = '-1', pitcher_hand:str = '-1', params_dict:dict=None) -> pd.DataFrame:
    '''
    Scrapes player info from Brooks Baseball. Takes player name, if you want pitching or batting data,
    batter/pitcher handedness, desired season, and desired table. Returns pandas dataframe of desired table.
    
    table_type input currently can be 'po', 'ra', or 'usage'. pitcher_or_batter accepts 'pitcher' or 'batter'.
    
    Balls, strikes, and baserunners can also be specified as follows in params_dict input:
    params_dict={'balls':2,'strikes':0,'1b':1,'2b':0,'3b':1,'risp':0,'tto':-1}
    Baserunners are boolean 0 or 1, while balls can be 0,1,2,3 or -1 for any, and  strikes 0,1,2 or -1 for any.
    risp is -1, for False, 1 for True, 0 for Doesn't Matter
    tto can be -1 for Any, 1,2, or 3 for 3 or more.
    Batter/Pitcher Handedness params can be 'L','R', or '-1' for either.
    
    NOTE: When table_type = 'usage', batter_hand must be 'L' or 'R' and pitcher_or_batter must be 'pitcher'.
    '''
    # Get ID of given player for use in query params
    player_id = id_lookup(player)
    startDate = '01/01/' + str(season)
    endDate = '01/01/' + str(season + 1)
    
    # Create/complete query param dict to send with request
    if not params_dict:
        params_dict = {'player':player_id, 'rType':'perc', 'var':table_type,
                       'balls':-1, 'strikes':-1, '1b':0, '2b':0, '3b':0, 'risp': 0, 'tto':-1,
                       'startDate':startDate, 'endDate':endDate}
    else:
        params_dict['player'] = player_id
        params_dict['rType'] = 'perc'
        params_dict['var'] = table_type
        params_dict['startDate'] = startDate
        params_dict['endDate'] = endDate
        
    # Check if querying pitchers or hitters and send request
    # Note: site uses b_hand param for both pitchers and batters, so have to assign it here
    if pitcher_or_batter.lower().strip() == 'pitcher':
        brooksbb_url = "http://www.brooksbaseball.net/tabs.php" # For pitching data
        params_dict['b_hand'] = batter_hand
    else:
        brooksbb_url = "http://www.brooksbaseball.net/h_tabs.php" # For hitting data
        params_dict['b_hand'] = pitcher_hand
        
    req = requests.get(brooksbb_url,params=params_dict)
    
    # Extract table as pd dataframe, clean, and return
    if table_type == 'usage':
        df = pd.read_html(req.text,header=0)[0].drop_duplicates() # Raw table extraction
        df = df.iloc[1+int(df[df['Unnamed: 0'] == batter_hand + 'HH'].index.values):-1,:] # Choose hand
        df = df.shift(-1,axis=1).rename(columns={'Unnamed: 0':'Count Type'}) # Fix columns
        return(df.set_index('Count Type').dropna(axis=1)) # Set index, drop columns of NAs, return
    else:
        return(pd.read_html(req.text,header=0)[0].drop_duplicates().dropna().set_index('Pitch Type')[:-1])<jupyter_output><empty_output><jupyter_text>Function to convert Brooks BB data from string percentages to decimal values<jupyter_code>def perc_to_dec(df:pd.DataFrame, ignore_cols:list=None) -> pd.DataFrame:
    '''
    Converts df values from string percentages to float decimals. Returns pandas DataFrame.
    Can include list of columns names to ignore while performing conversion.
    '''
    # Get columns names
    perc_cols = list(df.columns)
    
    # Loop through columns and convert percentages to float decimals (just float if not in ignore_cols)
    for col in perc_cols:
        if col in ignore_cols:
            try: 
                df[col] = df[col].astype(float) # Try to convert to float
            except Exception:
                pass # Pass if can't convert to float
        else:
            df[col] = df[col].str.replace(r'\%','').astype(float)/100
    
    # Return dataframe
    return(df)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12005766062602966, 'fraction_numerical': 0.016062602965403624, 'mean_word_length': 3.2493438320209975, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '351637', 'license': 'MIT', 'n_tokens_mistral': 1648, 'n_tokens_neox': 1569, 'n_words': 450, 'path': 'Lib/bb_webscraper.ipynb', 'repo_name': 'ungersk1998/WhichPitch', 'size': '4869'}