示例#1
0
def test_bulk_athena():
    # Same as Minerva (that is, delta = infinity)

    # Ballot-by-ballot Minerva should yield identical stopping rules to BRAVO.
    contest = Contest(100000, {
        'A': 60000,
        'B': 40000
    }, 1, ['A'], ContestType.MAJORITY)
    athena = Athena(.1, 2**31 - 1, .01, contest)
    athena.compute_all_min_winner_ballots(athena.sub_audits['A-B'])
    # p0 not hardcoded as .5 for scalability with odd total contest ballots.
    p0 = (athena.contest.contest_ballots // 2) / athena.contest.contest_ballots
    log_winner_multiplier = math.log(
        athena.sub_audits['A-B'].sub_contest.winner_prop / p0)
    log_loser_multiplier = math.log(
        (1 - athena.sub_audits['A-B'].sub_contest.winner_prop) / p0)
    log_rhs = math.log(1 / athena.alpha)

    for i in range(len(athena.rounds)):
        n = athena.rounds[i]
        kmin = athena.sub_audits['A-B'].min_winner_ballots[i]
        # Assert this kmin satisfies ratio, but a kmin one less does not.
        assert kmin * log_winner_multiplier + (
            n - kmin) * log_loser_multiplier > log_rhs
        assert (kmin - 1) * log_winner_multiplier + (
            n - kmin + 1) * log_loser_multiplier <= log_rhs
示例#2
0
def test_exceptions():
    contest = Contest(100000, {
        'A': 60000,
        'B': 40000
    }, 1, ['A'], ContestType.MAJORITY)
    with pytest.raises(ValueError):
        Athena(.1, 0, .1, contest)
    athena = Athena(.1, 1, .1, contest)
    with pytest.raises(Exception):
        athena.stopping_condition_pairwise('A-B')
    athena.rounds.append(10)
    with pytest.raises(ValueError):
        athena.stopping_condition_pairwise('X')
    athena.rounds = []
    with pytest.raises(ValueError):
        athena.compute_min_winner_ballots(athena.sub_audits['A-B'], [])
    with pytest.raises(ValueError):
        athena.compute_min_winner_ballots(athena.sub_audits['A-B'], [0])
    with pytest.raises(ValueError):
        athena.compute_min_winner_ballots(athena.sub_audits['A-B'], [1, 2])
    with pytest.raises(ValueError):
        athena.compute_min_winner_ballots(athena.sub_audits['A-B'], [20, 20])
    with pytest.raises(ValueError):
        athena.compute_min_winner_ballots(athena.sub_audits['A-B'], [20, 19])
    with pytest.raises(ValueError):
        athena.compute_min_winner_ballots(athena.sub_audits['A-B'], [10001])

    athena.compute_min_winner_ballots(athena.sub_audits['A-B'], [20])
    with pytest.raises(ValueError):
        athena.compute_min_winner_ballots(athena.sub_audits['A-B'], [20])
    with pytest.raises(ValueError):
        athena.compute_min_winner_ballots(athena.sub_audits['A-B'], [19])
    with pytest.raises(ValueError):
        athena.compute_min_winner_ballots(athena.sub_audits['A-B'], [10001])

    contest2 = Contest(100, {'A': 60, 'B': 30}, 1, ['A'], ContestType.MAJORITY)
    athena2 = Athena(0.1, 1, 1.0, contest2)
    with pytest.raises(ValueError):
        athena2.compute_min_winner_ballots(athena2.sub_audits['A-B'], [91])
    athena2.rounds.append(10)
    with pytest.raises(Exception):
        athena2.compute_all_min_winner_ballots(athena2.sub_audits['A-B'])
    athena2.rounds = []
    with pytest.raises(ValueError):
        athena2.compute_all_min_winner_ballots(athena2.sub_audits['A-B'], 0)
    with pytest.raises(ValueError):
        athena2.compute_all_min_winner_ballots(athena2.sub_audits['A-B'], 200)
    with pytest.raises(ValueError):
        athena2.compute_all_min_winner_ballots(athena2.sub_audits['A-B'], 0)