-
Notifications
You must be signed in to change notification settings - Fork 0
/
ScoresHelper.py
118 lines (96 loc) · 3.48 KB
/
ScoresHelper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import datetime
from google.appengine.ext import db
from Player import Player
import operator
from google.appengine.api import memcache
class ScoreType:
Mean14Day = "Mean14Day"
Max14Day = "Max14Day"
Count14Day = "Count14Day"
@staticmethod
def types():
return [v for v in vars(ScoreType) if not v.startswith("__") and not v.startswith("types")]
class ScoresHelper:
CACHE_EXPIRY = 43200 # 12 hours
MIN_SCORE_COUNTS = {
ScoreType.Mean14Day : 10,
ScoreType.Max14Day : 1,
}
def __init__(self, playerId):
self._playerId = playerId
self._scores14Days = None
def get14DayScores(self, now = datetime.datetime.now()):
if self._scores14Days is None:
player = db.get(db.Key.from_path('Player', self._playerId))
date14DaysAgo = now - datetime.timedelta(days=14)
results = player.scores.filter('date >=', date14DaysAgo)
self._scores14Days = [s.points for s in results]
return self._scores14Days
def count14DayScores(self, now = datetime.datetime.now()):
mckey = "player-%s-14-day-count" % (self._playerId,)
count = memcache.get(mckey)
if count is None:
count = len(self.get14DayScores())
memcache.add(mckey, count, self.CACHE_EXPIRY)
return count
def get14DayMean(self):
score = None
if self.count14DayScores() >= self.MIN_SCORE_COUNTS[ScoreType.Mean14Day]:
mckey = "player-%s-14-day-mean" % (self._playerId,)
score = memcache.get(mckey)
if score is None:
scores = self.get14DayScores()
if len(scores) > 0:
score = round(float(sum(scores))/len(scores))
memcache.add(mckey, score, self.CACHE_EXPIRY)
return score
def get14DayMax(self):
score = None
if self.count14DayScores() >= self.MIN_SCORE_COUNTS[ScoreType.Max14Day]:
mckey = "player-%s-14-day-max" % (self._playerId,)
score = memcache.get(mckey)
if score is None:
scores = self.get14DayScores()
if len(scores) > 0:
score = round(max(scores))
memcache.add(mckey, score, self.CACHE_EXPIRY)
return score
def getScore(self, scoreType):
if scoreType == ScoreType.Mean14Day:
return self.get14DayMean()
elif scoreType == ScoreType.Max14Day:
return self.get14DayMax()
elif scoreType == ScoreType.Count14Day:
return self.count14DayScores()
return None
def hasScores(self):
return self.count14DayScores() > 0
def clearCache(self):
memcache.delete_multi([
"player-%s-14-day-count" % (self._playerId,),
"player-%s-14-day-mean" % (self._playerId,),
"player-%s-14-day-max" % (self._playerId,),
])
class Rankings:
@staticmethod
def getRankings():
scoresByType = {t : list() for t in ScoreType.types()}
players = Player.all(keys_only=True)
for player in players:
playerId = player.id_or_name()
scoresHelper = ScoresHelper(playerId)
if scoresHelper.hasScores():
for scoreType in ScoreType.types():
score = scoresHelper.getScore(scoreType)
scoresByType[scoreType].append({'playerId':playerId, 'score':score})
# Sort scores
for scoreType in ScoreType.types():
scoresByType[scoreType] = sorted(scoresByType[scoreType], key=operator.itemgetter('score'), reverse=True)
rankings = {}
for scoreType in ScoreType.types():
rank = 1
rankings[scoreType] = {}
for t in scoresByType[scoreType]:
rankings[scoreType][t['playerId']] = rank
rank += 1
return rankings