Commit e5294591 by Julian Arni

Foldit leaderboard w/o tests

parent e4312d67
......@@ -66,6 +66,14 @@ class FolditModule(XModule):
PuzzleComplete.completed_puzzles(self.system.anonymous_student_id),
key=lambda d: (d['set'], d['subset']))
def puzzle_leaders(self, n=10):
"""
Returns a list of n pairs (user, score) corresponding to the top
scores; the pairs are in descending order of score.
"""
from foldit.models import Score
return [(e['username'], e['total_score']) for e in Score.get_tops_n(10)]
def get_html(self):
"""
......@@ -80,6 +88,7 @@ class FolditModule(XModule):
'success': self.is_complete(),
'goal_level': goal_level,
'completed': self.completed_puzzles(),
'top_scores': self.puzzle_leaders(),
}
return self.system.render_template('foldit.html', context)
......@@ -97,6 +106,7 @@ class FolditModule(XModule):
return 1
class FolditDescriptor(XmlDescriptor, EditingDescriptor):
"""
Module for adding open ended response questions to courses
......
......@@ -26,17 +26,19 @@ class Score(models.Model):
created = models.DateTimeField(auto_now_add=True)
@staticmethod
def display_score(score):
def display_score(score, sum_of=1):
"""
Argument:
score (float), as stored in the DB
score (float), as stored in the DB (i.e., "rosetta score")
sum_of (int): if this score is the sum of scores of individual
problems, how many elements are in that sum
Returns:
score (float), as displayed to the user in the game and in the leaderboard
"""
# TODO: put in correct formula
return -score
return (-score) * 10 + 8000 * sum_of
# TODO: delete this, incorporate it in get_tops_n
@staticmethod
def get_top_n(puzzle_id, n):
"""
......@@ -52,9 +54,33 @@ class Score(models.Model):
score: 8500}, ...]
"""
scores = Score.objects.filter(puzzle_id=puzzle_id).order_by('-best_score')[:n]
return [{'username': s.user.username, 'score': display_score(s.best_score)}
return [{'username': s.user.username, 'score': Score.display_score(s.best_score)}
for s in scores]
@staticmethod
def get_tops_n(n, puzzles=['994559']):
"""
Arguments:
puzzles: a list of puzzle ids that we will use. If not specified,
defaults to puzzle used in 7012x.
n (int): number of top scores to return
Returns:
The top n sum of scores for puzzles in <puzzles>. Output is a list
of disctionaries, sorted by display_score:
[ {username: 'a_user',
score: 12000} ...]
"""
scores = Score.objects.filter(puzzle_id__in=puzzles).annotate(
total_score=models.Sum('best_score')).order_by(
'-total_score')[:n]
num = len(puzzles)
return [{'username': s.user.username,
'total_score': Score.display_score(s.total_score, num)}
for s in scores]
class PuzzleComplete(models.Model):
"""
......
......@@ -10,6 +10,8 @@ from django.views.decorators.csrf import csrf_exempt
from foldit.models import Score, PuzzleComplete
from student.models import unique_id_for_user
import re
log = logging.getLogger(__name__)
......@@ -38,6 +40,13 @@ def foldit_ops(request):
"user %s, scores json %r, verify %r",
request.user, puzzle_scores_json, pz_verify_json)
else:
# This is needed because we are not getting valid json - the
# value of ScoreType is an unquoted string. Right now regexes are
# quoting the string, but ideally the json itself would be fixed.
# To allow for fixes without breaking this, the regex should only
# match unquoted strings,
a = re.compile(r':([a-zA-Z]*),')
puzzle_scores_json = re.sub(a, ':"\g<1>",', puzzle_scores_json)
puzzle_scores = json.loads(puzzle_scores_json)
responses.append(save_scores(request.user, puzzle_scores))
......@@ -98,10 +107,22 @@ def save_scores(user, puzzle_scores):
# BestScore (energy), CurrentScore (Energy), ScoreVersion (int)
puzzle_id = score['PuzzleID']
best_score = score['BestScore']
current_score = score['CurrentScore']
score_version = score['ScoreVersion']
# TODO: save the score
# SetPlayerPuzzleScoreResponse object
Score.objects.get_or_create(
user=user,
unique_user_id=unique_id_for_user(user),
puzzle_id=puzzle_id,
best_score=best_score,
current_score=current_score,
score_version=score_version)
# TODO: get info from db instead?
score_responses.append({'PuzzleID': puzzle_id,
'Status': 'Success'})
......
......@@ -25,4 +25,21 @@ You have not yet gotten to level ${goal_level}.
% endfor
</table>
</section>
\ No newline at end of file
</br>
<h3>Puzzle Leaderboard</h3>
<table>
<tr>
<th>User</th>
<th>Score</th>
</tr>
% for pair in top_scores:
<tr>
<td>${pair[0]}</td>
<td>${pair[1]}</td>
</tr>
% endfor
</table>
</section>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment