Exemplo n.º 1
0
 def testDefeatBatch(self):
     "tag is name of rule"
     b = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     E = Election(ElectionProfile(data=b), dict(rule='wigm-prf'))
     self.assertEqual(E.rule.tag(), 'wigm-prf')
     E = Election(ElectionProfile(data=b), dict(rule='wigm-prf-batch'))
     self.assertEqual(E.rule.tag(), 'wigm-prf-batch')
Exemplo n.º 2
0
 def testDroopOptions(self):
     "test [droop ...]"
     if 'meek' in droop.electionRuleNames():
         b = '''3 2 [droop arithmetic=fixed precision=4] 4 1 2 0 2 3 0 0
             "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
         E = Election(ElectionProfile(data=b), dict(rule='meek'))
         self.assertEqual(E.V.precision, 4)
         E = Election(ElectionProfile(data=b), dict(rule='meek',
                                                    precision=6))
         self.assertEqual(E.V.precision, 6)
         b = '''3 2 [droop rational precision=4] 4 1 2 0 2 3 0 0
             "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
         E = Election(ElectionProfile(data=b), dict(rule='meek'))
         self.assertEqual(E.V.name, 'rational')
         b = '''3 2 [droop meek] 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
         E = Election(ElectionProfile(data=b), dict())
         self.assertEqual(E.rule.method, 'meek')
         E = Election(ElectionProfile(data=b), None)
         self.assertEqual(E.rule.method, 'meek')
         b = '''3 2 [droop dump meek] 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
         E = Election(ElectionProfile(data=b), None)
         self.assertTrue(E.options.getopt('dump'))
         b = '''3 2 [droop dump=true meek] 4 1 2 0 2 3 0 0
             "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
         E = Election(ElectionProfile(data=b), None)
         self.assertTrue(E.options.getopt('dump'))
         b = '''3 2 [droop dump=false meek] 4 1 2 0 2 3 0 0
             "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
         E = Election(ElectionProfile(data=b), None)
         self.assertFalse(E.options.getopt('dump'))
         # fake a path to test double-path logic
         b = '''3 2 [droop 42.blt 513.blt meek] 4 1 2 0 2 3 0 0
             "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
         self.assertRaises(UsageError, Election, ElectionProfile(data=b),
                           dict())
Exemplo n.º 3
0
 def testNickReport(self):
     "using nicknames shouldn't alter dump or report"
     b1 = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     b2 = '''3 2 [nick a b c] 4 a b 0 2 c 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     E = Election(ElectionProfile(data=b1), dict(rule='meek-prf'))
     E.count()
     r1 = E.report()
     d1 = E.dump()
     E = Election(ElectionProfile(data=b2), dict(rule='meek-prf'))
     E.count()
     r2 = E.report()
     d2 = E.dump()
     self.assertEqual(r1, r2)
     self.assertEqual(d1, d2)
Exemplo n.º 4
0
 def testMeekWarren1(self):
     "meek responds to warren"
     b = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     profile = ElectionProfile(data=b)
     E = Election(profile, dict(rule='warren'))
     self.assertEqual(E.rule.tag(), 'warren-o9')
     self.assertRaises(UsageError, Election, profile,
                       dict(rule='warren', defeat_batch='whatever'))
Exemplo n.º 5
0
 def testArithmetic(self):
     "wigm-prf uses fixed"
     b = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     E = Election(ElectionProfile(data=b), dict(rule='wigm-prf', arithmetic='guarded', abc=4))
     self.assertEqual(E.options.getopt('arithmetic'), 'fixed')
     self.assertEqual(E.options.getopt('precision'), 4)
     self.assertEqual(E.options.overrides(), ['arithmetic'])
     self.assertEqual(E.options.unused(), ['abc'])
Exemplo n.º 6
0
 def testDefeatRemaining(self):
     "count a profile that has hopeful candidates left over to defeat"
     b = '''3 2  4 1 0  4 2 0  2 3 0  0 "Castor" "Pollux" "Helen" "test defeat-remaining"'''
     E = Election(ElectionProfile(data=b), dict(rule='wigm-prf'))
     E.count()
     elected = [c.name for c in E.elected]
     self.assertEqual(elected, ['Castor', 'Pollux'])
     defeated = [c.name for c in E.defeated]
     self.assertEqual(defeated, ['Helen'])
     report = E.report()
     self.assertTrue(report.find('Defeat remaining'))
Exemplo n.º 7
0
 def testElectAll(self):
     "count a profile with nSeats candidates"
     b = '''2 2  4 1 0  4 2 0  2 1 0  0 "Castor" "Pollux" "test nseats candidates"'''
     E = Election(ElectionProfile(data=b), dict(rule='cfer'))
     E.count()
     elected = [c.name for c in E.elected]
     self.assertEqual(elected, ['Castor', 'Pollux'])
     defeated = [c.name for c in E.defeated]
     self.assertEqual(defeated, [])
     report = E.report()
     self.assertTrue(report.find('Elect all'))
Exemplo n.º 8
0
 def testDefeatBatch(self):
     "count a profile that has with defeat_batch option"
     b = '''4 2  4 1 0  3 2 0  2 3 2 0  0 "Castor" "Pollux" "Helen" "George" "test defeat-batch"'''
     E = Election(ElectionProfile(data=b),
                  dict(rule='wigm', defeat_batch='zero'))
     E.count()
     elected = [c.name for c in E.elected]
     self.assertEqual(elected, ['Castor', 'Pollux'])
     defeated = [c.name for c in E.defeated]
     self.assertEqual(defeated, ['Helen', 'George'])
     report = E.report()
     self.assertTrue(report.find('Defeat batch'))
Exemplo n.º 9
0
    def testReports(self):
        "look at election outputs"
        b = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''

        profile = ElectionProfile(data=b)
        rulename = droop.electionRuleNames()[
            0]  # pick the first rule arbitrarily
        E = Election(profile, dict(rule=rulename))
        E.count()
        self.assertEqual(E.report().find('interrupted'), -1)
        self.assertTrue(E.report(intr=True).find('interrupted') > 0)
        E = Election(profile, dict(rule=rulename))
        E.count()
        self.assertEqual(E.dump().find('interrupted'), -1)
        self.assertTrue(E.dump(intr=True).find('interrupted') > 0)
        E = Election(profile, dict(rule=rulename))
        E.count()
        self.assertEqual(E.json().find('interrupted'), -1)
        self.assertTrue(E.json(intr=True).find('interrupted') > 0)
        r = E.record()
        self.assertTrue(r, dict)
        self.assertEqual(r['actions'][-1]['tag'], 'log')
Exemplo n.º 10
0
    def testRules(self):
        "basic test of each rule"
        b = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''

        profile = ElectionProfile(data=b)
        for rulename in droop.electionRuleNames():
            options = dict(rule=rulename)
            E = Election(profile, options)
            self.assertTrue(E.rule.__class__.__name__ == 'Rule',
                            'bad rule class')
            self.assertTrue(
                len(options) >= 1, 'rule should set/leave at least one option')
            self.assertTrue(
                E.options.getopt('arithmetic')
                in ('fixed', 'integer', 'guarded', 'rational'),
                'legal arithmetic')
            candidates = E.C
            self.assertTrue("Castor" in [c.name for c in candidates])
            self.assertTrue("Castor" in [str(c) for c in candidates])
            self.assertTrue(1 in [c for c in candidates])
            for c in candidates:
                self.assertEqual(c.order, c.tieOrder)
            E.count()
            self.assertEqual(len(E.elected), E.nSeats)
Exemplo n.º 11
0
def doDumpCompare(options, filename, subdir=''):
    '''
    helper: do a count and compare dump/report to reference
    '''
    if not filename.endswith('.blt'):
        filename += '.blt'
    base, ext = os.path.splitext(filename)  # pylint: disable=W0612

    blt = os.path.join(testdir, 'blt', subdir, filename)
    E = Election(ElectionProfile(blt), options)
    E.count()
    tag = '%s-%s-%s' % (base, E.rule.tag(), E.V.tag())

    def readFile(path):
        "read a json/dump/report file"
        f = open(path, 'r')
        data = f.read()
        f.close()
        return data

    def writeFile(path, data):
        "write a json/dump/report file"
        if not os.path.isdir(os.path.dirname(path)):
            os.makedirs(os.path.dirname(path))
        f = open(path, 'w')
        f.write(data)
        f.close()

    #  first do report
    #
    rref = os.path.join(testdir, 'ref', 'report', subdir, '%s.txt' % tag)
    rout = os.path.join(testdir, 'out', 'report', subdir, '%s.txt' % tag)
    report = E.report()
    if not os.path.isfile(rref):
        writeFile(rref, report)
    reportref = readFile(rref)
    if os.path.isfile(rout):
        os.unlink(rout)
    # don't include version number in comparison
    report0 = re.sub(r'droop v\d+\.\d+', 'droop v0.0', report)
    reportref = re.sub(r'droop v\d+\.\d+', 'droop v0.0', reportref)
    if report0 != reportref:
        writeFile(rout, report)
        if compare_report:
            return False

    #  same logic with json
    #
    sref = os.path.join(testdir, 'ref', 'json', subdir, '%s.txt' % tag)
    sout = os.path.join(testdir, 'out', 'json', subdir, '%s.txt' % tag)
    json = E.json()
    if not os.path.isfile(sref):
        writeFile(sref, json)
    jsonref = readFile(sref)
    if os.path.isfile(sout):
        os.unlink(sout)
    # don't include version number in comparison
    json0 = re.sub(r'"droop_version": "\d+\.\d+"', '"droop_version": "0.0"',
                   json)
    jsonref = re.sub(r'"droop_version": "\d+\.\d+"', '"droop_version": "0.0"',
                     jsonref)
    if json0 != jsonref:
        writeFile(sout, json)
        if compare_json:
            return False

    #  same logic with dump
    #
    dref = os.path.join(testdir, 'ref', 'dump', subdir, '%s.txt' % tag)
    dout = os.path.join(testdir, 'out', 'dump', subdir, '%s.txt' % tag)
    dump = E.dump()
    if not os.path.isfile(dref):
        writeFile(dref, dump)
    dumpref = readFile(dref)
    if os.path.isfile(dout):
        os.unlink(dout)
    if dump != dumpref:
        writeFile(dout, dump)
        if compare_dump:
            return False

    return True
Exemplo n.º 12
0
 def getDump(options, base):
     "run a count and return the dump"
     blt = '%s/blt/%s.blt' % (testdir, base)
     E = Election(ElectionProfile(blt), options)
     E.count()
     return E.dump()
Exemplo n.º 13
0
def main(options=None):
    "run an election"

    if not options:
        raise droop.common.UsageError("no ballot file specified")

    #  process options
    #
    #  we know about (path, profile)
    #  all the others are passed to the various consumers
    #
    path = None  # ballot path must be specified
    doProfile = False  # performance profiling
    reps = 1  # repetitions (for profiling)
    for opt, arg in options.items():
        if opt == 'path':  # path=<path to ballot file>
            path = arg
        elif opt == 'profile':  # profile=<number of repetitions>
            import cProfile
            import pstats
            reps = int(arg)
            doProfile = True
            profilefile = "profile.out"
    if not path:
        raise droop.common.UsageError("no ballot file specfied")

    #  run the election
    #
    #    fetch the election profile
    #    create the Election object
    #    count
    #    report
    #
    def countElection(E, repeat=1):
        "encapsulate for optional profiling"
        for i in xrange(repeat):  # pylint: disable=W0612
            E.count()

    electionProfile = ElectionProfile(
        path=path)  # don't repeat the profile loading
    E = Election(electionProfile, options)
    try:
        intr = False
        if doProfile:
            cProfile.runctx('countElection(E, reps)', globals(), locals(),
                            profilefile)
        else:
            countElection(E, reps)
    except KeyboardInterrupt:
        intr = True
    E.options.setopt('dump', default=False)
    E.options.setopt('json', default=False)
    ereport = ''
    if E.options.setopt('report', default=True):
        ereport += E.report(intr)
    if E.options.getopt('dump'):
        ereport += E.dump(intr)
    if E.options.getopt('json'):
        ereport += E.json(intr)

    if doProfile:
        p = pstats.Stats(profilefile)
        p.strip_dirs().sort_stats('time').print_stats(50)

    return ereport
Exemplo n.º 14
0
 def doCount(options, blt):
     "run the count and return the Election"
     p = ElectionProfile(testdir + '/blt/' + blt)
     E = Election(p, options)
     E.count()
     return E
Exemplo n.º 15
0
 def testElectionMpls1(self):
     "mpls: everyone elected at first"
     p_mpls1 = '''3 2 4 1 2 0 4 2 1 0 1 3 0 0 "a" "b" "c" "2 elected at first"'''
     E = Election(ElectionProfile(data=p_mpls1), dict(rule='mpls'))
     E.count()
     self.assertEqual(len(E.elected), 2)
Exemplo n.º 16
0
 def setUp(self):
     "initialize profile and rule"
     b = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     self.Profile = ElectionProfile(data=b)
     self.E = Election(self.Profile, dict(rule='qpq'))
Exemplo n.º 17
0
 def doQpqCount(filename):
     "each of five elections from the Woodall paper"
     blt = os.path.join(testdir, 'blt', 'qpq', filename)
     E = Election(ElectionProfile(blt), dict(rule='qpq'))
     E.count()
     return E
Exemplo n.º 18
0
 def testElectionQpq1(self):
     "qpq: everyone elected at first"
     b = '''3 2 4 1 2 0 4 2 1 0 1 3 0 0 "a" "b" "c" "2 elected at first"'''
     E = Election(ElectionProfile(data=b), dict(rule='qpq'))
     E.count()
     self.assertEqual(len(E.elected), 2)