# # Python Alternative Vote # # Copyright(c) 2011 Andrew Cassidy # http://www.jonisdumb.com/ # # This file may be licensed under the terms of of the # GNU General Public License Version 2 (the ``GPL''). # # Software distributed under the License is distributed # on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either # express or implied. See the GPL for the specific language # governing rights and limitations. # # You should have received a copy of the GPL along with this # program. If not, go to http://www.gnu.org/licenses/gpl.html # or write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # import io; import math; # valid choices choices = ["Strawberry","Vanilla","Chocolate","Mint","Fudge"] # list of votes votes = [] #open the votes file f = open("icecream.csv", "r") # load the votes. strip witespace from each line, # split it into votes, then check it's in the list of valid choices votes = map(lambda x: filter(lambda y: y in choices, x.strip().split(',')), f) #close the file f.close() # initial round round = 1 while True: # quota for this round, 50% or more of the total vote quota = math.ceil(len(votes)/2.0) print 'Round ' + str(round) + ': ' + str(len(votes)) + ' (' + str(quota) + ')' #count the votes, first take the current first preference votes voteheads = map(lambda x: x[0], votes) # count the number for each of the valid choices, filter out any that are 0 totalvotes = dict(filter(lambda (x,y): y > 0, map(lambda x: (x, voteheads.count(x)), choices))) #print the votes print totalvotes print '' # get the most votes highest = max(totalvotes, key=totalvotes.get) # do we have one >= 50%? if (totalvotes[highest] >= quota): # get ALL candidates with the same highest vote (check for a tie) allhighest = filter(lambda x: totalvotes[x] == totalvotes[highest], totalvotes.keys()) # single winer if (len(allhighest) == 1): print 'Winner:\t' + highest + ' (' + str(totalvotes[highest]) + ')' break #tie. The tie can only ever be 50/50 between 2 candidates. elif (len(allhighest) == 2): print 'TIE!' break # get the lowest count lowest = min(totalvotes, key=totalvotes.get) # get all tied lowest eliminated = filter(lambda x: totalvotes[x] == totalvotes[lowest], totalvotes.keys()) #remove all eliminated votes = map(lambda x: filter(lambda y: not (y in eliminated), x), votes) # remove all no further preference votes = filter(lambda x: x != [], votes) round = round + 1