feat: expose the tally analysis in the proposal result

pull/14/head^2
Dominique Merle 3 years ago
parent bb47f355ea
commit d193ed0eca

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

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

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

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

@ -41,7 +41,7 @@ class MajorityJudgmentDeliberatorTest {
String mode = datum.getString("mode", "None"); String mode = datum.getString("mode", "None");
TallyInterface tally; TallyInterface tally;
if ("StaticDefault".equalsIgnoreCase(mode)) { 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)) { } else if ("MedianDefault".equalsIgnoreCase(mode)) {
tally = new MedianDefaultTally(tallies, amountOfParticipants); tally = new MedianDefaultTally(tallies, amountOfParticipants);
} else if ("Normalized".equalsIgnoreCase(mode)) { } else if ("Normalized".equalsIgnoreCase(mode)) {

@ -146,6 +146,23 @@
5, 5,
1 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