Beispiel #1
0
def test_check_stability():
    """Test that HospitalResident can recognise whether a matching is stable or
    not."""

    residents = [Resident("A"), Resident("B"), Resident("C")]
    hospitals = [Hospital("X", 2), Hospital("Y", 2)]

    (a, b, c), (x, y) = residents, hospitals

    a.set_prefs([x, y])
    b.set_prefs([y])
    c.set_prefs([y, x])

    x.set_prefs([c, a])
    y.set_prefs([a, b, c])

    game = HospitalResident(residents, hospitals)

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

    (a, b, c), (x, y) = game.residents, game.hospitals
    matching[x] = [c]
    matching[y] = [a, b]

    assert not game.check_stability()
Beispiel #2
0
def multiples(
    draw,
    host_names_from=text(),
    player_names_from=text(),
    min_hosts=2,
    max_hosts=5,
    min_players=10,
    max_players=20,
):
    """A custom strategy for generating a matching for `MultipleMatching` out
    of `Hospital` and lists of `Player` instances."""

    num_hosts = draw(integers(min_value=min_hosts, max_value=max_hosts))
    num_players = draw(integers(min_value=min_players, max_value=max_players))

    hosts = [
        Hospital(draw(host_names_from), max_players) for _ in range(num_hosts)
    ]
    players = [Player(draw(player_names_from)) for _ in range(num_players)]

    dictionary = {}
    for host in hosts:
        matches = draw(lists(sampled_from(players), min_size=0, unique=True))
        dictionary[host] = matches

    return dictionary
Beispiel #3
0
def test_check_for_unacceptable_matches_residents(resident_names,
                                                  hospital_names, capacities,
                                                  seed, clean):
    """Test that HospitalResident recognises a valid matching requires each
    resident to have a preference of their match, if they have one."""

    _, _, game = make_game(resident_names, hospital_names, capacities, seed,
                           clean)

    resident = game.residents[0]
    hospital = Hospital(name="foo", capacity=1)
    resident.matching = hospital

    issues = game._check_for_unacceptable_matches("residents")
    assert len(issues) == 1

    issue = issues[0]
    assert issue.startswith(resident.name)
    assert issue.endswith(f"{resident.prefs}.")
    assert hospital.name in issue

    with pytest.raises(MatchingError) as e:
        game.check_validity()
        error = e.unacceptable_matches[0]
        assert issue == error
Beispiel #4
0
def test_init(name, capacity):
    """ Make an instance of Hospital and check their attributes are correct. """

    hospital = Hospital(name, capacity)

    assert hospital.name == name
    assert hospital.capacity == capacity
    assert hospital.prefs is None
    assert hospital.pref_names is None
    assert hospital.matching == []
Beispiel #5
0
def test_check_if_match_is_unacceptable(name, capacity, pref_names):
    """ Check that a hospital can verify the acceptability of its matches. """

    hospital = Hospital(name, capacity)
    others = [Resident(other) for other in pref_names]

    assert hospital.check_if_match_is_unacceptable() == []

    hospital.set_prefs(others[:-1])
    hospital.matching = [others[-1]]
    message = hospital.not_in_preferences_message(others[-1])
    assert hospital.check_if_match_is_unacceptable() == [message]
Beispiel #6
0
def test_get_successors(name, capacity, pref_names):
    """Check that a hospital can get the successors to its worst current match."""

    hospital = Hospital(name, capacity)
    others = [Resident(other) for other in pref_names]

    hospital.set_prefs(others)
    hospital.matching = [others[0]]
    assert hospital.get_successors() == others[1:]

    hospital.matching = others
    assert hospital.get_successors() == []
Beispiel #7
0
def test_match(name, capacity, pref_names):
    """ Check that a hospital can match to a player correctly. """

    hospital = Hospital(name, capacity)
    others = [Resident(other) for other in pref_names]

    hospital.set_prefs(others)
    for i, other in enumerate(others[:-1]):
        hospital.match(other)
        assert hospital.matching == others[:i + 1]

    hospital.match(others[-1])
    assert hospital.matching == others
Beispiel #8
0
def players(draw, **kwargs):
    """ A custom strategy for making a set of residents and hospitals. """

    resident_prefs, hospital_prefs, capacities = draw(connections(**kwargs))

    residents = [Resident(name) for name in resident_prefs]
    hospitals = [Hospital(name, cap) for name, cap in capacities.items()]

    residents = _get_preferences(residents, hospitals, resident_prefs)
    hospitals = _get_preferences(hospitals, residents, hospital_prefs)

    return residents, hospitals
Beispiel #9
0
def test_get_favourite(name, capacity, pref_names):
    """ Check the correct player is returned as the hospital's favourite. """

    hospital = Hospital(name, capacity)
    others = [Resident(other) for other in pref_names]

    hospital.set_prefs(others)
    assert hospital.get_favourite() == others[0]

    hospital.matching = others
    assert hospital.get_favourite() is None
Beispiel #10
0
def test_check_if_oversubscribed(name, capacity, pref_names):
    """ Check that a hospital can verify whether it is oversubscribed. """

    hospital = Hospital(name, capacity)
    others = [Resident(other) for other in pref_names]

    assert hospital.check_if_oversubscribed() is False

    hospital.matching = others
    hospital.capacity = 0
    message = hospital.oversubscribed_message()
    assert hospital.check_if_oversubscribed() == message
Beispiel #11
0
def _make_instances(resident_prefs, hospital_prefs, capacities):
    """ Create ``Player`` (resident) and ``Hospital`` instances for the names in
    each dictionary. """

    resident_dict, hospital_dict = {}, {}
    for resident_name in resident_prefs:
        resident = Resident(name=resident_name)
        resident_dict[resident_name] = resident
    for hospital_name in hospital_prefs:
        capacity = capacities[hospital_name]
        hospital = Hospital(name=hospital_name, capacity=capacity)
        hospital_dict[hospital_name] = hospital

    return resident_dict, hospital_dict
Beispiel #12
0
def test_unmatch(name, capacity, pref_names):
    """ Check that a hospital can unmatch from a player correctly. """

    hospital = Hospital(name, capacity)
    others = [Resident(other) for other in pref_names]

    hospital.matching = others
    for i, other in enumerate(others[:-1]):
        hospital.unmatch(other)
        assert hospital.matching == others[i + 1:]

    hospital.unmatch(others[-1])
    assert hospital.matching == []
Beispiel #13
0
def test_get_worst_match(name, capacity, pref_names):
    """ Check that a hospital can return its worst match. """

    hospital = Hospital(name, capacity)
    others = [Resident(other) for other in pref_names]

    hospital.matching = [others[0]]
    assert hospital.get_worst_match() == others[0]

    hospital.matching = others
    assert hospital.get_worst_match() == others[-1]
Beispiel #14
0
def make_players(resident_names, hospital_names, capacities):
    """ Given some names and capacities, make a set of players for HR. """

    residents = [Resident(name) for name in resident_names]
    hospitals = [
        Hospital(name, capacity)
        for name, capacity in zip(hospital_names, capacities)
    ]

    possible_prefs = get_possible_prefs(hospitals)
    logged_prefs = {}
    for resident in residents:
        prefs = possible_prefs[np.random.randint(len(possible_prefs))]
        resident.set_prefs(prefs)
        for hospital in prefs:
            try:
                logged_prefs[hospital] += [resident]
            except KeyError:
                logged_prefs[hospital] = [resident]

    for hospital, resids in logged_prefs.items():
        hospital.set_prefs(np.random.permutation(resids).tolist())

    return residents, [hosp for hosp in hospitals if hosp.prefs is not None]