feat: compute scores from ratings via management command
This commit is contained in:
parent
e3a82cb705
commit
8b1b807ef3
|
@ -1 +1 @@
|
|||
__version__ = "0.13.1"
|
||||
__version__ = "0.14.0"
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
import math
|
||||
import statistics
|
||||
from operator import itemgetter
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django_scopes import scope
|
||||
from pretalx.event.models import Event
|
||||
from pretalx.submission.models import Submission
|
||||
|
||||
from ...models import Rating, Score
|
||||
|
||||
RATINGS_MIN = 30
|
||||
SCALE = list(map(float, map(itemgetter(0), Rating.RATING_CHOICES)))
|
||||
|
||||
MEAN = statistics.mean(SCALE)
|
||||
STD = math.sqrt(statistics.mean([(i - MEAN) ** 2 for i in SCALE]))
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Compute submission scores from ratings"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("event")
|
||||
|
||||
def handle(self, *args, **kwargs):
|
||||
try:
|
||||
event = Event.objects.get(slug=kwargs["event"])
|
||||
except Event.DoesNotExist:
|
||||
raise CommandError(f"no event found with slug '{kwargs['event']}'")
|
||||
|
||||
with scope(event=event):
|
||||
submissions = {}
|
||||
|
||||
for juror in event.jurors.prefetch_related("ratings"):
|
||||
ratings = {
|
||||
r.submission.code: int(r.rating)
|
||||
for r in juror.ratings.exclude(rating="")
|
||||
}
|
||||
values = list(ratings.values())
|
||||
|
||||
if len(values) < RATINGS_MIN:
|
||||
mean = MEAN
|
||||
std = STD
|
||||
else:
|
||||
mean = sum(values) / len(values)
|
||||
std = math.sqrt(
|
||||
sum([(i - mean) ** 2 for i in values]) / len(values)
|
||||
)
|
||||
|
||||
for code in ratings:
|
||||
if code not in submissions:
|
||||
submissions[code] = []
|
||||
submissions[code].append((ratings[code] - mean) / std * STD + MEAN)
|
||||
|
||||
for submission in Submission.objects.prefetch_related("score").filter(
|
||||
code__in=submissions.keys()
|
||||
):
|
||||
try:
|
||||
score = submission.score
|
||||
except Submission.score.RelatedObjectDoesNotExist:
|
||||
score = Score(submission=submission)
|
||||
|
||||
ratings = submissions[submission.code]
|
||||
score.value = sum(ratings) / len(ratings)
|
||||
score.save()
|
Loading…
Reference in New Issue