Skip to content

Feat/sort pref interval strengths descending#371

Open
graceg571 wants to merge 3 commits into
mggg:3.4.1from
graceg571:feat/sort-pref-interval-strengths-descending
Open

Feat/sort pref interval strengths descending#371
graceg571 wants to merge 3 commits into
mggg:3.4.1from
graceg571:feat/sort-pref-interval-strengths-descending

Conversation

@graceg571

@graceg571 graceg571 commented Jun 5, 2026

Copy link
Copy Markdown

Closes #357

PreferenceInterval.from_dirichlet() currently assigns preference strengths randomly to candidates. A flag has been added called sort_strengths_descending that will assign preference strengths in descending order to the candidates list if True.

If user specifies candidates = [A,B,C] as input to from_dirichlet, a preference interval of [0.3, 0.6, 0.1] could be randomly sampled. If sort_strengths_descending = True, from_dirichlet will return a PreferenceInterval with interval = {A:0.6, B:0.3, C:0.1}. If sort_strengths_descending = False, the preference interval would be assigned as is with interval = {A:0.3, B:0.6, C:0.1}.

This allows the user to specify an ordering to the preference_interval where they would like their first candidate listed with the highest preference strength, second candidate with the second preference strength, and so on. sort_strengths_descending is False by default.

Tests

Added one test that generates a preference interval 3x with sort_strengths_descending = True to account for the randomness of the preference interval sampling (i.e. could already be in strengths descending order)

@graceg571 graceg571 requested a review from peterrrock2 June 5, 2026 14:39
@graceg571 graceg571 self-assigned this Jun 5, 2026
@graceg571 graceg571 force-pushed the feat/sort-pref-interval-strengths-descending branch from bf8429f to 2227c0f Compare June 10, 2026 20:00
Comment thread src/votekit/pref_interval.py Outdated
allow_zero_support (bool): If True, candidates with zero support are allowed. If False,
all candidates must have strictly positive support.
sort_strengths_descending (bool):
If True, the candidates are assigned their support values in descending order.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If True, the candidates are assigned their support values in descending order.
If True, the candidates are assigned their support values in descending order
according to the list passed to candidates.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to comment

Comment thread src/votekit/pref_interval.py Outdated
probs = [p + 10e-12 if p == 0 else p for p in probs]

pref_interval = (
{c: s for c, s in zip(candidates, sorted(probs, reverse=True))}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{c: s for c, s in zip(candidates, sorted(probs, reverse=True))}
{c: s for c, s in zip(candidates, sorted(probs, reverse=True), strict=True)}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Comment thread src/votekit/pref_interval.py Outdated
pref_interval = (
{c: s for c, s in zip(candidates, sorted(probs, reverse=True))}
if sort_strengths_descending
else {c: s for c, s in zip(candidates, probs)}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
else {c: s for c, s in zip(candidates, probs)}
else {c: s for c, s in zip(candidates, probs, strict=True)}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Comment thread tests/test_pref_interval.py Outdated
Comment on lines +95 to +113
def test_sort_strengths_descending_from_dirchlet():
candidates = ["A", "B", "C"]
pi = PreferenceInterval.from_dirichlet(
candidates=candidates, alpha=1, sort_strengths_descending=True
)
sorted_candidates = sorted(pi.interval, key=lambda c: pi.interval[c], reverse=True)
assert sorted_candidates == candidates

pi = PreferenceInterval.from_dirichlet(
candidates=candidates, alpha=1, sort_strengths_descending=True
)
sorted_candidates = sorted(pi.interval, key=lambda c: pi.interval[c], reverse=True)
assert sorted_candidates == candidates

pi = PreferenceInterval.from_dirichlet(
candidates=candidates, alpha=1, sort_strengths_descending=True
)
sorted_candidates = sorted(pi.interval, key=lambda c: pi.interval[c], reverse=True)
assert sorted_candidates == candidates

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just a loop?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now a loop of 50 iterations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants