X-Git-Url: https://projects.mako.cc/source/rubyvote/blobdiff_plain/74e5c5f3c50a36d8d8589c243395b9158977f4db..0ef8f53fb812bcc40337a92f9c4d11ab193f73a9:/lib/election.rb?ds=sidebyside diff --git a/lib/election.rb b/lib/election.rb deleted file mode 100644 index 7fd8396..0000000 --- a/lib/election.rb +++ /dev/null @@ -1,160 +0,0 @@ -# election library -- a ruby library for elections -# copyright © 2005 MIT Media Lab and Benjamin Mako Hill - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -################################################################# -## ==== election.rb ==== -## -## This file contains the core ElectionVote and ElectionResults -## classes and the most common and simple election methods including -## plurality and approval voting. -################################################################# - -################################################################## -## ElectionVote Classes and SubClasses -## -## There classes are used to store, verify, and "tally" (i.e. count -## votes for the standard Election superclass and for the most common -## types of elections. - -class ElectionVote - attr_reader :votes - attr_reader :candidates - - def initialize(votes=nil) - @votes = Hash.new unless defined?(@votes) - @candidates = Array.new unless defined?(@candidates) - - if votes - if votes.instance_of?( Array ) - votes.each do |vote| - self.tally_vote(vote) if self.verify_vote(vote) - end - else - raise ElectionError, "Votes must be in the form of an array.", caller - end - end - end - - protected - # by default, this is set to look if the vote is defined. it should - # be overridden in each class - def verify_vote(vote=nil) - vote ? true : false - end - - # by default, this does nothing. it must be redefined in any subclass - def tally_vote - self.verify_vote(vote) - end -end - -class PluralityVote < ElectionVote - def result - PluralityResult.new(self) - end - - protected - def verify_vote(vote=nil) - vote.instance_of?( String ) - end - - def tally_vote(candidate) - if @votes.has_key?(candidate) - @votes[candidate] += 1 - else - @votes[candidate] = 1 - @candidates << candidate - end - end -end - -class ApprovalVote < PluralityVote - def result - ApprovalResult.new(self) - end - - protected - def verify_vote(vote=nil) - vote.instance_of?( Array ) and vote.length >= 1 - end - - def tally_vote(approvals) - approvals.each {|candidate| super(candidate)} - end -end - - -################################################################## -## Election Result Classes -## - -## There classes are used to compute and report the results of an -## election. In almost all cases, these will be returned by the -## #results method of a corresponding ElectionVote subclass. - -class ElectionResult - attr_reader :winners - - def initialize(voteobj=nil) - unless voteobj and voteobj.kind_of?( ElectionVote ) - raise ArgumentError, "You must pass a ElectionVote array.", caller - end - - @election = voteobj - @winners = Array.new - end - - def winner - @winners[0] if @winners.length > 0 - end - - def winner? - @winners.length > 0 - end - -end - -class PluralityResult < ElectionResult - attr_reader :ranked_candidates - - def initialize(voteobj=nil) - super(voteobj) - - votes = @election.votes - candidates = @election.candidates - - @ranked_candidates = votes.sort do |a, b| - b[1] <=> a[1] - end.collect {|a| a[0]} - - # winners are anyone who has the same number of votes as the - # first person - @winners = @ranked_candidates.find_all do |i| - votes[i] == votes[@ranked_candidates[0]] - end - end -end - -# this class is complete because results for approval are computed -# identically to results from plurality -class ApprovalResult < PluralityResult -end - -class ElectionError < ArgumentError -end -