Created
August 5, 2014 06:15
-
-
Save velppa/af0ec7287e4bf425dee5 to your computer and use it in GitHub Desktop.
IPython notebook to compare multiple period in Ledger
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
| { | |
| "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