<?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>tadhg.com &#187; coding</title>
	<atom:link href="http://tadhg.com/wp/tag/coding/feed/" rel="self" type="application/rss+xml" />
	<link>http://tadhg.com/wp</link>
	<description>Wherein some things Tadhg are discussed</description>
	<lastBuildDate>Tue, 16 Mar 2010 20:50:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A Little More Functional Programming</title>
		<link>http://tadhg.com/wp/2010/02/25/a-little-more-functional-programming/</link>
		<comments>http://tadhg.com/wp/2010/02/25/a-little-more-functional-programming/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 07:55:51 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2712</guid>
		<description><![CDATA[After reading Dhananjay Nene’s comment on my post about a functional style approach to the “find longest repeater” problem, I decided to follow the line from that comment and divide the program into functions for finding the longest contiguous block and then for comparing the blocks. Naturally, I wanted to do this without using any [...]]]></description>
			<content:encoded><![CDATA[<p>After reading <a class="reference external" href="http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/#comment-19788">Dhananjay Nene’s comment</a> on my <a class="reference external" href="http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/">post about a functional style approach to the “find longest repeater” problem</a>, I decided to follow the line from that comment and divide the program into functions for finding the longest contiguous block and then for comparing the blocks. Naturally, I wanted to do this without using any variables&#8230;<br />
<span id="more-2712"></span><br />
It wasn’t too hard to write a variable-free function to return a list of blocks of letters from a string, e.g. <tt class="docutils literal"><span class="pre">continuous_blocks(&quot;anna&quot;)</span></tt> produces <tt class="docutils literal"><span class="pre">[&quot;a&quot;,</span> <span class="pre">&quot;nn&quot;,</span> <span class="pre">&quot;a&quot;]</span></tt>:</p>
<pre class="python literal-block">
def contiguous_blocks(string):
    def listbuilder(blocks, char, rest):
        if not rest:
            return add_to_blocks(char, blocks)
        return listbuilder(add_to_blocks(char, blocks), rest[0], rest[1:])

    def add_to_blocks(char, blocks):
        if blocks and char in blocks[-1]:
            return blocks[:-1] + [&quot;&quot;.join([blocks[-1], char])]
        return blocks+[char]

    return listbuilder([], string[0], string[1:])
</pre>
<p>And then <tt class="docutils literal"><span class="pre">findlongestrepeater</span></tt> becomes:</p>
<pre class="python literal-block">
def findlongestrepeater(string):
    def compare_blocks(previous, current):
        return current if len(current)&gt;len(previous) else previous

    return reduce(compare_blocks, contiguous_blocks(string))
</pre>
<p>Note that this approach provides a clear use for <tt class="docutils literal"><span class="pre">reduce</span></tt>, which is <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=98196" title="The fate of reduce() in Python 3000" >on the outs in Python these days</a>.</p>
<p>A crucial difference between <a class="reference external" href="http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/#comment-19788">Dhananjay Nene’s version</a> and mine, however, is that mine returns a list and not a generator. So I decided to write a variable-free generator version&#8230; and just couldn’t do it. I don’t know what it was, but I kept getting hung up on trying to track the previous, current, and next characters, and to do that without variables while trying to skip at the right times in the for loop just seemed impossible. While writing this blog post, however, I figured it out. I had intended to put it up as a puzzle for other people, so I guess I’ll put my solution at the end. If you plan to try it, don’t scroll beyond the warning below.</p>
<p>There’s an easier way, too, which is simply to do this:</p>
<pre class="python literal-block">
def contiguous_blocks(string):
    from itertools import groupby
    for k,g in groupby(string):
        yield u&quot;&quot;.join(list(g))
</pre>
<p>I found that last night after being unable to bend my mind in the right way, because I was sure that this problem couldn’t be so rare that itertools wouldn’t have something to handle it.</p>
<p>However, I felt like that was cheating&#8230; so I kept trying to build my own variable-free generator.</p>
<p>Because of the fact that <tt class="docutils literal"><span class="pre">reduce</span></tt> isn’t going to be in Python 3, I decided I’d write a version of it that would work as its replacement for this problem. It didn’t seem too hard to come up with this:</p>
<pre class="python literal-block">
def reducereplacement(func, generator):
    def runfunc(product, gen):
        try:
            return runfunc(func(product, gen.next()), gen)
        except StopIteration:
            return product

    return runfunc([], generator)
</pre>
<p>This only works with generators and not with lists, unlike the real <tt class="docutils literal"><span class="pre">reduce</span></tt>. There’s no reason to use this, either, given that <tt class="docutils literal"><span class="pre">reduce</span></tt> is in Python 2 and will be in the <tt class="docutils literal"><span class="pre">functools</span></tt> module for Python 3; I just wanted to try it as an experiment.</p>
<p>So, to restate the puzzle problem:</p>
<p>Write a version of <tt class="docutils literal"><span class="pre">contiguous_blocks</span></tt> that is functionally equivalent to the version above using <tt class="docutils literal"><span class="pre">itertools.groupby</span></tt>, without using the assignment operator anyhere, or anything from a module. This is a puzzle I found impossible last night but reasonably easy today. Like a lot of puzzles, looking at it in a slightly different way can make all the difference—advice which is often maddeningly useless while you’re trying to solve something.</p>
<p>The function, plus the version of <tt class="docutils literal"><span class="pre">findlongestrepeater</span></tt> I have above, should pass the following tests:</p>
<pre class="python literal-block">
def test_contiguous_blocks():
    testgen = contiguous_blocks(&quot;googlee&quot;)
    assert testgen.next() == &quot;g&quot;
    assert testgen.next() == &quot;oo&quot;
    assert testgen.next() == &quot;g&quot;
    assert testgen.next() == &quot;l&quot;
    assert testgen.next() == &quot;ee&quot;
    assert [c for c in contiguous_blocks(&quot;google&quot;)] == [&quot;g&quot;, &quot;oo&quot;, &quot;g&quot;, &quot;l&quot;, &quot;e&quot;]
    assert [c for c in contiguous_blocks(&quot;googlee&quot;)] == [
        &quot;g&quot;, &quot;oo&quot;, &quot;g&quot;, &quot;l&quot;, &quot;ee&quot;]

def test_findlongestrepeater():
    assert findlongestrepeater(&quot;google&quot;) == &quot;oo&quot;
    assert findlongestrepeater(&quot;gooooogle&quot;) == &quot;ooooo&quot;
    assert findlongestrepeater(&quot;eeffi&quot;) == &quot;ee&quot;
    assert findlongestrepeater(&quot;abcdef&quot;) == &quot;a&quot;
    assert findlongestrepeater(&quot;eeffeeeffeeeee&quot;) == &quot;eeeee&quot;
</pre>
<h4>WARNING, SOLUTION</h4>
<p>Don’t read past here if you want to solve it yourself, obviously.</p>
<hr class="docutils" />
The key insight that helped me get it (which seems utterly obvious now, of course) is that you’re not limited to the current and next (and/or previous) characters. I’d been approaching it with logic like this:</p>
<ul>
<li>Check the character to see if it’s different from the next character.
<ul>
<li>If it is, return it.
</li>
<li>If it isn’t, pass.
</li>
</ul>
</li>
<li>But also (somehow) store it so that you know what the current sequence of repeated characters is, and when you next return something, return that sequence instead of just the current character.
</li>
</ul>
<p>I couldn’t figure out how to make that work, and it may be impossible to get Python to do that without using variables (although maybe I just missed the trick).</p>
<p>However, that wasn’t the right way to look at it. With access to the index of the current character, you can get not only the next character, but also string up to that point. That was the realization: the logic should be as follows:</p>
<ul>
<li>Check the character to see if it’s different from the next character.
<ul>
<li>If it isn’t, pass.
</li>
<li>If it is, return all the characters in the string up to that point that are the same as the character.
</li>
</ul>
</li>
</ul>
<p>As I said, that seems awfully obvious now&#8230;</p>
<p>This is the solution I came up with:</p>
<pre class="python literal-block">
def contiguous_blocks(string):
    def inarow(row, string):
        if not string or row[0] != string[0]:
            return row
        return inarow(u&quot;&quot;.join([row, string[0]]), string[1:])

    for i,c in enumerate(string):
        if i &gt;= (len(string) -1) or c != string[i+1]:
            yield inarow(c, string[:i][::-1])
</pre>
<p>So, if the character is different from the next one, or you’ve run out of string, yield the result of passing the character and the (reversed) string up to that point to <tt class="docutils literal"><span class="pre">inarow</span></tt>. Otherwise, if the character is the same as the next character—do nothing.</p>
<p><tt class="docutils literal"><span class="pre">inarow</span></tt> doesn’t have to track anything but the characters until a different character shows up or you run out of string, so it returns what it has at that point if either of those happen, otherwise it calls itself with a new row of characters (the current one tacked onto the end) and the rest of the string.</p>
<p>The combination of <tt class="docutils literal"><span class="pre">find_longest_repeater</span></tt> and <tt class="docutils literal"><span class="pre">contiguous_blocks</span></tt> seems like a fairly elegant solution. Not only does it come in at two lines shorter than my version from Tuesday, but it also has the benefit of being more neatly divided in logical terms. (Which is something I wouldn’t have seen without the suggestion that the determination of contiguous blocks could be a discrete function.)</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/">Minor Foray into Functional Programming</a> <span class="related-post-date timestamp">Tue 23 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/">Some Vim Script Implementation, Testing, and Hackery</a> <span class="related-post-date timestamp">Tue 16 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/14/first-post-with-vim/">First Post With Vim</a> <span class="related-post-date timestamp">Sun 14 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/04/the-python-challenge/">The Python Challenge</a> <span class="related-post-date timestamp">Thu 04 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/">Better Word Count in Vim</a> <span class="related-post-date timestamp">Sun 17 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/15/code-katas/">Code Katas</a> <span class="related-post-date timestamp">Fri 15 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/08/python-coding-exercise-nested-dictionaries/">Python Coding Exercise: Nested Dictionaries</a> <span class="related-post-date timestamp">Fri 08 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/05/python-optimization-tips/">Python Optimization Tips</a> <span class="related-post-date timestamp">Tue 05 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/31/crossfit-and-coding-and-meat/">CrossFit and Coding (and Meat)</a> <span class="related-post-date timestamp">Thu 31 Dec 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/21/some-python-tips-and-tricks/">Some Python Tips and Tricks</a> <span class="related-post-date timestamp">Mon 21 Dec 2009</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/02/25/a-little-more-functional-programming/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Minor Foray into Functional Programming</title>
		<link>http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/</link>
		<comments>http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 23:56:05 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2709</guid>
		<description><![CDATA[Last night a friend asked me what functional programming was, and as part of my answer I decided to rewrite a trivial program in the functional style to see what it was like. I did this in Python without using the functional module.

The program finds the longest sequence of repeated characters in a string; if [...]]]></description>
			<content:encoded><![CDATA[<p>Last night a friend asked me what <a class="reference external" href="http://en.wikipedia.org/wiki/Functional_programming">functional programming</a> was, and as part of my answer I decided to rewrite a trivial program in the functional style to see what it was like. I did this in Python without using the <tt class="docutils literal"><span class="pre">functional</span></tt> module.<br />
<span id="more-2709"></span><br />
The program finds the longest sequence of repeated characters in a string; if there’s a tie, it returns the first sequence of that length. My (<a class="reference external" href="http://en.wikipedia.org/wiki/Imperative_programming">imperative</a>) version was six lines of Python:</p>
<pre class="python literal-block">
def findlongestrepeater(string):
    longest, curr = &quot;&quot;, &quot;&quot;
    for c in string:
        curr = &quot;&quot;.join([curr, c]) if c in curr else c
        longest = curr if len(curr) &gt; len(longest) else longest
    return longest
</pre>
<p>There are doubtless better ways to do it, but this is relatively succinct and clear. I can’t say the same about the functional version I came up with.</p>
<p>With my attempt at this example, “functional programming” basically meant “not using the assignment operator”.</p>
<p>I couldn’t see any way to do it without recursion, and it came out looking like a recursive decision tree:</p>
<pre class="python literal-block">
def findlongestrepeater(string):
    def flr(lr, curseq, s):
        return lr if len(s) == 0 else character_match(lr, curseq, s)

    def character_match(lr, curseq, s):
        if s[0] == curseq[0]:
            return sequence_length(lr, u&quot;&quot;.join([s[0],curseq]), s)
        else:
            return flr(lr, s[0], s[1:])

    def sequence_length(lr, newseq, s):
        if len(newseq) &gt; len(lr):
            return flr(newseq, newseq, s[1:])
        else:
            return flr(lr, newseq, s[1:])

    return flr(string[0], string[0], string[1:])
</pre>
<p><tt class="docutils literal"><span class="pre">flr</span></tt> takes arguments of the longest repeating sequence found so far, the current sequence, and the rest of the string. We kick it off by passing it the first character as the first two arguments, and then the rest of the string after the first character.</p>
<p>If the rest of string has a length of zero, we’ve reached the end of the string and <tt class="docutils literal"><span class="pre">flr</span></tt> returns the longest repeating sequence it was passed.</p>
<p>Otherwise, it calls <tt class="docutils literal"><span class="pre">character_match</span></tt>, which checks whether or not the current sequence matches the first character in the string. If not, it goes back to <tt class="docutils literal"><span class="pre">flr</span></tt> passing in the next character and the rest of the string; if so, it goes on to <tt class="docutils literal"><span class="pre">sequence_length</span></tt> passing in the longest repeater, the new sequence (which is the first character in the string plus the current sequence), and the string. <tt class="docutils literal"><span class="pre">sequence_length</span></tt> will then call <tt class="docutils literal"><span class="pre">flr</span></tt> with either the new sequence as the longest repeater, or the current longest repeater as the longest repeater.</p>
<p>It was pretty hard for me to approach the problem this way. It took me about forty minutes to get a working version, and another fifteen to clean it up (the first version was big jumble of conditionals). It’s also much harder to troubleshoot than the imperative version, at least for me. Recursion isn’t that hard to handle, but I really wanted to use variables just to make things clearer—for example, in <tt class="docutils literal"><span class="pre">character_match</span></tt>, I really want to replace <tt class="docutils literal"><span class="pre">u&quot;&quot;.join([s[0],curseq])</span></tt> with <tt class="docutils literal"><span class="pre">newseq</span> <span class="pre">=</span> <span class="pre">u&quot;&quot;.join([s[0],curseq])</span></tt> and then call <tt class="docutils literal"><span class="pre">sequence_length</span></tt> with <tt class="docutils literal"><span class="pre">newseq</span></tt> as the second argument, purely to make what’s going on more explicit.</p>
<p>It was definitely an interesting experiment, and in future I might try some exercises where I have to take functions and rewrite them without using assignment. I’m sure there are cases where this makes sense; I’m also sure that the above script would be a lot easier to deal with in a proper functional language (or perhaps using the <tt class="docutils literal"><span class="pre">functional</span></tt> module).</p>
<p>After doing that last night, this morning I came across an <a href="http://blog.dhananjaynene.com/2010/02/functional-programming-with-python-part-1/" title="Functional Programming with Python – Part 1" >introduction to functional programming with Python</a>.</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2010/02/25/a-little-more-functional-programming/">A Little More Functional Programming</a> <span class="related-post-date timestamp">Thu 25 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/">Some Vim Script Implementation, Testing, and Hackery</a> <span class="related-post-date timestamp">Tue 16 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/14/first-post-with-vim/">First Post With Vim</a> <span class="related-post-date timestamp">Sun 14 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/04/the-python-challenge/">The Python Challenge</a> <span class="related-post-date timestamp">Thu 04 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/">Better Word Count in Vim</a> <span class="related-post-date timestamp">Sun 17 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/15/code-katas/">Code Katas</a> <span class="related-post-date timestamp">Fri 15 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/08/python-coding-exercise-nested-dictionaries/">Python Coding Exercise: Nested Dictionaries</a> <span class="related-post-date timestamp">Fri 08 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/05/python-optimization-tips/">Python Optimization Tips</a> <span class="related-post-date timestamp">Tue 05 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/31/crossfit-and-coding-and-meat/">CrossFit and Coding (and Meat)</a> <span class="related-post-date timestamp">Thu 31 Dec 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/21/some-python-tips-and-tricks/">Some Python Tips and Tricks</a> <span class="related-post-date timestamp">Mon 21 Dec 2009</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Some Vim Script Implementation, Testing, and Hackery</title>
		<link>http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/</link>
		<comments>http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 07:50:47 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[Jython]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[text editing]]></category>
		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2690</guid>
		<description><![CDATA[As a result of my porting over jEdit (Jython) macros to Vim, I now have a fair amount of (Python) Vim scripts, and have learned some things about how to set up those scripts. I&#8217;ll go through some of that below, and hopefully other people writing Python scripts for Vim will find it useful.

In jEdit, [...]]]></description>
			<content:encoded><![CDATA[<p>As a result of my porting over <a class="reference external" href="http://jedit.org/">jEdit</a> (Jython) macros to <a class="reference external" href="http://www.vim.org/">Vim</a>, I now have a fair amount of (Python) Vim scripts, and have learned some things about how to set up those scripts. I&#8217;ll go through some of that below, and hopefully other people writing Python scripts for Vim will find it useful.<br />
<span id="more-2690"></span><br />
In jEdit, you invoke macros either by selecting them from a menu (clearly unacceptable) or by opening the <a class="reference external" href="http://www.jedit.org/users-guide/action-bar.html">Action Bar</a> (Ctrl-Enter, for me) and then typing the name of the macro, where “name” means the non-extension part of the filename. I put my macro files went in a subdirectory of the macros directory, and there were namespace issues—all macro names had to be unique, and also couldn&#8217;t match any internal jEdit actions. Furthermore, you couldn&#8217;t pass arguments to them. Despite those issues, it was a powerful and quick piece of functionality, and I wanted to make Vim at least match it.</p>
<p>You can put Python directly into Vim script files, but I wanted to do that as minimally as possible. I added a Vim script that would (essentially) include a Python file, and then I had that Python file import from other Python files as necessary. The Python file includes a class, <tt class="docutils literal"><span class="pre">TBase</span></tt>, that contains the functions I want to run; as much code as possible is kept out of those functions and is in other files—files which ideally are individually testable.</p>
<p>To get to those functions from within Vim, I did this:</p>
<pre class="literal-block">
if filereadable($HOME.&quot;/.vim/plugin/tadhg/tadhg.py&quot;)
    pyfile $HOME/.vim/plugin/tadhg/tadhg.py
endif

&quot; Create the commands pointing the Python in tadhg.py:
if !exists(&quot;:T&quot;)
  command! -range -nargs=+ T python tadhgbase = TBase('rs=&lt;line1&gt; rf=&lt;line2&gt;'); tadhgbase('&lt;args&gt;')
endif

nmap &lt;D-CR&gt; :T
</pre>
<p>That code goes in a Vim script that goes in <tt class="docutils literal"><span class="pre">~/.vim/plugins/tadhg/</span></tt>; it&#8217;s loaded when Vim is. This means that the code in <tt class="docutils literal"><span class="pre">tadhg.py</span></tt> is evaluated at Vim start, so the <tt class="docutils literal"><span class="pre">TBase</span></tt> class is available. Furthermore the user Ex mode command “T” creates a new instance of <tt class="docutils literal"><span class="pre">TBase</span></tt> and then calls it with whatever the user enters after “T”. Finally, Command-Enter is mapped to enter Ex mode and type “T ”, which is quite close indeed to the jEdit functionality I had, but without the disadvantages. I have much more control over the namespace, and I can pass arguments.</p>
<p>When the T command is invoked, a new <tt class="docutils literal"><span class="pre">TBase</span></tt> instance is created and it gets passed the range start and range end line numbers from Vim, which is pretty important for some of the functions. Then the new instance is called, with the argument of whatever was typed after “T ”.</p>
<p>This is the code for handling that latter aspect:</p>
<pre class="python literal-block">
def __call__(self, argstring):
    &quot;&quot;&quot;
    The first arg is the command; the rest are arguments to that command.
    &quot;&quot;&quot;
    args = argstring.split(u&quot; &quot;)

    #Need to extract the keyword args out of args
    kwargs = dict([(arg.split(&quot;=&quot;)[0], arg.split(&quot;=&quot;)[1]) for arg in s.split(&quot; &quot;) if &quot;=&quot; in arg])
    args = [arg for arg in s.split(&quot; &quot;) if &quot;=&quot; not in arg]

    if args and args[0] in self.__class__.__dict__.keys():
        import types
        f = self.__class__.__dict__[args[0]]
        if type(f) == types.FunctionType:
            if args[1:]:
                f(self, *args[1:])
            else:
                f(self)
    else:
        print &quot;no command by that name&quot;
</pre>
<p>In other words, if the first (non-keyword) argument matches the name of a function in the class, run it and pass the rest of the (non-keyword) arguments to it. If I ever need keyword arguments as well, I&#8217;ll add the ability to pass them along too.</p>
<p>In order to actually manipulate Vim from these scripts, you have to use <tt class="docutils literal"><span class="pre">import</span> <span class="pre">vim</span></tt>. When I started writing this, I wasn&#8217;t sure how I&#8217;d test that, and I tried to keep the meat of the code in other files, e.g.:</p>
<pre class="python literal-block">
def mpc(self):
    &quot;&quot;&quot;
    Count the words, then insert them into the document's word count line.
    &quot;&quot;&quot;
    from write_wordcount import WriteWordcount
    wwc = WriteWordcount(tadhgbase)
    wwc.vim_main(vim)
</pre>
<p>(Note that I use <tt class="docutils literal"><span class="pre">import</span> <span class="pre">sys;</span> <span class="pre">sys.path.append(myscriptdir)</span></tt> at the top of the file to make these imports work.)</p>
<p>One of the advantages of this construction is that <tt class="docutils literal"><span class="pre">WriteWordCount</span></tt> can theoretically be used as a standalone script, on any file, and also that its <tt class="docutils literal"><span class="pre">vim_main</span></tt> method takes <tt class="docutils literal"><span class="pre">vim</span></tt> as an argument. For testing purposes, I had to created a <tt class="docutils literal"><span class="pre">MockVim</span></tt> class, which currently looks like this:</p>
<pre class="python literal-block">
class MockVimBuffer(object):

    def __init__(self):
        self.lines = []

    def __contains__(self, item):
        return item in self.lines

    def __iter__(self):
        return self.lines.__iter__()

    def __getitem__(self, index):
        return self.lines.__getitem__(index)

    def __setitem__(self, index, value):
        return self.lines.__setitem__(index, value)

class MockVimCurrent(object):

    def __init__(self):
        self.__dict__[&quot;buffer&quot;] = MockVimBuffer()

    def __setattr__(self, attr, value):
        if attr == &quot;buffer&quot;:
            self.__dict__[&quot;buffer&quot;].lines = value
        else:
            self.__dict__[attr] = value

class MockVim(object):

    def __init__(self):
        self.current = MockVimCurrent()
        self.commands = []

    def eval(self, command):
        command_list = {
            &quot;&amp;ft&quot;: lambda: self.rawmodes,
            &quot;exists('b:TotalWordCount')&quot;: lambda: False,
            &quot;tvar&quot;: lambda: self.tvar,

        }
        return command_list.get(command, lambda: &quot;&quot;)()

    def command(self, command):
        self.commands.append(command)
</pre>
<p>The <tt class="docutils literal"><span class="pre">eval</span></tt> method in <tt class="docutils literal"><span class="pre">MockVim</span></tt> simply returns whatever was appropriate for various tests I was running; I should change it to return <tt class="docutils literal"><span class="pre">self.command_list.get(command,</span> <span class="pre">lambda:</span> <span class="pre">&quot;&quot;)()</span></tt> instead, and make <tt class="docutils literal"><span class="pre">command_list</span></tt> an instance variable so that the various tests can manipulate it as needed instead of having to put specific commands in the base code.</p>
<p>Because the methods in <tt class="docutils literal"><span class="pre">TBase</span></tt> pass <tt class="docutils literal"><span class="pre">vim</span></tt> along to the instances or methods of the modules they import, testing those modules is relatively simple: in the test, you create a new <tt class="docutils literal"><span class="pre">MockVim</span></tt> object, call it <tt class="docutils literal"><span class="pre">vim</span></tt>, and then pass it along instead.</p>
<p>So everything is great (and testable). Unless, that is, you (meaning me) lapse from full test-driven development discipline and bits and pieces of functionality creep into <tt class="docutils literal"><span class="pre">TBase</span></tt>. Because <tt class="docutils literal"><span class="pre">TBase</span></tt> has that <tt class="docutils literal"><span class="pre">import</span> <span class="pre">vim</span></tt> line at the top of it and running it when you&#8217;re not actually in Vim produces an <tt class="docutils literal"><span class="pre">ImportError</span></tt>.</p>
<p>The right way to deal with this is to refactor <tt class="docutils literal"><span class="pre">TBase</span></tt> to take <tt class="docutils literal"><span class="pre">vim</span></tt> as one of its initialization arguments, and then have it set that as an instance variable, and then pass that in its methods, while also altering the line in the parent Vim script to:</p>
<pre class="literal-block">
command! -range -nargs=+ T python import vim; tadhgbase = TBase(vim, 'rs=&lt;line1&gt; rf=&lt;line2&gt;'); tadhgbase('&lt;args&gt;')
</pre>
<p>That way <tt class="docutils literal"><span class="pre">TBase</span></tt> is much easier to test, since the fake <tt class="docutils literal"><span class="pre">vim</span></tt> can be passed in at test time. However, for a bunch of reasons I didn&#8217;t want to do that just yet, partly because it means some reasonably heavy refactoring of pieces of code that I use every day—without tests, because the whole issue here is that <tt class="docutils literal"><span class="pre">TBase</span></tt> isn&#8217;t testable. So I wanted a way to make it testable while altering as little of its existing code (which I know currently works, after all) as possible. This took me a while to figure out, and is rather hacky—but it works.</p>
<p>First, in the test file, do this:</p>
<pre class="python literal-block">
from mockvim import MockVim
#Hack a mock Vim into the global namespace so that we can actually test:
import __builtin__
mv = MockVim()
__builtin__.mv = mv
from tadhg import TBase
</pre>
<p>Then alter the <tt class="docutils literal"><span class="pre">import</span> <span class="pre">vim</span></tt> line above the <tt class="docutils literal"><span class="pre">TBase</span></tt> class to instead read:</p>
<pre class="python literal-block">
try:
    import vim
except ImportError:
    import __builtin__
    vim = __builtin__.mv
</pre>
<p>What this really does is hack a giant global variable, <tt class="docutils literal"><span class="pre">vim</span></tt>, into all of the Python that&#8217;s run after those lines in the test file. Normally doing this seems like a rather bad idea, but it&#8217;s also rather necessary to handle the less-than-ideal situation I&#8217;m dealing with. Once I have the test harness using this hackery running properly, I&#8217;ll feel a lot better about switching over to a better architecture.</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/jython/" rel="tag">Jython</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a>, <a href="http://tadhg.com/wp/tag/software/" rel="tag">software</a>, <a href="http://tadhg.com/wp/tag/tech/" rel="tag">tech</a>, <a href="http://tadhg.com/wp/tag/text-editing/" rel="tag">text editing</a>, <a href="http://tadhg.com/wp/tag/vim/" rel="tag">Vim</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2010/02/14/first-post-with-vim/">First Post With Vim</a> <span class="related-post-date timestamp">Sun 14 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/">Better Word Count in Vim</a> <span class="related-post-date timestamp">Sun 17 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/19/better-word-count-in-jedit/">Better Word Count in jEdit</a> <span class="related-post-date timestamp">Sun 19 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/09/24/rtf_word_restructuredtext-toolchain/">RTF/Word–reStructuredText Toolchain</a> <span class="related-post-date timestamp">Thu 24 Sep 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/08/02/python-script-for-subversion-status/">Python Script for Subversion Status</a> <span class="related-post-date timestamp">Sun 02 Aug 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/28/better-rest-wordpress-pipeline/">Better reST–WordPress Pipeline</a> <span class="related-post-date timestamp">Tue 28 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/17/jedit-macros-in-python/">jEdit Macros in Python</a> <span class="related-post-date timestamp">Fri 17 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/14/blog-workflow-with-restructuredtext/">Blog Workflow with reStructuredText</a> <span class="related-post-date timestamp">Tue 14 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/03/12/using-vim-with-thunderbird/">Using Vim with Thunderbird</a> <span class="related-post-date timestamp">Fri 12 Mar 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/22/imap-jj-esc-and-bclose-in-vim/"><tt class="docutils literal"><span class="pre">:imap</span> <span class="pre">jj</span> <span class="pre">&lt;Esc&gt;</span></tt> and <tt class="docutils literal"><span class="pre">:Bclose</span></tt> in Vim</a> <span class="related-post-date timestamp">Mon 22 Feb 2010</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>First Post With Vim</title>
		<link>http://tadhg.com/wp/2010/02/14/first-post-with-vim/</link>
		<comments>http://tadhg.com/wp/2010/02/14/first-post-with-vim/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 04:05:48 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[Jython]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[text editing]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2682</guid>
		<description><![CDATA[Over the last couple of weeks I’ve been hacking away on scripts to customize Vim, replicating the scripts I made for jEdit. I’m more or less done, and this blog post is being written in MacVim. This hopefully means that when I’m done with it I’ll be able to publish it from within Vim, the [...]]]></description>
			<content:encoded><![CDATA[<p>Over the last couple of weeks I’ve been hacking away on scripts to customize Vim, replicating the scripts I made for jEdit. I’m more or less done, and this blog post is being written in <a class="reference external" href="http://code.google.com/p/macvim/">MacVim</a>. This hopefully means that when I’m done with it I’ll be able to publish it from within Vim, the same as with <a class="reference external" href="http://jedit.org/">jEdit</a>.<br />
<span id="more-2682"></span><br />
Writing scripts for Vim has been rather different from writing them for jEdit. jEdit is an editor with a robust API; Vim is an editor that kind of gives the user access to the API all the time, via keyboard commands, and scripting for it often consists of simply passing keystrokes. As an example, this is the Jython code for getting the current selection in a jEdit macro:</p>
<pre class="python literal-block">
text = init.textArea.getSelectedText()
</pre>
<p>This is the Python for getting the current visual selection in Vim:</p>
<pre class="python literal-block">self.vim.command('normal gv&quot;wygv')
self.vim.command(&quot;let tvar = getreg(’t’)&quot;)
text = unicode(self.vim.eval(&quot;tvar&quot;), &quot;utf-8&quot;)
</pre>
<p>From a programming perspective, jEdit is clearly a lot nicer to deal with.</p>
<p>I have two primary reasons for making the switch:</p>
<ul>
<li>Future proofing: I couldn’t switch to the various pre-release versions of jEdit 4.3 because I couldn’t get my Jython scripts to work with them, and that made me worry that there simply weren’t enough people scripting jEdit in Python to make it likely that the plugin allowing Jython macros would be supported. Given how useful my scripts are, that would have trapped me with jEdit 4.2, or some future version, if support for JythonInterpreter flagged. Vim, on the other hand, seems to have a lot of people scripting for it in Python, and I don’t see Python support simply disappearing anytime soon with a new release.
</li>
<li>Power/speed: I’m someone who’s quite inclined towards keyboard shortcuts in all applications, and this means Vim should be a highly efficient environment.
</li>
<li>Mentality: Related to the previous point, I think that being able to manipulate text more powerfully will reinforce the approach of scripting as many steps as possible, rather than doing them (no matter how efficiently) manually. Even over the last couple of weeks, I’ve noticed that I’m more inclined to write scripts than to put up with various manual steps in my daily workflow.
</li>
</ul>
<p>So far I’ve mainly worked to replicate my jEdit setup in Vim, with a few small improvements here and there; the largest one is probably the live word count, which means that I can glance at the status line to see the current word count instead of having to select the text to be counted and then invoke the word counter. I’ve also tweaked it so it only counts the relevant parts of the document—for example, in this blog post, it doesn’t count the title or the datestamp.</p>
<p>I don’t intend to abandon jEdit, and have a feeling that I’ll use it for various things here and there, but I’ve switched over the Vim for the majority of my writing and programming.</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/jython/" rel="tag">Jython</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a>, <a href="http://tadhg.com/wp/tag/software/" rel="tag">software</a>, <a href="http://tadhg.com/wp/tag/tech/" rel="tag">tech</a>, <a href="http://tadhg.com/wp/tag/text-editing/" rel="tag">text editing</a>, <a href="http://tadhg.com/wp/tag/vim/" rel="tag">Vim</a>, <a href="http://tadhg.com/wp/tag/writing/" rel="tag">writing</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/">Better Word Count in Vim</a> <span class="related-post-date timestamp">Sun 17 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/">Some Vim Script Implementation, Testing, and Hackery</a> <span class="related-post-date timestamp">Tue 16 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/19/better-word-count-in-jedit/">Better Word Count in jEdit</a> <span class="related-post-date timestamp">Sun 19 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/09/24/rtf_word_restructuredtext-toolchain/">RTF/Word–reStructuredText Toolchain</a> <span class="related-post-date timestamp">Thu 24 Sep 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/08/02/python-script-for-subversion-status/">Python Script for Subversion Status</a> <span class="related-post-date timestamp">Sun 02 Aug 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/28/better-rest-wordpress-pipeline/">Better reST–WordPress Pipeline</a> <span class="related-post-date timestamp">Tue 28 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/17/jedit-macros-in-python/">jEdit Macros in Python</a> <span class="related-post-date timestamp">Fri 17 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/14/blog-workflow-with-restructuredtext/">Blog Workflow with reStructuredText</a> <span class="related-post-date timestamp">Tue 14 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/03/12/using-vim-with-thunderbird/">Using Vim with Thunderbird</a> <span class="related-post-date timestamp">Fri 12 Mar 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/22/imap-jj-esc-and-bclose-in-vim/"><tt class="docutils literal"><span class="pre">:imap</span> <span class="pre">jj</span> <span class="pre">&lt;Esc&gt;</span></tt> and <tt class="docutils literal"><span class="pre">:Bclose</span></tt> in Vim</a> <span class="related-post-date timestamp">Mon 22 Feb 2010</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/02/14/first-post-with-vim/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Python Challenge</title>
		<link>http://tadhg.com/wp/2010/02/04/the-python-challenge/</link>
		<comments>http://tadhg.com/wp/2010/02/04/the-python-challenge/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 23:18:35 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2653</guid>
		<description><![CDATA[The Python Challenge seems like a good way to have fun with Python through puzzle-solving. As with all riddles, it’s important to read the questions carefully&#8230;
Tags: coding, pythonRelated PostsA Little More Functional Programming Thu 25 Feb 2010Minor Foray into Functional Programming Tue 23 Feb 2010Some Vim Script Implementation, Testing, and Hackery Tue 16 Feb 2010First [...]]]></description>
			<content:encoded><![CDATA[<p>The <a class="reference external" href="http://www.pythonchallenge.com/">Python Challenge</a> seems like a good way to have fun with Python through puzzle-solving. As with all riddles, it’s important to read the questions carefully&#8230;</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2010/02/25/a-little-more-functional-programming/">A Little More Functional Programming</a> <span class="related-post-date timestamp">Thu 25 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/">Minor Foray into Functional Programming</a> <span class="related-post-date timestamp">Tue 23 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/">Some Vim Script Implementation, Testing, and Hackery</a> <span class="related-post-date timestamp">Tue 16 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/14/first-post-with-vim/">First Post With Vim</a> <span class="related-post-date timestamp">Sun 14 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/">Better Word Count in Vim</a> <span class="related-post-date timestamp">Sun 17 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/15/code-katas/">Code Katas</a> <span class="related-post-date timestamp">Fri 15 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/08/python-coding-exercise-nested-dictionaries/">Python Coding Exercise: Nested Dictionaries</a> <span class="related-post-date timestamp">Fri 08 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/05/python-optimization-tips/">Python Optimization Tips</a> <span class="related-post-date timestamp">Tue 05 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/31/crossfit-and-coding-and-meat/">CrossFit and Coding (and Meat)</a> <span class="related-post-date timestamp">Thu 31 Dec 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/21/some-python-tips-and-tricks/">Some Python Tips and Tricks</a> <span class="related-post-date timestamp">Mon 21 Dec 2009</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/02/04/the-python-challenge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery Project</title>
		<link>http://tadhg.com/wp/2010/01/21/jquery-project/</link>
		<comments>http://tadhg.com/wp/2010/01/21/jquery-project/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 07:36:54 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2606</guid>
		<description><![CDATA[I’ve been a big fan of jQuery more or less since it came out, and I’m happy to see the launch of The jQuery Project. I’ve used jQueryUI a couple of times and find it fairly useful; I haven’t tried Sizzle yet but it looks great for situations where you’re really concerned about keeping file [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve been a big fan of <a class="reference external" href="http://jquery.com/">jQuery</a> more or less since it came out, and I’m happy to see the launch of <a class="reference external" href="http://jquery.org/">The jQuery Project</a>. I’ve used <a class="reference external" href="http://jqueryui.com/">jQueryUI</a> a couple of times and find it fairly useful; I haven’t tried <a class="reference external" href="http://sizzlejs.com/">Sizzle</a> yet but it looks great for situations where you’re really concerned about keeping file sizes low but need decent CSS selector support; and I wish <a class="reference external" href="http://docs.jquery.com/Qunit">QUnit</a> had been around when I was writing a lot of client-side code.</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/javascript/" rel="tag">JavaScript</a>, <a href="http://tadhg.com/wp/tag/web-development/" rel="tag">web-development</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2009/10/11/some-javascript-programming-patterns/">Some JavaScript Programming Patterns</a> <span class="related-post-date timestamp">Sun 11 Oct 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/06/26/python-syntax-highlighting-for-star-light/">Python Syntax Highlighting for star-light</a> <span class="related-post-date timestamp">Fri 26 Jun 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/06/13/jquery-improvements/">jQuery Improvements</a> <span class="related-post-date timestamp">Fri 13 Jun 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/02/04/coding-and-concepts-tiebreakers/">Coding and Concepts: Tiebreakers</a> <span class="related-post-date timestamp">Mon 04 Feb 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/01/29/datejs/">Datejs</a> <span class="related-post-date timestamp">Tue 29 Jan 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/01/27/some-minor-software-projects/">Some Minor Software Projects</a> <span class="related-post-date timestamp">Sun 27 Jan 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/01/21/sfmagicorg-rewrite-pod-division/">sfmagic.org Rewrite: Pod Division</a> <span class="related-post-date timestamp">Mon 21 Jan 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/01/15/sfmagicorg-rewrite-planning-data-entry/">sfmagic.org Rewrite: Planning Data Entry</a> <span class="related-post-date timestamp">Tue 15 Jan 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/01/08/sfmagicorg-rewrite-stalledgraphs/">sfmagic.org Rewrite: Stalled/Graphs</a> <span class="related-post-date timestamp">Tue 08 Jan 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2007/04/16/ajax-cross-site-scripting-with-apache-rewriterule/"><abbr title='Asynchronous JavaScript and XML'>AJAX</abbr> Cross-Site Scripting with Apache RewriteRule</a> <span class="related-post-date timestamp">Mon 16 Apr 2007</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/01/21/jquery-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Better Word Count in Vim</title>
		<link>http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/</link>
		<comments>http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 07:40:14 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[Jython]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[text editing]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2596</guid>
		<description><![CDATA[I’m currently trying out Vim (again), and have made more progress this time, mainly due to Seth’s help. The key things that have made it better:

:set hidden. Absolutely critical, this. Stops Vim from complaining when you try to switch buffers and your current buffer has unsaved changes.

bufexplorer. Makes switching buffers a lot easier.

A better Python [...]]]></description>
			<content:encoded><![CDATA[<p>I’m currently trying out Vim (<a href="http://tadhg.com/wp/2009/08/09/time-to-try-vim/" title="Time to Try Vim" >again</a>), and have made more progress this time, mainly due to <a class="reference external" href="http://araxia.net/blog/seth">Seth</a>’s help. The key things that have made it better:</p>
<ul>
<li><tt class="docutils literal"><span class="pre">:set</span> <span class="pre">hidden</span></tt>. Absolutely critical, this. Stops Vim from complaining when you try to switch buffers and your current buffer has unsaved changes.
</li>
<li><a class="reference external" href="http://www.vim.org/scripts/script.php?script_id=42">bufexplorer</a>. Makes switching buffers a lot easier.
</li>
<li><a href="http://hlabs.spb.ru/vim/python3.0.vim" title="Python 3.0" >A better Python syntax file</a>. I didn’t like the defaults.
</li>
<li>My own indentation and syntax files for reStructuredText.
</li>
</ul>
<p>Really, though, the key first one was <tt class="docutils literal"><span class="pre">:set</span> <span class="pre">hidden</span></tt>. Before that I felt that I had completely misunderstood Vim’s file management model.<br />
<span id="more-2596"></span><br />
Once I got the syntax highlighting to a reasonable state, I ported my <a href="http://tadhg.com/wp/2009/07/19/better-word-count-in-jedit/" title="Better Word Count in jEdit" >word count macro</a> over to Vim. This wasn’t too hard after the inevitable character encoding problems. For working within Vim scripts, I strongly suggest using the following:</p>
<pre class="python literal-block">
ulines = [unicode(line, &quot;utf-8&quot;) for line in vim.current.buffer]
</pre>
<p>(Assuming your Vim encoding is set to UTF-8, of course.)</p>
<p>The Vim version of my script isn’t as versatile yet as the jEdit version, because I don’t know how to make it work with only selected lines (something that’s easy in jEdit). Apart from that, though, it seems to work quite well; the next version of it might do “live” word count in the status bar.</p>
<p>I’m currently writing this in Vim, or kind of: the actual writing is in Vim, but the creation of the file and the template, the automated expansion of various reStructuredText entities, output to reStructuredText, and the publication, are in jEdit as I haven’t ported those over yet.</p>
<p>The script:</p>
<pre class="python literal-block">
function! WordCount()
python &lt;&lt; EOF
import re
import vim

class WordCounter(object):
    &quot;&quot;&quot;
    Vim script for better word count.
    &quot;&quot;&quot;

    LINE_SEPARATORS = (
        &quot;\r&quot;,
        &quot;\n&quot;
    )

    WORD_SEPARATORS = (
        &quot; &quot;,        # space
        &quot;\t&quot;,       # tab
        &quot;/&quot;,        # slash
        &quot;&amp;&quot;,        # ampersand
        ’&quot;’,        # double quotation mark, straight
        u&quot;\u201C&quot;,  # double quotation mark, left
        u&quot;\u201D&quot;,  # double quotation mark, right
        u&quot;\u2018&quot;,  # single quotation mark, left
        u&quot;\u2013&quot;,  # en dash
        u&quot;\u2014&quot;,  # em dash
        &quot;&gt;&quot;,        # greater than symbol
        &quot;&lt;&quot;,        # less than symbol
        &quot;+&quot;,        # plus
        &quot;=&quot;,        # equals
    )

    REPEATER_SEPARATORS = (
    #These are only separators if they’re present consecutively, e.g. -- or ..
        &quot;-&quot;,
        &quot;.&quot;
    )

    IGNORE = (
    #Not separators per se, but should not be treated as word content
        &quot;’&quot;,        # single quotation mark, straight
        u&quot;\u2019&quot;,  # single quotation mark, right
        &quot;(&quot;,        # left parenthesis
        &quot;)&quot;,        # right parenthesis
        &quot;[&quot;,        # left bracket
        &quot;]&quot;,        # right bracket
        &quot;{&quot;,        # left curly bracket
        &quot;}&quot;,        # right curly bracket
        &quot;|&quot;,        # bar
        &quot;-&quot;,        # hyphen
        &quot;#&quot;,        # hash mark
        &quot;.&quot;,        # period
        &quot;_&quot;,        # underscore
        &quot;`&quot;,        # backtick
        &quot;\\&quot;,        # backslash
    )

    def word_count(self):

        ulines = [unicode(line, &quot;utf-8&quot;) for line in vim.current.buffer]
        text = u&quot;\n&quot;.join(ulines)

        chars = len(text) #Pretty sure I want the actual char count, not the adjusted char count.

        text = self.remove_directives(text)
        text = self.adjust_for_rest(text)
        words, lines = self.count_words(text)

        print &quot;chars: %s, words: %s, lines: %s&quot; % (chars, words, lines)

    def remove_directives(self, text):
        textlines = text.split(&quot;\n&quot;)
        newlines = []
        comment = re.compile(r&quot;[ ]*\.\. [a-zA-Z0-9_\|]&quot;)
        argument = re.compile(r&quot;    :[^\:]*:&quot;)
        for line in textlines:
            if not comment.match(line) and not argument.match(line):
                newlines.append(line)
        return &quot;\n&quot;.join(newlines)

    def adjust_for_rest(self, text):
        &quot;&quot;&quot;
            Go through each of the special cases for reST.
        &quot;&quot;&quot;
        text = self.rest_adjust_pipe_space(text)

        return text

    def rest_adjust_pipe_space(self, text):
        &quot;&quot;&quot;
            Special-case &quot;|\ &quot; to make sure e.g. &quot;|Hypnotic Specter|\ s&quot;
            doesn’t get counted as three words.

            |Incinerate|\ s |Hypnotic Specter|\ —|Hypnotic Specter|\ s
            The above line should be counted as five words.
        &quot;&quot;&quot;
        spacere = re.compile(r&quot;\|\\ ([^ ]{1})&quot;)
        finds = spacere.findall(text)
        text = spacere.sub(&quot;|\g&lt;1&gt;&quot;, text)
        return text

    def count_words(self, text):
        words, lines = 0, 1
        #go through the text character by character:
        word, previous_character = 0, None
        for character in text:
            if character in (self.LINE_SEPARATORS + self.WORD_SEPARATORS) or (character in self.REPEATER_SEPARATORS and previous_character in self.REPEATER_SEPARATORS):
                #it’s a separator
                word = 0
                if character in (self.LINE_SEPARATORS):
                    lines = lines + 1
            elif character in (self.IGNORE):
                pass
            else:
                #it’s part of a word.
                if not word:
                    words = words + 1
                    word = 1
            previous_character = character

        return (words, lines)

WordCounter().word_count()
EOF
endfunction

if !exists(&quot;:WW&quot;)
  command! WW  :call WordCount()
endif
</pre>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/jython/" rel="tag">Jython</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a>, <a href="http://tadhg.com/wp/tag/software/" rel="tag">software</a>, <a href="http://tadhg.com/wp/tag/tech/" rel="tag">tech</a>, <a href="http://tadhg.com/wp/tag/text-editing/" rel="tag">text editing</a>, <a href="http://tadhg.com/wp/tag/vim/" rel="tag">Vim</a>, <a href="http://tadhg.com/wp/tag/writing/" rel="tag">writing</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2010/02/14/first-post-with-vim/">First Post With Vim</a> <span class="related-post-date timestamp">Sun 14 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/">Some Vim Script Implementation, Testing, and Hackery</a> <span class="related-post-date timestamp">Tue 16 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/19/better-word-count-in-jedit/">Better Word Count in jEdit</a> <span class="related-post-date timestamp">Sun 19 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/09/24/rtf_word_restructuredtext-toolchain/">RTF/Word–reStructuredText Toolchain</a> <span class="related-post-date timestamp">Thu 24 Sep 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/08/02/python-script-for-subversion-status/">Python Script for Subversion Status</a> <span class="related-post-date timestamp">Sun 02 Aug 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/28/better-rest-wordpress-pipeline/">Better reST–WordPress Pipeline</a> <span class="related-post-date timestamp">Tue 28 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/17/jedit-macros-in-python/">jEdit Macros in Python</a> <span class="related-post-date timestamp">Fri 17 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/14/blog-workflow-with-restructuredtext/">Blog Workflow with reStructuredText</a> <span class="related-post-date timestamp">Tue 14 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/03/12/using-vim-with-thunderbird/">Using Vim with Thunderbird</a> <span class="related-post-date timestamp">Fri 12 Mar 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/22/imap-jj-esc-and-bclose-in-vim/"><tt class="docutils literal"><span class="pre">:imap</span> <span class="pre">jj</span> <span class="pre">&lt;Esc&gt;</span></tt> and <tt class="docutils literal"><span class="pre">:Bclose</span></tt> in Vim</a> <span class="related-post-date timestamp">Mon 22 Feb 2010</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Code Katas</title>
		<link>http://tadhg.com/wp/2010/01/15/code-katas/</link>
		<comments>http://tadhg.com/wp/2010/01/15/code-katas/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 01:26:06 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2593</guid>
		<description><![CDATA[I really like this idea from Dave Thomas: code katas, small pieces of programming practice involving some repetition. I came by it via Katacasts, a collection of screencasts of people doing the katas. I particularly recommend Gary Bernardt’s String Calculator in Python and Vim. (Which has inspired me to try once again to get past [...]]]></description>
			<content:encoded><![CDATA[<p>I really like this idea from <a class="reference external" href="http://en.wikipedia.org/wiki/Dave_Thomas_(programmer)">Dave Thomas</a>: <a class="reference external" href="http://codekata.pragprog.com/2007/01/code_kata_backg.html">code katas</a>, small pieces of programming practice involving some repetition. I came by it via <a class="reference external" href="http://www.katacasts.com/">Katacasts</a>, a collection of screencasts of people doing the katas. I particularly recommend <a class="reference external" href="http://vimeo.com/8569257">Gary Bernardt’s String Calculator in Python and Vim</a>. (Which has inspired me to try once again to get past the vim file management issues I have.)</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a>, <a href="http://tadhg.com/wp/tag/vim/" rel="tag">Vim</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/">Some Vim Script Implementation, Testing, and Hackery</a> <span class="related-post-date timestamp">Tue 16 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/14/first-post-with-vim/">First Post With Vim</a> <span class="related-post-date timestamp">Sun 14 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/">Better Word Count in Vim</a> <span class="related-post-date timestamp">Sun 17 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/25/a-little-more-functional-programming/">A Little More Functional Programming</a> <span class="related-post-date timestamp">Thu 25 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/">Minor Foray into Functional Programming</a> <span class="related-post-date timestamp">Tue 23 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/04/the-python-challenge/">The Python Challenge</a> <span class="related-post-date timestamp">Thu 04 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/08/python-coding-exercise-nested-dictionaries/">Python Coding Exercise: Nested Dictionaries</a> <span class="related-post-date timestamp">Fri 08 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/05/python-optimization-tips/">Python Optimization Tips</a> <span class="related-post-date timestamp">Tue 05 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/31/crossfit-and-coding-and-meat/">CrossFit and Coding (and Meat)</a> <span class="related-post-date timestamp">Thu 31 Dec 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/21/some-python-tips-and-tricks/">Some Python Tips and Tricks</a> <span class="related-post-date timestamp">Mon 21 Dec 2009</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/01/15/code-katas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress 2.9 Upgrade</title>
		<link>http://tadhg.com/wp/2010/01/10/wordpress-2-9-upgrade/</link>
		<comments>http://tadhg.com/wp/2010/01/10/wordpress-2-9-upgrade/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 23:56:30 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[web-development]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2579</guid>
		<description><![CDATA[I upgraded this blog to WordPress 2.9 today, and it appeared to go entirely smoothly. Please let me know if you notice any breakage.
Tags: Blog, coding, PHP, tech, web-development, WordPressRelated PostsWordPress 2.8 Upgrade Sun 14 Jun 2009WP Plugins: Recent Commentary and Show Tags in RSS Mon 23 Mar 2009Some RSS Changes Thu 19 Mar 2009New [...]]]></description>
			<content:encoded><![CDATA[<p>I upgraded this blog to <a class="reference external" href="http://codex.wordpress.org/Version_2.9">WordPress 2.9</a> today, and it appeared to go entirely smoothly. Please let me know if you notice any breakage.</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/blog/" rel="tag">Blog</a>, <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/php/" rel="tag">PHP</a>, <a href="http://tadhg.com/wp/tag/tech/" rel="tag">tech</a>, <a href="http://tadhg.com/wp/tag/web-development/" rel="tag">web-development</a>, <a href="http://tadhg.com/wp/tag/wordpress/" rel="tag">WordPress</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2009/06/14/wordpress-2-8-upgrade/">WordPress 2.8 Upgrade</a> <span class="related-post-date timestamp">Sun 14 Jun 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/03/23/wp-plugins-recent-commentary-and-show-tags-in-rss/">WP Plugins: Recent Commentary and Show Tags in RSS</a> <span class="related-post-date timestamp">Mon 23 Mar 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/03/19/some-rss-changes/">Some RSS Changes</a> <span class="related-post-date timestamp">Thu 19 Mar 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/02/23/new-blog-functionality-recent-commentary/">New Blog Functionality: Recent Commentary</a> <span class="related-post-date timestamp">Mon 23 Feb 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/02/13/my-wordpress-development-setup/">My WordPress Development Setup</a> <span class="related-post-date timestamp">Fri 13 Feb 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/28/better-rest-wordpress-pipeline/">Better reST–WordPress Pipeline</a> <span class="related-post-date timestamp">Tue 28 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/14/blog-workflow-with-restructuredtext/">Blog Workflow with reStructuredText</a> <span class="related-post-date timestamp">Tue 14 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/02/10/related-posts-plugin-and-sql-trickery/">Related Posts Plugin and SQL Trickery</a> <span class="related-post-date timestamp">Tue 10 Feb 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/11/10/html-past-and-future/">HTML Past and Future</a> <span class="related-post-date timestamp">Tue 10 Nov 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/09/10/404-pages/">404 Pages</a> <span class="related-post-date timestamp">Thu 10 Sep 2009</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/01/10/wordpress-2-9-upgrade/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Coding Exercise: Nested Dictionaries</title>
		<link>http://tadhg.com/wp/2010/01/08/python-coding-exercise-nested-dictionaries/</link>
		<comments>http://tadhg.com/wp/2010/01/08/python-coding-exercise-nested-dictionaries/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 07:54:56 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2576</guid>
		<description><![CDATA[I’ve been looking at a bunch of coding exercises recently, including the demo for Codility, and recalled an exercise that I came up with as an interview question. It’s not incredibly difficult, but strikes me as a good “real-world” exercise—it’s based on a task I had to perform while working on the discuss functionality for [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve been looking at a bunch of coding exercises recently, including the demo for <a class="reference external" href="http://codility.com/">Codility</a>, and recalled an exercise that I came up with as an interview question. It’s not incredibly difficult, but strikes me as a good “real-world” exercise—it’s based on a task I had to perform while working on the discuss functionality for <a class="reference external" href="http://www.freebase.com/">freebase.com</a>.<br />
<span id="more-2576"></span><br />
You have a list of objects (the objects can be dictionaries). In addition to other, irrelevant, properties, they all have <tt class="docutils literal"><span class="pre">id</span></tt> and <tt class="docutils literal"><span class="pre">parent</span></tt> keys (or properties). The <tt class="docutils literal"><span class="pre">parent</span></tt> key contains the id of the object’s parent. There are no recursive parent relationships (two objects cannot be each other’s parents), and there’s only one parent per object.</p>
<p>The goal is to go from this flat list of objects to a list of nexted objects, where each object has a <tt class="docutils literal"><span class="pre">child</span></tt> key (or property), and that contains not a list of ids but the child objects themselves, each of which also has a <tt class="docutils literal"><span class="pre">child</span></tt> property containing its child objects, and so on. Each dict should still show up only once in the entire structure (each only shows up once in the original list).</p>
<p>I think it gets slightly more difficult if you start with the objects having their parent relationships laid out at the start instead of the child relationships, but it’s still a similar problem.</p>
<p>I might post an answer to this over the next couple of weeks, and might also dig up my old solution to the problem to compare against how I’d do it now (if there’s much difference).</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2010/02/25/a-little-more-functional-programming/">A Little More Functional Programming</a> <span class="related-post-date timestamp">Thu 25 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/">Minor Foray into Functional Programming</a> <span class="related-post-date timestamp">Tue 23 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/">Some Vim Script Implementation, Testing, and Hackery</a> <span class="related-post-date timestamp">Tue 16 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/14/first-post-with-vim/">First Post With Vim</a> <span class="related-post-date timestamp">Sun 14 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/04/the-python-challenge/">The Python Challenge</a> <span class="related-post-date timestamp">Thu 04 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/">Better Word Count in Vim</a> <span class="related-post-date timestamp">Sun 17 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/15/code-katas/">Code Katas</a> <span class="related-post-date timestamp">Fri 15 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/05/python-optimization-tips/">Python Optimization Tips</a> <span class="related-post-date timestamp">Tue 05 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/31/crossfit-and-coding-and-meat/">CrossFit and Coding (and Meat)</a> <span class="related-post-date timestamp">Thu 31 Dec 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/21/some-python-tips-and-tricks/">Some Python Tips and Tricks</a> <span class="related-post-date timestamp">Mon 21 Dec 2009</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/01/08/python-coding-exercise-nested-dictionaries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Optimization Tips</title>
		<link>http://tadhg.com/wp/2010/01/05/python-optimization-tips/</link>
		<comments>http://tadhg.com/wp/2010/01/05/python-optimization-tips/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 14:34:28 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2564</guid>
		<description><![CDATA[I came across these on Hacker News recently, and think they’re worth calling out: Python Speed Performance Tips.

This comment is also worth reading.
There’s plenty of food for thought in those. They both encourage the use of list comprehensions, which I happen to like quite a lot.
On that note, I was recently asked about doing some [...]]]></description>
			<content:encoded><![CDATA[<p>I came across these on <a class="reference external" href="http://news.ycombinator.com/">Hacker News</a> recently, and think they’re worth calling out: <a class="reference external" href="http://wiki.python.org/moin/PythonSpeed/PerformanceTips">Python Speed Performance Tips</a>.<br />
<span id="more-2564"></span><br />
<a class="reference external" href="http://news.ycombinator.com/item?id=1031426">This comment</a> is also worth reading.</p>
<p>There’s plenty of food for thought in those. They both encourage the use of list comprehensions, which I happen to like quite a lot.</p>
<p>On that note, I was recently asked about doing some contrived simple programming problems in list comprehensions.</p>
<ol class="arabic">
<li>
<p>Find the overlapping elements in two lists:</p>
<pre class="literal-block python">
[item for item in list1 if item in list2]
</pre>
<p>This can also be done using sets:</p>
<pre class="literal-block python">
set(list1).intersection(list2)
</pre>
</li>
<li>
<p>Find the first repeating character in a string:</p>
<pre class="literal-block python">
<del>[char for char in s if s.count(char)&gt;1][0]</del>
</pre>
<p><a href="http://www.flett.org/">Alec</a> points out a far superior method in the comments:</p>
<pre class="literal-block python">
next(c for i,c in enumerate(s) if c in islice(s, i+1)
</pre>
</li>
<li>
<p>Reverse a string (couldn’t do this in less than 3 lines until I remembered <a href="http://tadhg.com/wp/2009/10/01/python-extended-list-slicing/" title="Python Extended List Slicing" >list slices</a>):</p>
<pre class="literal-block python">
s[::-1]
</pre>
</li>
</ol>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2010/02/25/a-little-more-functional-programming/">A Little More Functional Programming</a> <span class="related-post-date timestamp">Thu 25 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/">Minor Foray into Functional Programming</a> <span class="related-post-date timestamp">Tue 23 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/">Some Vim Script Implementation, Testing, and Hackery</a> <span class="related-post-date timestamp">Tue 16 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/14/first-post-with-vim/">First Post With Vim</a> <span class="related-post-date timestamp">Sun 14 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/04/the-python-challenge/">The Python Challenge</a> <span class="related-post-date timestamp">Thu 04 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/">Better Word Count in Vim</a> <span class="related-post-date timestamp">Sun 17 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/15/code-katas/">Code Katas</a> <span class="related-post-date timestamp">Fri 15 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/08/python-coding-exercise-nested-dictionaries/">Python Coding Exercise: Nested Dictionaries</a> <span class="related-post-date timestamp">Fri 08 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/31/crossfit-and-coding-and-meat/">CrossFit and Coding (and Meat)</a> <span class="related-post-date timestamp">Thu 31 Dec 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/21/some-python-tips-and-tricks/">Some Python Tips and Tricks</a> <span class="related-post-date timestamp">Mon 21 Dec 2009</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/01/05/python-optimization-tips/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>2010 Goals</title>
		<link>http://tadhg.com/wp/2010/01/01/2010-goals/</link>
		<comments>http://tadhg.com/wp/2010/01/01/2010-goals/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 16:53:36 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[CrossFit]]></category>
		<category><![CDATA[exercise]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[goals]]></category>
		<category><![CDATA[MTG]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[reading]]></category>
		<category><![CDATA[roleplaying]]></category>
		<category><![CDATA[web-development]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2554</guid>
		<description><![CDATA[Happy New Year!
Once again, my goals for the coming year.

Some of these recur from last year, but that’s okay. They’re not really in any order.

Write at least one draft of the fantasy novel.

Revive sfmagic.org. Many of my MTG-playing friends simply don’t believe I’ll ever do this one, but I’m still determined to make it happen, [...]]]></description>
			<content:encoded><![CDATA[<p>Happy New Year!</p>
<p>Once again, my goals for the coming year.<br />
<span id="more-2554"></span><br />
Some of these recur from last year, but that’s okay. They’re not really in any order.</p>
<ul>
<li>Write at least one draft of the fantasy novel.
</li>
<li>Revive sfmagic.org. Many of my MTG-playing friends simply don’t believe I’ll ever do this one, but I’m still determined to make it happen, and right now there are fewer obstacles to doing it than there have been in years.
</li>
<li>Celebrate my birthday. A strange-sounding resolution, perhaps, but I haven’t actually done any significant celebration of my birthday for a couple of years, and that’s just dumb. So this year I’m going to do <em>something</em>. I might need help figuring that something out, we’ll see.
</li>
<li>Participate in the <a class="reference external" href="http://games2010.crossfit.com/qualifiers/">CrossFit sectionals</a>. I don’t expect to qualify, or even come particularly close to qualifying, but I want to take part anyway to see what it’s like, and to give myself a training target. Given that at the end of March last year I was in fairly poor physical condition, competing in them at all will be an achievement.
</li>
<li>I have some miscellaneous fitness-related goals I’ll lump together: break three hundred pounds on the deadlift, get to ten dead-hang pullups, get my shoulders strong enough to safely do kipping pullups again and then get to thirty of those, break 23:00 for the 5K. Just because it’s the first day of the year and I think I should set one of these that’s a lot further away for me, I’ll add this: do <a class="reference external" href="http://www.crossfit.com/mt-archive2/001129.html">“Murph”</a> in under 50:00.
</li>
<li>Finish <a class="reference external" href="http://tadhg.com/afbh/"><cite>The Annotated Fantasy Bedtime Hour</cite></a>. Just five episodes to write up, I simply need to get down to it.
</li>
<li>Run a roleplaying campaign. I haven’t done this in fifteen years, and it’s time to start again. This already looks like it’s going to happen, but starting and finishing are separate things&#8230; this goal is to run at least one story arc, and to make it good (but not worry about it being perfect).
</li>
<li>I don’t like having amorphous goals, but this last one is going in regardless. I need to do something about building a sense of community for myself. I’m not totally sure what this means, and it’s not that I utterly lack a sense of community now, but it’s not quite where I want it, and I need to figure out what it is I want to change and how to do it. I have a post kind-of in my head about this, which I’ll hopefully get down in the next few weeks.
</li>
</ul>
<p>That seems like a good set. I also want to read 80 books, but for some reason this year that doesn’t feel like a goal in the same way as the above.</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/community/" rel="tag">community</a>, <a href="http://tadhg.com/wp/tag/crossfit/" rel="tag">CrossFit</a>, <a href="http://tadhg.com/wp/tag/exercise/" rel="tag">exercise</a>, <a href="http://tadhg.com/wp/tag/games/" rel="tag">games</a>, <a href="http://tadhg.com/wp/tag/goals/" rel="tag">goals</a>, <a href="http://tadhg.com/wp/tag/mtg/" rel="tag">MTG</a>, <a href="http://tadhg.com/wp/tag/personal/" rel="tag">personal</a>, <a href="http://tadhg.com/wp/tag/reading/" rel="tag">reading</a>, <a href="http://tadhg.com/wp/tag/roleplaying/" rel="tag">roleplaying</a>, <a href="http://tadhg.com/wp/tag/web-development/" rel="tag">web-development</a>, <a href="http://tadhg.com/wp/tag/writing/" rel="tag">writing</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2009/12/29/2009-goals-review/">2009 Goals Review</a> <span class="related-post-date timestamp">Tue 29 Dec 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/30/2009-goals-status/">2009 Goals Status</a> <span class="related-post-date timestamp">Thu 30 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/01/01/2009-goals/">2009 Goals</a> <span class="related-post-date timestamp">Thu 01 Jan 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/31/crossfit-and-coding-and-meat/">CrossFit and Coding (and Meat)</a> <span class="related-post-date timestamp">Thu 31 Dec 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/11/24/book-list/">Book List</a> <span class="related-post-date timestamp">Mon 24 Nov 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/04/29/literary-awards-in-freebase/">Literary Awards in Freebase</a> <span class="related-post-date timestamp">Tue 29 Apr 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2007/05/11/sfmagicorg-database-structure/">sfmagic.org Database Structure</a> <span class="related-post-date timestamp">Fri 11 May 2007</span></li><li class="related-post"><a href="http://tadhg.com/wp/2007/01/21/reading-gaming-critical-thinking/">Reading, Gaming, Critical Thinking</a> <span class="related-post-date timestamp">Sun 21 Jan 2007</span></li><li class="related-post"><a href="http://tadhg.com/wp/2006/08/09/some-plans-for-sfmagicorg/">Some Plans for sfmagic.org</a> <span class="related-post-date timestamp">Wed 09 Aug 2006</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/03/08/inkscape/">Inkscape</a> <span class="related-post-date timestamp">Mon 08 Mar 2010</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2010/01/01/2010-goals/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CrossFit and Coding (and Meat)</title>
		<link>http://tadhg.com/wp/2009/12/31/crossfit-and-coding-and-meat/</link>
		<comments>http://tadhg.com/wp/2009/12/31/crossfit-and-coding-and-meat/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 18:28:59 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[CrossFit]]></category>
		<category><![CDATA[diet]]></category>
		<category><![CDATA[exercise]]></category>
		<category><![CDATA[food]]></category>
		<category><![CDATA[health]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2551</guid>
		<description><![CDATA[In 2009 I achieved some significant things that weren’t on my list of goals, although they’re not concrete achievements in the same sense.

One of them was starting CrossFit—and sticking with it. Prior to this year, I had never been particularly fit. I’d never been horribly unfit, either. I’d always wanted to be fitter, and it’s [...]]]></description>
			<content:encoded><![CDATA[<p>In 2009 I achieved some significant things that weren’t on my <a href="http://tadhg.com/wp/2009/12/29/2009-goals-review/" title="2009 Goals Review" >list of goals</a>, although they’re not concrete achievements in the same sense.<br />
<span id="more-2551"></span><br />
One of them was <a href="http://tadhg.com/wp/2009/05/19/first-crossfit-wod/" title="First CrossFit WOD" >starting CrossFit</a>—and sticking with it. Prior to this year, I had never been particularly fit. I’d never been horribly unfit, either. I’d always wanted to be fitter, and it’s a fairly common theme in my morning pages throug their eleven years—wanting to start some exercise routine or other, wanting to figure out something that would really work. Many of the things that I tried would have worked, but I never stuck with them for too long. Even when I had physical activities I really enjoyed (e.g. tennis), I didn’t get into enough of a routine with them for that to have a really positive impact on my fitness.</p>
<p>It was something I was quite frustrated with, in a low-level way, for years. As with many things, the gaps between where I was and where I wanted to be, and between my intellectual motivation and my realized action, were wide and extremely frustrating to me. I was somewhat resigned to this continuing, and to perpetually going through patches of being slightly more fit but never truly getting too far.</p>
<p>CrossFit has changed that rather significantly. Not only am I probably the fittest I’ve been in my life, but both my determination to keep going and my confidence that I will are strong. The approach to fitness that I’ve been following for the last six months or so is one that I intend to stick with for the rest of my life, with the confidence that in terms of major features it is the right way for me. Those are all new states of mind for me, and I’m happy about them.</p>
<p>I spend a lot of my time using a computer. My profession, my writing, and many of my hobbies all involve computer use, and this has been true for years. I’ve always been rather interested in optimizing my software environment, and tend to quickly pick up shortcut keys and the like. At the same time, I’ve been progressing as a programmer. The last few years in particular have been challenging in a good way, and I’ve learned quite a lot. This year, I finally put these things together and wrote code to help my daily computer use in a serious way.</p>
<p>Python, a language that really helps me get things done rather than getting in my way, was a big part of this. The work I did this year to build a <a class="reference external" href="http://tadhg.com/wp/2009/07/28/better-rest-wordpress-pipeline/">reStructuredText–WordPress blogging workflow</a>, my <a class="reference external" href="http://tadhg.com/wp/2009/09/24/rtf_word_restructuredtext-toolchain/">RTF/Word–reStructuredText toolchain</a>, and a <a class="reference external" href="http://tadhg.com/wp/2009/07/19/better-word-count-in-jedit/">better word count for jEdit</a>, all constitute a positive shift in my attitude to programming. I’d always thought of programming as a useful tool (obviously), but this increased willingness to use it to directly alter my working environment has put me in a different place in regard to it—a place that I’m happy to be in.</p>
<p>Finally, meat. Not an achievement like the prior two, and whether it’s an unequivocally positive thing like them remains to be seen, but I have felt better since <a class="reference external" href="http://tadhg.com/wp/2009/07/20/considering-carnivorism/">resuming meat-eating</a> this year, after almost ten years of vegetarianism.</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/crossfit/" rel="tag">CrossFit</a>, <a href="http://tadhg.com/wp/tag/diet/" rel="tag">diet</a>, <a href="http://tadhg.com/wp/tag/exercise/" rel="tag">exercise</a>, <a href="http://tadhg.com/wp/tag/food/" rel="tag">food</a>, <a href="http://tadhg.com/wp/tag/health/" rel="tag">health</a>, <a href="http://tadhg.com/wp/tag/personal/" rel="tag">personal</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2009/07/20/considering-carnivorism/">Considering Carnivorism</a> <span class="related-post-date timestamp">Mon 20 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/01/2010-goals/">2010 Goals</a> <span class="related-post-date timestamp">Fri 01 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/07/2010-crossfit-sectionals/">2010 CrossFit Sectionals</a> <span class="related-post-date timestamp">Sun 07 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/09/24/rtf_word_restructuredtext-toolchain/">RTF/Word–reStructuredText Toolchain</a> <span class="related-post-date timestamp">Thu 24 Sep 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/08/17/crossfit-ireland-first-impressions/">CrossFit Ireland First Impressions</a> <span class="related-post-date timestamp">Mon 17 Aug 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/28/better-rest-wordpress-pipeline/">Better reST–WordPress Pipeline</a> <span class="related-post-date timestamp">Tue 28 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/14/blog-workflow-with-restructuredtext/">Blog Workflow with reStructuredText</a> <span class="related-post-date timestamp">Tue 14 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/02/a-month-of-crossfit/">A Month of CrossFit</a> <span class="related-post-date timestamp">Thu 02 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/06/08/a-week-of-crossfit/">A Week of CrossFit</a> <span class="related-post-date timestamp">Mon 08 Jun 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/05/21/second-crossfit-wod/">Second CrossFit WOD</a> <span class="related-post-date timestamp">Thu 21 May 2009</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2009/12/31/crossfit-and-coding-and-meat/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Some Python Tips and Tricks</title>
		<link>http://tadhg.com/wp/2009/12/21/some-python-tips-and-tricks/</link>
		<comments>http://tadhg.com/wp/2009/12/21/some-python-tips-and-tricks/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 13:08:53 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2514</guid>
		<description><![CDATA[Python Tips, Tricks, and Hacks at Siafoo is an excellent overview of useful Python knowledge. I was familiar with most of it but still think it’s worth reading over. I did learn a couple of new things, too.




“Burmese python 2” by Tambako the Jaguar


I’ve found myself wanting the equivalent of list comprehensions (e.g. newlist = [...]]]></description>
			<content:encoded><![CDATA[<p><a class="reference external" href="http://www.siafoo.net/article/52">Python Tips, Tricks, and Hacks</a> at <a class="reference external" href="http://www.siafoo.net/">Siafoo</a> is an excellent overview of useful Python knowledge. I was familiar with most of it but still think it’s worth reading over. I did learn a couple of new things, too.<br />
<span id="more-2514"></span></p>
<div class="captionimagels300 container">
<img alt="http://tadhg.com/images/photos/2009_12_21__some_python_tips_and_tricks/2009_12_21__some_python_tips_and_tricks.jpg" src="http://tadhg.com/images/photos/2009_12_21__some_python_tips_and_tricks/2009_12_21__some_python_tips_and_tricks.jpg" style="width: 300px; height: 225px;" /></p>
<div class="captiontext container">
<a class="reference external" href="http://www.flickr.com/photos/tambako/802764156/">“Burmese python 2”</a> by <a class="reference external" href="http://www.flickr.com/photos/tambako/">Tambako the Jaguar</a></p>
</div>
</div>
<p>I’ve found myself wanting the equivalent of list comprehensions (e.g. <tt class="docutils literal"><span class="pre">newlist</span> <span class="pre">=</span> <span class="pre">[do_something_to(item)</span> <span class="pre">for</span> <span class="pre">item</span> <span class="pre">in</span> <span class="pre">oldlist]</span></tt>) for dictionaries quite a few times, but never spent the time to figure out how to do that. The article does—you can use <tt class="docutils literal"><span class="pre">dict</span></tt> on a list of tuples that you’ve generated in a list comprehension in combination with <tt class="docutils literal"><span class="pre">dict.iteritems()</span></tt>.</p>
<p>The first piece of new knowledge for me was that you can create new dictionaries not just with keyword arguments (<tt class="docutils literal"><span class="pre">d</span> <span class="pre">=</span> <span class="pre">dict(key1=&quot;value1&quot;,</span> <span class="pre">key2=&quot;value2&quot;)</span></tt>) and curly braces (<tt class="docutils literal"><span class="pre">d</span> <span class="pre">=</span> <span class="pre">{&quot;key1&quot;:</span> <span class="pre">&quot;value1&quot;,</span> <span class="pre">&quot;key2&quot;:</span> <span class="pre">&quot;value2&quot;}</span></tt>) but also with a list of tuples of key/value pairs:</p>
<pre class="python literal-block">
d = dict([(&quot;key1&quot;, &quot;value1&quot;), (&quot;key2&quot;, &quot;value2&quot;)])
</pre>
<p>That method of dictionary construction isn’t that useful&#8230; unless you’re dealing with large numbers of keys, or you’re moving between lists and dictionaries. You can go the other way, from a dictionary to a list of tuples, using <tt class="docutils literal"><span class="pre">dict.items()</span></tt> or <tt class="docutils literal"><span class="pre">dict.iteritems()</span></tt>. So here’s how to remove keys with empty values from a dictionary:</p>
<pre class="python literal-block">
d = dict([key, value] for key, value in d.iteritems() if value)
</pre>
<p>That seems quite readable to me, and it’s definitely cleaner than the <tt class="docutils literal"><span class="pre">for</span></tt> and <tt class="docutils literal"><span class="pre">if</span></tt> statement approach that I used previously.</p>
<p>I also didn’t know about <tt class="docutils literal"><span class="pre">any</span></tt> and <tt class="docutils literal"><span class="pre">all</span></tt>, which can be used to evaluate whether any or all items in a list match a condition.</p>
<p>This next trick doesn’t come from the article, but was inspired by it: how to perform an operation on a specific set of keys in a dictionary only if those keys are in the dictionary. The obvious way:</p>
<pre class="python literal-block">
for vehicle in (&quot;planes&quot;, &quot;trains&quot;):
    if d.has_key(vehicle):
        d[vehicle] = d[vehicle].split(&quot;,&quot;)
</pre>
<p>There’s nothing wrong with that way, but I rather like being able to do this:</p>
<pre class="python literal-block">
for vehicle in set((&quot;planes&quot;, &quot;trains&quot;)).intersection(d.keys()):
    d[vehicle] = d[vehicle].split(&quot;,&quot;)
</pre>
<p>I suspect that there are all kinds of operations that could be streamlined using various <a class="reference external" href="http://docs.python.org/library/stdtypes.html#set"><tt class="docutils literal"><span class="pre">set</span></tt> functions</a>.</p>
<p>(The last example could be reduced to a one-liner, but at that point we’re really losing readability:</p>
<pre class="python literal-block">
d = dict(map(lambda (k,v): (k, d[k].split(&quot;,&quot;)) if k in (&quot;planes&quot;, &quot;trains&quot;) else (k, d[k]), d.iteritems()))
</pre>
<p>and it just doesn’t seem worth it.)</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2010/02/25/a-little-more-functional-programming/">A Little More Functional Programming</a> <span class="related-post-date timestamp">Thu 25 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/23/minor-foray-into-functional-programming/">Minor Foray into Functional Programming</a> <span class="related-post-date timestamp">Tue 23 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/">Some Vim Script Implementation, Testing, and Hackery</a> <span class="related-post-date timestamp">Tue 16 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/14/first-post-with-vim/">First Post With Vim</a> <span class="related-post-date timestamp">Sun 14 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/04/the-python-challenge/">The Python Challenge</a> <span class="related-post-date timestamp">Thu 04 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/">Better Word Count in Vim</a> <span class="related-post-date timestamp">Sun 17 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/15/code-katas/">Code Katas</a> <span class="related-post-date timestamp">Fri 15 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/08/python-coding-exercise-nested-dictionaries/">Python Coding Exercise: Nested Dictionaries</a> <span class="related-post-date timestamp">Fri 08 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/05/python-optimization-tips/">Python Optimization Tips</a> <span class="related-post-date timestamp">Tue 05 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/12/31/crossfit-and-coding-and-meat/">CrossFit and Coding (and Meat)</a> <span class="related-post-date timestamp">Thu 31 Dec 2009</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2009/12/21/some-python-tips-and-tricks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GPS, URLs, Math, Python, Featuritis</title>
		<link>http://tadhg.com/wp/2009/12/08/gps-urls-math-python-featuritis/</link>
		<comments>http://tadhg.com/wp/2009/12/08/gps-urls-math-python-featuritis/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 07:53:21 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2476</guid>
		<description><![CDATA[Earlier this evening Gever suggested a service dedicated to shortening URLs that had geolocation data in them. My immediate responses were that a) this was a great idea, and b) that I wanted the shortened URLs to still be human-readable in some sense—specifically, I wanted a person to be able to look at two URLs [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this evening <a class="reference external" href="http://www.gevertulley.com/">Gever</a> suggested a service dedicated to shortening URLs that had geolocation data in them. My immediate responses were that a) this was a great idea, and b) that I wanted the shortened URLs to still be human-readable in some sense—specifically, I wanted a person to be able to look at two URLs returned by this service and have some idea of how close to each other they were.<br />
<span id="more-2476"></span><br />
Gever hadn’t had that feature in mind at all, and so I had added a major feature as soon as I encountered this idea for a service.</p>
<p>We were at <a class="reference external" href="http://www.pywebsf.org/">PyWebSF</a>, so there were a number of programmers present, all of whom liked the idea, and all of whom appeared to have entirely different approaches to implementing it. <a class="reference external" href="http://en.wikipedia.org/wiki/Quadtree">Quadtrees</a> and <a class="reference external" href="http://en.wikipedia.org/wiki/Octree">octrees</a> were mentioned by the more CS-minded, but my approach was more basic (no pun intended): I thought it would be possible simply to encode the numbers in some higher base system and effectively shorten them that way.</p>
<p>I started with base 64, and looked at <a class="reference external" href="http://en.wikipedia.org/wiki/Base64">Base64</a> and at the <a href="http://www.fuyun.org/2009/10/how-to-convert-an-integer-to-base64-in-python/" title="How to convert an integer to Base64 in Python" >relatively easy Python implementation of an encoding system using it</a>, but found that I didn’t like it, for a few reasons. The main one was that the encoding just wasn’t that friendly: incrementing by one wasn’t that trivial, for example, and to me that made comparison of numbers difficult. I decided that the Base64 approach was clearly not designed with human readability in mind, and that one that was would map to base 10 for the numbers 0–9, then go to lowercase letters a–z, with a being 10, b 11 &#8230; z 35, and then uppercase letters A-Z, with A being 36, B 37 &#8230; Z 61. Then I tacked on _ for 62 and * for 63, for no particular reason. Apart from the last two, my choices were based on what I felt most people would grasp easily: numbers were their own values, uppercase letters were more than lowercase letter, and letters progress in alphabetical order.</p>
<p>Of course, that meant implementing my own system for the conversion, which I did in likely inefficient manner using Python <tt class="docutils literal"><span class="pre">dict</span></tt>s and some math for converting base systems in rather hacky fashion.</p>
<p>Given that I wanted the coordinates to remain somewhat readable, I decided to leave the integer parts of them alone. So the coordinates <tt class="docutils literal"><span class="pre">53.10680448323265,</span> <span class="pre">-9.580078125</span></tt> would still have 53 and 9—those numbers are always small enough that there’s not much point changing them to something else. That just left me with the task of compressing the numerals after the decimal point.</p>
<p>I had to account for the possibility of a string of zeroes, and chose a rude hack for this: the first numeral in my compressed number would always represent how many zeroes there were after the decimal point. (I intend to only deal with about 18 digits after the point, so there’s no chance of there being more than 63 zeroes in any data I’m planning to accept.) This means an extra digit in all cases where there are no zeroes, which is unfortunate.</p>
<p>After the zeroes are handled, I convert the rest to a base 64 number—which is really a string composed of the characters <tt class="docutils literal"><span class="pre">[0-9a-zA-Z_*]</span></tt>—using the method of storing the modulo 64 of the number and then dividing by 64 and repeating. I had to look up this method because I’d entirely forgotten how to convert from different base systems.</p>
<p>I got this working, and it converts e.g.</p>
<pre class="literal-block">
53.10680448323265, -9.580078125
</pre>
<p>to:</p>
<pre class="literal-block">
53.02rqYl0X1, -9.0yAQEJ
</pre>
<p>Unfortunately, I’m not that impressed with those results. Yes, we get from 17 to 12 and 12 to 9 characters, but I’m not convinced that’s sufficient progress to make the whole thing worth it.</p>
<p>At this point a certain degree of madness crept into the proceedings.</p>
<p>Clearly, the problem wasn’t with the overall approach, but with the disgraceful paucity of symbols. 64 just wasn’t a large enough base. Using a larger base would ensure fewer characters to represent large numbers. The only problem here is that while progressing from zero to 63 with <tt class="docutils literal"><span class="pre">[0-9a-zA-Z_*]</span></tt> makes at least some logical sense to most people familiar with the English alphabet, how to go beyond that?</p>
<p>I started looking at larger character sets. Unicode can be supported in URLs (e.g. <a class="reference external" href="http://?.ws/??">http://?.ws/??</a>), so why not start using whatever Unicode symbols make sense in a higher base system?</p>
<p>I thought that base 128 would be ideal, but ran into immediate problems. Unfortunately, there doesn’t seem to be any single additional feature or accent that’s available for all of the letters of the English alphabet—I looked for dots, macrons, umlauts, overlines, underlines&#8230; I even looked at the possibility of <a class="reference external" href="http://www.fileformat.info/convert/text/upside-down-map.htm">upside-down letters</a>, but not all of them are supported. If they were, I might have pursued that, but there’s an additional problem: they don’t aid experimentation.</p>
<p>I wanted the user of this shortening system to be able to change the characters with relative ease, and once you get into additional character sets, that’s tricky. Even if the upside-down letters had all been available, and the user realized that the progression was something like zero to nine in numerals, ten to thirty-five in lowercase letters, thirty-six to sixty-one in uppercase letters, sixty-two to eighty-seven in upside-down lowercase letters, eighty-eight to one hundred and thirteen in upside-down uppercase letters, and the remaining fourteen numbers in some pseudo-logical progression through (URL-safe) other symbols, how could they apply this knowledge to manipulate the strings? I don’t know of any OS that supports easily producing any of those upside-down letters. The same goes for any of the other alterations I considered, such as dots, umlauts, etc.</p>
<p>Having spent plenty of time exploring this, I eventually backed off it, and decided that my implementation took my approach about as far as it would go. We’ll see if any of the others end up with a better solution.</p>
<p>Incidentally, one positive aspect of my way of doing it is that unlike with traditional URL shorteners, no storage would be necessary, just a translation service, which could be trivially written in just about any language.</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/geolocation/" rel="tag">geolocation</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a>, <a href="http://tadhg.com/wp/tag/web-development/" rel="tag">web-development</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2009/11/17/addons-mozilla-org-moving-from-cakephp-to-django/">addons.mozilla.org Moving from CakePHP to Django</a> <span class="related-post-date timestamp">Tue 17 Nov 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/28/better-rest-wordpress-pipeline/">Better reST–WordPress Pipeline</a> <span class="related-post-date timestamp">Tue 28 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/16/some-character-encoding-gotchas/">Some Character Encoding Gotchas</a> <span class="related-post-date timestamp">Thu 16 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/14/blog-workflow-with-restructuredtext/">Blog Workflow with reStructuredText</a> <span class="related-post-date timestamp">Tue 14 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/06/26/python-syntax-highlighting-for-star-light/">Python Syntax Highlighting for star-light</a> <span class="related-post-date timestamp">Fri 26 Jun 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/06/12/pylons-via-apache-port-issues/">Pylons Via Apache Port Issues</a> <span class="related-post-date timestamp">Fri 12 Jun 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/06/09/pywebsf-meetup-for-sf-area-python-web-developers/">PyWebSF: Meetup for SF-Area Python Web Developers</a> <span class="related-post-date timestamp">Tue 09 Jun 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/01/27/some-minor-software-projects/">Some Minor Software Projects</a> <span class="related-post-date timestamp">Sun 27 Jan 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/01/15/sfmagicorg-rewrite-planning-data-entry/">sfmagic.org Rewrite: Planning Data Entry</a> <span class="related-post-date timestamp">Tue 15 Jan 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/01/14/sfmagicorg-rewrite-head-to-head-done/">sfmagic.org Rewrite: Head-to-Head Done</a> <span class="related-post-date timestamp">Mon 14 Jan 2008</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2009/12/08/gps-urls-math-python-featuritis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Open Source Thanks</title>
		<link>http://tadhg.com/wp/2009/11/26/open-source-thanks/</link>
		<comments>http://tadhg.com/wp/2009/11/26/open-source-thanks/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 07:54:28 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2422</guid>
		<description><![CDATA[It’s traditional on Thanksgiving to list things you’re thankful for. It struck me today that I should be extremely thankful for the existence of free software, and the contributions of thousands and thousands of programmers who have made their work freely available for others to use.

When I startd on a path towards software engineering, there [...]]]></description>
			<content:encoded><![CDATA[<p>It’s traditional on Thanksgiving to list things you’re thankful for. It struck me today that I should be extremely thankful for the existence of free software, and the contributions of thousands and thousands of programmers who have made their work freely available for others to use.<br />
<span id="more-2422"></span><br />
When I startd on a path towards software engineering, there wasn’t as much softwre libre around. The server-side operating systems and services did exist, and <a class="reference external" href="http://httpd.apache.org/">Apache</a> is one of the first of those I used at any serious level. The first “consumer-oriented” piece of open source code I used regularly was, I think, <a class="reference external" href="http://mamedev.org/">MAME</a>. I loved the concept of open source as soon as I encountered it, however, and gradually I’ve adopted more and more of it.</p>
<p>Apart from a few experiments, I haven’t gone fully to an open source platform, but there’s not a lot other than my OS that’s proprietary at this point. (That’s on the desktop side—on the server side everything is Free Software.) So I’m extremely thankful that as I’ve tried to adopt it fully, more and more people have contributed, so that almost everything I use regularly on the desktop side now is open source software:</p>
<ul>
<li><a class="reference external" href="http://www.mozilla.com/firefox/">Firefox</a> for browsing.</li>
<li><a class="reference external" href="http://www.mozilla.com/firefox/">jEdit</a> for writing and coding.</li>
<li><a class="reference external" href="http://www.mozillamessaging.com/thunderbird/">Thunderbird</a> for email.</li>
<li><a class="reference external" href="http://www.videolan.org/vlc/">VLC</a> for video.</li>
<li><a class="reference external" href="http://www.getsongbird.com/">Songbird</a> for music.</li>
<li><a class="reference external" href="http://www.openoffice.org/">OpenOffice.org</a> for when I have to interactively deal with RTF or .doc files.</li>
<li><a class="reference external" href="http://adium.im/">Adium</a> for IM.</li>
<li><a class="reference external" href="http://www.inkscape.org/">Inkscape</a> for vector graphics.</li>
<li><a class="reference external" href="http://www.gimp.org/">The GIMP</a> for bitmap graphics (admittedly I still have some issues here, but don’t do enough bitmap work at this point to justify giving up on The GIMP).</li>
<li><a class="reference external" href="http://subversion.tigris.org/">Subversion</a> for version control.</li>
</ul>
<p>That covers almost everything. I’ll move to a Free desktop OS at some point. The only other tool I really want that I haven’t found in the open source world yet is photo management software. That’s a small gap, and for all the excellent software that I can use now that’s non-proprietary, I’m thankful.</p>
<p>To all you open source and free software contributors out there: thank you. You rock.</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/personal/" rel="tag">personal</a>, <a href="http://tadhg.com/wp/tag/software/" rel="tag">software</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2009/09/24/rtf_word_restructuredtext-toolchain/">RTF/Word–reStructuredText Toolchain</a> <span class="related-post-date timestamp">Thu 24 Sep 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/28/better-rest-wordpress-pipeline/">Better reST–WordPress Pipeline</a> <span class="related-post-date timestamp">Tue 28 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/14/blog-workflow-with-restructuredtext/">Blog Workflow with reStructuredText</a> <span class="related-post-date timestamp">Tue 14 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2007/03/09/lastfm/">Last.fm</a> <span class="related-post-date timestamp">Fri 09 Mar 2007</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/03/09/trying-d-cubed-for-task-management/">Trying d-cubed for Task Management</a> <span class="related-post-date timestamp">Tue 09 Mar 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/03/08/inkscape/">Inkscape</a> <span class="related-post-date timestamp">Mon 08 Mar 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/16/some-vim-script-implementation-testing-and-hackery/">Some Vim Script Implementation, Testing, and Hackery</a> <span class="related-post-date timestamp">Tue 16 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/02/14/first-post-with-vim/">First Post With Vim</a> <span class="related-post-date timestamp">Sun 14 Feb 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/17/better-word-count-in-vim/">Better Word Count in Vim</a> <span class="related-post-date timestamp">Sun 17 Jan 2010</span></li><li class="related-post"><a href="http://tadhg.com/wp/2010/01/01/2010-goals/">2010 Goals</a> <span class="related-post-date timestamp">Fri 01 Jan 2010</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2009/11/26/open-source-thanks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>addons.mozilla.org Moving from CakePHP to Django</title>
		<link>http://tadhg.com/wp/2009/11/17/addons-mozilla-org-moving-from-cakephp-to-django/</link>
		<comments>http://tadhg.com/wp/2009/11/17/addons-mozilla-org-moving-from-cakephp-to-django/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 04:43:29 +0000</pubDate>
		<dc:creator>Tadhg</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://tadhg.com/wp/?p=2400</guid>
		<description><![CDATA[This post details why they’re making the move. I find this of interest partly because it’s a move from a very popular web language (PHP) to one that’s become vastly more popular in the last couple of years (Python), and also because Django is the one major Python framework I haven’t tried out yet. Because [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://micropipes.com/blog/2009/11/17/amo-development-changes-in-2010/" title="AMO Development Changes in 2010" >This post</a> details why they’re making the move. I find this of interest partly because it’s a move from a very popular web language (PHP) to one that’s become vastly more popular in the last couple of years (Python), and also because Django is the one major Python framework I haven’t tried out yet. Because of my liking for Python, I have a personal bias that makes me happy to see a prominent project such as this one move to the language.</p>
<p>I find it odd that they’re going from Subversion to git instead of to Mercurial, but I like the fact that they’re moving their documentation to the reStructuredText-based <a class="reference external" href="http://sphinx.pocoo.org/">Sphinx</a>.</p>
<p>Tags: <a href="http://tadhg.com/wp/tag/coding/" rel="tag">coding</a>, <a href="http://tadhg.com/wp/tag/python/" rel="tag">python</a>, <a href="http://tadhg.com/wp/tag/web-development/" rel="tag">web-development</a></p><h4 class='related-posts-header'>Related Posts</h4><ul class="related-posts-list"><li class="related-post"><a href="http://tadhg.com/wp/2009/12/08/gps-urls-math-python-featuritis/">GPS, URLs, Math, Python, Featuritis</a> <span class="related-post-date timestamp">Tue 08 Dec 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/28/better-rest-wordpress-pipeline/">Better reST–WordPress Pipeline</a> <span class="related-post-date timestamp">Tue 28 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/16/some-character-encoding-gotchas/">Some Character Encoding Gotchas</a> <span class="related-post-date timestamp">Thu 16 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/07/14/blog-workflow-with-restructuredtext/">Blog Workflow with reStructuredText</a> <span class="related-post-date timestamp">Tue 14 Jul 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/06/26/python-syntax-highlighting-for-star-light/">Python Syntax Highlighting for star-light</a> <span class="related-post-date timestamp">Fri 26 Jun 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/06/12/pylons-via-apache-port-issues/">Pylons Via Apache Port Issues</a> <span class="related-post-date timestamp">Fri 12 Jun 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2009/06/09/pywebsf-meetup-for-sf-area-python-web-developers/">PyWebSF: Meetup for SF-Area Python Web Developers</a> <span class="related-post-date timestamp">Tue 09 Jun 2009</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/01/27/some-minor-software-projects/">Some Minor Software Projects</a> <span class="related-post-date timestamp">Sun 27 Jan 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/01/15/sfmagicorg-rewrite-planning-data-entry/">sfmagic.org Rewrite: Planning Data Entry</a> <span class="related-post-date timestamp">Tue 15 Jan 2008</span></li><li class="related-post"><a href="http://tadhg.com/wp/2008/01/14/sfmagicorg-rewrite-head-to-head-done/">sfmagic.org Rewrite: Head-to-Head Done</a> <span class="related-post-date timestamp">Mon 14 Jan 2008</span></li></ul>]]></content:encoded>
			<wfw:commentRss>http://tadhg.com/wp/2009/11/17/addons-mozilla-org-moving-from-cakephp-to-django/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
