Why code?

I had a really interesting conversation with my roommate about "those types of people who just work all the time" and subsequently "become rich".  Her reaction (which is quite typical, I'd assume) was to question what happens after "these people" get rich.

She noted that they normally just keep working their asses off and keep coding.  They keep at it.  I can understand why it's generally difficult to understand, or to write that off as being "no fun".

The thing is, coding is fun.  It's sometimes frustrating and tedious, but if you pull off some product that becomes successful, (I imagine) the satisfaction is incredible.  Even from tiny projects I write for myself, it's an incredibly satisfying feeling to create something useful purely out of your ideas.  Not just satisfying, but FUN.

To non-tech folks, that (I think) is the missing key.  In other industries, it costs so much money and involves so much infrastructure that it just isn't possible to turn your ideas into working products.  But in the software industry, the barrier to entry is incredibly low.

Hacking is fun!

Comments [1]

Using python decorators to modify arguments

Just came across a cool little decorator use.

I'm using Python fabric for Djangy.com deployment.  We have a production server, a stage server, and a local VM for development.  The IP addresses for the two servers stay the same, while my VM's IP address changes according to whatever network I happen to be on.

Ideally, I'd like to run any of the following:

Now, I could simply alias 'stage' and 'production' to their respective ip addresses.  But where's the fun in that?  Instead, I added these two strings and their corresponding IP addresses into constants and then put them into a HOSTS dictionary:

Then I created a python decorator that checks the host argument and swaps it out for the right address, but only if it's included in the HOSTS dictionary.  Otherwise, it lets it pass through unchanged.

The new thing I learned here was the ability to unpack the calling arguments in a decorator.  You can specify them individually and then say *args to denote "the rest" of the arguments.  Useful to know!  Now, I can call any of those hosts by their aliases, or I can simply specify a hostname or IP address.

 

Comments [0]

My rant on the ever-widening technology gap

The pace of technological progress is absolutely staggering.  This website has color photos of russia from a century ago.  Before the Russian revolution.  Before WW1.

And there are little links to google maps so I can see where each image was taken overlayed on an interactive map of the world.  With satellite images and maps if I'd like.  And then I can read about it on wikipedia.

10 years ago, the internet was around, but it was very static.  I could simply read documents, but I could read them from anywhere in the world. I could communicate with anyone in the world, instantly (at very low cost).

50 years ago (1960), I could still communicate instantly with people across the world, but it was expensive.  I could call my family and friends but I'd need to keep my conversations short in order to not pay too much.  And sending documents? The mail was it.  GPS?  Forget it.  Ask for directions.

50 years before that was 1910.  There were no nuclear bombs.  Cars were still a luxury.  The average life span was 50 years old in the US.  Antibiotics?  What are those?  Uh oh, you got the flu.  You're dead.  

The pace of technology isn't just increasing.  It's ACCELERATING.  This is nothing new.  The technological singularity is not a new concept.  But what's interesting to me is the gap between tech-literate and tech-illiterate.

Think about the baby boomers.  Sure, there are quite a few (mostly in the tech industry) who are very up-to-date, who know enough about technology to be very successful.  But those are the exceptions.  Most folks my parents' age know how to use the web.  They know how to email, they know how to Google things, possibly how to organize their pictures and music on their computers and laptops.  And a small percentage even deeply understand what it means to store your information in the "cloud" versus on your local machine.  Fewer still understand enough to know which box to restart when the internet "stops working".

That gap is widening.  Because of this exponential growth in technology, no human generation can hope to keep up (not even yours).  The fact that 10 years from now, our parent's generation will not understand much more about technology than they do now is a fact.  Sure, we'll all learn about the new things that come along.  But for the most part, generational knowledge is static.  Once you reach a certain age, it's really really hard to learn more.

There are two realizations to make here.  1) This is unstoppable.  It's a fact of life.  2) If you can ease the life of the people on either side of the gap, you can probably make a killing.

We can make life easier for folks on the one side of the gap by making technology easy to use.  We can design things well enough so that people don't need to understand a shred of how anything works to get things done.  My parents shouldn't have to understand how a filesystem is organized to know how to burn a CD or print pictures.

Comments [0]

Gitosis on OS X (Snow Leopard): OSError [Errno 2] No such file or directory

If you run into this error when you first try to clone your gitosis-admin repository, the solution is to run:



git --exec-path


and copy that into your gitosis user's .bashrc.  (Mine was /usr/local/git/libexec/git-core):



PATH=/usr/local/git/libexec/git-core:$PATH


Done!

Comments [0]

Some ideas

I keep emailing these to myself and I figure I should just post them here

  • Everybody knows that variable reinforcement is the best way to pick up a habit.  Could we apply this to some kind of motivational priority list?  Every time my terminal starts up, I have it display a motivational saying, but I've started to ignore them.  Perhaps some kind of "random alert" system to remind you of your priorities, or goals, or quotes or something.
  • When I'm browsing webcomics like toothpastefordinner.com, xkcd.com, or pbfcomics.com, I'm annoyed that I have to keep clicking on "next" or "previous".  Could there be a firefox plugin or something that binds these to keystrokes (not just for users of, say, vimperator, but for everyone).  That would be incredibly useful.
  • Some of the comments on blogs like Failblog and thereifixedit are really hilarious.  More hilarious than the average, say, reddit comment (probably because their viewership is more broad).  I wonder if you could somehow crowdsource blog content or entertainment content on a more moderated level and still reward these people somehow.
So I guess that's it for now.

Comments [0]

Using logger from a Delayed Job on Heroku

Yes, another rails post.  This time I'm sharing a solution.

I have a class I wrote to utilize the Delayed::Job functionality of Heroku.  I tried to use the standard rails logger.info("some error") and it kept throwing exceptions.

The solution is to add the following line to your class:

logger = RAILS_DEFAULT_LOGGER

Everything is perfect after that. (Well, okay, rails is far from perfect, but whatever).

Comments [0]

The importance of namespaces

My newest project, Footprint Analytics, led me to try to be more productive by using Ruby on Rails.  I'd tried RoR 4 years ago with a project for ACM@UIUC called WebChalk, and I've improved by leaps and bounds in my hacking skills since then.  I've mostly taught myself how to solve all my programming problems with python, I "think" in Python when I think about code.

Ruby shares quite a bit with Python, which has been written about elsewhere on the web.  However, a huge gripe of mine with rails is the lack of organization and namespaces.  They exist, but they're not as strictly enforced.  

For example, let's say I'm writing a client to access the twitter api.  Their OAauth requires a consumer key and a consumer secret.  I have two of these, one that redirects back to my localhost for development and one that redirects back to the actual footprintanalytics.com URL.  In Django, I can put these into different configuration files (development.py and production.py) and point my server to those.  Then, in my controller, I just say "config.CONSUMER_KEY" and I grab the correct one, regardless of whether or not I'm developing or in a production environment.

You can do the same thing in Rails, but with one caveat: the config constants are global variables.  I don't say "config.CONSUMER_KEY", I just say CONSUMER_KEY.

If I'm looking at someone else's code and I see a constant, I have zero clue where that constant is defined.  I must resort to grep-ing through the source tree to find all instances, and you better hope there aren't many of them.  In Django (Pylons, web.py, and turbogears are all similar enough), it's utterly clear where everything comes from because only locally or class-scoped variables don't have namespaces appened to the beginning of them.

Python's "Zen" has the line "Namespaces are one honking great idea -- let's do more of those!".  Ruby/Rails seems to be missing this.  I don't like it.

Comments [0]

What I've been listening to

I went to a record store recently and went from listening station to listening station, writing down each of the albums currently playing.  It's old fashioned, but it's a good way to find new / forgotten music.  Here are the results:

Neil Young - Harvest (1972)

Erykah Badu - Baduizm (1997)

Mazzy Star - So Tonight That I Might See (1993)

KMFDM - Xtort (1996)

Massive Attack - Heligoland (2010)

Lisa Hannigan - Sea Stew (2008) thanks to Caroline at The Decanting Room

Femi Kuti - Femi Kuti (1995)

Humble Pie - Smokin' (1972)

 

This was an experiment, and frankly, a successful one.  I'll try to keep a regular schedule of updates, so we'll see what happens.  Oh, and add me on Last.FM if you have an account: http://www.last.fm/user/davezor94

Comments [0]

Another view on feature-creep

Reading rand's latest post (http://www.randsinrepose.com/archives/2010/06/28/how_to_write_a_book.html), he mentions a tool I use every once in awhile called WriteRoom.  Here's what it looks like:

Rands mentions that, during the process of writing a book, distractions appear everywhere and become the truest obstacles to your productivity and success.  I agree completely.  However, it struck me that MOST people who use WriteRoom probably aren't successful authors.  And I think WriteRoom knows that.  So they add these features so that their users can tweak and fiddle with them all day and FEEL productive.  Only a small fraction of a given software product's users are actually going to be using that product to its fullest potential, so I think alot of software products add features not just to make their software more (or less) useful, but to keep their users busy.

Comments [2]

Verified twitter followers script in python

Dan Freedman posted a nice perl script for finding all of a username's verified followers on twitter.  I ran into a problem (because I don't know perl), so I decided to port it to python for a fun exercise:



 #! /usr/bin/python
 
 import urllib2
 import sys
 import json
 
 def get_cursor(cursor = -1):
     return urllib2.urlopen("%s&cursor=%s" % (host, cursor)).read()
 
 def main():
     # start off
     twitter_json = get_cursor()
     while True:
         from_json = json.loads(twitter_json)
         if from_json['next_cursor'] == 0:
             break
 
         followers = from_json['users']
         for follower in followers:
             if follower['verified'] == True:
                 print follower['screen_name'], follower['name']
         twitter_json = get_cursor(from_json['next_cursor'])
 
 if len(sys.argv) < 2:
     print "Usage: python verified_followers.py <username>"
     sys.exit(1)
 
 host = "http://api.twitter.com/1/statuses/followers.json?screen_name=%s" % str(sys.argv[1])
 main()




It will print username and then real name on the same line.

Comments [2]