A transparent, single-file Python application designed to run robust, secure, and mathematically precise Single Transferable Vote (STV) elections via a simple command-line interface (CLI).
This project was initially developed for and used by the Informatix Club at Turkish-German University (TGU Informatix) for its General Assembly election. It was built with the goal of providing a fully open-source and auditable election system for any university club, association, or organization seeking a fair and proportional representation model.
This tool is built on two core principles: mathematical perfection and adherence to established standards.
To be "flawless", an election system cannot suffer from floating-point arithmetic errors. Instead of using float or fixed-point integers (which involve rounding), this tool uses Python's built-in fractions.Fraction module for all vote counting and transfers.
This guarantees that no rounding errors occur and every fraction of a vote is perfectly preserved throughout the entire counting process, from surplus transfers to eliminations.
The counting logic is not arbitrary. It is a strict implementation of the Weighted Inclusive Gregory Method, as specified in the official guidelines from the Electoral Reform Society (ERS).
This includes:
- Correct Droop Quota: The quota is correctly calculated using the standard formula:
(Total Ballots // (Seats + 1)) + 1. - Gregory Surplus Transfer: Surpluses are transferred proportionally using a transfer factor, with new ballots created for the fractional value.
- Elimination Transfer: Votes from eliminated candidates are transferred in their entirety (at their current value) to the next available preference.
- Robust Tie-Breaking: Ties during elimination are resolved by looking back at the vote counts from the previous rounds, as specified in the ERS guide.
- Single-File Script: The entire application is contained in one Python file, making it extremely easy to read, audit, and verify.
- Persistent SQLite Database: All candidates and cast ballots are stored in a local
election.dbfile. - Interactive CLI Menu: A simple menu guides the election administrator through adding candidates, casting votes, and calculating results.
- Separate Election Types: Supports running simultaneous but separate elections (e.g., "Executive Board" and "Audit Board") from the same database.
- Configurable Seats: Easily calculates winners and runners-up for different board sizes (e.g., 5 winners + 2 runners-up, 3 winners + 2 runners-up).
- Zero Dependencies: Runs on a standard Python 3 installation with no external libraries needed.
- Python 3.7+ (which includes the
sqlite3andfractionsmodules). - No external libraries are required.
Simply download the stv-election-cli.py file or clone the repository:
git clone https://github.com/egoistpizza/stv-election-cli.git
cd stv-election-cliRun the script from your terminal:
python3 stv-election-cli.pyThis will display the main menu:
--- STV Election CLI (Python Edition) ---
1. Add Candidate
2. List Candidates
3. Cast Vote
4. Calculate Executive Board Election (5+2)
5. Calculate Audit Board Election (3+2)
6. Exit
Your choice:
First, add all your candidates. You will be prompted to choose a board (E for Executive or A for Audit) and then enter names in a loop until you quit with 'q'.
Before casting votes, list the candidates for a specific board. This will show you the Candidate ID for each person, which is required for voting.
--- Executive Board Candidate List ---
1. Candidate Name A
2. Candidate Name B
3. Candidate Name C
...
This allows you to enter ballots one by one.
-
Voter 4-digit Hash: A unique, anonymized ID for the voter (e.g.,
a001,x42b). The program only checks that it is 4 characters long and unique. -
Vote Preference Order: The voter's preferences, entered as a dash-separated list of Candidate IDs.
- Example:
2-1-3means the voter's 1st choice is ID 2, 2nd choice is ID 1, and 3rd choice is ID 3. - Voters do not need to rank all candidates.
Select the board you want to calculate. The script will run the full STV algorithm and generate two outputs:
-
The final result (winners and runners-up) printed to the console.
-
A detailed, timestamped log file (e.g.,
election_log_executive_20251022_140000.txt).
Quits the application.
This tool is designed to be fully auditable by anyone, with no black boxes.
The script will automatically create a file named election.db in the same directory. This file is a standard SQLite database.
For 100% transparency, you can use any SQLite browser (like DB Browser for SQLite) to independently inspect, verify, or backup the raw candidate and ballot data before the count is run.
When you run an election calculation (options 4 or 5), the tool automatically generates a detailed, timestamped log file (e.g., election_log_executive_20251022_140000.txt).
This log file provides a complete, human-readable, round-by-round trace of the entire counting procedure, allowing for full post-election auditing. The log includes:
-
Initial quota calculation.
-
Vote counts for every active candidate in every round.
-
Clear notifications for candidates who are elected.
-
Detailed surplus transfer calculations, including the transfer factor and the fractional value being moved.
-
Clear notifications for eliminated candidates.
-
Explicit reasoning for all tie-breaks (showing the ERS look-back logic).
-
Tracking of newly exhausted ballots in each round.
This project is open-source and licensed under the GNU General Public License v3.0. See the LICENSE file for details.