Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

206 various small improvements to reports #222

Merged
merged 6 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions client/src/component/AuditReportForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ const REPORT_TYPES: ReportType[] = [
{key:'contest_selection', label:'Contest selection'},
{key:'contests_by_county', label:'Contests by county'},
{key:'seed', label:'Seed'},
{key:'tabulate', label:'Tabulate'},
{key:'tabulate_county', label:'Tabulate county'},
{key:'tabulate_plurality', label:'Tabulate'},
{key:'tabulate_county_plurality', label:'Tabulate county'},
{key:'upload_status', label:'Upload status'},
{key:'ResultReport', label:'Result Report'},
{key:'ActivityReport', label:'Activity Report'},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public static List<String> getSqlFolderFiles() {
final String folder = "sql";
final String[] fileNames = {"batch_count_comparison.sql", "contest.sql",
"contest_comparison.sql", "contest_selection.sql", "contests_by_county.sql",
"tabulate.sql", "tabulate_county.sql", "upload_status.sql", "seed.sql",
"tabulate_plurality.sql", "tabulate_county_plurality.sql", "upload_status.sql", "seed.sql",
"summarize_IRV.sql", "ranked_ballot_interpretation.sql"};
for (final String f : fileNames) {
paths.add(String.format("%s/%s", folder, f));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ public Workbook generateExcelWorkbook() {

max_cell_number = Math.max(max_cell_number, cell_number);
row_number = row_number - 1; // don't skip a line for the first contest
// Print the county contest results. These do not need IRV summaries.
for (final CountyContestResult ccr : my_driving_contest_results) {

StateReport.CellStatus status = StateReport.makeContestSummary(row_number, max_cell_number, ccr, summary_sheet,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ public Workbook generateExcelWorkbook() {

// County-level results really don't make sense for IRV. Therefore print a
// very brief summary and a reference to the assertions csv.
// At this stage, we don't want to print IRV choices.
for (final CountyContestResult ccr : e.getValue().drivingContestResults()) {

final CellStatus status = makeContestSummary(row_number, max_cell_number, ccr, summary_sheet,
Expand Down Expand Up @@ -684,15 +685,15 @@ public Workbook generateExcelWorkbook() {

/**
* Make the cells for one contest's worth of summary data. For IRV, this just prints the
* contest name, choices, and the fact that it's IRV. For plurality, it outputs much more
* detailed data.
* @param row_number Number of the current row, which is incremented as we progress and
* included in Cell Status on return.
* @param max_cell_number The maximum cell number used, which is included in Cell Status on return.
* @param ccr The County Contest Result to be summarized.
* @param summary_sheet The sheet to be added to.
* @param bold_style All these styles are included (though they could be class-level finals)
* in case a caller from another class wants different styles.
* contest name, the fact that it's IRV, and a message about where to find more information.
* For plurality, it outputs much more detailed data.
* @param row_number Number of the current row, which is incremented as we progress and
* included in Cell Status on return.
* @param max_cell_number The maximum cell number used, which is included in Cell Status on return.
* @param ccr The County Contest Result to be summarized.
* @param summary_sheet The sheet to be added to.
* @param bold_style All these styles are included (though they could be class-level finals)
* in case a caller from another class wants different styles.
* @param integer_style "
* @param bold_right_style "
* @param decimal_style "
Expand All @@ -704,52 +705,50 @@ public Workbook generateExcelWorkbook() {
protected static CellStatus makeContestSummary(int row_number, int max_cell_number, final CountyContestResult ccr,
final Sheet summary_sheet, final CellStyle bold_style, final CellStyle integer_style, final CellStyle bold_right_style,
final CellStyle decimal_style, final CellStyle standard_style, final CellStyle standard_right_style) {
row_number++;
Row row = summary_sheet.createRow(row_number++);
int cell_number = 0;
row_number++;
Row row = summary_sheet.createRow(row_number++);
int cell_number = 0;

Cell cell = row.createCell(cell_number++);
cell.setCellStyle(bold_style);
Cell cell = row.createCell(cell_number++);
cell.setCellStyle(bold_style);

final boolean isIRV = ccr.contest().description().equals(ContestType.IRV.toString());
final boolean isIRV = ccr.contest().description().equals(ContestType.IRV.toString());

if (isIRV) {
cell.setCellValue(ccr.contest().name() + " - IRV");
} else {
cell.setCellValue(ccr.contest().name() + " - Vote For " + ccr.contest().votesAllowed());
}
// Print the contest name, with a summary message about the contest type
final String contestname = ccr.contest().name() + (isIRV ? " - IRV" : " - Vote For " + ccr.contest().votesAllowed());
cell.setCellValue(contestname);

// Keep the choices column, for both IRV and plurality.
if (isIRV) {
// If it's IRV, the summary data is in the assertions csv. Add a message, that's all.
cell = row.createCell(cell_number++);
cell.setCellStyle(standard_style);
cell.setCellValue("See assertions csv");
} else {
// Plurality.
// Data headers - choices, winners, vote tallies, margins.
cell = row.createCell(cell_number++);
cell.setCellStyle(bold_style);
cell.setCellValue("Choice");

if (isIRV) {
// If it's IRV, the summary data is in the assertions csv. Add a message.
cell = row.createCell(cell_number++);
cell.setCellStyle(standard_style);
cell.setCellValue("See assertions csv");
} else {
// Plurality. Print the other data - winners, vote tallies, margins.
cell = row.createCell(cell_number++);
cell.setCellStyle(bold_right_style);
cell.setCellValue("W/L");
cell = row.createCell(cell_number++);
cell.setCellStyle(bold_right_style);
cell.setCellValue("W/L");

cell = row.createCell(cell_number++);
cell.setCellStyle(bold_right_style);
cell.setCellValue("Votes");
cell = row.createCell(cell_number++);
cell.setCellStyle(bold_right_style);
cell.setCellValue("Votes");

cell = row.createCell(cell_number++);
cell.setCellStyle(bold_right_style);
cell.setCellValue("Margin");
cell = row.createCell(cell_number++);
cell.setCellStyle(bold_right_style);
cell.setCellValue("Margin");

cell = row.createCell(cell_number++);
cell.setCellStyle(bold_right_style);
cell.setCellValue("Diluted Margin %");
}
cell = row.createCell(cell_number++);
cell.setCellStyle(bold_right_style);
cell.setCellValue("Diluted Margin %");

// Now print the actual data.
for (final String choice : ccr.rankedChoices()) {
// List all the choices, for both IRV and plurality.
// List all the choices.
row = summary_sheet.createRow(row_number++);
max_cell_number = Math.max(max_cell_number, cell_number);

Expand All @@ -758,40 +757,39 @@ protected static CellStatus makeContestSummary(int row_number, int max_cell_numb
cell.setCellStyle(standard_style);
cell.setCellValue(choice);

if (!isIRV) {
// Print the other data - winners, vote tallies, margins - only for plurality, not IRV.
cell = row.createCell(cell_number++);
cell.setCellStyle(standard_right_style);
if ((ccr.winners().stream().anyMatch(w -> w.equalsIgnoreCase(choice)))) {
cell.setCellValue("W");
} else {
cell.setCellValue("L");
}
// Winners, vote tallies, margins.
cell = row.createCell(cell_number++);
cell.setCellStyle(standard_right_style);
if ((ccr.winners().stream().anyMatch(w -> w.equalsIgnoreCase(choice)))) {
cell.setCellValue("W");
} else {
cell.setCellValue("L");
}

cell = row.createCell(cell_number++);
cell.setCellStyle(integer_style);
cell.setCellType(CellType.NUMERIC);
cell.setCellValue(ccr.voteTotals().get(choice));

if (ccr.winners().contains(choice)) {
cell = row.createCell(cell_number++);
cell.setCellStyle(integer_style);
cell.setCellType(CellType.NUMERIC);
cell.setCellValue(ccr.voteTotals().get(choice));

if (ccr.winners().contains(choice)) {
cell = row.createCell(cell_number++);
cell.setCellStyle(integer_style);
cell.setCellType(CellType.NUMERIC);
final OptionalInt margin = ccr.marginToNearestLoser(choice);
if (margin.isPresent()) {
cell.setCellValue(margin.getAsInt());
}
final OptionalInt margin = ccr.marginToNearestLoser(choice);
if (margin.isPresent()) {
cell.setCellValue(margin.getAsInt());
}

cell = row.createCell(cell_number++);
cell.setCellStyle(decimal_style);
cell.setCellType(CellType.NUMERIC);
final BigDecimal diluted_margin = ccr.countyDilutedMarginToNearestLoser(choice);
if (diluted_margin != null) {
cell.setCellValue(diluted_margin.doubleValue() * 100);
}
cell = row.createCell(cell_number++);
cell.setCellStyle(decimal_style);
cell.setCellType(CellType.NUMERIC);
final BigDecimal diluted_margin = ccr.countyDilutedMarginToNearestLoser(choice);
if (diluted_margin != null) {
cell.setCellValue(diluted_margin.doubleValue() * 100);
}
}
}
}
return new CellStatus(row_number, max_cell_number);
}

Expand Down
26 changes: 24 additions & 2 deletions server/eclipse-project/src/main/resources/sql/summarize_IRV.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
-- Show the IRV summaries, sorted by contest name.
-- This is usually a (unique) winner and an empty error, but may also be a
-- blank winner and a non-empty error with an explanatory message.
-- This also adds a column to indicate whether the contest was targeted for audit. This requires
-- a join with the contest_to_audit table, which is slightly complicated by the fact that that table
-- stores _one of_ the contest ids for multi-county contests, so we have to check whether there is
-- _any_ contest of the same name with an ID in the contest_to_audit table. This simply selects the
-- first audit reason, in the very unlikely event that one contest is selected for both COUNTY_WIDE
-- and STATE_WIDE reasons.

SELECT gas.contest_name, gas.winner, gas.error, gas.message
SELECT gas.contest_name, COALESCE(targets.targeted_reason, 'Not targeted') as target_reason, gas.winner, gas.error, gas.message
FROM generate_assertions_summary as gas
ORDER BY contest_name;
-- This sub-query attaches audit target reasons (aggregated), if any, to contest names, and
-- 'Not targeted' otherwise.
-- Inner join because we only want the ones in the generate_assertions_summary table.
LEFT JOIN (
SELECT contest.name as name, contest_to_audit.reason as targeted_reason
FROM contest_to_audit
-- Again an inner join, because we only want the ones in the table of targeted contests.
-- This will give us the one row of the contest table that happens to have been identified in the
-- contest_to_audit table
INNER JOIN contest
ON contest_to_audit.contest_id = contest.id
) AS targets
ON gas.contest_name = targets.name;




Loading