mirror of
https://github.com/tgorordo/carousel.git
synced 2026-06-12 20:42:13 -07:00
init commit; data shapes mostly defined. some tests and sketched documentation in README. core algorithm TODO next
This commit is contained in:
commit
c571fa1d17
8 changed files with 434 additions and 0 deletions
96
test/galeshapley_test.py
Normal file
96
test/galeshapley_test.py
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import rich
|
||||
import polars as pl
|
||||
import polars.selectors as pls
|
||||
import numpy as np
|
||||
|
||||
rng = np.random.default_rng()
|
||||
|
||||
from polars.testing import assert_frame_equal
|
||||
|
||||
import pytest
|
||||
from hypothesis import given, strategies as st
|
||||
|
||||
|
||||
@st.composite
|
||||
def rankings(draw, names=["a", "b", "c"], choices=["A", "B", "C"]):
|
||||
h = pl.DataFrame({"": choices})
|
||||
r = pl.DataFrame(
|
||||
{n: draw(st.just(rng.permutation(len(choices)) + 1)) for n in names}
|
||||
) # should add None option in generation of valid rankings
|
||||
return pl.concat([h, r], how="horizontal")
|
||||
|
||||
|
||||
@st.composite
|
||||
def preferences(draw, names=["a", "b", "c"], choices=["A", "B", "C"]):
|
||||
p = pl.DataFrame(
|
||||
{
|
||||
n: draw(st.just(rng.choice(choices, size=len(choices), replace=False)))
|
||||
for n in names
|
||||
}
|
||||
)
|
||||
return p
|
||||
|
||||
|
||||
import carousel as crsl
|
||||
|
||||
p = pl.DataFrame({"a": ["A", "C", "B"], "b": ["B", "A", "C"], "c": ["C", "B", "A"]})
|
||||
r = pl.DataFrame({"": ["A", "B", "C"], "a": [1, 3, 2], "b": [2, 1, 3], "c": [3, 2, 1]})
|
||||
|
||||
|
||||
def test_invalid_pref():
|
||||
pp = pl.DataFrame(
|
||||
{"a": ["A", "A", "B"], "b": ["B", "A", "C"], "c": ["C", "B", "A"]}
|
||||
)
|
||||
assert crsl.check_valid_pref(pp) is False
|
||||
|
||||
|
||||
def test_pref_to_rank():
|
||||
rr = crsl.pref_to_rank(p)
|
||||
rich.print(p, rr, r)
|
||||
assert_frame_equal(crsl.pref_to_rank(p), r, check_dtypes=False)
|
||||
|
||||
|
||||
def test_invalid_rank():
|
||||
rr = pl.DataFrame(
|
||||
{"": ["A", "B", "C"], "a": [1, 1, 2], "b": [2, 1, 3], "c": [3, 2, 1]}
|
||||
)
|
||||
assert crsl.check_valid_pref(rr) is False
|
||||
|
||||
|
||||
def test_rank_to_pref():
|
||||
assert_frame_equal(crsl.rank_to_pref(r), p, check_dtypes=False)
|
||||
|
||||
|
||||
@given(rankings())
|
||||
def test_valid_rank(R):
|
||||
assert crsl.check_valid_rank(R)
|
||||
|
||||
|
||||
@given(rankings())
|
||||
def test_ranks_tofrom_prefs(R):
|
||||
assert_frame_equal(crsl.pref_to_rank(crsl.rank_to_pref(R)), R, check_dtypes=False)
|
||||
|
||||
|
||||
@given(preferences())
|
||||
def test_valid_pref(P):
|
||||
assert crsl.check_valid_pref(P)
|
||||
|
||||
|
||||
@given(preferences())
|
||||
def test_prefs_tofrom_ranks(P):
|
||||
assert_frame_equal(crsl.rank_to_pref(crsl.pref_to_rank(P)), P, check_dtypes=False)
|
||||
|
||||
|
||||
def test_eg3_unstable():
|
||||
applicant_rankings = pl.DataFrame({"": ["A", "B", "C", "D"], "a": [1, 2, 3, 4], "b": [1, 4, 3, 2], "c": [2, 1, 3, 4], "d": [4, 2, 3, 1]})
|
||||
reviewer_rankings = pl.DataFrame({"": ["a", "b", "c", "d"], "A": [3, 4, 2, 1], "B": [3, 1, 4, 2], "C": [2, 3, 4, 1], "D": [3, 2, 1, 4] })
|
||||
match = pl.DataFrame({"A" : ["a"], "B": ["b"], "C": ["c"], "D": ["d"]})
|
||||
|
||||
assert crsl.check_unstable(match, applicant_rankings, reviewer_rankings)
|
||||
|
||||
def test_eg3_isstable():
|
||||
applicant_rankings = pl.DataFrame({"": ["A", "B", "C", "D"], "a": [1, 2, 3, 4], "b": [1, 4, 3, 2], "c": [2, 1, 3, 4], "d": [4, 2, 3, 1]})
|
||||
reviewer_rankings = pl.DataFrame({"": ["a", "b", "c", "d"], "A": [3, 4, 2, 1], "B": [3, 1, 4, 2], "C": [2, 3, 4, 1], "D": [3, 2, 1, 4] })
|
||||
match = pl.DataFrame({"A" : ["c"], "B": ["d"], "C": ["a"], "D": ["b"]})
|
||||
|
||||
assert crsl.check_stable(match, applicant_rankings, reviewer_rankings)
|
||||
Loading…
Add table
Add a link
Reference in a new issue