<?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"
	>

<channel>
	<title>Tsukasa's ramblings</title>
	<atom:link href="http://blag.tsukasa.net.au/feed/" rel="self" type="application/rss+xml" />
	<link>http://blag.tsukasa.net.au</link>
	<description>Tech ramblings of Greg Darke, a University of Sydney student</description>
	<pubDate>Sun, 04 Jan 2009 14:04:11 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.5</generator>
	<language>en</language>
			<item>
		<title>Multiplayer Snake</title>
		<link>http://blag.tsukasa.net.au/2009/01/05/multiplayer-snake/</link>
		<comments>http://blag.tsukasa.net.au/2009/01/05/multiplayer-snake/#comments</comments>
		<pubDate>Sun, 04 Jan 2009 14:04:11 +0000</pubDate>
		<dc:creator>Tsukasa</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blag.tsukasa.net.au/?p=57</guid>
		<description><![CDATA[Well, here we have yet another challenge&#8230; Though this one does not involve any prizes, as I want my students at the NCSS camp to actually do their projects and not spend all their time on my competition.
So, what is has to be done here? Well it is quite simple really&#8230; Design a bot to [...]]]></description>
			<content:encoded><![CDATA[<p>Well, here we have yet another challenge&#8230; Though this one does not involve any prizes, as I want my students at the <a href="http://www.ncss.edu.au/">NCSS</a> camp to actually do their projects and not spend all their time on my competition.</p>
<p>So, what is has to be done here? Well it is quite simple really&#8230; Design a bot to play snake for you. I am forcing people who submit to write their solution in python (though there is no real need, other than I am teaching python at the moment). The input/output of the program is quite simple&#8230; The output consists of one of the following four letters: &#8216;U&#8217;, &#8216;D&#8217;, &#8216;L&#8217;, &#8216;R&#8217; (corresponding to Up, Down, Left and Right).</p>
<p>The input consists of the following:<br />
<code>width height snake_id<br />
<i>board layout</i></code><br />
An example is:<br />
<code>7 7 A<br />
..*....<br />
..A....<br />
..a....<br />
..a....<br />
.......<br />
.......<br />
..Bbbb.</code></p>
<p>Where <code>*</code> is an apple, <code>.</code> is an empty cell, the uppercase letters are the head&#8217;s of the snakes, with the lowercase being the body.</p>
<p>Code for the engine is located in my repository under the <a href="http://tsukasa.net.au/~hg/snakes">snake project</a>. Submissions should be made to my email address, or in person.</p>
<p>The initial competition will have bots go up against each other, with no time limit given per move. The later rounds will ensure that all bots get equal cpu time (by running the faster bots more often).</p>
]]></content:encoded>
			<wfw:commentRss>http://blag.tsukasa.net.au/2009/01/05/multiplayer-snake/feed/</wfw:commentRss>
		</item>
		<item>
		<title>PyGolf - Winner of competition 1</title>
		<link>http://blag.tsukasa.net.au/2008/11/29/pygolf-winner-of-competition-1/</link>
		<comments>http://blag.tsukasa.net.au/2008/11/29/pygolf-winner-of-competition-1/#comments</comments>
		<pubDate>Sat, 29 Nov 2008 12:15:27 +0000</pubDate>
		<dc:creator>Tsukasa</dc:creator>
		
		<category><![CDATA[golf]]></category>

		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blag.tsukasa.net.au/?p=55</guid>
		<description><![CDATA[Well the deadline has come and passed, and we have a clear winner. That winner is Katie. Her solution comes in at a tiny 121 characters, with the closest solution coming from Tim with 187 characters.
The main difference came down to the fact that Katie decided to avoid using the regular expression that was given [...]]]></description>
			<content:encoded><![CDATA[<p>Well the deadline has come and passed, and we have a clear winner. That winner is <a rel="friend met" href="http://katharos.id.au/blog/">Katie</a>. Her solution comes in at a tiny 121 characters, with the closest solution coming from Tim with 187 characters.</p>
<p>The main difference came down to the fact that Katie decided to avoid using the regular expression that was given in the sample, and just parse the lines with <code>str.split</code>.<br />
So without much more talking, here is the winning solution.<br />
<!-- File:081129_katies_winning_solution.py -->
<div class="codeBlock">
<pre class="VimPre"><span class="VimPreProc">import</span> sys
s=sum(([l[0]]*int(l[-1])<span class="VimStatement">for</span> l <span class="VimStatement">in</span> map(str.split,sys.stdin)<span class="VimStatement">if</span> l[-1]!=<span class="VimNormal">'</span><span class="VimConstant">-</span><span class="VimNormal">'</span>),[])
<span class="VimStatement">for</span> x <span class="VimStatement">in</span> set(s):<span class="VimStatement">print</span> x,s.count(x)</pre>
</div>
<p>It is also interesting to note how she uses the sum function to append a set of lists together.</p>
]]></content:encoded>
			<wfw:commentRss>http://blag.tsukasa.net.au/2008/11/29/pygolf-winner-of-competition-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Python golf competition</title>
		<link>http://blag.tsukasa.net.au/2008/11/23/python-golf-competition/</link>
		<comments>http://blag.tsukasa.net.au/2008/11/23/python-golf-competition/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 13:21:46 +0000</pubDate>
		<dc:creator>Tsukasa</dc:creator>
		
		<category><![CDATA[golf]]></category>

		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blag.tsukasa.net.au/?p=53</guid>
		<description><![CDATA[I have written a few entries on python golf before, but I have now decided to make an official competition from it. The rules are fairly simple: I pose a problem simple problem which must be solved (in python) in the lowest number of characters (where a new line counts as one byte). Solutions may [...]]]></description>
			<content:encoded><![CDATA[<p>I have written a few entries on python golf before, but I have now decided to make an official competition from it. The rules are fairly simple: I pose a problem simple problem which must be solved (in python) in the lowest number of characters (where a new line counts as one byte). Solutions may be written for any 2.x version of python (ie, 2.3, 2.4, 2.5 or 2.6), and may use any library found on default install on a Debian machine.</p>
<p>Solutions must be emailed to me. In the case where two people have the same character count, the solution that arrived in my inbox first will be declared the winner (this is to stop people from playing with the date header in the email ^^). The winner will receive a chocolate bar or coffee &#8212; their choice.</p>
<p>The problem this week is one of parsing log files. You must parse a log file in the <a href="http://httpd.apache.org/docs/2.2/logs.html#common">common log format</a> that will be given on to your program on stdin. You must then print on stdout the amount of data that was sent to each ip address (and the ip address). A sample program has been provided:</p>
<p><!-- File:081124_sample_solution.py -->
<div class="codeBlock">
<pre class="VimPre"><span class="VimComment">#!/usr/bin/env python2.5</span>
<span class="VimComment"># Copyright 2008 Greg Darke &lt;greg+laptop@tsukasa.net.au&gt;</span>
<span class="VimComment"># Licensed for distribution under the GPL version 2, check COPYING for details</span>
<span class="VimComment"># Sample program to show the output format for the python golf problem posed at</span>
<span class="VimComment"># <a href="http://blag.tsukasa.net.au/2008/11/23/python-golf-competitionpython-golf-competition/">http://blag.tsukasa.net.au/2008/11/23/python-golf-competitionpython-golf-competition/</a></span>

<span class="VimPreProc">import</span> re, sys

<span class="VimStatement">def</span> <span class="VimIdentifier">main</span>():
    clf_regexp = re.compile(<span class="VimNormal">r'''</span><span class="VimConstant">^(\S+)\s(\S+)\s(\S+)\s\[([^\]]*)\]\s&quot;([^&quot;]*)&quot;\s(\d*)\s(\d*)$</span><span class="VimNormal">'''</span>)
    mapping = {}

    <span class="VimStatement">for</span> line <span class="VimStatement">in</span> sys.stdin:
        m = clf_regexp.match(line)
        <span class="VimStatement">if</span> <span class="VimStatement">not</span> m:
            <span class="VimStatement">continue</span>
        ip, _, _, _, _, _, size = m.groups()
        size = int(size)

        <span class="VimStatement">if</span> ip <span class="VimStatement">not</span> <span class="VimStatement">in</span> mapping:
            mapping[ip] = 0

        mapping[ip] += size

    <span class="VimStatement">for</span> ip <span class="VimStatement">in</span> mapping:
        <span class="VimStatement">print</span> <span class="VimNormal">'</span><span class="VimConstant">%s %d</span><span class="VimNormal">'</span> % (ip, mapping[ip])

<span class="VimStatement">if</span> __name__ == <span class="VimNormal">&quot;</span><span class="VimConstant">__main__</span><span class="VimNormal">&quot;</span>:
    main()</pre>
</div>
<p>Solutions will be accepted until 11:59:59pm(EDT) on Friday 28th November 2008.</p>
]]></content:encoded>
			<wfw:commentRss>http://blag.tsukasa.net.au/2008/11/23/python-golf-competition/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Moving away from Mail.app</title>
		<link>http://blag.tsukasa.net.au/2008/11/12/moving-away-from-mailapp/</link>
		<comments>http://blag.tsukasa.net.au/2008/11/12/moving-away-from-mailapp/#comments</comments>
		<pubDate>Wed, 12 Nov 2008 04:16:40 +0000</pubDate>
		<dc:creator>Tsukasa</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blag.tsukasa.net.au/?p=48</guid>
		<description><![CDATA[As most people know, I have moved away from using Apple&#8217;s Mail.app as my email client. I now use mutt to perform all of my mail duties&#8230; or, so I thought.
The other day I decided to use iCal to send an event invitation to a friend. When I clicked on the send button, I was [...]]]></description>
			<content:encoded><![CDATA[<p>As most people know, I have moved away from using Apple&#8217;s Mail.app as my email client. I now use <a href="http://www.mutt.org/">mutt</a> to perform all of my mail duties&#8230; or, so I thought.</p>
<p>The other day I decided to use iCal to send an event invitation to a friend. When I clicked on the send button, I was greeted with a copy of Mail.app, not exactly I wanted. At this point I changed the default Mail application to mutt (via iTerm).</p>
<p>Now you would expect iCal to listen to this setting, but alas, the mail was still (automatically) sent with Mail.app.</p>
<p>After a lot of investigating, I discovered there is a apple script within the iCal app bundle. The script of interest is <code>/Applications/iCal.app/Contents/Resources/Mail.applescript</code>. After spending a few hours learning applescript, I came up with a solution. You will need to replace the file <code >/Applications/iCal.app/Contents/Resources/Mail.applescript</code> with the one available from <a href="http://tsukasa.net.au/~hg/greg_stuff/file/tip/osx/Mail.applescript">my repositories</a>.</p>
<p>Once you have replaced this file, you must then recompile the script: <code>osacompile -o /Applications/iCal.app/Contents/Resources/Scripts/Mail.scpt /Applications/iCal.app/Contents/Resources/Mail.applescript</code></p>
<p>Note: You will need to have at the mail script and modify it so that it points to the correct version of mutt on your system.</p>
]]></content:encoded>
			<wfw:commentRss>http://blag.tsukasa.net.au/2008/11/12/moving-away-from-mailapp/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Not so smooth transition to xubuntu-intrepid</title>
		<link>http://blag.tsukasa.net.au/2008/11/04/not-so-smooth-transition-to-xubuntu-intrepid/</link>
		<comments>http://blag.tsukasa.net.au/2008/11/04/not-so-smooth-transition-to-xubuntu-intrepid/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 03:14:23 +0000</pubDate>
		<dc:creator>Tsukasa</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://blag.tsukasa.net.au/?p=43</guid>
		<description><![CDATA[So James and I decided to take the plunge and install the intrepid update on a newly installed machine we had here (it had had xubuntu-hardy installed only a week earlier).
This machine was using the nvidia binary package, but other than that did not have anything that was from a restricted repo.
Upon the upgrade we [...]]]></description>
			<content:encoded><![CDATA[<p>So James and I decided to take the plunge and install the intrepid update on a newly installed machine we had here (it had had xubuntu-hardy installed only a week earlier).</p>
<p>This machine was using the nvidia binary package, but other than that did not have anything that was from a restricted repo.</p>
<p>Upon the upgrade we found that the nvidia package no longer works. In fact, it no longer compiles the kernel module (even though it claims that the package is installed correctly). This left us without an X11 server. Even when trying to use the nv driver we could not get it to work.</p>
<p>On a side note: We found that the nv driver is now no-longer installed by default.</p>
<p>After about an hour of trying to get things to work, we decided that we will just have to live with the vesa driver. Although this makes the system slow, at least we can use X11.</p>
<p>Another thing I noticed, is that it now spams me with an annoying motd, I mean sure system stats on login is may be nice for some people, but I already have most of that coded in my scripts. The easiest way to get rid of this is to remove the package landscape-client with the following command:<br />
<code>sudo aptitude purge landscape-client</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blag.tsukasa.net.au/2008/11/04/not-so-smooth-transition-to-xubuntu-intrepid/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Simple cgi script to grab images from your Mac&#8217;s built in iSight camera</title>
		<link>http://blag.tsukasa.net.au/2008/10/07/simple-cgi-script-to-grab-images-from-your-macs-built-in-isight-camera/</link>
		<comments>http://blag.tsukasa.net.au/2008/10/07/simple-cgi-script-to-grab-images-from-your-macs-built-in-isight-camera/#comments</comments>
		<pubDate>Tue, 07 Oct 2008 03:49:58 +0000</pubDate>
		<dc:creator>Tsukasa</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blag.tsukasa.net.au/?p=41</guid>
		<description><![CDATA[While I was meant to be working on my thesis, I decided to update my little script to grab images from the built in iSight camera. The older version depended upon a instance of procfs to be started from within a login shell (which is not always possible).
To get around this, I stared looking for [...]]]></description>
			<content:encoded><![CDATA[<p>While I was meant to be working on my thesis, I decided to update my little script to grab images from the built in iSight camera. The older version depended upon a instance of <a href="http://pdb.finkproject.org/pdb/package.php/procfs">procfs</a> to be started from within a login shell (which is not always possible).</p>
<p>To get around this, I stared looking for a way to inject a process into a particular mach bootstrap session (After reading the OSX internals book, I knew this was where I should be looking). Now, I will not claim that this script is the best thing I have written&#8230; It requires you to set up a rule in the sudoers file to allow the _www user to execute the specified sudo command (as root). I will leave writing this line as an exercise to the user (I have written one version, it is just not completely secure). You will also have to grab the isightcapture binary from off the net, and update the script with the correct location.</p>
<p><!-- File:081007_webcam.cgi -->
<div class="codeBlock">
<pre class="VimPre"><span class="VimComment">#!/bin/bash</span>

<span class="VimIdentifier">function</span> <span class="VimIdentifier">pgrep {</span>
    ps -A -o <span class="VimIdentifier">pid</span>=,<span class="VimIdentifier">command</span>= <span class="VimStatement">|</span> <span class="VimStatement">grep</span> <span class="VimStatement">&quot;</span><span class="VimPreProc">$1</span><span class="VimStatement">&quot;</span> <span class="VimStatement">|</span> awk <span class="VimStatement">'</span><span class="VimConstant">{ print $1; }</span><span class="VimStatement">'</span> <span class="VimStatement">|</span> <span class="VimStatement">grep</span> -v <span class="VimPreProc">$$</span>
<span class="VimIdentifier">}</span>

<span class="VimIdentifier">function</span> <span class="VimIdentifier">cleanup {</span>
    <span class="VimStatement">if </span><span class="VimStatement">[</span> <span class="VimStatement">!</span> <span class="VimStatement">-z</span> <span class="VimStatement">&quot;</span><span class="VimPreProc">$MYTEMP</span><span class="VimStatement">&quot;</span> <span class="VimStatement">]</span><span class="VimStatement">;</span> <span class="VimStatement">then</span>
        <span class="VimStatement">rm</span> -rf <span class="VimStatement">&quot;</span><span class="VimPreProc">$MYTEMP</span><span class="VimStatement">&quot;</span>
    <span class="VimStatement">fi</span>
<span class="VimIdentifier">}</span>

<span class="VimIdentifier">MYTEMP</span>=<span class="VimStatement">&quot;</span><span class="VimPreProc">$(</span><span class="VimSpecial">mktemp -d</span><span class="VimPreProc">)</span><span class="VimStatement">&quot;</span>
<span class="VimStatement">trap</span> <span class="VimStatement">&quot;</span><span class="VimConstant">cleanup</span><span class="VimStatement">&quot;</span> <span class="VimConstant">15</span> <span class="VimConstant">0</span>

<span class="VimIdentifier">LOGIN_WINDOW_PID</span>=<span class="VimStatement">&quot;</span><span class="VimPreProc">$(</span><span class="VimSpecial">pgrep loginwindow.app</span><span class="VimPreProc">)</span><span class="VimStatement">&quot;</span>
<span class="VimIdentifier">OUTPUT_FILENAME</span>=<span class="VimStatement">&quot;</span><span class="VimPreProc">${</span><span class="VimPreProc">MYTEMP</span><span class="VimPreProc">}</span><span class="VimConstant">/isightcapture.jpg</span><span class="VimStatement">&quot;</span>
sudo launchctl bsexec <span class="VimStatement">&quot;</span><span class="VimPreProc">${</span><span class="VimPreProc">LOGIN_WINDOW_PID</span><span class="VimPreProc">}</span><span class="VimStatement">&quot;</span> /Users/gregdarke/bin/isightcapture <span class="VimSpecial">-t</span> jpg <span class="VimStatement">&quot;</span><span class="VimPreProc">${</span><span class="VimPreProc">OUTPUT_FILENAME</span><span class="VimPreProc">}</span><span class="VimStatement">&quot;</span>

<span class="VimStatement">echo</span><span class="VimConstant"> -en </span><span class="VimStatement">'</span><span class="VimConstant">Content-type: image/jpeg\r\n\r\n</span><span class="VimStatement">'</span>
cat <span class="VimStatement">&quot;</span><span class="VimPreProc">${</span><span class="VimPreProc">OUTPUT_FILENAME</span><span class="VimPreProc">}</span><span class="VimStatement">&quot;</span></pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blag.tsukasa.net.au/2008/10/07/simple-cgi-script-to-grab-images-from-your-macs-built-in-isight-camera/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Of databases and repositories</title>
		<link>http://blag.tsukasa.net.au/2008/10/06/of-databases-and-repositories/</link>
		<comments>http://blag.tsukasa.net.au/2008/10/06/of-databases-and-repositories/#comments</comments>
		<pubDate>Mon, 06 Oct 2008 12:13:41 +0000</pubDate>
		<dc:creator>Tsukasa</dc:creator>
		
		<category><![CDATA[Mercurial]]></category>

		<guid isPermaLink="false">http://blag.tsukasa.net.au/?p=39</guid>
		<description><![CDATA[One thing that most programmers will cringe at, is the thought of placing a database into a version control repository such as subversion or mercurial. Now I know that many of have done this for various reasons (I know I am guilty of it myself).
The point of this post is to show how this can [...]]]></description>
			<content:encoded><![CDATA[<p>One thing that most programmers will cringe at, is the thought of placing a database into a version control repository such as <a href="http://subversion.tigris.org/">subversion</a> or <a href="http://www.selenic.com/mercurial/">mercurial</a>. Now I know that many of have done this for various reasons (I know I am guilty of it myself).</p>
<p>The point of this post is to show how this can be made a little nicer under mercurial using <a href="http://www.selenic.com/mercurial/wiki/index.cgi/EncodeDecodeFilter">encode/decode filters</a>. With a carefully constructed set of filters, you are able to actually perform text diffs and make sane merges between repositories. All you have to do is drop the following into your hgrc file (either the one in your project or ~/.hgrc):</p>
<p><!-- File:081006_encode_decode_filter.hgrc -->
<div class="codeBlock">
<pre class="VimPre">[encode]
data.db = tempfile: sqlite3 INFILE .dump &gt; OUTFILE

[decode]
data.db = tempfile: sqlite3 OUTFILE '.read INFILE'</pre>
</div>
<p>This requires that you have the sqlite3 binary installed, otherwise you will end up with a data.db file containing the raw sql used to generate the database.</p>
]]></content:encoded>
			<wfw:commentRss>http://blag.tsukasa.net.au/2008/10/06/of-databases-and-repositories/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Recursive tuples</title>
		<link>http://blag.tsukasa.net.au/2008/09/26/recursive-tuples/</link>
		<comments>http://blag.tsukasa.net.au/2008/09/26/recursive-tuples/#comments</comments>
		<pubDate>Fri, 26 Sep 2008 12:05:44 +0000</pubDate>
		<dc:creator>Tsukasa</dc:creator>
		
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blag.tsukasa.net.au/?p=13</guid>
		<description><![CDATA[Now,
I have been thinking about this for a few days now&#8230; Is it possible to create a tuple in python that refers to itself. I don&#8217;t mean via some other object, so the following does not count:


def recursive():
    l = []
    t = (l,)
    l.append(t)
  [...]]]></description>
			<content:encoded><![CDATA[<p>Now,<br />
I have been thinking about this for a few days now&#8230; Is it possible to create a tuple in python that refers to itself. I don&#8217;t mean via some other object, so the following does not count:<br />
<!-- File:080926_recursive.py -->
<div class="codeBlock">
<pre class="VimPre"><span class="VimStatement">def</span> <span class="VimIdentifier">recursive</span>():
    l = []
    t = (l,)
    l.append(t)
    <span class="VimStatement">return</span> t</pre>
</div>
<p>I believe it is possible  to do directly from C, but I can not think of a way to do it from within python.</p>
<p>The idea of creating a recursive tuple was spawned from  this little comment I found in the <a href="http://www.python.org/doc/current/lib/module-pickle.html">pickle</a> source code: &#8220;&#8230; recursive  tuples are a rare thing&#8221;. At first I thought it was talking about a tuple that directly refers to itself, but then figured that it must be talking about tuple&#8217;s that indirectly refer to themselves.</p>
]]></content:encoded>
			<wfw:commentRss>http://blag.tsukasa.net.au/2008/09/26/recursive-tuples/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Python DNS server</title>
		<link>http://blag.tsukasa.net.au/2008/09/21/python-dns-server/</link>
		<comments>http://blag.tsukasa.net.au/2008/09/21/python-dns-server/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 11:53:34 +0000</pubDate>
		<dc:creator>Tsukasa</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blag.tsukasa.net.au/?p=12</guid>
		<description><![CDATA[Can anybody figure out why these links are related?

http://pydns.sourceforge.net/index.html
http://www.doxpara.com

]]></description>
			<content:encoded><![CDATA[<p>Can anybody figure out why these links are related?</p>
<ul>
<li>http://pydns.sourceforge.net/index.html</li>
<li>http://www.doxpara.com</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blag.tsukasa.net.au/2008/09/21/python-dns-server/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Significant whitespace</title>
		<link>http://blag.tsukasa.net.au/2008/09/18/significant-whitespace/</link>
		<comments>http://blag.tsukasa.net.au/2008/09/18/significant-whitespace/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 01:19:09 +0000</pubDate>
		<dc:creator>Tsukasa</dc:creator>
		
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blag.tsukasa.net.au/?p=11</guid>
		<description><![CDATA[One of the most common complains I hear from people about python is that whitespace is significant. I would have to disagree with them, I think that significant whitespace is an excellent feature in a programming language. Though only if it is implemented correctly, which I believe it is not in python.
My major complaint about [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most common complains I hear from people about python is that whitespace is significant. I would have to disagree with them, I think that significant whitespace is an excellent feature in a programming language. Though <em>only</em> if it is implemented correctly, which I believe it is not in python.</p>
<p>My major complaint about python is that it allows users to mix both tabs and spaces, and also different amounts of spaces to mark a code block. I believe that python should not allow this. I think a there should be one consistent method of indenting used within a file. I would love if this method was tabs, but I don&#8217;t really mind that much if it spaces.</p>
<p>This problem usually occurs when you have multiple people modifying code, over an extended period of time. Each person has their own preferred style of indenting code, and will use it (generally without thinking about it).</p>
<p>A friend of mine recently came across this exact problem, and in an attempt to make the file &#8220;sane&#8221; used a regular expression to fix the whitespace in the file. This ended up being a major problem, as their had inadvertently changed the meaning of the code, by subtle changing the indentation levels of the code. I came up with the idea of parsing the python program, then outputting the program back from the parse tree (thus ensuring the meaning of the code is unchanged).</p>
<p>After being shown the <a href="http://www.python.org/doc/2.5.2/lib/module-compiler.html">compiler module</a>, I started playing around with some code to reproduce code from the abstract parse tree that was provided to me. When I went looking for documentation, I found that there is a piece of sample code provided with the python source that does exactly what I was after (After a few bug fixes). This example is called unparse.py (located in the Demo/parser/ directory of the python 2.5.x source code).</p>
<p>I suggest anybody who is trying to fix inconsistent indentation in a python file to look at this program. There are a few things to note though:
<ul>
<li>The code must already work as wanted</li>
<li>This program will strip all comments from the program</li>
<li>The code will loose all of it&#8217;s layout - that is, code that may have been split over multiple lines, will now be over one line</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blag.tsukasa.net.au/2008/09/18/significant-whitespace/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
