Skip to main content

A simple STAR vote tabulator

Project description

starvote

A simple STAR vote tabulator

Copyright 2023 by Larry Hastings

STAR voting is a relatively-new electoral system. It's simple to vote and simple to tabulate. While a completely fair and perfect electoral system is impossible, STAR voting's approach makes reasonable tradeoffs and avoids the worst electoral system pitfalls. It's really great!

This module, starvote, implements a simple STAR vote tabulator. To use, import starvote, then instantiate a starvote.Poll object. Feed in the ballots using poll.add_ballot(ballot); ballots are dict objects, mapping the candidate to the ballot's vote for the candidate (an int in the range 0 to 5 inclusive).

Once you've added all the ballots, call poll.result to compute the winner. If there's an unbreakable tie, poll.result will raise an UnbreakableTieError. You can get a text description of the tie by calling str on the exception; also, you can get a list of the tied candidates in its candidates attribute.

The following scenarios produce an unbreakable tie:

  • If the top two candidates tie during the automated runoff round and their scores are also a tie.
  • If the second and third candidates during the score round tie, and their preference scores are also a tie.
  • If three or more candiates are tied for first or second place during the score round.

(These scenarios are highly unlikely with real-world data.)

If you want to see how the vote was tabulated, pass in an argument to the print keyword-only argument to poll.result. This should be a function that behaves like the builtin print function; it will only ever be called with positional parameters.

Here's an example of computing a poll between Amy, Brian, and Chuck:

import starvote

poll = starvote.Poll()
poll.add_ballot({'Amy': 1, 'Brian': 3, 'Chuck': 5})
poll.add_ballot({'Amy': 5, 'Brian': 2, 'Chuck': 3})
poll.add_ballot({'Amy': 4, 'Brian': 4, 'Chuck': 5})
winner = poll.result(print=print)
print()
print(f"[Winner]\n{winner}")

Here's what the output of this program looks like:

[Score round]
  Chuck -- 13 (average 4.33)
  Amy   -- 10 (average 3.33)
  Brian --  9 (average 3.00)
[Automatic runoff round]
  Chuck         -- 2
  Amy           -- 1
  No preference -- 0

[Winner]
Chuck

If the module is executed as a script, it will read a single CSV file in star.vote format, tabulate, and print the result. For example, you can run this from the root of the source-code repository:

% python3 -m starvote sample_polls/sample_poll_automatic_runoff_breakable_tie.csv

to see how starvote handles a tie during the automatic runoff round.

Multiple-winner elections

starvote also implements the Bloc STAR variant of STAR for multi-winner elections. Simply instantiate your Poll object passing in starvote.BLOC_STAR for the variant parameter, and the number of winners in the winners keyword-only parameter:

poll = starvote.Poll(variant=starvote.BLOC_STAR, winners=2)

This changes poll.result to return a list of winners instead of a single winner.

You can experiment with these with the command-line version of the module, too:

% python3 -m starvote -v BLOC_STAR -w 2 sample_polls/starvote_ballots_dd1wc4yx_20230520050413.csv

Limitations

Currently this module only supports single-winner STAR voting and the Bloc STAR variant. Proportional STAR (aka Allocated Score) is not yet supported.

License

starvote is licensed using the MIT license. See the LICENSE file.

The source code repository includes sample ballots downloaded from https://star.vote/. The licensing of these sample ballots is unclear, but they're assumed to be public-domain or otherwise freely redistributable.

Changelog

1.2 under development

  • Add support for Bloc STAR polls.

    • Added PollVariant enum.
    • Added variant and winners parameters to Poll.
  • Add the list of tied candidates to the UnbreakableTieError exception as the new candidates attribute.

1.1 2023/05/20

  • Bugfix: raise UnbreakableTieError if there's a three-way tie for second place. Previously starvote only noticed if there was a three-way tie for first place.
  • Added sample output for every sample poll in sample_polls/. These outputs have been confirmed correct by inspection, and could in the future be used as part of an automated test suite.

1.0 2023/05/20

  • Initial release.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

starvote-1.2.tar.gz (2.0 MB view details)

Uploaded Source

Built Distribution

starvote-1.2-py3-none-any.whl (7.4 kB view details)

Uploaded Python 3

File details

Details for the file starvote-1.2.tar.gz.

File metadata

  • Download URL: starvote-1.2.tar.gz
  • Upload date:
  • Size: 2.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.30.0

File hashes

Hashes for starvote-1.2.tar.gz
Algorithm Hash digest
SHA256 3485a49277f724d4decb6660f342dfe9cf4fbf6792df0c621dd4fd21b17121df
MD5 2f5088e50432089c085fe7e5033767e2
BLAKE2b-256 a5ff7d6fb1acc1111270d9f022b30f5db21faf302dfe3a66948e64f17ab6d3a9

See more details on using hashes here.

File details

Details for the file starvote-1.2-py3-none-any.whl.

File metadata

  • Download URL: starvote-1.2-py3-none-any.whl
  • Upload date:
  • Size: 7.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.30.0

File hashes

Hashes for starvote-1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6470bc7f5395bf2486aba7dd4e43f85bb69c3e230f7cc3f03f94bbd09a62bc8d
MD5 d3542c7aaa7882988008def1cf917628
BLAKE2b-256 c8016ed80baf7d83c7cbde48e4ad1e28c7dd36558b1506efe99cc2fe6e835377

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page