Replaced +1/+0/-0/-1 voting with +2/+1/-1/-2 (fixes lca2017/symposion/#1)

This commit is contained in:
Scott Bragg 2016-06-10 15:29:09 +10:00
parent ad8181091a
commit f1f29c6f61
2 changed files with 43 additions and 43 deletions

View file

@ -17,22 +17,22 @@ from symposion.schedule.models import Presentation
def score_expression(): def score_expression():
return ( return (
(3 * F("plus_one") + F("plus_zero")) - (2 * F("plus_two") + F("plus_one")) -
(F("minus_zero") + 3 * F("minus_one")) (F("minus_one") + 2 * F("minus_two"))
) )
class Votes(object): class Votes(object):
PLUS_TWO = "+2"
PLUS_ONE = "+1" PLUS_ONE = "+1"
PLUS_ZERO = "+0"
MINUS_ZERO = "0"
MINUS_ONE = "1" MINUS_ONE = "1"
MINUS_TWO = "2"
CHOICES = [ CHOICES = [
(PLUS_ONE, _("+1 — Good proposal and I will argue for it to be accepted.")), (PLUS_TWO, _("+2 — Good proposal and I will argue for it to be accepted.")),
(PLUS_ZERO, _("+0 — OK proposal, but I will not argue for it to be accepted.")), (PLUS_ONE, _("+1 — OK proposal, but I will not argue for it to be accepted.")),
(MINUS_ZERO, _("0 — Weak proposal, but I will not argue strongly against acceptance.")), (MINUS_ONE, _("1 — Weak proposal, but I will not argue strongly against acceptance.")),
(MINUS_ONE, _("1 — Serious issues and I will argue to reject this proposal.")), (MINUS_TWO, _("2 — Serious issues and I will argue to reject this proposal.")),
] ]
VOTES = Votes() VOTES = Votes()
@ -222,10 +222,10 @@ class ProposalResult(models.Model):
score = models.DecimalField(max_digits=5, decimal_places=2, default=Decimal("0.00"), verbose_name=_("Score")) score = models.DecimalField(max_digits=5, decimal_places=2, default=Decimal("0.00"), verbose_name=_("Score"))
comment_count = models.PositiveIntegerField(default=0, verbose_name=_("Comment count")) comment_count = models.PositiveIntegerField(default=0, verbose_name=_("Comment count"))
vote_count = models.PositiveIntegerField(default=0, verbose_name=_("Vote count")) vote_count = models.PositiveIntegerField(default=0, verbose_name=_("Vote count"))
plus_two = models.PositiveIntegerField(default=0, verbose_name=_("Plus two"))
plus_one = models.PositiveIntegerField(default=0, verbose_name=_("Plus one")) plus_one = models.PositiveIntegerField(default=0, verbose_name=_("Plus one"))
plus_zero = models.PositiveIntegerField(default=0, verbose_name=_("Plus zero"))
minus_zero = models.PositiveIntegerField(default=0, verbose_name=_("Minus zero"))
minus_one = models.PositiveIntegerField(default=0, verbose_name=_("Minus one")) minus_one = models.PositiveIntegerField(default=0, verbose_name=_("Minus one"))
minus_two = models.PositiveIntegerField(default=0, verbose_name=_("Minus two"))
accepted = models.NullBooleanField(choices=[ accepted = models.NullBooleanField(choices=[
(True, "accepted"), (True, "accepted"),
(False, "rejected"), (False, "rejected"),
@ -244,31 +244,31 @@ class ProposalResult(models.Model):
result, created = cls._default_manager.get_or_create(proposal=proposal) result, created = cls._default_manager.get_or_create(proposal=proposal)
result.comment_count = Review.objects.filter(proposal=proposal).count() result.comment_count = Review.objects.filter(proposal=proposal).count()
result.vote_count = LatestVote.objects.filter(proposal=proposal).count() result.vote_count = LatestVote.objects.filter(proposal=proposal).count()
result.plus_two = LatestVote.objects.filter(
proposal=proposal,
vote=VOTES.PLUS_TWO
).count()
result.plus_one = LatestVote.objects.filter( result.plus_one = LatestVote.objects.filter(
proposal=proposal, proposal=proposal,
vote=VOTES.PLUS_ONE vote=VOTES.PLUS_ONE
).count() ).count()
result.plus_zero = LatestVote.objects.filter(
proposal=proposal,
vote=VOTES.PLUS_ZERO
).count()
result.minus_zero = LatestVote.objects.filter(
proposal=proposal,
vote=VOTES.MINUS_ZERO
).count()
result.minus_one = LatestVote.objects.filter( result.minus_one = LatestVote.objects.filter(
proposal=proposal, proposal=proposal,
vote=VOTES.MINUS_ONE vote=VOTES.MINUS_ONE
).count() ).count()
result.minus_two = LatestVote.objects.filter(
proposal=proposal,
vote=VOTES.MINUS_TWO
).count()
result.save() result.save()
cls._default_manager.filter(pk=result.pk).update(score=score_expression()) cls._default_manager.filter(pk=result.pk).update(score=score_expression())
def update_vote(self, vote, previous=None, removal=False): def update_vote(self, vote, previous=None, removal=False):
mapping = { mapping = {
VOTES.PLUS_TWO: "plus_two",
VOTES.PLUS_ONE: "plus_one", VOTES.PLUS_ONE: "plus_one",
VOTES.PLUS_ZERO: "plus_zero",
VOTES.MINUS_ZERO: "minus_zero",
VOTES.MINUS_ONE: "minus_one", VOTES.MINUS_ONE: "minus_one",
VOTES.MINUS_TWO: "minus_two",
} }
if previous: if previous:
if previous == vote: if previous == vote:

View file

@ -41,10 +41,10 @@ def proposals_generator(request, queryset, user_pk=None, check_speaker=True):
obj.comment_count = obj.result.comment_count obj.comment_count = obj.result.comment_count
obj.total_votes = obj.result.vote_count obj.total_votes = obj.result.vote_count
obj.plus_two = obj.result.plus_two
obj.plus_one = obj.result.plus_one obj.plus_one = obj.result.plus_one
obj.plus_zero = obj.result.plus_zero
obj.minus_zero = obj.result.minus_zero
obj.minus_one = obj.result.minus_one obj.minus_one = obj.result.minus_one
obj.minus_two = obj.result.minus_two
lookup_params = dict(proposal=obj) lookup_params = dict(proposal=obj)
if user_pk: if user_pk:
@ -144,22 +144,22 @@ def review_admin(request, section_slug):
user.comment_count = Review.objects.filter(user=user).count() user.comment_count = Review.objects.filter(user=user).count()
user.total_votes = LatestVote.objects.filter(user=user).count() user.total_votes = LatestVote.objects.filter(user=user).count()
user.plus_two = LatestVote.objects.filter(
user=user,
vote=LatestVote.VOTES.PLUS_TWO
).count()
user.plus_one = LatestVote.objects.filter( user.plus_one = LatestVote.objects.filter(
user=user, user=user,
vote=LatestVote.VOTES.PLUS_ONE vote=LatestVote.VOTES.PLUS_ONE
).count() ).count()
user.plus_zero = LatestVote.objects.filter(
user=user,
vote=LatestVote.VOTES.PLUS_ZERO
).count()
user.minus_zero = LatestVote.objects.filter(
user=user,
vote=LatestVote.VOTES.MINUS_ZERO
).count()
user.minus_one = LatestVote.objects.filter( user.minus_one = LatestVote.objects.filter(
user=user, user=user,
vote=LatestVote.VOTES.MINUS_ONE vote=LatestVote.VOTES.MINUS_ONE
).count() ).count()
user.minus_two = LatestVote.objects.filter(
user=user,
vote=LatestVote.VOTES.MINUS_TWO
).count()
yield user yield user
@ -268,10 +268,10 @@ def review_detail(request, pk):
proposal.comment_count = proposal.result.comment_count proposal.comment_count = proposal.result.comment_count
proposal.total_votes = proposal.result.vote_count proposal.total_votes = proposal.result.vote_count
proposal.plus_two = proposal.result.plus_two
proposal.plus_one = proposal.result.plus_one proposal.plus_one = proposal.result.plus_one
proposal.plus_zero = proposal.result.plus_zero
proposal.minus_zero = proposal.result.minus_zero
proposal.minus_one = proposal.result.minus_one proposal.minus_one = proposal.result.minus_one
proposal.minus_two = proposal.result.minus_two
reviews = Review.objects.filter(proposal=proposal).order_by("-submitted_at") reviews = Review.objects.filter(proposal=proposal).order_by("-submitted_at")
messages = proposal.messages.order_by("submitted_at") messages = proposal.messages.order_by("submitted_at")
@ -319,22 +319,22 @@ def review_status(request, section_slug=None, key=None):
queryset = queryset.filter(kind__section__slug=section_slug) queryset = queryset.filter(kind__section__slug=section_slug)
proposals = { proposals = {
# proposals with at least VOTE_THRESHOLD reviews and at least one +1 and no -1s, sorted by # proposals with at least VOTE_THRESHOLD reviews and at least one +2 and no -2s, sorted by
# the 'score' # the 'score'
"positive": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__plus_one__gt=0, "positive": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__plus_two__gt=0,
result__minus_one=0).order_by("-result__score"), result__minus_two=0).order_by("-result__score"),
# proposals with at least VOTE_THRESHOLD reviews and at least one -1 and no +1s, reverse # proposals with at least VOTE_THRESHOLD reviews and at least one -2 and no +2s, reverse
# sorted by the 'score' # sorted by the 'score'
"negative": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__minus_one__gt=0, "negative": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__minus_two__gt=0,
result__plus_one=0).order_by("result__score"), result__plus_two=0).order_by("result__score"),
# proposals with at least VOTE_THRESHOLD reviews and neither a +1 or a -1, sorted by total # proposals with at least VOTE_THRESHOLD reviews and neither a +2 or a -2, sorted by total
# votes (lowest first) # votes (lowest first)
"indifferent": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__minus_one=0, "indifferent": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, result__minus_two=0,
result__plus_one=0).order_by("result__vote_count"), result__plus_two=0).order_by("result__vote_count"),
# proposals with at least VOTE_THRESHOLD reviews and both a +1 and -1, sorted by total # proposals with at least VOTE_THRESHOLD reviews and both a +2 and -2, sorted by total
# votes (highest first) # votes (highest first)
"controversial": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD, "controversial": queryset.filter(result__vote_count__gte=VOTE_THRESHOLD,
result__plus_one__gt=0, result__minus_one__gt=0) result__plus_two__gt=0, result__minus_two__gt=0)
.order_by("-result__vote_count"), .order_by("-result__vote_count"),
# proposals with fewer than VOTE_THRESHOLD reviews # proposals with fewer than VOTE_THRESHOLD reviews
"too_few": queryset.filter(result__vote_count__lt=VOTE_THRESHOLD) "too_few": queryset.filter(result__vote_count__lt=VOTE_THRESHOLD)