-
Notifications
You must be signed in to change notification settings - Fork 26
Fix bug in discrepancy calculation for ES&S overvotes #2162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Treat overvotes as 1s rather than 0s when calculating the numerical discrepancy
| deltas = { | ||
| choice.id: int(reported[choice.id]) - int(audited[choice.id]) | ||
| for choice in contest.choices | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
6ddd24c to
bef3648
Compare
| return None | ||
| else: | ||
| deltas = { | ||
| choice.id: 1 - int(audited[choice.id]) for choice in contest.choices |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a little weird, though it's closer to what the math does. The math treats an overvote as a vote for the winner and a vote for the loser, whereas this logic treats an overvote as a vote for every candidate.
arsalansufi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we're opening up a broader discussion about overvote handling, but what you've presented in this PR does seem sound and at least consistent with the current math
| # delta. Otherwise, return discrepancies as usual, but substituting in | ||
| # overvotes/undervotes. | ||
| if has_overvote: | ||
| if audited_votes > 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm I know this is just pulled from the audit math but do we need to account for the case that a contest allows for more than 1 vote?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ES&S CVRs only suport vote-for-1 so far: https://github.com/votingworks/arlo/blob/jonah/fix-ess-cvr-error/server/api/cvrs.py#L851-L853
We might want to add an assertion here and in the audit math about that assumption in case it changes
| choice.id: 1 - int(audited[choice.id]) for choice in contest.choices | ||
| } | ||
| elif has_undervote: | ||
| if audited_votes < 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming undervote here refers to a completely undervoted, i.e., blank contest. And not a vote for N where someone didn't vote for 0 but just some number less than N
|
Pausing for now per #2100 (comment) |
Alternate idea to fix #2100 that mimics the logic from
supersimple.discrepancy