Esempio n. 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()
Esempio n. 2
0
def test_check_for_unacceptable_matches_hospitals(resident_names,
                                                  hospital_names, capacities,
                                                  seed, clean):
    """Test that HospitalResident recognises a valid matching requires each
    hospital to have a preference of each of its matches, if any."""

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

    hospital = game.hospitals[0]
    resident = Resident(name="foo")
    hospital.matching.append(resident)

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

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

    with pytest.raises(MatchingError) as e:
        game.check_validity()
        error = e.unacceptable_matches[0]
        assert issue == error
Esempio n. 3
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]
Esempio n. 4
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
Esempio n. 5
0
def test_hospital_matching(resident_names, hospital_names, capacities, seed):
    """ Test that HospitalResident recognises a valid matching requires a
    hospital to have a preference of each of its matches, if any. """

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

    game.solve()
    game.hospitals[0].matching.append(Resident(name="foo"))

    with pytest.raises(Exception):
        game._check_hospital_matching()
Esempio n. 6
0
def test_resident_matching(resident_names, hospital_names, capacities, seed):
    """ Test that HospitalResident recognises a valid matching requires a resident
    to have a preference of their match, if they have one. """

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

    game.solve()
    game.residents[0].matching = Resident(name="foo")

    with pytest.raises(Exception):
        game._check_resident_matching()
Esempio n. 7
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
Esempio n. 8
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
Esempio n. 9
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]
Esempio n. 10
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() == []
Esempio n. 11
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 == []
Esempio n. 12
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
Esempio n. 13
0
def test_inputs_resident_prefs(resident_names, hospital_names, capacities,
                               seed):
    """ Test that each resident's preference list is a subset of the available
    hospitals, and check that an Exception is raised if not. """

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

    assert game._check_resident_prefs()

    game.residents[0].prefs = [Resident("foo")]

    with pytest.raises(Exception):
        game._check_resident_prefs()
Esempio n. 14
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
Esempio n. 15
0
def test_check_inputs_hospital_prefs_all_residents(game):
    """Test that every hospital has only residents in its preference list. If
    not, check that a warning is caught and the player's preferences are
    changed."""

    hospital = game.hospitals[0]
    hospital.prefs = [Resident("foo")]
    with warnings.catch_warnings(record=True) as w:
        game._check_inputs_player_prefs_all_in_party("hospitals", "residents")

        message = w[-1].message
        assert isinstance(message, PreferencesChangedWarning)
        assert hospital.name in str(message)
        assert "foo" in str(message)
        if game.clean:
            assert hospital.prefs == []
Esempio n. 16
0
def test_check_inputs_resident_prefs_all_hospitals(resident_names,
                                                   hospital_names, capacities,
                                                   seed, clean):
    """Test that every resident has only hospitals in its preference list. If
    not, check that a warning is caught and the player's preferences are
    changed."""

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

    resident = game.residents[0]
    resident.prefs = [Resident("foo")]
    with warnings.catch_warnings(record=True) as w:
        game._check_inputs_player_prefs_all_in_party("residents", "hospitals")

        message = w[-1].message
        assert isinstance(message, PreferencesChangedWarning)
        assert resident.name in str(message)
        assert "foo" in str(message)
        if clean:
            assert resident.prefs == []
Esempio n. 17
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]