Tuesday, November 1, 2011

I'm terribly nervous about running the NYC Marathon this Sunday, Nov. 6, 2011. I started training the first week of June. Over the past 5 months, I've ran over 350 miles. 70 miles/month. I've destroyed 1 pair of sneakers. Ran 15 miles in 100 degree heat. Ran across the Golden Gate Bridge. Ran on the Miami Beach Boardwalk at Sunrise. Just this weekend ran in 3" of slush.

18 Miles with Josh Anish in SF.

And for what?

Nearly a year ago, rushing to the PATH station, I felt my stomach slump over my ice cold belt buckle. "Holy Shit! How did I get so fat?" Early on in our relationship, my wife and I passed a man in the mall whose belly stuck out from under the bottom of his shirt over his pants. We agreed we would never let ourselves to go like that. I was not keeping up my end of the bargain.

This is how I decided I needed to do something? Neither fear of diabetes nor fear of heart disease had been enough to scare me into fixing my diet and exercising. This simple, all too fleshy sensation was the trigger. I knew I needed a change.

Shortly after my epiphany, Tim Ferriss released 4 Hour Body. The most important aspect of the book was that it illustrated how other over-worked techies could fix their diets by making simple, repeatable changes. He also got me to think of my diet as a science project instead of something to dread. Cheat day was a god send and got me through a couple tough weeks of travel. At my heaviest, I was 268, at my lightest, I'm down to 222 (really want to be ~210-215). I used to rush off to the train in the morning, and grab a 600 calorie breakfast sandwich, I now make myself a couple eggs with veggies and turkey bacon every morning. It doesn't take me anymore time. And I lost 40 pounds.

Sunrise run in Miami.

Then, in March, @naveen from Foursquare retweeted a message from @dens about Camp Interactive looking for marathon runners for their team in the 2011 NYC Marathon. I committed to run a marathon the year before as my New Year's Resolution, because I'm an idiot. Nevertheless, I filled out the form, I was honest that I didn't think I could run 26.2 miles or raise $5,000.

In June, Camp Interactive accepted me anyways.

I hadn't been exercising or running regularly for over a year. I had no idea how I was going to do run a marathon. Fortunately, as usual, our VP, Product Development had a plan for me. Brian setup some simple, achievable goals for my monthly distances. I also found a first-time marathon plan with the minimum amount of running during the week.

Final run in the snow?!?!

Every run was a new, faster time, or a new longer distance. I learned how to hydrate, when to eat Goo, how to master a negative split (fingers crossed for getting any/all of those right this Sunday), but most of all, I learned that I my body is an amazing, flexible (figuratively) piece of machinery willing to be pushed well beyond my mind's breaking point.

In less than a year, I've dropped 40 pounds and have run at least 20 miles. Fingers crossed for making it the full 26.2 this Sunday. Thank you all for your support and donations (not too late for more), especially my amazing wife who's put up with me spending 1 day every weekend for the past 5 months disappearing in the woods for 2-4 hours and coming home to ice my knees and pass out on the couch.

For all of my friends in or near the city, I'd love to hear your cheers on Sunday. My bib number is: 44712.
Best of luck to all my fellow runners -- esp. Team Interactive and fellow Knerds: Ken and Jen!

Monday, February 14, 2011

Many engineers seek to use the right tool for the job (and they should). Most tech managers get a bit freaked out at the idea of endless language proliferation (who cares?). To help your tech managers be a little less freaked out and ensure you never ever again get stuck in a J2EE stack, there are 3 things that you need to keep in mind when adding Python, Ruby, Haskell or Lisp to your runtime environment.

The MySQL bindings will suck.

The initial appserver config will be wrong.

The exception handling and reporting will be useless.

We'll miss you too Duke.

The MySQL bindings will suck.

I'm 0 for 3 (Java, Ruby, Python) in implementing a new language and having anything sort of like smart idle connection timeout handling. I've needed to implement wrappers in Java (hopefully this isn't still the case), patch the Ruby MySQL gems and have tried to figure out the one right Python wrapper for ensuring my app doesn't need a restart once connections are timed out by the server. These are all solvable. Just make sure you test for these issues and resolve them prior to production deployment.

The initial appserver config will be wrong.

Most languages run in some sort of appserver, typically that's wsgi or some mod_ apache plug-in. But, some appservers have strong language preferences - esp. in the Java world. Make sure you understand how your new language is going to run in a new appserver - multithreaded or multiple processes? how many threads or processes do you need? are database connections pooled?

The exception handling and reporting will be useless.

On our team, at Knewton, we email all engineers exceptions and stack traces. We've needed to implement this for both Ruby and Python. For both, we needed to add in important information for debugging - request params, headers, along with a usable stack trace. One other common issue we've encountered is that all libraries for connecting to external resources (curl) have useless default errors. Most of these libraries do not tell you explicitly what they were trying to connect to when the exception has occurred - "Destination Unreachable" is not useful; which destination (hostname, ip, port)? We've patched curb in Ruby and are currently patching Python to let us know what we were unable to connect to.

These are the most common issues I've seen when adding a new language to an environment. Are there any I'm missing (or conveniently forgetting about)? If you can think of any, drop me a comment below.

Thursday, February 10, 2011

Every once in awhile, I'll receive a large set of documents that I need to quickly read and categorize. Some day I hope to use NLP for those categorizations, but I still have much to learn. One document format that I always struggle with converting on Mac OS X with Python is .pdf. But, not anymore...

Monday, January 24, 2011

When learning a new API or programming language, I often get a bit nostalgic for the first programs I wrote in BASIC. Those programs looked a lot like this:

10 INPUT "What is your name? "; U$
20 PRINT"Hello, ", U$

To illustrate the simplicity of Twilio, Google's App Engine and CherryPy, I'll take this simple program and show you how to build it for an SMS interface.

Twilio allows you to automate placing and receiving phone calls, and placing and receiving SMS-messages (or TXTs). For this tutorial, we'll focus on placing and receiving SMS-messages. App Engine is a way to inexpensively (free to start) run web applications in Google's cloud. CherryPy is an extremely simple HTTP server for Python. CherryPy has nominal configuration and reminds me a *lot* of the simplicity of the original Java Servlet specification.

Before we get started, you need to signup for Twilio and Google App Engine accounts. Both are free and easy to setup. Once you've done that, swing on back, and we'll walk through the rest.

The Spec

A user sends an SMS to your sample Twilio account phone number with the text "?".

Twilio sends that request to your new Google App Engine App.

Google App Engine dispatches the request to your CherryPy app.

CherryPy reads the body of the request.

If the request field Body is "?", CherryPy responds with "What is your name?"

If the request field Body is not "?", CherryPy responds with "Hello, [Body]."

The user that sent the original SMS message receives the response on their phone.

The Development Process

First, we're going to get a simple app running in CherryPy on your local machine. Then, we'll get it running on App Engine locally, and in the cloud. Finally, we'll connect Twilio to App Engine and you can watch it all in action.

Add the parameter for the body to see how it works with a response http://localhost:8080/?Body=Pete. # Note case for form fields matters, cherrypy automatically maps query paramaters to variables in your index method.

You should see the response:

Hello, Pete. Shall we play a game?

Viewing the source will show you the XML that you will be sending to Twilio in just a little bit.

The cherrypy setup is really simple. You import cherrypy, mount the default URL "/" to your TwilioQA() class, and run the server with the quickstart() method.