Skip to content

Add a test case where the No Award runoff changes the result - #485

Open
JonathanLennox wants to merge 2 commits into
WorldconVotingSystems:mainfrom
JonathanLennox:test-no-award-runoff
Open

Add a test case where the No Award runoff changes the result#485
JonathanLennox wants to merge 2 commits into
WorldconVotingSystems:mainfrom
JonathanLennox:test-no-award-runoff

Conversation

@JonathanLennox

Copy link
Copy Markdown

Adds TestEdgeCases.test_no_award_wins_the_runoff, covering the minimal ballot set in which the final runoff against No Award overturns the instant-runoff count:

Voter 1: Candidate A, No Award
Voter 2: Candidate A, No Award
Voter 3: Candidate B, No Award
Voter 4: Candidate C, No Award
Voter 5: No Award

B, C and No Award tie for last with one first preference each and are eliminated together; no ballot has a surviving preference to transfer, so A fills the only seat with 2 votes. No Award then beats A 3–2 in the runoff.

Count round Runoff round
Candidate A 2 — Elected 2 — Rejected
Candidate B 1 — Rejected
Candidate C 1 — Rejected
No Award 1 — Rejected 3 — Elected

None of the existing cases fail if the runoff is dropped or miscounted; this one does.

Verified: 7 passed in test_constitution_2023.py, ruff check and ruff format --check clean. The test needs no database — it calls hugo_voting directly with pyrankvote objects.

🤖 Generated with Claude Code

Five ballots in which Candidate A survives the instant-runoff count, but
No Award is ranked above A on three of them, so the final runoff against
No Award overturns the count. None of the existing cases fail if the
runoff is dropped or miscounted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
if cr.status == CandidateStatus.Elected
)

def votes(round, candidate) -> float:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This type doesn't sit right with me; I know the underlying library works in floating point, but in practice these are integers. Seeing an int compared with equality to a float down on lines 250-251 is twitch-inducing.

I realize that's more an aesthetic judgement than a technical one, because a similar comparison happens up-file, but nevertheless, I'd prefer that the clamping to integer happen in this method instead of implicitly in the checks down below.

The tally is floating point in pyrankvote, but these are whole votes;
convert in the helper rather than leaving the assertions to compare an
int against a float. The helpers' `round` parameter is renamed so it
doesn't shadow the builtin.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@offbyone offbyone added development Work to improve the developer experience patch PR that should result in a patch version update (nitpicks, bugfixes) labels Jul 30, 2026
@JonathanLennox

Copy link
Copy Markdown
Author

I pushed a change to return int from votes.

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

Labels

development Work to improve the developer experience patch PR that should result in a patch version update (nitpicks, bugfixes)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants