<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>stevengharms.com &#187; Software</title>
	<atom:link href="http://stevengharms.com/category/software/feed" rel="self" type="application/rss+xml" />
	<link>http://stevengharms.com</link>
	<description>My Blog</description>
	<lastBuildDate>Thu, 24 Nov 2011 06:01:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>I Won the Podio API Release Hackathon Competition</title>
		<link>http://stevengharms.com/i-won-the-podio-api-release-competition</link>
		<comments>http://stevengharms.com/i-won-the-podio-api-release-competition#comments</comments>
		<pubDate>Sun, 22 May 2011 18:51:24 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[San Francisco]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology and Computers]]></category>

		<guid isPermaLink="false">http://stevengharms.com/?p=2248</guid>
		<description><![CDATA[Introduction On May 14th, I competed at a Hackfest hosted by Podio. Podio is a customizable social networking application delivered as a service (aaS). After 8 hours of coding, I placed first in the competition and won a beautiful Apple Cinema Display. In this post I will cover my hack, how it was done, and [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>

<p>On May 14<sup>th</sup>, I competed at a Hackfest hosted by <a href="http://podio.com">Podio</a>.
Podio is a customizable social networking application delivered as a service
(aaS).  After 8 hours of coding, I placed first in the competition and won a
beautiful Apple Cinema Display.  In this post I will cover my hack, how it was
done, and lessons learned.</p>

<p><a href="http://www.flickr.com/photos/podio/5724215201/" title="Steven G.
Harms with his first prize by Team Podio, on Flickr"><img
class="aligncenter size-full"
src="http://farm4.static.flickr.com/3124/5724215201_34a6023095.jpg"
width="500" height="333" alt="Steven G. Harms with his first prize"></a></p>

<p><em>Victori pretium it</em></p>

<p><em><a href="http://blog.podio.com/2011/05/25/interview-with-steven-g-harms-winner-of-the-podio-api-release-hackathon/">Or, you can watch my video interview</a></em></p>

<p><span id="more-2248"></span></p>

<h2>Background</h2>

<p>Let me first introduce the various companies involved and technologies
provided or implemented in the solution.  I think of these as the ingredients
in the recipe that allowed me to code my offering.</p>

<h3>Podio</h3>

<p>In case you haven&#8217;t noticed, people are spending phenomenally large amounts of
time on social networks.  These applications have their own vocabulary of
interactions and provide certain defined workflows that, thanks to their
popularity, are teaching the population certain workflows for successful
collaboration.  As younger employees enter the workforce, their models of
collaboration will be informed by these social networks whose existence and
interaction vocabulary are presumed to be ubiquitous.  Accordingly, it would
be wise for businesses to adjust <em>their</em> workflows to look something like
these social sites.</p>

<p>The traditional solution to this has been to acquire servers, place them in a
data center, and build your own social networking clone which, invariably,
would be perceived as a dismal dog in comparison to the glittery product like
Facebook, Linked In, et al. distilled in the market crucible.  In short,
building a social platform is probably not your core competency.</p>

<p>Enter Podio who offers a software solution that behaves &#8220;like Facebook&#8221; and
which can be used <em>as a service</em>.</p>

<p>Traditionally, when using  an aaS solution, one loses the ability to create
highly specfic applications (&#8220;Podio&#8217;s not going to build an app to show what&#8217;s
in our cafeteria today&#8221;).  Or one might expect that to get a specific app one
would have to pay Podio a handsome consulting engagement fee.  Podio has seen
a way around these drawbacks of using an aaS service by providing an
<strong>in-application, friendly, web-based, drag-and-drop application builder</strong>.
This is the first key element in my solution.</p>

<p>While a well-conceived application builder is great, certain behaviors are
unique to certain businesses (e.g. &#8220;SMS the sales manager if no one takes
ownership of the customer complaint within 24 hours.&#8221;) and don&#8217;t have an
obvious integration point in a web interface.  To remedy this concern, Podio
provides <strong>a rich API (Application Program Interface) that&#8217;s a pleasure to
use</strong>.  It allows 3<sup>rd</sup> parties to extend and share functionality
between the Podio core and their own custom applications.  It was the public
release of this API on Saturday that occasioned the Hackfest.  It was also
the second key element in my solution.</p>

<p>On the topic of the API, let me add that
many technical entities develop an API as an afterthought and the reliability
and consideration (or lack thereof) shows.  Podio bravely (!) decided to
re-implement their web interface as a client of their own API.  This is a
brave move, but by testing whether they themselves could work with the API
they were providing, they wound up creating a better, more-intuitive app.</p>

<p><a href="http://www.flickr.com/photos/podio/5553727063/" title="Work 2.0
Hackday at The Podio Store by Team Podio, on Flickr"><img
src="http://farm6.static.flickr.com/5225/5553727063_3ea610da89.jpg"
class="aligncenter size-full"
width="500" height="333" alt="Work 2.0 Hackday at The Podio Store"></a></p>

<p>Incidentally Podio is not purely a virtual experience, they have the Podio
Store in San Francisco&#8217;s SoMa districit where you can go and talk to their
staff about what you could do with Podio.  They&#8217;ve made the &#8220;app store&#8221;
software conceit physical.  It&#8217;s revolutionarily transgressive in a good way <img src='http://stevengharms.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<h3>Twilio</h3>

<p><a href="http://stevengharms.com/wp-content/uploads/2011/05/twilio-logo.png"><img src="http://stevengharms.com/wp-content/uploads/2011/05/twilio-logo-300x100.png" alt="" title="twilio-logo" width="300" height="100" class="aligncenter size-medium wp-image-2255" /></a></p>

<p><a href="http://www.twilio.com/">Twilio</a> is a service vendor who provides an
exceedingly simple-to-use API for interacting with phones:  setting up
phone menus (&#8220;Press 1 for &#8230;, Press 2 for&#8230;&#8221;), making phone
calls, bridging calls, setting up conference calls, setting up answer
menus, etc. is a breeze.  If you need to do something that touches a phone,
Twilio&#8217;s rich, well-documented API will make it easy.</p>

<p>I had gotten a Twilio developer key and $30.00 of free minutes that I hadn&#8217;t
touched since it was given to me at the Social Apps workshop held at Heroku in
January 2010 (<em>ulp</em>).  <strong>Twilio&#8217;s API was the third component</strong> in my solution.</p>

<h3>Heroku</h3>

<p><a href="http://stevengharms.com/wp-content/uploads/2011/05/heroku-logo-light-300x100.png"><img src="http://stevengharms.com/wp-content/uploads/2011/05/heroku-logo-light-300x100.png" alt="" title="heroku-logo-light-300x100" width="300" height="100" class="aligncenter size-full wp-image-2251" /></a></p>

<p><a href="http://heroku.com">Heroku</a> makes it incredibly easy to stand up and host web
applications.  I have only ever used it to deploy Rails and Sinatra
applications.  Heroku makes a very complex process managable, but it is not
without some complexity.  <strong>Heroku&#8217;s service was the fourth and final vended
technology involved in my solution</strong>.</p>

<h3>Previous Experience</h3>

<p>It is fair to say that I probably spent the most of my time on the
hack day trying to figure out the right way to develop with Heroku.  However,
if you read through this post and reference the <a href="http://devcenter.heroku.com/articles/quickstart">implementation process</a>, while not
completely <em>effortless</em>, you will capture the value proposition posed by
Heroku&#8217;s use.</p>

<p>Previously I had used Heroku to host my <a href="http://verbalatina.heroku.com">Verba Latina in Viis Ferrorum (Latin
on Rails)</a> application that I used in a failed
bid to get into grad school (<em>Cue violins and tears</em>).  As such I was familiar
with their streamlined, <a href="http://git-scm.com/">git</a>-based deployment design as
well as with the concept that you must configure your app to have a
configuration manifest so that Heroku builds the application the right way.</p>

<p>Last January <a href="http://blog.heroku.com/archives/2010/8/20/social_app_workshop_videos/">Heroku and Twilio hosted an
introduction</a>
to using Twilio and Heroku to create social, phone-based applications.  Here a
pattern emerged whose introduction was very important to my Podio solution:</p>

<ol>
<li>Acquire a Heroku instance</li>
<li>Run a web framework (the lighter the better, for debugging purposes)</li>
<li>Use your instance to bridge communications between API&#8217;s</li>
<li>Violà, mashup</li>
</ol>

<p>However at the Social Apps workshop, I didn&#8217;t really do this, instead I
learned about some other Ruby tools described below.  While the pattern would
have been good to have had some experience with, the following tools were
also essential to my success at Podio, so it was good that I spent time
learning a bit about them.</p>

<h3>Ruby Tooling</h3>

<h4>Sinatra</h4>

<p>Sinatra is a very light language for describing a web server.  You say:  hey,
when someone points to you with <code>/</code> at the end, send back some text generated
by executing some code.  It&#8217;s incredibly simple, incredibly clear and I had
done a &#8220;hello Heroku&#8221; on it as part of the Social Apps get-together.</p>

<h4>Ruby</h4>

<p>Sinatra is written in Ruby, so, I&#8217;m glad I know Ruby.</p>

<h4>RVM</h4>

<p><a href="http://rvm.beginrescueend.com/">RVM</a> is a way to have multiple Ruby
interpreters installed on a machine at the same time such that their various
libraries and dependencies don&#8217;t interfere with one another.  It also has a
wonderful tool called &#8220;gemsets&#8221; which allow you to store all your Ruby gems
(libraries for specific tasks) in a single sandbox so that you know what you
have when it comes time to deploy.</p>

<h4>git</h4>

<p><a href="http://git-scm.org">Git</a> is for revision control.  More than once I screwed
up a file and needed to get back to a working state quickly, specifically
because the competition was timed.  The ability to not have to do dozens of
&#8216;undo&#8217; operations was critical.</p>

<h4>vim</h4>

<p>A fast editor for editing text.  &#8216;Nuff said.</p>

<h2>Ingredient List</h2>

<p>Having shown the background above, I had the following ingredients when I
showed up:</p>

<ol>
<li>Podio:

<ol>
<li>In-application, web-based, drag-and-drop application builder</li>
<li>API</li>
</ol></li>
<li>Twilio

<ol>
<li>API</li>
<li>Free developer minutes from Social Apps workshop</li>
</ol></li>
<li>Heroku</li>
<li>Sinatra</li>
<li>Other development tools</li>
</ol>

<p>As of Saturday morning, I would rate my proficiency with Podio, Twilio, and
Heroku, and Sinatra as being very low.  It is a tribute to the designers of
these systems that I was able to stitch them all together in just a few hours.</p>

<h2>The Hack</h2>

<h3>Kick-Off</h3>

<p>First things first I arrived at Podio&#8217;s <a href="https://store.podio.com/">beautiful
storefront</a> on 6<sup>th</sup> street, SoMa, SF, CA,
but 2 blocks from my house, at 8am and was treated to some great brain-food
for breakfast.  The interior is beautuful with Scandinavian sensibility and
with several ukelele&#8217;s decorating the wall.  The loft-style space is modern
and tasteful and a great place to visit.</p>

<p><a href="http://www.flickr.com/photos/podio/5553731133/" title="IMG_5782 by
Team Podio, on Flickr"><img
src="http://farm6.static.flickr.com/5141/5553731133_32029ddb43.jpg"
class="aligncenter size-full"
width="500" height="333" alt="IMG_5782"></a></p>

<p><em>The ukelele wall</em></p>

<p>The morning started off with <a href="http://blog.podio.com/author/phil/">Phil
Chambers</a> (CTO,
<a href="http://twitter.com/#!/filchambers">@filchambers</a>) and
Christian Holm (Developer, <a href="http://twitter.com/#!/hlmrn">@hlmrn</a>) showing off
what the Podio drag and drop tool and API is capable of.</p>

<p><a href="http://www.flickr.com/photos/podio/5724806926/" title="Christian Holm
by Team Podio, on Flickr"><img
src="http://farm6.static.flickr.com/5268/5724806926_8cb74ce8b8.jpg"
class="aligncenter size-full"
width="500" height="333" alt="Christian Holm"></a></p>

<p><em>Christian demonstrates</em></p>

<p>Now here&#8217;s a bit of a sheepish confession I have to make:  <em>I hadn&#8217;t really
even considered there was a competition</em>.  I thought it was going to be a meet
and greet, code some, and get some tasty food and / or beverages&#8230;but then
Phil mentioned that there were prizes for the best use of the API!  To sweeten
the deal with the spectre of avarice, Podio had brought in some great prizes:
Dr.  Dre headphones, an iPad2, and a beautiful Apple Cinema Display.  I
figured going home with headphones wouldn&#8217;t be bad for a day&#8217;s work.  I
half-flirted with maybe even getting the iPad but didn&#8217;t put much store by it.
Besides, I had work to do.</p>

<h3>Ideation</h3>

<p>After the &#8220;Go!&#8221; bell was rung, I thought about something that had been on my
mind.  They day before I&#8217;d had a frustrating visit with my HOA.  I found
myself wishing that there were some way for us to keep better track of our
&#8220;shared&#8221; maintenance tickets (handled via email).  The first thing I did was use
Podio&#8217;s drag-and-drop application builder to build a basic ticket tracker.
While most tickets are private and bonded to a single resident, there should
be &#8220;shared / public&#8221; tickets for shared issues:  water stains in a hallway,
Insanity Wolf in the garage, etc.</p>

<p><a href="http://stevengharms.com/wp-content/uploads/2011/05/insanity_wolf.jpg"><img src="http://stevengharms.com/wp-content/uploads/2011/05/insanity_wolf-300x300.jpg" alt="" title="insanity_wolf" width="300" height="300" class="aligncenter size-medium wp-image-2254" /></a></p>

<p><em>A fearsome menace!  Insanity wolf does not read your Tumblr blog</em></p>

<p>I called this app &#8220;Is It Done Yet?&#8221; &mdash; a common-enough thought among most
urban flat-dwellers when considering the state of their work orders with their
property management companies.</p>

<p>By using the Podio app builder &#8230;</p>

<p><a href="http://stevengharms.com/wp-content/uploads/2011/05/app_builder.png"><img src="http://stevengharms.com/wp-content/uploads/2011/05/app_builder-300x262.png" alt="" title="app_builder" width="300" height="262" class="aligncenter size-medium wp-image-2250" /></a></p>

<p><em>Click for larger view</em></p>

<p>I was able to create &#8220;IIDY?&#8221; tickets&#8230;</p>

<p><a href="http://stevengharms.com/wp-content/uploads/2011/05/IIDY_ticket.png"><img src="http://stevengharms.com/wp-content/uploads/2011/05/IIDY_ticket-271x300.png" alt="" title="IIDY_ticket" width="271" height="300" class="aligncenter size-medium wp-image-2253" /></a></p>

<p><em>Click for larger view</em></p>

<p>This took me all of about 15 minutes to put together.  It was about this time
that Jon Froda, one of the founders, came by to talk to me about how things
were going.  I explained the work-order tracking idea and he suggested that
maybe I could add an alerting system for &#8220;Emergency&#8221; requests and that I could
have that page out.  Having been a sysadmin, I knew about pager notifications
and while I thought it might be a bit too simple to be a real competitor, I
knew that it was implementable in a few hours&#8230;provided I use Heroku and
Twilio.  I was a bit daunted since I was not too familiar with these peer
components and I certainly had no experience in tying them to the Podio API.</p>

<p><em>&#8230;But</em> Jon&#8217;s idea seemed audacious to win a prize but was slim enough to do
in a few hours.  I went with it.</p>

<p>I thought the idea over and sketched up a basic schematic for the design with
the help of Christian.  I worked from right to left.</p>

<pre>
Podio                    Heroku-hosted Custom App               Twilio
 Web Hook On Create -->    Receives event                  |-->API sends SMS
                           Evaluates emergency Status      |
                           If emergency, paged via Twilio -|
</pre>

<h3>Set Up the Development Space</h3>

<pre><code>$ mkdir podio
$ cd podio
$ git init
$ echo '\*.sw\*' &gt;&gt; .gitignore
$ touch Gemfile Gemfile.lock
$ echo 'rvm use ruby-1.9.2-p180@podio' &gt;&gt; .rvmrc
$ cd ~
$ rvm use ruby-1.9.2-p180
$ rvm gemset create podio
$ cd - 

info: Using ruby 1.9.2 p180 with gemset podio
$
</code></pre>

<p>As I mentioned earlier, knowing some core Ruby / Unix tools made getting
started and working efficiently an edge for a team of one.  These command set
creates a directory, a primitive git ignore file, and creates a Gemfile that
will be used for defining the apps&#8217; gem dependenices via
<a href="http://gembundler.com/v1.0/index.html">bundler</a> as required by Heroku.  It
also specifies an RVM gemset which will sandbox all the dependencies.</p>

<h3>Send an SMS via Twilio from the CLI</h3>

<p>Twilio provides an Ruby wrapper for dealing with their API. The first thing I
did was get the <code>twiliolib</code> gem.  I then found the <a href="http://www.twilio.com/docs/howto/sms-notifications-and-alerts">Twilio SMS
example</a> that,
although written in PHP, was sufficient to give me a place to start.</p>

<p>I implemented this code like so:</p>

<pre><code>#!/usr/bin/env ruby

require 'twiliolib' 
require 'pp'

# Twilio REST API version 
API_VERSION = '2010-04-01'

# Twilio AccountSid and AuthToken 
ACCOUNT_SID = 'MY-SID' 
ACCOUNT_TOKEN = 'MY-AUTH-TOKEN'

# Outgoing Caller ID previously validated with Twilio 
CALLER_ID = 'MY-VALIDATED CALLER ID';

# Create a Twilio REST account object using your Twilio account ID and token
account = Twilio::RestAccount.new(ACCOUNT_SID, ACCOUNT_TOKEN)

d = { 'From' =&gt; CALLER_ID, 'To' =&gt; 'MY-CELL-PHONE', 'Body' =&gt; ARGV.empty? ?
'An EMERGENCY severity task has been opened!  Please check PODIO task list.'
: ARGV[0] }

resp =
account.request("/#{API_VERSION}/Accounts/#{ACCOUNT_SID}/SMS/Messages",
'POST', d) resp.error! unless resp.kind\_of? Net::HTTPSuccess

puts "code: %s\nbody: %s" % [resp.code, resp.body]
</code></pre>

<p>What could be easier!?  Well, I got killed by a bug here that took a lot of
debugging.  I had put in the wrong <code>CALLER_ID</code> value.  Make sure you <strong>cut and
paste</strong> the validated phone number value into your code.  You can find the
number on your <a href="https://www.twilio.com/user/account/phone-numbers">Twilio user
page</a>.</p>

<p><em>Tip:</em>  In the last puts of the code, there is a call to <code>resp.code</code> and
<code>resp.body</code>.  Twilio provides another value <code>resp.moreinfo</code>.  This additional
property of the response object is described in the <a href="http://www.twilio.com/docs/api/rest/response">response
API</a>.  It will give your a more
verbose explanation of why a REST request failed.  I wound up finding out that
my approved number was incorrect from this property (see previous paragraph) by
tracing through the stack using <code>rdebug</code>.  Again, familiarity with the
lanaguge&#8217;s facets and debugging tools will make your race much easier.
Unfamiliarity with <code>moreinfo</code> cost me time and thus functionality :-/.</p>

<p><a href="http://www.flickr.com/photos/podio/5724247967/" title="Alan Davis by
Team Podio, on Flickr"><img
src="http://farm4.static.flickr.com/3457/5724247967_879907f893.jpg"
class="aligncenter size-full"
width="500" height="333" alt="Alan Davis"></a></p>

<p><em>Alan Davis, when not being harrassed on GChat by yours truly</em></p>

<p>As I was debugging that issue I had help from Alan Davis and Andrew Benton on
the Twilio team via GChat.  With a simple Twilio paging app completed, I was
ready for a midday snack.  After that I needed to put the logic of my
stand-alone app into a web framework: both on my local MacBook Pro as well as
a remote system reachable by Podio as well as Twilio, i.e. on Heroku.</p>

<h3>Building the Middleware: Heroku and Sinatra</h3>

<p>I started off small in Sinatra, basically cloning the Sinatra tutorial by
<a href="http://titusd.co.uk/2010/04/07/a-beginners-sinatra-tutorial">Joe Yates</a> with
additional support from <a href="http://sinatra-book.gittr.com/">The Sinatra Book</a>.
This set me up with a small web service on my local machine as a proving
ground for what I would deploy onto the <em>real</em> Internet on a Heroku node.</p>

<p>In about a half hour I had a Sinatra app running on my localhost that blended
in the Twilio logic from the previous step.  This file is <code>podio.rb</code>.</p>

<pre><code>require 'sinatra'
require 'twiliolib'


# Twilio REST API version
API_VERSION = '2010-04-01'

# Twilio AccountSid and AuthToken
ACCOUNT_SID = 'XXXXXXX'
ACCOUNT_TOKEN = 'XXXXXXX'

# Outgoing Caller ID previously validated with Twilio
CALLER_ID = 'XXXXXXX';


before do
  # Great debugging!
  pp params
end

helpers do
  def send_a_page(rest,num)
      account = Twilio::RestAccount.new(ACCOUNT_SID, ACCOUNT_TOKEN)

      d = {
          'From' =&gt; CALLER_ID,
          'To' =&gt; rest[0].nil? ? 'XXX-XXX-XXXX' : rest[0],
          'Body' =&gt; "Emergency page"
      }

     resp = 
     account.request("/#{API_VERSION}/Accounts/#{ACCOUNT_SID}/SMS/Messages",
                               'POST', d)
     puts "#### code: %s\nbody: %s" % [resp.code, resp.body]
   end


  end
end

get '/' do
  'Minimal Sinatra Hello World!'
end


get '/razzle' do
  'You have been razzled!'
end

get '/simplenotify/' do
 'Paging out simple'
 send_a_page [ nil, 'simple notify', nil, nil ] 
end
</code></pre>

<p>As you can see, given my inexperience with Sinatra I kept things simple.  The
first routes I added were &#8216;<code>/</code>&#8217; and &#8216;<code>/razzle</code>&#8217; (Old joke from the Perl camel
book&#8230;).  Having tested those locally, I was sure I had the right approach.  I
then wrote <code>/simplenotify</code> to see if I could page myself.  This basically
harvested the previous CLI implementation and had me underway.  I next needed
to get this code up into Heroku.</p>

<h3>Heroku</h3>

<p>As I said before, Heroku is not difficult.  But Heroku is not easy either.
Heroku deployments have a number of dependencies on constituent technologies
that are not easily understood unless you are already familiar with the
requisite, supporting technologies preferably in a realm where you have used
each of them independently where their dependencies don&#8217;t cloud the issue.
Regrettably, it doesn&#8217;t seem like there is much documentation that helps take a
developer through that process (although this post might fill that void).</p>

<p>That said, deploying to Heroku once you know these pieces is a snap, but before
then it is daunting, and especially so under time pressure!  For first timers,
your time will principally be spent here (<em>yes, I did just split that
infinitive</em>).</p>

<p>Let me try to simplify things as much as possible:</p>

<ol>
<li>Follow the <a href="http://devcenter.heroku.com/articles/quickstart">quickstart</a>, steps 1-3:</li>
<li>Get Heroku on Ruby 1.9: <code>heroku stack:migrate bamboo-mri-1.9.2</code> in your
working directory</li>
<li>Edit code in podio.rb that worked on localhost, commit it to the local git
repository</li>
<li>Execute step 4 and push to heroku; your code is now on Heroku!</li>
<li>Fail</li>
</ol>

<p>When I started I didn&#8217;t understand two critical constituent technologies that
are needed to make Heroku work.  Here they are.</p>

<h4>Bundler and Gemfile</h4>

<p>Bundler allows you to specify gems your app needs (on local development) in a
Gemfile.  Heroku respects this definition set when it gets your application
pushed to it.  Therefore <strong>any gem you need should be specified in the
Gemfile</strong>.  Thus my Gemfile looks like:</p>

<pre><code>source "http://rubygems.org"

gem "nokogiri"
gem "rack"
gem "sinatra", "1.2.6"
gem "twiliolib"
gem "podio"
</code></pre>

<p>What does this mean?  It means that I want you, Heroku, to install nokogiri,
rack, sinatra, twiliolib, podio into this instance&#8217;s (be it local or Heroku)
gemset repository.  On the local system, thanks to my <code>.rvmrc</code> this will ALSO
be in the <code>podio</code> gemset I specified when I set up the workspace.  Thus I can
issue <code>bundler install</code> and the gems will be downloaded and, thanks to RVM,
be stored in the <code>podio</code> gemset.  This is very cool.  When this directive goes to
Heroku the <em>same thing</em> will happen.  Heroku will grab all the gems specified
in the Gemfile and store it in your app&#8217;s gem repository.  If you want to
<code>require</code> it, make sure its gem is loaded in the <code>Gemfile</code>.  Speaking of
<code>require</code>&#8230;</p>

<h4>Rack and config.ru</h4>

<p>Sinatra uses &#8216;rack&#8217; as middleware.  To configure how a Rack instance is to be
launched, you specify the criteria in <code>config.ru</code>.  Here&#8217;s mine:</p>

<pre><code>require 'sinatra'
require 'twiliolib'
require 'pp'
require './podio.rb'

run Sinatra::Application
</code></pre>

<p>It is the logical complement to the Gemfile.  It says, given those gems that
are now available (thanks to bundler and <code>Gemfile</code>), I want to require these
libraries into the namespace:</p>

<ul>
<li><code>sinatra</code>:  (obviously!)</li>
<li><code>twiliolib</code>:  For use in Twilio operations</li>
<li><code>pp</code>:  pretty-print debugging</li>
<li><code>./podio.rb</code>:  My code!</li>
</ul>

<p>The last step is a command to run a <code>Sinatra::Application</code>.</p>

<p>With these two files in place and in the git repository, we&#8217;re good to run a
Heroku-based simple-page out.  With a simple <code>git push heroku master</code> I was
able to get my code up on Heroku.  The <code>heroku logs (-n lineCount)</code> command
was a good friend during this process.  Pointing a browser at
<code>http://my-heroku-instance.heroku.com/simplenotify</code> sent my phone a page.  Next
was to tie the other half in:  link into Podio.</p>

<p><a href="http://www.flickr.com/photos/podio/5724245617/" title="Neil Mansilla
and Andreas Haugstrup by Team Podio, on Flickr"><img
src="http://farm4.static.flickr.com/3624/5724245617_5101f91113.jpg"
class="aligncenter size-full"
width="407" height="500" alt="Neil Mansilla and Andreas Haugstrup"></a></p>

<p><em>Neil uses Skype to contact Podio home-base in Copenhagen for Andreas&#8217; help
and Journey playlist</em></p>

<h3>Podio API</h3>

<p>First, I went back to my app editor and added a field called &#8220;Emergency&#8221; with
values of &#8220;Yes&#8221; and &#8220;No.&#8221;  Then I saved the app.  This would be my signal of
whether to page out.</p>

<p><a href="http://stevengharms.com/wp-content/uploads/2011/05/webhook.png"><img src="http://stevengharms.com/wp-content/uploads/2011/05/webhook-300x145.png" alt="" title="webhook" width="300" height="145" class="aligncenter size-medium wp-image-2256" /></a></p>

<p>Next I clicked the &#8220;Settings &gt; WebHooks&#8221; menu.  I added a new hook and
specified that <code>item.create</code> tasks should trigger the URL to my Heroku
instance called <code>/verify</code>.  This name is a bad name, but I was in too much of
a hurry to change it.  I should have called it something else.  I specified,
thus, a URL of the form <code>http://my-heroku-instance/verify</code>.</p>

<p><a href="http://stevengharms.com/wp-content/uploads/2011/05/hookspecify.png"><img src="http://stevengharms.com/wp-content/uploads/2011/05/hookspecify-288x300.png" alt="" title="hookspecify" width="288" height="300" class="aligncenter size-medium wp-image-2252" /></a></p>

<p>The next step is to verify your URL.  To accomplish this Podio will send a
form-encoded data blob (POST) to your URL.  You must catch this and send back
the <a href="https://developers.podio.com/doc/hooks/validate-hook-verificated-215241">validation information specified per the
spec</a>.</p>

<p>At this time I was encouraged by Christian to make use of the 
<a href="https://developers.podio.com/clients/ruby">Ruby client API</a> to handle the
validation.  Ergo I added <code>podio</code> to my Gemfile and required <code>podio</code> in my
<code>config.ru</code>.  I then ran <code>bundler install</code> and viola, I had the gem I needed.
I then did another <code>git push heroku master</code> and Heroku built in the new
dependency.  I was now able to get validation working via API.</p>

<p>Getting validation set up took me a while, but it basically boils down to
this.</p>

<p>In my <code>podio.rb</code>, in the listener for the route I specified in the WebHook
configuration to use I added the following logic:</p>

<p>require &#8216;sinatra&#8217;
  require &#8216;twiliolib&#8217;</p>

<p>post &#8216;/verify&#8217; do
    if params[&#8220;type&#8221;] == &#8220;hook.verify&#8221;
      Podio.setup( :api_key => &#8216;MY API KEY&#8217;, :api_secret => &#8216;SECRET_STUFF&#8217;)<br />
      Podio.client.authenticate_with_credentials(&#8216;MY_PODIO_EMAIL_LOGIN&#8217;, &#8216;PW&#8217;)
      Podio::Hook.validate params[&#8220;hook_id&#8221;],  params[&#8220;code&#8221;]
    end
  end</p>

<p>Then you hit the &#8220;Verify&#8221; button in Podio.  If you watch your Heroku logs,
you&#8217;ll see the request come through and the validation trigger occur.
<strong>NOTE:</strong>  I lost a lot of time because I had &#8216;get&#8217; as the first word for
/verify.  Verification happends as a <strong>POST</strong> operation.  It was getting late
at that point and I was completely blind to that error.</p>

<p><a href="http://www.flickr.com/photos/podio/5724781980/" title="Podio
Hackathon by Team Podio, on Flickr"><img
src="http://farm3.static.flickr.com/2791/5724781980_11d41ea4c8.jpg"
class="aligncenter size-full"
width="500" height="333" alt="Podio Hackathon"></a></p>

<p><em>Probably about this point I got stuck on this stupid bug&#8230;</em></p>

<p>Now that the hook was validated, all I needed was a means to catch
<code>item.create</code> operations.  So I added:</p>

<pre><code>if params["type"] == "item.create"
 send_a_page [ nil, 'simple notify', nil, nil ], params["item_id"]
end
</code></pre>

<p>This would pass the configuration message as well as the critical item_id
for the newly-created item to a helper method which would implement the
Twilio bridge to place a page.</p>

<p>Here&#8217;s that method, it should look familiar based on the content presented
thus far.</p>

<pre><code>helpers do
  def send_a_page(rest,num)

   Podio.setup( :api_key =&gt; 'XXXXXX', :api_secret =&gt; 'XXXXXX')   
   Podio.client.authenticate_with_credentials('XXXXXX', 'XXXXX')

   # The ID passed in from /verify
   anItem=Podio::Item.find(num)

   # Very ugly JSON hash dereferencing
   theField=
     anItem["fields"].detect{|x| x["external_id"] == "is-this-an-emergency" }
   theRes=anItem["tasks"].first["created_by"]["name"]

   # If the emergency value field is set to use
   if  theField["values"].first["value"] =~ /yes/i 
     # Cheap Heroku logging <img src='http://stevengharms.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> 
     puts "YES!  It is an emergency" 

      account = Twilio::RestAccount.new(ACCOUNT_SID, ACCOUNT_TOKEN)

      d = {
          'From' =&gt; CALLER_ID,
          'To' =&gt; rest[0].nil? ? 'XXX-XXX-XXXX' : rest[0],
          'Body' =&gt; "Emergency page: Task: #{params["item_id"]}" +
                          " from resident "+ 
                           "#{theRes} has been reported in Podio!"
      }

     resp = 
     account.request("/#{API_VERSION}/Accounts/#{ACCOUNT_SID}/SMS/Messages", 
                               'POST', d)
     puts "#### code: %s\nbody: %s" % [resp.code, resp.body]
   else
     puts "NO"
   end
  end
end
</code></pre>

<p><a href="http://www.flickr.com/photos/podio/5724240261/" title="The demo that
never was.  by Team Podio, on Flickr"><img
src="http://farm3.static.flickr.com/2673/5724240261_e6fdbd2397.jpg"
class="aligncenter size-full"
width="500" height="333" alt="The demo that never was. "></a></p>

<p><em>Caleb invited me to show up via the SF Ruby group</em></p>

<h2>Finish Line</h2>

<p>At this point all the pieces were in place and I created a test item, set to
emergency, and had it page my cell phone.  It worked!  I finished about 10
minutes ahead of time and did something revolutionary.</p>

<p><strong>I STOPPED WORKING</strong></p>

<p>A failing app is a non-competitor, so I decided to quit with a small bit
of functionality in place.  I had planned for more, but learning Heroku,
Sinatra, Twilio, and Podio had taken more time than I had expected.  I credit
knowing when to stop to be the result of 10 years hard experience in coding
before deadlines or change request endings.</p>

<h2>Comments</h2>

<p>The story I tell here is pretty straight-forward and linear, but in reality
(and I have the git commit logs to prove it!) it was much messier.  I hope
anyone interested can follow this post for didactic purposes not narratorial
veracity.</p>

<h2>Demo</h2>

<p>I grabbed a beer and started talking with some of the guests who had come for
the demos.  The beer was necessary because my furious coding had left my
nerves shot and my hands shaking.  We sat down and were called upon to
demonstrate in order.  When my turn came I explained about the need for case
tracking and alert systems.  I created a new &#8220;Is It Done Yet&#8221; item, set the
flag to emergency, and submitted the item.  And as I talked I felt a buzz and
ring from my chest pocket:  I pulled out my phone and showed that the alert
had worked!</p>

<p><a href="http://www.flickr.com/photos/podio/5724795210/" title="Winner Steven
G. Harms by Team Podio, on Flickr"><img
src="http://farm4.static.flickr.com/3100/5724795210_34b7d5772d.jpg"
class="aligncenter size-full"
width="500" height="333" alt="Winner Steven G. Harms"></a></p>

<p><em>I demonstrate&#8230;</em></p>

<p>It was a good feeling to get down from the presentation with a working app.
The other entrants were all great.  Alas, several good ideas were also presented
where the developers couldn&#8217;t <em>quite</em> get all the pieces working in the time
allotted.</p>

<p><a href="http://www.flickr.com/photos/podio/5724793064/" title="Ching Mey and
John Fan by Team Podio, on Flickr"><img
src="http://farm6.static.flickr.com/5087/5724793064_4d3a7f3a85.jpg"
class="aligncenter size-full"
width="500" height="333" alt="Ching Mey and John Fan"></a></p>

<p><em>Cardinal Blue did a great job</em></p>

<h2>The Winner, Me?</h2>

<p>When the judges&#8217; delibrations had finished they returned and announced that
3rd prize was going to Nick who had worked with us remotely from Copenhagen
(home of Podio).  He won the sweet headphones as his application was designed
to catalog entrants in the Eurovision contest.</p>

<p><a href="http://www.flickr.com/photos/podio/5724209323/" title="Andreas
Haugstrup and Nick Barnwell  by Team Podio, on Flickr"><img
src="http://farm3.static.flickr.com/2363/5724209323_db0771a8ee.jpg"
class="aligncenter size-full"
width="500" height="333" alt="Andreas Haugstrup and Nick Barnwell "></a></p>

<p>Coming up next, for the iPad 2, was the team from Cardinal Blue.  I thought their conference call bridging app (also using Twilio!) between Podio contacts was really great.</p>

<p><a href="http://www.flickr.com/photos/podio/5724214565/" title="Ching Mey and
John Fa by Team Podio, on Flickr"><img
src="http://farm6.static.flickr.com/5265/5724214565_58d4f21337.jpg"
class="aligncenter size-full"
width="500" height="333" alt="Ching Mey and John Fa"></a></p>

<p>But I was very surprised when Phil Chambers announced that the
winner was &#8220;Team Solo&#8221; that is, me.  I was awarded the beautiful cinema
display on which, even now, I type this document.</p>

<p><a href="http://www.flickr.com/photos/podio/5724220057/" title="Winner Steven
G. Harms by Team Podio, on Flickr"><img
src="http://farm4.static.flickr.com/3481/5724220057_a58c974d62.jpg"
class="aligncenter size-full"
width="500" height="333" alt="Winner Steven G. Harms"></a></p>

<p><em>Checking my iPhone for an update as triggered from Podio for the camera</em></p>

<p>I gave a little speech, thanking the Twilio guys and the Podio guys who helped
me.  I was thankful to all of them for creating systems that had openness and
hybridization at their heart.  With such a good design principle at their
core, all apps can be integrated for great and surprising effect.</p>

<p>After that it was time for more beer and a great lasagne dinner.  Podio is
first-class all the way through.</p>

<p>I had a great night talking with contacts who urged me to take the idea
further and I hope to talk with all of them again soon.</p>

<h2>Thanks</h2>

<p>I am so thankful to everyone who helped me on the way and am thankful to Podio
for their generosity and initiative in setting this up.  I urge all of you to
try to make a hack fest.  It really gels your skills and, who knows, you
might win!</p>
]]></content:encoded>
			<wfw:commentRss>http://stevengharms.com/i-won-the-podio-api-release-competition/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Reiser story coverage made worse by Gawker Media ads</title>
		<link>http://stevengharms.com/reiser-story-coverage-made-worse-by-gawker-media-ads</link>
		<comments>http://stevengharms.com/reiser-story-coverage-made-worse-by-gawker-media-ads#comments</comments>
		<pubDate>Thu, 10 Jul 2008 13:34:40 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Critique]]></category>
		<category><![CDATA[Culture]]></category>
		<category><![CDATA[Modern Times]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://stevengharms.com/reiser-story-coverage-made-worse-by-gawker-media-ads</guid>
		<description><![CDATA[Once upon a time there was a genius software developer named Hans Reiser. He used to join Linux forums and lambaste other hackers as being foolish, prodigal, indolent, and was generally a bit of an egomaniacal ass. In other words, par for the course in the world of software development. But then he was indicted, [...]]]></description>
			<content:encoded><![CDATA[<p>Once upon a time there was a genius software developer named Hans Reiser.  He used to join Linux forums and lambaste other hackers as being foolish, prodigal, indolent, and was generally a bit of an egomaniacal ass.</p>

<p>In other words, par for the course in the world of software development.</p>

<p>But then he was indicted, and convicted, for the murder of his wife amid a tale of S&amp;M, Linux development ( intimately linked ), Russian internet-ordered brides, and infidelity.</p>

<p>A crucial feature of the trial was, well, that the cops couldn&#8217;t find the body.  Upon being found guilty, Reiser seems to have copped a plea with the judge such that he could get a lesser sentence in exchange for the victim&#8217;s family and, <em>nota bene</em>, his own children being able to lay the body of their daughter / mother to rest.</p>

<p>Here was Gawker media&#8217;s “Valleywag” summation picture:</p>

<p><img src="http://stevengharms.com/wp-content/uploads/2008/07/gawker-reiser.png" alt="Gawker Reiser" title="" /></p>

<p>First of all, and not to be juvenile, but a copy-editor would have caught the phrase “fingers corpse”&mdash;oh right this is <em>blogging</em>, ahem, never-mind.</p>

<p>Secondly, the incapacitated girl in the ad in the party dress appears <em>dead</em> if not <em>really whacked out on <a href="http://en.wikipedia.org/wiki/Laudanum" title="Laudanum - Wikipedia, the free encyclopedia">laudanum</a></em>.  One could foreseeably think that <em>that</em> was the corpse under discussion.</p>

<p>The whole post is pretty distasteful, I&#8217;d say.</p>

<p>I&#8217;m reminded of pro-feminist blogs decrying things like “new bikini&#8217;s are scandalous” or left-leaning blogs that decry “It&#8217;s insane that McCain can run for president in the 21<sup>st</sup> century given that he can&#8217;t even use a computer” only to be served up, guess what, an ad featuring said bikini&#8217;s or a clip of the <a href="http://www.crooksandliars.com/2008/07/05/john-mccain-i-hate-the-bloggers/">blogger-hating senator</a> as an ad.</p>
]]></content:encoded>
			<wfw:commentRss>http://stevengharms.com/reiser-story-coverage-made-worse-by-gawker-media-ads/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails and Unicode and PostGres DB (Oh My!):  Understanding how UTF-8 works</title>
		<link>http://stevengharms.com/rails-and-unicode-and-postgres-db-oh-my-trying-understand-how-unicode-characters-get-entered</link>
		<comments>http://stevengharms.com/rails-and-unicode-and-postgres-db-oh-my-trying-understand-how-unicode-characters-get-entered#comments</comments>
		<pubDate>Sat, 05 Jan 2008 20:12:48 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology and Computers]]></category>

		<guid isPermaLink="false">http://stevengharms.net/?p=1082</guid>
		<description><![CDATA[Examine the Unicode standard&#8217;s code page collection for &#8220;Latin small letter a with macron&#8221;. Nets U0100.pdf &#8220;Latin small letter a with macron&#8221; appears on chart as 0101. This is a hexidemial number which points to U+0101 as its code point. Converting 0101 to decimal gets you 257, this is the same as the HTML entity [...]]]></description>
			<content:encoded><![CDATA[<ol>
<li><p>Examine the <a href="http://unicode.org/standard/standard.html" title="Unicode Standard">Unicode standard&#8217;s</a> code page collection for &#8220;Latin small letter a with macron&#8221;.</p></li>
<li><p>Nets U0100.pdf</p></li>
<li><p>&#8220;Latin small letter a with macron&#8221; appears on chart as 0101.  This is a hexidemial number which points to U+0101 as its code point.  Converting 0101 to decimal gets you 257, this is the same as the HTML entity code.  Thus one can enter either &amp;#257; or &amp;amp#x0101; and get the right glyph [&#257;|&#x0101;]</p></li>
<li><p>Put &#257; character into a view via Rails that is back-ended by a PostGres database.</p></li>
<li><p>Using script/console, write the collection of models that contain this accented character to a YAML file.</p></li>
<li><p>&#8220;Latin small letter a with macron&#8221; is stored in a YAML dump of accented charcters as:  \xC4\x81</p></li>
<li><p>Hm, OK that&#8217;s a start.  Somehow 0101 or 257 is linked to C4 81.  How?   I know, BTW, the database that holds that entry is in UTF-8 as <code>psql -l</code> shows this.</p></li>
<li><p>C4:  196</p></li>
<li><p>81:   129</p></li>
<li><p>196+129=325  != 0101.  Hm, look at documentation.</p></li>
<li><p>Be stumped.</p></li>
<li><p>Send mail to mailing lists for help.</p></li>
</ol>


<hr />


<p><em>In the immortal words of <a href="http://www.civ3.com/" title="Civilization III: Home">Sid Meier&#8217;s &#8220;Civilization&#8221;</a>:  &#8220;Time Passes&#8230;&#8221;</em></p>


<hr />


<ol>
<li><p>\xC4\x81 is the UTF-8 encoding for the Unicode code point U+0101.</p></li>
<li><p>[Q:]  Which table does U+0101 fall into?  <br/><br/>[A:]  &#8220;So the first 128 characters (US-ASCII) need one byte. The next 1920 characters need two bytes to encode. This includes Latin alphabet characters with diacritics, Greek, Cyrillic, Coptic, Armenian, Hebrew, and Arabic characters. The rest of the BMP characters use three bytes, and additional characters are encoded in four bytes.&#8221;</p></li>
<li><p>OK this means that the code point will be of the form:  &#8220;<strong>110</strong><em>yyyyy</em> <strong>10</strong><em>zzzzzz</em>&#8221;</p></li>
<li><p>We will now work to fill in the &#8220;y&#8221; and &#8220;z&#8221; values:</p></li>
<li><p>Hexidecimal &#8220;U+0101&#8221; converts to binary:  &#8220;<em>100000001</em>&#8221;</p></li>
<li><p>There are 5 y&#8217;s and 6 z&#8217;s.  So let&#8217;s split the above number to match that form: &#8220;<em>[00]100-000001</em>&#8221;.  Note, we moved from the right.  Where the leading 0&#8217;s were required to turn 100 into 00100, they were pre-pended.</p></li>
<li><p>Integrate and produce:  &#8220;<strong>110</strong>&#8221; + &#8220;<em>00100</em>&#8221; : &#8220;<strong>10</strong>&#8221; + &#8220;<em>000001</em>&#8221; => 11000100 : 10000001</p></li>
<li><p>Take THESE numbers and convert them <strong>back</strong> to hex => c4 81</p></li>
<li><p>String notation for this is \xc4\x81 - viol&aacute;!</p></li>
<li><p>Figuring this out letter by letter is a major pain in the keester.  A good URL resource is:  <a href="http://www.fileformat.info/info/unicode/">Fileformat.info</a> or, handily a URI of the form:</p></li>
</ol>

<pre>http://www.fileformat.info/info/unicode/char/&lt;unicode char value&gt;/index.htm</pre>

<p><em>Special Thanks to:  Michael Flester</em></p>
]]></content:encoded>
			<wfw:commentRss>http://stevengharms.com/rails-and-unicode-and-postgres-db-oh-my-trying-understand-how-unicode-characters-get-entered/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Brave new world</title>
		<link>http://stevengharms.com/brave-new-world</link>
		<comments>http://stevengharms.com/brave-new-world#comments</comments>
		<pubDate>Thu, 20 Dec 2007 14:06:33 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[blogging moving personalsites.orgsucks]]></category>

		<guid isPermaLink="false">http://stevengharms.net/?p=1043</guid>
		<description><![CDATA[Thanks for following me across to my new site, note the new .net domain. I&#8217;ve not written for so long owing to my fear of having to migrate more data or lose more data should the lost stevengharms.com die that I&#8217;ve completely fallen out of the habit of writing. So far the folks at hostgator [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks for following me across to my new site, note the new <strong>.net</strong> domain.</p>

<p>I&#8217;ve not written for so long owing to my fear of having to migrate more data or lose more data should the lost stevengharms.com die that I&#8217;ve completely fallen out of the habit of writing.</p>

<p>So far the folks at <a href="http://www.hostgator.com">hostgator</a> have meen a dream to work with, I opened 3 different support cases with respect to getting things set up and going and all three were addressed and dealt with between the hourse of 9 and 5.  Totally, professional, friendly, and smooth.</p>

<p>I noticed a few links on the navigation tab are broken, i&#8217;ll be getting to those shortly, but for the moment my virtual home is safe.</p>
]]></content:encoded>
			<wfw:commentRss>http://stevengharms.com/brave-new-world/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Big Nerd Ranch: RoR Camp: Day 3 (cont&#8217;d): Evening: &#8220;The fatigue&#8221;</title>
		<link>http://stevengharms.com/big-nerd-ranch-ror-camp-day-3-evening-the-fatigue</link>
		<comments>http://stevengharms.com/big-nerd-ranch-ror-camp-day-3-evening-the-fatigue#comments</comments>
		<pubDate>Fri, 16 Feb 2007 02:17:55 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[bignerdranch]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology and Computers]]></category>

		<guid isPermaLink="false">http://stevengharms.net/?p=838</guid>
		<description><![CDATA[Yesterday&#8217;s post looks a little incoherent with a day of rest between it and I. Based on the entreaty of Mr. Graitcer in the comments, I thought that perhaps I could try to characterize what it is to be fatigued in this way. First, let&#8217;s just say that it&#8217;s not the expectation of the teacher [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday&#8217;s post looks a little incoherent with a day of rest between it and I.  Based on the entreaty of Mr. Graitcer in the comments, I thought that perhaps I could try to characterize what it is to be fatigued in this way.</p>

<p>First, let&#8217;s just say that it&#8217;s not the expectation of the teacher or the class curriculum that you work yourself into fatigue of this type.  It&#8217;s not necessary or required.  Yet in <em>both</em> of the BNR classes I&#8217;ve taken, the students worked late into the night on their own projects, or improving the assignments.</p>

<p>Therefore, the motivation to work to this level of fatigue is not <em>extrinsic</em>, it is clearly <em>intrinsic</em>.  This is, clearly, the more cruel mistress.  In a previous post I spoke of the self-selection implicit in defining the population for BNR classes.  I suggested that one of the primary contributing factors in being in the class is having the funds to pay the fee or having a job where the administrators feel that paying such a fee for such a person is a worthy investment.  People who have such funds ( if the meritocracy be believed ) or faith of their financial administrators likely get to this position be not being able to simply <em>let it go</em>.</p>

<p>I have worked through weekends at work, on work stuff simply because I <em>could not let it go</em>.  I have gone to work early, repeatedly, after a few hours of sleep because the problem stalked me.  It wouldn&#8217;t let me go, it wouldn&#8217;t let me sleep.  It was better to be awake, approaching understanding, than to endure fitful sleep under the Damocles sword of the unfound answer&#8217;s shadow.[1]</p>

<p>Many people I&#8217;ve talked to say: &#8220;Go do something else, come back to it.&#8221;  My sweet girlfriend has shuffled around in the wee hours to find me tapping away and urged me to come back to bed.  I hear this, but this is something that I ( and I suspect many others ) simply cannot do.  If I were to come back to bed I would imagine my text editor.  If I were to go do something else I would be irked that I couldn&#8217;t look up on Google possible solutions as I was doing it.</p>

<p>I don&#8217;t know it well enough.  I don&#8217;t understand it well enough, I don&#8217;t <em>see</em> how the parts work.  Granted this quality among the full rank of attendees, you can see how I would suggest that a startup out of any one of these classes could blow the doors off of any particular problem.[2]</p>

<p>So it&#8217;s under this background mentality that you&#8217;ll see BNR-class attendees whipping themselves to perform, to create, and realize until deep into the night.  Simply put, this is just how we&#8217;re wired.</p>

<p>Attendees like to maximize effort.  That&#8217;s why we&#8217;re programmers, we like the force multiplier effect of knowing a programming tool.  The reason we&#8217;re at this class is because we want help learning something very difficult in the most efficient and deep manner possible.  BNR classes deliver this.  So much of the work done here can be seen in light of trying to optimize knowledge gained per unit time.</p>

<p>Most of us have attempted to learn the material back in &#8220;the real world&#8221;, but we couldn&#8217;t get the information to &#8216;etch&#8217; deeply enough.  Learning this material against deadlines, users, wives, taxes, other obligations was simply too slow or too confusing.  If you are a &#8220;can&#8217;t let it go&#8221; person who knows that shortly he&#8217;ll have to be back in the real world where he&#8217;ll <strong>have to let it go</strong> and you won&#8217;t have access to immediate peer feedback or a guru, <strong>you work hard</strong>.</p>

<p>Like summer camp, we come, we know it will be hard, but we know, looking back, we&#8217;ll be amazed by how much we learned, how much we changed, and we&#8217;ll remember the conversations, the food, the hard nights.  We&#8217;ll remember that we were part of a special community for a brief flicker of time.</p>

<p>And if, to chase to that next <em>eureka</em>, we have to have bleary eyes and catnaps in the conference room, so be it.  Damn the torpedoes, I came to learn rails.</p>

<p>So we slurp down cups of rocket fuel, we dose up on small quick munchies, we talk, we think, we code, we edit, we close our eyes and doze and then turn back to it, we take more fuel[3].  At the end of a multi-hour run  your sugar crash comes but you have to keep pushing.  And sure, you could go back to your bedroom, but the feedback loop outside of Oz is too slow.   You see, we have to be good enough to be independent when we leave because, it all likelihood, we will be.</p>

<p>So what&#8217;s it like, in the dark of night as we ply away?  Well, to set the scene, we&#8217;re in a very large conference room with a large projection screen hanging from the front wall.  The churn of the heating provides a constant white noise that is overlain with  collective symphony of keyboard tapping[4] and occasional double-click.</p>

<p>For the most part it&#8217;s fairly quiet, except that there are &#8216;flexible duos&#8217; merging and separating.  These duos emerge when one party wants to discuss an idea or a problem he is describing to the other party.  They conversation is usually pretty quiet, but occasionally precipitates a whiteboard session.</p>

<p>The lighting is dim, but not dark.  The eyes of the coders in troglodyte mode is respected.</p>

<p>And, of course the half audible curse of &#8216;fuck&#8217; or &#8216;damn&#8217; as an execution fails, or even worse, does something you didn&#8217;t know about and or didn&#8217;t plan for.</p>

<p>The tablecloths that drape the tables are rumpled.  There are big reference books from O&#8217;Reilly press and the Pragmatic Programmers stacked up, splayed open, or fallen onto the floor.</p>

<p><a href="http://www.flickr.com/photos/sgharms/407741862/" title="Photo Sharing"><img src="http://farm1.static.flickr.com/151/407741862_4c392230f9_o.jpg" width="640" height="480" alt="IMG_7286.JPG" /></a></p>

<p>With the dim lighting and the lack of a clock in the room, Vegas-style, you could easily fall through scheduled reality and forget that time is actually passing.  Eventually, the time will turn late and that&#8217;s when the real fatigue sets in.</p>

<p>There are enough peers present such that your quorum sensing lets you know &#8220;It&#8217;s OK to stay a bit longer&#8221;.  Your eyes are dried out from staring at the screen, the typing fingers are sore and tired.  The myriad of files you edit get lost, your new enemies are questions like &#8220;Where did I just write that thing a second ago?&#8221;</p>

<p>You reach the next item on your &#8220;to do&#8221; list and you attack that problem&#8230;and keep on going.  In some ways it&#8217;s actually invigorating, working on something you care about this much, something that has this much of your love in it.  Few things &#8220;outside&#8221; can hold your interest like this.  In some ways, you feel more alive doing this kind of work in this environment that you may have felt at your day job for the last year.</p>

<p>Eventually the discussions between students achieves a sort of level of conversational shorthand.  We&#8217;ve all been speaking to one another in these highly specialized terms for days and days.  We&#8217;re all coming from the same reference and our discussions are short, brief, and truncated.</p>

<p>As the evening wears down more stammers work their way into the dialog.  The solutions wear down.  The bowl full of ice chips melts and the bottles, coffee mugs, and cans on the desk continue to multiply as the diminishing returns on coffee and sugar is reached, crossed, and run over by a distance of several miles.</p>

<p><a href="http://www.flickr.com/photos/sgharms/407741862/" title="Photo Sharing"><img src="http://farm1.static.flickr.com/151/407741862_4c392230f9_o.jpg" width="640" height="480" alt="IMG_7286.JPG" /></a></p>

<p>But eventually you reach your goal and you shuffle back to your hotel room and unwind by watching infomericals or NOVA and then drift off to sleep.</p>

<p>This is the society of the hack, and you&#8217;ve done a good day&#8217;s work.  Sleep is quick and hurried, because the next round of class starts bright and early at nine in the morning.</p>

<h1>Footnotes:</h1>

<ol>
<li><p>Incidentally, the Silicon Valley exacerbates this problem.  Most people can&#8217;t let it go, and there&#8217;s not much else to do besides work anyway, thus so many good ideas and good companies coming from that area.</p></li>
<li><p>This is what the early internet adopters must have thought would happen.  Global, flexible, talented groups meeting and fluxing, producing brilliance.  Regrettably, it seems that this talent needs to be pulled out of their quotidian affairs to achieve this maximal &#8220;group flow&#8221; dynamic ( see:  <a href="http://cocoadevhouse.org">Cocoa Dev House</a> or <a href="http://www.burningman.com/">Burning Man</a> )</p></li>
<li><p>I recall a passage in <a href="http://en.wikipedia.org/wiki/The_Fountainhead">The Fountainhead</a> where Roark falls asleep at his drafting table and breaks a pot of coffee.  I recall <a href="http://en.wikipedia.org/wiki/Ender_Wiggin">Ender Wiggin</a> facing yet another round in the battle room after another brilliant performance around the absurd rules.  In these passages I always see the author <em>comme createur</em> writing his experiences into the character&#8217;s life.</p></li>
<li><p>Not really tapping.  Apple laptops don&#8217;t have a cheap, plastic, clackity sound, like the PCs, but rather have a very pleasing whisper.</p></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://stevengharms.com/big-nerd-ranch-ror-camp-day-3-evening-the-fatigue/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Big Nerd Ranch: RoR Camp: Day 3:  Evening: &#8220;The Grinder&#8221;</title>
		<link>http://stevengharms.com/big-nerd-ranch-ror-camp-day-3-evening-the-grinder</link>
		<comments>http://stevengharms.com/big-nerd-ranch-ror-camp-day-3-evening-the-grinder#comments</comments>
		<pubDate>Thu, 15 Feb 2007 04:34:23 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[bignerdranch]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology and Computers]]></category>

		<guid isPermaLink="false">http://stevengharms.net/?p=837</guid>
		<description><![CDATA[Hi all, After the lengthy tour of duty yesterday, I&#8217;m back in for another lengthy day. I think that Wednesday is really the grinder day. First, you&#8217;ve been lectured to for the last 3 days. There are very few minds that can take 8hr. / day lectures without feeling a bit tapioca-ish on the 24th [...]]]></description>
			<content:encoded><![CDATA[<p>Hi all,</p>

<p>After the lengthy tour of duty yesterday, I&#8217;m back in for another lengthy day.  I think that Wednesday is really the grinder day.</p>

<p>First, you&#8217;ve been lectured to for the last 3 days.  There are very few minds that can take 8hr. / day lectures without feeling a bit tapioca-ish on the 24th hour.</p>

<p>Secondly, you&#8217;re listening and then working very hard on something that you just were introduced to.  You have these head bashing against a wall sessions and then, suddenly, you&#8217;re set free ( because you&#8217;re doing something that&#8217;s old hat, something you learned, say, that morning ) and then you hit the wall with all that built-up acceleration.  It takes a certain mental flexibility.</p>

<p>Third, the sugar, the munchies, the food, etc.  By this time it&#8217;s all having some funky effects on your body.</p>

<p>Homesickness becomes a bit of a factor.  You remember how good your bed is, how nice it is to be among your things and your life.</p>

<p>Now, about the work.  You see, you can slide on day 1.  You learn the material, you review it, you&#8217;re probably OK.  <strong>DON&#8217;T BE FOOLED</strong> this is your one and only chance to get ahead of the abbatoir days 2 and 3.</p>

<p>Then comes day 2.  If you want to keep ahead you&#8217;ll be working late on day 2, maybe even thinking that you&#8217;re going to catch a break on day 3.  But no, my friends, day 3 is the grinder.  Day 3 says &#8220;OK, you&#8217;re determined, but <em>how</em> determined are you?&#8221;  You&#8217;re bleary from day 2, the cokes, the mountain of water bottles, can you do <em>another</em> 18-hour run at things?</p>

<p>At day 4 you&#8217;re going to be exhausted.  You&#8217;re going to reach your limit.  You start to feel like your treading water capability is turning into negative progress.  Unless you&#8217;ve stayed up on the exercises and mentally integrated the concept and become with the &#8216;way things are done in this language&#8217;, you&#8217;re going to feel a bit behind.</p>

<p>Fortunately day 5 is the wind-up day.  There&#8217;s a sense of graduation and possibility.  If you can integrate the first 3 days quickly you&#8217;re going to be in a good position to re-discover the last two days quickly.  I think that may be the optimal take-away from a class like this.</p>

<p>I&#8217;m not sure, I&#8217;ll be a good empirical guinea pig for the next few months.</p>
]]></content:encoded>
			<wfw:commentRss>http://stevengharms.com/big-nerd-ranch-ror-camp-day-3-evening-the-grinder/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Big Nerd Ranch: RoR Camp: Day 3</title>
		<link>http://stevengharms.com/big-nerd-ranch-ror-camp-day-3</link>
		<comments>http://stevengharms.com/big-nerd-ranch-ror-camp-day-3#comments</comments>
		<pubDate>Wed, 14 Feb 2007 15:43:39 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[bignerdranch]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology and Computers]]></category>
		<category><![CDATA[Travelogue]]></category>

		<guid isPermaLink="false">http://stevengharms.net/?p=835</guid>
		<description><![CDATA[Goodmorning. I had a late morning this morning &#8230; because I had a late night last night. Last night, per BNR tradition ( and I can say this because of me experiences at the Cocoa camp ), post dinner ( and occasionally a drink or two ) many of the students returned to the classroom [...]]]></description>
			<content:encoded><![CDATA[<p>Goodmorning.</p>

<p>I had a late morning this morning &#8230; because I had a late night last night.</p>

<p>Last night, per BNR tradition ( and I can say this because of me experiences at the Cocoa camp ), post dinner ( and occasionally a drink or two ) many of the students returned to the classroom to review, invent, create, etc. under the tutelage of our teacher.</p>

<p>I basically re-ran all the exercises from Day 2 again, inventing scenarios to make sure that I truly &#8220;got it&#8221;.  In training, it&#8217;s <strong>very</strong> easy to simply nod and do the exercise but, as my math teacher says, when you are working the problem alone, you will get <em>the loneliness</em>.  You will say, &#8220;Where is my teacher?  Where is the format, I&#8217;m so lonely, I cannot solve this problem.&#8221;</p>

<p>So, to make sure that I could work through <em>the loneliness</em> me and a few other students were here until about 1:30&#8230;<em>and I wasn&#8217;t the last to leave</em>!  We Big Nerds be hard<a href="javascript:alert('HARD TO THA CORE!')" style="text-decoration: none">^</a>core.</p>

<p>I moseyed into class about 5 minutes behind and Charles had already begun the lecture on &#8220;Data Validation&#8221;.  It&#8217;s a pretty gentle way of starting the morning.</p>

<p>Outside, Georgia has tuned cold and windy, a lot like the Bay actually.</p>

<p>This morning we did a lesson data validation and man, I hit a tough bug.  Rails was telling that the error was at some line in some process.  With the help of another patient peer we commented out all the lines of my code and methodically worked through and found out that the error message was completely un-helpful, the error was some 6 lines earlier!</p>

<p>BNR classes always leave me with the feeling that working should be more like this: patient people focused on exploration and the delivery of solid products with understanding produced as a natural side-effect (oh yeah, and having an absolute guru around to ask questions to is not a bad part either).  I&#8217;m pretty sure you could take any BNR class, tell them to attack some market problem, and they would be able to deliver it as a successful startup.</p>

<p>Consider the self-selection principle at play.  People pay ( or are in positions where employers are willing to pay ) what, on paper, might seem like a rather steep fee ( in reality, it&#8217;s entirely reasonable for the type, depth, and knowledge provided ), this indicates a certain level of success obtained in the world.  Further, even people of that level of success are usually rather loath to take one-fifty-second of their life and spend it doing &#8220;work&#8221; for <em>at least</em> 9 hours a day.  <a href="http://www.paulgraham.com/start.html">Paul Graham said</a> that the magic of a startup wasn&#8217;t that it was a small amount of people, it was a small amount of people <strong>like you</strong>.  During these sessions you feel like you&#8217;re part of a larger community of people <strong>like you</strong>.</p>

<p>For 5 days people like you, focused on learning, learn, work and talk together.  It&#8217;s kinda special.  Sorta like camp, but instead of popsicle stick birdhouses you build powerful computer applications.  If, in 5 days, we could do something like this, in 90 days what sort of application could we build?</p>
]]></content:encoded>
			<wfw:commentRss>http://stevengharms.com/big-nerd-ranch-ror-camp-day-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programmers: Are you good in math?</title>
		<link>http://stevengharms.com/programmers-are-you-good-in-math</link>
		<comments>http://stevengharms.com/programmers-are-you-good-in-math#comments</comments>
		<pubDate>Thu, 01 Feb 2007 19:31:27 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Culture]]></category>
		<category><![CDATA[Education]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://stevengharms.net/?p=811</guid>
		<description><![CDATA[The Leauge sent in an email to see if I had fallen off the edge of the world. Although it appears irony has fallen upon The League, for as I type this, his web site has, in fact, fallen off the edge of the world: Blogger appears to be down. I have not left the [...]]]></description>
			<content:encoded><![CDATA[<p>The Leauge sent in an email to see if I had fallen off the edge of the world.  Although it appears irony has fallen upon The League, for as I type this, his web site has, in fact, fallen off the edge of the world: Blogger appears to be down.</p>

<p>I have not left the gravitational field of this big, blue, glob. There&#8217;s a bunch of interesting work stuff going on ( more later ), my mom was in town and I started classes at <a href="http://www.austincc.edu">Austin Community College</a>.</p>

<p>I&#8217;m taking two classes:  Intermediate Algebra and C++.</p>

<p>First, this is the kind of mathematics I learned in high school ( or should have learned better ).  I eventually matriculated to the university and there went as far as 2 semesters of business calculus: integration, derivation, the whole shebang.  But, after ten ( and I am astounded to type that ) years away from calculus, I&#8217;ve forgotten so much.  So, here I am, back at square one, learning the basics <em>again</em>.  It&#8217;s easy to forget a lot because, to answer those kids in high school who asked &#8220;when am I going to use this in the real world&#8221; the answer, I&#8217;m afraid to say, is rarely.  So much, that, you&#8217;re right, you might be wasting your time.  Sorry.</p>

<p>In any case, this time through I&#8217;m finding it much easier to learn and encode this information.  I&#8217;ve thought about why, but I think that my brain must have been conditioned for understanding symbolic and abstract systems through years of programming and a bit of symbolic logic.  As is suggested by the action of <strong>Snow Crash</strong>, I think that the brain arrives with just a tiny bit of software pre-installed.  The first several routines (&#8220;primary routines&#8221;) decide whether or not you will be more or less receptive to new (&#8220;secondary&#8221;) routines.</p>

<p>The primary routines must be incredibly fundamental.  Do you use symbolic language, pictorgrams, pictographs?  Using pictographs may <strong>disincline</strong> a learner from picking up a certain set of secondary routines ( I don&#8217;t believe anything is un-learnable, although research shows that past the age of 7 there&#8217;s no chance for language acquisition if it hasn&#8217;t already happened, sorry Tarzan).</p>

<p>So this secondary routine, algebra, just didn&#8217;t stick for me.  But I think that I&#8217;ve been running secondary programs of an abstracting and variant nature now for so many years that receiving new routines which share similar pathways as other abstracting secondary routines&#8217; function has made it easier to integrate the data.</p>

<p>Or, maybe because my teacher is exceedingly competent.  Gustavo Cepparo is one of the best lecturers I&#8217;ve had at any school I&#8217;ve ever attended.  He does not advocate &#8220;niceness&#8221; he educates giving you an education (although he is very personable).  He sees himself as your worthy adversary, trying your skills and, in so doing, giving you an education.  Damn straight.</p>

<p>I was discussing this &#8220;inclination for symbolic systems&#8221; with Lauren who, in her own life, is also undertaking an effort to put some &#8216;new secondary routine momentum&#8217; into her gray matter.  She&#8217;s learning computer science and programming.  Oddly, when she programs she feels the same structure and scalpel that she came to know doing her literature work: themes, repetition, motifs, it&#8217;s all there.</p>

<p>But then we came to a question:  Why is it, if you want to go into programming, pedestrian ( or parental ) wisdom holds:  &#8220;Are you good at math.&#8221;</p>

<p>This, parents, friends, teachers, I want to warn you away from asking.  The question is <strong>not</strong> &#8220;are you good at math&#8221; but do you like symbolic systems, creating them, imagining them, adhering and bending them?  That&#8217;s the question.</p>

<p>Good programmers are kids who memorize the armor charts to Dungeons and Dragons.  Good programmers like to corollate data on baseball cards, they like to organize baseball cards.  I&#8217;ve seen kids read chess books, or play Magic or play Yu-Gi-Oh, know the Dewy Decimal system, it&#8217;s all the same thing: breathing life into internal rules processing machines in your brain, and then using physical ( versus digital ) objects as the inputs to your automata.</p>

<p>So why do kids get asked &#8220;but are you good at math&#8221;.</p>

<p>Math is a convenient, albeit misleading, question, it&#8217;s a forced symbolic system that kids are forced to learn.  To this extent, it <em>can</em> be used as a good measure of &#8220;will you be a good programmer&#8221;.  Further, and a child has no way of knowing this, this <strong>lazy</strong> question implies that &#8220;liking math&#8221; and &#8220;liking the pedagogical approach used by the school board and as practiced by your teacher&#8221; are the same.  They are wholly different and a child has no way of knowing this.</p>

<p>I disliked most of my math teachers, and the pedagogy was slow, pedantic, too slow to build connections, to sketch an architecture, to paint a direction.  Math class, for me, was about exercises and who in their right mind gives a flip about that?  I knew math was important, but there was no direction or structure for that statement beyond the obscure &#8220;but you&#8217;ll need it in college&#8221;.</p>

<p>Here&#8217;s how I now propose that math should be explained.</p>

<ul>
<li>There are many difficult problems in the world ( how to get a satellite in a crater on the moon), how long to incubate a new medicine, etc.</li>
<li>The language for expressing these ideas is mathematics.  Just as anyone would look at this figure ( draw a capital &#8216;A&#8217; ) without knowing the alphabet would suppose it&#8217;s a picture of a bird or an interesting shape, you must come to learn the basic letters and words of mathematics</li>
<li>For the next several years, you will be learning basic ideas and words in mathematics, this study is called arithmetic.</li>
<li>(later) You have learned arithmetic, but most questions in life do not hinge upon known quantities.  Like we said in point 1, how do we do something that we don&#8217;t know, how do we model and predict?  The branch of mathematics which deals with discovering unknown players in systems is called algebra</li>
<li>(later) You have learned algebra.  Algebra helps discover nouns in systems (what plus 4 equals 11), but the world is a constant state of flux, as noted by Newton.  A mathematical language for discussing flux and rates of change was invented by him and Leibniz, that is called <strong>the calculus</strong>.</li>
</ul>

<p>I don&#8217;t know much more about math than that, but with that framework I could have seen that learning that 3/4 * 4/3 = 1 was something important in the sense that it was as fundamental as learning the crucial verbs to express want or need or identity.</p>

<p>And that, balance, unknown, systems for discovery of unknown, systems for modeling the unknown is incredibly interesting.  Had mathematics pedagogy been about systems of symbolic manipulation to discern the unknown versus timed tests and a litany of rules and obscure little &#8220;tricks&#8221;: loose islands of thought, I feel I would have grasped the beauty of math earlier.</p>

<p>And ultimately this brings me back to the most sublime poem ever written &#8220;Ode on a Grecian Urn&#8221;</p>

<blockquote>
  <p>Than ours, a friend to man, to whom thou say&#8217;st,
  &#8220;Beauty is truth, truth beauty&#8221;&#8212;-that is all
  Ye know on earth, and all ye need to know.</p>
</blockquote>

<p>Algerbra, comes from the original Arabic book in which its tenets were first set: <em>Science of the Reunion and the Opposition</em>.</p>

<p>Isn&#8217;t that a beautiful phrasing for what algebra allows us to do?  This is truth and this is beauty.</p>

<p>And hoary old double-entry accounting, it is a science of reuniting the not with the present, the received with the owed.  That is truth, and <strong>that</strong>, to my good accountant friends, is beauty too.  I can see why those who ply this craft love it.</p>

<p>And programming, it is the balancing of the abstract concepts against the abstract concepts.  In this vacuum, you create, and you create function, and then you create beauty.  And that&#8217;s why we love it.</p>

<p>And assuredly, if you choose to plumb the deepest depths of that digital reality, you will do a lot of math, but don&#8217;t scare off a child from playing in our world of pure abstraction because they mistakenly associate it with the pitiful educational quality in this country or rote, staid, pedagogy.</p>


<hr />


<p>**I&#8217;m posting this, but I feel it&#8217;s incomplete, I think I need to read it some more and refine it, so, this content may update. **</p>
]]></content:encoded>
			<wfw:commentRss>http://stevengharms.com/programmers-are-you-good-in-math/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>I love ancient software that&#8217;s artistic sensible and impeccably well designed</title>
		<link>http://stevengharms.com/i-love-ancient-software-thats-artistic-sensible-and-impeccably-well-designed</link>
		<comments>http://stevengharms.com/i-love-ancient-software-thats-artistic-sensible-and-impeccably-well-designed#comments</comments>
		<pubDate>Sun, 05 Jun 2005 00:10:47 +0000</pubDate>
		<dc:creator>steven</dc:creator>
				<category><![CDATA[Culture]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Technology and Computers]]></category>

		<guid isPermaLink="false">http://stevengharms.net/?p=466</guid>
		<description><![CDATA[There have been a number of people who have refused to upgrade - like they got the best of whatever it was and refused to get more. There&#8217;s a cult of people who refused to leave MS Office 5.1. It was small, effective, perfect, light. Not many people could say that about Office anymore. Those [...]]]></description>
			<content:encoded><![CDATA[<p>There have been a number of people who have refused to upgrade - like they got the best of whatever it was and refused to get more.  There&#8217;s a cult of people who refused to leave MS Office 5.1.  It was small, effective, perfect, light.  Not many people could say that about Office anymore.  Those who refuse to upgrade are called &#8220;refuseniks&#8221;.</p>

<p>A similar cult: <a href="http://www.sfwriter.com/wordstar.htm">WordStar</a></p>
]]></content:encoded>
			<wfw:commentRss>http://stevengharms.com/i-love-ancient-software-thats-artistic-sensible-and-impeccably-well-designed/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

