Content AND Presentation

(Note to English-speaking readers: the links entitled Komentarze na tej stronie lead to comment pages.)

2016-07-18 Ledger – virtual postings aka envelopes

As I mentioned some time ago, I’ve been a ledger user since 2014. Until now, however, I did not really use any of its advanced features. There are a lot of them; the problem is, the manual is not the best one I’ve read. (Don’t get me wrong – it’s not that bad. But while it is a decent manual, it makes a very bad tutorial. Yes, there is a tutorial-like section at the beginning, and it’s nice, it does cover only the very basics.) So I figured out that after almost two and a half years of using Ledger, it’s high time to read the manual again.

It turned out that I found one feature I’m probably going to use: virtual transactions. The idea is that I have a budget for some kinds of expenses (notably what I call “life” expenses, mainly food and hygiene-related things like soap, toilet paper, dish soap etc.). I have to say that I’m pretty conservative here: near the beginning of each month, I go to the ATM and then set aside some cash for each week in physical envelopes. I do not own (well, technically nobody does – AFAIK, formally it is the bank’s property) a credit card (they are evil), and I avoid paying with a debit card (which is only slightly less evil). Also, some time ago I counted all my expenses that are due less often than monthly (like electricity, which is paid for once every two months, or car insurance, which is paid for once a year) and took the monthly average; each month I set aside that amount of money to a separate bank account. That way I don’t have liquidity problems when I have to pay a large invoice once a year.

Still, I figure it would be nice if Ledger helped me with all that stuff. And it can, thanks to the idea of virtual postings. Here’s a simple example.

2016/07/01 * Opening balance
    Assets:Cash                              $100.00
    Assets:Bank                             $1000.00
    Equity:Opening balance

2016/07/01 * Salary
    Assets:Bank                             $2000.00
    Income:Salary
    (Budget:Food)                            $500.00
    (Budget:Books)                           $200.00

2016/07/02 * Lunch
    Expenses:Food                             $20.00
    Assets:Cash
    (Budget:Food)                            -$20.00

(Note that all amounts are completely fictitious!) Here, after the opening balance we record the salary and set aside some money for food and books. An example food purchase follows. We can now launch ledger with the --real option to exclude the budget “accounts”:

ledger -f envelopes-1.ledger --real bal

or say

ledger -f envelopes-1.ledger bal ^Budget

to see the remaining budget for this month.

Be warned that virtual postings do not have to balance out: we manipulate our Budget:Food virtual account, but whenever we increase (after we get our salary) or decrease it (after we spend money on food), there is no corresponding posting of the opposite sign anywhere in the system! This means that ledger bal will not report a balance of 0 USD unless we use the --real option. If your OCD really insists on having everything (including virtual postings) balance out, you can use square brackets instead of parens; Ledger will then complain if balance of any transaction is anything but zero.

Now while this is nice, it certainly violates the DRY principle: in the last posting, for example, we record the fact that we had spent 20 USD on food twice. While the account name is not a huge problem, since Emacs’ Ledger mode has autocompletion anyway (and everyone uses Emacs, right?), what would happen if we got the amount wrong the second time?

Enter automatic transactions. Here’s a better way to accomplish exactly the same set of transactions.

2016/07/01 * Opening balance
    Assets:Cash                              $100.00
    Assets:Bank                             $1000.00
    Equity:Opening balance

= /Salary/
    (Budget:Food)                            $500.00
    (Budget:Books)                           $200.00

= /Food/
    (Budget:Food)                               -1.0

2016/07/01 * Salary
    Assets:Bank                             $2000.00
    Income:Salary

2016/07/02 * Lunch
    Expenses:Food                             $20.00
    Assets:Cash

Here, after the opening balance (we could do it earlier, too, of course), we instruct Ledger to add the two budgeting postings to any transactions whose account name matches Salary (this is in fact a regex), and also add a posting with exactly the opposite value as the amount given for all Food-related transactions. (The unitless value -1.0 is treated as a multiplier. In our case, if a posting’s account name matches Food, Ledger adds a posting with the same amount value but opposite sign to the Budget:Food account.)

OK, that’s it for today. Expect some other Ledger-related posts in the future!

CategoryBlog, CategoryEnglish, CategoryLedger

Comments on this page

2016-07-11 How to teach oneself properly, or read the manual again in two months

Today I started writing a blog post on Ledger and my experience with it, but I quickly digressed into my way of learning things. Since I guess this might be interesting on its own, I decided to make a separate (albeit short) blog post on this issue. Here’s the gist: my preferred way of learning nowadays consists (roughly speaking) of reading a few tutorials first and skimming the manual, then actually using whatever I’m learning, and then carefully reading the manual. The first part is obvious: reading a few tutorials instead of one may give you better perspective, and tutorials (by their very nature) omit some things – but different tutorials may omit different things. But what about postponing studying the manual until after a few weeks or so? Well, I strongly recommend doing exactly that. If you’re learning a piece of software, a programming language, a tool etc., start using it as early as possible, perhaps with a tab pointing to StackOverflow in your browser. Then, after (at least) a few weeks, read the manual again. Chances are you will now appreciate (and understand) a lot more things, since by now you may have enountered some real problems the tool/langauge is addressing (or creating!).

Being (among other things) a math teacher, I can’t help but think about a similar attitude in case of math teaching or learning. Would it be possible to first teach some very basic notions and patterns for solving common problems, then make the student solve a few of them, and only then teach him or her the theory proper? Would this help gain deeper understanding, not only for the theorems and proofs, but for the need for them to exist? On a “micro” level, a similar technique might be used to teach individual proofs. Mathematical proofs are chock-full of tricks, and most students do not understand why they are there. One way to teach them this would be first to present some special case, where they don’t need the tricks, prove it, then show a more general case and a counterexample showing that the simple proof won’t work, and only then introduce the tricks. It would be much slower than traditional teaching, but I’m quite convinced it could result in way deeper comprehension…

CategoryBlog, CategoryEnglish

Comments on this page

2016-07-04 Compiling a single Beamer frame in AUCTeX

Some time ago I basically stopped using Beamer. I turned to reveal.js, and did a few presentation in it, using Org-mode’s exporter. That was nice, my slides were not “like anyone else’s” (since everyone and their mother uses Beamer), and even equations worked great thanks to MathJax.

Some time ago, I taught a Calculus course (which is a challenge on its own, probably worth a blog post or two, especially that it is not aimed at mathematicians, but geographers – but that’s another story). The slides are very diagram-heavy – you know, all sorts of stuff like tangent lines (since we’re doing derivatives), approximations of arc length or areas (since we’re doing integrals), and occasional cute pictures (since we’re also having fun, or so I hope at least).

And it turned out that reveal.js (or at least the Org reveal exporter) really doesn’t like images. And it didn’t let me zoom them. Maybe if I were a CSS wizard, I could make it play nice. But I’m not, and I started missing Beamer, with its very precise control of what goes where.

So I came back. It was kind of refreshing to play with LaTeX and TikZ again. Of course, I’m using Emacs and AUCTeX, which is really great. (It will be even better when I finally start contributing to AUCTeX. I have a few functions which make certain TeX-related editing stuff really nice – IMHO at least – and I can’t wait to incorporate them into AUCTeX. But this is again another story – and a long one, since I’m preparing a lengthy post about my issues with the FSF. OK, let’s get back on topic.)

One problem I had with Beamer is that it’s huge, and compiling a slideshow for a 90 minutes lecture (some 30 frames with 3 slides per frame on average) took a lot of time on my netbook. So here’s a tip for making the cycle faster. If you want to compile just one frame, you can press C-c . (LaTeX-mark-environment) – possibly with a prefix argument (or just press it a few times) to mark the current frame, and then press C-c C-r (TeX-command-region). The latter command is extremely useful. It takes the “pinned region” (i.e., if there’s no active region, it remembers the previously used one), saves it to a temporary file (together with the whole preamble), and launches a compile or view command on that. This way I can cut down on the compile time by at least an order of magnitude.

Of course, pressing that combo repeatedly is not something an Emacs user would do too long. Let us write a short function to do that for us.

(defun LaTeX-command-beamer-frame ()
  "Run `TeX-command-region' on the current frame environment."
  (interactive)
  (save-mark-and-excursion
    (while (not (looking-at-p "\\\\begin *{frame}"))
      (LaTeX-find-matching-begin))
    (forward-char)
    (LaTeX-mark-environment)
    (TeX-command-region)))

It is fairly simple: we climb up the document structure until we reach the beginning of a frame environment, then move forward one character so that we are actually inside it, then we mark the current environment and launch compilation on the region. In the case we are not in a frame, LaTeX-find-matching-begin throws an error, and happily save-mark-and-excursion restores the point etc. in such a case, too. (There is a little price to pay for the simplicity of the above code: the error message is a bit cryptic: Can't locate beginning of current environment. Not a huge problem in my book, so I didn’t do anything to prevent it. In case I wanted to do that, I could have wrapped the LaTeX-find-matching-begin in a condition-case.)

There is, however, another (rather annoying) issue with the above code. The point is that TeX-command-region asks the user for the command to launch. In interactive use, it’s just fine. Here, it’s a nuisance: we can safely assume that what the user wants is either just compile, or possibly DWIM (i.e., compile or launch viewer if compilation was successful and there was no need to rerun it). The cuplrit is the function TeX-command-query, which (unfortunately) does not have any switch to just return the default instead of asking the user.

There are a few solutions to this problem, none of which is simple. (I asked about it on the ML, and got a few very good responses. You can look up that thread if you want to.) Probably the easiest one is just to copy the TeX-command-region function and change what is needed. This is far from elegant, though.

A better idea might be to replace TeX-command-query with something similar that just returns the default instead of asking the user what to do. Similar in that it’s not elegant, but should work.

Probably the best idea would be just to submit a patch to AUCTeX. I’m cosidering doing exactly that, but until then I’ll resort to advising TeX-command-query. Here’s one possibility:

(defcustom TeX-command-use-default nil
  "If non-nil, just use the deafult command instead of asking.")

(defun TeX-command-query-or-default (orig-fun name)
  "A piece of advice for `TeX-command-query' to make it obey
`TeX-command-use-default'."
  (if TeX-command-use-default
      (TeX-command-default name)
    (funcall orig-fun name)))

(advice-add 'TeX-command-query :around #'TeX-command-query-or-default)

I can now let-bind the newly defined TeX-command-use-default option to t in my function:

(defun LaTeX-command-beamer-frame ()
  "Run `TeX-command-region' on the current frame environment."
  (interactive)
  (save-mark-and-excursion
    (while (not (looking-at-p "\\\\begin *{frame}"))
      (LaTeX-find-matching-begin))
    (forward-char)
    (LaTeX-mark-environment)
    (let ((TeX-command-use-default t))
      (TeX-command-region -1))))

The negative argument to TeX-command-region ensures that not only aren’t we being asked for what command to issue, but nor are we asked about e.g. which viewer to launch.

Happy TeXing!

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryLaTeX

Comments on this page

More...

(Więcej means More in Polish; click it to see older entries.)

CategoryEnglish, CategoryBlog