I recently ran the vote for the Pearple's Choice Awards, which used to
happen on the old Shut Up & Sit Down forum and now happen on
discussion.tekeli.li.
I like the Hugo nomination and voting system, so I decided to
implement that. Except that apparently they don't make their software
public, so I had to write my own. (Well, there's openstv
, but it
doesn't do the nomination handling, it's an ugly GUI thing rather than
command-line, and when I looked for the software's web site I found
some completely different vote-counting service which the project has
apparently morphed into.)
My model is very simple: rather than have a GUI, each separate program
takes a file, processes it, and outputs another file (plus a log of
what was done). For example the vote counter checks that all ballots
are valid then does the full counting procedure and produces a file of
the results.
Counting ballots is easy. Confirming you're working by the rules is
harder. I used two sources: the WSFS
Constitution,
which seems to have a bug at one point (§6.5 nowhere defines what a
"run-off candidate" is meant to be), and the Hugo Award
notes.
So first you have a bunch of nominations, which have to be reduced to
about six. First of all nominations for the same game have to be
character-identical; I suppose I could have used BGG IDs, but at least
one game wasn't yet listed on BGG, so that's less than ideal. Is a
nomination valid in a single category? What about something like
Unmatched: do people vote and nominate for the whole system, or for
just one game within that system?
Then it comes down to the software. §3.9.1 says that each nomination
for a single category is worth one "point", which is divided between
all the nominees you list; so obviously rather than commit the sin of
using floating point I scaled this up to enough points to be evenly
divided between any valid number of nominees (since people were
allowed five, that was 60 points). Anyway, each potential nominee gets
both a number of points and a number of votes from which it got those
points, and the lowest-point options are eliminated – and their points
distributed among other nominees. (There's a lot of that in this
system, redoing a thing from scratch after some options are
eliminated rather than looking at what's left.)
Nominations done! Time to count the votes. These are a bit simpler:
take every vote's first choice. If there's an absolute majority,
that's the winner. Otherwise eliminate the nominee that got least
votes, strike out the votes at the top of the ballots voting for it,
and go back to taking every vote's first choice, until there's a
majority. But you don't list runners-up in order of elimination, oh
no: instead you strike out all votes for the winner, then run the
whole multi-round process again. I'm sure someone had a reason for
this.
And explain to people the difference between listing everything
including No Award and simply listing the things you care about.
This is the first time I've written software with explicit comments
linking to the points of the voting system which a chunk of code
implements.
If anyone else wants to run a vote like this, give me a shout. I'll
probably put the code and documentation on GitHub eventually, but I
say that a lot and don't seem actually do to it very much. Maybe I'll
rewrite it in Rust first.
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.