mirror of
https://github.com/tgorordo/carousel.git
synced 2026-06-12 20:42:13 -07:00
tweak cgi html form with TODOs
This commit is contained in:
parent
5da4a21a3f
commit
6d9d8978cf
4 changed files with 65 additions and 50 deletions
|
|
@ -144,56 +144,8 @@ def check_stable(*args, **kwargs):
|
|||
return not check_unstable(*args, **kwargs)
|
||||
|
||||
|
||||
def deferred_acceptance(applicant_rankings, reviewer_rankings):
|
||||
"""Find the Gale-Shapley deferred-acceptance stable matching for preferences A, R."""
|
||||
reviewer_rankings = reviewer_rankings.rename(
|
||||
{reviewer_rankings.columns[0]: "applicant"}
|
||||
)
|
||||
|
||||
app_prefs = rank_to_pref(applicant_rankings)
|
||||
offers = app_prefs.transpose(
|
||||
include_header=True,
|
||||
header_name="applicant",
|
||||
column_names=["pref" + str(i + 1) for i in range(app_prefs.width)],
|
||||
).with_columns(pl.coalesce(pl.all().exclude("applicant")).alias("offer"))
|
||||
|
||||
# offers = pl.concat(pl.align_frames(offers, reviewer_rankings, on="applicant"), how="horizontal")
|
||||
offers = pl.concat([offers, reviewer_rankings], how="align_left")
|
||||
|
||||
match = pl.DataFrame(
|
||||
{
|
||||
r: offers.select(pl.col("applicant", "offer").sort_by(r))
|
||||
.select(
|
||||
pl.when(pl.col("offer").eq(r)).then(pl.col("applicant")).otherwise(None)
|
||||
)
|
||||
.select(pl.all().fill_null(strategy="backward").first())
|
||||
.to_series()
|
||||
for r in reviewer_rankings.columns[1:]
|
||||
}
|
||||
) # .select(pl.all().fill_null(strategy="backward").first())
|
||||
|
||||
# while check_unstable(match, applicant_rankings, reviewer_rankings):
|
||||
while match.select(pl.any_horizontal(pl.all().has_nulls())).item():
|
||||
# TODO null applicant preferences that rejected
|
||||
|
||||
rejected_applicants = offers.select(
|
||||
pl.col("applicant").is_in(match.row(0)).alias("matched")
|
||||
)
|
||||
|
||||
return match
|
||||
|
||||
offers = offers.with_columns(pl.col("pref"))
|
||||
|
||||
offers = offers.with_columns(
|
||||
pl.coalesce(
|
||||
# TODO: select prefn columns using a regex
|
||||
).alias("offer")
|
||||
)
|
||||
|
||||
# TODO update match
|
||||
|
||||
# else if stable
|
||||
return match
|
||||
from .brute import *
|
||||
from .def_acc import *
|
||||
|
||||
|
||||
def main() -> None:
|
||||
|
|
|
|||
3
src/carousel/brute.py
Normal file
3
src/carousel/brute.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
def brute(applicant_rankings, reviewer_rankings):
|
||||
"""Brute force search for stable matches."""
|
||||
pass
|
||||
50
src/carousel/def_acc.py
Normal file
50
src/carousel/def_acc.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
def deferred_acceptance(applicant_rankings, reviewer_rankings):
|
||||
"""Find Gale-Shapley deferred-acceptance stable matchings for preferences A, R."""
|
||||
reviewer_rankings = reviewer_rankings.rename(
|
||||
{reviewer_rankings.columns[0]: "applicant"}
|
||||
)
|
||||
|
||||
app_prefs = rank_to_pref(applicant_rankings)
|
||||
offers = app_prefs.transpose(
|
||||
include_header=True,
|
||||
header_name="applicant",
|
||||
column_names=["pref" + str(i + 1) for i in range(app_prefs.width)],
|
||||
).with_columns(pl.coalesce(pl.all().exclude("applicant")).alias("offer"))
|
||||
|
||||
# offers = pl.concat(pl.align_frames(offers, reviewer_rankings, on="applicant"), how="horizontal")
|
||||
offers = pl.concat([offers, reviewer_rankings], how="align_left")
|
||||
|
||||
match = pl.DataFrame(
|
||||
{
|
||||
r: offers.select(pl.col("applicant", "offer").sort_by(r))
|
||||
.select(
|
||||
pl.when(pl.col("offer").eq(r)).then(pl.col("applicant")).otherwise(None)
|
||||
)
|
||||
.select(pl.all().fill_null(strategy="backward").first())
|
||||
.to_series()
|
||||
for r in reviewer_rankings.columns[1:]
|
||||
}
|
||||
) # .select(pl.all().fill_null(strategy="backward").first())
|
||||
|
||||
# while check_unstable(match, applicant_rankings, reviewer_rankings):
|
||||
while match.select(pl.any_horizontal(pl.all().has_nulls())).item():
|
||||
# TODO null applicant preferences that rejected
|
||||
|
||||
rejected_applicants = offers.select(
|
||||
pl.col("applicant").is_in(match.row(0)).alias("matched")
|
||||
)
|
||||
|
||||
return match
|
||||
|
||||
offers = offers.with_columns(pl.col("pref"))
|
||||
|
||||
offers = offers.with_columns(
|
||||
pl.coalesce(
|
||||
# TODO: select prefn columns using a regex
|
||||
).alias("offer")
|
||||
)
|
||||
|
||||
# TODO update match
|
||||
|
||||
# else if stable
|
||||
return match
|
||||
|
|
@ -399,8 +399,14 @@
|
|||
|
||||
<h3>Tabular Input</h3>
|
||||
You can enter tables of preferences directly in the first tab of the form above.
|
||||
|
||||
TODO
|
||||
|
||||
<h4>Example:</h4>
|
||||
Suppose we want to figure out a Grad TA-to-Class assignment. Graduate students will be our "Applicants"
|
||||
- each one will be assigned a class to TA -, and classes will be our "Reviewers" - taking a quota of needed TAs.
|
||||
|
||||
TODO
|
||||
|
||||
<h3>File Upload</h3>
|
||||
|
||||
|
|
@ -410,8 +416,12 @@
|
|||
Two file formats are supported, Excel and CSV:
|
||||
|
||||
<h4>Excel</h4>
|
||||
|
||||
TODO
|
||||
|
||||
<h4>CSV</h4>
|
||||
|
||||
TODO
|
||||
|
||||
</details>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue