<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" version="2.0">
<channel>
<title><![CDATA[Unified Python Planet]]></title>
<description><![CDATA[A uniqued union of the Official and Unofficial Python planet feeds.  Generated by Atomisator FTW!]]></description>
<link>http://feeds2.feedburner.com/UnifiedPythonPlanet</link>
<language>en</language>
<copyright>Copyright 2008, Atomisator</copyright>
<pubDate>Sat, 15 Mar 2008 00:15:05 +0200</pubDate>
<lastBuildDate>Sat, 15 Mar 2008 00:15:05 +0200</lastBuildDate>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/UnifiedPythonPlanet" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
    <title><![CDATA[Mike C. Fletcher: Getting the old OpenGL.Tk module working again...]]></title>
    <description><![CDATA[<br />
<p>Had a user complain that we don't have Togl support any more (again).  It's another one of those &quot;blah&quot; tasks that I really feel ambivalent about.  I've long since completely given up on Tkinter, particularly since it's no longer installed by default on any reasonable Linux distributions.  However, Togl, while still not (AFAICS) packaged for Ubuntu, has binary tarballs that can be installed on any modern Python + Tkinter, so while I may not see it as a good idea to use Tkinter in new projects, the barrier to entry for providing access to Togl for those who choose to do so has dropped (i.e. I no longer have to compile the dratted thing).</p><p>I almost went totally nuts and included Togl into the PyOpenGL distribution, then I realized just how much that would add to the size of the distribution.  So, there's now a script &quot;src/togl.py&quot; which downloads the binaries from SourceForge and installs them into PyOpenGL.  There's also fixes to the OpenGL/Tk package that make it work with Togl 2.0 and allow for the difference between 32 and 64-bit builds (though there's no Win64 build of Togl AFAICS, luckily we apparently don't work on Win64 to begin with).</p><p>Fixed a few other bugs in preparation for the beta-1 release.  Need to start testing tomorrow for that on the various platforms, video-cards, etceteras.</p><br />]]></description>
    <link><![CDATA[http://blog.vrplumber.com/index.php?/archives/2393-Getting-the-old-OpenGL.Tk-module-working-again....html]]></link>
    <pubDate>2009-11-08 04:23:51</pubDate>
  </item>
  <item>
    <title><![CDATA[Paul Bissex: Branching and merging in real life]]></title>
    <description><![CDATA[<p>At work I still mostly use Subversion for version control. Its main selling points: stable, performs as expected, integrates nicely with Trac, holds all our old stuff (legacy inertia). </p>
<p>Note that "pain-free branching and merging" is not on that list. (And don't give me the old "branching is cheap in svn!" line. It's not about the branching, it's about the merging.) A couple years ago I started <a href="http://news.e-scribe.com/388">also using Mercurial</a> and plan to eventually replace svn with it entirely. The aspect of Mercurial that made my life better recently is its support for branching and merging.</p>
<p>The scenario: an important internal web app (in use all day every school day) needed some <em>significant</em> changes on a short timetable. Normally I'd work on the app thus: edit the staging copy, commit, update the live copy. I didn't want to take that approach here. I knew that during the development window there might arise unrelated urgent change requests; I wanted to keep the new code isolated during development, but also deploy and track those unrelated urgent changes. Branching seemed like the right approach. </p>
<p>I could have made a full clone of the app (<code>hg clone mainrepo newrepo</code>). However, handling environment dependencies (web server, PythonPath, database) would have added time and fussiness to the job, and time was in short supply. So, using Mercurial's named-branches feature, I made a new branch (<code>hg branch newstuff</code>) right inside the fully-functional staging copy of the app. That way I was able to develop and test as usual, secure that my unproven work-in-progress was not "polluting" the current app's revision history.</p>
<p>To handle "unrelated urgent changes" as mentioned above, I'd:</p>
<ol>
<li>Commit any current work on the "newstuff" branch</li>
<li>Switch to the main branch (<code>hg update -r default</code>)</li>
<li>Make the urgent change, test, commit, update the live copy</li>
<li>Switch back to the new branch (<code>hg update -r newstuff</code>)</li>
</ol>
<p>It took me a couple tries to understand how branch-switching worked, but it's simple: you really <em>are</em> updating your working directory to a new revision, it just happens to be a revision stored in a different branch from the current one.</p>
<p>It was fun looking at the graph (via HgWeb) and seeing my two parallel branches with their individual commits.</p>
<p>The moment of truth came at the end of the day Friday, when it was time to merge the tested and complete "newstuff" code with the current live codebase. It was dead simple, and effectively instantaneous. Condensed version: <code>hg update -r default; hg merge -r newstuff; hg ci -m "merged new stuff"</code>. Followed by: update live copy and let out a big sigh.</p>]]></description>
    <link><![CDATA[http://news.e-scribe.com/437]]></link>
    <pubDate>2009-11-07 22:18:56</pubDate>
  </item>
  <item>
    <title><![CDATA[Alex Gaynor: My Workflow]]></title>
    <description><![CDATA[About a year ago I blogged about how I didn't like easy_install, and I alluded to the fact that I didn't really like any programming language specific package managers.  I'm happy to say I've changed my tune quite drastically in the past 2 months.  Since I started working with Eldarion I've dived head first into the <a href="http://pip.openplans.org/">pip</a> and <a href="http://pypi.python.org/pypi/virtualenv">virtualenv</a> system and I'm happy to say it works brilliantly.  The nature of the work is that we have lots of different projects all at once, often using wildly different versions of packages in all sorts of incompatible ways.  The only way to stay sane is to have isolated environments for each of them.  Enter virtualenv stage left.<br /><br />If you work with multiple Python projects that use different versions of things virtualenv is indispensable.  It allows you to have totally isolated execution environments for different projects.  I'm also using <a href="http://www.doughellmann.com/">Doug Hellmann's</a> <a href="http://www.doughellmann.com/projects/virtualenvwrapper/">virtualenvwrapper</a>, which wraps up a few virtualenv commands and gives you some hooks you can use.  When I start a new project it looks something like this:<br /><pre><br />    $ git checkout some_repo<br />    $ cd some_repo/<br />    $ mkvirtualenv project_name<br /></pre><br /><br />The first two steps are probably self explanatory.  What mkvirtualenv does is to a new virtual environment, and activate it.  I also have a hook set up with virtualenvwrapper to install the latest development version of pip, as well as ipython and ipdb.  pip is a tremendous asset to this process.  It has a requirements file that makes it very easy to keep track of all the dependencies for a given project, plus pip allows you to install packages out of a version control system which is tremendously useful.<br /><br />When I want to work on an existing project all I need to do is:<br /><pre><br />    $ workon project_name<br /></pre><br /><br />This activates the environment for that project.  Now the PATH prioritizes stuff installed into that virtualenv, and my Python path only has stuff installed into this virtualenv.  I can't imagine what my job would be like without these tools, if I had to manually manage the dependencies for each project I'd probably go crazy within a week.  Another advantage is it makes it easy to test things against multiple versions of a library.  I can test if something works on Django 1.0 and 1.1 just by switching which environment I'm in.<br /><br />As promised tomorrow I'll be writing about an optimization that just landed in Unladen Swallow, and I'm keeping Monday's post a secret.  I'm not sure what Tuesday's post will be, but I think I'll be writing something Django related, either about my new templatetag library, or the state of my multiple database work.  See you around the internet.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7176062489626496619-975393468580714646?l=lazypython.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://lazypython.blogspot.com/2009/11/my-workflow.html]]></link>
    <pubDate>2009-11-07 22:02:47</pubDate>
  </item>
  <item>
    <title><![CDATA[Jarrod Millman: SciPy 2009 proceedings coming soon ...]]></title>
    <description><![CDATA[This is the second year that we are going to publish proceedings for the <a href="http://conference.scipy.org/">SciPy conference</a>.  Last year's <a href="http://conference.scipy.org/proceedings/SciPy2008/">proceedings</a> included 17 articles ranging from discussions on recent developments in the core projects to research articles describing how our community-developed software tools were used in different fields.<div><br /></div><div><a href="http://gael-varoquaux.info/">Gaël Varoquaux</a>, <a href="http://mentat.za.net/">Stéfan van der Walt</a>, and I are editing the proceedings this year.  All accepted articles have been reviewed and sent back to the authors for revision.  The deadline for the revised articles is November 14th and we plan to release the proceedings by the end of the month.  The articles are looking very good and I expect that the complete proceedings will be very informative and useful for the community.</div><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7039308593110047510-7131374906847249485?l=jarrodmillman.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://jarrodmillman.blogspot.com/2009/11/scipy-2009-proceedings-coming-soon.html]]></link>
    <pubDate>2009-11-07 19:35:10</pubDate>
  </item>
  <item>
    <title><![CDATA[Gael Varoquaux: Acceleration estimation in atom-interferometric tests of the Einstein equivalence principle]]></title>
    <description><![CDATA[<p>Hurray! The pivot article that marks my transition from physics to statistic modeling is finally out:</p>
<p><a href="http://www.iop.org/EJ/article/1367-2630/11/11/113010/njp9_11_113010.pdf"><strong class="tocTitle">How to estimate the differential acceleration in a two-species atom interferometer to test the equivalence principle</strong></a><br />
<em class="tocAuth">G Varoquaux, R A Nyman, R Geiger, P Cheinet, A Landragin and P Bouyer</em></p>
<p>To put things in context, at the end of my PhD, we had been building an atom interferometer to test the Einstein equivalence principle and my reflections on the limits of atom interferometry shifted from worrying about the underlying physics, to worrying about the estimation: the inverse problem of going from the experimental signal, to the underlying quantities that we are measuring, confounded by all the horrible experimental noise.</p>
<h2>Atoms, light, gravity fields and free-fall planes</h2>
<p>The problem is: we want to do high precision metrologic tests in a free-falling plane. We use interferometry to measure gravity fields. But rather than doing interferometry with light, we use atoms, that are much more coupled to gravity. When probing gravity fields with light, the trick is to use huge highly-sensitive interferometers. For instance the <a href="http://www.ligo.caltech.edu/">ligo</a> and <a href="http://www.virgo.infn.it/">virgo</a> projects are kilometer-long light interferometers listening for gravitational waves, and the <a href="http://www.ringlaser.org.nz/content/facilities.php">giant ring lasers</a> can test for tiny modifications in the Earth rotation and gravity field. Gravimetric coupling with matter waves and light waves describes the <a href="http://www.turpion.org/php/paper.phtml?journal_id=pu&paper_id=6425">very exact same underlying physics</a>. However, matter waves, atoms in the case of PhD, fall in gravity fields. While this is the expression of the very exact phenomena we are trying to measure, it also means that to build a very large atom interferometer, you have to let the atoms fall for a large distance. And I can attest that even <a href="http://gael-varoquaux.info/physics/KRubLog/07/0518/P1010619.jpg">laboratory-sized versions</a> of <a href="http://gael-varoquaux.info/physics/KRubLog/index.html">atom-interferometric experiments</a> are fairly nasty to run:</p>
<p><img src="http://gael-varoquaux.info/physics/KRubLog/07/0518/P1010619.jpg" alt="" width="400" height="300" /></p>
<p>This is why we simply decided to build an experiment in a <a href="http://arxiv.org/pdf/0705.2922">freely-falling plane</a>: <strong>let&#8217;s fall <a href="http://gael-varoquaux.info/physics/ICELog/index.html">with the atoms</a></strong> for 6 kilometers (30 seconds).</p>
<p><img src="http://gael-varoquaux.info/physics/ICELog/07/0328/DSCF0662.jpg" alt="" width="400" height="300" /><img src="http://gael-varoquaux.info/physics/ICELog/07/0327/100_6838.jpg" alt="" width="400" height="300" /></p>
<h2>Measuring free fall, while in free fall?</h2>
<p><img src="http://gael-varoquaux.info/blog/wp-content/uploads/2009/11/coyote.png" alt="" width="237" height="220" /></p>
<p>Of course, the plane is not really in free fall. The pilots try as hard as possible to compensate for drag and atmospheric turbulence but there is a limit to what they can achieve with an Airbus. The atoms are a vacuum apparatus, so they are indeed in free fall (before they crash in the side of the apparatus). However, making sens of measure of fall-free made relative to an unstable, and unpredictable platform is not trivial. This is where the statistical modeling kicked in. After reading a bit about noise in interferometers, I realized that we had a well-known problem in statistics: estimation of hidden variables from noisy observations. I learned about <a href="http://www.google.fr/url?sa=t&source=web&ct=res&cd=1&ved=0CAcQFjAA&url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FRecursive_Bayesian_estimation&ei=S331StLdCof34Ab117i4BA&usg=AFQjCNFeQT7-ruBii_IfqL5C7smW9jBL3Q&sig2=fYSw1ieKbBFPLqnoBEsdEQ">recursive Bayesian estimation</a>, coded a proof-of-principle algorithm for our problem (in Python, of course), and was sold. The rest of the story is about noise simulations, and trying to convince a metrology community that you could perform good measurements in a noisy environment.</p>
<p>It took us a lot of time (2 years) to write an article that was acceptable to the target scientific community, while keeping the core estimation and statistics message. Publishing new ideas is hard, because you are not answering questions that people already have in mind. This is why the fact that <a href="http://www.iop.org/EJ/abstract/1367-2630/11/11/113010">this article</a> is out is a huge deal for me. It marks a turning point in my reflection: I switched from worrying only about forward models, with which try to describe as well as possible the system at hand, to inverse problems, in which you worry about estimating the parameters from the data.</p>
<p>I was startled to see that people are ready to spend a huge amount of money and efforts in improving complicated experiments involving quantum physics and very sophisticated technology, but can be weary of processing the output signal to increase statistical power. Scientific communities have their own goals that they pitch (e.g. reducing the phase noise in lasers) and there can be huge divides between different scientific interests. Realizing this played an important role in <a href="http://gael-varoquaux.info/blog/?p=34">my career shift</a>. I wanted to know more about the power of statistical modeling and machine learning applied to real-life system. I decided that to learn more, I had to work with people that had a different culture from mine. It&#8217;s been a huge amount of fun so far&#8230; More about that later.</p>]]></description>
    <link><![CDATA[http://gael-varoquaux.info/blog/?p=118]]></link>
    <pubDate>2009-11-07 14:24:54</pubDate>
  </item>
  <item>
    <title><![CDATA[Tim Golden: London Python Dojo: that was interesting…]]></title>
    <description><![CDATA[<p>Thursday night saw the third London Python Dojo, which involved us completing a &#8212; very simple &#8212; noughts &#038; crosses game, with a random computer player which seemed have a winning streak a lot of the time! </p>
<p>Why interesting? Because, for whatever combination of reasons, there were fewer people there: about 10 of us, compared to something around 25 the last couple of times. One obvious factor was that it was November the 5th, so many people would have been with their families at fireworks displays. It might be that the attraction had palled, but I doubt if that accounts for everyone. However it came about, we had a reduced number.</p>
<p>That meant two things, I think: that everyone had a go at piloting (or at least co-piloting; I don&#8217;t thing Peter actually coded at all); and that everyone was engaged to a greater extent, just because there were fewer people. (Possibly also because those who did come were slightly keener&#8230;). I had a great time, and the audience participation, which was certainly there as I made a mull of trying to get clever with an itertools.cycle, was more &#8212; how shall I put it? &#8212; manageable. It also meant that there were fewer people still at the pub, and we had a quiet corner to ourselves, which I find more pleasant than shouting at someone in an awkward corner of a noisy and crowded room. (But then, I&#8217;m not really a pub person).</p>
<p>Apart from small bits and pieces, most of the time around the pub table was spent debating a proposal of Jon&#8217;s that Security bugs are always logically more important than any other class of bugs, because whatever effect another bug can be caused can just as well be caused by someone breaking into your system, making that happen, and then doing whatever they were going to do anyway (sending your credit card details to the Russian mafia, etc&#8230;).</p>
<p>As <a href="http://mail.python.org/pipermail/python-uk/2009-November/001711.html">Nicholas has already posted</a>, we discussed various ideas around the future of this particular meetup. We definitely all agreed that it should *have* a future, and more or less coalesced around the idea of a regular, but varying, lineup which might include Dojos of different types, but would also have more conventional talks / lightning talks etc. The idea also would be to keep it in the first week of the month, thus alternating with the Pyssup which is in the third week, but varying there&#8217;s always some day *someone* can never make. (For me, it&#8217;s Wednesday). It was also agreed that &#8220;official&#8221; communications would happen on the Python-UK list as everyone can easily see that; not everyone has Twitter / Wave / the-latest-and-greatest-thing.</p>
<p>Personally, I think Fry-IT are very generous in not only allowing us to use their offices, but also providing beer &#038; pizzas. It makes it much easier to talk to people before, after (and even during). If you&#8217;re in or around London in the first week of December, why not turn up? Watch the <a href="http://mail.python.org/mailman/listinfo/python-uk">python-uk mailing list</a> for info.</p>]]></description>
    <link><![CDATA[http://ramblings.timgolden.me.uk/2009/11/07/london-python-dojo-that-was-interesting/]]></link>
    <pubDate>2009-11-07 11:53:55</pubDate>
  </item>
  <item>
    <title><![CDATA[IronPython-URLs: QCon Presentation: Real World IronPython]]></title>
    <description><![CDATA[In March I spoke at the&nbsp; <a href="http://qconlondon.com/london-2009/">QCon London 2009</a> conference on "Real World IronPython". InfoQ has just put up a video of the presentation, including the slides and a demo of "Resolver One", the highly programmable spreadsheet system created by Resolver Systems with IronPython.<br />
<ul><li><a href="http://www.infoq.com/presentations/foord-real-world-ironpython">Real World IronPython</a></li>
</ul><blockquote><b>Summary </b><br />
Michael Foord discusses IronPython, the DLR, dynamic languages on .Net, static vs. dynamic typing, Visual Studio integration, Resolver One, Intellipad, Crack.net, embedding IronPython, the ScriptEngine, error handling, dynamic operations, functions as delegates, and the C# 4.0 dynamic keyword. <br />
<br />
<b>Bio </b><br />
Michael Foord works full time with IronPython for <a href="http://www.resolversystems.com/">Resolver Systems</a>; creating a highly programmable spreadsheet called Resolver One. He has been using IronPython since about version 0.7, and has been developing with Python since 2002. He blogs and writes about Python and IronPython far more than is healthy for one individual and in 2008 was made the first Microsoft MVP for dynamic languages. <br />
<b><br />
About the conference </b><br />
QCon is a conference that is organized by the community, for the community.The result is a high quality conference experience where a tremendous amount of attention and investment has gone into having the best content on the most important topics presented by the leaders in our community. QCon is designed with the technical depth and enterprise focus of interest to technical team leads, architects, and project managers.<br />
</blockquote><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/3604515438787408842-5658454015202141692?l=ironpython-urls.blogspot.com" /></div>
<p><a href="http://feedads.g.doubleclick.net/~a/6Fosa0ga9Og2590dYqVKY8cEV2Y/0/da"><img src="http://feedads.g.doubleclick.net/~a/6Fosa0ga9Og2590dYqVKY8cEV2Y/0/di" border="0" ismap="true" /></a><br />
<a href="http://feedads.g.doubleclick.net/~a/6Fosa0ga9Og2590dYqVKY8cEV2Y/1/da"><img src="http://feedads.g.doubleclick.net/~a/6Fosa0ga9Og2590dYqVKY8cEV2Y/1/di" border="0" ismap="true" /></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/IronpythonUrls?a=0kF121nsWjU:Js6hoXlG3Ng:4cEx4HpKnUU"><img src="http://feeds.feedburner.com/~ff/IronpythonUrls?i=0kF121nsWjU:Js6hoXlG3Ng:4cEx4HpKnUU" border="0" /></a> <a href="http://feeds.feedburner.com/~ff/IronpythonUrls?a=0kF121nsWjU:Js6hoXlG3Ng:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/IronpythonUrls?d=YwkR-u9nhCs" border="0" /></a> <a href="http://feeds.feedburner.com/~ff/IronpythonUrls?a=0kF121nsWjU:Js6hoXlG3Ng:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/IronpythonUrls?i=0kF121nsWjU:Js6hoXlG3Ng:F7zBnMyn0Lo" border="0" /></a>
</div><img src="http://feeds.feedburner.com/~r/IronpythonUrls/~4/0kF121nsWjU" height="1" width="1" />]]></description>
    <link><![CDATA[http://feedproxy.google.com/~r/IronpythonUrls/~3/0kF121nsWjU/qcon-presentation-real-world-ironpython.html]]></link>
    <pubDate>2009-11-07 10:39:08</pubDate>
  </item>
  <item>
    <title><![CDATA[IronPython-URLs: A Good Mix 28: NTornado, WPF, Testing in Italian, More Benchmarking, and adodbapi]]></title>
    <description><![CDATA[Yet another collection of IronPython and DLR related articles, projects and blog entries from the past few weeks.<br />
<ul><li><a href="http://ntornado.codeplex.com/">NTornado</a></li>
</ul>NTornado is an IronPython version of the Tornando web server. The Tornado Web Server is the open source version of the non-blocking web server that power FriendFeed and now part of the Facebook's open source initiative. This server is coded in Python and with strong emphasis on operating systems with epoll support.<br />
<br />
NTornado is a port of Tornado to IronPython using asynchronous high-performance sockets in .NET. To run the demos (requires IronPython 2.6):<br />
<blockquote>&gt; ipy -X:Frames "demo file name".py<br />
</blockquote><ul><li><a href="http://loosexaml.wordpress.com/2009/10/14/getting-wpf-control-template-in-ironpython/">Getting WPF Control Template in IronPython</a></li>
</ul><blockquote>I always find myself needing a control template so I can customize one of the WPF controls. I used to fire up Expression Blend to get it, and then realized I could write a little IronPython code to do it. Paste this code into the IronPython 2.0 or 2.6 console to see it work!<br />
</blockquote><ul><li> <a href="http://msdn.microsoft.com/it-it/magazine/dd882509.aspx">Modulo .NET test con IronPython</a></li>
</ul>&nbsp;A translation of James McCaffrey's article on testing .NET code with IronPython into Italian, for the MSDN magazine.<br />
<ul><li><a href="http://pyevolve.sourceforge.net/wordpress/?p=862">Pyevolve benchmark on different Python flavors</a></li>
</ul><a href="http://pyevolve.sourceforge.net/">Pyevolve</a> aims to be a&nbsp; "<i>complete genetic algorithm framework written in pure python</i>". The Pyevolve blog has benchmarked some genetic algorithms code running on all the major Python implementations: CPython 2.6 &amp; 2.5, Unladen Swallow, IronPython, PyPy and Jython. IronPython 2.6 comes out slower than CPython (and Unladen Swallow) and faster than PyPy and Jython.<br />
<ul><li><a href="http://lists.ironpython.com/pipermail/users-ironpython.com/2009-October/011436.html">adodbapi works with IronPython 2.6</a></li>
</ul><a href="http://adodbapi.sourceforge.net/">adodbapi</a> is a Python module for working with Microsoft ADO for connecting to databases and datasources. adodbapi is compatible with the Python <a href="http://www.python.org/dev/peps/pep-0249/">DB-API 2.0</a> specification, meaning that it can be used by any DB-API compatible code. Thanks to the work of Vernon Cole, adodbapi now passes all tests when run on both CPython and IronPython.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/3604515438787408842-22197891330111278?l=ironpython-urls.blogspot.com" /></div>
<p><a href="http://feedads.g.doubleclick.net/~a/36TrNh_dc6fR_Koq3dqupVCCCA8/0/da"><img src="http://feedads.g.doubleclick.net/~a/36TrNh_dc6fR_Koq3dqupVCCCA8/0/di" border="0" ismap="true" /></a><br />
<a href="http://feedads.g.doubleclick.net/~a/36TrNh_dc6fR_Koq3dqupVCCCA8/1/da"><img src="http://feedads.g.doubleclick.net/~a/36TrNh_dc6fR_Koq3dqupVCCCA8/1/di" border="0" ismap="true" /></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/IronpythonUrls?a=iYhMQmYHaWE:gjSJ1kpnF-w:4cEx4HpKnUU"><img src="http://feeds.feedburner.com/~ff/IronpythonUrls?i=iYhMQmYHaWE:gjSJ1kpnF-w:4cEx4HpKnUU" border="0" /></a> <a href="http://feeds.feedburner.com/~ff/IronpythonUrls?a=iYhMQmYHaWE:gjSJ1kpnF-w:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/IronpythonUrls?d=YwkR-u9nhCs" border="0" /></a> <a href="http://feeds.feedburner.com/~ff/IronpythonUrls?a=iYhMQmYHaWE:gjSJ1kpnF-w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/IronpythonUrls?i=iYhMQmYHaWE:gjSJ1kpnF-w:F7zBnMyn0Lo" border="0" /></a>
</div><img src="http://feeds.feedburner.com/~r/IronpythonUrls/~4/iYhMQmYHaWE" height="1" width="1" />]]></description>
    <link><![CDATA[http://feedproxy.google.com/~r/IronpythonUrls/~3/iYhMQmYHaWE/good-mix-28-ntornado-wpf-testing-in.html]]></link>
    <pubDate>2009-11-07 10:20:33</pubDate>
  </item>
  <item>
    <title><![CDATA[Mike C. Fletcher: Any Win64 PyOpenGL devs?]]></title>
    <description><![CDATA[I don't really use Windows.  I have a Vista partition on my laptop that I use for compiling and releasing projects, but it's a 32-bit image.  I honestly don't care enough about Win64 to buy a copy, but there are obviously people who do want to run PyOpenGL on it.  So, any Win64 developers feel like figuring out what's wrong with PyOpenGL there?  I'm guessing it'll wind up being something fairly straightforward like using the wrong DLL or something like that (PyOpenGL works perfectly fine on Linux in 64-bit, so I doubt it's a fundamental problem).]]></description>
    <link><![CDATA[http://blog.vrplumber.com/index.php?/archives/2392-Any-Win64-PyOpenGL-devs.html]]></link>
    <pubDate>2009-11-07 07:17:28</pubDate>
  </item>
  <item>
    <title><![CDATA[Tarek Ziade: virtualenv and zc.buildout now with Distribute included]]></title>
    <description><![CDATA[<div class="snap_preview"><br /><p>We are still actively working in fixing all the remaining bugs in <a href="http://pypi.python.org/pypi/distribute">Distribute</a> (our Setuptools fork).</p>
<p>But we have reached an important milestone this week: both <a href="http://pypi.python.org/pypi/virtualenv/1.4" target="_blank">virtualenv</a> and <a href="http://pypi.python.org/pypi/zc.buildout" target="_blank">zc.buildout</a> now comes with an option to switch to Distribute.</p>
<p>In virtualenv:</p>
<pre>$ virtualenv --distribute ENV</pre>
<p>In zc.buildout, using its bootstrap.py file:</p>
<pre>$ python bootstrap.py --distribute</pre>
<p>Enjoy !</p>
<p>For those who may wonder why they should switch to Distribute over Setuptools, it&#8217;s quite simple:</p>
<ul>
<li>Distribute 0.6.x is a drop-in replacement for Setuptools</li>
<li>Distribute is actively maintained, and has over 10 commiters</li>
<li>Distribute 0.6.x offers Python 3 support !</li>
</ul>
<p>And if you still struggle with packaging issues, the place to hang around to get some help is the #distutils IRC channel on Freenode.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tarekziade.wordpress.com/973/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tarekziade.wordpress.com/973/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tarekziade.wordpress.com/973/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tarekziade.wordpress.com/973/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tarekziade.wordpress.com/973/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tarekziade.wordpress.com/973/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tarekziade.wordpress.com/973/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tarekziade.wordpress.com/973/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tarekziade.wordpress.com/973/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tarekziade.wordpress.com/973/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tarekziade.wordpress.com&blog=448161&post=973&subd=tarekziade&ref=&feed=1" /></div>]]></description>
    <link><![CDATA[http://tarekziade.wordpress.com/2009/11/07/virtualenv-and-zc-buildout-now-with-distribute-included/]]></link>
    <pubDate>2009-11-07 01:43:13</pubDate>
  </item>
  <item>
    <title><![CDATA[Alex Gaynor: Towards a Better Template Tag Definition Syntax]]></title>
    <description><![CDATA[<a href="http://ericholscher.com/">Eric Holscher</a> has blogged a <a href="http://ericholscher.com/blog/2009/nov/3/class-based-template-tags/">few</a> <a href="http://ericholscher.com/blog/2009/nov/3/making-template-parsing-easier/">times</a> this month about various template tag definition syntax ideas.  In particular he's looked at a system based on <a href="http://github.com/codysoyland/surlex">Surlex</a> (which is essentially an alternate syntax for certain parts of regular expressions), and a system based on keywords.  I highly recommend giving his posts a read as they explain the ideas he's looked at in far better detail than I could.  However, I wasn't particularly satisfied with either of these solution, I love Django's use of regular expressions for URL resolving, however, for whatever reason I don't really like the look of using regular expressions (or an alternate syntax like Surlex) for template tag parsing.  Instead I've been thinking about an object based parsing syntax, similar to <a href="http://pyparsing.wikispaces.com/">PyParsing</a>.<br /><br />This is an idea I've been thinking about for several months now, but Eric's posts finally gave me the kick in the pants I needed to do the work.  Therefore, I'm pleased to announce that I've released <a href="http://github.com/alex/django-kickass-templatetags">django-kickass-templatetags</a>.  Yes, I'm looking for a better name, it's already been pointed out to me that a name like that won't fly in the US government, or most corporate environments.  This library is essentially me putting to code everything I've been thinking about, but enough talking let's take a look at what the template tag definition syntax:<br /><pre><br />    @tag(register, [Constant("for"), Variable(), Optional([Constant("as"), Name()])]):<br />    def example_tag(context, val, asvar=None):<br /></pre><br /><br />As you can see it's a purely object based syntax, with different classes for different components of a template tag.  For example this would parse something like:<br /><pre><br />    {% example_tag for variable %}<br />    {% example_tag for variable as new_var %}<br /></pre><br /><br />It's probably clear that this is significantly less code than the manual parsing, manual node construction, and manual resolving of variable that you would have needed to do with a raw templatetag definition.  Then the function you have gets the resolved values for each of its parameters, and at that point it's basically the same as Node.render, it is expected to either return a string to be inserted into the template or alter the context.  I'm looking forward to never writing manual template parsing again.  However, there are still a few scenarios it doens't handle, it won't handle something like the logic in the {% if %} tag, and it won't handle tags with {% end %} type tags.  I feel like these should both be solvable problems, but since it's a bolt-on addition to the existing tools it ultimately doesn't have to cover every use case, just the common ones (when's the last time you wrote your own implementation of the {% if %} or {% for %} tags).<br /><br />It's my hope that something like this becomes popular, as a) developers will be happier, b) moving towards a community standard is the first step towards including a solution out of the box.  The pain and boilerplate of defining templatetags has long been a complain about Django's template language (especially because the language itself limits your ability to perform any sort of advanced logic), therefore making it as painless as possible ultimately helps make the case for the philosophy of the language itself (which I very much agree with it).<br /><br />In keeping with my promise I'm giving an overview of what my next post will be, and this time I'm giving a full 3-day forecast :).  Tommorow I'm going to blog about pip, virtualenv, and my development workflow.  Sunday's post will cover a new optimization that just landed in Unladen Swallow.  And finally Monday's post will contain a strange metaphor, and I'm not saying any more :P.  <a href="http://github.com/alex/django-kickass-templatetags">Go checkout the code and enjoy.</a><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7176062489626496619-1955330441532928689?l=lazypython.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://lazypython.blogspot.com/2009/11/towards-better-template-tag-definition.html]]></link>
    <pubDate>2009-11-06 23:17:38</pubDate>
  </item>
  <item>
    <title><![CDATA[Shannon -jj Behrens: Suicide]]></title>
    <description><![CDATA[My friend committed suicide.  He was a brilliant programmer, and he had everything going for him.  He was very successful.<br /><br />I'm crushed because I know I could have helped if only he had given me a chance.  He never did.<br /><br />We in the programming world aren't always the most emotionally balanced.  I know of three others who took their lives in the programming world.  I've hinted at this before on my <a href="http://jjinux.blogspot.com/2008/05/bipolar-lisp-programmer.html">Bipolar Lisp Programmer</a> post.  To compound matters, our society has been moving away from personal interaction and responsibility for decades, leading to a culture that is toxic.<br /><br />Mother Theresa said that the greatest poverty that she ever saw was to see people who felt unloved.  If your friends are feeling unloved, please reach out to them.  We are each far more loved than we think.  In the programming world, it's so easy to get caught up in petty struggles, like Pylons vs. Django, Ruby vs. Python, free software vs. open source, Linux vs. pretty much everything else ;)  What we forget is that we're all people with hopes and dreams, fears and insecurities.  We're all trying to change the world, but as Mother Theresa said, "In this life we cannot do great things. We can only do small things with great love."<br /><br />Look out for each other, but if you have no where to turn, contact me!  Call me directly at (925) 209-6439.  Don't consider the middle of the night an inconvenience.  When else am I going to work with five kids around ;)  I will do everything I can to help.  I don't want to wake up on another day to find another brilliant mind missing from this great community of thinkers.  We are a community and we are only as great as the individuals that thrive and share with one another in that community.  Everyone contributes, whether in small ways or large, and every loss is felt by more people than we consider in our moments of darkness.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/11788780-527242992269361490?l=jjinux.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://jjinux.blogspot.com/2009/11/suicide.html]]></link>
    <pubDate>2009-11-06 22:15:40</pubDate>
  </item>
  <item>
    <title><![CDATA[Python Secret Weblog: The Success of the Zope Component Architecture]]></title>
    <description><![CDATA[<p>Prompted by recent brief negative <a class="reference" href="http://mockit.blogspot.com/2009/11/emperors-new-clothes.html">pronunciations</a> by Malthe on the
Zope Component Architecture (ZCA), I thought I'd talk a bit about what
I think about it. I'm not going to go into hermeneutics here of what
Malthe might mean -- others attempts at exegesis exist in the comments
to that blog entry already. Instead, I'll just talk about what I think
makes the ZCA useful, and why it is successful. Finally I'll go into
some reasons why people are frustrated by the ZCA.</p>
<div class="section">
<h1><a id="what-is-the-zca-used-for" name="what-is-the-zca-used-for">What is the ZCA used for?</a></h1>
<p>What is the ZCA used for? It's used to glue things to each other: glue
event handlers to events, glue views to models, glue plugins into
applications and libraries, and more abstractly, glue adapters to
adaptees. In ZCA terms, providing such glue is termed providing
<em>configuration</em>.</p>
<p>Why was the ZCA created? The Zope community had been building
pluggable web applications for a long time and we noticed our
components became overly complex and were hard to glue together and
override. The ZCA is one answer to this problem.</p>
<p>The ZCA is implemented by <a class="reference" href="http://pypi.python.org/pypi/zope.component">zope.component</a>. It's a library for
gluing. It's built on top of <a class="reference" href="http://pypi.python.org/pypi/zope.interface">zope.interface</a>, a library that helps
one define the bits that are being glued.</p>
<p>What advantage does such gluing bring?</p>
<ul class="simple">
<li>many, perhaps all, larger applications contain glue. The ZCA makes
the glue explicit and uniform.</li>
<li>ZCA glue can be overridden explicitly.</li>
<li>you can extend existing systems by gluing in new things.</li>
</ul>
<p>One place where the ZCA is helpful is when you want to write a library
that offers a few plugin points to configure it for a particular
environment. For instance when I wrote <a class="reference" href="http://pypi.python.org/pypi/hurry.resource">hurry.resource</a>, a library
for handling javascript and other resources, I included a few plugin
points in it that allow it to be plugged into a particular web
framework. Then to allow it to be used with Zope Toolkit-based
frameworks such as Grok, I wrote <a class="reference" href="http://pypi.python.org/pypi/hurry.zoperesource">hurry.zoperesource</a> to provide the
knowledge about that.</p>
<p>This way, hurry.resource doesn't need to know anything in particular
about URL generation or requests; its plugins can take care of
this. This allowed me to write and test hurry.resource without
worrying too much about the larger Zope Toolkit framework, knowing I
could plug it in later, and now the library becomes more useful for a
broader group of people.</p>
<p>The ZCA doesn't just allow one to glue one thing to another, but also
to override the glue in specific cases. A common example of overriding
glue occurs with views. Zope Toolkit applications follow a view/model
approach, where the view is looked up on the model dependent on its
class (or interface). It happens frequently enough in an application
that I want many models to share a particular view, but override one
model with a more specialized view. This is much like the way
inheritance works in plain Python: I implement a method on a base
class shared completely by some subclasses, but for one subclass I'd
like to override it.</p>
<p>What I described just now is overriding for particular subclasses. The
ZCA also allows other ways of overriding based on the
<a class="reference" href="http://pypi.python.org/pypi/zope.configuration">zope.configuration</a> library, overriding one glue registration with
another one. I myself find myself using this kind of override less
frequently, but it's still very useful in the 1 percent of cases where
other options would be very ugly.</p>
<p>The question is sometimes asked why not just modify code dynamically
for overrides? Why not <em>monkey patch</em> it? (or &quot;open the class&quot;, or
whatever other terminology one would like to use).</p>
<p>Brandon Rhodes at PyCon 2008 gave <a class="reference" href="http://rhodesmill.org/brandon/adapters/">a great presentation</a> explaining
why the ZCA approach can be superior to monkey-patching and some other
approaches. The point he makes is that the ZCA is the most composable
and maintainable approach of the alternatives (subclassing, mixins,
monkey-patching, adaptation). I recommend everyone interested in this
topic to read his slides.</p>
<p>Of course as with everything in programming, everything depends on the
trade-offs. In many circumstances the ZCA is overkill. The ZCA can be
misused. But I also maintain that in many circumstances the ZCA is
very useful.</p>
<p>Component approaches have become quite popular with web
frameworks. Many popular ones adopt elements of it, but often in a
somewhat limited way. For instance, one very popular <em>interface</em> is
the WSGI interface, and one popular form of <em>adaptation</em> of this WSGI
interface is to use WSGI middleware and framework components. With
WSGI we see that <em>just one</em> well-defined, consensus interface has
become an amazing source of creativity and pluggability within web
development. With the ZCA we are able to define <em>more than one</em>
interface in our applications, and potentially create ecosystems of
creativity around those. Not that this is easy, but at least we have a
mechanism and method to do so.</p>
</div>
<div class="section">
<h1><a id="the-zca-is-successful" name="the-zca-is-successful">The ZCA is successful</a></h1>
<p>Why do I say the Zope Component Architecture (ZCA) is successful? It's
successful as it's <em>being used</em>, by many people, for many years
now. Of course you can say it's only used by that weird Zope
community, and a bit by weird Twisted people as well perhaps. That's
fine, but realize that the wider Zope community is <em>big</em> and is made
of many parts: Plone, Silva, Zope 2, Zope Toolkit, Grok. I'll also
count BFG as part of the wider Zope community.</p>
<p>The ZCA is successful for <em>me</em>. Without it, I'd have to invent
something very much like it. It comes back in much code that I've
written. I'm able to do all kinds of small, cool things in my
applications and libraries on a daily basis, and I'm creating more
reusable code as a result.</p>
</div>
<div class="section">
<h1><a id="frustration-with-the-zca" name="frustration-with-the-zca">Frustration with the ZCA</a></h1>
<p>The ZCA isn't perfect. Humans aren't perfect, either. It's not easy to
create good reusable interfaces, or to build pluggable frameworks and
applications. It's easy to overdo the pluggability. It's easy to
create the wrong pluggability points. It can get overly complex and
overwhelming.</p>
<p>Writing XML configuration files to glue things together can be
cumbersome and lead to repeating yourself, though his last issue has
been overcome for some time now by the Grok project and its reusable
solution (<a class="reference" href="http://pypi.python.org/pypi/grokcore.component">grokcore.component</a>) is available to everybody.</p>
<p>It's easy to let the pain of the mistakes in the use of the ZCA, and
the pain of complex applications in which it is used in general,
overshadow the many successes of the ZCA: in a large part thanks to to
the ZCA's ability to glue things together people are able to use Zope
Toolkit libraries within a Zope 2 or Plone context. Grok was able to
remix the Zope Toolkit in part because we could easily modify and
extend the framework. I think the web frameworks that use the ZCA
offer pluggability and flexibility unrivaled by the competition.</p>
<p>We generally don't say that the problems and complexities in our large
libraries and applications are due to the Python programming
language. While Python isn't perfect, we tend to think overall it
helps. I also tend to think that the ZCA helps.</p>
<p>Are there alternatives to the ZCA? Certainly: any library or
application specific pluggability system is an alternative. Sometimes
a specific approach is better than a generic one. It can be easier
to understand it's smaller.</p>
<p>Usually I'd say it's the other way around. Each custom pluggability
system is another one to learn, and has its own limitations. I've
found multiple times that I can make a far more powerful pluggability
system for a library in a shorter time if I build it on top of the
ZCA.</p>
<p>There are also more general approaches where there's at least some
overlap with the ZCA: setuptools entry points, WSGI middleware, and
PEAK-Rules. To use any of them for pluggability and overriding one
needs to have a notion of an interface one can implement and plug
into, a notion that the ZCA makes explicit.</p>
</div>
<div class="section">
<h1><a id="conclusions" name="conclusions">Conclusions</a></h1>
<p>The ZCA is useful. The ZCA is powerful. The ZCA is successful. The ZCA
is imperfect. When I've run into its imperfections I've helped build
solutions on top of it, such as Grok's in-python gluing
approach. Sometimes I've considered its use overkill and gone for some
other approach. I think it's useful to step back and consider
alternative approaches.  But let's consider them in the light of the
success of the ZCA as much as in the light of its flaws.</p>
</div>]]></description>
    <link><![CDATA[http://faassen.n--tree.net/blog/view/weblog/2009/11/06/0]]></link>
    <pubDate>2009-11-06 20:33:52</pubDate>
  </item>
  <item>
    <title><![CDATA[Greg Wilson: Misa Sakamoto on DB2 Technology Explorer]]></title>
    <description><![CDATA[<p>One of our PEY students, Misa Sakamoto, has an article up on DeveloperWorks about <a href="http://www.ibm.com/developerworks/data/library/techarticle/dm-0911techexplorerdb2auth/index.html">the stuff she&#8217;s doing at IBM</a> &#8212; yay!</p>]]></description>
    <link><![CDATA[http://pyre.third-bit.com/blog/archives/3142.html]]></link>
    <pubDate>2009-11-06 19:31:00</pubDate>
  </item>
  <item>
    <title><![CDATA[Logilab: First contact with pupynere]]></title>
    <description><![CDATA[<p>I spent some time this week evaluating <a class="reference" href="http://http://dealmeida.net/projects/pupynere">Pupynere</a>, the PUre PYthon NEtcdf REader written by Roberto De Almeida. I see several advantages in pupynere.</p>
<p>First it's a pure Python module with no external dependency. It doesn't even depend on the <a class="reference" href="http://www.unidata.ucar.edu/software/netcdf/">NetCDF</a> lib and it is therefore very easy to deploy.</p>
<p>Second, it offers the same interface as <cite>Scientific Python</cite>'s NetCDF bindings which makes transitioning from one module to another very easy.</p>
<p>Third pupynere is being integrated into <a class="reference" href="http://www.scipy.org/">Scipy</a> as the <tt class="docutils literal"><span class="pre">scypi.io.netcdf</span></tt> module. Once integrated, this could ensure a wide adoption by the python community.</p>
<p>Finally it's easy to dig in this clear and small code base of about 600 lines. I have just sent several fixes and bug reports to the author.</p>
<p>However pupynere isn't mature yet. First it seems pupynere has been only used for simple cases so far. Many common cases are broken. Moreover there is no support for new NetCDF formats such as long-NetCDF and NetCDF4, and important features such as file update are still missing. In addition, The lack of a test suite is a serious issue. In my opinion, various bugs could already have been detected and fixed with simple unit tests. Contributions would be much more
comfortable with the safety net offered by a test suite. I am not certain
that the fixes and improvements I made this week did not introduce regressions.</p>
<p>To conclude, pupynere seems too young for production use. But I invite people
to try it and provide feedback and fixes to the author. I'm looking forward to using this project in production in the future.</p>]]></description>
    <link><![CDATA[http://feedproxy.google.com/~r/logilaborg_en/~3/spIl_Qr7Qvg/18838]]></link>
    <pubDate>2009-11-06 18:39:02</pubDate>
  </item>
  <item>
    <title><![CDATA[Jean-Paul Calderone: Twisted Web in 60 seconds: HTTP authentication]]></title>
    <description><![CDATA[<p>
Welcome to the 14th installment of "Twisted Web in 60 seconds". In many of the previous installments, I've demonstrated how to serve content by using existing resource classes or implementing new ones. In this installment, I'll demonstrate how you can use Twisted Web's basic or digest HTTP authentication to control access to these resources.
</p> <p>
<a rel="nofollow" target="_blank" href="http://twistedmatrix.com/documents/current/api/twisted.web.guard.html">Guard</a>, the Twisted Web module which provides most of the APIs which will be used in this example, helps you to add <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Authentication">authentication</a> and <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Authorization">authorization</a> to a resource hierarchy. It does this by providing a resource which implements <code>getChild</code> to <a rel="nofollow" target="_blank" href="http://jcalderone.livejournal.com/48953.html">return a dynamically selected resource</a>. The selection is based on the authentication headers in the request. If those headers indicate the request is made on behalf of Alice, then Alice's resource will be returned. If they indicate it was made on behalf of Bob, his will be returned. If the headers contain invalid credentials, an error resource is returned. Whatever happens, once this resource is returned, URL traversal continues as normal from that resource.
</p> <p>
The resource which implements this is <a rel="nofollow" target="_blank" href="http://twistedmatrix.com/documents/current/api/twisted.web.guard.HTTPAuthSessionWrapper.html">HTTPAuthSessionWrapper</a>, though it is directly is directly responsible for very little of the process. It will extract headers from the request and hand them off to a credentials factory to parse them according to the appropriate standards (eg <a rel="nofollow" target="_blank" href="http://tools.ietf.org/html/rfc2617">HTTP Authentication: Basic and Digest Access Authentication</a>) and then it hands the resulting credentials object off to a <a rel="nofollow" target="_blank" href="http://twistedmatrix.com/documents/current/api/twisted.cred.portal.Portal.html">portal</a>, the core of <a rel="nofollow" target="_blank" href="http://twistedmatrix.com/projects/core/documentation/howto/cred.html">Twisted Cred</a>, a system for uniform handling of authentication and authorization. I am not going to discuss Twisted Cred in much depth here. To make use of it with Twisted Web, the only thing you really need to know is how to implement a <a rel="nofollow" target="_blank" href="http://twistedmatrix.com/documents/current/api/twisted.cred.portal.IRealm.html">realm</a>.
</p> <p>
You need to implement a realm because the realm is the object which actually decides which resources are used for which users. This can be as complex or as simple as it suitable for your application. For this example, I'll keep it very simple: each user will have a resource which is a static file listing of the <code>public_html</code> directory in their UNIX home directory. First, I need to import <code>implements</code> from <code>zope.interface</code> and <code>IRealm</code> from <code>twisted.cred.portal</code>. Together these will let me mark this class as a realm (this is mostly - but notentirely - a documentation thing). I'll also need <a rel="nofollow" target="_blank" href="http://twistedmatrix.com/documents/current/api/twisted.web.static.File.html">File</a> for the actual implementation later.
</p> <pre> &nbsp;from zope.interface import implements<br /><br /> &nbsp;from twisted.cred.portal import IRealm<br /> &nbsp;from twisted.web.static import File<br /><br /> &nbsp;class PublicHTMLRealm(object):<br /> &nbsp; &nbsp; &nbsp;implements(IRealm)<br /></pre> <p>
A realm only needs to implement one method, <code>requestAvatar</code>. This is called after any successful authentication attempt (ie, Alice supplied the right password). Its job is to return the <em>avatar</em> for the user who succeeded in authenticating. An <em>avatar</em> is just an object that represents a user. In this case, it will be a <a rel="nofollow" target="_blank" href="http://twistedmatrix.com/documents/current/api/twisted.web.static.File.html">File</a>. In general, with Guard, the avatar must be a resource of some sort.
</p> <pre> &nbsp; &nbsp; &nbsp;def requestAvatar(self, avatarId, mind, *interfaces):<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if IResource in interfaces:<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return (IResource, File("/home/%s/public_html" % (avatarId,)), lambda: None)<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;raise NotImplementedError()<br /></pre> <p>
A few notes on this method:
</p> <ul> <li>The avatarId parameter is essentially the username. It's the job of some other code to extract the username from the request headers and make sure it gets passed here.</li> <li>The mind is always <code>None</code> when writing a realm to be used with Guard. You can ignore it until you want to write a realm for something else.</li> <li>Guard always passed <code>IResource</code> for the <code>interfaces</code> parameter. If <code>interfaces</code> only contains interfaces your code doesn't understand, raising <code>NotImplementedError</code> is the thing to do, as above. You'll only need to worry about getting a different interface when you write a realm for something other than Guard.</li> <li>If you want to track when a user <em>logs out</em>, that's what the last element of the returned tuple is for. It will be called when this avatar logs out. <code>lambda: None</code> is the idiomatic no-op logout function.</li> <li>Notice that I have written the path handling code in this example very poorly. This example may be vulnerable to certain unintentional information disclosure attacks. This sort of problem is exactly the reason <a rel="nofollow" target="_blank" href="http://twistedmatrix.com/documents/current/api/twisted.python.filepath.FilePath.html">FilePath</a> exists. However, that's an example for another day...
</li></ul> <p>
We're almost ready to set up the resource for this example. To create an <code>HTTPAuthSessionWrapper</code>, though, we need two things. First, a portal, which requires the realm above, plus at least one credentials checker:
</p> <pre> &nbsp;from twisted.cred.portal import Portal<br /> &nbsp;from twisted.cred.checkers import FilePasswordDB<br /><br /> &nbsp;portal = Portal(PublicHTMLRealm(), [FilePasswordDB('httpd.password')])<br /></pre> <p>
<code>FilePasswordDB</code> is that credentials checker I mentioned. It knows how to read passwd(5)-style (loosely) files to check credentials against. It is responsible for the <em>authentication</em> work after <code>HTTPAuthSessionWrapper</code> extracts the credentials from the request.
</p> <p>
Next we need either <code>BasicCredentialFactory</code> or <code>DigestCredentialFactory</code>. The former knows how to challenge HTTP clients to do basic authentication; the latter, digest authentication. I'll use digest here:
</p> <pre> &nbsp;from twisted.web.guard import DigestCredentialFactory<br /><br /> &nbsp;credentialFactory = DigestCredentialFactory("md5", "example.org")<br /></pre> <p>
The two parameters to this constructor are the <em>hash algorithm</em> and the <em>http authentication realm</em> which will be used. The only other valid hash algorithm is <code>"sha"</code> (but be careful, MD5 is more widely supported than SHA). The http authentication realm is mostly just a string that is presented to the user to let them know why they're authenticating (you can read more about this in the RFC).
</p> <p>
With those things created, we can finally instantiate <code>HTTPAuthSessionWrapper</code>:
</p> <pre> &nbsp;from twisted.web.guard import HTTPAuthSessionWrapper<br /><br /> &nbsp;resource = HTTPAuthSessionWrapper(portal, [credentialFactory])<br /></pre> <p>
There's just one last thing that needs to be done here. When I introduced <a rel="nofollow" target="_blank" href="http://jcalderone.livejournal.com/50056.html">rpy scripts</a>, I mentioned that they're evaluated in an unusual context. This is the first example which actually needs to take this into account. It so happens that <code>DigestCredentialFactory</code> instances are actually stateful. Authentication will only succeed if the same instance is used to generate challenges and examine the responses to those challenges. However, the normal mode of operation for an rpy script is for it to be re-executed for every request. This leads to a new <code>DigestCredentialFactory</code> being created for every request, preventing any authentication attempt from ever succeeding.
</p> <p>
There are two ways to deal with this. First, the better of the two ways, I could move almost all of the code into a real Python module, including the code which instantiates the <code>DigestCredentialFactory</code>. This would make ensure the same instance was used for every request. Second, the easier of the two ways, I could add a call to <code>cache</code> to the beginning of the rpy script:
</p> <pre> &nbsp;cache()<br /></pre> <p>
<code>cache</code> is part of the globals of any rpy script, so you don't need to import it (it's okay to be cringing at this point). Calling <code>cache</code> makes Twisted re-use the result of the first evaluation of the rpy script for subsequent requests too. Just what I want in this case.
</p> <p>
Here's the complete example (with imports re-arranged to the more conventional style):
</p> <pre>cache()<br /><br />from zope.interface import implements<br /><br />from twisted.cred.portal import IRealm, Portal<br />from twisted.cred.checkers import FilePasswordDB<br />from twisted.web.static import File<br />from twisted.web.resource import IResource<br />from twisted.web.guard import HTTPAuthSessionWrapper, DigestCredentialFactory<br /><br />class PublicHTMLRealm(object):<br /> &nbsp; &nbsp;implements(IRealm)<br /><br /> &nbsp; &nbsp;def requestAvatar(self, avatarId, mind, *interfaces):<br /> &nbsp; &nbsp; &nbsp; &nbsp;if IResource in interfaces:<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return (IResource, File("/home/%s/public_html" % (avatarId,)), lambda: None)<br /> &nbsp; &nbsp; &nbsp; &nbsp;raise NotImplementedError()<br /><br />portal = Portal(PublicHTMLRealm(), [FilePasswordDB('httpd.password')])<br /><br />credentialFactory = DigestCredentialFactory("md5", "localhost:8080")<br />resource = HTTPAuthSessionWrapper(portal, [credentialFactory])<br /></pre> <p>
And voila, a password-protected per-user Twisted Web server.
</p> <p>
I've gotten several requests to write something about sessions, so there's a good chance that's what you'll find in the next installment.
</p>]]></description>
    <link><![CDATA[http://jcalderone.livejournal.com/53074.html]]></link>
    <pubDate>2009-11-06 15:08:26</pubDate>
  </item>
  <item>
    <title><![CDATA[Patrick Stinson: An interesting thread problem]]></title>
    <description><![CDATA[<span>Interesting problem</span><br /><br />I am trying to flesh out the thread locking for our embedded python interpreter. A user can write scripts for our application, and if a script defines a callback it can respond to events from the application (like a midi note or musical clock tick).<br /><br />As it stands, we are not using process migration to allow for true multiprocessing, but instead are just hamming a single lock from multiple threads to protect the CPython library. This is good enough for now - it works quite well at relatively low latencies.<br /><br />I compiled python without thread management to avoid an incredible number of 'NULL tstate' errors caused by unpredictable thread management by sequencing host applications. The app is solid, but now I want to integrate a simple stack frame mechanism to allow scripts to behave a little better when calling other scripts. Short intro, but the details don't matter anyway...<br /><br /><span>Here's the deal</span><br /><br />I have one audio engine per thread, and several scripts per engine. The currently executing script is stored as a pointer on the engine object using my function setActiveScript(), and when a new script is called it is swapped with the current one, much like PyThreadState_Swap(). This in effect creates a stack of scripts in the engine, where when execution returns to the original script NULL is passed to setActiveScript().<br /><br />This works great, but when there is more than one engine (and so more than one thread), I need to acquire a critical section lock and swap the engine for another one, while maintaining the current script on that engine. The script pointer is stored in the engine, but where to enter and exit the critical section is tough. Hairy.<br /><br />The function looks like this:<br /><br />Script *ScriptingApplication::instance()->setActiveScript(Script *)<br /><br />I haven't written much complex code in the last while, so lining out the algorithm and thread locks is kind of clunky at best. it doesn't help that Ableton Live (a host that loads our audio plugin) suddenly doesn't want to be debugged.<br /><br />*crash*. uggh.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/130402213334709639-3282047014695827839?l=pkaudio.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://pkaudio.blogspot.com/2009/11/interesting-thread-problem.html]]></link>
    <pubDate>2009-11-06 12:55:14</pubDate>
  </item>
  <item>
    <title><![CDATA[Simon Willison: Python in the Scientific World]]></title>
    <description><![CDATA[<div class="blogmark segment"><p><a href="http://neopythonic.blogspot.com/2009/11/python-in-scientific-world.html">Python in the Scientific World</a>. Python continues to make strides in the scientific world—and the Hubble Space Telescope team have been using it for 10 years!</p>
</div>]]></description>
    <link><![CDATA[http://simonwillison.net/2009/Nov/6/neopythonic/]]></link>
    <pubDate>2009-11-06 11:04:04</pubDate>
  </item>
  <item>
    <title><![CDATA[S. Lott: BBEdit Configuration]]></title>
    <description><![CDATA[After installing Python 2.6 in Mac OS X, I had problems with BBEdit not finding the right version of Python.  It kept running an old 2.5 version.<div><br /></div><div>I finally tracked down the BBEdit documentation, http://pine.barebones.com/manual/BBEdit_9_User_Manual.pdf.  </div><div><br /></div><div>Found this:  "BBEdit expects to find Python in <span class="Apple-style-span">/usr/bin</span>, <span class="Apple-style-span">/usr/local/bin</span>, or <span class="Apple-style-span">/sw/bin</span>. If you have installed Python elsewhere, you must create a symbolic link in <span class="Apple-style-span">/usr/local/bin</span> pointing to your copy of Python in order to use pydoc and the Python debugger."</div><div><br /></div><div>Checked in <span class="Apple-style-span">/usr/bin</span> and found an old Python there.  I think Fink did that.  Removed it and BBEdit is much happier.  As is Komodo Edit.</div><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/684183198890094283-8590203215247302804?l=slott-softwarearchitect.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://slott-softwarearchitect.blogspot.com/2009/11/bbedit-configuration.html]]></link>
    <pubDate>2009-11-06 10:07:37</pubDate>
  </item>
  <item>
    <title><![CDATA[Thomas Vander Stichele: Dedicated separate Firefox windows]]></title>
    <description><![CDATA[<p>Dear intarweb,</p>
<p>here&#8217;s what I&#8217;d like to be able to do.  I would like to start a completely separate Firefox window, in a separate process, with a given webpage.  This process should be completely separate from my regular browsing, not take new links in its window when I click links somewhere else (usually they go to the most recently opened window), not crash when the regular firefox process crashes, and not bog down because my regular firefox goes to 100% CPU and beyond.</p>
<p>It seems to be hard to google for this idea; is it possible ?</p>]]></description>
    <link><![CDATA[http://thomas.apestaart.org/log/?p=1061]]></link>
    <pubDate>2009-11-06 09:59:59</pubDate>
  </item>
  <item>
    <title><![CDATA[Ludvig Ericson: Multitouch on Unibody MacBooks]]></title>
    <description><![CDATA[<div class="document">
<p>A little known fact about the unibody touchpad is that it can distinguish between up to eleven touch points - i.e., fingers.</p>
<p>Another little known fact is that the sensor knows about the contact surface area (in terms of ellipsoids).</p>
<p>Another yet less known fact is that <a href="http://www.johan-nordberg.com/">Johan Nordberg</a> didn't sleep much last night, and wrote a neat OS X application which simply plots what the trackpad (or Magic Mouse!) is saying about touches.<p>
<p>Download <a href="http://xn--bl-wia.se/FingerMgmt.zip">blä.se/FingerMgmt.zip</a> to try it out.</p>
<p><img src="http://bsg.lericson.se/jing/d1f2324eba.png" /></p>
</p></p></div>

<p><a href="http://delicious.com/save?url=http://lericson.blogg.se/http://lericson.blogg.se/code/2009/november/multitouch-on-unibody-macbooks.html&title=Multitouch on Unibody MacBooks"><img src="http://static.delicious.com/img/delicious.small.gif" height="10" width="10" alt="Save on Delicious" /> delicious.com</a></p>


<img src="http://stats.blogg.se/?id=1395964" border="0" width="0" height="0" alt="" />]]></description>
    <link><![CDATA[http://lericson.blogg.se/code/2009/november/multitouch-on-unibody-macbooks.html]]></link>
    <pubDate>2009-11-06 09:56:18</pubDate>
  </item>
  <item>
    <title><![CDATA[S. Lott: Parsing HTML from Microsoft Products (Like Front Page, etc.)]]></title>
    <description><![CDATA[Ugh.  When you try to parse MS-generated HTML, you find some extension syntax that is completely befuddling.  <div><br /></div><div>I've tried a few things in the past, none were particularly good.</div><div><br /></div><div>In reading a file recently, I found that even <a href="http://www.crummy.com/software/BeautifulSoup/">Beautiful Soup</a> was unable to prettify or parse it.</div><div>The document was filled with <span class="Apple-style-span"><span class="Apple-style-span">&lt;!--[if...]&gt;...&lt;![endif]--&gt;</span></span> constructs that looked vaguely directive or comment-like, but still managed to stump the parser.</div><div><br /></div><div>The BeautifulSoup parser has a <span class="Apple-style-span">markupMassage</span> parameter that applies a sequence of regexps to the source document to cleanup things that are baffling.  Some things, however, are too complex for simple regexp's.  Specifically, these nested comment-like things were totally confusing.</div><div><br /></div><div>Here's what I did.  I wrote a simple generator which emitted the text that was unguarded by these things.  The resulting sequence of text blocks could be assembled into a document that BeautifulSoup could parse.</div><div><div><div><code><pre><br />def clean_directives( page ):<br />"""<br />Stupid Microsoft "Directive"-like comments!<br />Must remove all &lt;!--[if...]&gt;...&lt;![endif]--&gt; sequences.  Which can be nested.<br />Must remove all &lt;![if...]&gt;...&lt;![endif]&gt; sequences.  Which appear to be the nested version.<br />"""<br />if_endif_pat= re.compile(  r"(\&lt;!-*\[if .*?\]\&gt;)|(&lt;!\[endif\]-*\&gt;)" )<br />context= []<br />start= 0<br />for m in if_endif_pat.finditer( page ):<br />   if "[if" in m.group(0):<br />       if start is not None:<br />           yield page[start:m.start()]<br />       context.append(m)<br />       start= None<br />   elif "[endif" in m.group(0):<br />       context.pop(-1)<br />       if len(context) == 0:<br />           start= m.end()+1<br />if start is not None:<br />   yield page[start:]<br /></pre></code><br /></div></div></div><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/684183198890094283-24164141902509361?l=slott-softwarearchitect.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://slott-softwarearchitect.blogspot.com/2009/11/parsing-html-from-microsoft-products.html]]></link>
    <pubDate>2009-11-06 09:53:15</pubDate>
  </item>
  <item>
    <title><![CDATA[Thomas Vander Stichele: Best post-sale screen ever]]></title>
    <description><![CDATA[<p>Just gave in to the geeky side of the force this morning and bought a DVD documentary about BBS&#8217;s.  (the version I bought comes with a DVD full with BBS text files, ANSI art, and random crap.)</p>
<p>After buying, this is the screen I got:</p>
<p><img src="http://thomas.apestaart.org/download/tmp/screenshot-order.png" border="0" /></p>
<p>I don&#8217;t think I ever got a chuckle out of what happened right *after* I forked over cash.  Here&#8217;s to you, Bob!</p>]]></description>
    <link><![CDATA[http://thomas.apestaart.org/log/?p=1059]]></link>
    <pubDate>2009-11-06 09:24:09</pubDate>
  </item>
  <item>
    <title><![CDATA[Ned Batchelder's blog: Continuous integration for Python with Hudson]]></title>
    <description><![CDATA[<p>Continuous integration is a great idea: you configure a server to periodically
pull your source code, build it, run the tests, run lint, measure coverage, and
so on.  Then it graphs everything, stores the results for examination, and so on.
</p><p>I'd been trying to figure out how to use the
<a href="https://hudson.dev.java.net/">Hudson</a> CI server with Python, and the
few times I tried to get my mind around it, it just wasn't clicking. I happened
to mention my mental block to Joe Heck, and a few days later, he produced
<a class="offsite" href="http://www.rhonabwy.com/wp/2009/11/04/setting-up-a-python-ci-server-with-hudson/">Setting up a python CI server with Hudson</a>.
It's a great step-by-step how-to covering everything you need to get Hudson
going for a Python project.
</p><p>Running through his guide finally cleared the last misconception for me:
continuous integration isn't a build tool or a test runner.  You don't run
Hudson on your development machine.  Sounds silly, but something needed to clear
it up, and this was it.</p><p>Thanks, Joe!</p>]]></description>
    <link><![CDATA[http://nedbatchelder.com/blog/200911/continuous_integration_for_python_with_hudson.html]]></link>
    <pubDate>2009-11-06 02:26:32</pubDate>
  </item>
  <item>
    <title><![CDATA[PyPy Development: Düsseldorf Sprint Started]]></title>
    <description><![CDATA[The Düsseldorf sprint starts today. Only Samuele and me are there so far, but that should change over the course of the day. We will mostly work on the JIT during this sprint, trying to make it a lot more practical. For that we need to decrease its memory requirements some more and to make it use less aggressive inlining. We will post more as the sprint progresses.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/3971202189709462152-7608527610228870250?l=morepypy.blogspot.com" /></div><img src="http://feeds.feedburner.com/~r/PyPyStatusBlog/~4/LNqtYWN8_ng" height="1" width="1" />]]></description>
    <link><![CDATA[http://feedproxy.google.com/~r/PyPyStatusBlog/~3/LNqtYWN8_ng/dusseldorf-sprint-started.html]]></link>
    <pubDate>2009-11-06 01:25:48</pubDate>
  </item>
  <item>
    <title><![CDATA[Graham Dumpleton: A roadmap for the Python WSGI specification.]]></title>
    <description><![CDATA[EDIT: Note that the discussion around this on the Python WEB-SIG went round in many circles and died. Thus nothing much here came into being and thus should be viewed merely for amusement value and not taken as being any indicator of any sort of reality.The discussion on the Python WEB-SIG about what to do about WSGI and Python 3.X has been going round and round in circles for some time now]]></description>
    <link><![CDATA[http://blog.dscpl.com.au/2009/09/roadmap-for-python-wsgi-specification.html]]></link>
    <pubDate>2009-11-06 00:43:34</pubDate>
  </item>
  <item>
    <title><![CDATA[Eric Holscher: Adding testing to pip]]></title>
    <description><![CDATA[<p>Python packaging has been in a bit of a state of disarray for as long as I've been using it. Pip has come along to make installing python packages easier. It has a lot of features that are useful, but they have been talked about in many other blog posts.
</p>
<p>Today I want to talk about adding testing to pip. If you are familiar with the Perl community, then you probably know about <a href="http://cpan.org/">CPAN</a>. It is basically Pypi for Perl. They have a command, called cpan, which allows you to install packages in a similar way to pip.
</p>
<p>One of the steps that a package goes through before being installed on your system is that the tests are run. This allows you to know if the package that you have installed is actually going to work on your system. It may be broken on your platform, or you may be missing a library that it thought you had. Currently, pip has no way to test packages when they are being installed. I went looking for a way to make that happen.
</p>
<p>It should be noted that pip is based on setuptools. Setuptools is what parses and understands most of the logic inside of your setup() function in the setup.py for your project (which you have, right?). Setuptools has an option called <code>test_suite</code>, which allows you to run <a href="http://peak.telecommunity.com/DevCenter/setuptools#test-build-package-and-run-a-unittest-suite">setup.py test</a> on your package, and have it run the unit tests. This is done by calling whatever python function is defined in <code>test_suite</code>. 
</p>
<p>I added the ability for pip to run <code>setup.py test</code> on a package that it is installing. It is executed by running <code>pip install --test &lt;package&gt;</code>. The implementation is on a <a href="http://bitbucket.org/ianb/pip/issue/11/allow-tests-to-be-run-upon-install">ticket</a> on bitbucket, and in a <a href="http://github.com/ericholscher/pip/tree/test_command">repository</a> on github.
</p>
<p>If you want to check it out, go ahead and clone my repo and check out the test_command branch. Then you can simply run
</p>
<pre><code>python pip.py install --test wsgiref
</code></pre><p>for an example package. If a package doesn't have a <code>test_suite</code>, then it simply doesn't run anything.
</p>
<p>Note that if the tests fail, it doesn't impact the installation of the package. The python community's tests aren't quite good enough,and almost any Django package you try this on will not have any tests. I wrote about how to <a href="http://ericholscher.com/blog/2009/jun/29/enable-setuppy-test-your-django-apps/">add testing to your django package</a>, but the process is long and involved. I'm working to improve the situation for Django and hopefully having the ability to run tests in the package management tool will spur people to add testing ability to their setup scripts!
</p>
<p><a href="http://somethingaboutorange.com/mrl/projects/nose/0.11.1/">Nose</a> makes this really easy, by simply adding <code>test_suite = 'nose.collector'</code> to your setup.py, nose will run your tests correctly. This is the level of support that I am hoping to implement for Django. 
</p>
<p>On a side node, I talked to <a href="http://blog.ianbicking.org/">Ian Bicking</a> about this, and he suggested writing the test command as a separate command, so you would be able to do <code>pip test wsgiref</code>, if it was installed. This has some other problems, which I will talk about after I have implemented this functionality.
</p>
<p>I would love to hear feedback, or if anyone has ideas for improving testing in the python and django communities. I have lots of ideas, and I will be writing more of them up over the following weeks.
</p>]]></description>
    <link><![CDATA[http://ericholscher.com/blog/2009/nov/5/adding-testing-pip/]]></link>
    <pubDate>2009-11-06 00:38:04</pubDate>
  </item>
  <item>
    <title><![CDATA[Python News: SciPy India Call for Papers]]></title>
    <description><![CDATA[<!--utf-8--><!--0.5-->




<p>SciPy India 2009 -- Call for Presentations The first <a class="reference external" href="http://scipy.in">Scientific Computing with Python conference in India</a> has announced its <a class="reference external" href="http://scipy.in/talks-cfp/">Call for Presentations</a>.  The conference will be held at the <a class="reference external" href="http://www.technopark.org/">Technopark</a> in Trivandrum, Kerala, India from December 12th to 17th, 2009.</p>]]></description>
    <link><![CDATA[http://www.python.org/news/index.html#Thu5Nov2009184600-0500]]></link>
    <pubDate>2009-11-05 23:46:00</pubDate>
  </item>
  <item>
    <title><![CDATA[Malthe Borch: Emperor's new clothes]]></title>
    <description><![CDATA[The <a href="http://wiki.zope.org/zope3/ComponentArchitectureOverview">Zope Component Architecture</a> is often touted for letting you override so-called components which have already been registered elsewhere (by a library, out of your immediate control).<br /><br />It's <span>wrong</span>.<br /><br />Shrink-wrap software is a circumstance. If you must change it from outside (instead of <a href="http://mockit.blogspot.com/2009/08/singing-and-branching.html">branching</a>, which is a fine approach in many cases), just go ahead and update the functions or classes in question using the <a href="http://mail.python.org/pipermail/edu-sig/2007-February/007787.html">reload approach</a> (object identity changes should be avoided at all costs).<br /><br />There's nothing wrong with ZCA; it's in my view a misunderstanding to employ it for web application development at large. Rather, it's applicable for deployments that require live software component introspection. I don't know that web applications need this in general. What happens is that frameworks like <a href="http://docs.zope.org/zopetoolkit/">Zope Toolkit</a> and <a href="http://www.plone.org">Plone</a> use these introspection features to map requests to code. That's a bit like using <a href="http://en.wikipedia.org/wiki/Radio-frequency_identification">RDIF</a> tags for consumption tracking (hint: require credit card payment or identity-based rebate instead).<br /><br />Most software is misunderstood. How to use it, when to use it. Sometimes it's worth the while to retrace your steps to learn why you ended up using a particular software.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/8212254010436871241-4433996884499631327?l=mockit.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://mockit.blogspot.com/2009/11/emperors-new-clothes.html]]></link>
    <pubDate>2009-11-05 23:29:00</pubDate>
  </item>
  <item>
    <title><![CDATA[Alex Gaynor: The Pycon Program Committee and my PyCon Talk]]></title>
    <description><![CDATA[Last year I presented at a conference for the first time in my life at PyCon, I moderated a panel on ORMs and I enjoyed it a ton (and based on the feedback I've gotten at least a few people enjoyed attending it).  Above and beyond that the two PyCons I've attended have both been amazing conferences, tons of awesome talks, great people to hang out with, and an awesome environment for maximizing both.  For both of the last two years I've hung around the PyCon organizers mailing list since the conference was in Chicago and I lived there, however this year I really wanted to increase my contributions to such a great conference.  Therefore, I joined the Pycon program committee.  This committee is responsible for reviewing all talk submissions and selecting the talks that will ultimately appear at PyCon.<br /><br />This year the PyCon programming committee had a really gargantuan task.  There were more talks submitted then ever before, more than 170 of them, for only 90 or so slots.  Unfortunately this meant that we had to reject some really good talks, which always sucks.  There's been a fair bit of discussion about the process this year and what can be done to improve it.  As a reviewer the one thing I wish I'd known going in was that the votes left on talks were just a first round, and ultimately didn't count for a huge amount.  Had I known this I would have been less tepid in giving positive reviews to talks which merely looked interesting.<br /><br />Another hot topic in the aftermath is whether or not the speaker's identity should factor into a reviewer's decision.  My position is that it should wherein the speaker has a reputation, be it good or bad.  If I know a speaker is awesome I'm way more likely to give them the +1, likewise if I see a speaker has a history of poor talks I'm more likely to give them a -1.  That being said I don't think new speakers, or slightly inexperienced ones should be penalized for that, I was a brand new speaker last time and I'm grateful I was given the chance to present.<br /><br />To give an example of this one of the talks I'm really looking forward to is Mark Ramm's, "To relate or not to relate, that is the question".  Mark and I spoke about this topic for quite a while at PyOhio, and every talk from Mark I've ever seen has been excellent.  Therefore I was more than willing to +1 it.  However, had I not known the speaker it would still have been a good proposal, and an interesting topic, I just would not have gotten immediately excited about going to see the talk.<br /><br />As an attendee one of the things I've always found is that speakers who are very passionate about their topics almost always give talks I really enjoy.  Thinking back to my first PyCon Maciej Fijalkowski managed to get me excited and interested in PyPy in just 30 minutes, because he was so passionate in speaking about the topic.<br /><br />All that being said I wanted to share a short list of the talks I'm excited about this year, before I dive into what my own talk will be about:<br /><ul><li>Optimizations And Micro-Optimizations In CPython</li><li>Unladen Swallow: fewer coconuts, faster Python</li><li>Managing the world's oldest Django project</li><li>Understanding the Python GIL</li><li>The speed of PyPy</li><li>Teaching compilers with python</li><li>To relate or not to relate, that is the question</li><li>Modern version control: Mercurial internals</li><li>Eventlet: Asynchronous I/O with a synchronous interface</li><li>Hg and Git : Can't we all just get along?</li><li>Mastering Team Play: Four powerful examples of composing Python tools</li></ul><br /><br />It's a bit of a long list, but compared to the size of the list of accepted talks I'm sure there are quite a few gems I've missed.<br /><br />The talk I'm going to be giving this year is about the real time web, also known as HTTP push, Comet, or reverse Ajax.  All of those are basically synonyms for the server being able to push data to the browser, rather than having the browser constantly poll the server for data.  Specifically I'm going to be looking at my experience building three different things, LeafyChat, DjangoDose's DjangoCon stream, and Hurricane.<br /><br />Leafychat is an IRC client built for the DjangoDash by myself, Leah Culver, and Chris Wanstrath.  The DjangoDose DjangoCon stream was a live stream of all the Twitter items about DjangoCon that Eric Florenzano and I built in the week leading up to DjangoCon.  Finally, Hurricane is the library Eric Florenzano and I have been working on in order to abstract the lessons learned from our experience building "real time" applications in Python.<br /><br />In the talk I'm going to try to zero in on what we did for each of these projects, what worked, what didn't, and what I'm taking away from the experience.  Finally, Eric Florenzano and I are working to put together a new updated, better version of the DjangoCon stream for PyCon.  I'm going to discuss what we do with that project, and why we do it that way in light of the lessons of previous projects.<br /><br />I'm hoping both my talk, and all of them will be awesome.  One thing's for sure, I'm already looking forward to PyCon 2010.  Tomorrow I'm going to be writing about my thoughts on a more ideal template tag definition syntax for Django, and hopefully sharing some code if I have time to start working on it.  See you then (and in Atlanta ;))!<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7176062489626496619-5486694113588267806?l=lazypython.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://lazypython.blogspot.com/2009/11/pycon-program-committee-and-my-pycon.html]]></link>
    <pubDate>2009-11-05 23:09:02</pubDate>
  </item>
  <item>
    <title><![CDATA[Rene Dudfield: rakarrack is a decent effects rack for linux]]></title>
    <description><![CDATA[<a href="http://rakarrack.sourceforge.net/">rakarrack</a> is a decent effects rack for linux.  <br /><br />It's not packaged for ubuntu(of course), but is fairly easy to compile.  I've been using the cvs version (yes, people are still quite happily using cvs it seems).<br /><br />Once you get it set up you have access to 80 presets of realtime guitar effects(2-40ms depending on your computer sound card setup).<br /><br />It works with the jack audio system, so you can route audio into it, and route its audio out to other programs easily enough.  You can also control it with midi(alsa, or jack).  Meaning you can hook it up to a midi controller of some sort.  I've been using it with an maudio axiom 25 controller, and with python scripts via pygame.midi.<br /><br /><a href="http://renesd.blogspot.com/2009/11/rakarrack-is-decent-effects-rack-for.html"><img src="http://1.bp.blogspot.com/_eJJgehXCsQ4/SvNGJ6HUP3I/AAAAAAAAAEs/XSY-5Aaro68/s400/rackarrack.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5400737514180067186" /></a><br /><br />It even has a very nice help manual integrated into the program... I wish more programs had a good help section.  It details the 17 different effects that come with the program.<br /><br />One thing which is a bit funny is that it doesn't use <a href="http://www.ladspa.org/">LADSPA</a> or <a href="http://lv2plug.in/">lv2</a> plugins.  You can of course still use these other plugins through other jack programs if you want.  However the ones it comes with are all fairly good quality from my tinkering.  There is a lot you can do with the various plugins in different orders with different settings in each one.  The 80 presets show a good variations of sounds you can get out of it.<br /><br />I've been using it in conjunction with the <a href="http://www.mixxx.org/">mixxx</a> mixing program and the <a href="http://www.hydrogen-music.org/">hydrogen</a> drum machine.  So you don't need to use it just with guitars... any program or audio input will do.<br /><br />If you are using guitars it also has a tuner which might come in handy... if you've never quite got the hang of playing that song called Tuning that you hear at the start of every gig.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/10678074-2583167037261338039?l=renesd.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://renesd.blogspot.com/2009/11/rakarrack-is-decent-effects-rack-for.html]]></link>
    <pubDate>2009-11-05 22:01:30</pubDate>
  </item>
  <item>
    <title><![CDATA[Patrick Stinson: Pure Art]]></title>
    <description><![CDATA[There comes a point when a piece of art is so refined that the products, byproducts, and even messiest and most defiled anty-products of that piece of art look good. The old rule that the back of the cross-stich should look as nice as the front applies throughout all kinds of art, whether it's computer programming, music, or athletic prowess.<br /><br />You've got your face deep down in the last algorithm that will finish your crowning achievement of the last nine months of work. The goal is met, the task is complete, but the project is a mess.<br /><br />Now its done, and you start polishing and packaging it up, writing API docs, making CD art, distributing re-usable instrument tracks for the rest of the world to see - the piece is packaged and ready to ship.<br /><br />Ableton live is one of those pieces of fine art, where the purity of the design lends itself to producing beautiful musical sets, even among some of the crappiest work you've done. The layout of the clips, the coloring and grouping of the built-in tools, everything can end up being a work of art in it's own, not just the final audio dump that you'll stick on your new album.<br /><br />Go download the <a href="http://cdn1.ableton.com/download/8736a17660353a4e1fad57724182aecd/AbleTen_Mum.zip">free Múm set</a> on Ableton's site and check out the work that they've done. If you don't have Live just download the free demo.<br /><br />First off, everything sounds amazing. Any clip sounds good with any clip. Even a monkey could play a nice sounding song here. This is the meaning of the back of the cross-stitch work. The loops are clean, refined, polished, done.<br /><br />They also spelled their name with inactive tracks down at the bottom of the set, and spelled their name again in midi notes in each of those tracks. I know this is poking at nerdy details, but this set just emanates the very cleanliness and artistic presentation that such a flexible tool makes possible. It's just a feeling I get, man.<br /><br />This software <span>makes</span> me want to be creative, whether I like it or not. Not only that, but it plainly shows the way to easy and readily available creativity, without having to wade through the much of documentation and technical cribby-crap.<br /><br />Ableton have nailed the solution to the music problem. They have nailed it, and then shown us what we didn't know we wanted to do in the first place. They've redefined the industry. While people preach this crap all the time, you almost never really see it.<br /><br />Because of this, Ableton Live is the best piece of software out there.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/130402213334709639-4709054541894079059?l=pkaudio.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://pkaudio.blogspot.com/2009/11/pure-art.html]]></link>
    <pubDate>2009-11-05 21:38:31</pubDate>
  </item>
  <item>
    <title><![CDATA[Menno's Musings: Why I chose Disqus Comments]]></title>
    <description><![CDATA[<p>I recently moved my blog comments away the <a class="reference external" href="http://pyblosxom.sourceforge.net/">PyBlosxom</a> <a class="reference external" href="http://pyblosxom.sourceforge.net/registry/input/comments/comments.html">comments</a> plugin
to a hosted system. The main driver was the ability for people to
subscribe to comments for an article using email or RSS. It's a pain
for people to have to check back to the site to see if someone has
replied to their comments. I was also keen on
user-experience-enhancing features such as integration with external
systems like OpenID, Twitter and Yahoo.</p>
<p>My criteria were:</p>
<ul class="simple">
<li>email subscription, RSS a bonus</li>
<li>support for pre-formatted text sections in comments (essential for
code samples)</li>
<li>an import mechanism for existing comments</li>
<li>threading of comments to allow commenters to respond to each other
sensibly</li>
<li>clean look with some ability to customise</li>
<li>support for a variety of authentication/profile systems</li>
</ul>
<p>There are a number of hosted comment systems out there. The most
popular options seem to be <a class="reference external" href="http://disqus.com/">Disqus</a>, <a class="reference external" href="http://js-kit.com/">JS-Kit Echo</a> and
<a class="reference external" href="http://www.intensedebate.com/">IntenseDebate</a>.</p>
<p>IntenseDebate was eliminated first because it doesn't seem to provide
an import mechanism for custom websites. Import only seems to be
supported for well known blog platforms such as Wordpress. There's no
comment API either. The approach seems to be to leave your old comment
system in place and just have new comments go into IntenseDebate. Not
good enough, I wanted to completely replace the existing comments
system.</p>
<p>After some deliberation I decided on JS-Kit Echo for one tiny reason:
it supports the &lt;pre&gt; tag. The closest Disqus supported was the
&lt;code&gt; tag which doesn't preserve white-space (useless for Python code
samples).</p>
<p>So I paid my US$12 (it's the only service that doesn't have a free
option) and started looking at how to import my existing comments
using their API ... and quickly found that it sucks. Comments can be
submitted but you can't specify a timestamp so they are dated with the
import date. Far from ideal. Then there's the API for retrieving
comments: it returns the data as JavaScript code (no not JSON)! It's
pretty clear that the API is what they use with the JavaScript for
Echo itself and geared for that use only. They've just thrown it out
there and documented it, warts and all.</p>
<p>Back to the drawing board.</p>
<p>The only showstopper for Disqus was the lack of &lt;pre&gt;. Everything else
about it was great: it met all my requirements and the API was clean
and comprehensive. If only there was a way to have properly formatted
source code in the comments.</p>
<p>Light bulb moment: use a CSS hack to make &lt;code&gt; in comments behave
like &lt;pre&gt;. The trick is to turn code into a block element and change
how white-space is handled. The CSS snippet looks like:</p>
<div class="highlight"><pre>.dsq-comment-message code {
  display:block;
  white-space:pre;
}
</pre></div>
<p>Works great.</p>
<p>With the only blocker gone, I wrote a Python script with the help of
Ian Lewis' excellent <a class="reference external" href="http://code.google.com/p/disqus-python-client/">disqus-python-client</a> package to pull in the
existing comments from the old system. Within an hour or so it was
ready to go.</p>
<p>Hopefully this article saves someone else some time if they decide to
use one of these systems. Getting things running chewed up a lot more
time then I had expected.</p>]]></description>
    <link><![CDATA[http://freshfoo.com/blog/disqus]]></link>
    <pubDate>2009-11-05 19:49:00</pubDate>
  </item>
  <item>
    <title><![CDATA[Greg Wilson: The Greatest Failing of High School Science]]></title>
    <description><![CDATA[<p>I don&#8217;t care exactly what science is taught in high schools, so long as people learn that:</p>
<ol>
<li>The universe works according to rules.</li>
<li>If we ask questions carefully and humbly, we can find out what those rules are.</li>
<li><em>We don&#8217;t get to pick or change those rules</em>. It&#8217;s not like basketball, where we can just decide one day that if you throw the round thing through the other round thing from far enough away, then bingo, you get an extra point.</li>
</ol>
<p>I think #3 is the fundamental &#8220;don&#8217;t get it&#8221; in the minds of many climate change deniers. Just read <a href="http://blogs.nature.com/news/thegreatbeyond/2009/11/global_warming_views_are_philo.html">this story</a>: it doesn&#8217;t matter what Tim Nicholson, James Delingpole, or the unnamed judge believes, the universe is going to go ahead and do what it damn well pleases with or without us. Fiction often portrays scientists as egotistical, but honestly, I think it&#8217;s the people who think they can dictate to reality who have the ego problems&#8230;</p>]]></description>
    <link><![CDATA[http://pyre.third-bit.com/blog/archives/3137.html]]></link>
    <pubDate>2009-11-05 19:40:26</pubDate>
  </item>
  <item>
    <title><![CDATA[Jason Baker: How programming language webpages should be designed]]></title>
    <description><![CDATA[<p><p>A while back, I asked a <a rel="nofollow" target="_blank" href="http://stackoverflow.com/questions/345672/fun-programming-languages">question on Stackoverflow</a> that taught me something (other than what programming languages are fun to work with). A lot of programming language authors just aren't very good at marketing their languages. <p></p> There are a lot of programming languages out there that I <em>wanted</em> to try out, but couldn't figure out an excuse to spend my time on them. And that's pretty sad considering how much I like trying new languages out. <p></p> Therefore, I'd like to present to the world my ideal website for programming languages: <a rel="nofollow" target="_blank" href="http://www.ruby-lang.org/en/">the Ruby webpage</a>. In fact, I have to admit that if I were trying to decide between Python (my favorite programming language) and Ruby today, I'd easily choose Ruby just based on their website. And that would be sad considering that I love Python so much more than Ruby (but that's just a personal preference, nothing against Ruby). <p></p> Let's take a look at why this is.
<h2>Show me the code!</h2>
<p>I still don't understand why this is such a difficult concept for some programming languages. The first thing I want to know is how my code <br />will look if I write it in your language. With Ruby, it's right there on the first page.&nbsp; Now try doing the same thing on the <a rel="nofollow" target="_blank" href="http://www.python.org">Python webpage</a>.&nbsp; Not as easy is it?</p>
<p>Even if you don't want to put it on the first page, it should at least be reachable using one click on the first page.&nbsp; See the <a rel="nofollow" target="_blank" href="http://www.scala-lang.org">Scala webpage</a> for an example of this.</p>
<h2>Feature lists are useless, documentation is priceless</h2>
<p>Hey, your language is cross-platform, has object-oriented and/or functional and/or concatenative and/or [insert language buzzword here] features. Good for you! Since you've taken a whole lot of time to provide me with great features, <em>show them to me</em>. <p></p> Again, I hold up Ruby as a prime example of how to do this. Right on the front page is <a rel="nofollow" target="_blank" href="http://www.ruby-lang.org/en/documentation/quickstart/2/">Ruby in Twenty Minutes</a>. This shows me all of the great features in brief code examples. And if that doesn't work for me, I can even <a rel="nofollow" target="_blank" href="http://tryruby.sophrinix.com/">try Ruby out in my browser</a>. <p></p> As an example of how <em>not</em> to do this, I present the <a rel="nofollow" target="_blank" href="http://unicon.sourceforge.net/">Unicon webpage</a>. From the front page, I can gather that Unicon is a "very high level, goal-directed, object-oriented, general purpose applications language", but that's about it.
<h2>But we just met!</h2>
<p>And one other thing, don't try to sell me a book. Yes, you should make it easy to find books on your programming language. No, you shouldn't remind me of it every chance you get. I view suggestions to buy a book as being somewhat like asking me to move in with you on the first date. Yeah, I find you interesting. I'm just not ready for the commitment.</p>  <p><a rel="nofollow" target="_blank" href="http://jasonmbaker.com/how-programming-language-webpages-should-be-d">Permalink</a> | <a rel="nofollow" target="_blank" href="http://jasonmbaker.com/how-programming-language-webpages-should-be-d#comment">Leave a comment&nbsp;&nbsp;&raquo;</a> </p></p></p></p>]]></description>
    <link><![CDATA[http://feedproxy.google.com/~r/posterous/NmsE/~3/WkEDpqotaCQ/how-programming-language-webpages-should-be-d]]></link>
    <pubDate>2009-11-05 18:44:00</pubDate>
  </item>
  <item>
    <title><![CDATA[Gary Bernhardt: How I Started TDD]]></title>
    <description><![CDATA[<p>
    This story is about the first code I ever wrote with proper TDD.  I'd been
    doing test-first for several months, but I didn't understand the design
    aspect. Fortunately, <a href="http://www.coreyhaines.com">Corey Haines</a>
    wanted to learn Python, and I wanted to learn TDD, so we paired up at a
    Coding Dojo.  It went something like this.<sup>1</sup>
</p>


<div class="discussion">

    <blockquote>
        <cite class="person1">Corey</cite>: Let's write a test.
    </blockquote>
    <pre><code>def test_fib_of_0_is_0():
        assert fib(0) == 0</code></pre>
    <div class="error">1 test failed; 0 tests passed.</div>
    <blockquote>
        <cite class="person1">Corey</cite>: Now let's make it pass.
    </blockquote>
    <blockquote>
        <cite class="person2">Me</cite>: Well, we could iterate...
    </blockquote>
    <blockquote>
        <cite class="person1">Corey</cite>: Why?
    </blockquote>
    <blockquote>
        <cite class="person2">Me</cite>: Because it's fibonacci...
    </blockquote>
    <blockquote>
        <cite class="person1">Corey</cite>: The test says it returns zero!
    </blockquote>
    <blockquote>
        <cite class="person2">Me</cite>: Oh. Well, OK.
    </blockquote>
    <pre><code>def fib(n):
        return 0</code></pre>


    <div class="success">1 test passed.</div>


    <blockquote>
        <cite class="person1">Corey</cite>: Let's write another test.
    </blockquote>
    <pre><code>def test_fib_of_1_is_1():
        assert fib(1) == 1</code></pre>
    <div class="error">1 test failed; 1 tests passed.</div>
    <blockquote>
        <cite class="person1">Corey</cite>: Now let's make it pass.
    </blockquote>
    <blockquote>
        <cite class="person2">Me</cite>: OK, we need to recursively...
    </blockquote>
    <p>I stop myself. I know what this got me last time.</p>
    <blockquote>
        <cite class="person2">Me</cite>: We can check for which input we got.
    </blockquote>
    <blockquote>
        <cite class="person1">Corey</cite>: We don't even need that.
    </blockquote>
    <pre><code>def fib(n):
        return n</code></pre>


    <div class="success">2 tests passed.</div>


    <blockquote>
        <cite class="person1">Corey</cite>: Let's write another test.
    </blockquote>
    <pre><code>def test_fib_of_2_is_1():
        assert fib(2) == 1</code></pre>
    <div class="error">1 test failed; 2 tests passed.</div>
    <blockquote>
        <cite class="person1">Corey</cite>: Now let's make it pass
    </blockquote>
    <p>I pause while I find the correct answer.</p>
    <blockquote>
        <cite class="person2">Me</cite>: Only the zero case is different.
    </blockquote>
    <pre><code>def fib(n):
        if n == 0:
            return 0
        else:
            return 1</code></pre>


    <div class="success">3 tests passed.</div>


    <p>
    (I consider the implications of this. "Only the zero case is different."
    This is an inductive system, so it needs a basis case. Zero is only half
    of the basis case of a fibonacci sequence, but I never had to think about
    a basis case or recursion to write this code. The tests showed me what the
    code needed to do.)
    </p>


    <blockquote>
        <cite class="person1">Corey</cite>: Let's write another test.
    </blockquote>
    <pre><code>def test_fib_of_3_is_2():
        assert fib(3) == 2</code></pre>
    <div class="error">1 test failed; 3 tests passed.</div>
    <blockquote>
        <cite class="person2">Me</cite>: Another if?
    </blockquote>
    <blockquote>
        <cite class="person1">Corey</cite>: Another if.
    </blockquote>
    <pre><code>def fib(n):
        if n == 0:
            return 0
        elif n  3:
            return 1
        else:
            return 2</code></pre>


    <div class="success">4 tests passed.</div>


    <blockquote>
        <cite class="person1">Corey</cite>: Refactor!
    </blockquote>
    <blockquote>
        <cite class="person2">Me</cite>: I don't know...
    </blockquote>
    <p>My brain hurts for a moment.</p>
    <pre><code>def fib(n):
        if n  2:
            return n
        else:
            return n - 1</code></pre>


    <div class="success">4 tests passed.</div>


    <p>
    The full basis case is in place and we don't even need recursion yet.  I'm
    surprised by how many cases we've written without needing recursion or
    iteration.
    </p>


    <blockquote>
        <cite class="person1">Corey</cite>: Another test.
    </blockquote>
    <pre><code>def test_fib_of_4_is_2():
        assert fib(4) == 2</code></pre>
    <div class="success">5 tests passed.</div>

    <blockquote>
        <cite class="person2">Me</cite>: It passed without changes. Is that
        OK?
    </blockquote>
    <blockquote>
        <cite class="person1">Corey</cite>: Another test!
    </blockquote>


    <pre><code>def test_fib_of_5_is_5():
        assert fib(5) == 5</code></pre>
    <div class="error">1 test failed; 5 tests passed.</div>
    <p>I think I can handle this now.</p>
    <pre><code>def fib(n):
        if n  2:
            return n
        elif n == 5:
            return 5
        else:
            return n - 1</code></pre>


    <div class="success">6 tests passed.</div>


    <blockquote>
        <cite class="person1">Corey</cite>: Refactor!
    </blockquote>
    <blockquote>
        <cite class="person2">Me</cite>: Combine them into... recursion?
    </blockquote>
    <blockquote>
        <cite class="person1">Corey</cite>: Combine them into recursion.
    </blockquote>
    <pre><code>def fib(n):
        if n = 1:
            return n
        else:
            return fib(n - 1) + fib(n - 2)</code></pre>


    <div class="success">6 tests passed.</div>
</div>

<p>
    This isn't a perfect example of TDD, but that's not the point. The first
    thing you need to understand is the rough process: write the smallest
    failing test you can; then write the smallest code to make it pass; then
    refactor without changing behavior.
</p>

<p>
    After getting this lesson from Corey, I went off and TDDed a couple
    thousand lines of code with almost no outside feedback.  I was doing it
    very poorly, and often became frustrated, but in retrospect it was still
    the best code I'd ever written.
</p>

<p>
    It takes years to learn how to do this well, and consistently, across a
    wide variety of situations. I've been doing it for two years, and I still
    <a href="http://blog.extracheese.org/2009/10/my-personal-failures-in-test-isolation.html">have
        non-trivial problems</a>, but I can almost always move forward
    confidently.
</p>
<p>
    Building software without TDD was crushingly stressful, but I couldn't see
    it at the time.  It was only shown to me when I started working one test
    at a time, one line of code at a time, with verification that the entire
    system is working in less than two seconds.
</p>

<blockquote>
    <sup>1</sup> In reality, the Coding Dojo probably went only vaguely like
    this, and this isn't even the problem we solved, but that's not the point.
    This is what the first true TDD session always looks like.
</blockquote>]]></description>
    <link><![CDATA[http://blog.extracheese.org/2009/11/how_i_started_tdd.html]]></link>
    <pubDate>2009-11-05 18:38:00</pubDate>
  </item>
  <item>
    <title><![CDATA[Jean-Paul Calderone: Free Agent]]></title>
    <description><![CDATA[<p>
As of Monday, the 9th, I will be considering opportunities for short term consulting and contract work. Please feel free to <a rel="nofollow" target="_blank" href="mailto:exarkun@twistedmatrix.com">contact me</a> if you have a software challenge to tackle, particularly if it involves one or more of Python, Twisted, networking, event-driven architectures, massive scaling, or open source software.
</p> <p>
Immediately following the demise of Divmod this summer, I took a job at a major international corporation. A number of factors conspired to make this decision non-viable in the long term. Today I gave notice. I'm excited to be able to get back to doing what I love - solving challenging, interesting problems in a flexible, open environment.
</p> <p>
One of the other things I've been unable to do since even before Divmod's end is commit serious time to Twisted development and maintenance. This is something else I'm looking forward to re-engaging in. I made a sizable dent in Twisted's open ticket count last fall and winter, thanks to funding from the <a rel="nofollow" target="_blank" href="http://twistedmatrix.com/trac/wiki/TwistedSoftwareFoundation">Twisted Software Foundation</a> (in turn thanks to all of the <a rel="nofollow" target="_blank" href="http://twistedmatrix.com/trac/wiki/TSF/FoundingSponsors">Twisted founding sponsors</a>). I'll be able to continue this work thanks to this year's sponsors (visible on the front page of <a rel="nofollow" target="_blank" href="http://twistedmatrix.com/">the Twisted site</a>), though perhaps not to the same extent. If you'd like to help out in this regard, <a rel="nofollow" target="_blank" href="http://twistedmatrix.com/trac/wiki/TwistedSoftwareFoundation#BenefitsofSponsorship">become a sponsor!</a> All donations are <a rel="nofollow" target="_blank" href="http://labs.twistedmatrix.com/2009/04/sponsorship-in-2009.html">useful</a> and appreciated!
</p>]]></description>
    <link><![CDATA[http://jcalderone.livejournal.com/52962.html]]></link>
    <pubDate>2009-11-05 18:31:59</pubDate>
  </item>
  <item>
    <title><![CDATA[Kenneth Reitz: OSX + MAMP + Python + PHP + MySQL]]></title>
    <description><![CDATA[<div class="center">
<p>If you&#8217;re a web developer who uses MAMP in conjunction with anything other than PHP, <br />I&#8217;m sure you&#8217;ve quite a large bit of frustration involving multiple MyQL instances.</p>
<p>Not any more! This simple chain of commands will save you days upon days of troubles:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="sh">sudo rm  /tmp/mysql.sock
sudo ln  /Applications/MAMP/tmp/mysql/mysql.sock /tmp/mysql.sock</pre></td></tr></table></div>

<p>I only wish I had found this sooner.</p>
<div></div>
<p><big>Enjoy.</big></p>
</div>]]></description>
    <link><![CDATA[http://kennethreitz.com/blog/osx-mamp-python-php-mysql/]]></link>
    <pubDate>2009-11-05 18:15:28</pubDate>
  </item>
  <item>
    <title><![CDATA[Patrick Stinson: Sell Out]]></title>
    <description><![CDATA[<span>Music people</span><br /><br />Go download the free Ableton Live demo and then have a look at Adam Freeland's Live set on there site, <a href="http://cdn1.ableton.com/download/fdab17e3d2734be0e73ed8e3d9c56d9c/AbleTen_AdamFreeland.zip">here</a>. Fabulous.<br /><br /><span>Programming people</span><br /><br />What's the difference between music and programming anymore anyway? Bloody hell, all of today's music has been recorded, mixed, and sometimes even conceived on software.<br /><br />When I went broke a month ago I sort of sold out and took back my old programming job. At least they called me before I called them!<br /><br />Jackson Hole is a tough place to find a bartending job, especially in the off-season. In fact you'd be better off trying to break into the hooker scene in Amsterdam. Keeping journalistic ties with fasterskier.com has given me some opportunities to supplement my income while staying very much a part of the cross country skiing world.<br /><br />This time around though, I have don't have the pressure of deadlines. I'm also working on my python-based audio scripting engine, which is a piece that only I have knowledge of and so I'm sort of working in a social hole. Oh well, at least it's money.<br /><br />The good news is that I finally get to focus on Play's python-based scripting engine. We've paid a couple of guys to write some subtle portamento and legato scripts, but as of yet no one with notable python experience has gotten a chance to sit down and flush out the development workflow. It badly needs scripts written with good style and reusability concepts so that the infinite multitudes of users that write scripts for it will have a solid place to start.<br /><br />Build settings and complex symbol linkage, processor optimizations, and deployment schemes still scare the nuts off me. So, the goal these days is to do most of my work in Play itself instead of actually developing the application.<br /><br />The cool thing about this for Python is that we've found that the language works extremely well in a real-time audio environment. It is very fast, and imposes no noticeable CPU overhead on our professional sampling engine. I am excited to have some content and discussion-prone scripting topics on this blog, and end this needless bickering about my poor job experiences.<br /><br />Oh yeah, and post some pictures of sick ski lines.<br /><br />Yay<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/130402213334709639-5577486355580492597?l=pkaudio.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://pkaudio.blogspot.com/2009/11/sell-out.html]]></link>
    <pubDate>2009-11-05 16:43:09</pubDate>
  </item>
  <item>
    <title><![CDATA[Greg Wilson: Toronto Innovations Showcase]]></title>
    <description><![CDATA[<p>My students and I a few hours on Monday and Tuesday (Nov 2-3) at City Hall showing off our projects. It wasn&#8217;t as busy as expected, thanks primarily to H1N1 fears, but there was still more traffic at our double booth than at any other I saw, and I was proud of how well the students presented their work. The projects and teams were:</p>
<ul>
<li>Q-Me: using SMS text messaging to manages lineups for things like building permits and vaccinations (Dejana Bajic, Tyler de Witt, Alex Lee, and Akhil Mathur)</li>
<li>I-Spy: allowing you to see who has looked at your medical records (Fan Dong, Lenny Han, Benton Hui, and Shobhit Jain)</li>
<li>Traffiz: analyzing and visualizing traffic accident data for the Greater Toronto Area (Samar Sabie, Alyssa Rosenzweig, and David Nowak)</li>
<li>U-Translate: crowdsourcing translation of city documents and information pamphlets (Betim Shahini and Peng Su)</li>
<li>Toronto ServiceSeeker: helping you find a better place to live based on proximity to facilities and services (Andriy Borzenko, Abayomi King, and James McRae)</li>
<li>Greenbelt Marketplace: connecting mid-sized farms in the Greenbelt to individual and institutional customers (Michael Gorecki, Jory Graham, Frank Li, and Mohit Jain)</li>
<li>XTagg: managing conversations in Twitter (Tyler Lu, Kevin Regan, Jasper Snoek, and Danny Tarlow)</li>
</ul>
<p>Feedback on the whole event is starting to appear &#8212; see for example:</p>
<ul>
<li><a href="http://webrebrand.blogspot.com/2009/11/too-many-cooks-and-not-enough-kitchens.html">Too many cooks and not enough kitchens</a></li>
<li><a href="http://torontoist.com/2009/11/toronto_exposes_its_data.php">Toronto Exposes Its Data</a></li>
</ul>
<p>I&#8217;ll add more as I find them, and post links to video of the sessions and demos when they come in. My thanks once again to the students for doing such a great job, and to all the city staff and others who&#8217;ve been so generous with their time.</p>]]></description>
    <link><![CDATA[http://pyre.third-bit.com/blog/archives/3133.html]]></link>
    <pubDate>2009-11-05 15:43:15</pubDate>
  </item>
  <item>
    <title><![CDATA[William's Journal: Non blocking connections]]></title>
    <description><![CDATA[By testing my Fapws3 webserver on different type of systems, I've discovered a strange behaviour of the Linux kernels. <br /><br />Indeed on Linux, despite my dfferent tests, I've never had the "EAGAIN" error. On the opposite, on OpenBSD 4.6 I receive a lot of those errors during the write process. <br /><br />OpenBSD is reporting that this error pop's-up because the resource is not available. Within a non-blocking context this sounds logic. Indeed, the resource can still be busy with the previous write when we try to send the new one. <br /><br />Now the valid question is why we don't have such behaviour on the linux kernel ?<br /><br />I must deeper investigate, but if someone has a explanation, I'm interested.<br /><br /><br />William<br /><a href="http://github.com/william-os4y/">http://github.com/william-os4y/</a> <br /><br /><br />ps:<br />I've used OpenBSD-4.6<br />Linux-2.6.31 from Archlinux and Ubuntu]]></description>
    <link><![CDATA[http://william-os4y.livejournal.com/6918.html]]></link>
    <pubDate>2009-11-05 15:37:52</pubDate>
  </item>
  <item>
    <title><![CDATA[Aaron Brady: Drying, with free heat]]></title>
    <description><![CDATA[<p><img src="http://insom.me.uk/09/server-room.png" alt="Server Room Temperature Graph" title="" /></p>

<p>I got very rained on today, but I need to cycle home, and I don&#8217;t want that to be in a wet coat. Where&#8217;s the warmest place in the office to put a coat to dry? Well, the server room can always use a humidity boost.</p>

<p>For what it&#8217;s worth, it <em>worked</em> and my coat is now bone dry, and you can see at (1) where I put the coat in, and (2) where it was finished drying.</p>

        

    <img src="http://feeds.feedburner.com/~r/insommeuk/~4/UBxbrbBzvW8" height="1" width="1" />]]></description>
    <link><![CDATA[http://feedproxy.google.com/~r/insommeuk/~3/UBxbrbBzvW8/drying-with-free-heat.html]]></link>
    <pubDate>2009-11-05 14:29:11</pubDate>
  </item>
  <item>
    <title><![CDATA[V.S. Babu: SVN client over SSH to remote Unix server from Windows]]></title>
    <description><![CDATA[<p>
I needed to get a quick way to work with a personal version control system accessible from multiple computers running Linux or Windows. Ideally, I'd have liked to use <a href="http://mercurial.selenic.com/">Mercurial</a> (light, easy, no great GUI available) or <a href="http://bazaar-vcs.org/">Bazaar</a> (thicker, slower, good renaming capabilities, just about the best GUI available) or <a href="http://git-scm.com/">Git </a>(fast, not a bad GUI, portable MSYS port is pretty good). However, my hosting provider provides
only CVS or Subversion and I didn't want to install any of the above ones from source under my account. Nor do I want to run any server for this. Things should work with plain SSH. Initial approach was to
create an SVN repository on the server and then access this from my computers using SSH. I tried getting <tt>svn+ssh</tt> pull for all of these above and couldn't get to work quickly enough on my Windows XP box. Had to then settle for an SVN client. Turns out that it is little tricky. Given below are the quick steps I followed to get this working.
</p>

<p>
Just a personal preference - I don't prefer using any of the <em>Tortoise*</em>GUIs. GUI as such is fairly nice, but I don't generally like installing shell extensions on Windows. Ideal solution for me would've been the ability for any of these to init a repository on a remote filesystem by SSH - couldn't find it out though.
</p>]]></description>
    <link><![CDATA[http://vsbabu.org/mt/archives/2009/11/05/svn_client_over_ssh_to_remote_unix_server_from_windows.html]]></link>
    <pubDate>2009-11-05 14:20:41</pubDate>
  </item>
  <item>
    <title><![CDATA[Grig Gheorghiu: Automated deployments with Puppet and Fabric]]></title>
    <description><![CDATA[I've been looking into various configuration management/automated deployment tools lately. At OpenX we used <a href="http://code.google.com/p/slack/">slack</a>, but I wanted something with a bit more functionality than that (although I'm not badmouthing slack by any means -- it can definitely be bent to your will to do pretty much whatever you need in terms of automating your deployments).<br /><br />From what I see, there are 2 types of configuration management tools:<br /><ol><li>The first type I call '<b>pull</b>', which means that the servers pull their configurations and their marching orders in terms of applying those configurations from a centralized location -- both slack and Puppet are in this category. I think this is great for initial configuration of a server. As I described in another post, you can have a server bootstrap itself by installing Puppet (or slack) and then 'call home' to the central Puppet master (or slack repository) and get all the information it needs to configure itself</li><li>The second type I call '<b>push</b>', which means that you send configurations and commands to a list of servers from a centralized location -- Fabric is in this category. I think this is a more appropriate mode for application-specific deployments, where you might want to deploy first to a subset of servers, then push it to all servers.</li></ol>So, as a rule of thumb, I think it makes sense to use a tool like Puppet for the initial configuration of the OS and of the packages required by your application (things like MySQL, Apache, Tomcat, Tornado, Nginx, or whatever your application relies on). When it comes time to deploy your application, I think a tool like Fabric is more appropriate, since it gives you more immediate and finer-grained control over what you want to do.<br /><br />I also like the categorization of these tools done by the people at ControlTier. Check out their <a href="http://blog.controltier.com/2009/04/new-whitepaper-achieving-fully.html">blog post on Achieving Fully Automated Provisioning </a> (which also links to a white paper <a href="http://www.dtosolutions.com/storage/downloads/FullyAutomatedProvisioning_Whitepaper.pdf">PDF</a>) for a nice diagram of hierarchy of deployment tools:<br /><ul><li>at the bottom you have tools that install or launch the initial OS on physical servers (via Kickstart/Jumpstart/Cobbler) or on virtual machines/cloud instances (via various vendor tools, or by rolling your own)</li><li>in the middle you have what they call 'system configuration' tools, such as Puppet/Chef/SmartFrog/cfengine/bcfg2</li><li>at the top you have what they call 'application service deployment' tools, such as Fabric/Capistrano/Func -- and of course their own ControlTier tool</li></ul>In a <a href="http://agiletesting.blogspot.com/2009/09/bootstrapping-ec2-images-as-puppet.html#c6668282733983700258">comment</a> on one of my posts,&nbsp; Damon Edwards from ControlTier calls Fabric a "command dispatching tool", as opposed to Puppet, which he calls a "configuration management tool". I think this relates to the 2 types of tools I described above, where you 'push' or 'dispatch' commands with Fabric, and you 'pull' configurations and actions with Puppet.<br /><br />Before I go on, let me just say that in my evaluation of different deployment tools, I quickly eliminated the ones that use XML as their configuration language. In my experience, many tools that aim to be language-neutral end up using XML as their configuration language, and then they try to bend XML into a 'real' programming language, thus ending up reinventing the wheel badly. I'd rather use a language I like (Python in my case) as the glue around the various tools in my toolchain. Your mileage may vary of course.<br /><br />OK, enough theory, let's see some practical examples of Puppet and Fabric in action. While Fabric is very easy to install and has a minimal learning curve, I can't say the same about Puppet. It takes a while to get your brain wrapped around it, and there isn't a lot of great documentation online, so for this reason I warmly recommend that you go buy <a href="http://www.amazon.com/Pulling-Strings-Puppet-Configuration-Management/dp/1590599780">the book</a>.<br /><br /><b>Puppet examples</b><br /><br />The way I organize things in <a href="http://reductivelabs.com/trac/puppet/">Puppet</a> is by creating a module for each major package I need to configure. On my puppetmaster server, under <i>/etc/puppet/modules</i>, I have directories such as <i>apache2</i>, <i>mysqlserver</i>, <i>nginx</i>, <i>scribe</i>, <i>tomcat</i>, <i>tornado</i>. Under each such directory I have 2 directories, one called <i>files</i> and one called <i>manifests</i>. I keep files and directories that I need downloaded to the puppet clients under <i>files</i>, and I create manifests (series of actions to be taken on the puppet clients) under <i>manifests</i>. I usually have a single manifest file called <i>init.pp</i>.<br /><br />Here's an example of the init.pp manifest file for my tornado module:<br /><br /><pre class="code">class tornado {<br /> $tornado = "tornado-0.2"<br /> $url = "http://mydomain.com/download"<br /><br /> $tornado_root_dir = "/opt/tornado"<br /> $tornado_log_dir = "/opt/tornado/logs"<br /> $tornado_src_dir = "/opt/tornado/$tornado"<br /><br /> Exec {<br />  logoutput =&gt; on_failure,<br />  path =&gt; ["/bin", "/sbin", "/usr/bin", "/usr/sbin", "/usr/local/bin",  "/usr/local/sbin"]<br /> }<br /><br /> file { <br />  "$tornado_root_dir":<br />  ensure =&gt; directory,<br />  recurse =&gt; true,<br />  source =&gt;  "puppet:///tornado/bin";<br /> }<br /><br /> file { <br />  "$tornado_log_dir":<br />  ensure =&gt; directory,<br /> }<br /><br /> package {<br />  ["curl", "libcurl3", "libcurl3-gnutls", "python-setuptools", "python-pycurl", "python-simplejson", "python-memcache", "python-mysqldb", "python-imaging"]:<br />  ensure =&gt; installed;<br /> }<br /><br /> define install_pkg ($pkgname, $extra_easy_install_args = "", $module_to_test_import) {<br />  exec {<br />   "InstallPkg_$pkgname":<br />   command =&gt; "easy_install-2.6 $extra_easy_install_args $pkgname",<br />   unless =&gt; "python2.6 -c 'import $module_to_test_import'",<br />   require =&gt; Package["python-setuptools"];<br />  }<br /> }<br /><br /> install_pkg {<br />  "virtualenv":<br />  pkgname =&gt; "virtualenv",<br />  module_to_test_import =&gt; "virtualenv";<br /><br />  "boto":<br />  pkgname =&gt; "boto",<br />  module_to_test_import =&gt; "boto";<br /><br />  "grizzled":<br />  pkgname =&gt; "grizzled",<br />  module_to_test_import =&gt; "grizzled.os";<br /> }<br /><br /> $oracle_root_dir = "/opt/oracle"<br /> <br /> case $architecture {<br />  i386, i686: { <br />   $oracle_instant_client_pkg = "instantclient_11_2-linux-i386"<br />   $oracle_instant_client_dir = "instantclient_11_2"<br />  }<br />  x86_64: { <br />   $oracle_instant_client_pkg = "instantclient_11_1-linux-x86_64"<br />   $oracle_instant_client_dir = "instantclient_11_1"<br />  }<br /> }<br /><br /> package {<br />  ["libaio-dev", "gcc"]:<br />  ensure =&gt; installed;<br /> }<br /><br /> file { <br />  "$oracle_root_dir":<br />  ensure =&gt; directory;<br /> }<br /><br /> exec {<br />  "InstallOracleInstantclient":<br />  command =&gt; "(cd $oracle_root_dir; wget $url/$oracle_instant_client_pkg.tar.gz; tar xvfz $oracle_instant_client_pkg.tar.gz; rm $oracle_instant_client_pkg.tar.gz; <br />cd $oracle_instant_client_dir; ln -s libclntsh.so.11.1 libclntsh.so); echo $oracle_root_dir/$oracle_instant_client_dir &gt; /etc/ld.so.conf.d/oracleinstantclient.conf; ldconfig",<br />  creates =&gt; "$oracle_root_dir/$oracle_instant_client_dir",<br />  require =&gt; File[$oracle_root_dir];<br /> }<br /><br /> $cx_oracle = "cx_Oracle-5.0.2"<br /> exec {<br />  "InstallCxOracle":<br />  command =&gt; "(cd $oracle_root_dir; wget $url/$cx_oracle.tar.gz; tar xvfz $cx_oracle.tar.gz; rm $cx_oracle.tar.gz; cd $oracle_root_dir/$cx_oracle; export ORACLE_HO<br />ME=$oracle_root_dir/$oracle_instant_client_dir; python2.6 setup.py install)",<br />  unless =&gt; "python2.6 -c 'import cx_Oracle'",<br />  require =&gt; [Package["libaio-dev"], Package["gcc"], Exec["InstallOracleInstantclient"]];<br /> }<br /><br /> exec {<br />  "InstallTornado":<br />  command =&gt; "(cd $tornado_root_dir; wget $url/$tornado.tar.gz; tar xvfz $tornado.tar.gz; rm $tornado.tar.gz; cd $tornado; python2.6 setup.py install)",<br />  creates =&gt; $tornado_src_dir,<br />  unless =&gt; "python2.6 -c 'import tornado.web'",<br />  require =&gt; [File[$tornado_root_dir], Package["python-pycurl"], Package["python-simplejson"], Package["python-memcache"], Package["python-mysqldb"]];<br /> }<br />}<br /></pre><br />I'll go through this file from the top down. At the very top I declare some variables that are referenced throughout the file. In particular, $url points to the location where I keep large files that I need every puppet client to download. I could have kept the files inside the tornado module's <i>files</i> directory, and they would have been served by the puppetmaster process, but I prefered to use Apache for better performance and scalability. Note that I do this only for relatively large files such as tar.gz archives.<br /><br />The Exec stanza (note upper case E) defines certain parameters that will be common to all 'exec' actions that follow. In my case, I specify that I only want to log failures, and I also specify the path for the binaries called in the various 'exec' actions -- this is so I don't have to specify that path each and every time I call 'exec' (alternatively, you can specify the full path to each binary that you call).<br /><br />The next 2 stanzas define files and directories that I want created on the puppet client nodes. Both 'exec' and 'file' are what is called '<a href="http://reductivelabs.com/trac/puppet/wiki/TypeReference">types</a>' in Puppet lingo. I first specify that I wanted the directory <i>/opt/tornado</i> created on each node, and by setting '<i>recurse=&gt;true</i>' I'm saying that the contents of that directory should be taken from a source which in my case is "<i>puppet:///tornado/bin</i>". This translates to a directory called <i>bin</i> which I created under <i>/etc/puppet/modules/tornado/files</i>. The contents of that directory will be copied over via the puppet internal communication protocol to the destination <i>/opt/tornado</i> by each Puppet client node.<br /><br />The 'package' type that follows specifies the list of packages I want installed on the client nodes. Note that I don't need to specify <b>how</b> I want those packages installed, only <b>what</b> I want installed. Puppet's language is mostly <b>declarative</b> -- you tell Puppet what you want done, and it does it for you, using OS-specific commands that can vary from one client node to another. It so happens in my case that I know my client nodes all run Ubuntu, so I did specify Ubuntu/Debian-specific package names.<br /><br />Next in my manifest file is a function definition. You can have these definitions inline, or in a separate manifest file. In my case, I declare a function called <i>'install_pkg</i>' which takes 3 arguments: the package name, any extra arguments to be passed to the installer, and a module name to test the installation with. The function runs the easy_install command via the '<i>exec</i>' type, but only if the specified module wasn't already installed on the system.<br /><br />A paranthesis: the Puppet docs don't recommend the overuse of the '<i>exec</i>' type, because it strays away from the declarative nature of the Puppet language. With <i>exec</i>, you specifically tell the remote node how to run a specific command, not merely what to do. I find myself using <i>exec</i> very heavily though. I means that I don't grokk Puppet fully yet, but it also means that Puppet doesn't have enough native types yet that can hide OS-specific commands.<br /><br />One important thing to keep in mind is that for every <i>exec</i> action that you write, you need to specify a condition which becomes true after the successful completion of the action. Otherwise <i>exec</i> will be called each and every time the manifest will be inspected by the puppet nodes. Examples of such conditions:<br /><ul><li>'<i>creates</i>' -- specifies a file or directory that gets created by the exec action; if the file or directory is already there, exec won't be called<br /></li><li>'<i>unless</i>' -- specifies a condition that, if true, results in exec not being called. In my case, this condition is the import of a given Python module, but it can be any shell command that returns 0</li></ul>Another thing to note in the <i>exec</i> action is the '<i>require</i>' parameter. You'll find yourself using '<i>require</i>' over and over again. It is a critical component of Puppet manifests, and it is so important because it allows you to <b>order</b> the actions in the manifest. Without it, actions would be executed in random order, which is most likely something you don't want. In my function definition, I require the existence of the package python-setuptools, and I do it because I need the easy_install command to be present on the remote node.<br /><br />After defining the function '<i>install_pkg</i>', I call it 3 times, with various parameters, thus installing 3 Python packages -- virtualenv, boto and grizzled. Note that the syntax for calling a function is funky; it's one of the many things I don't necessarily like about Puppet, but it's an evil you learn to deal with.<br /><br />Next up in my manifest file is a <i>case</i> statement based on the <i>$architecture</i> variable. Puppet makes several such variables available to your manifests, based on facts gathered from the remote nodes via <a href="http://reductivelabs.com/trac/puppet/tags/facter%2Crecipe">Facter</a> (which comes with Puppet).<br /><br />Moving along, we have a package definition, a file definition -- both should be familiar by now -- followed by 3 exec actions:<br /><ul><li><i>InstallOracleInstantclient</i> performs the download and unpacking of this package, followed by some ldconfig incantations to actually make it work</li><li><i>InstallCxOracle</i> downloads and installs the cx_Oracle Python package (not a trivial feat at all in and of itself); note that for this action, the <i>require</i> parameter contains <i>Package["libaio-dev"], Package["gcc"], Exec["InstallOracleInstantclient"]</i> -- so we're saying that these 2 packages, and the Instantclient Oracle libraries need to be installed before attempting to even install cx_Oracle<br /></li><li><i>InstallTornado</i> -- pretty self-explanatory, with the observation that the <i>require</i> parameter again points to a directory and several packages that need to be on the remote node before the installation of Tornado is attempted</li></ul>Whew. Nobody said Puppet is easy. But let me tell you, when you get everything working smoothly (after much pulling of hair), it's a great feeling to let a node 'phone home' to the puppetmaster server and configure itself unattended in a matter of minutes. It's worth the effort and the pain.<br /><br />One more thing here: once you have a module with manifests and files defined properly, you need to define the set of nodes that this module will apply to. The way I do it is to have the following files on the puppet master, in /etc/puppet/manifests:<br /><br />1) A file called <i>modules.pp</i> which imports the modules I have defined, for example:<br /><pre class="code">import "common" <br />import "tornado"<br /></pre>('common' can be a module where you specify actions that are common across all types of nodes)<br /><br />2) A file called <i>nodetemplates.pp</i> which contains definitions for 'node templates', i.e. classes of nodes that have the same composition in terms of modules they import and actions they perform. For example:<br /><pre class="code">node basenode {<br />&nbsp;&nbsp;&nbsp; include common<br />}<br /><br />node default inherits basenode {<br />}<br /><br />node webserver inherits basenode {<br />&nbsp;&nbsp;&nbsp; include scribe<br />&nbsp;&nbsp;&nbsp; include apache2<br />&nbsp;&nbsp;&nbsp; $required_apache2_modules = ["rewrite", "proxy", "proxy_http", "proxy_balancer", "deflate", "headers", "expires"]<br />&nbsp;&nbsp;&nbsp; apache2::module {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $required_apache2_modules:<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ensure =&gt; 'present',<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; include tomcat<br />&nbsp;&nbsp;&nbsp; include tornado<br />}<br /></pre><br />Here I defined 3 types of nodes: basenode (which includes the 'common' module), default (which applies to any machine not associated with a specific node definition) and webserver (which includes modules such as apache2, tomcat, tornado, and also requires that certain apache modules be enabled).<br /><br />3) A file called nodes.pp which maps actual machine names of the Puppet clients to node template definitions. For example:<br /><pre class="code">node "web1.mydomain.com" inherits webserver {}<br /></pre>4) A file called site.pp which ties together all these other files. It contains:<br /><pre class="code">import "modules"<br />import "nodetemplates"<br />import "nodes"&nbsp;</pre><pre class="code"></pre><br />Much more documentation on node definition and node inheritance can be found on the Puppet wiki, especially in the <a href="http://reductivelabs.com/trac/puppet/wiki/LanguageTutorial">Language Tutorial</a>.<br /><br /><b>Fabric examples</b><br /><br />In comparison with Puppet, <a href="http://www.nongnu.org/fab/">Fabric</a> is a breeze. I wanted to live on the cutting edge, so I installed the latest version (alpha, pre-1.0) from <a href="http://github.com/bitprophet/fabric">github</a> via:<br /><br />git clone <a class="git_url_facebox" href="git://github.com/bitprophet/fabric.git" rel="#git-clone">git://github.com/bitprophet/fabric.git</a><br /><br />I also easy_install'ed paramiko, which at this time brings down paramiko-1.7.6 (the Fabric documentation warns against using 1.7.5, but I assume 1.7.6 is OK).<br /><br />Then I proceeded to create a so-called 'fabfile', which is a Python module containing fabric-specific functions. Here is a fragment of a file I called fab_nginx.py:<br /><br /><pre class="code">from __future__ import with_statement<br />import os<br />from fabric.api import *<br />from fabric.contrib.files import comment, sed<br /><br /># Globals<br /><br />env.user = 'myuser'<br />env.password = 'mypass'<br />env.nginx_conf_dir = '/usr/local/nginx/conf'<br />env.nginx_conf_file = '%(nginx_conf_dir)s/nginx.conf' % env<br /><br /># Environments<br /><br /><br />def prod():<br />    """Nginx production environment."""<br />    env.hosts = ['nginx1', 'nginx2']<br /><br />def test():<br />    """Nginx test environment."""<br />    env.hosts = ['nginx3']<br /><br /># Tasks<br /><br />def disable_server_in_lb(hostname):<br />    require('hosts', provided_by=[nginx,nginxtest])<br />    comment(env.nginx_conf_file, "server %s" % hostname, use_sudo=True)<br />    restart_nginx()<br /><br />def enable_server_in_lb(hostname):<br />    require('hosts', provided_by=[nginx,nginxtest])<br />    sed(env.nginx_conf_file, "#server %s" % hostname, "server %s" % hostname, use_sudo=True)<br />    restart_nginx()<br /><br />def restart_nginx():<br />    require('hosts', provided_by=[nginx,nginxtest])<br />    sudo('/etc/init.d/nginx restart')<br />    is_nginx_running()<br /><br />def is_nginx_running(warn_only=False):<br />    with settings(warn_only=warn_only):<br />        output = run('ps -def|grep nginx|grep -v grep')<br />        if warn_only:<br />            print 'output:', output<br />            print 'failed:', output.failed<br />            print 'return_code:', output.return_code<br /></pre><br />Note that in its 0.9 and later versions, Fabric uses the '<i>env</i>' <a href="http://docs.fabfile.org/0.9/usage/env.html">environment dictionary</a> for configuration purposes (it used to be called 'config' pre-0.9).<br /><br />My file starts by defining or assigning global <i>env</i> configuration variables, for example <i>env.user</i> and <i>env.password</i> (which are special pre-defined variables that I assign to, and which are used by Fabric when connecting to remote hosts via the ssh functionality provided by paramiko). I also define my own variables, for example <i>env.nginx_conf_dir</i> and <i>env.nginx_conf_file</i>. This makes it easy to pass the env dictionary as a whole when I need to format a string. Here's an example from another fab file:<br /><br /><pre class="code">cmd = 'mv -f %(crt_egg)s %(backup_dir)s' % env<br /></pre><br />I then have 2 function definitions in my fab file: one called <i>prod</i>, which sets env.hosts to a list of production nginx servers, and one called <i>test</i>, which does the same but sets env.hosts to test nginx servers.<br /><br />Next I have the actions or tasks that I want performed on the remote hosts. Note the <i>require</i> function (similar in a way to the parameter used in Puppet manifests), which says that the function will only be executed if the given variable in the env dictionary has been assigned to (in my case, the variable is hosts, and I require that the value need to have been provided by either the prod or the test function). This is a useful mechanism to ensure that certain things have been defined before attempting to run commands on the remote servers.<br /><br />The first task is called <i>disable_server_in_lb</i>. It takes a host name as a parameter, which is the server that I want disabled in the nginx configuration file. I use the handy '<i>comment</i>' function available in fabric.contrib.files to comment out the lines that contain '<i>server HOSTNAME</i>' in the nginx configuration. The comment function can be invoked with sudo rights on the remote host by passing <i>use_sudo=True</i>.<br /><br />The task also calls another function defined in my fab file, <i>restart_nginx</i>. This taks simply calls '<i>/etc/init.d/nginx restart</i>' on the remote host, then verifies that nginx is running by calling <i>is_nginx_running</i>.<br /><br />By default, when running a command on the remote host, if the command returns a non-zero code, it is considered to have failed by Fabric, and execution stops. In most cases, this is exactly what you want. In case you just want to run a command to get the output, and you don't care if it fails, you can set <i>warn_only=True</i> before running the command. I show an example if this in the <i>is_nginx_running </i>function.<br /><br />The other main task in my fabfile is <i>enable_server_in_lb</i>. Here I use another handy function offered by Fabric -- the <i>sed</i> function. I substitute '<i>#server&nbsp; HOSTNAME</i>' with '<i>server HOSTNAME</i>' in the nginx configuration file, then I restart nginx.<br />So now that we have the fabfile, how do we actually perform the tasks we defined? Let's assume we have a server called 'web1.mydomain.com' that we want disabled in nginx. We want to test our task first in a test environment, so we would call:<br /><pre class="code">fab -f fab_nginx.py test disable_server_in_lb:web1.mydomain.com<br /></pre>(note the syntax for passing parameters to a function/task)<br /><br />By specifying test on the command line before specifying the task, I ensure that Fabric first calls the function named 'test' in the fabfile, which sets the hosts to the test nginx servers.<br /><br />Once I'm satisfied that this works well in the test environment, I call:<br /><br /><pre class="code">fab -f fab_nginx.py prod disable_server_in_lb:web1.mydomain.com<br /></pre><br />For a real deployment procedure, let's say for deploying tornado-based servers that are behind one or more nginx load balancer, I would do something like this:<br /><br /><pre class="code">fab -f fab_nginx.py prod disable_server_in_lb:web1.mydomain.com<br />fab -f fab_tornado.py prod deploy<br />fab -f fab_nginx.py prod enable_server_in_lb:web1.mydomain.com<br /></pre><br />This will deploy my new application code to web1.mydomain.com. Of course I can script this and call the above sequence for all my production servers. I assume here that I have another fabfile called fab_tornado.py and a task defined in in which does the actual deployment of the application code (most likely by downloading and easy_install'ing an egg).<br /><br />That's it for today. It's been more like a whirlwind through two types of automated deployment tools -- Puppet/pull and Fabric/push. I didn't do justice to either of these tools in terms of their full capabilities, but I hope this will still be useful for some people as a starting point into their own explorations.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/9238405-8491072546269562393?l=agiletesting.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://agiletesting.blogspot.com/2009/11/automated-deployments-with-puppet-and.html]]></link>
    <pubDate>2009-11-05 13:55:52</pubDate>
  </item>
  <item>
    <title><![CDATA[Guido van Rossum: Python in the Scientific World]]></title>
    <description><![CDATA[<div><div>Yesterday I attended a biweekly meeting of an informal a UC Berkeley group devoted to Python in science (Py4Science), organized by Fernando Perez. The format (in honor of my visit) was a series of 4-minute lightning talks about various projects using Python in the scientific world (at Berkeley and elsewhere) followed by an hourlong Q&amp;A session. This meant I didn't have to do a presentation and still got to interact with the audience for an hour -- my ideal format.</div><div><br /></div><div>I was blown away by the wide variety of Python use for scientific work. It looks like Python (with extensions like numpy) is becoming a standard tool for many sciences that need to process large amounts of data, from neuroimaging to astronomy.</div><div><br /></div><div>Here is a list of the topics presented. All these describing Python software; I've added names insofar they were present on the slides. Most projects are easily found by Googling for them, so I have not included hyperlinks except in some cases where the slides emphasized them.</div><div><ul><li>Fernando gave an overview of the core Python software used throughout scientific computing: NumPy, Matplotlib, IPython (by Fernando), Mayavi, Sympy (about which more later), Cython, and lots more.</li></ul></div><div><ul><li>On behalf of Andrew Straw (Caltech), Fernando showed a video of an experimental setup where a firefly is tracked in real time by 8 camaras spewing 100 images per second, using Python software.</li></ul></div><div><ul><li>Nitimes, a time-series analysis tool for neuroimaging.</li></ul><ul><li>A comparative genomics tool by Brent Pedersen of the Freeling Lab / Plant Biology.</li></ul><ul><li>Copperhead: Data-Parallel Python, by Bryan Catanzaro and others.</li></ul><ul><li>Nipype: Neuroimaging analysis pipeline and interfaces in Python (http://nipy.sourceforge.net/nipype/).</li></ul><ul><li>SymPy -- a library for symbolic mathematics in Pure Python, by Ondrej Certik (runs on Google App Engine: http://live.sympy.org).</li></ul><ul><li>Enthought Python Distribution -- a Python distro with scientific batteries inluded (some proprietary, many open source), supporting Windows, Mac, Linux and Solaris.</li></ul><ul><li>PySKI, by Erin Carson and others -- a tool for auto-tuning computational kernels on sparse matrices.</li></ul><ul><li>Rapid classification of astronomical time-series data, by Josh Bloom, Astronomy Dept. One of the many tools using Python is GroupThink, which lets random people on the web help classify galaxies (more fun than watching porn :-).</li></ul><ul><li>The Hubble Space Telescope team in Baltimore has used Python for 10 years. They showed a tool for removing noise generated by cosmic rays from photos of galaxies. The future James Webb Space Telescope will also be using Python.</li></ul><ul><li>A $1B commitment by the Indian government to improve education in India includes a project by Prabhu Ramachandran of the Department of Aerospace Engineering at IIT Bombay for Python in Science and Engineering Education in India (see http://fossee.in/).</li></ul><ul><li>Wim Lavrijsen from LBNL presented work on Python usage in High Energy Physics.</li></ul><ul><li>William Stein presented SAGE, a viable free open source alternative to Magma, Maple, Mathematica and Matlab.</li></ul></div><div>All in all, the impression I got was of an incredible wealth of software, written and maintained by dedicated volunteers all over the scientific community.</div><div><br /></div><div>During the Q&amp;A session, we touched upon the usual topics, like Python 3 transition, the GIL (there was considerable interest in Antoine Pitrou's newgil work, which unfortunately I could not summarize adequately because I haven't studied it enough yet), Unladen Swallow, and the situation with distutils, setuptools and the future 'distribute' package (for which I unfortunately had to defer to the distutil-sig).</div><div><br /></div><div>The folks maintaining NumPy have thought about Python 3 a lot, but haven't started planning the work. Like many other projects faced with the Python 3 porting task, they don't have enough people who actually know the code base well enough do embark upon such a project. They do have a plan for arriving at PEP 3118 compliance within the next 6 months.</div><div><br /></div><div>Since NumPy is at the root of the dependency graph for much of the software packages presented here, getting NumPy ported to Python 3 is pretty important. We briefly discussed a possible way to obtain NumPy support for Python 3 sooner and with less effort: a smaller "core" of NumPy could be ported first, which would give the NumPy maintainers a manageable task, combined with the goal of selecting a smaller "core" which would give them the opportunity for a clean-up at the same time. (I presume this would mostly be a selection of subpackage to be ported, not an API-by-API cleanup of APIs; the latter would be a bad thing to do simultaneous with a big port.)</div><div><br /></div><div>After the meeting, Fernando showed me a little about how NumPy is maintained. They have elaborate docstrings that are marked up with a (very light) variant of Sphynx, and they let the user community edit the docstrings through a structured wiki-like setup. Such changes are then presented to the developers for review, and can be incorporated into the code base with minimal effort.</div><div><br /></div><div>An important aspect of this approach is that the users who edit the docstrings are often scientists who understand the computation being carried out in its scientific context, and who share their knowledge about the code and its background and limitations with other scientists who might be using the same code. This process, together with the facilities in IPython for quickly calling up the docstring for any object, really improves the value of the docstrings for the community. Maybe we could use something like this for the Python standard library; it might be a way that would allow non-programmers to help contribute to the Python project (one of the ideas also mentioned in the diversity discussions).</div></div><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/4195135246107166251-6686408606508944888?l=neopythonic.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://neopythonic.blogspot.com/2009/11/python-in-scientific-world.html]]></link>
    <pubDate>2009-11-05 10:18:31</pubDate>
  </item>
  <item>
    <title><![CDATA[Python Software Foundation: First pyArkansas an Unqualified Success]]></title>
    <description><![CDATA[<p><span>We are grateful to Greg Lindstrom for the following feedback on a recent successful regional event. Congratulations are due to the organizers.</span></p>

<p>We held our 1-day "pyArkansas" conference on the campus of the University of Central Arkansas with 57 people attending.  There was a surprising mix of beginners (which we expected) and experienced (which pleasantly surprised us).  The first half of the day was dedicated to classes; <span>Python 101</span> (Dr. Bernard Chen of UCA), <span>Intermediate Python</span> (Jeff Rush) and <span>Python for System Administrators</span> (Noah Gift).  A way cool perk was that everyone attending the sys admin class received a copy of Noah's new book!  The afternoon was dedicated to talks and open space.  All participants received a swag bag with a copy of Python Magazine, a GIS magazine, python stickers and other stuff.</p>

<p>We had fantastic support from various employers and the Conway Chamber of Commerce.  I am pleased to thank the PSF for your offer of $300 reimbursement and very respectfully decline it; we were able to cover our expenses, provide lodging for Jeff and Noah, and even give them a few dollars for their efforts.  We have a grant request in to the Conway Advertising and Promotion Commission for $3,000 for next year.  If we get that, the Chamber of Commerce will pony up another $1,500, leaving us with about $1,000 more to raise.  Bringing in speakers was very well -- extremely well -- received and we want to expand on it next year, with a goal to bring in 4 speakers/teachers.  Modeling the conference as a hybrid between a "mini-PyCon" and an "unconference" makes sense as many of our participants were brand new to Python while others wanted open space.</p>

<p>We got some <a href="http://businessfromthejohn.blogspot.com/2008/10/arkansas-gets-it.html">very nice ink</a> from Dr. John Tabor.  It's that kind of response that prompted the Chamber of Commerce to have us submit a grant request to the A&amp;P.</p>

<p>I have a more detailed report written up if anyone would like to see it (or if there is somewhere I can post it).</p>

<p>Thanks for your encouragement and support.  Special thanks to Noah and Jeff for making the trip to Arkansas.</p>

<p><span>Please note that, while we are pleased that this event managed to run without our sponsorship, the PSF Board is always prepared to consider funding requests for events that demonstrably benefit the Python community.</span></p><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/8520-1193395844710913600?l=pyfound.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://pyfound.blogspot.com/2008/10/first-pyarkansas-unqualified-success.html]]></link>
    <pubDate>2009-11-05 08:27:48</pubDate>
  </item>
  <item>
    <title><![CDATA[Catherine Devlin: pernicious python.org proxy problem]]></title>
    <description><![CDATA[For the past few weeks, I haven't been able to access python.org or any of its pages through a proxy server.  My workplace has one standard proxy server, and I also use a personal machine as a SOCKS proxy for an SSH tunnel - and both of them have been getting name resolution errors for all python.org sites.  I haven't seen it for any other sites, or when using no proxy.<br /><br />Does anybody know what's going on?  Is there something about python.org that would make name resolution work differently for it?<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/11802292-7453620171955511211?l=catherinedevlin.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://catherinedevlin.blogspot.com/2009/11/pernicious-pythonorg-proxy-problem.html]]></link>
    <pubDate>2009-11-05 07:21:16</pubDate>
  </item>
  <item>
    <title><![CDATA[Jarrod Millman: SciPy India 2009 Call for Presentations]]></title>
    <description><![CDATA[The <a href="http://scipy.in/">SciPy India 2009</a> Program Committee is currently developing the conference program.   We are seeking presentations from industry as well as the academic world.<br /><br />We look forward to hearing your how you are using Python!  For more information, please read the full <a href="http://scipy.in/talks-cfp/">call for presentations</a>.<br /><br /><span>About the SciPy India 2009 Conference</span><br /><br />The first <a href="http://scipy.in/">SciPy India Conference</a> will be held from December 12th to 17th, 2009 at the <a href="http://www.technopark.org/">Technopark</a> in Trivandrum, Kerala, India.<br /><br />The theme of the conference is "Scientific Python in Action" with respect to application and teaching.  We are pleased to have Travis Oliphant, the creator and lead developer of <a href="http://numpy.scipy.org/">numpy</a> as the keynote speaker.<br /><br />Please register <a href="http://scipy.in/submit-registration/">here</a>.<br /><br /><span>Important Dates</span><br /><ul><li>Friday, Nov. 20: Abstracts Due</li><li>Friday, Nov. 27: Announce accepted talks, post schedule</li><li>Saturday-Sunday, Dec. 12-13               Conference</li><li>Monday-Tuesday, Dec. 14-15        Tutorials</li><li>Wednesday-Thursday, Dec. 16-17     Sprints</li></ul><span>Organizers</span><br /><ul><li><a href="http://www.jarrodmillman.com/">Jarrod Millman</a>, <a href="http://neuroscience.berkeley.edu/">Helen Wills Neuroscience Institute</a>, <a href="http://www.berkeley.edu/">University of California, Berkeley</a>, USA (Conference Co-Chair)</li><li><a href="http://www.aero.iitb.ac.in/%7Eprabhu">Prabhu Ramachandran</a>, <a href="http://www.aero.iitb.ac.in/">Department of Aerospace Engineering</a>, <a href="http://www.iitb.ac.in/">Indian Institute of Technology, Bombay</a>, India (Conference Co-Chair)</li><li><a href="http://fossee.in/people">FOSSEE Team</a></li></ul><span>Sponsors</span><br /><ul><li><a href="http://www.sakshat.ac.in/">National Mission on Education (NME)</a> through Information and Communication Technologies (ICT), Government of India</li><li><a href="http://space-kerala.org/">SPACE-Kerala</a></li><li><a href="http://www.itmission.kerala.gov.in/">Kerala State IT Mission (KSITM)</a></li><li><a href="http://csi-india.org/">SIG-FOSS Of CSI</a></li></ul><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7039308593110047510-7499928018150977554?l=jarrodmillman.blogspot.com" /></div>]]></description>
    <link><![CDATA[http://jarrodmillman.blogspot.com/2009/11/scipy-india-2009-call-for-presentations.html]]></link>
    <pubDate>2009-11-05 03:33:25</pubDate>
  </item>
  <item>
    <title><![CDATA[Evan Fosmark: Python Markov Chains and how to use them]]></title>
    <description><![CDATA[<p>So, due to <a href="http://www.evanfosmark.com/2009/07/creating-fake-words/#comments">recommendations to use Markov chains for text generation</a> after my last little script on <a href="http://www.evanfosmark.com/2009/07/creating-fake-words/">creating fake words</a>, I have finally gotten around to learning and implementing the <a href="http://en.wikipedia.org/wiki/Markov_chain#Markov_text_generators">Markov chain algorithm for text generation</a> in Python. There were <a href="http://code.activestate.com/recipes/194364/">a few</a> <a href="http://uswaretech.com/blog/2009/06/pseudo-random-text-markov-chains-python/">different implementations</a> already available, but they all seemed a bit gimpy.  The solution I wrote up aims to be able to support high volumes of text. Take a look at what I conjured up and tell me what you think: </p>

<div class="wp_syntax"><div class="code"><pre class="python"><span>import</span> <span>collections</span>
<span>import</span> <span>random</span>
&nbsp;
<span>class</span> _ChainLink<span>&#40;</span><span>object</span><span>&#41;</span>:
    <span>""</span><span>" Internal use only.
        This is used for managing the possibilities for a next item (usually a
        word or letter) randomly through keeping track of quantity.
    "</span><span>""</span>
    <span>def</span> <span>__init__</span><span>&#40;</span><span>self</span><span>&#41;</span>:
        <span>self</span>._list = <span>&#91;</span><span>&#93;</span>
&nbsp;
    <span>def</span> add<span>&#40;</span><span>self</span>, item<span>&#41;</span>:
        <span>""</span><span>" Add an item to the chain link.
            If the item is already in the chain link, simply increment the 
            quantity counter.
        "</span><span>""</span>
        <span>for</span> i, <span>&#40;</span>qty, value<span>&#41;</span> <span>in</span> <span>enumerate</span><span>&#40;</span><span>self</span>._list<span>&#41;</span>:
            <span>if</span> value == item:
                <span>self</span>._list<span>&#91;</span>i<span>&#93;</span> = <span>&#40;</span>qty<span>+1</span>, item<span>&#41;</span>
                <span>return</span>
        <span>self</span>._list.<span>append</span><span>&#40;</span><span>&#40;</span><span>1</span>, item<span>&#41;</span><span>&#41;</span>
&nbsp;
    <span>def</span> get_random<span>&#40;</span><span>self</span><span>&#41;</span>:
        <span>""</span><span>" Retreive a random item.
            This works by using the quantity as a weight for selecting a random
            value.
        "</span><span>""</span>
        total = <span>sum</span><span>&#40;</span>qty <span>for</span> qty, val <span>in</span> <span>self</span>._list<span>&#41;</span>
        random_num = <span>random</span>.<span>randint</span><span>&#40;</span><span>0</span>, total<span>&#41;</span>
        total_pos = <span>0</span>
        <span>for</span> qty, value <span>in</span> <span>self</span>._list:
            total_pos += qty
            <span>if</span> random_num <span>&lt;</span>= total_pos:
                <span>return</span> value
&nbsp;
&nbsp;
<span>class</span> MarkovChain<span>&#40;</span><span>collections</span>.<span>defaultdict</span><span>&#41;</span>:
    <span>""</span><span>" Yet another markov chain implementation.
        This one differs in the sense that it is able to better support
        huge amounts of data since the weighted randomization doesn't rely
        on duplicates.
    "</span><span>""</span>
&nbsp;
    <span># Sentinals </span>
    <span># Discussion here: http://stackoverflow.com/questions/1677726</span>
    <span>class</span> START<span>&#40;</span><span>object</span><span>&#41;</span>:<span>pass</span>
    <span>class</span> END<span>&#40;</span><span>object</span><span>&#41;</span>:<span>pass</span>
&nbsp;
    <span>def</span> <span>__init__</span><span>&#40;</span><span>self</span><span>&#41;</span>:
        <span>collections</span>.<span>defaultdict</span>.<span>__init__</span><span>&#40;</span><span>self</span>, _ChainLink<span>&#41;</span>
&nbsp;
    <span>def</span> add<span>&#40;</span><span>self</span>, iterable<span>&#41;</span>:
        <span>""</span><span>" Insert an iterable (pattern) item into the markov chain.
            The order of the pattern will define more of the chain.
        "</span><span>""</span>
        item1 = item2 = MarkovChain.<span>START</span>
        <span>for</span> item3 <span>in</span> iterable:
            <span>self</span><span>&#91;</span><span>&#40;</span>item1, item2<span>&#41;</span><span>&#93;</span>.<span>add</span><span>&#40;</span>item3<span>&#41;</span>
            item1 = item2
            item2 = item3
        <span>self</span><span>&#91;</span><span>&#40;</span>item1, item2<span>&#41;</span><span>&#93;</span>.<span>add</span><span>&#40;</span>MarkovChain.<span>END</span><span>&#41;</span>
&nbsp;
    <span>def</span> random_output<span>&#40;</span><span>self</span>, <span>max</span>=<span>100</span><span>&#41;</span>:
        <span>""</span><span>" Generate a list of elements from the markov chain.
            The `max` value is in place in order to prevent excessive iteration.
        "</span><span>""</span>
        output = <span>&#91;</span><span>&#93;</span>
        item1 = item2 = MarkovChain.<span>START</span>
        <span>for</span> i <span>in</span> <span>range</span><span>&#40;</span><span>max</span><span>-2</span><span>&#41;</span>:
            item3 = <span>self</span><span>&#91;</span><span>&#40;</span>item1, item2<span>&#41;</span><span>&#93;</span>.<span>get_random</span><span>&#40;</span><span>&#41;</span>
            <span>if</span> item3 <span>is</span> MarkovChain.<span>END</span>:
                <span>break</span>
            output.<span>append</span><span>&#40;</span>item3<span>&#41;</span>
            item1 = item2
            item2 = item3
        <span>return</span> output</pre></div></div>

<p>It&#039;s not really complicated as long as you understand Markov chains. Let&#039;s use this in an example to generate some fake words:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span>import</span> markov
chain = markov.<span>MarkovChain</span><span>&#40;</span><span>&#41;</span>
&nbsp;
<span># Load the dictionary into the markov chain</span>
dictionary = <span>"/usr/share/dict/words"</span>
<span>for</span> word <span>in</span> <span>open</span><span>&#40;</span>dictionary<span>&#41;</span>:
    word = word.<span>strip</span><span>&#40;</span><span>&#41;</span>
    <span>if</span> word <span>!</span>= <span>""</span> <span>and</span> <span>not</span> word.<span>endswith</span><span>&#40;</span><span>"'s"</span><span>&#41;</span>:
        chain.<span>add</span><span>&#40;</span>word<span>&#41;</span>
&nbsp;
<span># Let's generate 10 random pseudowords</span>
<span>for</span> i <span>in</span> <span>range</span><span>&#40;</span><span>10</span><span>&#41;</span>:
    <span>print</span> <span>""</span>.<span>join</span><span>&#40;</span>chain.<span>random_output</span><span>&#40;</span><span>&#41;</span><span>&#41;</span></pre></div></div>

<p>The way I did it above isn&#039;t actually that good since it loads every word in the English language into the Markov chain. Of course, you don&#039;t need all of the words to get good looking output. This is just an example, though. I&#039;ll leave it up to you to make a sufficient solution. </p>
<p>As always, if you see a way that the code in this post could be improved, please leave a comment!</p>]]></description>
    <link><![CDATA[http://www.evanfosmark.com/2009/11/python-markov-chains-and-how-to-use-them/]]></link>
    <pubDate>2009-11-05 02:34:23</pubDate>
  </item>
  <item>
    <title><![CDATA[Mikeal Rogers: CouchDB View Performance (Python vs JavaScript)]]></title>
    <description><![CDATA[<p>We&#8217;re gearing up for some heavy CouchDB usage in a new automation system and it has fallen upon me to do some performance benchmarking.</p>
<p>The most important thing for us to figure out was whether or not the CentOS virtual machine we&#8217;re currently running CouchDB on is going to be enough even in the short term. Until today we&#8217;ve been running 0.9 and have encountered performance problems. </p>
<p>Our main bottleneck is, and has always been, view generation and update performance. We tend to have medium to large size documents (jobs are relatively small but results from test runs can be incredibly large). </p>
<p>View generation of large documents has typically been our biggest issue which we have previously mitigated by refreshing all views after any large write but that isn&#8217;t going to work for the amount of results that we plan on pouring in to the new system.</p>
<p>Last weekend I wrote a <a href="http://github.com/mikeal/couchdb-pythonviews">Python view server for CouchDB</a>. couchdb-python <a href="http://code.google.com/p/couchdb-python/source/browse/trunk/couchdb/view.py">includes a view server</a> but in the past I&#8217;ve heard complaints about performance (although none recently). In addition, the view server in couchdb-python only supports map and reduce, which is only about 1/5 of the current view server spec which includes handlers for update, show, list, filter, and validate which provide the groundwork for CouchDB as an application platform. As of Sunday my view server passes <a href="http://github.com/mikeal/couchdb/blob/master/test/query_server_spec.rb">all of the current CouchDB spec</a> and initial performance tests showed it faster than the JavaScript view server.</p>
<p>Below are the performance graphs for CouchDB trunk running on a CentOS virtual machine. I&#8217;m using Python 2.6 with the default stdlib json library. The spidermonkey core is 1.7 (I don&#8217;t know what the status of using 1.8 with CouchDB is but as we&#8217;ll see below, this won&#8217;t improve performance too much for these tests).</p>
<p>These graphs show view generation time for a given number of documents in a new database. The design doc I used had two views, one does emit(doc['type'],doc), the other emit(doc['_id'], 1). </p>
<p>The graphs support zooming, mouseover and all kinds of <a href="http://code.google.com/p/flot/">flot</a> goodness <img src="http://www.mikealrogers.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /> </p>
<p>JavaScript is the yellow line. Python is the Blue line.</p>
<p>

    
    
    
    #placeholder .button {
        position: absolute;
        cursor: pointer;
    }
    .message {
        padding-left: 50px;
        font-size: smaller;
    }
    
        <div id="placeholder"></div>
        <p id="message-text" class="message"></p><div id="message" class="message"></div>
        <p>This is a test of moderately sized documents, what we normally expect the size of a job or build description. Each document is identical and fairly simple with a size of ~1,588 bytes.</p>
        <div id="placeholder2"></div>
        <p id="message-text2" class="message"></p><div id="message2" class="message"></div>
        <p>These documents were incredibly large, they were taken from a full fennec mochitest run. Each document is identical and while large it consists mostly of small sized JSON objects inside a much larger JSON object coming in at ~139,096 bytes.</p>
    &ndash;&ndash;<div id="tooltip"></div>&ndash;&ndash;
</p>
<p>I had also intended to chart the reduce performance with a simple sum operation but all the results were sub-second regardless of the amount of documents I threw at it with Python being only a little faster than JavaScript.</p>
<p>The nearly identical reduce time tells me that the actual code processing time inside the view functions are hardly different which means that the large difference in performance during view generation is most likely due to JSON serialization time. This also explains why larger documents cause an even greater difference in performance between Python and JavaScript.</p>
<h3>Improving Performance</h3>
<p>The Python view server is already as optimized as I can imagine for processing time inside the views. Since CouchDB doesn&#8217;t provide a way for the view server to support it&#8217;s own concurrency we&#8217;ve basically hit the wall here on what Python can provide. If we increased the complexity of the view functions I think that Python would start to show better than Spidermonkey 1.7, but 1.8 with traceing enabled would likely bridge that gap, possibly even showing JavaScript faster than Python.</p>
<p>The big problem is JSON serialization. We can make Python faster by compiling simplejson with C speedups. But using the C based JSON parser in newer versions of Spidermonkey requires some other changes to CouchDB since there are differences in the encoding of <strong>undefined</strong>.</p>
<p>At the end of the day though, this all looks great. CouchDB trunk (pre-0.11) is going to run fast enough for what we need right now even on a virtual machine and if we start to see view generation bottlenecks on views that aren&#8217;t hit as often and have to update a large number of documents we can just move those views to Python and the performance should be back down to sub-second.</p>]]></description>
    <link><![CDATA[http://www.mikealrogers.com/archives/673]]></link>
    <pubDate>2009-11-05 02:13:35</pubDate>
  </item>
</channel>
</rss>
