<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title><![CDATA[Eric Florenzano's Blog]]></title>
    <link href="http://eflorenzano.com/atom.xml" rel="self"/>
    <link href="http://eflorenzano.com/"/>
    <updated>2013-04-22T08:51:02.763713</updated>
    <id>http://eflorenzano.com/</id>
    <author>
        <name><![CDATA[Eric Florenzano]]></name>
    </author>
    <generator uri="https://github.com/ericflo/simpleblog">simpleblog</generator>
    
    <entry>
        <title type="html"><![CDATA[Using Twitter&#39;s iOS5 Integration for Single Sign-On]]></title>
        <link href="http://eflorenzano.com/blog/2012/04/18/using-twitter-ios5-integration-single-sign-on/"/>
        <updated>2012-04-18T22:34:47</updated>
        <id>http://eflorenzano.com/blog/2012/04/18/using-twitter-ios5-integration-single-sign-on/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2012/04/18/using-twitter-ios5-integration-single-sign-on/">Using Twitter&#39;s iOS5 Integration for Single Sign-On</a></h3>
<p class="datetime">Apr 18, 2012</p>
<div class="document">
<p>Apple has included integration with Twitter in iOS5, which can be really handy to allow your users to easily tweet or log in. The only problem is that, as far as documentation of this feature is concerned, you're largely on your own. This blog post is an attempt to correct that, at least in the case of sign-on.</p>
<div class="section" id="add-the-twitter-and-accounts-libraries-to-your-project">
<h4>Add the Twitter and Accounts libraries to your project</h4>
<p>Click on your project file, and then on your build target. Make sure you're on the &quot;build phases&quot; tab. Under the &quot;Link Binary With Libraries&quot; section, click the plus symbol to the bottom left, and search for <tt class="docutils literal">Accounts.framework</tt> and add it. Then do the same for <tt class="docutils literal">Twitter.framework</tt>. This will link all of the necessary libraries into your project so that we can use the Twitter integration.</p>
</div>
<div class="section" id="requesting-access-to-a-user-s-twitter-account">
<h4>Requesting access to a user's twitter account</h4>
<p>The first thing to do when you want to let a user sign-on with Twitter is to create a long-lived (save it as an instance variable, for example) instance of ACAccountStore and request access to the Twitter accounts contained within:</p>
<pre class="code objc literal-block">
<span class="n">ACAccountStore</span> <span class="o">*</span><span class="n">store</span> <span class="o">=</span> <span class="p">[[</span><span class="n">ACAccountStore</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span> <span class="c1">// Long-lived
</span><span class="n">ACAccountType</span> <span class="o">*</span><span class="n">twitterType</span> <span class="o">=</span> <span class="p">[</span><span class="n">store</span> <span class="nl">accountTypeWithAccountTypeIdentifier:</span><span class="n">ACAccountTypeIdentifierTwitter</span><span class="p">];</span>
<span class="p">[</span><span class="n">store</span> <span class="nl">requestAccessToAccountsWithType:</span><span class="n">twitterType</span> <span class="nl">withCompletionHandler:</span><span class="o">^</span><span class="p">(</span><span class="kt">BOOL</span> <span class="n">granted</span><span class="p">,</span> <span class="n">NSError</span> <span class="o">*</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span><span class="p">(</span><span class="n">granted</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Access has been granted, now we can access the accounts
</span>    <span class="p">}</span>
    <span class="c1">// Handle any error state here as you wish
</span><span class="p">}];</span>
</pre>
<p>What do we do once we have access to the accounts? Well, we get a list of 'em. If they don't have any accounts, then we can show a dialog asking them to connect one in the iOS settings app:</p>
<pre class="code objc literal-block">
<span class="c1">// Remember that twitterType was instantiated above
</span><span class="n">NSArray</span> <span class="o">*</span><span class="n">twitterAccounts</span> <span class="o">=</span> <span class="p">[</span><span class="n">store</span> <span class="nl">accountsWithType:</span><span class="n">twitterType</span><span class="p">];</span>

<span class="c1">// If there are no accounts, we need to pop up an alert
</span><span class="k">if</span><span class="p">(</span><span class="n">twitterAccounts</span> <span class="o">!=</span> <span class="nb">nil</span> <span class="o">&amp;&amp;</span> <span class="p">[</span><span class="n">twitterAccounts</span> <span class="n">count</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">UIAlertView</span> <span class="o">*</span><span class="n">alert</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UIAlertView</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithTitle:</span><span class="s">&#64;&quot;No Twitter Accounts&quot;</span>
                                                    <span class="nl">message:</span><span class="s">&#64;&quot;There are no Twitter accounts configured. You can add or create a Twitter account in Settings.&quot;</span>
                                                   <span class="nl">delegate:</span><span class="nb">nil</span>
                                          <span class="nl">cancelButtonTitle:</span><span class="s">&#64;&quot;OK&quot;</span>
                                          <span class="nl">otherButtonTitles:</span><span class="nb">nil</span><span class="p">];</span>
    <span class="p">[</span><span class="n">alert</span> <span class="n">show</span><span class="p">];</span>
    <span class="p">[</span><span class="n">alert</span> <span class="n">release</span><span class="p">];</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="n">ACAccount</span> <span class="o">*</span><span class="n">account</span> <span class="o">=</span> <span class="p">[</span><span class="n">twitterAccounts</span> <span class="nl">objectAtIndex:</span><span class="mi">0</span><span class="p">];</span>
    <span class="c1">// Do something with their Twitter account
</span><span class="p">}</span>
</pre>
</div>
<div class="section" id="now-what">
<h4>Now what?</h4>
<p>Well, now you have an access token to read some information about the user from their Twitter stream. The vast majority of apps will just want to grab the user's basic info to get things like a username, real name, and maybe their location. Here's how that would look:</p>
<pre class="code objc literal-block">
<span class="n">NSURL</span> <span class="o">*</span><span class="n">url</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSURL</span> <span class="nl">URLWithString:</span><span class="s">&#64;&quot;http://api.twitter.com/1/account/verify_credentials.json&quot;</span><span class="p">];</span>
<span class="n">TWRequest</span> <span class="o">*</span><span class="n">req</span> <span class="o">=</span> <span class="p">[[</span><span class="n">TWRequest</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithURL:</span><span class="n">url</span>
                                     <span class="nl">parameters:</span><span class="nb">nil</span>
                                  <span class="nl">requestMethod:</span><span class="n">TWRequestMethodGET</span><span class="p">];</span>

<span class="c1">// Important: attach the user's Twitter ACAccount object to the request
</span><span class="n">req</span><span class="p">.</span><span class="n">account</span> <span class="o">=</span> <span class="n">account</span><span class="p">;</span>

<span class="p">[</span><span class="n">req</span> <span class="nl">performRequestWithHandler:</span><span class="o">^</span><span class="p">(</span><span class="n">NSData</span> <span class="o">*</span><span class="n">responseData</span><span class="p">,</span>
                                 <span class="n">NSHTTPURLResponse</span> <span class="o">*</span><span class="n">urlResponse</span><span class="p">,</span>
                                 <span class="n">NSError</span> <span class="o">*</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>

    <span class="c1">// If there was an error making the request, display a message to the user
</span>    <span class="k">if</span><span class="p">(</span><span class="n">error</span> <span class="o">!=</span> <span class="nb">nil</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">UIAlertView</span> <span class="o">*</span><span class="n">alert</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UIAlertView</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithTitle:</span><span class="s">&#64;&quot;Twitter Error&quot;</span>
                                                        <span class="nl">message:</span><span class="s">&#64;&quot;There was an error talking to Twitter. Please try again later.&quot;</span>
                                                       <span class="nl">delegate:</span><span class="nb">nil</span>
                                              <span class="nl">cancelButtonTitle:</span><span class="s">&#64;&quot;OK&quot;</span>
                                              <span class="nl">otherButtonTitles:</span><span class="nb">nil</span><span class="p">];</span>
        <span class="p">[</span><span class="n">alert</span> <span class="n">show</span><span class="p">];</span>
        <span class="p">[</span><span class="n">alert</span> <span class="n">release</span><span class="p">];</span>
        <span class="k">return</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="c1">// Parse the JSON response
</span>    <span class="n">NSError</span> <span class="o">*</span><span class="n">jsonError</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
    <span class="kt">id</span> <span class="n">resp</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSJSONSerialization</span> <span class="nl">JSONObjectWithData:</span><span class="n">responseData</span>
                                                      <span class="nl">options:</span><span class="mi">0</span>
                                                        <span class="nl">error:</span><span class="o">&amp;</span><span class="n">jsonError</span><span class="p">];</span>

    <span class="c1">// If there was an error decoding the JSON, display a message to the user
</span>    <span class="k">if</span><span class="p">(</span><span class="n">jsonError</span> <span class="o">!=</span> <span class="nb">nil</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">UIAlertView</span> <span class="o">*</span><span class="n">alert</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UIAlertView</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithTitle:</span><span class="s">&#64;&quot;Twitter Error&quot;</span>
                                                        <span class="nl">message:</span><span class="s">&#64;&quot;Twitter is not acting properly right now. Please try again later.&quot;</span>
                                                       <span class="nl">delegate:</span><span class="nb">nil</span>
                                              <span class="nl">cancelButtonTitle:</span><span class="s">&#64;&quot;OK&quot;</span>
                                              <span class="nl">otherButtonTitles:</span><span class="nb">nil</span><span class="p">];</span>
        <span class="p">[</span><span class="n">alert</span> <span class="n">show</span><span class="p">];</span>
        <span class="p">[</span><span class="n">alert</span> <span class="n">release</span><span class="p">];</span>
        <span class="k">return</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="n">NSString</span> <span class="o">*</span><span class="n">screenName</span> <span class="o">=</span> <span class="p">[</span><span class="n">resp</span> <span class="nl">objectForKey:</span><span class="s">&#64;&quot;screen_name&quot;</span><span class="p">];</span>
    <span class="n">NSString</span> <span class="o">*</span><span class="n">fullName</span> <span class="o">=</span> <span class="p">[</span><span class="n">resp</span> <span class="nl">objectForKey:</span><span class="s">&#64;&quot;name&quot;</span><span class="p">];</span>
    <span class="n">NSString</span> <span class="o">*</span><span class="n">location</span> <span class="o">=</span> <span class="p">[</span><span class="n">resp</span> <span class="nl">objectForKey:</span><span class="s">&#64;&quot;location&quot;</span><span class="p">];</span>

    <span class="c1">// Make sure to perform our operation back on the main thread
</span>    <span class="n">dispatch_async</span><span class="p">(</span><span class="n">dispatch_get_main_queue</span><span class="p">(),</span> <span class="o">^</span><span class="p">{</span>
        <span class="c1">// Do something with the fetched data
</span>    <span class="p">});</span>
<span class="p">}];</span>
</pre>
<p>Most of the code here is actually error handling code. The meat of what we're doing is simply fetching the user's credentials from Twitter, parsing the JSON, and doing something with it. (What exactly you want to do with the username and name data is left as an excercise for the reader.)</p>
</div>
<div class="section" id="that-s-it">
<h4>That's it?</h4>
<p>Yep, that's it. You should be able to implement Twitter sign-on for your app with the simple code I've shown here. The only bummer is the case when the user doesn't have a Twitter account registered. We're <a class="reference external" href="http://stackoverflow.com/questions/10055853/opening-ios-settings-preferences">not allowed</a> to help the user out by sending them to the Settings app. All we can do is tell users to go there and hope they can figure it out.</p>
<p>Any other tips or tricks you have for implementing sign-on with Twitter on iOS? Be sure to <a class="reference external" href="http://twitter.com/ericflo">tweet me</a> about it!</p>
<p>P.S. If you're building mobile apps, my startup <a class="reference external" href="https://clutch.io/">clutch.io</a> can help you build and iterate faster on them. Check us out :)</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/login/">Login</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/registration/">Registration</a></li>
      
        <li><a href="/blog/categories/sign-on/">Sign-On</a></li>
      
        <li><a href="/blog/categories/twitter/">Twitter</a></li>
      
        <li><a href="/blog/categories/ios/">iOS</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Reducing Code Nesting]]></title>
        <link href="http://eflorenzano.com/blog/2012/01/02/reducing-code-nesting/"/>
        <updated>2012-01-02T02:00:00</updated>
        <id>http://eflorenzano.com/blog/2012/01/02/reducing-code-nesting/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2012/01/02/reducing-code-nesting/">Reducing Code Nesting</a></h3>
<p class="datetime">Jan 02, 2012</p>
<div class="document">
<p>&quot;This guy's code sucks!&quot;  It's something we've all said or thought when we run
into code we don't like.  Sometimes it's because it's buggy, sometimes it's
because it conforms to a style we don't like, and sometimes it's because it
just feels wrong.  Recently I found myself thinking this, and automatically
jumping to the conclusion that the developer who wrote it was a novice.  The
code had a distinct property that I dislike: lots of nesting.  But the more I
think about it, the more I realized that it's not really something I've heard
discussed much.</p>
<p>So let's talk about it.  I'm going to first talk about what I mean by nesting,
why I think it's a bad quality, and then I'm going to go over some tricks I've
learned over the years to reduce it.</p>
<div class="section" id="what-do-i-mean-by-code-nesting-and-why-is-it-bad">
<h4>What do I mean by code nesting, and why is it bad?</h4>
<p>It's easier to demonstrate rather than talk about it.  This is what I mean by
deep code nesting, with my apologies for the contrived example:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">get_cached_user</span><span class="p">(</span><span class="n">user_id</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">username</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;
    Returns a cached user object either by their user_id or by their username.
    &quot;&quot;&quot;</span>
    <span class="n">user</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="p">:</span>
        <span class="n">user</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get_user_by_username</span><span class="p">(</span><span class="n">username</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="p">:</span>
            <span class="n">user</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="p">:</span>
                <span class="n">user</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">get_user_by_username</span><span class="p">(</span><span class="n">username</span><span class="p">)</span>
                <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s">'User not found'</span><span class="p">)</span>
            <span class="n">cache</span><span class="o">.</span><span class="n">set_user</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">username</span><span class="o">=</span><span class="n">user</span><span class="o">.</span><span class="n">username</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">user</span>
</pre>
<p>You can see in this Python code just by looking at the indentation level that
there's lots of nesting.  Before we can determine that the user was not found,
we must pass through four conditionals, and each conditional is nested within
the previous conditional.</p>
<p>I argue that this is bad code.  Every added level of nesting is another piece
of context that your brain has to keep track of.  Each nested block is one you
have to line up by eye to see what conditional it lines up with (even if your
editor helps at this with visuals, it doesn't remove the issue entirely.)  And
this is just a straightforward example where we just return the user at the
end, let's take a look at an example that does something more complicated:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">get_media_details</span><span class="p">(</span><span class="n">media</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;
    Returns a dictionary of extra data about the given media object.
    &quot;&quot;&quot;</span>
    <span class="n">data</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="k">if</span> <span class="n">media</span><span class="o">.</span><span class="n">is_video</span><span class="p">:</span>
        <span class="n">data</span><span class="p">[</span><span class="s">'kind'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'video'</span>
        <span class="k">if</span> <span class="n">media</span><span class="o">.</span><span class="n">is_youtube</span><span class="p">:</span>
            <span class="n">data</span><span class="p">[</span><span class="s">'url'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'http://youtube.com/'</span>
        <span class="k">if</span> <span class="n">media</span><span class="o">.</span><span class="n">is_vimeo</span><span class="p">:</span>
            <span class="n">data</span><span class="p">[</span><span class="s">'vimeo'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">True</span>
            <span class="k">if</span> <span class="n">media</span><span class="o">.</span><span class="n">vimeo_version</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
                <span class="n">data</span><span class="p">[</span><span class="s">'url'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'http://vimeo.com/v2/'</span>
        <span class="k">if</span> <span class="s">'url'</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
            <span class="n">data</span><span class="p">[</span><span class="s">'secure_url'</span><span class="p">]</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s">'url'</span><span class="p">]</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'http:'</span><span class="p">,</span> <span class="s">'https:'</span><span class="p">)</span>
    <span class="k">elif</span> <span class="n">media</span><span class="o">.</span><span class="n">is_audio</span><span class="p">:</span>
        <span class="n">data</span><span class="p">[</span><span class="s">'kind'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'audio'</span>
    <span class="k">elif</span> <span class="n">media</span><span class="o">.</span><span class="n">is_text</span><span class="p">:</span>
        <span class="n">data</span><span class="p">[</span><span class="s">'kind'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'text'</span>
    <span class="k">if</span> <span class="s">'kind'</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
        <span class="n">data</span><span class="p">[</span><span class="s">'kind_verbose'</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s">'video'</span><span class="p">:</span> <span class="s">'Video Stream'</span><span class="p">,</span>
            <span class="s">'audio'</span><span class="p">:</span> <span class="s">'Audio File'</span><span class="p">,</span>
            <span class="s">'text'</span><span class="p">:</span> <span class="s">'Text Content'</span><span class="p">,</span>
        <span class="p">}[</span><span class="n">data</span><span class="p">[</span><span class="s">'kind'</span><span class="p">]]</span>
    <span class="k">return</span> <span class="n">data</span>
</pre>
<p>It was unbelievably hard for me to even write that last example.  It's
obviously contrived and such, but the point is that it's so difficult to
even understand what it's doing.  Unlike the previous example, this doesn't
simply nest and then return; it nests and then un-nests, and then nests again,
and then finally returns.</p>
</div>
<div class="section" id="how-to-avoid-nesting">
<h4>How to Avoid Nesting</h4>
<p>The best way that I've discovered to avoid nesting is to return early.  Caching
is the perfect example of this.  Instead of testing for a cache failure and
fetching from the database inside the conditional, check for cache success and
return that early.</p>
<p>So this code:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">get_cached_user</span><span class="p">(</span><span class="n">user_id</span><span class="p">):</span>
    <span class="n">user</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>
    <span class="c"># The main logic all happens in this nested block</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="p">:</span>
        <span class="n">user</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>
        <span class="n">cache</span><span class="o">.</span><span class="n">set_user_for_id</span><span class="p">(</span><span class="n">user_id</span><span class="p">,</span> <span class="n">user</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">user</span>
</pre>
<p>Becomes this:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">get_cached_user</span><span class="p">(</span><span class="n">user_id</span><span class="p">):</span>
    <span class="n">user</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">user</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">user</span>
    <span class="c"># The main logic happens outside of the nested block</span>
    <span class="n">user</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>
    <span class="n">cache</span><span class="o">.</span><span class="n">set_user_for_id</span><span class="p">(</span><span class="n">user_id</span><span class="p">,</span> <span class="n">user</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">user</span>
</pre>
<p>In the simple case, it doesn't seem to improve much, but what happens if we
apply this technique to our first example?  It's dramatically improved:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">get_cached_user</span><span class="p">(</span><span class="n">user_id</span><span class="p">,</span> <span class="n">username</span><span class="p">):</span>
    <span class="c"># First check the cache by id</span>
    <span class="n">user</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">user</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">user</span>

    <span class="c"># Now check the cache by username</span>
    <span class="n">user</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get_user_by_username</span><span class="p">(</span><span class="n">username</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">user</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">user</span>

    <span class="c"># Both caches failed, so try hitting the db for the id</span>
    <span class="n">user</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">user</span><span class="p">:</span>
        <span class="n">cache</span><span class="o">.</span><span class="n">set_user</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">username</span><span class="o">=</span><span class="n">user</span><span class="o">.</span><span class="n">username</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">user</span>

    <span class="c"># Looks like that didn't exist, try the username</span>
    <span class="n">user</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">get_user_by_username</span><span class="p">(</span><span class="n">username</span><span class="p">)</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s">'User not found'</span><span class="p">)</span>

    <span class="c"># Cache our final user value for future use</span>
    <span class="n">cache</span><span class="o">.</span><span class="n">set_user</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">username</span><span class="o">=</span><span class="n">user</span><span class="o">.</span><span class="n">username</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">user</span>
</pre>
<p>Not only does it make it easier to read top-to-bottom, and force us to keep
track of way less context, and make our code editors do less line wrapping,
but it also makes it easier to separate the blocks of code and more easily
comment them.</p>
<p>So what other techniques can we use?  It starts to depend more on the
situation.  Are you nesting because you're writing a bunch of callbacks?  If
so, you can usually restructure your code to use named functions instead of
anonymous functions.  Here's how that would might look before refactoring:</p>
<pre class="code javascript literal-block">
<span class="kd">function</span> <span class="nx">getCachedUser</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">cache</span><span class="p">.</span><span class="nx">getUser</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">user</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span><span class="p">(</span><span class="nx">user</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">callback</span><span class="p">(</span><span class="nx">user</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="nx">db</span><span class="p">.</span><span class="nx">getUser</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">user</span><span class="p">)</span> <span class="p">{</span>
            <span class="nx">cache</span><span class="p">.</span><span class="nx">setUser</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="nx">user</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">callback</span><span class="p">(</span><span class="nx">user</span><span class="p">);</span>
            <span class="p">});</span>
        <span class="p">});</span>
    <span class="p">});</span>
<span class="p">}</span>
</pre>
<p>Note that in this example we even applied the technique of returning early in
the first callback function, but as you can see there's still a bunch of
nesting going on.  Now if we switch to using named functions?</p>
<pre class="code javascript literal-block">
<span class="kd">function</span> <span class="nx">curry</span><span class="p">(</span><span class="nx">fn</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">slice</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">slice</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
    <span class="k">return</span> <span class="kd">function</span> <span class="p">(</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">fn</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nx">args</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span><span class="nx">slice</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">arguments</span><span class="p">)));</span>
    <span class="p">};</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="kr">final</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">user</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">callback</span><span class="p">(</span><span class="nx">user</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">dbResult</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">userId</span><span class="p">,</span> <span class="nx">user</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">cache</span><span class="p">.</span><span class="nx">setUser</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="nx">user</span><span class="p">,</span> <span class="nx">curry</span><span class="p">(</span><span class="kr">final</span><span class="p">,</span> <span class="nx">callback</span><span class="p">,</span> <span class="nx">user</span><span class="p">));</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">cacheResult</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">userId</span><span class="p">,</span> <span class="nx">user</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span><span class="p">(</span><span class="nx">user</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">callback</span><span class="p">(</span><span class="nx">user</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="nx">db</span><span class="p">.</span><span class="nx">getUser</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="nx">curry</span><span class="p">(</span><span class="nx">dbResult</span><span class="p">,</span> <span class="nx">callback</span><span class="p">,</span> <span class="nx">userId</span><span class="p">));</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">getCachedUser</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">cache</span><span class="p">.</span><span class="nx">getUser</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="nx">curry</span><span class="p">(</span><span class="nx">cacheResult</span><span class="p">,</span> <span class="nx">callback</span><span class="p">,</span> <span class="nx">userId</span><span class="p">));</span>
<span class="p">}</span>
</pre>
<p>This is a lot better in terms of nesting.  Unfortunately we had to write a
helper function called curry, but that only has to be written once and can be
re-used for all code written in this style.  Also unfortunately I still find
this kind of code difficult to follow, which is why I avoid writing much
callback-style code.  However, at least you can reduce the nesting.  In all
honesty, there are probably better ways of reducing nesting that I'm not aware
of.  If you can rewrite the <tt class="docutils literal">getCachedUser</tt> function in JS in a better way,
please blog it!</p>
<p>Another way to reduce nesting is to assign an intermediate variable.  Here's
an example in Erlang of some file function that nests a case statement within
another case statement.</p>
<pre class="code erlang literal-block">
<span class="nf">do_some_file_thing</span><span class="p">(</span><span class="nv">File</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="k">case</span> <span class="nn">file</span><span class="p">:</span><span class="n">open</span><span class="p">(</span><span class="nv">File</span><span class="p">,</span> <span class="p">[</span><span class="n">raw</span><span class="p">,</span> <span class="n">binary</span><span class="p">,</span> <span class="n">read</span><span class="p">])</span> <span class="k">of</span>
        <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">Fd</span><span class="p">}</span> <span class="o">-&gt;</span>
            <span class="nv">Start</span> <span class="o">=</span> <span class="n">now</span><span class="p">(),</span>
            <span class="k">case</span> <span class="n">process_file_data</span><span class="p">(</span><span class="nv">Fd</span><span class="p">)</span> <span class="k">of</span>
                <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">Processed</span><span class="p">}</span> <span class="o">-&gt;</span>
                    <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">Start</span><span class="p">,</span> <span class="n">now</span><span class="p">(),</span> <span class="nv">Processed</span><span class="p">};</span>
                <span class="nv">Error</span> <span class="o">-&gt;</span>
                    <span class="nv">Error</span>
            <span class="k">end</span><span class="p">;</span>
        <span class="nv">Error</span> <span class="o">-&gt;</span>
            <span class="nv">Error</span>
    <span class="k">end</span><span class="p">.</span>
</pre>
<p>We can assign to an intermediate &quot;Resp&quot; variable, and bring that second case
statement out into the function's main code block, like so:</p>
<pre class="code erlang literal-block">
<span class="nf">do_some_file_thing</span><span class="p">(</span><span class="nv">File</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="nv">Resp</span> <span class="o">=</span> <span class="k">case</span> <span class="nn">file</span><span class="p">:</span><span class="n">open</span><span class="p">(</span><span class="nv">File</span><span class="p">,</span> <span class="p">[</span><span class="n">raw</span><span class="p">,</span> <span class="n">binary</span><span class="p">,</span> <span class="n">read</span><span class="p">])</span> <span class="k">of</span>
        <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">Fd</span><span class="p">}</span> <span class="o">-&gt;</span>
            <span class="p">{</span><span class="n">timestamp</span><span class="p">,</span> <span class="n">now</span><span class="p">(),</span> <span class="n">process_file_data</span><span class="p">(</span><span class="nv">Fd</span><span class="p">)};</span>
        <span class="nv">Error</span> <span class="o">-&gt;</span>
            <span class="nv">Error</span>
    <span class="k">end</span><span class="p">,</span>
    <span class="k">case</span> <span class="nv">Resp</span> <span class="k">of</span>
        <span class="p">{</span><span class="n">timestamp</span><span class="p">,</span> <span class="nv">Start</span><span class="p">,</span> <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">Processed</span><span class="p">}}</span> <span class="o">-&gt;</span>
            <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">Start</span><span class="p">,</span> <span class="n">now</span><span class="p">(),</span> <span class="nv">Processed</span><span class="p">};</span>
        <span class="p">{</span><span class="n">timestamp</span><span class="p">,</span> <span class="nv">Start</span><span class="p">,</span> <span class="nv">Error</span><span class="p">}</span> <span class="o">-&gt;</span>
            <span class="nv">Error</span><span class="p">;</span>
        <span class="nv">Error</span> <span class="o">-&gt;</span>
            <span class="nv">Error</span>
    <span class="k">end</span><span class="p">.</span>
</pre>
</div>
<div class="section" id="what-does-this-all-mean">
<h4>What does this all mean?</h4>
<p>At the end of the day, this isn't going to make or break you as a programmer.
In fact, nothing I've mentioned even changes the code's logic, but simply its
implementation.  It's simply something to think about as you code, as you read
other people's code.  Hopefully you agree with me that less nesting is an
admirable goal, and you find more and more ways to achieve it.</p>
<p>Discuss this post <a class="reference external" href="http://news.ycombinator.com/item?id=3414526">on Hacker News</a>.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/observations/">Observations</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[The Technology Behind Convore]]></title>
        <link href="http://eflorenzano.com/blog/2011/02/16/technology-behind-convore/"/>
        <updated>2011-02-16T20:29:35</updated>
        <id>http://eflorenzano.com/blog/2011/02/16/technology-behind-convore/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2011/02/16/technology-behind-convore/">The Technology Behind Convore</a></h3>
<p class="datetime">Feb 16, 2011</p>
<div class="document">
<p>We launched <a class="reference external" href="https://convore.com/">Convore</a> last week, and the first question developers tend to ask
when they find <a class="reference external" href="https://convore.com/">Convore</a> is &quot;what technology powers this site?&quot;  It is asked so
often, in fact, that we have started to copy and paste the same short response
again and again.  That response was good enough to satisfy people who simply
wanted to know if we were Rails or Django, or whether we were using node.js for
the real-time stuff, but this article will expand upon that--  not only giving
more details for the curious, but also giving us a link to point people at when
they ask the question in the future.  I always wish other people were totally
open about their architectures, so that I can learn from their good choices and
their bad, so I'd like to be as open as possible about ours.  Let's dive in!</p>
<div class="section" id="the-basics">
<h4>The basics</h4>
<p>All of our application code is powered by Python.  Our front-end html page
generation is done by Django, which we use in a surprisingly traditional way
given the real-time nature of Convore as a product.  Everything is assembled
at once: all messages, the sidebar, and the header are all rendered on the
server instead of being pulled in after-the-fact with JavaScript.  All of the
important data is canonically stored in PostgreSQL, including messages, topics,
groups, unread counts, and user profiles.  Search functionality is provided by
Solr, which is interfaced into our application by way of the handy Haystack
Django application.</p>
</div>
<div class="section" id="the-message-lifecycle">
<h4>The message lifecycle</h4>
<p>When a new message comes into the system, first it's parsed by a series of
regular expressions designed to pull out interesting bits of information from
the message.  Right now all we're looking for is username references and
links (and further, whether those links point at images which should be
rendered in-line.)  At the end of this parsing stage, we have a structured
message parse list, which is converted into JSON.</p>
<p>So, for example if someone posted the message:</p>
<pre class="code text literal-block">
&#64;ericflo &#64;simonw Here's how we connect/disconnect from Redis in production: http://dpaste.com/406797/
</pre>
<p>The resulting JSON parse list would look like this:</p>
<pre class="code text literal-block">
[
    {
        &quot;type&quot;: &quot;username&quot;,
        &quot;user_id&quot;: 1,
        &quot;username&quot;: &quot;ericflo&quot;,
        &quot;markup&quot;: &quot;&lt;a href=\&quot;/users/ericflo/\&quot;&gt;&#64;ericflo&lt;/a&gt;&quot;
    },
    {
        &quot;type&quot;: &quot;username&quot;,
        &quot;user_id&quot;: 56,
        &quot;username&quot;: &quot;simonw&quot;,
        &quot;markup&quot;: &quot; &lt;a href=\&quot;/users/simonw/\&quot;&gt;&#64;simonw&lt;/a&gt;&quot;
    },
    {
        &quot;type&quot;: &quot;text&quot;,
        &quot;markup&quot;: &quot; Here&amp;#39;s how we connect/disconnect from Redis in production: &quot;
    },
    {
        &quot;type&quot;: &quot;url&quot;,
        &quot;url&quot;: &quot;http://dpaste.com/406797/&quot;,
        &quot;markup&quot;: &quot;&lt;a href=\&quot;http://dpaste.com/406797/\&quot; target=\&quot;_blank\&quot;&gt;http://dpaste.com/406797/&lt;/a&gt;&quot;
    }
]
</pre>
<p>After this is constructed, we log all our available information about this
message, and then save to the database--  both the raw message as it was received,
and the JSON-encoded parsed node list.</p>
<p>Now a task is sent to Celery (by way of Redis) notifying it that this new
message has been received.  This Celery task now increments the unread count
for everyone who has access to the topic that the message was posted in, and
then it publishes to a Redis pub/sub for the group that the message was posted
to.  Finally, the task scans through the message, looking for any users that
were mentioned in the message, and writes entries to the database for every
mention.</p>
<p>On the other end of that pub/sub are the many open http requests that our users
have initiated, which are waiting for any new messages or information.  Those
all simultaneously return the new message information, at which point they
reconnect again, waiting for the next message to arrive.</p>
</div>
<div class="section" id="the-real-time-endpoint">
<h4>The real-time endpoint</h4>
<p>Our live updates endpoint is actually a very simple and lightweight pure-WSGI
Python application, hosted using Eventlet.  It spawns off a coroutine for each
request, and in that coroutine, it looks up all the groups that a user is a
member of, and then opens a connection to Redis subscribing to all of those
channels.  Each of these Eventlet-hosted Python applications has the ability to
host hundreds-to-thousands of open connections, and we run several instances
on each of our front-end machines.  It has a few more responsibilities, like
marking a topic as read before it returns a response, but the most important
thing is to be a bridge between the user and Redis pub/sub.</p>
</div>
<div class="section" id="future-improvements">
<h4>Future improvements</h4>
<p>There are so many places where our architecture can be improved.  This is our
first version, and now that real users are using the system, already some of
our initial assumptions are being challenged.  For instance, we thought that
pub/sub to a channel per group would be enough, but what that means is that
everyone in a group sees the exact same events as everyone else in that group.</p>
<p>This means we don't have the ability to customize each user's experience based
on their preferences--no way to put a user on ignore, filter certain messages,
etc.  It also means that we aren't able to sync up a user's experience across
tabs or browsers, since we don't really want to broadcast to everyone in the
group that one user has visited a topic, thereby removing any unread messages
in that topic.  So going forward we're going to have to break up that per-group
pub/sub into per-user pub/sub.</p>
<p>Another area that could be improved is our unread counts.  Right now they're
stored as rows in our PostgreSQL database, which makes it extremely easy to
batch update them and do aggregate queries on them, but the number of these
rows is increasing rapidly, and without some kind of sharding scheme, it will
at some point become more difficult to work with such a large amount of rows.
My feeling is that this will eventually need to be moved into a non-relational
data store, and we'll need to write a service layer in front of it to deal with
pre-aggregating and distributing updates, but nothing is set in stone just yet.</p>
<p>Finally, Python may not be the best language for this real-time endpoint.
Eventlet is a fantastic Python library and it allowed us to build something
extremely fast that has scaled to several thousand concurrent connections
without breaking a sweat on launch day, but it has its limits.  There is a
large body of work out there on handling a large number of open connections,
using Java's NIO framework, Erlang's mochiweb, or node.js.</p>
</div>
<div class="section" id="that-s-all-folks">
<h4>That's all folks</h4>
<p>We're pretty proud of what we've built in a very short time, and we're glad
it has held up as well as it has on our launch day and afterwards.  We're
excited about the problems we're now being faced with, both scaling the
technology, and scaling the product.  I hope this article has quenched any
curiosity out there about how Convore works.  If there are any questions,
feel free to join <a class="reference external" href="https://convore.com/">Convore</a> and ask away!</p>
<p>(Or discuss it <a class="reference external" href="http://news.ycombinator.com/item?id=2228137">on Hacker News</a>)</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/postgresql/">PostgreSQL</a></li>
      
        <li><a href="/blog/categories/convore/">Convore</a></li>
      
        <li><a href="/blog/categories/realtime/">Realtime</a></li>
      
        <li><a href="/blog/categories/redis/">Redis</a></li>
      
        <li><a href="/blog/categories/haystack/">Haystack</a></li>
      
        <li><a href="/blog/categories/solr/">Solr</a></li>
      
        <li><a href="/blog/categories/eventlet/">Eventlet</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[An Object Lesson in How to Respond to Criticism]]></title>
        <link href="http://eflorenzano.com/blog/2010/10/10/object-lesson-how-respond-criticism/"/>
        <updated>2010-10-10T16:56:12</updated>
        <id>http://eflorenzano.com/blog/2010/10/10/object-lesson-how-respond-criticism/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2010/10/10/object-lesson-how-respond-criticism/">An Object Lesson in How to Respond to Criticism</a></h3>
<p class="datetime">Oct 10, 2010</p>
<div class="document">
<p>In the moments leading up to my DjangoCon keynote this year (called
<a class="reference external" href="http://djangocon.blip.tv/file/4112452/">Why Django Sucks, and How We Can Fix It</a>), I pictured the room an hour in the
future and imagined what things would be like.  I envisioned all kinds of
scenarios: one where people were literally booing, or another where I needed to
sneak back to my hotel room to avoid embarassment.  I imagined all of these
scenarios because I was about to level some harsh criticism at a technology
that everyone in the room was enthusiastic about.</p>
<p>And then I went on stage and gave the talk.</p>
<p>When it was finished, I braced myself for one of these scenarios to unfold.
Instead, what happened in the following moments, the following days, and indeed
the following month since then has been what I consider to be the most gracious
and useful response to criticism that I've ever seen.  And I think it deserves
to be highlighted, because I believe that reacting well to criticism is vital
for any successful community.</p>
<p>So what happened in the moments directly following the talk?
<a class="reference external" href="http://cecinestpasun.com/">Russell Keith-Magee</a>, arguably the most active core developer at the time,
made a special point to march up to the front of the stage and publicly shake
my hand. This gesture not only legitimized some of the things that I said (some
of which were quite extreme), but it also set the tone for the discourse around
my talk; civility.</p>
<p>Afterwards, privately, I apologized to several of the Django core developers.
These are people I respect and admire, and I wanted to make sure that they knew
that, at least on my end, it wasn't personal.  I was expecting forgiveness, but
instead I received thanks.  Thanking me for criticising their project?  Not
what I was expecting.</p>
<p>One of the things that I suggested was to make <a class="reference external" href="http://alexgaynor.net/">Alex Gaynor</a> a core developer.
A few people at the conference made comments wondering how many days it would
take before that would happen.  Days went by, and the conference ended without
this happening.  A week went by.  A few more.  But I knew better, because the
Django core committers don't do anything brashly.  They took their time, let
all dust and emotions settle down, and listened to the discussion.</p>
<p>And then <a class="reference external" href="http://jacobian.org/">Jacob Kaplan-Moss</a> issued <a class="reference external" href="http://groups.google.com/group/django-developers/browse_thread/thread/9ebc3e57d539d1ff">an official announcement</a>.  I
particularly agreed with one of the <a class="reference external" href="http://news.ycombinator.com/item?id=1740675">top comments on hackernews</a>:</p>
<pre class="literal-block">
&quot;I don't know enough about the specifics of the case to
assess the new policy on the merits, but I will say that
as a piece of writing this is a model of how to change
policy gracefully: clear, forthright, and non-defensive.&quot;
</pre>
<p>Clear.  Forthright.  Non-defensive.</p>
<p>Some people saw this as an opening to change even more about Django, and even
when some of the discussion was phrased rudely or accusatory, the Django team's
responses were thoughtful and calm.  Now, over a week later (again
demonstrating that things aren't done brashly), we see that a half-dozen new
people have been added to the core team.  Yes, that includes <a class="reference external" href="http://alexgaynor.net/">Alex Gaynor</a>.
So not only was the new policy clear, forthright, and non-defensive, but there
was concrete follow-through so that everyone can see that it wasn't just words.</p>
<p>And even in that short time since the new committers were added, Django's code
is already reaping the benefits--we've seen a flurry of bugs fixed and tickets
closed.  Django's future has never looked so promising!</p>
<p>Why do I think this is so important?  Because a community which welcomes
constructive criticism is one in which people feel they can make a difference.
And it's because they <em>can</em> make a difference.  It's a community that's never
satisfied with the status quo.  It's a community that can grow and change and
adapt, when the world around it changes.  It's a community that we can be proud
of.</p>
<p>NB: I was not the only one to criticize Django at DjangoCon.  I was merely one
voice.  This is just written from my perspective.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/djangocon/">DjangoCon</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/criticism/">Criticism</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Why node.js disappoints me]]></title>
        <link href="http://eflorenzano.com/blog/2010/09/27/why-node-disappoints-me/"/>
        <updated>2010-09-27T08:23:47</updated>
        <id>http://eflorenzano.com/blog/2010/09/27/why-node-disappoints-me/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2010/09/27/why-node-disappoints-me/">Why node.js disappoints me</a></h3>
<p class="datetime">Sep 27, 2010</p>
<div class="document">
<p><a class="reference external" href="http://nodejs.org/">Node.js</a> is currently at the center of a huge cyclone of hype.  At this point it's clear that Node is going to be a major player in the next few years of web development.  It's no wonder, either!  It represents a fresh start, one with no legacy synchronous baggage in our increasingly asynchronous, increasingly real-time web. And it's accessible to anyone who's written JavaScript (read: all web developers.)</p>
<p>Oh, and those benchmarks!  Compared trivially to the currently popular web technologies, it seems an obvious leap forward.</p>
<p>Yet one of Node's advantages that you'll hear repeated again and again by its proponents is that you can now code in One Language, and you won't have to deal with the cognitive load of context switching between different languages.  Especially as ORMs and NoSQL continue to rise in popularity, there's no need to even deal with SQL. At the end of the day you're writing JavaScript, HTML, and CSS, and that's it.</p>
<p>Seeing this happen with all of these pieces falling into place--a fresh start with a unified language--I started to get excited.  This would change the way we thought about our web code.  The frontend is the backend is the query language is the storage layer is JavaScript!  It's a revolution.</p>
<p>And then I saw what people did with this opportunity.  They effectively ported Sinatra/Django/Rails to JavaScript--and did it in such a way that it would only run on the server, with a specific feature set of JavaScript that only Node can reasonably understand.</p>
<p>Not exactly the revolution I was hoping for.</p>
<p>Instead of coding in one language, we're actually coding in two. One is the subset JavaScript that can be run in all browsers, and another is the set of JavaScript that can be run by Node.  Knowing the difference between the two languages and context switching between them is simply a required skill.</p>
<p>You know what would be awesome? If we wrote our libraries so that they could run either on the server or on the client, and they did so in a transparent way.  Maybe it would help to give a concrete example of how this could be awesome.  Let's talk about HTML templating.</p>
<p>Imagine a framework where the first page-load was always rendered server-side, meaning the client gets a single fully-rendered page.  Then for desktop browsers, browsing around the site just made calls to API endpoints returning JSON or XML, and the client rendered the templates for the changed portions of the page.  For mobile browsers with less power or for search engines, the rendering would always be done on the server.  Imagine that the templating library could record some key metrics to determine how long things were taking to render, and dynamically switch between rendering on the server and client based on server load or client speed.</p>
<p>Imagine a case where a back-end service fails temporarily.  In this case the rendering of that particular component could be deferred, the browser could be told to poll a resource.  When the back-end service is recovered, it could send the data for the client to render on its own.</p>
<p>How awesome would that be?</p>
<p>It's not just HTML templating, either.  This same principle could be applied to any number of things: URL routing, form validation, hell even most application logic could be done using this style.</p>
<p>But it's going to take discipline.  Instead of reaching for those fancy V8 features, code will need to be written in a strict subset of the JavaScript that's available.  Maybe Node could detect incompatible code and throw warnings, that would be cool.</p>
<p>I just really hope that someday we stop re-inventing the same exact wheel, and instead build something substantially different and better.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/javascript/">Javascript</a></li>
      
        <li><a href="/blog/categories/node/">Node</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[We need a new word for &#34;Open&#34;]]></title>
        <link href="http://eflorenzano.com/blog/2010/05/20/we-need-new-word-open/"/>
        <updated>2010-05-20T07:09:27</updated>
        <id>http://eflorenzano.com/blog/2010/05/20/we-need-new-word-open/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2010/05/20/we-need-new-word-open/">We need a new word for &#34;Open&#34;</a></h3>
<p class="datetime">May 20, 2010</p>
<div class="document">
<p>When I say I'm developing an &quot;open&quot; API, what does that mean to you?</p>
<p>To Facebook, it means something where you can get at some of your own data, as long as you abide by their restrictions on what you can do with it.</p>
<p>To Twitter, it means something where you get back what you put in.</p>
<p>To Flickr, it means something where you can get every single piece of data that you've ever put in the system, enriched by any value that Flickr can provide.</p>
<p>To Google, it means something where you can get back what you put in, you can host your own version of the API on your own server, and your server has exactly the same status as any Google server has, and that Google's servers and your server will interact and work as a system.</p>
<p>We need new words.  Words that have more specific meaning--which encompass the broad idea of &quot;open&quot;, yet remain accessible and recognizable by everyone.  Federated is a good word, but it's possible to have a closed, federated system.</p>
<p>What words should we use?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/open/">Open</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[How do we kick our synchronous addiction?]]></title>
        <link href="http://eflorenzano.com/blog/2010/02/09/how-do-we-kick-our-synchronous-addiction/"/>
        <updated>2010-02-09T06:15:31</updated>
        <id>http://eflorenzano.com/blog/2010/02/09/how-do-we-kick-our-synchronous-addiction/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2010/02/09/how-do-we-kick-our-synchronous-addiction/">How do we kick our synchronous addiction?</a></h3>
<p class="datetime">Feb 09, 2010</p>
<div class="document">
<p>Asynchronous programming is superior <a class="reference external" href="http://blog.webfaction.com/a-little-holiday-present">both in memory usage and in overall throughput</a> when compared to synchronous programming .  We've <a class="reference external" href="http://www.kegel.com/c10k.html">known this fact for years</a>.  If we look at Django or Ruby on Rails, arguably the two most promising new web application frameworks to emerge in the past few years, both of them are written in such a way that synchronous programming  is assumed. Why is it that even in 2010 we're still writing programs that rely on synchronous programming ?</p>
<p>The reason that we're stuck on synchronous programming  is twofold.  Firstly, the programming model required for straightforward asynchronous implementations is inconvenient.  Secondly, popular and/or mainstream languages lack the built-in language constructs that are needed to implement a less-straightforward approach to asynchronous programming.</p>
<div class="section" id="asynchronous-programming-is-too-hard">
<h4>Asynchronous programming is too hard</h4>
<p>Let's first examine the straightforward implementation: an event loop.  In this programming model, we have a single process with a single loop that runs continuously.  Functionality is achieved by writing functions to execute small tasks quickly, and inserting those functions into that event loop.  One of those functions might read some bytes from a socket, while another function might write a few bytes to a file, and yet another function might do something computational like calculating an XOR on the data that's been buffered from that first socket.</p>
<p>The most important part about this event loop is that only one thing is ever happening at a time.  That means that you really have to break your logic up into small chunks that can be performed incrementally.  If any one of our functions blocks, it hogs the event loop and nothing else can execute during that time.</p>
<p>We have some really great frameworks geared towards making this event loop model easier to work with.  In Python, there's <a class="reference external" href="http://twistedmatrix.com/trac/">Twisted</a> and, more recently, <a class="reference external" href="http://www.tornadoweb.org/">Tornado</a>.  In Ruby there's <a class="reference external" href="http://rubyeventmachine.com/">EventMachine</a>.  In PERL there's <a class="reference external" href="http://poe.perl.org/">POE</a>.  What these frameworks do is twofold: provide constructs for more easily working with an event loop (e.g. <a class="reference external" href="http://twistedmatrix.com/documents/current/core/howto/defer.html">Deferreds</a> or <a class="reference external" href="http://en.wikipedia.org/wiki/Futures_and_promises">Promises</a>), and provide asynchronous implementations of common tasks (e.g. HTTP clients and DNS resolution).</p>
<p>But these frameworks stop very short of making asynchronous programming easy for two reasons.  The first reason is that we really do have to completely change our coding style.  Consider what it would take to render a simple blog web page with comments.  Here's some JavaScript code to demonstrate how this might work in a synchronous framework:</p>
<pre class="code javascript literal-block">
<span class="kd">function</span> <span class="nx">handleBlogPostRequest</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="nx">response</span><span class="p">,</span> <span class="nx">postSlug</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">db</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">DBClient</span><span class="p">(</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">post</span> <span class="o">=</span> <span class="nx">db</span><span class="p">.</span><span class="nx">getBlogPost</span><span class="p">(</span><span class="nx">postSlug</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">comments</span> <span class="o">=</span> <span class="nx">db</span><span class="p">.</span><span class="nx">getComments</span><span class="p">(</span><span class="nx">post</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">html</span> <span class="o">=</span> <span class="nx">template</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="s1">'blog/post.html'</span><span class="p">,</span>
        <span class="p">{</span><span class="s1">'post'</span><span class="o">:</span> <span class="nx">post</span><span class="p">,</span> <span class="s1">'comments'</span><span class="o">:</span> <span class="nx">comments</span><span class="p">});</span>
    <span class="nx">response</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">html</span><span class="p">);</span>
    <span class="nx">response</span><span class="p">.</span><span class="nx">close</span><span class="p">(</span><span class="p">);</span>
<span class="p">}</span>
</pre>
<p>Now here's some JavaScript code to demonstrate how this might look in an asynchronous framework.  Note several things here: We've specifically written this in such a way that it doesn't become nested four levels deep.  We've also written these callback functions inside of the <tt class="docutils literal">handleBlogPostRequest</tt> function to take advantage of closure so as to retain access to the request and response objects, the template context, and the database client. Both the desire to avoid nesting and the closure are things that we need to think about as we write this code, that were not even considerations in the synchronous version:</p>
<pre class="code javascript literal-block">
<span class="kd">function</span> <span class="nx">handleBlogPostRequest</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="nx">response</span><span class="p">,</span> <span class="nx">postSlug</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">context</span> <span class="o">=</span> <span class="p">{</span><span class="p">};</span>
    <span class="kd">var</span> <span class="nx">db</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">DBClient</span><span class="p">(</span><span class="p">);</span>
    <span class="kd">function</span> <span class="nx">pageRendered</span><span class="p">(</span><span class="nx">html</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">response</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">html</span><span class="p">);</span>
        <span class="nx">response</span><span class="p">.</span><span class="nx">close</span><span class="p">(</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="kd">function</span> <span class="nx">gotComments</span><span class="p">(</span><span class="nx">comments</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">context</span><span class="p">[</span><span class="s1">'comments'</span><span class="p">]</span> <span class="o">=</span> <span class="nx">comments</span><span class="p">;</span>
        <span class="nx">template</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="s1">'blog/post.html'</span><span class="p">,</span> <span class="nx">context</span><span class="p">).</span><span class="nx">addCallback</span><span class="p">(</span><span class="nx">pageRendered</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="kd">function</span> <span class="nx">gotBlogPost</span><span class="p">(</span><span class="nx">post</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">context</span><span class="p">[</span><span class="s1">'post'</span><span class="p">]</span> <span class="o">=</span> <span class="nx">post</span><span class="p">;</span>
        <span class="nx">db</span><span class="p">.</span><span class="nx">getComments</span><span class="p">(</span><span class="nx">post</span><span class="p">.</span><span class="nx">id</span><span class="p">).</span><span class="nx">addCallback</span><span class="p">(</span><span class="nx">gotComments</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="nx">db</span><span class="p">.</span><span class="nx">getBlogPost</span><span class="p">(</span><span class="nx">postSlug</span><span class="p">).</span><span class="nx">addCallback</span><span class="p">(</span><span class="nx">gotBlogPost</span><span class="p">);</span>
<span class="p">}</span>
</pre>
<p>I've chosen JavaScript here to prove a point, by the way.  People are very excited about <a class="reference external" href="http://nodejs.org/">node.js</a> right now, and it's a very cool framework, but it doesn't hide all of the complexities involved in doing things asynchronously.  It only hides some of the implementation details of the event loop.</p>
<p>The second reason why these frameworks fall short is because not all IO can be handled properly by a framework, and in these cases we have to resort to bad hacks.  For example, MySQL does not offer an asynchronous database driver, so most of the major frameworks end up using threads to ensure that this communication happens out of band.</p>
<p>Given the inconvenient API, the added complexity, and the simple fact that most developers haven't switched to using this style of programming, leads us to the conclusion that this type of framework is not a desirable final solution to the problem (even though I do concede that you can get Real Work done today using these techniques, and many people do).  That being the case, what other options do we have for asynchronous programming? Coroutines and lightweight processes, which brings us to our next major problem.</p>
</div>
<div class="section" id="languages-don-t-support-easier-asynchronous-paradigms">
<h4>Languages don't support easier asynchronous paradigms</h4>
<p>There are a few language constructs that, if implemented properly in modern programming languages, could pave the way for alternative methods of doing asynchronous programming that don't have the drawbacks of the event loop.  These constructs are coroutines and lightweight processes.</p>
<p>A coroutine is a function that can suspend and resume its execution at certain, programmatically specified, locations.  This simple concept can serve to transform blocking-looking code to be non-blocking.  At certain critical points in your IO library code, the low-level functions that are doing IO can choose to &quot;cooperate&quot;.  That is, it can choose to suspend execution in order for another function to resume execution and continue on.</p>
<p>Here's an example (it's Python, but fairly understandable for all I hope):</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">download_pages</span><span class="p">():</span>
    <span class="n">google</span> <span class="o">=</span> <span class="n">urlopen</span><span class="p">(</span><span class="s">'http://www.google.com/'</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
    <span class="n">yahoo</span> <span class="o">=</span> <span class="n">urlopen</span><span class="p">(</span><span class="s">'http://www.yahoo.com/'</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
</pre>
<p>Normally the way this would work is that a socket would be opened, connected to Google, an HTTP request sent, and the full response would be read, buffered, and assigned to the <tt class="docutils literal">google</tt> variable, and then in turn the same series of steps would be taken for the <tt class="docutils literal">yahoo</tt> variable.</p>
<p>Ok, now imagine that the underlying socket implementation were built using coroutines that cooperated with each other.  This time, just like before, the socket would be opened and a connection would be made to Google, and then a request would be fired off.  This time, however, after sending the request, the socket implementation suspends its own execution.</p>
<p>Having suspended its execution (but not yet having returned a value), execution continues on to the next line.  The same thing happens on the Yahoo line: once its request has been fired off, the Yahoo line suspends its execution.  But now there's something else to cooperate with--there's actually some data ready to be read on the Google socket--so it resumes execution at that point.  It reads some data from the Gooogle socket, and then suspends its execution again.</p>
<p>It jumps back and forth between the two coroutines until one has finished.  Let's say that the Yahoo socket has finished, but the Google one has not.  In this case, the Google socket just continues to read from its socket until it has completed, because there are no other coroutines to cooperate with.  Once the Google socket is finally finished, the function returns with all of the buffered data.</p>
<p>Then the Yahoo line returns with all of its buffered data.</p>
<p>We've preserved the style of our blocking code, but we've used asynchronous programming to do it.  Best of all, we've preserved our original program flow--the <tt class="docutils literal">google</tt> variable is assigned first, and then the <tt class="docutils literal">yahoo</tt> variable is assigned.  In truth, we've got a smart event loop going on underneath the covers to control who gets to execute, but it's hidden from us due to the fact that coroutines are in play.</p>
<p>Languages like PHP, Python, Ruby, and Perl simply don't have built-in coroutines that are robust enough to implement this kind of behind-the-scenes transformation.  So what about these lightweight processes?</p>
<p>Lightweight processes are what Erlang uses as its main concurrency primitive.  Essentially these are processes that are mostly implemented in the Erlang VM itself.  Each process has approximately 300 words of overhead and its execution is scheduled primarily by the Erlang VM, sharing no state at all amongst processes.  Essentially, we don't have to think twice about spawning a process, as it's essentially free.  The catch is that these processes can only communicate via message passing.</p>
<p>Implementing these lightweight processes at the VM level gets rid of the memory overhead, the context switching, and the relative sluggishness of interprocess communication provided by the operating system.  Since the VM also has insight into the memory stack of each process, it can freely move or resize those processes and their stacks.  That's something that the OS simply cannot do.</p>
<p>With this model of lightweight processes, it's possible to again revert back to the convenient model of using a separate process for all of our asynchronous programming needs.  The question becomes this: can this notion of lightweight processes be implemented in languages other than Erlang?  The answer to that is &quot;I don't know.&quot;  To my knowledge, Erlang takes advantage of some features of the language itself (such as having no mutable data structures) in its lightweight process implementation.</p>
</div>
<div class="section" id="where-do-we-go-from-here">
<h4>Where do we go from here?</h4>
<p>The key to moving forward is to drop the notion that developers need to learn to think about all of their code in terms of callbacks and asynchrony, as the asynchronous event loop frameworks require them to do.  Over the past ten years, we can see that most developers, when faced with that decision, simply choose to ignore it.  They continue to use the inferior blocking methodologies of yesteryear.</p>
<p>We need to look at these alternative implementations like coroutines and lightweight processes, so that we can make asynchronous programming as easy as synchronous programming.  Only then will we be able to kick this synchronous addiction.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/asynchronous/">Asynchronous</a></li>
      
        <li><a href="/blog/categories/threads/">Threads</a></li>
      
        <li><a href="/blog/categories/processes/">Processes</a></li>
      
        <li><a href="/blog/categories/coroutines/">Coroutines</a></li>
      
        <li><a href="/blog/categories/erlang/">Erlang</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[You care about Facebook, you just might not know it yet]]></title>
        <link href="http://eflorenzano.com/blog/2009/11/11/you-care-about-facebook-you-just-might-not-know-it/"/>
        <updated>2009-11-11T06:25:12</updated>
        <id>http://eflorenzano.com/blog/2009/11/11/you-care-about-facebook-you-just-might-not-know-it/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2009/11/11/you-care-about-facebook-you-just-might-not-know-it/">You care about Facebook, you just might not know it yet</a></h3>
<p class="datetime">Nov 11, 2009</p>
<div class="document">
<p>I recently had a conversation with a few friends that I know through the Python community. These are people who I respect a great deal, and look to for advice and insight when it comes to web development.  During the course of this conversation, the subject of Facebook came up.  What I wasn't expecting at all was that a large number of them said that they have no interest in Facebook, and quite a few of them proudly didn't even have accounts.</p>
<p>To put it bluntly, I believe that ignorance of Facebook is a major handicap today, both for developers and for entrepreneurs, and people who are not paying attention to it are burying their head in the sand.</p>
<p>Facebook has gotten to a point where it's the destination where <a class="reference external" href="http://mashable.com/2009/09/17/facebook-google-time-spent/">the most time is spent online</a>.  It gets an estimated <a class="reference external" href="https://www.google.com/adplanner/planning/site_profile#siteDetails?identifier=facebook.com&amp;lp=true">260 billion</a> (that's a B on that number) pageviews per month.  In a single week, new properties are able to garner <a class="reference external" href="http://www.insidesocialgames.com/2009/10/08/zyngas-cafe-world-goes-from-0-to-8-6-million-users-in-a-week-with-big-implications/">8.6 million new active users</a>. Sites which implement <a class="reference external" href="http://developers.facebook.com/connect.php">Facebook Connect</a> typically see a <a class="reference external" href="http://www.businessinsider.com/six-months-in-facebook-connect-is-a-huge-success-2009-7">1.3x-2x boost in registrations</a>. Companies building on Facebook's platform are <a class="reference external" href="http://www.guardian.co.uk/technology/2009/nov/09/playfish-ea">being sold for 400 million dollars</a> and are <a class="reference external" href="http://www.virtualgoodsnews.com/2009/04/100m-annual-revenues-reported-for-zynga.html">making 100 million dollars yearly</a>. There are over <cite>300 million</cite> active registered users.  In other words, if you talk to a person that spends any time on the internet at all, they likely have a Facebook account.  These numbers, by the way, are trending <a class="reference external" href="http://www.insidefacebook.com/2009/08/12/comscore-facebooks-us-audience-jumps-by-14-in-july/">up and to the right--</a>.</p>
<p>Take the word Facebook out of the above paragraph, and replace it with icanhazcheeseburger. Replace it with 4chan, or somethingawful, or barbie, or anything. No matter what you replace as the company name, it doesn't change the fact that those numbers are compelling enough to be irresponsible to ignore.</p>
<p>Let me be perfectly clear: I don't particularly enjoy using Facebook.  I find its UI cluttered, its privacy controls confusing, and its content fairly trivial.  From the development side, Facebook's APIs are clunky at best. I'm definitely not advocating that you should log in every day and love it.  I don't.  The mass populous, however, does.  I'm simply advocating that you should at least have an account, log in every once in a while, and keep tabs on the announcements that they make for developers.</p>
<p>As people spend more and more time consuming and producing content inside of the Facebook ecosystem, it's going to be those who change and embrace it who succeed, and those who fail to adapt that stand to lose.  Note that I said producing content &quot;inside of the Facebook ecosystem&quot;, and not &quot;inside Facebook&quot;, as Facebook has been making very strong pushes to extend the reach of its platform well outside of its destination site.  You can augment your site to have people pushing content into Facebook from your own destination sites.</p>
<p>Facebook is willing to give you access to a person's information, to their entire social graph, and to allow your user to become an advocate of your site, all while making registration on your site as simple as one click.  Sure, you may evaluate all of that as an option and decide that it's not important enough to implement, but surely it's an important enough option to warrant your cognizance.</p>
<p>Do I think that Facebook will be relevant in 10 years? Probably. I'm not willing to bet much on it.  One thing you can be <strong>absolutely</strong> sure about though, is that if another service with this much power comes along, I'll have an account and be acutely aware of its developer resources.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/social-graph/">Social Graph</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/facebook/">Facebook</a></li>
      
        <li><a href="/blog/categories/social-networking/">Social Networking</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[My Thoughts on NoSQL]]></title>
        <link href="http://eflorenzano.com/blog/2009/07/21/my-thoughts-nosql/"/>
        <updated>2009-07-21T13:44:17</updated>
        <id>http://eflorenzano.com/blog/2009/07/21/my-thoughts-nosql/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2009/07/21/my-thoughts-nosql/">My Thoughts on NoSQL</a></h3>
<p class="datetime">Jul 21, 2009</p>
<div class="document">
<p>Over the past few years, relational databases have fallen out of favor for a
number of influential people in our industry.  I'd like to weigh in on that,
but before doing so, I'd like to give my executive summary of the events leading up to
this movement:</p>
<p>In the late nineties and early thousands, websites were mostly read-only--a
publisher would create some content and users would consume that content.
The data access patterns for these types of applications became very
well-understood, and as a result many tools were created and much research and
development was done to further develop these technologies.</p>
<p>As the web has grown more social, however, more and more it's the people
themselves who have become the publishers.  And with that fundamental shift
away from read-heavy architectures to read/write and write-heavy
architectures, a lot of the way that we think about storing and retrieving
data needed to change.</p>
<p>Most people have done this by relying less on the features provided by
traditional relational databases and engineering more database logic in their
application code.  Essentially, they stop using relational databases the way
they were intended to be used, and they instead use them as dumb data stores.</p>
<p>Other people have engineered new database systems from the ground up, each
with a different set of tradeoffs and differences from their relational
database brethren.  It's these new databases that have some in our industry
excited, and it's these databases that I'm going to focus on primarily in this
post.</p>
<p>(By the way, there's a whole lot more theory behind the movement away from
SQL.  Primarily of interest is the CAP theorem and the Dynamo paper.  Both of
these illustrate the necessary tradeoffs of between different approaches to
designing databases.)</p>
<div class="section" id="let-s-get-this-out-of-the-way">
<h4>Let's get this out of the way</h4>
<p>I love SQL.  More than even that, I love my precious ORM and being able to
query for whatever information I want whenever I want it.  For the vast
majority of sites out there (we're talking 99.9% of the sites out there,
folks) it suits their needs very well, providing a good balance of ease of use
and performance.</p>
<p>There's no reason for them to switch away from SQL, and there's no way they
will.  If there's one thing I <em>don't</em> like about this whole NoSQL movement,
it's the presumption that everyone who's interested in alternative databases
hates the status quo.  That's simply not true.</p>
<p>But we're not talking about most sites out there, we're not talking about the
status quo, we're talking about the few applications that need something
totally different.</p>
</div>
<div class="section" id="tokyo-cabinet-tokyo-tyrant">
<h4>Tokyo Cabinet / Tokyo Tyrant</h4>
<p>Tokyo Cabinet (and its network interface, Tokyo Tyrant) is the logical
successor to Berkeley DB--a blazing fast, open-source, embeddable key-value
store that does just about what you would expect from its description.  It
supports 3 modes of operation: hashtable mode, b-tree mode, and table mode.</p>
<p>(Table mode still pretty much sucks, and I'm not convinced it's a good idea
for the project since it's added bloat and other systems like RDBMs are
probably better for storing tabular data, so I'm going to skip it.)</p>
<p>Essentially, the API into Tokyo Cabinet is that of a gigantic associative
array.  You give it a key and a value, and then later, given a key, it will
give you back the value you put in.  Its largest assets are that it's fast and
straightforward.</p>
<p>If your problem is such that you have a small to medium-sized amount of data,
which needs to be updated rapidly, and can be easily modeled in
terms of keys and values (almost all scenarios can be rewritten in terms of
keys and values, but some problems are easier to convert than others), then
Tokyo Cabinet and Tokyo Tyrant are the way to go.</p>
</div>
<div class="section" id="couchdb">
<h4>CouchDB</h4>
<p>CouchDB is similar to Tokyo Cabinet in that it essentially maps keys to data,
but CouchDB's philosophy is completely different. Instead of arbitrary data,
its data has structure--it's a JSON object.  Instead of only being able to
query by keys, you can upload functions that index your data for you and then
you can call those functions.  All of this is done over a very simple REST
interface.</p>
<p>But none of this really matters.  None of these really set CouchDB apart,
because you could just encode JSON data and store it in Tokyo Cabinet, you can
maintain your own indexes of data fairly easily, and you can build a simple
REST API in a matter of days, if not hours.</p>
<p>What really sets CouchDB apart from the pack is it's innovative replication
strategy.  It was written in such a way that nodes which are disconnected for
long periods of time can reconnect, sync with each other, and reconcile their
differences in a way that no other database (since Lotus Notes?) could do.</p>
<p>It's functionality that allows for interesting and new distributed types of
applications and data that I think could possibly change the way we take our
applications offline.  I imagine that some day every computer will come with
CouchDB pre-installed and it'll be a data store that we use without even
knowing that we're using it.</p>
<p>However, I wouldn't choose it for a super high scalability site with lots of
data and sharding and replication and high availability and all those
buzzwords, because I'm not convinced it's the right tool for that job, but I
am convinced that its replication strategy will keep it relevant for years to
come.</p>
</div>
<div class="section" id="redis">
<h4>Redis</h4>
<p>Wow, looking at the bullet points this database seems to do just about
everything, perfectly!  Yeah, it's a bit prone to hyperbole and there are some
great things about it, but a lot of it is hot air.  For example, it claims to
support sharding but really all it does is have the client run a hash function
on its key and use that to determine which server to send its value to.  This
is something that any database can do.</p>
<p>When you get down to it, Redis is a key-value store which provides a richer
API than something like Tokyo Cabinet.  It does more operations in memory,
only periodically flushing to disk, so there's more of a risk that you could
lose data on a crash.  The tradeoff is that it's extremely fast, and it does
some neat things like allow you to append a value to the end of a list of
items already stored for a given key.</p>
<p>It also has atomic operations.  This is honestly the only reason I find this
project interesting, because the atomic operation support that it has means
that it can be turned into a best-of-breed tally server.  If you are building
a server to keep real-time counts of various things, you would be remiss to
overlook Redis as a very viable option.</p>
</div>
<div class="section" id="cassandra">
<h4>Cassandra</h4>
<p>It's good to save the best for last, and that's exactly what I've done as I
find Cassandra to be easily the most interesting non-relational database out
there today.  Originally developed by Facebook, it was developed by some of
the key engineers behind Amazon's famous Dynamo database.</p>
<p>Cassandra can be thought of as a huge 4-or-5-level associative array, where
each dimension of the array gets a free index based on the keys in that level.
The real power comes from that optional 5th level in the associative array,
which can turn a simple key-value architecture into an architecture where you
can now deal with sorted lists, based on an index of your own specification.
That 5th level is called a SuperColumn, and it's one of the reasons that
Cassandra stands out from the crowd.</p>
<p>Cassandra has no single points of failure, and can scale from one machine to
several thousands of machines clustered in different data centers.  It has no
central master, so any data can be written to any of the nodes in the cluster,
and can be read likewise from any other node in the cluster.</p>
<p>It provides knobs that can be tweaked to slide the scale between consistency
and availability, depending on your particular application and problem domain.
And it provides a high availability guarantee, that if one node goes down,
another node will step in to replace it smoothly.</p>
<p>Writing about all the features of Cassandra is a whole different post, but I
am convinced that its data model is rich enough to support a wide variety of
applications while providing the kind of extreme scalability and high
availability features that few other databases can achieve--all while
maintaining a lower latency than other solutions out there.</p>
</div>
<div class="section" id="conclusion">
<h4>Conclusion</h4>
<p>There are many other non-relational databases out there: HBase and Hypertable,
which are replicating Google's BigTable despite its complexity and problems
with single points of failure.  MongoDB is another database that has been
getting some traction, but it seems to be a jack of all trades, master of
none.  In short, the above databases are the ones that I find interesting
right now, and I would use each of them for different use cases.</p>
<p>What do you all think about this whole non-relational database thing?  Do you
agree with my thoughts or do you think I'm full of it?</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/databases/">Databases</a></li>
      
        <li><a href="/blog/categories/editorial/">Editorial</a></li>
      
        <li><a href="/blog/categories/nosql/">NoSQL</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Flojax: A unobtrusive and easy strategy for creating AJAX-style web applications]]></title>
        <link href="http://eflorenzano.com/blog/2009/04/03/flojax-unobtrusive-and-easy-strategy-creating-ajax/"/>
        <updated>2009-04-03T02:05:18</updated>
        <id>http://eflorenzano.com/blog/2009/04/03/flojax-unobtrusive-and-easy-strategy-creating-ajax/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2009/04/03/flojax-unobtrusive-and-easy-strategy-creating-ajax/">Flojax: A unobtrusive and easy strategy for creating AJAX-style web applications</a></h3>
<p class="datetime">Apr 03, 2009</p>
<div class="document">
<p>Writing AJAX-style web applications can be very tedious.  If you're using XML
as your transport layer, you have to parse the XML before you can work with it.
It's a bit easier if you're using JSON, but once you have parsed the data, the
data still needs to be turned into HTML markup that matches the current markup
on the page.  Finally, the newly created markup needs to be inserted into the
correct place in the DOM, and any event handlers need to be attached to the
appropriate newly-inserted markup.</p>
<p>So there's the parsing, the markup assembly, the DOM insertion, and finally the
event handler attachment.  Most of the time, people tend to write custom code
for each element that needs asynchronous updating.  There are several drawbacks
with this scenario, but the most frustrating part is probably that the
presentation logic is implemented twice--once in a templating language on the
server which is designed specifically for outputting markup, and again on the
client with inline Javascript.  This leads to problems both in the agility and
in the maintainability of this type of application.</p>
<p>With flojax, this can all be  accomplished with one generalized implementation.
The same server-side logic that generates the data for the first synchronous
request can be used to respond to subsequent asynchronous requests, and
unobtrusive attributes specify what to do for the rest.</p>
<div class="section" id="the-basics">
<h4>The Basics</h4>
<p>The first component for creating an application using the flojax strategy is to
break up the content that you would like to reload asynchronously into smaller
fragments.  As a basic example of this, let's examine the case where there is a
panel of buttons that you would like to turn into asynchronous requests instead
of full page reloads.</p>
<p>The rendered markup for a fragment of buttons could look something like this:</p>
<pre class="code html literal-block">
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;buttons&quot;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/vote/up/item1/&quot;</span><span class="nt">&gt;</span>Vote up<span class="nt">&lt;/a&gt;</span>
    <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/vote/down/item1/&quot;</span><span class="nt">&gt;</span>Vote down<span class="nt">&lt;/a&gt;</span>
    <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/favorite/item1/&quot;</span><span class="nt">&gt;</span>Add to your favorites<span class="nt">&lt;/a&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</pre>
<p>In a templating language, the logic might look something like this:</p>
<pre class="code html literal-block">
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;buttons&quot;</span><span class="nt">&gt;</span>
    {% if voted %}
        <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/vote/clear/{{ item.id }}/&quot;</span><span class="nt">&gt;</span>Clear your vote<span class="nt">&lt;/a&gt;</span>
    {% else %}
        <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/vote/up/{{ item.id }}/&quot;</span><span class="nt">&gt;</span>Vote up<span class="nt">&lt;/a&gt;</span>
        <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/vote/down/{{ item.id }}/&quot;</span><span class="nt">&gt;</span>Vote down<span class="nt">&lt;/a&gt;</span>
    {% endif %}
    {% if favorited %}
        <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/favorite/{{ item.id }}/&quot;</span><span class="nt">&gt;</span>Add to your favorites<span class="nt">&lt;/a&gt;</span>
    {% else %}
        <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/unfavorite/{{ item.id }}/&quot;</span><span class="nt">&gt;</span>Remove from your favorites<span class="nt">&lt;/a&gt;</span>
    {% endif %}
<span class="nt">&lt;/div&gt;</span>
</pre>
<p>(Typically you wouldn't use anchors to do operations that can change state on
the server, so you can imagine this would be accomplished using forms.  However,
for demonstration and clarity purposes I'm going to leave these as links.)</p>
<p>Now that we have written a fragment, we can start using it in our larger
templates by way of an include, which might look something like this:</p>
<pre class="code html literal-block">
...
<span class="nt">&lt;p&gt;</span>If you like this item, consider favoriting or voting on it:<span class="nt">&lt;/p&gt;</span>
{% include &quot;fragments/buttons.html&quot; %}
...
</pre>
<p>To change this from being standard links to being asynchronously updated, we
just need to annotate a small amount of data onto the relevant links in the
fragment.</p>
<pre class="code html literal-block">
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;buttons&quot;</span><span class="nt">&gt;</span>
    {% if voted %}
        <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/vote/clear/{{ item.id }}/&quot;</span> <span class="na">class=</span><span class="s">&quot;flojax&quot;</span> <span class="na">rel=</span><span class="s">&quot;buttons&quot;</span><span class="nt">&gt;</span>Clear your vote<span class="nt">&lt;/a&gt;</span>
    {% else %}
        <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/vote/up/{{ item.id }}/&quot;</span> <span class="na">class=</span><span class="s">&quot;flojax&quot;</span> <span class="na">rel=</span><span class="s">&quot;buttons&quot;</span><span class="nt">&gt;</span>Vote up<span class="nt">&lt;/a&gt;</span>
        <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/vote/down/{{ item.id }}/&quot;</span> <span class="na">class=</span><span class="s">&quot;flojax&quot;</span> <span class="na">rel=</span><span class="s">&quot;buttons&quot;</span><span class="nt">&gt;</span>Vote down<span class="nt">&lt;/a&gt;</span>
    {% endif %}
    {% if favorited %}
        <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/favorite/{{ item.id }}/&quot;</span> <span class="na">class=</span><span class="s">&quot;flojax&quot;</span> <span class="na">rel=</span><span class="s">&quot;buttons&quot;</span><span class="nt">&gt;</span>Add to your favorites<span class="nt">&lt;/a&gt;</span>
    {% else %}
        <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/unfavorite/{{ item.id }}/&quot;</span> <span class="na">class=</span><span class="s">&quot;flojax&quot;</span> <span class="na">rel=</span><span class="s">&quot;buttons&quot;</span><span class="nt">&gt;</span>Remove from your favorites<span class="nt">&lt;/a&gt;</span>
    {% endif %}
<span class="nt">&lt;/div&gt;</span>
</pre>
<p>That's it!  At this point, all of the click events that happen on these links
will be changed into POST requests, and the response from the server will be
inserted into the DOM in place of this div with the class of &quot;buttons&quot;.  If you
didn't catch it, all that was done was to add the &quot;flojax&quot; class onto each of
the links, and add a rel attribute that refers to the class of the parent node
in the DOM to be replaced--in this case, &quot;buttons&quot;.</p>
<p>Of course, there needs to be a server side component to this strategy, so that
instead of rendering the whole page, the server just renders the fragment.  Most
modern Javascript frameworks add a header to the request to let the server know
that the request was made asynchronously from Javascript.  Here's how the code
on the server to handle the flojax-style request might look (in a kind of
non-web-framework-specific Python code):</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">vote</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">direction</span><span class="p">,</span> <span class="n">item_id</span><span class="p">):</span>
    <span class="n">item</span> <span class="o">=</span> <span class="n">get_item</span><span class="p">(</span><span class="n">item_id</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">direction</span> <span class="o">==</span> <span class="s">'clear'</span><span class="p">:</span>
        <span class="n">clear_vote</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="n">item</span><span class="p">)</span>
    <span class="k">elif</span> <span class="n">direction</span> <span class="o">==</span> <span class="s">'up'</span><span class="p">:</span>
        <span class="n">vote_up</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="n">item</span><span class="p">)</span>
    <span class="k">elif</span> <span class="n">direction</span> <span class="o">==</span> <span class="s">'down'</span><span class="p">:</span>
        <span class="n">vote_down</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="n">item</span><span class="p">)</span>

    <span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="s">'voted'</span><span class="p">:</span> <span class="n">direction</span> <span class="o">!=</span> <span class="s">'clear'</span><span class="p">,</span> <span class="s">'item'</span><span class="p">:</span> <span class="n">item</span><span class="p">}</span>

    <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">is_ajax</span><span class="p">():</span>
        <span class="k">return</span> <span class="n">render_to_response</span><span class="p">(</span><span class="s">'fragments/buttons.html'</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>

    <span class="c"># ... the non-ajax implementation details go here</span>

    <span class="k">return</span> <span class="n">render_to_response</span><span class="p">(</span><span class="s">'items/item_detail.html'</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
</pre>
<p>There are several advantages to writing your request handlers in this way.
First, note that we were able to totally reuse the same templating logic from
before--we just render out the fragment instead of including it in a larger
template.  Second, we have provided a graceful degradation path where users
without javascript are able to interact with the site as well, albeit with a
worse user experience.</p>
<p>That's really all there is to writing web applications using the flojax
strategy.</p>
</div>
<div class="section" id="implementation-details">
<h4>Implementation Details</h4>
<p>I don't believe that the Javascript code for this method can be easily reused,
because each web application tends to have a different way of showing errors and
other such things to the user.  In this post, I'm going to provide a reference
implementation (using jQuery) that can be used as a starting point for writing
your own versions.  The bulk of the work is done in a function that is called on
every page load, called <tt class="docutils literal">flojax_init</tt>.</p>
<pre class="code javascript literal-block">
<span class="kd">function</span> <span class="nx">flojax_clicked</span><span class="p">(</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">link</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">parent</span> <span class="o">=</span> <span class="nx">link</span><span class="p">.</span><span class="nx">parents</span><span class="p">(</span><span class="s1">'.'</span> <span class="o">+</span> <span class="nx">link</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'rel'</span><span class="p">));</span>

    <span class="kd">function</span> <span class="nx">successCallback</span><span class="p">(</span><span class="nx">data</span><span class="p">,</span> <span class="nx">textStatus</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">parent</span><span class="p">.</span><span class="nx">replaceWith</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>
        <span class="nx">flojax_init</span><span class="p">(</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="kd">function</span> <span class="nx">errorCallback</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="nx">textStatus</span><span class="p">,</span> <span class="nx">errorThrown</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">alert</span><span class="p">(</span><span class="s1">'There was an error in performing the requested operation'</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">(</span><span class="p">{</span>
        <span class="s1">'url'</span><span class="o">:</span> <span class="nx">link</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'href'</span><span class="p">),</span>
        <span class="s1">'type'</span><span class="o">:</span> <span class="s1">'POST'</span><span class="p">,</span>
        <span class="s1">'data'</span><span class="o">:</span> <span class="s1">''</span><span class="p">,</span>
        <span class="s1">'success'</span><span class="o">:</span> <span class="nx">successCallback</span><span class="p">,</span>
        <span class="s1">'error'</span><span class="o">:</span> <span class="nx">errorCallback</span>
    <span class="p">});</span>

    <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">flojax_init</span><span class="p">(</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">$</span><span class="p">(</span><span class="s1">'a.flojax'</span><span class="p">).</span><span class="nx">live</span><span class="p">(</span><span class="s1">'click'</span><span class="p">,</span> <span class="nx">flojax_clicked</span><span class="p">);</span>
<span class="p">}</span>
</pre>
<p>There's really not a lot of code there.  It POSTS to the given URL and replaces
the specified parent class with the content of the response, and then
re-initializes the flojax handler.  The re-initialization could even be done in
a smarter way, as well, by targeting only the newly inserted content.  Also, you
might imagine that an alert message probably wouldn't be such a great user
experience, so you could integrate error messages into some sort of Javascript
messaging or growl-style system.</p>
</div>
<div class="section" id="extending-flojax">
<h4>Extending Flojax</h4>
<p>Often times you'll want to do other things on the page when the asynchronous
request happens.  For our example, maybe there is some kind of vote counter that
needs to be updated or some other messages that need to be displayed.</p>
<p>In these cases, I have found that using hidden input elements in the fragments
can be useful for transferring that information from the server to the client.
As long as the value in the hidden elements adheres to some predefined structure
that your client knows about (it could even be something like JSON if you need
to go that route).</p>
<p>If what you want can't be done by extending the fragments in this way, then
flojax isn't the right strategy for that particular feature.</p>
</div>
<div class="section" id="limitations">
<h4>Limitations</h4>
<p>This technique cannot solve all of the world's problems.  It can't even solve
all of the problems involved in writing an AJAX-style web application.  It can,
however, handle a fair amount of simple cases where all you want to do is
quickly set up a way for a user's action to replace content on a page.</p>
<p>Some specific examples of things that flojax can't help with are if a user
action can possibly update many items on a page, or if something needs to happen
without a user clicking on a link.  In these situations, you are better off
coding a custom solution instead of trying to shoehorn it into the flojax
workflow.</p>
</div>
<div class="section" id="conclusion">
<h4>Conclusion</h4>
<p>Writing AJAX-style web applications is usually tedious, but using the techniques
that I've described, a large majority of the tedious work can be reduced.  By
using the same template code for rendering the page initially as with subsequent
asynchronous requests, you ensure that code is not duplicated.  By rendering HTML
fragments, the client doesn't have to go through the effort of parsing the
output and converting the result into correct DOM objects.  Finally, by using a
few unobtrusive conventions (like the <tt class="docutils literal">rel</tt> attribute and the <tt class="docutils literal">flojax</tt>
class), the Javascript code that a web application developer writes is able to
be reused again and again.</p>
<p>I don't believe that any of the details that I'm describing are new.  In fact,
people have been doing most of these things for years.  What I think may in fact
be new is the generalization of the sum of these techniques in this way.  It's
still very much a work in progress, though.  As I use flojax more and more, I
hope to find not only places where it can be extended to cover more use cases,
but also its limitations and places where it makes more sense to use another
approach.</p>
<p>What do you think about this technique?  Are you using any techniques like this
for your web applications?  If so, how do they differ from what I've described?</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/javascript/">Javascript</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/ajax/">AJAX</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Tagging cache keys for O(1) batch invalidation]]></title>
        <link href="http://eflorenzano.com/blog/2009/03/02/tagging-cache-keys-o1-batch-invalidation/"/>
        <updated>2009-03-02T04:46:37</updated>
        <id>http://eflorenzano.com/blog/2009/03/02/tagging-cache-keys-o1-batch-invalidation/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2009/03/02/tagging-cache-keys-o1-batch-invalidation/">Tagging cache keys for O(1) batch invalidation</a></h3>
<p class="datetime">Mar 02, 2009</p>
<div class="document">
<p>Recently I've been spending some quality time trying to decrease page load times and decrease the number of database accesses on a site I'm working on.    As you would probably suspect, that means dealing with caching.  One common thing that I need to do, however, is invalidate a large group of cache keys when some action takes place.  I've devised a pattern for doing this, and while I'm sure it's not novel, I haven't seen any recent write-ups of this technique.  The base idea is that we're going to add another thin cache layer, and use the value from that first layer in the key to the second layer.</p>
<p>First, let me give a concrete example of the problem that I'm trying to solve.  I'm going to use Django/Python from here on in, but you could substitute anything else, as this pattern should work across other frameworks and even other languages.</p>
<pre class="code python literal-block">
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">Favorite</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">user</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">User</span><span class="p">)</span>
    <span class="n">item</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">Item</span><span class="p">)</span>
    <span class="n">date_added</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">u'</span><span class="si">%s</span><span class="s"> has favorited </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">item</span><span class="p">)</span>
</pre>
<p>Given this model, now let's say that we have a function that gets the Favorite instances for a given user, which might look like this:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">get_favorites</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="n">faves</span> <span class="o">=</span> <span class="n">Favorite</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">user</span><span class="o">=</span><span class="n">user</span><span class="p">)</span>
    <span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">faves</span><span class="p">[</span><span class="n">start</span><span class="p">:</span><span class="n">end</span><span class="p">])</span>
</pre>
<p>There's not much here yet--we're simply filtering to only include the Favorite instances for the given user, slicing it based on the given start and end numbers, and forcing evaluation before returning a list.  Now let's start thinking about how we will cache this.  We'll start by just implementing a naive cache strategy, which in this case simply means that the cache is never invalidated:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.core.cache</span> <span class="kn">import</span> <span class="n">cache</span>

<span class="k">def</span> <span class="nf">get_favorites</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="n">key</span> <span class="o">=</span> <span class="s">'get_favorites-</span><span class="si">%s</span><span class="s">-</span><span class="si">%s</span><span class="s">-</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">)</span>
    <span class="n">faves</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">faves</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">faves</span>
    <span class="n">faves</span> <span class="o">=</span> <span class="n">Favorite</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">user</span><span class="o">=</span><span class="n">user</span><span class="p">)[</span><span class="n">start</span><span class="p">:</span><span class="n">end</span><span class="p">]</span>
    <span class="n">cache</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">faves</span><span class="p">),</span> <span class="mi">86400</span> <span class="o">*</span> <span class="mi">7</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">faves</span>
</pre>
<p>Now we come to the hard part: how do we invalidate those cache keys?  It's especially tricky because we don't know exactly what keys have been created.  What combinations of start/end have been given? We could invalidate all combinations of start/end up to some number, but that's horribly inefficient and wasteful.  So what do we do?  My solution is to introduce another layer.  Let me explain with code:</p>
<pre class="code python literal-block">
<span class="kn">import</span> <span class="nn">uuid</span>
<span class="kn">from</span> <span class="nn">django.core.cache</span> <span class="kn">import</span> <span class="n">cache</span>

<span class="k">def</span> <span class="nf">favorite_list_hash</span><span class="p">(</span><span class="n">user</span><span class="p">):</span>
    <span class="n">key</span> <span class="o">=</span> <span class="s">'favorite-list-hash-</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">,)</span>
    <span class="n">cached_key_hash</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">cached_key_hash</span><span class="p">:</span>
        <span class="n">key_hash</span> <span class="o">=</span> <span class="n">cached_key_hash</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">key_hash</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid</span><span class="o">.</span><span class="n">uuid4</span><span class="p">())</span>
        <span class="n">cache</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">key_hash</span><span class="p">,</span> <span class="mi">86400</span> <span class="o">*</span> <span class="mi">7</span><span class="p">)</span>
    <span class="k">return</span> <span class="p">(</span><span class="n">key_hash</span><span class="p">,</span> <span class="ow">not</span> <span class="n">cached_key_hash</span><span class="p">)</span>
</pre>
<p>Essentially what this gives us is a temporary unique identifier for each user, that's either stored in cache or generated and stuffed into the cache.  How does this help?  We can use this identifier in the <em>keys</em> to the <tt class="docutils literal">get_favorites</tt> function:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.core.cache</span> <span class="kn">import</span> <span class="n">cache</span>

<span class="k">def</span> <span class="nf">get_favorites</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="n">key_hash</span><span class="p">,</span> <span class="n">created</span> <span class="o">=</span> <span class="n">favorite_list_hash</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
    <span class="n">key</span> <span class="o">=</span> <span class="s">'get_favorites-</span><span class="si">%s</span><span class="s">-</span><span class="si">%s</span><span class="s">-</span><span class="si">%s</span><span class="s">-</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">,</span> <span class="n">key_hash</span><span class="p">)</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">created</span><span class="p">:</span>
        <span class="n">faves</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">faves</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">faves</span>
    <span class="n">faves</span> <span class="o">=</span> <span class="n">Favorite</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">user</span><span class="o">=</span><span class="n">user</span><span class="p">)[</span><span class="n">start</span><span class="p">:</span><span class="n">end</span><span class="p">]</span>
    <span class="n">cache</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">faves</span><span class="p">),</span> <span class="mi">86400</span> <span class="o">*</span> <span class="mi">7</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">faves</span>
</pre>
<p>As you can see, the first thing we do is grab that hash for the user, then we use it as the last part of the key for the function.  The whole <tt class="docutils literal">if not created</tt> thing is just an optimization that helps to avoid cache fetches when we know they will fail.  Here's the great thing now: invalidating all of the different cached versions of <tt class="docutils literal">get_favorite</tt> for a given user is a single function call:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.core.cache</span> <span class="kn">import</span> <span class="n">cache</span>

<span class="k">def</span> <span class="nf">clear_favorite_cache</span><span class="p">(</span><span class="n">user</span><span class="p">):</span>
    <span class="n">cache</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="s">'favorite-list-hash-</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">id</span><span class="p">,))</span>
</pre>
<p>By deleting that single key, the next time <tt class="docutils literal">get_favorites</tt> is called, it will call <tt class="docutils literal">favorite_list_hash</tt> which will result in a cache miss, which will mean it will generate a new unique identifier and stuff it in cache, meaning that all of the keys for <tt class="docutils literal">get_favorites</tt> are instantly different.  I think that this is a powerful pattern that allows for coarser-grained caching without really sacrificing much of anything.</p>
<p>There is one aspect of this technique that some people will not like: it leaves old cache keys around taking up memory.  I don't consider this a problem because memory is cheap these days and Memcached is generally smart about evicting the least recently used data.</p>
<p>I'm interested though, since I don't see people posting much about nontrivial cache key generation and invalidation.  How are you doing this type of thing?  Are most people just doing naive caching and calling that good enough?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/memcached/">Memcached</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/software-development/">Software Development</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Notice Something Different?]]></title>
        <link href="http://eflorenzano.com/blog/2009/03/01/notice-something-different/"/>
        <updated>2009-03-01T01:24:25</updated>
        <id>http://eflorenzano.com/blog/2009/03/01/notice-something-different/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2009/03/01/notice-something-different/">Notice Something Different?</a></h3>
<p class="datetime">Mar 01, 2009</p>
<div class="document">
<p>Several months ago after rolling out the lifestreaming features on this site, I became unhappy with the way that the design scaled with the new feature.  Around that time I did a purely-visual refactor (just templates and CSS changed--no code), but it has sat untouched on my hard drive for several months.</p>
<p>Today I ran across that redesign and since it essentially looked complete, I deployed it to the site.  I'm still not very happy with the design, but I think that this time it's at least easier to read than the last one, which had become very cluttered and difficult to navigate and read.</p>
<p>Let me know what you think in the comments.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
        <li><a href="/blog/categories/design/">Design</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Writing Blazing Fast, Infinitely Scalable, Pure-WSGI Utilities]]></title>
        <link href="http://eflorenzano.com/blog/2009/01/08/writing-blazing-fast-infinitely-scalable-pure-wsgi/"/>
        <updated>2009-01-08T10:29:10</updated>
        <id>http://eflorenzano.com/blog/2009/01/08/writing-blazing-fast-infinitely-scalable-pure-wsgi/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2009/01/08/writing-blazing-fast-infinitely-scalable-pure-wsgi/">Writing Blazing Fast, Infinitely Scalable, Pure-WSGI Utilities</a></h3>
<p class="datetime">Jan 08, 2009</p>
<div class="document">
<p>Lately I've really fallen in love with writing utilities whose interface is
simply HTTP.  By making it accessible via HTTP, it's really easy to write
clients that talk to the utility and, if the need arises, there are lots of
tools that already exist for doing things with HTTP, like load balancing and
caching, etc.</p>
<p>While it would be easy to use a framework to build these utilities, lately I've
been choosing not to do so.  Web frameworks like <a class="reference external" href="http://www.djangoproject.com/">Django</a> and <a class="reference external" href="http://pylonshq.com/">Pylons</a> are great
when you need to build a fully-featured web application that will be accessible
by people.  When it will only be computers talking to the service, however, a
lot of the machinery provided by frameworks is unneeded and will only slow your
utility down.  Instead of using a framework, we're going to write a pure <a class="reference external" href="http://wsgi.org/wsgi/">WSGI</a>
application.</p>
<div class="section" id="an-example-music-discovery-website">
<h4>An Example: Music Discovery Website</h4>
<p>This has all been very abstract, so let's take an example: Suppose you run a
music discovery website that lets you play songs online.  Next to each song, you
simply want to display how many times the song has been played.</p>
<p>One solution to that problem could be to have a <tt class="docutils literal">play_count</tt> column on the
table where the song metadata is stored.  Every time someone plays the song, you
could issue an <tt class="docutils literal">UPDATE</tt> on the row and increase the <tt class="docutils literal">play_count</tt> by one.
This solution will work while your site is small, but as more and more people
begin using the application, the number of writes to your database is going to
kill its performance.</p>
<p>A much more robust and scalable solution is to append a new line to a text
log file every time a song is played, and have a process run regularly to scoop
up all of the log files and update those <tt class="docutils literal">play_count</tt> fields in the database.</p>
<p>However, even if you have that regular process run once every hour, there's
still too great a lag time between when a user takes an action and when they see
the results of that action.  This is where our WSGI utility comes into play. It
can serve as a realtime play counter to count the plays in between the time when
the logs are analyzed and the <tt class="docutils literal">play_count</tt> columns updated.</p>
</div>
<div class="section" id="song-play-counter">
<h4>Song Play Counter</h4>
<p>We can design the interface for our WSGI song play counter utility any way that
we like, but I'm going to try to keep it as <a class="reference external" href="http://en.wikipedia.org/wiki/Representational_State_Transfer">RESTful</a> as I can.  The interface
will look like this:</p>
<ul class="simple">
<li><tt class="docutils literal">GET /song/SONGID</tt> will return the current play count of the given song</li>
<li><tt class="docutils literal">POST /song/SONGID</tt> will increment the play count of the given song by one, and return its new value</li>
<li><tt class="docutils literal">GET /</tt> will return a mapping of all songs registered to their respective play counts</li>
<li><tt class="docutils literal">DELETE /</tt> will clear the whole mapping</li>
</ul>
<p>So let's get started.  First, I always like to start with a very basic skeleton:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
    <span class="n">start_response</span><span class="p">(</span><span class="s">'200 OK'</span><span class="p">,</span> <span class="p">[(</span><span class="s">'content-type'</span><span class="p">,</span> <span class="s">'text/plain'</span><span class="p">)])</span>
    <span class="k">return</span> <span class="p">(</span><span class="s">'Hello world!'</span><span class="p">,)</span>
</pre>
<p>This does what you would imagine, returns <tt class="docutils literal">Hello world!</tt> to each and every
request that it receives.  Not very useful, so let's make it more interesting:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
<span class="n">counts</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
    <span class="k">global</span> <span class="n">counts</span>
    <span class="n">path</span> <span class="o">=</span> <span class="n">environ</span><span class="p">[</span><span class="s">'PATH_INFO'</span><span class="p">]</span>
    <span class="n">method</span> <span class="o">=</span> <span class="n">environ</span><span class="p">[</span><span class="s">'REQUEST_METHOD'</span><span class="p">]</span>
    <span class="k">if</span> <span class="n">path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">'/song/'</span><span class="p">):</span>
        <span class="n">song_id</span> <span class="o">=</span> <span class="n">path</span><span class="p">[</span><span class="mi">6</span><span class="p">:]</span>
        <span class="k">if</span> <span class="n">method</span> <span class="o">==</span> <span class="s">'GET'</span><span class="p">:</span>
            <span class="n">start_response</span><span class="p">(</span><span class="s">'200 OK'</span><span class="p">,</span> <span class="p">[(</span><span class="s">'content-type'</span><span class="p">,</span> <span class="s">'text/plain'</span><span class="p">)])</span>
            <span class="k">return</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">counts</span><span class="p">[</span><span class="n">song_id</span><span class="p">]),)</span>
        <span class="k">elif</span> <span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span>
            <span class="n">counts</span><span class="p">[</span><span class="n">song_id</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="n">start_response</span><span class="p">(</span><span class="s">'200 OK'</span><span class="p">,</span> <span class="p">[(</span><span class="s">'content-type'</span><span class="p">,</span> <span class="s">'text/plain'</span><span class="p">)])</span>
            <span class="k">return</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">counts</span><span class="p">[</span><span class="n">song_id</span><span class="p">]),)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">start_response</span><span class="p">(</span><span class="s">'405 METHOD NOT ALLOWED'</span><span class="p">,</span> <span class="p">[(</span><span class="s">'content-type'</span><span class="p">,</span> <span class="s">'text/plain'</span><span class="p">)])</span>
            <span class="k">return</span> <span class="p">(</span><span class="s">'Method Not Allowed'</span><span class="p">,)</span>
    <span class="n">start_response</span><span class="p">(</span><span class="s">'404 NOT FOUND'</span><span class="p">,</span> <span class="p">[(</span><span class="s">'content-type'</span><span class="p">,</span> <span class="s">'text/plain'</span><span class="p">)])</span>
    <span class="k">return</span> <span class="p">(</span><span class="s">'Not Found'</span><span class="p">,)</span>
</pre>
<p>We've now added the data structure that we're using to keep track of the counts,
which in this case is a <tt class="docutils literal">defaultdict(int)</tt>.  We're also now looking at the
request path and method, as well.  If it's a GET starting with /song/, we look
up the count and return it, and if it's a POST starting with /song/, we
increment it by one before returning it.  Also, we're doing the proper thing if
we detect a method that's not allowed: we're returning HTTP error code 405.</p>
<p>Now let's add the final bit of functionality:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
<span class="n">counts</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
    <span class="c"># ... start of app</span>
    <span class="k">if</span> <span class="n">path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">'/song/'</span><span class="p">):</span>
        <span class="c"># ... song-specific logic</span>
    <span class="k">elif</span> <span class="n">path</span> <span class="o">==</span> <span class="s">'/'</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">method</span> <span class="o">==</span> <span class="s">'GET'</span><span class="p">:</span>
            <span class="n">res</span> <span class="o">=</span> <span class="s">','</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s">'</span><span class="si">%s</span><span class="s">=</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">counts</span><span class="o">.</span><span class="n">iteritems</span><span class="p">()])</span>
            <span class="n">start_response</span><span class="p">(</span><span class="s">'200 OK'</span><span class="p">,</span> <span class="p">[(</span><span class="s">'content-type'</span><span class="p">,</span> <span class="s">'text/plain'</span><span class="p">)])</span>
            <span class="k">return</span> <span class="p">(</span><span class="n">res</span><span class="p">,)</span>
        <span class="k">elif</span> <span class="n">method</span> <span class="o">==</span> <span class="s">'DELETE'</span><span class="p">:</span>
            <span class="n">counts</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>
            <span class="n">start_response</span><span class="p">(</span><span class="s">'200 OK'</span><span class="p">,</span> <span class="p">[(</span><span class="s">'content-type'</span><span class="p">,</span> <span class="s">'text/plain'</span><span class="p">)])</span>
            <span class="k">return</span> <span class="p">(</span><span class="s">'OK'</span><span class="p">,)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">start_response</span><span class="p">(</span><span class="s">'405 METHOD NOT ALLOWED'</span><span class="p">,</span> <span class="p">[(</span><span class="s">'content-type'</span><span class="p">,</span> <span class="s">'text/plain'</span><span class="p">)])</span>
            <span class="k">return</span> <span class="p">(</span><span class="s">'Method Not Allowed'</span><span class="p">,)</span>
    <span class="c"># ... rest of app</span>
</pre>
<p>We've done basically the same thing here as we did with the previous example: we
are looking at the request path and method and doing the appropriate action.
There really is nothing very tricky going on here.  We're inventing our own
format for the case where we return the counts for all songs, but it's nothing
that will be hard to parse.</p>
<p><strong>NOTE:</strong> Generally you would want to use some sort of threading lock primitive
before accessing a global dictionary like this.  I will be using <a class="reference external" href="http://pypi.python.org/pypi/Spawning/0.7">Spawning</a> to
run this <a class="reference external" href="http://wsgi.org/wsgi/">WSGI</a> application, with a threadpool size of 0 to use cooperative
coroutines instead of standard threads, so I am able to get away without locks
for this application.  To install <a class="reference external" href="http://pypi.python.org/pypi/Spawning/0.7">Spawning</a> for yourself, just type:</p>
<pre class="code bash literal-block">
sudo easy_install Spawning
</pre>
</div>
<div class="section" id="running-the-utility">
<h4>Running the Utility</h4>
<p>Let's just take a quick look at how this utility works, from the command line:</p>
<pre class="code bash literal-block">
<span class="nv">$ </span>spawn -t 0 -p 8000 counter.application
</pre>
<p>...and in another window:</p>
<pre class="code bash literal-block">
<span class="nv">$ </span>curl http://127.0.0.1:8000/song/1
0
<span class="nv">$ </span>curl -X POST http://127.0.0.1:8000/song/1
1
<span class="nv">$ </span>curl http://127.0.0.1:8000/song/1
1
<span class="nv">$ </span>curl -X POST http://127.0.0.1:8000/song/5
1
<span class="nv">$ </span>curl -X POST http://127.0.0.1:8000/song/5
2
<span class="nv">$ </span>curl http://127.0.0.1:8000/
<span class="nv">1</span><span class="o">=</span>1,5<span class="o">=</span>2
<span class="nv">$ </span>curl -X DELETE http://127.0.0.1:8000/
OK
</pre>
<p>As you can see, it seems to be working correctly. The play counter is behaving
as expected.</p>
</div>
<div class="section" id="writing-a-client-to-talk-to-our-utility">
<h4>Writing a Client to Talk to our Utility</h4>
<p>Now that we have our WSGI utility written to keep track of the counts on our
songs, we should write a client library to communicate with this server.</p>
<pre class="code python literal-block">
<span class="kn">import</span> <span class="nn">httplib</span>

<span class="k">class</span> <span class="nc">CountClient</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">servers</span><span class="o">=</span><span class="p">[</span><span class="s">'127.0.0.1:8000'</span><span class="p">]):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">servers</span> <span class="o">=</span> <span class="n">servers</span>

    <span class="k">def</span> <span class="nf">_get_server</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">song_id</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">servers</span><span class="p">[</span><span class="n">song_id</span> <span class="o">%</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">servers</span><span class="p">)]</span>

    <span class="k">def</span> <span class="nf">_song_request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">song_id</span><span class="p">,</span> <span class="n">method</span><span class="p">):</span>
        <span class="n">conn</span> <span class="o">=</span> <span class="n">httplib</span><span class="o">.</span><span class="n">HTTPConnection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_get_server</span><span class="p">(</span><span class="n">song_id</span><span class="p">))</span>
        <span class="n">conn</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="n">method</span><span class="p">,</span> <span class="s">'/song/</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">song_id</span><span class="p">,))</span>
        <span class="n">resp</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">getresponse</span><span class="p">()</span>
        <span class="n">play_count</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">resp</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
        <span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
        <span class="k">return</span> <span class="n">play_count</span>

    <span class="k">def</span> <span class="nf">get_play_count</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">song_id</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_song_request</span><span class="p">(</span><span class="n">song_id</span><span class="p">,</span> <span class="s">'GET'</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">increment_play_count</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">song_id</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_song_request</span><span class="p">(</span><span class="n">song_id</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">get_all_play_counts</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">dct</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="k">for</span> <span class="n">server</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">servers</span><span class="p">:</span>
            <span class="n">conn</span> <span class="o">=</span> <span class="n">httplib</span><span class="o">.</span><span class="n">HTTPConnection</span><span class="p">(</span><span class="n">server</span><span class="p">)</span>
            <span class="n">conn</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'/'</span><span class="p">)</span>
            <span class="n">counts</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">getresponse</span><span class="p">()</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
            <span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">counts</span><span class="p">:</span>
                <span class="k">continue</span>
            <span class="n">dct</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="nb">dict</span><span class="p">([</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">pair</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'='</span><span class="p">))</span> <span class="k">for</span> <span class="n">pair</span> <span class="ow">in</span> <span class="n">counts</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">','</span><span class="p">)]))</span>
        <span class="k">return</span> <span class="n">dct</span>

    <span class="k">def</span> <span class="nf">reset_all_play_counts</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">status</span> <span class="o">=</span> <span class="bp">True</span>
        <span class="k">for</span> <span class="n">server</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">servers</span><span class="p">:</span>
            <span class="n">conn</span> <span class="o">=</span> <span class="n">httplib</span><span class="o">.</span><span class="n">HTTPConnection</span><span class="p">(</span><span class="n">server</span><span class="p">)</span>
            <span class="n">conn</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="s">'DELETE'</span><span class="p">,</span> <span class="s">'/'</span><span class="p">)</span>
            <span class="n">resp</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">getresponse</span><span class="p">()</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
            <span class="k">if</span> <span class="n">resp</span> <span class="o">!=</span> <span class="s">'OK'</span><span class="p">:</span>
                <span class="n">status</span> <span class="o">=</span> <span class="bp">False</span>
            <span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
        <span class="k">return</span> <span class="n">status</span>
</pre>
<p>What we have here is a simple class that converts Python method calls to the
RESTful HTTP equivalents that we have written for our WSGI utility.  The best
part about this setup, though, is that it uses a hash based on the song_id to
determine which server to connect to.  If you only ever do per-song operations,
this setup is quite literally infinitely scalable.  You could have thousands of
servers keeping track of song counts, none of them knowing about each other.
Since the decision about which server to talk to happens on the client side,
there needs to be no communication between the servers whatsoever.</p>
<p>However, if you start to use the <tt class="docutils literal">get_all_play_counts</tt> and
<tt class="docutils literal">reset_all_play_counts</tt>, then eventually after many many servers are added it
will start to get slower.</p>
<p>Let's explore this client:</p>
<pre class="code pycon literal-block">
<span class="kn"></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">countclient</span> <span class="kn">import</span> <span class="n">CountClient</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">CountClient</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">get_play_count</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="go">0
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">increment_play_count</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="go">1
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">increment_play_count</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="go">2
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">get_play_count</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="go">2
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">increment_play_count</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="go">1
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">get_all_play_counts</span><span class="p">()</span>
<span class="go">{1: 2, 5: 1}
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">reset_all_play_counts</span><span class="p">()</span>
<span class="go">True
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">get_all_play_counts</span><span class="p">()</span>
<span class="go">{}</span>
</pre>
</div>
<div class="section" id="benchmarks">
<h4>Benchmarks!</h4>
<p>I'm not a benchmarking nut in any way, shape, or form these days.  However, in
Python it's quite tough to beat pure-WSGI applications for raw speed.  Using my
MacBook Pro with a 2.5GHz Intel Core 2 Duo and 2 GB 667 MHz DDR2 SDRAM I got
these results from ApacheBench:</p>
<pre class="literal-block">
e:Desktop ericflo$ ab -n 10000 http://127.0.0.1:8000/song/1
...
Concurrency Level:      1
Time taken for tests:   7.792 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1020000 bytes
HTML transferred:       10000 bytes
Requests per second:    1283.31 [#/sec] (mean)
Time per request:       0.779 [ms] (mean)
Time per request:       0.779 [ms] (mean, across all concurrent requests)
Transfer rate:          127.83 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       2
Processing:     0    1   0.8      1      43
Waiting:        0    1   0.5      0      43
Total:          1    1   0.8      1      43
</pre>
<p>Take these results with a huge grain of salt, but suffice it to say, it's fast.
It would probably be even faster using <a class="reference external" href="http://code.google.com/p/modwsgi/">mod_wsgi</a> instead of <a class="reference external" href="http://pypi.python.org/pypi/Spawning/0.7">Spawning</a>.</p>
</div>
<div class="section" id="drawing-conclusions-from-this-exercise">
<h4>Drawing Conclusions From This Exercise</h4>
<p>I don't want to misconstrue my standpoint on this: frameworks definitely have
their place.  There's no way you would want to write an entire user-facing
application with pure WSGI unless you were using lots of middleware and stuff
and at some point you're just recreating <a class="reference external" href="http://pylonshq.com/">Pylons</a>.  But when you're writing a
HTTP utility like we did here, then I think that pure-WSGI is the way to go.</p>
<p>I'd like to touch on one more nice side effect of using pure-WSGI: You can run
it in any application server that supports WSGI.  That means
<a class="reference external" href="http://code.google.com/appengine/">Google App Engine</a>, Apache, Spawning, CherryPy, and many other containers. It
can easily be served by pure python so even on very restrictive shared hosting
it's possible to run your utility.</p>
<p>What do you think of pure-WSGI utilities?  Are you using them in your app? I'd
love to hear about it--leave me a comment and tell me your thoughts on this
subject.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/scalability/">Scalability</a></li>
      
        <li><a href="/blog/categories/wsgi/">WSGI</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[2008 in Review &amp; 2009 Goals]]></title>
        <link href="http://eflorenzano.com/blog/2009/01/03/2008-review-2009-goals/"/>
        <updated>2009-01-03T03:19:17</updated>
        <id>http://eflorenzano.com/blog/2009/01/03/2008-review-2009-goals/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2009/01/03/2008-review-2009-goals/">2008 in Review &amp; 2009 Goals</a></h3>
<p class="datetime">Jan 03, 2009</p>
<div class="document">
<p>Yesterday was the day of &quot;2008 in review&quot; posts.  I really enjoyed reading over
what people had accomplished during the year, and what they planned on doing in
the new year.  I hadn't planned on writing this post, but for some reason I'm
doing it anyway.  So here goes, not much technical stuff ahead, so if personal
stuff bores you then click away now.</p>
<div class="section" id="in-review">
<h4>2008 in Review</h4>
<p>What a fantastic year.  What a crazy year.  I don't think there's ever been a
year in my life so filled with change.  For starters, I...</p>
<ul class="simple">
<li>Learned Erlang</li>
<li>Joined <a class="reference external" href="http://twitter.com/ericflo">Twitter</a> and <a class="reference external" href="http://friendfeed.com/ericflo">FriendFeed</a></li>
<li>Drove 3 hours to caucus in Iowa (what a strange ritual that is!)</li>
<li>Met <a class="reference external" href="http://lazypython.blogspot.com/">some</a> <a class="reference external" href="http://oebfare.com/">really</a> <a class="reference external" href="http://blog.michaeltrier.com/">cool</a> <a class="reference external" href="http://jtauber.com/">people</a> at <a class="reference external" href="http://us.pycon.org/2008/about/">PyCon 2008</a></li>
<li>Became involved in the <a class="reference external" href="http://pinaxproject.com/">Pinax</a> project</li>
<li>Wrote and released my first 7 open source Django applications</li>
<li>Guest hosted <a class="reference external" href="http://thisweekindjango.com/">a podcast</a></li>
<li>Learned how to use <a class="reference external" href="http://git.or.cz/">Git</a></li>
<li>Graduated from college with bachelor's degree in Computer Science</li>
<li>Accepted a job offer with <a class="reference external" href="http://www.mochimedia.com/">Mochi Media</a></li>
<li>Moved to San Francisco</li>
<li>Released a series of <a class="reference external" href="http://thisweekindjango.com/screencasts/">14 screencasts</a> building a project from the ground up</li>
<li>Wrote <a class="reference external" href="http://www.eflorenzano.com/blog/archive/2008/11/">one blog post every day</a> in the month of November</li>
<li>Quit drinking soda</li>
<li>Participated in the most notable election of my lifetime</li>
<li>Started a <a class="reference external" href="http://www.meetup.com/The-San-Francisco-Django-Meetup-Group/">Django San Francisco local user group</a></li>
</ul>
<p>...but those are just the highlights.  It's been really interesting
transitioning from college student to the real world.  Somehow I thought that
not having homework would mean that I would have more free time to do other
things, but it turns out that you actually have less time if you have a job to
go to every day.</p>
<p>But I don't think that being a student ever stopped.  I've learned so much from
my coworkers: different ways of thinking about problems, theoretical problems,
real world challenges, prioritizing work, RESTful principles of the web, and
a whole lot about databases.  This is what I like about this industry.  However
much you know, there's more to learn, and people are generally willing to share
their expertise with you.</p>
<p>I've learned a lot about what it means to be part of a community; part of a
company.  I've learned a lot about life, this year.</p>
<p>But the learning's not over.</p>
</div>
<div class="section" id="goals-for-2009">
<h4>Goals for 2009</h4>
<p>While I'm weary of posting my goals for all the world to see, I think it's
important to codify them and make them public.  That way, maybe it'll compel me
to actually follow through on these goals.  I've tried to keep them realistic
and with a few exceptions, specific enough to be testable.  Without further ado,
here are my goals for 2009 (in no particular order):</p>
<ul class="simple">
<li>Learn a concatenative/stack-based language</li>
<li>Meet new people, especially those that I wouldn't normally meet</li>
<li>Write a virtual machine</li>
<li>Double both my blog and Twitter followership</li>
<li>Be more consistent in my contributions to the Pinax project, instead of helping in fits and spurts like I currently am</li>
<li>Post at least twice a month to this blog</li>
<li>Release some non-open source software, and maybe even charge for it</li>
<li>Work out an average of 2 times a week or more over the whole year</li>
<li>Learn <a class="reference external" href="http://processing.org/">Processing</a></li>
<li>Learn about investments, and invest 10% of my earnings each month</li>
<li>Give a talk at a conference</li>
</ul>
<p>I think that all of these goals are achievable.  In fact, I'd like to do more
than just what I listed here, but these are the ones I'm willing to commit to.
Frankly, I can't wait to see how this year shapes up.  If it turns out to be
anything like last year, I'm in for quite a ride.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/goals/">Goals</a></li>
      
        <li><a href="/blog/categories/review/">Review</a></li>
      
        <li><a href="/blog/categories/life/">Life</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[It&#39;s been a wild ride]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/30/its-been-wild-ride/"/>
        <updated>2008-11-30T23:58:11</updated>
        <id>http://eflorenzano.com/blog/2008/11/30/its-been-wild-ride/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/30/its-been-wild-ride/">It&#39;s been a wild ride</a></h3>
<p class="datetime">Nov 30, 2008</p>
<div class="document">
<p>This post is my final post in the blog-post-per-day challenge.  There have been days when I really didn't want to blog (resulting in posts <a class="reference external" href="http://www.eflorenzano.com/blog/post/why-you-should-blog/">like this</a>), and there have been days where I was excited about what I was writing about and spent a lot of time on a post (resulting in posts like <a class="reference external" href="http://www.eflorenzano.com/blog/post/easy-multi-database-support-django/">this one</a>).  It was much more difficult and time-consuming than I was expecting.  Another thing I wasn't expecting which actually kept motivating me to write more: actual traffic to this site.  Previously this site saw maybe 100 hits/day due to mostly various google hits on certain Django topics.  When I started doing the blog post-per-day thing, however, this is what my traffic turned into:</p>
<img alt="http://media.eflorenzano.com/img/analytics.png" src="http://media.eflorenzano.com/img/analytics.png" />
<p>But as I started to look at where that traffic was coming from, I realized it wasn't organic at all.  <em>(insert sad puppy face here)</em>  In fact, most of the traffic was coming from just a few sites.  Here's what my top 10 referring sites were:</p>
<img alt="http://media.eflorenzano.com/img/analytics-2.png" src="http://media.eflorenzano.com/img/analytics-2.png" />
<p>Once I found out that nearly all my traffic was coming from <a class="reference external" href="http://reddit.com/">reddit</a>, I started to try to cater towards that audience.  To reddit's credit, however, the more I tried to target content towards what I thought redditers would like, the less successful the articles did over there.  Either I was doing a bad job of writing articles for that audience, or they wisened up to my act (I'm thinking the latter is more likely).</p>
<p>I was also very surprised by which articles turned out to be the most popular.  Here's the list of articles that I thought were my best:</p>
<ol class="arabic simple">
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/easy-multi-database-support-django/">Easy Multi-Database Support for Django</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/writing-markov-chain-irc-bot-twisted-and-python/">Writing an Markov-Chain IRC Bot with Twisted and Python</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/lambda-calculus/">Lambda Calculus</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/drop-dead-simple-django-caching/">Drop-dead simple Django caching</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/using-couchdb-django/">Using CouchDB with Django</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/why-couchdb-rocks/">Why CouchDB Rocks</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/web-hooks/">&quot;Web Hooks&quot;</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/reverse-http/">Reverse HTTP</a></li>
</ol>
<p>Here's the list of my top 8 most popular articles over the past few days, in order, by traffic:</p>
<ol class="arabic simple">
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/gems-python/">Gems of Python</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/why-couchdb-sucks/">Why CouchDB Sucks</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/its-caches-all-way-down/">It's caches all the way down</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/internet-immediate-danger-collapse/">The internet is in immediate danger of collapse</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/why-use-varchar-when-you-can-use-text/">Why use VARCHAR when you can use TEXT?</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/using-couchdb-django/">Using CouchDB with Django</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/why-couchdb-rocks/">Why CouchDB Rocks</a></li>
<li><a class="reference external" href="http://www.eflorenzano.com/blog/post/secrets-django-orm/">Secrets of the Django ORM</a></li>
</ol>
<p>Interestingly enough there are only two posts that appear on both lists.  Really, it surprised me which articles got picked up and which didn't.  I suppose it has something to do with the sensational titles and the sometimes-controversial posts.  Specifically the VARCHAR/TEXT post got much much more push-back than I was expecting.  In hindsight, I was wrong to mention anything other than PostgreSQL and SQLite, as those are what I've actually done the TEXT-only experimentation in.</p>
<p>After doing <a class="reference external" href="http://showmedo.com/videos/series?name=PPN7NA155">14 screencasts</a> and now <a class="reference external" href="http://www.eflorenzano.com/blog/archive/2008/11/">30 blog posts</a> over the past few months, I'm pretty well spent in terms of creating new, original, content.  That's not to say that I'm going to stop writing here or anything like that, but certainly I won't be posting quite as much.  When I do, it will be because I legitimately have something to say, instead of because of an obligation.</p>
<p>Thanks for visiting my site while I participated in this challenge.  I hope you stick around.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/analytics/">Analytics</a></li>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
        <li><a href="/blog/categories/blogging/">blogging</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Why CouchDB Rocks]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/29/why-couchdb-rocks/"/>
        <updated>2008-11-29T22:31:31</updated>
        <id>http://eflorenzano.com/blog/2008/11/29/why-couchdb-rocks/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/29/why-couchdb-rocks/">Why CouchDB Rocks</a></h3>
<p class="datetime">Nov 29, 2008</p>
<div class="document">
<p>Last week I wrote an article called <a class="reference external" href="http://www.eflorenzano.com/blog/post/why-couchdb-sucks/">Why CouchDB Sucks</a>, which many people
correctly said should have been called &quot;What CouchDB Sucks at Doing&quot;.  Nearly
everyone pointed out that it was not designed to do the things that I was
mentioning in the article.  This time around, I'd like to focus on some of the
features about CouchDB that I think absolutely rock.</p>
<div class="section" id="couchdb-is-schema-free">
<h4>CouchDB is schema-free</h4>
<p>One of the most annoying parts of dealing with a traditional SQL database is
that you invariably need to change your schemata. This can be done usually with
some <tt class="docutils literal">ALTER TABLE</tt> statements, but other times it requires scripts and careful
use of transactions, etc.  In CouchDB, the solution is to just start using your
new schema.  No migration needed.  If it's a significant change, then you might
need to change your views slightly, but nothing as annoying as what would be
needed with SQL.</p>
<p>The other advantage of having no schema is that some types of data just aren't
well suited to having a strict schema enforced upon them.  My CouchDB-based
<a class="reference external" href="http://github.com/ericflo/django-couch-lifestream/tree/master">lifestreaming application</a> is a perfect example of the inherent flexibility of
CouchDB's schemaless design is that all kinds of disparate information can be
stored alongside each other and sorted and aggregated.  There's also no reason
that you need to use its schema-free nature this way.  You could, for example,
manually enforce a schema for certain databases, if needed.</p>
</div>
<div class="section" id="couchdb-is-restful-http">
<h4>CouchDB is RESTFUL HTTP</h4>
<p>When is the last time you tried to install MySQL or PostgreSQL drivers for your
web development platform of choice?  If you're using <tt class="docutils literal"><span class="pre">apt-get</span></tt> it's not so
bad, but for just about every other platform, it's a total pain to get these
drivers up and running.  With CouchDB, there's no need.  It speaks HTTP.  Want
to create a new database?  Send an HTTP PUT request.  Want to retrieve a
document from the database?  Send an HTTP GET.  Want to delete a database?  Send
an HTTP DELETE.  As you can see, the API is quite straightforward and if a
client library doesn't already exist for your language of choice (hint:
<a class="reference external" href="http://wiki.apache.org/couchdb/Basics">it does</a>), then it will take you only a few minutes to write one.</p>
<p>But the best part about this is that we already have so many amazing and
well-tested tools to deal with HTTP.  For example, let's say you want to store
one database on one server and another database on another server?  It's as
simple as setting up <a class="reference external" href="http://wiki.codemongers.com/Main">nginx</a> or <a class="reference external" href="http://www.danga.com/perlbal/">perlbal</a> or <a class="reference external" href="http://varnish.projects.linpro.no/">varnish</a> as a reverse proxy and
having each URL go to a different machine.  The same thing goes for transparent
caching, etc.  Oh, and also, web browsers know how to speak HTTP, too.  You
could easily write <a class="reference external" href="http://jchris.mfdz.com/code/2008/11/my_couch_or_yours__shareable_ap">whole web apps served only from CouchDB</a>.</p>
</div>
<div class="section" id="map-reduce">
<h4>Map/Reduce</h4>
<blockquote>
Map/Reduce will kill every traditional data warehousing vendor in the
market.  Those who adapt to it as a design/deployment pattern will survive,
the rest won't.</blockquote>
<p>Sounds like someone from Google must have said this, or some Hadoop evangelist,
or maybe someone who works on CouchDB.  In fact, this comes from <a class="reference external" href="http://krow.livejournal.com/622006.html">Brian Aker</a>,
a MySQL hacker who was Director of Architecture at MySQL AB and is now
developing the open source fork of MySQL named <a class="reference external" href="http://drizzle.org/wiki/Main_Page">Drizzle</a> (also a very exciting
project in its own right).  He's right, too.  Google was on to something in a
big way when they unveiled their whitepaper on <a class="reference external" href="http://labs.google.com/papers/mapreduce.html">Map/Reduce</a>.  It's not the
be-all end-all for processing and generating large data sets, but it certainly
is a proven technology for that task.</p>
<p><a class="reference external" href="http://krow.livejournal.com/622006.html">Brian</a> talks about massively multi-core machines which seem the inevitability
these days, and we will need to start writing logic that is massively
parallelizable to take advantage of these masses of CPUs.  Map/Reduce is one
way to force ourselves to write logic that can be parallelized.  It is a good
choice for any new database system to adopt for this reason, and that's why
it's great to see that CouchDB has adopted it.  It's just one more reason why
CouchDB rocks.</p>
</div>
<div class="section" id="so-much-more">
<h4>So much more</h4>
<p>I could talk about how it can handle 2,500 concurrent requests in 10mb of
resident memory usage.  I could talk about its pluggable view server backends,
so that instead of writing views in JavaScript you can write them in Python or
any other language (given the correct bindings).  I could talk about <a class="reference external" href="http://jan.prima.de/~jan/plok/archives/142-CouchDBX-Revival.html">CouchDBX</a>,
which makes installing it on the Mac, quite literally, one click.  I could even
talk about how it's written in Erlang, with an eye towards scalability.  Or
maybe about how its database store is append-only.</p>
<p>I could talk about any of those things, and more.  It just comes down to this:
CouchDB rocks.  But don't take my word for it--try it out for yourself!</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/couchdb/">CouchDB</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Drop-dead simple Django caching]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/29/drop-dead-simple-django-caching/"/>
        <updated>2008-11-29T05:30:13</updated>
        <id>http://eflorenzano.com/blog/2008/11/29/drop-dead-simple-django-caching/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/29/drop-dead-simple-django-caching/">Drop-dead simple Django caching</a></h3>
<p class="datetime">Nov 29, 2008</p>
<div class="document">
<p>Caching is easy to screw up.  Usually it's a manual process which is error-prone
and tedious.  It's actually quite easy to cache, but knowing when to invalidate
which caches becomes a lot harder.  There is a subset of caching the caching
problem that, with Django, can be done quite easily.  The underlying idea is
that every Django model has a primary key, which makes for an excellent key to
a cache.  Using this basic idea, we can cover a fairly large use case for
caching, automatically, in a much more deterministic way.  Let's begin.</p>
<p>First, we need to decide upon a setting for how long each individual item should
be saved in the cache.  I'm going to call that <tt class="docutils literal">SIMPLE_CACHE_SECONDS</tt> and
grab it like so:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>

<span class="n">SIMPLE_CACHE_SECONDS</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s">'SIMPLE_CACHE_SECONDS'</span><span class="p">,</span> <span class="mi">2592000</span><span class="p">)</span>
</pre>
<p>The next thing we need to do is be able to generate a cache key from an instance
of a model.  Thanks to Django's <tt class="docutils literal">_meta</tt> information, we can get the app label
and model name, plus the primary key, and we're all set.</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">key_from_instance</span><span class="p">(</span><span class="n">instance</span><span class="p">):</span>
    <span class="n">opts</span> <span class="o">=</span> <span class="n">instance</span><span class="o">.</span><span class="n">_meta</span>
    <span class="k">return</span> <span class="s">'</span><span class="si">%s</span><span class="s">.</span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">app_label</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">module_name</span><span class="p">,</span> <span class="n">instance</span><span class="o">.</span><span class="n">pk</span><span class="p">)</span>
</pre>
<p>So now let's start setting the cache!  My preferred way to do it is via a
signal, but you could do it in a less generic way by overriding <tt class="docutils literal">save</tt> on a
model.  My signal looks like this:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.core.cache</span> <span class="kn">import</span> <span class="n">cache</span>
<span class="kn">from</span> <span class="nn">django.db.models.signals</span> <span class="kn">import</span> <span class="n">post_save</span>

<span class="k">def</span> <span class="nf">post_save_cache</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="n">cache</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">key_from_instance</span><span class="p">(</span><span class="n">instance</span><span class="p">),</span> <span class="n">instance</span><span class="p">,</span> <span class="n">SIMPLE_CACHE_SECONDS</span><span class="p">)</span>
<span class="n">post_save</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">post_save_cache</span><span class="p">)</span>
</pre>
<p>Now that we're putting items in the cache, we should probably delete them from
the cache when the model instance is deleted:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.db.models.signals</span> <span class="kn">import</span> <span class="n">pre_delete</span>

<span class="k">def</span> <span class="nf">pre_delete_uncache</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="n">cache</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="n">key_from_instance</span><span class="p">(</span><span class="n">instance</span><span class="p">))</span>
<span class="n">pre_delete</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">pre_delete_uncache</span><span class="p">)</span>
</pre>
<p>This is all good and well, but right now we don't really have a way to get at
that information.  Cache is pretty useless if we never use it!  Our interface to
the database is through the model's <tt class="docutils literal">QuerySet</tt>, so let's make sure that our
QuerySet is making good use of our newly-populated cache.  To do so, we'll
subclass <tt class="docutils literal">QuerySet</tt>:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.db.models.query</span> <span class="kn">import</span> <span class="n">QuerySet</span>

<span class="k">class</span> <span class="nc">SimpleCacheQuerySet</span><span class="p">(</span><span class="n">QuerySet</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">filter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="n">pk</span> <span class="o">=</span> <span class="bp">None</span>
        <span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="p">(</span><span class="s">'pk'</span><span class="p">,</span> <span class="s">'pk__exact'</span><span class="p">,</span> <span class="s">'id'</span><span class="p">,</span> <span class="s">'id__exact'</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
                <span class="n">pk</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="n">val</span><span class="p">]</span>
                <span class="k">break</span>
        <span class="k">if</span> <span class="n">pk</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
            <span class="n">opts</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span>
            <span class="n">key</span> <span class="o">=</span> <span class="s">'</span><span class="si">%s</span><span class="s">.</span><span class="si">%s</span><span class="s">:</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">app_label</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">module_name</span><span class="p">,</span> <span class="n">pk</span><span class="p">)</span>
            <span class="n">obj</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">obj</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">_result_cache</span> <span class="o">=</span> <span class="p">[</span><span class="n">obj</span><span class="p">]</span>
        <span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">SimpleCacheQuerySet</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</pre>
<p>The only method that we really need to overwrite is <tt class="docutils literal">filter</tt>, since <tt class="docutils literal">get</tt>
and <tt class="docutils literal">get_or_create</tt> both just rely on filter anyway.  The first <tt class="docutils literal">for</tt> loop
in the filter method just checks to see if there is a query by <tt class="docutils literal">id</tt> or <tt class="docutils literal">pk</tt>,
and if so, then we construct a key and try to fetch it from the cache.  If we
found the item in the cache, then we place it into Django's internal result
cache.  At that point we're as good as done.  Then we just let Django do the
rest!</p>
<p>This <tt class="docutils literal">SimpleCacheQuerySet</tt> won't be used all on its own though, we need to
actually force a model to use it.  How do we do that?  We create a manager:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">SimpleCacheManager</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Manager</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">get_query_set</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">SimpleCacheQuerySet</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">model</span><span class="p">)</span>
</pre>
<p>Now that we have this transparent caching library set up, we can go around to
all of our models and import it and attach it as needed.  Here's how that might
look:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>
<span class="kn">from</span> <span class="nn">django_simplecache</span> <span class="kn">import</span> <span class="n">SimpleCacheManager</span>

<span class="k">class</span> <span class="nc">BlogPost</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
    <span class="n">body</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>

    <span class="n">objects</span> <span class="o">=</span> <span class="n">SimpleCacheManager</span><span class="p">()</span>
</pre>
<p>That's it!  Just by attaching this manager to our model we're getting all the
benefits of per-object caching right away. Of course, this isn't comprehensive.
It does hit the vast majority of use cases, though.  If you were to use this for
a real site, however, then you wouldn't be able to use <tt class="docutils literal">update</tt> method.  It's
a little bit trickier since there's no <tt class="docutils literal">post_update</tt> signal, but it's nowhere
near impossible. Let's just say that, for now, it's being left unimplemented as
an exercise for the reader. <tt class="docutils literal">in_bulk</tt> would be actually quite fun to
implement, too, because you could get all of the results possible from cache,
and all the rest could be gotten from the database, then merge those two
dictionaries before returning.</p>
<p>I think this would be a really good reusable Django application.  Essentially,
we've grown a library from the ground up that really isn't all that much code.
I think it took me 20 minutes to write the actual code, but with some serious
polish and love, this library could evolve into something that I think many
reusable apps would use to great benefit.  What do you think?  What should a
good, simple, Django caching library have?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/caching/">Caching</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Reverse HTTP]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/27/reverse-http/"/>
        <updated>2008-11-27T18:31:05</updated>
        <id>http://eflorenzano.com/blog/2008/11/27/reverse-http/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/27/reverse-http/">Reverse HTTP</a></h3>
<p class="datetime">Nov 27, 2008</p>
<div class="document">
<p>Yesterday I <a class="reference external" href="http://www.eflorenzano.com/blog/post/web-hooks/">wrote about Web Hooks</a> and how powerful it could be if one web
service sends HTTP requests to another web service.  Today I want to take that
concept one step further.  What if you tell that service that you would like it
to send a POST request back to <strong>you</strong>, whenever an event happens?  This slight
modification makes for a very powerful tool.</p>
<p>Let's take the example of popular real-time web applications like Facebook's
instant messenger or FriendFeed's &quot;Real-time&quot; view.  Both of these services make
use of a technique called <a class="reference external" href="http://cometdaily.com/2007/11/16/more-on-long-polling/">long polling</a>, where the client sends an HTTP
request and the server does not respond until it has some event to deliver.  The
client can only keep the request open for so long, so it periodically times out
and re-sends the request. (It also re-sends the request if it does receive some
data).</p>
<p>The problem with this technique is that it's really trying to turn a client into
a server.  It's really fighting against the way that HTTP wants to work.  So why
fight it?  Imagine that all of our browsers have simple, lightweight, HTTP
servers installed.  The client could request to upgrade to reverse HTTP, and
then the <em>server</em> could initiate a connection with the <em>client</em>.  Now, as events
come in to the web service, the service could directly send those updates to the
client.</p>
<p>Going back to the example of Facebook IM, here's how that would work: When I
open a Facebook page, my client sends a request to Facebook's IM server.
Facebook's IM server sends a response with the HTTP/1.1 Upgrade header reading
&quot;PTTH/0.9&quot;  (funny, huh?).  Then, the client knows to accept an HTTP connection
from Facebook's IM server.  Facebook's IM server then opens that connection with
the client, and sends HTTP POSTs every time it receives a new instant message
that the client should receive.  The client's web browser would have some
JavaScript hooks to parse the body of those requests, so that it could update
the content of the instant message window on the page.</p>
<p>Isn't this brilliant?  It directly meshes with the HTTP protocol, and makes this
system which seems like a hack right now, instantly become an elegant solution.
I really wish I could take credit for thinking this up, but I did not.  My
coworker <a class="reference external" href="http://ulaluma.com/pyx/">Donovan Preston</a> blew my mind with this a few weeks back.  If you're
looking for a more visual example of how this might work, or a reference
implementation of the protocol in action, check out <a class="reference external" href="http://wiki.secondlife.com/wiki/Reverse_HTTP">this wiki page</a>.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/reverse-http/">Reverse HTTP</a></li>
      
        <li><a href="/blog/categories/http/">HTTP</a></li>
      
        <li><a href="/blog/categories/web-hooks/">Web Hooks</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[&#34;Web Hooks&#34;]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/27/web-hooks/"/>
        <updated>2008-11-27T04:43:30</updated>
        <id>http://eflorenzano.com/blog/2008/11/27/web-hooks/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/27/web-hooks/">&#34;Web Hooks&#34;</a></h3>
<p class="datetime">Nov 27, 2008</p>
<div class="document">
<p>A few months back <a class="reference external" href="http://github.com/">GitHub</a> rolled out its implementation of something that they
call &quot;Service Hooks&quot;.  The idea behind these hooks is that when you commit
some new piece of code to GitHub, they want to be able to alert other services
that you have committed that code.  For example, one of the service hooks is
the ability to send a tweet to Twitter, and another of those hooks updates the
<a class="reference external" href="http://lighthouseapp.com/">Lighthouse</a> ticket tracker.</p>
<p>I thought this was a really good idea when they rolled it out, so I did a bit of
searching and found out that there is a larger body of work surrounding this
idea, and that body of work is called <a class="reference external" href="http://webhooks.pbwiki.com/">Web Hooks</a>.  The central idea behind
web hooks is that a user supplies a service that they use with a URL.  Then,
when that user performs an action on that service, the service agrees to send an
HTTP POST request to the user's specified URL, with some information about the
action that the user took on the service.</p>
<p>SlideShare has an excellent <a class="reference external" href="http://www.slideshare.net/progrium/web-hooks">presentation</a> deck about this idea, which likens it
to Unix pipes.  That analogy makes a lot of sense if you think about it.  With
the standard model that most websites follow today, a client can only send
requests.  This means repeated polling until the client receives the information
that it is interested in.  With web hooks, however, the service is responsible
for passing that action along to the next service.  This simple yet powerful
mechanism can allow for very advanced systems which interoperate very simply
through chaining.</p>
<p>Let's expore a concrete example of what this might look like.  A few months back
I signed up for a pro account on <a class="reference external" href="http://flickr.com/">Flickr</a>, so that I could upload some of the
pictures that I had stored on my computer.  What I did was to upload some
pictures with descriptions, and then I went and posted on Twitter some of the
links to those pictures.  I also went and added that new Flickr account to
<a class="reference external" href="http://friendfeed.com/">FriendFeed</a> so that others could see my pictures as well.</p>
<p>This was all a manual process.  If both Flickr and Twitter supported web hooks,
I could have simply set up their respective URLs and uploaded my pictures.  The
process might have happened like this:  First, the pictures are uploaded.  Then
Flickr sends a POST request to Twitter, with the description of the picture and
a link to the picture.  Twitter sends a POST request to FriendFeed, adding the
new item to my FriendFeed lifestream.</p>
<p>You could even write custom scripts to handle the web hooks. For example let's
say that I want any tweet with the name 'Kevin' to be sent to my brother's email
address.  I could add a URL to Twitter linking to a script on my computer which
scans the contents of the tweet.  If the tweet has the name 'Kevin' in it, it
would send an email.  If not, it might do nothing.</p>
<p>I think that this concept is very powerful not only in terms of rendering
trivial the interoperability between disparate services, but also in terms of
simply saving on bandwidth and computing power.  Technologies which constantly
poll resources hoping for updated content seem silly in comparison to the
powerful simplicity that web hooks provide.</p>
<p>There are definitely some drawbacks to a system like this.  Firstly, the name: I
actually can't think of a worse name for this concept.  Web hooks?!  Let's come
up with something better.  All joking aside though, this type of system does
face a serious problem when it comes to the question of reliability.  If a
script receives no POST, it could mean that either no event happened, or that
the internet connection went down for a bit, or that the service is down, or any
number of other possible things.  I think the solution for this is a hybrid
model of sparse polling in conjunction with web hooks.</p>
<p>Most of all, this technology just seems so underused.  There are ridiculously
few people who implement something like this, yet it seems like an undeniably
useful service--especially given its relative simplicity to implement.  Let's
all try to encourage the services that we use on a daily basis to support web
hooks, because by doing just that, we can make the web a lot better.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/flickr/">Flickr</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/web-services/">Web Services</a></li>
      
        <li><a href="/blog/categories/friendfeed/">FriendFeed</a></li>
      
        <li><a href="/blog/categories/twitter/">Twitter</a></li>
      
        <li><a href="/blog/categories/web-hooks/">Web Hooks</a></li>
      
        <li><a href="/blog/categories/github/">GitHub</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Screencast Competition for Pinax/Django]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/26/screencast-competition-pinaxdjango/"/>
        <updated>2008-11-26T04:47:04</updated>
        <id>http://eflorenzano.com/blog/2008/11/26/screencast-competition-pinaxdjango/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/26/screencast-competition-pinaxdjango/">Screencast Competition for Pinax/Django</a></h3>
<p class="datetime">Nov 26, 2008</p>
<div class="document">
<p>I love screencasts.  I love them at least enough to create 16 of them this year.
That's why when <a class="reference external" href="http://jtauber.com/">James Tauber</a> <a class="reference external" href="http://jtauber.com/blog/2008/11/24/first_pinax_screencast_competition/">announced</a> that the <a class="reference external" href="http://pinaxproject.com/">Pinax Project</a> would be
having a <a class="reference external" href="http://contests.pinaxproject.com/contest/3/">screencast competition</a>, it made me very very happy!</p>
<p><a class="reference external" href="http://pinaxproject.com/">Pinax</a> is already a great aide for those who want to build a website with a
great deal of functionality in a short period of time.  If you haven't checked
it out yet, I really hope that you do.  It tries to take the best of breed
Django applications and glues them together with minimal configurable code and
a set of common templates and conventions.</p>
<p>One area that Pinax could be better about, however, is documentation.  We're
working on it, but it still has a bit to go.  That's one of the reasons why this
contest is so great.  By entering a screencast into the contest, you are really
helping the Pinax community out a lot.</p>
<p>The best part about this contest, however, is that there are prizes!  One prize,
$100 at Amazon, will go to the very best screencast.  A second prize, $40 at
Amazon, will go to the second best screencast.  As of this writing, there are no
entries.  So what are you waiting for?  Head on over to the
<a class="reference external" href="http://contests.pinaxproject.com/contest/3/">contest details page</a> and enter your screencast today!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/pinax/">Pinax</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Trying to Start a Programming Meme]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/25/trying-start-programming-meme/"/>
        <updated>2008-11-25T05:13:18</updated>
        <id>http://eflorenzano.com/blog/2008/11/25/trying-start-programming-meme/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/25/trying-start-programming-meme/">Trying to Start a Programming Meme</a></h3>
<p class="datetime">Nov 25, 2008</p>
<div class="document">
<p>I've never tried to start a meme before, but since I don't really have anything
great to post about, I'd like to try to start one.  I think this one could be
particularly fun because it encourages implementation of a basic program in many
different languages.</p>
<p>Rules:</p>
<ol class="arabic simple">
<li>Implement a program that takes in a user's name and their age, and prints
hello to them once for every year that they have been alive.</li>
<li>Post these rules, the source code for your solution, and the following list
(with you included) on your blog.</li>
<li>Bonus points if you implement it in a language not yet seen on the following
list!</li>
</ol>
<p>The List:</p>
<ol class="arabic simple">
<li>[Python] <a class="reference external" href="http://www.eflorenzano.com/blog/post/trying-start-programming-meme">http://www.eflorenzano.com/blog/post/trying-start-programming-meme</a></li>
<li>[Bash] <a class="reference external" href="http://aartemenko.com/texts/bash-meme/">http://aartemenko.com/texts/bash-meme/</a></li>
<li>[C] <a class="reference external" href="http://dakrauth.com/media/site/text/hello.c">http://dakrauth.com/media/site/text/hello.c</a></li>
<li>[Java] <a class="reference external" href="http://adoleo.com/blog/2008/nov/25/programming-meme/">http://adoleo.com/blog/2008/nov/25/programming-meme/</a></li>
<li>[Python 3] <a class="reference external" href="http://mikewatkins.ca/2008/11/25/hello-meme/">http://mikewatkins.ca/2008/11/25/hello-meme/</a></li>
<li>[Ruby] <a class="reference external" href="http://stroky.l.googlepages.com/gem">http://stroky.l.googlepages.com/gem</a></li>
<li>[Ruby] <a class="reference external" href="http://im.camronflanders.com/archive/meme/">http://im.camronflanders.com/archive/meme/</a></li>
<li>[Lisp] <a class="reference external" href="http://justinlilly.com/blog/2008/nov/25/back-on-the-horse/">http://justinlilly.com/blog/2008/nov/25/back-on-the-horse/</a></li>
<li>[Lua] <a class="reference external" href="http://aartemenko.com/texts/lua-hello-meme/">http://aartemenko.com/texts/lua-hello-meme/</a></li>
<li>[Functional Python] <a class="reference external" href="http://aartemenko.com/texts/python-functional-hello-meme/">http://aartemenko.com/texts/python-functional-hello-meme/</a></li>
<li>[Erlang] <a class="reference external" href="http://surfacedepth.blogspot.com/2008/11/erics-programming-meme-in-erlang.html">http://surfacedepth.blogspot.com/2008/11/erics-programming-meme-in-erlang.html</a></li>
<li>[Haskell] <a class="reference external" href="http://jasonwalsh.us/meme.html">http://jasonwalsh.us/meme.html</a></li>
<li>[PHP] <a class="reference external" href="http://fitzgeraldsteele.wordpress.com/2008/11/25/memeing-in-php-2/">http://fitzgeraldsteele.wordpress.com/2008/11/25/memeing-in-php-2/</a></li>
<li>[Javascript] <a class="reference external" href="http://www.taylanpince.com/blog/posts/responding-to-a-programming-meme/">http://www.taylanpince.com/blog/posts/responding-to-a-programming-meme/</a></li>
<li>[Single-File Django] <a class="reference external" href="http://www.pocketuniverse.ca/archive/2008/november/27/florenzano-factor/">http://www.pocketuniverse.ca/archive/2008/november/27/florenzano-factor/</a></li>
</ol>
<p>(...and make sure to check out the comments on this post for some other fun implementations!)</p>
<p>And here's my implementation:</p>
<pre class="code python literal-block">
<span class="n">name</span> <span class="o">=</span> <span class="nb">raw_input</span><span class="p">(</span><span class="s">'Please enter your name: '</span><span class="p">)</span>
<span class="n">age</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">raw_input</span><span class="p">(</span><span class="s">'Please enter your age: '</span><span class="p">))</span>

<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="n">age</span><span class="p">):</span>
    <span class="k">print</span> <span class="s">&quot;</span><span class="si">%2d</span><span class="s">) Hello, </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
</pre>
<p>And its output:</p>
<pre class="code bash literal-block">
Please enter your name: Eric Florenzano
Please enter your age: 22
 0<span class="o">)</span> Hello, Eric Florenzano
 1<span class="o">)</span> Hello, Eric Florenzano
 2<span class="o">)</span> Hello, Eric Florenzano
 3<span class="o">)</span> Hello, Eric Florenzano
 4<span class="o">)</span> Hello, Eric Florenzano
 5<span class="o">)</span> Hello, Eric Florenzano
 6<span class="o">)</span> Hello, Eric Florenzano
 7<span class="o">)</span> Hello, Eric Florenzano
 8<span class="o">)</span> Hello, Eric Florenzano
 9<span class="o">)</span> Hello, Eric Florenzano
10<span class="o">)</span> Hello, Eric Florenzano
11<span class="o">)</span> Hello, Eric Florenzano
12<span class="o">)</span> Hello, Eric Florenzano
13<span class="o">)</span> Hello, Eric Florenzano
14<span class="o">)</span> Hello, Eric Florenzano
15<span class="o">)</span> Hello, Eric Florenzano
16<span class="o">)</span> Hello, Eric Florenzano
17<span class="o">)</span> Hello, Eric Florenzano
18<span class="o">)</span> Hello, Eric Florenzano
19<span class="o">)</span> Hello, Eric Florenzano
20<span class="o">)</span> Hello, Eric Florenzano
21<span class="o">)</span> Hello, Eric Florenzano
</pre>
<p>Well there you have it, my attempt at a programming meme.  I hope someone enjoys it!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/meme/">Meme</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Why CouchDB Sucks]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/23/why-couchdb-sucks/"/>
        <updated>2008-11-23T19:14:12</updated>
        <id>http://eflorenzano.com/blog/2008/11/23/why-couchdb-sucks/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/23/why-couchdb-sucks/">Why CouchDB Sucks</a></h3>
<p class="datetime">Nov 23, 2008</p>
<div class="document">
<p><a class="reference external" href="http://couchdb.org/">CouchDB</a> really sucks at doing some things.  That should come as no surprise, as
every technology has its advantages and its drawbacks.  The thing is, when a new
technology comes out that looks really promising and cool, everyone writes about
all of its advantages, and none of its drawbacks.  Then, people start to use it
for things it isn't very good at, and they are disappointed.  In that spirit, I
would like to talk about some of the things that (in my experience) CouchDB is
absolutely not good at, and that you shouldn't try to use it for.</p>
<p>First, it doesn't support transactions in the way that most people typically
think about them.  That means, enforcing uniqueness of one field across all
documents is not safe.  A classic example of this would be enforcing that a
username is unique.  You can check whether a username exists, and if not, create
a new one.  There is no guarantee, however, that between the time that your app
has checked for its existence, and the time that you write the new user to the
database, that some other instance of your app hasn't beat you to that write.</p>
<p>Another consequence of CouchDB's inability to support the typical notion of a
transaction is that things like inc/decrementing a value and saving it back are
also dangerous.  Fortunately there aren't many instances that you would want to
simply inc/decrement some value where you couldn't just store the individual
documents separately and aggregate them with a view.</p>
<p>Secondly, CouchDB sucks at dealing with relational data.  If your data makes a
lot of sense to be in <a class="reference external" href="http://en.wikipedia.org/wiki/Third_normal_form">3rd normal form</a>, and you try to follow that form in
CouchDB, you're going to run into a lot of trouble.  Yes, it's probably possible
with tricks with view collations, but you're constantly going to be fighting
with the system.  If your data can be reformatted to be much more denormalized,
then CouchDB will work fine.</p>
<p>Thirdly, CouchDB sucks at being a data warehouse.  In every data warehouse that
I've ever run into, people have all kinds of different requests for how to slice
the data.  And they all want it to be done, yesterday.  The problem with this is
that temporary views in CouchDB on large datasets are really slow, because it
can't use any of its normal indexing tricks.  If you by some chance have a very
rigid way of looking at your data, using CouchDB and permanent views could work
quite well.  But in 99% of cases, a <a class="reference external" href="http://en.wikipedia.org/wiki/Column-oriented_DBMS">Column-Oriented Database</a> of some sort is
a much better tool for the data warehousing job.</p>
<p>So does CouchDB suck?  No, it's by far my favorite new database technology on
the block.  What it's good at doing, it's <em>great</em> at doing, but that doesn't
mean that it should be used for everything.  With the kinds of scaling issues
that we're seeing with today's highly-interactive web applications, we need to
make use of a broad range of technologies, and use each one for its greatest
strengths.  That's called using the right tool for the job, and that's never
gone out of style.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/couchdb/">CouchDB</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[The most widely available virtual machine]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/23/most-widely-available-virtual-machine/"/>
        <updated>2008-11-23T05:37:57</updated>
        <id>http://eflorenzano.com/blog/2008/11/23/most-widely-available-virtual-machine/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/23/most-widely-available-virtual-machine/">The most widely available virtual machine</a></h3>
<p class="datetime">Nov 23, 2008</p>
<div class="document">
<p>A few months back, I had a bit of an epiphany.  I suspect I was about 5 years
too late with this epiphany, but nevertheless here it is: Microsoft,
Sun, and Adobe all have these virtual machines that they want everyone to
develop on top of.  For Microsoft it's the <a class="reference external" href="http://en.wikipedia.org/wiki/Common_Language_Runtime">CLR</a>, for Sun it's the <a class="reference external" href="http://en.wikipedia.org/wiki/Java_virtual_machine">JVM</a>, and for
Adobe it's <a class="reference external" href="http://www.adobe.com/devnet/actionscript/">AVM</a>.  The problem that each of them have is that not everyone goes
out of their way to install all of these VMs, so each vendor only has a subset
of the entire computing space.</p>
<p>My epiphany was that there is one VM which nearly every modern computer has
access to.  It's JavaScript.  Every browser developed in the past 10 years
ships with some variation of it, and some systems even come with it as a
command-line option.  Whilst they do have a big problem in terms of
standardization (or lack thereof), there is certainly a lowest common
denominator that could be useful for writing apps on top of.</p>
<p>That being the case, why don't we see more language implementations on top of
JavaScript?  There is <a class="reference external" href="http://ejohn.org/blog/processingjs/">Processing.js</a>, a port of the <a class="reference external" href="http://processing.org/">Processing</a> programming
language.  There is also <a class="reference external" href="http://cappuccino.org/">Objective J and Cappuccino</a>, a port of Objective C
and Cocoa, respectively.  Each of those language implementations have received
quite a bit of attention (both positive and negative, mind you).</p>
<p>So why don't we see Ruby, Python, or other languages implemented on top of
JavaScript?  For that matter, why don't we see more ports of apps to JavaScript?
I know that in the Python world, PyPy has a JavaScript backend, but to the best
of my knowledge that backend has been all-but-abandoned.  I think it would be
really cool if we were to see more applications and programming languages
targeting the most widely adopted virtual machine ever: JavaScript.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/javascript/">Javascript</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/john-resig/">John Resig</a></li>
      
        <li><a href="/blog/categories/ruby/">Ruby</a></li>
      
        <li><a href="/blog/categories/virtual-machines/">Virtual Machines</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Are pure client-side web apps the wave of the future?]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/22/are-pure-client-side-web-apps-wave-future/"/>
        <updated>2008-11-22T03:11:49</updated>
        <id>http://eflorenzano.com/blog/2008/11/22/are-pure-client-side-web-apps-wave-future/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/22/are-pure-client-side-web-apps-wave-future/">Are pure client-side web apps the wave of the future?</a></h3>
<p class="datetime">Nov 22, 2008</p>
<div class="document">
<p>It seems that the world of computing is always oscillating between offloading
more work to the server, and offloading more work to the client.  In the very
early days of dumb terminals, we had most of the actual computation being done
on big mainframes.  Then personal computers became more powerful, allowing for
much richer applications to be created.</p>
<p>With the advent of the internet, the landscape of computing architectures
shifted again to being done focused on the server.  Now, however, JavaScript has
become more powerful.  Combined with things like SVG and the canvas tag, we can
create extremely rich applications that take place solely in the browser.</p>
<p>Projects like <a class="reference external" href="http://incubator.apache.org/couchdb/">CouchDB</a> are even starting to open the door for
<a class="reference external" href="http://jchris.mfdz.com/code/2008/11/my_couch_or_yours__shareable_ap">truly peer-to-peer web applications</a>.  With all of this taking place, it seems
that client-side web applications are poised to see some fairly strong growth.
This is especially evident now that companies as big as Google seem interested
in the idea, with its <a class="reference external" href="http://gears.google.com/">Google Gears</a> product that allows you to &quot;work offline&quot;.
But there are certain things that need to be satisfied first.</p>
<p>We need a way of enforcing security across these apps.  It looks like some
combination of OpenID and OAuth are going to be the winners in this space, but
I've never seen a seamless implementation of either of these protocols, even by
the companies most invested in the technology.  There is a lot of work to go on
usability before authentication and authorization are ubiquitous through these
open protocols.</p>
<p>We also need to standardize more on the data interchange formats that we use to
shuttle information back and forth between these different apps.  <a class="reference external" href="http://en.wikipedia.org/wiki/Atom_(standard)">Atom</a> goes a
long way towards describing the data that we use, but its adoption is nowhere
near ubiquitous, and some sites still rely on older, more outdated, RSS
syndication formats that aren't quite up to the task.</p>
<p>But even if we standardize on some application platform (be it Google Gears or
CouchDB or some other container), security, and data interchange formats, there
are certain things that need to be considered.  For one, there are some
applications that just aren't practical to be implemented on the client.  Video
editing comes to mind (and I would know, considering I interned for <a class="reference external" href="http://eyespot.com/">eyespot</a>, a
company which was attempting to do just that).</p>
<p>Another concern is that, as we've seen with the emergence of standards for CSS
and HTML, a certain amount of rigidness is good, but a strict conformist
attitude leads to significantly stifled innovation.  If you were to write an app
that doesn't fall within the boundaries of what's possible given the agreed-upon
standards, would you still be able to go forward with the development of the
app, or would you run into resistance from those who have a stake in those
standards?</p>
<p>In all, I have a feeling that we are going to move more and more to a hybrid
approach, with much more logic being computed on the side of the client
(especially in terms of visual components and interactivity), and that much more
of the server side is going to be involved in slicing and serving up just the
raw data.  We can see this happening today with technologies like AJAX being
touted as the centerpiece of some &quot;Web Two Point Oh&quot; sites.  I'm excited to see
where this will all go, and more than excited that, being a developer during
this time, get to help shape that direction.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/javascript/">Javascript</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/couchdb/">CouchDB</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Blog Updated (now with more CouchDB)]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/21/blog-updated-now-more-couchdb/"/>
        <updated>2008-11-21T05:56:20</updated>
        <id>http://eflorenzano.com/blog/2008/11/21/blog-updated-now-more-couchdb/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/21/blog-updated-now-more-couchdb/">Blog Updated (now with more CouchDB)</a></h3>
<p class="datetime">Nov 21, 2008</p>
<div class="document">
<p>I posted a while back about <a class="reference external" href="http://www.eflorenzano.com/blog/post/using-couchdb-django/">using CouchDB with Django</a>, talking about how one might build a lifestreaming application combining the flexibility and power of <a class="reference external" href="http://incubator.apache.org/couchdb/">CouchDB</a> with the ease of use and utility of <a class="reference external" href="http://www.djangoproject.com/">Django</a>.  I even linked to <a class="reference external" href="http://github.com/ericflo/django-couch-lifestream/tree/master">the project on github</a>.  At the time I was taking a hard look at the Django-based software that was running this blog.  It needed some work, to say the least.  So I did a bit of cleanup, a LOT of reorganization, and integrated this CouchDB-based lifestreaming application into the mix.</p>
<p>There's no visual refresh--that will come some other time.  For right now, it's just a backend refresh, so for the most part nobody will notice anything.  But I can rest much easier knowing that the backend is just a little bit less of a mess.  It's also a LOT easier to deploy.  I've integrated a <a class="reference external" href="http://www.nongnu.org/fab/">Fabric</a> deployment script so that all I need to do is type:</p>
<pre class="code bash literal-block">
fab deploy
</pre>
<p>And everything gets zipped up, sent to the server, unziped, and all of the relevant processes get restarted.  Pretty cool!  That's going to allow for much more rapid iteration on the site, so changes can come more often and bugs can be fixed.</p>
<p>Because of that, expect more experimentation.  As I'm experimenting with Django stuff, I'll do a lot more public demos where the experimentations are public for the world to see and play around with.  I've got lots of ideas for Django-y experiments and it's going to be really fun to see how they shape up.</p>
<p>So what do you think?  Is the new lifestreaming stuff annoying or cool?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Lambda Calculus]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/20/lambda-calculus/"/>
        <updated>2008-11-20T05:00:09</updated>
        <id>http://eflorenzano.com/blog/2008/11/20/lambda-calculus/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/20/lambda-calculus/">Lambda Calculus</a></h3>
<p class="datetime">Nov 20, 2008</p>
<div class="document">
<p>It seems that people either love things like <a class="reference external" href="http://en.wikipedia.org/wiki/Lambda_calculus">lambda calculus</a> and eat it up,
or their eyes gloss over and they don't care or want to learn about it.  I was
firmly part of the latter group, until I took a class in college that forced
me to learn about it.  The thing is, once you learn more about a subject like
this, the less you'll understand why you were so averse to learning about it.</p>
<p>In the spirit of broadening our horizons, let's explore the lambda calculus and
see if it's as hard as it's cracked up to be.  I don't claim to be a wizard at
this stuff, and by no means am I a theoretical computer scientist, but that's
not the goal.  The goal is to cut down on the formality and see if we can expore
this stuff a bit.  First, let's look at a very basic function: addition.  In
lambda calculus it looks like this:</p>
<pre class="code text literal-block">
&gt;&gt; x. x + 1
</pre>
<p>That is, a function whose argument is named <tt class="docutils literal">x</tt>, returns the value <tt class="docutils literal">x + 1</tt>.
This looks really similar to some syntax that we have in Python.  Let's see
if we can find a corollary to help make things easier:</p>
<pre class="code python literal-block">
<span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span>
</pre>
<p>Surprisingly, the syntax is almost the same!  It's an anonymous function which
takes <tt class="docutils literal">x</tt> as its one argument and returns <tt class="docutils literal">x + 1</tt>.  Lambda calculus doesn't
have powerful enough syntax for talking about functions with multiple arguments,
though, so you may think that it's not very powerful.  Thanks to a technique
called <a class="reference external" href="http://en.wikipedia.org/wiki/Currying">currying</a>, however, we can express functions with infinite numbers of
arguments.  This is how that might look:</p>
<pre class="code text literal-block">
&gt;&gt; x. &gt;&gt; y. x + y
</pre>
<p>This is where I think the syntax starts to get in the way of readability.  Let's
see what this would look like in Python:</p>
<pre class="code python literal-block">
<span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">y</span><span class="p">:</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span>
</pre>
<p>Hmmm...it's not much more readable, but at least we can open up an interactive
interpreter to see what we're doing.  Basically what we're doing is creating a
function which returns another function.  That inner function then has access
not only to its single argument, but to its parent's argument as well.  Let's
demonstrate that this works:</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">add</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">y</span><span class="p">:</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">add</span><span class="p">(</span><span class="mi">5</span><span class="p">)(</span><span class="mi">4</span><span class="p">)</span>
<span class="go">9</span>
</pre>
<p>Now does this work if we start to change the variable names?  What if I just
decide that I can't stand the letter <tt class="docutils literal">x</tt> and don't want it inside any more of
my functions.  Well I can simply change the variable name, as long as I change
any uses of that variable.  It would work just the same:</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">add</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">z</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">y</span><span class="p">:</span> <span class="n">z</span> <span class="o">+</span> <span class="n">y</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">add</span><span class="p">(</span><span class="mi">5</span><span class="p">)(</span><span class="mi">4</span><span class="p">)</span>
<span class="go">9</span>
</pre>
<p>In this instance, we have changed all of our instances of <tt class="docutils literal">x</tt> with <tt class="docutils literal">z</tt>.
This ability to change the names of bound variables is the first rule of lambda
calculus, and it's called ?-conversion.</p>
<p>As developers, we intuitively understand the idea of function application.  We
understand that a function which takes in an argument replaces all references
to that argument with the given value, and returns a result.  For example, in
the addition function, lets go through the steps for function application:</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">add</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">y</span><span class="p">:</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">add5</span> <span class="o">=</span> <span class="n">add</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="go"># We can envision what's happening here by replacing x with 5
# add5 = lambda 5: lambda y: 5 + y
# add5 = lambda y: 5 + y
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">add5</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="go"># And now the final function application, resulting in a value
# lambda 4: 5 + 4
9</span>
</pre>
<p>This idea of function application, in lambda calculus is given the name
2-reduction.  To review, in lambda calculus syntax that process would look like
so:</p>
<pre class="code text literal-block">
(&gt;&gt; x. &gt;&gt; y. x + y) 5
(&gt;&gt; y. 5 + y) 4
5 + 4
9
</pre>
<p>Something that we also intuitively know as developers is that functions can do
the exact thing, but have very different implementations.  For example this
function:</p>
<pre class="code python literal-block">
<span class="o">&gt;&gt;</span> <span class="n">x</span><span class="o">.</span> <span class="n">x</span> <span class="o">+</span> <span class="n">x</span>
</pre>
<p>...will give the same results for all values as this function:</p>
<pre class="code python literal-block">
<span class="o">&gt;&gt;</span> <span class="n">x</span><span class="o">.</span> <span class="n">x</span> <span class="o">*</span> <span class="mi">2</span>
</pre>
<p>We understand that code which uses the former function can easily swap out the
latter and expect the program the function correctly.  This idea is called
.-conversion in lambda calculus.</p>
<p>See, this is pretty simple stuff!  Obviously there are subtleties that I didn't
go into, and it gets a bit more confusing when we start to try to figure out
formally which variables occur bound and which occur free, and as we attempt to
preserve that status while doing ?-conversion, 2-reduction, and .-conversion.</p>
<p>Here's some really mind bending food for thought:</p>
<pre class="code text literal-block">
(&gt;&gt; x. x x) (&gt;&gt; x. x x)
</pre>
<p>Think about how this would reduce:</p>
<pre class="code text literal-block">
(&gt;&gt; x. x x) (&gt;&gt; x. x x)
(&gt;&gt; (&gt;&gt; x. x x). (&gt;&gt; x. x x) (&gt;&gt; x. x x))
(&gt;&gt; x. x x) (&gt;&gt; x. x x)
</pre>
<p>As you can see, we could do this forever.  This is called the ? combinator,
and it lets us do some really cool things with recursion. Maybe more on that in
a later blog post.</p>
<p>What is all of this good for?  Well, with only this very simple, rigidly
defined ruleset, we can express every possible computer program.  That makes it
very good for doing mathematical proofs and other various scholarly things
when we want to explore algorithms.  It also forms the basis of all programming
languages, and especially functional programming languages.</p>
<p>Of particular interest to me is that we can actually represent numbers, truth,
and logic using only these very basic primitives.  I'll explore that in another
post.  To me, all of this is fascinating, and it's hard to believe that before
my teacher forced me to learn it, I actively didn't want to know about it.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/theory/">Theory</a></li>
      
        <li><a href="/blog/categories/lambda-calculus/">Lambda Calculus</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Why you should blog]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/19/why-you-should-blog/"/>
        <updated>2008-11-19T05:17:48</updated>
        <id>http://eflorenzano.com/blog/2008/11/19/why-you-should-blog/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/19/why-you-should-blog/">Why you should blog</a></h3>
<p class="datetime">Nov 19, 2008</p>
<div class="document">
<p>Whenever I tell people that I'm participating in this blog post per day event,
most people begin laughing hysterically.  Then the next thing that people
typically do, unprompted, is to start making excuses as to why they don't blog.
Most of the time it is something like, &quot;I don't feel like I have anything
important to say,&quot; and sometimes it's more like &quot;I tried it but nobody was
reading it, so I gave up.&quot;  These are valid reasons why someone shouldn't blog.</p>
<p>But you shouldn't make those excuses, and you should blog anyway.  Firstly,
writing is a valuable skill in any profession.  Simply forcing yourself to
write more helps to improve your writing abilities, and ensures that you're
able to organize your thoughts in a way that others can understand.  Even if it
doesn't make your writing any better, it will make you more aware of your
shortcomings as a writer.  Myself, for instance: I have found that a big
problem with my writing is that I start too many sentences with conjugations.
I also use way too much of the passive voice and alternate between subjective
personal pronouns.</p>
<p>Another reason why you should blog is because it forces you to look at things
from different perspectives.  I can't count how many times I've begun writing
an opinion post, and give up after a while because after putting it into
writing, I realize how weak my actual argument is.  It makes me question some
of my opinions.  Conversely, if the argument comes across as strong and
obvious, then I am even more certain of my opinion.</p>
<p>Finally, blogging is a classic chicken-and-egg problem.  If you don't blog,
nobody will read your blog.  If people don't read your blog, you won't want to
blog.  Fortunately if you just remain steadfast during the beginning portion
of your blogging life (and make sure to participate with other bloggers who
talk about similar things as you), then people will surely start to read your
posts.</p>
<p>Honestly now that I'm reading through this article, it seems a bit weak.  It's
11:15PM and I can't think of another subject to write about before midnight,
though, so this post will have to do!</p>
<p>I hope that you guy start/continue to blog, because it really is a good habit
to get into.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/blogging/">blogging</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[WSGI middleware is awesome, and Django should use it more]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/18/wsgi-middlware-awesome-django-use-it-more/"/>
        <updated>2008-11-18T03:26:48</updated>
        <id>http://eflorenzano.com/blog/2008/11/18/wsgi-middlware-awesome-django-use-it-more/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/18/wsgi-middlware-awesome-django-use-it-more/">WSGI middleware is awesome, and Django should use it more</a></h3>
<p class="datetime">Nov 18, 2008</p>
<div class="document">
<p>Most people in the Django community are deploying their apps these days with
<a class="reference external" href="http://code.google.com/p/modwsgi/">mod_wsgi</a>.  If not, then you're at least using <a class="reference external" href="http://wsgi.org/wsgi/">WSGI</a> as a communication layer
with your application server, in one way or another.  The great thing about
WSGI is that it gives everyone a common interface through which to talk.  It
also has the added benefit of being a common abstraction that many people have
built these great, really useful tools on top of.</p>
<p>Consider <a class="reference external" href="http://repoze.org/">Repoze</a>.  If you navigate to the <a class="reference external" href="http://repoze.org/repoze_components.html#middleware">middleware section</a> of their
website, they have some really cool stuff available!  There are utilities for
logging, authentication, security, profiling, templating, etc.  All of these
pieces of middleware are designed to be totally pluggable, because they are
designed to work solely based on what's available through WSGI.</p>
<p>My personal favorite of that lot is <tt class="docutils literal">repoze.profile</tt>.  It accumulates
Python profiling information about whatever app is being run, and allows you to
view that profile information via a web interface by visiting a special URL.
There is absolutely no reason that the Pylons, TurboGears, or CherryPy guys
should be able to get away with keeping this stuff for themselves, so I want to
show just how easy it is to integrate this profiling module with Django.</p>
<p>First, though, here's a typical .wsgi file that might be used in conjunction
with <tt class="docutils literal">mod_wsgi</tt>:</p>
<pre class="code python literal-block">
<span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">sys</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span>

<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">'DJANGO_SETTINGS_MODULE'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'settings'</span>

<span class="kn">import</span> <span class="nn">django.core.handlers.wsgi</span>

<span class="n">application</span> <span class="o">=</span> <span class="n">django</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">wsgi</span><span class="o">.</span><span class="n">WSGIHandler</span><span class="p">()</span>
</pre>
<p>There's really nothing special going on here, and if you would like to learn
more about how to set up this WSGI file, visit
<a class="reference external" href="http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango">mod_wsgi's documentation on the subject</a>.  Now if you'll notice,
<tt class="docutils literal">application</tt> is simply an instance of <tt class="docutils literal">WSGIHandler</tt>, which is simply a
callable.  A WSGI middleware is just a wrapper around that callable.  Here's how
easy it is to add the profiling middleware:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">repoze.profile.profiler</span> <span class="kn">import</span> <span class="n">AccumulatingProfileMiddleware</span>
<span class="n">application</span> <span class="o">=</span> <span class="n">AccumulatingProfileMiddleware</span><span class="p">(</span>
    <span class="n">application</span><span class="p">,</span>
    <span class="n">log_filename</span><span class="o">=</span><span class="s">'/tmp/djangoprofile.log'</span><span class="p">,</span>
    <span class="n">discard_first_request</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
    <span class="n">flush_at_shutdown</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
    <span class="n">path</span><span class="o">=</span><span class="s">'/__profile__'</span><span class="p">)</span>
</pre>
<p>There we go!  We have imported the profiling middleware, and passed the Django
WSGI application as the first argument.  The rest is just setting options for
the middleware.  You can restart apache and the WSGI profiling middleware is
already working.</p>
<p>Sometimes, though, you don't want all of Apache just to run some middleware.
You want to be able to do the same thing, but locally.  Believe it or not,
Django's local development server is just a WSGI server itself, so one option
would be to do the wrapping directly in django, <a class="reference external" href="http://code.djangoproject.com/browser/django/trunk/django/core/management/commands/runserver.py#L60">right here</a>.  But you really
don't want to be hacking inside of Django internals if you don't have to.
Fortunately there are many alternative WSGI servers out there.  Brian Rosner
has created a custom management command to use the excellent CherryPy WSGI
server with Django, on <a class="reference external" href="http://oebfare.com/blog/2008/nov/03/writing-custom-management-command/">his blog</a>.</p>
<p>Let's say you just want to try this out quickly after reading this blog post,
though.  If you're running Python 2.5 or greater, you're in luck, because a
script less than 10 lines long can get you up and running:</p>
<pre class="code python literal-block">
<span class="c">#!/usr/bin/env python</span>

<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">wsgiref.simple_server</span> <span class="kn">import</span> <span class="n">make_server</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="nb">execfile</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
    <span class="n">httpd</span> <span class="o">=</span> <span class="n">make_server</span><span class="p">(</span><span class="s">''</span><span class="p">,</span> <span class="mi">8000</span><span class="p">,</span> <span class="n">application</span><span class="p">)</span>
    <span class="n">httpd</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
</pre>
<p>Now, to run it, simply invoke it like this:</p>
<pre class="code bash literal-block">
python runserver.py my_wsgi_file.wsgi
</pre>
<p>Now, navigate around your app for a little bit and then point your browser to
<a class="reference external" href="http://localhost:8000/__profile__">the profile url</a> and see how freaking awesome middleware can be.</p>
<p>I'm not trying to stir up any controversy, I'm not saying we should stop making
Django middleware or anything like that.  But I seriously, seriously hope that
someone tries this out and realizes the multitudes of great WSGI apps out there
that can be taken advantage of.  <a class="reference external" href="http://compoundthinking.com/blog/">Mark Ramm</a> wasn't full of hot air when he
talked about this at DjangoCon or <a class="reference external" href="http://compoundthinking.com/blog/index.php/2008/10/06/wsgi-middleare-is-cool/">blogged about it</a> later.  He was right, and
I for one wish I had listened sooner.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/wsgi/">WSGI</a></li>
      
        <li><a href="/blog/categories/repoze/">Repoze</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Writing an Markov-Chain IRC Bot with Twisted and Python]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/17/writing-markov-chain-irc-bot-twisted-and-python/"/>
        <updated>2008-11-17T05:59:34</updated>
        <id>http://eflorenzano.com/blog/2008/11/17/writing-markov-chain-irc-bot-twisted-and-python/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/17/writing-markov-chain-irc-bot-twisted-and-python/">Writing an Markov-Chain IRC Bot with Twisted and Python</a></h3>
<p class="datetime">Nov 17, 2008</p>
<div class="document">
<p><a class="reference external" href="http://twistedmatrix.com/trac/">Twisted</a> is one of Python's great secret weapons.  It is an absolute workhorse,
allowing for insanely fast network applications to be written with very little
effort.  So let's do what everyone does when they want to learn more about
Twisted: let's write an IRC bot!  This bot is going to use <a class="reference external" href="http://en.wikipedia.org/wiki/Markov_chain">Markov Chains</a> to
simulate human speech.  For whatever reason, I named this bot &quot;YourMomDotCom&quot;.</p>
<p>First let's create a skeleton on top of which the rest of the bot will be
created:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">twisted.words.protocols</span> <span class="kn">import</span> <span class="n">irc</span>
<span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">protocol</span>

<span class="k">class</span> <span class="nc">MomBot</span><span class="p">(</span><span class="n">irc</span><span class="o">.</span><span class="n">IRCClient</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">_get_nickname</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">nickname</span>
    <span class="n">nickname</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">_get_nickname</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">signedOn</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">channel</span><span class="p">)</span>
        <span class="k">print</span> <span class="s">&quot;Signed on as </span><span class="si">%s</span><span class="s">.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">nickname</span><span class="p">,)</span>

    <span class="k">def</span> <span class="nf">joined</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">channel</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&quot;Joined </span><span class="si">%s</span><span class="s">.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">channel</span><span class="p">,)</span>

    <span class="k">def</span> <span class="nf">privmsg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
        <span class="k">print</span> <span class="n">msg</span>

<span class="k">class</span> <span class="nc">MomBotFactory</span><span class="p">(</span><span class="n">protocol</span><span class="o">.</span><span class="n">ClientFactory</span><span class="p">):</span>
    <span class="n">protocol</span> <span class="o">=</span> <span class="n">MomBot</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">nickname</span><span class="o">=</span><span class="s">'YourMomDotCom'</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="n">channel</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">nickname</span> <span class="o">=</span> <span class="n">nickname</span>

    <span class="k">def</span> <span class="nf">clientConnectionLost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connector</span><span class="p">,</span> <span class="n">reason</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&quot;Lost connection (</span><span class="si">%s</span><span class="s">), reconnecting.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">reason</span><span class="p">,)</span>
        <span class="n">connector</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">clientConnectionFailed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connector</span><span class="p">,</span> <span class="n">reason</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&quot;Could not connect: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">reason</span><span class="p">,)</span>
</pre>
<p>We've now created an <tt class="docutils literal">IRCClient</tt> subclass which will hold our application
logic, and we've also written a factory class which will create instances of
that <tt class="docutils literal">MomBot</tt> client.  Let's tie these together and start the event loop:</p>
<pre class="code python literal-block">
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="n">chan</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
    <span class="n">reactor</span><span class="o">.</span><span class="n">connectTCP</span><span class="p">(</span><span class="s">'irc.freenode.net'</span><span class="p">,</span> <span class="mi">6667</span><span class="p">,</span> <span class="n">MomBotFactory</span><span class="p">(</span><span class="s">'#'</span> <span class="o">+</span> <span class="n">chan</span><span class="p">))</span>
    <span class="n">reactor</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</pre>
<p>Now already we have a complete working IRC bot.  Right now all it will do is
connect to an IRC channel and echo all of the output to the command line.  Not
bad for how little code we've written. Now all we have to do is implement our
application logic.  Let's first start by creating the 'brain' of our Markov
chain responder, and adding a function to train the brain:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>

<span class="n">markov</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
<span class="n">STOP_WORD</span> <span class="o">=</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span>

<span class="k">def</span> <span class="nf">add_to_brain</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">chain_length</span><span class="p">,</span> <span class="n">write_to_file</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">write_to_file</span><span class="p">:</span>
        <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'training_text.txt'</span><span class="p">,</span> <span class="s">'a'</span><span class="p">)</span>
        <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">msg</span> <span class="o">+</span> <span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">)</span>
        <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
    <span class="n">buf</span> <span class="o">=</span> <span class="p">[</span><span class="n">STOP_WORD</span><span class="p">]</span> <span class="o">*</span> <span class="n">chain_length</span>
    <span class="k">for</span> <span class="n">word</span> <span class="ow">in</span> <span class="n">msg</span><span class="o">.</span><span class="n">split</span><span class="p">():</span>
        <span class="n">markov</span><span class="p">[</span><span class="nb">tuple</span><span class="p">(</span><span class="n">buf</span><span class="p">)]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">word</span><span class="p">)</span>
        <span class="k">del</span> <span class="n">buf</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">buf</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">word</span><span class="p">)</span>
    <span class="n">markov</span><span class="p">[</span><span class="nb">tuple</span><span class="p">(</span><span class="n">buf</span><span class="p">)]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">STOP_WORD</span><span class="p">)</span>
</pre>
<p>In this, we are creating a defaultdict of lists.  For every n-word sliding
window, the word after that window is appended to the list of possible words.
Here's an image which hopefully depicts better than words how the algorithm
populates the brain:</p>
<img alt="http://media.eflorenzano.com/img/markov.png" src="http://media.eflorenzano.com/img/markov.png" />
<p>But what good is a brain like this if we can't get words back from it.  We're
going to need to write a function to generate sentences from that brain:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">generate_sentence</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">chain_length</span><span class="p">,</span> <span class="n">max_words</span><span class="o">=</span><span class="mi">10000</span><span class="p">):</span>
    <span class="n">buf</span> <span class="o">=</span> <span class="n">msg</span><span class="o">.</span><span class="n">split</span><span class="p">()[:</span><span class="n">chain_length</span><span class="p">]</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">msg</span><span class="o">.</span><span class="n">split</span><span class="p">())</span> <span class="o">&gt;</span> <span class="n">chain_length</span><span class="p">:</span>
        <span class="n">message</span> <span class="o">=</span> <span class="n">buf</span><span class="p">[:]</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">message</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="n">chain_length</span><span class="p">):</span>
            <span class="n">message</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">(</span><span class="n">markov</span><span class="p">[</span><span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">(</span><span class="n">markov</span><span class="o">.</span><span class="n">keys</span><span class="p">())]))</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="n">max_words</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">next_word</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">(</span><span class="n">markov</span><span class="p">[</span><span class="nb">tuple</span><span class="p">(</span><span class="n">buf</span><span class="p">)])</span>
        <span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
            <span class="k">continue</span>
        <span class="k">if</span> <span class="n">next_word</span> <span class="o">==</span> <span class="n">STOP_WORD</span><span class="p">:</span>
            <span class="k">break</span>
        <span class="n">message</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">next_word</span><span class="p">)</span>
        <span class="k">del</span> <span class="n">buf</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">buf</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">next_word</span><span class="p">)</span>
    <span class="k">return</span> <span class="s">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
</pre>
<p>We start out our seed buffer with the first few words of the message, and if the
message wasn't long enough, we fill the seed buffer with some random words from
the markov's brain.  Then we use the buffer as a key into the markov brain and
randomly pick one of the values as our next word.  Then we slide that buffer
so that the chosen word is now the next word in the buffer (ejecting the oldest
word in the buffer).  If we ever see a stop word, we stop and return the
generated sentence.</p>
<p>Now it's a matter of expanding our bot to take advantage of our markov brain.
The first change we will need to make is to modify the <tt class="docutils literal">MomBotFactory</tt> to take
more parameters in its <tt class="docutils literal">__init__</tt> method:</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">MomBotFactory</span><span class="p">(</span><span class="n">protocol</span><span class="o">.</span><span class="n">ClientFactory</span><span class="p">):</span>
    <span class="n">protocol</span> <span class="o">=</span> <span class="n">MomBot</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">nickname</span><span class="o">=</span><span class="s">'YourMomDotCom'</span><span class="p">,</span> <span class="n">chain_length</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span>
        <span class="n">chattiness</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">max_words</span><span class="o">=</span><span class="mi">10000</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="n">channel</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">nickname</span> <span class="o">=</span> <span class="n">nickname</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">chain_length</span> <span class="o">=</span> <span class="n">chain_length</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">chattiness</span> <span class="o">=</span> <span class="n">chattiness</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">max_words</span> <span class="o">=</span> <span class="n">max_words</span>

    <span class="c"># ...</span>
</pre>
<p>Now that it has all of that new information, we can add the final bit of
functionality to <tt class="docutils literal">MomBot</tt> responding using sentences generated from the
markov brain by updating the <tt class="docutils literal">privmsg</tt> method:</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">MomBot</span><span class="p">(</span><span class="n">irc</span><span class="o">.</span><span class="n">IRCClient</span><span class="p">):</span>

    <span class="c"># ...</span>

    <span class="k">def</span> <span class="nf">privmsg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="p">:</span>
            <span class="k">return</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">nickname</span> <span class="ow">in</span> <span class="n">msg</span><span class="p">:</span>
            <span class="n">msg</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">nickname</span> <span class="o">+</span> <span class="s">&quot;[:,]* ?&quot;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">I</span><span class="p">)</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s">''</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span>
            <span class="n">prefix</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">: &quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'!'</span><span class="p">,</span> <span class="mi">1</span><span class="p">)[</span><span class="mi">0</span><span class="p">],</span> <span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">prefix</span> <span class="o">=</span> <span class="s">''</span>
        <span class="n">add_to_brain</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">chain_length</span><span class="p">,</span> <span class="n">write_to_file</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">prefix</span> <span class="ow">or</span> <span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">()</span> <span class="o">&lt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">chattiness</span><span class="p">:</span>
            <span class="n">sentence</span> <span class="o">=</span> <span class="n">generate_sentence</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">chain_length</span><span class="p">,</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">max_words</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">sentence</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">factory</span><span class="o">.</span><span class="n">channel</span><span class="p">,</span> <span class="n">prefix</span> <span class="o">+</span> <span class="n">sentence</span><span class="p">)</span>
</pre>
<p>If it gets a message from a non-user, we don't care about it, so we just
disregard that message.  Otherwise, if it's a message directed at the bot, we
want to respond to the sending user so we add the user as a prefix to our next
message.  Then we grab a sentence from the markov brain and send it to the
channel.</p>
<p>Not so bad.  Now lets modify our startup portion of the script to re-train the
brain with anything learned during the course of the bot's life.  Here's how
the new script will look:</p>
<pre class="code python literal-block">
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">chan</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
    <span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&quot;Please specify a channel name.&quot;</span>
        <span class="k">print</span> <span class="s">&quot;Example:&quot;</span>
        <span class="k">print</span> <span class="s">&quot;  python yourmomdotcom.py django-hotclub&quot;</span>
    <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="s">'training_text.txt'</span><span class="p">):</span>
        <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'training_text.txt'</span><span class="p">,</span> <span class="s">'r'</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span>
            <span class="n">add_to_brain</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="n">chain_length</span><span class="p">)</span>
        <span class="k">print</span> <span class="s">'Brain Reloaded'</span>
        <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
    <span class="n">reactor</span><span class="o">.</span><span class="n">connectTCP</span><span class="p">(</span><span class="s">'irc.freenode.net'</span><span class="p">,</span> <span class="mi">6667</span><span class="p">,</span> <span class="n">MomBotFactory</span><span class="p">(</span><span class="s">'#'</span> <span class="o">+</span> <span class="n">chan</span><span class="p">,</span>
        <span class="s">'YourMomDotCom'</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="n">chattiness</span><span class="o">=</span><span class="mf">0.05</span><span class="p">))</span>
    <span class="n">reactor</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</pre>
<p>I have found personally that, counter-intuitively, a length of <strong>2</strong> seems to
produce the most realistic-looking responses.  We've really accomplished a lot
in a very little amount of code.  Instead of my normal closing remarks, let me
simply close with a snippet of conversation recently had with YourMomDotCom:</p>
<pre class="literal-block">
[9:57pm] ericflo: YourMomDotCom: Hello, I'd like to show you off for the readers of my blog.
[9:57pm] YourMomDotCom: ericflo: Hello, I'd like to do, after checking with another.
[9:57pm] ericflo: YourMomDotCom: I'm not exactly sure what you mean by that.
[9:57pm] YourMomDotCom: ericflo: I'm not sure, but I'm in &quot;Easter mode&quot; already I think.
[9:58pm] ericflo: YourMomDotCom: That's funny since we aren't really very close to easter.
[9:58pm] YourMomDotCom: ericflo: That's funny since i missed much of a ForeignKey field?
[9:58pm] ericflo: YourMomDotCom: I miss ForeignKey fields all the time
[9:58pm] YourMomDotCom: ericflo: I miss that
[9:58pm] ericflo: YourMomDotCom: We both agree, then.
[9:58pm] YourMomDotCom: ericflo: We both agree, then.
[9:58pm] ericflo: YourMomDotCom: yay!
</pre>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/twisted/">Twisted</a></li>
      
        <li><a href="/blog/categories/irc/">IRC</a></li>
      
        <li><a href="/blog/categories/markov-chains/">Markov Chains</a></li>
      
        <li><a href="/blog/categories/bot/">Bot</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Exploring Erlang&#39;s gen_server]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/16/exploring-erlangs-genserver/"/>
        <updated>2008-11-16T04:20:40</updated>
        <id>http://eflorenzano.com/blog/2008/11/16/exploring-erlangs-genserver/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/16/exploring-erlangs-genserver/">Exploring Erlang&#39;s gen_server</a></h3>
<p class="datetime">Nov 16, 2008</p>
<div class="document">
<p>Today I found myself at <a class="reference external" href="http://superhappydevhouse.org/">Super Happy Dev House</a>, amongst a whole house full
of geeks (I say this in the most friendly way possible).  I thought for a while
about working on <a class="reference external" href="http://pinaxproject.com/">Pinax</a> project, which is what I really wanted to do.  However,
it didn't seem geeky enough for the occasion.</p>
<p>No, today the call of the geek was too strong.  There was only one place to turn
to achieve maximal geekiness: functional programming.  Not only functional
programming, but I thought this occasion called for a concurrency-oriented
programming language. Yes, today was the perfect day for some Erlang.</p>
<p>I've done a few small projects with Erlang, but never before have I used <a class="reference external" href="http://www.erlang.org/doc/design_principles/part_frame.html">OTP</a>.
So the goal is to write an OTP <tt class="docutils literal">gen_server</tt> which would store a user's
&quot;presence&quot; (think <a class="reference external" href="http://twitter.com/">Twitter</a>, <a class="reference external" href="http://pownce.com/">Pownce</a>, etc.) in memory.  No, it's not a good idea.
Yes, it's kind of fun.  So here we go!</p>
<p>First we need to decide on an API:</p>
<pre class="code erlang literal-block">
<span class="nf">start_link</span><span class="p">()</span> <span class="o">-&gt;</span>
    <span class="nn">gen_server</span><span class="p">:</span><span class="n">start_link</span><span class="p">({</span><span class="n">local</span><span class="p">,</span> <span class="o">?</span><span class="nv">SERVER</span><span class="p">},</span> <span class="o">?</span><span class="nv">MODULE</span><span class="p">,</span> <span class="p">[],</span> <span class="p">[]).</span>

<span class="nf">post_presence</span><span class="p">(</span><span class="nv">UserID</span><span class="p">,</span> <span class="nv">Presence</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="nn">gen_server</span><span class="p">:</span><span class="n">cast</span><span class="p">(</span><span class="o">?</span><span class="nv">SERVER</span><span class="p">,</span> <span class="p">{</span><span class="n">post_presence</span><span class="p">,</span> <span class="nv">UserID</span><span class="p">,</span> <span class="nv">Presence</span><span class="p">}).</span>

<span class="nf">list_presence</span><span class="p">(</span><span class="nv">UserID</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="nn">gen_server</span><span class="p">:</span><span class="n">call</span><span class="p">(</span><span class="o">?</span><span class="nv">SERVER</span><span class="p">,</span> <span class="p">{</span><span class="n">list_presence</span><span class="p">,</span> <span class="nv">UserID</span><span class="p">}).</span>

<span class="nf">list_presence</span><span class="p">(</span><span class="nv">UserID</span><span class="p">,</span> <span class="nv">Limit</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="nn">gen_server</span><span class="p">:</span><span class="n">call</span><span class="p">(</span><span class="o">?</span><span class="nv">SERVER</span><span class="p">,</span> <span class="p">{</span><span class="n">list_presence</span><span class="p">,</span> <span class="nv">UserID</span><span class="p">,</span> <span class="nv">Limit</span><span class="p">}).</span>

<span class="nf">public_list</span><span class="p">(</span><span class="nv">Limit</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="nn">gen_server</span><span class="p">:</span><span class="n">call</span><span class="p">(</span><span class="o">?</span><span class="nv">SERVER</span><span class="p">,</span> <span class="p">{</span><span class="n">public_list</span><span class="p">,</span> <span class="nv">Limit</span><span class="p">}).</span>
</pre>
<p><tt class="docutils literal">start_link</tt> will start the server.  <tt class="docutils literal">post_presence</tt> will post a user's
current presence to the server.  <tt class="docutils literal">list_presence</tt> with one argument gets all
of the specified user's presence information.  With a second argument, it limits
the amount of returned presence information to the specified number. Calling
<tt class="docutils literal">public_list</tt> means that you're getting the latest posts from anyone.</p>
<p>Before that, though, let's get some of the <tt class="docutils literal">gen_server</tt> cruft out of the way:</p>
<pre class="code erlang literal-block">
<span class="p">-</span><span class="ni">module</span><span class="p">(</span><span class="n">presence_database</span><span class="p">).</span>
<span class="p">-</span><span class="ni">behavior</span><span class="p">(</span><span class="n">gen_server</span><span class="p">).</span>

<span class="p">-</span><span class="ni">define</span><span class="p">(</span><span class="no">SERVER</span><span class="p">,</span> <span class="o">?</span><span class="nv">MODULE</span><span class="p">).</span>

<span class="c">%% gen_server API
</span><span class="p">-</span><span class="ni">export</span><span class="p">([</span><span class="n">init</span><span class="o">/</span><span class="mi">1</span><span class="p">,</span> <span class="n">handle_call</span><span class="o">/</span><span class="mi">3</span><span class="p">,</span> <span class="n">handle_cast</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">handle_info</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">terminate</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span>
    <span class="n">code_change</span><span class="o">/</span><span class="mi">3</span><span class="p">]).</span>

<span class="c">%% presence API
</span><span class="p">-</span><span class="ni">export</span><span class="p">([</span><span class="n">start_link</span><span class="o">/</span><span class="mi">0</span><span class="p">,</span> <span class="n">post_presence</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">list_presence</span><span class="o">/</span><span class="mi">1</span><span class="p">,</span> <span class="n">list_presence</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span>
    <span class="n">public_list</span><span class="o">/</span><span class="mi">1</span><span class="p">]).</span>

<span class="nf">handle_info</span><span class="p">(_</span><span class="nv">Info</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="p">{</span><span class="n">noreply</span><span class="p">,</span> <span class="nv">State</span><span class="p">}.</span>

<span class="nf">terminate</span><span class="p">(_</span><span class="nv">Reason</span><span class="p">,</span> <span class="p">_</span><span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="n">ok</span><span class="p">.</span>

<span class="nf">code_change</span><span class="p">(_</span><span class="nv">OldVersion</span><span class="p">,</span> <span class="nv">State</span><span class="p">,</span> <span class="p">_</span><span class="nv">Extra</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">State</span><span class="p">}.</span>

<span class="nf">init</span><span class="p">([])</span> <span class="o">-&gt;</span>
    <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nn">dict</span><span class="p">:</span><span class="n">new</span><span class="p">()}.</span>
</pre>
<p>These are mostly things that we need to have in order for things to work.  We
define our module name, the behavior that this module mimics, and define a
constant.  Then, we export the required functions for gen_server and export
our public presence api functions.  Finally we implement really simple functions
for those gen_server functions that we don't care much about.</p>
<p>Now since I couldn't figure out how to slice a list in Erlang, I wrote my own
slice function.  Make sure to flame me for this.</p>
<pre class="code erlang literal-block">
<span class="nf">slice</span><span class="p">(</span><span class="nv">List</span><span class="p">,</span> <span class="nv">Start</span><span class="p">,</span> <span class="nv">End</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="n">slice</span><span class="p">(</span><span class="nv">List</span><span class="p">,</span> <span class="nv">Start</span><span class="p">,</span> <span class="nv">End</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">[]).</span>

<span class="nf">slice</span><span class="p">([],</span> <span class="p">_</span><span class="nv">Start</span><span class="p">,</span> <span class="p">_</span><span class="nv">End</span><span class="p">,</span> <span class="p">_</span><span class="nv">Index</span><span class="p">,</span> <span class="nv">Acc</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="nn">lists</span><span class="p">:</span><span class="n">reverse</span><span class="p">(</span><span class="nv">Acc</span><span class="p">);</span>
<span class="nf">slice</span><span class="p">([</span><span class="nv">Item</span> <span class="p">|</span> <span class="nv">Rest</span><span class="p">],</span> <span class="nv">Start</span><span class="p">,</span> <span class="nv">End</span><span class="p">,</span> <span class="nv">Index</span><span class="p">,</span> <span class="nv">Acc</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="k">case</span> <span class="nv">Index</span> <span class="o">&gt;=</span> <span class="nv">Start</span> <span class="k">of</span>
        <span class="n">true</span> <span class="o">-&gt;</span>
            <span class="k">case</span> <span class="nv">Index</span> <span class="o">&lt;</span> <span class="nv">End</span> <span class="k">of</span>
                <span class="n">true</span> <span class="o">-&gt;</span>
                    <span class="n">slice</span><span class="p">(</span><span class="nv">Rest</span><span class="p">,</span> <span class="nv">Start</span><span class="p">,</span> <span class="nv">End</span><span class="p">,</span> <span class="nv">Index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="p">[</span><span class="nv">Item</span> <span class="p">|</span> <span class="nv">Acc</span><span class="p">]);</span>
                <span class="n">false</span> <span class="o">-&gt;</span>
                    <span class="n">slice</span><span class="p">(</span><span class="nv">Rest</span><span class="p">,</span> <span class="nv">Start</span><span class="p">,</span> <span class="nv">End</span><span class="p">,</span> <span class="nv">Index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nv">Acc</span><span class="p">)</span>
            <span class="k">end</span><span class="p">;</span>
        <span class="p">_</span> <span class="o">-&gt;</span>
            <span class="n">slice</span><span class="p">(</span><span class="nv">Rest</span><span class="p">,</span> <span class="nv">Start</span><span class="p">,</span> <span class="nv">End</span><span class="p">,</span> <span class="nv">Index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nv">Acc</span><span class="p">)</span>
    <span class="k">end</span><span class="p">.</span>
</pre>
<p>...and I'm pretty sure that using <a class="reference external" href="http://www.erlang.org/doc/reference_manual/expressions.html#guards">guard expressions</a> this could be done in one
case statement.  Or maybe it could be done in a single list comprehension.  I
don't know.  This works for our purposes.</p>
<p>Now we have to write functions called <tt class="docutils literal">handle_cast</tt> and <tt class="docutils literal">handle_call</tt>.
<tt class="docutils literal">handle_cast</tt> is essentially a server function which you don't expect a
response from.  Messages can queue up to this function and they will be handled
sequentially but never return any value to the caller.  <tt class="docutils literal">handle_call</tt> is
exactly the opposite.  The caller is expecting a response, so this is a blocking
operation.</p>
<p>Let's use <tt class="docutils literal">handle_cast</tt> to accept new presence notifications:</p>
<pre class="code erlang literal-block">
<span class="nf">handle_cast</span><span class="p">({</span><span class="n">post_presence</span><span class="p">,</span> <span class="nv">UserID</span><span class="p">,</span> <span class="nv">Presence</span><span class="p">},</span> <span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="k">case</span> <span class="nn">dict</span><span class="p">:</span><span class="n">is_key</span><span class="p">(</span><span class="nv">UserID</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="k">of</span>
        <span class="n">true</span> <span class="o">-&gt;</span>
            <span class="p">{</span><span class="n">noreply</span><span class="p">,</span> <span class="nn">dict</span><span class="p">:</span><span class="n">append</span><span class="p">(</span><span class="nv">UserID</span><span class="p">,</span> <span class="p">{</span><span class="nn">erlang</span><span class="p">:</span><span class="n">now</span><span class="p">(),</span> <span class="nv">Presence</span><span class="p">},</span> <span class="nv">State</span><span class="p">)};</span>
        <span class="p">_</span> <span class="o">-&gt;</span>
            <span class="p">{</span><span class="n">noreply</span><span class="p">,</span> <span class="nn">dict</span><span class="p">:</span><span class="n">store</span><span class="p">(</span><span class="nv">UserID</span><span class="p">,</span> <span class="p">[{</span><span class="nn">erlang</span><span class="p">:</span><span class="n">now</span><span class="p">(),</span> <span class="nv">Presence</span><span class="p">}],</span> <span class="nv">State</span><span class="p">)}</span>
    <span class="k">end</span><span class="p">;</span>
<span class="nf">handle_cast</span><span class="p">(_</span><span class="nv">Msg</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="p">{</span><span class="n">noreply</span><span class="p">,</span> <span class="nv">State</span><span class="p">}.</span>
</pre>
<p>In essence, we check to see if the user has registered their presence, and if
so, we add their presence to their presence list.  If they haven't submitted
their presence before, we create a new presence list for them and add their
submitted presence to that list.  We have also generated a catchall version
of the function for when the call doesn't match the signature
<tt class="docutils literal">{post_presence, UserID, Presence}</tt> for some reason.</p>
<p>Now let's do the harder one: the call to get various presence information from
our server:</p>
<pre class="code erlang literal-block">
<span class="nf">userfy_list</span><span class="p">(</span><span class="nv">User</span><span class="p">,</span> <span class="nv">List</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="nn">lists</span><span class="p">:</span><span class="n">map</span><span class="p">(</span><span class="k">fun</span><span class="p">({</span><span class="nv">Time</span><span class="p">,</span> <span class="nv">Msg</span><span class="p">})</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">User</span><span class="p">,</span> <span class="nv">Time</span><span class="p">,</span> <span class="nv">Msg</span><span class="p">}</span> <span class="k">end</span><span class="p">,</span> <span class="nv">List</span><span class="p">).</span>

<span class="nf">handle_call</span><span class="p">({</span><span class="n">list_presence</span><span class="p">,</span> <span class="nv">UserID</span><span class="p">},</span> <span class="p">_</span><span class="nv">From</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="k">case</span> <span class="nn">dict</span><span class="p">:</span><span class="n">find</span><span class="p">(</span><span class="nv">UserID</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="k">of</span>
        <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">Value</span><span class="p">}</span> <span class="o">-&gt;</span>
            <span class="p">{</span><span class="n">reply</span><span class="p">,</span> <span class="nv">Value</span><span class="p">,</span> <span class="nv">State</span><span class="p">};</span>
        <span class="n">error</span> <span class="o">-&gt;</span>
            <span class="p">{</span><span class="n">reply</span><span class="p">,</span> <span class="p">{</span><span class="n">error</span><span class="p">,</span> <span class="n">user_does_not_exist</span><span class="p">},</span> <span class="nv">State</span><span class="p">}</span>
    <span class="k">end</span><span class="p">;</span>
<span class="nf">handle_call</span><span class="p">({</span><span class="n">list_presence</span><span class="p">,</span> <span class="nv">UserID</span><span class="p">,</span> <span class="nv">Limit</span><span class="p">},</span> <span class="p">_</span><span class="nv">From</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="k">case</span> <span class="nn">dict</span><span class="p">:</span><span class="n">find</span><span class="p">(</span><span class="nv">UserID</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="k">of</span>
        <span class="p">{</span><span class="n">ok</span><span class="p">,</span> <span class="nv">Value</span><span class="p">}</span> <span class="o">-&gt;</span>
            <span class="p">{</span><span class="n">reply</span><span class="p">,</span> <span class="nn">lists</span><span class="p">:</span><span class="n">nthtail</span><span class="p">(</span><span class="nv">Limit</span><span class="p">,</span> <span class="nv">Value</span><span class="p">),</span> <span class="nv">State</span><span class="p">};</span>
        <span class="n">error</span> <span class="o">-&gt;</span>
            <span class="p">{</span><span class="n">reply</span><span class="p">,</span> <span class="p">{</span><span class="n">error</span><span class="p">,</span> <span class="n">user_does_not_exist</span><span class="p">},</span> <span class="nv">State</span><span class="p">}</span>
    <span class="k">end</span><span class="p">;</span>
<span class="nf">handle_call</span><span class="p">({</span><span class="n">public_list</span><span class="p">,</span> <span class="nv">Limit</span><span class="p">},</span> <span class="p">_</span><span class="nv">From</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="nv">LatestEntries</span> <span class="o">=</span> <span class="nn">lists</span><span class="p">:</span><span class="n">flatten</span><span class="p">([</span><span class="n">userfy_list</span><span class="p">(</span><span class="nv">User</span><span class="p">,</span> <span class="nv">List</span><span class="p">)</span> <span class="p">||</span> <span class="p">{</span><span class="nv">User</span><span class="p">,</span> <span class="nv">List</span><span class="p">}</span> <span class="o">&lt;-</span> <span class="nn">dict</span><span class="p">:</span><span class="n">to_list</span><span class="p">(</span><span class="nv">State</span><span class="p">)]),</span>
    <span class="nv">Sorted</span> <span class="o">=</span> <span class="nn">lists</span><span class="p">:</span><span class="n">sort</span><span class="p">(</span><span class="k">fun</span><span class="p">({_,</span> <span class="nv">A</span><span class="p">,</span> <span class="p">_},</span> <span class="p">{_,</span> <span class="nv">B</span><span class="p">,</span> <span class="p">_})</span> <span class="o">-&gt;</span> <span class="nv">A</span> <span class="o">&gt;</span> <span class="nv">B</span> <span class="k">end</span><span class="p">,</span> <span class="nv">LatestEntries</span><span class="p">),</span>
    <span class="p">{</span><span class="n">reply</span><span class="p">,</span> <span class="n">slice</span><span class="p">(</span><span class="nv">Sorted</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">Limit</span><span class="p">),</span> <span class="nv">State</span><span class="p">};</span>
<span class="nf">handle_call</span><span class="p">(_</span><span class="nv">Request</span><span class="p">,</span> <span class="p">_</span><span class="nv">From</span><span class="p">,</span> <span class="nv">State</span><span class="p">)</span> <span class="o">-&gt;</span>
    <span class="p">{</span><span class="n">reply</span><span class="p">,</span> <span class="n">ok</span><span class="p">,</span> <span class="nv">State</span><span class="p">}.</span>
</pre>
<p>The first version of <tt class="docutils literal">handle_call</tt> is very straightforward.  It simply looks
up the list of presence information for a given user and returns that in
the reply.  The second version does a similar thing, but calls <tt class="docutils literal">lists:nthtail</tt>
on the value to limit the number of presence data that is included in that list.</p>
<p>The final version of <tt class="docutils literal">handle_call</tt> is the most complicated, because we want to
get information about everyone, order it by the date that it was posted, and
limit the number of returned results by the specified limit.  An added
complexity is that we have to change the data format to include the name of the
user who posted it.</p>
<p>First it uses a list comprehension to take the state dictionary and run our
<tt class="docutils literal">userfy_list</tt> function on every User/List pair.  This will add the user to the
presence tuple.  Then we flatten that list to be just a single list of userfied
tuples.  Then, we sort that by the middle value (the timestamp of the presence).
Finally, we use our newly-created slice function to take just the slice of
information that we care about and return it to the user.  Again, there is a
catchall <tt class="docutils literal">handle_call</tt> which discards incorrectly-formatted messages.</p>
<div class="section" id="demo">
<h4>Demo</h4>
<pre class="code erlang literal-block">
<span class="mi">1</span><span class="o">&gt;</span> <span class="n">c</span><span class="p">(</span><span class="n">presence_database</span><span class="p">).</span>
<span class="p">{</span><span class="n">ok</span><span class="p">,</span><span class="n">presence_database</span><span class="p">}</span>
<span class="mi">2</span><span class="o">&gt;</span> <span class="nn">presence_database</span><span class="p">:</span><span class="n">start_link</span><span class="p">().</span>
<span class="p">{</span><span class="n">ok</span><span class="p">,</span><span class="o">&lt;</span><span class="mi">0</span><span class="p">.</span><span class="mi">37</span><span class="p">.</span><span class="mi">0</span><span class="o">&gt;</span><span class="p">}</span>
<span class="mi">3</span><span class="o">&gt;</span> <span class="nn">presence_database</span><span class="p">:</span><span class="n">post_presence</span><span class="p">(</span><span class="s">&quot;ericflo&quot;</span><span class="p">,</span> <span class="s">&quot;I am at Super Happy Dev House&quot;</span><span class="p">).</span>
<span class="n">ok</span>
<span class="mi">4</span><span class="o">&gt;</span> <span class="nn">presence_database</span><span class="p">:</span><span class="n">post_presence</span><span class="p">(</span><span class="s">&quot;ericflo&quot;</span><span class="p">,</span> <span class="s">&quot;I am writing erlang code&quot;</span><span class="p">).</span>
<span class="n">ok</span>
<span class="mi">5</span><span class="o">&gt;</span> <span class="nn">presence_database</span><span class="p">:</span><span class="n">post_presence</span><span class="p">(</span><span class="s">&quot;dreid&quot;</span><span class="p">,</span> <span class="s">&quot;I am having fun at SHDH&quot;</span><span class="p">).</span>
<span class="n">ok</span>
<span class="mi">6</span><span class="o">&gt;</span> <span class="nn">presence_database</span><span class="p">:</span><span class="n">list_presence</span><span class="p">(</span><span class="s">&quot;ericflo&quot;</span><span class="p">).</span>
<span class="p">[{{</span><span class="mi">1226</span><span class="p">,</span><span class="mi">816100</span><span class="p">,</span><span class="mi">955</span><span class="p">},</span><span class="s">&quot;I am at Super Happy Dev House&quot;</span><span class="p">},</span>
 <span class="p">{{</span><span class="mi">1226</span><span class="p">,</span><span class="mi">816113</span><span class="p">,</span><span class="mi">249498</span><span class="p">},</span><span class="s">&quot;I am writing erlang code&quot;</span><span class="p">}]</span>
<span class="mi">7</span><span class="o">&gt;</span> <span class="nn">presence_database</span><span class="p">:</span><span class="n">list_presence</span><span class="p">(</span><span class="s">&quot;dreid&quot;</span><span class="p">).</span>
<span class="p">[{{</span><span class="mi">1226</span><span class="p">,</span><span class="mi">816135</span><span class="p">,</span><span class="mi">937300</span><span class="p">},</span><span class="s">&quot;I am having fun at SHDH&quot;</span><span class="p">}]</span>
<span class="mi">8</span><span class="o">&gt;</span> <span class="nn">presence_database</span><span class="p">:</span><span class="n">public_list</span><span class="p">(</span><span class="mi">5</span><span class="p">).</span>
<span class="p">[{</span><span class="s">&quot;dreid&quot;</span><span class="p">,{</span><span class="mi">1226</span><span class="p">,</span><span class="mi">816135</span><span class="p">,</span><span class="mi">937300</span><span class="p">},</span><span class="s">&quot;I am having fun at SHDH&quot;</span><span class="p">},</span>
 <span class="p">{</span><span class="s">&quot;ericflo&quot;</span><span class="p">,{</span><span class="mi">1226</span><span class="p">,</span><span class="mi">816113</span><span class="p">,</span><span class="mi">249498</span><span class="p">},</span><span class="s">&quot;I am writing erlang code&quot;</span><span class="p">},</span>
 <span class="p">{</span><span class="s">&quot;ericflo&quot;</span><span class="p">,</span>
  <span class="p">{</span><span class="mi">1226</span><span class="p">,</span><span class="mi">816100</span><span class="p">,</span><span class="mi">955</span><span class="p">},</span>
  <span class="s">&quot;I am at Super Happy Dev House&quot;</span><span class="p">}]</span>
<span class="mi">9</span><span class="o">&gt;</span> <span class="nn">presence_database</span><span class="p">:</span><span class="n">public_list</span><span class="p">(</span><span class="mi">2</span><span class="p">).</span>
<span class="p">[{</span><span class="s">&quot;dreid&quot;</span><span class="p">,{</span><span class="mi">1226</span><span class="p">,</span><span class="mi">816135</span><span class="p">,</span><span class="mi">937300</span><span class="p">},</span><span class="s">&quot;I am having fun at SHDH&quot;</span><span class="p">},</span>
 <span class="p">{</span><span class="s">&quot;ericflo&quot;</span><span class="p">,{</span><span class="mi">1226</span><span class="p">,</span><span class="mi">816113</span><span class="p">,</span><span class="mi">249498</span><span class="p">},</span><span class="s">&quot;I am writing erlang code&quot;</span><span class="p">}]</span>
</pre>
</div>
<div class="section" id="conclusions">
<h4>Conclusions</h4>
<p>This really isn't robust.  If we wanted it to be more robust, we should use
some sort of persistent storage, we should use more than one process and do some
sort of consistent hashing to distribute the load, and we should have a
supervisor process to ensure that crashed processes restart correctly and reload
their data.</p>
<p>All of that is the case, but yet through this simple exercise I've learned a ton
about Erlang's <tt class="docutils literal">gen_server</tt> module.  I don't know if my explanations will do
people any good, but hopefully they give a glimpse into the world of Erlang.  So
now that all of that is said, show me how to slice in Erlang!</p>
<p><strong>EDIT:</strong> Commenter <em>Mihai</em> has made me aware of the <tt class="docutils literal">lists:sublist</tt> function, which does exactly what I want.  I can now discard my crappy slice function.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/gen_server/">gen_server</a></li>
      
        <li><a href="/blog/categories/presence/">Presence</a></li>
      
        <li><a href="/blog/categories/erlang/">Erlang</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Easy Multi-Database Support for Django]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/15/easy-multi-database-support-django/"/>
        <updated>2008-11-15T05:51:44</updated>
        <id>http://eflorenzano.com/blog/2008/11/15/easy-multi-database-support-django/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/15/easy-multi-database-support-django/">Easy Multi-Database Support for Django</a></h3>
<p class="datetime">Nov 15, 2008</p>
<div class="document">
<div class="section" id="background">
<h4>Background</h4>
<p>One of the most requested features in Django is that it support connecting to
multiple databases at once.  This can come in several flavors, but the two
most common cases are <a class="reference external" href="http://en.wikipedia.org/wiki/Shard_(database_architecture)">sharding</a>, and (vertical) <a class="reference external" href="http://en.wikipedia.org/wiki/Partition_(database)">partitioning</a>.  If you've been
waching closely, some of the core developers have been saying in various places
for a few months now that this is technically possible, right now, in Django 1.0.</p>
<p>Of course, being technically possible is a long way from being easy.  Right now
there is no public API for dealing with multiple databases.  So why do the
developers say that it's possible to do?  The answer is simple: shortly before
Django 1.0 was released, much of the internals of QuerySet objects (Django's
interface to the database) were refactored to use object state-level connection
objects instead of a global connection object.</p>
<p>This seemingly-small change opens the doors for multiple databases, even if
there is no API in front of it.  So let's create an API.  We're going to be
focusing on vertical partitioning, since it's slightly easier, but the technique
demonstrated here will be illustrative when implementing sharding as well.  Oh,
and since we're poking deep into the core of Django's internals, I'm obliged to
give the standard disclaimer: this is not supported and may break in future
versions of Django, so use these techniques at your own risk.</p>
</div>
<div class="section" id="first-things-first">
<h4>First things first</h4>
<p>The first thing that needs to be done when implementing multiple database
support is to supply Django with the information about all of the databases
that you would like to connect to.  Here's how that should look in
<tt class="docutils literal">settings.py</tt>:</p>
<pre class="code python literal-block">
<span class="n">DATABASE_ENGINE</span> <span class="o">=</span> <span class="s">'sqlite3'</span>
<span class="n">DATABASE_NAME</span> <span class="o">=</span> <span class="s">'primary.db'</span>
<span class="n">DATABASE_USER</span> <span class="o">=</span> <span class="s">''</span>
<span class="n">DATABASE_PASSWORD</span> <span class="o">=</span> <span class="s">''</span>
<span class="n">DATABASE_HOST</span> <span class="o">=</span> <span class="s">''</span>
<span class="n">DATABASE_PORT</span> <span class="o">=</span> <span class="s">''</span>

<span class="n">DATABASES</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
    <span class="n">primary</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
        <span class="n">DATABASE_ENGINE</span><span class="o">=</span><span class="n">DATABASE_ENGINE</span><span class="p">,</span>
        <span class="n">DATABASE_NAME</span><span class="o">=</span><span class="n">DATABASE_NAME</span><span class="p">,</span>
        <span class="n">DATABASE_USER</span><span class="o">=</span><span class="n">DATABASE_USER</span><span class="p">,</span>
        <span class="n">DATABASE_PASSWORD</span><span class="o">=</span><span class="n">DATABASE_PASSWORD</span><span class="p">,</span>
        <span class="n">DATABASE_HOST</span><span class="o">=</span><span class="n">DATABASE_HOST</span><span class="p">,</span>
        <span class="n">DATABASE_PORT</span><span class="o">=</span><span class="n">DATABASE_PORT</span><span class="p">,</span>
    <span class="p">),</span>
    <span class="n">secondary</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
        <span class="n">DATABASE_ENGINE</span><span class="o">=</span><span class="n">DATABASE_ENGINE</span><span class="p">,</span>
        <span class="n">DATABASE_NAME</span><span class="o">=</span><span class="s">'secondary.db'</span><span class="p">,</span>
        <span class="n">DATABASE_USER</span><span class="o">=</span><span class="n">DATABASE_USER</span><span class="p">,</span>
        <span class="n">DATABASE_PASSWORD</span><span class="o">=</span><span class="n">DATABASE_PASSWORD</span><span class="p">,</span>
        <span class="n">DATABASE_HOST</span><span class="o">=</span><span class="n">DATABASE_HOST</span><span class="p">,</span>
        <span class="n">DATABASE_PORT</span><span class="o">=</span><span class="n">DATABASE_PORT</span><span class="p">,</span>
    <span class="p">),</span>
<span class="p">)</span>
</pre>
<p>We have not only created the typical database information that Django
requires, but we've also created a dictionary containing information about all
of the databases that we intend to connect to.  In this case, we are connecting
to two sqlite databases in the same directory, named <tt class="docutils literal">primary.db</tt> and
<tt class="docutils literal">secondary.db</tt>.</p>
<p>Let's now create an app, named <tt class="docutils literal">blog</tt> (I know, I know, very unoriginal).  The
<tt class="docutils literal">models.py</tt> will look like this:</p>
<pre class="code python literal-block">
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">Post</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
    <span class="n">body</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
    <span class="n">date_submitted</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Link</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">url</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">URLField</span><span class="p">()</span>
    <span class="n">description</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">(</span><span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">blank</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">date_submitted</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">)</span>
</pre>
<p>And we hook it up to the admin and settings.py in the normal manner.  For more
information on how to do this, follow <a class="reference external" href="http://docs.djangoproject.com/en/dev/#tutorial-writing-your-first-django-application">the official tutorial</a>.  We're going to
be storing the <tt class="docutils literal">Post</tt> objects in the primary database, and the <tt class="docutils literal">Link</tt>
objects in the secondary database.  Since they don't have any foreign keys, we
don't have to worry about joins. (They are possible, but not easy to describe
in one post.)</p>
</div>
<div class="section" id="multiple-databases">
<h4>Multiple databases</h4>
<p>We should probably write some code that will inspect all of our models and
create only the tables that we want in each database.  For the sake of
simplicity and practicality of a blog post, we're not going to do that.
Instead, we will simply create all of the schema on both databases.  The
management command to do so might look something like this (I called it
multi_syncdb):</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.core.management.base</span> <span class="kn">import</span> <span class="n">NoArgsCommand</span>
<span class="kn">from</span> <span class="nn">django.core.management</span> <span class="kn">import</span> <span class="n">call_command</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>

<span class="k">class</span> <span class="nc">Command</span><span class="p">(</span><span class="n">NoArgsCommand</span><span class="p">):</span>
    <span class="n">help</span> <span class="o">=</span> <span class="s">&quot;Sync multiple databases.&quot;</span>

    <span class="k">def</span> <span class="nf">handle_noargs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">options</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">database</span> <span class="ow">in</span> <span class="n">settings</span><span class="o">.</span><span class="n">DATABASES</span><span class="o">.</span><span class="n">iteritems</span><span class="p">():</span>
            <span class="k">print</span> <span class="s">&quot;Running syncdb for </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,)</span>
            <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">database</span><span class="o">.</span><span class="n">iteritems</span><span class="p">():</span>
                <span class="nb">setattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
            <span class="n">call_command</span><span class="p">(</span><span class="s">'syncdb'</span><span class="p">)</span>
</pre>
<p>All of this has been fine, but the real workhorse of multiple database support
lies in the model's <tt class="docutils literal">Manager</tt>.  Let's write a multi-db aware manager right
now:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">sql</span>
<span class="kn">from</span> <span class="nn">django.db.transaction</span> <span class="kn">import</span> <span class="n">savepoint_state</span>

<span class="k">try</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">thread</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">dummy_thread</span> <span class="kn">as</span> <span class="nn">thread</span>

<span class="k">class</span> <span class="nc">MultiDBManager</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Manager</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">database</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">database</span> <span class="o">=</span> <span class="n">database</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">MultiDBManager</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">get_query_set</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">qs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">MultiDBManager</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">get_query_set</span><span class="p">()</span>
        <span class="n">qs</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">connection</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_db_wrapper</span><span class="p">()</span>
        <span class="k">return</span> <span class="n">qs</span>

    <span class="k">def</span> <span class="nf">get_db_wrapper</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">database</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">DATABASES</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">database</span><span class="p">]</span>
        <span class="n">backend</span> <span class="o">=</span> <span class="nb">__import__</span><span class="p">(</span><span class="s">'django.db.backends.'</span> <span class="o">+</span> <span class="n">database</span><span class="p">[</span><span class="s">'DATABASE_ENGINE'</span><span class="p">]</span>
            <span class="o">+</span> <span class="s">&quot;.base&quot;</span><span class="p">,</span> <span class="p">{},</span> <span class="p">{},</span> <span class="p">[</span><span class="s">'base'</span><span class="p">])</span>
        <span class="n">backup</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">database</span><span class="o">.</span><span class="n">iteritems</span><span class="p">():</span>
            <span class="n">backup</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
            <span class="nb">setattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
        <span class="n">wrapper</span> <span class="o">=</span> <span class="n">backend</span><span class="o">.</span><span class="n">DatabaseWrapper</span><span class="p">()</span>
        <span class="n">wrapper</span><span class="o">.</span><span class="n">_cursor</span><span class="p">(</span><span class="n">settings</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">backup</span><span class="o">.</span><span class="n">iteritems</span><span class="p">():</span>
            <span class="nb">setattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">wrapper</span>

    <span class="k">def</span> <span class="nf">_insert</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">return_id</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">raw_values</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
        <span class="n">query</span> <span class="o">=</span> <span class="n">sql</span><span class="o">.</span><span class="n">InsertQuery</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">model</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_db_wrapper</span><span class="p">())</span>
        <span class="n">query</span><span class="o">.</span><span class="n">insert_values</span><span class="p">(</span><span class="n">values</span><span class="p">,</span> <span class="n">raw_values</span><span class="p">)</span>
        <span class="n">ret</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">execute_sql</span><span class="p">(</span><span class="n">return_id</span><span class="p">)</span>
        <span class="n">query</span><span class="o">.</span><span class="n">connection</span><span class="o">.</span><span class="n">_commit</span><span class="p">()</span>
        <span class="n">thread_ident</span> <span class="o">=</span> <span class="n">thread</span><span class="o">.</span><span class="n">get_ident</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">thread_ident</span> <span class="ow">in</span> <span class="n">savepoint_state</span><span class="p">:</span>
            <span class="k">del</span> <span class="n">savepoint_state</span><span class="p">[</span><span class="n">thread_ident</span><span class="p">]</span>
        <span class="k">return</span> <span class="n">ret</span>
</pre>
<p>I know that's a lot of code!  Let's go through each piece one-by-one.  In the
<tt class="docutils literal">__init__</tt> function, we're just taking in the name of the database that we
want to use, and passing the rest into the inherited <tt class="docutils literal">__init__</tt> function.</p>
<p><tt class="docutils literal">get_query_set</tt> gets the <tt class="docutils literal">QuerySet</tt> instance that it would have gotten, but
replaces the connection on the query object with one provided by the manager,
before returning the <tt class="docutils literal">QuerySet</tt>.  In essence, this <tt class="docutils literal">get_db_wrapper</tt> function
is doing the bulk of the work.</p>
<p><tt class="docutils literal">get_db_wrapper</tt> first gets the dictionary of the database connection
information for the given database name (captured from <tt class="docutils literal">__init__</tt>), then
dynamically imports the correct database backend from Django.  It then sets
the global settings to the values that they should be for that database (while
backing up the original settings for restoration later).  Then, it initializes
that database connection, and restores the settings to their original values.</p>
<p>Most of the database operations are done through the <tt class="docutils literal">QuerySet</tt>, there is
still one operation which takes place elsewhere--saving.  To account for that,
we needed to override the <tt class="docutils literal">_insert</tt> method on the manager.  In fact, all we're
doing here is providing the <tt class="docutils literal">InsertQuery</tt> with the correct connection and
executing that query.  Then, we need to ensure that the query is committed and
do any transaction management that's necessary.</p>
<p>That's it!</p>
<p>How do we specify that one ore more models will use another database then?
Because so far all that we have done is write this <tt class="docutils literal">MultiDBManager</tt>.  We will
just add one line assigning the manager to our <tt class="docutils literal">Link</tt> model.  The model
now looks like this:</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">Link</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">url</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">URLField</span><span class="p">()</span>
    <span class="n">description</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">(</span><span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">blank</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">date_submitted</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">)</span>

    <span class="n">_default_manager</span> <span class="o">=</span> <span class="n">MultiDBManager</span><span class="p">(</span><span class="s">'secondary'</span><span class="p">)</span>
</pre>
</div>
<div class="section" id="conclusion">
<h4>Conclusion</h4>
<p>The <tt class="docutils literal">MultiDBManager</tt> can be re-used for any number of models to be partitioned
on to any number of databases.  The hard part is making sure that none of the
models in one database reference any models in the other database.  It's
possible to do it, by storing the foreign key as a regular integer and querying
for all of the referenced model instances through Python instead of using the
database (for obvious reasons), but then it becomes much harder.</p>
<p>It will be great when Django provides a public API for doing this in a more
transparent way, but for now this works.  Please let me know if you use any
of these techniques for large scale Django deployments, and if so, what were the
problems that were encountered along the way?</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/databases/">Databases</a></li>
      
        <li><a href="/blog/categories/multiple-databases/">Multiple Databases</a></li>
      
        <li><a href="/blog/categories/database-sharding/">Database Sharding</a></li>
      
        <li><a href="/blog/categories/database-partitioning/">Database Partitioning</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[&#34;To IDE or not to IDE?&#34;, that is the question]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/14/ide-or-not-ide-question/"/>
        <updated>2008-11-14T04:24:18</updated>
        <id>http://eflorenzano.com/blog/2008/11/14/ide-or-not-ide-question/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/14/ide-or-not-ide-question/">&#34;To IDE or not to IDE?&#34;, that is the question</a></h3>
<p class="datetime">Nov 14, 2008</p>
<div class="document">
<p>A few years ago, when I first started using Python, I spent an inordinate amount
of time looking for &quot;a good Python IDE.&quot;  The classic <a class="reference external" href="http://wiki.python.org/moin/CategoryIntegratedDevelopmentEnvironment?highlight=((IntegratedDevelopmentEnvironments))">IDE links</a> page on the
Python wiki was around back then, and looked fairly similar to the way it looks
now.  I was used to Java and Eclipse.  Java, if you haven't used it, is
difficult at best to use without an IDE.</p>
<p>Understandably, then, I wanted to see what was available (and free).  At the
time, the two reigning free ones were Eric3, and SPE, and PyDev was quickly
gaining popularity.  I found Eric3 to be extremely buggy, crashing every few
minutes.  Everyone seemed to love it, but I couldn't get it to work stably for
me, which was a deal breaker.</p>
<p>PyDev seemed too heavyweight.  After all, I was trying to switch <em>away</em> from
Java!  Plus, the fact that it stored metadata in these strange .project files
bugged me to no end.  SPE was one that I actually used for a while.  It was
stable, seemed to be featureful, and had a good community around it.  But
I found that the interface ended up getting in the way more than helping, and
eventually I abandoned that as well.</p>
<p>I tried trial versions of Wing and Komodo, and of course they were the best, but
they sure didn't seem like they were worth what their respective companies were
asking for them.  Anyway, at this point several months had gone by, and I had
gotten pretty comfortable with Python.  The search for an IDE ended up making me
proficient enough that I found I didn't need an IDE at all!</p>
<p>Today, I code in TextMate.  But I have no strong preference over any other text
editor (in fact, I think my preferred text editor is <a class="reference external" href="http://kate-editor.org/">Kate</a>), but the simplicity
that it brings is pretty much unbeatable.</p>
<p>All of this brings me to my question for anyone who's willing to answer: should
I take a second look at any of these IDEs?  A few years after I did this
research and I'm willing to entertain the idea that it's possible an IDE could
make development easier.  Is there a new kid on the block that is sweeping people
off their feet?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/java/">Java</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/ide/">IDE</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Book Meme]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/13/book-meme/"/>
        <updated>2008-11-13T05:19:41</updated>
        <id>http://eflorenzano.com/blog/2008/11/13/book-meme/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/13/book-meme/">Book Meme</a></h3>
<p class="datetime">Nov 13, 2008</p>
<div class="document">
<p>&quot;Another feature that's easy to add is a per-entry way to allow or disallow comments.&quot;
From <em>Practical Django Projects</em> by <a class="reference external" href="http://www.b-list.org/">James Bennett</a>.</p>
<p>Meme from <a class="reference external" href="http://jtauber.com/blog/2008/11/12/book_meme/">James Tauber</a>, <a class="reference external" href="http://www.20seven.org/journal/2008/11/book-meme.html">Greg Newman</a>, <a class="reference external" href="http://justinlilly.com/blog/2008/nov/12/book-memery/">Justin Lilly</a> and <a class="reference external" href="http://oebfare.com/blog/2008/nov/12/book-memery/">Brian Rosner</a>.</p>
<blockquote>
<ul class="simple">
<li>Grab the nearest book.</li>
<li>Open it to page 56.</li>
<li>Find the fifth sentence.</li>
<li>Post the text of the sentence in your journal along with these instructions.</li>
<li>Don't dig for your favorite book, the cool book, or the intellectual one: pick the CLOSEST.</li>
</ul>
</blockquote>
<p>The MOST ironic part about this all, is that I was not going to do this meme tonight, and instead write a post.  However, I was so busy trying to beat James Bennett's score on level 3 of <a class="reference external" href="http://www.mochiads.com/challenge/accept/68dbee0cb670b06e8d0ced46fd616c87">this challenge</a>, that I ran out of time for tonight.</p>
<p>P.S. I dare you to beat my now 357,500 points on level 3 of the game in that link.  I bet you can't.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/meme/">Meme</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Why use a VARCHAR when you can use TEXT?]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/11/why-use-varchar-when-you-can-use-text/"/>
        <updated>2008-11-11T16:23:24</updated>
        <id>http://eflorenzano.com/blog/2008/11/11/why-use-varchar-when-you-can-use-text/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/11/why-use-varchar-when-you-can-use-text/">Why use a VARCHAR when you can use TEXT?</a></h3>
<p class="datetime">Nov 11, 2008</p>
<div class="document">
<p>Admit it, you've done it many times before: you create a database schema,
arbitrarily guessing at upper limits to the lengths of various columns, only to
later have to perform annoying schema upgrades as you change those columns to
fit real-world data.</p>
<p>If you're using <a class="reference external" href="http://www.postgresql.org/">PostgreSQL</a>, what you're doing is pointless.  There is quite
literally no performance benefit to be had, and possibly a performance penalty
as the database needs to check the length constraint.  This fact can even be
found <a class="reference external" href="http://www.postgresql.org/docs/8.3/interactive/datatype-character.html">right here, in the official documentation</a>.</p>
<p>If you're using <a class="reference external" href="http://www.mysql.com/">MySQL</a> with <a class="reference external" href="http://www.innodb.com/">InnoDB</a>, it's practically the same situation.  The
data is laid out on disk in exactly the same way for both TEXT and VARCHAR
fields, as explained <a class="reference external" href="http://forums.innodb.com/read.php?4,61,80#msg-80">here</a>.  I couldn't find any resources about MyISAM other
than that TEXT is stored externally, but I just fired up a test table and did
some rudimentary benchmarking and the numbers were well within the margin of
error.</p>
<p>If you're using <a class="reference external" href="http://www.sqlite.org/">SQLite</a>, everything's a TEXT whether you want it to be or not (
with the notable exception of INTEGER PRIMARY KEY) so it doesn't matter what
you try to specify, it will be a TEXT.</p>
<p>I'm as guilty as anyone else on this--I use varchar all the time!  But come on,
let's stop imposing these arbitrary character limits on our columns when the
only reason we're doing it is for historical reasons.  Is anyone with me?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/postgresql/">PostgreSQL</a></li>
      
        <li><a href="/blog/categories/databases/">Databases</a></li>
      
        <li><a href="/blog/categories/innodb/">InnoDB</a></li>
      
        <li><a href="/blog/categories/myisam/">MyISAM</a></li>
      
        <li><a href="/blog/categories/sqlite/">sqlite</a></li>
      
        <li><a href="/blog/categories/mysql/">MySQL</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Making Django Imports Less Painful]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/11/making-django-imports-less-painful/"/>
        <updated>2008-11-11T03:25:58</updated>
        <id>http://eflorenzano.com/blog/2008/11/11/making-django-imports-less-painful/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/11/making-django-imports-less-painful/">Making Django Imports Less Painful</a></h3>
<p class="datetime">Nov 11, 2008</p>
<div class="document">
<p>Way back in the early days of Django, it used to magically import certain functions before any views were ever run.  At some point that bit of magic got stripped out and now we have to explicitly import the things that we are going to use...much like everything else in Python.  One thing that <a class="reference external" href="http://simonwillison.net/">Simon Willison</a> suggested at DjangoCon is that the core developers might think about including a common set of functions that could be imported and used as shortcuts instead of importing everything again and again.</p>
<p>I shrugged it off at the time, thinking it was a solution in search of a problem, but wanting to keep an open mind, I wanted to try it out in one app to see how it would look.  In this spirit, I created a file called <tt class="docutils literal">dj.py</tt> inside of a project of mine, <a class="reference external" href="http://code.google.com/p/django-avatar/">django-avatar</a>.  I looked around at what some of the most commonly used functions were, and came up with a <tt class="docutils literal">dj.py</tt> file that looked something like this:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponseRedirect</span>
<span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render_to_response</span>
<span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">RequestContext</span>
<span class="kn">from</span> <span class="nn">django.contrib.auth.decorators</span> <span class="kn">import</span> <span class="n">login_required</span>
<span class="kn">from</span> <span class="nn">django.contrib.auth.models</span> <span class="kn">import</span> <span class="n">User</span>
<span class="kn">from</span> <span class="nn">django.utils.translation</span> <span class="kn">import</span> <span class="n">ugettext</span> <span class="k">as</span> <span class="n">_</span>
<span class="kn">from</span> <span class="nn">django</span> <span class="kn">import</span> <span class="n">forms</span>
<span class="kn">from</span> <span class="nn">django.utils.safestring</span> <span class="kn">import</span> <span class="n">mark_safe</span>
</pre>
<p>Then I went through and deleted all of these imports from throughout the project, and replaced it with a single import:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">avatar</span> <span class="kn">import</span> <span class="n">dj</span>
</pre>
<p>Now we have that shortcut module loaded, we can use it.  Here's an example of what one view looked like before:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.contrib.auth.decorators</span> <span class="kn">import</span> <span class="n">login_required</span>
<span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">RequestContext</span>
<span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render_to_response</span>
<span class="kn">from</span> <span class="nn">django.utils.translation</span> <span class="kn">import</span> <span class="n">ugettext</span> <span class="k">as</span> <span class="n">_</span>
<span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponseRedirect</span>

<span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">extra_context</span><span class="o">=</span><span class="p">{},</span> <span class="n">next_override</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="n">avatars</span> <span class="o">=</span> <span class="n">Avatar</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">user</span><span class="o">=</span><span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="p">)</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s">'-primary'</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">avatars</span><span class="o">.</span><span class="n">count</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">avatar</span> <span class="o">=</span> <span class="n">avatars</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">avatar</span> <span class="o">=</span> <span class="bp">None</span>
    <span class="n">delete_avatar_form</span> <span class="o">=</span> <span class="n">DeleteAvatarForm</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">POST</span> <span class="ow">or</span> <span class="bp">None</span><span class="p">,</span> <span class="n">user</span><span class="o">=</span><span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">delete_avatar_form</span><span class="o">.</span><span class="n">is_valid</span><span class="p">():</span>
            <span class="n">ids</span> <span class="o">=</span> <span class="n">delete_avatar_form</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">'choices'</span><span class="p">]</span>
            <span class="n">Avatar</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">id__in</span><span class="o">=</span><span class="n">ids</span><span class="p">)</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
            <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">message_set</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
                <span class="n">message</span><span class="o">=</span><span class="n">_</span><span class="p">(</span><span class="s">&quot;Successfully deleted the requested avatars.&quot;</span><span class="p">))</span>
            <span class="k">return</span> <span class="n">HttpResponseRedirect</span><span class="p">(</span><span class="n">next_override</span> <span class="ow">or</span> <span class="n">_get_next</span><span class="p">(</span><span class="n">request</span><span class="p">))</span>
    <span class="k">return</span> <span class="n">render_to_response</span><span class="p">(</span>
        <span class="s">'avatar/confirm_delete.html'</span><span class="p">,</span>
        <span class="n">extra_context</span><span class="p">,</span>
        <span class="n">context_instance</span> <span class="o">=</span> <span class="n">RequestContext</span><span class="p">(</span>
            <span class="n">request</span><span class="p">,</span>
            <span class="p">{</span> <span class="s">'avatar'</span><span class="p">:</span> <span class="n">avatar</span><span class="p">,</span>
              <span class="s">'avatars'</span><span class="p">:</span> <span class="n">avatars</span><span class="p">,</span>
              <span class="s">'delete_avatar_form'</span><span class="p">:</span> <span class="n">delete_avatar_form</span><span class="p">,</span>
              <span class="s">'next'</span><span class="p">:</span> <span class="n">next_override</span> <span class="ow">or</span> <span class="n">_get_next</span><span class="p">(</span><span class="n">request</span><span class="p">),</span> <span class="p">}</span>
        <span class="p">)</span>
    <span class="p">)</span>
<span class="n">change</span> <span class="o">=</span> <span class="n">login_required</span><span class="p">(</span><span class="n">change</span><span class="p">)</span>
</pre>
<p>And here's what the code looked like afterward:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">avatar</span> <span class="kn">import</span> <span class="n">dj</span>

<span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">extra_context</span><span class="o">=</span><span class="p">{},</span> <span class="n">next_override</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="n">avatars</span> <span class="o">=</span> <span class="n">Avatar</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">user</span><span class="o">=</span><span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="p">)</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s">'-primary'</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">avatars</span><span class="o">.</span><span class="n">count</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">avatar</span> <span class="o">=</span> <span class="n">avatars</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">avatar</span> <span class="o">=</span> <span class="bp">None</span>
    <span class="n">delete_avatar_form</span> <span class="o">=</span> <span class="n">DeleteAvatarForm</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">POST</span> <span class="ow">or</span> <span class="bp">None</span><span class="p">,</span> <span class="n">user</span><span class="o">=</span><span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">delete_avatar_form</span><span class="o">.</span><span class="n">is_valid</span><span class="p">():</span>
            <span class="n">ids</span> <span class="o">=</span> <span class="n">delete_avatar_form</span><span class="o">.</span><span class="n">cleaned_data</span><span class="p">[</span><span class="s">'choices'</span><span class="p">]</span>
            <span class="n">Avatar</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">id__in</span><span class="o">=</span><span class="n">ids</span><span class="p">)</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
            <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">message_set</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
                <span class="n">message</span><span class="o">=</span><span class="n">dj</span><span class="o">.</span><span class="n">_</span><span class="p">(</span><span class="s">&quot;Successfully deleted the requested avatars.&quot;</span><span class="p">))</span>
            <span class="k">return</span> <span class="n">dj</span><span class="o">.</span><span class="n">HttpResponseRedirect</span><span class="p">(</span><span class="n">next_override</span> <span class="ow">or</span> <span class="n">_get_next</span><span class="p">(</span><span class="n">request</span><span class="p">))</span>
    <span class="k">return</span> <span class="n">dj</span><span class="o">.</span><span class="n">render_to_response</span><span class="p">(</span>
        <span class="s">'avatar/confirm_delete.html'</span><span class="p">,</span>
        <span class="n">extra_context</span><span class="p">,</span>
        <span class="n">context_instance</span> <span class="o">=</span> <span class="n">dj</span><span class="o">.</span><span class="n">RequestContext</span><span class="p">(</span>
            <span class="n">request</span><span class="p">,</span>
            <span class="p">{</span> <span class="s">'avatar'</span><span class="p">:</span> <span class="n">avatar</span><span class="p">,</span>
              <span class="s">'avatars'</span><span class="p">:</span> <span class="n">avatars</span><span class="p">,</span>
              <span class="s">'delete_avatar_form'</span><span class="p">:</span> <span class="n">delete_avatar_form</span><span class="p">,</span>
              <span class="s">'next'</span><span class="p">:</span> <span class="n">next_override</span> <span class="ow">or</span> <span class="n">_get_next</span><span class="p">(</span><span class="n">request</span><span class="p">),</span> <span class="p">}</span>
        <span class="p">)</span>
    <span class="p">)</span>
<span class="n">change</span> <span class="o">=</span> <span class="n">dj</span><span class="o">.</span><span class="n">login_required</span><span class="p">(</span><span class="n">change</span><span class="p">)</span>
</pre>
<p>It works!  Although after all of that, I have decided that in my opinion it's just not worth the effort.  It adds an extra level of indirection when tracing through the code, it litters the view with the <tt class="docutils literal">dj</tt> namespace, and it's harder to know what you have available to you.  Maybe you like this style better, though.  If so, what about this style do you like?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Using CouchDB with Django]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/10/using-couchdb-django/"/>
        <updated>2008-11-10T05:59:59</updated>
        <id>http://eflorenzano.com/blog/2008/11/10/using-couchdb-django/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/10/using-couchdb-django/">Using CouchDB with Django</a></h3>
<p class="datetime">Nov 10, 2008</p>
<div class="document">
<p>Ahhh, <a class="reference external" href="http://www.djangoproject.com/">Django</a>: my favorite web framework.  And <a class="reference external" href="http://incubator.apache.org/couchdb/">CouchDB</a>: my favorite new
database technology.  How can I pair these two awesomes together to make an
awesome-er?</p>
<p>One of the features that I would like to add to this site when it's time for an
upgrade is a lifestream.  It seems like everyone is doing it these days (isn't
this great logic!), so I probably should too.  Originally this was going to be
written in the standard Django way--write some models, fill it with data, and
slice and dice that data to make it pretty.</p>
<p>After thinking about it, I decided not to go that route.  Why?  Well, let's go
over it: There needs to be a <a class="reference external" href="http://twitter.com/">Twitter</a> model, that's for sure.  I also want a
<a class="reference external" href="http://pownce.com/">Pownce</a> model, and a <a class="reference external" href="http://flickr.com/">Flickr</a> model.  Already this is becoming tedious!  At this
point we have two options: continue creating these individual models and fill
them with data, or try to find the common bits and group them into Ubermodels
of some sort, with some type of field to use as a discriminator.  Ugh.</p>
<p>This is the perfect use case for a schemaless database, and <a class="reference external" href="http://incubator.apache.org/couchdb/">CouchDB</a> fits that
bill just perfectly.  Plus its <a class="reference external" href="http://code.google.com/p/couchdb-python/">python support</a> is actually quite mature, and
running it on a mac is, quite literally, <a class="reference external" href="http://jan.prima.de/~jan/plok/archives/142-CouchDBX-Revival.html">one click</a>.  So now that we've all
agreed (we all agree, right?) that we want to use <a class="reference external" href="http://incubator.apache.org/couchdb/">CouchDB</a> with <a class="reference external" href="http://www.djangoproject.com/">Django</a>, how
can we make it happen?</p>
<p>First let's set some database settings:</p>
<pre class="code python literal-block">
<span class="n">COUCHDB_HOST</span> <span class="o">=</span> <span class="s">'http://localhost:5984/'</span>
<span class="n">TWITTER_USERNAME</span> <span class="o">=</span> <span class="s">'ericflo'</span>
</pre>
<p>So far, so good.  Now let's write some initialization code and put it in to an
application in the <tt class="docutils literal">__init__.py</tt>:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">couchdb</span> <span class="kn">import</span> <span class="n">client</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>

<span class="k">class</span> <span class="nc">CouchDBImproperlyConfigured</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="k">try</span><span class="p">:</span>
    <span class="n">HOST</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">COUCHDB_HOST</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
    <span class="k">raise</span> <span class="n">CouchDBImproperlyConfigured</span><span class="p">(</span><span class="s">&quot;Please ensure that COUCHDB_HOST is &quot;</span> <span class="o">+</span> \
        <span class="s">&quot;set in your settings file.&quot;</span><span class="p">)</span>

<span class="n">DATABASE_NAME</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s">'COUCHDB_DATABASE_NAME'</span><span class="p">,</span> <span class="s">'couch_lifestream'</span><span class="p">)</span>
<span class="n">COUCHDB_DESIGN_DOCNAME</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s">'COUCHDB_DESIGN_DOCNAME'</span><span class="p">,</span>
    <span class="s">'couch_lifestream-design'</span><span class="p">)</span>

<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s">'couchdb_server'</span><span class="p">):</span>
    <span class="n">server</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">Server</span><span class="p">(</span><span class="n">HOST</span><span class="p">)</span>
    <span class="n">settings</span><span class="o">.</span><span class="n">couchdb_server</span> <span class="o">=</span> <span class="n">server</span>

<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s">'couchdb_db'</span><span class="p">):</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">db</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">DATABASE_NAME</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">client</span><span class="o">.</span><span class="n">ResourceConflict</span><span class="p">:</span>
        <span class="n">db</span> <span class="o">=</span> <span class="n">server</span><span class="p">[</span><span class="n">DATABASE_NAME</span><span class="p">]</span>
    <span class="n">settings</span><span class="o">.</span><span class="n">couchdb_db</span> <span class="o">=</span> <span class="n">db</span>
</pre>
<p>In this code, we're loading the CouchDB client and either creating or
connecting to a database.  We do a bit of error checking to ensure that if we
forgot to add <tt class="docutils literal">COUCHDB_HOST</tt> in our settings file, it will yell at us. So how
do we use this?  Let's write some data importing stuff!</p>
<pre class="code python literal-block">
<span class="k">try</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">simplejson</span> <span class="kn">as</span> <span class="nn">json</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">json</span>

<span class="n">TWITTER_USERNAME</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s">'TWITTER_USERNAME'</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>

<span class="n">fetched</span> <span class="o">=</span> <span class="n">urlopen</span><span class="p">(</span><span class="s">'http://twitter.com/statuses/user_timeline.json?id=</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span>
    <span class="n">TWITTER_USERNAME</span><span class="p">,))</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">fetched</span><span class="p">)</span>
<span class="n">map_fun</span> <span class="o">=</span> <span class="s">'function(doc) { emit(doc.id, null); }'</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
    <span class="n">item</span><span class="p">[</span><span class="s">'item_type'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'twitter'</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">db</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">map_fun</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">item</span><span class="p">[</span><span class="s">'id'</span><span class="p">]))</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">db</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
</pre>
<p>This can go inside a Django management command or in a standalone script.
Essentially what we're doing is loading the timeline for a user, and then for
each item in that response we're setting the <tt class="docutils literal">item_type</tt> to 'twitter'.  Then
we're checking to see if an item with that current twitter id already exists,
and if not, we're creating it.</p>
<p>Now we need a way to query this data.  In <a class="reference external" href="http://incubator.apache.org/couchdb/">CouchDB</a>, the way to query for data is
using <a class="reference external" href="http://wiki.apache.org/couchdb/Views">views</a>.  Views are stored in the database, so they can be entered
manually, but I much prefer to manage views programmatically.  Thankfully,
Python's CouchDB library and Django give us all we need to make this very, very
easy:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">signals</span>
<span class="kn">from</span> <span class="nn">couch_lifestream</span> <span class="kn">import</span> <span class="n">models</span><span class="p">,</span> <span class="n">db</span><span class="p">,</span> <span class="n">COUCHDB_DESIGN_DOCNAME</span>
<span class="kn">from</span> <span class="nn">couchdb.design</span> <span class="kn">import</span> <span class="n">ViewDefinition</span>
<span class="kn">from</span> <span class="nn">textwrap</span> <span class="kn">import</span> <span class="n">dedent</span>

<span class="n">by_date</span> <span class="o">=</span> <span class="n">ViewDefinition</span><span class="p">(</span><span class="n">COUCHDB_DESIGN_DOCNAME</span><span class="p">,</span> <span class="s">'by_date'</span><span class="p">,</span>
    <span class="n">dedent</span><span class="p">(</span><span class="s">&quot;&quot;&quot;
    function(doc) {
        emit(doc.couch_lifestream_date, null);
    }
&quot;&quot;&quot;</span><span class="p">))</span>

<span class="k">def</span> <span class="nf">create_couchdb_views</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">created_models</span><span class="p">,</span> <span class="n">verbosity</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="n">ViewDefinition</span><span class="o">.</span><span class="n">sync_many</span><span class="p">(</span><span class="n">db</span><span class="p">,</span> <span class="p">[</span><span class="n">by_date</span><span class="p">])</span>
<span class="n">signals</span><span class="o">.</span><span class="n">post_syncdb</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">create_couchdb_views</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">models</span><span class="p">)</span>
</pre>
<p>Make sure that this is placed somewhere that will be loaded when Django's
<tt class="docutils literal">manage.py</tt> is called.  In this case, I put it in the <tt class="docutils literal">__init__.py</tt> file
under <tt class="docutils literal">management/</tt>.  What we're doing is creating two views--one which is
keyed by the <tt class="docutils literal">item_type</tt> (we set this earlier to be 'twitter'), and another
which is keyed simply by date.  When we run <tt class="docutils literal">python manage.py syncdb</tt>, these
views will automatically be re-synced with the database.  Using this method, we
are able to manage these views quickly and easily, and distribute them in a
reusable way.</p>
<p>Now let's create some Django views so that we can visualize this data:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">couch_lifestream</span> <span class="kn">import</span> <span class="n">db</span><span class="p">,</span> <span class="n">COUCHDB_DESIGN_DOCNAME</span>
<span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render_to_response</span>
<span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">RequestContext</span>
<span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">Http404</span>
<span class="kn">from</span> <span class="nn">couchdb</span> <span class="kn">import</span> <span class="n">client</span>

<span class="k">def</span> <span class="nf">item</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="nb">id</span><span class="p">):</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">obj</span> <span class="o">=</span> <span class="n">db</span><span class="p">[</span><span class="nb">id</span><span class="p">]</span>
    <span class="k">except</span> <span class="n">client</span><span class="o">.</span><span class="n">ResourceNotFound</span><span class="p">:</span>
        <span class="k">raise</span> <span class="n">Http404</span>
    <span class="n">context</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s">'item'</span><span class="p">:</span> <span class="n">obj</span><span class="p">,</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">render_to_response</span><span class="p">(</span>
        <span class="s">'couch_lifestream/item.html'</span><span class="p">,</span>
        <span class="n">context</span><span class="p">,</span>
        <span class="n">context_instance</span><span class="o">=</span><span class="n">RequestContext</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
    <span class="p">)</span>

<span class="k">def</span> <span class="nf">items</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">item_type_viewname</span> <span class="o">=</span> <span class="s">'</span><span class="si">%s</span><span class="s">/by_date'</span> <span class="o">%</span> <span class="p">(</span><span class="n">COUCHDB_DESIGN_DOCNAME</span><span class="p">,)</span>
    <span class="n">lifestream_items</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">view</span><span class="p">(</span><span class="n">item_type_viewname</span><span class="p">,</span> <span class="n">descending</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">context</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s">'items'</span><span class="p">:</span> <span class="nb">list</span><span class="p">(</span><span class="n">lifestream_items</span><span class="p">),</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">render_to_response</span><span class="p">(</span>
        <span class="s">'couch_lifestream/list.html'</span><span class="p">,</span>
        <span class="n">context</span><span class="p">,</span>
        <span class="n">context_instance</span><span class="o">=</span><span class="n">RequestContext</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
    <span class="p">)</span>
</pre>
<p>The <tt class="docutils literal">item</tt> view is fairly self-explanatory.  We query the db for the object of
the specified id, and if it doesn't exist, we throw a 404.  If it does exist, we
throw it into the context and let the template render the page.  The <tt class="docutils literal">items</tt>
view is slightly more interesting.  In this case, we're using that CouchDB view
that we created to query the database by date, and passing that list into the
context.</p>
<p>Obviously there's a ton more that we could cover, but these basic building
blocks that I've demonstrated are enough to get you started.  After this it's
mostly all presentational work.  I've open sourced all of the code that has been
written so far for the upcoming lifestream portion of this site, even though
right now it only supports <a class="reference external" href="http://twitter.com/">Twitter</a> and <a class="reference external" href="http://pownce.com/">Pownce</a>.  I plan on continuing work
on it to support all of the services that I use.  You can track my progress
at the <a class="reference external" href="http://github.com/ericflo/django-couch-lifestream/tree/master">project's page</a>.</p>
<p>I'll make sure to blog about this again once the project is more mature, but for
now it should be fun to play around with.  Are you using CouchDB with Django?
If yes, then how are you dealing with that interaction?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/couchdb/">CouchDB</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Legacy Code]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/09/legacy-code/"/>
        <updated>2008-11-09T02:45:13</updated>
        <id>http://eflorenzano.com/blog/2008/11/09/legacy-code/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/09/legacy-code/">Legacy Code</a></h3>
<p class="datetime">Nov 09, 2008</p>
<div class="document">
<p>Prompted by this whole blog post-per-day thing, I've begun looking at the source
code for this site again.  It was my first real Django project in early 2006,
and I was excited about all of the features that it gave me.  The community was
much smaller then, and although I suspect the guys from <a class="reference external" href="http://www.mediaphormedia.com/">Lawrence</a> had a good
idea of where site logic should go, at that time there was not the
<a class="reference external" href="http://www.b-list.org/weblog/2007/mar/27/reusable-django-apps/">widespread</a> <a class="reference external" href="http://pinaxproject.com/">knowledge</a> of <a class="reference external" href="http://apress.com/book/view/1590599969">best</a> <a class="reference external" href="http://www.djangobook.com/">practices</a>.</p>
<p>No knowledge of best practices, still learning Django, and being a relative
web development newbie, means that the code ended up being quite bad.  It was
all under one application, named 'blog'.  All of the content loaded into the
sidebar was done via context processors (one processor called back to this
<tt class="docutils literal">get_digg_rss</tt> function that I <a class="reference external" href="http://www.eflorenzano.com/blog/post/new-site-live/">blogged about</a>, for example), and all the
templates were housed under that application.</p>
<p>Yeah.  It was that bad.</p>
<p>But over the years, Django evolved, and some code that this blog used were
deprecated while new functionality was added.  Over time as things broke, little
by little things were fixed and broken out into their own apps.  In short, the
site got better.  It was always organic improvement, though, and never a
deliberate effort.  Meaning that while it's better than it was, it's still not
very good.</p>
<p>Browsing through the code gives me a bit of nostalgia, but overwhelmingly my
urge is to just delete the entire thing and start over, picking from the best
reusable apps and migrating data as needed.  After some consideration, I don't
think that urge is a good urge to act upon.  While it would take me a few
afternoons to fix the code of the site, it would take several days to start
from scratch.</p>
<p>This is one of my biggest faults as a programmer.  Instead of working with ugly
code and molding it into better code, I always enjoy starting from a clean slate
and building it up from there--so much so that I'll sacrifice productivity to
do so.  I'm going to attempt to face this fault by not giving in to the
temptation to rebuild, and instead to work with what I've got.  Who knows, maybe
I'll even open-source it.  I won't open-source it unless its quality is up to
par with the other open source apps in the Django reusable app ecosystem.</p>
<p>How do you deal with legacy code?  Do you have any tips or tricks on how to do
it?  Do you think that it's better to just start from scratch?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[It&#39;s Caches All the Way Down]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/08/its-caches-all-way-down/"/>
        <updated>2008-11-08T05:52:53</updated>
        <id>http://eflorenzano.com/blog/2008/11/08/its-caches-all-way-down/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/08/its-caches-all-way-down/">It&#39;s Caches All the Way Down</a></h3>
<p class="datetime">Nov 08, 2008</p>
<div class="document">
<p>A few years back a non-technical person asked me to explain what, exactly, the
operating system did.  I first started out by speaking in broad generalities,
saying that it takes care of the basic needs of the computer and that it helps
one thing talk to another.  But that answer wasn't good enough.  This person
wanted me to go into more detail.  What happens when I'm in the calculator
application and I type 1+1 and hit enter?  What things need to happen?</p>
<p>That really tripped me up.  It's hard to even know where to start when someone
who's curious like that asks a relatively innocent question like that.  So I
decided to just start from the basics.  &quot;A processor has these things called
registers&quot;, I said.  &quot;And they store a tiny little amount of information, which
they can do things with, like add and subtract.&quot;  That seemed to basically
satisfy them, but not me.</p>
<p>I made sure to say that, &quot;You can't just keep everything in registers, because
there are only a few of those.  So you have to keep some data stored
in this place with more space for data but it's slower.&quot;  To which they
responded, &quot;Oh, so is that why when I add more RAM my computer gets faster?&quot;
&quot;No,&quot; I said, &quot;this is all still on the processor.&quot;  &quot;OK, so what's RAM then
and why is it supposed to help?&quot; they asked.  &quot;Because we can't store everything
on the processor itself, because there's not enough space for data, so we have
to store it in this place with much more space for data, but which is slower.&quot;</p>
<p>At this point I realized how redundant this conversation was going to get.  It's
the same thing for the hard drive, and (if you're old-school) tape drive or (if
you're new-school) the internet.  At the same point that person seemed to get
bored--that moment of curiosity had passed.  Computers just do their thing
and we really didn't have to do anything special for all of that data movement
to take place.</p>
<p>That's what struck me.  When you come down to it, computers are just a waterfall
of different caches, with systems that determine what piece of data goes where
and when.  For the most part, in user space, we don't care about much of that
either.  When writing a web application or even a desktop application, we don't
much care whether a bit is in the register, the L1 or L2 cache, RAM, or if it's
being swapped to disk.  We just care that whatever system is managing that data,
it's doing the best it can to make our application fast.</p>
<p>But then another thing struck me.  Most web developers <em>DO</em> have to worry about
the cache.  We do it every day.  Whether you're using memcached or velocity or
some other caching system, everyone's manually moving data from the database
to a cache layer, and back again.  Sometimes we do clever things to make sure
this cached data is correct, but sometimes we do some braindead things.  We
certainly manage the cache keys ourselves and we come up with systems again and
again to do the same thing.</p>
<p>Does this strike anyone else as inconsistent?  For practically every cache layer
down the chain, a system (whose algorithms are usually the result of years and
years of work and testing) automatically determines how to best utilize that
cache, yet we do not yet have a <strong>good</strong> system for doing that with databases.
Why do you think that is?  Is it truly one of the two hard problems of
computer science?  Is it impossible to do this automatically?  I honestly don't
have the answers, but I'm interested if you do.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/memcached/">Memcached</a></li>
      
        <li><a href="/blog/categories/caching/">Caching</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Secrets of the Django ORM]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/06/secrets-django-orm/"/>
        <updated>2008-11-06T17:14:54</updated>
        <id>http://eflorenzano.com/blog/2008/11/06/secrets-django-orm/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/06/secrets-django-orm/">Secrets of the Django ORM</a></h3>
<p class="datetime">Nov 06, 2008</p>
<div class="document">
<p>You won't see this in the Django documentation, you won't see it mentioned on
other blogs, and you certainly won't hear the core developers of Django boasting
about it, but Django's ORM has a secret weapon: it supports SQL <em>group_by</em> and
<em>having</em> clauses, and it has for quite some time.</p>
<p>It's not part of the public <tt class="docutils literal">QuerySet</tt> API, but rather a part of the private
<tt class="docutils literal">Query</tt> API.  But just because it's not part of the public API doesn't mean
that it's not easy to use--it just means that it might change in the future.
So it's really a &quot;use at your own risk&quot; type of deal now.  If you're up for
keeping on top of things so that you know what to change when the next version
of Django comes out, then read on.  First, let's start with some model
definition:</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">TumbleItem</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">255</span><span class="p">)</span>
    <span class="n">item_type</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">50</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">'</span><span class="si">%s</span><span class="s">: &quot;</span><span class="si">%s</span><span class="s">&quot;'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">item_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">)</span>
</pre>
<p>A simple tumblog item.  Very simple, as in, not really useful at all.  But
that's OK since this is just a demonstration.  To demonstrate, let's create
some data:</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">ti1</span> <span class="o">=</span> <span class="n">TumbleItem</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">'Blog Post 1'</span><span class="p">,</span> <span class="n">item_type</span><span class="o">=</span><span class="s">'blog'</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ti2</span> <span class="o">=</span> <span class="n">TumbleItem</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">'Blog Post 2'</span><span class="p">,</span> <span class="n">item_type</span><span class="o">=</span><span class="s">'blog'</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ti3</span> <span class="o">=</span> <span class="n">TumbleItem</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">'Blog Post 3'</span><span class="p">,</span> <span class="n">item_type</span><span class="o">=</span><span class="s">'blog'</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ti4</span> <span class="o">=</span> <span class="n">TumbleItem</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">'Article Dugg 1'</span><span class="p">,</span> <span class="n">item_type</span><span class="o">=</span><span class="s">'digg'</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ti5</span> <span class="o">=</span> <span class="n">TumbleItem</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">'Article Dugg 2'</span><span class="p">,</span> <span class="n">item_type</span><span class="o">=</span><span class="s">'digg'</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ti6</span> <span class="o">=</span> <span class="n">TumbleItem</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">'Link Saved 1'</span><span class="p">,</span> <span class="n">item_type</span><span class="o">=</span><span class="s">'link'</span><span class="p">)</span>
</pre>
<p>OK now that we've loaded some data, let's use the group_by functionality!</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">qs</span> <span class="o">=</span> <span class="n">TumbleItem</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">qs</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">group_by</span> <span class="o">=</span> <span class="p">[</span><span class="s">'item_type'</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">item_types</span> <span class="o">=</span> <span class="p">[</span><span class="n">i</span><span class="o">.</span><span class="n">item_type</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">qs</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">item_types</span>
<span class="go">[u'blog', u'digg', u'link']</span>
</pre>
<p>There we go, it's quick, easy, and it seems to Just Work. But let's try to grab
only the item_types which have more than one item:</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">qs</span> <span class="o">=</span> <span class="n">TumbleItem</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">qs</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">group_by</span> <span class="o">=</span> <span class="p">[</span><span class="s">'item_type'</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">qs</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">having</span> <span class="o">=</span> <span class="p">[</span><span class="s">'COUNT(item_type) &gt; 1'</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">item_types</span> <span class="o">=</span> <span class="p">[</span><span class="n">i</span><span class="o">.</span><span class="n">item_type</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">qs</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">item_types</span>
<span class="go">[u'blog', u'digg']</span>
</pre>
<p>And now we've successfully used the group_by and having functionality in the
Django ORM.  I'm excited for some aggregation functionality to start being
exposed as a public API, as I'm sure it will be more elegant than this solution,
but at the same time this is a neat hidden secret in the Django ORM.  Well now
you have the knowledge, so you have the power, and it's up to you to use it wisely!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/databases/">Databases</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[The internet is in immediate danger of collapse]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/06/internet-immediate-danger-collapse/"/>
        <updated>2008-11-06T05:38:48</updated>
        <id>http://eflorenzano.com/blog/2008/11/06/internet-immediate-danger-collapse/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/06/internet-immediate-danger-collapse/">The internet is in immediate danger of collapse</a></h3>
<p class="datetime">Nov 06, 2008</p>
<div class="document">
<p>Wow, that's quite a title!  You're already probably queuing up all of your
counterpoints and your rebuttals.  In fact it's not quite that serious, but a
seriously worrying trend is emerging that I'd like to address.</p>
<div class="section" id="the-problem">
<h4>The Problem</h4>
<p>Today many sites are so totally dependent on 3rd-party services that when
certain services go down, a chain of outages end up knocking out many of the
sites that we use on a daily basis--some for critical business applications.
But I'm being too abstract, so let's take a concrete example of this: Google
Analytics.</p>
<p>Back in late 2007, <a class="reference external" href="http://www.google.com/analytics">Google's analytics and monitoring service</a> went
down with no explanation.  Most sites at that time had installed a line of
Javascript in their HTML <tt class="docutils literal">head</tt> element which made a call to
<tt class="docutils literal">document.write</tt>.  This causes the <strong>rest of the site to stop and wait for
Google's servers</strong>.  Normally this is not a bad thing, because Google has some
pretty fast and reliable web servers.  But in this 24 hour period, anyone who
had this code in their <tt class="docutils literal">head</tt> element had an absolutely broken site.  Users
could not see their site at all.  And was no fault of either the site developers
or of the users--just Google's fault.</p>
<p>Another example: Earlier this year, Amazon had an outage in their popular <a class="reference external" href="http://aws.amazon.com/s3/">S3</a>
file storage service for several hours.  At the time, you didn't need to be very
tech savvy or know much about computers to know that something was seroiusly
wrong with the internet.  Sites from across the net were throwing 500 errors,
looking completely awful without their media files, and the internet simply
became a pretty awful place to get things done.  From one company.  Having a
problem with one service.</p>
<p>And since then we have become even more dependent on 3rd party services for
even more widgets, &quot;cloud computing&quot;, and more.  Frankly this &quot;cloud computing&quot;
craze scares the hell out of me.  The more interconnected our various bits of
HTML and HTTP are, the more chances there are for massive catastrophe.  Just
look at the credit default swaps problem we're having in the USA for another
concrete example of how this type of interdependence can fail in catastrophic
ways.</p>
</div>
<div class="section" id="the-solution">
<h4>The Solution</h4>
<p>Services like S3, Google Analytics, and even Twitter are great services.  They
add lots of value for larger businesses and even more for a startup, so there's
a large incentive to use them.  I think that's absolutely fine and is actually
a good idea.  That being said, we need to manage our use of these services in a
responsible way.  Instead of storing data directly to S3, store it on a server
and asynchronously upload it to S3.  That way, you can set up an S3-pinger and
if it goes down you can have the server automatically switch to serving the
media itself.</p>
<p>We need to build standardized tools that fetch data from webservices locally,
from which they are served to the user.  We need to build systems that
asynchronously sync data bidirectionally from all of these different webservers
and ensure that the integrity of our data on the web is sound.  Right now this
is a tedious, and error-prone task, but we can do better.  We can build
cross-platform tools and libraries that will solve this problem, allow us to
use 3rd-party services, and rest sound knowing that tomorrow no matter what
happens to Amazon, the internet will still be around.</p>
<p>DISCLAIMER: This is almost entirely a ripoff of a talk given by <a class="reference external" href="TimothyFitz">Timothy Fitz</a>
at <a class="reference external" href="http://superhappydevhouse.org/">Super Happy Dev House</a> last month in San Francisco.  While I think it's a
really good point I can't take credit for having been the first to worry about
it.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/amazon/">amazon</a></li>
      
        <li><a href="/blog/categories/web-services/">Web Services</a></li>
      
        <li><a href="/blog/categories/internet/">internet</a></li>
      
        <li><a href="/blog/categories/google/">Google</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Why SQLAlchemy is the best ORM on the face of the planet]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/05/why-sqlalchemy-best-orm-face-planet/"/>
        <updated>2008-11-05T02:03:04</updated>
        <id>http://eflorenzano.com/blog/2008/11/05/why-sqlalchemy-best-orm-face-planet/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/05/why-sqlalchemy-best-orm-face-planet/">Why SQLAlchemy is the best ORM on the face of the planet</a></h3>
<p class="datetime">Nov 05, 2008</p>
<div class="document">
<p><a class="reference external" href="http://www.sqlalchemy.org/">SQLAlchemy</a> started out with a bang.  When it came out, there was really nothing else out there that even came close in terms of features, performance, and ease of use.  <a class="reference external" href="http://www.sqlobject.org/">SQLObject</a> was the reigning champion of Python ORMs, and the Django ORM was around but much less powerful at that time.  So now it's 3 years later.  Is SQLAlchemy still the best?  I think it is, and here's why:</p>
<ol class="arabic simple">
<li>It has <em>no</em> preconception of how your database should be laid out.  If you haven't created your database yet, you can choose to use the ActiveRecord-style layout of one object mapping to one table.  If that's not the case for your application, you can even map arbitrary select statements onto objects, if that's how much flexibility you want.  So already, SQLAlchemy is an option for thousands of people for which the other ORMs would not be.</li>
<li>It's tuned for performance.  Whether it's the extremely slick connection pooling feature, or whether it's the <a class="reference external" href="http://www.sqlalchemy.org/docs/05/session.html#unitofwork">Unit of Work</a> design pattern which will issue as few queries as possible.  Whether it's the ability to specify lazily or eagerly loaded columns, or whether you note the identity map which keeps track of all of the objects that are in memory, SQLAlchemy has lots of performance-tuning abilities.  In my mind, SQLAlchemy gives you all the tools that you need to create a blazing fast application.</li>
<li>It has a wonderful community which is building great tools on top of SQLAlchemy itself.  A clear example of this is the set of plugins that are shipped with SQLAlchemy, by default.  These include a simple <a class="reference external" href="http://www.sqlalchemy.org/docs/05/plugins.html#plugins_declarative">declarative</a> layer, an <a class="reference external" href="http://www.sqlalchemy.org/docs/05/plugins.html#plugins_associationproxy">association proxy</a>, and <a class="reference external" href="http://www.sqlalchemy.org/docs/05/plugins.html#plugins_sqlsoup">SqlSoup</a>, which uses introspection to map tables on the fly.  These are great examples of how the community is creating great libraries that sit on top of SQLAlchemy.  They also serve as proof of the configurability of the ORM itself.</li>
<li>It supports your database.  According to its own website, &quot;SQLAlchemy includes dialects for SQLite, Postgres, MySQL, Oracle, MS-SQL, Firebird, MaxDB, MS Access, Sybase and Informix; IBM has also released a DB2 driver.&quot;  This is a pretty massive list and goes a long way in proving the power of the ORM.</li>
</ol>
<p>It comes down to this.  SQLAlchemy is a well-designed, performant, widely supported ORM which treats SQL with the respect it deserves.  I haven't provided any code samples here because you should do that yourselves, with your own apps.  It's just that good.  So what are you waiting for?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/sqlalchemy/">SQLAlchemy</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Database triggers aren&#39;t evil, and they actually kind of rock]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/04/database-triggers-arent-evil-and-they-actually-kin/"/>
        <updated>2008-11-04T02:44:19</updated>
        <id>http://eflorenzano.com/blog/2008/11/04/database-triggers-arent-evil-and-they-actually-kin/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/04/database-triggers-arent-evil-and-they-actually-kin/">Database triggers aren&#39;t evil, and they actually kind of rock</a></h3>
<p class="datetime">Nov 04, 2008</p>
<div class="document">
<div class="section" id="who-says-they-suck">
<h4>Who says they suck?</h4>
<p>Nobody that I've seen has come out and actually said that they don't like
database triggers, but at the same time, Python (Django) programmers like to
program in Python.  And PL/pgSQL certainly is not Python.  There's a tendency to
do everything in Python--especially with the use of Django's dispatcher.</p>
<p>But there's some serious overhead with that approach, and roundtrips, and race
conditions, etc.  If you're using a good database, there's an alternative:
you guessed it, database triggers.</p>
</div>
<div class="section" id="let-s-set-up-some-models">
<h4>Let's set up some models</h4>
<p>Here will be our models for the remainder of this post:</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">Bookmark</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
    <span class="n">url</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">URLField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">255</span><span class="p">)</span>

    <span class="n">num_votes</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">PositiveIntegerField</span><span class="p">(</span><span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">blank</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
    <span class="n">score</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">IntegerField</span><span class="p">(</span><span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">blank</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Vote</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">bookmark</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">Bookmark</span><span class="p">,</span> <span class="n">related_name</span><span class="o">=</span><span class="s">'votes'</span><span class="p">)</span>
    <span class="n">value</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">IntegerField</span><span class="p">()</span>
</pre>
<p>As you can tell, we have a straightforward <tt class="docutils literal">Bookmark</tt> and <tt class="docutils literal">Vote</tt> models here.
But there are also two denormalized fields: <tt class="docutils literal">num_votes</tt>, and <tt class="docutils literal">score</tt>.</p>
</div>
<div class="section" id="doing-it-in-python">
<h4>Doing it in Python</h4>
<p>The advantage of doing this in Python is that it's simple and Django supports
it out of the box.  Here's how the code for that would look:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">signals</span>

<span class="k">def</span> <span class="nf">update_bookmark_aggregate</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="n">bmark</span> <span class="o">=</span> <span class="n">instance</span><span class="o">.</span><span class="n">bookmark</span>
    <span class="n">bmark</span><span class="o">.</span><span class="n">num_votes</span> <span class="o">=</span> <span class="n">bmark</span><span class="o">.</span><span class="n">votes</span><span class="o">.</span><span class="n">count</span><span class="p">()</span>
    <span class="n">bmark</span><span class="o">.</span><span class="n">score</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">bmark</span><span class="o">.</span><span class="n">votes</span><span class="o">.</span><span class="n">values_list</span><span class="p">(</span><span class="s">'value'</span><span class="p">,</span> <span class="n">flat</span><span class="o">=</span><span class="bp">True</span><span class="p">))</span>
    <span class="n">bmark</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">force_update</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">signals</span><span class="o">.</span><span class="n">post_save</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">update_bookmark_aggregate</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">Vote</span><span class="p">)</span>
</pre>
<p>Very simply, every time a vote is saved, the <tt class="docutils literal">update_bookmark_aggregate</tt>
function is called which updates the bookmark with its new score and num_votes.</p>
</div>
<div class="section" id="doing-it-in-pl-pgsql">
<h4>Doing it in Pl/pgSQL</h4>
<p>Create a new file, named <tt class="docutils literal">management.py</tt> under your bookmarks app directory.
Its contents will be as follows:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">signals</span>
<span class="kn">from</span> <span class="nn">bookmarks</span> <span class="kn">import</span> <span class="n">models</span>

<span class="n">sql</span> <span class="o">=</span> <span class="s">&quot;&quot;&quot;
CREATE LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION update_bookmark_aggregate_trigger()
    RETURNS &quot;trigger&quot; AS '
    DECLARE
        new_score INTEGER;
        new_num_votes INTEGER;
    BEGIN
        SELECT COUNT(*) INTO STRICT new_num_votes FROM bookmarks_vote
            WHERE bookmark_id = NEW.bookmark_id;
        SELECT COALESCE(SUM(value), 0) INTO STRICT new_score FROM bookmarks_vote
            WHERE bookmark_id = NEW.bookmark_id;
    UPDATE bookmarks_bookmark
        SET
            score = new_score,
            num_votes = new_num_votes
        WHERE id = NEW.bookmark_id;
    RETURN NEW;
    END;' LANGUAGE 'plpgsql' VOLATILE;

CREATE TRIGGER update_bookmark_aggregate_trigger AFTER INSERT OR UPDATE
    ON bookmarks_vote FOR EACH ROW
    EXECUTE PROCEDURE update_bookmark_aggregate_trigger();
&quot;&quot;&quot;</span>

<span class="k">def</span> <span class="nf">create_trigger</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">created_models</span><span class="p">,</span> <span class="n">verbosity</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">connection</span>
    <span class="n">cursor</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
    <span class="n">cursor</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">)</span>
<span class="n">signals</span><span class="o">.</span><span class="n">post_syncdb</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">create_trigger</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">models</span><span class="p">)</span>
</pre>
<p>In this file we have declared two variables, <tt class="docutils literal">new_score</tt>, and
<tt class="docutils literal">new_num_votes</tt>.  We do two queries to get the aggregate data.  And then we
update the bookmark to reflect the new aggregated values.  This script is
executed once when the bookmarks models are first loaded into the database, and
we're all set!</p>
</div>
<div class="section" id="let-s-see-how-it-works">
<h4>Let's see how it works</h4>
<pre class="code pycon literal-block">
<span class="kn"></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">bookmarks.models</span> <span class="kn">import</span> <span class="n">Bookmark</span><span class="p">,</span> <span class="n">Vote</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">b</span> <span class="o">=</span> <span class="n">Bookmark</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">&quot;Blog&quot;</span><span class="p">,</span> <span class="n">url</span><span class="o">=</span><span class="s">'http://eflorenzano.com/'</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">b</span><span class="o">.</span><span class="n">num_votes</span>
<span class="go">0
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">b</span><span class="o">.</span><span class="n">score</span>
<span class="go">0
# There is no aggregate data yet
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Vote</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">bookmark</span><span class="o">=</span><span class="n">b</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="go">&lt;Vote: Vote object&gt;
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">Vote</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">bookmark</span><span class="o">=</span><span class="n">b</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="go">&lt;Vote: Vote object&gt;
# We need to re-query for the bookmark, due to no identity map in Django.
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">b</span> <span class="o">=</span> <span class="n">Bookmark</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">b</span><span class="o">.</span><span class="n">num_votes</span>
<span class="go">2
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">b</span><span class="o">.</span><span class="n">score</span>
<span class="go">3</span>
</pre>
<p>Voila!  This was all done in the database behind the scenes.  Very cool, very
fast, and it kind of rocks.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/databases/">Databases</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/triggers/">Triggers</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Gems of Python]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/02/gems-python/"/>
        <updated>2008-11-02T22:04:42</updated>
        <id>http://eflorenzano.com/blog/2008/11/02/gems-python/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/02/gems-python/">Gems of Python</a></h3>
<p class="datetime">Nov 02, 2008</p>
<div class="document">
<p>I've been using Python for a few years now, and continue to love it.  But the language is large enough that it seems every project that I look at uses a different subset of the language's features.  The nice thing is that by reading different people's code, you can find out about some real gems in the Python programming language.  Some of these tips are extremely obvious, and some are more obscure.  In any case, here are what I consider to be some real gems:</p>
<ol class="arabic">
<li><p class="first"><a class="reference external" href="http://docs.python.org/library/functions.html?highlight=filter#filter">filter</a>  This is one of Python's built-in functions, which allows you to remove unwanted items from a list.  It's very useful and highly overlooked.  Here's an example of how to use it:</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">lst</span> <span class="o">=</span> <span class="p">[</span><span class="s">'1'</span><span class="p">,</span> <span class="s">'2'</span><span class="p">,</span> <span class="s">'3'</span><span class="p">,</span> <span class="s">'4'</span><span class="p">,</span> <span class="s">'asdf'</span><span class="p">,</span> <span class="s">'5'</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">is_int_string</span><span class="p">(</span><span class="n">i</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>        <span class="nb">int</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="bp">True</span>
<span class="gp">... </span>    <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="bp">False</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">int_string_list</span> <span class="o">=</span> <span class="nb">filter</span><span class="p">(</span><span class="n">is_int_string</span><span class="p">,</span> <span class="n">lst</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">int_string_list</span>
<span class="go">['1', '2', '3', '4', '5']</span>
</pre>
<p>But there is a really neat filter shortcut, too.  You can have it filter out any values which evaluate to False.</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">lst</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="s">''</span><span class="p">,</span> <span class="s">'asdf'</span><span class="p">,</span> <span class="bp">None</span><span class="p">,</span> <span class="p">[],</span> <span class="p">(),</span> <span class="s">'fdsa'</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">filter</span><span class="p">(</span><span class="bp">None</span><span class="p">,</span> <span class="n">lst</span><span class="p">)</span>
<span class="go">[2, 'asdf', 'fdsa']</span>
</pre>
<p>This is really great for filtering out unwanted values in a list.  I use it actually quite frequently and hope to see it in more python projects.</p>
</li>
<li><p class="first"><a class="reference external" href="http://docs.python.org/library/itertools.html?highlight=itertools#itertools.chain">itertools.chain</a>  I often have a list of lists, and want to run some operation on each item in that list of lists.  itertools.chain allows that to happen.  Let me demonstrate with an example:</p>
<pre class="code pycon literal-block">
<span class="kn"></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">itertools</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">lst</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">],</span> <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">]]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">list</span><span class="p">(</span><span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="o">*</span><span class="n">lst</span><span class="p">))</span>
<span class="go">[1, 2, 3, 4, 5, 6, 7, 8, 9]
</span><span class="nb"></span><span class="gp">&gt;&gt;&gt; </span><span class="nb">sum</span><span class="p">(</span><span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="o">*</span><span class="n">lst</span><span class="p">))</span>
<span class="go">45</span>
</pre>
<p><strong>itertools.chain</strong> has become a major part of my day-to-day coding toolbox, and it's a real python gem.</p>
</li>
<li><p class="first"><a class="reference external" href="http://docs.python.org/library/stdtypes.html?highlight=setdefault#dict.setdefault">setdefault</a> Do you find yourself writing this type of <tt class="docutils literal"><span class="pre">try..except</span> KeyError</tt> pattern often?</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">dct</span> <span class="o">=</span> <span class="p">{}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">items</span> <span class="o">=</span> <span class="p">[</span><span class="s">'anne'</span><span class="p">,</span> <span class="s">'david'</span><span class="p">,</span> <span class="s">'kevin'</span><span class="p">,</span> <span class="s">'eric'</span><span class="p">,</span> <span class="s">'anthony'</span><span class="p">,</span> <span class="s">'andrew'</span><span class="p">]</span>
<span class="gp">... </span><span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">items</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>        <span class="n">dct</span><span class="p">[</span><span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="gp">... </span>    <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="gp">... </span>        <span class="n">dct</span><span class="p">[</span><span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="p">[</span><span class="n">name</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">dct</span>
<span class="go">{'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']}</span>
</pre>
<p>That's a lot of boilerplate code for something that seems like it should be much easier.  Thankfully, this can be solved much  more easily by using <strong>setdefault</strong>, like so:</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">dct</span> <span class="o">=</span> <span class="p">{}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">items</span> <span class="o">=</span> <span class="p">[</span><span class="s">'anne'</span><span class="p">,</span> <span class="s">'david'</span><span class="p">,</span> <span class="s">'kevin'</span><span class="p">,</span> <span class="s">'eric'</span><span class="p">,</span> <span class="s">'anthony'</span><span class="p">,</span> <span class="s">'andrew'</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">items</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">dct</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">dct</span>
<span class="go">{'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']}</span>
</pre>
<p>Much better, isn't it?</p>
</li>
<li><p class="first"><a class="reference external" href="http://docs.python.org/library/collections.html?highlight=defaultdict#collections.defaultdict">defaultdict</a> Given <cite>setdefault</cite>, it still seems like there should be a better way.  If you know upfront that you will be setting everything to an empty list if it isn't found, you should be able to specify that and have it just Do The Right Thing.  Thankfully, <strong>defaultdict</strong> does just that:</p>
<pre class="code pycon literal-block">
<span class="kn"></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">dct</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">items</span> <span class="o">=</span> <span class="p">[</span><span class="s">'anne'</span><span class="p">,</span> <span class="s">'david'</span><span class="p">,</span> <span class="s">'kevin'</span><span class="p">,</span> <span class="s">'eric'</span><span class="p">,</span> <span class="s">'anthony'</span><span class="p">,</span> <span class="s">'andrew'</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">items</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">dct</span><span class="p">[</span><span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">dct</span>
<span class="go">defaultdict(&lt;type 'list'&gt;, {'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']})
</span><span class="nb"></span><span class="gp">&gt;&gt;&gt; </span><span class="nb">dict</span><span class="p">(</span><span class="n">dct</span><span class="p">)</span>
<span class="go">{'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']}</span>
</pre>
<p>I usually end up converting the defaultdict back to a regular dict before passing it around, but other than that, it's quite a useful tool to use.</p>
</li>
<li><p class="first"><a class="reference external" href="http://docs.python.org/library/functions.html?highlight=zip#zip">zip</a> This is one that most people usually know, but still I find that sometimes people do strange things where a zip would be much easier.</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">numbers</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">letters</span> <span class="o">=</span> <span class="p">[</span><span class="s">'a'</span><span class="p">,</span> <span class="s">'b'</span><span class="p">,</span> <span class="s">'c'</span><span class="p">,</span> <span class="s">'d'</span><span class="p">,</span> <span class="s">'e'</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">num</span><span class="p">,</span> <span class="n">let</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">numbers</span><span class="p">,</span> <span class="n">letters</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">print</span> <span class="s">&quot;Letter </span><span class="si">%d</span><span class="s"> is '</span><span class="si">%s</span><span class="s">'&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="n">let</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">Letter 1 is 'a'
Letter 2 is 'b'
Letter 3 is 'c'
Letter 4 is 'd'
Letter 5 is 'e'</span>
</pre>
<p>Pretty simple, very common, and yet sometimes coders seem to work around it.  Also worth mentioning is that there's an iterable version of this, <a class="reference external" href="http://docs.python.org/library/itertools.html?highlight=izip#itertools.izip">izip</a>, which is located in itertools.</p>
</li>
<li><p class="first"><a class="reference external" href="http://docs.python.org/library/stdtypes.html?highlight=title#str.title">title</a>  I wrote some little function to turn a string of lower case text into a 'titleized' string at work, and a few coworkers laughed and said,  &quot;why didn't you just use title&quot;?  The answer: I didn't know about it.  It's not something you run into every day, but when you need it, it's super useful.  Here's an example:</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">s</span> <span class="o">=</span> <span class="s">'the little green men'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">s</span><span class="o">.</span><span class="n">title</span><span class="p">()</span>
<span class="go">'The Little Green Men'</span>
</pre>
<p>It's that easy!  Next time you need to turn something into a title, look for this method on strings first.</p>
</li>
</ol>
<p>That's all I've got for now.  There are many more gems in the Python programming language, but these are some that I think are especially useful.  Please share in the comments if you have any other gems that you have found in your uses of Python.</p>
<p><strong>UPDATE</strong>: Eric Holscher has posted <a class="reference external" href="http://ericholscher.com/blog/2008/nov/3/python-gems-my-own/">a list of his Python gems as well</a>, and it's got some great stuff on it.  Check it out!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[What&#39;s Next?]]></title>
        <link href="http://eflorenzano.com/blog/2008/11/02/whats-next/"/>
        <updated>2008-11-02T01:24:11</updated>
        <id>http://eflorenzano.com/blog/2008/11/02/whats-next/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/11/02/whats-next/">What&#39;s Next?</a></h3>
<p class="datetime">Nov 02, 2008</p>
<div class="document">
<p>A few days ago, someone asked me &quot;What's the next big thing?&quot;  The context was a discussion of web development tools, as they exist today.  At first I laughed and brushed off the question as clichA, because everyone seems to have a different answer and almost nobody ends up being correct.  But it is a good question to ask oneself, and I'm noticing that more and more people seem to be searching for that &quot;next big thing&quot;.</p>
<p>The standard response du jour seems to be &quot;cloud computing&quot;.  However with a term like that, you can understand why there are disagreements as to what exactly cloud computing is.  I'm not so convinced.  I'm not convinced that thick client computing will come back, either, but certainly the thought of distributed computing will continue to resurface--which is quite directly at odds with the concept of cloud computing (depending on how you define cloud computing, of course).</p>
<div class="section" id="examining-today-s-problems">
<h4>Examining today's problems</h4>
<p>Before we can talk about what will emerge as the next big thing, we need to first look at what sucks right now:</p>
<ol class="arabic simple">
<li><strong>Concurrency.</strong>  Do I even need to spell out why this sucks right now?  It's easy to get wrong, and anyone who thinks that it isn't, is probably getting it wrong.</li>
<li><strong>Database technology, specifically relational databases.</strong>  This area of study is a proven and well-understood area of computer science, and for simple tasks, using a database could not get any easier.  Especially with the advance of <a class="reference external" href="http://en.wikipedia.org/wiki/Object-relational_mapping">object relational mappers</a> that are starting to generate really good SQL, it's easier than ever to set up some data structures to store and retrieve data from a database.  Try to start scaling this solution, as <a class="reference external" href="http://twitter.com/">many</a> <a class="reference external" href="http://mahalo.com/">people</a> <a class="reference external" href="http://digg.com/">are</a>, and you'll see why this technology (as it is today) doesn't hold up.</li>
<li><strong>Push.</strong>  With the emergence of data whose value is highly time dilated (think <a class="reference external" href="http://twitter.com/">Twitter</a>, <a class="reference external" href="http://friendfeed.com/">FriendFeed</a>, etc.), systems which operate under a &quot;pull&quot;-only interface are growing long in the tooth.  In fact, <a class="reference external" href="http://friendfeed.com/">FriendFeed</a> has a post explaining <a class="reference external" href="http://blog.friendfeed.com/2008/08/simple-update-protocol-fetch-updates.html">just how hard this is for them</a> (and proposing their own protocol which hasn't seemed to get any traction).</li>
</ol>
</div>
<div class="section" id="those-next-big-things">
<h4>Those next big things</h4>
<p>Given the aforementioned problems facing developers today, is the outlook bleak?  Is there no hope for the future?  Of course not!  As always, there are some exciting new technologies that are addressing these very problems.</p>
<ol class="arabic simple">
<li><a class="reference external" href="http://erlang.org/">Erlang</a>.  People who hype it up will tell you that this magically solves all concurrency problems, and they are simply being overzealous.  That being said, erlang encourages a style of programming that is extremely conducive to writing highly scalable applications.  Not only that, but there are over 20 years worth of experience and effort that have gone into making this language rock solid.  We've seen, over the past few years, an uptake in the number of applications that are written in erlang.  I expect that trend to continue, and as our need for highly concurrent applications increases, that rate will increase as well.  It's a good time to be an erlang programmer!</li>
<li><a class="reference external" href="http://incubator.apache.org/couchdb/">CouchDB</a>.  This is a system which, from the ground up, was designed for scale.  Built upon the aforementioned Erlang programming language, and upon the well tested and trusted <a class="reference external" href="http://spawnlink.com/articles/introduction-to-the-open-telecom-platform/">OTP</a> methodology, CouchDB takes a completely new approach to databases.  It is a document-oriented database, which means that it's best suited towards those documents which can easily be written down on a piece of paper.  (A business card is the prototypical example of a type of document that would be great to store in CouchDB.)  It's a blog post unto itself, but the forward-looking nature of CouchDB, along with it's adherence to the fundamentals of what makes the web work so well, has gotten a lot of people interested in the project.  I'd bet my career on CouchDB becoming a Very Big Deal.</li>
<li><a class="reference external" href="http://xmpp.org/">XMPP</a>.  Let's first start with the bad things about it.  It's complicated, overly abstract, obtuse, and there doesn't seem to be a succinct definition of what it is.  You may disagree with any or all of those points, but one thing is clear: what it does well, it does better than anything else, and that is push communication.  Look for laconi.ca and twitter to be early leaders in this field, and for the technology to be simplified and clarified.  If you're not subscribed to <a class="reference external" href="http://metajack.im/">Jack Moffitt</a>'s blog, do so.  Now.  He has pretty much single handedly rekindled my excitement for this technology, and with a few more people like him, we'll see this technology execute on its vast potential.</li>
<li><a class="reference external" href="http://python.org/">Python</a> and <a class="reference external" href="http://djangoproject.com/">Django</a>.  Of course I'm biased due to my closeness to these projects, and these are already big deals really.  But I think they will continue to further distinguish themselves from the competition.  Both projects have a reputation for not making important design decisions rashly and for sticking to their ideals.  As long as this trend continues, I believe the number of people flocking to these technologies will continue to grow.</li>
</ol>
</div>
<div class="section" id="what-do-you-think">
<h4>What do you think?</h4>
<p>I suspect I won't meet a lot of resistance on these choices.  But I hope I do!  What do you think about these choices?  Is there something that I'm missing?  Please share your thoughts in a blog post or in the comments.</p>
</div>
<div class="section" id="an-aside">
<h4>An aside</h4>
<p>I'm going to try to post one blog post each day of the month of November, as a challenge to myself and with some of my friends.  Others participating are:</p>
<ul class="simple">
<li><a class="reference external" href="http://oebfare.com/">Brian Rosner</a>.</li>
<li><a class="reference external" href="http://jtauber.com/blog/">James Tauber</a>.</li>
<li><a class="reference external" href="http://ericholscher.com/">Eric Holscher</a>.</li>
<li><a class="reference external" href="http://www.20seven.org/">Greg Newman</a>.</li>
<li><a class="reference external" href="http://justinlilly.com/">Justin Lilly</a>.</li>
<li><a class="reference external" href="http://adam.gomaa.us/blog/">Adam Gomaa</a>.</li>
<li><a class="reference external" href="http://jannisleidel.com/">Jannis Leidel</a>.</li>
</ul>
<p>Please check out their blogs and see all of the amazing content that they're already creating.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Programming Languages I&#39;ve Learned (In Rough Order) Meme]]></title>
        <link href="http://eflorenzano.com/blog/2008/09/29/programming-languages-ive-learned-rough-order/"/>
        <updated>2008-09-29T00:49:15</updated>
        <id>http://eflorenzano.com/blog/2008/09/29/programming-languages-ive-learned-rough-order/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/09/29/programming-languages-ive-learned-rough-order/">Programming Languages I&#39;ve Learned (In Rough Order) Meme</a></h3>
<p class="datetime">Sep 29, 2008</p>
<div class="document">
<p>Via <a class="reference external" href="http://jtauber.com/blog/2008/09/28/programming_languages_i've_learned_in_order/">James Tauber</a> via <a class="reference external" href="http://blog.dougalmatthews.com/2008/09/languages-ive-learned-in-order/">Dougal Matthews</a> and also <a class="reference external" href="http://homepage.mac.com/s_lott/iblog/architecture/C588245363/E20080928192106/index.html">Steven Lott</a>.</p>
<ul class="simple">
<li>Logo</li>
<li>C</li>
<li>Tcl/Tk</li>
<li>VB6</li>
<li>Java</li>
<li>C++</li>
<li>Python</li>
<li>Javascript</li>
<li>Scheme</li>
<li>MIPS Assembly</li>
<li>Perl</li>
<li>Erlang</li>
<li>ActionScript</li>
</ul>
<p>I've dabbled in a bunch more, like Ruby, but these are all of the ones that I've done one or more projects with.  This is fun--everyone should post their list!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/meme/">Meme</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[&#34;Django From the Ground Up&#34; Screencast Series Launched]]></title>
        <link href="http://eflorenzano.com/blog/2008/09/19/django-ground-screencast-series-launched/"/>
        <updated>2008-09-19T04:33:09</updated>
        <id>http://eflorenzano.com/blog/2008/09/19/django-ground-screencast-series-launched/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/09/19/django-ground-screencast-series-launched/">&#34;Django From the Ground Up&#34; Screencast Series Launched</a></h3>
<p class="datetime">Sep 19, 2008</p>
<div class="document">
<p>Over the past few weeks I've been busy coding, planning, and recording a series of screencasts which walk through the complete process of building a web application, from the ground up, with Django.  First I actually needed to code the site, deploy the site, and release the source code for the site.  Then, I had to go back and decide what in that whole process was worth talking about.  Finally, I had to re-code the site, but this time in front of the camera.  It's been a long process so far and I'm not finished yet, but tonight is the night that I am finally able to unveil the first two episodes.</p>
<p>If you haven't checked them out yet, head over to <a class="reference external" href="http://thisweekindjango.com/screencasts/episode/10/django-ground-episodes-1-and-2/">their spot on thisweekindjango.com</a>.</p>
<p>One thing that I'm a little bit worried about is that, by the very nature of going every step along the way, there are going to be some times where a topic I cover is on the more advanced side of things, and there are going to be topics that I cover which are on the more beginner side of things.  That can be fine, but there's a risk that in targeting such a broad audience, nobody ends up enjoying it.  As long as at least one person gets something out of the screencasts, I'll be happy.</p>
<p>So please, I only have 7 screencasts recorded so far, which means there is still time to turn this boat around!  If you have any suggestions or comments or questions, please leave a comment either here or on the <a class="reference external" href="http://thisweekindjango.com/screencasts/episode/10/django-ground-episodes-1-and-2/">episode's page at thisweekindjango.com</a>.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/django-from-the-ground-up/">Django From the Ground Up</a></li>
      
        <li><a href="/blog/categories/screencast/">Screencast</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[DjangoCon: Great conference, or greatest conference ever?]]></title>
        <link href="http://eflorenzano.com/blog/2008/09/08/djangocon-great-conference-or-greatest-conference/"/>
        <updated>2008-09-08T07:58:30</updated>
        <id>http://eflorenzano.com/blog/2008/09/08/djangocon-great-conference-or-greatest-conference/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/09/08/djangocon-great-conference-or-greatest-conference/">DjangoCon: Great conference, or greatest conference ever?</a></h3>
<p class="datetime">Sep 08, 2008</p>
<div class="document">
<p>The internet is such a strange place.  It allows us to collaborate on projects without ever seeing each other in person.  It allows us to meet new people, discover interests that we never knew we had, and keep in touch with friends.  However much the internet allows us to connect, though, there's simply no replacement for face-to-face contact.  Who would have thought that a piece of software whose main goal is to ease the pain of creating websites could bring people together from Prague, London, Germany, and even Lawrence, Kansas?  To me, it's nearly inconceivable.  But inconceivable or not, Django now has its <a class="reference external" href="http://djangocon.org/">very own conference</a>.</p>
<p>What I noticed about this first DjangoCon was a strange and exciting dichotomy of sorts, best exemplified by the opening and closing keynotes.  On the one hand, it's difficult to believe just how far Django has come since it was first released in 2005.  On the other hand, there are so many great ideas for Django and Django-related projects that it's nearly impossible to fight the urge to pop open your favorite text editor and start coding right now.</p>
<p>For <a class="reference external" href="http://avalonstar.com/">some people</a>, it was great to <a class="reference external" href="http://blog.howiworkdaily.com/">meet them</a> for the <a class="reference external" href="http://rob.cogit8.org/">first time</a>, and for <a class="reference external" href="http://jtauber.com/">others</a>, it was <a class="reference external" href="http://justinlilly.com/">great</a> to simply <a class="reference external" href="http://thisweekindjango.com/">reconnect</a>.  (Apologies to those that I couldn't fit into those links, by the way.)  Below is what I find to be a hilarious image, courtesy of <a class="reference external" href="http://devdojo.de/stream/">Sebastian Hillig</a>--whose <a class="reference external" href="http://www.flickr.com/photos/bastispicks/sets/72157607140512491/">Flickr page</a> has some really well-shot photos of the conference.</p>
<img alt="http://media.eflorenzano.com/img/djangocon.jpg" src="http://media.eflorenzano.com/img/djangocon.jpg" />
<p>For those of us involved in the <a class="reference external" href="http://pinaxproject.com/">Pinax</a> project, DjangoCon was a bit of a coming out party.  Firstly, in a literal sense--as <a class="reference external" href="http://cloud27.com/">cloud27</a>, the flagship website built on <a class="reference external" href="http://pinaxproject.com/">Pinax</a>, was launched (real men launch during presentations).  But also in a figurative sense--as most of us sported our Pinax-branded shirts and trumpeted the features that Pinax provides out of the box.  James Tauber's talk that kicked it all off couldn't have gone better, and I'm certain that when the video comes out on YouTube, it will enjoy a second and third life while people discover and become interested in the platform.</p>
<p>Another thing that surprised me about the conference was the amount of healthy criticism that went around in the conference.  Only a select few presentations escaped the <a class="reference external" href="http://flickr.com/photos/postneo/2836990032/">constructive criticism</a> of <a class="reference external" href="http://www.b-list.org/">James Bennett</a>, the <a class="reference external" href="http://www.flickr.com/photos/704race/2835013556/in/set-72157607147999891/">wrath</a> of <a class="reference external" href="http://www.iamcal.com/">Cal Henderson</a>, or the <a class="reference external" href="http://www.flickr.com/photos/704race/2837100896/">healthy reminders</a> by <a class="reference external" href="http://compoundthinking.com/blog/">Mark Ramm</a>.  Instead of people getting upset, though, I heard all sorts of conversations throughout the conference discussing ideas and strategies for how to overcome the shortcomings that were pointed out.</p>
<p>But in the end, what would DjangoCon be without a good old fashioned group hug?  Thanks to everyone who made it possible, and here's to another year of friendship and achievement for everyone in Django-land!</p>
<img alt="http://farm4.static.flickr.com/3185/2838728852_9c6a460602.jpg?v=0" src="http://farm4.static.flickr.com/3185/2838728852_9c6a460602.jpg?v=0" />
<p>(Picture by <a class="reference external" href="http://flickr.com/photos/704race/">704race</a>, whose pictures are also really fun!)</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/djangocon/">DjangoCon</a></li>
      
        <li><a href="/blog/categories/pinax/">Pinax</a></li>
      
        <li><a href="/blog/categories/cloud27/">Cloud27</a></li>
      
        <li><a href="/blog/categories/awesome/">Awesome</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Spawning + Django]]></title>
        <link href="http://eflorenzano.com/blog/2008/07/31/spawning-django/"/>
        <updated>2008-07-31T04:51:17</updated>
        <id>http://eflorenzano.com/blog/2008/07/31/spawning-django/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/07/31/spawning-django/">Spawning + Django</a></h3>
<p class="datetime">Jul 31, 2008</p>
<div class="document">
<p>Yesterday <a class="reference external" href="http://ulaluma.com/pyx/">Donovan Preston</a> released new versions of both <a class="reference external" href="http://pypi.python.org/pypi/eventlet/0.7">eventlet</a> and <a class="reference external" href="http://pypi.python.org/pypi/Spawning/0.7">Spawning</a>.  What are those, you ask?  <a class="reference external" href="http://pypi.python.org/pypi/eventlet/0.7">Eventlet</a> is a networking library written using coroutines instead of normal subroutes, which makes writing networked non-blocking IO applications much much simpler.  Spawning is a <a class="reference external" href="http://www.wsgi.org/wsgi/">WSGI</a> server, written using <a class="reference external" href="http://pypi.python.org/pypi/eventlet/0.7">eventlet</a>, which supports all of the things you'd expect of a good <a class="reference external" href="http://www.wsgi.org/wsgi/">WSGI</a> server: multiple processes, multiple threads, etc.</p>
<p>Considering that I sit next to Donovan at work all day, I've overheard him extolling the numerous advantages to using a server such as <a class="reference external" href="http://pypi.python.org/pypi/Spawning/0.7">Spawning</a>--the most obvious of which is completely graceful code reloading.  Donovan has given a presentation explaining how all of this works, the <a class="reference external" href="http://soundfarmer.com/content/slides/coroutines-nonblocking-io-eventlet-spawning/coros,%20nonblocking%20i:o,%20eventlet,%20spawning.pdf">slides of which</a> probably explain it better than I could.  When he told me that he'd added the ability to easily run Django apps with Spawning, I decided to check it out.</p>
<p>First, I installed spawning:</p>
<pre class="code bash literal-block">
sudo easy_install Spawning
</pre>
<p>And away setuptools went and installed all of the prerequisites and the package itself.  (I have had problems with this in the past, but grabbing greenlet, eventlet, simplejson, PasteDeploy, and Spawning and installing them individually does the trick).</p>
<p>The next thing to do is go to the directory which holds your settings.py, or at least make setup.py available on the Python path.  I tend to find it easier to just go to the directory.  Then type the following:</p>
<pre class="code bash literal-block">
spawn --factory<span class="o">=</span>spawning.django_factory.config_factory settings --port 9090 -s 4 -t 100
</pre>
<p>This starts up a Spawning server with 4 processes and 100 threads.  I chose those numbers almost completely arbitrarily.  (Well, that's not entirely true, my Apache setup previously had 4 processes and 100 requests per child.  I know that requests per child doesn't map at all to threads, but that's where I got the number.)  The next thing to do is visit your site, but instead of visiting the normal port 80 or 8000, visit port 9090.  If you're running it on your own box, that should be <a class="reference external" href="http://127.0.0.1:9090/">http://127.0.0.1:9090/</a>.</p>
<p>For me, it worked like a charm.  It felt like my server was responding faster than ever, but at that point it was just a feeling.  To get some quantitative analysis, I ran <a class="reference external" href="http://en.wikipedia.org/wiki/ApacheBench">apachebench</a> with 20 concurrent requests for a total of 10000 requests.  On my Apache + <a class="reference external" href="http://code.google.com/p/modwsgi/">mod_wsgi</a> setup, I got <strong>235.65</strong> requests per second.  That was really good, I thought!  However, with the Spawning setup, I got <strong>347.20</strong> requests per second.  I would need to test this much more in-depth if I were a statistician, but it's good enough for me as it did confirm my qualitative analysis.</p>
<p>If you're viewing this on my website directly, then you've already used Spawning, as I've switched over this blog to use the new server.  Let me know what you think!  Has my site slowed to a crawl?  Is it going faster than ever (because I know everyone remembers the speed at which eflorenzano.com loads)?</p>
<p>In all, it was an extremely easy upgrade.  I would recommend that everyone who has an interest in these types of things at least try it--especially if you're looking into other pure-python WSGI servers like <a class="reference external" href="http://www.cherrypy.org/">CherryPy</a>.</p>
<p><strong>UPDATE</strong>: If you were having troubles reaching the site before, it's because I was having problems with my database due to another app on the same server, not due to anything that Spawning was doing wrong.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/eventlet/">Eventlet</a></li>
      
        <li><a href="/blog/categories/spawning/">Spawning</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Intermediary Models and PyMag]]></title>
        <link href="http://eflorenzano.com/blog/2008/07/30/intermediary-models-and-pymag/"/>
        <updated>2008-07-30T06:11:17</updated>
        <id>http://eflorenzano.com/blog/2008/07/30/intermediary-models-and-pymag/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/07/30/intermediary-models-and-pymag/">Intermediary Models and PyMag</a></h3>
<p class="datetime">Jul 30, 2008</p>
<div class="document">
<div class="section" id="journey-to-intermediary-models">
<h4>Journey to Intermediary Models</h4>
<p>It's been around an 8 month journey in adding intermediary model support to Django, starting with <a class="reference external" href="http://code.djangoproject.com/ticket/6095">a ticket</a> opened during a sprint by <a class="reference external" href="http://www.jacobian.org/">Jacob Kaplan-Moss</a>.  Earlier that month I had been wrestling with several pretty nasty models, each with two foreign keys and many extra properties on that relation.  I kept thinking that Django makes everything else so easy, but that in at least this one aspect, it doesn't make things easy enough.  When Jacob posted his API idea, I was hooked.</p>
<p>I quickly posted some thoughts and asked for a bit of clarification, and volunteered to write the patch.  Jacob responded saying he was glad to help me out.  It was only then that I actually delved into the code to see how it could be done.  It was only then that I realized that I had absolutely no knowledge or familiarity with that portion of the codebase--a portion that is nontrivial, to say the least.  But that's the good thing about committing to something: you feel pressure to follow through.</p>
<p>Despite my incredible NaA-vitA, the patch got to a rudimentary usable state very quickly, and then started to flounder.  It was then that <a class="reference external" href="http://djangopeople.net/freakboy3742/">Russell Keith-Magee</a> came into the picture, continually prodding me to add more tests, and thinking up many different test cases that I would have never come up with on my own.  I'm 100% certain that if Russ had not lent his expertise and guidance on this patch, it would have gotten lost and forgotten for a long time until someone more capable came along to take a look at it.</p>
<p>A few hours ago, Russ <a class="reference external" href="http://code.djangoproject.com/changeset/8136">committed the patch to trunk</a>.  It's interesting to see the <a class="reference external" href="http://www.reddit.com/comments/6tzig/django_gets_intermediate_models/">reactions</a> that <a class="reference external" href="http://www.reddit.com/comments/6ty8n/extra_fields_on_m2m_relationships_has_landed_in/">some people have</a>, but on any project like this you'll always be scrutinized.  In any case, check out the <a class="reference external" href="http://www.djangoproject.com/documentation/model-api/#extra-fields-on-many-to-many-relationships">two</a> new bits of <a class="reference external" href="http://www.djangoproject.com/documentation/admin/#working-with-many-to-many-intermediary-models">documentation</a>, and see if intermediary models are right for your project.  After having this great experience with working on a patch for Django, I'll definitely be looking to help out in other places as well.  My advice for anyone looking to get involved with the project is to, well, get involved!  Jump in over your head.  It's more fun that way.</p>
</div>
<div class="section" id="pymag">
<h4>PyMag</h4>
<p>For around as long as I have been working on intermediary model support, I've been supporting another Django project of mine: <a class="reference external" href="http://code.google.com/p/django-threadedcomments/">django-threadedcomments</a>.  One of the things that I noticed a few months into maintaining the project is that outside of a few people who were actively using it, not many people really knew about its existence.  So when <cite>Doug Hellmann</cite> (of the famously excellent <a class="reference external" href="http://blog.doughellmann.com/search/label/PyMOTW">PyMOTW</a> series) contacted me about writing an article for <a class="reference external" href="http://pymag.phparch.com/">PyMag</a>, it was immediately apparent what I would love to write about.  Over 4000 words later, between finals and school projects and moving across state boundaries, the article was written.</p>
<p>To be honest, I had almost completely forgotten about having written it, aside from one short e-mail conversation with the technical editor.  It turns out that the July 2008 edition of <a class="reference external" href="http://pymag.phparch.com/">PyMag</a> has arrived and my article is listed under &quot;featured articles&quot;.  How cool is that!?  I'm quite proud of the article, and really hope that it helps some people out with their Django websites.  If you aren't a <a class="reference external" href="http://pymag.phparch.com/">PyMag</a> subscriber, then what are you waiting for?</p>
<p>This post seems to be doing a lot of self-promotion--sorry for that.  But these two things really made my day, and to me, blogging is about sharing those awesome days with others.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/django-threadedcomments/">django-threadedcomments</a></li>
      
        <li><a href="/blog/categories/pymag/">PyMag</a></li>
      
        <li><a href="/blog/categories/awesome/">Awesome</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[First Two Django Screencasts]]></title>
        <link href="http://eflorenzano.com/blog/2008/07/13/first-two-django-screencasts/"/>
        <updated>2008-07-13T03:09:49</updated>
        <id>http://eflorenzano.com/blog/2008/07/13/first-two-django-screencasts/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/07/13/first-two-django-screencasts/">First Two Django Screencasts</a></h3>
<p class="datetime">Jul 13, 2008</p>
<div class="document">
<p>It's always been a goal of mine to post screencasts here on my blog, but for whatever reason I never ended up getting around to it.  Today, that all changes as I have created two new screencasts.  Of course, this space is already very well-covered by both <a class="reference external" href="http://blog.michaeltrier.com/screencasts">Michael Trier</a> and <a class="reference external" href="http://oebfare.com/blog/2008/jan/23/using-git-django-screencast/">Brian Rosner</a>, so hopefully this adds something new to the conversation.</p>
<div class="section" id="setting-up-a-django-development-environment">
<h4>Setting up a Django Development Environment</h4>
<p>In this screencast I show how I typically set up my Django development environment.  It goes through installing Django by checking out the latest development version and linking it to the correct places on your system.  It also talks about how to install reusable applications.  Finally, it covers how to update all of those projects and keep a toolbox of snippets for your personal use.</p>
<embed src="http://blip.tv/play/AcH7agA" type="application/x-shockwave-flash" width="720" height="510" allowscriptaccess="always" allowfullscreen="true"></embed><p>The simple pylink command that I use in the screencast is this:</p>
<pre class="code python literal-block">
<span class="c">#!/bin/bash</span>
<span class="n">ln</span> <span class="o">-</span><span class="n">s</span> <span class="sb">`pwd`</span><span class="o">/</span><span class="err">$</span><span class="mi">1</span> <span class="sb">`python -c &quot;from distutils.sysconfig import get_python_lib; print get_python_lib()&quot;`</span><span class="o">/</span><span class="err">$</span><span class="mi">1</span>
</pre>
<p><strong>UPDATE:</strong> <a class="reference external" href="http://www.uzix.org/">Joshua Uziel</a> has sent me a much more robust version of this script, which handles the edge cases much better.  I highly recommend using this version instead of my one-liner.</p>
<pre class="code bash literal-block">
<span class="c">#!/bin/bash
</span>
<span class="nv">SITE_PACKAGES</span><span class="o">=</span><span class="s2">&quot;$HOME/prog/python/site-packages&quot;</span>

<span class="k">if</span> <span class="o">[</span> ! <span class="nv">$SITE_PACKAGES</span> <span class="o">]</span>
<span class="k">then
    </span><span class="nv">SITE_PACKAGES</span><span class="o">=</span><span class="sb">`</span>python -c <span class="s2">&quot;from distutils.sysconfig import get_python_lib; print get_python_lib()&quot;</span><span class="sb">`</span>
<span class="k">fi

</span><span class="nv">BASE</span><span class="o">=</span><span class="sb">`</span>basename <span class="nv">$1</span><span class="sb">`</span>
<span class="nv">DIR</span><span class="o">=</span><span class="sb">`</span>dirname <span class="nv">$1</span><span class="sb">`</span>

<span class="nb">cd</span> <span class="nv">$DIR</span>
ln -sfnv <span class="sb">`</span><span class="nb">pwd</span><span class="sb">`</span>/<span class="nv">$BASE</span> <span class="nv">$SITE_PACKAGES</span>/<span class="nv">$BASE</span>
</pre>
<p><strong>UPDATE2:</strong> <a class="reference external" href="http://gist.github.com/21649">Zachary Voase</a> has updated this new version, and it seems to be even more improved.  I'm loving this!  He has also written a &quot;pyunlink&quot; script, which can be found <a class="reference external" href="http://gist.github.com/21650">here</a>.</p>
<p>Please let me know in the comments if you have any other tips and tricks for setting up a development environment for Django.</p>
</div>
<div class="section" id="using-django-pagination">
<h4>Using Django-Pagination</h4>
<p><a class="reference external" href="http://code.google.com/p/django-pagination/">Django-pagination</a> is an application that I wrote and released a while ago, which I use <em>all the time</em>, but that hasn't really seen much attention.  In this screencast, I show how to take an existing project with too much data on one page, and use <a class="reference external" href="http://code.google.com/p/django-pagination/">django-pagination</a> to quickly and easily paginate the items on the page.  There is a bit more documentation for the project that's available in the project directory if you do a subversion checkout, and docstrings throughout the source code, if you're interested in how it works.</p>
<embed src="http://blip.tv/play/AcH4UAA" type="application/x-shockwave-flash" width="720" height="510" allowscriptaccess="always" allowfullscreen="true"></embed></div>
<div class="section" id="keep-in-mind">
<h4>Keep in Mind</h4>
<p>These are my very first screencasts, ever.  I'm not entirely sure what I'm doing yet, and the only way I can improve is by your feedback.  If you have any advice and/or criticisms of these screencasts, please don't keep your mouth shut--speak up, and let me know in the comments.  Hopefully someone finds these useful, and thanks for watching!</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/screencast/">Screencast</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Japan and San Francisco]]></title>
        <link href="http://eflorenzano.com/blog/2008/07/10/japan-and-san-francisco/"/>
        <updated>2008-07-10T08:20:14</updated>
        <id>http://eflorenzano.com/blog/2008/07/10/japan-and-san-francisco/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/07/10/japan-and-san-francisco/">Japan and San Francisco</a></h3>
<p class="datetime">Jul 10, 2008</p>
<div class="document">
<div class="section" id="japan-what-a-trip">
<h4>Japan: What a Trip</h4>
<p>There comes a time towards the end of most vacations where you've had a good time, but you're ready to head back home and sleep in your own bed and see your friends.  No offense to any of my friends, but that time never came for me in Japan.  I completely fell in love with Tokyo, and didn't want to come home.</p>
<p>I spent the vast majority of my time in Tokyo itself, but there was so much to do that there was never a dull moment.  Whether it was being completely and utterly lost in the red light district of Shinjuku, playing pachinko in Ueno, or people watching in Shibuya, I was always up to something.  Staying in hostels was probably the best choice that I could have made, because I met so many interesting and fun people!  Who else would I have done karaoke with, had it not been for the people I met at the hostel?</p>
<p>Spending a night in a capsule hotel was really interesting, too.  There's way more space in there than you would think!  You can sit up, or just watch crazy people pretending to time travel on Japanese TV (the best parts are the advertisements, though).  And Japanese people are stylish!  Some of the styles are very over-the-top, and some are very conservative (never before have I seen so many suits and ties), but almost everyone is trying their hardest to go for style.</p>
<p>Good thing the German guys that I met had met Kazuya, or how would I have gotten in to that crazy hole-in-the-wall bar with only Japanese people and no tourists?</p>
<p>I could really go on endlessly about the trip, but needless to say, I'll have the memories that will last forever.  If anyone is thinking of going to Japan, then stop thinking, just do it!</p>
</div>
<div class="section" id="san-francisco">
<h4>San Francisco</h4>
<p>As of the 4th of July, I'm a resident of the state of California.  I've got an awesome apartment on Bush street between Powell and Stockton--near Union Square where there are a lot of tourists.  It's interesting because whenever I walk outside, I hear a whole variety of different languages and accents.  It's really neat, although I suspect after a year its novelty will have worn off and then some.</p>
<p>It's also the first time that I've lived without any roommates.  To me, this is refreshing and fun.  It's nice to get together with friends whenever I want, but also to be able to relax and avoid all possible forms of human interaction when I feel so inclined.  This is helped by the fact that I'm connected to the fastest internet connection that I've ever owned.</p>
<p>Also starting work at <a class="reference external" href="http://mochimedia.com/">Mochi Media</a> has been really good.  There's a lot of new stuff to learn, though, so I'm not able to crank out as much code yet as I would like.  Their primary web development environment is <a class="reference external" href="http://pylonshq.com/">Pylons</a>, which has a decidedly different worldview than <a class="reference external" href="http://www.djangoproject.com/">Django</a>.  I definitely think that there are good things and bad things from both sides, and hopefully the good things can eventually be shared.  I'll  definitely revisit this once I've got more experience on the Pylons side.</p>
<p>Cheers to travelling around the globe, living independently, and learning new things!  Because in a nutshell, that's what I've been doing.</p>
<p>Up next: A series of screencasts.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/japan/">Japan</a></li>
      
        <li><a href="/blog/categories/personal/">Personal</a></li>
      
        <li><a href="/blog/categories/san-francisco/">San Francisco</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Djangodash was Fun!]]></title>
        <link href="http://eflorenzano.com/blog/2008/06/07/djangodash-was-fun/"/>
        <updated>2008-06-07T08:05:00</updated>
        <id>http://eflorenzano.com/blog/2008/06/07/djangodash-was-fun/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/06/07/djangodash-was-fun/">Djangodash was Fun!</a></h3>
<p class="datetime">Jun 07, 2008</p>
<div class="document">
<p><a class="reference external" href="http://djangodash.com/">Djangodash</a>, a two-day two-person sprint to create a project using Django, took place last weekend.  To be honest, I wasn't expecting it to be much fun, but it ended up being an absolute blast!</p>
<div class="section" id="feedalizer-net">
<h4><a class="reference external" href="http://feedalizer.net/">Feedalizer.net</a></h4>
<p>Before getting too far into this post mortem, I'm going to just get it out of the way and shamelessly promote the site that Tony and I created during the dash: <a class="reference external" href="http://feedalizer.net/">feedalizer.net</a>.  The idea behind the site is that it's a feed aggregator, but people vote on the feeds.  The higher the feed's score, the more likely items from that feed will bubble up to the top of the list.  There's also the concept of a &quot;channel&quot;, which only aggregates feeds for a specific area.  For example, there's a Humor channel, a Django channel, and a Python channel.  You can also subscribe to channels to create your own &quot;station&quot;, which aggregates the content from the channels that you care about.</p>
<p>The idea came to me when a friend of mine asked me <em>&quot;I've never used a feed reader before, but I want to get started and subscribe to programming feeds.  What are some good ones for me to subscribe to?&quot;</em>  It took me about 30 minutes to cull through my feeds and produce a list of the best.  But it shouldn't have taken me any time at all--there should have been a site out there to do this for him!</p>
<p>OK, enough shameless self-promotion.</p>
</div>
<div class="section" id="the-dash">
<h4>The Dash</h4>
<p><a class="reference external" href="http://djangodash.com/contest/team/">52 teams</a> registered for the dash, so watching the commit activity at the turn of the clock was pretty crazy.  Unfortunately, Tony was driving from 4 hours away and he hadn't arrived yet.  When he did arrive, we both wanted to spend some time catching up and talking about non-Django things.  So we didn't even get started until about 3:30AM.  Getting started mainly consisted of frantically checking in 3rd party projects that we thought we would use, and talking about architecture, and writing a few cron jobs.  Not much code got written that night (morning?), since we still had a lot of planning to do.</p>
<p>The next day, all of a sudden our commits weren't working!  We went to the website to see what was going on, and the website wasn't responding to our requests.  Something was definitely going on, and it was slowing down our progress significantly.  We tried working on our own separate parts of the project, but at this early stage there was simply too much overlap.  We found out later in the night that there were problems at <a class="reference external" href="http://www.webfaction.com/">Webfaction's</a> data warehouse,`The Planet`_, where a transformer quite literally exploded.</p>
<p>This severely slowed us down, because we ended up having to switch to git, and then once we got everything into our git repository, we had tons of merge conflicts.  We got an e-mail saying that the due date would be postponed, so we decided to take the afternoon and night off to do other things.</p>
<p>The next day we did the brunt of our work.  I had the task of designing the frontend, so I opened up my trusty text editor and hammered out the worst-looking CSS file you'll ever see in your life, producing some of the worst-looking pages you'll ever see in your life.  This changed over the course of the day, but not by much as you'll see if you visit the site.  This same day, Tony was working on some of the harder queries etc.</p>
<p>The final day (the deadline had been extended, remember) was all about integration.  There was nothing really notable about this, but it took all day to get everything working properly together.  I ended up writing a bunch of Javascript to make the client experience more enjoyable, and Tony had the chance to debug his views now that I had templates and we had sample data.  It was a crunch to make the deadline, but we tried to do the little important extra details like write an &quot;about&quot; page, a README file, etc.</p>
</div>
<div class="section" id="conclusion">
<h4>Conclusion</h4>
<p>Whether we win or lose, and despite the technical difficulties that <a class="reference external" href="http://www.theplanet.com/">The Planet</a> suffered, I had a blast doing the competition.  I think that our idea is novel, and Tony and I got to work on something once more post-graduation.  (Nothing like a programming competition to bring people together, I always say.)  In fact, we'll probably continue to work on it for the months to come, especially in upgrading its graphics.  It's going to be really awesome to see what everyone else produced this year.  I encourage anyone who thought about participating this year, or anyone who even considers it as a possibility, to sign up and <strong>just do it</strong> next year!</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/django-dash/">Django Dash</a></li>
      
        <li><a href="/blog/categories/feedalizer/">Feedalizer</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Where I&#39;ve Been, and Where I&#39;m Going]]></title>
        <link href="http://eflorenzano.com/blog/2008/06/06/where-ive-been-and-where-im-going/"/>
        <updated>2008-06-06T07:43:28</updated>
        <id>http://eflorenzano.com/blog/2008/06/06/where-ive-been-and-where-im-going/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/06/06/where-ive-been-and-where-im-going/">Where I&#39;ve Been, and Where I&#39;m Going</a></h3>
<p class="datetime">Jun 06, 2008</p>
<div class="document">
<p>Firstly, my apologies to any technical readers of this blog, as this post is mostly personal.</p>
<div class="section" id="iowa-state-university">
<h4>Iowa State University</h4>
<p>For the past four years, I have attended <a class="reference external" href="http://www.iastate.edu/">Iowa State University</a>, pursuing a Bachelors of Science in Computer Science.  Finally last month, that process was over.  Degree in hand, I can't help but think back about all of the truly great memories, experiences, and new friends that were made possible by going to <a class="reference external" href="http://www.iastate.edu/">Iowa State</a>.  Not only was the extracurricular experience great, but at the same time, I feel like the education was top-notch as well.  For anyone that knocks state schools, tell them to try to keep up in my Essentials of Programming Languages class with Professor Lumpe.</p>
</div>
<div class="section" id="tokyo-japan">
<h4>Tokyo, Japan</h4>
<p>I recognize that this point in my life is the last time (for a while, at least) that I'll be able to do something crazy and go to a foreign country for two weeks.  The logical choice would have been to go to France, since I minored in French and know some people who live there.  That's why I didn't do that.  Instead, I'm doing something that I've always wanted to do, but never have: go to Japan.</p>
<p>I know there are some <a class="reference external" href="http://www.youtube.com/watch?v=BE35onlIySk">crazy things</a> going on all the time in Japan, and honestly that's what's so exciting to me.  It's a completely different culture from our own and up until now I've only had glimpses into that culture.  I'll have a ton more to say about this after the trip is done, along with a dizzying amount of pictures, so stay tuned for that if you're at all interested.</p>
</div>
<div class="section" id="mochi-media">
<h4>Mochi Media</h4>
<p>I have accepted a position at <a class="reference external" href="http://www.mochimedia.com/">Mochi Media</a>, where I'll be working with some ridiculously smart and talented people.  Not only that, but I get to use my favorite technologies, like <a class="reference external" href="http://www.python.org/">Python</a> and <a class="reference external" href="http://www.erlang.org/">Erlang</a>.  In the case of <a class="reference external" href="http://www.erlang.org/">Erlang</a>, Mochi Media is actively pioneering its use in the web space with its open source project <a class="reference external" href="http://code.google.com/p/mochiweb/">mochiweb</a> (most recently noted for being a key component in Facebook's chat feature).  Contributing to open source, using languages that I like, pioneering the use of established technology in new ways, working with smart people, and having a great business model to boot.  All of that combined makes me one hell of an excited guy!</p>
<p>More practically, what this means is that I'm moving to San Francisco!  Hopefully there'll be more Pythonistas there than there was in Iowa.  Whether there are or not, one thing is certain: there'll be a lot more to do.</p>
<p>I'm a bit bored right now, and it's a feeling I'm going to savor, because starting next week and into the foreseeable future, boredom is not a feeling I'll be having much at all.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/iowa/">Iowa</a></li>
      
        <li><a href="/blog/categories/japan/">Japan</a></li>
      
        <li><a href="/blog/categories/mochi-media/">Mochi Media</a></li>
      
        <li><a href="/blog/categories/personal/">Personal</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[FriendFeed Comment Expand Bookmarklet]]></title>
        <link href="http://eflorenzano.com/blog/2008/05/27/friendfeed-comment-expand-bookmarklet/"/>
        <updated>2008-05-27T07:47:57</updated>
        <id>http://eflorenzano.com/blog/2008/05/27/friendfeed-comment-expand-bookmarklet/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/05/27/friendfeed-comment-expand-bookmarklet/">FriendFeed Comment Expand Bookmarklet</a></h3>
<p class="datetime">May 27, 2008</p>
<div class="document">
<p>Recently I've been using a lot of <a class="reference external" href="http://friendfeed.com/">FriendFeed</a> lately, and found it a bit annoying to expand comments one-by-one, so I wrote a quick bookmarklet to automatically expand all comments out.</p>
<p>Drag this bookmarklet to your bookmarks toolbar to get in on the action:</p>
<p><a class="reference external" href="javascript:(function(A){A.parents(&quot;.commentexpander&quot;).hide();A.parents(&quot;.comments&quot;).show().find(&quot;.hiddencomments&quot;).show(100)})(jQuery('.l_showcomments'))">Show All Comments</a></p>
<p>By the way, feel free to <a class="reference external" href="http://friendfeed.com/ericflo">follow me</a> on FriendFeed as well to see my various online activities.  I'm in the habit of following people who follow me.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/jquery/">jquery</a></li>
      
        <li><a href="/blog/categories/friendfeed/">FriendFeed</a></li>
      
        <li><a href="/blog/categories/bookmarklet/">Bookmarklet</a></li>
      
        <li><a href="/blog/categories/javascript/">Javascript</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Managers and Voting and Subqueries, Oh My!]]></title>
        <link href="http://eflorenzano.com/blog/2008/05/24/managers-and-voting-and-subqueries-oh-my/"/>
        <updated>2008-05-24T23:12:19</updated>
        <id>http://eflorenzano.com/blog/2008/05/24/managers-and-voting-and-subqueries-oh-my/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/05/24/managers-and-voting-and-subqueries-oh-my/">Managers and Voting and Subqueries, Oh My!</a></h3>
<p class="datetime">May 24, 2008</p>
<div class="document">
<p>Recently I launched <a class="reference external" href="http://peevalizer.com/">Peevalizer</a>, a website for talking about your pet peeves, which of course was written in Python using the Django web framework.  In fact, it was the culmination of my efforts to <a class="reference external" href="http://www.eflorenzano.com/blog/post/learning-design/">teach myself design</a>, and while I made some progress, it's clear that I'll never be a designer.  Anyway, part of <a class="reference external" href="http://peevalizer.com/">Peevalizer</a> is that users can vote on different pet peeves, and view the peeves with the highest score.  I used <a class="reference external" href="http://code.google.com/p/django-voting/">django-voting</a> as the application to enable this functionality, and it provides a manager on the <tt class="docutils literal">Vote</tt> object with methods for getting the top N results, where N is a positive integer.</p>
<p>One of the reasons for custom manager on <tt class="docutils literal">Vote</tt> is because <a class="reference external" href="http://code.google.com/p/django-aggregation/">aggregate support</a> has not yet been finished.  However with Django's built-in <a class="reference external" href="http://www.djangoproject.com/documentation/pagination/">Pagination</a> support, it's necessary to retrieve not only a list of the top N voted pet peeves, but a list of all of the pet peeves, ordered by score.  How is this possible?  Specifically, how is this possible without forking <a class="reference external" href="http://code.google.com/p/django-voting/">django-voting</a>?  Here is the solution that I came up with:</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">VoteAwareManager</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Manager</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">_get_score_annotation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">model_type</span> <span class="o">=</span> <span class="n">ContentType</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_for_model</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">model</span><span class="p">)</span>
        <span class="n">table_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">db_table</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">extra</span><span class="p">(</span><span class="n">select</span><span class="o">=</span><span class="p">{</span>
            <span class="s">'score'</span><span class="p">:</span> <span class="s">'SELECT COALESCE(SUM(vote),0) FROM </span><span class="si">%s</span><span class="s"> WHERE content_type_id=</span><span class="si">%d</span><span class="s"> AND object_id=</span><span class="si">%s</span><span class="s">.id'</span> <span class="o">%</span>
                <span class="p">(</span><span class="n">Vote</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">db_table</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">model_type</span><span class="o">.</span><span class="n">id</span><span class="p">),</span> <span class="n">table_name</span><span class="p">)}</span>
        <span class="p">)</span>

    <span class="k">def</span> <span class="nf">most_hated</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_score_annotation</span><span class="p">()</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s">'-score'</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">most_loved</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_score_annotation</span><span class="p">()</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s">'score'</span><span class="p">)</span>
</pre>
<p>Then I assigned that manager onto all of the objects that could be voted on.  What that's doing is literally issuing a subquery for every row, doing an aggregate on all of the votes for that row, and assigning it to an attribute named <em>score</em>.</p>
<p>However, we also wanted to allow for voting on <tt class="docutils literal">User</tt> objects, which is built in to Django and cannot be easily changed.  How do we add this manager to user?  I spent a while thinking about that before realizing that it's not the right question to ask.  The right question to ask is, how can we associate the <tt class="docutils literal">User</tt> model with this manager?  A quick look through some Django source code revealed this to be an absolutely trivial task.  Here's how it goes in our code:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.contrib.auth.models</span> <span class="kn">import</span> <span class="n">User</span>
<span class="n">manager</span> <span class="o">=</span> <span class="n">VoteAwareManager</span><span class="p">()</span>
<span class="n">manager</span><span class="o">.</span><span class="n">model</span> <span class="o">=</span> <span class="n">User</span>

<span class="k">for</span> <span class="n">user</span> <span class="ow">in</span> <span class="n">manager</span><span class="o">.</span><span class="n">most_hated</span><span class="p">():</span>
    <span class="c"># Do something with user's score</span>
</pre>
<p>There are a few things to note about this implementation.  Firstly, it can be much more computationally expensive to use this method instead of using <a class="reference external" href="http://code.google.com/p/django-voting/">django-voting</a>'s method (which executes some custom SQL), so either be aware of that or use aggressive caching strategies to overcome this shortcoming.  The other thing is if you're not using a manager like this on multiple models, and since managers mostly just proxy to <tt class="docutils literal">QuerySet</tt> anyway, it might be simpler to just acquire a <tt class="docutils literal">QuerySet</tt> on the model that you would like to get, and run the <tt class="docutils literal">extra()</tt> method in the calling function.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Exploring Mixins with Django Model Inheritance]]></title>
        <link href="http://eflorenzano.com/blog/2008/05/17/exploring-mixins-django-model-inheritance/"/>
        <updated>2008-05-17T07:24:03</updated>
        <id>http://eflorenzano.com/blog/2008/05/17/exploring-mixins-django-model-inheritance/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/05/17/exploring-mixins-django-model-inheritance/">Exploring Mixins with Django Model Inheritance</a></h3>
<p class="datetime">May 17, 2008</p>
<div class="document">
<p><a class="reference external" href="http://www.djangoproject.com/">Django</a> now supports <a class="reference external" href="http://www.djangoproject.com/documentation/model-api/#model-inheritance">Model Inheritance</a>, and one of the coolest new opportunities that model inheritance brings is the possibility of the creation of <a class="reference external" href="http://en.wikipedia.org/wiki/Mixin">mixins</a>, so in this post I'll walk through the steps I went through to create some simple examples. This is just an excercise (although it could be modified to be more robust)--and right now there are better ways to achieve all of the effects of the following mixins.  (See <a class="reference external" href="http://code.google.com/p/django-mptt/">django-mptt</a>, for example).</p>
<div class="section" id="model-and-field-setup">
<h4>Model and Field Setup</h4>
<p>First let's just set up two basic models.  The first will be our mixin, <tt class="docutils literal">NaiveHierarchy</tt>, which has a single field, <tt class="docutils literal">parent</tt>, which is a reference to itself.  Using this, we can traverse the tree and find all sorts of fun hierarchical information.  Also, we'll create the canonical example model: the blog post.  Our models start out looking something like this:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">NaiveHierarchy</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">parent</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="s">'self'</span><span class="p">,</span> <span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

    <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
        <span class="n">abstract</span> <span class="o">=</span> <span class="bp">True</span>

<span class="k">class</span> <span class="nc">BlogPost</span><span class="p">(</span><span class="n">NaiveHierarchy</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span> <span class="o">=</span> <span class="mi">128</span><span class="p">)</span>
    <span class="n">body</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span>
</pre>
<p>Now let's test to make sure that worked.  We'll create some data and test that <tt class="docutils literal">parent</tt> exists on the instances.</p>
<pre class="code pycon literal-block">
<span class="kn"></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">mixins.models</span> <span class="kn">import</span> <span class="n">BlogPost</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">bp</span> <span class="o">=</span> <span class="n">BlogPost</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">&quot;post1&quot;</span><span class="p">,</span> <span class="n">body</span><span class="o">=</span><span class="s">&quot;First post!&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">bp2</span> <span class="o">=</span> <span class="n">BlogPost</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">&quot;post2&quot;</span><span class="p">,</span> <span class="n">body</span><span class="o">=</span><span class="s">&quot;Second post!&quot;</span><span class="p">,</span> <span class="n">parent</span><span class="o">=</span><span class="n">bp</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">bp3</span> <span class="o">=</span> <span class="n">BlogPost</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">&quot;post3&quot;</span><span class="p">,</span> <span class="n">body</span><span class="o">=</span><span class="s">&quot;Third post!&quot;</span><span class="p">,</span> <span class="n">parent</span><span class="o">=</span><span class="n">bp2</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">bp</span><span class="o">.</span><span class="n">parent</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">bp2</span><span class="o">.</span><span class="n">parent</span>
<span class="go">&lt;BlogPost: post1&gt;</span>
</pre>
</div>
<div class="section" id="inherited-class-level-methods">
<h4>Inherited Class-Level Methods</h4>
<p>So as you can see, everything is working correctly!  But that really doesn't save us much time yet, as it's fairly easy to copy and paste fields onto new models, and we still have to write methods which take advantage of those new fields.  In this case, I already know that I'm going to want to get the related children and descendants of my blogposts.  So why not write those methods on the abstract model?  Thanks to inheritance, those methods will apply to the new model as well.</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">NaiveHierarchy</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">parent</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="s">'self'</span><span class="p">,</span> <span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">get_children</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default_manager</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">parent</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">get_descendants</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">descs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_children</span><span class="p">())</span>
        <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="n">descs</span><span class="p">):</span>
            <span class="n">descs</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">get_descendants</span><span class="p">())</span>
        <span class="k">return</span> <span class="n">descs</span>

    <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
        <span class="n">abstract</span> <span class="o">=</span> <span class="bp">True</span>
</pre>
<p>Now, getting all the children or descendents of a particular node is easy:</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">bp</span><span class="o">.</span><span class="n">get_children</span><span class="p">()</span>
<span class="go">[&lt;BlogPost: post2&gt;]
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">bp</span><span class="o">.</span><span class="n">get_descendants</span><span class="p">()</span>
<span class="go">set([&lt;BlogPost: post2&gt;, &lt;BlogPost: post3&gt;])</span>
</pre>
<p>Now this <tt class="docutils literal">NaiveHierarchy</tt> mixin is starting to become quite useful!  But what happens if I want to get all of the BlogPosts that have no parents?  It's really manager-level functionality.  So let's write a manager which defines a <tt class="docutils literal">get_roots</tt> function.  Unfortunately, using abstract managers doesn't quite work yet (it works for non-abstract inheritance), but it probably will in future versions of Django.  In fact, by applying the latest patch on either Django ticket <a class="reference external" href="http://code.djangoproject.com/ticket/7252">7252</a> or <a class="reference external" href="http://code.djangoproject.com/ticket/7154">7154</a>, it will work today. Let's see how this would look:</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">NaiveHierarchyManager</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Manager</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">get_roots</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_query_set</span><span class="p">()</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">parent__isnull</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">NaiveHierarchy</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">parent</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="s">'self'</span><span class="p">,</span> <span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

    <span class="n">tree</span> <span class="o">=</span> <span class="n">NaiveHierarchyManager</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">get_children</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default_manager</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">parent</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">get_descendants</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">descs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_children</span><span class="p">())</span>
        <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="n">descs</span><span class="p">):</span>
            <span class="n">descs</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">get_descendants</span><span class="p">())</span>
        <span class="k">return</span> <span class="n">descs</span>

    <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
        <span class="n">abstract</span> <span class="o">=</span> <span class="bp">True</span>

<span class="k">class</span> <span class="nc">BlogPost</span><span class="p">(</span><span class="n">NaiveHierarchy</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span> <span class="o">=</span> <span class="mi">128</span><span class="p">)</span>
    <span class="n">body</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>

    <span class="n">objects</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">Manager</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span>
</pre>
<p>Note that we needed to explicitly define objects as the basic manager, because once a parent class specifies a manager, it gets set as the default manager on all inherited subclasses.  This would play out exactly how you would expect:</p>
<pre class="code pycon literal-block">
<span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">BlogPost</span><span class="o">.</span><span class="n">tree</span><span class="o">.</span><span class="n">get_roots</span><span class="p">()</span>
<span class="go">[&lt;BlogPost: post1&gt;]
</span><span class="n"></span><span class="gp">&gt;&gt;&gt; </span><span class="n">BlogPost</span><span class="o">.</span><span class="n">tree</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="go">[&lt;BlogPost: post1&gt;, &lt;BlogPost: post2&gt;, &lt;BlogPost: post3&gt;]</span>
</pre>
</div>
<div class="section" id="advanced-stuff">
<h4>Advanced Stuff</h4>
<p>So now I really wanted to push the limit, and write a mixin which would enhance one of the basic methods of all <tt class="docutils literal">Model</tt> classes: <tt class="docutils literal">save()</tt>.  This would be a DateMixin which would contain <tt class="docutils literal">date_added</tt> and <tt class="docutils literal">date_modified</tt>, where <tt class="docutils literal">date_modified</tt> was updated on each save.  To my surprise, this <em>Just Worked</em>.  Let's see the final result:</p>
<pre class="code python literal-block">
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">DateMixin</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">date_added</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">)</span>
    <span class="n">date_modified</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">date_modified</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">DateMixin</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">NaiveHierarchyManager</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Manager</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">get_roots</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_query_set</span><span class="p">()</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">parent__isnull</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">NaiveHierarchy</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">parent</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="s">'self'</span><span class="p">,</span> <span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

    <span class="n">tree</span> <span class="o">=</span> <span class="n">NaiveHierarchyManager</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">get_children</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_default_manager</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">parent</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">get_descendants</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">descs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_children</span><span class="p">())</span>
        <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="n">descs</span><span class="p">):</span>
            <span class="n">descs</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">get_descendants</span><span class="p">())</span>
        <span class="k">return</span> <span class="n">descs</span>

    <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
        <span class="n">abstract</span> <span class="o">=</span> <span class="bp">True</span>

<span class="k">class</span> <span class="nc">BlogPost</span><span class="p">(</span><span class="n">NaiveHierarchy</span><span class="p">,</span> <span class="n">DateMixin</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span> <span class="o">=</span> <span class="mi">128</span><span class="p">)</span>
    <span class="n">body</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>

    <span class="n">objects</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">Manager</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span>
</pre>
</div>
<div class="section" id="conclusions">
<h4>Conclusions</h4>
<p><a class="reference external" href="http://en.wikipedia.org/wiki/Mixin">Mixins</a> can be powerful tools, but there are some hazards in using mixins, which all boil down to the same basic problem:  unexpected consequences.  In the case of the <tt class="docutils literal">DateMixin</tt>, if any other class has defined a <tt class="docutils literal">save()</tt> method, our custom <tt class="docutils literal">save()</tt> method simply won't be called unless called explicitly.  Perhaps this is a documentation problem, but perhaps it's a fault in the idea of a date mixin altogether.</p>
<p>So all that being said, I'm not suggesting to go off and start using any of the mixins that I have provided here, but rather to illustrate how a mixin can be constructed with <a class="reference external" href="http://www.djangoproject.com/">Django</a>'s new <a class="reference external" href="http://www.djangoproject.com/documentation/model-api/#model-inheritance">Model Inheritance</a>.  I do hope that a reusable app emerges with some great mixins that are useful for a large variety of tasks.  Because mixins are powerful, and new shiny things that Django can do, and new shiny things are worth being explored!</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/object-oriented-programming/">Object Oriented Programming</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Revolutionary Ideas]]></title>
        <link href="http://eflorenzano.com/blog/2008/05/15/revolutionary-ideas/"/>
        <updated>2008-05-15T16:18:44</updated>
        <id>http://eflorenzano.com/blog/2008/05/15/revolutionary-ideas/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/05/15/revolutionary-ideas/">Revolutionary Ideas</a></h3>
<p class="datetime">May 15, 2008</p>
<div class="document">
<p>Everyone has had the experience of hearing about something new and thinking: &quot;That makes so much sense!  Why didn't I think of that?&quot;  For programmers that keep up on open source software, new projects that fit the previous description attract not only our admiration, but we want to be a part of this new idea.  We become involved and contribute and try to push that new software into any new direction that we can; learning from it and evolving it along the way.</p>
<p>One such idea that fits my description perfectly is <a class="reference external" href="http://ejohn.org/blog/processingjs/">Processing.js</a>.  Not to belittle <a class="reference external" href="http://ejohn.org/">John Resig</a>'s hard work in actually developing the initial codebase, but the <strong>idea</strong> is what is so much more important.  Thousands of developers knew of both the <a class="reference external" href="http://processing.org/">Processing language</a> and about the <a class="reference external" href="http://en.wikipedia.org/wiki/Canvas_(HTML_element)">canvas tag</a> which is coming to prevalence, but it was a revolutionary idea to notice that the pairing of the two was &quot;both possible and desirable to do in the first place&quot;, as <a class="reference external" href="http://reddit.com/">Reddit</a> commenter <a class="reference external" href="http://reddit.com/user/MarshallBanana/">MarshallBanana</a> <a class="reference external" href="http://reddit.com/info/6ipvz/comments/c03ygkq">pointed out</a>.</p>
<p>As a community we need both the revolutionary ideas and the evolutionary changes so that we get great software that solves problems in new and innovative ways, but also that doesn't have bugs and provides a polished experience.  But I think that we've become too bogged down in the evolutionary.  We get so wrapped up in others' ideas--so interested in polish and shine--that seldom few think outside the boundary of the incremental.  I won't claim to be the exception here, and rightly can't claim to be, but it's something that's worrisome nonetheless.</p>
<p>I think that a big part of it is that the open source community has gotten so wary of experimentation with well-established applications.  Why can't a development version of Firefox include a Python or Ruby interpreter alongside a JavaScript interpreter?  Why can't CSS directives for reflections be explored, or animations be built into the rendering engine?  I think that a big part of it is because we've spent so long talking about validation and standards that we forgot about that sense of wonder; that feeling of anything being possible with a bit of code and enthusiasm.</p>
<p><a class="reference external" href="http://ejohn.org/blog/processingjs/">Processing.js</a>, and projects like it, give me hope that revolutionary ideas are still out there.  They rekindle that sense of wonder in me.  They make me think about other things that are possible.  They make me excited about open source again.  Let's foster more and greater and better ideas, and just once in a while, eschew the incremental.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/couchdb/">CouchDB</a></li>
      
        <li><a href="/blog/categories/john-resig/">John Resig</a></li>
      
        <li><a href="/blog/categories/processing/">Processing</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[My Awesome Regex Snippet]]></title>
        <link href="http://eflorenzano.com/blog/2008/05/06/my-awesome-regex-snippet/"/>
        <updated>2008-05-06T08:24:07</updated>
        <id>http://eflorenzano.com/blog/2008/05/06/my-awesome-regex-snippet/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/05/06/my-awesome-regex-snippet/">My Awesome Regex Snippet</a></h3>
<p class="datetime">May 06, 2008</p>
<div class="document">
<p>There are many times when the programming task at hand is to iterate over some semi-structured text, transform parts of that text in some way, and reintegrate those transformed parts back into the original text.</p>
<p>Typically using a regular expression with re.sub and a callback function, but sometimes you want a bit more control of the process (especially over those parts that <em>dont</em> match the regex). Usually my solution is to write a one-off function that does it, but today I had to write that function yet again and decided to generalize it and post it here.</p>
<p>To be completely honest, this post is more for my own archival purposes than for the internet as a whole, but if anyone else finds it useful, then I'm ecstatic.</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">re_parts</span><span class="p">(</span><span class="n">regex_list</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;
    An iterator that returns the entire text, but split by which regex it
    matched, or none at all.  If it did, the first value of the returned tuple
    is the index into the regex list, otherwise -1.

    &gt;&gt;&gt; first_re = re.compile('asdf')
    &gt;&gt;&gt; second_re = re.compile('an')
    &gt;&gt;&gt; list(re_parts([first_re, second_re], 'This is an asdf test.'))
    [(-1, 'This is '), (1, 'an'), (-1, ' '), (0, 'asdf'), (-1, ' test.')]

    &gt;&gt;&gt; list(re_parts([first_re, second_re], 'asdfasdfasdf'))
    [(0, 'asdf'), (0, 'asdf'), (0, 'asdf')]

    &gt;&gt;&gt; list(re_parts([], 'This is an asdf test.'))
    [(-1, 'This is an asdf test.')]

    &gt;&gt;&gt; third_re = re.compile('sdf')
    &gt;&gt;&gt; list(re_parts([first_re, second_re, third_re], 'This is an asdf test.'))
    [(-1, 'This is '), (1, 'an'), (-1, ' '), (0, 'asdf'), (-1, ' test.')]
    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">match_compare</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">x</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="o">-</span> <span class="n">y</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
    <span class="n">prev_end</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="n">iters</span> <span class="o">=</span> <span class="p">[</span><span class="n">r</span><span class="o">.</span><span class="n">finditer</span><span class="p">(</span><span class="n">text</span><span class="p">)</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">regex_list</span><span class="p">]</span>
    <span class="n">matches</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">while</span> <span class="n">iters</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">matches</span><span class="p">:</span>
            <span class="n">match</span> <span class="o">=</span> <span class="n">matches</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
            <span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">)</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">span</span><span class="p">()</span>
            <span class="k">if</span> <span class="n">start</span> <span class="o">&gt;</span> <span class="n">prev_end</span><span class="p">:</span>
                <span class="k">yield</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">text</span><span class="p">[</span><span class="n">prev_end</span><span class="p">:</span><span class="n">start</span><span class="p">])</span>
                <span class="k">yield</span> <span class="p">(</span><span class="n">regex_list</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">match</span><span class="o">.</span><span class="n">re</span><span class="p">),</span> <span class="n">text</span><span class="p">[</span><span class="n">start</span><span class="p">:</span><span class="n">end</span><span class="p">])</span>
            <span class="k">elif</span> <span class="n">start</span> <span class="o">==</span> <span class="n">prev_end</span><span class="p">:</span>
                <span class="k">yield</span> <span class="p">(</span><span class="n">regex_list</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">match</span><span class="o">.</span><span class="n">re</span><span class="p">),</span> <span class="n">text</span><span class="p">[</span><span class="n">start</span><span class="p">:</span><span class="n">end</span><span class="p">])</span>
            <span class="n">prev_end</span> <span class="o">=</span> <span class="n">end</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">matches</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="k">for</span> <span class="n">iterator</span> <span class="ow">in</span> <span class="n">iters</span><span class="p">:</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="n">matches</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">iterator</span><span class="o">.</span><span class="n">next</span><span class="p">())</span>
                <span class="k">except</span> <span class="ne">StopIteration</span><span class="p">:</span>
                    <span class="n">iters</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">iterator</span><span class="p">)</span>
            <span class="n">matches</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">matches</span><span class="p">,</span> <span class="n">match_compare</span><span class="p">)</span>
    <span class="n">last_bit</span> <span class="o">=</span> <span class="n">text</span><span class="p">[</span><span class="n">prev_end</span><span class="p">:]</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">last_bit</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">yield</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">last_bit</span><span class="p">)</span>
</pre>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/regex/">Regex</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Inheritance vs. Composition]]></title>
        <link href="http://eflorenzano.com/blog/2008/05/04/inheritance-vs-composition/"/>
        <updated>2008-05-04T23:12:38</updated>
        <id>http://eflorenzano.com/blog/2008/05/04/inheritance-vs-composition/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/05/04/inheritance-vs-composition/">Inheritance vs. Composition</a></h3>
<p class="datetime">May 04, 2008</p>
<div class="document">
<p>Lately there's been a lot of discussion in certain programming communities about which method of object extension makes more sense: inheritance, or composition.  Most of the time these discussions turn into debates, and when that happens developers tend to &quot;take sides&quot;--often moving towards extremist positions on the issue.  I've been sort of quietly thinking about it all lately, trying to determine which use case warrants which approach.  Here I show examples of both, explore some properties and consequences of both composition and inheritance, and finally talk about my own preferences.</p>
<div class="section" id="examples-of-composition-and-inheritance">
<h4>Examples of Composition and Inheritance</h4>
<p>Before talking about the consequences of inheritance vs. composition, some simple examples of both are needed.  Here's a simplistic example of object composition (using Python, of course, as our demonstration language):</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">UserDetails</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="n">email</span> <span class="o">=</span> <span class="s">&quot;floguy&#64;gmail.com&quot;</span>
    <span class="n">homepage</span> <span class="o">=</span> <span class="s">&quot;http://www.eflorenzano.com&quot;</span>

<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="n">first_name</span> <span class="o">=</span> <span class="s">&quot;Eric&quot;</span>
    <span class="n">last_name</span> <span class="o">=</span> <span class="s">&quot;Florenzano&quot;</span>
    <span class="n">details</span> <span class="o">=</span> <span class="n">UserDetails</span><span class="p">()</span>
</pre>
<p>Obviously these are not very useful classes, but the essential point is that we have created a namespace for each User object, &quot;details&quot;, which contains the extra information about that particular user.</p>
<p>An example of the same objects, modified to use object inheritance might look as follows:</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="n">first_name</span> <span class="o">=</span> <span class="s">&quot;Eric&quot;</span>
    <span class="n">last_name</span> <span class="o">=</span> <span class="s">&quot;Florenzano&quot;</span>

<span class="k">class</span> <span class="nc">UserDetails</span><span class="p">(</span><span class="n">User</span><span class="p">):</span>
    <span class="n">email</span> <span class="o">=</span> <span class="s">&quot;floguy&#64;gmail.com&quot;</span>
    <span class="n">homepage</span> <span class="o">=</span> <span class="s">&quot;http://www.eflorenzano.com&quot;</span>
</pre>
<p>Now we have a flat namespace, which contains all of the attributes from both of the objects.  In the case of any collisions, Python will take the attribute from UserDetails.</p>
</div>
<div class="section" id="consequences">
<h4>Consequences</h4>
<p>From a pure programming language complexity standpoint, object composition is the simpler of the two methods.  In fact, the word &quot;object&quot; may not even apply here, as it's possible to achieve this type of composition using structs in C, which are clearly not objects in the sense that we think of them today.</p>
<p>Another immediate thing to notice is that with composition, there's no possibility of namespace clashes.  There's no need to determine which attribute should &quot;win&quot;, between the object and the composed object, as each attribute remains readily available.</p>
<p>The composed object, more often than not, has no knowledge about its containing class, so it can completely encapsulate its particular functionality.  This also means that it cannot make any assumptions about its containing class, and the entire scheme can be considered less brittle.  Change an attribute or method on <tt class="docutils literal">User</tt>? That's fine, since <tt class="docutils literal">UserDetails</tt> doesn't know or care about <tt class="docutils literal">User</tt> at all.</p>
<p>That being said, object inheritance is arguably more straightforward.  After all, an e-mail address isn't a logical property of some real-world object called a &quot;UserDetails&quot;.  No--it's a property of a user--so it makes more sense to make it an attribute on our virtual equivalent, the <tt class="docutils literal">User</tt> class.</p>
<p>Object inheritance is also a more commonly-understood idea.  Asking a typical developer about object composition will most likely result in some mumbling and deflection, whereas the same question about object inheritance will probably reveal a whole host of opinions and experience.  That's not to say that composition is some sort of dark art, but simply that it's less commonly talked about in so many words.</p>
<p>As more of a sidenote than anything else, inheritance can be speedier in some compiled languages due to some compile-time optimizations vs. the dynamic lookup that composition requires.  Of course, in Java you can't escape the dynamic method lookup, and in Python it's all a moot point.</p>
</div>
<div class="section" id="my-preferences">
<h4>My Preferences</h4>
<p>In general, I find object composition to be desirable.  I've seen too many projects get incredibly (and unnecessarily) confusing due to complicated inheritance hierarchies.  However, there are some cases where inheritance simply makes more sense logically and programmatically.  These are typically the cases where an object has been broken into so many subcomponents that it doesn't make sense any more as an object itself.</p>
<p>The <a class="reference external" href="http://www.djangoproject.com/">Django</a> web framework has an interesting way of dealing with model inheritance, and I think that more projects should follow its example.  It uses composition behind the scenes, and then flattens the namespace according to typical inheritance rules.  However, that composition still exists under the covers, so that that method may be used instead.</p>
<p>The answer is not going to be &quot;composition always&quot; or &quot;inheritance always&quot; or even any combination of the two, &quot;always&quot;.  Each has its own drawbacks and advantages and those should be considered before choosing an approach.  More research needs to be done on the hybrid approaches, as well, because things like what Django is doing will provide more answers to more people than traditional approaches.  Cheers to continued thought about these problems and to challenging conventional thought!</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/java/">Java</a></li>
      
        <li><a href="/blog/categories/object-oriented-programming/">Object Oriented Programming</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Learning Design]]></title>
        <link href="http://eflorenzano.com/blog/2008/04/17/learning-design/"/>
        <updated>2008-04-17T17:49:29</updated>
        <id>http://eflorenzano.com/blog/2008/04/17/learning-design/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/04/17/learning-design/">Learning Design</a></h3>
<p class="datetime">Apr 17, 2008</p>
<div class="document">
<p>What could have more of an impact on visitors of a website than its design?  It's the first thing that people notice when they visit the site, and it dictates what they see and how they interact with the site.  A <a class="reference external" href="http://www.dinghyinsurance.com/">bad design</a> can drive visitors away, whereas a <a class="reference external" href="http://pownce.com/">good design</a> can bring people back again and again.</p>
<p>It seems that a common misconception is that design is how to make a site &quot;look good&quot;.  While this is true, to an extent, the design also determines the flow of information from the screen to the user.  In the words of <a class="reference external" href="http://www.andyrutledge.com/">Andy Rutledge</a>, &quot;<a class="reference external" href="http://www.andyrutledge.com/creativediscovery.php">It's not about the design, it's about communicating.</a>&quot;.  This only underlines the importance of good design.</p>
<p><a class="reference external" href="http://37signals.com/">37signals</a> designs their <a class="reference external" href="http://gettingreal.37signals.com/ch09_Interface_First.php">interfaces first</a>, citing two basic reasons.  First, design is lightweight relative to programming.  That is, it's much easier to change the position of a navigation bar than to change the data persistence layer of the backend.  Second, is that the interface <em>is</em> your product--if the visitor sees and interacts and remembers the interface and its design only, then the design really <em>is</em> the site itself.  I'm not sure how much I agree with the former, as I believe that design is becoming more and more heavyweight, but the latter definitely has some merit.</p>
<p>So it's a reasonably well-accepted fact that design is one of the most important aspects of a website, so why don't more people focus on it?  I think that the problem is specialization:  programmers--preferring to write code and think through the program logic--attempt to muddle their way through creating a user interface, while designers--preferring to perfect the margins, whitespace, and typography--attempt to muddle their way through defining logic of the backend.</p>
<p>Of course, I'm talking about smaller projects of only one or two members.  Once they get larger than that, they need to bring a few of &quot;the other&quot; type of people into the mix.  That being said, where are the people who are excellent dual designer-developers?  Of course people like this <a class="reference external" href="http://jeffcroft.com/">exist</a>, but these people are few and far between.</p>
<p>Part of the problem is that both disciplines are ones of constant improvement.  As a developer, I know that I will never stop getting better and more experienced in my craft.  I will always look at <a class="reference external" href="http://www.eflorenzano.com/blog/post/simple-random-character-function/">code that I wrote a year ago</a> and cringe.  <strong>This is part of what makes developing interesting to developers</strong>.  As I understand it, the same is true with design.  This property of both disciplines renders learning the other discipline futile, or at least makes it seem futile (which is a bit of a self-fulfilling prophecy).</p>
<p>Is it possible to become at least conversational in the language of design, when your experience and main interests is developer?  That's what I'll be trying to discover in the next few weeks and months.  I don't have more than a few hours a week to devote to it, but I've embarked on a bit of &quot;independent study&quot; about design, trying to learn from the best out there about grid-based layouts, color theory, etc.</p>
<p>The encouraging thing is that both designers and developers trend towards being bloggers as well, and that means that there's a wealth of great <a class="reference external" href="http://www.alistapart.com/">articles</a> and <a class="reference external" href="http://avalonstar.com/topic/design/">information</a> out there to learn from.  Keep an eye out here for updates on my progress, my successes/frustrations, and other theoretical ramblings about design.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/design/">Design</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Lessons Learned]]></title>
        <link href="http://eflorenzano.com/blog/2008/04/10/lessions-learned/"/>
        <updated>2008-04-10T17:08:40</updated>
        <id>http://eflorenzano.com/blog/2008/04/10/lessions-learned/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/04/10/lessions-learned/">Lessons Learned</a></h3>
<p class="datetime">Apr 10, 2008</p>
<div class="document">
<p>Yesterday I came across a quote from <a class="reference external" href="http://en.wikipedia.org/wiki/George_S._Patton">George Patton</a> (<a class="reference external" href="http://www.37signals.com/svn/posts/944-george-patton-quotes">via</a>), which stuck me as really insightful, but later something burned the quote directly into my brain.</p>
<blockquote>
--  A good plan, violently executed now, is better than a perfect plan next week.--</blockquote>
<p>It's a quote which rings quite similar to the commonly-said open source phrase, coined by <a class="reference external" href="http://www.catb.org/~esr/">Eric S. Raymond</a> in his article <a class="reference external" href="http://www.firstmonday.org/issues/issue3_3/raymond/#d4">The Cathedral and the Bazaar</a>.</p>
<blockquote>
&quot;Release early.  Release often.&quot;</blockquote>
<p>The thing which burned these ideas into my brain is the discovery of <a class="reference external" href="http://djangoplugables.com/">djangoplugables.com</a>.  Simply put: this is an excellent site, which follows the ideas that I mentioned above completely.  The premise behind it is essentially to list all of the available django reusable applications on google code, and to display a bit of information about each app.</p>
<p>A group of about 5 people, including myself, have been silently working on a very similar site for the past month or so (the bulk of our work took place during PyCon), but we utterly failed to follow the above sentiment.  We debated for hours over how users would be able to submit applications, claim them, and how we could ensure that those claims were accurate.  We had tagging, voting, comments, voting ON comments, graphs detailing how &quot;hot&quot; each application was (based on a frequency analysis of the votes over time), and OpenID integration.</p>
<p>But all of this functionality took time, and we implemented it behind closed doors, in a vacuum--without ever seriously focusing on the user interface.  I don't know yet what will become of all of our work, but I have a feeling that it will be discontinued in favor of the much better-looking and simpler <a class="reference external" href="http://djangoplugables.com/">djangoplugables.com</a>.  Maybe we'll see parts of it resurface again, but that's not really the message behind this post.  The real message to take away from this experience is that we should practice what we so often preach.  In the case of web development, execute the good plan now and iterate, versus trying to perfect everything before release.</p>
<p>The upside of all of this is that our goal has been achieved.  What we really wanted to accomplish is what now exists: an excellent resource for finding reusable django applications, and no matter who implements it, that's a win for everyone!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/eric-s-raymond/">Eric S. Raymond</a></li>
      
        <li><a href="/blog/categories/george-patton/">George Patton</a></li>
      
        <li><a href="/blog/categories/reusable-apps/">Reusable Apps</a></li>
      
        <li><a href="/blog/categories/software-development/">Software Development</a></li>
      
        <li><a href="/blog/categories/wisdom/">Wisdom</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[April Fools]]></title>
        <link href="http://eflorenzano.com/blog/2008/04/01/april-fools/"/>
        <updated>2008-04-01T06:14:03</updated>
        <id>http://eflorenzano.com/blog/2008/04/01/april-fools/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/04/01/april-fools/">April Fools</a></h3>
<p class="datetime">Apr 01, 2008</p>
<div class="document">
<p>April Fool's Day rocks!  Maybe I enjoy it because it happens to share the same day as my birthday, but I think it's more to do with the fact that everyone's having fun, being lighthearted, and simply not taking things too seriously.  Last year the blog wasn't in any shape to do anything fun for the occasion, but this year it took me about 10 minutes to whip up some middleware fun.  That's right, if you can read and understand this right now, the secret is out: a bit of Django middleware is all that's needed to turn your blog into l33t-sp34k central.</p>
<p>I'll even go one step further than telling you how I did it, I'll give you the code:</p>
<pre class="code python literal-block">
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">lxml.html</span>

<span class="n">trans</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">'cks'</span><span class="p">:</span> <span class="s">r'xxors'</span><span class="p">,</span>
    <span class="s">'lol'</span><span class="p">:</span> <span class="s">r'r0flc0pt3r'</span><span class="p">,</span>
    <span class="s">'the'</span><span class="p">:</span> <span class="s">r'teh'</span><span class="p">,</span>
    <span class="s">'a'</span><span class="p">:</span> <span class="s">r'4'</span><span class="p">,</span>
    <span class="s">'e'</span><span class="p">:</span> <span class="s">r'3'</span><span class="p">,</span>
    <span class="s">'f'</span><span class="p">:</span> <span class="s">r'ph'</span><span class="p">,</span>
    <span class="s">'g'</span><span class="p">:</span> <span class="s">r'6'</span><span class="p">,</span>
    <span class="s">'h'</span><span class="p">:</span> <span class="s">r'|-|'</span><span class="p">,</span>
    <span class="s">'i'</span><span class="p">:</span> <span class="s">r'1'</span><span class="p">,</span>
    <span class="s">'o'</span><span class="p">:</span> <span class="s">r'0'</span><span class="p">,</span>
    <span class="s">'s'</span><span class="p">:</span> <span class="s">r'5'</span><span class="p">,</span>
<span class="p">}</span>

<span class="k">def</span> <span class="nf">is_code_block</span><span class="p">(</span><span class="n">node</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">node</span><span class="o">.</span><span class="n">attrib</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'class'</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> <span class="o">==</span> <span class="s">'highlight'</span>

<span class="k">def</span> <span class="nf">recursive_leetifier</span><span class="p">(</span><span class="n">node</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">child</span> <span class="ow">in</span> <span class="n">node</span><span class="o">.</span><span class="n">iterchildren</span><span class="p">():</span>
        <span class="k">if</span> <span class="n">child</span><span class="o">.</span><span class="n">text</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">is_code_block</span><span class="p">(</span><span class="n">child</span><span class="p">):</span>
            <span class="k">for</span> <span class="n">pattern</span> <span class="ow">in</span> <span class="n">trans</span><span class="o">.</span><span class="n">iterkeys</span><span class="p">():</span>
                <span class="n">child</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">I</span><span class="p">)</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="n">trans</span><span class="p">[</span><span class="n">pattern</span><span class="p">],</span> <span class="n">child</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">is_code_block</span><span class="p">(</span><span class="n">child</span><span class="p">):</span>
            <span class="n">recursive_leetifier</span><span class="p">(</span><span class="n">child</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">LeetSpeakMiddleware</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">process_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">html</span> <span class="o">=</span> <span class="n">lxml</span><span class="o">.</span><span class="n">html</span><span class="o">.</span><span class="n">fromstring</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">content</span><span class="p">)</span>
            <span class="n">recursive_leetifier</span><span class="p">(</span><span class="n">html</span><span class="p">)</span>
            <span class="n">response</span><span class="o">.</span><span class="n">content</span> <span class="o">=</span> <span class="n">lxml</span><span class="o">.</span><span class="n">html</span><span class="o">.</span><span class="n">tostring</span><span class="p">(</span><span class="n">html</span><span class="p">)</span>
        <span class="k">except</span><span class="p">:</span>
            <span class="k">pass</span>
        <span class="k">return</span> <span class="n">response</span>
</pre>
<p>The idea behind it is simple: Let the request go completely through Django's request/response cycle, and just before returning the correct response, parse the HTML and convert all of the actual content to l33t by doing some simple regular expression substitution.  I'm using <a class="reference external" href="http://codespeak.net/lxml/parsing.html#parsing-html">lxml.html</a> simply because I attended <a class="reference external" href="http://blog.ianbicking.org/2008/03/21/pycon-talks/">Ian Bicking's talk at Pycon 2008</a> and was intrigued.  I must say that the familiar <a class="reference external" href="http://docs.python.org/lib/module-xml.etree.ElementTree.html">ElementTree</a> interface helped a lot in getting this code up and running in a short amount of time.</p>
<p>Hopefully you all find this holiday to be as fun as I do, and maybe I'll see some more l33t next year!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/april-1st/">April 1st</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Talk Controversy, Django Community, Sprints, and People]]></title>
        <link href="http://eflorenzano.com/blog/2008/03/21/talk-controversy-django-community-sprints-and-peop/"/>
        <updated>2008-03-21T00:14:33</updated>
        <id>http://eflorenzano.com/blog/2008/03/21/talk-controversy-django-community-sprints-and-peop/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/03/21/talk-controversy-django-community-sprints-and-peop/">Talk Controversy, Django Community, Sprints, and People</a></h3>
<p class="datetime">Mar 21, 2008</p>
<div class="document">
<p>PyCon 2008  has come to an end for me today, and while it was a highly different
event for me this year than last year, it was more enoyable in many ways.
During my flight today, I contemplated the previous week and my thoughts
invariably came back to four main themes:</p>
<div class="section" id="formal-talks-and-the-controversy-surrounding-them">
<h4>Formal Talks and the Controversy Surrounding Them</h4>
<p>I was blissfully unaware of all of the controversy surrounding the conference
this year until well after everyone else seemed to be.  I disagree on many of
the points that were brought up on the Python mailing list, but I can't help but
think that a few of the points brought up there hit close to the truth.</p>
<p>Last year was my first PyCon, and every talk that I went to excited me,
intrigued me, inspired me, and made me feel like Python was really something
great.  This year, I seemed to consistently pick the talk right next to the
great talks--I could tell because of the laughing and cheering from the other
side of the wall.</p>
<p>That's not to say that I didn't attend any great talks this year.  The PyPy
and IronPython/Silverlight talks were definitely highlights.  Both projects are
really thinking outside the box about traditional ways of doing things and are
succeeding in implementing their crazy ideas that could never work.  It's
exactly that kind of conceptual evolutionary change that excites me to try new
things myself, and anything that does that is a good thing.</p>
</div>
<div class="section" id="the-django-community-thrives">
<h4>The Django Community Thrives</h4>
<p>Wow.  The Django community is now huge.  At last year's Django BoF, we were able
to sit in a big circle and eat pizza and talk about Django, but this year there
were way too many people for that to have been possible.  The BoF was literally
a mini-conference inside of PyCon this year.</p>
<p>It seems like everywhere I went, I'd run into somebody that I recognized from
the Django community.  There were even some crazy times where people actually
recognized me! (Sometimes I forget that people actually read this blog.)
Whenever there were Django people to be found, they were always grouped together
and keeping each other company.  I think that this is mostly a great thing, as
long as it never turns into a reality distortion field.</p>
<p>No matter how you look at it, the rate of growth of the Django community, even
when compared to the growth of the Python community, is staggering.  At one
point in Adrian Holovaty's &quot;The State of Django&quot; talk, he asked everyone to
raise their hand if they were learning Python specifically through using Django.
A large portion of the people in attendence raised their hands.  How cool is
that!?</p>
</div>
<div class="section" id="sprints">
<h4>Sprints</h4>
<p>Sprints dominated my time this year.  Last year I got to stay for one portion of
one sprint--simply not enough to really understand what sprinting is all about.
This year, however, I got to sprint a lot!  The first day, I smashed through
about four patches and then started working on many-to-many intermediary model
support.  The merging of newforms-admin is really one big barrier for this patch
right now, so I was basically forced to stop working on it.</p>
<p>Aside from those contributions to Django itself, however, about 5 of us (who, by
the way ranged in previous experience in Django from almost none to branch
committer) began working on a project for the community.  Unfortunately we're
not yet finished with the site (we're probably sitting at about 75% complete),
so I can't publicly reveal it.  Rest assured that I'll blog about the site
itself once it's ready.</p>
<p>In all actuality, however, we didn't put our noses to the grindstone on this
site.  Sure we got a ton of work done on it in an extremely short amount of
time, but we could have gotten more done.  Instead of being code monkeys,
though, we really ended up taking the time to just drink some beer, make fun of
each other, and get to know one another.  And that's really what it's all about.</p>
</div>
<div class="section" id="it-always-boils-down-to-the-people">
<h4>It Always Boils Down to the People</h4>
<p>This feels like it's becoming sort of a recurring theme to my blog, but it's
something that I find to be true time and time again.  If PyCon had been just
the talks and coding by oneself, it would not have been very fun--it really
boils down to this: it's the people who make life fun.  People that challenge
you, trust you, people who don't match up with your expectations of them,
people who make you laugh, and people who you just can't figure out.</p>
<p>There's never a better place to find people who fit all of the above criteria
than PyCon, and in this case we all share a common interest: Python.  I found
myself thinking at the end about some of my fellow sprinters that we had become
quite good friends.  I don't know why it happened, but in only a week we really
seemed to get along.</p>
<p>Why do I love PyCon?  Because you can get into debates about computational
linguistics, walk 20 blocks with arms full of beer, stay up all night coding,
and groove out to some really amazing live jazz, all in one week.  That's why
I love PyCon.</p>
<p>(Note: There are no links in this post since I wrote it on a plane and posted it in-between connecting flights in an airport.)</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/pycon/">PyCon</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/sprint/">Sprint</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[PyCon 2008]]></title>
        <link href="http://eflorenzano.com/blog/2008/03/14/pycon-2008/"/>
        <updated>2008-03-14T01:04:47</updated>
        <id>http://eflorenzano.com/blog/2008/03/14/pycon-2008/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/03/14/pycon-2008/">PyCon 2008</a></h3>
<p class="datetime">Mar 14, 2008</p>
<div class="document">
<p>I'm currently on my way to Chicago for PyCon 2008!  I've miraculously convinced two of my good friends, Tony Hauber and Chris Coudron to come along as well.  They're even going to participate in the sprints.</p>
<p>Last year I was still 20 years old and therefore couldn't participate in any of the drinking activities, but this year it's a different story.  It's going to be really fun to see that side of the conference this year.</p>
<p>Come talk to me about...well..anything, really.  Pretty much any Django-related activity is a good bet on where to find me, otherwise hit up Twitter/Pownce, as I'll attempt to use those services to their fullest.  Have a wonderful PyCon and I hope to see and talk to a lot of you there!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/pycon/">PyCon</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Ideas and Execution]]></title>
        <link href="http://eflorenzano.com/blog/2008/03/12/ideas-and-execution/"/>
        <updated>2008-03-12T10:57:30</updated>
        <id>http://eflorenzano.com/blog/2008/03/12/ideas-and-execution/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/03/12/ideas-and-execution/">Ideas and Execution</a></h3>
<p class="datetime">Mar 12, 2008</p>
<div class="document">
<p>After my <a class="reference external" href="/blog/post/ajax-voting-nicer-css-threadedcomments-test/">last post about django-threadedcomments</a>, there have been several new releases.  We've integrated completely with <a class="reference external" href="http://code.google.com/p/django-comment-utils/">comment_utils</a>, added support for <a class="reference external" href="http://site.gravatar.com/">gravatar</a>, and added some internationalization (I love that we abbreviate this as i18n) support as well.  Every day more and more people seem to be adding bug reports, patches, and feature requests to the ticket tracker.  This couldn't make me happier, and I hope to see it continue.  But what does this have to do with ideas?  It's the first programming idea that I've taken through conception, execution and all the way to support.  After <a class="reference external" href="http://code.google.com/p/django-threadedcomments/">django-threadedcomments</a>, I've decided to change my outlook on how to organize and deal with ideas that I get every day.</p>
<div class="section" id="supporting-a-project">
<h4>Supporting a Project</h4>
<p>There sure is a thrill to just sitting down and quickly hammering out the solution to a problem.  Who cares if it's hacky and incomplete?  You just proved that your idea was doable and you did it.  It instills quite the sense of accomplishment.  That's the style of project that I've worked on until now (aside from work).  With <a class="reference external" href="http://code.google.com/p/django-threadedcomments/">django-threadedcomments</a>, however, there's a completely different feeling that's just as thrilling:  people are actually using it.  It gives a completely different and stronger sense of accomplishment.  The reason is because I made a conscious effort to support the application after its initial release, for my own benefit and for others'.</p>
<p>Admittedly it can be tedious at first.  I'm convinced that nobody enjoys writing test code, and writing documentation can take as long as writing the code itself (especially if you delete and re-write as much as I do), but being able to apply patches that people submit and actually <em>ghasp</em> re-use your own code in other projects is where the reward really lies.</p>
</div>
<div class="section" id="ideas">
<h4>Ideas</h4>
<p>I have ideas all the time--as I think most people do.  Whether it be while writing code for one project, sitting idly in class, or even eating my cereal in the morning, ideas for nifty programs or websites or APIs just sort of pop into my head.  What do I do with them?  Until recently, what happened is that I'd start working on it and lose interest after a while.  Over the last few months, however, I've begun to form a list instead of starting on the projects.</p>
<p>Why make a list?  Looking at my track record of starting and abandoning projects--and assuming that I'd like to do that far less often--it seems that something needs to change.  The change that I've settled on is to put them on a list instead of hastily implementing them.  When I attack one of these ideas, I'll attack it fully and correctly; bringing it from conception to implementation, and finally to support.  The reasons for this are three-fold:</p>
<ol class="arabic simple">
<li>It's a good incubation period.  After a while, some ideas seem stupid, while others keep begging to be solved.</li>
<li>It allows for a greater sense of accomplishment.  Once you cross out a few items on your list, you'll realize that what you've done is quite a feat.</li>
<li>You can simply remember all those crazy ideas that you have had.</li>
</ol>
</div>
<div class="section" id="what-is-on-my-list">
<h4>What is on my List?</h4>
<p>I'm sure many of you may be asking what, specifically, I have on my list.  <a class="reference external" href="http://code.google.com/p/django-threadedcomments/">django-threadedcomments</a> is on there, and my next project is <a class="reference external" href="http://code.google.com/p/django-simplestats/">django-simplestats</a>.  The latter is not ready for public consumption yet, but check it out if you'd like to see a sneak peek.  There are also several other items, but I'm not going to talk about them because it would take all the fun away from me!  Honestly though, don't ask me for my list.  Come up with your own and work through it for yourself.</p>
</div>
<div class="section" id="and-you">
<h4>And You</h4>
<p>Enough about me in this rambling post, what about you--how do you deal with ideas that you get every day?  Am I crazy for actually enjoying supporting a project?  Do you have any tips for me in my organizational endeavours?  Please respond in the comment section below.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/django-threadedcomments/">django-threadedcomments</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Hosting a Django Site with Pure Python]]></title>
        <link href="http://eflorenzano.com/blog/2008/02/22/hosting-django-site-pure-python/"/>
        <updated>2008-02-22T20:47:48</updated>
        <id>http://eflorenzano.com/blog/2008/02/22/hosting-django-site-pure-python/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/02/22/hosting-django-site-pure-python/">Hosting a Django Site with Pure Python</a></h3>
<p class="datetime">Feb 22, 2008</p>
<div class="document">
<p>Developing a site with Django is usually a breeze.  You've set up your models, created some views and used some generic views, and you've even created some spiffy templates.  Now it's time to publish that site for everyone to see.  Now if you're not already familiar with Apache, Lighttpd, or Nginx, you're stuck trying to figure out complicated configuration files and settings directives.  &quot;Why can't deployment be just as easy as running the development server?&quot;, you scream.</p>
<p>It's tempting to just attempt to use the development server in production.  But then you read the documentation (you do read the documentation, right?) and it clearly says:</p>
<blockquote>
DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through security audits or
performance tests. (And that--  s how it--  s gonna stay. We--  re in the business of making Web
frameworks, not Web servers, so improving this server to be able to handle a production
environment is outside the scope of Django.)</blockquote>
<p>Looks like it's time to fire up Apache, right?  Wrong.  At least, you don't have to.</p>
<div class="section" id="cherrypy-to-the-rescue">
<h4>CherryPy to the Rescue</h4>
<p>One of the features that <a class="reference external" href="http://www.cherrypy.org/">CherryPy</a> touts quite highly is that they include <tt class="docutils literal">&quot;A fast, <span class="pre">HTTP/1.1-compliant,</span> WSGI <span class="pre">thread-pooled</span> webserver&quot;</tt>, however a lesser known fact about that webserver is that it can be run completely independently of the rest of CherryPy--it's a standalone WSGI server.</p>
<p>So let's grab a copy of the CherryPy WSGI webserver:</p>
<pre class="code bash literal-block">
wget http://svn.cherrypy.org/trunk/cherrypy/wsgiserver/__init__.py -O wsgiserver.py
</pre>
<p>Now that you've got a copy of the server, let's write a script to start it up.  Your choices may vary depending on how many threads you want to run, etc.</p>
<pre class="code python literal-block">
<span class="kn">import</span> <span class="nn">wsgiserver</span>
<span class="c">#This can be from cherrypy import wsgiserver if you're not running it standalone.</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">django.core.handlers.wsgi</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">'DJANGO_SETTINGS_MODULE'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'settings'</span>
    <span class="n">server</span> <span class="o">=</span> <span class="n">wsgiserver</span><span class="o">.</span><span class="n">CherryPyWSGIServer</span><span class="p">(</span>
        <span class="p">(</span><span class="s">'0.0.0.0'</span><span class="p">,</span> <span class="mi">8000</span><span class="p">),</span>
        <span class="n">django</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">wsgi</span><span class="o">.</span><span class="n">WSGIHandler</span><span class="p">(),</span>
        <span class="n">server_name</span><span class="o">=</span><span class="s">'www.django.example'</span><span class="p">,</span>
        <span class="n">numthreads</span> <span class="o">=</span> <span class="mi">20</span><span class="p">,</span>
    <span class="p">)</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">server</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
    <span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span class="p">:</span>
        <span class="n">server</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span>
</pre>
</div>
<div class="section" id="consequences">
<h4>Consequences</h4>
<p>Now you've got the server up and running, lets talk about some consequences of this approach.</p>
<ol class="arabic simple">
<li>This is a multithreaded server.  Django is not guaranteed to be completely thread safe.  Many people seem to be running it fine in multithreaded environments, but thread safety may break at any time without notice.  It might be an interesting project to convert cherrypy.wsgiserver to use <a class="reference external" href="http://pyprocessing.berlios.de/">processing</a> instead of <a class="reference external" href="http://www.python.org/doc/lib/module-threading.html">threading</a> and see how the performance changes.</li>
<li>This server is written in Python, and as with any other Python program, it will be difficult for it to match the speed of pure C.  For exactly this reason, <a class="reference external" href="http://code.google.com/p/modwsgi/">mod_wsgi</a> is probably always going to be faster than this solution.</li>
<li>You can have a completely self-contained server environment that can be run on Mac, Windows, and Linux with only Python and a few Python libraries installed.  Distributing this wsgiserver.py script along with your Django project (or with a Django app, even) could be a great way of keeping the entire program self-contained.</li>
</ol>
</div>
<div class="section" id="conclusion">
<h4>Conclusion</h4>
<p>Would I use this instead of a fully-featured web server like Apache or Nginx?  Probably not.  I would, however, use it for an intranet which demands more performance and security than the built-in development server.  In any case, it's a nice nugget of information to have in your deployment toolbox.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/cherrypy/">CherryPy</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Syntax Highlighting]]></title>
        <link href="http://eflorenzano.com/blog/2008/02/22/syntax-highlighting/"/>
        <updated>2008-02-22T01:12:01</updated>
        <id>http://eflorenzano.com/blog/2008/02/22/syntax-highlighting/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/02/22/syntax-highlighting/">Syntax Highlighting</a></h3>
<p class="datetime">Feb 22, 2008</p>
<div class="document">
<p>Over the past week, I've had several people write me asking how I prefer to do syntax highlighting.  It's funny that this question cropped up now, just as I changed the way that it's handled on this blog.  The way that I used to do it was what I <a class="reference external" href="http://www.djangosnippets.org/snippets/25/">posted to djangosnippets</a> almost a year ago: use a regular expression to parse out <tt class="docutils literal"><span class="pre">&lt;code&gt;&lt;/code&gt;</span></tt> blocks, highlight the stuff in-between, and spit it back out.</p>
<p>The problem with that method was that that would require some more sophisticated logic now that I'm using <a class="reference external" href="http://docutils.sourceforge.net/rst.html">RestructuredText</a> to write all of my posts.  Unwilling to think any harder than necessary, I did a quick <a class="reference external" href="http://www.google.com/search?q=restructured+text+pygments">google search</a>, and the second result was exactly what I was looking for: a RestructuredText <a class="reference external" href="http://docutils.sourceforge.net/docs/ref/rst/directives.html">directive</a>, ready-made by the <a class="reference external" href="http://pygments.org/">Pygments</a> people.</p>
<p>The trick is to put <a class="reference external" href="http://dev.pocoo.org/projects/pygments/browser/external/rst-directive.py">this file</a> somewhere on your python path.  Then, in the <tt class="docutils literal">__init__.py</tt> of one of the Django apps that will use syntax highlighting, just import the file.  It's <strong>that simple</strong>!  (I love RestructuredText.)  But it's not only RestructuredText that benefits from this style of plugin.  <a class="reference external" href="http://daringfireball.net/projects/markdown/">Markdown</a>, too, has a <a class="reference external" href="http://dev.pocoo.org/projects/pygments/browser/external/markdown-processor.py">similar plugin</a>--again provided by the Pygments people.</p>
<pre class="code restructuredtext literal-block">
<span class="p">..</span> <span class="ow">code-block</span><span class="p">::</span> python

    print &quot;This is an example of how to use RestructuredText's new directive.&quot;
</pre>
<p>I hope that this answers some of the questions that people had.  On a similar note, I'm extremely happy to see that people have been finding the <a class="reference external" href="http://www.eflorenzano.com/contact/">Contact Me</a> link on the right side of the page.  Please continue to send me any questions and comments that you have for me!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/restructured-text/">Restructured Text</a></li>
      
        <li><a href="/blog/categories/syntax-highlighting/">Syntax Highlighting</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Django Tip: A Denormalization Alternative]]></title>
        <link href="http://eflorenzano.com/blog/2008/02/15/django-tip-denormalization-alternative/"/>
        <updated>2008-02-15T21:28:06</updated>
        <id>http://eflorenzano.com/blog/2008/02/15/django-tip-denormalization-alternative/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/02/15/django-tip-denormalization-alternative/">Django Tip: A Denormalization Alternative</a></h3>
<p class="datetime">Feb 15, 2008</p>
<div class="document">
<p>In creating an any website with textual content, you have the choice of either writing plaintext or writing in a markup language of some kind.  The immediately obvious choice for markup language is HTML (or XHTML), but HTML is not as human-readable as something like <a class="reference external" href="http://www.textism.com/tools/textile/">Textile</a>, <a class="reference external" href="http://daringfireball.net/projects/markdown/">Markdown</a>, or <a class="reference external" href="http://docutils.sourceforge.net/rst.html">Restructured Text</a>.  The advantage of choosing one of those human-readable alternatives is that content encoded using one of them can be translated very easily into HTML.</p>
<p>When one of my <a class="reference external" href="http://thauber.com/">friends</a> started designing his blog using Django, it got me thinking about how best to deal with that translated HTML.  It seems like a waste to keep re-translating it every time a visitor views the page, but it also seems like it's redundant to keep the translated HTML stored in the database.</p>
<p>Here's my solution to the problem: <strong>cache it</strong>.  For a month.  Here's an example, using Restructured Text:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>
<span class="kn">from</span> <span class="nn">django.contrib.markup.templatetags.markup</span> <span class="kn">import</span> <span class="n">restructuredtext</span>
<span class="kn">from</span> <span class="nn">django.core.cache</span> <span class="kn">import</span> <span class="n">cache</span>
<span class="kn">from</span> <span class="nn">django.utils.safestring</span> <span class="kn">import</span> <span class="n">mark_safe</span>

<span class="k">class</span> <span class="nc">MyContent</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">content</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">_get_content_html</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">key</span> <span class="o">=</span> <span class="s">'mycontent_html_</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pk</span><span class="p">)</span>
        <span class="n">html</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">html</span><span class="p">:</span>
            <span class="n">html</span> <span class="o">=</span> <span class="n">restructuredtext</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">content</span><span class="p">)</span>
            <span class="n">cache</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">html</span><span class="p">,</span> <span class="mi">60</span><span class="o">*</span><span class="mi">60</span><span class="o">*</span><span class="mi">24</span><span class="o">*</span><span class="mi">30</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">mark_safe</span><span class="p">(</span><span class="n">html</span><span class="p">)</span>
    <span class="n">content_html</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">_get_content_html</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">:</span>
            <span class="n">cache</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="s">'mycontent_html_</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pk</span><span class="p">))</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">MyContent</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</pre>
<p>What I'm doing here is writing a method which either gets the translated HTML from the cache, or translates it and stores it in the cache for a month.  Then, it returns it as safe HTML to display in a template.  The last thing that we do is override the save method on the model, so that whenever the model is re-saved, the cache is deleted.</p>
<p>There we go!  We now have the HTML-rendered data that we want, and no duplicated data in the database.  Keep in mind that this way of doing things becomes more and more useful the more RAM that your webserver has.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/caching/">Caching</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/html/">HTML</a></li>
      
        <li><a href="/blog/categories/restructured-text/">Restructured Text</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[On Context Processors in Django]]></title>
        <link href="http://eflorenzano.com/blog/2008/02/11/context-processors-django/"/>
        <updated>2008-02-11T20:20:01</updated>
        <id>http://eflorenzano.com/blog/2008/02/11/context-processors-django/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/02/11/context-processors-django/">On Context Processors in Django</a></h3>
<p class="datetime">Feb 11, 2008</p>
<div class="document">
<p>This started out as a response in the comments to James Bennett's <a class="reference external" href="http://www.b-list.org/weblog/2008/feb/11/integrity/">latest post</a>, but I think that there's enough here to warrant its own post.  If you haven't yet read it, then I suggest you do--it's a well-put argument for Django's application-level modularity and pluggability.</p>
<p>But I do disagree with him on one point.  One of the things that he highlights is about <em>&quot;how easy it is for one Django application to expose functionality to others through things like context processors&quot;.</em>  I don't find this to be true.  Currently there are only two ways of adding processors to the list of <tt class="docutils literal">context_processors</tt> for a particular view:</p>
<ol class="arabic simple">
<li>Adding them as an argument to the RequestContext (per-view).</li>
<li>Adding them to the global context processors list in settings.py (global).</li>
</ol>
<p>What these methods lack is a middle ground: per-app specification of context processors.  This is what  James Bennett seemingly alludes to which simply doesn't exist. What if I'd like all of the views in my blog app, and all views in flatpages to get a certain context processor list?  Currently in Django that is not possible.  I do think that there is demand for this, and it's something that probably wouldn't be too hard to add to trunk.</p>
<p>But really, if I can think of this particular use case of context processor loading, I'm sure there are other people who could think of others.  For example, what about a different set of processors based on URL, or based on IP address, or something even more strange?  What Django really needs is a pluggable context processor loader similar to how it loads session backends, authentication backends, database backends, urls, etc.  That way, people could provide their own loaders to do any kind of context processing differentiation that they want.</p>
<p>The only thing that this could do is make Django applications more pluggable--and that's always a good thing!  The good news is that PyCon is coming up, and I can try to tackle this during the sprinting days.</p>
<p><strong>UPDATE:</strong>  <a class="reference external" href="http://www.pointy-stick.com/blog/2008/02/12/django-tip-application-level-context-processors/">Malcolm Tredinnick</a> has posted an excellent followup to this post that suggests a simple solution for those who want to do something similar to application-level context processor loading right now.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/context-processors/">Context Processors</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/james-bennett/">James Bennett</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[OOP and Django]]></title>
        <link href="http://eflorenzano.com/blog/2008/02/09/oop-and-django/"/>
        <updated>2008-02-09T07:06:52</updated>
        <id>http://eflorenzano.com/blog/2008/02/09/oop-and-django/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/02/09/oop-and-django/">OOP and Django</a></h3>
<p class="datetime">Feb 09, 2008</p>
<div class="document">
<p>Being a senior in college means many things.  It means job interviews and upper-level classes, emotional instability and independent living.  It also means countless hours of sitting in uninteresting classes whose sole purpose is to fulfill some graduation requirement.  For me, that means lots of daydreaming--about anything other than that class.  Recently however, during one daydream, I had a brain wave worth typing up: What's the deal with Object-Oriented Programming and Django?</p>
<div class="section" id="the-convention">
<h4>The Convention</h4>
<p>Browsing through the <tt class="docutils literal">views.py</tt> file in just about any publicly-available Django-based application will almost certainly reveal nothing more than a bunch of functions.  These functions are undeniably specialized: they take in an <tt class="docutils literal">HttpRequest</tt> object (plus possibly some more information), and they return an <tt class="docutils literal">HttpResponse</tt> object.  Although these functions may be specialized, nevertheless they are still just functions.</p>
<p>This should come as no surprise to anyone who has used the framework--in fact, it's encouraged by common convention!  Not only does <a class="reference external" href="http://www.djangoproject.com/documentation/tutorial03/">the tutorial</a> use plain functions for views, but also the <a class="reference external" href="http://djangobook.com/en/1.0/chapter08/">Django Book</a>, and <a class="reference external" href="http://code.google.com/p/django-voting/">just</a> <a class="reference external" href="http://code.google.com/p/django-registration/">about</a> <a class="reference external" href="http://code.google.com/p/django-profiles/">every</a> <a class="reference external" href="http://code.google.com/p/django-tagging/">other</a> <a class="reference external" href="http://code.google.com/p/django-openid/">application</a> <a class="reference external" href="http://code.google.com/p/django-threadedcomments/">out</a> <a class="reference external" href="http://code.google.com/p/django-contact-form/">there</a>.  The question now becomes &quot;why&quot;?  Why, in a language that seems to be &quot;objects all the way down&quot;, does a paradigm emerge for this domain (Django views) wherein functions are used almost exclusively in lieu of objects?</p>
</div>
<div class="section" id="that-s-not-entirely-true-sir">
<h4>That's not entirely true, sir...</h4>
<p>Any time a broad statement like &quot;just about any&quot; is used, the exceptions are what become interesting.  The admin application (both newforms-admin and old) is probably the most notable and interesting exception to my earlier broad statement.  It's interesting because it's Django's shining star!  Other applications which use object orientation: databrowse and formtools.  These are some great Django apps which use Object-Orientation in the views.</p>
<p>Looking at those apps which use OOP and those which don't reveals an interesting idea: those apps which strive to go above-and-beyond in terms of modularity tend to be those who end up using classes and their methods for views.  Now this same functionality could be accomplished by using plain functions, but they haven't--their functionality was accomplished using classes and methods.</p>
<p>Please keep in mind that what I'm not trying to do is make a value judgement on Object-Oriented programming vs. functional programming vs. any other <a class="reference external" href="http://en.wikipedia.org/wiki/Programming_paradigm">programming paradigm</a>.  Instead, I'm providing an observation about the emergence of a common practice, and trying to analyze its implications.</p>
</div>
<div class="section" id="but-wait">
<h4>But wait!</h4>
<p>What really is the difference between writing a plain function as a view and Object-Oriented programming?  It's completely reasonable to argue that writing a plain function for a view <strong>is</strong>, in fact, Object-Oriented programming.  All class methods take in self as their first positional argument, and all views take in request as their first positional argument.  Taking in this argument allows access to state which would otherwise be difficult to access.  Changing the order of urlpatterns is equivalent to changing the polymorphic properties of a class and dynamic method lookup.</p>
<p>In essence, one could argue that <strong>using a plain function as a view is strictly equivalent to writing a method on the HttpRequest object</strong>.  Thinking about it in this way, writing a Django application is really nothing more than building up a monolithic <tt class="docutils literal">HttpRequest</tt> object which the user can call different methods on using its API: the URL.  To me, this is a really interesting idea!</p>
</div>
<div class="section" id="off-my-rocker">
<h4>Off My Rocker</h4>
<p>This is the result of extreme classroom boredom--so maybe posts here will continue down this slightly-more-esoteric road for a while.  But honestly this was an interesting thought-experiment, and I'd like to get some feedback on what people think as well.   Am I totally off base with this analysis?  Moreover, do you use true Python &quot;classes&quot; as your views?  If so, what benefits does it bring to the table?</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/object-oriented-programming/">Object Oriented Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[XFN Markup Enabled]]></title>
        <link href="http://eflorenzano.com/blog/2008/02/05/xfn-markup-enabled/"/>
        <updated>2008-02-05T18:35:01</updated>
        <id>http://eflorenzano.com/blog/2008/02/05/xfn-markup-enabled/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/02/05/xfn-markup-enabled/">XFN Markup Enabled</a></h3>
<p class="datetime">Feb 05, 2008</p>
<div class="document">
<p>The recently released <a class="reference external" href="http://code.google.com/apis/socialgraph/">Google Social Graph API</a> was a bit of a wake-up call for me on the power and importance of <a class="reference external" href="http://microformats.org/">microformats</a>.  So I've hacked together a quick implementation of <a class="reference external" href="http://gmpg.org/xfn/">XFN</a> for the blogroll, and added a few <tt class="docutils literal">rel=me</tt> links as well.</p>
<p>I'll follow this sometime soon with a post about how I implemented the XFN on a Django model.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
        <li><a href="/blog/categories/google/">Google</a></li>
      
        <li><a href="/blog/categories/social-graph/">Social Graph</a></li>
      
        <li><a href="/blog/categories/xfn/">XFN</a></li>
      
        <li><a href="/blog/categories/microformats/">Microformats</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[AJAX, Voting, and Some Nicer CSS: Putting django-threadedcomments to the Test]]></title>
        <link href="http://eflorenzano.com/blog/2008/01/30/ajax-voting-nicer-css-threadedcomments-test/"/>
        <updated>2008-01-30T18:02:13</updated>
        <id>http://eflorenzano.com/blog/2008/01/30/ajax-voting-nicer-css-threadedcomments-test/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/01/30/ajax-voting-nicer-css-threadedcomments-test/">AJAX, Voting, and Some Nicer CSS: Putting django-threadedcomments to the Test</a></h3>
<p class="datetime">Jan 30, 2008</p>
<div class="document">
<p>It's an interesting feeling open-sourcing an application that you've developed for your own purposes.  Will people use it?  Will people find major design flaws?  Is it just a big waste of time?  These were the questions that were going through my mind before open-sourcing <a class="reference external" href="http://code.google.com/p/django-threadedcomments/">django-threadedcomments</a>.  Fortunately, my worries were quelled almost instantly as a people reacted quite positively to the application.  There was one recurring comment, however, that almost everyone who tried the sample implementation said: <strong>those colors are hideous</strong>.</p>
<p>Beyond even that though, it seems that people saw the sample implementation and got the impression that django-threadedcomments = that sample implementation.  To me, that's an underestimation of the power of the modular django app.  I think that <a class="reference external" href="http://www.b-list.org/weblog/2007/nov/29/django-blog/">James Bennett</a> hits the nail on the head when he says that:</p>
<blockquote>
&quot;Rather than a single definitive 'Django blog' application, for example, I think it--  s much more likely
we--  ll see a collection of applications which, taken together, provide all the key
functionality...&quot;</blockquote>
<p>It was this sentiment that pervaded nearly all of the design decisions behind django-threadedcomments: it should be flexible, modular, and reusable so that, taken together with other similarly-designed apps, it can provide some compelling functionality at a fraction of the effort.  Now we most assuredly didn't achieve all of those design goals fully, but I believe we're headed in at least the right direction with its development.</p>
<p>To prove my point, I decided to create an improved Digg/Reddit comment system clone using <a class="reference external" href="http://insin.webfactional.com/weblog/">Jonathan Buchanan</a>'s wonderful <a class="reference external" href="http://code.google.com/p/django-voting/">django-voting</a> application, alongside <a class="reference external" href="http://code.google.com/p/django-threadedcomments/">django-threadedcomments</a>, and a fair bit of <a class="reference external" href="http://jquery.com/">jQuery</a>.  Being almost completely new to Javascript, I was pleasantly surprised by how easy it was to not only integrate all of these technologies and use extensive client- and server-side scripting, but also to achieve a compelling commenting system in well under a week of spare time.  Oh, and this time there was actually some effort in making the look and feel of the commenting system acceptable!  As with the first example, this one is completely open sourced and available in the django-threadedcomments SVN repository.</p>
<p>Without further ado, the <a class="reference external" href="http://www.eflorenzano.com/threadexample/blog/">Example Digg/Reddit Comment Clone Plus Focus</a>.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/jquery/">jquery</a></li>
      
        <li><a href="/blog/categories/javascript/">Javascript</a></li>
      
        <li><a href="/blog/categories/django-threadedcomments/">django-threadedcomments</a></li>
      
        <li><a href="/blog/categories/reddit/">Reddit</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Announcing django-threadedcomments]]></title>
        <link href="http://eflorenzano.com/blog/2008/01/23/announcing-django-threadedcomments/"/>
        <updated>2008-01-23T17:26:04</updated>
        <id>http://eflorenzano.com/blog/2008/01/23/announcing-django-threadedcomments/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/01/23/announcing-django-threadedcomments/">Announcing django-threadedcomments</a></h3>
<p class="datetime">Jan 23, 2008</p>
<div class="document">
<p><a class="reference external" href="http://code.google.com/p/django-threadedcomments/">Django-threadedcomments</a> is a simple yet flexible threaded commenting system for Django.  What I mean when I say threaded is that commenters can reply not only to the original item, but to other comments as well.  It is very similar to what Reddit or Digg have in their comments sections.</p>
<p>The idea for this application started about a month and a half ago, when my good friend Tony Hauber asked if I would work with him on a project idea that he had (more info on this in the future).  One of the major components of the project would need to be threaded comments.  Naturally, the first thing that I did was attempt to make <tt class="docutils literal">django.contrib.comments</tt> work for this purpose.  In the end, however, I kept running into problems which all basically boiled down to the fact that <tt class="docutils literal">django.contrib.comments</tt> was never meant for this purpose.</p>
<p>So I used <tt class="docutils literal">django.contrib.comments</tt> as a starting point, brought in some of the best features of the excellent <a class="reference external" href="http://code.google.com/p/django-comment-utils/">django-comment-utils</a> (In fact, <a class="reference external" href="http://code.google.com/p/django-threadedcomments/">django-threadedcomments</a> actually provides a fair amount of compatiblity with the Managers from django-comment-utils), and added a bit of my own alchemy.  This is the result of those things.</p>
<p>A lot of effort has gone into documentation on this project: inline documentation, <a class="reference external" href="http://api.rst2a.com/1.0/rst2/html?uri=http%3A//django-threadedcomments.googlecode.com/svn/trunk/docs/tutorial.txt&amp;style=zope">a tutorial on setting it up with a blog</a>, and <a class="reference external" href="http://api.rst2a.com/1.0/rst2/html?uri=http%3A//django-threadedcomments.googlecode.com/svn/trunk/docs/api.txt&amp;style=zope">complete API documentation</a>.  In fact, to see what you'll get after completing <a class="reference external" href="http://api.rst2a.com/1.0/rst2/html?uri=http%3A//django-threadedcomments.googlecode.com/svn/trunk/docs/tutorial.txt&amp;style=zope">the tutorial</a>, head on over to <a class="reference external" href="http://www.eflorenzano.com/threadedcomments/example/">this page</a>.  Please excuse my color scheme there--It's the comments that I'm trying to show off, not my design skills (or lack thereof).</p>
<p>If you're worried about the hassle of writing a script to migrate all of your <tt class="docutils literal">django.contrib.comments</tt> comments to this new system, then fear not: there's an included migration script and you'll only need to run <tt class="docutils literal">python manage.py migratecomments</tt> and the migration is automatically taken care of for you.</p>
<p>I really hope that this can be a useful tool for people looking to add a threaded commenting system to a project of theirs.  <a class="reference external" href="http://code.google.com/p/django-threadedcomments/">Check it out</a> and see if it's right for you!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/digg/">Digg</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/open-source/">Open Source</a></li>
      
        <li><a href="/blog/categories/django-threadedcomments/">django-threadedcomments</a></li>
      
        <li><a href="/blog/categories/reddit/">Reddit</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[I Caucused Tonight]]></title>
        <link href="http://eflorenzano.com/blog/2008/01/04/i-caucused-tonight/"/>
        <updated>2008-01-04T02:20:58</updated>
        <id>http://eflorenzano.com/blog/2008/01/04/i-caucused-tonight/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2008/01/04/i-caucused-tonight/">I Caucused Tonight</a></h3>
<p class="datetime">Jan 04, 2008</p>
<div class="document">
<p>I just got back from the caucuses, and am happy to report that Obama took our precinct in a landslide.  It was an immensely interesting experience to be a part of this process and it really felt like I was doing something important--because I was.  What was most interesting was that a small group of dedicated Obama supporters conscientiously defected to go support Biden, because the Biden supporters pledged to support Edwards if Biden was not deemed viable.  This meant that Obama lost no delegates, but that Edwards lost one delegate.</p>
<p>It was also great to see celebrities get involved too.  I was sitting about 4 feet away from Scarlett Johansson before the caucus when she was calling people to support Obama.  Didn't know she was going to be there and then looked over to my right and there she was!  I've also heard that Kal Penn was very involved, as my friend got a call from him directly.</p>
<p>Our final precinct results were:
Obama: 5 delegates
Clinton: 2 delegates
Edwards: 1 delegate
Biden: 1 delegate</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/politics/">Politics</a></li>
      
        <li><a href="/blog/categories/us-presidential-elections/">US Presidential Elections</a></li>
      
        <li><a href="/blog/categories/government/">Government</a></li>
      
        <li><a href="/blog/categories/iowa/">Iowa</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Creating a Pownce Widget Using Django]]></title>
        <link href="http://eflorenzano.com/blog/2007/12/18/creating-pownce-widget-using-django/"/>
        <updated>2007-12-18T18:37:52</updated>
        <id>http://eflorenzano.com/blog/2007/12/18/creating-pownce-widget-using-django/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/12/18/creating-pownce-widget-using-django/">Creating a Pownce Widget Using Django</a></h3>
<p class="datetime">Dec 18, 2007</p>
<div class="document">
<p>Widgets are everywhere!  It seems that every blog these days has at least a couple of widgets on their sidebar.  Yesterday I realized that I had never written one, and probably more importantly, I really had no concrete idea how they worked.  Using Django and a bit of Javascript, it turned out to be quite easy!  I'm going to show you the basics of how to write a widget yourself, but if enough people would like the source code to mine, I'll happily open source it.</p>
<p>Before starting on creating a widget, we've got to make sure that it has an API of some sort.  In the case of Pownce, there some <a class="reference external" href="http://pownce.pbwiki.com/API+Documentation1-1">Community Documentation</a> about the various things that can be done with its API.  For a simple widget, all we really need is to be able to <a class="reference external" href="http://pownce.pbwiki.com/API+Documentation1-1#PublicNoteList">fetch some public notes.</a></p>
<p>Our API call will be: <tt class="docutils literal"><span class="pre">http://api.pownce.com/1.1/public_note_lists.json</span></tt></p>
<p>Now that we've determined where to get our data, let's parse it and do something with it.</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">urllib2</span> <span class="kn">import</span> <span class="n">urlopen</span>
<span class="kn">from</span> <span class="nn">django.utils</span> <span class="kn">import</span> <span class="n">simplejson</span>
<span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">loader</span><span class="p">,</span> <span class="n">Context</span>
<span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>
<span class="k">def</span> <span class="nf">pownce_widget</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">api_call</span> <span class="o">=</span> <span class="s">&quot;http://api.pownce.com/1.1/public_note_lists.json&quot;</span>
    <span class="n">notes</span> <span class="o">=</span> <span class="n">simplejson</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">urlopen</span><span class="p">(</span><span class="n">api_call</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())[</span><span class="s">'notes'</span><span class="p">]</span>
    <span class="n">t</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s">'powncewidget/widget_content.html'</span><span class="p">)</span>
    <span class="n">c</span> <span class="o">=</span> <span class="n">Context</span><span class="p">({</span><span class="s">'notes'</span> <span class="p">:</span> <span class="n">notes</span><span class="p">})</span>
    <span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">c</span><span class="p">))</span>
</pre>
<p>Now you may be noticing that I'm not using the simpler <tt class="docutils literal">django.shortcuts.render_to_response</tt>.  That's because we're going to use the content that we've rendered here as context for another template which we'll use in a moment.  Also note that if you were to do this in a production environment, using a simple urlopen is not considered good practice.  See <a class="reference external" href="http://www.diveintopython.org/http_web_services/review.html">chapter 11</a> in <a class="reference external" href="http://diveintomark.org/">Mark Pilgrim's</a> excellent <a class="reference external" href="http://www.diveintopython.org/toc/index.html">Dive Into Python</a> for more information about what to do instead.</p>
<p>Now let's create a template:</p>
<pre class="code html+django literal-block">
<span class="nt">&lt;ul</span> <span class="na">id=</span><span class="s">&quot;pownce_widget&quot;</span><span class="nt">&gt;</span>
    <span class="cp">{%</span> <span class="k">for</span> <span class="nv">note</span> <span class="k">in</span> <span class="nv">notes</span> <span class="cp">%}</span>
        <span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">&quot;</span><span class="cp">{{</span> <span class="nv">note.permalink</span> <span class="cp">}}</span><span class="s">&quot;</span><span class="nt">&gt;</span><span class="cp">{{</span> <span class="nv">note.body</span><span class="o">|</span><span class="nf">slice</span><span class="s2">:&quot;:30&quot;</span> <span class="cp">}}</span><span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
    <span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
<span class="nt">&lt;/ul&gt;</span>
</pre>
<p>What we've done here is iterated over the public notes, and simply created an unordered list with the first 30 or less words from the note.  Also, we've provided a link to Pownce for each note listed.</p>
<p>If browsers could make cross-domain requests, we'd be done now: you could embed a small Javascript file which would asynchronously request this page and update the DOM accordingly.  However, this is not possible, so I've come up with a way to do it instead.  I'm not sure if it's a best practice--it sure seems to me like it's not--but it works, which is probably more important anyway.</p>
<p>So let's modify our view:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">urllib2</span> <span class="kn">import</span> <span class="n">urlopen</span>
<span class="kn">from</span> <span class="nn">django.utils</span> <span class="kn">import</span> <span class="n">simplejson</span>
<span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">loader</span><span class="p">,</span> <span class="n">Context</span><span class="p">,</span> <span class="n">RequestContext</span>
<span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>
<span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="kn">import</span> <span class="n">render_to_response</span>
<span class="k">def</span> <span class="nf">pownce_widget</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">api_call</span> <span class="o">=</span> <span class="s">&quot;http://api.pownce.com/1.1/public_note_lists&quot;</span>
    <span class="n">notes</span> <span class="o">=</span> <span class="n">simplejson</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">urlopen</span><span class="p">(</span><span class="n">api_call</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())[</span><span class="s">'notes'</span><span class="p">]</span>
    <span class="n">t</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s">'powncewidget/widget_content.html'</span><span class="p">)</span>
    <span class="n">c</span> <span class="o">=</span> <span class="n">Context</span><span class="p">({</span><span class="s">'notes'</span> <span class="p">:</span> <span class="n">notes</span><span class="p">})</span>
    <span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="s">&quot;widget_content&quot;</span> <span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">c</span><span class="p">))}</span>
    <span class="k">return</span> <span class="n">render_to_response</span><span class="p">(</span><span class="s">&quot;powncewidget/widget.html&quot;</span><span class="p">,</span> <span class="n">context</span><span class="p">,</span> <span class="n">context_instance</span><span class="o">=</span><span class="n">RequestContext</span><span class="p">(</span><span class="n">request</span><span class="p">))</span>
</pre>
<p>We've taken the rendered output from <tt class="docutils literal">widget_content.html</tt> and used it as context for another template, <tt class="docutils literal">widget.html</tt>, which we return as an <tt class="docutils literal">HttpResponse</tt> to the browser.  This doesn't make much sense until we've seen what that <tt class="docutils literal">widget.html</tt> template contains.  Here it is:</p>
<pre class="code html+django literal-block">
<span class="cp">{%</span> <span class="k">load</span> <span class="nv">stripwhitespace</span> <span class="cp">%}</span>

var _cssNode = document.createElement('link');
_cssNode.type = 'text/css';
_cssNode.rel = 'stylesheet';
_cssNode.href = '<span class="cp">{{</span> <span class="nv">MEDIA_URL</span> <span class="cp">}}</span>css/powncewidgetstyle.css';
_cssNode.media = 'screen';
document.getElementsByTagName(&quot;head&quot;)[0].appendChild(cssNode);
document.write('<span class="cp">{{</span> <span class="nv">widget_content</span><span class="o">|</span><span class="nf">stripwhitespace</span><span class="o">|</span><span class="nf">safe</span> <span class="cp">}}</span>');
</pre>
<p>What we're doing here is dynamically creating Javascript using Django's templating system which injects your rendered HTML into the page.  The first few lines add a new stylesheet to the page, and the last one writes your content to the page.  But what is this stripwhitespace filter that we see?  Javascript does not like multi-line string declarations such as what <tt class="docutils literal">widget_content</tt> produces.  With Django, it's easy to write a simple filter to make it all exist on one line:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django</span> <span class="kn">import</span> <span class="n">template</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="n">inbetween</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">'&gt;[ </span><span class="se">\r\n</span><span class="s">]+&lt;'</span><span class="p">)</span>
<span class="n">newlines</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">'</span><span class="se">\r</span><span class="s">|</span><span class="se">\n</span><span class="s">'</span><span class="p">)</span>
<span class="n">register</span> <span class="o">=</span> <span class="n">template</span><span class="o">.</span><span class="n">Library</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">stripwhitespace</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">newlines</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s">''</span><span class="p">,</span> <span class="n">inbetween</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s">'&gt;&lt;'</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span>
<span class="n">register</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="s">'stripwhitespace'</span><span class="p">,</span> <span class="n">stripwhitespace</span><span class="p">)</span>
</pre>
<p>With that, we've pretty much finished up on creating our widget.  There are lots of customization options from here: GET arguments, different API endpoints, etc.  Not only that, but there's lots of room for visual customization using CSS.  What we're doing is effectively generating Javascript, so anything that you'd like to do using Javascript is fair game as well.</p>
<p>The result after tweaking for a bit is what you see at the right under my &quot;Widgets&quot; links.  Here is a picture in case it stops working for some reason:</p>
<a class="reference external image-reference" href="http://media.eflorenzano.com/static/powncecreate.html"><img alt="http://media.eflorenzano.com/img/powncesample.png" src="http://media.eflorenzano.com/img/powncesample.png" /></a>
<p>If you'd like to create a pownce widget of your own by simply adding a snippet to your site, I've provided a <a class="reference external" href="http://media.eflorenzano.com/static/powncecreate.html">Pownce Widget Creator</a> for your convenience.</p>
<p>I think that it was fairly easy to do this using Django and Python, and if you've got any tips on best practices, please let me know so that I can code a better widget!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/javascript/">Javascript</a></li>
      
        <li><a href="/blog/categories/pownce/">Pownce</a></li>
      
        <li><a href="/blog/categories/widget/">Widget</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Django-Related Audio from Last Year&#39;s PyCon]]></title>
        <link href="http://eflorenzano.com/blog/2007/12/11/django-related-audio-last-years-pycon/"/>
        <updated>2007-12-11T23:44:14</updated>
        <id>http://eflorenzano.com/blog/2007/12/11/django-related-audio-last-years-pycon/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/12/11/django-related-audio-last-years-pycon/">Django-Related Audio from Last Year&#39;s PyCon</a></h3>
<p class="datetime">Dec 11, 2007</p>
<div class="document">
<p>I was lucky enough to be able to attend PyCon last year, and hope to do so again, but some great resources are starting to show up online for those who couldn't.  One example is Jacob Kaplan-Moss's talk named <a class="reference external" href="http://advocacy.python.org/podcasts/pycon/PyCon2007-BecomingOSDeveloper.mp3">Becoming an Open Source Developer: Lessons from the Django Project</a>.</p>
<p>Even if you've read James Bennett's <a class="reference external" href="http://www.b-list.org/weblog/2007/feb/23/pycon-2007-web-frameworks-panel/">excellent writeup</a> from the conference, some <a class="reference external" href="http://advocacy.python.org/podcasts/pycon/PyCon2007-WebFrameworksPanel.mp3">audio from the event itself</a> can always be fun to listen to.  Right now that's all I could find, but there's new audio showing up from PyCon every week.  The only way to stay updated is to subscribe to the <a class="reference external" href="http://advocacy.python.org/podcasts/pycon2007.rss">PyCon 2007 Podcast RSS Feed</a>.</p>
<p>P.S. Hello Django community aggregator!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/pycon/">PyCon</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Looking Forward: Upcoming Django Developments Worth Waiting For]]></title>
        <link href="http://eflorenzano.com/blog/2007/12/10/looking-forward-upcoming-django-developments-worth/"/>
        <updated>2007-12-10T20:18:26</updated>
        <id>http://eflorenzano.com/blog/2007/12/10/looking-forward-upcoming-django-developments-worth/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/12/10/looking-forward-upcoming-django-developments-worth/">Looking Forward: Upcoming Django Developments Worth Waiting For</a></h3>
<p class="datetime">Dec 10, 2007</p>
<div class="document">
<ol class="arabic">
<li><dl class="first docutils">
<dt><a class="reference external" href="http://code.djangoproject.com/wiki/NewformsAdminBranch">Newforms-Admin</a></dt>
<dd><p class="first">Started soon after the newforms package started to become stable, the newforms-admin branch
allows for a much more modular and flexible admin application.  The amount of flexibility allowed in
this branch extends to permissions, allowing for user-defined permissions schemes--can you say
'row-level permissions'?  It's even flexible enough to require no permissions at all: I needed a quick
display interface for work this past summer, and I used some of the hooks in the newforms-admin
branch to disable login and permissions and simply display some data publicly.</p>
<p class="last">Also, multiple different admin interfaces are easy with newforms-admin.  Group your apps into
functional sets and give each functional set its own admin interface.  Those who are using this
branch know that once you've gone newforms-admin, you'll never go back!</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt><a class="reference external" href="http://code.djangoproject.com/wiki/GeoDjango">GeoDjango</a></dt>
<dd><p class="first last">This one flew under my radar until very recently.  Their stated goal is &quot;to make it as easy as
possible to build GIS web applications and harness the power of spatially enabled data.&quot;  These guys
have done some really amazing things with this branch, including linking of the geographic data to
cool widgets that can be displayed in the admin interface (think google maps, openlayers, and more
to come as time goes on).  I don't personally have a need for any of the capabilities being added in
this project, but the scope and quality of what is being produced is impressive to say the least.</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt><a class="reference external" href="http://code.djangoproject.com/wiki/QuerysetRefactorBranch">Queryset-Refactoring</a></dt>
<dd><p class="first last">As code grows and evolves, it's difficult to stop at a certain point and say, &quot;this code doesn't fit the
bill anymore.&quot;  <a class="reference external" href="http://www.pointy-stick.com/blog/">Malcolm Tredinnick</a> was the one who stopped and said it.  Already at this stage,
<a class="reference external" href="http://code.djangoproject.com/query?status=new&amp;status=assigned&amp;status=reopened&amp;keywords=%7Eqs-rf&amp;order=priority">many many bugs</a> have been fixed by this branch.  Queryset-refactoring is not just for fixing
bugs.  Once it's completed, database backends will have a much easier time of customizing their
generated SQL.  With each change like this, Django becomes more modular.</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt><a class="reference external" href="http://code.djangoproject.com/ticket/6095">Manually-Specified Intermediary Model Support</a></dt>
<dd><p class="first last">OK I'm biased on this one.  This is the patch that I've been working on lately.  It's because every
time I create an Django application, I start out with a ManyToManyField and end up breaking that off
into a separate model.  Once that's done, I have to change all of my code so that it doesn't use the
convenient ManyToManyField helpers.  Once this patch is complete, you'll be able to specify an
intermediary model which will act as the storage for your m2m data.  In this way, extra information
can be attached to each relationship.</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt><a class="reference external" href="http://groups.google.com/group/django-developers/browse_thread/thread/d1eca0f5dca49a07/8aea3e9ece9835ec#8aea3e9ece9835ec">Fixing app_label</a></dt>
<dd><p class="first last">We're entering into 2008 soon, and that will mean that Django has been public for over two years.
Some of the core developers have been using it internally for even longer than that.  So one of the
things which people have started running into, is that app_labels have started clashing.  There hasn't
been any definitive decision on how to avoid these clashes, but there have been several promising
proposals.  In any case, expect this functionality to change somewhat in the next few months, so
that 'ellington.search' can coexist alongside 'chicagocrime.search'.  No longer will you have to worry
about naming everything differently!</p>
</dd>
</dl>
</li>
</ol>
<p>These are just a few of the developments that are going on which seem interesting and promising.  I hope that each and every one of these developing features eventually makes it into trunk, so that everyone can benefit from the hard work that people have put into the project.  Also, if you've got a feature that you're excited about, let me know through the comments.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Getting Involved in the Django Project]]></title>
        <link href="http://eflorenzano.com/blog/2007/12/07/getting-involved-django-project/"/>
        <updated>2007-12-07T18:24:10</updated>
        <id>http://eflorenzano.com/blog/2007/12/07/getting-involved-django-project/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/12/07/getting-involved-django-project/">Getting Involved in the Django Project</a></h3>
<p class="datetime">Dec 07, 2007</p>
<div class="document">
<p>Getting involved in an open source project is hard.  I've been working with <a class="reference external" href="http://www.djangoproject.com">Django</a> since early 2006 and doing so makes me want to contribute back to the project.  Several times now I've made attempts to do so, but all of them have failed.  Looking back it's easy to see where I, as a newcomer to the open source world, went wrong.  So let's start out with what <strong>not</strong> to do, by example.  After that I'll give some suggestions on what I think is the right way to go about it.</p>
<div class="section" id="don-t-do-these-things">
<h4>Don't do these things:</h4>
<ol class="arabic">
<li><dl class="first docutils">
<dt>Don't bite off more than you can chew</dt>
<dd><p class="first last">As a newcomer to both Python and Django, and to web development in general, one thing that I
constantly needed to do was redefine my models slightly differently as I discovered flaws in my
previous designs.  Django does not make this easy, as you either have to manually migrate your
SQL or you have to delete all of your data.  Can you see where this is going?  I thought, &quot;Perfect,
there's a way that I can contribute!  I'll add schema evolution to Django!&quot;  This was a huge
undertaking, it took a long time, and it eventually flopped because I simply didn't have the
experience at that point necessary to accomplish this task.</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>Don't work privately</dt>
<dd><p class="first last">The other problem with tackling schema evolution was that I had contacted off-list another person
who was enthusiastic about the idea, <a class="reference external" href="http://www.crankycoder.com/">Victor NG</a>.  Now  he's a great coder and did a lot of the
work on that project, but he wasn't an established member of the community.  We had set up a
completely separate SVN (actually <a class="reference external" href="http://svk.bestpractical.com/view/HomePage">SVK</a>) server and everything.  The result was that we were
completely shut off from the rest of the development community, and didn't get any input or insight
from the people who were really running the project.</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>As a newcomer, don't work on a community project</dt>
<dd><p class="first last">The next thing that I tried working on was a &quot;DjangoForge&quot; project.  I worked very hard for almost a
month--the month leading up to PyCon--and got a complete prototype up and running.  When I got
to PyCon, I expected to make a big debut and everyone would instantly love it and jump on board.
Wow, was that naive!  Nobody knew who I was, and everyone had different ideas about what a
community portal, a &quot;DjangoForge&quot;, would need to be.</p>
</dd>
</dl>
</li>
</ol>
</div>
<div class="section" id="do-these-things">
<h4>Do these things:</h4>
<ol class="arabic">
<li><dl class="first docutils">
<dt>Start without code</dt>
<dd><p class="first last">Start on documentation.  There are two reasons that this is a good idea.  Firstly, those people who
are checking in tickets will start to recognize your name and will see that you're interested in
contributing.  Secondly, you will begin to understand more and more about the internals of the
framework as you see how people are adding features.  I think that writing documentation is boring,
but what's more boring is not knowing the codebase well enough and writing bad code as a result.</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>Then do test code</dt>
<dd><p class="first last">After documenting some of the underpinnings of the framework, you now have a pretty good idea
about how it <em>should</em> behave.  Now make sure it really behaves that way.  Many people don't follow
the <a class="reference external" href="http://c2.com/cgi/wiki?CodeUnitTestFirst">Code Unit Test First</a> or test-driven development methodology.  That is, they write the code
and submit the patch without formal tests.  These patches usually can't be checked in to Django
without test code, as a lot of people rely on the trunk to be stable.  So you can do a lot of good by
simply writing test code, and it will earn you a lot of gratitude from the folks trying to get things
done.  On top of being helpful and earning gratitude, it helps you to learn the framework that much
better.</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>Work on already-submitted tickets.</dt>
<dd><p class="first last">It can be tempting to work on a pet-feature that you would like to have done.  This is not a bad
temptation, but for someone who is trying to become part of the community, it may be better to look
at what the core developers are anxious to have done.  This is where I am currently, working on
<a class="reference external" href="http://code.djangoproject.com/ticket/6095">tickets</a> <a class="reference external" href="http://code.djangoproject.com/ticket/6064">that the</a> <a class="reference external" href="http://code.djangoproject.com/ticket/6066">core devs</a> <a class="reference external" href="http://code.djangoproject.com/ticket/6092">have filed</a>.  They have good reasons for filing these tickets:
they have deemed it a wanted feature or bug, they have determined that it's a solvable idea or
problem, and they may even have insights in how to implement it!  These tickets can range from
small-scale to large-scale and now is when you can really start to show your stuff as a programmer.</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>Read django-dev mailing list</dt>
<dd><p class="first last">There's nothing more helpful than tracking where Django is going and what ideas are being kicked
around on that list.  Many times an idea has been brought up, fleshed out, and eventually decided
upon.  This doesn't always happen in the ticket tracker, and it shouldn't.  Whenever discussion is
needed, the mailing lists are a much better forum for that discussion to take place.  This is also a
good place to ping the community on tickets that you're interested in or have worked on.  Just
<em>please</em> don't spam the list, as nothing will make people more upset at you than a whiny spammer
on the django-dev mailing list.</p>
</dd>
</dl>
</li>
</ol>
</div>
<div class="section" id="and-beyond">
<h4>...and beyond</h4>
<p>After that, I have no more solid advice.  That's where I'm sitting right now with the Django project.  I'd like to become even more involved.  I'll probably will go about doing so by starting to propose new features, jumping in on the conversation, attending PyCon 2008, and working on spinoff projects like the excellent <a class="reference external" href="http://code.google.com/p/django-evolution/">django-evolution</a>.  But I'd like to know how other people have done it.  <strong>How have you gotten involved in the Django project?</strong></p>
<p><strong>Update:</strong> <a class="reference external" href="http://www.holovaty.com/">Adrian Holovaty</a> makes a great point in mentioning to check out the <a class="reference external" href="http://www.djangoproject.com/documentation/contributing/">Contributing to Django</a> section of the Django documentation, with gives a plethora of guidelines and tips for doing just that.  Thanks, Adrian!</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/open-source/">Open Source</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Fun Way of Displaying a Blogroll]]></title>
        <link href="http://eflorenzano.com/blog/2007/12/06/fun-way-displaying-blogroll/"/>
        <updated>2007-12-06T03:33:14</updated>
        <id>http://eflorenzano.com/blog/2007/12/06/fun-way-displaying-blogroll/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/12/06/fun-way-displaying-blogroll/">Fun Way of Displaying a Blogroll</a></h3>
<p class="datetime">Dec 06, 2007</p>
<div class="document">
<p>I've just relaunched the redesign of this site.  Nothing major is different, but one fun thing that I'd like to highlight is the way the blogroll is displayed.  I got the idea from <a class="reference external" href="http://www.moteldemoka.com/">Motel de Moka</a>, which has more links to work with than I do.</p>
<p>First, I set up a very simple model:</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">BlogRollLink</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">128</span><span class="p">)</span>
    <span class="n">date_added</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">)</span>
    <span class="n">url</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">URLField</span><span class="p">()</span>
</pre>
<p>But we've got a problem at this point: we can't order this by the number of characters in the name.  So we must modify our model to have an integer called <tt class="docutils literal">name_size</tt>, and then override <tt class="docutils literal">BlogRollLink</tt>'s save function to fill in that field any time the model is saved.  Our final model is below:</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">BlogRollLink</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">128</span><span class="p">)</span>
    <span class="n">name_size</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">IntegerField</span><span class="p">(</span><span class="n">editable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
    <span class="n">date_added</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">)</span>
    <span class="n">url</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">URLField</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">name_size</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">BlogRollLink</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>

    <span class="k">def</span> <span class="nf">get_absolute_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">url</span>

    <span class="k">class</span> <span class="nc">Admin</span><span class="p">:</span>
        <span class="k">pass</span>
</pre>
<p>Now to display this on every page, I've created a context processor named <tt class="docutils literal">blogroll_processor</tt>.  It looks like this:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">blogroll_processor</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">blogrolls</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'blogrolls'</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">blogrolls</span> <span class="o">==</span> <span class="bp">None</span><span class="p">:</span>
        <span class="n">blogrolls</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">BlogRollLink</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s">'name_size'</span><span class="p">))</span>
        <span class="n">cache</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">'blogrolls'</span><span class="p">,</span> <span class="n">blogrolls</span><span class="p">)</span>
    <span class="k">return</span> <span class="p">{</span><span class="s">'blogrolls'</span> <span class="p">:</span> <span class="n">blogrolls</span><span class="p">}</span>
</pre>
<p>And we're done!  A nifty &quot;waterfall&quot; of blogs.  Let me know what you think about this technique.  Is it stupid?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/design/">Design</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Picky]]></title>
        <link href="http://eflorenzano.com/blog/2007/09/14/picky/"/>
        <updated>2007-09-14T02:36:02</updated>
        <id>http://eflorenzano.com/blog/2007/09/14/picky/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/09/14/picky/">Picky</a></h3>
<p class="datetime">Sep 14, 2007</p>
<div class="document">
<p>I'm picky.  And I'm sick of this blog's design.  I'm going to redesign it again, and get rid of runs and scratchpad, since I don't use them any more.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Eyespot Internship: Complete]]></title>
        <link href="http://eflorenzano.com/blog/2007/08/11/eyespot-internship-complete/"/>
        <updated>2007-08-11T04:48:35</updated>
        <id>http://eflorenzano.com/blog/2007/08/11/eyespot-internship-complete/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/08/11/eyespot-internship-complete/">Eyespot Internship: Complete</a></h3>
<p class="datetime">Aug 11, 2007</p>
<div class="document">
<p>Today marked the last day of my internship at Eyespot.  There was such an outpouring of good will that it made me want to quit school immediately and stay with Eyespot.</p>
<p>I could not have asked for a better experience!</p>
<p>That's all for today.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/eyespot/">eyespot</a></li>
      
        <li><a href="/blog/categories/internship/">Internship</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Interesting Discussion, Nginx]]></title>
        <link href="http://eflorenzano.com/blog/2007/08/08/interesting-discussion-nginx/"/>
        <updated>2007-08-08T05:09:21</updated>
        <id>http://eflorenzano.com/blog/2007/08/08/interesting-discussion-nginx/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/08/08/interesting-discussion-nginx/">Interesting Discussion, Nginx</a></h3>
<p class="datetime">Aug 08, 2007</p>
<div class="document">
<p><a class="reference external" href="http://groups.google.com/group/django-developers/browse_thread/thread/37801d8c2f46a313/a002ad9645e64e0a#a002ad9645e64e0a">Very interesting discussion</a> going on right now about Django's templating language and whether to split it off into its own separate library.  One of the justifications is that it will &quot;feel&quot; easier to plug in other template languages into Django itself.  Funny how <a class="reference external" href="http://www.eflorenzano.com/blog/cheetah-and-django/">I just blogged about how easy this is already</a>.</p>
<p>Also, previously this site was run with apache2 and perlbal.  Now it's running apache2 and nginx.  At some point I'm going to make the switch to having all of the media pointing to an nginx-only server which short circuits the mod_python (also soon to be mod_wsgi, lol) handlers altogether.</p>
<p>Sorry that this is another in a line of short posts, but I expect this trend will continue as I move twice in the next 2 weeks.  Crazy stuff happening in my life right now!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/templating/">Templating</a></li>
      
        <li><a href="/blog/categories/nginx/">nginx</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Sphinx Search, Totally Rad Website]]></title>
        <link href="http://eflorenzano.com/blog/2007/08/07/sphinx-search-totally-rad-website/"/>
        <updated>2007-08-07T05:00:36</updated>
        <id>http://eflorenzano.com/blog/2007/08/07/sphinx-search-totally-rad-website/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/08/07/sphinx-search-totally-rad-website/">Sphinx Search, Totally Rad Website</a></h3>
<p class="datetime">Aug 07, 2007</p>
<div class="document">
<p><a class="reference external" href="http://www.sphinxsearch.com/">Sphinx Search ROCKS!</a>  I'm pretty sure it'll be the solution to my MusicBrainz problems for my secret project.  I'm going to set up a simple postgres server holding the MusicBrainz database, with Sphinx Search installed, and have it index on a cron.  It'll be awesome!  After trying out <a class="reference external" href="http://lucene.apache.org/java/docs/">Lucene</a> and its derivatives and being so underwhelmed, it's exciting to discover an app that truly seems to rock.  I'll report back on it later, but right now the indexer is 4 million queries into a 60 million query index.  Yeah, it's going to be a while.</p>
<p>I've been wanting to test drive two new technologies this past week, the first is <a class="reference external" href="http://bjorkoy.com/blueprint/index.html">Blueprint, the CSS Framework</a> which I saw on <a class="reference external" href="http://www.digg.com">Digg</a> a few days ago.  I also really wanted to try some new stuff with FreeComments, including saving people's login information in the session.  I'm messing with both of those things in a side-side project related to <a class="reference external" href="http://revision3.com/trs">The Totally Rad Show</a> which I think promises to be really fun.  I've spent only a couple of hours on it, but I think it's going to be probably my first project that people end up using.</p>
<p>So, <a class="reference external" href="http://revision3.com/trs/tuned">Stick Tuned</a> for a fun announcement from me in the next week or 2 weeks at the latest.  (The problem with this project is there's lots of data to enter which will take time.)</p>
<p>That's it for today, a short and sweet entry into this blog-o-rama.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/digg/">Digg</a></li>
      
        <li><a href="/blog/categories/secret-project/">Secret Project</a></li>
      
        <li><a href="/blog/categories/musicbrainz/">Musicbrainz</a></li>
      
        <li><a href="/blog/categories/lucene/">Lucene</a></li>
      
        <li><a href="/blog/categories/sphinx/">Sphinx</a></li>
      
        <li><a href="/blog/categories/totally-rad-show/">Totally Rad Show</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Cheetah and Django]]></title>
        <link href="http://eflorenzano.com/blog/2007/08/04/cheetah-and-django/"/>
        <updated>2007-08-04T03:18:41</updated>
        <id>http://eflorenzano.com/blog/2007/08/04/cheetah-and-django/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/08/04/cheetah-and-django/">Cheetah and Django</a></h3>
<p class="datetime">Aug 04, 2007</p>
<div class="document">
<p>Django is my preferred web development framework.  As such, I like it as a total solution: ORM, Template System, and Request/Response Mechanisms.  One of the criticisms that gets tossed around regarding Django is that it's a monolithic web framework, and as such it is not loosely coupled.  I would argue that while it is a monolithic framework, it is still loosely coupled, and I'll prove it by showing just how easy it is to replace the templating system.</p>
<p>After a quick google search for django and cheetah, I was surprised to find that there seem to be no really great examples online of the replacement of the template part of the Django stack.  That being the case, I have decided to provide some examples of how that can be accomplished.  In short, I'm going to demonstrate how to use the <a class="reference external" href="http://www.cheetahtemplate.org/">Cheetah template language</a> with the <a class="reference external" href="http://www.djangoproject.com/">Django web framework</a>.</p>
<p>Before we delve into how to integrate Cheetah with Django, first let's look at some basic Cheetah syntax.  Basically all placeholders in cheetah templates are prefixed by $, and all control flow logic is prefaced by #.  Beyond that, mostly the syntax follows normal Python syntax.</p>
<p>If there's a python object <tt class="docutils literal">test = [1, 2, &quot;3.1415&quot;, 4, range]</tt>, the Cheetah placeholder <tt class="docutils literal">$test[0]</tt> would return 1, <tt class="docutils literal">$test[2]</tt> would return 3.1415, and <tt class="docutils literal"><span class="pre">$test[4](0,$test[1])</span></tt> would return <tt class="docutils literal">[0, 1]</tt>.  To learn about control flow or any of the more advanced topics, you'll have to visit <a class="reference external" href="http://www.cheetahtemplate.org/docs/users_guide_html/users_guide.html">the excellent Cheetah Users Guide</a>.</p>
<p>To demonstrate using Cheetah with Django, we're going to use the canonical example: the blog.  First, the model (about the most simplistic one I could think of for a blog):</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>

<span class="k">class</span> <span class="nc">BlogPost</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">maxlength</span> <span class="o">=</span> <span class="mi">128</span><span class="p">)</span>
    <span class="n">body</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">__unicode__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span>
</pre>
<p>Now, let's make sure to add a template folder to TEMPLATE_DIRS in settings.py:</p>
<pre class="code python literal-block">
<span class="n">TEMPLATE_DIRS</span> <span class="o">=</span> <span class="p">(</span>
    <span class="s">'/path/to/myproject/templates'</span><span class="p">,</span>
<span class="p">)</span>
</pre>
<p>Now, one aspect of Django that I've gotten really accustomed to is the render_to_response method.  It's nice to be able to specify a template name and pass in some context, and get an <tt class="docutils literal">HttpResponse</tt> object back.  So we'll start by replacing that method, but for cheetah:</p>
<pre class="code python literal-block">
<span class="kn">import</span> <span class="nn">os.path</span>
<span class="kn">from</span> <span class="nn">Cheetah.Template</span> <span class="kn">import</span> <span class="n">Template</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>
<span class="k">def</span> <span class="nf">render_to_response</span><span class="p">(</span><span class="n">template_name</span><span class="p">,</span> <span class="n">context</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">template_dir</span> <span class="ow">in</span> <span class="n">settings</span><span class="o">.</span><span class="n">TEMPLATE_DIRS</span><span class="p">:</span>
        <span class="n">path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">template_dir</span><span class="p">,</span> <span class="n">template_name</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
            <span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="nb">file</span> <span class="o">=</span> <span class="n">path</span><span class="p">,</span> <span class="n">searchList</span> <span class="o">=</span> <span class="p">(</span><span class="n">context</span><span class="p">,))</span>
            <span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="nb">unicode</span><span class="p">(</span><span class="n">template</span><span class="p">),</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">,</span> <span class="s">'Could not find template for </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">template_name</span>
</pre>
<p>This code snippet can go anywhere, but to make it easy you can just put it in your <tt class="docutils literal">views.py</tt>.  As for how it works: basically we're just iterating over each template directory in <tt class="docutils literal">TEMPLATE_DIRS</tt>.  If we find that a file exists, we create a cheetah Template object with that file as its base and with the specified context as its search list.  Then, we simply render the result into an <tt class="docutils literal">HttpResponse</tt> object.  I feel that this solution is both simple and robust--two concepts that usually exclude each other.</p>
<p>So, how would a simple view look using our new helper render_to_response?</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">myproject.blog.models</span> <span class="kn">import</span> <span class="n">BlogPost</span>
<span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">blogs</span> <span class="o">=</span> <span class="n">BlogPost</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
    <span class="n">context</span> <span class="o">=</span> <span class="p">{</span> <span class="s">'blogs'</span> <span class="p">:</span> <span class="n">blogs</span> <span class="p">}</span>
    <span class="k">return</span> <span class="n">render_to_response</span><span class="p">(</span><span class="s">'index.tmpl'</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
</pre>
<p>Ok, it's going to take a bit of explaining for that last snippet.  There's a lot of advanced things going on that make it look totally unfamiliar.  But actually that's just one big lie: this looks EXACTLY like any other Django view!  We've just completely and transparently replaced the templating system of Django, and all it took was a 7-line helper function.  But we're not done yet.  We still have to write the template:</p>
<pre class="code html literal-block">
<span class="nt">&lt;html&gt;</span>
    <span class="nt">&lt;head&gt;&lt;title&gt;</span>I can has cheetah templates!<span class="nt">&lt;/title&gt;&lt;/head&gt;</span>
    <span class="nt">&lt;body&gt;</span>
    #for $post in $blogs
    <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;blogpost&quot;</span><span class="nt">&gt;</span>
        <span class="nt">&lt;h1&gt;</span>$post.title<span class="nt">&lt;/h1&gt;</span>
        <span class="nt">&lt;p&gt;</span>$post.body<span class="nt">&lt;/p&gt;</span>
    <span class="nt">&lt;/div&gt;</span>
    #end for
    <span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</pre>
<p>Now point a url to the example view, and watch the magic unfold.  I'm not a Cheetah user normally, so I can't really comment about some of the more complex features of that language, but I can't imagine that enabling them would be much more difficult than what we've already done here.  So, that means I'm totally aware that there may be some naivity in my implementation.  If so, please comment and I'll change it accordingly.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/cheetah/">Cheetah</a></li>
      
        <li><a href="/blog/categories/templating/">Templating</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[SimpleAggregation update, Eyespot]]></title>
        <link href="http://eflorenzano.com/blog/2007/08/03/simpleaggregation-update-eyespot/"/>
        <updated>2007-08-03T03:06:05</updated>
        <id>http://eflorenzano.com/blog/2007/08/03/simpleaggregation-update-eyespot/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/08/03/simpleaggregation-update-eyespot/">SimpleAggregation update, Eyespot</a></h3>
<p class="datetime">Aug 03, 2007</p>
<div class="document">
<div class="section" id="django-simpleaggregation">
<h4>django-simpleaggregation</h4>
<p>I have just released Version 0.2 of <a class="reference external" href="http://code.google.com/p/django-simpleaggregation/">django-simpleaggregation</a>.  Updates in this release:</p>
<ul class="simple">
<li>The detection of an update on a unique field was not being correctly computed.  It used to use the addition of an id field to determine whether an aggregate should be incremented, but now it uses another hook into the dispatcher to annotate pre-save the model instance with some metadata related to aggregation.</li>
<li>The old helper functions which were used to get aggregate data have now been replaced with an object which is smarter and cleaner.  I suspect there will be a few more cleanup changes to the implementation of this, but the API should now stay fairly stable.</li>
<li>Pagination is now usable.  In 0.1, some rudimentary pagination abilities existed, but now it supports most of the same pagination data that a generic view gives a template.</li>
</ul>
</div>
<div class="section" id="eflorenzano-com">
<h4>Eflorenzano.com</h4>
<p>I've updated this site to use freecomment and the excellent <a class="reference external" href="http://code.google.com/p/django-comment-utils/">django-comment-utils</a> by <a class="reference external" href="http://www.b-list.org/">James Bennett</a>, which allows me to automatically use Akismet to block spam.  Hopefully this will solve the problems that I've been having with comment spam, despite the efforts that I've made in the past to combat it programmaticaly.</p>
</div>
<div class="section" id="eyespot">
<h4>Eyespot</h4>
<p>My internship at <a class="reference external" href="http://www.eyespot.com/">eyespot</a> is coming to an end in a little over a week.  It's really bittersweet for me:  it has been such a great experience, moving out to California and working on the &quot;Web too pwoint oahh&quot; craziness, but I miss my friends from the midwest.  I was a little nervous to take this internship, because of the technologies that I knew eyespot was using (notably, Perl), but my experience this summer only reinforces my original thought: programming language doesn't matter, it's people who matter.</p>
<p>If it's people who matter, eyespot matters a whole lot, because there has been no other time when I have respected the people around me even close to as much as I respect those at eyespot.  I've never seen someone who can come up with the solution to a problem as I'm still trying to grasp the idea of the problem itself.  I've never seen people so willing to listen to and implement the ideas of an intern.  I've never seen a group of coworkers who were more welcoming and tight-knit, hanging out after work as much as during.  And most of all, I've never seen a group of people who were more skilled at their craft, as the people at eyespot.</p>
<p>Sure, there are some things that I think could be done better at eyespot.  Sometimes, frankly, I'm surprised that it all works.  But I'm not going to go into those things, however, because it's actually not relevant to my point.</p>
<p>So, all said, I'm excited for what the future holds for me and eyespot, my working life after college, etc.  But to bring it back to my earlier point, I'm also excited for my last year in college.  Being away from home and family and friends has made me realize just how much I appreciate all of them on a daily basis, and perhaps just how much I take them for granted.  I could care less about going back to learn computer science--I'm going back for the people (is this a recurring theme, or what?)</p>
<p>I'm going to carpe diem this next school year, because it's the last one I've got.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/simpleaggregation/">SimpleAggregation</a></li>
      
        <li><a href="/blog/categories/eyespot/">eyespot</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[35W Bridge]]></title>
        <link href="http://eflorenzano.com/blog/2007/08/02/35w-bridge/"/>
        <updated>2007-08-02T01:35:42</updated>
        <id>http://eflorenzano.com/blog/2007/08/02/35w-bridge/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/08/02/35w-bridge/">35W Bridge</a></h3>
<p class="datetime">Aug 02, 2007</p>
<div class="document">
<p>My thoughts go out to everyone affected in the tragedy of the fallen 35W bridge today in Minnesota.</p>
<p>This is such a terrible event, but I hope that it ends up looking worse than it actually is.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/tragedy/">tragedy</a></li>
      
        <li><a href="/blog/categories/news/">news</a></li>
      
        <li><a href="/blog/categories/minnesota/">Minnesota</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[iPhone Says: &#34;Hello, World&#34;]]></title>
        <link href="http://eflorenzano.com/blog/2007/07/31/iphone-says-hello-world/"/>
        <updated>2007-07-31T05:45:48</updated>
        <id>http://eflorenzano.com/blog/2007/07/31/iphone-says-hello-world/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/07/31/iphone-says-hello-world/">iPhone Says: &#34;Hello, World&#34;</a></h3>
<p class="datetime">Jul 31, 2007</p>
<div class="document">
<p>It was only a matter of time before the iPhone private SDK was cracked, and it looks as if that matter of time is <a class="reference external" href="http://iphone.fiveforty.net/wiki/index.php/UIKit_Hello_World">Up</a>.  This news is exciting to me as an iPhone user, but also as a programmer.  Assuming Apple doesn't patch this, which is a fairly large assumption, the UIKit will just continue to get more and more community documentation, and get easier and easier to work with.  There are so many little apps that I want to see, (...for example, a voice record app!) that no bad can come out of this development.</p>
<p>About django_simpleaggregation:  Well, one person responded on the mailing list, but that's it.  I guess I hoped to get more of a response, given all of the work that went into the documentation and tutorial for it.  In hindsight, I should have posted it to both the django-users and the django-developers mailing lists, instead of just the one for developers.  But that's not really an option either, as you look like a jerk for crossposting.  In any case, I'm sure people will stumble upon it and find it useful.</p>
<p>Google analytics rocks, by the way.  I installed it for this site just a few days ago and am amazed by how polished and easy to use it is for a free site.  It would be nice to get more frequent updates on the metrics, but hey, it's free!  Not only is it good for figuring out where your traffic is coming from (mine is coming from Europe, mostly), but its good for finding out what people are looking at.  In my case, embarrassingly enough,  people are looking at that old unfinished django gallery app tutorial.</p>
<p>Besides all of this geeky stuff that this blog is usually about, I've recently started watching the BBC-produced TV show Jekyll.  It sounds like a terrible idea for a series, and maybe it is, but it's got me hooked.  There's something intrinsically great about a story where one is constantly learning/discovering.</p>
<p>Think about the first time you saw the first Matrix movie, and they started explaining what the Matrix was, or in Memento when you finally started getting the necessary information to piece everything together, or even in The Usual Suspects, when you find out about Kaiser Sose.  It's the same thing with every episode of Jekyll.  The first episode, you know just a tiny sliver of information about the overall story, and as they reveal more information, what you automatically assumed ended up being wrong.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/simpleaggregation/">SimpleAggregation</a></li>
      
        <li><a href="/blog/categories/iphone/">iPhone</a></li>
      
        <li><a href="/blog/categories/secret-project/">Secret Project</a></li>
      
        <li><a href="/blog/categories/jekyll/">Jekyll</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Information has a Long Way to Go]]></title>
        <link href="http://eflorenzano.com/blog/2007/08/01/information-has-long-way-go/"/>
        <updated>2007-08-01T03:29:33</updated>
        <id>http://eflorenzano.com/blog/2007/08/01/information-has-long-way-go/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/08/01/information-has-long-way-go/">Information has a Long Way to Go</a></h3>
<p class="datetime">Aug 01, 2007</p>
<div class="document">
<p>I don't know how <a class="reference external" href="http://www.google.com/musica?aid=CthfGxkPMTB">Google</a> manages to <a class="reference external" href="http://www.google.com/musicl?lid=1SpDWykV7NL&amp;aid=CthfGxkPMTB">do it</a>!  They've linked music track/artist/album to online music vendors, a deceivingly simple-sounding task which has been the bane of my existence for the last two weeks.</p>
<p>Let's start with two of the big players:</p>
<div class="section" id="itunes">
<h4>iTunes</h4>
<p>iTunes has a terrible API: You go to <a class="reference external" href="http://ax.phobos.apple.com.edgesuite.net/WebObjects/MZStoreServices.woa/wa/itmsLinkMaker">iTunes Link Maker</a> and type in the keywords of your choice.  You can come up with a programmatic way to access this but it involves parsing invalid HTML.</p>
</div>
<div class="section" id="amazon">
<h4>Amazon</h4>
<p>Amazon's API is a good programmatic interface to its own internal service, but unfortunately that service is TERRIBLE.  Take <a class="reference external" href="http://www.amazon.com/Rodrigo-y-Gabriela-Bonus-DVD/dp/B000HKDEE2/ref=pd_bbs_sr_1/102-5025068-6051344?ie=UTF8&amp;s=music&amp;qid=1185941115&amp;sr=8-1">this</a>, for example: a CD from a wonderful band called Rodrigo y Gabriela.  One of the songs on it is named &quot;Ixtapa&quot;, so let's do a search for &quot;Ixtapa Rodrigo y Gabriela.&quot;  Makes sense, right?  Apparently not to Amazon's search.  In fact, amazon's search really has no concept of the song.  It's not something that they sell. Amazon knows all about album titles and artists, but not about the song itself.  This renders it useless for linking song to vendor!</p>
<p>But what about open source?</p>
</div>
<div class="section" id="musicbrainz">
<h4>MusicBrainz</h4>
<p>So the next thing that I try is using <a class="reference external" href="http://musicbrainz.org/">MusicBrainz</a>, an open source database of music metadata, which seems to have Amazon.com linking information built right in.  However, reading through the wiki, for hours, and hours, and hours, is not fun.  They have bits and pieces from all different times of the project's lifecycle, most of which is irrelevant.  But after a while I find out that to get access to the web services, you either need to limit your requests to 1 per second (unacceptable in my case), or you have to set up your own MusicBrainz server.  OK, let's do that!</p>
<p>Oh wait, they forgot to mention that it's the most rediculous dependency-ridden piece of bloatware ever.  It's so bad that they don't even really have a guide on how to set it up--they've given up and just created a virtual machine for people to download.  OK, well fine, let's download that and go from there.  What's this?  There's more setup?  Apparently so, because I had to leave my computer to import data and compute indexes for 3 days straight.</p>
<p>Finally, finally, I am ready to start accessing that music -&gt; amazon.com data, when I notice something: Non-Commercial license.  After all of this, the AMAZON SPECIFIC PORTION ONLY is licensed differently, and I cannot use it.  I am disappointed with this service, to say the least.  MusicBrainz needs a major overhaul in its software dependencies (Hint: Use Python, it's got batteries included.)  It also needs to take a serious look at its licensing scheme.  If it can address these two things, it will be much further along in its goal to make a great community database.</p>
<p>Information has a long way to go.  Music metadata and the ability to link to different music vendors should be ubiquitous and available in a standard way.  Nobody is benefiting by putting a <a class="reference external" href="http://www.gracenote.com/">lock and key</a> on this sort of data.  The people who really lose, in the end, is the music vendors who get ultimately less sales.  Hopefully someday soon they see the light, and fight to make this information accessible.</p>
</div>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/secret-project/">Secret Project</a></li>
      
        <li><a href="/blog/categories/musicbrainz/">Musicbrainz</a></li>
      
        <li><a href="/blog/categories/amazon/">amazon</a></li>
      
        <li><a href="/blog/categories/itunes/">iTunes</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Introducing django_simpleaggregation]]></title>
        <link href="http://eflorenzano.com/blog/2007/07/30/introducing-django_simpleaggregation/"/>
        <updated>2007-07-30T08:44:58</updated>
        <id>http://eflorenzano.com/blog/2007/07/30/introducing-django_simpleaggregation/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/07/30/introducing-django_simpleaggregation/">Introducing django_simpleaggregation</a></h3>
<p class="datetime">Jul 30, 2007</p>
<div class="document">
<p>I have just released version 0.1 of a spinoff project I did today.  I've been working on a side project which I'm not ready to talk about yet, and one of the things that I have consistently  needed was simple aggregation on Django models.  Nothing complicated like what we'll start to see with the new aggregation framework, but just simple things like counts on objects based on the uniqueness of certain fields of a model.</p>
<p>So check that out: <a class="reference external" href="http://code.google.com/p/django-simpleaggregation/">Here</a>  I'd really appreciate any feedback or comments you can give me.</p>
<p>So, that actually took quite a bit of time an energy to write, document, create a google project, package and upload, etc.  More time than I would have liked, but if it helps even one person, then it's worth it.</p>
<p>In other news, I have tried out <a class="reference external" href="http://code.google.com/p/modwsgi/">mod_wsgi</a> for Python and hosting my Django stuff, and WOW I must say that I'm quite impressed.  I haven't done any formal testing on it like <a class="reference external" href="http://code.google.com/p/modwsgi/wiki/PerformanceEstimates">Graham Dumpleton, the creator, has done</a>, but from my own informal observations I've noticed a good bump up in the snappiness of the app that I'm working on.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/simpleaggregation/">SimpleAggregation</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Woohoo!]]></title>
        <link href="http://eflorenzano.com/blog/2007/07/26/woohoo/"/>
        <updated>2007-07-26T15:44:43</updated>
        <id>http://eflorenzano.com/blog/2007/07/26/woohoo/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/07/26/woohoo/">Woohoo!</a></h3>
<p class="datetime">Jul 26, 2007</p>
<div class="document">
<p>I just found a designer!  And it's one of those guys that is way too high-profile for my budget, but he's interested in my idea!</p>
<p>WOOHOO!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/design/">Design</a></li>
      
        <li><a href="/blog/categories/joy/">Joy</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Web Design]]></title>
        <link href="http://eflorenzano.com/blog/2007/07/26/web-design/"/>
        <updated>2007-07-26T07:40:10</updated>
        <id>http://eflorenzano.com/blog/2007/07/26/web-design/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/07/26/web-design/">Web Design</a></h3>
<p class="datetime">Jul 26, 2007</p>
<div class="document">
<p>For the past month or so, in my free time I've been working on a potentially very profitable/successful idea.  I've had this idea for years, and have waited for someone else to do it, but nobody did.  This summer seemed like the perfect time to realize this idea, and to see just how far I could go with it.  There have been challenges in writing the back end for it so far, that much is certain, but by far most of my time has been spent looking for a designer.</p>
<p>I realized almost immediately that my design skills are not adequate to realize my idea in any decent way, so one of the first things that I decided was that I would need to enlist the help of a designer.  I have a budget of no more than $1000, so it should be fairly easy to find a decent if not good designer, right?  Wrong!  I never could have imagined that finding a designer would be so hard!</p>
<p>My first tactic was to email the guy who created inviteshare.com, because I like that design a lot and think he's a budding web designer who just needs to be discovered.  He responded, seemingly interested, and as soon as I presented my entire idea he was gone.  I'm actually fairly suspicious that he'll try and implement it himself, effectively stealing it from me.  But judging from his previous <em>development</em> work, I don't think I have too much to worry about.</p>
<p>My second tactic was to troll at a community for web designers/developers, like sitepoint.com, and look for potential candidates there.  One can not appreciate just how many AWFUL designers there are out there, until they visit the critique section of sitepoint.  And it's the same for all the designer web forums.  For the most part, the good designers don't go there while the bad ones go there to get help from the other bad designers.</p>
<p>My third tactic was to scour blogs of the truly great designers, and look at the comments.</p>
<ul class="simple">
<li><a class="reference external" href="http://jeffcroft.com/">Jeff Croft</a></li>
<li><a class="reference external" href="http://subtraction.com/">Khoi Vinh</a></li>
<li><a class="reference external" href="http://shauninman.com/">Shaun Inman</a></li>
<li><a class="reference external" href="http://andyrutledge.com/">Andy Rutledge</a></li>
<li><a class="reference external" href="http://bryanveloso.com/">Bryan Veloso</a></li>
</ul>
<p>...along with the best agencies:</p>
<ul class="simple">
<li><a class="reference external" href="http://simplebits.com/">simplebits.com</a></li>
<li><a class="reference external" href="http://electricpulp.com/">electricpulp.com</a></li>
<li><a class="reference external" href="http://thebignoob.com/">thebignoob.com</a></li>
</ul>
<p>...and so on and so forth for about 30 of the best of the best designers and agencies.</p>
<p>I would look at who posted comments and go to their websites, but even those people--fans of the best--are way too high-profile for my price range.</p>
<p>Right now, I'm not really sure whether to get some books and try and teach myself the principles of design, or to try and earn some more money, or to simply keep scouring the net for that budding designer that's willing to work for me for a reasonable price.</p>
<p>It'll be extremely interesting to see what ends up happening in the coming months.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/design/">Design</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Simple Random Character Function]]></title>
        <link href="http://eflorenzano.com/blog/2007/04/16/simple-random-character-function/"/>
        <updated>2007-04-16T05:27:22</updated>
        <id>http://eflorenzano.com/blog/2007/04/16/simple-random-character-function/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/04/16/simple-random-character-function/">Simple Random Character Function</a></h3>
<p class="datetime">Apr 16, 2007</p>
<div class="document">
<p>I use this function all the time, most recently for some anti-spam techniques, and it's worth posting somewhere.  It's modified from an entry on the activestate cookbook.</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">random_chars</span><span class="p">(</span><span class="n">length</span><span class="p">):</span>
    <span class="kn">import</span> <span class="nn">random</span>
    <span class="n">allowed_chars</span> <span class="o">=</span> <span class="s">&quot;abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWZYZ0123456789&quot;</span>
    <span class="n">word</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">length</span><span class="p">):</span>
        <span class="n">word</span> <span class="o">=</span> <span class="n">word</span> <span class="o">+</span> <span class="n">allowed_chars</span><span class="p">[</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mh">0xffffff</span><span class="p">)</span> <span class="o">%</span> <span class="nb">len</span><span class="p">(</span><span class="n">allowed_chars</span><span class="p">)]</span>
    <span class="k">return</span> <span class="n">word</span>
</pre>
<p>Also, for anyone who knows me and is interested: my surgery went well and I'm recovering faster than I would have expected.  Hopefully I'll be back to 100% speed in the next few days!</p>
<p>Anyways, hopefully this small code snippet is useful to someone else, as well!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Notice Anything?]]></title>
        <link href="http://eflorenzano.com/blog/2007/03/09/notice-anything/"/>
        <updated>2007-03-09T08:15:13</updated>
        <id>http://eflorenzano.com/blog/2007/03/09/notice-anything/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/03/09/notice-anything/">Notice Anything?</a></h3>
<p class="datetime">Mar 09, 2007</p>
<div class="document">
<p>So I've yet again redesigned the site.  This was not a backend redesign, but rather an aesthetic redesign consisting of mostly changing the CSS.  The other change that was made was that now I am deploying via subversion checkout.  I do my changes on my local copy, and then I commit those changes to subversion, and finally I do a checkout from the server's SVN.  This makes it much easier to deploy in general, and I will see how this ease continues into the future.</p>
<p>I'd like to work on all of the project ideas that I've got, but it seems like every time I get a free moment, it gets snapped up by something else.  For example, I thought that I would have some time to set up the secret santa site for my family finally, but then I realized that the database backend to this website is going to change a bit in the next few days and if I send everyone links to the secret santa stuff now then they won't be able to access it in the near future.  That's why I've got to do the database transition to postgresql during spring break and then I can get the secret santa information sent out.</p>
<p>I'd also like to work on my Django API idea, and I have a rough implementation figured out.  But it's not as robust as I'd like it to be before I release it to the public, and I'll actually have to do a little hacking on Django's source itself so that I can serialize some meta-information about models themselves, and not just instances of models which are supported right now.</p>
<p>But unfortunately right now I've got to do some learning of Perl, although in a way that kind of excites me.  (Sometimes I just get the itch to try something completely different, and that's happening now for sure.)  I'll need to invent some kind of pet project to help learn Perl for the future.</p>
<p>Blah, there's a bunch more personal stuff to write about, and frustrating professional stuff as well, but nobody that reads this (e.g. nobody) wants to hear about my personal stuff nor be frustrated by the professional stuff.</p>
<p>Despite all there, I'm excited for what this summer holds in store for me.  No matter what happens, it'll be a new and exciting experience and I cannot wait to see what does end up happening.</p>
<p>Until next time!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/design/">Design</a></li>
      
        <li><a href="/blog/categories/css/">CSS</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Post-Pycon Thoughts]]></title>
        <link href="http://eflorenzano.com/blog/2007/02/26/post-pycon-thoughts/"/>
        <updated>2007-02-26T09:10:01</updated>
        <id>http://eflorenzano.com/blog/2007/02/26/post-pycon-thoughts/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/02/26/post-pycon-thoughts/">Post-Pycon Thoughts</a></h3>
<p class="datetime">Feb 26, 2007</p>
<div class="document">
<p>On the plane ride back from PyCon today, right before getting all excited about a new code idea, I sat there reflecting about PyCon and about all of the things that I remembered.</p>
<p>I remembered feeling like a saturated sponge, soaking up all the knowledge that was possible from all of the amazing people who I met.  I remembered Macs and Ubuntu, and the sea of laptops on which they were operating.  I remember the panels and discussions, where insight into the development process was shared.  And I remembered every night getting back to the hotel room, crashing down into the bed, and being blissfully exhausted.</p>
<p>PyCon brought me to a new place with open source software.  Before going, I knew that I wanted to help, in an abstract sort of way.  But I wasn't really motivated until I saw the type of creative thinking that was going on.  It must be that creative thinking is infectious, because new ideas have been popping into my head ever since the convention.  It would be great to take a month or two and just brainstorm and program and implement all of the things that I'd like to do, without having to worry about where I can slot in that coding time.</p>
<p>Very interesting, as well, was how non-age-discriminating everyone was.  I was expecting to be looked down upon since I'm only 20, but even in the van on the way to the hotel, I was asked if I was giving a speech.  Next year, maybe!</p>
<p>Things that I'm excited for in the upcoming weeks and months: databrowse (will be huge in the Django community), hot club of france (vital for the community aspect of Django), Python 3000, Hopefully an array interface built directly into python (thanks NumPy guys!), and finally my own new brainchild: autoapi.  I'm not fully ready to talk about it, but it is a mechanism triggered similarly to Django's admin interface, which provides automatically a publicly accessible api for your app.</p>
<p>Also, the DjangoForge app is in Alpha stage, currently attached to www.flosblog.com.  I don't know what will happen from here, however.  Comments on the app ranged from &quot;Hmm&quot; to &quot;Ooh!&quot; but mostly &quot;Hmm&quot;s.  It didn't feel great to have people be so unenthusiastic about my work, but that just means that it's not good enough.  Also since it's a community project, it really should have been a community effort (which the hot club of france will be, hopefully).  In all, it was as good of a learning tool as anything else could be, and possibly something to put on a resume.</p>
<p>So in all: Excellent!  I met so many new people and learned so many great things.  I wish that I could have split up and attended multiple talks and BoFs and lectures all at the same time!  After having only worked with this technology for 6 months, I can't imagine anything having a greater impact on my aspirations than what this community has done to them.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
        <li><a href="/blog/categories/pycon/">PyCon</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[I&#39;m at PyCon]]></title>
        <link href="http://eflorenzano.com/blog/2007/02/22/at-pycon-at-django/"/>
        <updated>2007-02-22T21:10:23</updated>
        <id>http://eflorenzano.com/blog/2007/02/22/at-pycon-at-django/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/02/22/at-pycon-at-django/">I&#39;m at PyCon</a></h3>
<p class="datetime">Feb 22, 2007</p>
<div class="document">
<p>I'm, right now, sitting in the advanced Django tutorial at PyCon.  How cool is that?</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/pycon/">PyCon</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[PyCon Plans]]></title>
        <link href="http://eflorenzano.com/blog/2007/02/21/pycon-plans/"/>
        <updated>2007-02-21T04:53:35</updated>
        <id>http://eflorenzano.com/blog/2007/02/21/pycon-plans/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/02/21/pycon-plans/">PyCon Plans</a></h3>
<p class="datetime">Feb 21, 2007</p>
<div class="document">
<p>I've never been to PyCon before, nor any other conference for that matter, but I'm leaving tomorrow and so I've come up with a list of talks that I plan on attending.  This is preliminary, obviously, but for now this is my plan:</p>
<p>Tutorial Day (Thursday):</p>
<ul class="simple">
<li>Advanced Django Tutorial in Addison</li>
<li>Attendee Bag Stuffing by Volunteers in Bent Tree I</li>
</ul>
<p>Friday:</p>
<ul class="simple">
<li>Plenary: Chair's Opening Remarks - Ballrooms A-E and F-J</li>
<li>Plenary: Keynote 1 - Ivan Krsti? - Ballrooms A-E and F-J</li>
<li>Writing Your Own Python Types in C (#95) - Ballrooms F-J</li>
<li>Writing a Python Extension module in C++ using Swig (#45) - Ballrooms F-J</li>
<li>Using Stackless (#76) - Ballrooms F-J</li>
<li>Lunch &amp; Plenary: Sponsor Lightning Talks (Fri) (Probably Django BoF)- Ballrooms A-E and F-J</li>
<li>Python inside Imageworks (#2) - Ballrooms A-E</li>
<li>pyweek: making games in 7 days (#32) - Ballrooms F-J</li>
<li>Python for Visual Effects and Animation Pipelines: A Case Study of Tippett Studio's JET (#86) - Ballrooms A-E</li>
<li>Break w/o Snacks (Room Divider Change)</li>
<li>Plenary: Lightning Talks (Fri PM) - Ballrooms A-E and F-J</li>
<li>Python Lab: Solve This! - Ballrooms F-J</li>
</ul>
<p>Saturday:</p>
<ul class="simple">
<li>Plenary: Keynote 2 - Adele Goldberg - Ballrooms A-E and F-J</li>
<li>SQLAlchemy -- the Front-to-Back database toolkit (#47) - Ballrooms A-E</li>
<li>Understanding and Using NumPy (#52) - Ballrooms F-J</li>
<li>Lunch &amp; Plenary: Keynote 3 - Guido van Rossum - Ballrooms A-E and F-J</li>
<li>Becoming an Open Source Developer: Lessons from the Django Project (#20) - Mesquite</li>
<li>The Absolute Minimum an Open Source Developer Must Know About Intellectual Property (#25) - Mesquite</li>
<li>Dateutil to the Rescue! (#88) - Ballrooms A-E</li>
<li>Break w/ Snacks - All Ballrooms</li>
<li>Interactive Parallel and Distributed Computing with IPython (#50) - Ballrooms A-E</li>
<li>Why and when to use ctypes? (#51) - Ballrooms A-E</li>
<li>Break w/o Snacks (Prep for Lightning + Room Divider Change) - All Ballrooms</li>
<li>Plenary: Lightning Talks (Sat PM) - Ballrooms A-E and F-J</li>
<li>Dinner Break - All Ballrooms</li>
<li>Hands-On with the One-Laptop-per-Child - Mesquite</li>
<li>The Advocacy of Python - Community Discussion - Mesquite</li>
</ul>
<p>So there it is, and I'm looking forward to seeing all of these interesting talks!</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/pycon/">PyCon</a></li>
      
        <li><a href="/blog/categories/python/">Python</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Yet Another Project]]></title>
        <link href="http://eflorenzano.com/blog/2007/02/14/yet-another-project/"/>
        <updated>2007-02-14T08:29:31</updated>
        <id>http://eflorenzano.com/blog/2007/02/14/yet-another-project/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/02/14/yet-another-project/">Yet Another Project</a></h3>
<p class="datetime">Feb 14, 2007</p>
<div class="document">
<p>Well a few things have happened over the past few months.  Firstly, I have failed again in keeping this blog up to date.  Hopefully this post will be cathartic and I'll enjoy writing it so much that I will begin to post more often.  Secondly, I have been busy with new classes, Algorithms and Programming Languages being the most interesting of the bunch.  Thirdly, I have registered for PyCon!  Fourthly, and this is more recent, I've been working on a Django-related project which, until now, has been secret.</p>
<p>I have been working on a DjangoForge application.  It is not ready for release yet by any means, but it is at the point where I know I'll continue working on it until it's completed.  Right now, the Model classes are all created, and almost all of the public interface views.  Now all that's left is templating and CSS.  It's a well-known fact that you should do the hardest things first.</p>
<p>In this case, I should have done the templating and CSS first, since website DESIGN is so hard for me.  However, I have not followed the conventional wisdom, and am now paying for it with my design unskillfulness.  In any case, I am really grinding on this with every spare moment, in the hopes that when PyCon comes around, I'll at least have a prototype to show a few people.</p>
<p>Also, if you're wondering when Part II of the gallery application is coming: I don't know.  I was developing that gallery application for my brother's band website, and recently the creation of that website has gone down on his priority list.  That means that it has gone down on my priority list too, especially with PyCon coming up and all of the work on DjangoForge.</p>
<p>If you read this and have any ideas on functionality that DjangoForge should have, or on anything else, just leave a comment and I'll get back to it as soon as I can.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/neglect/">Neglect</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[A Poem Crossed My Mind]]></title>
        <link href="http://eflorenzano.com/blog/2007/02/14/poem-crossed-mind/"/>
        <updated>2007-02-14T09:29:12</updated>
        <id>http://eflorenzano.com/blog/2007/02/14/poem-crossed-mind/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2007/02/14/poem-crossed-mind/">A Poem Crossed My Mind</a></h3>
<p class="datetime">Feb 14, 2007</p>
<div class="document">
<p>A glimmer of tomorrow tugs mercilessly on the fabric of tonight.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/poem/">Poem</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Writing a Gallery App in Django, Part I]]></title>
        <link href="http://eflorenzano.com/blog/2006/12/20/writing-gallery-app-part-one/"/>
        <updated>2006-12-20T04:28:17</updated>
        <id>http://eflorenzano.com/blog/2006/12/20/writing-gallery-app-part-one/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2006/12/20/writing-gallery-app-part-one/">Writing a Gallery App in Django, Part I</a></h3>
<p class="datetime">Dec 20, 2006</p>
<div class="document">
<p>One thing that I see the need for on almost every site is a place to put images.  Whether it's a band website, a personal homepage, or a school newspaper, there will be a need for a photo gallery.  The easy way to do that is to use an open source package available already like Gallery2.  But that's written in PHP and it won't integrate easily with the rest of your site--especially if you use Django as the framework for the rest of your site.</p>
<p>The solution: write a gallery application for use in your website.  At first it may seem like a daunting task to create, but as I've found out, it can be quite easy.  My implementation is not completely up and running yet, but that's due to design issues with the rest of the site, not the photo gallery app itself.  With no further adieu, let's dive in and see how this can work.</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">Album</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">maxlength</span><span class="o">=</span><span class="mi">128</span><span class="p">)</span>
    <span class="n">slug</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">SlugField</span><span class="p">(</span><span class="n">prepopulate_from</span><span class="o">=</span><span class="p">(</span><span class="s">&quot;name&quot;</span><span class="p">,))</span>
    <span class="n">summary</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">()</span>
    <span class="n">date_created</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">auto_now_add</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">date_modified</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">auto_now</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</pre>
<p>As you can see, this is the Album object which contains information about a set of associated photos.  But wait, we don't have photos created yet!  Let's do that now.</p>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">Photo</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">maxlength</span><span class="o">=</span><span class="mi">256</span><span class="p">)</span>
    <span class="n">summary</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">TextField</span><span class="p">(</span><span class="n">blank</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">date_created</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">auto_now_add</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">date_modified</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="n">auto_now</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">image</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ImageField</span><span class="p">(</span><span class="n">upload_to</span><span class="o">=</span><span class="s">'photos/%Y/%m'</span><span class="p">)</span>
    <span class="n">album</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">Album</span><span class="p">)</span>
    <span class="n">is_cover_photo</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">BooleanField</span><span class="p">()</span>
</pre>
<p>Ok so now we have albums which have photos, and photos have a lot of information like a file which contains an image, a title, and a summary.</p>
<p>Now that we have these objects, we have some choices to make.  The images need to be resized into medium and small images for display on the list and detail pages, respectively.  This can be done several ways:</p>
<ol class="arabic simple">
<li>Use the HTML width and height attributes to resize the images.</li>
<li>Create a Django view with width and height parameters to both resize and serve the images.  (Lazy computation)</li>
<li>Resize the images on upload and store them to disk.  (Upfront computation)</li>
</ol>
<p>The first way is not optimal for two reasons.  Firstly each picture must be downloaded in it's entirety.  This is inefficient and could upset people with less bandwidth or bandwidth limits.  Secondly, when most browsers resize images, they do so using poor quality filters, resulting in a low quality representation of an image.</p>
<p>The second way is the most flexible, since the height and the width can be changed in a template or in a view and the resized images will change accordingly.  However, there is more on-the-fly computation with this way, possibly increasing page load times.  Also, Django is not designed to be used to serve binary files directly, so there could be unforseen consequences with handling a large number of photos this way.</p>
<p>The third way is less flexible, but it has one key advantage: it's fast.  Since the computation is done on upload, Apache or any other http media server can be used instead, completely removing the need to use the Django framework at all.  Let's implement it this way.</p>
<p>First, we'll need to overload the save function of the Photo model:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_cover_photo</span><span class="p">:</span>
        <span class="n">other_cover_photo</span> <span class="o">=</span> <span class="n">Photo</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">album</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">album</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">is_cover_photo</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">photo</span> <span class="ow">in</span> <span class="n">other_cover_photo</span><span class="p">:</span>
            <span class="n">photo</span><span class="o">.</span><span class="n">is_cover_photo</span> <span class="o">=</span> <span class="bp">False</span>
            <span class="n">photo</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
    <span class="n">filename</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_image_filename</span><span class="p">()</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">filename</span> <span class="o">==</span> <span class="s">''</span><span class="p">:</span>
        <span class="n">img</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
        <span class="n">img</span><span class="o">.</span><span class="n">thumbnail</span><span class="p">((</span><span class="mi">512</span><span class="p">,</span><span class="mi">512</span><span class="p">),</span> <span class="n">Image</span><span class="o">.</span><span class="n">ANTIALIAS</span><span class="p">)</span>
        <span class="n">img</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_medium_filename</span><span class="p">())</span>
        <span class="n">img</span><span class="o">.</span><span class="n">thumbnail</span><span class="p">((</span><span class="mi">150</span><span class="p">,</span><span class="mi">150</span><span class="p">),</span> <span class="n">Image</span><span class="o">.</span><span class="n">ANTIALIAS</span><span class="p">)</span>
        <span class="n">img</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_small_filename</span><span class="p">())</span>
    <span class="nb">super</span><span class="p">(</span><span class="n">Photo</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</pre>
<p>Before I talk about the thumbnailing aspect of this function, I'd like to briefly explain what's going on with the cover_photo aspect of Photo objects.  Each Album has a cover photo, so if the Album needs to be represented, it can be represented by one special photo.  This is just part of the way that I have designed my object, and can easily be removed.  However, there is a small bit of obligatory boilerplate code in this save function which sets any other is_cover_photo attributes to False if necessary.  (There can only be one cover photo per album, after all).  I'll come back to dealing with cover photos later.</p>
<p>First off, the <tt class="docutils literal">if not filename == ''</tt> statement is needed because save is sometimes called with no image data, and that can and will throw exceptions if PIL is used on a None object.  Then, it resizes a medium-sized (512px by 512px) image and saves it to a location provided by get_medium_filename.  I leave it to you to define your own get_medium_filename and get_small_filename with your own naming convention.  I followed Flickr's example of an underscore followed by an argument (image001.jpg becomes image001_m.jpg for medium and image001_s.jpg for small).  Finally, this method must call the it's parent save method so that all of the other attributes are saved correctly.</p>
<p>Now that we've overloaded the save functionality, we are going to have a problem with deletion.  Django will automatically delete the original image, but the resized thumbnails will be left on the disk forever.  This is not a huge problem, but we don't want that to happen anyways.  So let's take care of that by also overloading the delete function of Photo's model:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="n">filename</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_image_filename</span><span class="p">()</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_medium_filename</span><span class="p">())</span>
        <span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_small_filename</span><span class="p">())</span>
    <span class="k">except</span><span class="p">:</span>
        <span class="k">pass</span>
    <span class="nb">super</span><span class="p">(</span><span class="n">Photo</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
</pre>
<p>Simply put, it deletes the thumbnail files and then calls it's parent's delete, which will in turn delete it's original file.</p>
<p>Aside from creating some optional helper functions like <tt class="docutils literal">get_small_image_url</tt> and/or <tt class="docutils literal">get_medium_image_url</tt>, there's not much more to be done with the Photo model.  What can be done still, however, is in Album.  We now have zero or one cover photos for each Album, but it's going to be tricky to query for this each time, so let's create a function in Album to help us retrieve the associated cover_photo Photo object:</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">get_cover_photo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo_set</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">is_cover_photo</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span><span class="o">.</span><span class="n">count</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo_set</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">is_cover_photo</span><span class="o">=</span><span class="bp">True</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
    <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo_set</span><span class="o">.</span><span class="n">all</span><span class="p">()</span><span class="o">.</span><span class="n">count</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo_set</span><span class="o">.</span><span class="n">all</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">None</span>
</pre>
<p>That is, if the Album has a photo with <tt class="docutils literal">is_cover_photo == True</tt>, then grab it, otherwise grab the first image.  If there are no images in the album, return None.  That's it for the models.  Easy, huh?  Just run <tt class="docutils literal">manage.py syncdb</tt>, and let Django do the heavy lifting for you.</p>
<p>That's all for part one of this series on writing a gallery application with Django.  Next up: writing the views, urlconfs, and putting it all together.  Templating will be left up to you, since there are so many ways to display this information, but some examples will be given to point you in the right direction.</p>
<p>Note to purists:  I know that some of the functionality that is being implemented as helper functions in the models would be better implemented as custom template tags, but I find it easier to take a less philosophical stance on the &quot;right&quot; way to do things and sometimes do what's more practical.  In this case, writing model functions is a much easier solution than creating completely new template tags.  In either case, moving to a new site will require a rewrite, so I'm not even convinced that it hurts reusability.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/gallery/">Gallery</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Free Icons!]]></title>
        <link href="http://eflorenzano.com/blog/2006/12/09/free-icons/"/>
        <updated>2006-12-09T09:25:04</updated>
        <id>http://eflorenzano.com/blog/2006/12/09/free-icons/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2006/12/09/free-icons/">Free Icons!</a></h3>
<p class="datetime">Dec 09, 2006</p>
<div class="document">
<p>If you have noticed, there are now icons next to each comments link.  These are provided, free of cost, by <a class="reference external" href="http://www.famfamfam.com">famfamfam.com</a>.  If some 16x16 icons are needed, and you are not graphically or creatively inclined, this is your one-stop-shop.</p>
<p>In other news, a Speed graph has been added to the running page as well as a distance graph.  In doing that, I ran into a problem which was hard to debug, since it only happens on the live site.  In Django, trying to serialize a Numeric data type with simplejson will not work, so make sure to cast it to a python-native data type first.</p>
<p>Problem code:</p>
<pre class="code python literal-block">
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">run</span> <span class="ow">in</span> <span class="n">runs</span><span class="p">:</span>
    <span class="n">distance</span> <span class="o">=</span> <span class="n">run</span><span class="o">.</span><span class="n">distance</span><span class="p">()</span>
    <span class="n">speed_data</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span><span class="n">distance</span><span class="o">/</span><span class="n">run</span><span class="o">.</span><span class="n">time</span><span class="p">))</span>
    <span class="n">distance_data</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span><span class="n">distance</span><span class="p">))</span>
    <span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span>
</pre>
<p>Solution:</p>
<pre class="code python literal-block">
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">run</span> <span class="ow">in</span> <span class="n">runs</span><span class="p">:</span>
    <span class="n">distance</span> <span class="o">=</span> <span class="n">run</span><span class="o">.</span><span class="n">distance</span><span class="p">()</span>
    <span class="n">speed_data</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span><span class="n">distance</span><span class="o">/</span><span class="nb">float</span><span class="p">(</span><span class="n">run</span><span class="o">.</span><span class="n">time</span><span class="p">)))</span>
    <span class="n">distance_data</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span><span class="n">distance</span><span class="p">))</span>
    <span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span>
</pre>
<p>I also noticed a problem with my Pygments function, due to the regular expression, where it only allowed me to post one code snippet.  As you can see in this post, that has been fixed (although it was another particularly nasty bug to track down, and required a complete refactoring of my code in the end).</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/famfamfam-com/">Famfamfam.com</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/pygments/">Pygments</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[MythTV Box Down]]></title>
        <link href="http://eflorenzano.com/blog/2006/12/06/mythtv-box-down/"/>
        <updated>2006-12-06T07:27:13</updated>
        <id>http://eflorenzano.com/blog/2006/12/06/mythtv-box-down/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2006/12/06/mythtv-box-down/">MythTV Box Down</a></h3>
<p class="datetime">Dec 06, 2006</p>
<div class="document">
<p>Yesterday the MythTV computer that my roommate and I has died.  That is to say that the hard drives which contained all of the shows stopped functioning.  I think what we're going to do is wipe the hard drives and put only a small main hard drive in the MythTV box, and put the rest into a <a class="reference external" href="http://www.freenas.org/">FreeNAS</a> NAS server.</p>
<p>It'll have 2x200GB, 1x160GB, and 1x500GB hard drives by the time we're done, making for a total of 1060GB (just over a terabyte!) of total hard drive space.</p>
<p>Then, we'll have some HDs used for our respective media files, and probably the 500gb drive mapped from the MythTV box as the media storage for all the TV shows.  That way, if something happens to the MythTV box, we don't lose everything like we did this time.  The only problem that I can see is if the network just isn't fast enough for us to store our files on there and access it from our computers simultaneously.</p>
<p>I'm also trying to decide what case will be best to put the new MythTV components in.  Right now I'm leaning towards the Lian Li PC-V880B, but any other suggestions are welcome.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/freenas/">FreeNAS</a></li>
      
        <li><a href="/blog/categories/mythtv/">MythTV</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[Memcached and OpenWebLoad]]></title>
        <link href="http://eflorenzano.com/blog/2006/12/04/memcached-and-openwebload/"/>
        <updated>2006-12-04T21:46:58</updated>
        <id>http://eflorenzano.com/blog/2006/12/04/memcached-and-openwebload/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2006/12/04/memcached-and-openwebload/">Memcached and OpenWebLoad</a></h3>
<p class="datetime">Dec 04, 2006</p>
<div class="document">
<p>There has been a somewhat minor update to the site.  Now almost all of the site is cached.  That is, there is a <a class="reference external" href="http://www.danga.com/memcached/">memcached</a> backend running on the server, and this website can take advantage of that.</p>
<p>To test out the site's load capabilities, I used an open source program called <a class="reference external" href="http://sourceforge.net/projects/openwebload/">OpenWebLoad</a>.  It's quite impressive in its simplicity and utility.  With it, I was able to test a load of over 50 simultaneous users to the website.  Surprisingly, the site handled it with flying colors.</p>
<p>On a side note, I went to <a class="reference external" href="http://wilwheaton.typepad.com/">Wil Wheaton's site</a> after a long stint of not visiting it, and it's still as good as it's ever been.  There's an almost tangible difference between a writer's website and a blogger's website.  I think that it boils down to the fact that using only words, Wil can make you feel the emotion that he wants you to feel.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
        <li><a href="/blog/categories/memcached/">Memcached</a></li>
      
        <li><a href="/blog/categories/wil-wheaton/">Wil Wheaton</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
    <entry>
        <title type="html"><![CDATA[New Site Live!]]></title>
        <link href="http://eflorenzano.com/blog/2006/12/03/new-site-live/"/>
        <updated>2006-12-03T22:23:54</updated>
        <id>http://eflorenzano.com/blog/2006/12/03/new-site-live/</id>
        <content type="html"><![CDATA[<h3><a href="/blog/2006/12/03/new-site-live/">New Site Live!</a></h3>
<p class="datetime">Dec 03, 2006</p>
<div class="document">
<p>Hello all!  I have finally put my new website up for the world to see!  I'm still not much for designing the look and feel of websites, but after learning all about Django, I felt like I just had to update my website to use Django.</p>
<p>Under the hood, there is low-level caching being done on both the Digg RSS feed and the Yahoo Flickr feed.  There are two RSS feeds available for the site: new blog posts, and new run information.  To show the graph under runs, I've used some AJAX to get the running data dynamically and create the graph with javascript.  Finally, I've created a custom Django template tag to allow me to post syntax-highlighted code using Pygments.</p>
<p>Example of pygmentized code (the one from this site, actually, that gets my latest digg articles):</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">get_digg_rss</span><span class="p">():</span>
    <span class="n">d</span> <span class="o">=</span> <span class="n">feedparser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s">'http://www.digg.com/rss/floguy/index2.xml'</span><span class="p">)</span>
    <span class="n">dugg_dicts</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'dugg_dicts'</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">dugg_dicts</span> <span class="o">==</span> <span class="bp">None</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&quot;Had to re-fetch digg links&quot;</span>
        <span class="n">dugg_dicts</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">d</span><span class="o">.</span><span class="n">entries</span><span class="p">:</span>
            <span class="n">dugg_dicts</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s">'title'</span><span class="p">:</span><span class="n">entry</span><span class="o">.</span><span class="n">title</span><span class="p">,</span> <span class="s">'link'</span><span class="p">:</span><span class="n">entry</span><span class="o">.</span><span class="n">link</span><span class="p">})</span>
        <span class="n">cache</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">'dugg_dicts'</span><span class="p">,</span> <span class="n">dugg_dicts</span><span class="p">,</span> <span class="mi">60</span><span class="o">*</span><span class="mi">60</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">dugg_dicts</span>
</pre>
<p>I hope that you all enjoy the website, and I also hope that you'll begin to frequent it, because I'll be keeping it up-to-date with the goings-on of my professional life.</p>
</div>

<div class="categories">
    Posted in:
    <ul>
      
        <li><a href="/blog/categories/pygments/">Pygments</a></li>
      
        <li><a href="/blog/categories/ajax/">AJAX</a></li>
      
        <li><a href="/blog/categories/flickr/">Flickr</a></li>
      
        <li><a href="/blog/categories/digg/">Digg</a></li>
      
        <li><a href="/blog/categories/django/">Django</a></li>
      
        <li><a href="/blog/categories/eflorenzano-com/">Eflorenzano.com</a></li>
      
        <li><a href="/blog/categories/programming/">Programming</a></li>
      
    </ul>
  </div>]]></content>
    </entry>
    
</feed>