<?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>machine-envy &#187; python</title>
	<atom:link href="http://www.machine-envy.com/blog/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.machine-envy.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 27 Jul 2010 23:23:10 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>pivot tables with sqlalchemy</title>
		<link>http://www.machine-envy.com/blog/2009/10/30/pivot-tables-with-sqlalchemy/</link>
		<comments>http://www.machine-envy.com/blog/2009/10/30/pivot-tables-with-sqlalchemy/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 18:23:12 +0000</pubDate>
		<dc:creator>James Casbon</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.machine-envy.com/blog/?p=243</guid>
		<description><![CDATA[If your database doesn&#8217;t support pivots, here is a quick technique to get pivot columns with sqlalchemy

import operator
from sqlalchemy.sql import case, func, select

def pivot_report(report, pivot_on=None, pivot_columns=None, pivot_func=func.sum,
                    non_pivot_columns=None, group_by=None):
    """ produce a pivot [...]]]></description>
			<content:encoded><![CDATA[<p>If your database doesn&#8217;t support pivots, here is a quick technique to get pivot columns with sqlalchemy</p>
<pre lang="python">
import operator
from sqlalchemy.sql import case, func, select

def pivot_report(report, pivot_on=None, pivot_columns=None, pivot_func=func.sum,
                    non_pivot_columns=None, group_by=None):
    """ produce a pivot on a select

    if we have a report: 

        id, type, count
        1, white, 10
        1, black, 20
        2, white, 12
        2, black, 20

    and we want 

        id, black count, white count
        1, 20, 10
        2, 20, 12

    pass in type as the pivot_on, and [count] as pivot columns  

    """

    # find all possible values of the pivot
    pivot_values = map(
        operator.itemgetter(0),
        select([pivot_on], from_obj=[report]).distinct().execute()
    )

    # build the new pivot columns
    new_columns = [
        pivot_func(case([(pivot_on == value, column)])).label("%s %s" % (value, column))
        for value in pivot_values
        for column in pivot_columns
    ]

    return select(
        non_pivot_columns + new_columns,
        from_obj=[report],
        group_by=group_by
    )

# example code
from sqlalchemy import Table, Column, Integer, String, MetaData
from sqlalchemy import create_engine

metadata = MetaData()
example = Table('example', metadata,
    Column('id', Integer),
    Column('type', String),
    Column('count', Integer),
)

engine = create_engine('sqlite:///:memory:')
metadata.bind = engine
example.create()
example.insert().execute(
    dict(id=1, type='white', count=10),
    dict(id=1, type='black', count=20),
    dict(id=2, type='white', count=30),
    dict(id=2, type='black', count=40),
)

report = example.select()

# now build the pivot
report = pivot_report(
    report,
    pivot_on=report.c.type,
    pivot_columns=[report.c.count],
    non_pivot_columns=[report.c.id],
    group_by=[report.c.id])

for r in report.execute():
    print r.items()
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.machine-envy.com/blog/2009/10/30/pivot-tables-with-sqlalchemy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>object ceremony, dynamic languages, JSON and algebraic data types</title>
		<link>http://www.machine-envy.com/blog/2009/10/28/object-ceremony-dynamic-languages-json-and-algebraic-data-types/</link>
		<comments>http://www.machine-envy.com/blog/2009/10/28/object-ceremony-dynamic-languages-json-and-algebraic-data-types/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 17:54:12 +0000</pubDate>
		<dc:creator>James Casbon</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.machine-envy.com/blog/?p=228</guid>
		<description><![CDATA[The reason most people end up using a dynamic language is to avoid the boilerplate associated with object creation.  You know, typing &#8220;FileWriter fout = new FileWriter(&#8221;fred.txt&#8221;);&#8221; gets boring quickly.  I think this is a good enough reason to move to another language on its own.  This boilerplate is also sometimes called [...]]]></description>
			<content:encoded><![CDATA[<p>The reason most people end up using a dynamic language is to avoid the boilerplate associated with object creation.  You know, typing &#8220;FileWriter fout = new FileWriter(&#8221;fred.txt&#8221;);&#8221; gets boring quickly.  I think this is a good enough reason to move to another language on its own.  This boilerplate is also sometimes called ceremony, and I have come to realize that far from being low ceremony, dynamic languages actually <em>revolve</em> around ceremony.</p>
<p>Think of the hash of hashes, list of hashes approach that you often find in a perl, python or ruby program.  These are so useful, that they have been codified as JSON &#8211; which can simply be evaled to return your data in several languages.  Ad-hoc data structures like this have a great appeal when hacking something in python, yet you quickly get to a pain point when using them when the data doesn&#8217;t look exactly as you would expect and you need to handle exceptions and edge cases.</p>
<p>So why is the hash of hashes approach so tempting?  Because it avoids the ceremony around object creation.  Things like Python&#8217;s &#8220;__init__&#8221; and Perl&#8217;s &#8220;bless&#8221; are ceremony and are <em>necessarily</em> ceremony because  all a type in a dynamic language is just  data with some ceremony.  Clearly, perl has got a perfect name for the ceremony in &#8220;bless&#8221;.</p>
<p>The eureka moment comes when you use a typed language that is low ceremony, such as Haskell.  <a href="http://en.wikipedia.org/wiki/Algebraic_data_type">Algebraic data types</a> give you the freedom to create complex data structures without ceremony, which you can then process without the hassle involved in unpicking a big blob of JSON, which will typically need lots of switches.  Instead, you can pattern match on the type.</p>
<p>So if you went to a dynamic language to avoid the ceremony, you may well be moving in the wrong direction.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.machine-envy.com/blog/2009/10/28/object-ceremony-dynamic-languages-json-and-algebraic-data-types/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>cogent: the unsung hero of bioinformatics and python</title>
		<link>http://www.machine-envy.com/blog/2009/10/27/cogent-the-unsung-hero-of-bioinformatics-and-python/</link>
		<comments>http://www.machine-envy.com/blog/2009/10/27/cogent-the-unsung-hero-of-bioinformatics-and-python/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 16:57:53 +0000</pubDate>
		<dc:creator>James Casbon</dc:creator>
				<category><![CDATA[bioinformatics]]></category>
		<category><![CDATA[ensembl]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.machine-envy.com/blog/?p=225</guid>
		<description><![CDATA[I recently started using cogent &#8211; the COmparative GENomics Toolkit and discovered that it is an excellent piece of kit.  A google search for &#8216;python ensembl&#8216; doesn&#8217;t even show it at all, yet it definitely has the best bindings for ensembl avaiable in python &#8211; they&#8217;re based on sqlalchemy making it easy enough to [...]]]></description>
			<content:encoded><![CDATA[<p>I recently started using <a href="http://pypi.python.org/pypi/cogent">cogent &#8211; the COmparative GENomics Toolkit</a> and discovered that it is an excellent piece of kit.  A google search for &#8216;<a href="http://www.google.co.uk/search?q=python+ensembl">python ensembl</a>&#8216; doesn&#8217;t even show it at all, yet it definitely has the best <a href="http://pycogent.sourceforge.net/examples/query_ensembl.html">bindings for ensembl avaiable in python</a> &#8211; they&#8217;re based on <a href="http://www.sqlalchemy.org/">sqlalchemy</a> making it easy enough to pull of any query.  Have a look at the full list of <a href="http://pycogent.sourceforge.net/examples/index.html">examples</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.machine-envy.com/blog/2009/10/27/cogent-the-unsung-hero-of-bioinformatics-and-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing python bioinformatics tools with virtualenv and pip</title>
		<link>http://www.machine-envy.com/blog/2009/07/11/installing-python-bioinformatics-tools-with-virtualenv-and-pip/</link>
		<comments>http://www.machine-envy.com/blog/2009/07/11/installing-python-bioinformatics-tools-with-virtualenv-and-pip/#comments</comments>
		<pubDate>Sat, 11 Jul 2009 13:56:52 +0000</pubDate>
		<dc:creator>James Casbon</dc:creator>
				<category><![CDATA[bioinformatics]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.machine-envy.com/blog/?p=222</guid>
		<description><![CDATA[Python seems to have developed a decent set of tools for quickly building development environments.  I want to store my notes on how to get a good environment for bioinformatics set up quickly.
First of all, if you haven&#8217;t already, install virtualenv and pip.  Both are easy installable.  Now install virtualenv wrapper.
Now we [...]]]></description>
			<content:encoded><![CDATA[<p>Python seems to have developed a decent set of tools for quickly building development environments.  I want to store my notes on how to get a good environment for bioinformatics set up quickly.</p>
<p>First of all, if you haven&#8217;t already, install virtualenv and pip.  Both are easy installable.  Now install <a href="http://www.doughellmann.com/projects/virtualenvwrapper/">virtualenv wrapper</a>.</p>
<p>Now we are going to setup a bioinformatics environment with both biopython and pygr installed so that you can hack on them. Firstly create a new virtualenv, passing the no site packages flag to keep this clean:</p>
<p><code lang="bash">james@flapjack:~/Documents/virtualenvs$ mkvirtualenv --no-site-packages bio<br />
New python executable in bio/bin/python<br />
Installing setuptools............done.<br />
(bio)james@flapjack:~/Documents/virtualenvs$ cdvirtualenv<br />
(bio)james@flapjack:~/Documents/virtualenvs/bio$ </code></p>
<p>Now, to install biopython we first use pip to install numpy:</p>
<p><code lang="bash">(bio)james@flapjack:~/Documents/virtualenvs/bio$ pip -E . install numpy<br />
Downloading/unpacking numpy<br />
...</code></p>
<p>Important to remember the &#8216;-E&#8217; flag which tells pip to use the virtualenv we are in (this should be added to virtualenv_wrapper IMHO).  Now we can install biopython from our github fork, using the &#8216;-e&#8217; flag to keep it editable (i.e we are hacking on it).</p>
<p><code lang="bash">(bio)james@flapjack:~/Documents/virtualenvs/bio$ pip -E . install -e git://github.com/jamescasbon/biopython.git#egg=biopython<br />
Obtaining biopython from git+git://github.com/jamescasbon/biopython.git#egg=biopython<br />
  Cloning git://github.com/jamescasbon/biopython.git to ./src/biopython<br />
remote: Counting objects: 22719, done.<br />
...</code></p>
<p>Next up, we want pygr so we need pyrex to build the c files:</p>
<p><code lang="bash">(bio)james@flapjack:~/Documents/virtualenvs/bio$ pip -E . install -U pyrex -f http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/Pyrex-0.9.8.5.tar.gz<br />
Downloading/unpacking pyrex<br />
  Downloading Pyrex-0.9.8.5.tar.gz (242Kb): 242Kb downloaded<br />
  In the tar file /var/folders/Gn/GneSaDeKGaGpZXx+hcopdU+++TI/-Tmp-/tmpTEdhFd/Pyrex-0.9.8.5.tar.gz the member Pyrex-0.9.8.5/Demos/embed/Makefile is invalid: 'filename None not found'<br />
  Running setup.py egg_info for package pyrex<br />
Installing collected packages: pyrex<br />
  Running setup.py install for pyrex<br />
    changing mode of build/scripts-2.5/pyrexc from 644 to 755<br />
    changing mode of /Users/james/Documents/virtualenvs/bio/bin/pyrexc to 755<br />
Successfully installed pyrex</code></p>
<p>Now, to get and editable pygr:</p>
<p><code lang="bash">(bio)james@flapjack:~/Documents/virtualenvs/bio$ pip -E . install -e git://github.com/jamescasbon/pygr.git#egg=pygr<br />
Obtaining pygr from git+git://github.com/jamescasbon/pygr.git#egg=pygr<br />
  Cloning git://github.com/jamescasbon/pygr.git to ./src/pygr<br />
remote: Counting objects: 6281, done.<br />
...<br />
Successfully installed pygr</code></p>
<p>Finally, ipython:</p>
<p><code lang="bash">(bio)james@flapjack:~/Documents/virtualenvs/bio$ pip -E . install ipython<br />
Downloading/unpacking ipython<br />
  Downloading ipython-0.9.1.tar.gz (2.8Mb): 2.8Mb downloaded<br />
</code></p>
<p>We now have a completely isolated environment, where pygr and biopython are editable:</p>
<p><code lang="python">(bio)james@flapjack:~/Documents/virtualenvs/bio$ bin/ipython<br />
Python 2.5.4 (r254:67916, Mar  2 2009, 10:40:04)<br />
Type "copyright", "credits" or "license" for more information.</p>
<p>IPython 0.9.1 -- An enhanced Interactive Python.<br />
?         -> Introduction and overview of IPython's features.<br />
%quickref -> Quick reference.<br />
help      -> Python's own help system.<br />
object?   -> Details about 'object'. ?object also works, ?? prints more.</p>
<p>In [1]: import pygr</p>
<p>In [2]: pygr.__file__<br />
Out[2]: '/Users/james/Documents/virtualenvs/bio/src/pygr/pygr/__init__.pyc'<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.machine-envy.com/blog/2009/07/11/installing-python-bioinformatics-tools-with-virtualenv-and-pip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>chimpy: MailChimp API for python</title>
		<link>http://www.machine-envy.com/blog/2008/09/21/chimpy-mailchimp-api-for-python/</link>
		<comments>http://www.machine-envy.com/blog/2008/09/21/chimpy-mailchimp-api-for-python/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 17:17:23 +0000</pubDate>
		<dc:creator>James Casbon</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.machine-envy.com/blog/?p=206</guid>
		<description><![CDATA[I needed to use MailChimp from a Django app, so I have knocked up a wrapper for their API.  Come on over to the google code site for chimpy if it is useful to you.
]]></description>
			<content:encoded><![CDATA[<p>I needed to use <a href="http://www.mailchimp.com">MailChimp</a> from a Django app, so I have knocked up a wrapper for their <a href="http://www.mailchimp.com/api">API</a>.  Come on over to the google code site for <a href="http://code.google.com/p/chimpy/">chimpy</a> if it is useful to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.machine-envy.com/blog/2008/09/21/chimpy-mailchimp-api-for-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>TextMate with nose</title>
		<link>http://www.machine-envy.com/blog/2008/09/04/textmate-with-nose/</link>
		<comments>http://www.machine-envy.com/blog/2008/09/04/textmate-with-nose/#comments</comments>
		<pubDate>Thu, 04 Sep 2008 09:54:14 +0000</pubDate>
		<dc:creator>James Casbon</dc:creator>
				<category><![CDATA[nose]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://www.machine-envy.com/blog/?p=190</guid>
		<description><![CDATA[If you want to use nose as your test runner while developing with TextMate, then you need the nosexml plugin.  Install and then follow these instructions.
]]></description>
			<content:encoded><![CDATA[<p>If you want to use <a href="http://code.google.com/p/python-nosexml/wiki/TextMateFormatter">nose as your test runner while developing with TextMate</a>, then you need the <a href="http://code.google.com/p/python-nosexml/">nosexml plugin</a>.  Install and then follow <a href="http://code.google.com/p/python-nosexml/wiki/TextMateFormatter">these instructions</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.machine-envy.com/blog/2008/09/04/textmate-with-nose/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Howto: pyjamas + pylons + json</title>
		<link>http://www.machine-envy.com/blog/2006/12/10/howto-pyjamas-pylons-json/</link>
		<comments>http://www.machine-envy.com/blog/2006/12/10/howto-pyjamas-pylons-json/#comments</comments>
		<pubDate>Sun, 10 Dec 2006 16:57:36 +0000</pubDate>
		<dc:creator>James Casbon</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.machine-envy.com/blog/2006/12/10/howto-pyjamas-pylons-json/</guid>
		<description><![CDATA[
I&#8217;ve been playing with the excellent pyjamas and I thought i&#8217;d share my experiences of using pylons to create a simple json service for the pyjamas client.



The idea is simple.  Pyjamas can create rich ajax applications in the same style as GWT but in python rather than Java.  However, it leaves the implementation [...]]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;ve been playing with the excellent <a href="http://pyjamas.pyworks.org/">pyjamas</a> and I thought i&#8217;d share my experiences of using <a href="http://pylonshq.com/">pylons</a> to create a simple json service for the pyjamas client.
</p>
<p><span id="more-103"></span></p>
<p>
The idea is simple.  Pyjamas can create rich ajax applications in the same style as <a href="http://code.google.com/webtoolkit/">GWT</a> but in python rather than Java.  However, it leaves the implementation of the server side up to you.  The aim of this entry is to show how easy it is to use pylons to provide a json based service for the client.</p>
<p><p>
First, you need to make sure you&#8217;ve got pylons and pyjamas installed, which you can do with easy_install.  Next, create the template using paster, and start the server.
</p>
<blockquote>
<pre>
<code>
/tmp$paster create --template pylons echo
....
/tmp$ cd echo/
/tmp/echo$ paster serve --reload development.ini
Starting subprocess with file monitor
Starting server in PID 6377.
serving on 0.0.0.0:5000
</code>
</pre>
</blockquote>
<p>
Now, point your browser at http://localhost:5000/ and you should see the default pylons page.  To get the client side working.  We need to copy the json pyjamas example into the public directory (this contains static files to be served).   Then edit build.sh to point to your pyjamas installation build script.
</p>
<blockquote>
<pre>
<code>
/tmp/echo$ cd echo/public/
/tmp/echo/echo/public$ cp -r /.../pyjamas/examples/jsonrpc/* .
/tmp/echo/echo/public$ echo "python2.4 /.../pyjamas/builder/build.py JSONRPCExample.py" > build.sh
james@jlap:/tmp/echo/echo/public$ ./build.sh
Building 'JSONRPCExample.py' to output directory 'output'
...
</code>
</pre>
</blockquote>
<p>
If you now point your browser at http://localhost:5000/output/JSONRPCExample.html you should be able to see the example.  I recommend that you install the mozilla <a href="http://livehttpheaders.mozdev.org/">live http headers</a> plugin.  This allows you to see what resources the client is interacting with.  If you press &#8220;send to python service&#8221;, you will see a POST to output/services/EchoService.py.  Edit JSONRPCExample.py so that the EchoServicePython class looks like this:
</p>
<blockquote>
<pre>
<code>
class EchoServicePython(JSONProxy):
    def __init__(self):
        JSONProxy.__init__(self, "/echoservice/json", ["echo", "reverse", "uppercase", "lowercase"])
</code>
</pre>
</blockquote>
<p>You now need to rebuild the client with build.sh and restart the server.  Unfortunately, the paster server doesn&#8217;t reload automatically when changes are made to the public directory so you need to do this manually.  We have now set the python rpc service to point at /echoservice/json.  In pylons terms, this will be automatically mapped to a method named json on a controller called echoservice.  Create a file called echoservice.py in echo/controllers and put this in it.
</p>
<blockquote>
<pre>
<code>
from echo.lib.base import *

class EchoserviceController(BaseController):
    def index(self):
        return Response('Echo World')
</code>
</pre>
</blockquote>
<p>If you now visit http://localhost:5000/echoservice/index you should see &#8220;echo world&#8221; coming from that controller.  Now all we need to add is the json part of the controller.  Put this into echoservice.py
</p>
<blockquote>
<pre>
<code>
from echo.lib.base import *
from pylons.decorators import jsonify
import simplejson

class EchoserviceController(BaseController):
    def index(self):
        return Response('Hello World')

    @jsonify
    def json(self):
        body = request.body.read(int(request.environ['CONTENT_LENGTH']))
        json = simplejson.loads(body)
        data = json['params'][0]
        method = json['method']
        if method == 'reverse':
            data = data[::-1]
        if method == 'uppercase':
            data = data.upper()
        if method == 'lowercase':
            data = data.lower()
        return dict(result=data)
</code>
</pre>
</blockquote>
<p>Now try the &#8220;send to python service&#8221; and you should see the correct results returned.  So what have we done here?  Firstly, we needed to decode the method body.  Import simplejson and use the loads method on the body got from the request object.  The json object is a dict, so we can access the method name and parameters and create a dictionary with the answer stored under the result key.  To return the data in json format, we just need the jsonify decorator which will translate the dictionary for us.  Simple, huh?
</p>
<p>When you mess up the service, it is worth knowing that you can inspect the stack using the debug url.  This is given both in the console, and the http headers.  Note also that storing the source python for the client in the public directory is stupid, but you knew that.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.machine-envy.com/blog/2006/12/10/howto-pyjamas-pylons-json/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>A treemap viewer for python</title>
		<link>http://www.machine-envy.com/blog/2006/07/29/a-treemap-viewer-for-python/</link>
		<comments>http://www.machine-envy.com/blog/2006/07/29/a-treemap-viewer-for-python/#comments</comments>
		<pubDate>Sat, 29 Jul 2006 23:27:51 +0000</pubDate>
		<dc:creator>James Casbon</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.machine-envy.com/blog/?p=47</guid>
		<description><![CDATA[As part of my current obsession with visualising test coverage for my huge app at work (I have a sneaky suspicion that other coders are not testing their code) I have been playing around with tree visualisation.  My first port of call, graphviz, works ok for a small app but cant handle the huge [...]]]></description>
			<content:encoded><![CDATA[<p>As part of my current obsession with visualising test coverage for my huge app at work (I have a sneaky suspicion that other coders are not testing their code) I have been playing around with tree visualisation.  My first port of call, graphviz, works ok for a small app but cant handle the huge app I&#8217;m interested in. <a href="http://en.wikipedia.org/wiki/Eye_of_GNOME">eog</a> was using all 1gig of my memory to try and render the svg file, which got quite boring.  Then I remembered <a href="http://www.cs.umd.edu/hcil/treemap-history/">treemaps</a>.  They&#8217;re a great way of viewing trees where the nodes are considered to have a size.</p>
<p>I couldn&#8217;t find a decent viewer in python, so I thought I&#8217;d knock one up.  It seems quick enough and does the job.  I even used pylab to allow the use to zoom in on particular nodes to see whats going on in a busy part.</p>
<p><img width="464" height="348" alt="demo treemap" id="image46" src="http://www.machine-envy.com/blog/wp-content/uploads/2006/07/image.png" /></p>
<p>You can&#8217;t see the node labels, but they are displayed in the interactive map.  I couldn&#8217;t think of a decent way of getting them into a node that could be really small.</p>
<p>It also became a nice guinea pig for testing the setuptools automate cheeseshop /pypi upload.  Its really good, and worked without a hitch.  You should now be able to do easy_install treemap!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.machine-envy.com/blog/2006/07/29/a-treemap-viewer-for-python/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Automated python testing with nose and eclipse</title>
		<link>http://www.machine-envy.com/blog/2006/07/29/automated-python-testing-with-nose-and-eclipse/</link>
		<comments>http://www.machine-envy.com/blog/2006/07/29/automated-python-testing-with-nose-and-eclipse/#comments</comments>
		<pubDate>Sat, 29 Jul 2006 13:33:33 +0000</pubDate>
		<dc:creator>James Casbon</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.machine-envy.com/blog/?p=45</guid>
		<description><![CDATA[I use eclipse with the excellent pydev for my coding.  Yes, I know I should be using emacs but at work I&#8217;m forced to use windows so I like the way eclipse insulates me from the OS. Also, I could never get over the ugliness of emacs default fonts (anyone know to make it [...]]]></description>
			<content:encoded><![CDATA[<p>I use <a href="http://www.eclipse.org/">eclipse</a> with the excellent <a href="http://pydev.sourceforge.net/">pydev</a> for my coding.  Yes, I know I should be using emacs but at work I&#8217;m forced to use windows so I like the way eclipse insulates me from the OS. Also, I could never get over the ugliness of emacs default fonts (anyone know to make it look better?).  I also like not having to think about versioning, as subclipse does a great job of doing it all for me.</p>
<p>I also use <a href="http://somethingaboutorange.com/mrl/projects/nose/">nose</a> for testing.  Even written a few plugins (eg one that dumps the test results into a nice excel spreadsheet to give to the QA department) and contibuted a few patches.   The test attributes are a great feature, and it allows you to mix unittest, simple test methods and doctests without thinking about it.  However, I was inspired by <a href="http://jeffwinkler.net/2006/04/27/keeping-your-nose-green/">this post</a> on automating nose whenever a source file changes to look at doing the same in eclipse.  Turns out, its easier than I could have imagined.</p>
<p>Under project properties, define a new &#8216;program&#8217; builder.  Set the location to the nosetests script, set its working directory to ${project loc}, append any command line options you want (eg &#8211;with-coverage -a !slow,!gui) and then, under the build options tab, tick the &#8216;launch in background&#8217; and &#8216;during auto builds&#8217;.  Now, whenever you save the changes to a file, the test results will come out in the console.</p>
<p>Unfortunately, it seems eclipse cannot share builders between projects.  However, you can setup nose as an external tool.  Then, when you need it as a builder you can import it.  It&#8217;s also quite nice to have an external tool set up that runs nose only on the selected file.  To do this set up an external tool as before,  but instead set working directory to {$container loc} and put {$resource loc} in the command line arguments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.machine-envy.com/blog/2006/07/29/automated-python-testing-with-nose-and-eclipse/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.252 seconds -->
