def _get_winning_percentage(player_name):
        """Populates ranking entity based on players winning %"""

        user = User.query(User.name == player_name).get()
        if user:
            total_win = float(
                len(
                    Score.query(Score.user == user.key,
                                Score.result == 'win').fetch()))
            total_lose = float(
                len(
                    Score.query(Score.user == user.key,
                                Score.result == 'lose').fetch()))
            total_tie = float(
                len(
                    Score.query(Score.user == user.key,
                                Score.result == 'tie').fetch()))
            # tie counts for 1/2 win and 1/2 lose
            winning_per = ((total_win + (total_tie / 2)) /
                           (total_win + total_lose + total_tie))

            # logging.info(total_win)
            # logging.info(total_lose)
            # logging.info(total_tie)
            # logging.info(winning_per)

            ranking = Ranking.query(Ranking.user == user.key).get()
            if ranking:
                ranking.winning_percent = winning_per
                ranking.put()
            else:
                ranking = Ranking(user=user.key, winning_percent=winning_per)
                ranking.put()
예제 #2
0
    def get_user_ranking(self, request):
        """Returns the performance of the player as a Ranking."""
        user = User.query(User.name == request.user_name).get()
        if not user:
            raise endpoints.NotFoundException(
                    'A User with that name does not exist!')

        scores = Score.query(Score.user == user.key).fetch()
        if not scores:
            raise endpoints.NotFoundException(
                    'No scores were found for that user!')

        wins = sum(s.won == True for s in scores)
        percent_won = (float(wins)/len(scores)) * 100
        number_of_guesses = sum(score.total_incorrect for score in scores)
        avg_wrong = float(number_of_guesses)/len(scores)

        ranking = Ranking.query(Ranking.user == user.key).get()
        if ranking:
            ranking.wins = wins
            ranking.percent_won = percent_won
            ranking.avg_wrong = avg_wrong
            ranking.put()
            return ranking.to_form("Ranking has been updated for {}".format(
                                        user.name))
        else:
            ranking = Ranking.new_ranking(user=user.key,
                                          wins=wins,
                                          percent_won=percent_won,
                                          avg_wrong=avg_wrong)
            return ranking.to_form("Ranking created for {}".format(user.name))
예제 #3
0
def rank_them(users, number_of_results):
    rankings = []
    for user in users:
        scores = Score.query(ancestor=user.key)
        wins = losses = cats = moves = 0.0
        for score in scores:
            # chore: might not want to include moves in losses in the
            # rankings algorithm
            moves += score.moves
            if score.won:
                wins += 1.0
            elif score.cats:
                cats += 1.0
            else:
                losses += 1.0
        games = wins + cats + losses
        # don't rank users who haven't finished a game
        if games != 0:
            rating = Ranking(user=user.name,
                             win_percent=wins / games,
                             cats_percent=cats / games,
                             avg_moves=moves / games)
            rankings.append(rating)
    # sorts are stable(order from initial sort retained unless changed
    # by a later sort) so execute the last sort criteria first
    rankings = sorted(rankings, key=attrgetter('avg_moves'))
    rankings = sorted(rankings,
                      key=attrgetter('win_percent', 'cats_percent'),
                      reverse=True)
    if number_of_results:
        rankings = rankings[:number_of_results]
    return rankings
    def rankings_handler(self, request):
        rankings = Ranking.query()
        rankings = rankings.order(-Ranking.ranking)

        return Ranking_forms(
            items=[copy_ranking_from_list_to_form(rank) \
                   for rank in rankings]
        )
예제 #5
0
 def load_rankings(cls, table, matches, has_hs=True):
     """has_hs=False is necessary for rly old data"""
     try:
         event_key = matches[0][0].event_key
     except IndexError:
         logging.warning("can't load rankings on zero length match table!")
         return
     high_scores, wlt = cls.highscores_wlt(matches)
     ret = []
     #first = True
     for tr in table.find_all("tr"):
         td_tags = list(tr.find_all("td"))
         if not td_tags:
             continue
         td = [td.get_text() for td in td_tags]
         tkey = "ftc" + td[1]
         twlt = wlt[tkey]
         if not has_hs:
             r = Ranking(event_key=event_key,
                         team_key=tkey,
                         rank=int(td[0]),
                         qp_rp=int(td[3]),
                         rp_tbp=int(td[4]),
                         high_score=high_scores.get(tkey, 0),
                         wins=twlt[0],
                         losses=twlt[1],
                         ties=twlt[2],
                         dqed=0,
                         played=int(td[5]))
         else:
             r = Ranking(event_key=event_key,
                         team_key=tkey,
                         rank=int(td[0]),
                         qp_rp=int(td[3]),
                         rp_tbp=int(td[4]),
                         high_score=int(td[5]),
                         wins=twlt[0],
                         losses=twlt[1],
                         ties=twlt[2],
                         dqed=0,
                         played=int(td[6]))
         ret.append(r)
     return ret
예제 #6
0
 async def generate_rankings(cls, event_key):
     match_data = await cls.get_match_data(where="m.event_key=$1",
                                           params=[event_key],
                                           use_dict=False)
     rankings = {}
     red: MatchScore
     blue: MatchScore
     match: Match
     for match, red, blue in match_data:
         for team in red.teams + blue.teams:
             if team not in rankings:
                 rankings[team] = Ranking(event_key=event_key,
                                          team_key=team,
                                          qp_rp=0,
                                          rp_tbp=0,
                                          high_score=0,
                                          wins=0,
                                          losses=0,
                                          ties=0,
                                          played=0,
                                          dqed=0)
         if match.winner == 'tie':
             for team in red.teams + blue.teams:
                 if team in red.surrogates or team in blue.surrogates:
                     continue
                 rankings[team].played += 1
                 rankings[team].ties += 1
                 rankings[team].qp_rp += 1
                 rankings[team].rp_tbp += min(red.total - red.penalty,
                                              blue.total - blue.penalty)
             continue
         elif match.winner == 'red':
             winner = red
             loser = blue
         elif match.winner == 'blue':
             winner = blue
             loser = red
         else:
             raise ValueError(
                 f"{match.winner} is invalid value for match.winner!")
         for team in winner.teams:
             if team in winner.surrogates:
                 continue
             rankings[team].played += 1
             rankings[team].wins += 1
             rankings[team].qp_rp += 2
             rankings[team].rp_tbp += loser.total - loser.penalty
         for team in loser.teams:
             if team in loser.surrogates:
                 continue
             rankings[team].played += 1
             rankings[team].losses += 1
             rankings[team].rp_tbp += loser.total
     await asyncio.gather(*[r.upsert() for r in rankings.values()])
     await Ranking.update_ranks(event_key)
예제 #7
0
    def check_if_user_exists(self, user):
        # Check if current user is already registered in datastore User table.
        user_id = self.get_user_id(user)
        u_key = ndb.Key(User, user_id)
        user_profile = u_key.get()

        # If user is not registered, register it.
        if not user_profile:
            user_profile = User(key=u_key,
                                name=user.nickname(),
                                email=user.email())
            user_profile.put()

            user_ranking = Ranking(user=u_key,
                                   total_moves=0,
                                   guessed_moves=0,
                                   ranking=0)

            user_ranking.put()
        return copy_user_profile_to_form(user_profile)
예제 #8
0
파일: tictactoe.py 프로젝트: NojNo/Project4
 def get_users_wins(self, request):
     """Returns all wins of a player + prepares the ranking"""
     player = Player.query(Player.name == request.user_name).get()
     if not player:
         raise endpoints.NotFoundException(
             'A User with that name does not exist!')
     rankings = Ranking.query().fetch()
     members_in_ranking = []
     for ranking in rankings:
         members_in_ranking.append(ranking.player)
         if player.name in members_in_ranking:
             scores = Score.query(Score.player == player.key).count()
             players_positons = Ranking.query(Ranking.player == player.name).get()
             players_positons.number_of_wins = scores
             players_positons.put()
             return StringMessage(message="wins: {} by player:{}".format(scores, player.name))
         else:
             scores = Score.query(Score.player == player.key).count()
             get_ranked = Ranking.new_in_ranking(player.name, scores)
             return StringMessage(message="wins: {} by {}".format(scores, player.name))
예제 #9
0
 def get_ranking(self, event="10K", sex="M", year="2014", age_group="ALL"):
     
     r = requests.get("http://www.thepowerof10.info/rankings/rankinglist.aspx", params={"event": event, "agegroup": age_group, "sex": sex, "year": 2014})
     
     soup = BeautifulSoup(r.content)
     rankings_table = soup.find(id="ctl00_cphBody_lblCachedRankingList").find_all('table')[0]
     
     ranking_rows = [row for row in rankings_table.find_all("tr") if row["class"][0] not in ["rankinglisttitle", "rankinglistheadings", "rankinglistsubheader"]]
     
     rankings = []
     for row in ranking_rows:
         if row.find_all("td")[0].string is None:
             continue
         r = Ranking({"athlete": Athlete(), "event": event, "year": year, "age_group": age_group})
         r.rank = int(row.find_all("td")[0].string)
         r.time = row.find_all("td")[1].string
         r.athlete.name = row.find_all("td")[6].string.encode("utf-8")
         r.athlete.id = int(row.find_all("td")[6].a["href"].split("=")[1])
         r.venue = row.find_all("td")[11].string
         r.date = row.find_all("td")[12].string
         
         rankings.append(r)
         
     return rankings
         
예제 #10
0
 def get_users_wins(self, request):
     """Returns all wins of a player + prepares the ranking"""
     player = Player.query(Player.name == request.user_name).get()
     if not player:
         raise endpoints.NotFoundException(
             'A User with that name does not exist!')
     rankings = Ranking.query().fetch()
     members_in_ranking = []
     for ranking in rankings:
         members_in_ranking.append(ranking.player)
         if player.name in members_in_ranking:
             scores = Score.query(Score.player == player.key).count()
             players_positons = Ranking.query(
                 Ranking.player == player.name).get()
             players_positons.number_of_wins = scores
             players_positons.put()
             return StringMessage(message="wins: {} by player:{}".format(
                 scores, player.name))
         else:
             scores = Score.query(Score.player == player.key).count()
             get_ranked = Ranking.new_in_ranking(player.name, scores)
             return StringMessage(
                 message="wins: {} by {}".format(scores, player.name))
예제 #11
0
def update_rank(event, context):
    with application.app_context():
        my_kwargs = event.get("kwargs")
        date = datetime.datetime.utcnow().strftime('%Y/%m/%d')
        for i in range(my_kwargs["start"], my_kwargs["end"]):
            url = "https://www.acmicpc.net/ranklist/" + str(i)
            soup = get_soup_from_url(url)
            table = soup.find(id='ranklist')
            trs = table.tbody.find_all('tr')
            boj_ids = list()
            boj_ranks = list()
            for tr in trs:
                tds = tr.find_all('td')
                if int(tds[3].a.string.strip()) <= 19:
                    break
                boj_ids.append(''.join(tds[1].find_all(text=True, recursive=True)).strip())
                boj_ranks.append(int(tds[0].string))

            api = request_koo_api("user", boj_ids)
            koo_ranks = list(user["ranking"] for user in api)
            for _ in range(len(boj_ids)):
                boj_id = boj_ids[_]
                boj_rank = boj_ranks[_]
                if koo_ranks[_] == None:
                    koo_rank = 0
                else:
                    koo_rank = koo_ranks[_] + 1
                data = {date: [boj_rank, koo_rank]}
                if not Ranking.query.filter_by(boj_id=boj_id).scalar():
                    ranking = Ranking(boj_id=boj_id, ranking=data)
                    db.session.add(ranking)
                    db.session.commit()
                else:
                    user = Ranking.query.filter_by(boj_id=boj_id)
                    new_ranking = user.first().ranking
                    new_ranking.update(data)
                    user.first().ranking = new_ranking
                    db.session.commit()

                print("{0} {1} {2}".format(boj_id, boj_rank, koo_rank))
    return "OK"
예제 #12
0
 def load_rankings(cls, data, matches, event_key):
     # since ftcscores has basically everything we need, we just load it right in!
     _, wlt = ResultsPageHelper.highscores_wlt(matches)
     rankings = []
     for r in data['rankings']:
         c = r['current']
         tkey = f"ftc{r['number']}"
         twlt = wlt[tkey]
         ranking = Ranking(event_key=event_key,
                           team_key=tkey,
                           rank=r['rank'],
                           qp_rp=c['qp'],
                           rp_tbp=c['rp'],
                           high_score=c['highest'],
                           wins=twlt[0],
                           losses=twlt[1],
                           ties=twlt[2],
                           dqed=0,
                           played=c['matches'])
         rankings.append(ranking)
     return rankings
예제 #13
0
    def move_handler(self, request):
        # Check for current user.
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnexpectedException('Authentication required!')

        # Get game web safe key.
        web_safe_key = request.web_safe_key

        # Get key for cards moved.
        move_one = request.move_one
        move_two = request.move_two

        # If no card as been turned, raise exception.
        if move_one is None and move_two is None:
            raise endpoints.UnauthorizedException('No move has been made!')

        # Get game key using web safe key.
        game_key = ndb.Key(urlsafe=request.web_safe_key)
        if not game_key:
            raise endpoints.UnauthorizedException('Game is not available!')

        # Fetch game.
        game = game_key.get()
        if not game:
            raise endpoints.NotFoundException('Game not found')

        if game.complete:
            raise endpoints.UnauthorizedException('This game is already finished!')

        sequence = game.sequence
        tiles_found = game.tiles_found
        score = game.score
        move_record = game.move_record

        # If car as been already guessed, alert user.
        if (move_one is not None and tiles_found[move_one] >= 0) or \
                (move_two is not None and tiles_found[move_two] >= 0):
            raise endpoints.UnauthorizedException('Figure already found')

        # If move one and two correspond to the same card, its an illegal move.
        # Alert user.
        if (move_one == move_two):
            raise endpoints.UnauthorizedException('Illegal move')

        # -1 stands for None because has to be Integer, not Boolean
        move_one_key = -1
        move_two_key = -1

        # Get figures from sequence list corresponding to turned card.
        if move_one is not None:
            move_one_key = sequence[move_one]

        if move_two is not None:
            move_two_key = sequence[move_two]

        guessed = False

        # Run if two carsd were turned.
        if move_one_key != -1 and move_two_key != -1:
            complete = None

            # Get user key
            u_key = ndb.Key(User, user.email())

            # Fetch user ranking.
            rankings = Ranking.query()
            rankings = rankings.filter(Ranking.user == u_key)
            rankings = rankings.fetch(1)

            ranking = rankings[0]

            # Update user ranking.
            ranking.total_moves = ranking.total_moves + 1

            # Run if user guessed.
            if move_one_key == move_two_key:
                guessed = True
                score = score + 3
                tiles_found[move_one] = move_one_key
                tiles_found[move_two] = move_two_key
                game.tiles_found = tiles_found

                complete = True

                # Check if game is over.
                for t in tiles_found:
                    if t == -1:
                        complete = False
                        break
                game.complete = complete
                ranking.guessed_moves = ranking.guessed_moves + 1

            else:
                score = score - 1

                if score < 0:
                    score = 0

            # Update game data.
            move_record.append(move_one)
            move_record.append(move_two)
            game.move_record = move_record
            game.score = score
            game.put()

            # Update ranking data.
            ranking.ranking = float(ranking.guessed_moves) / ranking.total_moves
            ranking.put()

            # update score data table if games is complete.
            if complete:
                score = Score(
                    user=u_key,
                    score=score,
                    total_moves=len(move_record) / 2
                )
                score.put()

        # Return move info.
        return copy_move_result_to_form(game, move_one_key, move_two_key, guessed)
예제 #14
0
 def get_user_rankings(self, request):
     """Returns Players in descending order. The one with
     most wins is on the top"""
     rankings = Ranking.query().order(-Ranking.number_of_wins).fetch()
     return RankingForms(items=[ranking.to_form() for ranking in rankings])
예제 #15
0
    async def calc_rankings(cls, matches, team_keys: set):
        # the correct way to do this would be to use a minPQ
        best_ten = {k: [] for k in team_keys}

        for m, red, blue in matches:
            if team_keys.isdisjoint(red.teams) and team_keys.isdisjoint(
                    blue.teams):
                continue
            if m.winner == "tie":
                mi = cls.MatchItem(qp_rp=1,
                                   score=red.total,
                                   match_tuple=(m, red, blue),
                                   rp_tbp=min(red.total - red.penalty,
                                              blue.total - blue.penalty))
                for team in red.teams + blue.teams:
                    if team in red.surrogates or team in blue.surrogates:
                        continue
                    if team in team_keys:
                        enqueue(mi, best_ten[team])
                continue
            elif m.winner == "red":
                winner, loser = red, blue
            elif m.winner == "blue":
                winner, loser = blue, red
            else:
                raise ValueError(
                    f"match.winner for {m.key} is not in {{'red', 'blue', 'tie'}}"
                )

            for team in winner.teams:
                if team in winner.surrogates:
                    continue
                mi = cls.MatchItem(qp_rp=2,
                                   score=winner.total,
                                   match_tuple=(m, red, blue),
                                   rp_tbp=loser.total - loser.penalty)
                print(team, repr(mi))
                if team in team_keys:
                    enqueue(mi, best_ten[team])

            for team in loser.teams:
                if team in loser.surrogates:
                    continue
                mi = cls.MatchItem(qp_rp=0,
                                   score=loser.total,
                                   match_tuple=(m, red, blue),
                                   rp_tbp=loser.total - loser.penalty)
                print(team, repr(mi))
                if team in team_keys:
                    enqueue(mi, best_ten[team])
        ret = []
        import pprint
        pprint.pprint(best_ten)
        for team, match_item in best_ten.items():
            ret.append(
                Ranking(
                    team_key=team,
                    qp_rp=sum(a.qp_rp for a in match_item),
                    rp_tbp=sum(a.rp_tbp for a in match_item),
                    high_score=max(a.score for a in match_item),
                    wins=len([2 for a in match_item if a.qp_rp == 2]),
                    losses=len([0 for a in match_item if a.qp_rp == 0]),
                    ties=len([0 for a in match_item if a.qp_rp == 1]),
                    played=len(match_item),
                    dqed=0,
                ))
        return ret
예제 #16
0
파일: tictactoe.py 프로젝트: NojNo/Project4
 def get_user_rankings(self, request):
     """Returns Players in descending order. The one with
     most wins is on the top"""
     rankings = Ranking.query().order(-Ranking.number_of_wins).fetch()
     return RankingForms(items=[ranking.to_form() for ranking in rankings])
 def get_user_rankings(self, request):
     """Return all ranking sort by winning percent"""
     return RankForms(items=[
         rank.to_form()
         for rank in Ranking.query().order(-Ranking.winning_percent)
     ])