Posts from 2010

Questions or comments? Email me.

Sun 05 December 2010

The Everlasting Fight To Expand My Metaphorical Sight (Part 1)

For the past few weeks, I've had the incredibly fun experience of living in Tokyo, Japan. I've already fielded quite a few questions as to the "why" I decided to do this, and in an effort to not re-type the story another hundred times, I figured I'd throw it down here along with my experiences thus far. This post is not programming centric; for those of you who follow the feeds for them, you'll have something soon, no worries.

The Backstory

Back in early November, I was at somewhat of a crossroads. I had recently come to the conclusion that I'm not a huge fan of San Francisco. I went ahead and checked out Chicago after that experience, and while it's an incredible city in its own right (and certainly one of my favorite US cities), I found myself wanting more. The funny part about traveling in the US is that for all its regions and supposed differences, at the end of the day you'll find largely the same things no matter where you go.

So I figured, alright, let's see what other countries have to offer. I applied, and (somehow) got my passport within a week. The question then became "where to?". I could've gone somewhere like England, France, Germany... the standard "alright, let's backpack for a year and see the world" destinations that are often suggested.

Thing is, I'm not like that. I enjoy jumping off the deep end; the way I see it, if I can survive the biggest changes and come out fine, then anything else in between is a cakewalk. This is largely one of the reasons I chose Tokyo/Japan; not only is the language incredibly different than anything I know at the moment*, but it is literally on the other side of the planet.

(...though some would argue German is on the same level, if not higher, but I digress...)

One of the exciting parts of this journey is the path I've taken. I flew off the west coast, came to Japan, and will head to England and/or The Netherlands for about a week after this. From there, I fly back to the east coast. I will have fully circled the globe by the age of 23, under my own power. This has been a goal of mine for quite some time now, and it's really satisfying to see it come about.

Initial Life In Japan

The minute the plane touched down (after a lovely 12 hour flight) was interesting, because the culture shock hit me immediately. Not "uncomfortable, get me out of here" style, but definitely "wow, there is definitely something different here". I'll state up front that this has been evident the entire time I've been here, too; back home, I obviously grew accustomed to a lot of things, and the way they're done here is almost always radically different in some way. It definitely took some getting used to, but overall I've enjoyed it so far.

I rented an apartment a little bit outside central Tokyo, in an area known as Nishimagome. Trains into the central part from there are cheap, and take about ~15 minutes, so overall it worked out incredibly well. One part that I found very interesting was the feeling of being a minority - while I'm sure this comes across as potentially ignorant to some who'll read this, I've never actually felt that before in my life. I've lived in areas as a kid where some might say I was, but there was very little social divide in those scenarios. Being here incurred a language barrier and a customs barrier (i.e, society here has their own customs which the US doesn't necessarily follow), which sits on top of the typical social divides that we as human beings tend to exhibit in general.

For the first two weeks, almost nobody in Nishimagome wanted to deal with me. It was very fascinating; some appeared to do it out of a lack of understanding in regards to my home culture (and believing that I didn't understand theirs), whereas others seem steeped in what some have described to me as the "old Japan" ways. It's very evident the way foreigners are treated differently here; while I had read about it prior to arrival, I wasn't quite sure what to expect. Getting over that initial barrier in the area I was staying in required a lot of careful conversations, as if walking on a field of landmines. At the time of this writing (about 3 weeks in), this has largely disappeared, but it definitely took some effort - a very eye opening experience indeed.

Cleanliness Is Godliness

The streets of this country are incredibly clean. To be completely blunt, living here for a stint has made me feel like shit as an American. Tokyo is an insanely huge city, and the amount of trash on the ground pales in comparison to that of New York City (NYC) or San Francisco (SF). I believe that a large part of the reasoning behind this is that you are literally looked down upon if you litter - in America, we're far too accepting of waste and littering.

The ironic part is that it's nigh impossible to find a trash can half the time here. Your best bet is to, hey, recycle everything at the bins you'll find around vending machines and food marts. On top of this, having this mentality around you the entire time brings a sense of wanting things to be clean to you. I'll say what a lot of Americans will deny out of pride: much of the time, in the US, I feel as though it's perfectly fine to litter because everyone else is doing it. Here, I can't bring myself to do it; the gravity of the act is taken to such a higher level here.

Say what you will about peer pressure and such; none of it will matter, because you'd be arguing the wrong point here. That scenario exists for many Americans, and trying to solve things through peer pressure dissolution efforts will go nowhere. Small scale deployments of the Japanese recycling system in the US could potentially work, provided people help to enforce and spread the effort around - I believe that many recycling efforts in the US largely fail because people are given the alternative. Having one right choice doesn't make you a communist, people, it just means it's the best fit for the task.

Convenience Is Underrated

I've spent a decent amount of time in just about every American city, and I can say with a relative amount of certainty that Tokyo easily beats them all out when it comes to convenience. As I type this, it's 3 in the morning, and I have no less than 4 different shops open and 20 different vending machines within a one mile radius, all giving me access to coffee, food, emergency supplies, and whatever else I need. NYC comes closest in this regard, but Tokyo's ability to provide at all hours is staggering, and still surpasses anything I've seen in NYC.

Cover Charges At Bars Are Annoying

Drinking in Tokyo can be quite an expensive task if you're not careful. Most bars and clubs you'll hit up require a cover charge (anywhere from $8 - $30, in my experiences), and if you're lucky that includes a free drink up front. While I don't particularly care about this, it inadvertently becomes a social barrier when out with a group - some people aren't always game to pay for two drinks when they're only getting one. In the US, the ability to just stroll into a bar and have a drink with a friend is a nice luxury when compared with here.

Public Transportation Rocks, But Should Stay Open Later

I find public transportation here to be a catch-22 of hilarious proportions. The ability to get just about anywhere in the entire country by public transportation is incredible. This has nothing to do with the overall size of the country, it's simply a situation where they've paid attention and built the necessary infrastructure. If trains were open past midnight, I'd call it a perfect situation, but having to choose to stay in central Tokyo or run to catch a train home around midnight can be quite the bummer if you're having a blast.

What's Next?

This is the first entry in a multi-part series, as I couldn't hope to cover everything I've experienced in the past few weeks in one post. In another week, I head to Europe for a stint, and then back into the US. Traveling is an incredible experience, and I'll continue to do this as long as it benefits me and helps me grow as a person.

Keep an eye out for the next entry in this series!

Tue 02 November 2010

Emulating Ruby's "method_missing" in Python

I don't pretend to be a huge fan of Ruby. That said, I can respect when a language has a feature that's pretty damn neat and useful. For the uninformed, method_missing in Ruby is something like the following:

# Basic class, no methods, but method_missing love
class Rapture
    def initialize
        @missing_msg = "Oh god, calling method_missing"
    end

    # Called when a non-existent method call on an instance
    # of this class is made.
    def method_missing(method_name, *args, &block)
        puts @missing_msg
    end
end

bioshock = Rapture.new
bioshock.play

# play doesn't exist, so this will output
# "Oh god, calling method_missing"

Obviously, this is a trick that should be used with caution. It can make for some unmaintainable code, as a class with many methods could get difficult to trace through and figure out just what the hell is happening. It can be put to good use, though - take an API wrapper, for instance. What's it consist of? Generally, nothing more than the same function calls made over and over to various service endpoints.

Cool, let's use this in Python!

I recently rewrote Twython to support OAuth authentication with Twitter (as of Twython 1.3). It ships with an example Django application to get people up and running quickly, and the adoption has been pretty awesome so far.

The funny thing about the Twython 1.3.0 release is that it was largely a rewrite of the entire library. It had become somewhat unwieldy, some odd two thousand lines of code with each API endpoint getting its own method definition. The only differing aspect of these calls is the endpoint URL itself. This is a perfect case for a method_missing setup - let's catch the calls to non-existent methods, and grab them out of a dictionary mapping to every endpoint.

method_dictionary = {
    "getPublicTimeline": {
        "endpoint": "http://...",
    },
}

class Twython(object):
    def __init__(self, params):
        """
            Store params and junk. Ordinarily more verbose.
        """
        self.params = params
    
    def __getattr__(self, method_name):
        """
            This is called every time a class method or property 
            is checked and/or called.
            
            In here we'll return a new function to handle what we
            want to do.
        """
        def get(self, **kwargs):
            # Make our API calls, return data, etc
        
        if method_name in method_dictionary:
            return get.__get__(self)
        else:
            # If the method isn't in our dictionary, act normal.
            raise AttributeError, method_name

# Instantiate...
twitter = Twython()

# Call an arbitrary method.
twitter.getPublicTimeline()

The source above is fairly well commented, but feel free to ask in the comments if you need further explanation. This resulted in a much more maintainable version of Twython - for each function that's listed in a hash table, we can now just take any named parameter and url-encode/combine it. This makes Twython pretty API-change agnostic of the entire Twitter API. Pretty awesome sauce, no?

Thu 14 October 2010

How to properly ask a girl to Homecoming

Before we get into this, I'll note that this post is actually about mobile web development, not the romantic adventures of anyone in particular. You've been forewarned.

Sometimes in life, you feel as though doing things the "ordinary" way just doesn't cut it. I've found this to be a common theme in my work, and I'm not the only one who operates this way. One example is my brother (one of them, at least). I recently dropped by my parents house for a visit as I plan my next trip, and I was catching up with him as we walked up to a store. We somehow ended up discussing his upcoming Homecoming dance, and how there's some girl that he wanted to ask, but in doing so go above and beyond the normal methods.

I sat there and sarcastically threw ideas at him for about 5 minutes, as I'm prone to do when I'm bored. One of them involved using a spare iPhone I recently came into possession of to display some message to her. He decided to take it one step further, and asked me if I could help him craft a simple game that, upon winning, would ask her to the dance.

I found myself thinking the idea was pretty awesome. To make that long story short, we built it, she liked it, he's happy, I'm awesome, and the world keeps on a-spinnin'. The game can be found at the following link - best viewed on an iPhone, but should still be beautifully awesome on any device (Android, PC, WebOS, etc):

Give the game a whirl

Oh hallo thar Mobile Safari

So, making the game was an interesting experience. I opted to build it in a Webkit wrapper - HTML/CSS/Javascript are a much faster way to prototype, and I wasn't looking to spend 12 hours on this project (I somewhat did, but not for the reasons one would think offhand). The process we took was pretty simple - sat down, sketched out the game play and general UI, then started building; I, of course, actually implementing things in the tech sense, and my brother handling the artwork/color scheme/etc. Building the game, all said and done, took us around an hour and a half from start to finish.

At this point, I figured, let's Phonegap it up and call it a day. This would've worked, except for the fact that Apple has apparently blocked newer i(Phone|OS) SDKs from running on Leopard. I've since upgraded to Snow Leopard, but seriously, this seems a bit overbearing to me.

Of course, at that point, I wasn't going to upgrade my OS then and there, as it was past midnight. I experimented with reverting the firmware back to the 2.x series, which I'm able to build and target to, but there were a myriad of problems there due (apparently) to some earlier jailbreaking that had occurred with the device. Go figure.

As a last resort, I decided to bookmark the app on the phone to "install" it. The one caveat with this approach is that it'd require an internet connection upon opening it up every time. What'd be ideal is if we could jam the entire thing into the Mobile Safari cache - there's a simple trick here that'll make life easier. I found that Mobile Safari, by default, won't cache sites like you think it would, but you can supply it with an HTML5 Cache Manifest that'll be respected by the browser, forcing everything to get shoved in the cache.

The cache isn't huge, though, and the initial load shouldn't be huge as a principal. There are a lot of external scripts used here, mainly to automate smooth CSS transitions so the device hardware accelerates animations, so the entire app is roughly ~130kb. Small, in this case, but the limitations were worth discussing.

To get around cold cache loads, the single image used in the game (the strawberry) is Base64 encoded into the html file itself, and all scripts are also placed inline. Combine this with a few Apache directives, and it loads quick enough the first time. The final trick is the following:

# At the top of your file, specify the cache manifest (your_app.html)
<html manifest="dragonfruit.manifest">

# The cache manifest itself (dragonfruit.manifest)
CACHE MANIFEST
index.html
apple-touch-icon-precompressed.png

# Needs to be sent back to the browser as a header for the manifest (.htaccess, etc)
AddType text/cache-manifest .manifest

In there, we modify three files. In the app itself, specify the location of the cache manifest; the second set is an example cache manifest you can borrow (the icon is used in the bookmark flow for the iPhone); the final piece is a header that needs to be sent downstream to the browser when the manifest is requested.

Voila, we've installed an app onto the iPhone without compiling anything. Shove it all into the cache, and it can sit there for quite some time - if we were to combine it with some localStorage action, it's an (almost) potent combination. It still doesn't beat the App Store for distribution, but hey, it worked.

Wed 06 October 2010

...and what's the deal with San Francisco? (along with my travels)

It's been a good two months since I last updated this. Ordinarily I'd be a little angry that I let it slide for that long, but in this case I think it's warranted. For those interested, here's a summary of what I've been up to, along with my thoughts on San Francisco in general.

Since leaving Webs.com (see my previous post for more information on that), I've been pretty much all over the United States. About a week after leaving Webs, I embarked on an epic road trip with a friend that went from North Carolina all the way to California. Driving across the USA is a fun journey, one that I recommend everyone take at some point. The midwest is a surprisingly desolate place; never before have I seen so many sex shops randomly dotting the countryside.

Out of all the states that we passed through, a choice few gave me some of the best memories. Louisville, Kentucky, was a fun stop, as I got to finally meet up with my long time friend (from my old IRC days) Zach Winter. We used to fight like brothers back in the day, but he's become a pretty awesome web developer/designer in the time I've known him, so between that and talking about old IRC crap we probably wasted a good four hours there. Riverton, Wyoming was pretty cool, as it's a totally small town in the middle of nowhere with an indian casino. Driving through Yellowstone was something to behold, and the same goes for the desert-esque areas. I could go on here, but there's enough to write a small novel at this point.

California was an interesting time period, and is actually the primary reason I'm even writing this post. I enjoy getting out and trying new areas of the world, traveling and exploring is a truly exhilarating experience that, in many regards, can't be matched. As is (seemingly) the norm, being a developer, I naturally headed to San Francisco. The city (and the "Valley" in general) are routinely hyped as being an incredible experience if you're in the industry. Living there taught me two things: I have a lot of reservations about the "startup" industry as a whole, and San Francisco as an area to live in isn't all it's hyped up to be.

I'm putting my reservations on hold for another post, as I'd like to more carefully formulate those into something more concise to read. In terms of the living area, though, I'll put it bluntly: San Francisco is a trashy, over-hyped city that masquerades as a clean, eco-friendly environment where there's a seemingly open exchange of new ideas every day.

Before the inevitable shit storm starts here...

Let's pick apart that statement.

Walk down any street in the Mission, SOMA, or even North Beach, and look at the amount of trash on the ground. Now, with a straight face, tell me that San Francisco is a clean city - I'll bet money that you can't do it. This is counter to a city like New York City (NYC); with NYC, it's a trash fest, sure, but nobody is going to try and tell you that it's actually a clean city. After living in the DC area for most of my life, and checking out Chicago, Boston, and Seattle (all of which are fairly clean in their nicer areas, which I'm comparing to the nicer areas of San Francisco), I'd say the same sentiment goes for those cities.

I'll cede the point that this issue can go either way depending on who you talk to, but my experience was that most people tried to claim it's a clean city, and it quite frankly astounded me. Your mileage on this one may vary, and I invite you to judge for yourself.

What follows is a dissection of some of the allures of San Francisco living, at least from what I gathered through the various groups I hung out with in my time there. We'll go one by one here. Feel free to grab a snack if you're going to read any further, by the way.

The tech scene

This one could be construed as a personal preference, so I'll keep this short. The tech scene in San Francisco bothers me much more than I ever thought possible. Perhaps I just went to the Valley at a low point in history, but seriously, what the hell is with the amount of startups building on top of something like Twitter's API? Beyond that, how many god damn social networks need to re-invent the fucking wheel before someone finally wakes up and decides that enough is enough?

Hell, I can even deal with the existence of these things, but the fact that you're taking funding for such concepts? You do realize there are more important things in the world than blowing a couple hundred grand on sharing pictures through Twitter, right?

There are a lot of cool ideas and new technologies being developed out in San Francisco, but for every awesome idea, there's about four ridiculous ones that are setting themselves up for failure by doing something as stupid as relying on the API of a network that has a history of letting people do all the discovery work for them, then building their own version.

Tech companies (both good and bad) can exist anywhere, but it's a myth that only great tech companies exist (and can exist) in San Francisco. Live where you actually enjoy living and don't feel pressured to accept and praise an area based on a set-forth notion that it's the end-all-be-all of an industry.

The food scene

Huzzah, burritos. What's there to get for lunch? Oh... burritos. Oh, wait, no, there's about three different French places all serving the same stuff, too, so I suppose we could do that for lunch.

Past nine o'clock? Nevermind half those places if you want a quick bite, they're either closed or going to be closing at that time. So your options then become... oh, go into a bar, order a pizza, or get another burrito. Such incredible choices in a city supposedly known for its food choices - I definitely never had those choices anywhere else! Why would I ever leave this place?

The people

I met a lot of awesome people in San Francisco, don't get me wrong. Thing is, I've met a lot of awesome people in every city I've been to. This is just part of society in general - no matter where you go, there's people you like, and people you don't like.

With that in mind, let's take an objective look at San Francisco. 90% of the people I met were transplants, and they all came for one of two reasons: technology (the startup world specifically), or some artistic venture that hasn't panned out and they heard that San Francisco is an "accepting" city. This all ends up melding into a very "me too" culture, where it's nothing but people clamoring for attention around their newest idea.

This wouldn't even be that big of a deal if it wasn't compounded by the fact that everyone essentially circle-jerks one another on these concepts to a ridiculous degree. Yeah, you think you can form a real business around something like a Firefox browser extension? Please take a seat over there, your head has been in the clouds for far too long (no pun intended).

Get to the point please

San Francisco feels incredibly fake, and gets a free pass due to the overall net worth of the Valley. The city is an incredibly trashy place to live, it has an incredibly overbearing "me too" culture, and almost everything that's supposedly great about the city can easily be found in other areas that are cleaner and provide a better overall living experience.

It's funny, really. If you try to explain any of this to anyone living San Francisco, there's a good chance you'll send them into a mode where they feel the need to defend the aforementioned points. The only other city I've found where people get that extreme is - surprise, surprise - New York City. San Francisco is like the punk kid in school who, even though they're really no different, felt the need to dress completely different and act out to feel individual.

I suppose that's worked for people throughout history, though, so there's not too much more to say on the matter. If you need me, though, I'll be traveling around to cities that are a bit more pleasant and fun overall (and, hey, if you enjoy living in San Francisco, more power to you, but you just make me scratch my head).

Mon 02 August 2010

Moving right along...

For those who haven't heard the news, my last day at Webs.com was this past Thursday (July 29th, 2010). After three and a half years, I figured it was finally time to move on.

It's interesting to reflect on such a large portion of a lifespan. When I joined Webs (then Freewebs) back in 2007, I was actually homeless, and was working a part time job at a Blockbuster. I had gotten pretty tired of that routine, and started cold-emailing companies. Out of all of them, Freewebs was the one who responded and invited me out to interview with them.

I remember being shocked when, a few weeks later, I received an offer to join up. Y'see, it's no secret that I'm pretty much self taught through and through when it comes to web design - with no formal training, I was surprised that anyone would consider me for a position in this field. Accepting that offer led me down a long path that's definitely shaped a lot of who I am today, both professionally and personally.

Prior to joining Webs, I knew HTML and CSS well, but when it came to actual programming I had just dabbled here and there, never gaining a solid understanding of the craft in general. Working at Webs was, in many ways, a great substitution for a college experience. The amount of things I learned is staggering - data analysis, in depth design techniques, and more.

Granted, while all that certainly contributed to my growth, I worked my ass off while I was there; I guess I'm simply stating that the environment is easily one of the best possible places to ever work if you're a developer. All those startup companies in San Francisco that seem so great to work at? Good luck finding anything similar in the Washington DC/Metro area... short of Webs.com.

So what's next?

I'm tired of Washington DC. It's a great city with a culture all its own, but I've grown up around all of this, and I want to see more of the world in general. The west coast is very appealing to me, so I'm most likely headed out there. As my career situation develops, I'll update this space accordingly.

Besides all of that, I've got my open source work to maintain, as well as some other cool projects in the pipeline. This isn't the end, but moreso the beginning of an epic awesome adventure.

I'm awesome.

Sun 18 July 2010

On Date/Time/DateTime in Ruby, and why they suck

This is Old!

I wrote this when I was much younger, and arguably, a bit of a jackass (pardon my French). I keep it up for personal reasons, and there might be some technical content of note here... so just please ignore the tone.

Yeah, there, I said it - this is a stupid situation for a language to be in. The concepts of Date, Time, and DateTime are all pretty well related. Date is a point in Time, DateTime is a really nice representation of Date and Time mashed together.

In a world that actually makes sense, you'd be able to easily convert between these types (e.g: DateTime should be able to easily convert over to a Time object). Some people might suggest patching the aforementioned classes (like Rails does, for parsing relative dates), but this just feels like an incredibly hacky solution.

Now, normally, I'm not much of a Ruby guy, give me Javascript any day. However, there are a lot of awesome projects written in Ruby, and it's hard to deny that they've easily got the best packaging solution for any language. As it so happens, earlier this week I was hacking on a little Sinatra side project. DataMapper was my ORM of choice here, because it's just so beautifully plug and play.

In the example app we'll look at, it's your basic Post/Comment scenario. For each Post/Comment, we want to be able to render the relative time ago that the item in question was submitted (e.g, "16 hours ago", etc). Rails has conventions for this baked in by default (because they, y'know, enjoy polluting namespaces, go figure). When you're outside of Rails and want to do this, it's somewhat more difficult.

Originally I started by storing the creation time as DateTime; makes sense, we should be able to convert this to Time to do easy comparisons against Time.now, right?

Well, uhh, no. Definitely not that simple. After some digging around, I discovered the dm-types gem, which adds some extra types to DataMapper. One of these types is known as EpochTime, which is (you guessed it) the time since Epoch that the entry was created.

With that, we can pretty much stay within the realm of Time. Ripping apart ActionView gives us a good base to work with on the act of getting a relative string; putting it all together, we get the following Sinatra app (two files - the main Sinatra app, and our custom date_helper library).

require 'rubygems'
require 'sinatra'
require 'dm-core'
require 'dm-migrations'
require 'dm-serializer'
require 'dm-types'
require 'date_helper'

DataMapper.setup(:default, {
    :adapter => 'mysql',
    :database => 'database_name',
    :username => 'database_username',
    :password => 'database_password',
    :host => 'localhost'
})

class Post
    include DataMapper::Resource

    property :id, Serial
    property :username, String
    property :entry, Text
    property :created_at, EpochTime

    has n, :comments
end


class Comment
    include DataMapper::Resource

    property :id, Serial
    property :username, String
    property :entry, Text
    property :created_at, EpochTime

    belongs_to :post
end


DataMapper.finalize
DataMapper.auto_upgrade!

# Requests/views/etc
get '/' do
    erb :index
end

post '/post/new' do
    @post = Post.create(
        :username => params[:username],
        :entry => params[:entry],
        :created_at => Time.now.to_i # See? Epoch-goodness.
    )

    if @post
        # .create automatically saves the post; now override the created_at
        # point before we pass back our JSON object to the view.
        # "distance_of_time_in_words" is from date_helper.rb
        @post.created_at = distance_of_time_in_words(@post[:created_at].to_i)
        @post.to_json
    else
        {:error => true}.to_json
    end
end

# Get views for comments, posts, etc
# Proudly (or shamefully, depending on how you look at it) ripped right out
# of ActionView and modified to base it all on the Epoch. Give credit where credit is due.
# from_time expects another judgement from Epoch (e.g, Time.whatever.to_i)
def distance_of_time_in_words(from_time, to_time = Time.now.to_i, include_seconds = false)
    distance_in_minutes = (((to_time - from_time).abs)/60).round
    distance_in_seconds = ((to_time - from_time).abs).round

case distance_in_minutes
when 0..1
return (distance_in_minutes==0) ? 'less than a minute ago' : '1 minute ago' unless include_seconds

case distance_in_seconds
when 0..5   then 'less than 5 seconds ago'
when 6..10  then 'less than 10 seconds ago'
when 11..20 then 'less than 20 seconds ago'
when 21..40 then 'half a minute ago'
when 41..59 then 'less than a minute ago'
else             '1 minute ago'
end

when 2..45           then "#{distance_in_minutes} minutes ago"
when 46..90          then 'about 1 hour ago'
when 90..1440        then "about #{(distance_in_minutes / 60).round} hours ago"
when 1441..2880      then '1 day ago'
when 2881..43220     then "#{(distance_in_minutes / 1440).round} days ago"
when 43201..86400    then 'about 1 month ago'
when 86401..525960   then "#{(distance_in_minutes / 43200).round} months ago"
when 525961..1051920 then 'about 1 year ago'
else                      "over #{(distance_in_minutes / 525600).round} years ago"
end
end
Sun 18 July 2010

The perception of "Inception"

It's no secret that I primarily use this space to talk about programming and the web at large. It's a huge part of who I am, but it's not all that I am. Sometimes I see something so incredibly cool and inspiring that I just feel the need to talk about it; such is the case with the movie "Inception".

  • Please note: the following is full of spoilers if you haven't seen the movie yet!
  • Believe me when I say that this is a movie that you should avoid having spoiled at all costs, because it's just such an incredibly fun ride. This post will also make little sense unless you've actually seen the movie. Seriously, go see the movie if you haven't already, then come on back, this post isn't going anywhere.

What really happened in this movie?

I'll start by making sure this is noted right off the bat: I believe that the Wikipedia explanation of the ending of the movie is completely wrong. The article states that, in the end of the movie, everyone wakes up on the plane just fine. The genius part about this movie is that Christopher Nolan, the director, rarely strayed towards one ending; everything throughout the movie is meant to spark discussion about the final ending scene, where the top may or may not have fallen.

Throughout the film, Nolan obviously took great care to make the audience aware of the mathematics surrounding the way the levels relate to one another. The idea with this is that, in the end, even though Cobb is left underwater in the van, the time that he spent in the sublevels beyond could be as little as a few minutes there, giving enough space where he could've magically gotten back up through the levels.

That's all nothing but a ploy, though. Here's the thing - in the ending, I believe Cobb never actually woke up. Let's look at the film this way...

Cobb and his children

First off, the kids and the shot at the end. Did anybody else notice anything strange about it? The kids never aged!. Cobb goes back to his place and it's as if he never left. We're purposely never given a timeline as to when Cobb and Mal had their little incident with Mal having a bad case of PMS and jumping out a window. I'd say it's safe to assume that this has to have been at least a few months to a year, though; we're shown shots of Cobb talking to various psychiatrists, attempting to persuade people that he did not, in fact, kill Mal. If this is in relation to court proceedings of some kind... well, we all know how long those acts can take.

That said, we really don't even need to consider that, it's just a nice piece to note. What we should really be looking at is that, throughout the film, every time Cobb sees his kids in a dream, they're the same (just like in the end of the film). It's his last memory of his kids; in some way, they're his inception.

Keep this in mind, because the rabbit hole goes a bit deeper.

Cobb and Saito: honoring the agreement

When the team is in the first sublevel, Saito takes a bullet to the chest. There's a scene where he specifically states that no matter what happens, he'll be sure to honor their agreement. Of course, at that point in time, we all have reason to believe that Saito is going to make it out alright, Cobb will be able to get back into the US, and everyone will go on their merry way.

As the film continues, though, Saito's condition worsens, and he eventually passes away in the third sublevel. This is a huge fact: Saito is now in limbo. Cobb, after finally killing Mal, stays behind in limbo to find Saito to make sure he honors the agreement.

See a pattern here? In this case, there's more than one way to honor their agreement. Cobb eventually does find Saito, when Saito is much, much older. They speak of honoring their agreement, which is why Cobb came, and Saito reaches for the gun. This is the most notable piece of their entire level of interaction throughout the movie - if dying in a sublevel when you're that far under puts you in limbo, what happens when you die in limbo?

Of course, we're never directly told. Tricky, tricky Nolan, but we'll pin this down yet.

On Heaven, Hell, and Unicorns

Mal's dead, no? What's funny about Mal inside Cobb's subconscious is that she's located in the basement of his mind, an eternal hell that Cobb can't seem to get rid of, as if he was condemned to that fate for his action against Mal (trying inception on her first). Eventually, when they make it down to limbo, Cobb finally kills the idea of Mal - this is his redemption.

Cobb is essentially painted as a fallen angel throughout the movie, barred from heaven. By atoning for his sins, he's allowed back in and everything is supposedly great. That said...

What was really Cobb's Heaven? Real life, where he got back to see his kids? His one goal was to go home, to be with his family, but it's made apparent to us, the viewers, that when you're in limbo it's difficult (or almost impossible) to get out.

Bringing it all together

As I said before, Cobb never actually woke up. Saito reaching for the gun is meant to imply that he kills Cobb, setting him free - not in the sense of waking him up, but allowing Cobb to dream that which he's wanted for ages, to be back with his family (hence why, when he goes back to his kids, they're exactly the same as in every other shot).

Nolan again takes great care to make sure this is difficult to prove - specifically, the scene where Cobb and Mal allow themselves to be run over by a damn train. This is supposed to imply that simply dying in limbo allows you to truly wake up. That said, unless Saito kills himself and Cobb (which seems a little odd - Saito knew the rules of the game, why wouldn't he just kill himself prior to Cobb finding him?), the final scene really does seems like Cobb is dreaming forever.

See, Saito supposedly woke up just fine, made the call, everything's great. However, what guarantee is there that either of them woke up normally from limbo, the level that seriously messed up Mal? None.

This all brings us to the final scene with the spinning top: it was a great move on Nolan's part to end it right as the thing supposedly topples, essentially forcing the entire discussion this article was even written about. Sure, we could assume that it signifies Cobb is alive and well, not dreaming.

However, a friend of mine offered this suggestion, which I think really ties it all together: she proposed that the top falling was Cobb giving in to his dreams, accepting that reality as reality itself. This is utterly genius, and makes an insane amount of sense.

The other theory that comes to mind is that it was Mal's totem originally, and she's now, for all intents and purposes, finally gone, a demon purged from his mind, allowing him to dream peacefully forever.

This movie was an incredible mental trip, and one I definitely intend to watch again. What do you think? Feel free to leave comments below; they'll be moderated to deal with spam and trolls, but healthy discussion on this film is highly encouraged.

Tue 13 July 2010

Rendering emails with Django templates

I talk a lot about Javascript on this blog: client-side, server-side, wherever the language can be used. It's not the only language I enjoy working in, though; Python has always had a bit of a soft spot with me, and with that comes some inevitable Django love.

I use Django for a lot of my server side tasks where I don't feel I can safely use something like Node.js. On top of being battle tested beyond belief, it's a veritable bag of magic tricks just waiting to be used. Take this one case I ran into recently: I'm building a service (stealth at the moment, stay tuned) that has to do something as simple as send out an email when a new user signs up.

Now, that email should ideally contain a few things. Let's assume that, for a basic example, we're gonna just include their username, a brand new password, and their full name (how we'll use each of these is shown in depth below). Django makes sending mail pretty easy, using the send_mail function:

# Make sure you import this, otherwise... well, you get the idea.
from django.core.mail import send_mail

# send_mail is pretty straightforward, as you can see.
send_mail('Title', "Body", "from_addy", ["emails", "sent", "to"], fail_silently = True)

That's all well and good, but what if we want to do more than just a simple string for our body message? Ideally, we should be able to treat this like any other Django template. In practice, this is actually incredibly easy (and fun).

The code should be fairly well documented, but for those who'd like a little more verbose of a walkthrough, it's pretty simple: instead of passing in a string, load up a template and pass it a rendering context. See, what got me the first time around is that the render method of get_template needs a Template Context to do the dirty work, not a standard dict.

# We should all know what this is used for by now.
from django.core.mail import send_mail

# get_template is what we need for loading up the template for parsing.
from django.template.loader import get_template

# Templates in Django need a "Context" to parse with, so we'll borrow this.
# "Context"'s are really nothing more than a generic dict wrapped up in a
# neat little function call.
from django.template import Context

# Some generic stuff to parse with
username = "fry"
password = "password_yo"
full_name = "Philip J Fry"

# Our send_mail call revisited. This time, instead of passing
# a string for the body, we load up a template with get_template()
# and render it with a Context of the variables we want to make available
# to that template.
send_mail(
    'Thanks for signing up!',
    get_template('templates_path/email.html').render(
        Context({
            'username': username,
            'password': password,
            'full_name': full_name
        })
    ),
    'admin@moxlee.com',
    ['users_email@gmail.com'],
    fail_silently = True
)

With that, here's an example of an email template - it's literally just a Django template, but ready for all your email attributes.

Welcome {{ full_name }}!

Your username is {{ username }} and your password is {{ password }}.

- Management 

Django's templating system is incredibly flexible, and can easily be used for more than just your generic views. If you have any questions or suggestions, feel free to throw them in the comments!

Thu 17 June 2010

You got your Base64 in my CSS!

If you're a developer working on a website that's getting any traffic, you'll inevitably come up against the problem of making sure you're as performant as possible on the front-end. You'll probably compress your Javascript and CSS, maybe refine the slower portions of your site after profiling them, and maybe (if you're smart) sprite your images.

You see, one of the chief goals in terms of a highly performant site is to get the amount of HTTP requests as low as possible. Most people turn to CSS sprites; they're a great technique for designers, and fairly easy to understand. That said, they're not without their downsides. They can become quite an unmaintainable mess if you're not careful - change the location of a few images, and you have to change the corresponding CSS declaration to match it. On a large site, you'll end up repeatedly putting together a puzzle that's wasting your time.

What if you're working on a team? How do you manage to keep one image in sync across 2 people? 5 people? At this point, you're probably wondering why I'm even bothering to rant on this, since these points are all fairly well known. Well, here's the thing - there's an alternate solution, depending on how open to the concept you are.

What the hell is Base64?

Just about every modern browser supports the concept of Data URI Schemes. With this, you can do the following:

body {
    background: transparent url(data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAAAEAAABnCAIAAABO2r+ZAAAA
GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAA
AG9JREFUeNp8T9sNgDAIvJCu4Ay6rEO5hXEBP9yB0xLa0Fr9
aLgHBxTrdgpIASB8HoiAXf/VaJmSbbj1df1jnpyn1qfViF+e
31T3Rxw8yzSez4u4u89medWMtWiZB197jYP8t1dv878u85T2
47oFGAC4z6tdlRsLNAAAAABJRU5ErkJggg==) repeat-x top left;
}

A bit ugly? Yeah, you might say so. Effective? Definitely. The above code simply generates a blue gradient that tiles perfectly. The really long block of text you see there is a Base64 encoded string that essentially gets transformed into your image. There's various different ways to generate the Base64 representation you need; if you want a really simple tool, check out this Firefox extension.

The format of a Data URI is fairly simple to understand - in this case, we're saying that this is a PNG, getting passed via Base64, and then the Base64 string itself. If it helps, think of it as a glorified function call.

As I noted above, most modern browsers support this technique. The one caveat worth mentioning is that Internet Explorer 8 is limited on the size of a Data URI to around 32kb. It's not really recommended to use this technique for anything above that size, but hey, your life, do what you want.

Oh, and Internet Explorer 6 and 7 have absolute zero support for this method.

Don't fret, we can make Base64 encoding work in IE6/7!

Internet Explorer (Explorer in general, really) supports another file type that does understand Base64: mhtml. We can use this trick to make IE6/7 do some awesome magic:

/*
Content-Type: multipart/related; boundary="_"
--_
Content-Location:1
Content-Type: image/png
Content-Transfer-Encoding:base64
iVBORw0KGgoAAAANSUhEUgAAAAEAAABnCAIAAABO2r+ZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAG9JREFUeNp8T9sNgDAIvJCu4Ay6rEO5hXEBP9yB0xLa0Fr9aLgHBxTrdgpIASB8HoiAXf/VaJmSbbj1df1jnpyn1qfViF+e31T3Rxw8yzSez4u4u89medWMtWiZB197jYP8t1dv878u85T247oFGAC4z6tdlRsLNAAAAABJRU5ErkJggg==
--_--
*/

body {
    background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAABnCAIAAABO2r+ZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAG9JREFUeNp8T9sNgDAIvJCu4Ay6rEO5hXEBP9yB0xLa0Fr9aLgHBxTrdgpIASB8HoiAXf/VaJmSbbj1df1jnpyn1qfViF+e31T3Rxw8yzSez4u4u89medWMtWiZB197jYP8t1dv878u85T247oFGAC4z6tdlRsLNAAAAABJRU5ErkJggg==) repeat-x top left;
    *background: transparent url('mhtml:http://absolute_url.com/css_file.css!1') repeat-x top left;
}

What we're doing here is fairly simple, but hilariously hacky. Take a look at the top of the file - it's a damn MIME header, with a little "pointer" (content-location) to our Base64 representation. We then just do a second background declaration for IE only that points to the same stylesheet, but parses it as mhtml instead. Our !1 is simply an identifier pointing to our first declaration - subsequent encodings could use 2, 3, "jackalope", whatever you want. Each "block" is defined by a "separator" or "boundary" - in this case, we're using "_".

I stumbled across this little trick while working on performance for Webs.com. However, it seems I can't take credit for it - Stoyan Stefanov posted on this awhile back. However, finding his work led me to one barrier that I've yet to see a solution to.

IE7 on Windows Vista - oh god, why?

It would seem that, due to some of the security settings on Vista (and maybe Windows 7), IE7 refuses to load the necessary styles. Stefanov advocates making the browser always request the mhtml as a new file. This is counter to the goal, though - we want that file cached.

Well, I happened to stumble on an easier solution (a combination of reading the MHTML spec and rearranging formats out of madness). Just make sure to end your IE hackery on a boundary declaration - the IE code above already does this: notice the "--_--" right before the end of the comment containing all the Base64 encodings for IE. This'll have IE7 parsing correctly everywhere, and we can all sleep soundly at night.

Whew! Awesome, now what?

Well, that's for you to decide. This technique can be quite useful - at Webs.com, I was able to cut the size of our sprite down immensely by relying on this trick for all the background tiling gradients on the page. In my humble opinion, this trick is good, but it works best when you combine it with a CSS sprite. I've found the best method is to split the usage down the middle - constant, rarely changing pieces become encoded, and the other pieces (testing-related, generally) get sprited out.

With any luck, this post can help someone else out. It seems like there's a lot of information regarding this technique, but it's been haphazardly organized over time. This isn't quite a "definitive" guide, but it aims to be a kickass outline!

Wed 09 June 2010

Quit incorrectly passing functions in Javascript

In my line of work, I edit a lot of legacy code, and with that I see a lot of the following:

// Bad practice. Can you see why?
var foo = function() { alert("bar"); };
setTimeout("foo()", 2000);

That little piece of code is actually a really bad way of doing things, and (to me) is illustrative of when someone is working in Javascript and doesn't actually know what they're doing.

For those who don't know (and would like to learn), setTimeout (and its sister, setInterval) can accept a string of code to be executed as an argument. Know what other method takes a string of code and executes it? eval() does. Generally, methods like these should be avoided, as they leave ways for arbitrary scripts to run if you're not careful.

So how could the above code be improved? Take the following:

var foo = function() { alert("bar"); };

// Better practice. Note how the function is passed this time.
setTimeout(foo, 2000);

What's important to remember here is that *everything* in Javascript is an object. This may seem like grade school material, but it's surprising how many people miss it - since our function (foo) is an object, we can point to it like any other object. What we're essentially doing now is, instead of telling setTimeout "hey, evaluate this script after this timer expires", just "run this function when this timer expires". There's no need to invoke eval() for such a simple operation.

But what about my arguments?

Yes, you can still pass arguments with this form. Whereas before you'd make up a whole string to be executed, you'd now just run it with an anonymous function. For those of you using jQuery, this should feel very familiar:

// Bad practice. Why concoct such an ugly string?
var delayedLol = function(laugh) {
    setTimeout("alert('Laughing: " + laugh + "')", 2000);
};

delayedLol("bwahahaha");

// Instead, pass around your argument (laugh) with anonymous functions.
var delayedLol = function(laugh) {
    setTimeout(function() {
        alert('Laughing: ' + laugh);
    }, 2000);
};

delayedLol("bwahahaha");

Javascript is incredibly flexible. If you're going to work in it, take the time to actually understand what's going on. You (and your users) will be better off for it.

Thu 13 May 2010

jQuery Introduction, Refresh Fred May 2010

I had the awesome chance to give a presentation at the May 2010 meeting of Refresh Fred. The talk I gave was on an introduction to jQuery (as well as some basic Javascript).

The great part is that, since I opted to build the presentation in HTML, CSS, and JS, it's easily viewable online. You can check out the presentation online, or check out the source on Github.

The entire presentation is MIT licensed (of course, that goes as far as a presentation even so much as *can* be licensed). Feel free to take the code, remix it, extend it, or re-use it - go crazy and enjoy.

Mon 10 May 2010

Time for a revival

Alright, so while it's taken me a nine hour long sprint of coding and design, I've finally revived Veno. This is pretty significant, at least on a personal level - the last time I had a personal site and portfolio online was around the beginning of 2007. Several people have asked me why this took so long, though, and so I figured I'd take a moment to jot down my thoughts on the matter.

Full time jobs take... well, time

See, the biggest draw on my time over the past 3 years has been my day job with Webs.com. I wanted to take the time to really dig in and better my skills in this craft, and there's really been no better opportunity presented to me since. It's been grueling at points (week long coding sessions without sleep to push a redesign out the door, anyone?), but well worth it.

Now, after three years, I've found that I missed having a personal platform to do... well, anything I wanted to, in terms of the internet. This led to a six month period of trashed redesign attempts for Veno; after enough failed designs, I decided to just power through it in a day, and this is the result. It's heavily CSS3-based, but should fall back gracefully in just about every browser. I foresee myself refining it over time, though - there's certain things I'm unhappy with, such as the overall "tightness" of the layout. Expect to see it open up and breathe a bit more over the next few weeks, as well as become more personalized.

The other drain... wait, Twitter?

Ah, the micro-blogging phenomenon known as Twitter. For a pretty long while, Twitter dominated most of my "soapbox" needs. I could throw out a small note about whatever I'm feeling, and it would instantly hit an incredibly connected and thriving community. I've probably met and interfaced with more developers and designers over Twitter than anywhere else!

Of course, Twitter is limited to 140 characters. What if I wanna throw up a Javascript or Python tutorial? That certainly can't be done over Twitter (at least, not without annoying the hell out of everyone). By re-igniting Veno, I can provide some much needed separation to my "web 2.0 social aspects", so to speak. Expect this space to be occupied by deeper thoughts and more intricate material, whereas my Twitter feed will remain filled with smaller pieces (updates to my open source projects, etc).

So there it is, all laid out. It's taken a few years, but I firmly believe that this is a case of "good things come to those who wait". It's good to be back - expect to see some awesome things here in the next few months!

Mon 25 January 2010

Interviewing for front-end development

This is Old!

I wrote this at a much younger age, when I was honestly a bit of a jackass (pardon my french). I'm leaving it up because this is my personal space, and I periodically review my old work to see how far I've come. You probably shouldn't take too much away from this piece, though.

Interviewing people can be one of the most aggravating things in this industry. Just about everybody who walks through your door could be some run of the mill engineer who's set in their ways.

Now, I should be fair here - I probably see this more often, due to the position I'm in. As a front-end developer, I can't begin to count the number of times I've had somebody come in for an interview, expecting their database skills and server-setup capabilities to translate into web skills. It's maddening, at points, and a real problem in the industry - we're only now beginning to get out of the era where front-end development is treated as a necessary evil.

Front-end development carries its own unique set of problems. Nobody who's been doing database optimizations for the past five years is going to be able to hit the ground running on UI work; the playing field for this stuff is constantly changing. To that end, I've started trying to come up with different interview questions that can help show how someone attacks the kind of work we routinely face.

Seeing as how I've been in Javascript-land for the past four months, the most recent one I came up with is this:

var t = {
    r: {},

    b: function() {
        var m = "%45%6D%61%69%6C%20";

        for(var i = 0; i < arguments.length; i++) {
            if(arguments[i] instanceof Array) t.r.a = arguments[i];
            else t.r.f = arguments[i];
        }

        for(p in t.r.a) {
            if(t.r.a[p] === decodeURIComponent("%72%65%64%64%69%74")) 
                m += "%72%79%61%6E%40%76%65%6E%6F" +
                    "%64%65%73%69%67%6E%73%2E%6E" +
                    "%65%74%20%74%6F%20%74%61%6C" +
                    "%6B%20%66%75%72%74%68%65%72";
        }

        if(typeof t.r.f === "function") t.r.f(m);
    }
};

The problem is simple: figure out what arguments need to be passed to t.b() for it to display the proper message.

I feel like this is a great problem to have someone solve, as it illustrates a few things right off the bat. Are they scared away by encoded characters? Do they even know how to decode those characters? Can they tell, based off the arguments work being done, what types of objects need to be passed?

It helps to draw a clear line between someone who just manages to get by with Javascript, and someone who can really dive in and tear things apart if need be. The code is just ugly enough to make some people roll their eyes back into their head, but it's deceivingly simple when you get down to it, and that's why it succeeds at the job.

Ryan around the Web