Questioning Coffee Geeks with Science

Monday, October 19th, 2009

There are a few people I work with who are very passionate about coffee, which is something I enjoy very much as well, and have been known to geek out on.

Recently, I passed around this video from Sweet Maria’s, which is one of the bean providers the most enthusiastic of said co-workers shops with.

The Sweet Maria’s gent claimed as an aside in that video (which really raises the bar on coffee geekery, truly impressive) that one should always weigh one’s water, as the volume changes when it is heated.

I get that the volume changes, but it seemed to me that it can’t change that much. I realized this weekend that I had a way to find out exactly how: WolframAlpha. I just had to ask it Volume of 1kg of water at 90 degrees Celsius and, lo and behold, it knows!

Curious, I punched in a few more numbers, and made the following chart:

Water Volume vs Temp.png

So the water expands a pretty impressive 3.5% on it’s way from “very cold” to “coffee temp”. Assuming you start with water which is not totally chilled, however, the expansion starts to become less of an issue.

So, does it matter to most of us — no. We probably don’t measure our water within 3.5% accuracy on the best of days, anyway. (And if you have a hot water machine, like we do, which happens to dispense perfect temp water anyway, you’re measuring pre-expanded.)

But if you’re making any kind of serious volume, 3.5% might actually start to have an impact. It’s at least a sip out of a cup.

I’d say we have to call this geek “Plausible.” But I’m still not weighing my water.

Aside: if anyone knows how to use WolframAlpha to actually make a chart like this, let me know. It seems like it should be doable, I just couldn’t finesse my query in such a way to make it happen. OmniGraphSketcher to the rescue.

FlickrPress now available: Turns Flickr RSS to WordPress Posts

Friday, October 16th, 2009

My wife and I like to post a lot of photos of our son to his blog.

Carter's Site

After using WordPress from both the browser and the iPhone client, I just wasn’t that happy using it for our pictures. On the other hand, we both love (and already use, and have Pro accounts on) Flickr.

Having the photos “live” on Flickr means some handy things.

  1. They let you get an RSS feed of a tag. (We use ‘carterbarratt.’) This means we don’t even have to use an API key, which is convenient.
  2. They always have an image available that’s sized to 500 on the longest side. This turns out to be a perfect image size (either height or width) for a lot of WordPress themes.
  3. They handle video and make the thumbnails look exactly like a “non-video image” in the RSS feed.
  4. Lots of things can upload to Flickr — we use mostly the desktop uploader (after exporting from Lightroom) and the new Flickr native client on our iPhones.
  5. The exact same stuff (title, description) that I’d want on a photo blog is available when I upload to Flickr.

So, FlickrPress was born. It’s a fairly simple perl script, intended to be run as a cron job, which uses WordPress::Post to create new blog posts for every flickr photo it finds with a certain tag, from certain users.

FlickrPress Workflow

Check out the FlickrPress page for downloads and installation instructions.

Testing perl system interactions

Tuesday, October 6th, 2009

A lot of the code I end up needing to work on makes calls to various executables to read and process system state. It might be DTrace, or one of the tools that comes with the Virtuozzo/OpenVZ management suite, or one of the HP hardware monitoring tools — they all want to be called from the command line.

In the old days, I probably would have just used perl backticks to run the command and capture the output. I’d “test” on a machine that had those tools installed, and call it a day.

my $output = `some system command`;
# process the output here

However, that’s pretty evil, and it’s essentially untestable.

Here’s a pattern that works pretty well.

The IPC::Run module includes a ‘run’ command, which in the simple form takes 4 references: To a list of a command and it’s arguments, and then scalar references for the contents of Standard In, Standard Out, and Standard Error.

If all you care about is capturing STDOUT, you might call it like:

my @raidstate = ("hpacucli", "'controller slot=0 physicaldrive all show'")
my $raid_output;
IPC::Run::run(\@raidstate, \undef, \$raid_output, \undef);

Ok, but how does that help us test?
Enter the venerable Test::MockModule.

All I need to do is override the run() function for the module in my test!

use Test::MockModule;

my $module = new Test::MockModule('IPC::Run');
$module->mock('run', \&mock_ipc_run);

Ok, so how do I get the right content to get in the $raid_output?

It depends on how exactly you’re calling run: I hand-tuned this for the specific use case I’m doing right now, where I just care about capturing output.

What we do is store a list of command lines in the data block, followed by their output. When someone calls ‘run()’ with one of those command lines, we send that output back to them.

sub mock_ipc_run {
    my($cmd, $stdin, $stdout, $stderr) = @_;
    # very important to rewind DATA so this subroutine can be called more than once
    seek(DATA, 0, 0);
    my $cmd_str = join(" ", @$cmd);
    while(<DATA>) {
        # iterate until we match the command name with '*' @ the beginning
        if(/^\* $cmd_str/) {
            while(<DATA>) {
                # until we find another command entry...
                if(/\*\s/) {
                    return;
                } else {
                    # pack the results into the $stdout reference we were given
                    $$stdout .= $_;
                }
            }
        }
    }
}

And the matching section in the DATA block:

__END__
* hpacucli 'controller slot=0 physicaldrive all show'

Smart Array P400i in Slot 0

  array A
   physicaldrive 1I:1:1 (port 1I:box 1:bay 1, SAS, 73.4 GB, OK)
   physicaldrive 1I:1:2 (port 1I:box 1:bay 2, SAS, 73.4 GB, OK)
   physicaldrive 1I:1:3 (port 1I:box 1:bay 3, SAS, 73.4 GB, OK)
   physicaldrive 1I:1:4 (port 1I:box 1:bay 4, SAS, 73.4 GB, OK)
   physicaldrive 2I:1:5 (port 2I:box 1:bay 5, SAS, 73.4 GB, OK)
   physicaldrive 2I:1:6 (port 2I:box 1:bay 6, SAS, 73.4 GB, OK)

And you’re done! This is nice and easily extensible. If you have several specific use cases (like output that actually starts with ‘* ‘, for example, or needing STDIN/STDERR) you’d need to modify it. It’s a handy general pattern for making “sysadmin code” a lot more like “developer code”, though. (The great thing is I was able to write and test this whole code suite on a VM that didn’t even have an HP raid controller, let alone hpacucli installed, for example.)