Why Voting Is Hard

How Voting Systems Work ๐Ÿ†

Chapter 1 ยท Why Voting Is Hard

Counting votes sounds like the easiest job in the world: add them up and the biggest number wins. Yet the same pile of ballots can name different winners depending on the rule you use to read it, and which rule is “right” is a question people have argued about for more than two centuries. This course takes the rules apart one at a time, from the simplest to the strangest, and tests each with small Python programs. This first chapter sets up the vocabulary, shows the problem with a nine-voter election you can check by hand, and builds the tally code that later chapters reuse. You need arithmetic and a little algebra; the maths stays light, and every idea is something you can run.

What was run, and what to trust
Every Python snippet in this chapter and in the three exercise solutions was executed, and the output in the comments is what Python printed. Definitions and history come from the Wikipedia articles on plurality voting and the Condorcet paradox, fetched with a tool that often returns truncated pages or model-written summaries, so treat the wording as a paraphrase, not a quotation. The elections in the code are assumed or illustrative: invented to show a method, not results from any real vote. Statements marked (check) were not confirmed against a source.

What Is a Vote For?

A vote is a small piece of information from one person, and an election is a rule for turning many such pieces into one decision. The decision might be a single winner (a mayor), several winners (a council), or a yes or no (a referendum). Notice that the word “winner” hides a choice about what the group is trying to find: the option the most people put first, the option most people can live with, or the option that beats every rival one on one. Those are different targets, and a voting system is a bet on which one matters.

Voting systems also differ in what each voter is allowed to say. That is the first thing to look at, because it limits everything that can be done afterwards.

Ballot typeWhat the voter writesWhat the counter learns
Choose onea single candidateonly each voter’s first choice
Rankedcandidates in order of preferencethe whole order, so pairwise comparisons are possible
Approvala tick for every acceptable candidatewho is acceptable, but not the order
Scorea number (say 0 to 5) for each candidatestrength of feeling, as the voter chooses to scale it

The next chapters cover these ballot types and the rules that go with them: How Voting Systems Work 2 for choose-one ballots, How Voting Systems Work 3 and 4 for ranked ballots, and How Voting Systems Work 5 for approval and score ballots. In this chapter we use ranked ballots, because a ranked ballot contains enough information to simulate nearly every other kind.

Preferences and Ballots

A preference is what a voter privately thinks; a ballot is what the voter is allowed to write down. For a ranked ballot with three candidates there are 3 × 2 × 1 = 6 possible strict orders, and in Python a ballot is simply a tuple with the favourite first. An electorate is then a list of ballots, and a list can hold repeats, so “four voters share this order” is just four copies.

Our running example has nine voters and three candidates, A, B and C. Four voters rank A, B, C; three rank B, C, A; two rank C, B, A. The first tally is the one most people think of as “the election”: count first choices.

from collections import Counter # Nine voters, each with a full ranking of three candidates, best first. # Illustrative numbers: invented to show a method, not a real election. ballots = ( [("A", "B", "C")] * 4 + [("B", "C", "A")] * 3 + [("C", "B", "A")] * 2 ) firsts = Counter(ballot[0] for ballot in ballots) total = len(ballots) for name, votes in firsts.most_common(): print(f"{name}: {votes} first-choice votes ({votes / total:.1%})") winner, top = firsts.most_common(1)[0] print("plurality winner:", winner, "| has a majority:", top > total / 2) # A: 4 first-choice votes (44.4%) # B: 3 first-choice votes (33.3%) # C: 2 first-choice votes (22.2%) # plurality winner: A | has a majority: False

Candidate A wins a plurality with 4 of 9 first-choice votes (44.4%), but does not reach a majority, which means more than half. The Wikipedia article on plurality voting defines plurality voting as a system in which the candidate who polls more than any other (a plurality, or relative majority) is elected, and says that it does not require a majority. In the UK the system is called first past the post for general elections (the article does not give a separate US term, but says it is widely used in most of the United States). Critics, the article says, point to wasted votes, pressure toward tactical voting, and the spoiler effect, where similar candidates split the vote. How Voting Systems Work 2 looks at all three.

TermMeaningIn our nine-voter example
Pluralitymore votes than any rivalA has 4, ahead of B with 3 and C with 2
Majoritymore than half of the votesneeds 5 of 9; nobody has it
Preferencewhat a voter thinksnever seen directly by the counter
Ballotwhat a voter writesa full ranking of A, B and C

The Same Votes, a Different Winner

Winning with 44% looks fine until you ask who the other 56% would have picked. Look at the ballots from the bottom instead of the top:

from collections import Counter ballots = ( [("A", "B", "C")] * 4 + [("B", "C", "A")] * 3 + [("C", "B", "A")] * 2 ) # The same ballots, looked at from the bottom instead of the top. lasts = Counter(ballot[-1] for ballot in ballots) total = len(ballots) for name in "ABC": print(f"{name}: last choice of {lasts[name]} of {total} voters") # A: last choice of 5 of 9 voters # B: last choice of 0 of 9 voters # C: last choice of 4 of 9 voters

The plurality winner is the last choice of five of the nine voters, a majority, while B is last for nobody. That is uncomfortable. Now compare the candidates head to head: for every pair, give each voter's vote to whichever of the two they rank higher.

from itertools import combinations ballots = ( [("A", "B", "C")] * 4 + [("B", "C", "A")] * 3 + [("C", "B", "A")] * 2 ) def head_to_head(ballots, x, y): """Votes for x and for y when each voter picks whichever they rank higher.""" x_votes = sum(1 for b in ballots if b.index(x) < b.index(y)) return x_votes, len(ballots) - x_votes beats = {} for x, y in combinations("ABC", 2): vx, vy = head_to_head(ballots, x, y) print(f"{x} vs {y}: {vx} to {vy}") beats[(x, y)] = vx > vy beats[(y, x)] = vy > vx for c in "ABC": if all(beats[(c, other)] for other in "ABC" if other != c): print("beats every rival head to head:", c) # A vs B: 4 to 5 # A vs C: 4 to 5 # B vs C: 7 to 2 # beats every rival head to head: B

B beats A by 5 to 4 and beats C by 7 to 2, so B would win a straight contest against either rival. A candidate who beats every other candidate head to head is called a Condorcet winner, after the Marquis de Condorcet, whose 1785 Essai sur l’application de l’analyse à la probabilité des décisions rendues à la pluralité des voix is the source the Wikipedia article on the Condorcet paradox cites. Here the plurality rule picks A, while the head-to-head rule picks B. Neither answer is a mistake in counting; they are two definitions of “best”. How Voting Systems Work 4 builds the full pairwise matrix.

RuleQuestion it asksWinner here
Pluralitywho has the most first places?A (4 first places)
Condorcetwho beats every rival one on one?B (5 to 4 and 7 to 2)
Fewest last placeswho is disliked by the fewest voters?B (0 of 9), a rough guide only

When No One Wins: The Cycle

The Condorcet winner in the example was lucky to exist. The Wikipedia article on the Condorcet paradox gives a three-voter example: one voter ranks A, B, C; one ranks B, C, A; one ranks C, A, B. Every pairwise contest ends 2 to 1, and the majority preferences form a loop, so no candidate beats all the others. The article says the paradox shows that majority rule can be self-contradictory even when every individual's preferences are rational (each voter's own ranking is perfectly consistent).

ballots = [("A", "B", "C"), ("B", "C", "A"), ("C", "A", "B")] # three voters def head_to_head(ballots, x, y): x_votes = sum(1 for b in ballots if b.index(x) < b.index(y)) return x_votes, len(ballots) - x_votes for x, y in [("A", "B"), ("B", "C"), ("C", "A")]: vx, vy = head_to_head(ballots, x, y) print(f"{x} vs {y}: {vx} to {vy} -> {x if vx > vy else y} wins") # A vs B: 2 to 1 -> A wins # B vs C: 2 to 1 -> B wins # C vs A: 2 to 1 -> C wins

A beats B, B beats C and C beats A. No candidate is the winner by this definition, and a rule that insists on a Condorcet winner has nothing to say. The same article credits the 13th-century Catalan writer Ramon Llull with describing the paradox first, in a work lost until the 21st century, but the page as fetched gave no title or year for it, and older accounts credit only Condorcet (check). Cycles are the root of the impossibility result in How Voting Systems Work 6.

Why This Is Hard

Put the pieces together and you can see the problem the rest of the course explores. The counter sees only ballots, not preferences. Different rules read the same ballots as asking different questions. Some rules sometimes have no answer, or give answers that depend on details such as who else is standing. Every system you meet later can be judged on what it asks, how easy it is to explain, and how it can go wrong.

Common mistakes
Treating “most votes” as if it meant “a majority” (a plurality is often well under half); assuming that the winner of one rule is the winner of all; assuming a Condorcet winner always exists (cycles can happen); forgetting that the counter sees ballots, not preferences, so a ballot may not match what the voter thinks; and reading invented example numbers, such as the ones in this chapter, as if they were measurements of real elections.
Exercise 1

A club of 15 members (assumed numbers) ranks four candidates. Write a program that finds the plurality winner and its share of the vote, says whether it is a majority, plays every head-to-head contest, and reports the Condorcet winner if there is one. Do the two methods agree?

๐Ÿ“„ View solution
Exercise 2

How common are cycles? List all 216 ways three voters can each pick one of the six rankings of three candidates and count the electorates with a cycle. Then simulate random electorates of 3, 11 and 101 voters (seeded) and compare the rates. Does a bigger electorate remove the problem?

๐Ÿ“„ View solution
Exercise 3

Start from the nine-voter electorate. Move k of the four A-first voters so that they rank B first instead, for k from 0 to 4, and report the plurality winner and the Condorcet winner each time. How many voters have to change before the plurality winner changes, and why does the Condorcet winner not move?

๐Ÿ“„ View solution

Quick Reference

  • Ballot: what the voter writes (one choice, a ranking, approvals or scores); the counter never sees the underlying preference
  • Plurality: the most votes; majority: more than half; a plurality winner need not have a majority
  • Condorcet winner: beats every rival head to head; it may not exist
  • Condorcet cycle: A beats B, B beats C, C beats A, each by majority
  • Python habit: a ranked ballot is a tuple, an electorate is a list, and Counter tallies first choices
  • Check before trusting a winner: which rule, what the ballot allowed, and whether the numbers are real or illustrative
Coming next
How Voting Systems Work 2 is about plurality and its quirks: first-past-the-post, spoiler candidates, vote splitting, and simulating three-way races.