Open circosine opened 5 years ago
No, I don't think that's published anywhere.
How would one create a Guts scoreboard to mimic the one found in Babbage?
Heh, the actual version that runs for HMMT isn't the best code in the world, but I'll try to describe it. The scoreboard itself is just an HTML file that will periodically query an AJAX hook and then display the results. The AJAX hook will look something like:
guts_exam = He.models.Exam.objects.get(name="Guts") # or however you want to identify it
num_problems = guts_exam.problem_set.count()
data = He.models.Verdict.objects.filter(problem__exam = guts_exam, score__isnull=False)\
.order_by().values("entity__shortname", "entity__name", "entity__id",
"problem__allow_partial", "problem__weight", "score")
class GutsTeam:
def __init__(self, name):
self.name = name
score = 0
progress = 0
@property
def progress_width(self):
return 100 * self.progress / num_problems
score_dict = {} # id -> GutsTeam object
for d in data:
eid = d['entity__id']
t = score_dict.get(eid, GutsTeam(d['entity__shortname'] or d['entity__name']))
t.progress += 1
if d['problem__allow_partial']:
t.score += int(d['score'])
else: # all-or-nothing
t.score += int(d['problem__weight'] * d['score'])
score_dict[eid] = t
teams_s = list(score_dict.values())
# Add empty teams
for team in He.models.Entity.teams.all():
if team.id not in score_dict:
teams_s.append(GutsTeam(team.shortname or unicode(team)))
teams_s.sort(key=lambda t: -t.score) # sort teams in descending order
That will give you a sorted list of GutsTeam objects. You can then format that into a JSON however you see fit, send it back to the client, which should then (by javascript/jquery) format and display the results.
Thank you for the code! However, I am having some problems implementing this. So far, I have added a few line to import the json and helium modules and attempted to format the GutsTeam objects into a JSON.
import json
import helium as He
guts_exam = He.models.Exam.objects.get(name="Guts") # or however you want to identify it
num_problems = guts_exam.problem_set.count()
data = He.models.Verdict.objects.filter(problem__exam = guts_exam, score__isnull=False)\
.order_by().values("entity__shortname", "entity__name", "entity__id",
"problem__allow_partial", "problem__weight", "score")
class GutsTeam:
def __init__(self, name):
self.name = name
score = 0
progress = 0
@property
def progress_width(self):
return 100 * self.progress / num_problems
score_dict = {} # id -> GutsTeam object
for d in data:
eid = d['entity__id']
t = score_dict.get(eid, GutsTeam(d['entity__shortname'] or d['entity__name']))
t.progress += 1
if d['problem__allow_partial']:
t.score += int(d['score'])
else: # all-or-nothing
t.score += int(d['problem__weight'] * d['score'])
score_dict[eid] = t
teams_s = list(score_dict.values())
# Add empty teams
for team in He.models.Entity.teams.all():
if team.id not in score_dict:
teams_s.append(GutsTeam(team.shortname or unicode(team)))
teams_s.sort(key=lambda t: -t.score) # sort teams in descending order
GutsDump = json.dumps(GutsTeam.__dict__)
print GutsDump
I executed this python script in the ./manage.py shell of Django using execfile(helium/GutsTeam.py) and got this message: TypeError: <function __init__ at 0x7f227fc6cd70> is not JSON serializable
Any clue on how to fix this issue?
If you print GutsTeam.__dict__
, you'll see why it's not working... this is a bunch of information about the class itself (not even about its objects), which in particular is not something you can JSON-ify. ;)
Maybe you would want to JSON-ify something like [(t.name, t.progress, t.score) for t in teams_s]
instead.
Do you have a link to the Babbage software?