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

<channel>
	<title>Mental Pandiculation</title>
	<atom:link href="http://mentalpandiculation.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mentalpandiculation.com</link>
	<description>One Man's Attempt To Find Elegant Code Through Big Words</description>
	<lastBuildDate>Mon, 05 Mar 2012 22:48:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Testing A Rails and Backbone App with Jasmine &#8211; Part 1 (of possibly 1 parts so far)</title>
		<link>http://mentalpandiculation.com/2012/03/testing-a-rails-and-backbone-app-with-jasmine-part-1-of-possibly-1-parts-so-far/</link>
		<comments>http://mentalpandiculation.com/2012/03/testing-a-rails-and-backbone-app-with-jasmine-part-1-of-possibly-1-parts-so-far/#comments</comments>
		<pubDate>Mon, 05 Mar 2012 22:48:48 +0000</pubDate>
		<dc:creator>Niklaus Wirth's Ghost</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[backbone]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://mentalpandiculation.com/?p=380</guid>
		<description><![CDATA[I&#8217;ve been playing around with Backbone.js in my Rails work but I haven&#8217;t gotten around to testing the Backbone code until today. There are quite a few tutorials out there but my basic setup took some digging around and I thought I&#8217;d document the steps I took to get a brand new Rails app in [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing around with <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> in my Rails work but I haven&#8217;t gotten around to testing the Backbone code until today.  There are quite a few tutorials out there but my basic setup took some digging around and I thought I&#8217;d document the steps I took to get a brand new Rails app in a state where I could test the JavaScript code I&#8217;m writing.</p>
<p>My application is going to be an ESPN Headline browser essentially using the <a href="http://developer.espn.com/">ESPN Developer API</a>.  This API really isn&#8217;t very interesting in that it gives about zero useful information to non-paying developers but there isn&#8217;t much I can do about that.  If you want to follow along, you&#8217;ll need to request an API key from ESPN.  This first part doesn&#8217;t involve any actual calls to ESPN so you can skip that step for now.  All the code for this app is up on <a href="https://github.com/osiris43/espn_api_toy">Github</a>.   </p>
<p>I&#8217;m using the Rails 3.1.3 and the lastest Jasmine code.  The first thing you need to do is install the jasmine gem by adding it to your Gemfile</p>
<pre class="brush: ruby; title: ; notranslate">group :test do
  gem 'jasmine'
end</pre>
<p>Once that&#8217;s done, run &#8220;bundle install&#8221;.</p>
<p>There is some jasmine initialization that needs to happen once the gem has been installed so run &#8220;bundle exec jasmine init&#8221;.  This will create configuration files for jasmine as well as some sample tests and javascript that you can safely delete.  At the time of publication of this post, Jasmine seems to still be expecting an earlier version of Rails because the generated code ends up in the &#8220;public&#8221; folder and the configuration files all reference that generated code.  If you&#8217;re using Rails 3.1.3 and the new asset folders, you just need to update the jasmine.yml file in spec/javascripts/support to reference those folders.  More on that in a minute.</p>
<p>Once we have the gem installed, we can write our first test.  I&#8217;m following the convention of <a href="https://github.com/froots/backbone-jasmine-examples">this guy</a> and arranging my test code into spec/javascripts/** and my javascript into app/assets/javascripts/** where ** will match models, collections, views, etc.  Fire up the Jasmine test runner by executing:</p>
<pre class="brush: ruby; title: ; notranslate">rake jasmine</pre>
<p>and then hit localhost:8888 in your browser.  You should see something like this:</p>
<p><a href="http://mentalpandiculation.com/2012/03/testing-a-rails-and-backbone-app-with-jasmine-part-1-of-possibly-1-parts-so-far/initialtests1/" rel="attachment wp-att-406"><img src="http://mentalpandiculation.com/wp-content/uploads/2012/03/initialtests1-1024x625.png" alt="" title="initialtests1" width="1024" height="625" class="alignnone size-large wp-image-406" /></a></p>
<p>Those five tests are the sample ones that Jasmine created.  A conscientious developer would delete those but I&#8217;m lazy.  Plus, it makes me feel better that five tests already pass.  Now, we&#8217;re ready to write our first test.  I created Headline.spec.js in spec/javascripts/models to contain the test code for my Headline Backbone model.  </p>
<pre class="brush: jscript; title: ; notranslate">describe(&quot;Headline model&quot;, function () {
  beforeEach(function() {
    this.headline = new Headline({
      headline: &quot;My Headline&quot;,
      description: &quot;a description&quot;,
      source: &quot;ESPN News&quot;,
      byline: &quot;Brett Bim&quot;
    });
  });

  describe(&quot;when instantiated&quot;, function() {
    it(&quot;exhibits the attributes&quot;, function() {
      expect(this.headline.get(&quot;headline&quot;)).toEqual(&quot;My Headline&quot;);
    });
  });

});</pre>
<p>This is a really basic test that in actuality is testing Backbone functionality more than code but it&#8217;s a good first starting point to make sure everything is set up correctly.  Refresh localhost:8888 and you&#8217;ll find out it&#8217;s not.</p>
<p><a href="http://mentalpandiculation.com/2012/03/testing-a-rails-and-backbone-app-with-jasmine-part-1-of-possibly-1-parts-so-far/firstfail/" rel="attachment wp-att-427"><img src="http://mentalpandiculation.com/wp-content/uploads/2012/03/firstfail-1024x268.png" alt="" title="firstfail" width="1024" height="268" class="alignnone size-large wp-image-427" /></a></p>
<p>As you can see, Headline is not defined which is expected given that we haven&#8217;t defined it yet.  Let&#8217;s do that now.  Create Headline.js in app/assets/javascripts/models and add this code to it:</p>
<pre class="brush: jscript; title: ; notranslate">var Headline = Backbone.Model.extend();</pre>
<p>This creates our model.  Save the file and refresh localhost:8888.  Surprisingly, you get the same failed test.  This is because the Jasmine gem does not automatically reflect the asset structure from Rails 3.1.3.  You need to explicitly specify where your files are.  You can do this by going to spec/javascripts/support and opening the jasmine.yml file.  There is a section for source files.  You need to tell it where your source files are and add references to backbone.js and underscore.js as well.</p>
<pre class="brush: bash; title: ; notranslate">src_files:
  - public/javascripts/prototype.js
  - public/javascripts/effects.js
  - public/javascripts/controls.js
  - public/javascripts/dragdrop.js
  - app/assets/javascripts/underscore.js
  - app/assets/javascripts/backbone.js
  - public/javascripts/application.js
  - public/javascripts/**/*.js
  - app/assets/javascripts/**/*.js</pre>
<p>I&#8217;ve added the three lines pointing to app/assets which will inform Jasmine where to find those files.  Once that&#8217;s done and the file is saved, we can refresh localhost:8888 again.</p>
<p><a href="http://mentalpandiculation.com/2012/03/testing-a-rails-and-backbone-app-with-jasmine-part-1-of-possibly-1-parts-so-far/finaltests/" rel="attachment wp-att-428"><img src="http://mentalpandiculation.com/wp-content/uploads/2012/03/finaltests-1024x78.png" alt="" title="finaltests" width="1024" height="78" class="alignnone size-large wp-image-428" /></a></p>
<p>And our first test passes.  We should now have Jasmine up and running for testing all our Backbone code.  Stay tuned for another episode of &#8220;One Post Every 8 Months About Random Crap&#8221; where we discuss writing tank driving software using Lisp.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentalpandiculation.com/2012/03/testing-a-rails-and-backbone-app-with-jasmine-part-1-of-possibly-1-parts-so-far/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Confusing The Perfect With Progress</title>
		<link>http://mentalpandiculation.com/2011/06/confusing-the-perfect-with-progress/</link>
		<comments>http://mentalpandiculation.com/2011/06/confusing-the-perfect-with-progress/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 23:31:03 +0000</pubDate>
		<dc:creator>Niklaus Wirth's Ghost</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://mentalpandiculation.com/?p=364</guid>
		<description><![CDATA[One thing that I constantly suffer from is letting the concept of perfection keep me from making progress on something. This happens not only in my software development but in my writing, my gardening, my golf game, almost everything. I have no idea how this came to be but it seems to be a pervasive [...]]]></description>
			<content:encoded><![CDATA[<p>One thing that I constantly suffer from is letting the concept of perfection keep me from making progress on something.  This happens not only in my software development but in my writing, my gardening, my golf game, almost everything.  I have no idea how this came to be but it seems to be a pervasive element of my flawed character.  I have found that it&#8217;s important to constantly focus on identifying when I&#8217;m trying to hard for the perfect.  Progress, even negative progress, is almost always better than paralysis.  I don&#8217;t seem to be alone in this characteristic.  Take for example <a href="http://www.garann.com/dev/2011/separation-of-concerns-is-a-bunch-of-bull/">this post</a> that is arguing, albeit in an extremely conflicted way, that the concept of <a href="http://en.wikipedia.org/wiki/Separation_of_concerns">Separation of Concerns</a> in software development is useless because a perfect Separation of Concerns is impossible.</p>
<p>Anyone who says that a system must display perfect separation of concerns has either never written any large-scale software systems or is certifiable and can safely be ignored.  The goal of writing software isn&#8217;t to produce perfect separation of concerns.  That is only one of many possible means to get to the end result of long term maintainable software that produces some quantity of value.  Writing any meaningful software without an eye on SoC results in a jumbled morass of unmaintainable and untestable crap.  Does this mean that your HTML views should be completely dumb, devoid of logic?  Of course not and no one with any real world experience would argue that.  But if you don&#8217;t constantly strive to keep them as dumb as possible, you will end up with junk.  It must be a constant focus, one that is in the forefront of every decision because if it is not, it is always easier to do what is wrong than what is right.</p>
<p>When I first read <em>Atlas Shrugged</em>, I was enthralled with the concept and philosophy behind the novel, that selfishness was inherently good and that every action should be judged based on one&#8217;s own self interest.  Of course, I was 16 and frankly, the philosophy fit nicely into a 16 year old&#8217;s limited world view.  As I got older, I began to realize that while acting in self interest as a general rule is good, taking it to the extremes that Objectivist philosophy did will result in a terribly narcissistic life.  </p>
<p>The same thing happened when when I first discovered design patterns.  Everything was a Factory.  I loved Factories.  Concrete Factories, Abstract Factories, <a href="http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12">Factory Factories</a>, by God they were all fantastic.  But slowly over time, I learned not every thing was a Factory and not every thing fit neatly into design patterns.  But as a guiding rule, design patterns are good but it&#8217;s just as important to know when to not use one as it is to use one.  </p>
<p>Separation of Concerns is the same.  As an overall guiding principle, it is critically important.  There are going to be times when ignoring it is in fact the right decision but those times are very few and far between and you better have a damn good reason for doing it.  But not doing it because it&#8217;s never going to be possible to have a perfect separation isn&#8217;t one of those reasons.  </p>
]]></content:encoded>
			<wfw:commentRss>http://mentalpandiculation.com/2011/06/confusing-the-perfect-with-progress/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Web Deployment Cage Fight &#8211; 2002 versus 2011</title>
		<link>http://mentalpandiculation.com/2011/06/web-deployment-cage-fight-2002-versus-2011/</link>
		<comments>http://mentalpandiculation.com/2011/06/web-deployment-cage-fight-2002-versus-2011/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 19:01:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Heroku]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Zerigo]]></category>

		<guid isPermaLink="false">http://mentalpandiculation.com/?p=354</guid>
		<description><![CDATA[When I first started doing web development with Visual Studio 2005, it was pretty painful work. Not only was the development itself difficult in many ways (if I say &#8220;typed DataSet&#8221; and &#8220;bloodthirsty bedbugs&#8221;, which makes you cringe more?) but the deployment of sites was often a long, tedious manual process for a site of [...]]]></description>
			<content:encoded><![CDATA[<p>When I first started doing web development with Visual Studio 2005, it was pretty painful work.  Not only was the development itself difficult in many ways (if I say &#8220;typed DataSet&#8221; and &#8220;bloodthirsty bedbugs&#8221;, which makes you cringe more?) but the deployment of sites was often a long, tedious manual process for a site of any size.  I distinctly remember having to log into my hosting provider, upload a zip file or collection of files, manually unzip or move them around and then hope that everything and the stars were lined up properly.  Microsoft tried to make things easier with the Publish technology from Visual Studio but that never worked particularly seamlessly, at least not in my limited experience.  On top of all that, it required considerable discipline (and a kickass source control which I&#8217;m not sure existed) if you wanted to deploy certain changes but not others.</p>
<p>Take a quantum leap forward into 2011.  Over the last 3.5 days, I built a website to serve as my central home on the web, a place where I can aggregate my work, writing and other activities easily.  I built the site in Rails, used git for source control and when it came time to deploy the site, <a href="http://www.heroku.com">Heroku</a> for the hosting.  To deploy my site, I had to do to things:
<pre class="brush: bash; title: ; notranslate">heroku create</pre>
<p> and
<pre class="brush: plain; title: ; notranslate">git push heroku master</pre>
<p>  When that was done, I had a live, working test site on the internet that I could test in multiple browsers, get feedback on, etc.  When I was ready to redirect my current home on the web to the new one, all I had to do was add a custom domain and Zerigo DNS add-on at Heroku, update my nameservers and presto chango, the production site was up and running.</p>
<p>On top of that, because branches are so painless and easy in git, I can create a new branch, work on it, merge it with the master and update the site all from the command line of my laptop.  The idea of having to log into a hosting provider to upload files suddenly feels like waterboarding.  If you have a significant test suite, it&#8217;s a matter of having your tests pass and then just updating your production site.  Obviously, as a site grows, it won&#8217;t be quite that easy but it&#8217;s not going to get that much harder either.  </p>
<p>The smart folks at Heroku have removed some of the major obstacles to web development so we can focus more on writing the code now and less on the administrative agony.  On top of all that, for small sites like mine, the cost is negligible or non-existent.  Lots of things aren&#8217;t better in 2011 than they were in 2002 (the world&#8217;s going to end next year) but web deployment, if you choose the right tools, is infinitely better in a way that&#8217;s almost inexpressible.  </p>
]]></content:encoded>
			<wfw:commentRss>http://mentalpandiculation.com/2011/06/web-deployment-cage-fight-2002-versus-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Technical Debt Is Johnny Cash&#8217;s Cadillac Of Software</title>
		<link>http://mentalpandiculation.com/2011/03/technical-debt-is-johnny-cashs-cadillac-of-software/</link>
		<comments>http://mentalpandiculation.com/2011/03/technical-debt-is-johnny-cashs-cadillac-of-software/#comments</comments>
		<pubDate>Mon, 28 Mar 2011 02:22:48 +0000</pubDate>
		<dc:creator>Niklaus Wirth's Ghost</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[technical debt]]></category>

		<guid isPermaLink="false">http://mentalpandiculation.com/?p=331</guid>
		<description><![CDATA[For those of you who aren&#8217;t country music fans, Johnny Cash sings about working in the the GM plant and building a Caddy one piece at a time by bringing the pieces home in his lunch pail over a number of years. In the end, he puts the car together and while he has a [...]]]></description>
			<content:encoded><![CDATA[<p><iframe title="YouTube video player" width="480" height="390" src="http://www.youtube.com/embed/sIuo0KIqD_E" frameborder="0" allowfullscreen></iframe></p>
<p>For those of you who aren&#8217;t country music fans, Johnny Cash sings about working in the the GM plant and building a Caddy one piece at a time by bringing the pieces home in his lunch pail over a number of years.  In the end, he puts the car together and while he has a functioning, hot-rod Cadillac, it&#8217;s a bit, how shall we say, bolted together with duct tape and bailing wire.  I can only imagine what it would be like to perform repairs on a car that&#8217;s built from a variety of parts over 10 or 15 years.  It seems like a far fetched system but in the software world, it&#8217;s exactly what you get in a system that ignores technical debt over time to focus on delivery of features.</p>
<p>There&#8217;s been <a href="http://www.m3p.co.uk/blog/2010/07/23/bad-code-isnt-technical-debt-its-an-unhedged-call-option/">some</a> <a href="http://blog.jayfields.com/2011/03/types-of-technical-debt.html">writing</a> lately on metaphors for technical debt which has caused me to think about what it means to have bad, messy, untested code in a system of any size.  I think the idea of Johnny&#8217;s Caddy is an excellent metaphor for explaining both what technical debt is and how it affects the functionality and maintainability of a system.  When you have three headlights and no tail fins, the car still runs but it&#8217;s a little odd looking.  But when you try to dig into the guts and replace a &#8217;52 carburetor bolted onto a a &#8217;62 intake manifold, you&#8217;re going to have to have extremely specialized system knowledge about the car you are working on.  If the original mechanic gets hit by a bus, the new guy can&#8217;t go to AutoZone and pick up a &#8217;49, &#8217;50, &#8217;51, &#8217;52, &#8217;53, &#8217;54, &#8217;55, &#8217;56, &#8217;57, &#8217;59 Caddy manual.  </p>
<p>The same thing holds true for a system that&#8217;s been continually extended over a number of years to do more and more things for its users.  If the code is never revisited to make it more maintainable or flexible and if it was originally written without consideration for future changes, the system becomes brittle and difficult to understand.  Without a manual (either the domain knowledge of the original system builders or tests to protect developers from unintended consequences), modifying the system can become rather hazardous.  Over time, if no attempts are made to bring the code into some semblance of normalcy, the system can even get to the point where it can&#8217;t be changed for fear of the <a href="http://chadfowler.com/2011/03/17/leaving-a-legacy-system">consequences</a>.</p>
<p>One thing to keep in mind, technical debt is a sign of success.  Without the continual driver of success, systems don&#8217;t evolve to the point of having technical debt.  But it&#8217;s important to always be aware of the debt, of its force and effect on the flexibility and maintainability of the system.  Without constant attention, eventually the system becomes fragile and unstable, breaking unexpectedly when changes are made to seemingly unrelated sections of the app.  Without some sort of design, either architectural through an initial design phase or protective through the use of solid tests, the system development is likely to eventually come to a slow halt because of the interrelatedness of the pieces.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentalpandiculation.com/2011/03/technical-debt-is-johnny-cashs-cadillac-of-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why I Don&#8217;t Hang Out With People Named David</title>
		<link>http://mentalpandiculation.com/2011/03/why-i-dont-hang-out-with-people-named-david/</link>
		<comments>http://mentalpandiculation.com/2011/03/why-i-dont-hang-out-with-people-named-david/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 22:18:15 +0000</pubDate>
		<dc:creator>Niklaus Wirth's Ghost</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Satire]]></category>

		<guid isPermaLink="false">http://mentalpandiculation.com/?p=334</guid>
		<description><![CDATA[As many of you know, I like to hang out with cool people. I go out of my way to search my iPhone phone book for cool people to hang out with. Sometimes, my mom even sends me the email of random children in my general cohort of people she knows so that I might [...]]]></description>
			<content:encoded><![CDATA[<p>As many of you know, I like to hang out with cool people.  I go out of my way to search my iPhone phone book for cool people to hang out with.  Sometimes, my mom even sends me the email of random children in my general cohort of people she knows so that I might randomly email them and hang out with them.  Seriously, I like cool people.  And my main criterion for whether or not people are cool is really simple: Is this someone I&#8217;d really want to hang out with?</p>
<p>And really, the only criterion of coolness worth checking out is &#8220;Are they named David?&#8221;  </p>
<p>Now let me clarify: people named David are nifty.  They pay their bills, don&#8217;t beat their wives, drink something other than Mickey&#8217;s Malt Liquor and generally are normal human beings.  But you see, being named David is a choice and whenever anyone voluntarily keeps David as their name, I have to ask &#8220;Why?&#8221;</p>
<p>Don&#8217;t get me wrong, being named David isn&#8217;t an instant showstopper for being cool.  It&#8217;s just that lots of people I&#8217;ve known that were named David just weren&#8217;t cool which is best explained by a really bad simile: Being named David is like being David Hasselhoff.</p>
<p><iframe title="YouTube video player" width="480" height="390" src="http://www.youtube.com/embed/PJQVlVHsFF8" frameborder="0" allowfullscreen></iframe><br />
Being David Hasselhoff is awesome if you want to be a world famous cult figure who goes to awesome parties, sings great songs on YouTube and was once the star of a kick-ass show called Knight Rider with a bad ass car that talked to him and saved him from bad guys.  But if you want to be in independent films with Natalie Portman, you can&#8217;t because Natalie Portman doesn&#8217;t hang out in Cannes with David Hasselhoff.  If you want to win Academy Awards, you can&#8217;t because David Hasselhoff doesn&#8217;t win Academy Awards.  In short, if you want to do anything that doesn&#8217;t involve being David Hasselhoff, you can&#8217;t because you ARE David Hasselhoff.</p>
<p>See, by being David Hasselhoff, he can&#8217;t be in independent films.  Well he could be but that doesn&#8217;t really fit in my story line.  Therefore, because David Hasselhoff can&#8217;t be in independent films with Natalie Portman (even though he can be, it&#8217;s not important, try to forget I pointed that flaw in my storyline out, OH LOOK A CHICKEN!), then it must be true that people named David aren&#8217;t cool.</p>
<p>Instead I look for people who aren&#8217;t named David because it&#8217;s more likely that they fit closely into my weird and oddly supported worldview that people named David can&#8217;t be cool.  I don&#8217;t want someone named David, I want someone named not David.  </p>
<p>Just by being named David, your chances of being cool are practically zero and thus, I&#8217;d rather have hung out with you after you took a long nap.  </p>
<p>So what&#8217;s the moral of this whole ridiculously overgeneralized and poorly thought out story? Two things:</p>
<blockquote><p>
  1. If you want to hang out with me, avoid being named David.  Unless you&#8217;re David Hasselhoff, it does you no favors.<br />
  2. If you are someone else and you meet someone named David, take notice and immediately become suspicious. They probably aren&#8217;t David Hasselhoff and thus, not cool.
</p></blockquote>
<p>It might sound harsh, and it is (with bad punctuation usage to boot). But frankly, life is too short to live without strict black and white rules that involve sweeping over-generalizations and easy ways to get lots of people to link to your site.</p>
<p>Yes, there really is a <a href="http://blog.expensify.com/2011/03/25/ceo-friday-why-we-dont-hire-net-programmers/">point to all this</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentalpandiculation.com/2011/03/why-i-dont-hang-out-with-people-named-david/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Changing System Variables in MySQL</title>
		<link>http://mentalpandiculation.com/2011/02/changing-system-variables-in-mysql/</link>
		<comments>http://mentalpandiculation.com/2011/02/changing-system-variables-in-mysql/#comments</comments>
		<pubDate>Fri, 18 Feb 2011 22:55:22 +0000</pubDate>
		<dc:creator>Niklaus Wirth's Ghost</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[mac dev]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://mentalpandiculation.com/?p=329</guid>
		<description><![CDATA[Lots of fun today, dealing with what feels like the innards of MySQL but probably just barely scratches the epidermis. What I did learn today though was how to set MySQL system variables using a configuration file on Mac OSX. I figure that this will come up again and I&#8217;ll have to learn it all [...]]]></description>
			<content:encoded><![CDATA[<p>Lots of fun today, dealing with what feels like the innards of MySQL but probably just barely scratches the epidermis.  What I did learn today though was how to set MySQL system variables using a configuration file on Mac OSX.  I figure that this will come up again and I&#8217;ll have to learn it all over again unless I write it down, thus, I&#8217;m writing it down while a 22 minute query runs on the other machine.</p>
<p>Today, I needed to increase the innodb_buffer_pool_size value from the default 8MB to something useful for my purposes like 2 GB.  You can&#8217;t do that from SqlYog or from the command line as it happens to be a readonly variable.  So you need to create a configuration file.  That file lives in root directory at /etc/my.cnf.  I first tried to create this file using vi, got it all typed up and then when I saved it, was told that wasn&#8217;t going to fly, you don&#8217;t have the requisite permissions.  Stupid *nix operating system.  Not that I&#8217;m complaining but after the day I&#8217;ve had, I would have liked to have just created the file.</p>
<p>So back to the command prompt and try sudo vi my.cnf.  Lo and behold that works like a champ.  The file looked like this when I was done:<br />
[mysqld]<br />
innodb_buffer_pool_size=2G</p>
<p>Saved that, restarted the MySQL server and it had updated correctly as seen using SHOW VARIABLES;</p>
<p>Probably all very elementary stuff but for a guy who prefers not to get his hands dirty with database stuff, good to know for the future.  Also learned about profiling which you can enable in a script in SqlYog with a SET profiling=1; at the beginning of your script and a SHOW profiles; at the end.  </p>
]]></content:encoded>
			<wfw:commentRss>http://mentalpandiculation.com/2011/02/changing-system-variables-in-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learning Rails (and a little Ruby)</title>
		<link>http://mentalpandiculation.com/2011/01/learning-rails-and-a-little-ruby/</link>
		<comments>http://mentalpandiculation.com/2011/01/learning-rails-and-a-little-ruby/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 02:47:29 +0000</pubDate>
		<dc:creator>Niklaus Wirth's Ghost</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[thinking out loud]]></category>

		<guid isPermaLink="false">http://mentalpandiculation.com/?p=324</guid>
		<description><![CDATA[As with most of my endeavors, I suddenly decided last week out of the blue that I needed to write a web site in Rails. I don&#8217;t really recall the thought process (which should tell you there wasn&#8217;t any) that led to this decision but given the fact that I didn&#8217;t know either Rails or [...]]]></description>
			<content:encoded><![CDATA[<p>As with most of my endeavors, I suddenly decided last week out of the blue that I needed to write a web site in Rails.  I don&#8217;t really recall the thought process (which should tell you there wasn&#8217;t any) that led to this decision but given the fact that I didn&#8217;t know either Rails or Ruby past what I had learned writing WATIR scripts, I knew I needed to find a good tutorial.  I reached out to my extensive (read: 82 followers) Twitter network and was pointed towards the <a href="http://railstutorial.org">Rails Tutorial</a> by <a href="http://twitter.com/#!/hkarthik">Karthik</a>.  Over the past 5 days, I&#8217;ve been spending a significant amount of time on learning Rails and I have to say that I have no idea why it took me this long to come around to trying it.</p>
<p>Quite awhile back, I dove into learning Python and the Pylons web framework and for the most part, I was happy with it.  I never deployed an app using Pylons but my Python skills got to be where I could at least make things work.  I enjoy the Python language but I always felt like testing was a second class citizen to a large degree.  Maybe I just never read the right tutorial but tests and deployment seemed to be an afterthought.  In Python&#8217;s defense, it never seemed to have the &#8220;cool kids&#8221; momentum like Ruby/Rails.  And Pylons certainly has different goals than Rails given the fact that Pylons gives you some defaults but let&#8217;s you do what you want whereas Rails has the Rails Way and it&#8217;s clear you stray from it at your own risk.</p>
<p>But learning Pylons especially always felt like I was stabbing at zombies in the dark.  I didn&#8217;t have a good mentor other than the web and while I certainly could have read code trying to figure out best practices, I&#8217;m lazy and would at least like to have some reasonable semblance of a roadmap to guide me.  With Rails in general and the Rails Tutorial linked above specifically, the road map is more like a TomTom GPS system, giving you the steps you need to create and deploy applications in Rails right from the start.  The emphasis on testing, source control and deployment is refreshing since I imagine that being a major headache of writing a decent sized web application in a new framework.</p>
<p>The use of convention over configuration, long a selling point for Rails, is wonderful.  There are so many places over the last few days where I have compared my experience in the ASP.Net world to what I was learning in Rails and found the former terribly lacking.  As an example, in ASP.Net MVC, named routes have to be created explicitly but in Rails, many useful named routes are created for you based on convention.  </p>
<p>Another place Rails seems to have the advantage is database updates as you develop an application.  I just went through a situation where I had to manually define how a couple of people would deal with updates to a database while working concurrently on a project.  With Rails, it&#8217;s built in through the concept of migrations.  So many pieces of the plumbing that you have to deal with on normal projects is just handled.  I&#8217;m sure there are gotchas waiting to jump up and bite me but for someone first learning a framework and comparing it to other experiences in the past, it&#8217;s wonderfully refreshing to find so many pieces of the puzzle are taken care of for you.</p>
<p>On top of that, as someone who has struggled with how to coordinate programming styles and conventions on projects in the past, imagine my excitement when I learned about the Rails Way and convention over configuration.  If you just do things the Rails Way, not only are certain things taken care of for you, but you can count on Rails code being comparable across projects.  Imagine reading the open source code for a couple of ASP.net projects.  While ASP.Net MVC has certainly moved the slider bar over towards convention, chances are the two projects would have drastically different flavors.  Yet it seems to me that Rails projects would likely be reasonably similar.</p>
<p>Overall, I&#8217;m thrilled (obviously since I just ran through 700 words detailing my excitement) with Rails and the potential it has in my development toolbox.  While it&#8217;s certainly early and I&#8217;ve no doubt been excited about things in the past, it&#8217;s encouraging to feel comfortable in a framework to some degree right from the start.  Of course, major props has to go to Michael Hartl who wrote the tutorial I&#8217;m learning from.  He&#8217;s done a fantastic job of laying out a good course through the material with reasons for doing things in a particular way.  I intend to buy the screencasts once I work my way through the online book because I imagine they are filled with exactly the same kind of good teaching that is available in the book.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentalpandiculation.com/2011/01/learning-rails-and-a-little-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Word Wrap Kata in Python</title>
		<link>http://mentalpandiculation.com/2011/01/word-wrap-kata-in-python/</link>
		<comments>http://mentalpandiculation.com/2011/01/word-wrap-kata-in-python/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 00:16:12 +0000</pubDate>
		<dc:creator>Niklaus Wirth's Ghost</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[katas]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://mentalpandiculation.com/?p=318</guid>
		<description><![CDATA[Last month at Dallas Hack Club, we did the Word Wrap Kata from Uncle Bob Martin&#8217;s &#8220;Clean Coder&#8221;. I got there a touch late and rapidly figured out that we were doing it in Ruby. Now, my Ruby skills are right up there with my Mandarin Chinese skills which is to say, I can&#8217;t even [...]]]></description>
			<content:encoded><![CDATA[<p>Last month at <a href="http://dallashackclub.com/">Dallas Hack Club</a>, we did the <a href="http://thecleancoder.blogspot.com/2010/10/craftsman-62-dark-path.html">Word Wrap Kata</a> from Uncle Bob Martin&#8217;s &#8220;Clean Coder&#8221;.  I got there a touch late and rapidly figured out that we were doing it in Ruby.  Now, my Ruby skills are right up there with my Mandarin Chinese skills which is to say, I can&#8217;t even order a scotch or find the restroom so I quickly figured out that if I followed along, I&#8217;d be sitting in a puddle of pee wishing I was drunk.  So I made the executive decision to ignore most everyone else and do it in parallel with the group but in Python since I can at least code like I&#8217;m drunk in Python.  </p>
<p>My experience was surprisingly similar to the post linked above, e.g. I went down the hardest path trying to solve the wrong test.  I&#8217;ve since gone back and deleted the code but the pseudocode went something like this:</p>
<pre class="brush: python; title: ; notranslate">Break text into a list using a list comprehension based on the length of the column
Start looking for words with spaces
Try to repiece things together based on the column length and the last space
Cry
</pre>
<p>Clearly, this wasn&#8217;t going to work.  About that time, we ran out of time and went to the Flying Saucer to drink beer and pretend like we weren&#8217;t geeks.  But I decided to finish the kata this week during a slow period at work.  Since I didn&#8217;t have Jerry there to talk me through how dumb I was, I started reading the post up until the point where it describes writing the wrong test and spending too much time trying to solve it.  So I backed up, deleted everything and started down the easier path of solving all the non-space related issues first.  Once I did that, and once I figured out that recursion was going to be a big help, the project really got easier.</p>
<p>The final solution is below:</p>
<pre class="brush: python; title: ; notranslate">
def wrap(text, num):

  if len(text) &lt;= num:
    return text
  elif text[num-1] == ' ':
    return text[:num].rstrip() + '\r\n' + wrap(text[num:], num)
  elif text[:num].find(' ') &gt; -1:
    rightSpaceIdx = text.rfind(' ')
    return text[:rightSpaceIdx] + '\r\n' + wrap(text[rightSpaceIdx:].lstrip(' '), num)
  else:
    return text[:num] + '\r\n' + wrap(text[num:].lstrip(), num)
</pre>
<p>It&#8217;s fascinating how quickly the algorithm starts to come together when you write the correct test.  The problem is, I&#8217;m terrible at all this so it&#8217;s going to take some time getting enough experience to correctly select what test to write next.  I was writing a ton of code trying to solve a problem that was too hard and the solution I eventually would have come up with would have been effective but brittle.  </p>
<p>The more I do TDD/BDD, the more I realize that it is *THE* way to develop software, especially if you&#8217;re working in a dynamic language.  I&#8217;m currently working through the tutorials at <a href="http://rubytutorials.org">Ruby Tutorials</a> and it&#8217;s great to see that TDD is a fundamental part of the process.  As I learned Python and Pylons, it was up to me to figure out best practices it seemed like and that&#8217;s workable but frustrating in the long run.  I&#8217;m planning on doing more katas in an effort to improve my craft.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentalpandiculation.com/2011/01/word-wrap-kata-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Route Gotchas In Pylons</title>
		<link>http://mentalpandiculation.com/2010/12/route-gotchas-in-pylons/</link>
		<comments>http://mentalpandiculation.com/2010/12/route-gotchas-in-pylons/#comments</comments>
		<pubDate>Thu, 30 Dec 2010 21:26:29 +0000</pubDate>
		<dc:creator>Niklaus Wirth's Ghost</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Pylons]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[routes]]></category>

		<guid isPermaLink="false">http://mentalpandiculation.com/?p=310</guid>
		<description><![CDATA[I&#8217;ve been working on a Pylons app quite a bit lately and occasionally I run across issues that warrant documentation on the interwebs. That happened today concerning routes and how Pylons deals with them. If you start getting an Import error that says &#8220;No module named content found&#8221;, you&#8217;ve run into it. According to the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a Pylons app quite a bit lately and occasionally I run across issues that warrant documentation on the interwebs.  That happened today concerning routes and how Pylons deals with them.</p>
<p>If you start getting an Import error that says &#8220;No module named content found&#8221;, you&#8217;ve run into it.  According to the <a href="http://pylonsbook.com/en/1.1/urls-routing-and-dispatch.html#unnecessary-routes-features">Pylons book</a>, &#8220;Routes has a surprising legacy feature that means that if you don’t specify a controller and an action for a particular route, the implicit defaults of controller=&#8217;content&#8217; and action=&#8217;index&#8217; will be used for you&#8221;.  This is certainly surprising to me and as always, things that are implicit tend to annoy me.  Luckily, you can change this behavior.  In your config/routing.py file, set map.explicit = True and then you&#8217;ll need to alter the route that is giving you problems to make the controller and action explicit.  For example:</p>
<p>Before</p>
<pre class="brush: python; title: ; notranslate">def make_map(config):
    &quot;&quot;&quot;Create, configure and return the routes Mapper&quot;&quot;&quot;
    map = Mapper(directory=config['pylons.paths']['controllers'],
                 always_scan=config['debug'])
    map.minimization = False
    map.explicit = False 

    # The ErrorController route (handles 404/500 error pages); it should
    # likely stay at the top, ensuring it can always be resolved
    map.connect('/error/{action}', controller='error')
    map.connect('/error/{action}/{id}', controller='error')

    # CUSTOM ROUTES HERE
    map.connect('schedule_entry', 'schedule/index/{scheduleDay}')
    map.connect('/{controller}/{action}')
    map.connect('/{controller}/{action}/{id}')

    return map
</pre>
<p>As you can see, the default behavior is for map.explicit to be set to False.  The first route under CUSTOM ROUTES HERE is a named route that to my eye should match schedule up with a controller and index up with the action.  Unfortunately, instead it tries to find the default implicit controller &#8220;content&#8221; which it can&#8217;t find and that throws the ImportError listed above.  To fix it do this:</p>
<p>After</p>
<pre class="brush: python; title: ; notranslate">
def make_map(config):
    &quot;&quot;&quot;Create, configure and return the routes Mapper&quot;&quot;&quot;
    map = Mapper(directory=config['pylons.paths']['controllers'],
                 always_scan=config['debug'])
    map.minimization = False
    map.explicit = True 

    # The ErrorController route (handles 404/500 error pages); it should
    # likely stay at the top, ensuring it can always be resolved
    map.connect('/error/{action}', controller='error')
    map.connect('/error/{action}/{id}', controller='error')

    # CUSTOM ROUTES HERE
    map.connect('/schedule/index/{scheduleDay}', controller='schedule', action='index')
    map.connect('/{controller}/{action}')
    map.connect('/{controller}/{action}/{id}')

    return map
</pre>
<p>Now the map is set to explicit and the controller and action are explicitly specified which works just fine.  This all may be an artifact my novice understanding of Routes but since the book documents it this way, I guess this is the way I&#8217;m going to do it.  </p>
]]></content:encoded>
			<wfw:commentRss>http://mentalpandiculation.com/2010/12/route-gotchas-in-pylons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TDD with Pylons</title>
		<link>http://mentalpandiculation.com/2010/11/tdd-with-pylons/</link>
		<comments>http://mentalpandiculation.com/2010/11/tdd-with-pylons/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 21:01:30 +0000</pubDate>
		<dc:creator>Niklaus Wirth's Ghost</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Pylons]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://mentalpandiculation.com/?p=298</guid>
		<description><![CDATA[I&#8217;ve written about test driven development and Pylons before but there have apparently been some changes to how it all works since Pylons 1.0. I didn&#8217;t run across anything in the documentation detailing the changes, specifically to the template context global and how you access it in your tests. From the Pylons docs on testing: [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve <a href="http://mentalpandiculation.com/2009/06/tdd-with-python-and-pylons/">written about</a> test driven development and Pylons before but there have apparently been some changes to how it all works since Pylons 1.0.  I didn&#8217;t run across anything in the documentation detailing the changes, specifically to the template context global and how you access it in your tests.</p>
<p>From the <a href="http://wiki.pylonshq.com/display/pylonsdocs/Unit+Testing">Pylons docs</a> on testing:</p>
<blockquote><p>Pylons will provide several additional attributes for the paste.fixture response object that let you access various objects that were created during the web request:</p>
<ol>
<li>session &#8212; Session object</li>
<li>req &#8212; Request object</li>
<li>c &#8212; Object containing variables passed to templates</li>
<li>g &#8212; Globals object</li>
</ol>
<p>To use them, merely access the attributes of the response after you&#8217;ve used a get/post command:</p>
<pre class="brush: python; title: ; notranslate">response = app.get('/some/url')
assert response.session['var'] == 4
assert 'REQUEST_METHOD' in response.req.environ</pre>
</blockquote>
<p>As it turns out, that&#8217;s sort of true.  I have a test that looks like this:</p>
<pre class="brush: python; title: ; notranslate">from nbapowerrank.tests import *

class TestGamedetailsController(TestController):

    def test_index(self):
        response = self.app.get(url(controller='admin/gamedetails', action='index'))
        self.assertEqual(len(response.c.games) &gt; 0, True)</pre>
<p>and a controller that looks like this:</p>
<pre class="brush: python; title: ; notranslate">from nbapowerrank.lib.base import BaseController, render
from nbapowerrank.model import meta
from nbapowerrank.model.game import Game

log = logging.getLogger(__name__)

class GamedetailsController(BaseController):
  def __before__(self):
    self.game_q = meta.Session.query(Game)

  def index(self):
    yesterday = datetime.today() - timedelta(1)
    c.games = self.game_q.filter_by(gamedate=yesterday).all()

    return render('/gamedetails.mako')</pre>
<p>Unfortunately, contra the documentation that says the &#8220;c&#8221; alias will be available on the test response object, that test always fails with an AttributeError stating that in fact, the c attribute does not exist.  It frustrated me even more because all the other attributes that are supposed to be on the response like session and g were in fact there.  After doing some random digging, I came across this in the <a href="http://wiki.pylonshq.com/display/pylonscommunity/Pylons+Roadmap+to+1.0">Pylons 1.0 roadmap</a>: &#8220;Deprecate pylons.c, pylons.g, and pylons.buffet. These have been disrecommended since 0.9.7.&#8221;</p>
<p>Apparently, they are/have deprecated using the c alias for tmpl_context even though when you create a controller under Pylons 1.0, it still aliases the context as c.  Sigh.  So in order to test data that you have added to your context for templating, your test should use the explicit tmpl_context instead of the c like this:</p>
<pre class="brush: python; title: ; notranslate">from nbapowerrank.tests import *

class TestGamedetailsController(TestController):

    def test_index(self):
        response = self.app.get(url(controller='admin/gamedetails', action='index'))
        self.assertEqual(len(response.tmpl_context.games) &gt; 0, True)</pre>
<p>And then all will be well with your world.  I do have to say that compared to both ASP.Net MVC and Rails, the testing support in Python/pylons seems to be a second class citizen.  I&#8217;m not sure why that is because as a dynamic language, it seems to benefit greatly from a TDD approach.  Maybe it&#8217;s just me getting back into a framework after a year&#8217;s worth of changes.</p>
<p>Anyway, that may help some people out there trying to search in the googleplex about TDD and Pylons.</p>
]]></content:encoded>
			<wfw:commentRss>http://mentalpandiculation.com/2010/11/tdd-with-pylons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

