Browse Source

feat: expose the tally analysis in the proposal result

master
Dominique Merle 1 year ago
parent
commit
d193ed0eca
  1. 17
      src/main/java/fr/mieuxvoter/mj/MajorityJudgmentDeliberator.java
  2. 16
      src/main/java/fr/mieuxvoter/mj/ProposalResult.java
  3. 7
      src/main/java/fr/mieuxvoter/mj/ProposalResultInterface.java
  4. 42
      src/main/java/fr/mieuxvoter/mj/ProposalTallyAnalysis.java
  5. 2
      src/test/java/fr/mieuxvoter/mj/MajorityJudgmentDeliberatorTest.java
  6. 19
      src/test/resources/assertions.json

17
src/main/java/fr/mieuxvoter/mj/MajorityJudgmentDeliberator.java

@ -34,8 +34,11 @@ final public class MajorityJudgmentDeliberator implements DeliberatorInterface {
for (int proposalIndex = 0; proposalIndex < amountOfProposals; proposalIndex++) {
ProposalTallyInterface proposalTally = tallies[proposalIndex];
String score = computeScore(proposalTally, amountOfJudges);
ProposalTallyAnalysis analysis = new ProposalTallyAnalysis();
analysis.reanalyze(proposalTally);
ProposalResult proposalResult = new ProposalResult();
proposalResult.setScore(score);
proposalResult.setAnalysis(analysis);
//proposalResult.setRank(???); // rank is computed below, AFTER the score pass
proposalResults[proposalIndex] = proposalResult;
}
@ -68,7 +71,7 @@ final public class MajorityJudgmentDeliberator implements DeliberatorInterface {
result.setProposalResults(proposalResults);
return result;
}
protected String computeScore(ProposalTallyInterface tally, BigInteger amountOfJudges) {
return computeScore(tally, amountOfJudges, true, false);
}
@ -77,11 +80,11 @@ final public class MajorityJudgmentDeliberator implements DeliberatorInterface {
* A higher score means a better rank.
* Assumes that grades' tallies are provided from "worst" grade to "best" grade.
*
* @param tally Holds the tallies of each Grade for a single Proposal
* @param tally Holds the tallies of each Grade for a single Proposal
* @param amountOfJudges
* @param favorContestation
* @param onlyNumbers Do not use separation characters, match `^[0-9]+$`
* @return
* @param favorContestation Use the lower median, for example
* @param onlyNumbers Do not use separation characters, match `^[0-9]+$`
* @return the score of the proposal
*/
protected String computeScore(
ProposalTallyInterface tally,
@ -106,7 +109,7 @@ final public class MajorityJudgmentDeliberator implements DeliberatorInterface {
}
score += String.format(
"%0"+digitsForGrade+"d",
"%0" + digitsForGrade + "d",
analysis.getMedianGrade()
);
@ -115,7 +118,7 @@ final public class MajorityJudgmentDeliberator implements DeliberatorInterface {
}
score += String.format(
"%0"+digitsForGroup+"d",
"%0" + digitsForGroup + "d",
// We offset by amountOfJudges to keep a lexicographical order (no negatives)
// amountOfJudges + secondMedianGroupSize * secondMedianGroupSign
amountOfJudges.add(

16
src/main/java/fr/mieuxvoter/mj/ProposalResult.java

@ -2,11 +2,13 @@ package fr.mieuxvoter.mj;
public class ProposalResult implements ProposalResultInterface {
protected Integer rank;
protected String score;
protected ProposalTallyAnalysis analysis;
public Integer getRank() {
return rank;
}
@ -23,4 +25,12 @@ public class ProposalResult implements ProposalResultInterface {
this.score = score;
}
public ProposalTallyAnalysis getAnalysis() {
return analysis;
}
public void setAnalysis(ProposalTallyAnalysis analysis) {
this.analysis = analysis;
}
}

7
src/main/java/fr/mieuxvoter/mj/ProposalResultInterface.java

@ -7,7 +7,7 @@ public interface ProposalResultInterface {
* Rank starts at 1 ("best" proposal), and goes upwards.
* Multiple Proposals may receive the same rank,
* in the extreme case where they received the exact same judgments,
* or judgment repartition in normalized tallies.
* or the same judgment repartition in normalized tallies.
*/
public Integer getRank();
@ -19,4 +19,9 @@ public interface ProposalResultInterface {
*/
public String getScore();
/**
* Get more data about the proposal tally, such as the median grade.
*/
public ProposalTallyAnalysis getAnalysis();
}

42
src/main/java/fr/mieuxvoter/mj/ProposalTallyAnalysis.java

@ -38,7 +38,7 @@ public class ProposalTallyAnalysis {
public ProposalTallyAnalysis() {}
public ProposalTallyAnalysis(ProposalTallyInterface tally) {
reanalyze(tally);
}
@ -135,80 +135,40 @@ public class ProposalTallyAnalysis {
return totalSize;
}
public void setTotalSize(BigInteger totalSize) {
this.totalSize = totalSize;
}
public Integer getMedianGrade() {
return medianGrade;
}
public void setMedianGrade(Integer medianGrade) {
this.medianGrade = medianGrade;
}
public BigInteger getMedianGroupSize() {
return medianGroupSize;
}
public void setMedianGroupSize(BigInteger medianGroupSize) {
this.medianGroupSize = medianGroupSize;
}
public Integer getContestationGrade() {
return contestationGrade;
}
public void setContestationGrade(Integer contestationGrade) {
this.contestationGrade = contestationGrade;
}
public BigInteger getContestationGroupSize() {
return contestationGroupSize;
}
public void setContestationGroupSize(BigInteger contestationGroupSize) {
this.contestationGroupSize = contestationGroupSize;
}
public Integer getAdhesionGrade() {
return adhesionGrade;
}
public void setAdhesionGrade(Integer adhesionGrade) {
this.adhesionGrade = adhesionGrade;
}
public BigInteger getAdhesionGroupSize() {
return adhesionGroupSize;
}
public void setAdhesionGroupSize(BigInteger adhesionGroupSize) {
this.adhesionGroupSize = adhesionGroupSize;
}
public Integer getSecondMedianGrade() {
return secondMedianGrade;
}
public void setSecondMedianGrade(Integer secondMedianGrade) {
this.secondMedianGrade = secondMedianGrade;
}
public BigInteger getSecondMedianGroupSize() {
return secondMedianGroupSize;
}
public void setSecondMedianGroupSize(BigInteger secondMedianGroupSize) {
this.secondMedianGroupSize = secondMedianGroupSize;
}
public Integer getSecondMedianGroupSign() {
return secondMedianGroupSign;
}
public void setSecondMedianGroupSign(Integer sign) {
this.secondMedianGroupSign = sign;
}
}

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

@ -41,7 +41,7 @@ class MajorityJudgmentDeliberatorTest {
String mode = datum.getString("mode", "None");
TallyInterface tally;
if ("StaticDefault".equalsIgnoreCase(mode)) {
tally = new TallyWithDefaultGrade(tallies, amountOfParticipants, datum.getInt("default"));
tally = new TallyWithDefaultGrade(tallies, amountOfParticipants, datum.getInt("default", 0));
} else if ("MedianDefault".equalsIgnoreCase(mode)) {
tally = new MedianDefaultTally(tallies, amountOfParticipants);
} else if ("Normalized".equalsIgnoreCase(mode)) {

19
src/test/resources/assertions.json

@ -146,6 +146,23 @@
5,
1
]
},
{
"title": "Feedback from Paris",
"participants": 21,
"mode": "StaticDefault",
"tallies": [
[ 1, 1, 4, 3, 7, 4, 1 ],
[ 0, 2, 4, 3, 7, 4, 1 ],
[ 1, 1, 4, 3, 7, 4, 1 ],
[ 1, 0, 4, 3, 7, 4, 1 ]
],
"ranks": [
2,
1,
2,
4
]
}
]
]
Loading…
Cancel
Save