def collision_effect(self): # TODO: a proper calculation of momentum and change in speed after collisions Logger.debug("KINEMATICS: collision_effect vel before = %s", str(self._vel)) self._vel.length *= self.COEFFICIENT_OF_BORDER_COLLISION Logger.debug("KINEMATICS: collision_effect vel after = %s", str(self._vel))
def __init__(self, player_id, pitch): """ initializes Player object and creates underlying Mallet :param player_id: defines which player are you creating :param pitch: pitch is needed to calculate borders for mallet :return: """ if player_id == Player.PLAYER_RED: Logger.info("PLAYER: initializing PLAYER_RED") self.playerColor = Player.PLAYER_RED self._borders = ((pitch.i_min, (pitch.i_min + pitch.i_max) / 2), (pitch.j_min, pitch.j_max)) self._center = (200, 300) self._goal_to_score = pitch.get_right_goal() # opponent's goal else: Logger.info("PLAYER: initializing PLAYER_BLUE") self.playerColor = Player.PLAYER_BLUE self._borders = (((pitch.i_min + pitch.i_max) / 2, pitch.i_max), (pitch.j_min, pitch.j_max)) self._center = (600, 300) self._goal_to_score = pitch.get_left_goal() self._points = 0 self._name = '' self._player_id = player_id self._mallet = Mallet(20.5, self._center[0], self._center[1], 100, self, self._borders)
def circle_collision(self, object): from scripts.gamecomponents.Disc import Disc if self._pos.get_distance(object.pos) <= self._radius + object.radius: Logger.debug("KINEMATICS: border_collision distance=%s self.radius=%s object.radius=%s", str(self._pos.get_distance(object.pos)), str(self._radius), str(object.radius)) vec_pos_diff = object.pos - self._pos vec_to = self._vel.projection(vec_pos_diff) obj_vec_to = object._vel.projection(vec_pos_diff) vec_side = self._vel - vec_to obj_vec_side = object._vel - obj_vec_to after_vec_to = (vec_to * (self._mass - object._mass) + (2 * object._mass * obj_vec_to)) / ( self._mass + object._mass) after_obj_vec_to = (obj_vec_to * (object._mass - self._mass) + (2 * self._mass * vec_to)) / ( self._mass + object._mass) # Change velocity only if it is Disc if isinstance(self, Disc): self._vel = after_vec_to + vec_side if isinstance(object, Disc): object._vel = after_obj_vec_to + obj_vec_side self.apply_speed_limit() self.correct_position_post_collision(object)
def __init__(self, x_init, y_init, mass, radius, borders): Logger.debug("KINEMATICS: PhysicsObject init(x_init=%s, y_init=%s, mass=%s, radius=%s, borders=%s)", str(x_init), str(y_init), str(mass), str(radius), str(borders)) self._pos = Vector(x_init, y_init) self._mass = mass self._radius = radius self._vel = Vector(0, 0) self._borders = borders
def __init__(self, image, imagerect, position): """ :param image: shape or image to be drawn :param position: position on screen (of type Point) :param imagerect: rectangle of image to be displayed """ Logger.debug("DRAWABLE: init(position=(%s)", str(position)) self._image = image self._pos = position
def border_collision(self, axis): from scripts.gamecomponents.Disc import Disc Logger.debug("KINEMATICS: border_collision axis=%s _vel=%s", str(axis), str(self._vel)) if isinstance(self, Disc): if axis == 'x': self._vel.x = -self._vel.x self.collision_effect() self.correct_position_in_borders() if axis == 'y': self._vel.y = -self._vel.y self.collision_effect() self.correct_position_in_borders() Logger.debug("KINEMATICS: _vel=%s", str(self._vel))
def in_goal(self, i, j, r): """ :param i: x coordinates of disk :param j: y coordinates of disk :param r: radius of disk :raise: WrongTypeException if i, j or r is not type of int, OutOfRangeException if disk is out of pitch """ if abs(i - self.i) < 1.2 * r and self.j_min < j < self.j_max: Logger.debug("GOAL: in_goal returned True") return True else: Logger.debug("GOAL: in_goal returned False") return False
def find_players(self): sports247 = Sports247() footballdatabase = FootballDatabase(self.max_eligible_years) sportsreference = SportsReference(self.max_eligible_years) profootballreference = ProFootballReference() players_list = [] for index, year in enumerate(range(self.start_year, self.end_year + 1)): Logger().log("PlayerController: starting player query for " + str(year)) players = sports247.get_player_rankings(year, year, self.ranking_cutoff) players = sportsreference.get_ncaaf_career(players) players = footballdatabase.get_ncaaf_career(players) players = profootballreference.get_draft_info(players) players_df = self.get_players_df(players) if index == 0: players_df.to_csv('Players_temp.csv', index=False) else: players_df.to_csv('Players_temp.csv', mode='a', header=False, index=False) players_list.append(players) Logger().log("PlayerController: finished player query for " + str(year)) players = list(itertools.chain.from_iterable(players_list)) for index, player in enumerate(players): player.id = str(index) try: player.position_side = Player().position_sides[player.position] player.position_group = Player().position_groups[ player.position] except: player.position_side = '' player.position_group = '' return players
def get_player_rankings(self, start_year, end_year, cutoff): query_start_time = time.perf_counter() core_url = 'https://247sports.com/Season/' page_url = '-Football/CompositeRecruitRankings/?ViewPath' \ '=~%2FViews%2FSkyNet%2FPlayerSportRanking%2F_SimpleSetForSeason.ascx&InstitutionGroup' \ '=HighSchool&Page=' suffix_url = '&_=1576263470372' responses = self.get_request_responses(start_year, end_year, cutoff, core_url, page_url, suffix_url) response_chunks, num_chunks = ChunkGenerator( ).generate_response_chunks(responses) pool = Pool(processes=num_chunks) players = pool.map(self.get_player_chunk, response_chunks) pool.close() players = list(itertools.chain.from_iterable(players)) query_end_time = time.perf_counter() Logger().log_query_time( "Sports247: player rankings query completed in ", query_start_time, query_end_time) return players
def get_request_responses(self, start_year, end_year, cutoff, core_url, page_url, suffix_url): years = list(range(start_year, end_year + 1)) pages = list((range(1, math.ceil(cutoff / 50) + 1))) request_urls = [] for year in years: for page in pages: request_url = core_url \ + str(year) \ + page_url \ + str(page) \ + suffix_url request_urls.append(request_url) try: responses = grequests.map((grequests.get( u, headers=self.request_header, timeout=self.request_timeout) for u in request_urls), size=len(request_urls)) except: Logger().log("Sports247: Unable to query some/all urls for " + ', '.join(map(str, pages)) + " | " + ', '.join(map(str, years))) responses = [ response for response in responses if response is not None ] return responses
def correct_position_post_collision(self, obj): """ Dislodges objects stuck in each other. """ distance_vector = self.pos - obj.pos if distance_vector.length < self.radius + obj.radius: distance_vector.length = self.radius + obj.radius self._pos = obj.pos + distance_vector self.correct_position_in_borders() Logger.debug("KINEMATICS: correct_position_post_collision distance_vector=%s self.radius=%s obj.radius=%s", str(distance_vector), str(self.radius), str(obj.radius)) distance_vector = obj.pos - self.pos if distance_vector.length < obj.pos - self.pos: distance_vector.length = self.radius + obj.radius obj._pos = self._pos + distance_vector obj.correct_position_in_borders() Logger.debug("KINEMATICS: correct_position_post_collision distance_vector=%s self.radius=%s obj.radius=%s", str(distance_vector), str(self.radius), str(obj.radius))
def __init__(self, x, y_center, width): """ define constructor of class Goal. If the value will not be equal 'L' or 'R', the function raise the ValueError :param x: x position :param y_center: y coordinate of the center of goal :param width: width of goal which is measured along y axis. :param goal_type: 'l' for left and 'r' for right goal :return: none :raise: WrongTypeException if v is not type of int """ self.j_min = y_center - 0.5 * width self.j_max = y_center + 0.5 * width self.i = x Logger.debug("GOAL: init(jmin=%s, jmax=%s, width=%s)", str(self.j_min), str(self.j_max), str(self.i))
def get_coaches(self, coaches_df=None): if coaches_df is None: coaches = self.find_coaches() return coaches coaches_df = coaches_df.reset_index(drop=True) coach_ids = coaches_df['id'].to_list() coaches = [] for coach_id in coach_ids: coach = Coach() coach.id = str(coach_id) coach.name = coaches_df.loc[coaches_df['id'] == coach_id]['name'] coach.name = str(self.get_attribute_value(coach.name)) if coach.name == "": Logger().log( "Coach: more than 1 row found for player id. skipping coach" ) continue coach.team = coaches_df.loc[coaches_df['id'] == coach_id]['team'] coach.team = str(self.get_attribute_value(coach.team)) coach.year = coaches_df.loc[coaches_df['id'] == coach_id]['year'] coach.year = str(self.get_attribute_value(coach.year)) coach.three_star = coaches_df.loc[coaches_df['id'] == coach_id]['three_star'] coach.three_star = str(self.get_attribute_value(coach.three_star)) coach.four_star = coaches_df.loc[coaches_df['id'] == coach_id]['four_star'] coach.four_star = str(self.get_attribute_value(coach.four_star)) coach.five_star = coaches_df.loc[coaches_df['id'] == coach_id]['five_star'] coach.five_star = str(self.get_attribute_value(coach.five_star)) coach.avg = coaches_df.loc[coaches_df['id'] == coach_id]['avg'] coach.avg = str(self.get_attribute_value(coach.avg)) coach.points = coaches_df.loc[coaches_df['id'] == coach_id]['points'] coach.points = str(self.get_attribute_value(coach.points)) coach.nat_rank = coaches_df.loc[coaches_df['id'] == coach_id]['nat_rank'] coach.nat_rank = str(self.get_attribute_value(coach.nat_rank)) coach.drafted = coaches_df.loc[coaches_df['id'] == coach_id]['drafted'] coach.drafted = str(self.get_attribute_value(coach.drafted)) coaches.append(coach) return coaches
def get_teams(self, teams_df=None): if teams_df is None: teams = self.find_teams() return teams teams_df = teams_df.reset_index(drop=True) team_ids = teams_df['id'].to_list() players = [] for team_id in team_ids: team = Team() team.id = str(team_id) team.name = teams_df.loc[teams_df['id'] == team_id]['name'] team.name = str(self.get_attribute_value(team.name)) if team.name == "": Logger().log( "Player: more than 1 row found for player id. skipping player" ) continue team.conference = teams_df.loc[teams_df['id'] == team_id]['conference'] team.conference = str(self.get_attribute_value(team.conference)) team.commits = teams_df.loc[teams_df['id'] == team_id]['commits'] team.commits = str(self.get_attribute_value(team.commits)) team.year = teams_df.loc[teams_df['id'] == team_id]['year'] team.year = str(self.get_attribute_value(team.year)) team.nat_rank = teams_df.loc[teams_df['id'] == team_id]['nat_rank'] team.nat_rank = str(self.get_attribute_value(team.nat_rank)) team.five_star = teams_df.loc[teams_df['id'] == team_id]['five_star'] team.five_star = str(self.get_attribute_value(team.five_star)) team.four_star = teams_df.loc[teams_df['id'] == team_id]['four_star'] team.four_star = str(self.get_attribute_value(team.four_star)) team.three_star = teams_df.loc[teams_df['id'] == team_id]['three_star'] team.three_star = str(self.get_attribute_value(team.three_star)) team.avg = teams_df.loc[teams_df['id'] == team_id]['avg'] team.avg = str(self.get_attribute_value(team.avg)) team.points = teams_df.loc[teams_df['id'] == team_id]['points'] team.points = str(self.get_attribute_value(team.points)) players.append(team) return players
def circle_collision(self, object): from scripts.gamecomponents.Disc import Disc if self._pos.get_distance( object.pos) <= self._radius + object.radius: # impact Logger.debug( "KINEMATICS: border_collision distance=%s self.radius=%s object.radius=%s", str(self._pos.get_distance(object.pos)), str(self._radius), str(object.radius)) vec_pos_diff = object.pos - self._pos vec_to = self._vel.projection(vec_pos_diff) obj_vec_to = object._vel.projection(vec_pos_diff) vec_side = self._vel - vec_to obj_vec_side = object._vel - obj_vec_to after_vec_to = (vec_to * (self._mass - object._mass) + (2 * object._mass * obj_vec_to)) / (self._mass + object._mass) after_obj_vec_to = (obj_vec_to * (object._mass - self._mass) + (2 * self._mass * vec_to)) / (self._mass + object._mass) dx = self._pos[0] - object._pos[0] dy = self._pos[1] - object._pos[1] distance = math.hypot(dx, dy) tangent = math.atan2(dy, dx) # self._radius = 2*tangent - self._radius # object._radius = 2*tangent - object._radius (self._vel, object._vel) = (object._vel, self._vel) angle = 0.5 * math.pi + tangent # Change velocity only if it is Disc if isinstance(self, Disc): self._vel = after_vec_to + vec_side if isinstance(object, Disc): object._vel = after_obj_vec_to + obj_vec_side self.apply_speed_limit() self.correct_position_post_collision(object) self._pos[0] += math.sin(angle) self._pos[1] -= math.cos(angle) object._pos[0] -= math.sin(angle) object._pos[1] += math.cos(angle)
def correct_position_in_borders(self): """ Dislodges objects stuck in the pitch borders """ x_min, x_max = self._borders[0] y_min, y_max = self._borders[1] log = False if self.pos.x - self.radius < x_min: self.pos.x = x_min + self.radius log = True if self.pos.x + self.radius > x_max: self.pos.x = x_max - self.radius log = True if self.pos.y - self.radius < y_min: self.pos.y = y_min + self.radius log = True if self.pos.y + self.radius > y_max: self.pos.y = y_max - self.radius log = True if log: Logger.debug("KINEMATICS: correct_position_in_borders pos.x=%s pos.y=%s", str(self.pos.x), str(self.pos.y))
def __init__(self,pitch_name): """ define constructor of class Pitch. """ Logger.info("PITCH: Initializing pitch") self.i_min = 42 self.i_max = 762 self.j_min = 154 self.j_max = 562 self.i_border = 50 Logger.debug("PITCH: init i_min=%s i_max=%s j_min=%s j_max=%s i_border=%s", str(self.i_min), str(self.i_max), str(self.j_min), str(self.j_max), str(self.i_border)) goal_width = 150 j_middle = 0.5 * (self.j_min + self.j_max) self.goals = [Goal(self.i_min, j_middle, goal_width), Goal(self.i_max, j_middle, goal_width)] # drawable part # TODO better pitch image Logger.info("PITCH: loading image") # self._image = pygame.image.load("resources/graphics/pitch.png") self._image = pygame.image.load(pitch_name) self._pos = Vector(0, 0)
def update_players(self, players): Logger().log("PlayerController: starting update player query") footballdatabase = FootballDatabase(self.max_eligible_years) sportsreference = SportsReference(self.max_eligible_years) profootballreference = ProFootballReference() subset_list = [] for i in range(0, len(players), 500): subset = players[i:i + 500] subset = sportsreference.get_ncaaf_career(subset) subset = footballdatabase.get_ncaaf_career(subset) subset = profootballreference.get_draft_info(subset) subset_list.append(subset) players = list(itertools.chain.from_iterable(subset_list)) Logger().log("PlayerController: finished update player query") return players
def get_ncaaf_career(self, players): query_start_time = time.perf_counter() player_chunks, num_chunks = ChunkGenerator().generate_data_chunks( players) pool = Pool(processes=num_chunks) players = pool.map(self.get_data_chunks, player_chunks) pool.close() players = list(itertools.chain.from_iterable(players)) query_end_time = time.perf_counter() Logger().log_query_time("FootballDB: career query completed in ", query_start_time, query_end_time) return players
def find_teams(self): sports247 = Sports247() teams_list = [] for index, year in enumerate(range(self.start_year, self.end_year + 1)): Logger().log("TeamController: starting team query for " + str(year)) teams = sports247.get_team_rankings(year, year, self.ranking_cutoff) teams_df = self.get_teams_df(teams) if index == 0: teams_df.to_csv('Teams_temp.csv', mode='a', index=False) else: teams_df.to_csv('Teams_temp.csv', mode='a', header=False, index=False) teams_list.append(teams) Logger().log("TeamController: finished team query for " + str(year)) teams = list(itertools.chain.from_iterable(teams_list)) teams = sports247.add_conferences(teams) for index, team in enumerate(teams): team.id = str(index) return teams
def apply_speed_limit(self): from scripts.gamecomponents.Disc import Disc from scripts.gamecomponents.Mallet import Mallet Logger.debug("KINEMATICS: apply_speed_limit MAX_DISC_VELOCITY=%s MAX_MALLET_VELOCITY=%s vel=%s", str(self.MAX_DISC_VELOCITY), str(self.MAX_MALLET_VELOCITY), str(self._vel.length)) if isinstance(self, Disc) and self._vel.length > self.MAX_DISC_VELOCITY: Logger.debug("KINEMATICS: apply_speed_limit is a Disc") self._vel.length = self.MAX_DISC_VELOCITY if isinstance(self, Mallet) and self._vel.length > self.MAX_MALLET_VELOCITY: Logger.debug("KINEMATICS: apply_speed_limit is a Mallet") self._vel.length = self.MAX_MALLET_VELOCITY
def is_border_collision(self, object): """ check a collision between disk and a border of the pitch :param object: object with x,y,radius parameters :return: 'x' or 'y' if the collision between a disk/mallet and the border of pitch have taken place, false - if it haven't :raise: WrongTypeException if object is not type of disc/mallet """ # TODO: Is there a way to do it better ? if not isinstance(object, Disc) and not isinstance(object, Mallet): Logger.error("PITCH: is_border_collision raised WrongTypeException") raise WrongTypeException if object.pos.x - object.radius < self.i_min or object.pos.x + object.radius > self.i_max: Logger.debug("PITCH: is_border_collision return x") return 'x' if object.pos.y - object.radius < self.j_min or object.pos.y + object.radius > self.j_max: Logger.debug("PITCH: is_border_collision return y") return 'y' Logger.debug("PITCH: is_border_collision return False") return False
def move_to(self, x, y): from scripts.gamecomponents.Kinematics import Vector Logger.debug("MALLET: move_to(%s,%s) pos before =%s", str(x), str(y), str(self._pos)) move_vector = Vector(x, y) - self._pos if move_vector.length > PhysicsObject.MAX_MALLET_VELOCITY: move_vector.length = PhysicsObject.MAX_MALLET_VELOCITY self.pos.state = (self._pos.x + move_vector.x, self._pos.y + move_vector.y) Logger.debug("MALLET: move_to(%s,%s) pos after =%s", str(x), str(y), str(self._pos)) self.correct_position_in_borders() Logger.debug("MALLET: move_to(%s,%s) pos after position correction=%s", str(x), str(y), str(self._pos))
def get_team_rankings(self, start_year, end_year, cutoff): query_start_time = time.perf_counter() core_url = 'https://247sports.com/Season/' page_url = '-Football/CompositeTeamRankings/?page=' suffix_url = '' responses = self.get_request_responses(start_year, end_year, cutoff, core_url, page_url, suffix_url) response_chunks, num_chunks = ChunkGenerator( ).generate_response_chunks(responses) pool = Pool(processes=num_chunks) teams = pool.map(self.get_team_chunk, response_chunks) pool.close() teams = list(itertools.chain.from_iterable(teams)) query_end_time = time.perf_counter() Logger().log_query_time("Sports247: team rankings query completed in ", query_start_time, query_end_time) return teams
def load_image(self, image1, image2): """ Method used to load sprite for Mallet according to Player. :return: None """ from Player import Player if self._player.playerColor == Player.PLAYER_BLUE: Logger.debug("MALLET: load_image playerColor = PLAYER_BLUE") image = image1 elif self._player.playerColor == Player.PLAYER_RED: Logger.debug("MALLET: load_image playerColor = PLAYER_RED") image = image2 else: Logger.error("MALLET: Invalid value for player (" + self._player.playerColor + ")") raise ValueError('Invalid value for player (' + self._player.playerColor + ')') self._image = pygame.transform.scale( pygame.image.load(image), (int(2 * self.radius), int(2 * self.radius)))
def find_player_url(self, player, team, enrolled_year): curr_year = int(date.today().year) eligible_years = list( range(enrolled_year, enrolled_year + self.max_eligible_years)) eligible_years = [x for x in eligible_years if x <= curr_year] request_urls = [] for eligible_year in eligible_years: request_url = 'https://www.footballdb.com/college-football/teams/fbs/' \ + str(team) \ + '/roster/' \ + str(eligible_year) request_urls.append(request_url) try: responses = grequests.map((grequests.get( u, headers=self.request_header, timeout=self.request_timeout) for u in request_urls), size=len(request_urls)) except: Logger().log("FootballDB: Unable to query some/all urls for " + player.name + " | " + team + " | " + ', '.join(map(str, eligible_years)) + ', '.join(map(str, request_urls))) player_url = '' return player_url responses = [ response for response in responses if response is not None ] for response in responses: page_html = response.text page_soup = soup(page_html, "lxml") if page_soup is None: Logger().log("FootballDB: " + "no html page returned") continue roster_list = page_soup.find( "div", {"class": "divtable divtable-striped divtable-mobile"}) roster_list = roster_list.findAll( "a", href=re.compile( r"/college-football/players/")) if roster_list else [] for roster_item in roster_list: roster_player = roster_item.get_text() if roster_item else "" roster_player = " ".join(roster_player.split(",")[::-1]) roster_player = Player().trim_name(roster_player) player_of_interest = Player().trim_name(player.name) if player_of_interest == roster_player: player_url = 'https://www.footballdb.com' + roster_item[ 'href'] return player_url player_url = '' return player_url
def add_stats(self, player, player_url): if not player_url: Logger().log("FootballDB: " + "Unable to find " + player.name + " | " + player.team + " | " + player.enrolled + " | " + player_url) return player try: response = requests.get(url=player_url, headers=self.request_header, timeout=self.request_timeout) except: Logger().log("FootballDB: Unable to get web query for " + player.name + " | " + player_url) return player if response is None: Logger().log("FootballDB: " + "No query response for " + player.name + " | " + player_url) return player page_html = response.text page_soup = soup(page_html, "lxml") if page_soup is None: Logger().log("FootballDB: " + "No html page returned for " + player.name + " | " + player_url) return player stats_list = page_soup.find("table", {"class": "statistics scrollable"}) stats_list = stats_list.find("tbody") if stats_list else [] stats_list = stats_list.findAll( "tr", re.compile(r"row")) if stats_list else [] if not stats_list: Logger().log("FootballDB: " + "No stats found for " + player.name + " | " + player_url) return player enrolled_years = [] teams = [] for stats_item in stats_list: playing_year = stats_item.find("td", {"class": "center"}) playing_year = playing_year.get_text() if playing_year else "" team = stats_item.find( "a", href=re.compile(r"/college-football/teams/fbs/")) team = team['href'] if team else "" team = team.replace("/college-football/teams/fbs/", "") team = Team().get_global_name(team, 'FootballDB') if not team: team = stats_item.find("span", {"class": "hidden-xs"}) team = team.get_text() if team else "" team = re.sub("\(.*\)|\s-\s.*", "", team).strip() enrolled_years.append(playing_year) teams.append(team) if not all(x == teams[0] for x in teams): player.transferred = self.trim(teams[-1]) player.ncaaf_years = self.trim(str(len(enrolled_years))) last_enrolled_year = int(enrolled_years[-1]) curr_year = int(date.today().year) if last_enrolled_year < curr_year: player.ncaaf_status = "exhausted" else: player.ncaaf_status = "active" return player
def add_stats(self, player, player_url): if not player_url: Logger().log("SportsReference: " + "Unable to find " + player.name + " | " + player.team + " | " + player.enrolled + " | " + player_url) return player try: response = requests.get(url=player_url, headers=self.request_header, timeout=self.request_timeout) except: Logger().log("SportsReference: Unable to get web query for " + player.name + " | " + player_url) return player if response is None: Logger().log("SportsReference: " + "No query response for " + player.name + " | " + player_url) return player page_html = response.text page_soup = soup(page_html, "lxml") if page_soup is None: Logger().log("SportsReference: " + "No html page returned for " + player.name + " | " + player_url) return player stats_list = page_soup.find("div", {"id": "content"}) stats_list = stats_list.find("tbody") if stats_list else [] stats_list = stats_list.findAll("tr") if stats_list else [] if not stats_list: Logger().log("SportsReference: " + "No stats found for " + player.name + " | " + player_url) return player enrolled_years = [] teams = [] for stats_item in stats_list: playing_year = stats_item.find("a", href=re.compile(r"/cfb/years")) playing_year = playing_year.get_text() if playing_year else "" team = stats_item.find("a", href=re.compile(r"/cfb/schools/")) team = team['href'].split('/')[3] if team else "" team = Team().get_global_name(team, 'SportsReference') enrolled_years.append(playing_year) teams.append(team) if not all(x == teams[0] for x in teams): player.transferred = self.trim(teams[-1]) player.ncaaf_years = self.trim(str(len(enrolled_years))) last_enrolled_year = int(enrolled_years[-1]) curr_year = int(date.today().year) if last_enrolled_year < curr_year: player.ncaaf_status = "exhausted" else: player.ncaaf_status = "active" return player
def friction(self): Logger.debug("KINEMATICS: friction vel before = %s", str(self._vel)) self._vel.length *= self.COEFFICIENT_OF_FRICTION self._vel.length = 0 if self._vel.length < self.STOPPING_VELOCITY else self._vel.length Logger.debug("KINEMATICS: friction vel after = %s", str(self._vel))
def find_player_url(self, player, team, enrolled_year): # lets search all years the player could have been eligible curr_year = int(date.today().year) eligible_years = list( range(enrolled_year, enrolled_year + self.max_eligible_years)) eligible_years = [x for x in eligible_years if x <= curr_year] request_urls = [] for eligible_year in eligible_years: request_url = 'https://www.sports-reference.com/cfb/schools/' \ + str(team) \ + '/' \ + str(eligible_year) \ + '-roster.html' request_urls.append(request_url) try: responses = grequests.map((grequests.get( u, headers=self.request_header, timeout=self.request_timeout) for u in request_urls), size=len(request_urls)) except: Logger().log( "SportsReference: Unable to query some/all urls for " + player.name + " | " + team + " | " + ', '.join(map(str, eligible_years)) + ', '.join(map(str, request_urls))) player_url = '' return player_url responses = [ response for response in responses if response is not None ] for response in responses: page_html = response.text page_soup = soup(page_html, "lxml") if page_soup is None: Logger().log("SportsReference: " + "No html page returned for " + team) continue roster_list = page_soup.find("div", {"id": "div_roster"}) roster_list = roster_list.find("tbody") if roster_list else [] roster_list = roster_list.findAll( "a", href=re.compile(r"/cfb/players/")) if roster_list else [] for roster_item in roster_list: roster_player = Player().trim_name(roster_item.get_text()) player_of_interest = Player().trim_name(player.name) if player_of_interest == roster_player: player_url = 'https://www.sports-reference.com' + roster_item[ 'href'] return player_url player_url = '' return player_url