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)
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
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".')
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
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
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
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
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()
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
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)
def games(draw, **kwargs): """ A strategy for making an instance of SR. """ players_ = draw(players(**kwargs)) return StableRoommates(players_)
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()