The Fugue

Counterpoint by Hans Fugal

Feijoada

Posted by Hans Fugal Mon, 12 May 2008 21:29:27 GMT

You haven't lived until you've had Brazilian cuisine, and feijoada is as Brazilian as it gets. (Personally, churrasco beats the pants off feijoada any day, but churrasco is in a class all its own.)

I finally got up the courage this weekend to make feijoada, even though I had no Brazilians to guide me except ye olde internet. I'm happy to report the experiment was a success. It was delicious, and probably not entirely unlike authentic feijoada (it has been over 9 or 10 years since I had some, not counting Tucanos).

The trouble with trying to make feijoada from the cookbook of Google is that the dish is at once both incredibly simple and incredibly complex and varied. It's simple in that it's essentially just beans and pork. It's complex and varied in that most recipes call for a half dozen kinds of pork, make huge amounts, and generally contradict each other.

The recipe I ended up using as a basis was from Maria's Cookbook. It's a veritable gold mine of Brazilian recipes.

So, let's get down to my experiment. I went to Albertson's and grabbed one 1-lb bag of black beans, 1 package (about 1 lb) of salt pork, and 1 kielbasa sausage (about 1 lb). For some reason my wife didn't let me get pig's feet, but that would have been fairly traditional. I also picked up some yuca, since farofa was nowhere to be found. Oh, and I grabbed some kale.

Saturday night I started the beans soaking, then realized the timing might be a little off. I read somewhere that you don't want to soak more than about 12 hours, but we were to be at church from 12–4. So I began contemplating slow cookage.

The next morning, into the crock pot on high. I sautéed about half the onion and 2 small cloves garlic in a bit of olive oil, and threw that in too. Then some 3 hours or so later I chopped up the salt pork and kielbasa and put it in as well, and a couple pinches of kosher salt (I think I had to add a touch of water at this point too).

After church, the beans were still not quite done, but the meat definitely was. However, the salt pork was still a lot of solid fat. I think next time I would render the fat before putting it in, and since it was so fatty I'd probably just use bacon or pork butt next time (or pig's feet if I could get away with it). It was also a tad too salty, so if I were using salt pork or something equally salty in its place, I'd skip the pinches of kosher salt.

While it continued cooking I boiled the yuca and made the rice. When the yuca was fork-tender, I drained, dried, and cut into strips. Then I fried it. It was disgusting, I think because it was probably really old. I wonder if you can order farofa online…

About 5:30 or 6 the beans were nice and tender, so I chopped up the kale and just barely wilted it in butter (per this recipe for couve a mineira, though it was kale instead of collard greens). Then dinner was served to salivating family.

The long cook had made the meat bloated and a bit too soft, and though most of the salt pork fat was melted in the end I still wished I had rendered it or used something else. The kale garnish was delicious and contributed as much as anything to the authenticity. We threw the yuca away.

So here's the recipe I'll try next time:

Feijoada

1 lb black beans
1 lb bacon, pork butt, ham hock, pigs feet, salt pork, or any other pork
1 lb kielbasa sausage
1/4 of a medium onion
1 clove garlic

Soak beans, bring to a boil and simmer one hour. Sauté garlic and onion in
olive oil, render fat out of garlic or salt pork as needed, and add to the
beans. Continue to simmer about another half hour, add salt to taste, and
simmer until beans are tender. Mash some beans to thicken. Serve over rice
and garnish with greens and farofa.

I'm making two assumptions here that need bearing out: it really does take about 2.5–3 hours to cook soaked black beans, and that the meat will cook thoroughly in the 1–1.5 hours time. I think the latter assumption is fairly safe, but I'm not sure about the former. Why don't you give it a try and let me know?

1 comment |

Fixed Point for Sysadmins

Posted by Hans Fugal Fri, 09 May 2008 14:31:00 GMT

In CS language theory we sometimes talk about fixed points. Everyone seems to have a bit of a hard time understanding what a fixed point is at first, and I thought of an interesting analogy just now that will make sense to sysadmins.

When you go to install foo, with apt-get install foo, apt will tell you all the dependencies it will install, and it will also tell you the recommendations and suggestions, then ask for your permission. You might decide to say no and repeat the command with one or more of the suggestions added. Then it will do the same, but now with the suggestions of the suggested packages as well. You might repeat a couple of times. Finally, you will be happy with the selection of packages you're going to install. You've found the fixed point.

Apt itself does the same thing when resolving dependencies. If you remember rpm-based distros before apt-alikes, you used to have to find the dependencies fixed point by yourself. We called this rpm hell for good reason.

So when you're finding a fixed point in math, you're doing a similar thing. You're repeatedly performing the operation until further operations don't change the answer. The fixed point of a function f(x) is x0 such that f(x0) = x0.

no comments |

Token Bucket of Life

Posted by Hans Fugal Mon, 21 Apr 2008 15:00:00 GMT

When it comes down to it, the secret of productivity is to just do it. In our line of work, it's not as simple as you're either chopping a tree down or you're not. So it's easy to get distracted on tangential or unrelated tasks and trains of thought. If I didn't know people personally who somehow manage to avoid this trap most of the time, I'd think it was impossible. For the rest of us, I present a nifty trick.

Grab two condiment bowls, shot glasses, rolls of tape, whatever. Now grab some glass "stones", some pebbles, some M&Ms, whatever. The former are buckets. The latter are tokens. Put all the tokens into bucket A.

Now for every hour you work (really), move a token from bucket A to bucket B. Do this every day for a week and keep a tally. This will show you how much time you are working and how much time you are squandering. It will be depressing. Don't let your boss see.

Now decide how much time you will permit yourself to squander. You might feel that should be 0, or maybe you feel you deserve an hour a day. No matter what you feel it should be, make a realistic goal at this point. It's just like physical excercise you know. So figure out the ratio between work time and play time. 4:1 makes the math convenient, so let's take that ratio. Now, for every hour you work you bring a token from A to B. It represents 4 quarter hours in bucket A, but only 1 quarter hour in bucket B. That is, you get to play 15 minutes for every token you have in B. Think of it as a bank account. If you don't got no tokens in the play bucket, you work. If you do, you might keep working because you're in the zone. But you might play, because you have the tokens to do so. So play, and play guilt free. The guilt-free recreation is as important as anything here. If you can't bring yourself to give yourself permission to play at work, then split it up between stuff you hate and stuff you enjoy. You do enjoy some aspect of your work, no?

This is just a slightly-modified token bucket scheme, like that used in network shaping (e.g. Quality of Service). When I first came up with it, I was inspired by "token economics" which was suggested for potty training. When I had the system going for a day or two, and was working on a QoS presentation, it dawned on me that what I had here was a token bucket. That makes it all the more cool.

What good is it? I think it's an effective tool for a couple of reasons: it's simple, unobtrusive, and authoritative. It keeps you accountable, both to it and to yourself, and to anyone who looks on that knows what it means. It doesn't nag you, nor is it susceptible to your rationalizations. It's easy to reset or set aside when it doesn't apply (when a deadline looms and you don't have time to play at all). The only habit you need to get into is checking your account before playing. But if you fail to remember, you can always adjust the totals retroactively, in which case although you may have overdrawn you will still see the state of affairs, and have an opportunity for introspection.

Now if you'll excuse me, my play bucket just ran out.

1 comment |

64-bit Transcoding

Posted by Hans Fugal Sun, 20 Apr 2008 16:38:24 GMT

I have a 64-bit desktop machine, that has rarely been run as a 64-bit machine. The hassle was too great and I couldn't really see a reason to put up with it.

I think that 64-bit support has come a long way in the meantime, and it may be time to try it out. It sounds like a livable situation. So with the pending release of the next Ubuntu version I'm thinking of wiping and going 64-bit.

One of the primary motivators is that 64-bit holds some promise for transcoding video, and now that I have an HDHomeRun to capture over-the-air HDTV signals, I will be doing quite a bit of video transcoding for MythTV (to save disk space—a full-quality HDTV program is about 9 gigabytes per hour).

But before taking the plunge, I thought I'd do an empirical test and see if there would be any real savings. I captured a couple of minutes of HD content from PBS, then transcoded 60 seconds using ffmpeg and mencoder. Then I did the same with the Ubuntu 64-bit live CD. The 64-bit execution difference was statistically significant.

ffmpeg was about 1.12 times as fast—a savings of about 10 seconds per minute, or 10 minutes per hour.

mencoder was about 1.08 times as fast—similar savings.

I didn't test mythtranscode itself, since getting it installed in a live CD environment would be too much work. I also must point out some other possible confounding variables. I used the Ubuntu 7.10 versions of ffmpeg and mencoder in 32-bit, and the Ubuntu 8.04 versions in 64-bit. Did both projects improve their code to be about 10% faster in the meantime? Unlikely, but perhaps not unfathomable.

So will I make the switch? I don't know yet. 10% faster is significant, but not obviously worth it. I'll have to think about it.

For the curious, here's my numbers. I did at least two runs of each to check for agreement, and what you see is the average. Of course, these would not be the settings you'd necessarily use to transcode—ffmpeg has a pretty low default bitrate for example—but I think we can agree the speedup is likely to be in the same ballpark no matter what settings you're using.

# 64-bit    32-bit
# 86 s      95 s
time ffmpeg -y -t 60 -i foo.avi -acodec copy bar.avi
# 55 s      64 s
time ffmpeg -y -t 60 -i foo.avi -acodec copy -s 640x480 bar.avi
# 83 s      90 s
time mencoder foo.avi -oac copy -ovc lavc -frames $[30*60] -o baz.avi

no comments |

DIY UHF Antenna

Posted by Hans Fugal Mon, 14 Apr 2008 16:03:00 GMT

I had one of these antennas:

RCA VHF/UHF Antenna

Not top of the line, I know, but it did have an amplifier and it did cost probably $30 when I bought it. And it's pretty much worthless. We got the PBS station in town but rarely could we pick up any of the El Paso stations.

Now that we're on the DTV bandwagon, I set out to improve the antenna situation. Antennaweb told me that I should be able to pick up almost all of the stations with a "yellow" antenna—a small multidirectional antenna (actually one station called for a medium directional w/pre-amp, and antennaweb doesn't realize some of those stations are broadcasting digital on UHF channels for now). In other words, it should be easy to get those stations. So I did a little searching and researching. All the digital stations here are UHF, so all I really needed was a UHF antenna.

I decided to make me a simple loop antenna—the same design as the UHF component on the one I already had. I fired up a wavelength calculator and figured out that the center of bandwidth for the channels I was interested in (15,16,17,18,23, I found that with the help of HDHomeRun's Channel Page, although my strongest station was mysteriously absent there) was almost exactly 2 feet (Here is an excellent TV Frequencies Table. Remember λ=c/f=3e4/MHz.). So I cut a coat hanger at 2 feet, shaped it into a circle, and soldered on a female coax connector. There are pictures here.

DIY UHF Antenna

I found that it didn't work much better than the other one in the same position, but as I moved it around and found a good position I got a satisfactory signal. So, to be rigorous, I tried the other antenna in that position. It was pitiful. So I was still justified.

I ended up hanging it on a nail on the wall, where it gets satisfactory to excellent reception for every station. Total cost: under $5.

If you need a directional antenna in your area, you might still be able to do this, and add a reflector (cardboard with aluminum foil) ¼ wavelength on the far side. I held a piece of foil behind it and it improved the signal strength quite a bit. Just how to rig that up is your problem, but I suppose some pieces of 2x6 and some nails and washers (and electrical tape for insulation) would do the job.

Speaking of electrical tape, if you look at those photos you'll see that there is a bunch of electrical tape scraps on my loop. That's just because I reused the hanger from my coat hanger dipole when constructing it. Which is an excellent VHF antenna, if your stations are VHF.

no comments |

rlwrap

Posted by Hans Fugal Thu, 10 Apr 2008 03:25:13 GMT

Thanks to Tene for pointing this out to me. It seems like a really useful tool. I am playing with Clojure in my spare time (ha!), and its repl doesn't have readline support (or anything like it). The clojure website suggests some Java readline-like jar, but I like this solution much better. I just made a script to wrap clojure in rlwrap, and it's working great.

$ cat ~/bin/clojure
#!/bin/sh
exec rlwrap java -jar ~/src/clojure/clojure.jar

no comments |

Grab Conference with Hpricot

Posted by Hans Fugal Mon, 07 Apr 2008 12:43:52 GMT

So you slept through a few sessions of conference (or you were distracted by the computer or stuck in the bathroom with a potty training toddler). The natural thing to do is to listen to sessions one at a time on your mp3 player over the next week or two. But it would be too much work to go to the archives website every day to download the appropriate session, then sync your mp3 player. No, you need to download them all now. But clicking on each one is tedious at best.

Enter a script. Now I've done something like this in the past with just sed and grep, but this time I thought I'd skip the sed trial and error and practice some Hpricot. It was quick and painless:

require 'rubygems'
require 'hpricot'
require 'open-uri'
CONFERENCE_URL="http://www.lds.org/conference/sessions/display/0,5239,49-1-851,00.html"
doc = Hpricot(open(CONFERENCE_URL))
puts (doc/"a").map{|a| a['href']}.join("\n")

That little script extracts all the urls from a URL. Well maybe there's a program that does that already. Maybe it's urlview, but an impatient google didn't find it in time (and urlview isn't installed on my laptop). Now you continue on with the grep magic:

./strip_urls.rb | grep mp3 | grep -v Complete | xargs wget

And you're on your way.

no comments |

Functional Floundering

Posted by Hans Fugal Sun, 06 Apr 2008 23:21:04 GMT

Levi pointed me to a presentation on Clojure, "a dynamic programming language for the JVM". That's actually a pretty bland description. I'd describe it at least as a dynamic functional concurrency-oriented lispy language for the JVM. The presentation was interesting, though I wish I had been able to follow the ant colony demo (it's audio-only).

It awakened the oft-recurring "functional floundering" feeling. I've written a semester worth of scheme in a programming languages course. I've read the Erlang book and written a little Erlang code. I recently went through a graduate course in programming languages with emphasis on denotational semantics. I understand the lambda calculus, functional programming, etc. But I feel completely stymied whenever I think about actually programming in a functional language.

I'm not sure what the root is, but I'm sure it boils down to lack of practice. That undergraduate course aside, I haven't had any practice. And since that course was very handholding (too much in retrospect), I don't feel like I took any practical skill away from it. Yet I feel that in the future functional programming for concurrency will be important, even if I'm not convinced it will be essential.

So I don't have time right now to really rectify the situation, but that doesn't stop me from wondering—how does one learn practical functional programming? What problem sets do you work through to get the needed practice? I suppose the question can apply to learning any new language, but there is much paradigm carry-over between imperative languages (and probably between functional languages). Are there certain problems that will aid that paradigm shift? If you feel like you've developed functional chops, in any functional language, I'd like to hear in the comments how you got there, what you'd change in retrospect, and your advice for me and others like me.

1 comment |

iptables doesn't do TOS/DSCP masking

Posted by Hans Fugal Sat, 29 Mar 2008 14:14:00 GMT

iptables, I'm really disappointed in you. If I'm reading your manpage correctly, and the NAG says that I am, you don't support matching or setting the TOS field (whether as a TOS byte or as the DSCP 6-bit subfield) with a mask. You can only match exact values.

That's just about pretty much useless. And considering that ipchains did let you do masks (although it was a cumbersome and-mask and xor-mask pair), inexcusable. One could use -m u32, but this doesn't seem to be available in OpenWRT. Luckily the goal is to mark packets for QoS, and I can just drop into tc directly to accomplish what I need. So to match any packet with the low delay bit set,

tc filter add dev $DEV parent $PARENT protocol ip u32 \
    match ip tos 0x10 0xff flowid $FLOW

no comments |

sh.vim

Posted by Hans Fugal Sat, 29 Mar 2008 06:38:58 GMT

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.

no comments |

Older posts: 1 2 3 ... 36