Browse Source

feat: add a CollectedTally to ease collection of judgments

feat-normalized-lcm
Dominique Merle 1 year ago
parent
commit
7ae56b56cc
  1. 47
      README.md
  2. 72
      src/main/java/fr/mieuxvoter/mj/CollectedTally.java
  3. 3
      src/main/java/fr/mieuxvoter/mj/Tally.java
  4. 54
      src/test/java/fr/mieuxvoter/mj/MajorityJudgmentDeliberatorTest.java

47
README.md

@ -90,6 +90,53 @@ TallyInterface tally = new TallyNormalized(new ProposalTallyInterface[] {
> This normalization uses the Least Common Multiple, in order to skip floating-point arithmetic.
### Collect a Tally from judgments
It's usually best to use structured queries (eg: in SQL) directly in your database to collect the tallies, since it scales better with high amounts of participants, but if you must you can collect the tally directly from individual judgments, with a `CollectedTally`.
```java
Integer amountOfProposals = 3;
Integer amountOfGrades = 4;
DeliberatorInterface mj = new MajorityJudgmentDeliberator();
CollectedTally tally = new CollectedTally(amountOfProposals, amountOfGrades);
Integer firstProposal = 0;
Integer secondProposal = 1;
Integer thirdProposal = 2;
Integer gradeReject = 0;
Integer gradePassable = 1;
Integer gradeGood = 2;
Integer gradeExcellent = 3;
// Collect the judgments one-by-one with `collect()`, for example:
tally.collect(firstProposal, gradeReject);
tally.collect(firstProposal, gradeReject);
tally.collect(firstProposal, gradePassable);
tally.collect(firstProposal, gradePassable);
tally.collect(firstProposal, gradePassable);
tally.collect(firstProposal, gradeExcellent);
tally.collect(firstProposal, gradeExcellent);
tally.collect(secondProposal, gradeReject);
tally.collect(secondProposal, gradeReject);
tally.collect(secondProposal, gradeGood);
tally.collect(secondProposal, gradeGood);
tally.collect(secondProposal, gradeGood);
tally.collect(secondProposal, gradeExcellent);
tally.collect(secondProposal, gradeExcellent);
tally.collect(thirdProposal, gradeReject);
tally.collect(thirdProposal, gradePassable);
tally.collect(thirdProposal, gradeGood);
tally.collect(thirdProposal, gradeGood);
tally.collect(thirdProposal, gradeGood);
tally.collect(thirdProposal, gradeExcellent);
tally.collect(thirdProposal, gradeExcellent);
ResultInterface result = mj.deliberate(tally);
```
## Roadmap
- [x] Unit-Tests

72
src/main/java/fr/mieuxvoter/mj/CollectedTally.java

@ -0,0 +1,72 @@
package fr.mieuxvoter.mj;
import java.math.BigInteger;
public class CollectedTally implements TallyInterface {
Integer amountOfProposals = 0;
Integer amountOfGrades = 0;
ProposalTally[] proposalsTallies;
public CollectedTally(Integer amountOfProposals, Integer amountOfGrades) {
setAmountOfProposals(amountOfProposals);
setAmountOfGrades(amountOfGrades);
proposalsTallies = new ProposalTally[amountOfProposals];
for (int i = 0; i < amountOfProposals; i++) {
ProposalTally proposalTally = new ProposalTally();
Integer[] tally = new Integer[amountOfGrades];
for (int j = 0; j < amountOfGrades; j++) {
tally[j] = 0;
}
proposalTally.setTally(tally);
proposalsTallies[i] = proposalTally;
}
}
@Override
public ProposalTallyInterface[] getProposalsTallies() {
return proposalsTallies;
}
@Override
public BigInteger getAmountOfJudges() {
return guessAmountOfJudges();
}
@Override
public Integer getAmountOfProposals() {
return this.amountOfProposals;
}
public void setAmountOfProposals(Integer amountOfProposals) {
this.amountOfProposals = amountOfProposals;
}
public Integer getAmountOfGrades() {
return amountOfGrades;
}
public void setAmountOfGrades(Integer amountOfGrades) {
this.amountOfGrades = amountOfGrades;
}
protected BigInteger guessAmountOfJudges() {
BigInteger amountOfJudges = BigInteger.ZERO;
for (ProposalTallyInterface proposalTally : getProposalsTallies()) {
amountOfJudges = proposalTally.getAmountOfJudgments().max(amountOfJudges);
}
return amountOfJudges;
}
public void collect(Integer proposal, Integer grade) {
assert(0 <= proposal);
assert(amountOfProposals > proposal);
assert(0 <= grade);
assert(amountOfGrades > grade);
BigInteger[] tally = proposalsTallies[proposal].getTally();
tally[grade] = tally[grade].add(BigInteger.ONE);
}
}

3
src/main/java/fr/mieuxvoter/mj/Tally.java

@ -2,6 +2,9 @@ package fr.mieuxvoter.mj;
import java.math.BigInteger;
/**
* A Basic implementation of a TallyInterface that reads from an array of ProposalTallyInterface.
*/
public class Tally implements TallyInterface {
protected ProposalTallyInterface[] proposalsTallies;

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

@ -94,13 +94,65 @@ class MajorityJudgmentDeliberatorTest {
}
}
@Test
public void testDemoUsageCollectedTally() {
Integer amountOfProposals = 3;
Integer amountOfGrades = 4;
DeliberatorInterface mj = new MajorityJudgmentDeliberator();
CollectedTally tally = new CollectedTally(amountOfProposals, amountOfGrades);
Integer firstProposal = 0;
Integer secondProposal = 1;
Integer thirdProposal = 2;
Integer gradeReject = 0;
Integer gradePassable = 1;
Integer gradeGood = 2;
Integer gradeExcellent = 3;
tally.collect(firstProposal, gradeReject);
tally.collect(firstProposal, gradeReject);
tally.collect(firstProposal, gradePassable);
tally.collect(firstProposal, gradePassable);
tally.collect(firstProposal, gradePassable);
tally.collect(firstProposal, gradeExcellent);
tally.collect(firstProposal, gradeExcellent);
tally.collect(firstProposal, gradeExcellent);
tally.collect(secondProposal, gradeReject);
tally.collect(secondProposal, gradeReject);
tally.collect(secondProposal, gradeGood);
tally.collect(secondProposal, gradeGood);
tally.collect(secondProposal, gradeGood);
tally.collect(secondProposal, gradeGood);
tally.collect(secondProposal, gradeExcellent);
tally.collect(secondProposal, gradeExcellent);
tally.collect(thirdProposal, gradeReject);
tally.collect(thirdProposal, gradeReject);
tally.collect(thirdProposal, gradePassable);
tally.collect(thirdProposal, gradeGood);
tally.collect(thirdProposal, gradeGood);
tally.collect(thirdProposal, gradeGood);
tally.collect(thirdProposal, gradeExcellent);
tally.collect(thirdProposal, gradeExcellent);
ResultInterface result = mj.deliberate(tally);
assertNotNull(result);
assertEquals(3, result.getProposalResults().length);
assertEquals(3, result.getProposalResults()[0].getRank());
assertEquals(1, result.getProposalResults()[1].getRank());
assertEquals(2, result.getProposalResults()[2].getRank());
}
@Test
public void testWithStaticDefaultGrade() {
DeliberatorInterface mj = new MajorityJudgmentDeliberator();
Integer defaultGrade = 0;
TallyInterface tally = new TallyWithDefaultGrade(new ProposalTallyInterface[] {
new ProposalTally(new Integer[]{ 0, 0, 1 }),
new ProposalTally(new Integer[]{ 0, 3, 0 }),
}, 3L, 0);
}, 3L, defaultGrade);
ResultInterface result = mj.deliberate(tally);

Loading…
Cancel
Save