Seeing the Tour of California

We had a real treat today. We got to see the end of stage 6 of the Amgen Tour of California at Snow Summit. What’s interesting is that, not knowing about the race, we had originally intended to come up to Big Bear Lake on Friday night. At the last minute, we decided to drive up on Thursday night instead, which allowed us to take a stroll over to Summit Boulevard to see the race.

If I’d known about the race and the day’s events ahead of time, I may have brought my bike, to participate in the King of the Mountain Challenge:

The morning of the race, participants can ride on the same course as the professionals, just hours before the Pros make it to Big Bear. Start at the finish area at 10:00 a.m., ride to Snow Valley and then back through the finish line.

As a fan of the Tour de France, I’ve always wanted to see a race live. Watching a bicycle race live is not at all the same as watching a race on television, where you get to follow the riders for the length of the course. No, it’s all about the anticipation when viewing in person. The riders come up the road, pass you by, and are gone. Just like that.

I’ve included a copy of the spectator map from the Big Bear Climb and marked our location with a red dot. There were activities at the finish line that we didn’t partake of, and that’s where most of the crowd was. Only a few people were on the north side of Big Bear Boulevard, providing me an excellent view of the race.

The final stretch of stage six took the riders up Summit Boulevard, to the finish line at Snow Summit.

Very few people were on the north side of Big Bear Boulevard, leaving me ample space to observe the race and take pictures.

Perhaps a dozen or so escorts from the California Highway Patrol passed us, making sure the road was clear ahead of the riders.

Here comes the stage winner, Sylvain Georges of AG2R La Mondiale.

About a minute and a half later, the peloton rounded the last turn.

Bringing up the rear for this mountain finish is the polka dot jersey. According to the race web site, Sébastian Salas kept the jersey, so he must have fallen back near the end of the stage.

Automating On Call Jury Instructions

A version of this article is also published on my Perl blog.

Early in February, I received a jury summons for the United States District Court, Southern District of California. Prospective jurors for federal jury service (at least in this court) are placed on call for a period of about 30 days. I was to call for instructions on April 1 and potentially proceed to do so periodically until May 4 (assuming I wasn’t instructed to report).

Since my initial instruction date was nearly two months away, I created an entry for it in Google Calendar, and promptly forgot about it. On Monday, April 2, I was riding the train to work when I realized that I hadn’t remembered to check my instructions. Fortunately, after arriving at my office and checking my instructions, I had been deferred to the next day.

So I added a new entry in Google Calendar, this time with an SMS reminder. I proceeded to do this for most of April, checking my instructions and duplicating the calender entry with another SMS reminder.

I’m embarrassed to admit that it wasn’t until the last week of April that it occurred to me that I could automate the whole process. After all, isn’t automating drudgery the whole reason I ended up programming Perl in an engineering support group at my day job?

In addition to a telephone recording, jury instructions can be obtained online. In fact, this is the method I used all month. The form uses the HTTP POST method, so it wasn’t a simple matter of constructing an URL to fetch my instructions. While I could construct a POST request with curl(1) or the LWP module, it’s so much easier to do with with the WWW::Mechanize module.

my $mech = WWW::Mechanize->new();
$mech->get('http://jury.casd.uscourts.gov/AppearWeb/Default.aspx');
$mech->submit_form(
    form_name => 'Form1',
    fields    => {
        'ctl02$txtPart' => 'PARTICIPANT_ID',
        'ctl02$txtZip'  => 'ZIP_CODE',
    },
    button => 'ctl02$btnInstructions',
);

When I’m not supposed to report, the following message appears in the returned content:

<span id="ctl02_lblMsg">Please check again Sunday, April 29, after 6:00pm for further reporting instructions. Do NOT report at this time.</span>

Given how simple this is, I could parse it with a regular expression. But, I figured it was worth trying to do it right, so I searched CPAN and found the HTML::DOM module. I’ve worked a bit with DOM in JavaScript, so the module appealed to me. Annoyingly, the parse method only supports file names or file handles. Fortunately, this isn’t terribly difficult to work around and the whole thing isn’t much more verbose than using a regular expression.

my $dom = HTML::DOM->new;
$dom->parse_file( IO::Scalar->new( do { my $c = $mech->content; \$c } ) );
my $message = $dom->getElementById('ctl02_lblMsg')->innerHTML;

Now that I have the message what does it say? Thus far my instructions have always been to check again on another day, so I’ll need to work with what I know and defensively code for the exceptions.

if ( $message !~ /Do NOT report at this time/ ) {
    # We didn't see the message we wanted to see, so we'd better alert...
}

If I don’t see the known message, I send myself an alert (I happened to use the Email::Sender module in the script) and exit. If this happens, I’ll need to address it as it probably means I need to report (or I’m no longer on call).

However, if I do see the above message, I need to figure out when I’m supposed to check again. If this fails for some reason (e.g., I don’t know what the format looks like if the day is a single digit), I go through the alert process again. It’s rather important that this script be noisy, given the nature of what I’m doing and the limited knowledge I’m working with.

if ( $message !~ /Please check again (?<weekday>\w+), (?<month>\w+) (?<day>\d+)/ ) {
    # We couldn't parse the next date to check, so we'd better alert...
}
 
my $dt = DateTime::Format::DateParse->parse_datetime("$+{'weekday'}, $+{'day'} $+{'month'} 18:15");

I’ve hard-coded the time to check as 6:15 PM, because the instructions are always updated at 6:00 PM.

Finally, the script schedules itself to run again at the time indicated. Here I’ve broken out of Perl to use the at(1) command. Since I’m running the script on my Linode VPS, this seemed an easy way to accomplish the task of rescheduling.

open my $at, '|-', 'at', $dt->strftime('%R'), $dt->strftime('%F');
say {$at} "$0 2>/dev/null"; # $0 must be fully qualified or in PATH
close $at;

Running this script once will set the rescheduling process in motion, alleviating me of the need to run it again. If I’d thought of this at the beginning of April, I could have forgotten about the whole bother of checking for instructions several times per week. Oh well, live and learn.

I’ve posted the full script as a Gist on GitHub.

As a way of outsourcing the work and perhaps offer this type of service to a wider audience, I looked at ifttt and Yahoo! Pipes. Unfortunately, the former doesn’t appear to have a way to trigger on scraping an arbitrary web page, and the latter doesn’t appear to support the HTTP POST method. If anyone knows of an approach using existing services, I’m open to suggestions.

Updated on 30 April 2012.

Mojo::UserAgent

Posting this on blogs.perl.org resulted in a few comments (including a rant I completely agree with, but that’s beside the point). There was one suggestion that I try using Mojo::UserAgent instead of WWW::Mechanize.

My first attempt at doing so wasn’t particularly successful. After a while, I realized that I needed to manually do some of the work that WWW::Mechanize was doing for me. Namely, fetch the page, extract the hidden fields, and submit the form with these fields included (there’s a cookie involved, but it’s taken care of behind the scenes by both modules).

Because of this, the Mojo::UserAgent version is a bit more annoying to write, but I think this is more than made up for by the built-in access to the DOM.

my $ua  = Mojo::UserAgent->new;
my $url = 'http://jury.casd.uscourts.gov/AppearWeb/Default.aspx';
my $res = $ua->get($url)->res;  # initial fetch to get cookie and form fields
my $tx  = $ua->max_redirects(3)->post_form(
    $url => {
        '__VIEWSTATE'           => $res->dom('form#Form1 > input#__VIEWSTATE')->[0]->attrs('value'),
        '__EVENTVALIDATION'     => $res->dom('form#Form1 > input#__EVENTVALIDATION')->[0]->attrs('value'),
        'ctl02$txtPart'         => 'PARTICIPANT_ID',
        'ctl02$txtZip'          => 'ZIP_CODE',
        'ctl02$btnInstructions' => 'Reporting Instructions',
    }
);
 
$res = $tx->success or die $tx->error;
my $message = $res->dom('span#ctl02_lblMsg')->[0]->text;

WWW::Scripter

As I was working on the Mojo::UserAgent version of my script, I kept thinking how perfect it would be if WWW::Mechanize gave me access to the DOM in the same way. Well, as I was pushing the new jury-mojo.pl script to my Gist, cpansprout left a comment to not only tell me how I could remove my IO::Scalar hack, but that WWW::Scripter does exactly what I had just been wishing for. It’s like he read my mind.

my $mech = WWW::Scripter->new();
$mech->get('http://jury.casd.uscourts.gov/AppearWeb/Default.aspx');
$mech->submit_form(
    form_name => 'Form1',
    fields    => {
        'ctl02$txtPart' => 'PARTICIPANT_ID',
        'ctl02$txtZip'  => 'ZIP_CODE',
    },
    button => 'ctl02$btnInstructions',
);
 
my $message = $mech->document->getElementById('ctl02_lblMsg')->innerHTML;

I like this last version the most and have updated my Gist accordingly. Also, my automation worked and emailed me tonight to inform me that my jury service has concluded.

Broccoflower Curry Rice

As I noted in my last post, I had planned to try the broccoli and cauliflower combination again using a different method. Over the weekend, I picked up two broccoli florets and one head of cauliflower at the farmers market.

To prepare the broccoli and cauliflower, I chopped them into pieces small enough to fit into the hole in the top of my Cuisinart food processor. Replacing the blades with the shredding disk, I tediously pushed all of the vegetables through the spinning steel. This pretty well filled my 14 cup food processor, so keep that in mind when deciding how much to make. At first I thought I had made too much, and that the labor wasn’t worthwhile, but I’m thoroughly enjoying the leftovers.

I heated a few tablespoons of extra virgin olive oil in a 12 inch stainless steel frying pan, emptying the entire contents of the food processor bowl to it. To this, I added ample amounts of salt and curry powder. While stirring, I occasionally added more oil, since broccoli and cauliflower are pretty dry vegetables and will readily absorb it.

I need to get some white dishes, so I can take better pictures

It’s a pretty simple recipe and, while I was initially skeptical, it turned out downright amazing. The best part is, having given up rice and other grains, I finally have a staple I can use to soak up sauces.

If you try out this recipe, let me know in the comments what you used for flavor and how it turned out. Enjoy!

Coconut Curry Chicken with Broccoflower Couscous

For a couple of weeks, I’ve been posting my dinner creations to Facebook. I’ve been doing this for three reasons. First, a lot of people don’t know what they would cook when following a paleo lifestyle, so I want to share what I make after living this way for a couple of years. Second, I hope to inspire my friends and family with these meals. Finally, I like to show off.

The more mundane and repeated meals will probably remain as short posts on Facebook. However, I’d like to capture some of these dinners on my website. This will allow me to share with a wider audience as well as being a better archive of recipes.

Inspired by a post on Richard Nikoley’s website, I’d been thinking about trying Nacho Rubio’s curry chicken dish.

Instead of crafting my own curry powder (which I will do someday), I used curry powder from Trader Joe’s. I stirred about two tablespoons of it into about two tablespoons of extra virgin olive oil in my 12″ cast iron skillet. While the mixture was heating, I sliced one package of boneless and skinless chicken thighs into bite sized pieces, which I added to the skillet to cook. When the chicken was cooked through, I added 3/4 of a can of Trader Joe’s light coconut milk, turned up the heat, and let the moisture boil off until I was rewarded with a thick sauce.

While the chicken was cooking, I put two heads of broccoli and one head of cauliflower into the food processor to blend. For a while, it looked like I was making baby food. Once I got the broccoflower mixture into a 12″ stainless steel skillet with several tablespoons of Kerrygold butter and some salt, it started gaining a couscous-like texture.

Updated: I should point out that it was difficult to get the broccoli and cauliflower to process properly. I had overfilled the food processor’s bowl and without a liquid the larger pieces tended to bounce off the blades rather than being pulverized by them. Next time I prepare this, I will probably use the shredding blade (the one that mounts the blade at the top of the bowl) and plunge smaller pieces through it. If I do, I’ll be sure to report my results.

That was it, simple as that. I think it turned out pretty tasty.

After dinner, I treated myself to a cup of Turkish coffee, which I’m enjoying as I write these words. The coffee was Sumatra Blue Batak from Peet’s Coffee & Tea, to which I added turbinado sugar, cocoa powder, cinnamon, and nutmeg.

Repeated Capturing and Parsing in Perl

When I checked my email after arriving at the office today, I found a query that had been sent to our internal Perl mail list. The questioner was trying to match a pattern repeatedly, capturing all of the results in an array. But, it wasn’t doing quite what he expected. The message, with minor edits, went a little something like the following.

I’m trying to extract key/value pairs from a file with the following contents:

- name = gcc_xo_src_clk, type = rcg
+ name = cxo_clk, type = xo, fgroup = xo, wt = 10, bloo = blah
? type = hm_mnd_rcg, name = bo : type = rcg_mn
+ name = pxo_clk

I was hoping to do something like this:

@list = $_ =~ m{ ^[-+?] \s* (\S+) \s* = \s* (\S+) \s* (?:, \s* (\S+) \s* = \s* (\S+) \s*)* }xms;

Thinking @list would be assigned the alternating key/value pairs. But the above doesn’t extract anything sane. Adding the /gc modifiers doesn’t make any difference.

If I do the following, it extracts the first two key/value pairs correctly (if the line has more than one pair).

@list = $_ =~ m{
    ^[-+?] \s* (\S+) \s* = \s* (\S+) \s*
    , \s* (\S+) \s* = \s* (\S+) \s*
}xms;

If I keep repeating the pattern in the second line, it keeps matching more key/value pairs.

I would expect using (?: )* should mean zero or more instances of match inside the parentheses, but obviously it’s not working. What am I doing wrong?

When I’m presented with a problem like this, that is some kind of structured data, I immediately think of writing a parser. I’ll get back to that in a bit, but I wanted to address the confusion about capturing in the pattern. And, in fact, that’s how the discussion on the mail list proceeded.

Repeated Capturing

First, let’s simplify the example to demonstrate why our seeker of wisdom isn’t getting back the list of items he expected.

my @matches = 'a b c d e' =~ /^(a) \s* (?: ([bcde]) \s* )*/xms;

say "(@matches)";   # prints "(a e)"

Capturing parentheses in Perl are treated somewhat like registers. Most Perl programmers are familiar with the $n variables, which hold the values of a successful pattern match. For example $1 holds the value matched by the first set of parentheses, $2 holds the value of the second set, and so on.

When a pattern is matched in list context, as above, it’s effectively the same as writing,

'a b c d e' =~ /^(a) \s* (?: ([bcde]) \s* )*/xms;

my @matches = ( $1, $2 );

These pattern match variables are scalars and, as such, will only hold a single value. That value is whatever the capturing parentheses matched last. So, in our simplified example, $1 matches a, which is obvious enough. As the pattern repeats, $2 would be set to b, then c, and so on until the final match of e.

That explains why the pattern match wasn’t returning the expected list. What can be done about it?

Capturing Along the Way

If we break down the sample data, we see that it generalizes to,

prefix key = value[, ...] [: key = value[, ...]]

The first approach that came to mind is to split the data into multiple lines. Each line can then have its initial prefix removed and saved, then parsed for its key/value pairs. That’s starting to look a lot like parsing, which I promised to get to later. For the purposes of this discussion, I wanted to be able to accomplish the task with a single regular expression.

To capture all of the values we want, we need to remove the repeating set of non-capturing parentheses. However, we still need to repeat the match, ideally returning all of the captured values in one statement. We can do that with the /g and /c regular expression modifiers.

my @list = $string =~ m{ ([-+?,:]) \s* (\w+) \s* = \s* (\w+) \s* }xmsgc;

I’ve done two things here. First, I replaced the \S character classes, used to match the key and value, with \w. The + pattern in a Perl regular expression is greedy, so the former character class was also matching the comma used to separate key/value pairs in the data. This left the literal comma with nothing to match, so was one source of confusion.

Second, I noted that the initial prefix, while syntactically important, could be viewed in the same way as the comma and colon separators. I combined all of these separators and added a capture around them so we can later make sense of the parsed data.

When matched against the data, the pattern results in a list like,

("-", "name", "gcc_xo_src_clk", ",", "type", "rcg", "+", "name", "cxo_clk", ...)

Now we can process the data using a simple state machine.

my $state = undef;

while ( my $token = shift @list ) {
    if ( $token eq '-' ) { $state = 'dash'; next; }
    # ...
    if ( $token eq ',' ) { next; }

    my $key   = shift @list;
    my $value = shift @list;

    if ( $state eq 'dash' ) {
        # ...
    }
}

Even though we did all of the data extraction using a single pattern match, it looks remarkably like … a parser! The pattern is simply the tokenizer used to feed tokens into our state machine, the parser.

Parsing

I stated at the outset that I looked at this as a parsing problem, so the solution I would use is most likely a parser. For simple, one-off scripts, I’d use a technique similar to the one I described in the previous section. However, for more complex data or a more complex script, I’d turn to a real parser.

In fact, one of my contributions to the thread that led me to compose this post included an example of using the $^R and $^N variables in embedded code blocks to demonstrate a rudimentary parser that allowed a simulated form of capturing within a repeated non-capturing group. I won’t go into any detail beyond showing what I wrote. As this was from an early point in the thread, the prefix is ignored in this example.

my @list = ();

my $kv = qr{
    (\w+) (?{ $^N; })           # capture the key
    \s* = \s* (\w+)
    (?{ $^R = [ $^R, $^N ]; })  # capture the value, saving the key
    (?{ push @list, @{ $^R } }) # push the key/value onto @list
}xms;

$data =~ m{ (?: ^[-+?] \s* $kv \s* (?:[,:] \s* $kv \s* )* )* }xms;

Fortunately for us, there are parsing modules on the CPAN.

Prior to Perl 5.10, Damian Conway had written Parse::RecDescent, but with the introduction of grammar-like facilities like named captures and named backreferences, Damian improved upon his original work and presented the Perl community with Regexp::Grammars.

What does a parser for this data built with Regexp::Grammars look like?

my $parser = qr{
    <[Line]>+

    <token: Prefix>   <MATCH= ([-+?]) >
    <token: Key>      <MATCH= (\w+) >
    <token: Value>    <MATCH= (\w+) >

    <rule: Line>      <Prefix> <Pairs> <Options>?
    <rule: Pairs>     <[Pair]>* % ,
    <rule: Pair>      <Key> = <Value>
    <rule: Options>   : <[Option]>* % ,
    <rule: Option>    <Key> = <Value>
}x;

if ( $data =~ $parser ) {
    # Do something with %/
}

This is a trivial example and all the work is left to be done by inspecting the parse tree in %/. However, the module supports embedded code that will be called when a token or rule matches, which can be used to process the data as its parsed.

References

Looking Ahead to 2012

One year ago in this space I attempted to start a new tradition for myself. While I rarely bothered in the past, mostly as an excuse to write a post, I jumped on the bandwagon and composed a set of resolutions for 2011. Now, in the waning hours of 2011, I wanted to take some time to review my resolutions and update them for 2012. Let’s take them from the top.

Spend more time with my daughter.

That should now read daughters, plural. In June we welcomed our second child, Brenna Rose, into the world. I’d like to think I’ve done well on this resolution. I spend every day looking forward to getting home to see my girls.

Read more.

I added this to the list because every year I would read a little less than the year before. I’ve managed to reverse this trend. Sure, I’ve added feeds to Google Reader, but I’ve removed a few as well. I’ve also opted to read actual books in my free time, reducing the amount of television I watch to a mere couple hours per week. I’ve read through two James Herriot books so far, with one remaining. I received a Barnes & Noble Nook for Christmas and purchased my first book for it on Thursday, The Ghosts of Belfast, which I’ve been rapidly devouring.

Write more.

While I frequently sat in front of my computer, pondering topics about which to write, I rarely found the necessary inspiration to put metaphorical pen to paper. Over the last 12 months, I composed a mere 16 posts. Four of those, a quarter of them, were about OSCON, which is far fewer than in years past when I would write an individual post for each session I attended. In addition, there are four drafts I never got around to completing. Looking them over, it appears that at least three of them are mostly done. I just need to give them a quick edit and post. Sadly, one of them is about Kaylee’s summer camp, so it’s a bit stale at this point.

Having read several blogs over the last year, I’ve developed a desire to be a more prolific writer. Not only personal posts, like this one, but anything that comes to mind. I can write about my programming work or even short fiction. I probably won’t delve into the realm of political commentary, but only because I lack any real desire to study the issues in enough depth to do them justice.

Be more Paleo.

More of the same here. I can count on one hand the number of bites of grains I had during the year. While my sweet tooth has been difficult to suppress, I really don’t eat very much sugar. One beer per week, to end Friday on a high note, is all I indulge in anymore. I managed to get my weight down to 158 pounds, which hasn’t budged in a few months. I would like to drop a few more pounds of body fat, so perhaps that is where I’ll focus my efforts for 2012.

Join a CrossFit Box.

I thought about it a few times, but never bothered. I have been going to the gym at work regularly and have been making decent strength gains. I’m mostly pleased with my progress on fitness and even earned my third degree black belt this year, so not accomplishing this particular resolution isn’t bothering me very much.

Get into MovNat.

The closest I got to this was our recent trip to Grape Day Park in Escondido. As a fitness program, it’s still something I want to do.

Actually use Facebook.

I added this one as a joke, but somehow I ended up using it. Sort of. I rarely post anything on Facebook, preferring Twitter and Google Plus, but I do try to keep tabs on what my friends are doing.

Looking Ahead to 2012

Aside from the above, what else should I look forward to doing in 2012?

I’ve recently been putting an emphasis on being more organized and getting things done in a more timely fashion. I’d like to keep this going into the new year, particularly with respect to the things that need doing around the house.

Segueing from organization into preparation, the recent power outage in San Diego made me take a serious look at our disaster preparations. My wife pokes fun at me for treating the entire situation as preparation for the zombie apocalypse, but I find it a fun way to stay motivated. Besides, when zombies show up and start eating people, who will be laughing then?

So that’s my theme for 2012: organization and preparation.

Grape Day Park

Over the weekend my wife and I took the girls to meet up with some friends. Our original plan was, after having lunch, to spend some time at the San Diego Children’s Discovery Museum in Escondido. However, after a couple of changes in that plan, we ended up at Grape Day Park, which happens to be adjacent to the museum.

Jump!

Action shot of me leaping from the grape slide.

The distinguishing features of the park are the slide, designed to look like a bunch of purple grapes, and Vinehenge. The latter feature is pretty awesome. It is a sculpture, by artists Valerie Salatino and Nancy Moran, of giant grape vines, which serves as an intricate climbing structure.

I couldn’t help myself. As soon as I saw the grapes and vines, I was all over them. I climbed from the bottom to the top, walking with all four limbs like a monkey. I leaped from the ground to the high vines, hauling myself up to perch atop them. I may have gotten more out of the vines than the kids did. Although, my daughter dubbed the tangle of vines the Spooky Forest, which from that point on was only to be entered with caution, not climbed upon.

We’ll definitely have to make this park a regular stop.

2011 Boot Camp Challenge

A little over a week ago, on Saturday, 24 September 2011, I participated in the MCRD San Diego 2011 Boot Camp Challenge. This is a short, three mile race that, according to the website, has over 40 obstacles, including hay jumps, tunnel crawls, log hurdles, a six foot wall, trenches, cargo net crawls, and push-up stations. In addition, United States Marine Corps drill instructors are positioned at each station to make sure each obstacle is properly completed.

It’s a fun course, as depicted by the map over on the left. The numbers on the map represent: (1) hay stacks; (2) hay stacks; (3) hay stacks; (4–19) jump over logs, crawl under logs, wall; (20) tunnels; (21) push-ups; (22) wall; (23) bayonet; (24) trenches; (25) tunnels; (26) low crawl; (27) planks; (28) push-ups; (29–43) jump over logs, crawl under logs, wall; (44) hay stacks; (45) hay stacks.

There are a lot of hay stacks on the course, and for good reason. Nothing breaks up your pace and depletes your muscles of glycogen quite like explosively leaping over hay stacks. Then come the obstacles. My group, the individual men, started the race early enough that I never had to stand in line to wait for an obstacle (I saw several lines in the photos of later groups). This is good for time, but exhausting as you sprint from one obstacle to the next only to do something that is very much not running.

If you’re anything like me, you saw number 23 and thought, “Bayonets?! Awesome!” At least, that’s what I thought when I first looked at the map. Yeah, not so much. We were allowed to run past the bayonet targets, and that’s it.

I had done this race once before, in 2004, but it has taken me seven years to finally do it again. That year I raced in a team of three with a couple of my friends. I don’t remember how we placed and the results are nowhere to be found, so I’ll just assume we didn’t do very well. Probably a good assumption, as the race was a week after my honeymoon and I recall being some 40 or so pounds heavier at the time.

I entered the race this year mostly as a test of my fitness. Was this paleo lifestyle thing really working out for me? Doing nothing more than three weeks of eating well, twice weekly body weight workouts, and once weekly sprints, I ran the race. I haven’t run more than a quarter mile since, well, since probably the last time I ran this race.

The results are here. Just in case that page vanishes, as most of the past results seem to have done, I’ve mirrored the page on my website, highlighting my result. I came in 47 out of 91 in my division and 340 out of 1,117 overall. Interestingly, my time of 26:44 would have put me 36 out of 48 in the mens elite division. Although, given the under 20 minute time of the first 10 people in that division, I don’t think I’ll ever race in it.

I’m sure I could have done better with more training, but my time was lower than I expected it to be. On the rare occasion that I do use a treadmill, it tells me that I run a 12 minute mile. So an average mile time of 8:55 for the race surprised me a bit. Back in high school, I could run a six minute mile, so I’ll consider that my new goal.

When I chose to wear shorts for the race, my wife asked me if I was worried about injuring myself on the obstacle course. Of course, I told her I wasn’t. I took the picture over on the right shortly after I got home from the race. I would call that relatively uninjured. Worst by far were my calves, which were sore for days, having run the race in my Vibram FiveFingers KSOs.

Overall, it was an incredibly fun race, and I can’t wait to do it again next year. I already have my calendar marked for Saturday, 6 October 2012. That’s over two months before the world ends, so I’m confident things will go off without a hitch. Next year I’ll try to get my time down to around 20 minutes.

San Diego Goes Dark

At approximately 3:35 this afternoon, I was standing in the hallway outside my office, talking to my boss and a coworker. It’s a very odd feeling when the power to the entire building goes out. Everything goes absolutely silent. I never appreciate how much noise the air conditioning, the computers, and even the vending machines make until it’s gone and the stillness sets in. A few seconds later, having given us enough time to pause and understand what was happening, the backup power kicked in, restoring light to the hallway. Looking at the time, I immediately decided to catch the 3:45 shuttle, which would get me on the 4:06 northbound COASTER home. As I sit here writing, reflecting on the afternoon, I’m grateful that I didn’t hesitate.

I received a text message from my wife as I was leaving the building, informing me that power was out at home, 20 miles away from my office. As I sat on the shuttle, listening to the chatter of the San Diego MTS radio, I learned that power was out across the county. I was relatively confident that the trains would continue to run, as they are self-powered and the railroads have radio procedures they follow when the signals lose power. Still, I was relieved when my train pulled into the Sorrento Valley station right on time. The trip home took much longer than usual, while the train proceeded slowly and waited for clearance over the radio. During the ride, I followed news about the power outage, and kept my dad up to date on my status, on Twitter. Fortunately, Verizon’s cell towers remained online.

Traffic was abysmal around the county by the time I arrived at the Carlsbad Poinsettia station, around 5:00 PM. I was fortunate, in that I only had a rough time until I crossed over the I-5 freeway. Most of my short, 7.5 mile trip between the train station and my house is done on less-traveled roads. Once into San Marcos, the traffic signals were operating on battery power, so the final few lights were even normal for me.

Finally arriving home shortly before 6:00 PM, I unplugged the computers and appliances—to safe-guard against possible surges when the power was restored—and prepared dinner. Fortunately, I intended all along to use the propane grill for dinner, so I didn’t have to alter our plans. We did end up eating our dinner by candle light, which is something we haven’t done in quite a while. After dinner, we finished off the chocolate ice cream, which was rapidly melting in the freezer. We spent the remainder of the evening listening to the news on one of our Eton crank-powered radios, all of which I’d selected as pledge gifts over the years from KPBS.

Our power was restored at 10:25 PM, at which point I plugged everything back in, set the few clocks we still have that don’t set themselves, and verified that the temperature of the refrigerator was okay. Then, as my brain wouldn’t let me go to sleep until I purged its thoughts into print, I sat down to compose this post. What did I do right today, and what lessons have I learned?

Know how you’re getting home. I was very lucky today. The power dropped minutes before the first MTS shuttle this afternoon, and I didn’t hesitate to take it. Further, the trains were still running. I do not have a backup plan for how I would get home otherwise. My parents live near my workplace so, barring a grave emergency, I’d likely wait things out at their house. Or, as I told my wife, chill out on the patio at Karl Strauss, knocking back a few pints.

Have portable radios where you need them. We succeeded here, having three of the aforementioned Eton radios. I had one in my car, but didn’t need it, since Verizon’s data network remained up the entire time. My wife has one in her car and we have one in the house, so she was able to listen to the news about the power outage. Our oldest radio doesn’t hold a charge for very long, so it may be time to replace it.

Have several flashlights in several locations, with batteries. Also, candles. We keep large Maglite flashlights in each of the cars and small tactical flashlights both in the cars and throughout the house. Between those and two boxes of candles from IKEA, we had plenty of light. Recently, we’d started moving to using rechargeable batteries for everything, which work great, when you have power to recharge them. I plan to purchase bulk packs of batteries in various sizes to store in an emergency kit, to be used only in emergencies. Speaking of which…

Have an emergency kit. We don’t really have one, though we didn’t suffer for it this time. Creating a plan and organizing a kit has been on my to-do list for a long time and it’s about time I take care of it.

Keep non-perishable food on hand. We’re somewhat okay on this. We have bottled water and canned food, though I don’t think we have enough for three days. I intend to remedy this on our next trip to Costco. In fact, I’ve been making a mental checklist of food items to stock for while. Canned meats are high on the list, followed by dried fruits, and water. Lots of water.

Know where to get news. I was fortunate that Verizon’s data service remained online. Between listening to KOGO and reading Twitter, I had a pretty good idea of what was going on. The Twitter accounts I found the most useful today were, @SDGE, @SanDiegoCounty, @ReadySanDiego, @SDSheriff, @GoNCTD, @KPBSnews, and @nctimes.

Have your bug out bag (BOB) packed and your cars fueled. While we don’t have bug out bags, we do keep the cars fueled. I decided long ago to never let the fuel tanks drop below half, because you never know when you’ll need to drive somewhere without the opportunity to refill. Obviously, these precautions were unnecessary today, but non-emergencies like a widespread power outage give us the opportunity to think about what we need and test our preparedness without great risk. What if this had been a wildfire or an earthquake? Would we have been ready to evacuate at a moment’s notice? I’m sad to say, probably not. That leads to my most important lesson…

Know what to do. I need to make sure my family and I are on the same page if a disaster occurs, even if we are unable to communicate. Under what circumstances do we evacuate? Where do we go? What if our primary choice is unreachable? What if, as is likely the case in San Diego, the roads are jammed? As important as knowing when to go is knowing when to stay put and for how long.

There are lot of considerations that go into designing an emergency plan and I know I didn’t go into all of them here, nor did I intend this to be a comprehensive list. These were just the main things I’ve been thinking generally about lately and specifically about today. When I do make our emergency preparation, I’ll likely follow up with another post. If anything, it will serve as documentation for my immediate and extended family. Now that I’ve put my thoughts into print, maybe my brain will let me sleep.

Farewell Rubio’s

Once one of my favorite restaurants, you and I simply don’t get along anymore.

I had food from Rubio’s for lunch today, brought in by the company hosting my colleagues and me for some technical training.  Not long after lunch, my asthma began to act up.  Since going Paleo several months ago, my daily inhaler and I have practically parted ways.  However, this evening I felt that I needed it.

A few weeks ago, I had dinner at Islands, where I indulged in some corn chips and salsa.  The following day, I needed my inhaler.  I, perhaps wrongly, concluded that grains, at least corn, were a trigger and have been much happier to avoid them ever since.

It should go without saying that I passed on the tortillas served alongside lunch today.  Nevertheless, not long afterwards I felt that all too familiar tightness in my chest, resulting in the use of my inhaler tonight, after two weeks without.

If I had to guess, I’d say it was the liberal use of soy in the cooking (is it to save money or demonstrate that the food is supposedly heart healthy?) that proved today’s trigger.  I don’t know what specifically was the cause, as it could be any one of soy’s negative properties, or even several in combination.  In the end, this is just further encouragement to avoid eating out.

Except for Elevation Burger (their site appears to be Flash-based, sorry).  That place is awesome.