Skip to content

Commit

Permalink
Merge pull request #157 from DemocracyDevelopers/100-persist-irvballo…
Browse files Browse the repository at this point in the history
…tinterpretation

Comment improvements based on @michelleblom's review.
  • Loading branch information
vteague authored Jul 30, 2024
2 parents 809285b + 19fc26e commit fab2f1c
Show file tree
Hide file tree
Showing 9 changed files with 320 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ public class GenerateAssertionsSummary {
* Name of the contest.
*/
@Column(name = "contest_name", unique = true, updatable = false, nullable = false)
public String contestName;
private String contestName;

/**
* Name of the winner of the contest, as determined by raire-java.
*/
@Column(name = "winner", updatable = false, nullable = false)
public String winner;
private String winner;

/**
* An error (matching one of the RaireServiceErrors.RaireErrorCodes), if there was one. Errors
Expand All @@ -78,25 +78,53 @@ public class GenerateAssertionsSummary {
* continue.
*/
@Column(name = "error", updatable = false, nullable = false)
public String error;
private String error;

/**
* A warning, if there was one, or emptystring if none. Warnings (e.g. TIME_OUT_TRIMMING_ASSERTIONS)
* mean that assertion generation succeeded and the audit can continue, but re-running with longer
* time allowed might be beneficial.
*/
@Column(name = "warning", updatable = false, nullable = false)
public String warning;
private String warning;

/**
* The message associated with the error, for example the names of the tied winners.
*/
@Column(name = "message", updatable = false, nullable = false)
public String message;
private String message;

/**
* Default no-args constructor (required for persistence).
*/
public GenerateAssertionsSummary() {
}

/**
* @return the winner.
*/
public String getWinner() {
return winner;
}

/**
* @return the error, or emptystring if there is none.
*/
public String getError() {
return error;
}

/**
* @return a warning, or emptystring if there is none.
*/
public String getWarning() {
return warning;
}

/**
* @return the message associated with the error, or emptystring if there is none.
*/
public String getMessage() {
return message;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*/
@Entity
@Table(name = "irv_ballot_interpretation")
public class IRVBallotInterpretation implements PersistentEntity, Serializable {
public class IRVBallotInterpretation implements PersistentEntity {

/**
* ID for interpretation record (for persistence).
Expand Down Expand Up @@ -87,16 +87,19 @@ public IRVBallotInterpretation() {

/**
* Create a record of an IRV vote interpretation for a given contest and a given ballot
* (identified by the CVR ID).
* (identified by the CVR ID). This works for any IRV vote, but is expected to be used only
* for invalid IRV votes.
* @param contest the Contest
* @param recordType the type, expected to be either UPLOADED, AUDITOR_ENTERED, or REAUDITED.
* @param cvrNumber the cvr Number, which appears in the csv file (not to be confused with the cvr_id, which the
* database makes).
* @param cvrNumber the cvr Number, which appears in the csv file (not to be confused with
* the cvr_id, which the database makes).
* @param imprintedId the imprinted ID, i.e. tabulator_id-batch_id-record_id.
* @param rawChoices the (invalid) raw IRV choices, e.g. [Bob(1),Alice(3),Chuan(4)].
* @param orderedChoices the way colorado-rla interpreted the raw choices, as an order list of names.
*/
public IRVBallotInterpretation(Contest contest, CastVoteRecord.RecordType recordType, int cvrNumber, String imprintedId, List<String> rawChoices, List<String> orderedChoices) {
public IRVBallotInterpretation(final Contest contest, final CastVoteRecord.RecordType recordType,
int cvrNumber, final String imprintedId, final List<String> rawChoices,
final List<String> orderedChoices) {
this.contest = contest;
this.recordType = recordType;
this.cvrNumber = cvrNumber;
Expand All @@ -106,10 +109,10 @@ public IRVBallotInterpretation(Contest contest, CastVoteRecord.RecordType record
}

/**
* Output contents as a String appropriate for a log message.
* Output details of the stored IRV vote interpretation as a String appropriate for a log message.
* @return the data with headers incorporated.
*/
public String logMessage(String cvrNumberHeader, String imprintedIDHeader) {
public String logMessage(final String cvrNumberHeader, final String imprintedIDHeader) {
return String.join(", ", (List.of(
"County " + contest.county().name(),
"Contest " + contest.name(),
Expand All @@ -132,7 +135,7 @@ public Long id() {
* {@inheritDoc}
*/
@Override
public void setID(Long the_id) {
public void setID(final Long the_id) {
id = the_id;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

/**
* Database queries relating to the retrieval of Assertion Generation Summaries from the
* database. It contains a method that executes a query to retrieval all GenerateAssertionsSummaries
* database. It contains a method that executes a query to retrieve all GenerateAssertionsSummaries
* belonging to a specific contest, identified by name.
* Also includes a shortcut function to get the winner, which inserts UNKNOWN_WINNER if either the
* record is absent, or the winner is blank.
Expand All @@ -54,9 +54,9 @@ public class GenerateAssertionsSummaryQueries {
* @param contestName the name of the contest.
*/
public static String matchingWinner(final String contestName) {
Optional<GenerateAssertionsSummary> optSummary = matching(contestName);
if(optSummary.isPresent() && !optSummary.get().winner.isBlank()) {
return optSummary.get().winner;
final Optional<GenerateAssertionsSummary> optSummary = matching(contestName);
if(optSummary.isPresent() && !optSummary.get().getWinner().isBlank()) {
return optSummary.get().getWinner();
} else {
return UNKNOWN_WINNER;
}
Expand All @@ -80,7 +80,7 @@ public static Optional<GenerateAssertionsSummary> matching(final String contestN
+ " where ca.contestName = :contestName", GenerateAssertionsSummary.class);
q.setParameter("contestName", contestName);

List<GenerateAssertionsSummary> result = q.getResultList();
final List<GenerateAssertionsSummary> result = q.getResultList();
LOGGER.debug(String.format("%s %d summary results retrieved for contest %s.", prefix,
result.size(), contestName));
if(result.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -670,14 +670,14 @@ private CastVoteRecord extractCVR(final CSVRecord the_line) {
// If it is IRV, convert it into an ordered list of names (without parentheses), then
// store.
final IRVChoices irvVotes = new IRVChoices(votes);
List<String> orderedChoices = irvVotes.getValidIntentAsOrderedList();
final List<String> orderedChoices = irvVotes.getValidIntentAsOrderedList();
if(!irvVotes.isValid()) {
// IRV preferences were invalid. Store a record of the raw votes for debugging/record-
// keeping purposes, but use the valid interpretation as the choices in the audit.
IRVBallotInterpretation irvInterpretation = new IRVBallotInterpretation(co,
final IRVBallotInterpretation irvInterpretation = new IRVBallotInterpretation(co,
RecordType.UPLOADED, cvr_id, imprinted_id, votes, orderedChoices);
Persistence.save(irvInterpretation);
String msg = "Interpretation of invalid IRV choices.";
final String msg = "Interpretation of invalid IRV choices.";
LOGGER.warn(String.format("%s %s %s.", prefix, msg,
irvInterpretation.logMessage(CVR_NUMBER_HEADER, IMPRINTED_ID_HEADER)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ public static BigDecimal percentage(final BigDecimal num) {
}

/**
* for each contest(per row), show all the variables that are interesting or
* For each contest (per row), show all the variables that are interesting or
* needed to perform the risk limit calculation
* This checks whether the contest is IRV and makes two modifications:
* 1. it takes the winner from the GenerateAssertionsSummary table, rather than the ComparisonAudit,
Expand Down
Loading

0 comments on commit fab2f1c

Please sign in to comment.