Skip to content

Instantly share code, notes, and snippets.

@velppa
Created August 5, 2014 06:15
Show Gist options
  • Save velppa/af0ec7287e4bf425dee5 to your computer and use it in GitHub Desktop.
Save velppa/af0ec7287e4bf425dee5 to your computer and use it in GitHub Desktop.
IPython notebook to compare multiple period in Ledger
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "",
"signature": "sha256:2622df70552f1370f54530d29ec61bd9978b4ed67289653cf4aebd958738ac55"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 Ledger\n",
"\n",
"\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0436\u0443\u0440\u043d\u0430\u043b `drewr.dat` \u0441 \u0441\u0430\u0439\u0442\u0430 [ledger](http://www.ledger-cli.org/3.0/doc/ledger3.html#Example-Journal-File)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"!echo $LEDGER_DIR\n",
"JOURNAL = '$LEDGER_DIR/drewr.dat'"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"/Users/rbd/Dropbox/Documents/Notes\r\n"
]
}
],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##\u0422\u0435\u043a\u0443\u0449\u0438\u0435 \u043e\u0441\u0442\u0430\u0442\u043a\u0438"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"balance_cmd = \"ledger -f {journal} balance Assets Liabilities\".format(journal=JOURNAL)\n",
"!{balance_cmd}"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
" \u001b[31m$ -3,804.00\u001b[0m \u001b[34mAssets\u001b[0m\r\n",
" $ 1,396.00 \u001b[34mChecking\u001b[0m\r\n",
" $ 30.00 \u001b[34mBusiness\u001b[0m\r\n",
" \u001b[31m$ -5,200.00\u001b[0m \u001b[34mSavings\u001b[0m\r\n",
" $ 180.00 \u001b[34mLiabilities\u001b[0m\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" \u001b[31m$ -20.00\u001b[0m \u001b[34mMasterCard\u001b[0m\r\n",
" $ 200.00 \u001b[34mMortgage:Principal\u001b[0m\r\n",
"--------------------\r\n",
" \u001b[31m$ -3,624.00\u001b[0m\r\n"
]
}
],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u0430"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import csv\n",
"import pandas as pd\n",
"\n",
"df = lambda src, label: pd.DataFrame({'category': src.keys(), label: src.values()})\n",
"merge = lambda x, y, how='outer', on='category': y if x is None else x.merge(y, how=how, on=on)\n",
"display = lambda x, columns='category': x.fillna('').sort(columns=columns)\n",
"\n",
"def read2dict(journal, categories):\n",
" result = dict()\n",
" prefix = categories if ' ' not in categories else ''\n",
"\n",
" reader = csv.reader([x if x[0]=='\"' else '\\n'+x for x in journal],\n",
" delimiter=',', quotechar='\"')\n",
" for row in reader:\n",
" category = row[0][len(prefix)+1:] if row[0].startswith(prefix) else row[0]\n",
" value = ' + '.join(row[1].split('\\n'))\n",
" result[category if category else ':: Total ::'] = value\n",
" \n",
" return result\n",
"\n",
"def balance(period, journal=JOURNAL, categories='Expenses', flags=''):\n",
" \"\"\"\n",
" Balance report\n",
" \"\"\"\n",
" LEDGER_BALANCE_CMD = '''ledger -f {journal} balance {categories} {flags}\\\n",
" --no-total --start-of-week=1 --depth 2\\\n",
" -F '\"%(account)\",\"%(display_total)\"\\n' -p \"{period}\"'''\n",
" command = LEDGER_BALANCE_CMD.format(period=period, journal=journal,\n",
" categories=categories, flags=flags)\n",
" expenses = !{command}\n",
" return read2dict(expenses, categories)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##\u041c\u0435\u0441\u044f\u0446\u044b \u0434\u043b\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"MONTHS = ('dec 2003', 'jan 2004', 'feb 2004')"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##\u0420\u0430\u0441\u0445\u043e\u0434"
]
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"expenses = None \n",
"for mon in MONTHS:\n",
" expenses = merge(expenses, df(balance(mon), mon))\n",
"\n",
"expenses = merge(expenses, df(balance('2003'), '2003'))\n",
"expenses = merge(expenses, df(balance('2004'), '2004'))\n",
"\n",
"display(expenses)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>category</th>\n",
" <th>dec 2003</th>\n",
" <th>jan 2004</th>\n",
" <th>feb 2004</th>\n",
" <th>2003</th>\n",
" <th>2004</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> :: Total ::</td>\n",
" <td> $ 1,025.00</td>\n",
" <td> $ 5,629.00</td>\n",
" <td> </td>\n",
" <td> $ 1,025.00</td>\n",
" <td> $ 5,629.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td> Auto</td>\n",
" <td> </td>\n",
" <td> $ 5,500.00</td>\n",
" <td> </td>\n",
" <td> </td>\n",
" <td> $ 5,500.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> Books</td>\n",
" <td> </td>\n",
" <td> $ 20.00</td>\n",
" <td> </td>\n",
" <td> </td>\n",
" <td> $ 20.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> Escrow</td>\n",
" <td> $ 300.00</td>\n",
" <td> </td>\n",
" <td> </td>\n",
" <td> $ 300.00</td>\n",
" <td> </td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> Food</td>\n",
" <td> $ 225.00</td>\n",
" <td> $ 109.00</td>\n",
" <td> </td>\n",
" <td> $ 225.00</td>\n",
" <td> $ 109.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> Interest</td>\n",
" <td> $ 500.00</td>\n",
" <td> </td>\n",
" <td> </td>\n",
" <td> $ 500.00</td>\n",
" <td> </td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 5,
"text": [
" category dec 2003 jan 2004 feb 2004 2003 2004\n",
"1 :: Total :: $ 1,025.00 $ 5,629.00 $ 1,025.00 $ 5,629.00\n",
"5 Auto $ 5,500.00 $ 5,500.00\n",
"4 Books $ 20.00 $ 20.00\n",
"3 Escrow $ 300.00 $ 300.00 \n",
"0 Food $ 225.00 $ 109.00 $ 225.00 $ 109.00\n",
"2 Interest $ 500.00 $ 500.00 "
]
}
],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##\u0414\u043e\u0445\u043e\u0434"
]
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"bal_income = lambda p, j=JOURNAL: balance(p, journal=j, categories='Income', flags='--invert')\n",
"\n",
"income = None\n",
"for mon in MONTHS:\n",
" income = merge(income, df(bal_income(mon), mon))\n",
"\n",
"income = merge(income, df(bal_income('2003'), '2003'))\n",
"income = merge(income, df(bal_income('2004'), '2004'))\n",
"\n",
"display(income)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>dec 2003</th>\n",
" <th>category</th>\n",
" <th>jan 2004</th>\n",
" <th>feb 2004</th>\n",
" <th>2003</th>\n",
" <th>2004</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> </td>\n",
" <td> :: Total ::</td>\n",
" <td> </td>\n",
" <td> </td>\n",
" <td> </td>\n",
" <td> $ 2,030.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> </td>\n",
" <td> Salary</td>\n",
" <td> $ 2,000.00</td>\n",
" <td> </td>\n",
" <td> </td>\n",
" <td> $ 2,000.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> </td>\n",
" <td> Sales</td>\n",
" <td> </td>\n",
" <td> $ 30.00</td>\n",
" <td> </td>\n",
" <td> $ 30.00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 6,
"text": [
" dec 2003 category jan 2004 feb 2004 2003 2004\n",
"2 :: Total :: $ 2,030.00\n",
"0 Salary $ 2,000.00 $ 2,000.00\n",
"1 Sales $ 30.00 $ 30.00"
]
}
],
"prompt_number": 6
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment