Browse Source

test: enable the median default grade in the JSON assertions

feat-median-default-grade
Dominique Merle 1 year ago
parent
commit
5e165841df
  1. 22
      src/main/java/fr/mieuxvoter/mj/DefaultGradeTally.java
  2. 2
      src/main/java/fr/mieuxvoter/mj/MedianDefaultTally.java
  3. 2
      src/main/java/fr/mieuxvoter/mj/TallyWithDefaultGrade.java
  4. 16
      src/test/java/fr/mieuxvoter/mj/MajorityJudgmentDeliberatorTest.java
  5. 45
      src/test/resources/assertions.json

22
src/main/java/fr/mieuxvoter/mj/DefaultGradeTally.java

@ -8,6 +8,13 @@ import java.math.BigInteger;
*/
abstract public class DefaultGradeTally extends Tally implements TallyInterface {
/**
* Override this to choose the default grade for a given proposal.
*/
abstract protected Integer getDefaultGradeForProposal(ProposalTallyInterface proposalTally);
// <domi41> /me is confused with why we need constructors in an abstract class?
public DefaultGradeTally(TallyInterface tally) {
super(tally.getProposalsTallies(), tally.getAmountOfJudges());
}
@ -15,11 +22,11 @@ abstract public class DefaultGradeTally extends Tally implements TallyInterface
public DefaultGradeTally(ProposalTallyInterface[] proposalsTallies, Integer amountOfJudges) {
super(proposalsTallies, amountOfJudges);
}
public DefaultGradeTally(ProposalTallyInterface[] proposalsTallies, Long amountOfJudges) {
super(proposalsTallies, amountOfJudges);
}
public DefaultGradeTally(ProposalTallyInterface[] proposalsTallies, BigInteger amountOfJudges) {
super(proposalsTallies, amountOfJudges);
}
@ -27,18 +34,17 @@ abstract public class DefaultGradeTally extends Tally implements TallyInterface
protected void fillWithDefaultGrade() {
int amountOfProposals = getAmountOfProposals();
for (int i = 0 ; i < amountOfProposals ; i++) {
ProposalTallyInterface proposal = getProposalsTallies()[i];
Integer defaultGrade = getDefaultGrade(proposal);
BigInteger amountOfJudgments = proposal.getAmountOfJudgments();
ProposalTallyInterface proposalTally = getProposalsTallies()[i];
Integer defaultGrade = getDefaultGradeForProposal(proposalTally);
BigInteger amountOfJudgments = proposalTally.getAmountOfJudgments();
BigInteger missingAmount = this.amountOfJudges.subtract(amountOfJudgments);
int missingSign = missingAmount.compareTo(BigInteger.ZERO);
assert(0 <= missingSign); // ERROR: More judgments than judges!
if (0 < missingSign) {
proposal.getTally()[defaultGrade] = proposal.getTally()[defaultGrade].add(missingAmount);
BigInteger[] rawTally = proposalTally.getTally();
rawTally[defaultGrade] = rawTally[defaultGrade].add(missingAmount);
}
}
}
abstract protected Integer getDefaultGrade(ProposalTallyInterface proposalTally);
}

2
src/main/java/fr/mieuxvoter/mj/MedianDefaultTally.java

@ -30,7 +30,7 @@ public class MedianDefaultTally extends DefaultGradeTally implements TallyInterf
}
@Override
protected Integer getDefaultGrade(ProposalTallyInterface proposalTally) {
protected Integer getDefaultGradeForProposal(ProposalTallyInterface proposalTally) {
ProposalTallyAnalysis analysis = new ProposalTallyAnalysis(proposalTally);
return analysis.getMedianGrade();
}

2
src/main/java/fr/mieuxvoter/mj/TallyWithDefaultGrade.java

@ -43,7 +43,7 @@ public class TallyWithDefaultGrade extends DefaultGradeTally implements TallyInt
}
@Override
protected Integer getDefaultGrade(ProposalTallyInterface proposalTally) {
protected Integer getDefaultGradeForProposal(ProposalTallyInterface proposalTally) {
return this.defaultGrade;
}

16
src/test/java/fr/mieuxvoter/mj/MajorityJudgmentDeliberatorTest.java

@ -20,6 +20,9 @@ class MajorityJudgmentDeliberatorTest {
@ParameterizedTest(name="#{index} {0}")
@JsonFileSource(resources = "/assertions.json")
public void testFromJson(JsonObject datum) {
// This test uses the JSON file in test/resources/
// It also allows testing the various modes of default grades.
JsonArray jsonTallies = datum.getJsonArray("tallies");
int amountOfProposals = jsonTallies.size();
BigInteger amountOfParticipants = new BigInteger(datum.get("participants").toString());
@ -39,6 +42,8 @@ class MajorityJudgmentDeliberatorTest {
TallyInterface tally;
if ("StaticDefault".equalsIgnoreCase(mode)) {
tally = new TallyWithDefaultGrade(tallies, amountOfParticipants, datum.getInt("default"));
} else if ("MedianDefault".equalsIgnoreCase(mode)) {
tally = new MedianDefaultTally(tallies, amountOfParticipants);
} else if ("Normalized".equalsIgnoreCase(mode)) {
tally = new NormalizedTally(tallies);
} else {
@ -287,9 +292,6 @@ class MajorityJudgmentDeliberatorTest {
// We're using primes to test the upper bounds of our LCM shenanigans.
// This test takes a long time! (3 seconds)
// List<Integer> generatedPrimes = sieveOfEratosthenes(15000);
// System.out.println(generatedPrimes);
int amountOfProposals = primes.length; // 1437
DeliberatorInterface mj = new MajorityJudgmentDeliberator();
ProposalTallyInterface[] tallies = new ProposalTallyInterface[amountOfProposals];
@ -306,7 +308,7 @@ class MajorityJudgmentDeliberatorTest {
assertEquals(amountOfProposals, result.getProposalResults().length);
for (int i = 0 ; i < amountOfProposals ; i++) {
assertEquals(
1 + (i % primes.length), result.getProposalResults()[i].getRank(),
1 + i, result.getProposalResults()[i].getRank(),
"Rank of Proposal #" + i
);
}
@ -316,7 +318,7 @@ class MajorityJudgmentDeliberatorTest {
@DisplayName("Test normalized tallies with thousands of proposals")
public void testNormalizedWithThousandsOfProposals() {
// This test is faster than the primes one (0.4 seconds),
// since primes are the worst case-scenario for our LCM.
// since primes are the worst-case scenario for our LCM.
int amountOfProposals = primes.length; // 1437
DeliberatorInterface mj = new MajorityJudgmentDeliberator();
@ -333,12 +335,14 @@ class MajorityJudgmentDeliberatorTest {
assertEquals(amountOfProposals, result.getProposalResults().length);
for (int i = 0 ; i < amountOfProposals ; i++) {
assertEquals(
1 + (i % primes.length), result.getProposalResults()[i].getRank(),
1 + i, result.getProposalResults()[i].getRank(),
"Rank of Proposal #" + i
);
}
}
//
// @Test
// public void runBenchmarks() throws Exception {
// Options options = new OptionsBuilder()

45
src/test/resources/assertions.json

@ -4,11 +4,11 @@
"title": "Few participants",
"participants": 3,
"tallies": [
[1, 1, 1],
[1, 0, 2],
[3, 0, 0],
[2, 0, 1],
[0, 3, 0]
[ 1, 1, 1 ],
[ 1, 0, 2 ],
[ 3, 0, 0 ],
[ 2, 0, 1 ],
[ 0, 3, 0 ]
],
"ranks": [
3,
@ -22,9 +22,9 @@
"title": "Thousands of participants",
"participants": 37000,
"tallies": [
[11142, 6970, 4040, 1968, 9888, 2992],
[10141, 8971, 4043, 1965, 8884, 2996],
[14141, 8971, 1043, 1965, 7884, 2996]
[ 11142, 6970, 4040, 1968, 9888, 2992 ],
[ 10141, 8971, 4043, 1965, 8884, 2996 ],
[ 14141, 8971, 1043, 1965, 7884, 2996 ]
],
"ranks": [
1,
@ -36,11 +36,11 @@
"title": "Millions of participants",
"participants": 72327456,
"tallies": [
[5272679, 19797001, 10732688, 9612936, 1379840, 16886281, 8646031],
[16354546, 11690342, 9451800, 14245973, 817593, 12461162, 7306040],
[9849171, 17970690, 14276861, 4606692, 16404594, 6760147, 2459301],
[2645563, 12907474, 1278331, 22843261, 8025412, 8964952, 15662463],
[16293252, 12277630, 38348, 14929905, 11087753, 10634266, 7066302]
[ 5272679, 19797001, 10732688, 9612936, 1379840, 16886281, 8646031 ],
[ 16354546, 11690342, 9451800, 14245973, 817593, 12461162, 7306040 ],
[ 9849171, 17970690, 14276861, 4606692, 16404594, 6760147, 2459301 ],
[ 2645563, 12907474, 1278331, 22843261, 8025412, 8964952, 15662463 ],
[ 16293252, 12277630, 38348, 14929905, 11087753, 10634266, 7066302 ]
],
"ranks": [
3,
@ -90,6 +90,25 @@
2
]
},
{
"title": "Median Default Grade",
"participants": 10,
"mode": "MedianDefault",
"tallies": [
[ 2, 2, 2, 2, 2 ],
[ 2, 2, 1, 2, 2 ],
[ 0, 0, 4, 0, 0 ],
[ 0, 0, 0, 0, 2 ],
[ 0, 0, 0, 1, 1 ]
],
"ranks": [
4,
4,
3,
1,
2
]
},
{
"title": "Normalization",
"participants": 10,

Loading…
Cancel
Save