Sunday, March 22, 2009

Do you remember SAT math?

The SAT I math test has a special class of questions called Quantitative Comparisons. Each question shows two columns, A and B, each describing some quantity, but the same four choices are always the same:

A. The quantity in Column A is greater.
B. The quantity in Column B is greater.
C. The two quantities are equal.
D. The relationship cannot be determined from the information given.

These questions can be devilishly tricky (particularly when the answer is D). Consider this classic example:

x > 0


Column AColumn B
2x(2x)2


Many students will only consider integer values of x and choose B as their answer, which is incorrect. What if x is ¼? Then the value of Column A is ½ and the value of Column B is ¼, so Column A is greater! But if x is any value larger than ½, then Column B will be greater. This means the correct answer must be D. (I deliberately chose 2x instead of x to eliminate the case where trying x=1 makes the two columns equal and trying any x>1 makes Column B greater, which makes it easier to come up with D as the right answer.)

So that is a quantitative comparison question. Like many upper-middle-class kids from the northeast, I took the SATs for the first time in the 7th grade to try to get into CTY. I didn't know what CTY was at the time, but my mother did, and fortunately for me, she recognized what a tremendous opportunity it would be for me to go. Mom bought me my first copies of 10 SATs and Cracking the SAT that year. (I say "first copies" because I had to buy new ones the following year when they re-centered the scoring and changed the test.) The SAT became my new challenge, and I've been kinda obsessed with the thing ever since.

Which is why while pondering the most efficient route on my walk to work, which involves walking around an arc (a rarity in New York City), I have developed the following Quantitative Comparison question:


CE and BD are 90° arcs on circles which are concentric at point A. Segment AC is greater than segment AB.


Column AColumn B
The length of arc CE.The length of arc BD plus the length of segment DE.


And also the following quantitative comparison question for the same diagram:



Column AColumn B
The length of arc CE.The length of segment CB plus length of arc BD plus the length of segment DE.


I'll write a follow-up post with the answers in a couple of days. I know I found the result surprising (and now I know the best way to walk to work)!

Tuesday, March 3, 2009

Tips for Tasks

If you saw my recent post on the Gmail blog, you've probably figured out that I work on Tasks. I've put together a personal list of tips to help you get the most out of Tasks:

P.S. If you have that problem where the popup with the arrow pointing to Tasks appears every time you log into Gmail: (1) I apologize, and (2) if you click on the Tasks link that it is pointing to, the popup should never show up again. Tell your friends!

Monday, February 9, 2009

A problem only I would have (or "How to build the most overengineered lightswitch possible")

Tonight I decided I should blow the dust off the machine I got from Dell a couple of years ago so I could achieve my longstanding dream to have a giant programmable lightswitch. I've lived in at least six apartments over the past two years (protip: keep track of old addresses by checking where you've shipped stuff on Amazon), so I've never been in any place long enough where it was worth trying to set this up. With my 13-month lease in hand, it seemed like it was finally time to try this out.

The key elements that I've acquired along the way are a Dell touchscreen monitor (2005), Windows XP machine (2007), and the X10 ActiveHome Pro 9 Piece Kit (2004?). My plan for stringing these things together seemed pretty simple:

  • Plug monitor into computer
  • Install ActiveHome software
  • Press giant virtual button

Simple, right? Actually, it had far fewer snafus than some of my other projects. Step one was to get the touchscreen working even though I didn't have the CD with the drivers. Despite my repeated Googling, the drivers were pretty hard to find until I discovered that somehow I was being sent to Dell Australia instead of Dell US (work VPN playing games, maybe?), but once I got that straightened out, I got the monitor live and responding to touch pretty easily.

The next step was to get the ActiveHome software running. Fortunately, I backed up the installer for the SDK on bolinfest.com a few years ago because I figured I would lose it otherwise (I was right!). Installing the SDK was no problem, but I couldn't seem to find the thing that launches the ActiveHome GUI pictured on the web site. This wasn't a big deal because the SDK comes with sample code in a bunch of languages, including JScript, which you can just load in IE if you allow ActiveX to do its thing. I even got the JScript sample to stop giving me ActiveX warnings every time I loaded it by sharing the folder and adding it as a Trusted Site. (The Trusted sites thing in IE doesn't let you trust local files unless you serve them from as a shared folder -- I'm wary of what I've opened myself up to as a result of this.)

Now I was up to step three: "press the big red button." I pressed. I pressed again. I pressed several more times and exclaimed some things I do not care to repeat. My X10 components had been working fine via the remote from the Kit until a few weeks ago when I bought some new components (uh-oh) and tripped a circuit breaker while trying to install a Socket Rocket in my apartment. I was hoping that maybe the x10 modules would respond better to the software than to the remote (what the hell do I know?), but obviously they did not, so I checked out one of the x10 troubleshooting pages. It said something about opposite-phases-blah-blah-don't-you-know-I-got-Cs-in-my-EE-courses-because-I-couldn't-be-bothered-to-go...

I really had no idea what I was reading, but I made up this hypothesis that tripping the breaker had knocked things out of phase and that turning it off and on again would magically realign my outlets. Believe it or not, this actually seemed to work! That was, until I realized that once I plugged anything else into the outlet next to the one that had the x10 module plugged into it, the x10 module would stop working. This is a problem since I don't have too many options when it comes to outlets in my apartment, so I'm not sure how I'm going to resolve this. Currently, I have to choose between the possibility of controlling a lamp via my iPhone and plugging my laptop into the wall. It's a toss-up.

Since I've come this far, I'm strongly considering reworking the outlet situation in my apartment to accomodate my fetish for automated lights. If any of you circuit jerks out there can tell me how to do this without making a trip to the electrical section at Home Depot, I'd be much obliged. I only have 10 months until it's time to setup the AIM bot to control my Christmas lights again!*

*I actually did that in 2005 using the SDK and an existing AIM bot library written in C#. I went with the AIM bot because it seemed a lot simpler than running IIS. It was also more fun, though I guess nowadays I'd do it over Jabber instead. When was the last time I logged on to AIM?

Sunday, January 18, 2009

Using an IFRAME to force a doctype

There have been times when I wanted to create a JavaScript widget that I could embed into any web page. One problem I ran into was that I would develop my widget in a standards mode page, but then it would not work when embedded on a page in quirksmode.

"Who still uses quirksmode?" you might ask. Well, for legacy reasons, iGoogle gadgets do. I thought that OpenSocial fixed that, but item 6 of the spec says otherwise, though the discussion group suggests a distasteful workaround.

Either way, this whole doctype thing is a problem. On a web page, the document has a doctype property, but it's read-only, so trying to edit that is a dead-end. Originally, I tried manipulating the content of an iframe with src="about:blank" which I thought would be clean because it had no content, but no content means no doctype, so it is also stuck in quirksmode.

One option that does work is to have an empty html page with the strict doctype on the same domain as your JavaScript widget. That way, your widget can write its content into a local iframe using the empty html page as its source. The drawbacks to that approach are: (1) it complicates the API of your widget because it requires the consumer of your API to make a server-side change and bake the URL into calls to your API; and (2) you have to add some extra logic to listen for the iframe to load before you can write to it, so it forces your API to become asynchronous rather than synchronous.

The best solution I've seen so far is to dynamically create an iframe with no src attribute and to use document.write() to insert the content of the iframe or to set the src attribute to javascript:parent.functionThatReturnsTheDesiredContentAsHtml(). This test page demonstrates both techniques.

One thing that is particularly advantageous with this technique is that if your widget requires its own stylesheet, it can load it in the iframe instead of the top-level page where your CSS class names run the risk of conflicting with the CSS class names used in the host page. So even if you know that your widget is going to be used in a standards-compliant page, you may want to use this technique to create a "fresh namespace" for your CSS.

The only disadvantage that I've found with iframeing over inlining is with managing overlays that need to appear outside the iframe. In the test page, there is a green box that appears over the iframes and the main page. For it to be visible, it needs to be an element of the top-level page, which (1) may be in quirksmode and (2) will not honor the CSS rules defined in your iframe. That means that you may have to design your popup so that it works in both rendering modes and uses inline styles (exactly what we were trying to avoid with our universally-embeddable JavaScript widget!).

Also, the JavaScript code that manages such an overlay needs to be wary of its use of the document variable as it is important to use it in the correct context (iframe vs. host page). It is best to create different getters for the two documents and to use those exclusively, avoiding direct access to document altogether.

Overall, I am still pretty happy with this solution, though one thing that occurred to me is that this is a little frightening with respect to phishing in that a malicious web page could easily display an iframe to foreign content (that is familiar to you) and then display its own login box or credit card form on top of it to lure you to enter your information. I mentioned this to Mihai, and he said this is somewhat of a known issue, citing this example at zombieurl.com (warning: page contains sound). I guess that goes to show that you can never be safe from zombies, not even on the Internet.

Saturday, December 13, 2008

Migrated from WordPress to Blogger. Good Lord.

When I created this blog, it wasn't possible to host your blog under your own domain name using Blogger like you can today. That was a big turnoff for me, so I decided to host my own blog using WordPress. I also liked the idea of being able to do whatever I wanted to my blog since the source code was living on my server.

As it turned out, having total control was never that interesting to me. As I noted when I started the blog, I didn't want it maintaining it to feel like a job, so I never made many changes to the PHP. I made a few tweaks to one of the default templates instead of trying to create my own, and I may have installed a plugin or two, but I didn't really touch those very much either.

Now consider the downsides of hosting your own blogging software:
  • You have to be aware of security vulnerabilities that arise in the software and update the system yourself when they happen. (My WordPress blog was hacked and spam links were inserted into my posts.)
  • You have to stay on top of the world of comment spam (which my WordPress blog suffered from) and patch your system accordingly (if patches are available) if you want to keep it out of your blog.
  • Your readers have to create separate accounts (as opposed to their Google Accounts, which I expect most of my readers to have) if they want to comment on your blog.
  • Your WordPress username/password is just one more thing you need to remember.
A friend pointed out the spam in my blog, and I knew that my version of WordPress was outdated, so I decided that I would finally tackle the migration. This turned out to be about as much fun as I expected it would be:
  • The migration required me to upgrade WordPress (just what I was trying to avoid!) because my existing version of WordPress (1.5?) didn't have the export feature that the Internets recommended I use.
  • I tried to upgrade WordPress on bolinfest.com, but that turned out to be impossible because bolinfest.com doesn't have PHP 4.3 (it has 4.2.2), and from past experience, I know that trying to upgrade PHP on Redhat 9 (yep, that's what bolinfest.com currently runs on -- clearly I have another migration in my future) is its own disaster, so I didn't even try.
  • I ended up doing a mysqldump of my Wordpress database and installed a new version of WordPress on a separate (more modern) server. (This required updating the siteurl and home options in the wp_options table to match the new server; otherwise, I couldn't load upgrade.php which runs the upgrade process.)
The one thing that shocked me while I was doing all the Googling to solve this problem were the number of people who are trying to migrate from Blogger to WordPress rather than the other way around. Sure, Blogger has its share of things that annoy me (I have to manually edit the height of the Compose box in Firebug to make it a reasonable size, and the HTML it generates for my post is completely unlike anything I would write had I done it by hand, making it hard to clean up), but WordPress has most of the same problems and requires so much extra maintenance!

What is wrong with you people?

Sunday, March 2, 2008

Fixed up iGoogleBar

It turns out the iGoogleBar needed a one-line fix to address what I can only assume was a recent change in Gmail. I updated the code in the Chickenfoot script wiki as well. Version 0.5.2 is now the latest version, so go to Tools -> Add-ons in Firefox to see if you have the latest version -- hit the Find Updates button if you don't!

Monday, February 4, 2008

iGoogleBar: Just because I haven't released a Firefox extension in awhile

iGoogleBar is my latest Firefox extension that adds Google Apps favicons to the Google Apps Bar, using them as triggers for the Apps' respective iGoogle Gadgets. As a courtesy to some of my colleagues, I included their projects in the bar so they’re easier to get to (or just preview) from Gmail and Calendar.

I built this extension using Chickenfoot, which hit version 1.0 recently. Part of that release included improvements to the extension-packaging tool, which made it much easier for me to convert my iGoogleBar prototype into a full-fledged Firefox extension!

The iGoogleBar page acknowledges that there are some missing features from the extension, so I put the source code in the Chickenfoot Scripts Wiki. That means, if you’d like to see a new feature added, please go and update the Wiki instead of just nagging me :) If I like your patch, then I’ll make a new release. And if I don’t like your patch, then you can at least install your modified version of iGoogleBar as a trigger in Chickenfoot.

Will this method of software development actually work? Probably not, but it should be fun to try!