<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>Techscapades</title>
    <link>http://techscapades.com/blog</link>
    <description>Mike Griffith's Adventures in Web Development</description>
    <pubDate>Sat, 14 Jan 2012 00:48:58 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>How Fast is Too Fast?</title>
      <link>http://techscapades.com/blog/2012/01/13/how-fast-is-too-fast</link>
      <pubDate>Fri, 13 Jan 2012 19:30:00 EST</pubDate>
      <category><![CDATA[Web]]></category>
      <guid isPermaLink="true">http://techscapades.com/blog/2012/01/13/how-fast-is-too-fast</guid>
      <description>How Fast is Too Fast?</description>
      <content:encoded><![CDATA[<div style="float:right; margin:5px;">
<a href="http://www.flickr.com/photos/joeshlabotnik/497312470/" title="Speed Limit What??? by Joe Shlabotnik, on Flickr"><img src="http://farm1.staticflickr.com/205/497312470_c6d3a7198d_m.jpg" width="180" height="240" alt="Speed Limit What???"></a>
</div>

<p>I was recently fixing a bug related to a javascript sliding animation
incorrectly computing its final position. When testing the fix, QA noticed
that the sliding animation exhibited a little jitter that
was not reproduceable in production.  At first glance, it must be the fault of
a new png being too "heavy" for the browser.  Let's put the old one back.
No change. Crap.  There weren't any changes to the easing or the duration of the
animation (change focused on DOM restructuring).  I was starting to feel stumped.</p>
<p>Just then, QA also pointed out that one of the content regions on the page in
test "flashed" its reload much quicker than the production version.  In production,
the reload didn't happen until ~ 1/2 second after the animation completed.  In
our new test version, the reload was happening almost immediately during the
animation (which had a duration of 200ms).</p>
<p>As it turns out, our test server wasn't under much load, so the AJAX request was
happening in ~80ms, as compared to ~800ms in production!  So now, the reloading
of the content region was consuming browser resources that could be spent on the animation.
Wow, What a good problem to have!</p>
<p>This is when I went to a crazy place.</p>
<p><a href="http://www.useit.com/papers/responsetime.html">Jakob Nielsen quotes Miller and
Card et al about response times</a> by saying::</p>
<blockquote>
<p>0.1 second is about the limit for having the user feel that the system is
reacting instantaneously, meaning that no special feedback is necessary
except to display the result.</p>
<p>1.0 second is about the limit for the user's flow of thought to stay
uninterrupted, even though the user will notice the delay. Normally, no
special feedback is necessary during delays of more than 0.1 but less than
1.0 second, but the user does lose the feeling of operating directly on the
data.</p>
</blockquote>
<p>I decided that any AJAX response &lt; 200ms is just about the same as 200ms,
especially when the users' eyes are likely distracted by the animation.  I
thought about waiting for the animation's <code>complete</code> event to fire the AJAX,
but that feels like a lot of wasted time that could be processing the request.
So I built a <code>throttleAjax</code> method that goes something like this:</p>
<div class="pygments_murphy"><pre><span class="cm">/**</span>
<span class="cm"> * Execute an AJAX request using the given parameters, but don&#39;t let it</span>
<span class="cm"> * fire ``success`` sooner than the given minTime.  E.g.</span>
<span class="cm"> *</span>
<span class="cm"> *     throttleAjax({</span>
<span class="cm"> *         url:&#39;/foo/bar&#39;,</span>
<span class="cm"> *         success:function(data) { alert(&#39;Got &#39; + data); }</span>
<span class="cm"> *     }, 200);</span>
<span class="cm"> *</span>
<span class="cm"> * Requires jQuery&gt;=1.4</span>
<span class="cm"> */</span>
<span class="kd">function</span> <span class="nx">throttleAjax</span><span class="p">(</span><span class="nx">params</span><span class="p">,</span> <span class="nx">minTime</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">start</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">getTime</span><span class="p">();</span>
    <span class="kd">var</span> <span class="nx">success</span> <span class="o">=</span> <span class="nx">params</span><span class="p">.</span><span class="nx">success</span> <span class="o">||</span> <span class="kd">function</span><span class="p">(){};</span>
    <span class="nx">params</span><span class="p">.</span><span class="nx">success</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">flight</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">getTime</span><span class="p">()</span> <span class="o">-</span> <span class="nx">start</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">stall</span> <span class="o">=</span> <span class="p">(</span><span class="nx">flight</span> <span class="o">&lt;</span> <span class="nx">minTime</span><span class="p">)</span> <span class="o">?</span> <span class="nx">minTime</span> <span class="o">-</span> <span class="nx">flight</span> <span class="o">:</span> <span class="mi">0</span><span class="p">;</span>
        <span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span> <span class="k">return</span> <span class="nx">success</span><span class="p">(</span><span class="nx">arguments</span><span class="p">);</span> <span class="p">},</span> <span class="nx">stall</span><span class="p">);</span>
    <span class="p">};</span>
    <span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">(</span><span class="nx">params</span><span class="p">);</span>
<span class="p">}</span>

<p><span class="c1">//</span>
<span class="c1">// GIANT DISCLAIMER: I haven&#39;t tested this version of code, it&#39;s more or less</span>
<span class="c1">// an abstracted version from memory of what I wrote on company time.</span>
<span class="c1">//</span>
</pre></div></p>
<p>Now, you can fire off an AJAX request, then immediately start your animation.
If the AJAX by itself takes &gt; 200ms (or whatever your animation duration is)
you get the response as soon as its done.  If it ends up only taking 50ms,
the browser holds on to it for ~150ms before handing it off.</p>
<p>If you depend on smooth animations to enhance your user experience, some things
really can be too fast.</p>]]></content:encoded>
    </item>
    <item>
      <title>I Want to Hire Scheduled Maintenance Programmers</title>
      <link>http://techscapades.com/blog/2011/03/24/i-want-to-hire-scheduled-maintenance-programmers</link>
      <pubDate>Thu, 24 Mar 2011 21:00:00 EDT</pubDate>
      <category><![CDATA[Agile]]></category>
      <category><![CDATA[Quality]]></category>
      <guid isPermaLink="true">http://techscapades.com/blog/2011/03/24/i-want-to-hire-scheduled-maintenance-programmers</guid>
      <description>I Want to Hire Scheduled Maintenance Programmers</description>
      <content:encoded><![CDATA[<p>Maintenance programmers get a bad wrap.  They're seen tucked away in the corner,
frustrated, cleaning up others' bugs.  Occasionally, they'll hack a new feature
into old code, but without being there from the beginning, their code is usually
clumsy.  There's little chance to get in on a sexy new project building
something cool.</p>
<div align="center" style="margin: 5px;">
<a href="http://www.flickr.com/photos/potomo/4562532684/" title="South Morocco Town by potomo, on Flickr"><img src="http://farm4.static.flickr.com/3112/4562532684_fb1a2d5e4a_m.jpg" width="240" height="180" alt="South Morocco Town" /></a>
</div>

<p>In comes the <strong>scheduled maintenance programmer</strong>.  The difference is in the
problem they are presented.  They're given a software product prior to it
blowing up and challenged to make sure it's gonna keep running smoothly.  Change
the spark plugs, flush and fill, calipers and rotors -- whatever it takes.</p>
<div align="center" style="margin: 5px;">
<a href="http://www.flickr.com/photos/ronniegavelin/4342986619/" title="Garage party with Lambretta Club Stockholm. by Ronnie Gavelin, on Flickr"><img src="http://farm3.static.flickr.com/2787/4342986619_4dae0418f1_m.jpg" width="240" height="161" alt="Garage party with Lambretta Club Stockholm."
/></a>
</div>

<p>The principles of XP/TDD teach us to refactor our own code to ensure the highest
quality before ever delivering it, but technical debt inevitably slips through.
Often we abstract more than necessary, creating unnecessary complexity. Other
times we miss an abstraction, forcing duplicated code. The scheduled
maintenance programmer's role is to remove that debt, run/write additional tests
(and automate them where not already), refactor to improve maintainability, and
keep the ship moving at full steam ahead.</p>
<p>I want to work in a shop where these guys are respected.  Where they take a
Porsche, tune it up, and make it run like a Ferrari.</p>]]></content:encoded>
    </item>
    <item>
      <title>Go Fast!</title>
      <link>http://techscapades.com/blog/2010/08/10/go-fast</link>
      <pubDate>Tue, 10 Aug 2010 12:00:00 EDT</pubDate>
      <category><![CDATA[Agile]]></category>
      <guid isPermaLink="true">http://techscapades.com/blog/2010/08/10/go-fast</guid>
      <description>Go Fast!</description>
      <content:encoded><![CDATA[<div style="float:right; margin: 5px;">
    <a title="&quot;Going nowhere fast&quot;, or my $800 picture by NathanFromDeVryEET, on Flickr" target="_blank" href="http://www.flickr.com/photos/thatguyfromcchs08/2300190277/" title="&quot;Going nowhere fast&quot;, or my $800 picture by NathanFromDeVryEET, on Flickr"><img src="http://farm3.static.flickr.com/2036/2300190277_360853ae0d.jpg" alt="&quot;Going nowhere fast&quot;, or my $800 picture" width="250" height="184" /></a>
</div>

<p>I was reading <a href="http://www.amazon.com/Kill-Zone-Sgt-Jack-Coughlin/dp/0312360185">Kill Zone</a>
by Gunnery Sgt. Jack Coughlin, and was struck by the personal mantra of one of
the Marine snipers:</p>
<blockquote>
<p>Slow is smooth, smooth is fast.</p>
</blockquote>
<p>Even though lives aren't on the line when we step into work, it’s still
important in the software industry to understand that sometimes we shouldn’t
rush around like chickens with our heads cut off. When we <strong>sprint</strong> during an
agile iteration, we must maintain control.  During your project’s crunch time,
this is most important.</p>
<p>Slow down, take a breather, and think before you slam in a bunch of crap code.
All the technical debt you create has to be accounted for by someone.</p>
<p>Be the rabbit, not the hare.</p>
<!-- Originally posted at: http://www.mike-griffith.com/blog/2010/08/go-fast/ -->]]></content:encoded>
    </item>
    <item>
      <title>Python Decorators, SRP, and Testability</title>
      <link>http://techscapades.com/blog/2010/06/04/python-decorators-srp-and-testability</link>
      <pubDate>Fri, 04 Jun 2010 12:00:00 EDT</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Testing]]></category>
      <guid isPermaLink="true">http://techscapades.com/blog/2010/06/04/python-decorators-srp-and-testability</guid>
      <description>Python Decorators, SRP, and Testability</description>
      <content:encoded><![CDATA[<p><strong>On the SRP:</strong>
For those unfamiliar with the Single Responsibility Principle (SRP), it states
that <em>there should never be more than one reason for a class to change</em>.</p>
<p>That is to say: do one thing, do it well.</p>
<p><a href="http://www.python.org/dev/peps/pep-0318/">Decorators</a> (not to be confused with
<a href="http://en.wikipedia.org/wiki/Decorator_pattern">the decorator pattern</a>) can
add behaviors or side-effects to a method, and this can be dangerous.
It seems harmless, because by adding a decorator, you’re likely taking
boilerplate code and shuffling it elsewhere. However, they often encourage
badness because of how easy it is to add these behaviors.</p>
<p><strong>On Testing Decorated Methods:</strong></p>
<p>Adding an <code>@decorator</code> to a python object unarguably makes the undecorated code
difficult to test in isolation. Decorators are applied at compile-time, and
cannot be mocked or made to not-execute without some pain.</p>
<p>There are certainly a few common tricks that can help test a decorated method
with minimal side-effects, but they require changes to the decorator itself.
There’s just plain and simple no way to un-decorate a method for isolated
testing.</p>
<p><strong>Let’s Look at a Few Common Examples:</strong></p>
<p><strong><code>@expose</code></strong>: register a URL for a view function in a web framework</p>
<div class="pygments_murphy"><pre><span class="k">class</span> <span class="nc">BlogPostController</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="nd">@expose</span><span class="p">(</span><span class="s">&quot;/blog/{post_id}&quot;</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">index</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">post_id</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; show a blog post &quot;&quot;&quot;</span>
        <span class="n">post</span> <span class="o">=</span> <span class="n">adapter</span><span class="o">.</span><span class="n">get_post</span><span class="p">(</span><span class="n">post_id</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="s">&quot;show_entry.html&quot;</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="n">post</span><span class="o">=</span><span class="n">post</span><span class="p">))</span>
</pre></div>

<p>Without the <code>@expose</code>, your <code>show_entry</code> knows how to get a given post and
render it in the proper template. With the decorator, it also now knows which
URL corresponds to that. You now have multiple reasons for this block of code
to change, including pointing to a different URL or using a different template.
It’s preferred to have a separate module for managing which urls point to which
views.</p>
<p>Harm factor: low. Ick factor: medium – high.</p>
<p><strong><code>@cache</code></strong>: try to get the result from memcache, otherwise, execute the
function and stick it in cache for next time</p>
<div class="pygments_murphy"><pre><span class="k">class</span> <span class="nc">PostAdapter</span><span class="p">(</span><span class="n">DataAdapter</span><span class="p">):</span>
    <span class="nd">@cache</span>
    <span class="k">def</span> <span class="nf">get_post</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">post_id</span><span class="p">)</span>
        <span class="sd">&quot;&quot;&quot; grab a blog post from the database &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Post</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">post_id</span><span class="p">)</span><span class="o">.</span><span class="n">one</span><span class="p">()</span> <span class="c"># SQLAlchemy folks need to talk to Demeter...</span>
</pre></div>

<p>OK this seems cool right? You only hit the database when you have to, otherwise
we get it even quicker by looking it up in the cache.</p>
<p>What happens if you want to disable caching? A separate cache abstraction layer
would reduce volatility in your data adapter.</p>
<p>And what does the unit test look like?</p>
<div class="pygments_murphy"><pre><span class="k">class</span> <span class="nc">TestGettingAPost</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">setup</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">query</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span> <span class="c">#don&#39;t hit the production database!</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">post_adapter</span> <span class="o">=</span> <span class="n">PostAdapter</span><span class="p">(</span><span class="n">query</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">test_getting_a_post</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">post_adapter</span><span class="o">.</span><span class="n">get_post</span><span class="p">(</span><span class="mi">123</span><span class="p">)</span>
</pre></div>

<p>Damn, there’s no way to mock out the @cache decorator so it doesn’t run. Try
to, I dare you. You’re likely going to actually get post 123 from your
production memcache. Crappy. The only thing you can do is make the @cache grab
the cache implementation from the PostAdapter instance (and mock that out in
your test), or find some other sneaky way of disabling caching for test runs.
But the @cache decorator isn’t all self-contained and fun anymore.</p>
<p>Harm factor: medium – high.</p>
<p><strong><code>@validate</code></strong>: Make sure the request matches the specified schema, otherwise
hand-off to error handler</p>
<div class="pygments_murphy"><pre><span class="k">class</span> <span class="nc">EditPostController</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">_save_error</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">errors</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot; @validate decorator kicked flow here, redisplay edit page with errors &quot;&quot;&quot;</span>
        <span class="o">...</span>
    <span class="nd">@validate</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="n">error_handler</span><span class="o">=</span><span class="n">_save_error</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="n">request</span><span class="p">)</span>
        <span class="n">post</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">schema</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">params</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">post_adapter</span><span class="o">.</span><span class="n">save_post</span><span class="p">(</span><span class="n">post</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="s">&quot;/blog/{0}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">post_id</span><span class="p">))</span>
</pre></div>

<p>Without this @validate, there would be a lot of boilerplate code inside the
<code>save</code> method. With it, any unit test for the save method will be likely linked
to your schema. You’d have to make an actual valid request in order to test
this method. That’s outside of any tests for your schema directly. That means
double-coverage but 2 tests to update when requirements shift.</p>
<p>Harm factor: low-medium</p>
<p><strong>Conclusions (or tl;dr):</strong></p>
<p>As easy as it is to become infatuated with Python decorators, they definitely
encourage you to violate the SRP. This can create a myriad of problems:</p>
<ul>
<li>Difficultly in isolating system under test</li>
<li>Added complexity to enable testing</li>
<li>Redundant redundant unit tests</li>
<li>Making a code module more volatile than it ought to</li>
</ul>
<p>They still have some valid use cases and can lead to cleaner code, however, as
Master Yoda wisely said, “when you look at the dark side, careful you must be…”</p>
<p><a name="comments"></a><h2>6 Responses</h2></p>
<ol class="commentlist">

<p><li class="graybox">
   <a name="comment-5617"></a><cite><a href='http://www.codesoftly.com' rel='external nofollow' class='url'>Aaron</a></cite> Says:<br /></p>
<p><!--<small class="commentmetadata"><a href="#comment-5617" title="Friday, June 4th, 2010 at 11:51 am"></a> after publication. </small>-->
   <small class="commentmetadata"><a href="#comment-5617" title="">June 4th, 2010 at 11:51 am</a> </small></p>
<p><p>Yeap. I tend to only use decorators after exhausting all other practical options.</p>
<p>I despair when people act like they don&#8217;t cost anything.</p></p>
</li>

<p><li class="">
   <a name="comment-5619"></a><cite><a href='http://blog.extracheese.org' rel='external nofollow' class='url'>Gary Bernhardt</a></cite> Says:<br /></p>
<p><!--<small class="commentmetadata"><a href="#comment-5619" title="Friday, June 4th, 2010 at 3:15 pm"></a> after publication. </small>-->
   <small class="commentmetadata"><a href="#comment-5619" title="">June 4th, 2010 at 3:15 pm</a> </small></p>
<p><p>Thanks for writing this post so I don&#8217;t have to. <img src='http://www.mike-griffith.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>TurboGears seems to get this more right than others. It uses decorators extensively, but they only add attributes to the function; they never actually wrap it. The result is that a TurboGears controller&#8217;s output is easy to test – you just get the template context dictionary when you call the function. No template rendering is even done.</p>
<p>TG has other design choices baked in that are testing-hostile (global tg.request object, I&#8217;m looking at you!), but the decorators are unusually benign, which was a nice surprise for me!</p></p>
</li>

<p><li class="graybox">
   <a name="comment-5629"></a><cite><a href='http://blog.tplus1.com' rel='external nofollow' class='url'>Matt Wilson</a></cite> Says:<br />
   <!--<small class="commentmetadata"><a href="#comment-5629" title="Saturday, June 5th, 2010 at 8:45 am"></a> after publication. </small>-->
   <small class="commentmetadata"><a href="#comment-5629" title="">June 5th, 2010 at 8:45 am</a> </small></p>
<p><p>Nice post!  But I don&#8217;t like the subtext that closures in general are sucky.  Closures are beautiful.</p></p>
<p>The problem comes from code that modifies parameters.</p>
<p>A decorator like this:</p>
<p><code><br />
@expose("/blog...")<br />
def index<br />
</code></p>
<p>Is really the same as rebinding the original name to something new, like this:</p>
<p><code><br />
index = expose(index, "/blog...")<br />
</code></p>
<p>I find it hard to follow anything that works like that.</p>

<p>So when I want to decorate a function, generally I&#8217;ll do it like this:</p>
<p>exposed_index = expose(index, &#8220;/blog&#8230;&#8221;)</p>
<p>Now there&#8217;s no need for fanciness in the tests.  It should be easy to verify the behavior at each layer.</p>
<p>When I use proper &#8220;@&#8221; decorators, I&#8217;m usually doing something like what Gary is talking about in TG.  But in general, the @ syntax gives me the willies.</p>
<p>PS: In your first example, based on the text afterward, maybe you meant to name the method show_entry.  And Demeter is a chick <img src='http://www.mike-griffith.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

</li>

<p><li class="">
   <a name="comment-5631"></a><cite><a href='http://www.mike-griffith.com' rel='external nofollow' class='url'>Mike</a></cite> Says:<br />
   <!--<small class="commentmetadata"><a href="#comment-5631" title="Saturday, June 5th, 2010 at 11:28 am"></a> after publication. </small>-->
   <small class="commentmetadata"><a href="#comment-5631" title="">June 5th, 2010 at 11:28 am</a> </small></p>
<p><p>Thanks for the comments everyone.</p></p>
<p>@Matt: The beauty of closures is what makes decorators so appealing.</p>
<p>The &#8220;decorate as a copy&#8221; would certainly be preferred to the &#8220;@&#8221; syntax, but I still don&#8217;t know that it addresses the root of the issue.</p>
<p>In your example, you still need to test `exposed_index`, because likely that&#8217;s what you&#8217;ll want consumers of your class to use.  What sort of tests would you write?  You still can&#8217;t mock your imported `expose` method, so in reality you&#8217;ll need to assert all the behaviors of index as well as assert that expose did what it ought to (leading to even more test duplication).</p>

<p>I think decorators and closures become most dangerous as they find their way into the lower layers of code.  Near the top (view, presentation), we generally expect code to be more volatile and can sacrifice that for the elegant solutions they give us</p>

</li>

<p><li class="graybox">
   <a name="comment-5632"></a><cite><a href='http://blog.tplus1.com' rel='external nofollow' class='url'>Matt Wilson</a></cite> Says:<br />
   <!--<small class="commentmetadata"><a href="#comment-5632" title="Saturday, June 5th, 2010 at 12:19 pm"></a> after publication. </small>-->
   <small class="commentmetadata"><a href="#comment-5632" title="">June 5th, 2010 at 12:19 pm</a> </small></p>
<p><p>After I was confident that my index function worked right, and I was confident that my expose function worked right, I wouldn&#8217;t bother writing tests to make sure that I could compose the two.</p>
<p>The only bug I can imagine showing up after combining expose and index would be due to some interface mismatch; like index returns None and expose expects index to return a dict.</p>
<p>If that happened, I could just add a new test for index.  No need to test the combination of index with expose.</p>
<p>exposed_index is just an output of expose.  If expose&#8217;s unit tests are written to cover the whole domain of valid inputs, what could go wrong, except when somebody feeds invalid inputs (e.g., a function that doesn&#8217;t follow the protocol)?</p></p>
</li>

<p><li class="">
   <a name="comment-5678"></a><cite><a href='http://arunnambyar.wikispaces.com' rel='external nofollow' class='url'>Arun</a></cite> Says:<br /></p>
<p><!--<small class="commentmetadata"><a href="#comment-5678" title="Monday, June 14th, 2010 at 7:27 am"></a> after publication. </small>-->
   <small class="commentmetadata"><a href="#comment-5678" title="">June 14th, 2010 at 7:27 am</a> </small></p>
<p><p>Try this link also,</p>
<p><a href="http://arunnambyar.blogspot.com/2010/05/python-decorators-in-depth.html" rel="nofollow">http://arunnambyar.blogspot.com/2010/05/python-decorators-in-depth.html</a></p>
<p>Its highly helpful.<br />
It is describing a to Z of python decorators..</p></p>
</li>

</ol>

<!-- Originally posted at http://www.mike-griffith.com/blog/2010/06/python-decorators-srp-and-testability/ -->]]></content:encoded>
    </item>
    <item>
      <title>Rally Pairing</title>
      <link>http://techscapades.com/blog/2010/05/10/rally-pairing</link>
      <pubDate>Mon, 10 May 2010 12:00:00 EDT</pubDate>
      <category><![CDATA[Agile]]></category>
      <guid isPermaLink="true">http://techscapades.com/blog/2010/05/10/rally-pairing</guid>
      <description>Rally Pairing</description>
      <content:encoded><![CDATA[<p>Iwein Fuld posted a great article about different styles of pair programming.
It’s a great post, and I encourage you to read it if you’ve tried pairing but
haven’t bought in yet. His rally car analogy is spot-on.</p>
<blockquote>
<p>My favorite driver is an outspoken dutch guy. He’s quick on the wheel and if
he doesn’t get the idea I’m trying to convey to him he’ll just type something
to try if that works. When he does get what I’m mumbling it’s on the screen
faster than when I would have typed it myself, so it doesn’t give me time to
get frustrated over things not being like the would be when I had the
keyboard. And that gives me time to look for exits and pittfalls. </p>
</blockquote>
<p align="center"><img src="/img/posts/rally-300x187.jpg"></p>

<p>He also dismisses anyone that tries to say pairing isn’t as effective as coding
solo.</p>
<blockquote>
<p>No you’re not faster on your own, you’re just creating more crap for your
colleagues to puzzle over and eventually delete. The code you write alone
sucks. That guy that is getting on your nerves is trying to tell you
(clumsily) that your code sucks, try to listen to him and you’ll turn into a
better programmer. Or maybe you can teach him something and he’ll stop
getting on your nerves. … If you’re slowing the other guy down, that’s a good
thing. That will prevent him from writing code that you cannot maintain. If
you don’t feel worthy of your colleagues code, get over it, or get off the
team.</p>
</blockquote>
<p>My biggest stumbling block to date has been the ratio of time driving to
navigating when you’re pairing a senior and junior dev. Trying to balance
productivity and mentoring isn’t always easy. I find allowing the Sr. dev to
drive 2/3 of the time and Jr. dev to drive 1/3 strikes close to the optimal
balance. Any more driving for the Sr and you’ll lose the Jr entirely as he
rides along for the tour. Any less and you lose valuable time in
guiding-by-doing.</p>
<p>Whether you’re the driver or navigator, take your role seriously. Share in the
responsibility and help foster a mutual respect for the other. </p>
<!-- Originally posted at http://www.mike-griffith.com/blog/2010/05/rally-pairing/ -->]]></content:encoded>
    </item>
    <item>
      <title>Show Me the $80 Million Blue</title>
      <link>http://techscapades.com/blog/2010/03/18/show-me-the-80-million-blue</link>
      <pubDate>Thu, 18 Mar 2010 12:00:00 EDT</pubDate>
      <category><![CDATA[Testing]]></category>
      <guid isPermaLink="true">http://techscapades.com/blog/2010/03/18/show-me-the-80-million-blue</guid>
      <description>Show Me the $80 Million Blue</description>
      <content:encoded><![CDATA[<p>There's a lot of buzz today about a color change on Bing's website.  So what
exactly does this
<a href="http://www.lukew.com/ff/entry.asp?1025">fancy shade of blue that made Bing so much money</a>
actually look like?</p>
<div style="border: 1px solid #888888;background-color: #0044cc;width: 150px;height: 50px;">&nbsp;</div>

<p>Eh. Doesn't really do it for me as a blob of color.</p>
<p>How about <a style="color: #0044cc;" href="javascript:void(0);">on a link</a>?
Well, that is actually quite pleasant against a white background.</p>
<p>Regardless, the takeaway from the whole story isn't that you should switch your
site pallette to #0044cc, but rather that you need to rigorously test your own
audience and be able to make changes based on the observed behavior.</p>
<p>Having the discipline to measure, quantify, and carefully react can and will
drive success.  Watch and listen to your users, it really is amazing how much
information they'll give you.</p>
<!-- Originally posted at http://www.mike-griffith.com/blog/2010/03/show-me-the-80-million-dollar-blue-0044cc/ -->]]></content:encoded>
    </item>
    <item>
      <title>VIM Tip Leave Python Comments Indented</title>
      <link>http://techscapades.com/blog/2009/05/15/vim-tip-leave-python-comments-indented</link>
      <pubDate>Fri, 15 May 2009 12:00:00 EDT</pubDate>
      <category><![CDATA[Linux]]></category>
      <guid isPermaLink="true">http://techscapades.com/blog/2009/05/15/vim-tip-leave-python-comments-indented</guid>
      <description>VIM Tip Leave Python Comments Indented</description>
      <content:encoded><![CDATA[<p>If you're ever been annoyed by VIM throwing your cursor to the left margin when
you type the pound key ("#") in a python file, there's a simple remedy. </p>
<div class="pygments_murphy"><pre><span class="p">:</span>inoremap # <span class="k">X</span><span class="p">&lt;</span>C<span class="p">-</span>H<span class="p">&gt;</span>#
</pre></div>

<p>It's the fault of "smartindent" in VIM, which in reality isn't all that smart.
If you want to leave smartindent on but fix the weird hash/pound behavior,
throw the prior statement in your <code>$HOME/.vimrc</code>.</p>
<p>See <a href="http://vim.wikia.com/wiki/Restoring_indent_after_typing_hash">http://vim.wikia.com/wiki/Restoring_indent_after_typing_hash</a></p>
<p><a name="comments"></a><h2>2 Responses</h2> </p>
<p><ol class="commentlist"> </p>
<p><li class="graybox"> 
   <a name="comment-1260"></a><cite>Jonathan</cite> Says:<br /> 
   <!--<small class="commentmetadata"><a href="#comment-1260" title="Monday, February 22nd, 2010 at 11:44 pm"></a> after publication. </small>--> 
   <small class="commentmetadata"><a href="#comment-1260" title="">February 22nd, 2010 at 11:44 pm</a> </small> </p>
<p><p>But the question is, <i>why</i> would you want to leave smartindent on when editing python (or anything for that matter)? I&#8217;m sure an indent feature with a few hard-coded rules for C-like languages was awesome back in the &#8217;80s ;P but we&#8217;ve moved on since then. Vim has real python specific indentation support, which is actually intelligent and actually tailored to the language in question.</p> 
<p>Just put &#8220;filetype plugin indent on&#8221; in your vimrc and make sure smartindent is off (it interferes with filetype indentation). Leaving autoindent on can be nice for consistent formatting in comments (it just carries the previous line&#8217;s indentation to a new line, if the python indentation support doesn&#8217;t override it because you just entered a new code block).</p> 
<p>You&#8217;ll also want to setup your PEP8-friendly softtabstop, shiftwidth, expandtab, smarttab, etc. settings. I&#8217;d recommend doing that inside a .vim/ftplugin/python/pep8.vim file, which will be auto-loaded anytime you edit a python language file.</p> 
<p>You could stick a &#8220;setlocal nosmartindent&#8221; in that pep8.vim file if you wanted to keep smartindent on for everything except python, but I think you&#8217;ll find that vim&#8217;s filetype indentation will have support for and be superior to smartindent for nearly every language around.</p> </p>
<p></li> </p>
<p><li class=""> 
   <a name="comment-1332"></a><cite><a href='http://www.mike-griffith.com' rel='external nofollow' class='url'>Mike</a></cite> Says:<br /> 
   <!--<small class="commentmetadata"><a href="#comment-1332" title="Wednesday, February 24th, 2010 at 12:07 am"></a> after publication. </small>--> 
   <small class="commentmetadata"><a href="#comment-1332" title="">February 24th, 2010 at 12:07 am</a> </small> </p>
<p><p>Jonathan: Thanks for the thorough reply!</p> 
<p>The only value I seem to get from  smartindent is what you mentioned &#8212; the comment formatting (which admittedly is still hokey, even with this kludge).</p> 
<p>I did already have the <code>filetype plugin indent on</code>, but had the softtabstop/shiftwidth/etc. inline in the .vimrc, rather than externalized in <code>ftplugin/python.vim</code></p> 
<p>Looks like it&#8217;s time to clean up my .vimrc.</p> </p>
<p></li> </p>
<p></ol> </p>
<!-- originally posted at http://www.mike-griffith.com/blog/2009/05/vim-tip-of-the-day-leave-python-comments-indented-dont-put-cursor-at-beginning-of-the-line/ -->]]></content:encoded>
    </item>
    <item>
      <title>Including External Data in Python Unit Tests</title>
      <link>http://techscapades.com/blog/2009/01/13/including-external-data-in-python-unit-tests</link>
      <pubDate>Tue, 13 Jan 2009 12:00:00 EST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Testing]]></category>
      <guid isPermaLink="true">http://techscapades.com/blog/2009/01/13/including-external-data-in-python-unit-tests</guid>
      <description>Including External Data in Python Unit Tests</description>
      <content:encoded><![CDATA[<p>Normally we prefer unit tests to be completely isolated -- wall off the
databases, network connections, and even disk I/O.  However, sometimes,
packaging sample data along with a unit test is the only way to get good
coverage, and that data normally requires disk access. If you do decide this is
necessary, you should provide that data set along side your tests.</p>
<p>Your package structure might then resemble the following:</p>
<div class="pygments_murphy"><pre>/package
  __init__.py
  module.py
  /tests
    __init__.py
    test_module.py
    /data
      data.txt
</pre></div>

<p>In your test, you’ll need to provide a relative path to the data file. To do
this, use the special <strong>file</strong> attribute of the package to provide a starting
point. This will let you know where the module lives on disk regardless of
where the package is installed.</p>
<div class="pygments_murphy"><pre><span class="c"># test_module.py</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">package.module</span> <span class="kn">import</span> <span class="n">ThingaMaBobber</span>
<span class="kn">from</span> <span class="nn">package.tests</span> <span class="kn">import</span> <span class="n">__file__</span> <span class="k">as</span> <span class="n">test_directory</span>

<p><span class="k">def</span> <span class="nf">data_dir</span><span class="p">():</span>
    <span class="k">return</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">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">test_directory</span><span class="p">),</span> <span class="s">&#39;data&#39;</span><span class="p">)</span></p>
<p><span class="k">class</span> <span class="nc">TestWhenUsingSampleData</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">setup</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">sample_data_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">data_dir</span><span class="p">(),</span> <span class="s">&#39;data.txt&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">thingamabobber</span> <span class="o">=</span> <span class="n">ThingaMaBobber</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">test_that_thingamabobber_confabulates</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sample_data_path</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
            <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">thingamabobber</span><span class="o">.</span><span class="n">confabulate</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</pre></div></p>
<p>Remember, there is a cost to doing business like this.  When your test suite
grows beyond a few thousand tests, disk IO in unit tests can make running your
entire suite painful.  Try to limit when you do this, or make these types of
tests part of your integration suite.</p>]]></content:encoded>
    </item>
    <item>
      <title>Recent SVN Commit Statistics</title>
      <link>http://techscapades.com/blog/2009/01/13/recent-svn-commit-statistics</link>
      <pubDate>Tue, 13 Jan 2009 12:00:00 EST</pubDate>
      <category><![CDATA[Subversion]]></category>
      <guid isPermaLink="true">http://techscapades.com/blog/2009/01/13/recent-svn-commit-statistics</guid>
      <description>Recent SVN Commit Statistics</description>
      <content:encoded><![CDATA[<p>Lines of code (LoC) are a historically terrible metric for software
productivity.  However, they can be used to guage the types of progress you are
making in a codebase.  Deletes are often a good thing when you're dealing with
a large legacy codebase and trying to improve.</p>
<p>Here’s a little script-fu that can help determine how many lines of code were
added vs. deleted for a single Subversion commit.</p>
<div class="pygments_murphy"><pre><span class="c">#!/bin/bash</span>
<span class="k">if</span> <span class="o">[</span> -z <span class="s2">&quot;$1&quot;</span> <span class="o">]</span>; <span class="k">then</span>
<span class="k">    </span><span class="nb">echo</span> <span class="s2">&quot;usage: $0 revision&quot;</span>
    <span class="nb">exit</span>
<span class="k">fi</span>
<span class="k"> </span>
<span class="nv">REV</span><span class="o">=</span><span class="nv">$1</span>

<p><span class="c"># Execute a svn diff on the revision, and search the output for deleted lines</span>
<span class="c"># (begin with a &#39;-&#39;, but aren&#39;t followed by another immediately),</span>
<span class="c"># and likewise with any added lines</span>
<span class="nv">DIFF</span><span class="o">=</span><span class="s2">&quot;$(svn diff -c $REV --diff-cmd=/usr/bin/diff)&quot;</span>
<span class="nv">DEL_COUNTS</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> -e <span class="s2">&quot;$DIFF&quot;</span> | egrep <span class="s1">&#39;^[-][^-]&#39;</span> | wc -lm<span class="k">)</span>
<span class="nv">ADD_COUNTS</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> -e <span class="s2">&quot;$DIFF&quot;</span> | egrep <span class="s1">&#39;^[+][^+]&#39;</span> | wc -lm<span class="k">)</span></p>
<p><span class="k">function </span>get_field <span class="o">{</span>
    <span class="c"># given an input string with 2 fields delimited by spaces, possibly with</span>
    <span class="c"># leading whitespace, return the field in the position specified.</span>
    <span class="c"># so,  <code>get_field &amp;quot;   123   45678&amp;quot; 1</code>  would return &quot;122&quot;</span>
    <span class="c"># and  <code>get_field &amp;quot;   123   45678&amp;quot; 2</code>  would return &quot;45678&quot;</span>
    <span class="nv">INPUT</span><span class="o">=</span><span class="nv">$1</span>
    <span class="nv">POSITION</span><span class="o">=</span><span class="nv">$2</span>
    <span class="nb">echo</span> <span class="nv">$INPUT</span> | sed <span class="s2">&quot;s/^[ ]<em>([0-9]</em>)[ ]<em>([0-9]</em>)/\$POSITION/g&quot;</span>
<span class="o">}</span></p>
<p><span class="nv">DEL_LINES</span><span class="o">=</span><span class="k">$(</span>get_field <span class="s2">&quot;$DEL_COUNTS&quot;</span> 1<span class="k">)</span>
<span class="nv">DEL_CHARS</span><span class="o">=</span><span class="k">$(</span>get_field <span class="s2">&quot;$DEL_COUNTS&quot;</span> 2<span class="k">)</span></p>
<p><span class="nv">ADD_LINES</span><span class="o">=</span><span class="k">$(</span>get_field <span class="s2">&quot;$ADD_COUNTS&quot;</span> 1<span class="k">)</span>
<span class="nv">ADD_CHARS</span><span class="o">=</span><span class="k">$(</span>get_field <span class="s2">&quot;$ADD_COUNTS&quot;</span> 2<span class="k">)</span></p>
<p><span class="nb">echo</span> <span class="s2">&quot;Removed $DEL_LINES lines ($DEL_CHARS characters)&quot;</span>
<span class="nb">echo</span> <span class="s2">&quot;Added $ADD_LINES lines ($ADD_CHARS characters)&quot;</span>
</pre></div></p>
<p>Save this as <code>$HOME/bin/svnstat</code>, then execute it passing in a revision, e.g. <code>$ svnstat 1001</code></p>
<div class="pygments_murphy"><pre>$ svnstat 61765
Removed 113 lines (4913 characters)
Added 63 lines (2975 characters)
</pre></div>

<p>If you want to then see your daily net lines of code, hook this up to an <code>egrep</code>'d <code>svn log</code>, piped into <code>xargs</code>.</p>
<p><strong>Update 1/13/2010:</strong>
I cleaned up the “get_field” function to use a single sed command with
backreferences rather than piping the string through tr, sed, and cut.</p>
<p>Also updated the initial calculation of DIFF_COUNTS and ADD_COUNTS to only
require 1 single svn diff execution. Used echo -e to solve the newline issue I
was having on a first failed attempt.</p>
<!-- originally posted at http://www.mike-griffith.com/blog/2010/01/recent-svn-commit-statistics/ -->]]></content:encoded>
    </item>
    <item>
      <title>Python Multiline Regex</title>
      <link>http://techscapades.com/blog/2009/01/13/python-multiline-regex</link>
      <pubDate>Tue, 13 Jan 2009 12:00:00 EST</pubDate>
      <category><![CDATA[Python]]></category>
      <guid isPermaLink="true">http://techscapades.com/blog/2009/01/13/python-multiline-regex</guid>
      <description>Python Multiline Regex</description>
      <content:encoded><![CDATA[<p>After pulling most of my hair out, I realized a simple mistake in my Python regular expression usage. I had been trying to search a simple HTML document for some text, which happened to be broken across a newline such as:</p>
<div class="pygments_murphy"><pre>  <span class="nt">&lt;div&gt;</span>I&#39;m some
               fancy text that needs
               to be found<span class="nt">&lt;/div&gt;</span>
</pre></div>

<p>I tried my very simple pattern match using the re.MULTILINE flag to no avail. The solution ended up being:</p>
<div class="pygments_murphy"><pre>  <span class="kn">import</span> <span class="nn">re</span>
  <span class="n">pattern</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">&#39;some\s*fancy&#39;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">DOTALL</span><span class="p">)</span>
  <span class="n">match</span> <span class="o">=</span> <span class="n">pattern</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">input_text</span><span class="p">)</span>
</pre></div>

<p>re.MULTILINE is not the same as re.DOTALL. Use DOTALL if you want your dot to match everything, including new lines. See more at this handy dandy reference site.</p>
<p>Doh!</p>
<p><a name="comments"></a><h2>4 Responses</h2> </p>
<p><ol class="commentlist"> </p>
<p><li class="graybox"> 
   <a name="comment-595"></a><cite>Tom L</cite> Says:<br /> 
   <!--<small class="commentmetadata"><a href="#comment-595" title="Sunday, February 14th, 2010 at 11:34 am"></a> after publication. </small>--> 
   <small class="commentmetadata"><a href="#comment-595" title="">February 14th, 2010 at 11:34 am</a> </small> </p>
<p><p>Thanks, Mike.  I was trying re.MULTILINE over and over wondering what I was missing.</p> 
<p>And google found your post.  Bless you.</p> </p>
<p></li> </p>
<p><li class=""> 
   <a name="comment-2898"></a><cite>Steve</cite> Says:<br /> 
   <!--<small class="commentmetadata"><a href="#comment-2898" title="Monday, March 15th, 2010 at 3:39 pm"></a> after publication. </small>--> 
   <small class="commentmetadata"><a href="#comment-2898" title="">March 15th, 2010 at 3:39 pm</a> </small> </p>
<p><p>Ditto. Thanks!</p> </p>
<p></li> </p>
<p><li class="graybox"> 
   <a name="comment-4084"></a><cite>Etan</cite> Says:<br /> 
   <!--<small class="commentmetadata"><a href="#comment-4084" title="Saturday, March 27th, 2010 at 8:20 am"></a> after publication. </small>--> 
   <small class="commentmetadata"><a href="#comment-4084" title="">March 27th, 2010 at 8:20 am</a> </small> </p>
<p><p>many thanks guy!</p> </p>
<p></li> </p>
<p><li class=""> 
   <a name="comment-6029"></a><cite>Egon</cite> Says:<br /> 
   <!--<small class="commentmetadata"><a href="#comment-6029" title="Wednesday, September 1st, 2010 at 1:47 pm"></a> after publication. </small>--> 
   <small class="commentmetadata"><a href="#comment-6029" title="">September 1st, 2010 at 1:47 pm</a> </small> </p>
<p><p>Many thanks!<br /> 
Good example, good explanation.</p> </p>
<p></li> </p>
<p></ol> </p>]]></content:encoded>
    </item>
  </channel>
</rss>

