Replaced +1/+0/-0/-1 voting with +2/+1/-1/-2 (fixes lca2017/symposion/#1)
This commit is contained in:
		
							parent
							
								
									ad8181091a
								
							
						
					
					
						commit
						f1f29c6f61
					
				
					 2 changed files with 43 additions and 43 deletions
				
			
		| 
						 | 
					@ -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:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue