#
# Python Alternative Vote 
#
# Copyright(c) 2011 Andrew Cassidy <andee@bytz.co.uk>
# 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

