Using Google Voice to Extend T-Mobile MyFaves

I switched to T-Mobile last fall when I switched to the G1, and have found their MyFaves feature really useful. For those of you who don't know about it, MyFaves are five phone numbers that you link to your account and get unlimited talk time to. This is GREAT. It turns out I talk to my two most frequently called numbers more than any of my other numbers combined. However, the 866 conference call number that I dial into for work is not allowed to be added as a MyFave. That's annoying. And it was more annoying after doing that a handful of times thinking the MyFave add went through (when it didn't) and getting the bill.

Enter Google Voice (formerly known as GrandCentral before being acquired). GrandCentral started out as a service that gave you a free phone number that you could link to your different physical phones. When your GrandCentral number rings, it rings all of your linked devices and you can pick up the one that's most convenient. For example, if you're at work and you don't want to pay for airtime minutes, you can pick up on your work phone. Neat. I signed up for this service when they launched and forgot about it until recently, with all the hub-bub about Google Voice.

Google Voice adds a lot of cool things that I will probably start using eventually. But let me get to the meat of it. Add your Google Voice number as a MyFave through T-Mobile. Then, from the web interface, you can supply it with a phone number and have it connect the call. When your cell phone rings, it's from your Google Voice number -- and since that's a MyFave, you get unlimited free talk time. Using Google Voice, you can turn your five MyFaves into unlimited MyFaves and never again have to pay extra minutes.


The Little S3 Backup Script That Could

After having an external enclosure fail (grrr LaCie!) and realizing that all of my backup data was spread over about 6 hard drives, I decided to check out Amazon's Simple Storage Service (S3) to back up all of my important files to one central location. A friend recommended Jungle Disk because it was "free", but since it wasn't, I decided to play with it on my own. Given my recent love for Bash scripting, I decided to start that way.

My first task was to make a back up of all my pictures, which was a set of about 100 folders following the format "YYYY-mm-dd name of event". Since S3 just gives you a table interface, I decided to archive each folder in a tar and then upload the tar. It seemed unlikely that I'd want only one picture from a set, so this also made sense. The caveats were that I needed to change spaces to underscores in the .tar filename and that I only wanted to keep the .tar around long enough to upload it. I found Google's s3-bash to be the most straightforward utility for copying files to S3 from my shell.


ls -d /media/gadget/pictures/* | while read -r FILE; do
# transpose spaces to underscores
tarfile=`echo $FILE | tr ' ' '_' `.tar
tar cvf $tarfile "$FILE"
/opt/s3-bash/s3-put -k #MY_KEY# -s /opt/s3-bash/.secret \
-T $tarfile /derwiki-media/`basename $tarfile`
rm $tarfile


Twitter Bowl 2009: A Ten Day Experiment in Gonzo (part 1)

Twitter Bowl is a Twitter mash-up that Adam Bossy (@abossy) and I (@derwiki) created in ten days for the Super Bowl. I'd like to share with you our experience and the lessons that we learned.

Day 1: Initial Conception and Working Prototype
This was the easy part. Coming up with the idea was inspired by a co-workers presentation about mash-ups, and a baseball mash-up he made. I had used TweetGrid for the AFC championship to see what the buzz was -- who the Twitterverse thought would be going to the Super Bowl. It was surprisingly entertaining to follow, but I figured the general public wouldn't want to play around with TweetGrid. Luckily, there's a TweetGrid widget, so I embedded two of those on a page with different keywords for different teams. From the time I opened Vim until I finished the first iteration, it honestly took two hours of work. I already had a Slicehost account, so I just threw it up on there, registered the domain, and set up the DNS records. It took all of 5 minutes to add Google analytics to the site and start tracking.

Day 2: Post First Iteration to Ask Hacker News
We didn't get as much traffic as I had hoped, and most of the criticisms weren't constructive: "your site design sucks", "do something useful", "solve a real problem", etc. By this point, I had gotten enough positive feedback from friends that I said fuck the naysayers cuz they don't mean a thang. They were right, but they didn't tell me how to improve it. There were a few good things that came out of this post, so it was completely worth it. Izak30 pointed out that there might be trademark issues using the term "Super Bowl" outside of the widget on the site, so we nixed that. He also wrote a blog post about our site and how we were soliciting feedback so early in the development cycle. I'd like to thank Evan Heiser (@sass9210) for the idea on making the new design. He pointed out out that the ESPN widget didn't really fit the rest of the site, but since it was unchangeable, we should make the rest of the site match it's styling. Brilliant!

Day 3: Snowboarding.
We talked about Twitter Bowl to people, but weren't able to really work on it. No regrets here :)

Day 4: Revamping the UI and Adding Inline Tweeting
With Bossy solidly on board, he plowed through some design mock-ups in Photoshop. We actually posted our ideas to Ask Proggit, but didn't get anyone to respond. We ended up just asking a lot of our friends and choosing the most popular design. As Bossy started chopping up the graphics into HTML/CSS/images, I started working on the inline Tweeting function. This was another recommendation from Evan, saying that it would make visitors feel more like active participants. There were some technical hurdles that I won't bore you with (cross site Ajax), but Script.aculo.us and a quick 'n dirty PHP script saved the day.

Day 5: Switching to GWT and integrating inline Tweeting
Amongst frustration with tables/CSS hell, Bossy started re-implementing the page using the Google Web Toolkit. In the meantime, we kept up our bastardized version that had basic inline Tweeting functionality -- but just didn't feel clean. I think it was this day that I also created the Twitter Bowl fan page on Facebook.

Day 6: Advertise Advertise Advertise!
I literally told anyone and everyone. I created a Twitter account, @tw1tterbowl, to announce to no one in particular about the site. My hopes were that people would search Twitter for things related to the Super Bowl and run across Twitter Bowl. We also posted to Reddit, and received a lackluster response. It was about this time that we realized web site + HN/Reddit/Digg wasn't going to be enough. At the recommendation of friend Ed Shelton, I started contacting every radio station in Pittsburgh who might want to talk about it and emailing people who ran Steelers blogs. No radio station that I know of said anything about it, but Matt Loede at Steelers Gab wrote an entire post about us.

Day 7: Implement Advertising
After still not hearing back from AdSense (wtf Google!) we signed up for AdBrite and put a banner on our site.

Day 8: Finished GWT Version
Bossy finished up the new site done with the Google Web Toolkit and we pushed it live.

Day 9: Snowboarding Again.
What can I say, I'm addicted!

Day 10: Super Bowl Sunday
We did a last minute blitz of advertising. We posted to Hacker News again, Digg, Twittered about it, and then sat back to watch the game. We kept a laptop open that was updating total/unique hits in real time. Just as anticipated, we saw a spike in both during the actual Super Bowl. That Sunday, we doubled the amount of traffic that our site had received in total. The next blog post will be a more detailed analysis of the traffic, but I will tell you that our total unique count is around 2000. That might seem paltry, but I don't know 2000 people, so I consider this a success.

That was a quick ten days! I was so happy to have something fun to program again, even if it wasn't technically challenging. What was challenging were the other aspects: incorporating feedback, advertising, and improving the user experience. And we learned a lot about that! Our major lessons:

Release as early as you can and start collecting feedback. This is the single most important thing I will take away from this experience. You, the developer, are creating the site/service for the user. There is absolutely nothing stopping you from using the community from the earliest stages. For Twitter Bowl, we had an idea, created a prototype, and launched. Everything we implemented after that, everything we tweaked, and how we advertised was a collaboration between myself, Bossy, and everyone else who cared enough to tell us.

Ask anyone for advice who you think might care, and don't get discouraged if they don't care. I asked everyone I knew for feedback almost every day (thanks guys!). My own personal Twitter account was non-stop about Twitter Bowl, and I asked everyone I knew for advice on how to improve the site -- especially the people who don't drink the Twitter Kool Aid (read: non-programmers/techies). But by the same token, I didn't get upset if people had nasty things or nothing to say. The good feedback/advice I got made all the crap worthwhile.

If you're going to post to Hacker News, Reddit, etc. asking for help, listen to the feedback! More importantly, take the time to personally thank everyone who responded with constructive criticism. They deserve it! But seriously, distance yourself from the project. Criticisms to the project are not criticisms of you. Every bit of feedback you receive is valuable and might help you realize a mistake you're making before it becomes a big mistake (this goes hand in hand with launching early and iterating quickly).

Don't re-invent the wheel. It's 10x quicker to consume existing solutions than to create your own. You end up wasting less time on details, and can focus more on the bigger picture. We used Google extensively: web toolkit for the page, analytics for daily updates, and AdSense to make 27 cents (seriously, that's it). TweetGrid provided a widget that provided the basic functionality; ESPN provided a widget that allowed us to legally put a Super Bowl logo on the page.

Don't advertise. I'm still really pissed at us for this one. We made twenty-seven lousy cents at the expense of putting up distracting and useless advertisements. If we had put up TipJoy and been tipped a quarter, we would have done just as well. Even with the modest goal of earning back the domain name registration ($10), we fell entirely too short and wasted too much time setting up and implementing advertising. I mean, it wasn't a lot of time -- but at a return of 25 cents, any amount of time was wasted time as far as I was concerned. On the other hand, this did confirm my suspicion that the advertising-based revenue model is total bullshit. If I ever do a start up that doesn't have a different revenue model... well, I just won't do that. This experiment cleared up any delusions that I might have had.

I'm going to conclude this post with a charge: if you have an idea, try it! This project was an invaluable learning experience, and cost very little. Maybe 10-20 hours of development time, and maybe 5-10 hours of advertising. That's IT. What's stopping you from putting your idea out there?


Learning How To Snowboard, In Engineer-Speak

This is going to be a slight departure from what I normally write about. This past winter, I've been learning how to snowboard and it's been fantastic! One of the new loves of my life, right up their with programming, fireworks, and Dark Side of the Moon. I was fortunate enough to have engineers teach me how to snowboard. That sounds silly, but some things are better expressed in engineer speak from one engineer to another; you can express ideas more succinctly and explain the underlying concept. This blog post is meant for engineers to quickly learn the fundamentals of how snowboarding works.

1. Standing up
Ok, the first thing you need to do is learn how to stand up. The important thing is that you position your board perpendicular to the slope of the hill! Remember, you move quickest along the long edge of your board, so you want the edge to be perpendicular to the slope vector of the hill to minimize downward motion. You want to stand up as fluidly as possible; kind of rock your upper torso back and forth, and then push your weight forward. As you stand up, remember that you're not putting the board flat down on the snow. If you do that, you'll start sliding and probably fall. Your back edge needs to dig into the snow, and your front edge should be raised slightly above the ground. All you're trying to do is balance here.

2. Sliding forward
Start from standing up and lean slightly forward, tilting your board down the slope you're going down. Do it slowly and you'll start inching forward. To stop, just lean back. The more you lean forward, the faster you will go, because your downward force on the hill will be distributed over a larger surface area and your board will have less ability to dig into the snow.

3. Leaf Falling
As you continue to slide forward, your board-to-slope will veer away from 90 degrees. You'll find yourself either moving more left or more right as your board starts turning slightly. Don't worry! You can easily correct this. If you start moving left, kick your right foot forward. The goal is to make the board closer to perpendicular to your motion vector. Once you correct, you will probably start sliding gradually towards the right. This is good! Kick your left foot forward and continue the process. You will look like a leaf wafting down from a tree, hence the name.

4. Stopping while Leaf Falling
This is all about getting your board perpendicular to the slope vector again. And if you can leaf fall, stopping is simple. When you go to change directions, don't kick your foot as far foward. Kick it far enough that you stop moving with respect to your motion vector, then immediately swoosh your feet so that the board is perpendicular to the slope vector of the mountain. This is a two step process: halt motion that is existing, and position the board to prevent more motion.

5. Faster!
As you become more comfortable with leaf falling, you can start aligning the edge of the board more with the direction vector; this will increase your velocity. When you think you're going to fast and want to stop, kick your trailing foot so that you're board is perpendicular to your motion vector. Get proficient at this before you move on.

6. Linking Turns
To graduate to linking turns is a natural progression -- if you're going fast enough. Carving an edge into the snow is much easier with a little bit of speed, so don't be too afraid of it. When you're sliding with your board flat on the ground, you have the least control -- your weight is being distributed over the maximum surface area. You only have control of the board when you're on your toe edge or your heel edge, because you're concentrating most or all of your force on that edge. So remember, carving == control. Going along with that, to go straight, you don't. As you go down the slope, you switch from toe edge to heel edge making "S" tracks in the snow. If you stard on your heel edge, you'll cut left across the mountain. Don't cut too sharply! When you've gone as far over as you want to, you shift weight from the heel edge to the toe edge. You'll briefly not have as much control when you're flat on your board, but as you continue leaning forward, you'll toe edge will engage and you'll curve to your right. Do the same thing in reverse when you get far to the right.

That's it! Like engineering, a solid understanding of the fundamentals and why certain things work will take you a long way. And just like engineering, you need practice, so hit the problem set (slopes)!


Using sed to remove deprecated function calls

I am super lazy. As a programmer, this is a good thing. For a project that I work on, I was recently given a code maintenance task of cleaning up assert statements. ASSERT_S_#_MED had been deprecated in favor of just ASSERT_S_# (where # is the number of informational parameters for logging purposes).

The caveats are that I don't know how many files have the deprecated call, and I didn't want to do a blind stripping of _MED because I wasn't sure if it was legitimately somewhere else in the code; so I needed to make sure a digit existed before it.

1 #!/bin/sh
2 LIST="`grep '_[1-9]_MED' *.C | awk '{print $1}' | sed 's/://g' |uniq`"
3 echo $LIST
4 for i in $LIST
5 do
6 cleartool co -nc $i
7 sed -i 's/_\([1-9]\)_MED/_\1/g' $i
8 cleartool ci -nc $i
9 done

Line 2: Populate a list of all files with the deprecated call. The awk takes the first part of the grep, then the sed strips the colon, and then uniq removes duplicates.
Line 7: The sed matches _[1-9]_MED, captures the digit, and uses a backreference to put it in the replacement. The -i flag means it edits in place.
Line 6,8: Version control that I'm using for the project

Hopefully this will be useful to someone! If you have a better way of doing it, I encourage you to post in the comments. We're all learning, after all!