Thursday, August 6, 2009

iPhone Bookmarklet to Install iPhone Bookmarklets

iPhone BookmarkletsAs a software engineer and a web developer, I have really grown to love the bookmarklet. I have a Regex Search Bookmarklet, my favorite javascript shell bookmarklet from Jesse's Bookmarklets, and of course, you've seen my blog post on Tabulate from the clever folks at Inventive Labs. However, installing bookmarklets on the iPhone without help from a computer is a royal PITA.

That's why I wrote the iPhone Bookmarklet Installer.

If you're interested in how it works, you can find details on my iPhone Installer Bookmarklet blog post. But, the short version is that I use Javascript to loop through all of the links on the page and make them look like anchor tags so you can just bookmark them on the iPhone and remove everything before the anchor tag character '#'.

With that out of the way, here's how you use it:
  1. Run the bookmarklet on this page by clicking the iPhone Bookmarklet Installer. You should see all of the bookmarklets on this page change styles (They'll look something like this).
  2. Click the bookmarklet you wish to install (n.b., the page won't reload).
  3. Bookmark the page.
  4. Edit the bookmark and remove everything up to and including the # character.
  5. Name the bookmarklet appropriately.
  6. Save and enjoy.

Friday, July 10, 2009

Leave the Poor Table Alone

Traffic SignSo, I realize that with some clever hacking and a butt-load of time, you can do just about anything with divs and CSS, but I think the anti-table thing has gone way too far! I've even seen people display tabular data without using tables. I mean, great. Look at you. You're fancy and all, but what have you accomplished? Tabular data is what tables were designed for in the first place.

So, why are people so steadfastly opposed to tables in HTML layout? Well, I've seen oodles of reasons including things like speed of data transfer, separation of content and layout, ease of redesign, no spacer gifs, lower html complexity, accessibility for persons with disabilities, etc.

Of course, there are sites out there that demonstrate all of the things that can be accomplished using nothing but divs and CSS and they're really great to look at and enjoy; I've learned a lot about CSS from them. But, just because you can doesn't mean you should. I mean, when was the last time you heard about someone doing something with "nothing but" and it wasn't a stupid human trick? Mac Gyver could take down a swarm of enemies with nothing but a Milk Bone, some shoe string, a little fertilizer, and duct tape; I, on the other hand, carry a Glock.

But, here's the real issue: whether you use tables or not, there're right and wrong ways to do anything. Just like there are wrong ways to use tables for layout, there are wrong ways not to. My point is that you can very cleanly and appropriately use tables for layout and still use CSS for almost all of your actual presentation.

As a result, I've yet to come up with a compelling reason to eliminate tables from layout altogether. For example, using a table for your overall layout can give you cross browser compatibility that is very difficult and effortful to achieve with CSS and divs. CSS and DIVs are rendered differently among the several browsers; however, CSS and tables are relatively consistent.

I've found that often times, I can use only one table and achieve exactly the layout I was looking for when a div design would require 3 or 4 levels of nesting. In this case, it is actually cheaper and less complex to use tables than it is to use divs and it took me a tenth of the time.

While I agree there should be a separation of concerns within the definition of websites to keep content, presentation, and behavior separated, using tables to position elements only is a very minor violation of this principle. In fact, using tables in this way is exactly the same as using divs this way. Afterall, any time you use an HTML tag your intent is to describe something about the way the content is displayed. Then, you modify that behavior with CSS. Really, the only thing you can't do with tables and CSS is fundamentally change the position of items.

I suppose that's where people are coming from when they mention redesign. Now, that may be the case and I don't really know that much about it. I'm not a web designer; I'm a software engineer. I spend a very small percentage of my time concerned with layout as there are usually much bigger fish to fry; however, I've never been on a redesign project that didn't require HTML changes.

As a result, it never made a difference whether the page was tables + CSS or divs + CSS; we always had to rewrite some HTML. Furthermore, it's generally in a template somewhere. In fact, many times, it has been easier for me to reposition elements on a page because I was using tables for layout rather than divs. The CSS required to move stuff around and make it cross-browser compatible is often a royal pain in the ass, but it's pretty easy for me to move a one line server side include or a user control in .net.

I never really understood why people used spacer gifs. I don't use them and never have so I don't know what that has to do with tables. I also don't know what tables have to do with accessibility. I've read some things about readers not being able to do anything with graphics because they can only interpret and present text. Divs, tables, plain text, whatever . . . it's all the same text so I don't really know what this has to do with tables for layout.

In my years of experience, I've gone through the dogmatic anti-table phase and I've gotten over it. I simply cannot come up with a good reason to eschew tabular layout. Most of the time, I can do what I want with divs and CSS and I do. When something is difficult with a div, I usually throw a table at it. As a result, I get the job done faster and I save clients money and they ultimately get the same quality software. I've also not had any complaints about accessibility, maintainability, or load times. To me, it's a win-all-around kind of thing, so until I can find solid arguments against tables, I say leave the poor table alone. It's another tool in the toolbox; use it if it makes your life easier.

Monday, July 6, 2009

Sign Placement Takes an Engineer

Traffic SignI was driving into work this morning and I noticed a sign off to my right. It was a temporary sign which evidently was warning us drivers of some upcoming event. It was too small to contain the entire message so they broke it down into pages which displayed for about 3 seconds each. The first page I saw read:
July 12, 2009
From 6:00 AM
To 7:00 AM
Interested, I eagerly awaited the next page. About 3 seconds later the sign read:
Between
Exits 6 and 7
But, before I could find out what was happening during that block of time, I passed the sign. What in the world did that third page read? Should I plan on staying home? Should I leave home? What's happening?

Well, I started thinking about it and it occurred to me that it was pretty dumb to put that sign on the side of the road right after a curve. Why not put it after the curve in the ensuing half mile straight away?

So, I looked into it. If you take a look at the image above, you'll see the approximate location of the sign. I drew a line segment starting at the sign, passing the west most occluder, and ending at the median between the northbound and southbound lanes.

Then, I traced the median all the way up to the approximate angle where I could no longer see the sign because the visual angle was too narrow.

Next, I traced the fast lane (the longest route within the "polygon of visibility"). I measured it out in google maps and it turns out that the sign was visible for 448 feet.

The speed limit at this point on GA 400 is 65 miles per hour (approx. 95 ft / s). That means that the sign was visible for just shy of 5 seconds.

I'm sure by now, you've done the math and come to the same conclusion. If the sign pages rotate at a minimum of 3 seconds per page and the maximum visible time at or above the speed limit is 5 seconds, then it is only possible to read 2 pages of data. However, the message must be at least 3 pages in order to be complete.

There's no way to reasonably expect drivers to read the entire message and therefore most people passing that sign today will have no idea what the full message is. Evidently, when it comes to sign placement, it takes an engineer.

It Takes an Engineer

EngineeringI'm pretty excited about this post. Not only is it my first blog post in a while (I've been pretty swamped lately and haven't had a chance to write anything), but it's also the first new section I've started in a long time.

This entry marks the first post in a series of posts I call, "It Takes an Engineer." It's about all of those things we see in daily life that would be better if they consulted an engineer first.

I'm sure, if you're reading this blog, you probably know what I'm talking about. It's the stuff that makes you stop and say, "what the hell were you thinking when you did this?" Or, "you really thought this would be intuitive?" Or, "if someone thought about how this was going to be used, I wouldn't have to fix it all the time."

Well, this is going to be my venue for venting on this topic so I hope it provides enjoyment to all. If you have anymore good examples, let me know and I'll blog about them too.

Tuesday, June 16, 2009

iPhone MMS Fail

iPhone MMSSo, I understand that Apple purports to have good reasons for not supporting MMS at the moment and that Apple plans to support MMS this summer for 3G and 3G S phones and AT&T seems to be proud of themselves for offering MMS for free on the iphone despite the fact that MMS is free with basic messaging with almost every other provider, but whatever. That's all well and good.

But, here's what pisses me off . . . aside the fact that MMS has been around a really long time and that the iPhone is one of the few phones that doesn't support it, I'm still really annoyed by the way AT&T . . . oh excuse me . . . at&t decided to hack together some form of MMS support.

If you don't have an iPhone, let me tell you how this goes. You get a text message. The text message links you to a simple at&t multimedia messaging page with text boxes for message id and password. Then, you enter your message id and password which are provided in the text message.

Now, if you don't have a computer handy and you want to view this message on your iPhone, you had better grab a pen, 'cause this message id looks something like this: esth9389uohh or 1ch309903hsuh or 47&75uck5r3411y3ffingb4d! How I'm expected to remember this, I don't know.

Then, the password is a little easier to remember. It's just two four letter words separated by a two digit number. So, why do I find this so frustrating? Well, simply because there is no reason under the sun to do this. There is absolutely no difference between my entering these codes manually and at&t tacking them onto the query string. In fact, if they did that, they could use longer keys and could make it harder to brute force.

Then, when I got an MMS message, I could just click the link and, lo and behold, there would be my message. I wouldn't have to try to write down the dumb message id and try to figure out if that l is a 1.

I've got a password for you at&t . . . epic69fail.

Friday, June 12, 2009

Soundex Extension Method for C#

British AirwaysI've been pretty swamped at work lately so I've not been blogging much. Worse than that, I haven't really been able to do much creative programming and virtually nothing academic.

A few days ago, I was working on some basic name searching and recognized an opportunity to squeeze in some play time. It occurred to me that the users of our application will be looking people up by name and will often not know how to spell the name correctly.

I wanted to allow users to search for people by name without regard for different spellings. For example, if you're looking for Geoff McArther or Jeff MacArther, both names will be returned by the same search term.

To do this, I used a technology invented back in the 1920s for the US Census called soundex. The following is a set of extension methods that implement the soundex phonetic algorithm:
public static string Soundex(this string s)
{
// by default, a soundex is the first letter
// followed by three numbers
return Soundex(s, 4);
}

public static string Soundex(this string s, int length)
{
return FullSoundex(s)
.PadRight(length, '0') // soundex is no shorter than
.Substring(0, length); // and no longer than length
}

public static string FullSoundex(this string s)
{
// the encoding information
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string codes = "0123012D02245501262301D202";

// some helpful regexes
Regex hwBeginString = new Regex("^D+");
Regex simplify = new Regex(@"(\d)\1*D?\1+");
Regex cleanup = new Regex("[D0]");

// i need a capitalized string
s = s.ToUpper();

// i'm building the coded string using a string builder
// because i think this is probably the fastest and least
// intensive way
StringBuilder coded = new StringBuilder();

// do the encoding
for (int i = 0; i < s.Length; i++)
{
int index = chars.IndexOf(s[i]);
if (index >= 0)
coded.Append(codes[index]);
}

// okay, so here's how this goes . . .
// the first thing I do is assign the coded string
// so that i can regex replace on it
string result = coded.ToString();

// then i remove repeating characters
//result = repeating.Replace(result, "$1");
result = simplify.Replace(result, "$1").Substring(1);

// now i need to remove any characters coded as D from
// the front of the string because they're not really
// valid as the first code because they don't have an
// actual soundex code value
result = hwBeginString.Replace(result, string.Empty);

// i used the char D to indicate that an h or w existed
// so that if to similar sounds were separated by an h or
// a w that I could remove one of them. if the h or w does
// not separate two similar sounds, then i need to remove
// it now
result = cleanup.Replace(result, string.Empty);

// return the first character followed by the coded
// string
return string.Format("{0}{1}", s[0], result);
}
Now, it may not yet be perfect as I had a pretty hard time finding the exact specs for the American soundex, but it should be pretty close. If you notice something wrong, please leave me a comment and I'll correct it.

Communication Clarity Fail

British AirwaysWhen I'm not writing awesome software (grin), you can usually find me flying airplanes, dreaming about airplanes, thinking about airplanes, or blogging about airplanes.

Yesterday, I was getting ready to make my first solo in a Super Decathlon, and I spent an agonizing nerve-racked hour waiting for my instructor to get off of a conference call. I thought I'd try to work off some nervous energy reading.

Lately, I've been reading The Pragmatic Programmer. It's a really great book and will probably be the subject of several forthcoming posts reviewing the book, but that's not the topic here.

This post is about the coincidence of me sitting there at the airport reading about programming and finding this British Airways memorandum that was published in Pilot Magazine in 2006:
From British Airways Flight Operations Department notice:

There appears to be some confusion over the new pilot role titles.
This notice will hopefully clear up any misunderstandings.
The titles P1, P2, and Co-Pilot will now cease to have any meaning,
within the British Airways operational manuals. They are to be
replaced by

-Handling Pilot,
-Non-Handling Pilot,
-Handling Landing Pilot,
-Non-Handling Landing Pilot,
-Handling Non-Landing Pilot,
-Non-Handling Non-Landing Pilot.

The Landing Pilot is initially the Handling Pilot and will handle the
take-off and landing except in role reversal when he is the
Non-Handling Pilot for taxi until the Handling Non-Landing hands
the handling to the Landing Pilot at 80 knots.
The Non-Landing (Non-Handling, since the Landing Pilot is handling)
Pilot reads the checklist to the Handling Pilot until after Before
Descent Checklist completion, when the Handling Landing Pilot
hands the handling to the Non-Handling Non-Landing Pilot who
then becomes the Handling Non-Landing Pilot.
The Landing Pilot is the Non-Handling Pilot until the 'decision
altitude' call, when the Handling Non-Landing Pilot hands the
handling to the Non-Handling Landing Pilot, unless the latter call
'go-around', in which case the Handling Non-Landing Pilot
continues handling and the Non-Handling Landing Pilot continues
non-handling until the next call of 'land' or 'go-around' as appropriate.
In view of recent confusions over these rules, it was deemed
necessary to restate them clearly
Oh, thanks for clearin' that one up fellas!