<?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>pko.ch</title>
	<atom:link href="http://pko.ch/feed/" rel="self" type="application/rss+xml" />
	<link>http://pko.ch</link>
	<description>Reflections about reflection</description>
	<lastBuildDate>Sun, 29 Jan 2012 23:45:23 +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>Taming git</title>
		<link>http://pko.ch/2012/01/28/taming-git/</link>
		<comments>http://pko.ch/2012/01/28/taming-git/#comments</comments>
		<pubDate>Sat, 28 Jan 2012 20:45:23 +0000</pubDate>
		<dc:creator>pkoch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://pko.ch/?p=90</guid>
		<description><![CDATA[I&#8217;ve switched from mercurial to git some time ago and I&#8217;m not regretting it. In general, there&#8217;s no difference from what I&#8217;ve learned in Mercurial. It all boils down to one sentence: Truly grok, love and take pride in your repo&#8217;s commit graph. To achieve this, these are some of the key points I follow. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve switched from mercurial to git some time ago and I&#8217;m not regretting it. In general, there&#8217;s no difference from what I&#8217;ve learned in Mercurial. It all boils down to one sentence:</p>
<p><big>Truly grok, love and take pride in your repo&#8217;s commit graph.</big></p>
<p>To achieve this, these are some of the key points I follow.</p>
<h3>Understanding the tree</h3>
<h4>Decent graph visibility</h4>
<p>To truly understand DSCMs, you have to completely grok what&#8217;s happening on you repo in terms of commits, yours or otherwise. I find a decent graphical view goes a log way. And we have a very good one built in.<br />
<code>
<pre>
git log --graph --oneline --decorate --all
</pre>
<p></code><br />
Try it!</p>
<p>If you really want to see all nodes, even those not reachable by a branch, try:<br />
<code>
<pre>
git log --graph --oneline --decorate --all $(git reflog | awk '{print $1}')
</pre>
<p></code></p>
<h4>Have a sane branching model</h4>
<p>Begin with <a href="http://nvie.com/posts/a-successful-git-branching-model/">git-flow&#8217;s model</a>, but have <a href="http://schacon.github.com/git/gitworkflows.html">git-workflow manpage</a> in mind. Try it out. If it hurts, stop, <a href="http://en.wikipedia.org/wiki/Five_whys">think</a> and, only then, act.</p>
<h3>Building the tree</h3>
<h4>Learn to use the index</h4>
<p>The index, or cache, or staging area (git should get its names strait) is a place where you put the hunks that should be in the next commit. Yes, hunks, not files. You can have a really fine grained control over what goes into the index with <code>git add --patch</code>. Selective removal of the index? <code>git reset -p</code>. Selectively throw out stuff not indexed? <code>git checkout -p</code>.</p>
<h4>Make your commits laser focused</h4>
<p>You should commit early and commit often. They should do one thing and do it right, on the right place in the commit graph. Don&#8217;t be afraid of having a commit with an one line diff and a commit message of &#8220;Whitespace.&#8221;.</p>
<p>This will make your history more browsable and understandable for other people. Your reviewers will buy you more drinks and you&#8217;ll thank yourself on the next time you have some serious merge/rebase conflicts.</p>
<p>Too many commits? Wish you could roll some of them into each other? Or maybe just re-order them? Use <code>git rebase --interactive</code>.</p>
<p>Forgot to include something in your last commit? Use <code>git commit --amend</code>.</p>
<p>Remember that public history must be immutable, atomic, and easy to follow. However, before you publish your commit, your private history is your own. It&#8217;s malleable, disposable and nobody&#8217;s business but your own!</p>
<h4>Switch tasks fast</h4>
<p>Is there something cramping you style you but you already have changes on you working copy? Use <code>git stash</code>, then go all out on your annoyance. When your done, checkout the right branch, and <code>git stash pop</code>.</p>
<p>Just remember that git stash won&#8217;t keep the untracked files. Add them to the index if you want to keep them.</p>
<h4>Know when to merge or rebase</h4>
<p>Merges should be meaningful. They convey a very strong message to others that says &#8220;I merged these two lines of thinking and made them compatible&#8221;. If you&#8217;re not merging lines of thinking, you shouldn&#8217;t be doing a merge. You should probably rebase.</p>
<p>Rebasing is the act of recreating a set of commits on top of a new node. If it helps you, think of it as &#8220;transplanting commits to a new place in the graph&#8221;.</p>
<h5>Caveat: Pull tries to be your friend, but it&#8217;s just too eager to please</h5>
<p>Don&#8217;t use <code>git pull</code>.</p>
<p>It&#8217;s meant to be a tool for syncing with upstream. It&#8217;s just a <code>git fetch</code> followed by a gratuitous <code>git merge</code>. Merges should be thought out. Fetches should not.</p>
<p>Handling upstream changes by hand can be laborious, though. So, use <code>git pull --rebase</code>. It&#8217;ll use rebase instead of merging your local history which will result in not having <a href="http://stevenharman.net/blog/archive/2011/06/09/git-pull-with-automatic-rebase.aspx">stupid auto-micro-merges</a>.</p>
<p>To give your clone some rebase love, just do:<br />
<code>
<pre>
git config branch.autosetuprebase always
git b | cut -c3- | xargs -I= echo git config branch.=.rebase true
</pre>
<p></code></p>
<h4>Honor public history</h4>
<p>Don&#8217;t rebase public commits.</p>
<p>When you rebase, you&#8217;re creating new nodes and &#8220;forgetting&#8221; about the old ones. In your local clone, at least. In everybody else&#8217;s, the nodes are still there and they won&#8217;t be able to make sense of a bunch of duplicated nodes (not right away, at least). And they&#8217;ll have to do some (serious) commit gardening to put things back where they should be. That will be a lot of work, I can guaranty you.</p>
<p>So, in order to keep thing clean for everyone, don&#8217;t change stuff you&#8217;ve already published.</p>
<p>However, while your commits are not yet published, muck around at will! The aim is to provide a good new addition to the repo&#8217;s public history.</p>
<h3>No rules beat practicality</h3>
<p>These are just a set of guidelines. They&#8217;re meant to keep things clean and easy to understand for normal operation. If there&#8217;s any situation that really demands it, you can (and probably should) violate your own rules. Just be sure to have everybody involved and aware of your punctual actions and its impact.</p>
<h3>Be happy</h3>
<p>Source code management should make you happy. Both in the present and in the future. If you having too much pain figuring out what going on, committing and sharing your changes or make sense of the past, figure out what&#8217;s causing you such pain and how you could be doing things differently.</p>
<p>Remember, this tool is more than appropriate to handle big projects like the Linux kernel. They&#8217;re not in pain, and so shouldn&#8217;t you.</p>
]]></content:encoded>
			<wfw:commentRss>http://pko.ch/2012/01/28/taming-git/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Powerful = Simple + Focused</title>
		<link>http://pko.ch/2012/01/27/powerful-simple-focused/</link>
		<comments>http://pko.ch/2012/01/27/powerful-simple-focused/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 22:14:21 +0000</pubDate>
		<dc:creator>pkoch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://pko.ch/?p=84</guid>
		<description><![CDATA[This guy says just that. I don&#8217;t find his conclusions all that groundbreaking. But I really loved his focus on &#8220;It&#8217;s a record store&#8221;. I&#8217;m pretty sure that&#8217;s not there is to it being a success. He, disguisedly, says that curating your content is fundamental. And he&#8217;ll charge you for that. Via A Better Mess]]></description>
			<content:encoded><![CDATA[<p><iframe width="560" height="315" src="http://www.youtube.com/embed/6a3-O4B9jL4" frameborder="0" allowfullscreen></iframe></p>
<p>This guy says just that. I don&#8217;t find his conclusions all that groundbreaking. But I really loved his focus on &#8220;It&#8217;s a record store&#8221;.</p>
<p>I&#8217;m pretty sure that&#8217;s not there is to it being a success. He, disguisedly, says that curating your content is fundamental. And he&#8217;ll charge you for that.</p>
<p><small><br />
Via <a href="http://bettermess.com/quick-quotes-weekly-the-uncommon-sense-edition/?utm_source=feedburner&#038;utm_medium=feed&#038;utm_campaign=Feed%3A+Michaelschechterme+%28A+Better+Mess%29&#038;utm_content=Google+Reader">A Better Mess</a><br />
</small></p>
]]></content:encoded>
			<wfw:commentRss>http://pko.ch/2012/01/27/powerful-simple-focused/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery &lt;select/&gt; filter</title>
		<link>http://pko.ch/2009/03/28/jquery-select-filter/</link>
		<comments>http://pko.ch/2009/03/28/jquery-select-filter/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 16:16:20 +0000</pubDate>
		<dc:creator>pkoch</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://pko.ch/?p=42</guid>
		<description><![CDATA[First I was like: &#60;script&#62; $(document).ready(function(){ jQuery.extend(jQuery.expr[':'], { containsIgnoreCase: "(a.textContent&#124;&#124;a.innerText&#124;&#124;jQuery(a).text()&#124;&#124;'').toLowerCase().indexOf((m[3]&#124;&#124;'').toLowerCase())>=0" }); $('input.filterer').keyup(function(){ $('#'+$(this).attr('target_id')+' option').show().not(':containsIgnoreCase('+$(this).val()+')').hide() }); }); &#60;/script&#62; &#60;input class="filterer" target_id="target_select_id" type="text"/&#62; But then IE made me do: &#60;script&#62; $(document).ready(function(){ jQuery.extend(jQuery.expr[':'], { containsIgnoreCase: "(a.textContent&#124;&#124;a.innerText&#124;&#124;jQuery(a).text()&#124;&#124;'').toLowerCase().indexOf((m[3]&#124;&#124;'').toLowerCase())>=0" }); $('input.filterer').each(function(){ $('&#60;select id="'+$(this).attr('target_id')+'_stash" style="display:none;" /&#62;') .insertBefore($('#'+$(this).attr('target_id'))); }); $('input.filterer').keyup(function(){ var visible_select = '#'+$(this).attr('target_id'); var hidden_select = visible_select+'_stash'; var needle = $(this).val(); $(visible_select+' [...]]]></description>
			<content:encoded><![CDATA[<p>First I was like:<br />
<code></p>
<pre>
&lt;script&gt;
$(document).ready(function(){
    jQuery.extend(jQuery.expr[':'], {
      containsIgnoreCase:
        "(a.textContent||a.innerText||jQuery(a).text()||'').toLowerCase().indexOf((m[3]||'').toLowerCase())>=0"
    });
    $('input.filterer').keyup(function(){
        $('#'+$(this).attr('target_id')+' option').show().not(':containsIgnoreCase('+$(this).val()+')').hide()
    });
});
&lt;/script&gt;
&lt;input class="filterer" target_id="target_select_id" type="text"/&gt;
</pre>
<p></code><br />
But then IE made me do:<br />
<code></p>
<pre>
&lt;script&gt;
$(document).ready(function(){
    jQuery.extend(jQuery.expr[':'], {
      containsIgnoreCase:
        "(a.textContent||a.innerText||jQuery(a).text()||'').toLowerCase().indexOf((m[3]||'').toLowerCase())>=0"
    });
    $('input.filterer').each(function(){
        $('&lt;select id="'+$(this).attr('target_id')+'_stash" style="display:none;" /&gt;')
            .insertBefore($('#'+$(this).attr('target_id')));
    });
    $('input.filterer').keyup(function(){
	var visible_select = '#'+$(this).attr('target_id');
	var hidden_select = visible_select+'_stash';
	var needle = $(this).val();
	$(visible_select+' option').not(':containsIgnoreCase('+needle+')').remove()
            .appendTo($(hidden_select)).removeAttr('selected');
	$(hidden_select+' option:containsIgnoreCase('+needle+')').remove()
            .appendTo($(visible_select)).removeAttr('selected');
    });
});
&lt;/script&gt;
&lt;input class="filterer" target_id="target_select_id" type="text"/&gt;
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://pko.ch/2009/03/28/jquery-select-filter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Taming KbdMgr.exe</title>
		<link>http://pko.ch/2009/03/28/taming-kbdmgrexe/</link>
		<comments>http://pko.ch/2009/03/28/taming-kbdmgrexe/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 15:54:56 +0000</pubDate>
		<dc:creator>pkoch</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[troubleshooting]]></category>

		<guid isPermaLink="false">http://pko.ch/?p=30</guid>
		<description><![CDATA[I have a bootcamp'ed Macbook Pro. As many people, I experienced some lagging sound and graphics from the computer, apparently at random. I googled it a bit, and found DPCs were the cause of it. And the cause DPCs were so slow were some drivers and <code>KbdMgr.exe</code>, a small app that listens to the hardware keys to raise brightness and stuff. I updated the drivers, and the lag dropped a bit, but not that much. Then I turned to <code>KbdMgr.exe</code>.  And python popped into my mind. After some 15 minutes of research, I found <a href="http://pypi.python.org/pypi/pywin32/210">win32all</a>. And from there, It was just remembering all of the win32 I had forgotten. I eventually churned out some code to scratch my itch.]]></description>
			<content:encoded><![CDATA[<p>I have a bootcamp&#8217;ed Macbook Pro. As many people, I experienced some lagging sound and graphics from the computer, apparently at random. I googled it a bit, and found DPCs were the cause of it. And the cause DPCs were so slow were some drivers and <code>KbdMgr.exe</code>, a small app that listens to the hardware keys to raise brightness and stuff.</p>
<p>I updated the drivers, and the lag dropped a bit, but not that much. Then I turned to <code>KbdMgr.exe</code>. I read that a quick fix was to set the affinity to the second core and set it to minimum priority. And so I did, and it worked! However, It was just a pain in the butt to do that dance on each boot. I thought of doing some wrapper <code>exe</code> for <code>KbdMgr.exe</code>, but just the thought of downloading Visual Studio and all the SDKs gave me nauseas. And python popped into my mind.</p>
<p>After some 15 minutes of research, I found <a href="http://pypi.python.org/pypi/pywin32/210">win32all</a>. And from there, It was just remembering all of the win32 I had forgotten. I eventually churned out some code to scratch my itch.</p>
<p><code></p>
<pre>
import win32api
import win32com.client
import win32process
import win32con
import time
import sys, traceback

class ProcessSeekerThrottler(object):

    def __init__(self):
        self.coup_de_grace = self.throttle_and_set_affinity
        self.backoff_interval = 1.0

    def throttle_and_set_affinity(self,pid):
        proc = win32api.OpenProcess(win32con.PROCESS_SET_INFORMATION, 0, pid)

        win32process.SetProcessAffinityMask(proc,0x02)
        win32process.SetPriorityClass(proc,win32process.IDLE_PRIORITY_CLASS)

        win32api.CloseHandle(proc)

    def pids_for(self,process_name):
        self.WMI = win32com.client.GetObject('winmgmts:')
        results = self.WMI.ExecQuery('select * from Win32_Process where Name="%s"'%(process_name,))
        if len(results) < 1:
            raise Exception("Not found: %s"%(process_name,))
        else:
            return [result.Properties_('ProcessId').Value for result in results]

    def hunt_pid_for(self,process_name):
        done = False
        while not done:
            try:
                [self.coup_de_grace(pid) for pid in self.pids_for(process_name)]
                print "Killed!"
                done = True
            except Exception as e:
                print >> sys.stderr, "-"*60
                traceback.print_exc(None,sys.stderr)
                print >> sys.stderr, "Backing off."
                time.sleep(self.backoff_interval)

if __name__ == '__main__':
    try:
        ProcessSeekerThrottler().hunt_pid_for("KbdMgr.exe")
    except Exception as e:
        traceback.print_exc(None,sys.stderr)
        raw_input()
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://pko.ch/2009/03/28/taming-kbdmgrexe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some more Mercurial goodness</title>
		<link>http://pko.ch/2009/02/17/some-more-mercurial-goodness/</link>
		<comments>http://pko.ch/2009/02/17/some-more-mercurial-goodness/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 00:38:18 +0000</pubDate>
		<dc:creator>pkoch</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Mercurial]]></category>

		<guid isPermaLink="false">http://pko.ch/?p=27</guid>
		<description><![CDATA[Today, I discovered some Mercurial extensions that will, forseeabily, make me more productive: Shelve, Bookmarks and Win32text.]]></description>
			<content:encoded><![CDATA[<p>Today, I discovered some Mercurial extensions that will, forseeabily, make me more productive.</p>
<ul>
<li>
		<a href="http://www.selenic.com/mercurial/wiki/index.cgi/ShelveExtension">Shelve</a>: No more diff mangling.
	</li>
<li>
		<a href="http://www.selenic.com/mercurial/wiki/index.cgi/BookmarksExtension">Bookmarks</a>: A pretty good interpretation on what local branches should be. Matches perfectly with my idea of them.
	</li>
<li>
		<a href="http://www.selenic.com/mercurial/wiki/index.cgi/Win32TextExtension">Win32text</a>: No more newline mambo-jumbo.
	</li>
</ul>
<p>Enjoy them too!</p>
]]></content:encoded>
			<wfw:commentRss>http://pko.ch/2009/02/17/some-more-mercurial-goodness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RegExp for capturing strings</title>
		<link>http://pko.ch/2008/12/15/regexp-for-capturing-strings/</link>
		<comments>http://pko.ch/2008/12/15/regexp-for-capturing-strings/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 00:54:59 +0000</pubDate>
		<dc:creator>pkoch</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[troubleshooting]]></category>

		<guid isPermaLink="false">http://pko.ch/?p=23</guid>
		<description><![CDATA['((?:\\['\n])&#124;[^'\n])*' Because I keep forgetting.]]></description>
			<content:encoded><![CDATA[<p><code>'((?:\\['\n])|[^'\n])*'</code></p>
<p>Because I keep forgetting.</p>
]]></content:encoded>
			<wfw:commentRss>http://pko.ch/2008/12/15/regexp-for-capturing-strings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>There&#8217;s no silver bullet, but there&#8217;s a silver DSCM. And it&#8217;s quick.</title>
		<link>http://pko.ch/2008/08/23/theres-no-silver-bullet-but-theres-a-silver-dscm-and-its-quick/</link>
		<comments>http://pko.ch/2008/08/23/theres-no-silver-bullet-but-theres-a-silver-dscm-and-its-quick/#comments</comments>
		<pubDate>Sat, 23 Aug 2008 01:59:23 +0000</pubDate>
		<dc:creator>pkoch</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://pko.ch/?p=5</guid>
		<description><![CDATA[Pre scriptum: This was dangling in my drafts forever. I just decided to post it as it is. In this post: Why I use Mercurial (sometimes abbreviated as hg) but not Git, and why I like it. One day, some moons ago, I watched a presentation with Linus on Git, and how it would forever [...]]]></description>
			<content:encoded><![CDATA[<p><em>Pre scriptum</em>: This was dangling in my drafts forever. I just decided to post it as it is.</p>
<p>In this post: Why I use <a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a> (sometimes abbreviated as hg) but not <a href="http://git.or.cz/">Git</a>, and why I like it.</p>
<p>One day, some moons ago, I watched a <a href="http://www.youtube.com/watch?v=4XpnKHJAok8">presentation with Linus on Git</a>, and how it would forever change our life. He explained why it&#8217;s a must-use on a very big distributed team or/and at a personal level. I mostly agreed. I still thought this was just a clever hack to solve merge conflits on svn and keep changes controlled on a mental level. CVS is dead, SVN is not. For most small teams, SVN is just a shortcut for the common workflow one would do with git, except for one little thing: you commit locally, and publish as needed.</p>
<p>Mercurial, or any DSCM, is great for detaching the act of committing work (accepting it as a valid step towards a goal) from the act of publishing work (putting your modifications up for other parties).</p>
<p>I prefer Mercurial over Git for the polish and supporting the anti-&#8221;linus is god&#8221; movement. I really didn&#8217;t like the way I was told he dismissed the idea of using incremental logs. I&#8217;m not being an extremist, or i would use <a href="http://en.wikipedia.org/wiki/Codeville">Codeville</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://pko.ch/2008/08/23/theres-no-silver-bullet-but-theres-a-silver-dscm-and-its-quick/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Memoization in Python: easier than what it should be</title>
		<link>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/</link>
		<comments>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/#comments</comments>
		<pubDate>Fri, 22 Aug 2008 10:14:52 +0000</pubDate>
		<dc:creator>pkoch</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://pko.ch/?p=15</guid>
		<description><![CDATA[I was writing some DB-access-intensive Python application and felt the need to cache function results. After fiddling with some dictionaries, I felt there was some underlying pattern I wasn&#8217;t spotting. Then it hit me. I was just memoizing function calls. So I came up with this decorator. import functools import cPickle def memoize(fctn): memory = [...]]]></description>
			<content:encoded><![CDATA[<p>I was writing some DB-access-intensive Python application and felt the need to cache function results. After fiddling with some dictionaries, I felt there was some underlying pattern I wasn&#8217;t spotting. Then it hit me. I was just memoizing function calls.</p>
<p>So I came up with this decorator.<br />
<code></p>
<pre>
import functools
import cPickle
def memoize(fctn):
        memory = {}
        @functools.wraps(fctn)
        def memo(*args,**kwargs):
                haxh = cPickle.dumps((args, sorted(kwargs.iteritems())))

                if haxh not in memory:
                        memory[haxh] = fctn(*args,**kwargs)

                return memory[haxh]
        if memo.__doc__:
            memo.__doc__ = "\n".join([memo.__doc__,"This function is memoized."])
        return memo
</pre>
<p></code></p>
<p>Python is <strong>really easy</strong> to write.</p>
<p><strong>23 August 2008 &#8211; Update:</strong> Corrected the bug pointed out by John.<br />
<strong>25 August 2008 &#8211; Update:</strong> Improved as per <a href="http://www.reddit.com/comments/6xj70/memoization_in_python_easier_than_what_it_should/">reddit comments</a>&#8216;s suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Chand-FAIL-ler</title>
		<link>http://pko.ch/2008/08/12/chand-fail-ler/</link>
		<comments>http://pko.ch/2008/08/12/chand-fail-ler/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 23:16:44 +0000</pubDate>
		<dc:creator>pkoch</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://pko.ch/?p=14</guid>
		<description><![CDATA[Chandler always looked promising. I was really happy when I heard 1.0 just came out. Because I hadn&#8217;t my laptop around, I tried the web version and felt ok with it. But that was my last step in my trail of Chandler faith. As soon as Chandler Desktop booted up, I was greeted with a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://chandlerproject.org/wikihome">Chandler</a> always looked promising. I was really happy when I heard 1.0 just came out. Because I hadn&#8217;t my laptop around, I tried the web version and felt ok with it.</p>
<p>But that was my last step in my trail of Chandler faith. As soon as <em>Chandler Desktop</em> booted up, I was greeted with a soft, warm and fuzzy python exception: &#8220;Hey! This function receives one argument, you gave it two!&#8221;. Never good.</p>
<p>Tried to report the bug. Need a login for some bugzilla somewhere. Hmm, guess I&#8217;ll pass.</p>
]]></content:encoded>
			<wfw:commentRss>http://pko.ch/2008/08/12/chand-fail-ler/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>When rewriting is the &#8220;not bad&#8221; result</title>
		<link>http://pko.ch/2008/06/20/when-rewriting-is-the-not-bad-result/</link>
		<comments>http://pko.ch/2008/06/20/when-rewriting-is-the-not-bad-result/#comments</comments>
		<pubDate>Fri, 20 Jun 2008 01:14:38 +0000</pubDate>
		<dc:creator>pkoch</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://pko.ch/?p=13</guid>
		<description><![CDATA[I was reading Don&#8217;t be clever and came across this excerpt: And don&#8217;t think that I am saying that there is no place for optimization, that is not true, there is just less room for optimization in the source itself, but there is lots of room for optimizations in terms of overall system performance and [...]]]></description>
			<content:encoded><![CDATA[<p>I was reading <a href="http://www.codethinked.com/post/2007/12/Dont-be-clever.aspx">Don&#8217;t be clever</a> and came across this excerpt:</p>
<blockquote><p>
And don&#8217;t think that I am saying that there is no place for optimization, that is not true, there is just less room for optimization in the source itself, but there is lots of room for optimizations in terms of overall system performance and in terms of developer productivity. It is more important to focus on the big picture and solve performance problems that are system wide, or refactor code so that changes can be made much faster, than it is to solve a performance problem in a single line of code&#8230;unless of course that line of code is being called 8 million times by 50 parts of the system.</p>
<p>So next time you go to write a super clever line of code, think to yourself &#8220;Will the benefits of this super cleverness be outweighed by the future issues in maintaining and understanding the code?&#8221; And if there is any hesitation at all, then you better not be clever, because 3 months from now you will come across that code and say &#8220;What the hell was I thinking?&#8221; Then you&#8217;ll end up rewriting it anyway.
</p></blockquote>
<p>It&#8217;s quite correct, except for one little detail: &#8220;Then you&#8217;ll end up rewriting it anyway&#8221;.</p>
<p>I wish! Doing it right the first time is the good solution, but rewriting it when you latter come across it and realise it&#8217;s stupid is a &#8220;not good, not bad&#8221; solution. The problem is when you just <strong>can&#8217;t</strong> rewrite that piece of crap! Maybe you can&#8217;t test it, maybe you have something more important to do, maybe you don&#8217;t really understand it, maybe maybe maybe&#8230;</p>
<p>I could segway this into the perfect TDD and &#8220;Tests as a living, runnable spec&#8221; pitch, but I&#8217;ll let it rest.</p>
]]></content:encoded>
			<wfw:commentRss>http://pko.ch/2008/06/20/when-rewriting-is-the-not-bad-result/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

