コード例 #1
0
    def create_player_stats_model(game, player, site_sport=None):
        """
        If site_sport is not specified, defaults to use PlayerStatsChild model

        may not work to well for baseball since there
        are 2 PlayerStats types (hitter/pitcher)
        """
        player_stats = None
        if site_sport is None:
            player_stats = PlayerStatsChild()
        else:
            ssm = SiteSportManager()
            player_stats_model_list = ssm.get_player_stats_class(site_sport)
            player_stats_model = player_stats_model_list[0]
            player_stats = player_stats_model()

        player_stats.fantasy_points = randint(0, 100)

        player_stats.game = game
        player_stats.player = player
        player_stats.srid_game = game.srid
        player_stats.srid_player = player.srid
        player_stats.position = player.position
        player_stats.save(fantasy_points_override=player_stats.fantasy_points)
        return player_stats
コード例 #2
0
    def get_player_stats(self, draft_group):
        """
        get the sports.<sport>.models.PlayerStats objects for the given draft_group
        returned in a dictionary of:

            {
                <model name> : [ list of objects ],
                <model name> : [ list of objects ],
                ... etc...
            }

        :param draft_group:
        :return:
        """
        ssm = SiteSportManager()
        game_srids = [
            x.game_srid for x in self.get_game_teams(draft_group=draft_group)
        ]
        player_stats_models = ssm.get_player_stats_class(
            sport=draft_group.salary_pool.site_sport)
        data = {}

        # fill with 0s for every player in the draft group first
        for stats_model in player_stats_models:
            # These are draftgroup.Player models!
            draft_group_players = Player.objects.filter(
                draft_group=draft_group).prefetch_related(
                    'salary_player__player__position')
            for draft_group_player in draft_group_players:
                data[draft_group_player.player_id] = {
                    stats_model.field_id: draft_group_player.player_id,
                    stats_model.field_fp: 0.0,
                    stats_model.field_pos: draft_group_player.position,
                }

        # then add the stats for the existing player stats objects
        for stats_model in player_stats_models:
            for player_stat_obj in stats_model.objects.filter(
                    srid_game__in=game_srids).select_related('position'):
                # l.append( player_stat_obj.to_json() )
                data[player_stat_obj.player_id] = player_stat_obj.to_score()

        return data
コード例 #3
0
    def get_player_stats(lineup_player):
        ssm = SiteSportManager()
        # get the player model(s) for the sport used (multiple for MLB)
        player_stats_models = ssm.get_player_stats_class(
            lineup_player.lineup.draft_group.salary_pool.site_sport)

        player_stats = []

        # check every stats model type ( ie: baseball has PlayerStatsHitter & PlayerStatsPitcher)
        for player_stats_model in player_stats_models:
            try:
                player_stats.append(
                    player_stats_model.objects.get(
                        player_id=lineup_player.player_id,
                        srid_game=lineup_player.draft_group_player.game_team.
                        game_srid).to_json())
            except player_stats_model.DoesNotExist:
                pass

        return player_stats
コード例 #4
0
    def lineup_players(obj):
        player_display = mark_safe("<ul>")
        sport = obj.draft_group.salary_pool.site_sport
        site_sport_manager = SiteSportManager()
        player_stats_classes = site_sport_manager.get_player_stats_class(sport)
        print(player_stats_classes)

        if obj.draft_group.start >= timezone.now():
            return "Cannot view the players in a lineup until it's draft group has started."

        for player in obj.players.all():
            player_stats = []

            for stats_class in player_stats_classes:
                game_srid = player.draft_group_player.game_team.game_srid
                player_stats_objects = stats_class.objects.filter(
                    srid_player=player.player.srid,
                    srid_game=game_srid
                )
                for player_stats_object in player_stats_objects:
                    player_stats.append(player_stats_object.to_json())

            player_display += format_html(
                "<li>"
                "<strong>Roster Spot:</strong> {}<br />"
                "<strong>sport.models.player:</strong> {}<br />    "
                "<strong>draftgroup.models.player:</strong> {} <br />"
                "<strong>sport.models.player_stats:</strong> {} <br /><br />"
                "</li>",
                player.roster_spot,
                "%s" % player.player,
                "%s" % player.draft_group_player,
                "%s" % player_stats,
            )

        player_display += mark_safe("</ul>")
        return player_display
コード例 #5
0
    def get_lineup_from_id(lineup_id, contest):
        """
        get lineup data we can show to other users, with masked
        out players if the contest has not started yet.

        :param lineup_id:
        :return:
        """

        data = []
        ssm = SiteSportManager()

        #
        # Get the lineup players for a lineup id
        lineup_players = LineupPlayer.objects.filter(
            lineup__pk=lineup_id).order_by('idx').select_related(
                'draft_group_player__game_team')

        #
        # sets the started flag to False if draftgroup has not started
        started = True
        if len(lineup_players
               ) > 0 and not lineup_players[0].lineup.draft_group.is_started():
            started = False

        #
        # get the player model(s) for the sport used (multiple for MLB)
        player_stats_models = ssm.get_player_stats_class(contest.site_sport)

        #
        # add all the players to the data array, but if the contest has not started make the
        # specific player information be an empty array.
        for lineup_player in lineup_players:

            #
            # check every stats model type ( ie: baseball has PlayerStatsHitter & PlayerStatsPitcher)
            category_stats = []
            for player_stats_model in player_stats_models:

                player_stats = None
                #
                # if the player is masked out in the starter map, do not display which player it is
                if not started:
                    continue

                #
                # Get the player stats if the model type applies to the player and they have stats
                try:
                    player_stats = player_stats_model.objects.get(
                        player_id=lineup_player.player_id,
                        srid_game=lineup_player.draft_group_player.game_team.
                        game_srid)
                except player_stats_model.DoesNotExist:
                    player_stats = None
                    pass

                #
                # add the stats to the data field for the given player.
                if player_stats is not None:
                    category_stats.append(player_stats.to_json())

            #
            # add the "category_stats" list  -- ie: the stats for each roster idx
            data.append({
                'started': started,
                'i': lineup_player.idx,
                'data': category_stats,
            })

        # this data is safe to return via the API because
        # the players whos games have not yet started have
        # not been shown!
        return data
コード例 #6
0
class Dummy(object):
    DEFAULT_SPORT = 'test'

    DEFAULT_ROSTER_MAP = {
        ('QB', 1, 0, True): ['QB'],
        ('WR', 1, 1, True): ['WR'],
        ('FX', 1, 2, False): ['RB', 'WR', 'TE']
    }

    #
    # DEFAULT_SPORT_FIELD_FOR_FANTASY_POINTS = {
    #     'nfl' : ['pass_yds', 'rush_yds', 'rec_yds'],
    #     'nba' : ['assists', 'rebounds', 'blocks'],
    #
    # }

    # this class will iterate these to create dummy teams
    # if game or player objects need foreign keys to them
    DEFAULT_TEAMS = [('away', 'AWAY'), ('home', 'HOME')]

    def __init__(self, sport):
        """
        Create dummy objects. This could interfere with the live site,
        and is strictly meant for testing environments, and specifically
        the "./manage.py test" tool
        """
        self.ssm = SiteSportManager()
        self.site_sport = self.ssm.get_site_sport(sport)

    def generate(self):
        """
        essentially does what generate_salaries() does, but for the
        sport this class was instantiated with, whereas generate_salaries()
        is a static method which uses the default sport and
        GameChild / PlayerChild tables.

        Use to this to make more realistic instances in the database
        of players/games/playerstats/salaries/etc...
        """
        # clear out any existing rosters with the same sport, because theyll be recreated
        Dummy.remove_existing_rosters_for_sport(site_sport=self.site_sport)
        # prerequisite calls to create_roster(), create_player_stats_list()
        Dummy.create_roster(sport=self.site_sport.name)
        Dummy.create_player_stats_list(site_sport=self.site_sport,
                                       round_start_times=True)
        # players = Dummy.create_players(n=players, site_sport=site_sport)   #  -done
        # games   = Dummy.create_games(n=games, site_sport=site_sport)       #  -done
        # create_player_stats_model( players,games)                          #  -done

        salary_conf = Dummy.create_salary_config()  # -done no changes

        pool = Pool()  # -done no changes
        pool.site_sport = self.site_sport  # -done use member variable
        pool.salary_config = salary_conf  # -done no changes
        pool.active = True  # -done default True so its useable
        pool.save()

        Dummy.create_trailing_game_weight(salary_conf, 3, 3)  # -done
        Dummy.create_trailing_game_weight(salary_conf, 7, 2)  # -done
        Dummy.create_trailing_game_weight(salary_conf, 10, 1)  # -done

        #
        # the SiteSportManager.get_player_stats_class()
        # method actually returns a list of sport.<sport>.PlayerStats subclasses for the sport
        player_stats_classes = self.ssm.get_player_stats_class(
            self.site_sport)  # -done

        generator = SalaryGenerator(player_stats_classes, pool)  # -done
        generator.generate_salaries()  # -done
        return generator  # -done

    @staticmethod
    def remove_existing_rosters_for_sport(site_sport):
        """
        call this at the beginning of create_rosters() to ensure
        that if the rosters already exist when a Dummy instance
        gets used in a test, we break down, and recreate the proper rosters.
        without adding more (which it doesnt/shouldnt handle nicely)
        :return:
        """
        if site_sport == None:
            raise Exception(
                'Dummy.remove_existing_rosters_for_sport() - site_sport not set yet'
            )

        rsps = RosterSpotPosition.objects.filter(
            roster_spot__site_sport=site_sport)
        rsps.delete()
        rps = RosterSpot.objects.filter(site_sport=site_sport)
        rps.delete()

    # Shared setup methods for the test cases
    @staticmethod
    def create_roster(sport=DEFAULT_SPORT, roster=DEFAULT_ROSTER_MAP):
        """
        example usage: the top level keys are tuples, the lists contain positions,
        each tuple key has the form: ('roster spot name',amount,idx,is_primary_boolean)
            >>> roster = {
            ...     ('QB',1,0,True)     :['QB'],
            ...     ('WR',1,1,True)     :['WR'],
            ...     ('FX',1,1,False)    :['RB','WR','TE']
            ... }
            >>> site_sport = Dummy.create_roster(sport='mysport', roster=roster ) #example!

        :param sport:
        :param roster:
        :return:
        """

        ret_roster_spot_position_list = []

        # order the incoming roster dict by the idx
        ordered_roster = OrderedDict(
            sorted(roster.items(), key=lambda k: k[0][2]))

        site_sport, created = SiteSport.objects.get_or_create(name=sport)
        # print(site_sport, 'site_sport')

        # create the roster spot mappings
        for rs_tuple, pos_names_list in ordered_roster.items():
            roster_spot_name = rs_tuple[0]
            roster_spot_amount = rs_tuple[1]
            roster_spot_idx = rs_tuple[2]
            primary = rs_tuple[3]
            # print('roster spot: %s, amount:%s, idx:%s, is_primary:%s' % (roster_spot_name,
            #                         roster_spot_amount, roster_spot_idx, primary))
            for pos_name in pos_names_list:
                #
                # 'c' is a boolean indicating whether the object was created or not
                position, c = Position.objects.get_or_create(
                    name=pos_name, site_sport=site_sport)
                # print('    ', position)
                roster_spot, c = RosterSpot.objects.get_or_create(
                    name=roster_spot_name,
                    amount=roster_spot_amount,
                    idx=roster_spot_idx,
                    site_sport=site_sport)
                # print('    ', roster_spot)
                roster_spot_position, c = RosterSpotPosition.objects.get_or_create(
                    position=position,
                    roster_spot=roster_spot,
                    is_primary=primary)
                ret_roster_spot_position_list.append(roster_spot_position)
                # print('    ', roster_spot_position)
        # print('...created!')
        return ret_roster_spot_position_list

    @staticmethod
    def create_player_stats(sport=DEFAULT_SPORT):
        """
        return a newly created player who could fit in the default roster.

        if 'roster' is None, we will call Dummy.create_roster() and use that data

        :param sport:
        :param roster:
        :return:
        """

        # ('QB',1,0,True)     :['QB'],
        position = None
        for rs_tuple, pos_list in Dummy.DEFAULT_ROSTER_MAP.items():
            for pos_name in pos_list:
                site_sport, c = SiteSport.objects.get_or_create(name=sport)
                position, c = Position.objects.get_or_create(
                    name=pos_name, site_sport=site_sport)
                break
            break
        if position is None:
            raise Exception(
                '>>>>> Dummy.create_player_stats() couldnt find any positions in roster'
            )

        dt_now = timezone.now()
        unix_ts = dt_now.strftime('%s')  # unix timestamp as srid ... not bad

        ssm = SiteSportManager()
        site_sport = ssm.get_site_sport(sport)
        game = Dummy.create_game(srid='game' + unix_ts, site_sport=site_sport)

        player = Dummy.create_player(srid='player' + unix_ts,
                                     position=position,
                                     team=game.home,
                                     site_sport=site_sport)

        if sport == Dummy.DEFAULT_SPORT:
            site_sport = None  # hack for backwards compatability, to not break older code
        player_stats = Dummy.create_player_stats_model(game, player,
                                                       site_sport)

        return player_stats

    @staticmethod
    def create_team(srid=None, alias=None, site_sport=None):
        """
        Creates a team with a random srid - based on current milliseconds.
        """
        if not srid:
            srid = "srid-%s" % int(round(time.time() * 1000)),
        if not alias:
            alias = "alias-%s" % int(round(time.time() * 1000)),

        if site_sport is None:
            t, created = TeamChild.objects.get_or_create(srid=srid,
                                                         alias=alias)
        else:
            ssm = SiteSportManager()
            team_model = ssm.get_team_class(site_sport)
            t, created = team_model.objects.get_or_create(srid=srid,
                                                          alias=alias)
        return t

    @staticmethod
    def create_game(srid=None,
                    status='scheduled',
                    away=None,
                    home=None,
                    site_sport=None,
                    round_start_times=False):
        # site_sport, created = SiteSport.objects.get_or_create(name=sport)

        ssm = SiteSportManager()
        season_model_class = ssm.get_season_class(site_sport)
        dum_srid = '%s' % site_sport
        dum_season_year = 2016
        dum_season_type = 'reg'
        dum_season, created = season_model_class.objects.get_or_create(
            srid=dum_srid,
            season_year=dum_season_year,
            season_type=dum_season_type,
        )

        if srid is None:
            srid = "srid-%s" % int(round(time.time() * 1000)),
        if away is None:
            away = Dummy.create_team(alias='AWAY', site_sport=site_sport)
        if home is None:
            home = Dummy.create_team(alias='HOME', site_sport=site_sport)

        dt_now = timezone.now()
        if round_start_times:
            # zero out the seconds and microseconds!
            dt_now = dt_now.replace(dt_now.year, dt_now.month, dt_now.day,
                                    dt_now.hour, dt_now.minute, 0, 0)

        if site_sport is None:
            game = GameChild()
        else:
            ssm = SiteSportManager()
            game_model = ssm.get_game_class(site_sport)
            game = game_model()

        game.season = dum_season  # cant be None
        game.srid = srid
        game.start = dt_now
        game.status = status

        game.away = away
        game.home = home

        game.save()
        return game

    @staticmethod
    def create_player(srid, position, team, site_sport=None):

        player = PlayerChild()
        player.srid = srid
        player.first_name = "Jon"
        player.last_name = "Doe"
        player.position = position

        player.team = team

        player.save()
        return player

    @staticmethod
    def create_player_stats_model(game, player, site_sport=None):
        """
        If site_sport is not specified, defaults to use PlayerStatsChild model

        may not work to well for baseball since there
        are 2 PlayerStats types (hitter/pitcher)
        """
        player_stats = None
        if site_sport is None:
            player_stats = PlayerStatsChild()
        else:
            ssm = SiteSportManager()
            player_stats_model_list = ssm.get_player_stats_class(site_sport)
            player_stats_model = player_stats_model_list[0]
            player_stats = player_stats_model()

        player_stats.fantasy_points = randint(0, 100)

        player_stats.game = game
        player_stats.player = player
        player_stats.srid_game = game.srid
        player_stats.srid_player = player.srid
        player_stats.position = player.position
        player_stats.save(fantasy_points_override=player_stats.fantasy_points)
        return player_stats

    @staticmethod
    def create_games(n=20, site_sport=None, round_start_times=False):
        # site_sport, created = SiteSport.objects.get_or_create(name=sport)
        dt_now = timezone.now()
        unix_ts = int(
            dt_now.strftime('%s'))  # unix timestamp as srid ... not bad
        games = []
        ssm = SiteSportManager()
        season_model_class = ssm.get_season_class(site_sport)

        # dum_srid        = '%s'%site_sport
        # dum_season_year = 2016
        # dum_season_type = 'reg'
        # dum_season, created = season_model_class.objects.get_or_create(srid=dum_srid,
        #                             season_year=dum_season_year, season_type=dum_season_type)

        for x in range(0, n):
            game = Dummy.create_game(srid='%s' % (unix_ts + x),
                                     site_sport=site_sport,
                                     round_start_times=round_start_times)
            # game.season = dum_season # cant be null
            game.start = game.start + timedelta(
                minutes=x)  # stagger each game by 1 minute
            game.save()
            games.append(game)

        return games

    @staticmethod
    def create_players(n=20, teams=DEFAULT_TEAMS, site_sport=None):
        """
        calls Dummy.create_roster() and then creates X players using the positions from the roster
        """
        team_list = []
        for t in teams:
            team, create = TeamChild.objects.get_or_create(srid=t[0],
                                                           alias=t[1])
            team_list.append(team)
        n_teams = len(team_list)

        dt_now = timezone.now()
        unix_ts = int(dt_now.strftime('%s'))
        if site_sport is None:
            Dummy.create_roster()

        Dummy.create_roster(sport=site_sport)
        positions = Position.objects.all()
        size = len(positions)
        players = []
        for x in range(0, n):
            pos_idx = x % (size)
            players.append(
                Dummy.create_player(srid='%s' % (unix_ts + x),
                                    position=positions[pos_idx],
                                    team=team_list[x % n_teams],
                                    site_sport=site_sport))
        return players

    @staticmethod
    def create_player_stats_list(players=20,
                                 games=20,
                                 site_sport=None,
                                 round_start_times=False):
        """
        calls Dummy.create_roster() as a preqrequisite

        'players' is the number of players we want to create
        'games' is the number of games for which we will generate player stats for each player for

        :param players:
        :param games:
        :return:
        """

        player_stats_list = []
        players = Dummy.create_players(
            n=players, site_sport=site_sport
        )  # n=20 is the default argument which creates 20 players
        games = Dummy.create_games(n=games,
                                   site_sport=site_sport,
                                   round_start_times=round_start_times
                                   )  # n=20 is default for game as well
        for game in games:
            for player in players:
                player_stats_list.append(
                    Dummy.create_player_stats_model(game, player, site_sport))
        # print(len(player_stats_list), 'player_stats objects created. here are the first 15...')
        # for ps in player_stats_list[:15]:
        #     print('    ', str(ps))
        return player_stats_list

    @staticmethod
    def create_salary_config():
        salary_conf = SalaryConfig()
        salary_conf.trailing_games = 10
        salary_conf.days_since_last_game_flag = 10
        salary_conf.min_games_flag = 7
        salary_conf.min_player_salary = 3000
        salary_conf.max_team_salary = 50000
        salary_conf.min_avg_fppg_allowed_for_avg_calc = 5
        salary_conf.save()
        return salary_conf

    @staticmethod
    def generate_salaries(sport=DEFAULT_SPORT, pool_active=True):
        """
        internally, in this order, calls:
            - create_roster()
            - create_player_stats_list()

        returns the SalaryGenerator which created the salaries.
        """

        # prerequisite calls to create_roster(), create_player_stats_list()
        Dummy.create_roster(sport=sport)
        site_sport, created = SiteSport.objects.get_or_create(name=sport)
        Dummy.create_player_stats_list(site_sport=site_sport)

        #
        # create the config and the pool
        site_sport, c = SiteSport.objects.get_or_create(name=sport)

        salary_conf = Dummy.create_salary_config()

        pool = Pool()
        pool.site_sport = site_sport
        pool.salary_config = salary_conf
        pool.active = pool_active
        pool.save()

        Dummy.create_trailing_game_weight(salary_conf, 3, 3)
        Dummy.create_trailing_game_weight(salary_conf, 7, 2)
        Dummy.create_trailing_game_weight(salary_conf, 10, 1)

        #
        # now use SalaryGenerator class on these objects
        player_stats_classes = [PlayerStatsChild]
        generator = SalaryGenerator(player_stats_classes, pool)
        generator.generate_salaries()
        return generator

    @staticmethod
    def create_trailing_game_weight(salary_config, through, weight):
        trailing_game_weight = TrailingGameWeight()
        trailing_game_weight.salary = salary_config
        trailing_game_weight.through = through
        trailing_game_weight.weight = weight
        trailing_game_weight.save()