Skip to content

Instantly share code, notes, and snippets.

@igorlg
Created May 11, 2016 02:53
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save igorlg/cc0e9cb14b8a25306d202c7091c734d0 to your computer and use it in GitHub Desktop.
Save igorlg/cc0e9cb14b8a25306d202c7091c734d0 to your computer and use it in GitHub Desktop.
YNAB Export Parser - Parse CSV Files exported from YNAB and add extra fields
import csv, sys
from datetime import date,datetime
def parse_budget(csvarr):
if '$' not in csvarr[4]:
return False
dt = datetime.strptime(csvarr[0], '%b %Y')
month = dt.month
year = dt.year
budgeted = float(csvarr[4].replace('$', ''))
activity = float(csvarr[5].replace('$', ''))
available = float(csvarr[6].replace('$', ''))
status = 'OK' if available >= 0 else 'Overspent'
output = {
'date': dt.date(),
'month': month,
'month_year': "%d/%d" % (month, year),
'month_word': dt.strftime('%B'),
'year': year,
'group': csvarr[2],
'category': csvarr[3],
'group_category': "%s/%s" % (csvarr[2], csvarr[3]),
'budgeted': budgeted,
'activity': activity,
'available': available,
'status': status
}
return output
csvreader = csv.reader(sys.stdin, delimiter=',')
csvwriter = csv.writer(sys.stdout, csv.QUOTE_NONNUMERIC)
csvreader.next()
parsed = parse_budget(csvreader.next())
csvwriter.writerow(parsed.keys())
csvwriter.writerow(parsed.values())
for i in csvreader:
parsed = parse_budget(i)
if not parsed:
continue
csvwriter.writerow(parsed.values())
import csv, sys
from datetime import date,datetime
def parse_register(csvarr):
if not csvarr[8].startswith('$'):
return False
dtarr = csvarr[2].split('/')
day = int(dtarr[0])
month = int(dtarr[1])
year = int(dtarr[2])
dt = date(year, month, day)
outflow = float(csvarr[8].replace('$', ''))
inflow = float(csvarr[9].replace('$', ''))
balance = inflow - outflow
cleared = True if csvarr[10]=='Reconciled' else False
if csvarr[3].startswith('Transfer : '):
reg_type='Transfer'
elif outflow>0:
reg_type='Expense'
else:
reg_type='Income'
output = {
'account': csvarr[0],
'flag': csvarr[1],
'date': dt,
'day': day,
'month': month,
'year': year,
'month_year': "%d/%d" % (month, year),
'month_word': dt.strftime('%B'),
'payee': csvarr[3],
'group': csvarr[5],
'category': csvarr[6],
'group_category': "%s/%s" % (csvarr[5], csvarr[6]),
'memo': csvarr[7],
'outflow': outflow,
'inflow': inflow,
'balance': balance,
'cleared': cleared,
'type': reg_type
}
return output
csvreader = csv.reader(sys.stdin, delimiter=',')
csvwriter = csv.writer(sys.stdout, csv.QUOTE_NONNUMERIC)
csvreader.next()
parsed = parse_register(csvreader.next())
csvwriter.writerow(parsed.keys())
csvwriter.writerow(parsed.values())
for i in csvreader:
parsed = parse_register(i)
if not parsed:
continue
csvwriter.writerow(parsed.values())
@igorlg
Copy link
Author

igorlg commented May 11, 2016

YNAB Export Parser

#1. Why?

I created this very simple Python scripts to parse my CSV Exports from YNAB (You Need a Budget), add a couple of calculated fields, sanitize numeric values and output as CSV again (to be imported on Excel/Google Docs).
Pretty much the only reason to do that is that I'm a bit of a data freak and like to keep track of/report on my expenses. This is whyle YNAB doesn't add a Reporting Feature (much overdue).

More information on YNAB: https://youneedabudget.com
#2. Usage

No extra libraries are necessary. Input is read from STDIN and output sent to STDOUT. Just use the < and > operators like this:

$ python parse_register.py < ynab_register_export.csv > parsed_register_export.csv
$ python parse_budget.py < ynab_budget_export.csv > parsed_budget_export.csv

Any and all feedback is welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment