fugalh
Counterpoint by Hans Fugal
2008-03-29T00:38:59-06:00
Typo
Updated: 6 weeks 6 days ago
Sat, 2008-03-29 01:00 -
Have you ever been frustrated with perfectly valid bash syntax being highlighted as incorrect in vim? Like this:
#!/bin/sh
foo=$(ls /tmp)
$() is a perfectly valid, nay preferred substitute for backticks. The problem is that vim is deciding this is pure old bourne shell instead of whatever else we'd like it to be. If you change the shebang to #!/bin/bash and re-edit the file, then the error markings go away. But maybe you're writing for the nebulous POSIX shell, not bash nor sh. Or maybe you just don't care and you don't want vim complaining that you're using bashisms even though your shebang says sh. You can set the defaults so that it reflects your system and preferences. It's all there in :help sh.vim.
Thu, 2008-03-27 11:00 -
I was doing some maintenance on my blog, and was devastated to find that Typo was taking 225 megabytes of resident RAM. Yikes! After some creative debug thinking and digging I figured out it was due to sessions. Typo now stores sessions in the database, so my maintenance cron job to delete old sessions didn't clean up old sessions. (Ha! had you going for a second!)
Well I could write a cron job to run a script to clean the sessions out of the db, like:
#!/bin/sh
sqlite3 /path/to/typo/db/production.db 'delete from sessions'
Ok, that's a bit extreme, but you get the idea. But when I deleted the sessions in this manner the memory usage didn't drop at all until I had restarted the server, which seems unnecessary. So instead I changed typo's configuration to use a different session store. I commented out this line in config/environment.rb:
- config.action_controller.session_store = :active_record_store
+ #config.action_controller.session_store = :active_record_store
Then I restarted the server and fired up a browser. "Huh, that's odd… no sessions in tmp/sessions or /tmp or anywhere I can see. No, they're not in the database…" What I was seeing didn't match up with what all the stuff Google said. The default session store was PStore, aka file system, so they said. But apparently that recently changed in Rails, and now the default is CookieStore. From ActionController::Base documentation:
Sessions are stored in a browser cookie that‘s cryptographically signed, but unencrypted, by default. This prevents the user from tampering with the session but also allows him to see its contents.
Do not put secret information in session!
Well a quick grep -ri session app lib told me that typo wasn't storing
anything secret, so I decided that default was alright with me. Now I don't
have to set up any session cleanup script at all. Sweet.
Now, don't stop there. You should set your session key and secret while you're
hanging out in config/environment.rb. Add the following lines in the same
place as the line you commented out above:
config.action_controller.session['session_key'] = 'something unique'
config.action_controller.session['secret'] = 'get this from rake secret'
Thu, 2008-03-27 09:00 -
I finally got around to building QCad on OS X Leopard. There are two main hurdles: getting Qt3 to build and getting QCad to build.
At first I tried building Qt3 with macports, but building QCad was a royal pain with the X11 version of Qt3 on OS X, for whatever reason. So I tried to install the qt3-mac MacPorts package, but that failed. So I was on my own building Qt3.
This patch will allow Qt3 to build on Leopard, by following the instructions in the INSTALL file. Here's the diffstat:
config.tests/mac/mac_version.test | 2 +-
src/kernel/qcursor_mac.cpp | 4 ++++
src/kernel/qt_mac.h | 2 +-
src/tools/qglobal.h | 5 ++++-
4 files changed, 10 insertions(+), 3 deletions(-)
I put it in /Developer/qt3, and I wrote a script to source on demand rather
than setting QTDIR and friends in my .profile or .bashrc, since I more
often want Qt4 than Qt3. I configure with -static, so applications like QCad
are built with Qt3 statically, which just makes things work better.
QCad needs a patch as well:
Index: qcad-2.0.5.0-1-community.src/mkspecs/defs.pro
===================================================================
--- qcad-2.0.5.0-1-community.src.orig/mkspecs/defs.pro 2008-03-26 08:46:25.000000000 -0600
+++ qcad-2.0.5.0-1-community.src/mkspecs/defs.pro 2008-03-26 08:46:48.000000000 -0600
@@ -1,6 +1,6 @@
# $Id: defs.pro 606 2004-12-25 03:08:40Z andrew $
-QMAKE_CXXFLAGS_DEBUG += -pedantic
-QMAKE_CXXFLAGS += -pedantic
+#QMAKE_CXXFLAGS_DEBUG += -pedantic
+#QMAKE_CXXFLAGS += -pedantic
win32 {
QMAKE_CFLAGS_THREAD -= -mthreads
Index: qcad-2.0.5.0-1-community.src/scripts/build_qcad.sh
===================================================================
--- qcad-2.0.5.0-1-community.src.orig/scripts/build_qcad.sh 2008-03-26 08:46:06.000000000 -0600
+++ qcad-2.0.5.0-1-community.src/scripts/build_qcad.sh 2008-03-26 08:46:49.000000000 -0600
@@ -30,7 +30,7 @@ then
export MAKE=gmake
echo "Platform is Solaris"
platform=solaris
-elif [ "x$OSTYPE" == "xdarwin8.0" ]
+elif [ "x$OSTYPE" == "xdarwin8.0" -o "x$OSTYPE" == "xdarwin9.0" ]
then
export MAKE=make
echo "Platform is Mac OS X"
Then do
cd scripts
./build_qcad.sh notrans
It will complain about not finding qm/*.qm, but that's a nonfatal error.
QCad.app will be in the qcad directory, ready for your use.
I built this on an Intel MacBook running Leopard. If you think that matches
your setup, you're free to download my QCad.app and avoid
building both Qt3 and QCad.
Thu, 2008-03-27 09:00 -
If I had a nickel for every time I had to scour the web to figure out the right setting for QTDIR on {Debian,Ubuntu,OS X}…
On OS X, if you installed the qt3 package, then the proper setting is
QTDIR=/opt/local/lib/qt3. I wrote this little script to source before
commencing building a Qt3 project:
#QTDIR=/usr/local/Trolltech/qt-mac-free-3.3.7
#QTDIR=/Developer/qt
QTDIR=/opt/local/lib/qt3
PATH=$QTDIR/bin:$PATH
DYLD_LIBRARY_PATH=$QTDIR/lib:$DYLD_LIBRARY_PATH
export QTDIR PATH DYLD_LIBRARY_PATH
Thu, 2008-03-27 09:00 -
I'm porting Aeolus to OS X. In the process I'm learning how CoreMIDI works. Naturally you get to hear my opinion on the matter.
CoreMIDI seems like a decent framework, actually. It is callback-based, which is good. It has a pretty reasonable design; physical devices and virtual devices alike communicate with eachother in the same way. They each have endpoints—source endpoints and destination endpoints.
It all looks well and good on the surface, but there's some problems. The first problem is arguably a feature. You can create input/output ports and connect sources/destinations to those ports from within your application. This allows you to make a cute or complicated dialog box where the user can select the MIDI (virtual) device(s) she wants to use. Sounds reasonable right? And so it is, and I wouldn't argue against this ability.
The badness comes in when you consider that every application has to duplicate this functionality. It would be much better to have an external patchbay for connecting applications together. This would be more powerful and flexible and free up application developers to not worry about it. They just have to create the endpoints and then they're done.
Alas, OS X proper has no such patchbay. "Yes it does, silly. It's called Audio MIDI Setup" you say. That's the most infuriating thing—Audio MIDI Setup lets you route between devices in just the sort of way I'm talking about, but it only works for physical devices. Someone needs to be shot.
Luckily, some guy named Pete wrote a MIDI Patchbay. It's serviceable, if quirky and ugly. He also wrote a simple software synthesizer called SimpleSynth (also quirky and ugly) that does what something in OS X (e.g. QuickTime Player) should already be doing: accept MIDI input and use the QuickTime music synthesizer to render it. Kudos to Pete for filling in the gaps, and I'm sorry for calling your children ugly.
While I'm complaining about patchbays, I'm still dumbfounded that JACK doesn't seem to have a command-line application for patching things together. I'm thinking something akin to aconnect for ALSA MIDI, though of course for JACK it would be for audio and MIDI both. qjackctl is absolutely marvelous, and I wouldn't use anything else given the choice, but sometimes you don't have qjackctl handy and it might be quite difficult indeed to get it. This was the case for me the other day. I had the latest greatest JACK installed from source, but qjackctl (which I finally managed to figure out how to build using the QtMac binary, whose qmake refuses to output a real Makefile but instead an XCode project) was choking on it. So I had to downgrade to Jack OS X and rebuild qjackctl (it's still an immense improvement over JackPilot). This is depressing because the newer version of JACK is much more friendly to the CLI user on OS X. The version in Jack OS X 0.76 still requires some ugly workarounds (which JackPilot helps you to do). The latest version of JACK (0.109.2) Just Works™ when you type jackd -R -d coreaudio. So I'm still starting JACK with JackPilot, which I then summarily quit in favor of qjackctl.
Thu, 2008-03-27 09:00 -
I find myself asking this question a lot: "Now what was that define that detects annoying platform that makes porting otherwise perfectly-portable code difficult?"
This will narrow your search down to something useful:
echo | cpp -dM
Go ahead, try it. I wish I'd known this one earlier.
Thu, 2008-03-27 09:00 -
If ever you find yourself wanting to do some network programming in C, C++, or any other language that uses the socket paradigm, you must be careful. You are only inches from the edge of the precipice of insanity.
Luckily, some guy who calls himself Beej wrote a fantastic guide to network programming. He takes you by the hand and leads you gently away from the precipice. His guide is fun and easy to grok, but doesn't water the topic down. It's a fine piece of writing.
Even if you're writing Ruby network code, for example, which streamlines much of the insanity (thanks to exceptions and some nice OO abstractions like TCPServer), the socket concepts you will gain from at least skimming this guide will be a huge help.
Wed, 2008-03-12 09:00 -
As many of you already know from this PLUG thread, the mail servers for MSN and Hotmail have been doing something despicable, for quite some time now. They quietly delete email that they think is spam, after accepting it for delivery.
Now, depending on your experience that may sound like no big deal, or it may rival the best plot ever for a horror movie. Let me explain why this is worse than zombies.
First, an analogy. If you put a stamp on an envelope and send a letter to your friend or business associate via the postal service, you expect it to get there. If you send a package via UPS you expect it to get there. You don't expect the recipient to show up at the post office to find the postal worker wearing the sweater you sent him. The mail may have been delayed, but it will get there. "Neither rain nor hail nor sleet nor snow nor heat of day nor dark of night shall keep this carrier from the swift completion of his appointed rounds."
If you show up to the post office with illegal mail—something that is outside the allowed dimensions or too heavy or has explosives in it—you will be told that you can't send it. You'll know you need to get a different envelope, pay more postage, etc. You have feedback. If you send mail to a bad address, or someone who hates your guts, you will get your mail back marked "Return to Sender" (assuming you provided a return address). Feedback. In neither case would you be satisfied if the post office just threw your important correspondence in the trash.
So, why would you accept this behavior from your email provider? When I send an email to fred@hotmail.com (whoever he is), and hotmail's mail server says 250 Queued mail for delivery, I expect fred will get my email. Maybe it's in his junk mailbox. Maybe fred is away on vacation and won't see it for a few months. Maybe it takes more than 5 minutes to traverse the internet. But I expect it will get there, or that I will get a bounce message if it doesn't. The reliability of email depends on it. The rules demand it.
If you use Hotmail or MSN, you have been losing email. I dare you to prove otherwise. You owe it to yourself and to the people with whom you correspond to switch right now. GMail is an excellent alternative. It has more features, better spam detection that doesn't delete mail without asking, a nicer user interface, more storage space than even you will use, and POP3 and IMAP support. While you're at it, if you use MSN for instant messaging switch over to Google Talk or, even better, Jabber.
If you have been corresponding with MSN or Hotmail users, your emails may have been trashed before the recipient ever saw them. They may not even realize this. Do your part and inform them. If they don't want to switch to a sane email service, then insist on communicating in a different manner.
And let this be a lesson to you: don't let the quest against spam (or anything else) turn into tilting at windmills. Keep your wits about you and consider the consequences of your actions. Especially if you're a system administrator. Really especially if you're a system administrator at a big email service like Hotmail. And that goes for SPF, too.
Mon, 2008-03-10 13:00 -
A short while back, we were enjoying some ice cream. Erin and I have different
ideas on the proper dressing for ice cream. She likes hot fudge and maybe some
chopped almonds. I like caramel, roasted peanuts (not chopped), and maybe
some chocolate (if she's already gone through the trouble of heating up her hot
fudge). So we traded spoonfuls as we sometimes do, and the hot fudge struck me
as more disgusting than usual. It really is sickening stuff. Not that I don't
like chocolate. In fact, a truly good hot fudge on ice cream is a treat indeed.
It's just that stuff they sell in the supermarkets that passes for hot fudge
that's disgusting.
This experience coincided with me running out of caramel sauce, so fate had
thrown down the gauntlet: make really delicious hot fudge and caramel sauce
from scratch.
To make a long story short, she actually wants a good hot chocolate sauce, not
a hot fudge sauce, and I really want a good cajeta sauce, not caramel sauce.
The hot chocolate sauce is easier. I consulted my mentor redbeard and he suggested a
ganache. It turned out to be the perfect suggestion. Bring 1/2 cup cream
just to a boil (in a large pot because it will bubble up), and pour over 3 oz
quality semisweet chocolate. Stir to melt and drizzle on ice cream. Store in a
jar in the fridge. It will set up, so the microwave is your friend in the
future. May I recommend a small glass condiment bowl for microwaving small
quantities? It will melt faster and you won't be remelting the stuff at the
bottom over and over. Now, this sauce isn't very sweet. More of a dark
chocolate flavor. But the ice cream is already sweet - all we need is creamy
chocolate and heat - and I think this sauce is a perfect ice cream topping.
For the cajeta, there were two challenges. First, cajeta is quite thick, more
suited to a cookie sandwich than an ice cream topping. Second, how do you make
the stuff? There's loads of unnecessary mystery, complication, and noise on the
internet on this subject.
Let's tackle the second one first. I had already convinced myself I was too simple for redbeard's simple caramel sauce. Either his recipe isn't foolproof or I'm less than a fool. (I think, after further reading, that my troubles could be mitigated by not adding that splash of water, but starting with just dry sugar). I was worried that making cajeta (which is a different beast than caramelizing sugar) would also fail, but I didn't have to worry. There's a good
article on Chowhound to clear up the
mystery surrounding this confection, and a simple
recipe by Suzanne
Martinson that fills in the gaps. There, that was easy.
Now, we need to make a sauce out of it. If you're smarter than me, it might
already be obvious to you how to make a sauce out of dulce de leche: add liquid
to thin it out. This didn't come to me until I was reading about the cold
water candy test
and it dawned on me that this mumbo jumbo about cooking sugar syrup to a
certain temperature isn't about the temperature so much as it is about the
concentration of the syrup. The thermometer, or cold water test, is just an
indicator of the sugar concentration. That's a bit oversimplified of course,
but that's how it came to me. Now, if you just stopped cooking cajeta at 230°F
(thread stage), you might not get the full maillard reaction. No, better to
cook the cajeta completely, then add liquid to bring it back to a sauce
consistency. You can find my recipe here. I burnt my
first batch (by not stirring it) and it was still too good to throw away.
Absolute heaven.
Thu, 2008-02-28 16:00 -
Have you ever thrown together a simple static webpage, only to find down the road that you want to add an RSS feed? What are your options? Maintain an ugly XML file by hand, or migrate to a big slow messy CMS. Yeah, no fun.
Sars is a simple RSS domain specific language. This:
# This is a YAML stream (http://yaml.org) but you don't need to know much YAML
# to get the hang of it.
# There are multiple "documents". The first document is the channel information:
---
title: Foo News Feed
link: http://example.com/foo/
description: News for the Foo Project
webmaster: you@example.com
# The second and subsequent documents are items. The first line is the title,
# the second line is the date, and the rest is the item description (Markdown).
# Because line endings are important, don't forget the pipe character.
--- |
Really Exciting Title
2/28/08 12:00
This is where I pontificate
about the really exciting fish
that is sitting on my plate.
Here's a [download link](http://example.com/foo/foo-1.0.tar.gz).
--- |
Another Item
2/28/08 12:04
You know, it doesn't really matter what order you put them in, since they each
have dates.
becomes this:
Foo News Feed
http://example.com/foo/
News for the Foo Project
Thu, 28 Feb 2008 12:07:32 -0700
yaml2rss
Really Exciting Title
<p>This is where I pontificate
about the really exciting fish
that is sitting on my plate.</p>
<p>Here's a <a href="http://example.com/foo/foo-1.0.tar.gz">download link</a>.</p>
Thu, 28 Feb 2008 12:00:00 -0700
http://example.com/foo//2008-02-28T12:00:00-07:00
Another Item
<p>You know, it doesn't really matter what order you put them in, since they each
have dates.</p>
Thu, 28 Feb 2008 12:04:00 -0700
http://example.com/foo//2008-02-28T12:04:00-07:00
Any questions?
Thu, 2008-02-28 16:00 -
I've released yet again. Go to the web page for the details. Now Crème Rappel has its own RSS feed so I'll shut up about here now.
Thu, 2008-02-28 12:00 -
Postfix is my MTA of choice. Recently I had a second opportunity to set up relaying from Postfix to Postfix, with TLS and authorization. Seeing how I remembered precious little from the first time, I decided it would be a good thing to blog on.
The documentation on doing this is really quite good, but you have to get acclimated to the acronym soup before it makes any sense at all. The first and most mysterious acronym is SASL.
SASL is the Simple Authentication and Security Layer, a method for adding authentication support to connection-based protocols. To use SASL, a protocol includes a command for identifying and authenticating a user to a server and for optionally negotiating protection of subsequent protocol interactions. If its use is negotiated, a security layer is inserted between the protocol and the connection.
If that's not a mouthful… Basically, SASL is a library and daemon that programs, like Postfix, can use to do authentication. The Postfix SASL Howto tells you all you need to know about configuring Postfix for Cyrus or Dovecot SASL. It also tells you how to configure either Dovecot or Cyrus SASL for Postfix.
I'm using Debian stable (4.0), and this is what I did. On both the client and server you need the postfix-tls package which includes SASL and TLS support for Postfix. On the server I had to install the sasl2-bin package (this is not at all obvious at first pass—I was looking for a saslauthd package). Then I had to enable saslauthd by editing /etc/default/saslauthd. The smtpd.conf file is in /etc/postfix/sasl on Debian, and it looks like this:
pwcheck_method: saslauthd
mech_list: PLAIN LOGIN
Here's the relevant snippet from /etc/postfix/main.cf:
smtpd_sasl_auth_enable = yes
smtpd_sasl_application_name = smtpd
smtpd_sasl_security_options = noanonymous
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination
Now, there's a problem. Debian runs Postfix in a chroot jail by default, which means you need to make special provision for Postfix to be able to find the saslauthd socket. This can be as easy as
mv /var/run/saslauthd/ /var/spool/postfix/var/run/
ln -s /var/spool/postfix/var/run/saslauthd/ /var/run/
You may also need to adduser postfix sasl, though I'm not sure if this is necessary.
That's it for the server. Now, on the client you need this in /etc/postfix/main.cf:
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
relayhost = [mail.example.com]
smtp_sasl_security_options = noanonymous
/etc/postfix/sasl_passwd looks like this:
[mail.example.com] username:password
You need to postmap /etc/postfix/sasl_passwd after changing it.
Now, authentication is well and good, but you don't want to be sending those passwords in the clear, especially when using the default PAM authentication source. So, you also need to configure TLS.
The Postfix TLS README tells you all you need to know for this. You need to create a certificate for the server, enable the use of TLS on both sides, and tell the server not to accept authentication without TLS. That last bit is perhaps the most vital element for security, though of course it does nothing to help you get TLS actually working. Here's the config snippet:
# client
smtp_use_tls = yes # This option deprecated in later versions of Postfix
# server
smtpd_tls_CAfile = /etc/ssl/CA/cacert.pem
smtpd_tls_cert_file = /etc/ssl/certs/mail.pem
smtpd_tls_key_file = /etc/ssl/private/mail.pem
tls_random_source = dev:/dev/urandom
smtpd_tls_loglevel = 1
smtpd_use_tls = yes # also deprecated
Creating the certificates is nothing extraordinary, but this seems like a good time to post my /etc/ssl/README file:
self-signed:
openssl req -new -nodes -out newreq.pem
openssl x509 -req -signkey privkey.pem -in newreq.pem -out cert.pem
create CA:
openssl req -nodes -new -x509 -days 3650
-keyout CA/private/cakey.pem -out CA/cacert.pem
generate request:
openssl req -new -text -nodes -keyout newkey.pem -out newreq.pem
sign request:
openssl ca -in newreq.pem -out newcert.pem -days $((365*2))
Don't forget to keep private keys private.
So there it is. Authentication and Encryption at your fingertips.
Wed, 2008-02-27 14:00 -
For my musical notation needs, I use LilyPond.
LilyPond is to music as LaTeX is to writing. I prefer to edit LilyPond files in Vim and compile them with lilypond at the command line. However, on OS X LilyPond.app is a front end to the compiler. An IDE of sorts. Not a spectacular one, in my opinion, but it does have one thing going for it: when you click on a note in the PDF preview, it takes you that note in your LilyPond source file in the IDE.
On Leopard, LilyPond is severely broken. The IDE will "start", but there is no menu. Further, if you are on Intel, when you try to run it at the command line, it just keels over and does nothing. It so happens that the workaround to this problem and using LilyPond without the IDE are almost identical solutions, so I'll describe them as one and the same.
First, and this is the only difference between Leopard brokenness and just wanting to run on the command-line, you want the powerpc version of LilyPond.app, not the Intel version. So go over to the download page and get the ppc version (the one that says it's for G3, G4, G5 Macs).
lilypond and its friends are in Lilypond.app/Contents/Resources/bin. You could add this to your PATH, but some of the binaries in there are things that I have installed elsewhere (e.g. with MacPorts), and I don't want them overriding my PATH. Likewise, I want lilypond to be able to find the binaries it expects, and since they're taking up disk space anyway let's help it along. So I wrote a script. A LilyPond launcher if you will. I call it ly and put it in my path, and then I call e.g. ly lilypond foo.ly. Here's the code:
#! /bin/sh
APP=/Applications/LilyPond.app
PATH=$APP/Contents/Resources/bin:$PATH
exec "$@"
Customize APP to point wherever you want to keep LilyPond.app. This will load up the environment that will give lilypond the best chance of success. You can run any of the binaries in that directory with ly, but the most common case is to run lilypond. So I recommend putting this in your .bashrc:
alias lilypond='ly lilypond'
The first time you run the ppc version of LilyPond, or anything else, on an Intel machine, it will seem to take forever while Rosetta fires up. Be patient. Subsequent invocations are quick enough.
Mon, 2008-02-25 18:00 -
Once upon a time I was on a quest to get Ogg Vorbis working on a Mac. I tried the QuickTime Components project and it worked for awhile. Then it broke with QuickTime 7. Truth be known, it never worked all that great before, though it did decode the music. Then I found VLC and never looked back.
Today I learned that somewhere in the interim Xiph.org filled the gap. Now you can download XiphQT, stick XiphQT.component in /Library/Components, and you're off and running. This is precisely how the issue should have been addressed in the first place, and I'm glad it finally was, whenever it was. I'm also happy to have been ignorant of the fact for so long, since I despise iTunes for other reasons, and this tells me I've lived without regular iTunes abuse for a long hapy time.
Fri, 2008-02-22 00:00 -
In the spirit of release early, rewrite often, I have released Crème Rappel version 2. Version 1 was a shell script that combined Growl and at. Then Apple released 10.5.2 not half a week later and broke at altogether. Sick of fighting with launchd and other Apple superiority complexes, I set about to nurture my own superiority complex and rewrite Crème Rappel to be completely independent of at.
Of course, that's getting too heavy for a shell script, so I moved to Ruby. One thing I didn't want was to require a daemon to be running. Daemons can fail or
forget to start up, and that means I couldn't really truly trust the tool. The recent at debacle is just another case in point. So, instead I wrote Crème to fork a process that sleeps until the moment of truth, then fires off the reminder. It turns out the obvious function for the job, sleep(), is a poor choice here. In fact, every timer I tried had the same problem, including one I thought would not: setitimer(). When you suspend the laptop, it appears you also suspend time. If you don't believe me, try this simple experiment:
date; sleep 30; date
Put the laptop to sleep during the sleep for a substantial time, then notice that when you resume you still have to wait for the full 30 seconds to tick by
even though it has actually been a minute plus since you issued the command. So I sleep for one second intervals instead, checking the time every time.
This is not just a backpedaling rewrite, though. It also adds more flexible and easy-to-type timespecs, and a spiffy website.
If you give it a try and it doesn't work, or you struggle with the documentation, please do drop me a line so I can fix it. I want it to be worth
every bit of bandwidth that you paid for it.
Sun, 2008-02-17 12:00 -
If my last post made your head spin, you're not alone. It made mine spin too when I was conceiving and writing it.
For your sanity and mine, I have put together a soap calculator spreadsheet. You tell it the precision of your scale, how much of each fat you want (sorry, you have to specify the saponification value too, but there's a reference chart included), and your target lye discount. It tells you how much lye and water or milk to use. It also tells you how the measurement error effects your expected lye discount, and warns you if your soap might turn out lye-heavy. You can easily scale the recipe arbitrarily.
Download the calculator and my recipes at http://hans.fugal.net/soap.
Sat, 2008-02-16 02:00 -
Have you ever wondered what significance the measurement error of your scale has in making soap? What, you didn't realize your digital scale has measurement error?
If your scale has 1-gram precision (the norm these days), then if it says 42 grams it actually means that it most probably is between 41.5 grams and 42.5 grams. The possible measurement error is ±0.5g.
What does this mean in measuring ingredients for soap? Well, there are two extremes: lye surplus and lye deficit (or inversely, fat deficit and fat surplus).
On the one extreme, you may have 0.5g more lye than the scale says, and 0.5g less fat than the scale says. In that case, the extra 0.5g lye is actually close to 4 grams worth of fat. The exact value depends on the saponification value of the fat in question. For example, olive oil has a saponification value of 0.134, so 0.5g/0.134 = 3.7g worth of oil. That means that if you do indeed have an extra half gram of lye, you need 3.7g more oil than the recipe called for (for simplicity, assume the recipe has no lye discount/superfatting). Now factor in the possibility that you have half a gram less oil than the scale says, and you need 4.2g more oil to be 100% sure you are not lye-heavy. Of course your scale only does 1g increments, so you have to bump it up to 5g. So, regardless of the recipe size, if you add 5g oil to the recipe, you're sure to have at least the nominal superfatting, but perhaps more. Actually, probably more.
What about the other extreme—a lye deficit? If you have 0.5g less lye than the scale says, and 0.5g more olive oil than the scale says, then you have 0.5g/0.134 + 0.5g = 4.2g extra oil. Add that to your 5g that you added to be sure you're not lye-heavy, and now you've got about 9–10g more oil than the recipe calls for in the most lye deficit case.
Now, we want to add the first 5g to a non-superfatted recipe, for sure, so we know we're not lye-heavy. Then, the scale threatens to add another 5g, so it's entirely possible we get more fat than we are willing to tolerate.
What kind of impact do those 10 grams actually have? Well that depends on the size of the recipe. For most recipes you'll find on the internet, that 5 grams will be less than 1% of the total weight. No big deal. But if you, like me, are experimenting and making quite small batches it becomes significant. I like to aim for 1–5% superfat, but I'd be ok with 0–8%. So if I want no more than 8% superfat, and I add 5 grams of oil to be absolutely sure I don't go below 0% superfat, and the scale adds another 4.2 in the worst case, then I want a minimum batch size of 9.2g/8% = 115g (before water). That's a nice one-bar batch size.
Well and good, as long as you're not trying to observe the effects of superfatting, since you have such a wide range of possible actual superfat. For that you'd have to break down and make larger batches.
But what is the expected value of your superfatting? The extremes are actually less likely to occur than something much closer to the actual reading. As a simplification, just take the actual reading to be your expected value. So if you add 5g oil to a 120g batch, then you probably have about 4% superfat. 4±4% superfatted soap. It's alright by me.
So, a pure castile soap one-bar ingredient list:
102 g olive oil
13 g lye
25–30 ml water or milk (preferably goat's milk)
So in summary, if you have a 1g scale and you make small batches, the above is important to understand and take into account. If you have a 1g scale and make medium to large batches, then you are going to get within ½–1% of your target superfatting.
Oh, and of course none of this actually takes into account the accuracy or variation of those saponification figures.
Fri, 2008-02-15 14:00 -
People doing creative work, e.g. programmers and grad students trying to write survey papers (ahem), do their best to get into the zone. Once there, the challenge is getting out of the zone at the right time. I've missed more classes and busses and meals than I can count because I was in the zone.
Another problem is that this business of trying to remember when to get out of the zone steals precious productive energy from the brain. So much better if you can rely on something external to remind you of things to be done, so you can literally lose yourself in the work.
The traditional approach is to program your calendar application to bring up an annoying dialog. This has several drawbacks. The UI is cumbersome. It's calendar-centric; you have to make a calendar entry to get an alarm. I don't know about you but I'm not inerested in entering the bus I intend to catch into a calendar. Entering a random event (e.g. take the bread out of the oven) is more trouble than it's worth. It's just the wrong way to do it.
Another approach is to use a watch with a timer. It's a bit faster and certainly more temporary and anonymous than the calendaring app, but it's limited to one event only. Something better is needed.
I've tried a few reminder apps but never really been pleased with them. The closest I've come to one I like is Pester. It comes really close, but I find it lacking for my needs. It's too cumbersome to enter events (although the author obviously put effort into streamlining it—I just don't need all those options). I need something lightning fast and completely keyboard-based, or I won't bother. Too many unnecessary keystrokes to enter an event in Pester. The reminders are annoying window and/or voice. Voice is ok, but too easy to miss (if away from the computer for a moment, or the music is up too loud, or if the volume is muted or too low). Annoying reminders are too annoying—I don't want an important thought in the zone interrupted by an annoying reminder that insists on being attended to before I can return to working in the window I was using. (If I tab away from the annoying reminder it will stay hidden below my windows indefinitely and won't do its job).
Enter Crème Rappel. The little reminder app with a silly French name. Crème combines the notification power of Growl, the scheduling prowess of at, and a no-frills quick-entry command-line UI. Voyez:
The growl notifications are sticky, so you have to acknowledge them before they go away. But they're not annoying; you can continue to work on that thought until you have a few cycles to spare. They won't get hidden behind other windows. You can configure Growl to play a sound whenever a Crème Rappel notification happens. What you can't hear in the screenshot above is that the text of the window is also spoken using say, so even if you're not looking you'll get reminded. The only thing that's missing I think is a snooze button, so it can go away and taunt you a second time. If anyone has any ideas…
The requirements are Growl, of course, growlnotify which is distributed with Growl in the Extras folder, and configuring your mac to pay attention to the at queue. If you need help with the latter, see my previous post on the matter. Crème Rappel is waiting for you to download it. Do not disappoint.
Here's how I use it in my life. Every morning I have a little planning session with my own self. I look at my calendar, figure out what I need to do and where I need to be. I set up my reminders, it looks something like this:
$ creme
1325 teach lab
job 44 at Fri Feb 15 13:25:00 2008
1642 bus
job 45 at Fri Feb 15 16:42:00 2008
^D
Now my mind is clear of remembering that stuff, as long as I'm by my laptop. Throughout the day, if I need to remember something say 15 minutes in the future, I do something like this:
$ creme +15minutes stretch my legs
Or more likely, I enter the time directly, since that's less typing. (One day I'd like to make this a real application with much nicer time parsing than what at handles. I should be able to type +15m, not have to type +15minutes. But this is the simplest thing that can possibly work, so it's good enough for now.)
For more details on using Crème Rappel, run creme -h. To configure it for your own needs, just hack at the script. If you think up a really neat enhancement, please let me know.
Oh, and if you like the idea but you use Linux, take a look at modifying the script to use Mumbles. Theoretically you should be able to do it easily, but I wasn't overly impressed with the manpage to the mumbles command-line event generator (in particular, I didn't see a way to make it sticky, nor to set the icon but that's just bells and whistles). Oh, and don't forget to make sure the frequency with which at jobs are run is enough for your needs. If you get something that works, please send it to me and I'll try to incorporate it into the same body of work.
Thu, 2008-02-14 18:00 -
Previously on The Fugue, I told you how to make Castile Soap in 5 Minutes. Having been through the process a few more times since then, I have a couple of addendums.
First, on measurements. If you're at all serious about making soap you either need to do large batches or get a scale with 1 gram precision. With my old scale (which had 5 gram precision) I had hits and misses with the size of batch that I like. i.e. 1–2 bars worth. Most recipes you find on the internet are what I would deem "large batches", and are really more like medium batches. But when you're trying to nail down the perfect recipe, making 5–10 bars of soap is wasteful, or at least a really really slow way to go about it.
Second, on ingredients. Pure castile soap is great, but has to be treated with respect or it can get really slimy. Coconut Oil is easy to obtain and adds hardness and lather. Lard or tallow is cheap and also hardens the bar. So I've been doing 6 parts olive, 2–3 parts tallow or lard, and 1–2 parts coconut oil and others (like cocoa butter). I calculate the lye then use 2 parts liquid for 1 part lye (by volume). I like to use milk instead of water, because I made this one bar with milk and the caramelized sugars (from the lye heating up when mixed with the milk) made a bar that smelled divine.
Third, on measuring again. For the size of batch I'm doing (on the order of 80 grams fat) I figured out that measurement error gives me ±2%. So I round the lye and fats (check the total weight so the measurement errors don't compound), then add 2g (a bit over 2%) of fat. So I know I'm between just under 1% superfat and 5% superfat, which is acceptable. I don't want more than 5% but of course you really don't want less than 0%. The same idea would apply with a 5g precision scale, but you'd have to be doing batches about 5 times as large (I think).
Fourth, on temperature. I don't measure temperatures. I aim for "warm to the touch" on the outside of each container before bringing them together. Rather than wait for the lye to cool down to "warm", I start with really cold liquid, sometimes in the form of one or two ice cubes. The ice cubes melt, and the final temperature is much closer to the target and so there's much less waiting. Obviously, if you're using more solid fats you want the temperature to be above their melting points until you get a good mixture.
Which brings us to the final point, mixing and molding. I am more than ever convinced that shaking in a water bottle (or large soda bottle) is an excellent way to go. It is safe, convenient, cheap, and fast. However, it's not such a great mold. It will work as a mold, but it will take that much longer to set up (evaporate water). Usually you demold after 1–2 days, but getting cheese-consistency soap out of a water bottle without marring it is an exercise in futility. So now I use paper cups as molds, and I pour the soap in from the water bottle when it reaches trace. As a bonus, you can clean out the water bottle and use it again the next time. It's easy to extract the soap from the paper cups, and they're cheap and nice and round.
So here's an updated base recipe. Go forth and wash!
Thu, 2008-02-14 18:00 -
So we got a toaster oven. The primary motivation was that I like to make biscuits and gravy, but preheating the big oven takes way too long. Plus I wanted to bake little one-day loaves of bread some mornings, with the same problem.
But always wanting to push the limits, I also wanted to try a larger loaf in the toaster oven. This is actually half the size I usually make, but it's about the limit of the size of boule I'd make in a toaster oven. Too much bigger and the top will burn.
Here are more pictures of the process. I moved a couple of tiles from the big oven to the toaster oven to make a nice baking stone, and I preheated the toaster oven. Then I put the bread in (conveniently on parchment paper, though in the future I think I'll trim the parchment paper for better convection airflow). There is noticeable oven spring, and it was fun to have such a clear view of it. Eventually it started to brown, and when I figured it should be about done I took it out. I found that it had actually browned quite a bit more in the back than in the front—maybe some tinfoil on the door next time to aid the radiation? The crust was a bit boring, but that may have been partially due to my using a slightly drier dough than I usually do. In any case, the crumb was as good as ever and the experiment was a success. As in the large oven, I definitely recommend some sort of stone setup though.
A few more experiments will be needed to know for sure, but it's possible that the close quarters will help in the steam department. However, it's a convection oven and I'm not sure whether that would counter any steam tendencies. As I said, this loaf was a bit drier than usual, so more tests are in order. Incidentally, I had a loaf in the dutch oven come out with the same boring crust the other day, and I think the hydration was about the same as with this loaf.
As for biscuits, it works great. I turn it down slightly from the called-for temperature but otherwise there's nothing to it.
|
:: Recent comments :.
26 weeks 4 days ago
39 weeks 4 days ago
40 weeks 3 days ago
40 weeks 3 days ago
47 weeks 2 days ago