gocondorcet

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 12, 2021 License: MIT Imports: 7 Imported by: 0

README

Panorama view of Pnyx, Athens.
Nikthestoned, C 2012, An image of the Pnyx, in central Athens, Pnyx, Athens

go-condorcet

A Go library and CLI tool for conducting Schulze Condorcet elections.

StatusUsageContributingLicense

[GitHub release] [Build Status] GitHub go.mod Go version [Go Report Card] [Code Coverage Report] [License]

Status

go-condorcet is complete, and the API is stable.

Usage

Library

package example

import (
	"strings"

	gocondorcet "github.com/liampulles/go-condorcet"
)

func runElection() gocondorcet.Results {
	// Each vote is a map which indicates preference given to candidates (lower
	// is better). You can give candidates equal preference, use any variation
	// of values (what is important is the relative preference in a vote) and
	// omit candidates (which is effectively giving them equal last place).
	votes := []gocondorcet.Vote{
		{"DAN": 0, "ALICE": 1, "SALLY": 2},
		// -> This is equivalent to {"SALLY": 0, "DAN": 0, "ALICE": 0}
		{"SALLY": 5, "DAN": 5, "ALICE": 5},
		{"BOB": 0},
	}

	// The output is an ordered slice of CandidateIDs, first being the most
	// preferred and last being the least preferred (according to the Schulze
	// method).
	// In this case, it will be ["DAN","ALICE","SALLY","BOB"].
	return gocondorcet.Evaluate(votes)
}

func readVotes() []gocondorcet.Vote {
	// We use a string in this example - but this could be a file, STDIN, etc.
	input := strings.NewReader(`
	Tom,Sally=Dan
	Bob,tom,DAN
	Sally,Tom,Sally
	`)

	// We then define a vote reader, using a pre-defined Candidate ID parse
	// function. You can use your own to match user input (above) to distinct
	// string IDs.
	voteReader := gocondorcet.NewVoteReader(input, gocondorcet.BasicParseFn)

	// ReadAll will evaluate the reader up to EOF, and return valid and invalid
	// parsed votes. In this case, we ignore the invalid votes,
	// but you may wish to log them, etc.
	valid, _ := voteReader.ReadAll()
	return valid
}

CLI

Given a votes.txt file:

C,A,B,E,D
A,C=B,E,D
B,E,D,A,C
C,B,A=D,E
C,A,B
B,E=D,A,C
A,C,B,E

You can then calculate the Schulze condorcet result as follows:

$ cat votes.txt | condorcli
A
C
B
E
D

Contributing

Please submit an issue with your proposal.

License

See LICENSE

Documentation

Overview

Package gocondorcet provides methods for running Condorcet elections.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrCyclicVote = errors.New("cyclic vote detected: cannot reference a candidate twice in a vote")
)

Defined errors.

Functions

This section is empty.

Types

type CandidateID

type CandidateID string

CandidateID is a unique identifier for a candidate.

func BasicParseFn

func BasicParseFn(in string) (CandidateID, error)

BasicParseFn provides a basic implementation of CandidateIDParseFn. The parser will trim whitespace and uppercase input.

type CandidateIDParseFn

type CandidateIDParseFn func(string) (CandidateID, error)

CandidateIDParseFn should convert a user inputted candidate name into a CandidateID. you may wish to trim whitespace, convert to uppercase, etc. If the input corresponds to no valid candidate, you should return an error with the main reason.

type InvalidVote

type InvalidVote struct {
	Line  int
	Issue string
}

InvalidVote describes an issue with input which could not be parsed into a vote.

type Preference

type Preference uint

Preference indicates to what degree something is preferred over other options. 0 is the highest preference, indicating most preferred.

type Results

type Results []CandidateID

Results consists of the ranked set of candidates, resulting from an election.

func Evaluate

func Evaluate(votes []Vote) Results

Evaluate will perform a Schulze Condorcet election.

type Vote

type Vote map[CandidateID]Preference

Vote allocates preferences to candidates (0 being highest preference). A vote may give candidates equal preference, and may omit candidates (effectively giving them equal lowest preference).

type VoteReader

type VoteReader struct {
	// contains filtered or unexported fields
}

VoteReader wraps an io.Reader to read Votes.

func NewVoteReader

func NewVoteReader(r io.Reader, parseFn CandidateIDParseFn) *VoteReader

NewVoteReader is a constructor.

func (*VoteReader) Read

func (vr *VoteReader) Read() (*Vote, error)

func (*VoteReader) ReadAll

func (vr *VoteReader) ReadAll() ([]Vote, []InvalidVote)

ReadAll reads all votes from the VoteReader (until the reader reaches EOF). Lines which can't be parsed are returned as InvalidVotes.

Directories

Path Synopsis
cmd
nolint
nolint

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL