Inspiring a New Generation of Engineers

I used to have an old Motorola e810, a standard non-smart phone with a camera, circa 2005. Being the cheap bastard that I am, this phone doubled as my alarm clock, boasting multiple different alarms. I stumbled across an interesting quirk: you couldn't set more than one alarm for a time; that is, if you had an alarm for 6:00pm that said "Laundry," you couldn't have one for 6:00pm that said "Order Piza". Honestly, it wasn't a big deal. It didn't matter which alarm went off, as long as one did, and that was probably a design decision made when they created the phone. But it still bothered me.

The only thing I could think of that made sense was that each alarm was some sort of key/value pair where the time was the key, and duplicates weren't allowed. I can sort of see the logic for this. If it was a hash table, for instance, then at each minute you just perform a look up to see if there was an alarm set. This makes slightly more sense then iterating over all of the possible alarms at each new minute (although since most people only have one or two alarms, probably not a huge savings).

While it was a fun exercise to try and determine why the phone wasn't working as I expected, it was sort of mental masturbation. Without the source code to the phone, I have no way of knowing if my educated guess is even in the ballpark. We're in the black box stage of our information age: we don't have to know why things work, we just know that they work. Is the voodoo too complex? Maybe. Because we don't care to know? Another likely possibility. But why with electronics versus other complicated devices?

The Man Code states that you should have a certain amount of automobile expertise. Since the dawn of cars, it's been accepted, if not expected, for man to have prowess with the car. In the beginning they were simple enough that this was a feasible task: there's the carburetor, there's the engine, there's the fuel pump -- ok, I've got this. However, a 2005 Honda Civic is not a 1949 Chrysler. The Civic is exponentially more complex, with computers, fuel saving devices, emissions lowering devices, etc -- but yet you can still change the oil, replacing the starter is not out of the question, and even replacing the brake pads is a manageable task. Heck, if you don't want to pay someone to replace the rotors or the the alternator, you can do it yourself. If you're a real gear head, you can even tackle an engine swap.

Let's go back to the cell phone real quick. I consider myself the computer equivalent of a gear head, but I was unable to do anything about this problem. I couldn't even confirm why it behaved this way because the software for the phone was unavailable. Not that it was too complex for me to figure out, but that I didn't even get the chance to try. I'm sure that everyone has run into that one glitch, that one feature of a program that doesn't work quite right -- the one that makes you think to yourself, "this is so close to working, I ought to be able to tweak it." Well, if it was a car, you could. You could tweak the air to fuel ratio in your carburetor. It's not like the hood of you car was sealed shut by Honda when they sent it to you, preventing you from peeking inside to see how everything works.

In the past, complex devices like tractors, lawnmowers, furnaces, cameras, clocks, etc have been possible to tinker with, if you're willing to put forth the time to get past the learning curve. Cellular phones, Windows, the iPod, GPSes, and other electronic gadgetry aren't accessible in the same way. And don't give me that bullshit about decompiling it to assembly code and tweaking it there; a human readable form (source code) exists that software gear heads just can't get to because the company safe guards it as proprietary information.

This is why open source is important. If you're curious how MySQL or Firefox works, you simply pop the hood and look. How many inventions that we depend on have been created by creative tinkerers? It's fine that most people don't care how their web browser works -- but for that .001% of people who do care enough to want to see makes it tick, why in the world would we prevent them from that?

This is one of the reasons I am such an advocate of the Google iPhone (aka the G1 aka the Android). Linux, Mozilla, MySQL, and a slew of other software has long been freely available to tinker with, but those are limited to computers. One of the other most important devices that we all use on a daily basis, the phone, has just joined the ranks. This is going to open up the phone to unexpected innovations that we have seen with computer, automobiles, and everything else with which tinkers are free to play with. Society has everything to gain from this.

Ultimately, I'm hoping that the open source movement will inspire a new generation of engineers. Not everyone will be interested, but there's no reason to prevent the people who will be. People who learn how things work because they want the satisfaction of knowing how something works. People who want to tweak something so that it works better for them. People who see something good and want to make it great.


Why I Program

On the bus this morning, I read part of "The World is Flat" that deals with left-brain versus right-brain activities; to Friedman, jobs that can be replaced by technology and outsourcing (left-brain) and those that require an element of creativity (right-brain). Friedman made a statement:

"This weekend there will be accountants painting watercolors in their garages. There will be lawyers writing screen plays. But I guarantee you that you won't find any sculptors who on weekends will be doing other people's taxes for fun."

Friedman is trying to convey that some things are done out of passion, and some out of necessity. People do taxes out of necessity, people paint watercolors out of passion. It's all very black and white, and the jobs of necessity are the ones that are more easily sent overseas to India.

Can't there be be passion for traditional "jobs of necessity"? You can outsource your financial management to an established group or mutual fund -- but what about the excitement of finding good deal and making a sound investment? The satisfaction of having researched it and adding your own judgment to what you find? You need a table to eat dinner on, but can't creating that table be a creative outlet? When categorizing these jobs, I don't think there are clear cut categories; it's up to the individual to say what he is passionate about.

Whenever I go home or spend time with my parents, a lot of my free time is devoted to programming, and they can't figure it out. "You do this all day for your job [or for school]. Can't you put down the laptop?" While it's true that I sit in front of a computer for my day job, I'm working on problems of necessity. Database development isn't particularly exciting for me; what I've been working doesn't require a lot of creativity and seems mechanical. So, in my free time, I need to exercise my creative muscle, and I choose programming for that task.

I've often said that good code is beautiful (no, I'm not talking about the Perl Camel). A well designed component or architecture has elegance and sophistication; simplicity yet robustness. You step back, look at the code, say "Damn, that's gorgeous", and you know when you've created beauty instead of just hacking out a quick fix. This element of beauty is something that I've found lacking in a lot of code and with a lot of programmers. Too often programming is treated like a boring job of necessity than the passionate job of creativity that it can be.

This is why I enjoy coding in my free time. Sure, it's all ones and zeros when it comes right down to it, but the important thing isn't what the end product does; how you got there is so much more important. Programming gives you a chance to come up with creative solutions. And they don't even have to be real problems!

I spent an entire day obsessed with the idea of programming language quines, which are programs that print out their own source code. Sounds easy, right? "Just keep a copy of the source code in the code, and print it out. Oh crap. How do I recursively store the code in the code..." Quines are, as my office mate likes to say, mental masturbation: they produce no value and in that sense are worthless, but so incredibly amazing at the same time.

I look at quines and other beautiful code with the same curiosity and admiration that I look at pieces of artwork in a museum; I appreciate them not because of their utility, but because of their elegance. And I code as a hobby outside of my day job not as a task of necessity, but the desire to create beauty.


Asynchronous PHP Gotchas

As part of a PixCede re-write (read: correcting damage from a rabbit I chased to far down a hole -- more on that in another post), I decided to modularize the scripts for handling new messages. Previously, procmail was sending the email to a single PHP script that handled extracting attachments, storing the image, and sending the confirmation message. As the script started to get unwieldy, I decided to break it into separate scripts:

  • newMailDaemon.php - main script that handles writing the attachment to disk and asynchronously calling additional tasks. This is purposely kept minimal, so that there is less chance of something going wrong (e.g. compilation error). Worst case scenario, the email is written to disk; if the other tasks fail, the unit of work can be replayed from the message dump

  • processMail.php - handles extracting the image, creating the shortname, inserting it into the database, and sending the email confirmation. This will be split up eventually

After newMailDaemon.php writes the mail file to disk, it calls exec(..) to asynchronously kick off processMail.php. I was about to pull my hair out until I figured out a couple of things:

  • exec(..) does not get called as though through a shell. As a result of that, you need to use absolute paths. That means that `php ./processMail.php` becomes `/usr/bin/php /var/pixcede/xxxx/processMail.php`

  • As a corollary to the previous point, absolute paths need to be specified in exec'ed scripts as well; e.g. the database file specified to sqlite3

  • Permissions matter! I was using a logger to follow the actions once an email was resolved, and I couldn't figure out why nothing from processMail.php was getting logged. I was logging the command that got exec'ed, and running it manually -- and it always worked. procmail calling newMailDaemon.php calling processMail.php runs at the permissions of the user account that procmail is acting on behalf of, so the script needs to permissions to run from that user. Whatever is running the main script needs permission to exec additional scripts

This design is far from perfect. The different actions need separated more; ideally, having newMailDaemon load and parse an external workflow file wouldbe nice -- then I could lock down newMailDaemon and not have to change it to update the workflow (less chance of it failing). To handle and track the different steps, I would like to keep a table of actions to process, have entries put into that, and have another script act on that table until all tasks are set to "complete"; that sounds more scalable and manageable than exec'ing scripts for each action that needs to be done. Having newMailDaemon schedule tasks and processTasks execute those tasks sounds cleaner.

At any rate, PixCede works again now!


Finally, someone made it dirt easy to transfer Flickr pictures to Facebook

Normally, I don't care about Facebook albums. Flickr has many more features, handles it better, and has a more photo-centric community around it. Unfortunately, I'm vain, and want as many people to look at my pictures as possible. I've played with a handful of Facebook applications that "integrate" Flickr into Facebook, but I've never found one that made the transition completely seamless. In fact, it seems as though the "new" Facebook design broke the last Flickr application that I used.

I could re-upload all my photos to Facebook. But why do that when I've already done it once? I just want some back end service to pull selected albums from Flickr and put the files on Facebook. It looks like dudemeister Matt McNamara felt the same way, so he wrote flickurbook. This is a dead-simple, hacked together way to pull photos from Flickr and put them on Facebook. I love it! It's exactly as unpolished of an application as I would have written. This does what I was hoping Oosah would do; Oosah is a start-up that I saw at the Palo Alto new-tech meetup a couple of months ago that boasted being able to do the same thing (remotely manage photos between different sources). Unfortunately, when I tried it, it didn't work. Looks like it would have been overkill anyway, flickurbook does exactly what I want it to do.

PS: Check out my Tahoe pictures
tahoe 027


Mango Lassi: Better than Synergy

About 3 years ago, my friend Lann showed me this sweet, cross platform program called Synergy that lets you share one computer's mouse and keyboard among multiple computer/screens. Why was this cool? This meant that with my laptop, sitting on my futon I could control my TV computer. Yea, I'm that lazy.

As the years go on, I find myself getting lazier. Now that I have an apartment, the couch is even further away from my TV! So, I went out to set up good ol' tried and true Synergy so that I can use my laptop to control my Mythbuntu box. But, it didn't work. Every time I moved my mouse off screen, if showed up back in the center of the original screen.

Now, I don't care why it doesn't work. Really, I don't. I fiddled for about five minutes, and then went to see if there was anything better out there, when I stumbled across Mango Lassi. It was designed specifically to solve the suckitude of Synergy and x2x. Unfortunately, there's not a package for Ubuntu, so we have to do it the old fashioned way:

(following Marius Gedminas's instructions)

sudo apt-get install git-core curl build-essential intltool \
automake1.9 libdbus-glib-1-dev libgtk2.0-dev libxtst-dev \
libavahi-glib-dev libavahi-client-dev libavahi-ui-dev \
libnotify-dev libglade2-dev

git clone http://git.0pointer.de/repos/mango-lassi.git/
cd mango-lassi
(acknowledge the prompt)
sudo make install
You get a nice little GUI:

Screenshot-Input Sharing

I learned the hard way: don't try launching this remotely over ssh with X forwarding enabled -- not good things happen. I've got this running on Intrepid Ibex and Hardy Haron, and it works beautifully!


Quick DB2 Express-C 9.5 Update

A while pack, I started a post series about getting Drupal to work with DB2 Express-C 9.5 under Ubuntu. Unfortunately, right after jumping into this project, I updated my laptop from Ubuntu Gutsy Gibbon (7.10) to Hardy Heron (8.04). During this process, DB2 completely broke itself. Not only did it break itself, it broke itself in such a way that it couldn't even be un-installed through apt-get.

I recently found instructions for how to force removal of a broken DB2 package on Hardy Heron. This is good news, because it seems that about 6 months later, there's finally a working version of Express-C 9.5 for Hardy Heron!

Let's just hope that the db2exc package for Intrepid Ibex (8.10) comes out in a more timely manner :)


PixCede gets shorter file identifiers

My initial filenaming convention for PixCede was pure rubbish.

It all started with the best of intentions. After reading about the development of Pastebin and why the database got scrapped, I was inspired to make PixCede rely on the filesystem and not the database. I did, however, need to keep the timestamp so I could sort the images by the order in which they arrived. So my initial naming convention was:


That is, PHP's date('c') followed by an MD5 of the file. My logic was, date('c') would keep the time property and, if by chance any two images hit the system in the same second, they would certainly have different contents, and the MD5 would differentiate them (unless of course, the same image hit at the same time, but.. I don't see why it would need to be there twice). Using date('c') was just a bad idea from the start; if I had spent 2 seconds more thinking about it, I would have just used time(), which returns the number of seconds since the Unix epoch. Using an MD5 hash is a dumb idea too, because it's a pretty expensive operation.

So for version two, I used time() concatenated to uniqid(), a function that creates a UID based on the current time in microseconds (it's what the PHP manual pages recommend to use for Session IDs). Without any parameters, uniqid() returns a 13 character string. That brings me to:


Substantially better, but.. as the great doctor says, if something's worth doing, it's worth doing right. Ideally, I want PixCede to send a small enough unique identifier back to the user that he can type it into his browser, after receiving an SMS back. Next on the chopping block: the 13 character unique identifier.

In a dream world, I might get 1000 pictures per second with PixCede. Realistically, I think I only need to worry about two at once (and that's a stretch), but 1000 seems like a nice round number. If I use PHP's base_convert(), I can create a random number from 0 to 1,679,616 (36^4), and convert it to base 36 (10 digits + 26 letters) and only use 4 precious characters. This brings it down to:


Which is a lot better! It preserves the ordering in the first 10 characters, and uses 4 characters on the end to make it unique. But why not go balls to the wall? I might as well convert both the timestamp and the random number to base 36; a timestamp in base36 will sort just as well as one in base10. The final code I am using:

$id = (time() * pow (10, 7)) + rand(0, pow(36, 4));
$uid = base_convert($id, 10, 36);


11 character total, a saving of 47 over my original, poorly encoded 58 characters! This, I feel is an acceptable UID to have to type in by hand. If you want to improve on it, base62 is just small function away (there's a user contributed one on the PHP base_convert() page).

I decided to go ahead and switch it over to base62 encoding. The comment on base_convert() actually didn't work for what I needed; the images were mostly sorted, but off a little bit. It turns out you need to switch the upper and lower case letter sets in the dec2any() function ("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), and now everything works proper, with a final, 9 character encoding of:



Adam's Hang Gliding Adventure: Cooler Than What You Did Saturday

As I was going through some envelopes last week, I found two $100 checks that I wasn't counting on. The "Rules of Surprise Money" were very clear on the next step: I had to buy something I didn't need that was awesome, or do something I didn't need to do that would be awesome. I've got enough junk, so I decided to go with the latter. Browsing through Meetup.com, I found a group of people going hang gliding on August 2nd, and the total cost of ground instruction plus a tandem flight at 1000 feet was $195. The choice was clear -- hang gliding and a Chipotle burrito!

This involved waking up early that man was meant to on a Saturday to meet the Meetup.com participants in Santa Clara at 6:15am and then continue the ride down to Trespines outside of Hollister, CA. Once we arrived there, we split into a ground instruction group and the tandem group. The ground training consisted of learning the basics: learning how to run taking long strides (the longer the strides, the less you bounce up and down, and the lower chance you have of rupturing air tension along the wings of the glider), picking up the glider and balancing it on your shoulders, learning how to orient the glider with or against the wind, walking the glider on the ground, running with the glider, and finally, freakin' lifting off the ground with the glider!


The tandem was a little more intense. They had a winch that pulled a tow line connected to the tandem glider, so that it would pick up enough speed to lift up. Man. There are very few things that I have experienced that are as intense as that initial lift -- you go up one hundred feet before you even realize what's going on!
After climbing to cruising altitude of about 700 feet, you see those birds flying around down there near the ground. I taunted them for being wusses. After circling around for six or seven minutes, we landed in the field right next to the runway.


The instructors had all been doing this for years, and had great stories; for example, jumping off of Glacier Point in Yosemite and hang gliding from one side of the valley to the other. Or, the guy who hang glided from Mt. Tam just north of San Francisco about a hundred miles south. Or, the guy who has the longest flight record at 440 miles. Yea. 440 miles. That's roughly equivalent to the distance between Cleveland, Ohio and New York City. In a hang glider.

Satisfied Customer


PixCede: Thoughts on how to proceed

I haven't done any "real" work on PixCede since late last week, but I've done a lot of thinking about it -- which is probably a lot better than implementing without thinking. I've also been using it myself more than I thought I would be, which is really exciting. I've told a couple of my friends and collected some feedback, but Zach is the only one who started really playing with it.

I've thought a lot about whether or not to allow emails from non-phones through. The main concern is the potential for abuse -- who's to stop someone from writing a script to constantly spam the front page with whatever? Zach had a good suggestion of getting a short SMS number (like GOOGL) and only allowing pictures to come in through that. Then, I realized that getting a picture from one of my computers to the other meant emailing it to myself, which for some reason just seems like a huge pain in the ass. I used GMail to email PixCede a picture of myself on the Half Dome, and just retrieved it through the web site on the other computer. Yea, still email on one end, but on the receiving end, I felt incredibly less inconvenienced. Therefore, I think I'm going to implement a simple file upload feature to PixCede so that you can post a picture from one computer quickly, and retrieve it from another computer quickly -- without the hassle of logging into email on both computers.

I know what you're thinking: great idea! TinyPic had that idea YEARS ago! Short answer, yes, long answer... not quite. For one, I really am going to try to model this site after PasteBin more so than TinyPic and other similar services. I really like the dead simple usage of PasteBin, and I also like the content expiration too. I feel like that would discourage people from using PixCede as an image hosting solution -- which it is not. PixCede is a simple way to transfer pictures from one device, be that a cell phone, a workstation, or something else I don't know about, to another. So in that respect, I hope to differentiate myself from TinyPic and Flickr -- this is more of a PasteBin fork.

So, speaking of PixCede, I realized that the owner made all of his code open source. I love not re-inventing the wheel, so I'm going to start reading his blog and poking into the source code. I've briefly scanned his blog, and I was happy to see that he switched from a database back end to just a plain file system -- a decision I arrived at with PixCede a week or so ago. For something this dead simple, a relational database is really overkill. It just seems like the common decision to "my web app needs to persist information" is to just cram it into a database without really thinking about it. A well designed file structure will work just as well in this case.


PixCede: First working version!

It now seems that PixCede is "working enough" to justify putting up that blog I've been avoiding. Thanks to Simple PHP Blog, I was able to get one up really quick without having to install database software.

After fighting with the mailparse extension for PHP, I decided to switch to the PEAR mimeDecode module. From what I understand, it will run a little slower than the extension, but it has the main advantage of working. The move to mimeDecode follows the initial proof of concept that used procmail to pipe new messages to the command line utility munpack, which was being called from within a PHP script. Currently, procmail pipes to a PHP script that does the MIME decoding in the same script. The only other thing I'm doing is creating a thumbnail for the main page, renaming the image, and storing it to disk.

Like I said, functionality is basic right now. I don't have a database running; images are just renamed to {timestamp}_{md5 of content}.jpg. The naming convention takes care of order of submission, and throwing the hash at the end makes sure that unless two people submit the exact same image at the exact same time, there won't be any collisions. But, then again, if the image is the same, and the submission time is the same, would you really need it stored twice anyway?

I still have a huge todo list:
* Allow images to be directly accessible
* Automatically update the main page when new pictures are submitted
* Video uploads
* Confirmation SMS with direct URL
* Browse by time periods

I'm not sure what the "final" product is going to end up looking like; it will just be a continual evolution. While this is completely open and anyone can use it, I'm assuming it's still going to be people I tell by word of mouth for now. If you have suggestions or comments, please let me know!


Introducing PixCede

PixCede is an idea I came up with on the bus into work one day. I've been doing some development on it in my free time, and finally put up a working "proof of concept" last week. There's a development blog on the site, but I've decided to mirror PixCede posts on this blog.

(ripped from my about page)
What is PixCede?
Take a picture with your cell phone camera, send it to submit@pixcede.com, and check pixcede.com to see your picture. Additionally, you can directly view your image using the submission code sent back to your phone.

Ok, that's what it does, but what is it?
PixCede is defined in purely functional terms because I don't care what you use it for. In fact, I'm very curious to see what kind of pictures show up on here. I'll worry about how it works, you worry about what to use it for.

That sounds dumb. Can't you think of anything to use it for?
Sure, I'll tell you exactly what I'm going to use it for: I take pictures with my cell phone camera, and then they just stay there. I'm just going to use this as a sort of Pastebin for my pictures, between cell phones and computers. I'd imagine a lot of the pictures I submit will be either things I think look cool, cool cars, or funny things. But seriously, you should use it for whatever you want. I'm just providing the tool.

Sounds like a cheap way to host pictures!
PixCede is not a traditional image hosting site. I am paying for bandwidth out of my own pocket. If you need a dedicated image hosting site, use S3, Flickr, Picasa, or any number of other services designed for that

So what are you getting out of it?
Entertainment. I, hopefully like you, am interested in seeing what kind of pictures get submitted! A couple of months ago I saw a site about a guy who took a disposable camera and tied it to a park bench with a note that said something to the effect of "take a picture of whatever you want, I'll develop the film once it's all been used." This is my virtual camera-attached-to-a-park-bench.

Am I giving you my pictures? Will you make money off of selling them?
First off, I really don't know who you are -- by design. But I certainly don't think it's right for me to own them either. By submitting a picture to PixCede, you are putting it into the public domain.

Are you making any money off of PixCede?
Not right now. If it really takes off and I have to start putting up AdSense to cover excessive bandwidth costs, I'll let the community know beforehand. For right now though, I'm taking a barebones Craigslist approach.

What does 'PixCede' mean?
The 'Pix' part is pretty obvious: pictures. The suffix '-cede' means to transfer. Altogether now... 'picture transfer.'


BASH Scripting: Inserting text into a fixed location of a file

Ever need to insert some test into the middle of a file? Turns out there's a pretty simple way to do it! Assume you want to put the contents of "addition.txt" into "myfile.txt" at line 10:

head -n 10 myfile.txt > output.txt
cat addition.txt >> output.txt
tail -n +10 myfile.txt >> output.txt
mv output.txt myfile.txt

Of course, 10 can be changed to a variable, and file names can be changed to variables.


Book Review: Here Comes Everybody

Recently appearing on the Colbert Report, Clay Shirky talked about his new book Here Comes Everybody. I thought it was a good interview and sounded like a good book, and then promptly forgot about it. Then I read an article I found on reddit: Gin, Television, and Social Surplus. It was easily the most insightful thing I'd read all day. Then I noticed the URL and decided to buy the book when I flew back to Cleveland for CWRU Commencement. This was one of those rare books that's hard to put down; I really hadn't been this engrossed since I read the Da Vinci Code in two days. Don't let the easy reading fool you; that just proves how well written it was.

One of the topics Shirky explores involves the activity of edits on a Wikipedia page. If you look at the revisions a page has gone through, most people who have touched the page make very small changes, and there's a very active minority who are responsible for the bulk of the work. This distribution follows the power law (I really enjoyed linking that to the Wikipedia page, btw). The power law, in brief, is a sharp curve that shows a skewed distribution (think back to Algebra II when you graphed 1/x on your TI-83). This is odd in that an "average" Wikipedia contributer (not just a viewer) has a really low contribution rate, but that there are a few people that put forth enormous contributions. This doesn't just work for Wikipedia, though -- the economist Pareto discovered this fit a wealth distribution for countries he studied. The interesting thing about this is, with relation to Wikipedia, is that you can't look at just the individual. An "average" user, in the mathematical sense, has contributed very little to the page. You have to look at a page by the group that has worked on it, because it only exists as a result of the group. This explains a number of other online activities: Flickr postings, web blog viewing, e-mail discussion threads. Really cool stuff, and I'm not doing it justice.

The book focuses on what advancements in technology have done, namely, broken down barriers. The cost of organizing people has gone down greatly with the advent of blogs, Facebook, MySpace, Meetup, and any number of other sites. But Shirky doesn't focus on what has been done already; almost quite the opposite. This is what's being done now. Here's the problem people have now, and here's the tools they are using. These tools aren't limited to this problem. Maybe something else will be done using them in the future, who knows? This reminded me a lot of a podcast I heard by Marc Andreessen, co-founder of Ning. Ning is a platform for building social networks, and one of the things Marc mentioned was that they don't try to control what people use it for -- they just enable the community aspect of it. One of Shirky's themes throughout the book was that the internet will change the world the way the printing press did: in an unexpected way. When the printing press came around, the first thought was, "Ok cool, more Bibles." It quickly went far beyond that, to literature, flyers, and newspapers to name but a few. For most of the history of the internet, we've used to to do things online the same way we would in real life. It's just cooler because it's online. Only in recent years have web sites started to harness the power of the internet for what it is, and this is only the tip of the iceberg.

Something that was cool to me was when Shirky mentioned Martin Wattenberg at IBM Research. Martin was the manager of the Many Eyes project that my Extreme Blue team worked with last summer. Martin and crew wrote a paper on visualizing Wikipedia activity. Basically, I felt like a bad ass for sitting on a conference call with him.

It's a great book and a quick read, but chock full of awesomeness.


CBAX 1: Gas Prices

At my girlfriend's suggestion, I'm trying to make this observation into an XKCD:

Luckily, I have a surge check coming in the mail

So yea, apparently, you can make comics that are drawn simpler than XKCD. Also, CBAX stands for "Could Be An XKCD"


Part 2: Drupal 6.2 and DB2 Express-C 9.5 on Ubuntu 7.10

This is part 2 in my series on getting Drupal 6.2 and DB2 Express-C 9.5 to play nicely with each other. In the first part, I installed DB2 Express-C 9.5. In this part, I'll look at getting Apache/PHP5 setup and DB2 working from within PHP.

Step 1: Configuring DB2. There were some additional configuration steps needed for DB2, which are detailed on the developerWorks forum. There were some superfluous steps, but the worst you're going to do is overwrite something with the same thing. In particular, all the user accounts were set up already. If you're not familiar with DB2, you can issue commands from the shell, in the form of:

db2 "create database testdb"
but just make sure you're running these commands as the user db2inst1, or you source db2inst1's db2profile. If you can create `testdb`, then DB2 is working correctly.

Step 2: Install Apache httpd 2.2 and PHP 5.2. The Ubuntu Guide has information on setting up Apache and PHP, but the quick and dirty steps are:
sudo apt-get install apache2
sudo apt-get install php5 libapache2-mod-php5
sudo /etc/init.d/apache2 restart
Step 3: Install DB2 support for PHP. There is a PECL module for IBM DB2, which can be installed with PHP's PEAR (PHP Extension and Application Repository, like apt-get for Ubuntu).
sudo apt-get install php-pear
sudo pecl install ibm_db2
When I first ran this, I got the error: "sh: phpize: not found". After doing a quick search, I realized that I needed the PHP development files to be able to compile the DB2 driver:
sudo apt-get install php5-dev
After the module is compiled, it will ask you where your installation of DB2 is. In my experience, it wouldn't believe me when I told it where DB2 was installed to. Luckily, it ended up not mattering. When you get to this part of the PECL install, just hit Ctrl-C.

Next, I needed to configured PHP to use the IBM DB2 driver. In `/etc/php5/apache2/php.ini`, go to the extension section and add:
Note: correct the path if you have your module installed somewhere else; do a `locate ibm_db2_5.2.1.so`)

After making the changes, I reloaded Apache:
sudo /etc/init.d/apache2 reload
Verify that the module is loaded by making a quick PHP page in /var/www/ with the content:
<?php phpinfo(); ?>
and make sure there's a DB2 driver loaded. I started playing around with DB2 in PHP, but it was getting late and I decided to put that off for another day. IBM has some information on developing PHP5 for DB2, but it's barebones at best. I'll post a sample script next time.

Ok, so at this point, I have Apache, PHP, and DB2 Express-C 9.5 all installed and playing well with each other. In the next article in this series, I'll look at getting Drupal 6.2 to use DB2 on the back end.


Part 1: Drupal 6.2 and DB2 Express-C 9.5 on Ubuntu 7.10

DrupalFinally! It's been far too long since I've had an interesting project to work on. With a couple of sites I might have to make in the foreseeable future, it's time to investigate what I can do with stuff available today. There's a couple of reasons I've hit upon Drupal 6.2 and DB2 Express-C 9.5:

  • Silicon Valley Lab had it's inaugural meeting of the SVL Linux Users Group this morning. I recognize that this is extremely nerdy, and even nerdier to be so excited about it. But the turnout for the SVLLUG's first, unstructured, sort of planning event was about 50 people. Now, to put this in perspective, at any one point in time, I've had about five friends interested in Linux. 50? All of which who are guaranteed to be on campus eight hours a day, five days a week? I'm certainly going to take advantage of it!

  • Seriously, I work for DB2. If I can't get this database to work with Drupal, I will pester people until I have it working, and then I'll blog about it.

  • With MySQL drifting away from open source (come back MySQL! Come back!), I don't see a whole lot of reason to use it. MySQL doesn't exactly have the most cutting edge features (native XML support), and if it's free in the same sense as DB2, why not? IBM has always supported Drupal (15 part series!)

  • I recently read an article comparing Django and Drupal. I've used Drupal for a couple of web sites in the past, and been happy overall. The problem always ended up being with 3rd party modules, but I'd rather have an architecturally sound framework than something flashy that won't last.
Anyway, first thing's first:
  1. Download DB2 Express-C V9.5 for Ubuntu: it's as easy as `sudo apt-get install db2exc`, but you can find more information on Ubuntu's DB2 Virtual Appliance Page

  2. Download Drupal 6.2

  3. Install Apache httpd with PHP support

  4. Install DB2 driver for PHP
Ok, in the time it took to write that post, DB2 Express-C has downloaded and installed. Time to start playing; next post will be how to do steps 3 and 4.


The Coshocton Cycle

Note: I wrote this in high school for the heck of it, and eventually transformed it into my college admission essay. It's amazing they let me in ;-)

The Coshocton Cycle

I live in Small Town, USA. This particular small town is called Coshocton, Ohio. The Indians named the area "Land of the Black Bear," but the bears are long gone. Our biggest store is a Walmart, and there is not much in the line of entertainment. There's a bowling alley and a sporadically open movie theater. The population is about 12,500 in the city and 39,000 in the entire county. Apart from Coshocton City, West Lafayette and Warsaw are the other two wide places in the road.

I've often commented on the stupidity of the people in my town. It seems to me to be full of idiots. I started wondering why people would stay in a town such as this one. All are given the same education in the local school system. Why do some escape the town and others not? About the same time I began wondering, I started going to high school and meeting people from different parts of town. The screw-ups in town often had parents who were screw-ups. However, I can remember at least one person who didn't have the best family background, had the intelligence, and at one point had the drive to get of this town. She was going to break this cycle of unambitious citizens populating the county with more of the same. However, she made a few decisions in order to fit in. She decided to smoke. She decided to have a boyfriend, who had been in jail, and to have sex with him. Then, she talked of marriage, and it became clear: the small town, small-minded cycle of apathy broke her.

One major mistake causes people to be stuck in this town. A relationship with a screw-up will do it. Getting pregnant in high school will trap you here forever. Dropping out of high school. "Postponing" college for a while. Drugs. It all feeds the cycle, and the cycle feeds itself.

What is the one consistent reason for all of these mindless decisions? Apathy. At one point or another, people just stop caring. Apathetics being the majority in Coshocton, it's easy for them to rationalize with the thought, "No one else cares." No one else is successful, either. There seems to be something about this town that harbors apathy; something that makes you think "everything is okay the way it is," when that is so far from the truth that it's laughable. It's like trying to boil a frog: if you drop him into boiling water, he'll jump out. But if you put him in temperate water and then slowly raise them temperature to boiling, the frog will die.

For me, Coshocton High School was the second scenario. Seventh grade, wow, you can accomplish anything if you put your mind to it. Right now, I'm in my senior year, and I have a few points to add to that previous statement: "... only if no one else of higher status wants to do it instead," "... only if your idea is so conservative there's nothing that really characterizes it as yours," "...only if influential persons don't feel threatened by you," "... only if you have the correct last name," and "...only if you care enough to overcome these previous hindrances." That last point is the most important. You have to care. You have to step back, look at everything and say, "I'm going to break the cycle." You can't lose touch with this goal. One critical slip, and you've re-fed the cycle.

I have a friend who wrote an article for the school newspaper entitled "Masses of Apathy," describing student life at Coshocton. The administration jumped on it, and criticized it as being completely unfounded. The administration forgot the goal a long time ago. Not only are they feeding the cycle, they are making it grow with each additional year. Do they mean to? Probably not. But the water they've been living in has been warmed so slowly, that they can't see anything wrong with it.

A few students jump out of the water. They go to successful colleges and get fantastic jobs. They deserve a hero's welcome when they return to Coshocton. Except... Most of them don't come back. Those who do return because they want to, not because it is their only option. However, the number of these individuals is dwarfed by those who do not come back. Who in their right mind would step back into water that is so obviously scorching? It's almost like natural selection: the motivated people leave town, not staying to have motivated offspring in this town, and fewer and fewer motivated individuals are produced by the town. Have you ever seen native Coshoctonian Bob Brenly giving public speeches in Coshocton?

Just recently, instead of looking at people as they are now, I've tried a new spin. I try to think of them twenty years into the future. It's scary and depressing just how many people can easily be seen falling into the cycle, ready to begin it again with their children. Try and think of your best friend working at the video store, full time, for fifteen years. Depressing thought? Now try the same thing for all of your peers. It's amazing how many of mine that I can picture doing just that.

Don't lose your vision. If something seems wrong to you, but no one else, don't concede so readily. You may very well be correct, it's just that no one else is willing to admit that. The worst thing you can do, in Coshocton, is go with the norm. The norm is so skewed, and yet no one seems to notice. They can't see the forest for the trees; all they see is the general attitude of the town. They become mindless blobs... and it all began with apathy.

Don't stop caring. Not only can you screw your life up, but quite possibly your friends' and family's, making the cycle only grow out of proportion. I'm not saying be perfect; that's impossible. Make mistakes, and learn from them.The only irrevocable mistake is when you stop caring.


The Best Way I've Seen to Fill Out PDF Forms

It always makes me cringe to have to fill out a PDF form for something. As technologically savvy as (I think) I am, I usually resort to filling it out with ink and sending it in. I know that Acrobat Professional will do it -- the problem is, not every computer I use has it (work laptop) or can have it (to be fair, I haven't investigated it for Ubuntu).

But finally, I found a nice web application that lets you load a PDF form and fill in the fields directly online. Which means: free and platform independent. I'm really digging the trend towards web apps like this!

Check out PDF Escape yourself!


Trying Out My New 28-105mm Lens

I decided to put my birthday present to good use today. Lia got me a Canon 28-105mm to supplement my 24-55mm lens, and I think it's my new default lens. I know the 4mm on the wide end doesn't sound like a whole lot, but it's actually noticeable. But on the other end, wow. It's ridiculously useful to be able to zoom in that far!





See the rest of thePalo Alto pictures on Flickr.


One Finished Table!

Alright, enough was enough: it was time to finish the table. I had been holding off on finishing the top because the mouse sander just wasn't cutting it. Luckily, Craigslist came to the rescue again; Saturday morning, I found a used Craftsmen Belt Sander for $40 in Walnut Creek. It turns out Walnut Creek is about 50 miles away from Palo Alto... but even considering gas and time, it was still worth the venture.

It took me about 20 minutes to hone my technique, but then I was able to hone the table top (tip: go with the grain, always). I decided to reinforce the table frame, at the urging of my brother by putting diagonals across the top of the frame:

Reinforced Table

Next step: varnishing. I found some polyurethane varnish that is supposed to protect without staining. Between coats, I used 00 steel wool between coats to smooth it down. Four coats later, finished!


Look at that shine! Next: refinishing the entertainment center.


Adam Pretends to be Amish

Apart from the wicked beards and the gun racks on their bicycles, Amish are known for a 3rd thing: building really good furniture. So, if they can do it, why can't I?

First stop: Palo Alto Hardware store. I didn't really expect them to have a wide selection of wood, but I figured they'd point me in the right direction. Next stop was Bauer Lumber down Camino Real; however, they only had planks of wood, and I need 2x2s for the legs. The guys there did help me decide what wood I should use, though. I had originally decided on cherry, but they convinced me it would be too expensive. Most hard wood is expensive, actually. Third stop: Minton's in Mountain View. Oh man, this was everything I wanted in a hardware/lumber store! I ended up with some 1x8 and 1x3 planks, some 2x3s for the frame, and 2x2s for legs.

The planks for the table top were already finished, but Minton's was able to saw off a quarter inch to get a nice clean edge. The first step was to wood glue and clamp two planks together and repeat until I had 3 planks composed of two boards. I glued two of these together, but I ran into a problem putting the third on: the clamp wasn't big enough. The hardware store didn't have pipe clamps, either. Hmm... I ended up being able to use both clamps connected together, and just clamping the middle. Easy!

For the frame, I connected the 2x3s and in a square pattern and screwed the 2x2s into the corners of them. 2 screws on 1 face and 1 screw on the other face seemed to be enough to make it stable. Easy!

Half of a Table

After the table top dried, I realized it wasn't too stable. I also had the problem of how to attach the table top to the frame. I had some 1x2s lying around from a failed attempt to make bed slats, so I decided to put them to good use. Going across all of the planks, I used wood screws to attach the 1x2s to each board, using a screw that fell just short of piercing the table top. I also placed them in such a way and cut them to the proper length so that they also act to secure the table top to the table. I don't know the right words to explain this, so check the picture. Easy!

The finishing touch was to put the 1x3s along the sides of the table going across the planks. I found some 4 inch wood screws and drilled holes through the width of these boards, and drilled appropriate places into the side of the planks. Then, wood glue was applied to the side of the 1x3s, except for where the holes were, and the 1x3s were screwed into place. This also solved the problem of not having clamps big enough to secure them. Easy!

Finished Table

That about wraps up the structural design of the table. We're still working on sanding it down (starting with 60 grit and a mouse sander, and working down to 120 and then 240). After the sanding is done, I've got some polyurethane varnish to protect it while keeping the original wood color. I think 3-4 coats should be enough, using 00 steel wool between coats to smooth the whole thing down. Total cost? Yea, I don't want to talk about it. Wood is freaking expensive! There were a lot of sunk costs though: wood glue, saw horses, wood clamps, etc... But, that just gives me more motivation to start another wood working project. Next up: coffee table!

(special thanks to my dad and Evan Heiser for advice)


Pictures from the Cruise in San Francisco

I just put my pictures on Flickr from the PureXML team outing to San Francisco. Started with 300+ pictures, whittled down to 69 `keepers`, and hopefully there's 2 or 3 good ones.


Follow the picture link to see the set.


What to do with that leftover Ramen?

If you're like me, you ate Ramen in college because... well it just made sense: ridiculously cheap, easy to prepare, really filling, and didn't taste half bad. And, if you're like me, you're trying to phase out Ramen because: you have a job now, you have your own kitchen now, you realized it didn't taste that good, and you're starting to worry that something that cheap probably isn't the healthiest thing in the world (come on! Homeless people don't even eat this junk!).
We had a potluck lunch today for one of the managers who is moving back to Germany. I decided to use the rest of my Ramen for a raw salad sort of deal. I seem to remember having this at a graduation party or something like that, and liking it. Using the pipes, I found this recipe:

Asian Ramen Salad with Chicken
Asian Ramen Chicken Salad!


  • 1 (3 ounce)package ramen noodles, crushed

  • 1/2cup sunflower seeds

  • 1/2cup slivered almonds

  • 1 (12 ounce)bag pre-shredded cabbage(coleslaw type)

  • 5 green onions, thinly sliced

  • 1 boneless skinless chicken breast, cooked and diced(can use pre-cooked rotisserie chicken)

  • 1 (5 ounce) can water chestnuts, drained and sliced

  • 1 cup snow pea pods

  • 1/2 cup slivered carrots

    For the Dressing:

  • 1/4cupvegetable oil

  • 1/4cuprice wine vinegar

  • 1tablespoonsoy sauce

  • 1/4cupwhite sugar (can use Splenda, to taste)

  • 1tablespoon dark sesame oil

I shredded the chicken with a cheese grater after using the ol' Foreman grill on it, and left out the sunflower seeds and almonds. And of course, already having the cheapest ingredient (Ramen), I had to buy everything else. It took about 30 minutes to make and it turned out really well. Hit it up.
Ready to Serve


Using Craigslist Effectively

Having just moved to the area (and not having furniture), I've been checking Craigslist fanatically for free furniture in the peninsula. If you've used Craigslist before, either buying or selling, you know that if you're not the first responder, you're probably shot-- hence the OCD Craigslist checking. Since I've been working on a project to automatically download Daily Shows and Colbert Reports from Mininova RSS feeds, I decided to use technology to my advantage.

  1. Find the Craiglist RSS feed most applicable. For me, this is http://sfbay.craigslist.com/pen/zip/index.rss.

  2. Sign up for an account at FeedRinse. This site lets you filter an RSS feed based on keywords. I set up a filter for: couch, sofa, chair, tv, mattress. It provides you with a URL to the filtered feed.

  3. (optional)Sign up for notifications at Feedwhip. I don't use Google Reader or any other aggregators on a regular basis, so email updates are the most useful thing for me. Additionally, I can just pull up GMail on my cell phone browser, so while I'm taking the bus home from work, I won't miss any good finds.


Coolest program I've run across today

I spent part of the day reading Wireless Hacks in hopes of building a sweet antenna to score free wireless in Palo Alto (or at least for the BAMF factor). Before the antenna section, they had a list of some software that would be useful: Kismet, Wireshark, aircrack-ng, tcpdump... the standards.

Then they showed Driftnet, a simple program that passively listens for traffic, scans for images (JPEG and GIF), and displays the images as it finds them.


It's a really simple concept, but is a lot more interesting than following TCP streams in Wireshark. The book mentioned a really cool use for this too: keep people honest by putting this in a public location. Would you surf racy web sites from work if you knew all the images would show up in the reception area? I mean, I would, but that's what tunneling traffic over http is for :) </nerd>

Driftnet was pretty easy to set up on my system (Ubuntu 7.10). Because you're building form source, you need build-essential and gcc and all that good junk, plus gtk-config, libgif/libungif, libjpeg. Play around with `apt-cache search` until you find the appropriate packages to allow you build.

I'm not going to get into an ethics discussion, but don't worry: this is passive capturing as far as I can tell, and as such is undetectable over wireless (despite what some Chief Information Security Officers would have you believe)


Even if Geico can't save you money on car insurance, maybe I can

For personal reference, this is what I've learned over the last month in shopping for auto insurance:

1. If you've had violations, check your driving record so you know what you have to report. Personal Plans, a company partnered with IBM, told me I couldn't get insurance through their two carriers since I wasn't considered a California Good Driver -- which mean, I've had 2 violations in the last three years. He was able to tell me what showed up when my driving record was checked, and I found out I was within a day of having one go off my record. Don't report more than you're required to!

2. Shop around. I know everyone says this, but it's true. There was about a $700/year difference between the lowest and highest rates I got, and those weren't the first and second places I tried. I contacted directly about 8 places and used Lower Auto Insurance to send my information to a number of different carriers. I thought it would be ineffective (like eSurance), but I received a number of phone calls with substantially lower rates than the other.

3. Let them know if you're in college, a college graduate, and what degree you have. A number of places gave me a discount just for having an engineering degree.

4. If your car isn't worth much, don't cover it. My car is probably only worth $3000, so if I hit someone, I'll just pay to fix it or get a new car. Insurance wouldn't pay me more than the value of the car, and getting that coverage isn't worth the increased premiums.

5. If you have health insurance, opt out of medical coverage. This was something that was on my dad's policy that he recommended, getting about $5000 of medical coverage per accident. After talking to some of the insurance representatives, it sounds like that won't even come into play if you have decent health insurance.

6. See if your company has deals worked out with insurance providers. I didn't qualify because I'm not a "California Good Driver", but I'll recheck with Personal Plans this summer when another ticket goes off my record. Check Beneplace to see if you get any discounts (this site will also list eligible discounts at other stores, like Circuit City, so definitely check it out!)

7. Consider public transit to work. I'm not sure how much this affected my rates, but after signing my apartment lease, I'm pretty sure I'll be using public transit to commute to work -- work commutes are something they take into account when they figure your rate.

If I've listed something that's illegal... let me know. But I think it's legit.


Palo Alto!

Google Street View


Flickr Pictures

We're signing the lease this afternoon -- I'm really excited!

Pics from Pacific Coast Highway

This is the last load of road trip pictures, sorry it took so long to post them. I got lazy. The sets aren't completely finalized -- some pictures need some rotating and cropping, and there are some dupes for some reason. Anyway, I think a lot of the pics still turned out pretty stellar.

Driving up PCH

Monterey Bay Aquarium

Next post: new apartment in Palo Alto!


Lake Havasu to Bermuda Dunes

Lake Havasu was a short 200 mile drive to Bermuda Dunes, where Lia's parents and little brother live. On the highway to I-10, a train track parallels the highway. The train tracks are elevated on little hills, and the entire way is graffitied with messages on the side of that hill written in rocks. As an added attraction, every time there's a bridge over a dried up creek, there's an extra slanted surface to write on that's much closer to the road. Lia and I made our own contribution.

Pictures from the trip to Bermuda Dunes

We got to Lia's house in the middle of the day and her little brother was home. When her mom got home, we went to the Verizon store to get Lia a replacement one. She ended up with a Samsung Juke, which I think it really cool. It has a plate the spins clockwise off the phone to open it and has a really skinny screen. I like it, but it's not the phone for me. Since I'm looking to upgrade, I checked out the Voyager and other QWERTY phones -- I'm sick of T9 and Motorola's iTAP. We had dinner at Lia's house and then saw Juno with her brother. Juno was a lot less comedy and a lot more Little Miss Sunshine than I was expecting. The soundtrack is pretty good though.


Grand Canyon National Park

After Carlsbad, we drove to Gallup on the New Mexico/Arizona border. As we pulled in, we realized it was a lot colder than we thought: there was snow on the ground. The guy at the front desk said it had been there a couple of weeks and it hadn't thawed yet.

We got to the Grand Canyon at about 2:00pm on the 16th. I decided to buy a season pass for the national parks, hoping that it will motivate me to go to Yosemite (like how gym memberships cajole people into going to the gym). They have a photo contest with the winning photo being displayed on the next years park pass. Hmm...

Just like Gallup, the Grand Canyon had snow but also an added bonus: wind. This terrible twosome made it miserable to be outside for more than 5 minutes. Luckily, the road that goes through Yosemite had a bunch of turnoff points for scenic overlooks. We stopped at about 5 of them over the course of 2 or 3 hours. The sky was a little overcast for most of the day, but as it began to set, the colors became a bit richer. I think shots in the summer would turn out much better, but I still think I got some neat ones.


Raven in flight

All the Grand Canyon National Park pictures

After leaving the Grand Canyon, we stopped at the Road Kill Cafe on Route 66. Mediocre food at high prices. Yea, blame the interstate all you want, Route 66, but you need to step it up. While looking for a place to camp for the night, Lia recognized a place she had gone to when she was growing up: Lake Havasu. We called the Crazy Horse Campgrounds (actually note a strip club) and reserved a site. When we got there, we realized that wouldn't be necessary because no one else was dumb enough to camp there in the winter. The camp sites were in sand by the lake, which got a slammed wind into the tent all night long. The fire wasn't bad, but we also had to buy all the wood to use in it, which was lame and expensive.

Route Recalculation...

17 Wednesday: To the grand canyon! Google map route. Spend rest of morning and day there until the sun goes down. Drive halfway to Palm Springs and camp
18 Thursday: drive to Palm Springs
19 Friday: Drive to San Diego (hour and a half) go to Tijuana
20 Saturday: Drive halfway up PCH
20 Sunday: Finish! Arrive in San Francisco! (early evening)
21 Monday: Lia flies back to Cleveland :(


Coolest cave pictures you'll see all day

Since we didn't go out last night, we were able to get on the road by 9:30 this morning. The weather didn't look to good, but after a couple of hours, we had out run the storm, and also entered New Mexico. We got to White's City, the nearest city to Carlsbad Cavern, and bought tickets to the Cavern. Tickets are only $6/person! And this is in our country! If you're in the area, you need to stop there. Avoid the restaurant though, it's the same quality as a Pilot Gas station. Do hit the grocery store though, they have rock candy and cherry cider (although the latter I noticed after I had checked out, so I didn't buy it).

There were two ways to enter the cave: the natural entrance that took about an hour and an elevator down 800 feet that took about 3 minutes. Since there was a lot to do below the 800 foot mark, we decided to take the elevator and give ourselves the option of walking back up to the top. The employee at the elevator asked us to get rid of any food or chewing gum, because it can attact animals that can't live there, end up dying, and need to be cleaned up by the staff. Also, there was a small one foot stalagmite that he told us to touch to get it out of the way -- and please don't touch any of the structures in the cave because it would cause them to stop growing.

We exited the elevator and Lia commented that the area just looked like museums and stuff decorated to look like a cave. This was in the food court area (impressive in itself, since it was 800 feet below the surface). It quickly turned into a real cave. Oh man, what a cave! I don't want to waste your time talking about it, you should really check out the pictures. Here's a couple to entice you:


(this is a must see at original size)

(this got favorited on Flickr after less than an hour)

Carlsbad Cavern Set on Flickr

Attention reddit army: I've posted this on reddit! Help it make it's way to the front page! Coolest cave pictures you'll see all day [visit Carlsbad! It's only $6!]


Texas and Ghost Towns

Charles sent me a link for ghost towns and said that we would be driving through ghost town central, Texas. Knowing that I wanted to end up a couple of hours from Carlsbad Caverns, I chose McCulloch county because it had a handful of ghost towns, including Salt Gap.

After a quick lunch at Taco Cabana in Houston, we hit the road on I-10 West, but not for long. When we hit Columbus, we took 71 north (no, seriously) towards Brady, Texas. When we got to Brady, we stopped to ask for directions to a Salt Gap. The first lady I talked to at a gas station was really confused -- she thought I wanted polo shirts. The second lady also didn't know about Salt Gap (this is in their county!), but the third guy did. It was on a county map, so we just found the relevant intersection and plugged it into the GPS.
It wasn't the type of ghost town I was expecting. The web site had said something about an abandoned post office, which we didn't see. Also, it looked like at least one of the houses was still inhabited. Off a side road though, I did find two collapsing buildings that yielded some good photos.



Here's the rest of the pictures on Flickr.

We decided to get a hotel in Odessa, TX, which was surprisingly big, considering I couldn't find anything special about the town.

Day 1: Cleveland to Memphis

This trip was the anticipated amount of boring. Lia and I have both driven the Cleveland to Cincinnati stretch, and just extending it down further south isn't too interesting. We saw the Florence Ya'll water tower in Kentucky. Our hotel in memphis was right by Beale St., and we met up with Lisa and some of her friends there.

Beale St. is really a cool looking place. I've heard it picks up later in the night, but we were only there until about 2am. The bars all stay open until 5am, and then the cops force everyone out. It's a little like Feast of the Assumption in Little Italy in that sense ... but only in that sense, really.

All the pics


Cross Country Road Trip #4

It's that time again -- time for me to make another cross country road trip in the Nissan, although this will probably be the last one for a while. Here's the tentative schedule:

Day 1 [Jan 12] - Cleveland to Memphis (visiting Lisa Keung)
Day 2 [Jan 13] - Memphis to Houston (visiting Charles Larrabee)
Day 3 [Jan 14] - Houston to El Paso (for no reason other than the song)
Day 4 [Jan 15] - El Paso to Vegas
Day 5 [Jan 16] - Vegas to Palm Springs
Day 6 [Jan 17] - Palm Springs to {somewhere between LA and SF on PCH}
Day 7 [Jan 18] - PCH to San Francisco
Day 8 [Jan 19] -
Day 9 [Jan 20] - Spend the day in San Francisco
Day 10 [Jan 21] - Lia flies back to Cleveland
Google Map

So... it looks like we have a day of play in the schedule. Suggestions?


Thinkpad Trackpoint on Xubuntu

After chasing many rabbits down many rabbit holes, I figured out that it's actually -really- easy to get the Trackpoint working in Xubuntu 7.10 (Gutsy Gibbon) on my Z60t. Open /etc/X11/xorg.conf and look for InputDevice with the Identifier `Configured Mouse`. Add:

Option   "EmulateWheel"   "true"
Option "EmulateWheelButton" "2"

As an added bonus to make all your Mac friends green, find the InputDevice with Identifier `Synaptics Touchpad` and add:
Option  "VertTwoFingerScroll"   "True"
Option "HorizTwoFingerScroll" "True"

and now you have that nifty two finger scrolling ability.