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