示例#1
0
class Role(SurrogatePK, Model):
    """A role for a user."""

    __tablename__ = 'roles'
    name = Column(db.String(80), unique=True, nullable=False)
    user_id = reference_col('users', nullable=True)
    user = relationship('User', backref='roles')

    def __init__(self, name, **kwargs):
        """Create instance."""
        db.Model.__init__(self, name=name, **kwargs)

    def __repr__(self):
        """Represent instance as a unique string."""
        return '<Role({name})>'.format(name=self.name)
示例#2
0
文件: models.py 项目: zoro13/league
class Player(SurrogatePK, Model):
    """A player."""

    __tablename__ = 'players'

    first_name = Column(db.String(30))
    last_name = Column(db.String(30))
    aga_id = Column(db.Integer, index=True, unique=True)
    aga_rank = Column(db.Integer)

    white_player_games = relationship('WhitePlayerGame', backref='player')
    white_games = association_proxy('white_player_games', 'game')

    black_player_games = relationship('BlackPlayerGame', backref='player')
    black_games = association_proxy('black_player_games', 'game')

    def __init__(self, first_name, last_name, aga_id, aga_rank):
        """Initialize player."""
        self.first_name = first_name
        self.last_name = last_name
        self.aga_id = aga_id
        self.aga_rank = aga_rank

    def __repr__(self):
        """Represent instance as a unique string."""
        return ('<Player({first_name}, {last_name}, {aga_id})>'.format(
            first_name=self.first_name,
            last_name=self.last_name,
            aga_id=self.aga_id))

    @property
    def games(self):
        """All games that player has played."""
        return self.black_games + self.white_games

    @property
    def full_name(self):
        """Full player name."""
        return '{0} {1}'.format(self.first_name, self.last_name)

    @classmethod
    def get_by_aga_id(cls, aga_id):
        """Get player by AGA ID."""
        return cls.query.filter_by(aga_id=aga_id)[0]

    @classmethod
    def get_players(cls):
        """Get all players."""
        return cls.query.all()

    def latest_season(self):
        """Get latest season player has played in."""
        return sorted([game.season for game in self.games])[-1]

    def season_stats(self, season=None):
        """Get player statistics for a season."""
        if season is None:
            season = self.latest_season()
        wins, losses = 0, 0
        for game in ([game for game in self.games if game.season == season]):
            if ((game.winner == Color.white and game.white == self)
                    or (game.winner == Color.black and game.black == self)):
                wins += 1
            else:
                losses += 1

        return {'wins': wins, 'losses': losses}

    def latest_episode(self):
        """Get latest episode player has played in."""
        return sorted([game.episode for game in self.games])[-1]

    def episode_stats(self, episode=None, season=None):
        """Get player statistics for an episode."""
        if episode is None:
            episode = self.latest_episode()
        if season is None:
            season = self.latest_season()
        wins, losses = 0, 0
        for game in ([
                game for game in self.games
                if game.season == season and game.episode == episode
        ]):
            if ((game.winner == Color.white and game.white == self)
                    or (game.winner == Color.black and game.black == self)):
                wins += 1
            else:
                losses += 1

        return {'wins': wins, 'losses': losses}

    def league_stats(self):
        """Get player statistics for the whole league."""
        wins, losses = 0, 0
        for game in self.games:
            if ((game.winner == Color.white and game.white == self)
                    or (game.winner == Color.black and game.black == self)):
                wins += 1
            else:
                losses += 1

        return {'wins': wins, 'losses': losses}
示例#3
0
文件: models.py 项目: zoro13/league
class Game(SurrogatePK, Model):
    """A game record."""

    __tablename__ = 'games'

    white_player_game = relationship('WhitePlayerGame',
                                     backref='game',
                                     cascade='all, delete-orphan',
                                     uselist=False)
    white = association_proxy('white_player_game',
                              'player',
                              creator=lambda pl: WhitePlayerGame(player=pl))

    black_player_game = relationship('BlackPlayerGame',
                                     backref='game',
                                     cascade='all, delete-orphan',
                                     uselist=False)
    black = association_proxy('black_player_game',
                              'player',
                              creator=lambda pl: BlackPlayerGame(player=pl))

    winner = Column(db.Enum(Color))
    handicap = Column(db.SmallInteger)
    komi = Column(db.SmallInteger)
    season = Column(db.Integer)
    episode = Column(db.Integer)

    created_at = Column(db.DateTime,
                        nullable=False,
                        default=dt.datetime.utcnow)
    played_at = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow)
    last_modified_at = Column(db.DateTime,
                              nullable=False,
                              default=dt.datetime.utcnow)

    db.Index('ix_games_season_episode', 'season', 'episode')

    def __init__(self,
                 white,
                 black,
                 winner,
                 handicap,
                 komi,
                 season,
                 episode,
                 created_at=None,
                 played_at=None,
                 last_modified_at=None):
        """Initialize game."""
        self.white = white
        self.black = black
        self.winner = winner
        self.handicap = handicap
        self.komi = komi
        self.season = season
        self.episode = episode
        self.created_at = created_at
        self.played_at = played_at
        self.last_modified_at = last_modified_at

    def __repr__(self):
        """Represent instance as a unique string."""
        return ('<Game({white!r}, {black!r}, {winner}, {handicap}, {komi})>'.
                format(white=self.white,
                       black=self.black,
                       winner=self.winner,
                       handicap=self.handicap,
                       komi=self.komi))

    def to_dict(self):
        """Return game as dictionary."""
        return {
            'game_id': self.id,
            'white_id': self.white.id,
            'black_id': self.black.id,
            'winner': self.winner.name,
            'handicap': self.handicap,
            'komi': self.komi,
            'season': self.season,
            'episode': self.episode,
            'created_at': str(self.created_at),
            'played_at': str(self.played_at),
            'last_modified_at': str(self.last_modified_at)
        }

    def update(self, **kwargs):
        """Override update method to reset last_modified_at."""
        self.last_modified_at = dt.datetime.utcnow()
        super().update(**kwargs)

    @classmethod
    def get_by_season_ep(cls, season, episode):
        """Get games by season and episode."""
        return cls.query.filter_by(season=season, episode=episode)

    @classmethod
    def get_max_season_ep(cls):
        """Get maximum season and episode."""
        max_season, max_episode = session.query(func.max(cls.season),
                                                func.max(cls.episode)).one()

        max_season = 0 if max_season is None else max_season
        max_episode = 0 if max_episode is None else max_episode

        return (max_season, max_episode)

    @property
    def players(self):
        """Get players in game as set."""
        return frozenset((self.white, self.black))

    @classmethod
    def latest_episode(cls):
        """Get latest episode."""
        games = cls.query.all()
        if len(games) > 0:
            return sorted([game.episode for game in games])[-1]
        else:
            return 1

    @classmethod
    def latest_season(cls):
        """Get latest season."""
        games = cls.query.all()
        if len(games) > 0:
            return sorted([game.season for game in games])[-1]
        else:
            return 1

    @classmethod
    def episode_stats(cls, episode=None, season=None, num_players=5):
        """Get statistics for an episode."""
        if episode is None:
            episode = cls.latest_episode()
        if season is None:
            season = cls.latest_season()
        wins, games_played = {}, {}
        games = [
            game for game in cls.query.all()
            if game.season == season and game.episode == episode
        ]
        for game in games:
            if game.winner is Color.white:
                wins[game.white.id] = wins.get(game.white.id, 0) + 1
            else:
                wins[game.black.id] = wins.get(game.black.id, 0) + 1
            games_played[game.white.id] = games_played.get(game.white.id,
                                                           0) + 1
            games_played[game.black.id] = games_played.get(game.black.id,
                                                           0) + 1

        wins_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_wins)
                    for player_id, player_wins in wins.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        games_played_list = enumerate(
            sorted(
                [(Player.get_by_id(player_id), player_games_played)
                 for player_id, player_games_played in games_played.items()],
                key=lambda stat: stat[1],
                reverse=True)[0:num_players])

        return {'wins': wins_list, 'games_played': games_played_list}
示例#4
0
class Game(SurrogatePK, Model):
    """A game record."""

    __tablename__ = 'games'

    white_player_game = relationship('WhitePlayerGame',
                                     backref='game',
                                     cascade='all, delete-orphan',
                                     uselist=False)
    white = association_proxy('white_player_game',
                              'player',
                              creator=lambda pl: WhitePlayerGame(player=pl))

    black_player_game = relationship('BlackPlayerGame',
                                     backref='game',
                                     cascade='all, delete-orphan',
                                     uselist=False)
    black = association_proxy('black_player_game',
                              'player',
                              creator=lambda pl: BlackPlayerGame(player=pl))

    winner = Column(db.Enum(Color))
    handicap = Column(db.SmallInteger)
    komi = Column(db.SmallInteger)
    season = Column(db.Integer)
    episode = Column(db.Integer)

    created_at = Column(db.DateTime,
                        nullable=False,
                        default=dt.datetime.utcnow)
    played_at = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow)
    last_modified_at = Column(db.DateTime,
                              nullable=False,
                              default=dt.datetime.utcnow)

    db.Index('ix_games_season_episode', 'season', 'episode')

    def __init__(self,
                 white,
                 black,
                 winner,
                 handicap,
                 komi,
                 season,
                 episode,
                 created_at=None,
                 played_at=None,
                 last_modified_at=None):
        """Initialize game."""
        self.white = white
        self.black = black
        self.winner = winner
        self.handicap = handicap
        self.komi = komi
        self.season = season
        self.episode = episode
        self.created_at = created_at
        self.played_at = played_at
        self.last_modified_at = last_modified_at

    def __repr__(self):
        """Represent instance as a unique string."""
        return ('<Game({white!r}, {black!r}, {winner}, {handicap}, {komi})>'.
                format(white=self.white,
                       black=self.black,
                       winner=self.winner,
                       handicap=self.handicap,
                       komi=self.komi))

    def to_dict(self):
        """Return game as dictionary."""
        return {
            'game_id': self.id,
            'white_id': self.white.id,
            'black_id': self.black.id,
            'winner': self.winner.name,
            'handicap': self.handicap,
            'komi': self.komi,
            'season': self.season,
            'episode': self.episode,
            'created_at': str(self.created_at),
            'played_at': str(self.played_at),
            'last_modified_at': str(self.last_modified_at)
        }

    def update(self, **kwargs):
        """Override update method to reset last_modified_at."""
        self.last_modified_at = dt.datetime.utcnow()
        super().update(**kwargs)

    @classmethod
    def get_by_season_ep(cls, season, episode):
        """Get games by season and episode."""
        return cls.query.filter_by(season=season, episode=episode)

    @classmethod
    def get_by_season(cls, season):
        """Get games by season."""
        return cls.query.filter_by(season=season)

    @classmethod
    def get_max_season_ep(cls):
        """Get maximum season and episode."""
        max_season, max_episode = session.query(func.max(cls.season),
                                                func.max(cls.episode)).one()

        max_season = 0 if max_season is None else max_season
        max_episode = 0 if max_episode is None else max_episode

        return (max_season, max_episode)

    @property
    def players(self):
        """Get players in game as set."""
        return frozenset((self.white, self.black))

    @classmethod
    def latest_season_episode(cls):
        """Get latest episode and season."""
        games = cls.query.all()
        if len(games) > 0:
            return sorted([(game.season, game.episode) for game in games])[-1]
        else:
            return (0, 0)

    @classmethod
    def episode_stats(cls, episode=None, season=None, num_players=5):
        """Get statistics for an episode."""
        latest_season_episode = cls.latest_season_episode()
        if episode is None:
            episode = latest_season_episode[1]
        if season is None:
            season = latest_season_episode[0]

        players = Player.query.all()
        wins = {p.id: 0 for p in players}
        games_played = {p.id: 0 for p in players}
        stones_given = {p.id: 0 for p in players}
        dans_slain = {p.id: 0 for p in players}
        kyus_killed = {p.id: 0 for p in players}

        games = [
            game for game in cls.query.all()
            if game.season == season and game.episode == episode
        ]
        for game in games:
            if game.winner is Color.white:
                wins[game.white.id] = wins.get(game.white.id, 0) + 1
            else:
                wins[game.black.id] = wins.get(game.black.id, 0) + 1

            games_played[game.white.id] = games_played.get(game.white.id,
                                                           0) + 1
            games_played[game.black.id] = games_played.get(game.black.id,
                                                           0) + 1

            stones_given[game.white.id] = \
                stones_given[game.white.id] + (game.handicap)

            black_player = Player.get_by_id(game.black.id)
            white_player = Player.get_by_id(game.white.id)
            if (white_player.aga_rank > 0 and black_player.aga_rank < 0
                    and game.winner is Color.black):
                dans_slain[game.black.id] = \
                    dans_slain.get(game.black.id, 0) + 1
            elif (black_player.aga_rank > 0 and white_player.aga_rank < 0
                  and game.winner is Color.white):
                dans_slain[game.white.id] = \
                    dans_slain.get(game.white.id, 0) + 1

            if (white_player.aga_rank > 0 and black_player.aga_rank < 0
                    and game.winner is Color.white):
                kyus_killed[game.white.id] = \
                    kyus_killed.get(game.white.id, 0) + 1
            elif (black_player.aga_rank > 0 and white_player.aga_rank < 0
                  and game.winner is Color.black):
                kyus_killed[game.black.id] = \
                    kyus_killed.get(game.black.id, 0) + 1

        win_ratios = {
            p.id: wins[p.id] / games_played[p.id]
            for p in players if games_played[p.id] > 0
        }

        wins_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_wins)
                    for player_id, player_wins in wins.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        games_played_list = enumerate(
            sorted(
                [(Player.get_by_id(player_id), player_games_played)
                 for player_id, player_games_played in games_played.items()],
                key=lambda stat: stat[1],
                reverse=True)[0:num_players])

        win_ratios_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_win_ratio)
                    for player_id, player_win_ratio in win_ratios.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        stones_given_list = enumerate(
            sorted(
                [(Player.get_by_id(player_id), player_stones_given)
                 for player_id, player_stones_given in stones_given.items()],
                key=lambda stat: stat[1],
                reverse=True)[0:num_players])

        dans_slain_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_dans_slain)
                    for player_id, player_dans_slain in dans_slain.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        kyus_killed_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_kyus_killed)
                    for player_id, player_kyus_killed in kyus_killed.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        return {
            'wins': wins_list,
            'games_played': games_played_list,
            'win_ratios': win_ratios_list,
            'stones_given': stones_given_list,
            'dans_slain': dans_slain_list,
            'kyus_killed': kyus_killed_list
        }

    @classmethod
    def season_stats(cls, season=None, num_players=5):
        """Get statistics for a season."""
        latest_season_episode = cls.latest_season_episode()
        if season is None:
            season = latest_season_episode[0]

        players = Player.query.all()
        wins_minus_losses = {p.id: 0 for p in players}
        wins = {p.id: 0 for p in players}
        games_played = {p.id: 0 for p in players}
        games_played_one_ep = {p.id: 0 for p in players}
        dans_slain = {p.id: 0 for p in players}
        kyus_killed = {p.id: 0 for p in players}
        games_against_weaker = {p.id: 0 for p in players}
        losses = {p.id: 0 for p in players}

        games_per_ep = {
            p.id: {ep: 0
                   for ep in range(1, latest_season_episode[1] + 1)}
            for p in players
        }
        wins_per_ep = {
            p.id: {ep: 0
                   for ep in range(1, latest_season_episode[1] + 1)}
            for p in players
        }
        losses_per_ep = {
            p.id: {ep: 0
                   for ep in range(1, latest_season_episode[1] + 1)}
            for p in players
        }

        games = [game for game in cls.query.all() if game.season == season]
        for game in games:
            if game.winner is Color.white:
                wins[game.white.id] = wins.get(game.white.id, 0) + 1
                wins_per_ep[game.white.id][game.episode] = \
                    wins_per_ep[game.white.id][game.episode] + 1

                losses[game.black.id] = losses.get(game.black.id, 0) + 1
                losses_per_ep[game.black.id][game.episode] = \
                    losses_per_ep[game.black.id][game.episode] + 1
            else:
                wins[game.black.id] = wins.get(game.black.id, 0) + 1
                wins_per_ep[game.black.id][game.episode] = \
                    wins_per_ep[game.black.id][game.episode] + 1

                losses[game.white.id] = losses.get(game.white.id, 0) + 1
                losses_per_ep[game.white.id][game.episode] = \
                    losses_per_ep[game.white.id][game.episode] + 1

            games_played[game.white.id] = games_played.get(game.white.id,
                                                           0) + 1
            games_played[game.black.id] = games_played.get(game.black.id,
                                                           0) + 1

            games_per_ep[game.white.id][game.episode] = \
                games_per_ep[game.white.id][game.episode] + 1
            games_per_ep[game.black.id][game.episode] = \
                games_per_ep[game.black.id][game.episode] + 1

            black_player = Player.get_by_id(game.black.id)
            white_player = Player.get_by_id(game.white.id)
            if (white_player.aga_rank > 0 and black_player.aga_rank < 0
                    and game.winner is Color.black):
                dans_slain[game.black.id] = \
                    dans_slain.get(game.black.id, 0) + 1
            elif (black_player.aga_rank > 0 and white_player.aga_rank < 0
                  and game.winner is Color.white):
                dans_slain[game.white.id] = \
                    dans_slain.get(game.white.id, 0) + 1

            if (white_player.aga_rank > 0 and black_player.aga_rank < 0
                    and game.winner is Color.white):
                kyus_killed[game.white.id] = \
                    kyus_killed.get(game.white.id, 0) + 1
            elif (black_player.aga_rank > 0 and white_player.aga_rank < 0
                  and game.winner is Color.black):
                kyus_killed[game.black.id] = \
                    kyus_killed.get(game.black.id, 0) + 1

            if (white_player.aga_rank > black_player.aga_rank):
                games_against_weaker[game.white.id] = \
                    games_against_weaker[game.white.id] + 1

            if (black_player.aga_rank > white_player.aga_rank):
                games_against_weaker[game.black.id] = \
                    games_against_weaker[game.black.id] + 1

        games_played_one_ep = {
            p.id: max([g for (d, g) in games_per_ep[p.id].items()])
            for p in players
        }

        wins_minus_losses = {
            p.id: 2 * wins[p.id] - games_played[p.id]
            for p in players if games_played[p.id] > 0
        }

        wins_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_wins)
                    for player_id, player_wins in wins.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        games_played_list = enumerate(
            sorted(
                [(Player.get_by_id(player_id), player_games_played)
                 for player_id, player_games_played in games_played.items()],
                key=lambda stat: stat[1],
                reverse=True)[0:num_players])

        games_played_one_ep_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_games_played_one_ep)
                    for player_id, player_games_played_one_ep in
                    games_played_one_ep.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        wins_minus_losses_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_wins_minus_losses)
                    for player_id, player_wins_minus_losses in
                    wins_minus_losses.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        games_against_weaker_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_games_against_weaker)
                    for player_id, player_games_against_weaker in
                    games_against_weaker.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        dans_slain_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_dans_slain)
                    for player_id, player_dans_slain in dans_slain.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        kyus_killed_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_kyus_killed)
                    for player_id, player_kyus_killed in kyus_killed.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        losses_list = enumerate(
            sorted([(Player.get_by_id(player_id), player_losses)
                    for player_id, player_losses in losses.items()],
                   key=lambda stat: stat[1],
                   reverse=True)[0:num_players])

        steady_freddy = [
            p for p in players
            if min([g for (d, g) in games_per_ep[p.id].items()]) > 0
        ]

        fifteen_min_fame = [
            p for p in players if len([
                g for (d, g) in games_per_ep[p.id].items()
                if (wins_per_ep[p.id][d] >= 3 and losses_per_ep[p.id][d] == 0)
            ]) > 0
        ]

        rock_bottom = [
            p for p in players if len([
                g for (d, g) in games_per_ep[p.id].items()
                if (losses_per_ep[p.id][d] >= 3 and wins_per_ep[p.id][d] == 0)
            ]) > 0
        ]

        return {
            'wins': wins_list,
            'games_played': games_played_list,
            'games_played_one_ep': games_played_one_ep_list,
            'wins_minus_losses': wins_minus_losses_list,
            'games_against_weaker': games_against_weaker_list,
            'dans_slain': dans_slain_list,
            'kyus_killed': kyus_killed_list,
            'losses': losses_list,
            'steady_freddy': steady_freddy,
            'fifteen_min_fame': fifteen_min_fame,
            'rock_bottom': rock_bottom
        }