예제 #1
0
    def add_debates(self, round_tag, motion, debate):
        debate_tag = SubElement(round_tag, 'debate', {
            'id': DEBATE_PREFIX + str(debate.id),
        })

        # Add list of motions as attribute
        adjs = " ".join([ADJ_PREFIX + str(d_adj.adjudicator_id) for d_adj in debate.debateadjudicator_set.all()])
        if adjs != "":
            debate_tag.set('adjudicators', adjs)

            chair = debate.debateadjudicator_set.get(type=DebateAdjudicator.TYPE_CHAIR).adjudicator_id
            debate_tag.set('chair', ADJ_PREFIX + str(chair))

        # Venue
        if debate.venue_id is not None:
            debate_tag.set('venue', VENUE_PREFIX + str(debate.venue_id))

        # Motion is optional
        if self.t.pref('enable_motions') and debate.confirmed_ballot is not None:
            motion = debate.confirmed_ballot.motion
        if motion is not None:
            debate_tag.set('motion', MOTION_PREFIX + str(motion.id))

        if debate.confirmed_ballot is not None:
            result = DebateResult(debate.confirmed_ballot, tournament=self.t)

            for side in self.t.sides:
                side_tag = SubElement(debate_tag, 'side', {
                    'team': TEAM_PREFIX + str(debate.get_team(side).id),
                })

                dt = debate.get_dt(side)
                if dt.debateteammotionpreference_set.exists():
                    side_tag.set('motion-veto', MOTION_PREFIX + str(dt.debateteammotionpreference_set.first().motion_id))

                if result.is_voting:
                    for (adj, scoresheet) in result.scoresheets.items():
                        self.add_team_ballots(side_tag, result, adj, scoresheet, side)
                elif not result.uses_speakers:
                    adv = side in result.get_winner()
                    ballot_tag = SubElement(side_tag, 'ballot', {
                        'adjudicators': adjs,
                        'rank': str(1 if adv else 2),
                        'ignored': 'false',
                    })
                    ballot_tag.text = str(adv)
                else:
                    self.add_team_ballots(
                        side_tag,
                        result,
                        adjs,
                        result.scoresheet,
                        side,
                    )

                if result.uses_speakers:
                    self.add_speakers(side_tag, debate, result, side)
예제 #2
0
        def create(self, validated_data):
            result = DebateResult(validated_data['ballot'], tournament=self.context.get('tournament'))

            sheets = self.SheetSerializer(context=self.context)
            for sheet in validated_data['sheets']:
                sheets._validated_data = sheet
                sheets.save(result=result)

            result.save()
            return result
예제 #3
0
파일: models.py 프로젝트: tienne-B/tabbycat
 def serialize_like_actionlog(self):
     if hasattr(self, '_result'):
         dr = self._result
     else:
         from results.result import DebateResult
         dr = DebateResult(self)
     result_winner, result = readable_ballotsub_result(dr)
     return {
         'user': result_winner,
         'id': self.id,
         'type': result,
         'param': '',
         'timestamp': badge_datetime_format(self.timestamp),
         'confirmed': self.confirmed,
         'debate': self.debate.id,
         'result_status': self.debate.result_status,
     }
예제 #4
0
def ballots_email_generator(to, debate):  # "to" is unused
    emails = []
    tournament = debate.round.tournament
    results = DebateResult(debate.confirmed_ballot)
    round_name = _("%(tournament)s %(round)s @ %(room)s") % {
        'tournament': str(tournament),
        'round': debate.round.name,
        'room': debate.venue.name
    }

    use_codes = use_team_code_names(tournament, False)

    def _create_ballot(result, scoresheet):
        ballot = "<ul>"

        for side, (side_name,
                   pos_names) in zip(tournament.sides,
                                     side_and_position_names(tournament)):
            side_string = ""
            if tournament.pref('teams_in_debate') == 'bp':
                side_string += _(
                    "<li>%(side)s: %(team)s (%(points)d points with %(speaks)s total speaks)"
                )
                points = 4 - scoresheet.rank(side)
            else:
                side_string += _(
                    "<li>%(side)s: %(team)s (%(points)s - %(speaks)s total speaks)"
                )
                points = _("Win") if side in scoresheet.winners() else _(
                    "Loss")

            ballot += side_string % {
                'side':
                side_name,
                'team':
                result.debateteams[side].team.code_name
                if use_codes else result.debateteams[side].team.short_name,
                'speaks':
                formats.localize(scoresheet.get_total(side)),
                'points':
                points,
            }

            ballot += "<ul>"

            for pos, pos_name in zip(tournament.positions, pos_names):
                ballot += _("<li>%(pos)s: %(speaker)s (%(score)s)</li>") % {
                    'pos': pos_name,
                    'speaker': result.get_speaker(side, pos).name,
                    'score': formats.localize(scoresheet.get_score(side, pos)),
                }

            ballot += "</ul></li>"

        ballot += "</ul>"

        return mark_safe(ballot)

    if isinstance(results, DebateResultByAdjudicatorWithScores):
        for adj, ballot in results.scoresheets.items():
            if adj.email is None:  # As "to" is None, must check if eligible email
                continue

            context = {
                'DEBATE': round_name,
                'USER': adj.name,
                'SCORES': _create_ballot(results, ballot)
            }
            emails.append((context, adj))
    elif isinstance(results, ConsensusDebateResultWithScores):
        context = {
            'DEBATE': round_name,
            'SCORES': _create_ballot(results, results.scoresheet)
        }

        for adj in debate.debateadjudicator_set.all().select_related(
                'adjudicator'):
            if adj.adjudicator.email is None:
                continue

            context_user = context.copy()
            context_user['USER'] = adj.adjudicator.name

            emails.append((context_user, adj.adjudicator))

    return emails
예제 #5
0
파일: dbutils.py 프로젝트: vicbab/tabbycat
def add_result(debate,
               submitter_type,
               user,
               discarded=False,
               confirmed=False,
               reply_random=False):
    """Adds a ballot set to a debate.

    ``debate`` is the Debate to which the ballot set should be added.
    ``submitter_type`` is a valid value of BallotSubmission.submitter_type.
    ``user`` is a User object.
    ``discarded`` and ``confirmed`` are whether the feedback should be discarded or
        confirmed, respectively.
    ``min_score`` and ``max_score`` are the range in which scores should be generated."""

    if discarded and confirmed:
        raise ValueError("Ballot can't be both discarded and confirmed!")

    t = debate.round.tournament

    if not debate.sides_confirmed:
        debate.sides_confirmed = True
        debate.save()

    # Create a new BallotSubmission
    bsub = BallotSubmission(submitter_type=submitter_type, debate=debate)
    if submitter_type == BallotSubmission.SUBMITTER_TABROOM:
        bsub.submitter = user
    bsub.save()

    # Create relevant scores
    result = DebateResult(bsub)

    if result.uses_speakers:
        for side in t.sides:
            speakers = list(debate.get_team(side).speakers)  # fix order
            for i in range(1, t.last_substantive_position + 1):
                result.set_speaker(side, i, speakers[i - 1])
                result.set_ghost(side, i, False)

            if t.reply_position is not None:
                reply_speaker = random.randint(0, t.last_substantive_position -
                                               2) if reply_random else 0
                result.set_speaker(side, t.reply_position,
                                   speakers[reply_speaker])
                result.set_ghost(side, t.reply_position, False)

    if result.is_voting:
        for scoresheet in result.scoresheets.values():
            fill_scoresheet_randomly(scoresheet, t)
    elif result.uses_advancing:
        result.set_advancing(random.sample(t.sides, 2))
    else:
        fill_scoresheet_randomly(result.scoresheet, t)

    assert result.is_valid()
    result.save()

    # Pick a motion
    motions = debate.round.motion_set.all()
    if motions:
        num_motions = 3 if motions.count() > 3 else motions.count()
        sample = random.sample(list(motions), k=num_motions)
        motion = sample[0]
        bsub.motion = motion

        if t.pref('motion_vetoes_enabled') and len(sample) == len(t.sides) + 1:
            for i, side in enumerate(t.sides, 1):
                dt = debate.get_dt(side)
                dt.debateteammotionpreference_set.create(
                    motion=sample[i],
                    preference=3,
                    ballot_submission=bsub,
                )

    bsub.discarded = discarded
    bsub.confirmed = confirmed

    bsub.save()

    # Update result status (only takes into account marginal effect, does not "fix")
    if confirmed:
        debate.result_status = Debate.STATUS_CONFIRMED
    elif not discarded and debate.result_status != Debate.STATUS_CONFIRMED:
        debate.result_status = Debate.STATUS_DRAFT
    debate.save()

    if t.pref('teams_in_debate') == 'two':
        logger.info(
            "%(debate)s won by %(team)s on %(motion)s", {
                'debate': debate.matchup,
                'team': result.winning_side(),
                'motion': bsub.motion and bsub.motion.reference
                or "<No motion>"
            })
    elif t.pref('teams_in_debate') == 'bp':
        if result.uses_advancing:
            logger.info(
                "%(debate)s: %(advancing)s on %(motion)s", {
                    'debate':
                    debate.matchup,
                    'advancing':
                    ", ".join(result.advancing_sides()),
                    'motion':
                    bsub.motion and bsub.motion.reference or "<No motion>"
                })
        else:
            logger.info(
                "%(debate)s: %(ranked)s on %(motion)s", {
                    'debate':
                    debate.matchup,
                    'ranked':
                    ", ".join(result.scoresheet.ranked_sides()),
                    'motion':
                    bsub.motion and bsub.motion.reference or "<No motion>"
                })

    return result
예제 #6
0
파일: dbutils.py 프로젝트: tfpk/tabbycat
def add_result(debate,
               submitter_type,
               user,
               discarded=False,
               confirmed=False,
               min_score=72,
               max_score=78,
               reply_random=False):
    """Adds a ballot set to a debate.

    ``debate`` is the Debate to which the ballot set should be added.
    ``submitter_type`` is a valid value of BallotSubmission.submitter_type.
    ``user`` is a User object.
    ``discarded`` and ``confirmed`` are whether the feedback should be discarded or
        confirmed, respectively.
    ``min_score`` and ``max_score`` are the range in which scores should be generated."""

    if discarded and confirmed:
        raise ValueError("Ballot can't be both discarded and confirmed!")

    t = debate.round.tournament

    # Create a new BallotSubmission
    bsub = BallotSubmission(submitter_type=submitter_type, debate=debate)
    if submitter_type == BallotSubmission.SUBMITTER_TABROOM:
        bsub.submitter = user
    bsub.save()

    # Create relevant scores
    result = DebateResult(bsub)

    for side in t.sides:
        speakers = debate.get_team(side).speakers
        for i in range(1, t.last_substantive_position + 1):
            result.set_speaker(side, i, speakers[i - 1])
            result.set_ghost(side, i, False)

        if t.reply_position is not None:
            reply_speaker = random.randint(0, t.last_substantive_position -
                                           1) if reply_random else 0
            result.set_speaker(side, t.reply_position, speakers[reply_speaker])
            result.set_ghost(side, t.reply_position, False)

    if result.is_voting:
        for scoresheet in result.scoresheets.values():
            fill_scoresheet_randomly(scoresheet, t)
    else:
        fill_scoresheet_randomly(result.scoresheet, t)

    result.save()

    # Pick a motion
    motions = debate.round.motion_set.all()
    if motions:
        motion = random.choice(motions)
        bsub.motion = motion

    bsub.discarded = discarded
    bsub.confirmed = confirmed

    bsub.save()

    # Update result status (only takes into account marginal effect, does not "fix")
    if confirmed:
        debate.result_status = Debate.STATUS_CONFIRMED
    elif not discarded and debate.result_status != Debate.STATUS_CONFIRMED:
        debate.result_status = Debate.STATUS_DRAFT
    debate.save()

    if t.pref('teams_in_debate') == 'two':
        logger.info(
            "%(debate)s won by %(team)s on %(motion)s", {
                'debate': debate.matchup,
                'team': result.winning_side(),
                'motion': bsub.motion and bsub.motion.reference
                or "<No motion>"
            })
    elif t.pref('teams_in_debate') == 'bp':
        logger.info(
            "%(debate)s: %(ranked)s on %(motion)s", {
                'debate': debate.matchup,
                'ranked': ", ".join(result.scoresheet.ranked_sides()),
                'motion': bsub.motion and bsub.motion.reference
                or "<No motion>"
            })

    return result
예제 #7
0
파일: models.py 프로젝트: tienne-B/tabbycat
 def result(self):
     if not hasattr(self, "_result"):
         self._result = DebateResult(self)
     return self._result
예제 #8
0
파일: dbutils.py 프로젝트: czlee/tabbycat
def add_result(debate, submitter_type, user, discarded=False, confirmed=False,
                  min_score=72, max_score=78, reply_random=False):
    """Adds a ballot set to a debate.

    ``debate`` is the Debate to which the ballot set should be added.
    ``submitter_type`` is a valid value of BallotSubmission.submitter_type.
    ``user`` is a User object.
    ``discarded`` and ``confirmed`` are whether the feedback should be discarded or
        confirmed, respectively.
    ``min_score`` and ``max_score`` are the range in which scores should be generated."""

    if discarded and confirmed:
        raise ValueError("Ballot can't be both discarded and confirmed!")

    t = debate.round.tournament

    # Create a new BallotSubmission
    bsub = BallotSubmission(submitter_type=submitter_type, debate=debate)
    if submitter_type == BallotSubmission.SUBMITTER_TABROOM:
        bsub.submitter = user
    bsub.save()

    # Create relevant scores
    result = DebateResult(bsub)

    for side in t.sides:
        speakers = list(debate.get_team(side).speakers)  # fix order
        for i in range(1, t.last_substantive_position+1):
            result.set_speaker(side, i, speakers[i-1])
            result.set_ghost(side, i, False)

        if t.reply_position is not None:
            reply_speaker = random.randint(0, t.last_substantive_position-1) if reply_random else 0
            result.set_speaker(side, t.reply_position, speakers[reply_speaker])
            result.set_ghost(side, t.reply_position, False)

    if result.is_voting:
        for scoresheet in result.scoresheets.values():
            fill_scoresheet_randomly(scoresheet, t)
    else:
        fill_scoresheet_randomly(result.scoresheet, t)

    assert result.is_valid()
    result.save()

    # Pick a motion
    motions = debate.round.motion_set.all()
    if motions:
        motion = random.choice(motions)
        bsub.motion = motion

    bsub.discarded = discarded
    bsub.confirmed = confirmed

    bsub.save()

    # Update result status (only takes into account marginal effect, does not "fix")
    if confirmed:
        debate.result_status = Debate.STATUS_CONFIRMED
    elif not discarded and debate.result_status != Debate.STATUS_CONFIRMED:
        debate.result_status = Debate.STATUS_DRAFT
    debate.save()

    if t.pref('teams_in_debate') == 'two':
        logger.info("%(debate)s won by %(team)s on %(motion)s", {
            'debate': debate.matchup,
            'team': result.winning_side(),
            'motion': bsub.motion and bsub.motion.reference or "<No motion>"
        })
    elif t.pref('teams_in_debate') == 'bp':
        logger.info("%(debate)s: %(ranked)s on %(motion)s", {
            'debate': debate.matchup,
            'ranked': ", ".join(result.scoresheet.ranked_sides()),
            'motion': bsub.motion and bsub.motion.reference or "<No motion>"
        })

    return result
예제 #9
0
    def import_results(self):
        for round in self.root.findall('round'):
            consensus = self.preliminary_consensus if round.get(
                'elimination') == 'false' else self.elimination_consensus

            for debate in round.findall('debate'):
                bs_obj = BallotSubmission(
                    version=1,
                    submitter_type=Submission.SUBMITTER_TABROOM,
                    confirmed=True,
                    debate=self.debates[debate.get('id')],
                    motion=self.motions.get(debate.get('motion')))
                bs_obj.save()
                dr = DebateResult(bs_obj)

                numeric_scores = True
                try:
                    float(debate.find("side/ballot").text)
                except ValueError:
                    numeric_scores = False

                for side, side_code in zip(debate.findall('side'),
                                           self.tournament.sides):

                    if side.get('motion-veto') is not None:
                        bs_obj.debateteammotionpreference_set.add(
                            debate_team=self.debateteams.get(
                                (debate.get('id'), side.get('team'))),
                            motion=self.motions.get(side.get('motion-veto')),
                            preference=3)

                    for speech, pos in zip(side.findall('speech'),
                                           self.tournament.positions):
                        if numeric_scores:
                            dr.set_speaker(
                                side_code, pos,
                                self.speakers.get(speech.get('speaker')))
                            if consensus:
                                dr.set_score(side_code, pos,
                                             float(speech.find('ballot').text))
                            else:
                                for ballot in speech.findall('ballot'):
                                    for adj in [
                                            self.adjudicators[a]
                                            for a in ballot.get(
                                                'adjudicators', "").split(" ")
                                    ]:
                                        dr.set_score(adj, side_code, pos,
                                                     float(ballot.text))
                    # Note: Dependent on #1180
                    if consensus:
                        if int(side.find('ballot').get('rank')) == 1:
                            dr.add_winner(side_code)
                    else:
                        for ballot in side.findall('ballot'):
                            for adj in [
                                    self.adjudicators.get(a) for a in
                                    ballot.get('adjudicators', "").split(" ")
                            ]:
                                if int(ballot.get('rank')) == 1:
                                    dr.add_winner(adj, side_code)
                dr.save()