Пример #1
0
 def testCompareFile(self):
     "normal init from file: 2 seats"
     path = testdir + '/blt/42.blt'
     pd = ElectionProfile(data=p_42)
     pp = ElectionProfile(path)
     self.assertFalse(pp.compare(pd),
                      'compare election 42 from file vs data blob')
Пример #2
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')
Пример #3
0
 def testInitTitle(self):
     "normal init: title set"
     t1 = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     t2 = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie" junk'''
     self.assertEqual(
         ElectionProfile(data=t1).title, 'Pollux and Helen should tie')
     self.assertEqual(
         ElectionProfile(data=t2).title, 'Pollux and Helen should tie')
Пример #4
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())
Пример #5
0
 def testDroopOptionCount(self):
     "set arithmetic options"
     b0 = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     self.assertEqual(len(ElectionProfile(data=b0).options), 0)
     b1 = '''3 2 [droop arithmetic=fixed] 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     self.assertEqual(len(ElectionProfile(data=b1).options), 1)
     b2 = '''3 2 [droop arithmetic=fixed precision=6] 4 1 2 0 2 3 0 0
         "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     p = ElectionProfile(data=b2)
     self.assertEqual(len(p.options), 2)
     self.assertEqual(p.options[0], 'arithmetic=fixed')
     self.assertEqual(p.options[1], 'precision=6')
Пример #6
0
 def testBallotEQ8(self):
     "test profile compare with equal rankings"
     b1 = '''3 2 4 1 2=3 0 2 2=3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     b2 = '''3 2 4 1 2=3 0 2 2=3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     b3 = '''3 2 3 1 2=3 0 3 2=3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     b4 = '''3 2 4 1 2=3 0 2 2=1 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     p1 = ElectionProfile(data=b1)
     p2 = ElectionProfile(data=b2)
     self.assertFalse(p1.compare(p2))
     p3 = ElectionProfile(data=b3)
     p4 = ElectionProfile(data=b4)
     self.assertTrue(p1.compare(p3))
     self.assertTrue(p1.compare(p4))
Пример #7
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)
Пример #8
0
 def testNick1(self):
     "test basic nicknames"
     b0 = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     b1 = '''3 2 [nick a b c ] 4 a b 0 2 c 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"'''
     p0 = ElectionProfile(data=b0)
     self.assertEqual(len(p0.nickName), 3)
     p1 = ElectionProfile(data=b1)
     self.assertEqual(len(p1.nickName), 3)
     p2 = ElectionProfile(data=b2)
     self.assertEqual(len(p2.nickName), 3)
     self.assertEqual(len(p2._nickCid), 3)
     for i in xrange(len(p1.ballotLines)):
         self.assertEqual(p1.ballotLines[i].multiplier, p2.ballotLines[i].multiplier)
         self.assertEqual(p1.ballotLines[i].ranking, p2.ballotLines[i].ranking)
         self.assertEqual(p1.ballotLines[i].multiplier, p0.ballotLines[i].multiplier)
         self.assertEqual(p1.ballotLines[i].ranking, p0.ballotLines[i].ranking)
Пример #9
0
 def testBadOptions(self):
     "try wigm with bad options"
     b = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     profile = ElectionProfile(data=b)
     self.assertRaises(UsageError, Election, profile,
                       dict(rule='wigm', integer_quota=2))
     self.assertRaises(UsageError, Election, profile,
                       dict(rule='wigm', defeat_batch="bad"))
Пример #10
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'))
Пример #11
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'])
Пример #12
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'))
Пример #13
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'))
Пример #14
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'))
Пример #15
0
 def testBallotEQ8(self):
     "test profile compare with equal rankings"
     b1 = '''3 2 4 1 2=3 0 2 2=3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     b2 = '''3 2 4 1 2=3 0 2 2=3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     b3 = '''3 2 3 1 2=3 0 3 2=3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     b4 = '''3 2 4 1 2=3 0 2 2=1 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     p1 = ElectionProfile(data=b1)
     p2 = ElectionProfile(data=b2)
     self.assertFalse(p1.compare(p2))
     p3 = ElectionProfile(data=b3)
     p4 = ElectionProfile(data=b4)
     self.assertTrue(p1.compare(p3))
     self.assertTrue(p1.compare(p4))
Пример #16
0
 def testInitSourceComment(self):
     "normal init: source & comment set"
     b1 = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "title" "source less" "comment more"'''
     b2 = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "title" "source less'''
     b3 = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "title" "source less" "comment more'''
     b4 = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "title" "source less" junk'''
     b5 = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "title" "source less" "comment more" junk'''
     b6 = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "title" "source less"'''
     self.assertEqual(ElectionProfile(data=b1).title, 'title')
     self.assertEqual(ElectionProfile(data=b1).source, 'source less')
     self.assertEqual(ElectionProfile(data=b6).source, 'source less')
     self.assertEqual(ElectionProfile(data=b4).source, 'source less')
     self.assertEqual(ElectionProfile(data=b1).comment, 'comment more')
     self.assertEqual(ElectionProfile(data=b5).comment, 'comment more')
     self.assertRaises(ElectionProfileError, ElectionProfile, data=b2)
     self.assertRaises(ElectionProfileError, ElectionProfile, data=b3)
Пример #17
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')
Пример #18
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)
Пример #19
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
Пример #20
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
Пример #21
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()
Пример #22
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
Пример #23
0
 def testInitSeats(self):
     "normal init: 2 seats"
     self.assertEqual(ElectionProfile(data=p_42).nSeats, 2)
Пример #24
0
 def testElectionNoRule(self):
     "trying an election without a rule should fail"
     b = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     p = ElectionProfile(data=b)
     self.assertRaises(ElectionError, Election, p, dict())
Пример #25
0
 def testElectionBadRule(self):
     "trying an election with an undefined rule should fail"
     b = '''3 2 4 1 2 0 2 3 0 0 "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     p = ElectionProfile(data=b)
     self.assertRaises(ElectionError, Election, p, dict(rule='nothing'))
Пример #26
0
 def testInitOneLine(self):
     "normal init: 2 seats (no newlines)"
     self.assertEqual(ElectionProfile(data=p_42a).nSeats, 2)
Пример #27
0
 def testInitOneTokenComment(self):
     "normal init: 2 seats (single-token comment)"
     b = '''3 2 4 1 2 0 2 3 0 0 /* nested /*comment*/ */ "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     self.assertEqual(ElectionProfile(data=b).nSeats, 2)
Пример #28
0
 def testInitHashComment(self):
     "normal init: 2 seats (hash comment)"
     b = '''3 2 4 1 2 0 2 3 0 0 # comment\n "Castor" "Pollux" "Helen" "Pollux and Helen should tie"'''
     self.assertEqual(ElectionProfile(data=b).nSeats, 2)
Пример #29
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)
Пример #30
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)
Пример #31
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'))
Пример #32
0
 def testCompareFile(self):
     "normal init from file: 2 seats"
     path = testdir + '/blt/42.blt'
     pd = ElectionProfile(data=p_42)
     pp = ElectionProfile(path)
     self.assertFalse(pp.compare(pd), 'compare election 42 from file vs data blob')