2

I have a working code but find that having numerous try/except blocks to handle exceptions very inefficient. Is there a better way to do this?

The code that I am currently using is pasted below. Should I do a custom function or for loops? How do I create one?

Code has been cut short due to requirements...

rows = []
rows.append(['Name','Weight', 'Height', 'Season', 'Age', 'Tm', 'Lg', 'Pos', 'G', 'GS', 'MP', 'FG', 'FGA' , 'FGP' , 'P3' , 'PA3' , 'PP3' , 'P2' , 'PA2', 'PP2', 'eFGP' , 'FT', 'FTA' , 'FTP', 'ORB', 'DRB' , 'TRB', 'AST' , 'STL', 'BLK', 'TOV', 'PF' , 'PTS'])

for result in results[1:len(results)]:
    Name = soup.find(name="h1", attrs={"itemprop":"name"}).text.strip()
    Weight = soup.find(name="span", attrs={"itemprop":"weight"}).text.strip()
    Height = soup.find(name="span", attrs={"itemprop":"height"}).text.strip()
    # find all columns per result

    # data = result.find_all('td')
    try:
        season = result.find_all('a')[0]
        season = season.getText()
    except:
        season = 'NA'
    # check that columns have data 
        # if len(data) == 0: 
            # continue
    Season = season
    Age_find = result.find_all('td', attrs={'data-stat': 'age'})
    Tm_find = result.find_all('td', attrs={'data-stat': 'team_id'})
    Lg_find = result.find_all('td', attrs={'data-stat': 'lg_id'})
    Pos_find = result.find_all('td', attrs={'data-stat': 'pos'})
    G_find = result.find_all('td', attrs={'data-stat': 'g'})
    GS_find = result.find_all('td', attrs={'data-stat': 'gs'})
    MP_find = result.find_all('td', attrs={'data-stat': 'mp_per_g'})
    FG_find = result.find_all('td', attrs={'data-stat': 'fg_per_g'})
    FGA_find = result.find_all('td', attrs={'data-stat': 'fga_per_g'})
    FGP_find = result.find_all('td', attrs={'data-stat': 'fg_pct'})
    P3_find = result.find_all('td', attrs={'data-stat': 'fg3_per_g'})
    PA3_find = result.find_all('td', attrs={'data-stat': 'fg3a_per_g'})
    PP3_find = result.find_all('td', attrs={'data-stat': 'fg3_pct'})
    P2_find = result.find_all('td', attrs={'data-stat': 'fg2_per_g'})
    PA2_find = result.find_all('td', attrs={'data-stat': 'fg2a_per_g'})
    PP2_find = result.find_all('td', attrs={'data-stat': 'fg2_pct'})
    eFGP_find = result.find_all('td', attrs={'data-stat': 'efg_pct'})
    FT_find = result.find_all('td', attrs={'data-stat': 'ft_per_g'})
    FTA_find = result.find_all('td', attrs={'data-stat': 'fta_per_g'})
    FTP_find = result.find_all('td', attrs={'data-stat': 'ft_pct'})
    ORB_find = result.find_all('td', attrs={'data-stat': 'orb_per_g'})
    DRB_find = result.find_all('td', attrs={'data-stat': 'drb_per_g'})
    TRB_find = result.find_all('td', attrs={'data-stat': 'trb_per_g'})
    AST_find = result.find_all('td', attrs={'data-stat': 'ast_per_g'})
    STL_find = result.find_all('td', attrs={'data-stat': 'stl_per_g'})
    BLK_find = result.find_all('td', attrs={'data-stat': 'blk_per_g'})
    TOV_find = result.find_all('td', attrs={'data-stat': 'tov_per_g'})
    PF_find = result.find_all('td', attrs={'data-stat': 'pf_per_g'})
    PTS_find = result.find_all('td', attrs={'data-stat': 'pts_per_g'})

    try:
        Age = Age_find[0].getText()
    except:
        Age = 'NA'

    try:
        Tm = Tm_find[0].getText()
    except:    
        Tm = 'NA'

    try:
        Lg = Lg_find[0].getText()
    except:    
        Lg = 'NA'

    try:
        Pos = Pos_find[0].getText()
    except:    
        Pos = 'NA'

    try:
        G = G_find[0].getText()
    except:
        G = 'NA'

    try:
        GS = GS_find[0].getText()
    except:    
        GS = 'NA'

    try:
        MP = MP_find[0].getText()
    except:    
        MP = 'NA'

    try:
        FG = FG_find[0].getText()
    except:    
        FG = 'NA'

    try:
        FGA = FGA_find[0].getText()
    except:    
        FGA = 'NA'

    try:
        FGP = FGP_find[0].getText()
    except:    
        FGP = 'NA'

    try:    
        P3 = P3_find[0].getText()
    except:    
        P3 = 'NA'

    try:
        PA3 = PA3_find[0].getText()
    except:    
        PA3 = 'NA'

    try:
        PP3 = PP3_find[0].getText()
    except:    
        PP3 = 'NA'

    try:
        P2 = P2_find[0].getText()
    except:    
        P2 = 'NA'

    try:
        PA2 = PA2_find[0].getText()
    except:    
        PA2 = 'NA'

    try:
        PP2 = PP2_find[0].getText()
    except:    
        PP2 = 'NA'

    try:    
        eFGP = eFGP_find[0].getText()
    except:    
        eFGP = 'NA'

    try:    
        FT = FT_find[0].getText()
    except:    
        FT = 'NA'

    try:
        FTA = FTA_find[0].getText()
    except:    
        FTA = 'NA'

    try:
        FTP = FTP_find[0].getText()
    except:    
        FTP = 'NA'

    try:
        ORB = ORB_find[0].getText()
    except:    
        ORB = 'NA'

    try:    
        DRB = DRB_find[0].getText()
    except:    
        DRB = 'NA'

    try:
        TRB = RRB_find[0].getText()
    except:    
        TRB = 'NA'

    try:
        AST = AST_find[0].getText()
    except:    
        AST = 'NA'


    rows.append([Name, Weight, Height, Season, 
                 Age, Tm, Lg, Pos, G, GS, MP, FG, FGA, 
                 FGP, P3, PA3, PP3, P2, PA2, PP2, eFGP, FT,
                 FTA , FTP, ORB, DRB, TRB, AST, STL, BLK, TOV, PF, PTS])

with open('player_zaid.csv','w', newline='') as f_output:
    csv_output = csv.writer(f_output)
    csv_output.writerows(rows)
4
  • Which exceptions are you expecting to catch? Never use a bare except; use at least except Exception to that you don't catch things like KeyboardInterrupt. Commented Mar 2, 2019 at 14:49
  • 3
    Your issue is that you have all those variable names. Make a dictionary instead, and you can then have a common function that operates on every key/value pair of that dict Commented Mar 2, 2019 at 14:50
  • 1
    It might also be easier to simply check in this case. season = result.find_all('a'); season = season[0].getText() if season else 'NA'. In Python 3.8, you can use an assignment expression to put this on one line: season = x[0].getText() if (x := result.find_all('a')) else 'NA'. Commented Mar 2, 2019 at 14:57
  • thank you so much! thank you! Commented Mar 3, 2019 at 16:08

1 Answer 1

4

You have many sections of code that do basically the same thing, which violates the Don't Repeat Yourself (DRY) principle. The usual way to avoid that repetition is to write a function to hide the repetition.

def get_text_or_NA(container):
    try:
        result = container[0].getText()
    except:
        result = 'NA'
    return result

Then your basic code is

Age = get_text_or_NA(Age_find)
Tm = get_text_or_NA(Tm_find)
Lg = get_text_or_NA(Lg_find)

and so on.

You could similar means to remove other repetitions in your code--I'll leave those to you. And as the comment from @roganjosh states, you really should not use except: without giving an exception. Your way just hides all problem. Be more specific and hide only the exceptions you expect, so unexpected ones can be caught at a higher level.

Sign up to request clarification or add additional context in comments.

4 Comments

You could take this much further and just not have all those variable names. They should be using a dictionary.
Agree with @roganjosh.
@roganjosh: I agree with you. I focused my answer on the actual question given by the OP. Note the first line of my last paragraph, which I was typing as you gave your comment--what you note is the kind of thing I meant. I tried to give a balance of answering the actual question and giving further advice.
I didn't mention the blanket Except, that was chepner :) but fair enough, it's still a decent improvement on the original code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.