Esempio n. 1
0
def test_check_inputs(player_names, seed):
    """ Test StableRoommates raises a ValueError when a player has not ranked
    all other players. """

    players = make_players(player_names, seed)
    game = StableRoommates(players)

    players[0].prefs = players[0].prefs[:-1]
    with pytest.raises(Exception):
        StableRoommates(players)
Esempio n. 2
0
def test_solve(player_names, seed):
    """ Test that StableRoommates can solve games correctly when passed players.
    """

    players = make_players(player_names, seed)
    game = StableRoommates(players)

    matching = game.solve()
    assert isinstance(matching, Matching)
    assert set(matching.keys()) == set(players)
    for match in matching.values():
        assert match is None or match in players
def makeQuads(students: dict, matchDict: dict, pairs: list):
    #Make a copy that won't change the orignal students
    extraStudents = []

    for pair in pairs:
        extraStudents.append(pair)
        
    quads = []

    #Control mechanisms for the loop: check if all the pairs been put into quads
    finished = False
    if len(extraStudents) == 0:
        finished = True
    i = 0
    
    #You don't want to loop too many times, but run five times at most to find good matches that have not matched before
    while(not finished and i < 10):
        preferenceList = preferenceSymmetricalSort(extraStudents, "TwoByTwo", matchDict)
        game = StableRoommates.create_from_dictionary(preferenceList)
        ans = game.solve()

        
        #remove the students who did not find matches out, delete them from the ans dict
        extraStudents = removeImpossibleTwo(ans, matchDict, students, pairs, extraStudents)
        
        #Take the remaining, succesful students, and place them into pairs
        moveStudentsTwo(ans, quads, students, pairs)

        #Update your controls
        if len(extraStudents) == 0:
            finished = True
        i = i + 1
    
    for index in range(5):
        listUsedIndexes = list()
        pairsToMake = list()
        for index1 in range(len(extraStudents)):
            for index2 in range(len(extraStudents)):
                if index1 != index2 and (index1 not in listUsedIndexes) and (index2 not in listUsedIndexes):
                    if isValidGroup(matchDict, [extraStudents[index1][0], extraStudents[index1][1], extraStudents[index2][0], extraStudents[index2][1]]) == 0:
                        listUsedIndexes.append(index1)
                        listUsedIndexes.append(index2)
                        pairsToMake.append([index1, index2])

        usedStudents = list()
        for pairToMake in pairsToMake:
            quads.append([extraStudents[pairToMake[0]][0], extraStudents[pairToMake[0]][1], extraStudents[pairToMake[1]][0], extraStudents[pairToMake[1]][1]])
            usedStudents.extend([extraStudents[pairToMake[0]], extraStudents[pairToMake[1]]])
        

        for student in usedStudents:
            extraStudents.remove(student)

    #Now do random
    for index in range(0, len(extraStudents), 2):
        quads.append([extraStudents[index][0], extraStudents[index][1], extraStudents[index+1][0], extraStudents[index+1][1]])
    extraStudents.clear()

    return quads
Esempio n. 4
0
def main():
    logging.info("Fetching player data...")
    player_data = fetch_player_data()

    logging.info("Calculating player preferences...")
    player_preferences = calculate_player_preferences(
        all_players=player_data,
        player_pool=_load_player_pool(),
        match_history_days=90,
    )

    logging.info("Calculating matchups...")
    game = StableRoommates.create_from_dictionary(
        player_prefs=player_preferences)
    result: SingleMatching = game.solve()

    matched_players: List[str] = []
    match_rows: List[str] = []
    court_number = 1
    for p, o in result.items():
        player_name = p.name
        opponent_name = o.name
        if player_name in matched_players:
            continue
        player = _find_player_by_name(players=player_data,
                                      player_name=player_name)
        if not player:
            raise MatchException(
                f'Could not find player "{player_name}" in player data.')
        opponent = _find_player_by_name(players=player_data,
                                        player_name=opponent_name)
        if not player or not opponent:
            raise MatchException(
                f'Could not find opponent "{opponent_name}" in player data.')
        matched_players += [player_name, opponent_name]
        player_history = fetch_player_match_history(player=player,
                                                    match_history_days=31)
        opponent_previous_match_dates = sorted(
            player_history.get(opponent.name, []),
            key=lambda x: x.match_date,
            reverse=True,
        )
        previous_match_date = (opponent_previous_match_dates[0].match_date
                               if opponent_previous_match_dates else None)
        match_rows.append(
            _create_match_row(
                court_number=court_number,
                player1=player,
                player2=opponent,
                stats=fetch_opponent_stats(player_id=player.id,
                                           opponent_id=opponent.id),
                previous_match_date=previous_match_date,
            ))
        court_number += 1

    with open("matchup-result.txt", "w") as file:
        file.write("\n".join(match_rows))

    logging.info('Done! Matchup result written to "matchup-result.txt".')
Esempio n. 5
0
def test_solve(player_names, seed):
    """Test that StableRoommates can solve games correctly when passed players."""

    players = make_players(player_names, seed)
    game = StableRoommates(players)

    matching = game.solve()
    assert isinstance(matching, Matching)

    players = sorted(players, key=lambda p: p.name)
    matching_keys = sorted(matching.keys(), key=lambda k: k.name)

    for game_player, player in zip(matching_keys, players):
        assert game_player.name == player.name
        assert game_player.pref_names == player.pref_names

    for match in matching.values():
        assert match is None or match in game.players
Esempio n. 6
0
def test_init(player_names, seed):
    """ Test that the StableRoommates solver takes a set of preformed players
    correctly. """

    players = make_players(player_names, seed)
    game = StableRoommates(players)

    assert game.players == players
    assert all([player.matching is None for player in game.players])
    assert game.matching is None
Esempio n. 7
0
def test_create_from_dictionary(preferences):
    """Test that StableRoommates solver can take a preference dictionary
    correctly."""

    game = StableRoommates.create_from_dictionary(preferences)

    for player in game.players:
        assert preferences[player.name] == player._pref_names
        assert player.matching is None

    assert game.matching is None
Esempio n. 8
0
def test_init(players):
    """Test that the StableRoommates solver has the correct attributes at
    instantiation."""

    game = StableRoommates(players)

    for player, game_player in zip(players, game.players):
        assert player.name == game_player.name
        assert player._pref_names == game_player._pref_names

    assert game.matching is None
Esempio n. 9
0
def test_stability():
    """Test that StableRoommates can recognise whether a matching is stable."""

    players = [Player("A"), Player("B"), Player("C"), Player("D")]
    a, b, c, d = players

    a.set_prefs([b, c, d])
    b.set_prefs([c, d, a])
    c.set_prefs([d, b, a])
    d.set_prefs([a, b, c])

    game = StableRoommates(players)

    matching = game.solve()
    assert game.check_stability()

    a, b, c, d = game.players

    matching[a] = c
    matching[b] = d
    matching[c] = a
    matching[d] = b

    assert not game.check_stability()

    matching[a] = None
    matching[c] = None
    assert not game.check_stability()
def calculate_matches(clique):
    clique = list(clique)
    preferences_dict = {}
    for node in clique:
        node_elo_diff_list = []
        for node2 in clique:
            if node == node2:
                continue
            node_elo_diff_list.append(
                [node2, abs(node.average_elo - node2.average_elo)])
        node_elo_diff_list.sort(key=lambda x: x[1])
        preferences_dict[node] = [item[0] for item in node_elo_diff_list]
    matches = StableRoommates.create_from_dictionary(preferences_dict)
    return matches.solve()
Esempio n. 11
0
def test_check_validity(player_names, seed):
    """ Test that StableRoommates can raise a ValueError if any players are left
    unmatched. """

    players = make_players(player_names, seed)
    game = StableRoommates(players)

    matching = game.solve()
    if None in matching.values():
        with pytest.raises(Exception):
            game.check_validity()

    else:
        assert game.check_validity()
def makePairs(students: dict, matchDict: dict):
    #Make a copy that won't change the orignal students
    extraStudents = []

    for student in students:
        extraStudents.append((students[student]))
        
    pairs = []

    #Control mechanisms for the loop: check if all the students have been paired, and that the list has not been 
    finished = False
    if len(extraStudents) == 0:
        finished = True
    
    i = 0
    #You don't want to loop too many times, but run five times at most to find good matches that have not matched before
    while(not finished and i < 10):
        preferenceList = preferenceSymmetricalSort(extraStudents, "OneByOne", matchDict)
        game = StableRoommates.create_from_dictionary(preferenceList)
        ans = game.solve()
        
        #remove the students who did not find matches out, delete them from the ans dict
        extraStudents = removeImpossibleOne(ans, matchDict, students, extraStudents)

        #Take the remaining, succesful students, and place them into pairs
        moveStudentsOne(ans, pairs, students)

        #Update your controls
        if len(extraStudents) == 0:
            finished = True
            break

        i = i + 1
    
    for index in range(5):
        listUsedIndexes = list()
        pairsToMake = list()
        for index1 in range(len(extraStudents)):
            for index2 in range(len(extraStudents)):
                if index1 != index2 and (index1 not in listUsedIndexes) and (index2 not in listUsedIndexes):
                    if isValidGroup(matchDict, [extraStudents[index1], extraStudents[index2]]) == 0:
                        listUsedIndexes.append(index1)
                        listUsedIndexes.append(index2)
                        pairsToMake.append([index1, index2])

        usedStudents = list()
        for pairToMake in pairsToMake:
            pairs.append([extraStudents[pairToMake[0]], extraStudents[pairToMake[1]]])
            usedStudents.extend([extraStudents[pairToMake[0]], extraStudents[pairToMake[1]]])
        

        for student in usedStudents:
            extraStudents.remove(student)


    if len(extraStudents)%2 == 1:
        print("Problem: odd number of students in extraStudents")

    #Match the rest of the students randomly and print that the matching sucked
    for index in range(0, len(extraStudents), 2):
        if (index+1) < len(extraStudents):
            pairs.append([extraStudents[index], extraStudents[index+1]])
    extraStudents.clear()

    
    #Return the pairs list (list[Student, Student])
    return pairs
Esempio n. 13
0
def match(eventName):
    client = pymongo.MongoClient(
        "mongodb+srv://admin1:[email protected]/matching?retryWrites=true&w=majority"
    )
    db = client['matching']
    print(db.list_collection_names())
    dbt = db['matchings']
    getresponses = db['responses']
    # create a dictionary
    print("HERE : ")
    users = {}
    resps = getresponses.find({"eventName": eventName})
    for response in resps:
        print(response)
        users[response['userEmail']] = {}
        users[response['userEmail']]["responses"] = response['Responses']
        users[response['userEmail']]["Name"] = response["userName"]
    usersim = {}
    simrank = {}
    #actual matching logic
    for key in users:
        simrank[key] = []
        for key2 in users:
            tempsim = 0
            for question in users[key]["responses"]:
                c1 = question.split(", ")
                c2 = question.split(", ")
                tempsim += sum(map(eq, c1, c2))
            #invert tempsim
            tempsim *= -1
            mytuple = (tempsim, key2)
            simrank[key].append(mytuple)
    for key in simrank:
        simrank[key].sort()
    gamedict = {}
    for key in simrank:
        gamedict[key] = [lis[1] for lis in simrank[key]]
    for key in gamedict:
        for match in gamedict[key]:
            if match == key:
                gamedict[key].remove(key)
    game = StableRoommates.create_from_dictionary(gamedict)
    matching = game.solve()
    # Open a json writer, and use the json.dumps()
    # function to dump data
    #Replace <password> with the password for the admin1 user. Replace <dbname> with the name of the database that connections will use by default. Ensure any option params are
    tosend = {}
    tosend['matchings'] = []
    for pair1 in matching:
        pair2 = matching[pair1]
        pair1 = str(pair1)
        pair2 = str(pair2)
        if pair2 in users:
            tosend['matchings'].append({
                "email": pair1,
                "match": {
                    "name": users[pair2]['Name'],
                    "email": pair2
                }
            })
    x = dbt.insert_one(tosend)
Esempio n. 14
0
def games(draw, **kwargs):
    """ A strategy for making an instance of SR. """

    players_ = draw(players(**kwargs))
    return StableRoommates(players_)
Esempio n. 15
0
def solve_stm(named_rankings):
    players = {name: prefs.index for name, prefs in named_rankings.items()}
    game = StableRoommates.create_from_dictionary(players)
    pairs = game.solve()
    return pairs.items()