HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

March Madness Simulator

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simulatormadnessmarch

Problem

It's a march madness simulator for the final 4!!!

Please be as critical as you can :)

```
# March Madness Program

import random
from bs4 import BeautifulSoup
import urllib3
import re
import time

def getTeams():
""" Get team data """
website = 'http://www.ncaa.com/rankings/basketball-men/d1'
siteData = urllib3.PoolManager().request('GET',
website).data
try:
teams = []
soup = BeautifulSoup(siteData, 'html.parser')
table = soup.find_all('table','ncaa-rankings-table')[0]
for i, row in enumerate(table.find_all('tr')):
if 1 <= i <= 4:
team = {}
for i, child in enumerate(row.children):
text = child.string
if i == 0:
team['seed'] = int(text)
elif i == 1:
team['name'] = text.split()[0]
elif i == 2:
team['record'] = [int(i) for i in text.split('-')]
team['beaten'] = []
team['eliminated'] = False
teams.append(team)
if len(teams) == 4:
return teams
else:
raise ValueError
except Exception:
return [
{
'name': 'Florida Gators',
'seed': 4,
'record': [24, 8],
'beaten': [],
'eliminated': False
}, {
'name': 'UCLA Bruins',
'seed': 3,
'record': [29, 4],
'beaten': [],
'eliminated': False
}, {
'name': 'Duke Blue Devils',
'seed': 2,
'record': [27, 8],
'beaten': [],
'eliminated': False
}, {
'name': 'North Carolina Tar Heels',
'seed': 1,
'record': [27, 7],
'bea

Solution

General things to improve:

  • fix the camelCase naming - follow PEP8 function and class method naming guidelines



  • organize imports per PEP8 (reference)



-
put your main() function call to under the if __name__ == '__main__': to avoid it being executed on import:

if __name__ == '__main__':
    main()


-
avoid hardcoded values like the list of teams you return on any exception in getTeams() function. define this list as a constant:

DEFAULT_TEAM_LIST = [...]


You may go further and keep the default team list in a JSON file which you would load if you cannot scrape the team data..

-
avoid catching bare exceptions

  • to ease debugging, specify a meaningful error message when raising built-in exceptions. Instead of raise ValueError, do something like raise ValueError("The scraped number of teams is not 4.")



  • use multi-line strings (for the strings variable definition and to replace multiple consecutive prints)



  • some functions and methods are not easily understandable - add helpful docstrings and comments



  • it feels like the Matchup class (which has only class methods defined) should be just a separate module which you would import from your main script



Scraping the teams improvements:

You can seriously improve the getTeams() function by replacing the enumerate() and index check with a slice, locating the table rows with a CSS selector and improving the way you select the row cell texts:

teams = []
for row in soup.select('table.ncaa-rankings-table tr')[1:5]:  # get 4 top rows skipping the header
    seed, name, record = row('td')[:3]  # get first 3 columns
    teams.append({
        'seed': int(seed.get_text()),
        'name': name.get_text(),
        'record': [int(item) for item in record.get_text().split("-")],
        'beaten': [],
        'eliminated': False
    })

Code Snippets

if __name__ == '__main__':
    main()
DEFAULT_TEAM_LIST = [...]
teams = []
for row in soup.select('table.ncaa-rankings-table tr')[1:5]:  # get 4 top rows skipping the header
    seed, name, record = row('td')[:3]  # get first 3 columns
    teams.append({
        'seed': int(seed.get_text()),
        'name': name.get_text(),
        'record': [int(item) for item in record.get_text().split("-")],
        'beaten': [],
        'eliminated': False
    })

Context

StackExchange Code Review Q#158528, answer score: 2

Revisions (0)

No revisions yet.