예제 #1
0
class PointsControllerTestCase(TestCase):

    def setUp(self):
        self.og = Mock()
        self.oo = Mock()
        self.cg = Mock()
        self.co = Mock()
        self.points_controller = PointsController()
        self.results_controller = Mock()
        debate = Mock(OG=self.og, OO=self.oo, CG=self.cg, CO=self.co)
        result = Mock(debate=debate, og=0, oo=1, cg=2, co=3,
                      ogsp1 = 60, ogsp2 = 65,
                      oosp1 = 70, oosp2 = 75,
                      cgsp1 = 80, cgsp2 = 85,
                      cosp1 = 90, cosp2 = 95)
        self.results_controller.result_for_team.return_value = result
        self.points_controller.results_controller = self.results_controller

    def testGetTeamPoints(self):
        self.assertEqual(0, self.points_controller.team_points_for_team(self.og, 1), "Did not get correct team score for OG")
        self.assertEqual(1, self.points_controller.team_points_for_team(self.oo, 1), "Did not get correct team score for OO")
        self.assertEqual(2, self.points_controller.team_points_for_team(self.cg, 1), "Did not get correct team score for CG")
        self.assertEqual(3, self.points_controller.team_points_for_team(self.co, 1), "Did not get correct team score for CO")

    def testGetTeamPointsCallsResultController(self):
        self.points_controller.team_points_for_team(self.og, 1)
        self.results_controller.result_for_team.assert_called_once_with(self.og, 1)

    def testGetTotalPointsCallsCorrectNumberOfRounds(self):
        self.points_controller.total_points_for_team(self.og, 3)
        calls = [call(self.og, 1), call(self.og, 2), call(self.og, 3)]
        self.results_controller.result_for_team.assert_has_calls(calls, any_order=True)

    def testGetSpeakerPointsReturnsCorrectNumberOfPoints(self):
        speaks = self.points_controller.speaker_points_for_team(self.og, 1)
        self.assertEqual(2, len(speaks), "Should only return two speaker points per team")

    def testSpeakerPointsCorrectForOG(self):
        speaks = self.points_controller.speaker_points_for_team(self.og, 1)
        self.assertEqual(speaks[0], 60)
        self.assertEqual(speaks[1], 65)

    def testSpeakerPointsCorrectForOO(self):
        speaks = self.points_controller.speaker_points_for_team(self.oo, 1)
        self.assertEqual(speaks[0], 70)
        self.assertEqual(speaks[1], 75)

    def testSpeakerPointsCorrectForCG(self):
        speaks = self.points_controller.speaker_points_for_team(self.cg, 1)
        self.assertEqual(speaks[0], 80)
        self.assertEqual(speaks[1], 85)

    def testSpeakerPointsCorrectForCO(self):
        speaks = self.points_controller.speaker_points_for_team(self.co, 1)
        self.assertEqual(speaks[0], 90)
        self.assertEqual(speaks[1], 95)
예제 #2
0
 def total_team_points(self):
     from results.controllers.PointsController import PointsController
     controller = PointsController()
     from draw.models import Tournament
     return controller.total_points_for_team(self, Tournament.instance().round_with_results)
예제 #3
0
class DrawController:

    resultsController = None
    pointsController = None

    def __init__(self):
        self.resultsController = ResultsController()
        self.pointsController = PointsController()

    def draw_next_round(self):
        tournament = Tournament.instance()
        next_round = tournament.round + 1
        pools = self.create_pools(Team.objects.all(), tournament.round)
        pools = self.remove_empty(pools)
        pools = self.shuffle_pools(pools)
        pools = self.balance_pools(pools)
        debates = self.draw_from_pools(next_round, pools)
        tournament.round = next_round
        tournament.save()
        mapper = VenueMapper()
        mapper.map_venues(next_round)
        return debates

    def create_pools(self, teams, max_round):
        if not self.resultsController.results_entered_for_round(Tournament.instance().round):
            raise TournamentStateException("All results for current round must be entered to draw")
        pools = self.create_blank_pools(max_round)

        for team in teams:
            points = self.pointsController.total_points_for_team(team, 1)
            pools[points].append(team)

        return pools

    @staticmethod
    def create_blank_pools(max_round):
        pools = {}
        if max_round == 0:
            return pools

        for points in range(0, 4 + ((max_round - 1) * 3)):
            pools.update({points: []})
        return pools

    @staticmethod
    def remove_empty(pools):
        keys = pools.keys()
        for key in keys:
            pool = pools[key]
            if len(pool) < 1:
                pools.pop(key)
        return pools

    @staticmethod
    def next_viable_pool(current, pools):
        for i in range(current + 1, len(pools.values())):
            next_pool = pools.values()[i]
            if len(next_pool) != 0:
                return next_pool
        raise ValueError("No viable pool")

    @staticmethod
    def shuffle_pools(pools):
        for pool in pools.values():
            random.shuffle(pool)
        return pools

    def balance_pools(self, pools):
        flattened_pools = [item for sublist in pools.values() for item in sublist]
        if len(flattened_pools) % 4 != 0:
            raise ValueError("Number of teams must be divisible by 4")

        made_swap = True
        while made_swap:
            made_swap = False
            for i in range(0, len(pools.values())):
                pool = pools.values()[i]
                if (len(pool) % 4 != 0) and pool != pools.values()[-1]:
                    teams_needed = 4 - (len(pool) % 4)
                    for t in range(0, teams_needed):
                        source_pool = self.next_viable_pool(i, pools)
                        pool.append(source_pool.pop(0))
                        made_swap = True

        return pools

    def draw_from_pools(self, round, pools):
        debates = []
        for pool in pools.values():
            if len(pool) % 4 != 0:
                raise ValueError("Number of teams must be divisible by four")

            num_debates = len(pool) / 4

            for i in range(0, num_debates):
                debate = Debate(round=round)
                debate.OG = pool[(i * 4)]
                debate.OO = pool[(i * 4) + 1]
                debate.CG = pool[(i * 4) + 2]
                debate.CO = pool[(i * 4) + 3]
                debate.full_clean()
                debate.save()
                debates.append(debate)
        return debates