(Note to English-speaking readers: the links entitled Komentarze na tej stronie lead to comment pages.)
Today, a friend asked me how to create a directory – or a hierarchy of them – while finding a file in a nonexistent directory. I found some clues on the ‘net, but the best one used the old advice mechanism. So I decided to do it myself, based on the hints found. It turned out to be simpler than I thought; it’s made even easier by the fact that Elisp’s
make-directory function acts basically like
mkdir -p when given non-nil second (optional) argument.
(defun make-parent-directory () "Make sure the directory of `buffer-file-name' exists." (make-directory (file-name-directory buffer-file-name) t)) (add-hook 'find-file-not-found-functions #'make-parent-directory)
Read the manual and/or relevant docstrings for the descriptions of the functions used. Note that (under normal conditions – see its source code)
make-directory always returns nil, so if there are any other functions in the
find-file-not-found-functions hook, they should also be executed.
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
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
OK, that’s it for today. Expect some other Ledger-related posts in the future!
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…
(Więcej means More in Polish; click it to see older entries.)