From e0f789b27f39c4db578bf2ad7227f58b8f99e9f2 Mon Sep 17 00:00:00 2001 From: Nick Kocharhook Date: Sun, 12 Mar 2017 16:06:55 +0000 Subject: [PATCH] Add a script to show progress on the state's elections. --- src/progress.py | 85 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100755 src/progress.py diff --git a/src/progress.py b/src/progress.py new file mode 100755 index 0000000..ea97f0c --- /dev/null +++ b/src/progress.py @@ -0,0 +1,85 @@ +#!/usr/local/bin/python3 +# -*- coding: utf-8 -*- + +# The MIT License (MIT) +# Copyright (c) 2017 Nick Kocharhook +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import csv +import os +import argparse +import collections +import pandas + +def main(): + args = parseArguments() + + progress = OEProgress(args.path) + progress.printProgress() + + +class OEProgress(object): + def __init__(self, path): + self.path = path + self.counts = collections.defaultdict(int) + self.weightedCounts = collections.defaultdict(int) + self.statuses = {'': 'Incomplete', 'done': 'Complete', 'n/a': 'Source missing'} + + self.populateResults() + + def populateResults(self): + self.elections = pandas.read_csv(self.path).fillna('') + + def printProgress(self): + for index, series in self.elections.iterrows(): + precinctCount = series['precinct count'] + gb = series.groupby(series[2:]) + + for group, values in gb: + self.counts[group] += len(values.index) + self.weightedCounts[group] += len(values.index) * precinctCount + + electionCount = sum(self.counts.values()) + print(f"By election:") + + for status, count in self.counts.items(): + print("{:>15} {:>5} {:>6.1%}".format(self.statuses[status], count, count/electionCount)) + + print("{:>15} {:>5}".format("Total", electionCount)) + + print("\nBy precinct:") + precinctCount = sum(self.weightedCounts.values()) + for status, count in self.weightedCounts.items(): + print("{:>15} {:>5} {:>6.1%}".format(self.statuses[status], count, count/precinctCount)) + + print("{:>15} {:>5}".format("Total", precinctCount)) + +def parseArguments(): + parser = argparse.ArgumentParser(description='Verify votes are correct using a simple checksum') + # parser.add_argument('--verbose', '-v', dest='verbose', action='store_true') + parser.add_argument('path', type=str, help='Path to county_matrix CSV file.') + parser.set_defaults(verbose=False) + + return parser.parse_args() + + +# Default function is main() +if __name__ == '__main__': + main() \ No newline at end of file