Hi! Here is a Schulze implementation, written in python, using gtk. Please someone confirm whether the last step of ranking candidates done correctly. It is in class Result, function compute. It gives correct result for the Tennessee example, but I am not sure.
It is specifically written for situations like a village meeting: lot of people, one computer, and the result should be known instantly. Voting is done by directly asking for relative preferences, so pairwise matrix is entered directly. In config tab you can give the number of candidates (default=5) In vote tab you give the names, and the pairwise matrix. The matrix gives the number of voters who preferred the candidate listed in the row caption to the candidate in the row corresponding to the column. Clicking on the result tab gives the ranking of the candidates.
#!/usr/bin/python # -*- coding: utf-8 -*- # Copyright [email protected] GNU GPL import pygtk pygtk.require('2.0') import gtk import pango class Hello: def hello(self,widget,data=None): print "hello" def delete_event(self,widget,event,data=None): return False def destroy(self,widget,data=None): gtk.main_quit() def __init__(self,children): self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.connect("delete_event", self.delete_event) self.window.connect("destroy", self.destroy) self.window.set_border_width(10) self.notebook = gtk.Notebook() self.window.add(self.notebook) self.notebook.show() self.window.show() self.children=children for w,n in children: self.add(w.widget,n) def main(self): gtk.main() def add(self,widget,name): self.notebook.add(widget) self.notebook.set_tab_label_text(widget,name) widget.show() class Config: def __init__(self,slave): self.slave=slave self.widget=gtk.HBox() self.label=gtk.Label("mennyi") self.widget.add(self.label) self.entry=gtk.Entry() self.entry.insert_text('5') self.widget.add(self.entry) self.button=gtk.Button("Legyen") self.button.connect('clicked',self.config,None) self.widget.add(self.button) self.label.show() self.entry.show() self.button.show() def config(self,widget,data=None): ns=self.entry.get_chars(0,-1) if ns == '': ns = '0' n=int(ns) print ns,n self.slave.config(n) class Entries: def __init__(self, number=5): self.number=number self.widget=gtk.Table(rows=number,columns=number+1) self.populate() self.widget.show() def populate(self,fr=0): fd=pango.FontDescription("Sans 20") self.children=[] for i in range(fr,self.number): cs=[] e=gtk.Entry() e.modify_font(fd) cs.append(e) e.set_property("width-chars",30) e.show() self.widget.attach(e,0,1,i,i+1) for j in range(fr,self.number): if i == j: e=gtk.Label(' - ') else: e=gtk.Entry() e.set_property("width-chars",3) cs.append(e) e.modify_font(fd) e.show() self.widget.attach(e,1+j,2+j,i,i+1,xoptions=0) self.children.append(cs) def harvest(self): l=[] for i in self.children: ll=[] for j in i: if j.__class__ == gtk.Label: ll.append("0") else: ll.append(j.get_chars(0,-1)) l.append(ll) return l def config(self,num): l=self.harvest() parent=self.widget.parent self.widget.destroy() self.number=num self.widget=gtk.Table(rows=self.number,columns=self.number+1) self.populate() x=0 for i in l[:self.number]: y=0 for j in i[:self.number+1]: k=self.children[x][y] if k.__class__ != gtk.Label: k.insert_text(j) y += 1 x += 1 parent.add(self.widget) parent.set_tab_label_text(self.widget,'vote') self.widget.show() class Result: def __init__(self,entries): self.widget=gtk.Label("ide jon\n az eredmeny") self.widget.connect('map',self.compute,None) self.entries=entries def compute(self,widget,data=None): self.widget.set_text('computing result') self.getdata() self.floyd_warshall() print self.candidates print self.d print self.p C = len(self.candidates) winners=[] hasnew = True while hasnew: hasnew = False for i in range(C): if i not in winners: isnew = True for j in range(C): if j not in winners: if i != j: if self.d[i,j] < self.d[j,i]: isnew = False if isnew: winners.append(i) hasnew = True print winners s="" for i in winners: s += self.candidates[i]+'\n' print s self.widget.set_text(s) def getdata(self): l=self.entries.harvest() candidates=[] d={} x=0 for line in l: candidates.append(line[0]) y=0 for pr in line[1:]: if pr == '': pr = '0' d[x,y]=int(pr) y+=1 x+=1 self.candidates=candidates self.d=d def floyd_warshall(self): candidates=self.candidates C=len(candidates) d=self.d p={} for i in range(C): for j in range(C): if i != j: if d[i,j] > d[j,i]: p[i,j] = d[i,j] else: p[i,j] = 0 for i in range(C): for j in range(C): if i != j: for k in range(C): if i != k: if j != k: p[j,k] = max(p[j,k],min(p[j,i],p[i,k])) self.p = p def main(go=False): e=Entries() c=Config(e) r=Result(e) hello = Hello([(c,'config'),(e,'vote'),(r,"result")]) if go: hello.main() return hello if __name__ == "__main__": main(True)
---- Election-Methods mailing list - see http://electorama.com/em for list info
