def test_parse_input_file(self):
        # Arrange
        path_to_test_data = os.path.abspath(os.path.realpath('juggle_fest_example.txt'))

        # Act
        circuits, jugglers = input_file_parser.parse_input_file(path_to_test_data)

        # Assert
        self.assertEqual('C0', circuits[0].name)
        self.assertEqual(7, circuits[0].hep_ranks[0])
        self.assertEqual(7, circuits[0].hep_ranks[1])
        self.assertEqual(10, circuits[0].hep_ranks[2])

        self.assertEqual('C1', circuits[1].name)
        self.assertEqual(2, circuits[1].hep_ranks[0])
        self.assertEqual(1, circuits[1].hep_ranks[1])
        self.assertEqual(1, circuits[1].hep_ranks[2])

        self.assertEqual('C2', circuits[2].name)
        self.assertEqual(7, circuits[2].hep_ranks[0])
        self.assertEqual(6, circuits[2].hep_ranks[1])
        self.assertEqual(4, circuits[2].hep_ranks[2])

        self.assertEqual('J0', jugglers[0].name)
        self.assertEqual(3, jugglers[0].hep_ranks[0])
        self.assertEqual(9, jugglers[0].hep_ranks[1])
        self.assertEqual(2, jugglers[0].hep_ranks[2])
        self.assertEqual(['C2', 'C0', 'C1'], jugglers[0].circuit_preferences)
    def test_juggler_fest_example(self):
        # Arrange
        circuits, jugglers = input_file_parser.parse_input_file("juggle_fest_example.txt")

        jugglers_prefer = juggler_circuit_matcher.jugglers_to_jugglers_prefers(jugglers)
        circuits_prefer = juggler_circuit_matcher.circuits_to_circuits_prefers(circuits, jugglers)

        expected_matches = {'C2': ['J3', 'J6', 'J10', 'J0'], 'C1': ['J8', 'J9', 'J1', 'J7'], 'C0': ['J11', 'J2', 'J4', 'J5']}

        # Act
        actual_matches = juggler_circuit_matcher.matchmaker(jugglers_prefer, circuits_prefer)

        # Assert
        self.assertEqual(expected_matches, actual_matches)
    def test_generate_output_juggle_fest_example(self):
        # Arrange
        path_to_test_data = os.path.abspath(os.path.realpath('juggle_fest_example.txt'))
        circuits, jugglers = input_file_parser.parse_input_file(path_to_test_data)

        matches = juggler_circuit_matcher.matchmaker(juggler_circuit_matcher.jugglers_to_jugglers_prefers(jugglers),
                                                     juggler_circuit_matcher.circuits_to_circuits_prefers(circuits, jugglers))

        output_file_generator.calc_representation_for_output_for_each_juggler(circuits, jugglers)

        expected_output = 'C2 J3 C2:120 C0:171 C1:31, J6 C2:128 C1:31 C0:188, J10 C0:120 C2:86 C1:21, J0 C2:83 C0:104 C1:17\nC1 J8 C1:21 C0:100 C2:80, J9 C1:23 C2:86 C0:94, J1 C0:119 C2:74 C1:18, J7 C2:75 C1:20 C0:106\nC0 J11 C0:154 C1:27 C2:108, J2 C0:128 C2:68 C1:18, J4 C0:122 C2:106 C1:23, J5 C0:161 C2:112 C1:26\n'

        # Act
        actual_output = output_file_generator.generate_output(matches, jugglers)
        output_file_generator.generate_output_file("juggle_fest_example_output.txt", matches, circuits, jugglers)

        # Assert
        self.assertEqual(expected_output, actual_output)
    def test_generate_output_juggle_fest(self):
        from datetime import datetime
        time_of_start = datetime.now()
        print 'starting test now (takes about 2 minutes to run): ' + str(time_of_start)
        # Arrange
        print 'starting test'
        path_to_test_data = os.path.abspath(os.path.realpath('juggle_fest.txt'))
        circuits, jugglers = input_file_parser.parse_input_file(path_to_test_data)
        print 'done parsing'
        matches = juggler_circuit_matcher.matchmaker(juggler_circuit_matcher.jugglers_to_jugglers_prefers(jugglers),
                                                     juggler_circuit_matcher.circuits_to_circuits_prefers(circuits, jugglers))
        print 'done matching'
        output_file_generator.calc_representation_for_output_for_each_juggler(circuits, jugglers)
        print 'done calculating output representation for jugglers'
        print 'all that is left is write to file!'
        # Act
        output_file_generator.generate_output_file("juggle_fest_output.txt", matches, circuits, jugglers)

        time_of_finish = datetime.now()
        print 'finishing test now: ' + str(time_of_finish)
        print 'total time for test: ' + str(time_of_finish - time_of_start)
    def test_calc_representation_for_output_for_each_juggler(self):
        # Arrange
        path_to_test_data = os.path.abspath(os.path.realpath('juggle_fest_example.txt'))
        circuits, jugglers = input_file_parser.parse_input_file(path_to_test_data)

        # Act
        output_file_generator.calc_representation_for_output_for_each_juggler(circuits, jugglers)

        # Assert
        self.assertEqual('J0 C2:83 C0:104 C1:17,', jugglers[0].representation_for_output)
        self.assertEqual('J1 C0:119 C2:74 C1:18,', jugglers[1].representation_for_output)
        self.assertEqual('J2 C0:128 C2:68 C1:18,', jugglers[2].representation_for_output)
        self.assertEqual('J3 C2:120 C0:171 C1:31,', jugglers[3].representation_for_output)
        self.assertEqual('J4 C0:122 C2:106 C1:23,', jugglers[4].representation_for_output)
        self.assertEqual('J5 C0:161 C2:112 C1:26,', jugglers[5].representation_for_output)
        self.assertEqual('J6 C2:128 C1:31 C0:188,', jugglers[6].representation_for_output)
        self.assertEqual('J7 C2:75 C1:20 C0:106,', jugglers[7].representation_for_output)
        self.assertEqual('J8 C1:21 C0:100 C2:80,', jugglers[8].representation_for_output)
        self.assertEqual('J9 C1:23 C2:86 C0:94,', jugglers[9].representation_for_output)
        self.assertEqual('J10 C0:120 C2:86 C1:21,', jugglers[10].representation_for_output)
        self.assertEqual('J11 C0:154 C1:27 C2:108,', jugglers[11].representation_for_output)
__author__ = 'Shay Weiss'

''' what we have here is obviously a small generalization of the stable marriage problem, where instead having each
    girl (circuit) accept just one suitor (juggler), each accepts a total of |jugglers|/|circuits| jugglers.

    The base code was taken from: http://rosettacode.org/wiki/Stable_marriage_problem
    and was modified to accommodate the new requirements (that's why code is a bit fugly)
'''

import copy
import input_file_parser

circuits, jugglers = input_file_parser.parse_input_file("juggle_fest_example.txt")

def jugglers_to_jugglers_prefers(jugglers):
    jugglers_prefers = {}
    for juggler in jugglers:
        jugglers_prefers[juggler.name] = juggler.circuit_preferences
    return jugglers_prefers

def circuits_to_circuits_prefers(circuits, jugglers):
    circuits_prefer = {}
    for circuit in circuits:
        circuits_prefer[circuit.name] = circuit.calc_preference_list(jugglers)
    return circuits_prefer

guy_prefers_demo = {
 'abe':  ['abi', 'eve', 'cath', 'ivy', 'jan', 'dee', 'fay', 'bea', 'hope', 'gay'],
 'bob':  ['cath', 'hope', 'abi', 'dee', 'eve', 'fay', 'bea', 'jan', 'ivy', 'gay'],
 'col':  ['hope', 'eve', 'abi', 'dee', 'bea', 'fay', 'ivy', 'gay', 'cath', 'jan'],
 'dan':  ['ivy', 'fay', 'dee', 'gay', 'hope', 'eve', 'jan', 'bea', 'cath', 'abi'],