Last active
January 5, 2018 03:18
-
-
Save Deconstrained/3eb0409290fb251ec11d35f5b0474098 to your computer and use it in GitHub Desktop.
Script to parse Clipper activity logs and calculate sums
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
@author Demitri Morgan <[email protected]> | |
Takes the ugly, poorly-formatted text output from Clipper's web portal... | |
https://www.clippercard.com/ClipperCard/dashboard.jsf | |
...and prints it to stdout in three columns: time, credit and debit. | |
Totals printed to stderr (in case you want to pipe to awk and do other things). | |
The way it's expected to work: | |
1. Copy and paste the table of Clipper Card activity into a text file | |
2. Pass the file as the sole argument to this script. | |
I wrote this as a stopgap for record keeping and metrics until Clipper improves | |
their website with some kind of CSV export, or if they're really nice, an API. | |
""" | |
import argparse | |
import re | |
import sys | |
datestamp = re.compile( | |
r'^(\d{2}\/\d{2}\/\d{4})', | |
flags=re.MULTILINE | |
) | |
currency_amount = re.compile( | |
r'^\d+\.\d{2}$' | |
) | |
def main(): | |
ap = argparse.ArgumentParser("Reads screwy input copied from Clipper's tra"\ | |
"sactions dashboard and translates it to cleanly-formatted data.") | |
ap.add_argument("in_file", type=argparse.FileType('r')) | |
args = ap.parse_args() | |
fh = args.in_file | |
file_contents = fh.read() | |
fh.close() | |
credit = 0. | |
debit = 0. | |
with_linebreaks = datestamp.sub(r'\n\1', file_contents) | |
for l in with_linebreaks.split('\n\n'): | |
entries = l.strip().split('\n') | |
datetime = entries[0] | |
if len(entries) < 5: | |
continue # Malformed entry | |
balance = entries.pop() | |
if currency_amount.match(entries[-1]) is None: | |
continue # A no-fare entrance (charged fare upon exit) | |
if 're-load' in entries[1]: | |
transaction = (datetime, entries[-1], '0.00') | |
else: | |
transaction = (datetime, '0.00', entries[-1]) | |
credit += float(transaction[1]) | |
debit += float(transaction[2]) | |
print('{0}\t{1}\t{2}'.format(*transaction)) | |
print(" Total fare: %.2f"%debit, file=sys.stderr) | |
print(" Total deposits: %.2f"%credit, file=sys.stderr) | |
if __name__=='__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment