Golden Gate Park - Stow Lake, Stawberry Hill and Museum Concourse

Updated on Friday, February 24, 2017
Golden Gate Park - Stow Lake, Stawberry Hill and Museum Concourse

An alternative to our normal loop is another three mile walk starting from JFK and Transverse. Instead of heading towards the beach walk up under the bridge and take the first right to Stow Lake.

Stow Lake
Stow Lake surrounds Strawberry Hill. There's a path around the lake with two bridges leading to the hill. I normally walk to one bridge, cross and then up to the top of the hill. It's generally pretty quiet with great city and ocean views in between the trees.

Top of Strawberry Hill in the middle of Stow Lake
View from the top of Strawberry Hill. Rudy is in there somewhere, click for a larger version.

de Young Museum
After the hill I walk over to the Museum Concourse. The de Young rises through the trees like an implausibly stranded copper aircraft carrier. It hosts a range of paintings, decorative art, sculpture and modern art. You're bound to find something you like here.

de Young Museum (Side)
The copper cladding will turn green eventually, probably before the new Bay Bridge span is finished.

California Academy of Sciences
Opposite the de Young is the California Academy of Sciences. The Academy features an outstanding digital planetarium, a three story rainforest and an aquarium. It reopened last year after a major rebuild and it's insanely popular - get there first thing to snag the first come first served planetarium tickets.

Prayerbook Cross
On the way back I detoured up to Prayerbook Cross, donated in 1894 to commemorate the first English sermon on the pacific coast after Sir Francis Drake discovered Drake's Bay (a name which didn't stick).

(2.97 miles, total elevation gain 103 feet, 1 hours, 17 minutes, average 2.29 mph, view in Google Earth, view in Google Maps.)

Hike starts at: 37.770433, -122.479941.

StackOverflow DevDays

Updated on Friday, February 24, 2017
Fort Mason, San Francisco

Just got back from the StackOverflow DevDays event in San Francisco. I was a bit worried that this would be overly focused on marketing FogBugz and StackOverflow. There were brief pitches on each (and I learned that FogCreek is launching hosted source control and code reviews called Kiln, now in beta and looking pretty nifty with tight integration with FogBugz) but this wasn't the focus.

I was also a little concerned that I'd be the only one there without a StackOverflow profile t-shirt. Luckily I didn't see any reputation toting pod people at the conference.

Happily the day was very code oriented, and very diverse. Spell checking in Python, smartphone development for iPhone, Nokia (via Qt) and Android, ASP.NET MVC and jQuery. I spend most of my time at the moment in C#/.NET and it was really valuable to spend a day briefly diving into different stacks and platforms.

Joel said that they'd be back next year and I'm hoping that it offers a similar diverse range of topics.

Do I need a Zumbox?

Updated on Tuesday, September 25, 2018
Zumbox is trying to take the paper out of the postal system. It's a laudable goal, if it takes off it would stop me from feeling that I need to do this:

Junk Mail Solution

Signing up is easy. Enter your mailing address and Zumbox send you a letter with a verification code. Once verified you can start sending and receiving mail online. You can mail a few people for free, bulk mail is five cents per recipient.

Of course you'll only receive mail that has been sent to you via Zumbox. It's not a mail scanning service (like Earth Class Mail) so you end up with yet another mailbox to check.

Zumbox is trying to help businesses go paperless. This includes bills and other necessary communication. It also includes junk mail.

My experience so far is mainly junk mail. I did get a circular about recycling from Gavin Newsom but otherwise just a stream of special offers.

This is a big problem because Zumbox provides very little control over email notifications:

Zumbox Email Preferences

It's all or nothing. Either I get a daily email reminding me to go look at junk mail, or I get no notification at all (and might miss the next thrilling update from Gavin).

Most of my bills and statements are already paperless via email. This isn't as secure as Zumbox, but I'm not sure how much of an advantage this is as I really just need notification.

I really want to like Zumbox, but right now it's just another source of spam.

Blogger Classic Templates Bugs and XHTML

Updated on Sunday, May 3, 2020
I've just migrated this blog from catfood.net to its own domain. In the process I needed to port the template from classic ASP to ASP.NET and I also wanted to end up with valid XHTML.

If you're using blogger on your own domain then you're using the classic templates. There is a known issue with the template tag that causes Blogger to emit unwanted JavaScript - this causes havoc, especially if you're using the tag in the section of a page.

Google recommends using the <$BlogPageTitle$> tag in the page title. This works, but it's not great from a usability or SEO perspective. For item pages you get the post title after the blog name and you probably want to put the post title first - the earlier that keywords appear in the title the better for search engine ranking.

Luckily there's an easy fix - just comment out the closing Blogger tag:

This doesn't interfere with the template rendering correctly and the JavaScript is then commented out on the rendered page. It's still an unpleasant bug, so if you use the classic templates please report it here and also star or comment on this forum topic to encourage Google to fix it.

If you use labels then Blogger includes them in a paragraph rendered with <$BlogItemBody$>. This means that wrapping <$BlogItemBody$> in a paragraph will cause XHTML validation errors for posts with labels because you can't nest another block element inside the paragraph.

The other XHMTL nasty I fixed was the post comments link. My template used the recommended Blogger code:
<p><a href="<$BlogItemCommentCreate$>"
<$BlogItemCommentFormOnClick$>>Post a Commenta>p>

This renders as:
<p><a href="https://www.blogger.com/comment.g?blogID=12345678&postID=1234567890123456789"
location.href=https://www.blogger.com/comment.g?blogID=12345678&postID=1234567890123456789;>
Post a Commenta>p>
And you end up with a gazillion cascading XHTML errors, all caused by the illegal ampersand. I fixed this by constructing my own comment URL using the <$BlogItemNumber$> tag (this emits the unique Post ID):
<p><a href="https://www.blogger.com/comment.g?blogID=12345678&postID=<$BlogItemNumber$>">
Post a Commenta>p>

Lake Merced

Updated on Friday, February 24, 2017
Lake Merced

Lake Merced is a natural lake near Fort Funston. It used to be San Francisco's main fresh water supply but is now the emergency reserve (somewhat worrying as a previous earthquake caused much of Lake Merced to drain into the Pacific).

The lake is also the site of the Terry/Broderick duel where in 1859 the Chief Justice of the California Supreme Court (Terry) killed a US Senator (Broderick) in an argument over slavery.

The loop around the lake is a flat five mile path, unfortunately marred by heavy traffic and constant gunfire from clay pigeon shooting and/or the SFPD firing range.

Rob and Rudy at Lake Merced
Rob and Rudy at Lake Merced.

Penguin's Prayer
Gill and Rudy next to a sculpture called "Penguin's Prayer". Given the latitude I expect the penguin is praying for the next ice age.

(4.85 miles, total elevation gain 0 feet, 1 hour, 39 minutes, average 2.93 mph, view in Google Earth, view in Google Maps.)

Hike starts at: 37.712302, -122.489232.

Overvalidation

Updated on Friday, February 24, 2017
Overvalidation is unhelpful error checking, usually caused by an over-zealous engineer with insufficient domain knowledge. My blood pressure has suffered from two cases of overvalidation this week.

I bought a new NAS - the Linksys NAS200 to set up RAID 1 with a couple of 1TB drives.

I was delighted to discover that the NAS could send email when it detects a problem or starts running out of disk space. Except it couldn't because someone decided that an email server could live at port 25, or at port 1024 or higher.

My ISP blocks port 25 - maybe to cut back on bot spam, maybe because their support staff are bored and lonely. This is far from unique and it's common for email providers to offer an alternative port. Which is almost always port 587. I tried to put a bug report into Linksys but their support pages effectively said "dude, you paid $89 for this box, go talk to other losers on some forum".

Linksys NAS Email Alert Fail

The NAS problem can be solved by redirecting a port on my router. I haven't figured out how to deal with Technorati yet. After spending seemingly months moving their datacenter they've evidently done some work on their blog claim process. I created a new blog yesterday (Webcam Updates, to remove some clutter from the main Catfood Blog) and went over to Technorati to claim it.

When you enter a URL like "http://www.site.com/blog" it's automatically changed to "http://site.com/blog". Which is a different URL. I 301 redirect any "catfood.net" url to "www.catfood.net" to prevent getting dinged by Google for duplicate content. Technorati's claim process fails if there's a 301 redirect.

Technorati Blog Claim Fail

I guess I could remove the redirect, complete the claim and then hope that I can put the redirect back without breaking Technorati. Possibly when my blood pressure is back to normal.

Please, by all means do some validation - "giraffe" is most certainly not a valid TCP/IP port - but don't overvalidate, and don't assume that your mail server port or preferred URL convention is some kind of universal constant.

Fastest image merge (alpha blend) in GDI+

Updated on Wednesday, December 19, 2018

Blended image from Catfood Earth

I've been experimenting with the best way to merge two images in C#. That is, paint one image on top of another with some level of transparency as opposed to using one color as a transparency mask. I tried three candidates, all included below:

SimpleBlend is the naive approach using GetPixel and SetPixel to add the desired alpha value to the second image before painting it on top of the first.

MatrixBlend configures a ColorMatrix to specify the desired alpha and then paints the second image on to the first using the matrix.

ManualBlend locks and directly manipulates the image data. This uses pointers and so introduces unsafe code (it's possible to marshal the image data into a managed array but I wanted to look at the performance with raw access).

I tested each approach ten times with a couple of large JPEG images. The results are:

SimpleBlend: 17.69 seconds
MatrixBlend: 0.74 seconds
ManualBlend: 1.13 seconds

I expect ManualBlend could be optimized further but both this and MatrixBlend are an order of magnitude faster than the naive approach. I'll be using MatrixBlend as no unsafe code is required.

Año Nuevo

Updated on Sunday, May 3, 2020
Año Nuevo

We decided to visit Año Nuevo State Natural Reserve today because it's one of the hundreds of California state parks threatened with closure by Governor Arnold Schwarzenegger's proposed cuts.

The main attraction of Año Nuevo is the presence of a large colony of elephant seals. At this time of the year you walk a couple of miles where volunteers are available to answer questions and lend binoculars. In the breeding season between December and March you need to book a guided walk at least a day in advance - or at least you will if the park survives.



(As well as my video, check out the streaming Sealcam on Año Nuevo Island.)

Elephant Seals at Año Nuevo
Elephant Seals at Año Nuevo.

Gill with Año Nuevo Island in the background
Gill, with Año Nuevo Island in the background. You can see the ruins of a lighthouse on the island (click the image for a larger version). The original name dating back to 1603 is La Punta de Año Nuevo or New Year's Point (much erosion since then).

A Lizard
One of many lizards encountered on the trail.

(4.18 miles, total elevation gain 268 feet, 1 hour, 48 minutes, average 2.32 mph, view in Google Earth, view in Google Maps.)

Hike starts at: 37.12086, -122.307237.

MessageInterceptor doesn't always...

Updated on Sunday, May 3, 2020

I've been writing a play by text message version of battleships for Windows Mobile 6 using the MessageInterceptor class to receive messages. This works great on my AT&T Tilt but completely fails on my wife's Pantech device. The MessageInterceptor hooks up fine but never fires.

The 2.0 compact framework SmsAccount lets you send messages but unaccountably doesn't let you read them.

I avoided some unpleasant interop by grabbing the MAPIdotnet library. This implements a NewMessage event for MAPI stores, however as with MessageInterceptor the event hooks up OK but never fires on the damned Pantech.

MAPIdotnet does allow you to read the SMS inbox though, so the final answer is to fall back to looking for, processing and then deleting game related text messages on a timer. This is far from ideal as the game messages arrive and vibrate the phone before getting processed but at least it's now possible to play without buying a new phone.

To add to the frustration during development the Visual Studio 2005 toolbox lost all icons except for the pointer and a custom control that was part of the project. Resetting the toolbox didn't help, nor did restarting VS and the computer. The fix was to exit VS and then delete all the .tbd files from Microsoft\VisualStudio\8.0 in local application data. Sigh.

Launching a URL in the user's default browser

Updated on Sunday, May 3, 2020

This has bitten me a few times. If you use Process.Start("url") it will work some of the time but you'll see a "The system cannot find the file specified" Win32Exception on some systems. Bummer.

Lots of people suggest looking up the HTTP handler in HKEY_CLASSES_ROOT but this is flawed as well - on my system for instance HTTP is registered to Firefox even though I'm actually using Chrome and I'd be unhappy waiting half an hour for Firefox to wake up and show the requested web page.

From XP there are a couple of registry settings tied to the current user's preferred browser.

First check HKEY_CURRENT_USER\Software\Clients\StartMenuInternet. This key will only exist if the user has overridden the system default browser - the default value is used to access the details (for me, it's chrome.exe).

If the user hasn't set a default then check HKEY_LOCAL_MACHINE\Software\Clients\StartMenuInternet. The default value here is the system default browser (on my system it's FIREFOX.EXE).

There is a set of subkeys under HKEY_LOCAL_MACHINE\Software\Clients\StartMenuInternet that contain details about each registered browser. The default value from StartMenuInternet (either HKCU or HKLM) is the subkey to look for. The path to my default browser is in this key:

HKEY_LOCAL_MACHINE\Software\Clients\StartMenuInternet\chrome.exe\shell\open\command

Now I can Process.Start(path, url) to safely launch the default browser. You can fall back to Process.Start(url) if registry access fails for some reason, but be prepared for that Win32 exception.