def test_get_matchups():
    mf = Misc_Functions()
    matches = {
        "Philadelphia Flyers at Buffalo Sabres":
        ["B.Brian Elliott", "L.Linus Ullmark"],
        "New York Islanders at Pittsburgh Penguins":
        ["S.Semyon Varlamov", "T.Tristan Jarry"],
        "Edmonton Oilers at Toronto Maple Leafs":
        ["M.Mike Smith", "M.Michael Hutchinson"],
        "Anaheim Ducks at Colorado Avalanche":
        ["R.Ryan Miller", "P.Philipp Grubauer"],
        "Winnipeg Jets at Calgary Flames":
        ["C.Connor Hellebuyck", "J.Jacob Markstrom"],
        "Los Angeles Kings at Vegas Golden Knights":
        ["J.Jonathan Quick", "R.Robin Lehner"],
        "Minnesota Wild at San Jose Sharks":
        ["C.Cam Talbot", "M.Martin Jones"]
    }
    test_matchups = mf.get_matchups(matches)
    result = [["Philadelphia Flyers", "Buffalo Sabres"],
              ["New York Islanders", "Pittsburgh Penguins"],
              ["Edmonton Oilers", "Toronto Maple Leafs"],
              ["Anaheim Ducks", "Colorado Avalanche"],
              ["Winnipeg Jets", "Calgary Flames"],
              ["Los Angeles Kings", "Vegas Golden Knights"],
              ["Minnesota Wild", "San Jose Sharks"]]
    if test_matchups == result:
        print("Matchups: PASS")
    else:
        print("Matchups: FAIL")
        print(f'Returned: {test_matchups}')
        print(
            "Expected: [['Philadelphia Flyers', 'Buffalo Sabres'], ['New York Islanders', 'Pittsburgh Penguins'], ['Edmonton Oilers', 'Toronto Maple Leafs'], [ \
            'Anaheim Ducks', 'Colorado Avalanche'], ['Winnipeg Jets', 'Calgary Flames'], ['Los Angeles Kings', 'Vegas Golden Knights'], ['Minnesota Wild', 'San Jose Sharks']]"
        )
 def get_scores(self):
     mf = Misc_Functions()
     html = open('results_test.html', "r")
     # html = mf.get_page_source(
     #     f'http://www.nhl.com/ice/m_scores.htm', 1)
     soup = BeautifulSoup(html, 'html.parser')
     scores = []
     matches = soup.find_all('table', class_='gmDisplay finalState')
     for match in matches:
         contents = match.find_all('tr')
         n = 0
         for content in contents:
             if n == 0:
                 pass
             else:
                 content = content.get_text().split('\n').remove('')
                 content[1] = content[1][0]
                 scores.append(content)
             n += 1
     n = 0
     temp_result, result = [], []
     for score in scores:
         temp_result.append(score)
         if n == 1:
             result.append(temp_result)
             temp_result = []
             n = -1
         n += 1
     print(result)
     for n in result:
         print(n)
Beispiel #3
0
    def get_injuries(self):

        mf = Misc_Functions()

        url = "https://www.espn.com/nhl/injuries"

        soup = BeautifulSoup(mf.get_page_source(url, 1), 'html.parser')
        card = soup.find('div', class_="page-container cf")

        teams = card.find_all('span', class_="injuries__teamName ml2")
        players = card.find_all('tbody', class_="Table__TBODY")
        injured = []
        for player in players:
            stats = player.find_all('tr')
            for tr in stats:
                name = tr.find('a').get_text().split('  ')
                try:
                    name = f'{name[0][0]}.{name[0]} {name[1]}'
                except IndexError:
                    continue
                injured.append(name)

        return injured
class Predict_GA():
    def __init__(self, goalies, offenses):
        self.goalie = Goalie_Functions()
        self.misc = Misc_Functions()
        self.goalies = goalies
        self.offenses = offenses

    def _get_opposing_score(self, goalie):
        team = self.misc.get_player_team(goalie)
        for offense in self.offenses:
            if team != offense[0]:
                return float(offense[1])

    def get_prediction(self, array_x, array_y, offense_score):
        x = np.array(array_x).reshape((-1, 1))
        y = np.array(array_y)
        model = LinearRegression()
        model.fit(x, y)
        if model.coef_ < 0:
            return -1
        return float(model.coef_ * offense_score + model.intercept_)

    def get_ga(self):
        predictions = []
        for goalie in self.goalies:
            performances = self.goalie.get_goalie_past_performance(
                [goalie], (len(os.listdir('./matchups')) - 1))
            array_x, array_y = [], []
            for performance in performances:
                if performance[3] != 'N/A':
                    array_x.append(performance[4])
                    array_y.append(performance[3])
            if len(array_x) > 1:
                opposing_score = self._get_opposing_score(goalie)
                prediction = self.get_prediction(array_x, array_y,
                                                 opposing_score)
            else:
                continue

            if prediction > 0:
                predictions.append([goalie, prediction])
        return predictions
Beispiel #5
0
class Starting_Goalies:
    def __init__(self):
        self.mf = Misc_Functions()

    def get_starting_goalies(self):
        html = self.mf.get_page_source(
            'https://www.dailyfaceoff.com/starting-goalies/', 3)
        soup = BeautifulSoup(html, 'html.parser')

        card = soup.find('div', class_='starting-goalies-list stat-cards-list')

        names = card.find_all('h4')
        temp_matchups = []
        n = 0
        # strength = card.find_all('h5', class_='news-strength not-confirmed')
        # for news in strength:
        #     print(news.get_text())

        for __ in range(len(names) // 3):
            temp = []
            for __ in range(3):
                if names[n].get_text() == 'Cal Petersen':
                    temp.append('Calvin Petersen')
                else:
                    temp.append(names[n].get_text())
                n += 1
            temp_matchups.append(temp)
        matchups = {}
        for matchup in temp_matchups:
            matchups[matchup[0]] = {}
            matchups[matchup[0]] = [
                f'{matchup[1][0]}.{matchup[1]}',
                f'{matchup[2][0]}.{matchup[2]}'
            ]

        return matchups
Beispiel #6
0
 def __init__(self):
     self.mf = Misc_Functions()
Beispiel #7
0
class Goalie_Functions():
    def __init__(self):
        self.mf = Misc_Functions()

    def get_goalie_score(self, matchup: list[str]) -> list[str]:
        result = []
        for goalie in matchup:
            score = 0
            try:
                svp = float(self.mf.recent_data['goalies'][goalie]['sv%'])
                so = float(self.mf.recent_data['goalies'][goalie]['so'])
                l = int(self.mf.recent_data['goalies'][goalie]['l'])
                gs = int(self.mf.recent_data['goalies'][goalie]['gs'])
                ga = int(self.mf.recent_data['goalies'][goalie]['ga'])
                sa = int(self.mf.recent_data['goalies'][goalie]['sa'])
                if ga == 0:
                    score = ((gs) + (svp) + sa) * (1 + so * .25)
                elif l == 0:
                    score = ((gs) + (svp) + (sa / ga)) * (1 + so * .25)
                else:
                    score = ((gs / l) + (svp) + (sa / ga)) * (1 + so * .25)

            except KeyError:
                print(f'No data for {goalie}')
                continue

            team = self.mf.get_player_team(goalie)
            result.append([goalie, team, "{:.2f}".format(score)])
        return result

    def _get_goalie_last_matchup(self, data, i, team, n):
        offense = Skater_Functions()
        matchup = f'./matchups/matchups_{self.mf.get_date(n - i)}.json'
        opposing_team = str
        with open(matchup) as f:
            matchup_data = json.load(f)
        for element in matchup_data:
            if team in element:
                for teams in element:
                    if element == team:
                        pass
                    opposing_team = team
                continue

        result = []
        try:
            for skater in data['teams'][opposing_team]:
                try:
                    result.append(
                        offense.get_skater_score(
                            data['teams'][opposing_team][skater]))
                except:
                    continue
            return sum(result) / len(result)
        except KeyError:
            return 0

    def get_goalie_past_performance(self,
                                    matchup: list[str],
                                    n: int = 7) -> list[str]:
        result = []
        for goalie in matchup:
            last_gp, last_ga, gaa = 0, 0, 0
            team = self.mf.get_player_team(goalie)
            for i in range(n):
                current_file = f'./nhl_stats/{self.mf.get_date(n - i)}.json'
                with open(current_file) as f:
                    data = json.load(f)
                try:
                    gp = data['goalies'][goalie]['gp']
                    ga = data['goalies'][goalie]['ga']
                    gaa = data['goalies'][goalie]['gaa']
                except KeyError:
                    continue
                if last_gp == 0:
                    last_gp, last_ga = gp, ga
                    continue
                if gp == last_gp:
                    result.append(
                        [goalie, gaa,
                         self.mf.get_date(n - i), 'N/A', 'N/A'])
                else:
                    self._get_goalie_last_matchup(data, i, team, n)
                    result.append([
                        goalie, gaa,
                        self.mf.get_date(n - i),
                        int(ga) - int(last_ga),
                        self._get_goalie_last_matchup(data, i, team, n)
                    ])
                    last_ga, last_gp = ga, gp
        return result
 def __init__(self, goalies, offenses):
     self.goalie = Goalie_Functions()
     self.misc = Misc_Functions()
     self.goalies = goalies
     self.offenses = offenses
Beispiel #9
0
async def main():
    mf = Misc_Functions()
    matchups = f'./matchups/matchups_{mf.get_date(0)}.json'
    today_data = f'./nhl_stats/{mf.get_date(0)}.json'
    yesterday_data = f'./nhl_stats/{mf.get_date(1)}.json'
    starting_goalies = mf.read_data('starting_goalies')

    def get_report():
        skaters = Skater_Functions()
        goalies = Goalie_Functions()
        matchup = []
        print(
            f'\n{bcolors.HEADER}{bcolors.BOLD}{datetime.datetime.now()}{bcolors.ENDC}\n \n')
        for matchups in starting_goalies:
            matchup = matchups.split(' at ')
            matchup[0], matchup[1] = matchup[0].strip(), matchup[1].strip()
            print(f'{bcolors.BOLD}{matchups}{bcolors.ENDC}')
            print('\nGoalie Performance')
            for gme_ds in goalies.get_goalie_past_performance(starting_goalies[matchups]):
                if gme_ds[3] == 'N/A':
                    print(
                        f'{gme_ds[0]} ({gme_ds[1]}) {gme_ds[2]}: {bcolors.WARNING}No Game{bcolors.ENDC}')
                else:
                    print(
                        f'{gme_ds[0]} ({gme_ds[1]}) {gme_ds[2]}: {gme_ds[3]} ga to a {"{:.4f}".format(gme_ds[4])} offense')
            print()
            for goalie in goalies.get_goalie_score(starting_goalies[matchups]):
                print(f'{goalie[0]} ({goalie[1]}): {goalie[2]}')
            print('\nOffensive Matchup')
            for offense in skaters.get_offense_score(matchup):
                print(offense[0], offense[1])
            print('\nEstimated Goals Against')
            pg = Predict_GA(
                starting_goalies[matchups], skaters.get_offense_score(matchup))
            print(pg.get_ga())
            print()

    if path.exists(yesterday_data) == False and datetime.datetime.now().hour < 16:
        players = Player_Stats()
        print(
            f'{bcolors.FAIL}Forgot to run yesterday\'s data. Be sure to change the file date and run again{bcolors.ENDC}')
        print('\n \n \n')
        players.write_daily_data()
        sys.exit(0)

    # Adjust hour based on when you want the goalie matchups
    # 15 should be standard time for weekdays
    if datetime.datetime.now().hour <= 8:
        mf = Misc_Functions()
        starters = Starting_Goalies()
        ir = Injury_Report()
        print('Refreshing Starting Goalies... \n')
        starting_goalies = starters.get_starting_goalies()
        print('Refreshing Injuries... \n')
        injuries = ir.get_injuries()
        mf.write_data(starting_goalies, "starting_goalies")
        mf.write_data(injuries, "injuries")
        if path.exists(matchups) == False:
            matchups = mf.get_matchups(starting_goalies)
            mf.write_data(matchups, "matchups")

    if path.exists(today_data) == False and datetime.datetime.now().hour > 20:
        players = Player_Stats()
        print()
        print(f'{bcolors.OKGREEN}Adding tonight\'s data{bcolors.ENDC}')
        print()
        time.sleep(2)
        players.write_daily_data()
        # also write scores data

    get_report()
class Player_Stats():
    def __init__(self):
        self.mf = Misc_Functions()

    def html_to_text(self, html_text):
        result = []
        temp_res = []
        for line in html_text:
            line = line.get_text().split('\n')
            for element in line:
                if element:
                    temp_res.append(element)
            temp_res[0] = temp_res[0].lstrip()
            result.append(temp_res)
            temp_res = []
        return result

    def format_player(self, player, ptype):
        player_dict = {}
        if ptype == 'goalie':
            player_dict['player'] = player[0]
            player_dict['gp'] = player[1]
            player_dict['gs'] = player[2]
            player_dict['w'] = player[3]
            player_dict['l'] = player[4]
            player_dict['t'] = player[5]
            player_dict['ot'] = player[6]
            player_dict['sa'] = player[7]
            player_dict['ga'] = player[8]
            player_dict['gaa'] = player[9]
            player_dict['s'] = player[10]
            player_dict['sv%'] = player[11]
            player_dict['so'] = player[12]
            player_dict['min'] = player[13]

        elif ptype == 'skater':
            player_dict['player'] = player[0]
            player_dict['gp'] = player[1]
            player_dict['g'] = player[2]
            player_dict['a'] = player[3]
            player_dict['p'] = player[4]
            player_dict['+/-'] = player[5]
            player_dict['pim'] = player[6]
            player_dict['ppg'] = player[7]
            player_dict['ppp'] = player[8]
            # smg is a typo for shg
            player_dict['smg'] = player[9]
            player_dict['shp'] = player[10]
            player_dict['gwg'] = player[11]
            player_dict['otg'] = player[12]
            player_dict['s'] = player[13]
            player_dict['s%'] = player[14]
            player_dict['fo%'] = player[15]

        return player_dict

    def get_data(self, team_names):
        nhl_stats = {}
        nhl_stats['goalies'] = {}
        nhl_stats['skaters'] = {}
        nhl_stats['teams'] = {}

        for team in team_names:
            url = f'https://www.nhl.com/{team}/stats/regular-season'
            html = self.mf.get_page_source(url, 2)
            soup = BeautifulSoup(html, 'html.parser')

            team_title = soup.find('title')
            try:
                team_name = team_title.get_text().split('|')[2].strip()
                print(f"{team_name}, complete")
            except IndexError as i:
                print(f"{team}: {i}")
                continue
            nhl_stats['teams'][team_name] = {}

            # Goalies
            goalie_div = soup.find('div', id='goalie-table')
            goalies = goalie_div.find_next('tbody').find_all('tr')

            # Skaters
            skater_div = soup.find('div', id='skater-table')
            skaters = skater_div.find_next('tbody').find_all('tr')

            skaters = self.html_to_text(skaters)
            goalies = self.html_to_text(goalies)

            for goalie in goalies:
                goalie_dict = self.format_player(goalie, 'goalie')
                nhl_stats['goalies'][goalie[0]] = goalie_dict

                team_goalie_dict = self.format_player(goalie, 'goalie')
                nhl_stats['teams'][team_name][goalie[0]] = team_goalie_dict

            for skater in skaters:
                skater_dict = self.format_player(skater, 'skater')
                nhl_stats['skaters'][skater[0]] = skater_dict

                team_skater_dict = self.format_player(skater, 'skater')
                nhl_stats['teams'][team_name][skater[0]] = team_skater_dict

        return nhl_stats

    def write_daily_data(self):
        all_teams = ['ducks', 'coyotes', 'canucks', 'bruins', 'predators', 'blues',
                     'flames', 'sabres', 'hurricanes', 'blackhawks', 'avalanche', 'stars',
                     'redwings', 'oilers', 'panthers', 'kings', 'wild', 'canadiens', 'devils',
                     'islanders', 'rangers', 'senators', 'flyers', 'penguins', 'sharks', 'bluejackets',
                     'lightning', 'mapleleafs', 'goldenknights', 'capitals', 'jets']
        stats = self.get_data(all_teams)
        self.mf.write_data(stats, "perm")