Subversion Repositories Remote Hare Voting

Rev

Rev 38 | Rev 45 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#!/p/python-2.5.1/bin/python

import optparse
import cgi
import string
import sys

import revision
import parseinput
import tally

fHTML = 1
formaction = string.split(sys.argv[0],"/")[-1]

def emitPreHTML(formaction):
    emitHTML("""Content-type: text/html\n
<html>
<body>
<title>Hare Ballot Calculation</title>
    <h1>Hare Ballot Calculation</h1>
    <form enctype="multipart/form-data" method=POST action=%s>
        <table>
        <tr><td>CSV file of ballots:
                <td><input type=file size=70 name=name>
        </table>
        <p>
        <input type=submit name="run1" value="Run 1 Time">
        <input type=submit name="run1000" value="Run 1000 Times">
    </form>
    <p>
Input file format is given
<a href="http://www.bikmort.com/wiki/index.php?title=Hare_Voting_Procedure">here</a>.
Almost no error checking is done, so be sure to review the trace output.
The source code is available <a href="%s?fetch=yes">here</a>.
<p>
<small>%s</small>
<hr>
<pre>
""" % (formaction, formaction, revision.revision))
    return

def emitPostHTML():
    emitHTML("""</pre>
</body>
</html>
""")
    return

def emitHTML(s):
    global fHTML
    if fHTML: print s
    return

def doone(nWinners, ballots):
    results = tally.dotally(nWinners, ballots)
    print "\nFINAL RESULTS"
    for winner in results:
        print "\t%s" % winner

def domany(nTimes, nWinners, ballots):
    print "RUNNING %d TIMES" % (nTimes)
    tally.fTrace = 0
    summary = {}
    for i in range(nTimes):
        results = str(tally.dotally(nWinners, ballots))
        # print "Run %2d: %s" % (i+1, results)
        if not summary.has_key(results):
            summary[results] = 0
        summary[results] = summary[results] + 1
    print "\nSUMMARY"
    l = summary.items()
    l.sort(lambda x,y: cmp(y[1], x[1]))
    for pair in l:
        print "%2d %s" % (pair[1], pair[0])

def doweb():
    emitPreHTML(formaction)
    form = cgi.FieldStorage()

    if not form:
        emitHTML("Enter file name and press a button to see results.")
    elif form.has_key("fetch"):
        filename = string.replace(formaction, "vote.py", "tally.py")
        source = open(filename).read()
        print cgi.escape(source)
    elif not form.has_key("name"):
        emitHTML("Error: no file received")
    elif not form["name"].filename:
        emitHTML("Error: file name missing")
    else:
        name = form["name"].filename
        contents = form["name"].value

        tally.trace("INPUT FILE")
        tally.trace(contents)

        nWinners, ballots = parseinput.parsestring(contents)
        if form.has_key("run1"):
            doone(nWinners, ballots)
        elif form.has_key("run1000"):
            domany(1000, nWinners, ballots)
        else:
            print "UNEXPECTED SUBMIT BUTTON: %s" % form
                
    emitPostHTML()
    return

def main():
    usage = "usage: %prog [options] filename.csv"
    parser = optparse.OptionParser(usage)
    parser.add_option("-m", "--multi", dest="multi", action="store_true",
                      help="run process multiple (1000) times")
    (options, args) = parser.parse_args()

    if len(args) == 0:
        doweb()
    else:
        nWinners, ballots = parseinput.parsefile(args[0])
        if options.multi:
            domany(1000, nWinners, ballots)
        else:
            doone(nWinners, ballots)

if __name__=='__main__':
    main()