Skip to content

Instantly share code, notes, and snippets.

@Deconstrained
Last active January 5, 2018 03:18
Show Gist options
  • Save Deconstrained/3eb0409290fb251ec11d35f5b0474098 to your computer and use it in GitHub Desktop.
Save Deconstrained/3eb0409290fb251ec11d35f5b0474098 to your computer and use it in GitHub Desktop.
Script to parse Clipper activity logs and calculate sums
#!/usr/bin/env python3
"""
@author Demitri Morgan <demitri.morgan@gmail.com>
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