Skip to content

Add ranked ballot marker filter - #382

Open
0xTaoZ wants to merge 1 commit into
mggg:mainfrom
0xTaoZ:feat/remove-rank-ballots-with-cands
Open

Add ranked ballot marker filter#382
0xTaoZ wants to merge 1 commit into
mggg:mainfrom
0xTaoZ:feat/remove-rank-ballots-with-cands

Conversation

@0xTaoZ

@0xTaoZ 0xTaoZ commented Aug 6, 2026

Copy link
Copy Markdown

Summary

  • add remove_rank_ballots_with_cands for dropping ranked ballots containing specified candidates or CVR markers
  • export the helper from votekit.cleaning
  • add regression coverage for single markers, multiple markers with ties, zero-weight handling, and non-rank profiles

Fixes #381.

Testing

  • uv run pytest tests/cleaning/rank_profiles/test_remove_rank_ballots_with_cands.py tests/cleaning/rank_profiles/test_remove_cand_ranked_profile.py tests/cleaning/rank_profiles/test_remove_and_condense_ranked_profile.py -q
  • uv run ruff format --check src/votekit/cleaning tests/cleaning/rank_profiles/test_remove_rank_ballots_with_cands.py
  • uv run ruff check src/votekit/cleaning tests/cleaning/rank_profiles/test_remove_rank_ballots_with_cands.py
  • uv run ty check src/votekit/cleaning tests/cleaning/rank_profiles/test_remove_rank_ballots_with_cands.py
  • uv run pytest tests/cleaning -q
  • git diff --check

I also tried broader repository checks. uv run pytest tests -q stops before this change on optional/environment-dependent tests: tests/test_animations.py needs manim, and URL-loading tests fail local TLS verification against GitHub. uv run ruff format --check src tests && uv run ruff check src tests passes. Repo-wide uv run ty check src tests stops on the same missing optional animation modules (manim, manimpango).

@fetachino fetachino left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I traced the filtering path through the Ranking_* frozensets, including markers inside tied ranks and multiple removal markers. Using isdisjoint here correctly drops the whole ballot as soon as any specified marker appears, while preserving the original candidate list and parent/index metadata for retained rows. The public export and the remove_zero_weight_ballots=False case are also covered.

I ran the new test together with the neighboring ranked-profile cleaning tests: 11 passed. Ruff and ty check also pass for the touched cleaning code and test. I did not find a blocking correctness or maintainability issue.

@peterrrock2

peterrrock2 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Hey @0xTaoZ!

Thank you so much for contributing to VoteKit! It's super exciting to see our work being used by people outside of our community. If you happen to have a moment, I would love to hear more about how you found the package and what you are using it for so that we can better fit the needs of our users.

You may have noticed that we made our latest release for VoteKit around two weeks ago. Since that time, I have been preoccupied with some other projects and did not notice the latest set of PRs that came in. Unfortunately, this led to me asking another member of the lab to work on this exact issue. They implemented a slightly faster version than the one that you have presented here that leverages the _df attribute of PreferenceProfile. This both improves performance and better aligns the internals of the function with our planned migration of the PrefereceProflie objects and election engines over to Rust.

That being said, I would still be thrilled to have your contributions on this project. If you would like, issue #322 is similar to this one and, if you comment on the thread in that issue, I or one of the other maintainers of the project would be happy to assign you that issue so no one else takes it. I'll leave this PR open until Wednesday, August 26th so that you have an opportunity to respond.


Additional notes (this section is a form that I am including on several recent PRs)

Since there have been so many new contributors in the last couple of weeks (a wonderful problem to have), I thought it important to update the "Use of AI Tools" section of the Contributing.md on our main branch to clarify what we currently consider to be best-practices for our lab.

To be clear, this this is not an indictment of the use of any AI tools or a statement about the work presented here (indeed, it would be a bit illogical to find anyone at issue with this policy before it was explicitly stated!). I include it here only because this is 1. a recent update in a document people infrequently visit and 2. an effort to clearly communicate our expectations around contributing to this project.

I'll include the exact snippet here so you don't have to go through the trouble of finding it yourself:

Use of AI tools

Researchers rely on VoteKit and its results, so contributors have a heightened responsibility for
the correctness and clarity of every change.

  • Core implementation and business logic in src/votekit/ must be written by humans. AI tools may
    provide inline assistance (e.g., an editor copilot) and may be used to navigate and deepen
    understanding of the codebase and domain material (e.g., with chat agents). Contributors should
    not delegate the generation or rewriting of core implementation code to agentic coding tools.
    For example, Codex GUI/CLI, Claude GUI/CLI, Cursor v3+, and similar tools should not be asked to
    generate or substantially rewrite that code.
  • Tests may be developed jointly by humans and AI. AI is particularly useful for adversarial
    testing, such as searching for user inputs that break an implementation, but the person
    responsible for the pull request must review every AI-generated or AI-assisted test and confirm
    that it meaningfully tests the intended behavior.
  • Docstrings may be developed jointly by humans and AI. The person responsible for the pull
    request must read, edit, and review every AI-assisted docstring for accuracy, thoroughness, and
    compliance with the documentation and formatting guidelines below.

The person responsible for a pull request remains accountable for all of its contents, regardless
of which tools assisted in preparing it.


Thank you again for your contribution, and I hope that we'll see more from you!

-Peter
(Lead Maintainer of VoteKit)

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.

Remove ranked ballots containing specified candidates

3 participants