Skip to content

Instantly share code, notes, and snippets.

@benprew
Last active January 11, 2026 02:07
Show Gist options
  • Select an option

  • Save benprew/4328b6d38c01d7e35bfc77671bda430a to your computer and use it in GitHub Desktop.

Select an option

Save benprew/4328b6d38c01d7e35bfc77671bda430a to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import csv
import sys
from typing import List, Dict
def main():
file_path = sys.argv[1]
candidates, votes = votes_from_csv(file_path)
bcounts = borda_counts(candidates, votes)
# Calculate the winner
winner = condorcet_winner(candidates, votes)
if winner is None:
print("No Condorcet winner found.")
winner = max(bcounts, key=bcounts.get)
print("The winner is:", winner)
print("For removing topics")
print("Ranked results:")
print(sorted(bcounts.items(), key=lambda x: x[1]))
def votes_from_csv(file_path):
# Read the CSV file
with open(file_path, "r") as csvfile:
reader = csv.DictReader(csvfile)
candidates = [field for field in reader.fieldnames if field != "VOTER"]
votes = {}
for row in reader:
voter = row["VOTER"]
rankings = []
for candidate, ranking in row.items():
if candidate != "VOTER" and ranking:
rankings.append((candidate, int(ranking)))
rankings.sort(key=lambda x: x[1])
votes[voter] = [candidate for candidate, _ in rankings]
return candidates, votes
def condorcet_winner(candidates: List[str], votes: Dict[str, List[str]]) -> str:
"""
Calculate the winner of the election using the Condorcet method.
Args:
candidates (list): List of candidates.
votes (dict):
- Keys are voter names, values are lists of ranked candidates.
Returns:
str: Name of the Condorcet winner, or None if there is no winner.
"""
# Initialize pairwise comparison dictionary
pairwise_comparisons = {
candidate: {other: 0 for other in candidates if other != candidate}
for candidate in candidates
}
# Compare each candidate against every other candidate
for rankings in votes.values():
ranked_candidates = set(rankings)
for i, candidate in enumerate(rankings):
for j in range(i + 1, len(rankings)):
other_candidate = rankings[j]
pairwise_comparisons[candidate][other_candidate] += 1
# Treat unranked candidates as ranked lower than any ranked candidates
for candidate in candidates:
if candidate not in ranked_candidates:
for ranked_candidate in ranked_candidates:
pairwise_comparisons[ranked_candidate][candidate] += 1
# Determine if there is a Condorcet winner
for candidate in candidates:
is_winner = True
for other_candidate in candidates:
if candidate != other_candidate:
if (
pairwise_comparisons[candidate][other_candidate]
<= pairwise_comparisons[other_candidate][candidate]
):
is_winner = False
break
if is_winner:
return candidate
return None
def borda_counts(candidates: List[str], votes: Dict[str, List[str]]) -> Dict[str, int]:
"""
Calculate the winner of the election using the Borda count method.
Args:
candidates (list): List of candidates.
votes (dict):
- Keys are voter names and values are lists of ranked candidates.
Returns:
Dict[str, int]: Dictionary of each candidate to their Borda score
"""
# Initialize a dictionary to store the Borda count for each candidate
borda_counts = {candidate: 0 for candidate in candidates}
num_candidates = len(candidates)
# Assign points based on rankings
for voter, rankings in votes.items():
for i, candidate in enumerate(rankings):
borda_counts[candidate] += num_candidates - i - 1
# Determine the candidate with the highest Borda count
return borda_counts
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment