<?xml version="1.0"?>
<rss version="2.0">

<channel>
	<title>unofficial planet python</title>
	<link>http://www.planetpython.org/</link>
	<language>en</language>
	<description>unofficial planet python - http://www.planetpython.org/</description>

<item>
	<title>S.Lott: Voice of the Customer</title>
	<guid isPermaLink="true">http://homepage.mac.com/s_lott/iblog/architecture/C588245363/E20080706150621/index.html</guid>
	<link>http://homepage.mac.com/s_lott/iblog/architecture/C588245363/E20080706150621/index.html</link>
	<description>&lt;br /&gt;Or What do people want in a book on programming?&lt;br /&gt;</description>
	<pubDate>Sun, 06 Jul 2008 19:06:21 +0000</pubDate>
</item>
<item>
	<title>Voidspace: Diagramming on the Mac</title>
	<guid isPermaLink="true">http://feeds.feedburner.com/~r/voidspace/~3/328164616/arch_d7_2008_07_05.shtml</guid>
	<link>http://feeds.feedburner.com/~r/voidspace/~3/328164616/arch_d7_2008_07_05.shtml</link>
	<description>One of the annoying things about writing a book is having to create my own diagrams. This was something I wasn't expecting when I started the project, I'm a good writer but awful at producing diagrams. ... [530 words]&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~f/voidspace?a=Da9nXj&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/voidspace?i=Da9nXj&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~f/voidspace?a=wNLskj&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/voidspace?i=wNLskj&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~f/voidspace?a=zCINkj&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/voidspace?i=zCINkj&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~f/voidspace?a=WpJk6J&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/voidspace?i=WpJk6J&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/voidspace/~4/328164616&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Sun, 06 Jul 2008 16:25:21 +0000</pubDate>
</item>
<item>
	<title>Chuck Thier: Things you didn't know about ninjas</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8822432123509721858.post-309763819916048968</guid>
	<link>http://www.evilchuck.com/2008/07/things-you-didnt-know-about-ninjas.html</link>
	<description>In trying to learn more about how to process the human language and how it can be applied in the context of a game, I recently ran across an interesting knowledge base called ConceptNet.

ConceptNet is a freely available commonsense knowledgebase and natural-language-processing toolkit which supports many practical textual-reasoning tasks over real-world documents right out-of-the-box

It comes</description>
	<pubDate>Sun, 06 Jul 2008 05:25:17 +0000</pubDate>
	<author>noreply@blogger.com (Chuck)</author>
</item>
<item>
	<title>James Tauber: On Intelligence and the HTM Workshop</title>
	<guid isPermaLink="false">http://jtauber.com/blog/2008/07/05/on_intelligence_and_the_htm_workshop</guid>
	<link>http://jtauber.com/blog/2008/07/05/on_intelligence_and_the_htm_workshop/</link>
	<description>&lt;p&gt;Like a lot of geeks, I've been interested in how the brain works for most of my life. Artificial Intelligence was always one of my interests within computing (and part of what got me interested in &lt;a href=&quot;http://jtauber.com/linguistics&quot;&gt;linguistics&lt;/a&gt; at a very early age).
&lt;/p&gt;
&lt;p&gt;
Within my linguistics research, I've always been interested in models that are biologically plausible so it was a huge delight to read Jeff Hawkins' &lt;a href=&quot;http://www.amazon.com/exec/obidos/tg/detail/-/0805074562&quot;&gt;On Intelligence&lt;/a&gt; back in early 2005 and find a theory that was biologically-based and believable from a linguistics point of view. One prominent psycholinguist told me in 2006 that it was one of the most promising theories he'd ever read.
&lt;/p&gt;
&lt;p&gt;
After reading the book, I promptly went out and built a library (as I am wont to do) of about 20 books on general neuroscience, computational neuroscience and the relationship between the brain and language. I started thinking about how to implement the ideas and, after reading some of Jeff's and Dileep George's early papers, augmented the library further with books on Bayesian networks, belief propagation, etc.
&lt;/p&gt;
&lt;p&gt;
When Jeff and Dileep started &lt;a href=&quot;http://numenta.com/&quot; class=&quot;external&quot;&gt;Numenta&lt;/a&gt; and eventually released an early version of their Hierarchical Temporal Memory (HTM) platform in Python, I was particularly excited to try it out, in particular applying it to linguistics. I started the &lt;a href=&quot;http://groups.google.com/group/htm-ling&quot; class=&quot;external&quot;&gt;htm-ling&lt;/a&gt; mailing list to gather other people interested in applying HTM to models of language. It turned out to be hard to get word out to other people interested in HTM and linguistics, however.
&lt;/p&gt;
&lt;p&gt;
I never got very far with Numenta's code, mostly because there were just too many other things I was working on.
&lt;/p&gt;
&lt;p&gt;
But then a couple of months ago, I found out Numenta was running a workshop / conference. I thought it would be an excellent opportunity for me to (a) get back up to speed with what Numenta was doing and how to use their NuPIC platform; (b) meet other people interested in applying HTM to linguistics.
&lt;/p&gt;
&lt;p&gt;
So a couple of weeks ago, I attended the first &lt;a href=&quot;http://www.htmworkshop.com/&quot; class=&quot;external&quot;&gt;Numenta HTM Workshop&lt;/a&gt;. I had a great time. It was great to meet Jeff and the rest of the team. Dileep's talk on the algorithms in NuPIC was particularly helpful to me in understanding how things work.
&lt;/p&gt;
&lt;p&gt;
There were a number of people who expressed an interest in the application to linguistics so in the evening I ran a BOF. None of the attendees (as far as I could tell) were linguists by training so I didn't really get to talk too technically from a linguistics perspective. The boost to the mailing list membership hasn't created any more discussion yet either.
&lt;/p&gt;
&lt;p&gt;
But I am still hopeful that an HTM-like approach (whether in the form of NuPIC or some other implementation) might be useful in building biologically-plausible models of language processing.&lt;/p&gt;</description>
	<pubDate>Sun, 06 Jul 2008 04:43:05 +0000</pubDate>
</item>
<item>
	<title>Ali Afshar: The problem with jQuery</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-27964390.post-857938055119101185</guid>
	<link>http://unpythonic.blogspot.com/2008/07/problem-with-jquery.html</link>
	<description>Ok, I'll start by saying that I love jQuery as much as the next developer, and every contributor has my eternal thanks, but there is a problem.&lt;br /&gt;&lt;br /&gt;Plugin development goes crazy, in that many similar plugins are released, and often these are just modifications including other sets of modifications. There must be a better way, like isn't this what version control is made for?&lt;br /&gt;&lt;br /&gt;Here is an excerpt of http://docs.jquery.com/Plugins#Forms&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    *  Autocomplete by Dylan Verheul&lt;br /&gt;      Autocomplete with caching to limit server requests and other options.&lt;br /&gt;&lt;br /&gt;    * jQuery Autocomplete Mod by Dan G. Switzer&lt;br /&gt;      Modification of Autocomplete plugin with enhancements and bug fixes.&lt;br /&gt;&lt;br /&gt;    * Modified Auto-complete by Anjesh Tuladhar&lt;br /&gt;      Auto-complete plugin extended for auto-completing multiple words in the same text input&lt;br /&gt;&lt;br /&gt;    * Autocomplete by Jörn Zaefferer&lt;br /&gt;      Heavily improved Dylan Verheul’s initial plugin, integrating modifications by Dan G. Switzer and Anjesh Tuladhar.&lt;br /&gt;&lt;br /&gt;    * jQuery Autocomplete by Saurabh Periwal&lt;br /&gt;      Modification of Autocomplete plugin with enhancements of onItemSelect and Multiselect.&lt;br /&gt;&lt;br /&gt;    * Jeditable + Autocomplete by Ritesh Agrawal&lt;br /&gt;      Extended jeditable to include option for autocomplete. Also extended Dylan Verheul's autocomplete javascript to include option for having input token separator. Check the demo.&lt;br /&gt;&lt;br /&gt;End of snippet.</description>
	<pubDate>Sun, 06 Jul 2008 01:04:13 +0000</pubDate>
	<author>noreply@blogger.com (Ali)</author>
</item>
<item>
	<title>Duncan McGreggor: Native LoadBalancing for Twisted Apps</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8825992.post-1731893800907898448</guid>
	<link>http://feeds.feedburner.com/~r/ElectricDuncan/~3/327632080/native-loadbalancing-for-twisted-apps.html</link>
	<description>&lt;div&gt;Yesterday, right before midnight, I tagged the 1.1.0 release of txLoadBalancer on Launchpad after completing the last of the planned features. There are some pretty radical changes that have been developed for this release... and the coolest part  is this is just the beginning :-) (See the TODO if you don't believe me!)&lt;br /&gt;&lt;br /&gt;You can checkout from &lt;a href=&quot;https://code.launchpad.net/%7Eoubiwann/txloadbalancer/1.1.0&quot;&gt;lp:~oubiwann/txloadbalancer/1.1.0&lt;/a&gt; or download from &lt;a href=&quot;http://pypi.python.org/pypi/txLoadBalancer/&quot;&gt;PyPI&lt;/a&gt;. If you're a PyPI expert, I've got some questions for you at the end of this post... Been having some sucky experiences with PyPI lately :-(&lt;br /&gt;&lt;br /&gt;So here's what's going on with txLoadBalancer:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Improved API&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The biggest thing you'll notice if you've switching from PythonDirector is the massive overhaul the API has undergone. Things are cleaner and generally more modern, with a concise and well-defined module layout.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;New Load Balancing Algorithm&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I've added support for a weighted host scheduler. Given a weight that represents the frequency a host should be used, a host will be randomly selected, based on it's weight. For example, with two hosts, one having a weight of 1 and the other having a weight of 3, host 2 will be chosen about 75% of the time and host 1 will get about 25% of the requests.&lt;br /&gt;&lt;br /&gt;Right now, this algorithm has to make several calls to other parts of the code in order to get all the data it needs (it also builds some crazy iterators). As such, it's rather slow and performs poorly when compared to the very light-weight least-connections algorithm. That being said, the next release will include optimizations for the weighted scheduler that make use of a Twisted timer and caching.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Native Twisted Load-Balancing&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here's the sexiest part: you can now load-balance your Twisted application by using the txLB API; you don't even need to run the load-balancer as a separate app! This evolved as a feature after a conversation with an as-yet unnamed cloud hosting provider, a follow-up discussion with the &lt;a href=&quot;http://about.divmod.com/team.html&quot;&gt;Divmod team&lt;/a&gt;, and then some quiet  pondering about ways in which Twisted applications could be supported in cloud/grid/massively-multi-core architectures.&lt;br /&gt;&lt;br /&gt;The &quot;self load-balancing&quot; API in txLB is not a comlete solution for grid-hosting, but it is a first step in one direction (we've been discussing lots of others, too, including the use of our deployment tool).&lt;br /&gt;&lt;br /&gt;Before I show you how to use the self load-balancing API, let's take a quick look at a normal Twisted application service:&lt;br /&gt;&lt;pre&gt;from twisted.web import static, server&lt;br /&gt;from twisted.application import service, internet&lt;br /&gt;&lt;br /&gt;application = service.Application(&quot;Demo Web Server&quot;)&lt;br /&gt;web = server.Site('/home/oubiwann/public_html')&lt;br /&gt;service = internet.TCPServer(7001, web)&lt;br /&gt;service.setServiceParent(application)&lt;br /&gt;&lt;/pre&gt;You start that with the command &lt;span style=&quot;font-family: courier new;&quot;&gt;twistd -noy myweb.tac&lt;/span&gt;. For use with the next example, you can also start two more, one on port 7002 and the other on port 7003.&lt;br /&gt;&lt;br /&gt;Now here's what you do to make a self load-balanced app:&lt;br /&gt;&lt;pre&gt;from twisted.application import service&lt;br /&gt;&lt;br /&gt;from txlb import manager&lt;br /&gt;from txlb.model import HostMapper&lt;br /&gt;from txlb.schedulers import leastc&lt;br /&gt;from txlb.application.service import LoadBalancedService&lt;br /&gt;&lt;br /&gt;proxyServices = [&lt;br /&gt;  HostMapper(proxy='127.0.0.1:8080', lbType=leastc, host='host1',&lt;br /&gt;      address='127.0.0.1:7001'),&lt;br /&gt;  HostMapper(proxy='127.0.0.1:8080', lbType=leastc, host='host2',&lt;br /&gt;      address='127.0.0.1:7002'),&lt;br /&gt;  HostMapper(proxy='127.0.0.1:8080', lbType=leastc, host='host3',&lt;br /&gt;      address='127.0.0.1:7003'),&lt;br /&gt;]&lt;br /&gt;&lt;br /&gt;application = service.Application('Demo LB Service')&lt;br /&gt;pm = manager.proxyManagerFactory(proxyServices)&lt;br /&gt;lbs = LoadBalancedService(pm)&lt;br /&gt;lbs.setServiceParent(application)&lt;br /&gt;&lt;/pre&gt;As you would expect, you need to indicate the proxy host:port, the algorithm to use, and the hosts that are to be balanced. The host setup assumes that you have three services running on localhost ports 7001, 7002, and 7003. All that's needed now is to just run that code with the usual &lt;span style=&quot;font-family: courier new;&quot;&gt;twistd -noy myapp.tac&lt;/span&gt;.  Also, for demonstration purposes, this is a somewhat simplified example of what is possible.&lt;br /&gt;&lt;br /&gt;This may seem like a lot of extra work when compared to the simple web host above, but think about it: we're &lt;span style=&quot;font-style: italic;&quot;&gt;load-balancing&lt;/span&gt; here :-) This saves you from having to manage yet another application. With a few extra lines of code, you can keep it all in one place and have it manage itself.&lt;br /&gt;&lt;br /&gt;Note that this API is in development and continuing to improve. The example above is from code running in trunk. For the more verbose configuration that is in the 1.1.0 release, be sure to see &lt;span style=&quot;font-family: courier new;&quot;&gt;./bin/txlbWeb.tac&lt;/span&gt; from the source tarball. To play with the latest and greatest, you'll want to checkout the code here: &lt;a href=&quot;https://code.launchpad.net/%7Eoubiwann/txloadbalancer/main&quot;&gt;lp:txloadbalancer&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Other Goodies&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here is some other good stuff in the release:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;You can now ssh into a txLB instance and mainipulate the load-balancer in real time from an interactive Python interpreter.&lt;/li&gt;&lt;li&gt;You can change the proxy to listen on a different port while the application is running (no restart requred!).&lt;/li&gt;&lt;li&gt;Changes made to the configuration while running are no longer volatile; they are saved to disk (and your old config gets backed up).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Work from Apple, Inc. was included in this release, too (they use the old PythonDirector in their Calendaring server). This includes a bug fix and management socket feature.&lt;/li&gt;&lt;li&gt;There is a significant jump in performance between this release and the previous one. I believe this to be due to the separation of concerns in the API, but haven't yet confirmed that.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Coming Work&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are a lot of &lt;span style=&quot;font-style: italic;&quot;&gt;exciting&lt;/span&gt; features coming for txLB. Just to name a few:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;improved weighted algorithm&lt;/li&gt;&lt;li&gt;resources-based algorithm (a scheduler that determins the weight of a proxied host by memory, CPU, etc., utilization)&lt;/li&gt;&lt;li&gt;smarter proxied host failover and recovery&lt;/li&gt;&lt;li&gt;a heartbeat manager&lt;br /&gt;&lt;/li&gt;&lt;li&gt;txLB-powered application cloning (when started, an app will determine if it needs to run the clone as the managing load-balancer or simply as a proxied host)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;auto-discovery of balanced hosts&lt;/li&gt;&lt;li&gt;proxy fail-over (a balanced host taking over as manager in the event that the manager goes down)&lt;/li&gt;&lt;li&gt;ApacheMQ/Stomp integration&lt;/li&gt;&lt;li&gt;LDAP/RADIUS authentication&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Additionally, I'll be putting together some basic performance metrics contrasting Apache and load-balanced Twisted apps. I will also be comparing previous versions of txLB/PythonDirector with the latest release(s).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Problems with PyPI&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I will close this post on a sad note: PyPI used to be an amazing experience for me (a couple years ago, when it was still being called &quot;cheeseshop&quot;). Everything worked as it was supposed to. This hasn't been the case when I've used it recently (over the past few months).&lt;br /&gt;&lt;br /&gt;For all that I say about PyPI, I allow for the fact that I may just be missing something, and it may be entirely my fault. That being said, I spent about 3 hours online last night combing though the SIG mail list, the bug list on sourceforge, and blog posts about setuptools and PyPI, and could find no answers to my questions. Well, with the possible exception of a bug report, but it doesn't look like it was confirmed by a PyPI team member, so I'm not sure if it's valid or not.&lt;br /&gt;&lt;br /&gt;Here are my issues:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;When I upload my project using &lt;span style=&quot;font-family: courier new;&quot;&gt;python setup.py [sdist|bdist_egg] upload&lt;/span&gt;, no metadata defined in my &lt;span style=&quot;font-family: courier new;&quot;&gt;setup()&lt;/span&gt; function is presented on my package's PyPI page. When I click the metadata link, it's only got three sparse lines.&lt;/li&gt;&lt;li&gt;When I manually upload from the package's PKG-INFO itself, all the metadata is presented on the page as it should be, with the exception of the long description. It is in plain text instead of ReST (I am checking that it is valid ReST using distutils settings of &lt;span style=&quot;font-family: courier new;&quot;&gt;reporter.halt_level = 5&lt;/span&gt;, &lt;span style=&quot;font-family: courier new;&quot;&gt;reporter.report_level = 1&lt;/span&gt;, &lt;span style=&quot;font-family: courier new;&quot;&gt;settings.pep_references = False&lt;/span&gt;, and &lt;span style=&quot;font-family: courier new;&quot;&gt;settings.trim_footnote_reference_space = None&lt;/span&gt;; these are the same settings that Zope Corp uses to verify the ReST that it uploads to PyPI).&lt;/li&gt;&lt;li&gt;When I manually edit the long description in the form, I get the same thing: plain text, no ReST.&lt;/li&gt;&lt;li&gt;When I upload a package that is displayed properly on PyPI (such as &lt;a href=&quot;http://pypi.python.org/pypi/zc.twist&quot;&gt;zc.twist&lt;/a&gt;; uploaded as one of my projects by chaning the name), I get the same problem (this is why I think it might be something that &lt;span style=&quot;font-style: italic;&quot;&gt;I'm&lt;/span&gt; doing wrong...): no metadata, and when I upload the PKG-INFO manually, no ReST.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Why, oh why, cruel fates, does this not work any more?  I used to be able to upload to PyPI without any of these issues...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/ElectricDuncan/~4/327632080&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Sat, 05 Jul 2008 21:51:40 +0000</pubDate>
	<author>noreply@blogger.com (Duncan McGreggor)</author>
</item>
<item>
	<title>Simon Willison's Weblog: OSM routing, A*, cycle-filtered, python</title>
	<guid isPermaLink="true">http://simonwillison.net/2008/Jul/5/osm/</guid>
	<link>http://simonwillison.net/2008/Jul/5/osm/</link>
	<description>&lt;div class=&quot;blogmark segment&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://almien.co.uk/OSM/Routing/&quot;&gt;OSM routing, A*, cycle-filtered, python&lt;/a&gt; (&lt;a href=&quot;http://wiki.openstreetmap.org/index.php/PyrouteLib&quot; title=&quot;OpenStreetMap Wiki&quot;&gt;via&lt;/a&gt;). A python library for finding routes using OpenStreetMap data.&lt;/p&gt;
&lt;/div&gt;</description>
	<pubDate>Sat, 05 Jul 2008 15:13:48 +0000</pubDate>
</item>
<item>
	<title>Armin Ronacher: virtualenv to the Rescue</title>
	<guid isPermaLink="false">http://lucumr.pocoo.org/cogitations/2008/07/05/virtualenv-for-the-rescue/</guid>
	<link>http://lucumr.pocoo.org/cogitations/2008/07/05/virtualenv-to-the-rescue/</link>
	<description>&lt;p&gt;Deploying Python applications is not that hard, but there are some pitfalls. The main problem everyone stumbles upon sooner or later is that &lt;code&gt;sys.modules&lt;/code&gt; is a singleton. Modules are cached there which the effect that there can be exaclty one version of a library loaded at the same time per interpreter. There is no way around that and it’s fine. However there is another problem: Everyone installs everything into a system wide singleton called site-packages. Sooner or later everything ends up there, and while pkg_sources supports switching between versions this is very unconfortable and requires extra hackery.&lt;/p&gt;
&lt;p&gt;My plan to solve these problems always was creating a folder, putting all libraries into that folder and &lt;code&gt;site.addsitedir()&lt;/code&gt;ing that folder in the file that starts up the application. But especially for web applications that’s a dull repetitive task and easy_install and other libraries don’t play well with this approach.&lt;/p&gt;
&lt;p&gt;Fortunately &lt;a href=&quot;http://blog.ianbicking.org/&quot;&gt;Ian Bicking&lt;/a&gt; wrote a really cool module called “virtualenv” that creates virtual Python environments. And it does that in a very cool manner. The following example shows how we run &lt;a href=&quot;http://paste.pocoo.org/&quot;&gt;LodgeIt&lt;/a&gt; on our server:&lt;/p&gt;
&lt;p&gt;First you need to install virtualenv. This assumes you already have easy_install:&lt;/p&gt;
&lt;pre&gt;mitsuhiko@nausicaa:~$ sudo easy_install virtualenv
Searching for virtualenv
Reading http://pypi.python.org/simple/virtualenv/
Best match: virtualenv 1.1
Downloading virtualenv-1.1-py2.5.egg
Processing virtualenv-1.1-py2.5.egg
creating /opt/local/lib/python2.5/site-packages/virtualenv-1.1-py2.5.egg
Extracting virtualenv-1.1-py2.5.egg to /opt/local/lib/python2.5/site-packages
Adding virtualenv 1.1 to easy-install.pth file
Installing virtualenv script to /opt/local/bin

Installed /opt/local/lib/python2.5/site-packages/virtualenv-1.1-py2.5.egg
Processing dependencies for virtualenv
Finished processing dependencies for virtualenv
&lt;/pre&gt;
&lt;p&gt;Now we can create a folder folder the application. In our case the folder is called after the domain where the web application runs:&lt;/p&gt;
&lt;pre&gt;mitsuhiko@nausicaa:~$ virtualenv paste.pocoo.org
New python executable in paste.pocoo.org/bin/python
Installing setuptools.......................done.
&lt;/pre&gt;
&lt;p&gt;The virtual python is now available in that folder and we can switch into that environment by sourcing the activate file:&lt;/p&gt;
&lt;pre&gt;mitsuhiko@nausicaa:$ cd paste.pocoo.org/
mitsuhiko@nausicaa:~/paste.pocoo.org$ . bin/activate
(paste.pocoo.org)mitsuhiko@nausicaa:~/paste.pocoo.org$
&lt;/pre&gt;
&lt;p&gt;From that point onwards “python” and “easy_install” point to the executables in the &lt;code&gt;~/paste.pocoo.org/bin&lt;/code&gt; folder. The prompt is prefixed with the name of the virtual environment so that we are reminded that “python” is our virtual Python. We can now install all the dependencies:&lt;/p&gt;
&lt;pre&gt;$ easy_install SQLAlchemy==0.4.4 Jinja2 Werkzeug Pygments&lt;/pre&gt;
&lt;p&gt;Half a minute later the virtual python interpreter will now have the libraries available and we’re ready to add out application:&lt;/p&gt;
&lt;pre&gt;$ hg clone http://dev.pocoo.org/hg/lodgeit-main&lt;/pre&gt;
&lt;p&gt;Lodgeit itself doesn’t have a setup.py file but we can just cd into the folder and run the testing server to test if it works:&lt;/p&gt;
&lt;pre&gt;$ cd lodgeit-main/
$ python runlodgeit.py runserver
 * Running on http://localhost:5000/
 * Restarting with reloader...
&lt;/pre&gt;
&lt;p&gt;That works perfectly for scripts invoking “python” directly such as standalone servers like CherryPy but won’t work for mod_wsgi where the interpreter is created by mod_wsgi and doesn’t point to the virtual environment.&lt;/p&gt;
&lt;p&gt;There are two ways to solve the problem. For mod_wsgi 2.0 you can run the web application in daemon mode and pass it the path to the site packages in the apache config:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;
&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;WSGIDaemonProcess&lt;/span&gt; lodgeit python-path=/path/to/site-packages
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Alternatively you can go into the .wsgi file and add the site-packages by hand:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;
&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;site&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addsitedir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/path/to/site-packages&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The site-packages of the virtual environment are located at &lt;code&gt;/path/to/virtual/env/lib/python2.X/site-packages&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Even though I was not interested in virtualenv in the beginning I changed my mind because it’s straightforward to use and easy to maintain. More information about virtualenv is available in the &lt;a href=&quot;http://pypi.python.org/pypi/virtualenv&quot;&gt;Cheeseshop&lt;/a&gt; and &lt;a href=&quot;http://blog.ianbicking.org/2007/10/10/workingenv-is-dead-long-live-virtualenv/&quot;&gt;the announcement blog post&lt;/a&gt; in Ian’s blog.&lt;/p&gt;</description>
	<pubDate>Sat, 05 Jul 2008 14:16:33 +0000</pubDate>
</item>
<item>
	<title>Andrew Dalke: Testing the bitslice algorithm for popcount</title>
	<guid isPermaLink="true">http://www.dalkescientific.com/writings/diary/archive/2008/07/05/bitslice_and_popcount.html</guid>
	<link>http://www.dalkescientific.com/writings/diary/archive/2008/07/05/bitslice_and_popcount.html</link>
	<description>&lt;p&gt;

This is part 7 of an on-going series dealing with molecular
fingerprints:
&lt;/p&gt;&lt;ol&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/06/26/fingerprint_background.html&quot;&gt;Molecular fingerprints, background&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/06/27/generating_fingerprints_with_openbabel.html&quot;&gt;Generating molecular fingerprints with OpenBabel&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/06/27/computing_tanimoto_scores.html&quot;&gt;Computing Tanimoto scores, quickly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/06/28/block_tanimoto_calculations.html&quot;&gt;Block Tanimoto calculations&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/07/01/faster_tanimtocat_search_search.html&quot;&gt;Faster block Tanimoto calculations&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/07/03/hakmem_and_other_popcounts.html&quot;&gt;HAKMEM 169 and other popcount implementations&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;Testing the bitslice algorithm for popcount&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;a href=&quot;http://dalkescientific.blogspot.com/2008/06/molecular-fingerprints.html&quot;&gt;Comments?&lt;/a&gt;
&lt;p&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;

I want to compute the popcount of molecular fingerprints containing
1024 bits.  My algorithm has been to compute the popcount 8, 16, 32,
or 64 bits at a time and repeat that for all of the words in the
fingerprint.  There are a couple of algorithms which compute the
popcount of multiple words in parallel by doing a partial popcount of
each word and combining the intermediate results to get the result
over all words.

&lt;/p&gt;&lt;p&gt;

Lauradoux Cédric wrote a nice &lt;a href=&quot;http://www.princeton.edu/~claurado/ham/overview.pdf&quot;&gt;overview on
Hamming weight&lt;/a&gt;, including explanations of the tree merging and
bit-slicing algorithms.  In personal email he pointed out &lt;a href=&quot;http://www.ciphersbyritter.com/NEWS4/BITCT.HTM&quot;&gt;this page&lt;/a&gt;
from comp.arch.arithmetic where someone attributes the algorithm to
Robert Harley.

&lt;/p&gt;&lt;p&gt;

It took me a while to understand it.  It's been rather a while since I
had to do much thinking about half-adders.  About 17 years.  But it's
not hard.  I'm not going to explain it though.  It's best in pictures
and that will take me too long to do.  You can follow those links
though.


&lt;/p&gt;&lt;p&gt;

While he hasn't finished the overview explanation on how to combine
the two algorithms, his &lt;a href=&quot;http://www.princeton.edu/~claurado/hamming.html&quot;&gt;Hamming
weight&lt;/a&gt; page includes &lt;a href=&quot;http://www.princeton.edu/~claurado/ham/merging.tar.gz&quot;&gt;source&lt;/a&gt;.

&lt;/p&gt;&lt;p&gt;

I've added two bit-slicing implementations to my &lt;a href=&quot;http://dalkescientific.com/writings/diary/popcnt.c&quot;&gt;popcnt.c&lt;/a&gt;
benchmark.  The algorithm from comp.arch.arithmetic processes 7 words
at a time and the one from Cédric processes 24 words at a time.
Both fall back to other methods for the last few words if the input
isn't an exact multiple of 24 or 7.

&lt;/p&gt;&lt;p&gt;

Cédric implemented several algorithms in his code distributions
and included programs to compare their performance.  The results
suggested that the 24 word bitslice algorithm would be twice as fast
as as the 16 bit looup table.  I implemented it and found that while
it was fast, and in my laptop even faster than the 16 bit lookup
table, it was only about 10% faster and not a factor of 2.

&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;% sysctl machdep.cpu.brand_string
machdep.cpu.brand_string: Intel(R) Core(TM)2 CPU         T7600  @ 2.33GHz
% gcc --version
i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367)
   ... deleted ...
% cc -O3 popcnt.c
% ./a.out
FreeBSD version 1   :  3854904 us; cnt=32511665
FreeBSD version 2   :  3517953 us; cnt=32511665
16-bit LUT          :  2127718 us; cnt=32511665   &lt;i&gt;was the fastest&lt;/i&gt;
8-bit LUT           :  5317244 us; cnt=32511665
8-bit LUT v2        :  3762467 us; cnt=32511665
Wikipedia #2        :  5493756 us; cnt=32511665
Wikipedia #3        :  5295541 us; cnt=32511665
gcc popcount        :  6242596 us; cnt=32511665
gcc popcountll      : 10402364 us; cnt=32511665
HAKMEM 169/X11      :  4305536 us; cnt=32511665
&lt;b&gt;Bitslice(7)         :  2077473 us; cnt=32511665
Bitslice(24)        :  1843217 us; cnt=32511665&lt;/b&gt;  &lt;i&gt;fastest&lt;/i&gt;
naive               : 23460323 us; cnt=32511665
Wegner/Kernigan     : 14976014 us; cnt=32511665
Anderson            : 63971600 us; cnt=32511665
8x shift and add    : 21728414 us; cnt=32511665
32x shift and add   : 19747808 us; cnt=32511665
&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;&lt;p&gt;

I dug around for a while and used Toby's comment to try Shark as a
profiler.  Things made a bit more sense after I remembered to add the
'-g' option to gcc so I could get Shark to line up the code and
assembly side-by-side.  My conclusion is that Cédric's code has
too much function call overhead because the 16-bit LUT is being called
for every 32 bit number, while the 24 word bitslice code is only
called every 24 words.  My code doesn't have that overhead, which is
why the times are closer to each other.

&lt;/p&gt;&lt;p&gt;

As before, I wondered how much &quot;-m64&quot; affects things.  I'll declare it
a tie between the new bitslice code and the old 16-bit lookup table.
(While though the numbers aren't the same, the difference is about the
same as when I run the same algorithm again.)

&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;% cc -O3 popcnt.c -m64
% ./a.out
FreeBSD version 1   :  3902385 us; cnt=32511665
FreeBSD version 2   :  3422655 us; cnt=32511665
16-bit LUT          :  1621557 us; cnt=32511665 &lt;i&gt;fastest&lt;/i&gt;
8-bit LUT           :  2070320 us; cnt=32511665
8-bit LUT v2        :  2094362 us; cnt=32511665
Wikipedia #2        :  2135130 us; cnt=32511665
Wikipedia #3        :  2142576 us; cnt=32511665
gcc popcount        :  8128024 us; cnt=32511665
gcc popcountll      :  4087390 us; cnt=32511665
HAKMEM 169/X11      :  5805272 us; cnt=32511665
&lt;b&gt;Bitslice(7)         :  1728262 us; cnt=32511665
Bitslice(24)        :  1698257 us; cnt=32511665&lt;/b&gt; &lt;i&gt;fastest&lt;/i&gt;
naive               : 24990997 us; cnt=32511665
Wegner/Kernigan     : 16864887 us; cnt=32511665
Anderson            : 12463648 us; cnt=32511665
8x shift and add    : 21715482 us; cnt=32511665
32x shift and add   : 20003160 us; cnt=32511665
&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;&lt;p&gt;

All of this was on one processor and compiler.  I decided to try
another machine with a slightly different processor and an earlier
version of gcc.

&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;%sysctl -w hw.model
hw.model: Intel(R) Core(TM)2 CPU          6420  @ 2.13GHz
%gcc --version
gcc (GCC) 3.4.6 [FreeBSD] 20060305
    ...
%cc popcnt.c -O3 
%./a.out 
FreeBSD version 1   :  4270677 us; cnt=32511665
FreeBSD version 2   :  3785047 us; cnt=32511665
16-bit LUT          :  2034836 us; cnt=32511665
8-bit LUT           :  1935156 us; cnt=32511665   &lt;i&gt;fastest&lt;/i&gt;
8-bit LUT v2        :  1987370 us; cnt=32511665
Wikipedia #2        :  5010639 us; cnt=32511665
Wikipedia #3        :  4931266 us; cnt=32511665
gcc popcount        :  5793299 us; cnt=32511665
gcc popcountll      :  6815575 us; cnt=32511665
HAKMEM 169/X11      : 10788366 us; cnt=32511665
&lt;b&gt;Bitslice(7)         :  2467150 us; cnt=32511665
Bitslice(24)        :  2469399 us; cnt=32511665&lt;/b&gt;
naive               : 27722786 us; cnt=32511665
  ... too slow to worry about ...
&lt;/pre&gt;

In this case I would use the 8-bit lookup table, which is about 20%
faster than the the bitslice code.

&lt;p&gt;&lt;/p&gt;&lt;p&gt;

Here's the results on an older Pentium 4 (Prescott) CPU 2.80GHz with
gcc 3.4.6:

&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;FreeBSD version 1   :  3745509 us; cnt=32500610
FreeBSD version 2   :  3774150 us; cnt=32500610
16-bit LUT          :  2762583 us; cnt=32500610
8-bit LUT           :  2430362 us; cnt=32500610    &lt;i&gt;fastest&lt;/i&gt;
8-bit LUT v2        :  2433684 us; cnt=32500610
Wikipedia #2        : 11509758 us; cnt=32500610
Wikipedia #3        :  8540921 us; cnt=32500610
gcc popcount        :  9100055 us; cnt=32500610
gcc popcountll      : 10568664 us; cnt=32500610
HAKMEM 169/X11      : 10970609 us; cnt=32500610
Bitslice(7)         :  4226871 us; cnt=32500610
Bitslice(24)        :  3700020 us; cnt=32500610
naive               : 36117662 us; cnt=32500610
Wegner/Kernigan     : 46479326 us; cnt=32500610
Anderson            : 174285325 us; cnt=32500610
8x shift and add    : 90028247 us; cnt=32500610
32x shift and add   : 86390410 us; cnt=32500610
&lt;/pre&gt;


Bitslice(24) is still the fastest bit-twiddler solution, but quite a
bit slower than using an 8-bit lookup table.  There is no single best
solution.  It seems the code is also compiler dependent so I'm
installing GCC 4.2 to see how that affects things.  That'll probably
take a few hours so it's time to sleep.

&lt;p&gt;&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;

Okay, fink installed gcc 4.2.2 (the most recent is 4.3.1 but I decided
it wasn't worth the time to compile it myself).  Here's the numbers
on my laptop for 32-bit:

&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;% gcc-4 -O3 popcnt.c
% ./a.out 
FreeBSD version 1   :  4161621 us; cnt=32511665
FreeBSD version 2   :  2930977 us; cnt=32511665  &lt;i&gt;was 3517953&lt;/i&gt;
16-bit LUT          :  2534380 us; cnt=32511665  &lt;i&gt;was 2127718&lt;/i&gt;
8-bit LUT           :  4472733 us; cnt=32511665
8-bit LUT v2        :  4499285 us; cnt=32511665  &lt;i&gt;was 3762467&lt;/i&gt;
Wikipedia #2        :  5031855 us; cnt=32511665
Wikipedia #3        :  3874931 us; cnt=32511665  &lt;i&gt;was 5295541&lt;/i&gt;
gcc popcount        :  4808307 us; cnt=32511665
gcc popcountll      :  5978393 us; cnt=32511665
HAKMEM 169/X11      :  4315751 us; cnt=32511665
Bitslice(7)         :  2111625 us; cnt=32511665
Bitslice(24)        :  1443337 us; cnt=32511665   &lt;i&gt;fastest; was 1843217&lt;/i&gt;
naive               : 51557971 us; cnt=32511665
Wegner/Kernigan     : 15616245 us; cnt=32511665
Anderson            : 63424235 us; cnt=32511665
8x shift and add    : 19179445 us; cnt=32511665
32x shift and add   : 19502222 us; cnt=32511665
%
&lt;/pre&gt;

and for 64 bit

&lt;pre class=&quot;code&quot;&gt;% gcc-4 -O3 popcnt.c -m64
% ./a.out
FreeBSD version 1   :  4192391 us; cnt=32511665
FreeBSD version 2   :  2812570 us; cnt=32511665    &lt;i&gt;was 3422655&lt;/i&gt;
16-bit LUT          :  1494747 us; cnt=32511665    &lt;i&gt;was 1621557&lt;/i&gt;
8-bit LUT           :  2182569 us; cnt=32511665
8-bit LUT v2        :  2170191 us; cnt=32511665    &lt;i&gt;was 2094362&lt;/i&gt;
Wikipedia #2        :  2001489 us; cnt=32511665
Wikipedia #3        :  1361488 us; cnt=32511665    &lt;i&gt;was 2142576&lt;/i&gt;
gcc popcount        :  7350367 us; cnt=32511665
gcc popcountll      :  3718116 us; cnt=32511665
HAKMEM 169/X11      :  4339839 us; cnt=32511665
Bitslice(7)         :  1693849 us; cnt=32511665
Bitslice(24)        :  1206318 us; cnt=32511665    &lt;i&gt;fastest; was 1698257&lt;/i&gt;
naive               : 24914902 us; cnt=32511665
Wegner/Kernigan     : 15557531 us; cnt=32511665
Anderson            :  8764008 us; cnt=32511665
8x shift and add    : 21710211 us; cnt=32511665
32x shift and add   : 19583803 us; cnt=32511665
%
&lt;/pre&gt;

It looks like things are nearly always faster for 64 bit code, and
sometimes faster for 32 bit code.

&lt;p&gt;&lt;/p&gt;</description>
	<pubDate>Sat, 05 Jul 2008 12:00:00 +0000</pubDate>
</item>
<item>
	<title>Michael Sparks: Concurrent software is not the problem - Intel talking about 1000s of cores</title>
	<guid isPermaLink="true">http://yeoldeclue.com/cgi-bin/blog/blog.cgi?rm=viewpost&amp;nodeid=1215258472</guid>
	<link>http://yeoldeclue.com/cgi-bin/blog/blog.cgi?rm=viewpost&amp;nodeid=1215258472</link>
	<description>Intel have &lt;a href=&quot;http://blogs.intel.com/research/2008/06/unwelcome_advice.php&quot;&gt;recently been talking about the fact that we'll probably have to deal with not hundreds but thousands of cores&lt;/a&gt; on a machine at some point in the near future (5-10 year time frame based on their 80 core prototype). Now many people seem to be &lt;a href=&quot;http://groups.google.com/groups?num=100&amp;amp;q=help%20me%20use%20both%20cores&quot;&gt;worried about how to use even a dual core machine&lt;/a&gt;, so naturally many people are probably going wa-HUH? However I suspect the &lt;a href=&quot;http://en.wikipedia.org/wiki/Erlang_%28programming_language%29&quot;&gt;Erlang&lt;/a&gt; crowd have a &lt;a href=&quot;http://edit.kamaelia.org/GetKamaelia&quot;&gt;similar reaction to us&lt;/a&gt; - which is &quot;cool&quot;. &lt;p&gt;Why? Like the erlang group, in &lt;a href=&quot;http://edit.kamaelia.org/GetKamaelia&quot;&gt;Kamaelia&lt;/a&gt;, the thing we've focussed on is &lt;a href=&quot;http://edit.kamaelia.org/Challenges/?tab=9&quot;&gt;making concurrency easy to work&lt;/a&gt; with, &lt;a href=&quot;http://c2.com/cgi/wiki?CodeForTheMaintainer&quot;&gt;primarily by aiming for making concurrent software maintenance easier&lt;/a&gt; (for the average developer). In practical terms this has meant putting &lt;a href=&quot;http://edit.kamaelia.org/Introduction&quot;&gt;friendly metaphors&lt;/a&gt; (hopefully) on top of well established &lt;a href=&quot;http://en.wikipedia.org/wiki/Communicating_sequential_processes&quot;&gt;principles&lt;/a&gt; of &lt;a href=&quot;http://en.wikipedia.org/wiki/Message_passing&quot;&gt;message passing&lt;/a&gt; systems, as well as adding support for &lt;a href=&quot;http://edit.kamaelia.org/STM&quot;&gt;other forms of constrained shared data&lt;/a&gt;. (STM is a bit like version control for variables).&lt;/p&gt;&lt;p&gt;We've done this by using various application domains as the starting point, such as &lt;a href=&quot;http://edit.kamaelia.org/KamaeliaMacro&quot;&gt;DVB&lt;/a&gt;, &lt;a href=&quot;http://edit.kamaelia.org/KamaeliaGrey&quot;&gt;networking&lt;/a&gt; and use of &lt;a href=&quot;http://edit.kamaelia.org/Cookbook&quot;&gt;audio/video etc&lt;/a&gt;, and used &lt;a href=&quot;http://www.python.org/&quot;&gt;Python&lt;/a&gt; as the language of choice to do so (Though we probably could've shouted about our application uses more/better, though we've &lt;a href=&quot;http://edit.kamaelia.org/SpeakAndWrite&quot;&gt;getting&lt;/a&gt; &lt;a href=&quot;http://edit.kamaelia.org/KamaeliaGrey&quot;&gt;better&lt;/a&gt; I think :-). However the approaches apply to more or less any non-functional language - so there's a proof of concept of our miniaxon core in &lt;a href=&quot;http://kamaelia.svn.sourceforge.net/viewvc/kamaelia/trunk/Code/CPP/Scratch/miniaxon.cpp?revision=68&amp;amp;view=markup&quot;&gt;C++&lt;/a&gt;, &lt;a href=&quot;http://kamaelia.svn.sourceforge.net/viewvc/kamaelia/trunk/Code/Ruby/miniaxon.rb?revision=3578&amp;amp;view=markup&quot;&gt;Ruby&lt;/a&gt;, &amp;amp; &lt;a href=&quot;http://blog.buni.org/blog/mbarker/Meldware/2007/08/24/Mini-Axon-for-Java&quot;&gt;Java&lt;/a&gt; as well. (C++ &amp;amp; ruby ones deliberately simple/naive coding style :)&lt;/p&gt;&lt;p&gt;This does mean that now when we approach a problem - such as the desire to build a tool that assists a child learning to read and write - we end up with a piece of code that internally exhibits high levels of concurrency. For example, even &lt;a href=&quot;http://edit.kamaelia.org/SpeakAndWrite&quot;&gt;the simple Speak And Write application is made of 37 components&lt;/a&gt; which at present all right in the same process, but could be easily be made to use 37 processes... (prepending all Pipelines &amp;amp; Graphlines with the word &quot;Process&quot;)&lt;/p&gt;&lt;p&gt;Despite this, we don't normally think in terms of number of components or concurrent things, largely because you don't normally think of the number of functions you use in a piece of code - we just focus on the functionality we want from the system. I'm sure once upon a time though people did, but I don't know anyone who counts the number of functions or methods they have. The diagram below for example is the high level functionality of the system:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div align=&quot;center&quot;&gt;&lt;img src=&quot;http://edit.kamaelia.org/images/SpeakNWriteCodeArchitecture.png&quot; /&gt;&lt;br /&gt;&lt;/div&gt;Unlike many diagrams though, this has a 1 to 1 correspondance with &lt;a href=&quot;https://kamaelia.svn.sourceforge.net/svnroot/kamaelia/branches/private_MPS_SpeakNLearn/Apps/SpeakNLearn/App/SpeakNWrite.py&quot;&gt;the code&lt;/a&gt;: (skipping some details below)&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier New, monospace&quot;&gt;bgcolour = (255,255,180)&lt;br /&gt;
&lt;/font&gt;&lt;font face=&quot;Courier New, monospace&quot;&gt;Backplane(&quot;SPEECH&quot;).activate()&lt;br /&gt;

&lt;br /&gt;Pipeline(&lt;br /&gt;    SubscribeTo(&quot;SPEECH&quot;),&lt;br /&gt;    UnixProcess(&quot;while read word; do echo $word | espeak -w foo.wav --stdin ; aplay foo.wav ; done&quot;),&lt;br /&gt;).activate()&lt;/font&gt;&lt;p&gt;&lt;font face=&quot;Courier New, monospace&quot;&gt;&lt;/font&gt;&lt;font face=&quot;Courier New, monospace&quot;&gt;&lt;/font&gt;&lt;font face=&quot;Courier New, monospace&quot;&gt;CANVAS  = Canvas( position=(0,40), size=(800,320),&lt;br /&gt;                  bgcolour = bgcolour ).activate()&lt;br /&gt;CHALLENGE  = TextDisplayer(size = (390, 200), position = (0,40),&lt;br /&gt;                           bgcolour = bgcolour, text_height=48,&lt;br /&gt;                           transparent =1).activate()&lt;br /&gt;TEXT  = Textbox(size = (800, 100), position = (0,260), bgcolour = (255,180,255),&lt;br /&gt;                text_height=48, transparent =1 ).activate()&lt;br /&gt;&lt;br /&gt;Graphline(&lt;br /&gt;    CHALLENGER  = Challenger(),&lt;br /&gt;    CHALLENGE_SPLITTER = TwoWaySplitter(),&lt;br /&gt;    CHALLENGE_CHECKER = Challenger_Checker(),&lt;br /&gt;    SPEAKER  = PublishTo(&quot;SPEECH&quot;),&lt;br /&gt;&lt;br /&gt;    CHALLENGE  = CHALLENGE,&lt;br /&gt;    TEXT  = TEXT,&lt;br /&gt;    CANVAS  = CANVAS,&lt;br /&gt;&lt;br /&gt;    PEN     = Pen(bgcolour = bgcolour),&lt;br /&gt;    STROKER = StrokeRecogniser(),&lt;br /&gt;    OUTPUT  = aggregator(),&lt;br /&gt;    ANSWER_SPLITTER = TwoWaySplitter(),&lt;br /&gt;&lt;br /&gt;    TEXTDISPLAY  = TextDisplayer(size = (800, 100), position = (0,380),&lt;br /&gt;                                 bgcolour = (180,255,255), text_height=48 ),&lt;br /&gt;&lt;br /&gt;    linkages = {&lt;br /&gt;               (&quot;CANVAS&quot;,  &quot;eventsOut&quot;) : (&quot;PEN&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;CHALLENGER&quot;,&quot;outbox&quot;)  : (&quot;CHALLENGE_SPLITTER&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;CHALLENGE_SPLITTER&quot;,&quot;outbox&quot;)  : (&quot;CHALLENGE&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;CHALLENGE_SPLITTER&quot;,&quot;outbox2&quot;)  : (&quot;SPEAKER&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;PEN&quot;, &quot;outbox&quot;)        : (&quot;CANVAS&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;PEN&quot;, &quot;points&quot;)        : (&quot;STROKER&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;STROKER&quot;, &quot;outbox&quot;)    : (&quot;OUTPUT&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;STROKER&quot;, &quot;drawing&quot;)   : (&quot;CANVAS&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;OUTPUT&quot;,&quot;outbox&quot;)      : (&quot;TEXT&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;TEXT&quot;,&quot;outbox&quot;)      : (&quot;ANSWER_SPLITTER&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;ANSWER_SPLITTER&quot;,&quot;outbox&quot;)  : (&quot;TEXTDISPLAY&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;ANSWER_SPLITTER&quot;,&quot;outbox2&quot;) : (&quot;CHALLENGE_CHECKER&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;CHALLENGE_CHECKER&quot;,&quot;outbox&quot;) : (&quot;SPEAKER&quot;, &quot;inbox&quot;),&lt;br /&gt;               (&quot;CHALLENGE_CHECKER&quot;, &quot;challengesignal&quot;) : (&quot;CHALLENGER&quot;, &quot;inbox&quot;),&lt;br /&gt;    },&lt;br /&gt;).run()&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;b&gt;However, what has this got to do with 1000s of cores? &lt;/b&gt;After all, even a larger application (like the &lt;a href=&quot;http://edit.kamaelia.org/Developers/Projects/Whiteboard&quot;&gt;Whiteboard&lt;/a&gt;) only really exhibits a hundred or two hundred of degrees of concurrency... Now, clearly if &lt;i&gt;&lt;b&gt;every&lt;/b&gt;&lt;/i&gt; application you were using was written the approach of &lt;a href=&quot;http://edit.kamaelia.org/Introduction&quot;&gt;simpler, friendl&lt;i&gt;&lt;b&gt;ier&lt;/b&gt;&lt;/i&gt; component metaphors&lt;/a&gt; that &lt;a href=&quot;http://edit.kamaelia.org/GetKamaelia&quot;&gt;Kamaelia&lt;/a&gt; currently uses, then it's likely that you would probably start using all those CPUs. I say &quot;approach&quot;, because I'd really like to see people taking our proofs of concept and making native versions for C++, Ruby, Perl, etc - I don't believe in the view of &lt;a href=&quot;http://en.wikipedia.org/wiki/Lisp_%28programming_language%29&quot;&gt;one language to rule them all&lt;/a&gt;. I'd hope it was easier to maintain and be more bug free, because that's a core aim, but the proof of the approach is in the coding really, not the talking.&lt;/p&gt;&lt;p&gt;However, when you get to 1000s of cores a completely different issue suddenly arises that you didn't have with concurrency at the levels of 1,5, 10, 100 cores. That of &lt;b&gt;software tolerance of hardware unreliability, and &lt;/b&gt;&lt;b&gt;that, not writing concurrent software is the &lt;/b&gt;&lt;b&gt;REAL problem.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;It's been well noted that Google currently scale their applications across 1000s of machines using Map Reduce, which fundamentally is just another metaphor for writing code in a concurrent way. However, they are also well known to work on the assumption that they will have a number of servers fail every single day. This will will fundamentally mean half way through doing something. Now with a web search, if something goes wrong, you can just redo the search, or just not aggregate the results of the search.&lt;/p&gt;&lt;p&gt;In a desktop application, what if the core that fails is handling audio output? Is it acceptable for the audio to just stop working? Or would you need to have some mechanism to back out from the error and retry? It was thinking about these issues early this morning that I realised that what you you need is a way of capturing what was going to be running on that core &lt;i&gt;&lt;b&gt;before&lt;/b&gt;&lt;/i&gt; you execute it, and then launch it. In that scenario, if the CPU fails (assuming a detection mechanism) you can then restart the component on a fresh core.&lt;/p&gt;&lt;p&gt;The interesting thing here is that ProcessPipeline can help us out here. The way process pipeline works is as follows. Given the following system:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier New, monospace&quot;&gt;ProcessPipeline( Producer(), Transformer(), Consumer() ).run()&lt;br /&gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;p&gt;Such as:&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;font face=&quot;Courier New, monospace&quot;&gt;ProcessPipeline( SimpleFileReader(), AudioDecoder(), AudioPlayer() ).run()&lt;/font&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;Then ProcessPipeline runs in the foreground process. For each of the components listed in the pipeline, it forks, and runs the component using the &lt;a href=&quot;http://pypi.python.org/pypi/pprocess&quot;&gt;pprocess library&lt;/a&gt;, with data passing between components via the ProcessPipeline (based on the principle of &lt;a href=&quot;http://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.html&quot;&gt;the simplest thing that could possibly work&lt;/a&gt;). The interesting thing about this is this: &lt;b&gt;ProcessPipeline therefore has a copy of each component before it started executing&lt;/b&gt;. Fundamentally this allows process pipeline to be able (at some later point in time) to be able to detect erroneous death of the component (somehow :) ), either due to bugs, or hardware failure, and to be able to restart the component - masking the error from the other components in the system.&lt;/p&gt;&lt;p&gt;Now, quite how that would actually work in practice, I'm not really sure, ProcessPipeline is after all experimental at present, with issues in it being explored by a &lt;a href=&quot;http://code.google.com/soc/2008/&quot;&gt;Google Summer of Code&lt;/a&gt; project aimed at &lt;a href=&quot;http://edit.kamaelia.org/Developers/Projects/KamaeliaPaint&quot;&gt;a multi-process paint program&lt;/a&gt; (by a first year CS student...). However, it gives me warm fuzzy feelings about both our approach and it's potential longevity - since we do have a clear reasonable answer as to how to deal with that (hardware) reliability issue.&lt;/p&gt;&lt;p&gt;So, whilst Intel may have some &quot;&lt;a href=&quot;http://blogs.intel.com/research/2008/06/unwelcome_advice.php&quot;&gt;unwelcome advice&lt;/a&gt;&quot;, and people may be reacting thinking &quot;how on earth do I even structure my code to work that way&quot;, but the real problem is &quot;how do I write application code that is resilient to and works despite hardware failure&quot;. &lt;/p&gt;&lt;p&gt;That's a much harder question, and the only solution to both that I can see is &quot;break your code down into restartable, non-datasharing, message passing, replaceable components&quot;. I'm sure other solutions either exist or will come along though :-) After all, Kamaelia turns out to have similarities to &lt;a href=&quot;http://async.org.uk/Hugo.Simpson/&quot;&gt;Hugo Simpon'&lt;/a&gt;s &lt;a href=&quot;http://async.org.uk/Hugo.Simpson/Cover-Preface-MASCOT-3.1-Manual-June-1987.pdf&quot;&gt;MASCOT&lt;/a&gt; (pdf, see also &lt;a href=&quot;http://en.wikipedia.org/wiki/Modular_Approach_to_Software_Construction_Operation_and_Test&quot;&gt;wikipedia link&lt;/a&gt;) which is over 30 years old but barely advertised, so I'm sure that other approaches exist.&lt;/p&gt;</description>
	<pubDate>Sat, 05 Jul 2008 11:47:52 +0000</pubDate>
</item>
<item>
	<title>Second p0st - Phillip Pearson: MySpace: &quot;Authentication failed. Failed to resolve application URI&quot; solution</title>
	<guid isPermaLink="true">http://www.myelin.co.nz/post/2008/7/5/#200807051</guid>
	<link>http://www.myelin.co.nz/post/2008/7/5/#200807051</link>
	<description>&lt;p&gt;I'm hacking on a MySpace OpenSocial app at the moment and have wasted several hours trying to debug this: all REST requests to &lt;code&gt;http://api.myspace.com/&lt;/code&gt; give me the error &lt;b&gt;Authentication failed. Failed to resolve application URI &quot;&lt;i&gt;my oauth key here&lt;/i&gt;&quot;&lt;/b&gt;.
&lt;/p&gt;

&lt;p&gt;In the end the solution was to create a new app; the REST call succeeded immediately with the new app ID.  Presumably some database migration failed on MySpace between me creating my first app (many months ago) and now, leaving my application unusable.
&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://www.myelin.co.nz/post/comments?u=2&amp;amp;p=200807051&amp;amp;link=http://www.myelin.co.nz/post/2008/7/5/#200807051&quot; title=&quot;Click here to comment on this post.&quot;&gt;Comment&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Sat, 05 Jul 2008 08:42:29 +0000</pubDate>
</item>
<item>
	<title>Mike Fletcher: IndexedFaceSet compilation improving</title>
	<guid isPermaLink="false">http://blog.vrplumber.com/index.php?/archives/2160-guid.html</guid>
	<link>http://blog.vrplumber.com/index.php?/archives/2160-IndexedFaceSet-compilation-improving.html</link>
	<description>&lt;p&gt;Working on the IndexedFaceSet support this afternoon and evening (with a birthday party for a friend in the middle).  IndexedFaceSet's are very generic ways of defining face geometry, which makes it easy to hand-edit VRML files with them.  Unfortunately, that generality means they are also rather involved to prepare for rendering, you basically have to do a lot of up-front compilation to turn the VRML97 mesh into something OpenGL compatible.&lt;/p&gt;&lt;p&gt;OpenGLContext has had (disabled) code to use display lists for IFS display for a very long time.  It was disabled because it was slower than the array-based geometry path.  The code that got used was a very generic mechanism that used the ArrayGeometry class to render the IFS.  ArrayGeometry is rendered with a straightforward call to glDrawArrays().&lt;/p&gt;&lt;p&gt;glDrawArrays says &quot;draw X primitives from all active arrays starting at a given index in the arrays&quot;.  It allows you to use a single call to render the arrays, but the arrays have to be in &quot;expanded&quot; form, that is, if you have three triangles that all share a vertex (extremely common) you will wind up with 3 copies of the vertex in the arrays.  The major advantage of this approach is that the code to produce the expanded form &lt;b&gt;for the general case&lt;/b&gt; of an IFS is fairly straightforward.  That is, expanding any IFS to an ArrayGeometry can be done robustly and (fairly) simply.&lt;/p&gt;&lt;p&gt;Obviously, however, there is a downside to the ArrayGeometry approach.  The expanded form uses a lot of memory and memory bandwidth, particularly for the (extremely common) case of geometry that shares vertices.  What we'd like is a way to tell the GL to render an array of indices into the active arrays, rather than a range of indices.  Enter the glDrawElements function.  It works like glDrawArrays, save that you specify an array of indices to render, rather than a start and count.&lt;/p&gt;&lt;p&gt;Thing is, glDrawElements is a bit more involved to prepare from an IFS than glDrawArrays.  You have to track more data in order to map the final tessellated vertices to the values in the original, and doing the mapping in the general case doesn't make sense, as in a lot of cases you'll wind up breaking down to a fully expanded set anyway.&lt;/p&gt;&lt;p&gt;Luckily, we already have the fallback code &lt;img src=&quot;http://blog.vrplumber.com/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt; .  I wrote a quick test function that determines which algorithm is appropriate for a given piece of geometry and uses glDrawElements (IndexedPolygons) only when it might provide an advantage over glDrawArrays (and is easy to generate).&lt;/p&gt;&lt;p&gt;I still need to alter IndexedPolygons to use VBOs and push/pop attribute operations, but once that's done common modeller-created IFS's in OpenGLContext should be a little bit faster and a lot more space-efficient.  At some point we could even try creating an glInterleavedArrays implementation, as the code is now set up to handle different IFS compilers.&lt;/p&gt;&lt;p&gt;Anyway, the code is still very rough, but I'm rather happy with the day's work.&lt;/p&gt;</description>
	<pubDate>Sat, 05 Jul 2008 05:04:05 +0000</pubDate>
	<author>nospam@example.com (Mike Fletcher)</author>
</item>
<item>
	<title>James Tauber: Changes to Google Maps Satellite Images</title>
	<guid isPermaLink="false">http://jtauber.com/blog/2008/07/04/changes_to_google_maps_satellite_images</guid>
	<link>http://jtauber.com/blog/2008/07/04/changes_to_google_maps_satellite_images/</link>
	<description>&lt;p&gt;It used to be obvious in Google Maps where the boundaries of different satellite images were. Each image had different brightness, contrast, colour, etc which gave away the stitching.
&lt;/p&gt;
&lt;p&gt;
I always wondered whether there were techniques to normalize that.
&lt;/p&gt;
&lt;p&gt;
I guess there are: Today I noticed the satellite images are stitched together seamlessly.
&lt;/p&gt;
&lt;p&gt;
I also noticed some level-of-detail differences between land and ocean and that is also done pretty seamlessly.
&lt;/p&gt;
&lt;p&gt;
It actually makes navigating around the satellite view a little eerie.
&lt;/p&gt;
&lt;p&gt;
Anyone know when the change was made?
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;UPDATE&lt;/b&gt;: Actually it depends on the zoom level. Compare &lt;a href=&quot;http://maps.google.com/?ie=UTF8&amp;amp;ll=42.361715,-70.937176&amp;amp;spn=0.293004,0.326843&amp;amp;t=h&amp;amp;z=12&quot; class=&quot;external&quot;&gt;this&lt;/a&gt; to &lt;a href=&quot;http://maps.google.com/?ie=UTF8&amp;amp;ll=42.361715,-70.937176&amp;amp;spn=0.146502,0.163422&amp;amp;t=h&amp;amp;z=13&quot; class=&quot;external&quot;&gt;this&lt;/a&gt;. And notice the image credits are different. Interestingly, my home town of Perth looks fully normalized at all scales, even though the image sources are still TerraMetrics for the large scale and DigitalGlobe/GeoEye for the small scale.
&lt;/p&gt;</description>
	<pubDate>Fri, 04 Jul 2008 22:51:17 +0000</pubDate>
</item>
<item>
	<title>Mike Fletcher: Smooth Movement for OpenGLContext</title>
	<guid isPermaLink="false">http://blog.vrplumber.com/index.php?/archives/2159-guid.html</guid>
	<link>http://blog.vrplumber.com/index.php?/archives/2159-Smooth-Movement-for-OpenGLContext.html</link>
	<description>&lt;br /&gt;
&lt;p&gt;Finally got around to implementing smooth movement for OpenGLContext.  Instead of just &quot;jumping&quot; a given distance on each press of the key, the default movement manager will now smoothly interpolate to the position (same for orientations).  Code is pretty straightforward, the only tricky thing was getting holding down the key to make the motion faster.&lt;/p&gt;&lt;p&gt;Under the covers I'm using a pair of timers to handle the interpolation.  Each time a key-press event is received the timer is restarted to interpolate between the current position and the target position.  Problem was that the timers would start a frame behind, and by the time they were firing the next key-press event would be firing as well.&lt;/p&gt;&lt;p&gt;Result was that the cycle-fractions produced for the first frame of the animation would be about 1/2 of the time that was intended (since the key-press processing occurs between frames).  Since a new keyboard event would come in that frame too, the timer would get reset all over again.  Result was that pressing and holding the key would slow down the motion by about 1/2 compared with pressing discretely.&lt;/p&gt;&lt;p&gt;To get around that, I compress the natural fraction from the timer by 1/2 and shift it 1/2 forward.  Result is that the viewer jumps forward 1/2 of the distance, then slowly adjusts into the final position if they press the key once.  If they kept the key pressed, however, they tend to move forward at about 1/2 of the step distance per frame.  Only real downside is that speed is once again affected by frame-rate, rather than being entirely simulation-driven.  Still, it looks reasonably good and feels natural.&lt;/p&gt;&lt;br /&gt;</description>
	<pubDate>Fri, 04 Jul 2008 20:13:40 +0000</pubDate>
	<author>nospam@example.com (Mike Fletcher)</author>
</item>
<item>
	<title>Titus Brown: zounds, for running lots of BLASTs</title>
	<guid isPermaLink="false">http://ivory.idyll.org/blog/2008/07/04/zounds-announce</guid>
	<link>http://ivory.idyll.org/blog/jul-08/zounds-announce</link>
	<description>&lt;div class=&quot;document&quot;&gt;
&lt;p&gt;I finally got sick of manually schlepping BLAST files around, so I wrote
something to do it for me.  'zounds' is a very simple server/client
system for coordinating a bunch of 'worker' nodes through a central
server; it does everything in Python with objects and pickling, so it's
easy to do extra Python-based processing on the worker nodes.  See
'filters' for more info.&lt;/p&gt;
&lt;p&gt;You can read a bit more about zounds here:&lt;/p&gt;
&lt;blockquote&gt;
&lt;a href=&quot;http://iorich.caltech.edu/~t/zounds/README.html&quot; class=&quot;reference&quot;&gt;http://iorich.caltech.edu/~t/zounds/README.html&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;It's freely available, open-source, etc. etc.&lt;/p&gt;
&lt;p&gt;Comments and thoughts welcome; send them to the &lt;a href=&quot;http://lists.idyll.org/listinfo/biology-in-python&quot; class=&quot;reference&quot;&gt;bip list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;--titus&lt;/p&gt;
&lt;/div&gt;</description>
	<pubDate>Fri, 04 Jul 2008 19:32:47 +0000</pubDate>
</item>
<item>
	<title>Simon Wittber: First steps to GameJam!</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8935780327334775165.post-9170083542760873163</guid>
	<link>http://entitycrisis.blogspot.com/2008/07/first-steps-to-gamejam.html</link>
	<description>Registration is up and running at &lt;a href=&quot;http://gamejam.org/&quot;&gt;http://gamejam.org/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There is more to the web app to be developed, but I'll hold off until enough people register their interest.</description>
	<pubDate>Fri, 04 Jul 2008 14:50:40 +0000</pubDate>
	<author>noreply@blogger.com (Simon Wittber)</author>
</item>
<item>
	<title>Simon Willison's Weblog: Running C and Python Code on The Web</title>
	<guid isPermaLink="true">http://simonwillison.net/2008/Jul/4/adobe/</guid>
	<link>http://simonwillison.net/2008/Jul/4/adobe/</link>
	<description>&lt;div class=&quot;blogmark segment&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://www.toolness.com/wp/?p=52&quot;&gt;Running C and Python Code on The Web&lt;/a&gt;. Adobe are working on a toolchain to compile C code to target the Tamarin VM in Flash. This will allow existing C code (from CPython to Quake) to execute in a safe sandbox in the browser.&lt;/p&gt;
&lt;/div&gt;</description>
	<pubDate>Fri, 04 Jul 2008 08:26:27 +0000</pubDate>
</item>
<item>
	<title>Michael Sparks: Interesting post on requirements for project websites</title>
	<guid isPermaLink="true">http://yeoldeclue.com/cgi-bin/blog/blog.cgi?rm=viewpost&amp;nodeid=1215158777</guid>
	<link>http://yeoldeclue.com/cgi-bin/blog/blog.cgi?rm=viewpost&amp;nodeid=1215158777</link>
	<description>I quite like &lt;a href=&quot;http://www.protocolostomy.com/2008/07/03/this-is-how-i-want-all-project-web-sites-to-look/&quot;&gt;this list of requirements for project websites&lt;/a&gt;by &lt;a href=&quot;http://www.protocolostomy.com/&quot;&gt;Brian Jones&lt;/a&gt;. We've been planning a rebuild of the Kamaelia website to focus on applications written using kamaelia, how to modify them, make your apps using it, and how to join in (hoping people are interested in doing so), and whilst that's a wider scope than some of the things he's suggesting, but it's a good checklist. (After all, each of the applications themselves should actually have a project page with that sort of information).&lt;br /&gt;</description>
	<pubDate>Fri, 04 Jul 2008 08:06:17 +0000</pubDate>
</item>
<item>
	<title>Go Deh: Essence of Duck</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-11149365.post-8775583360570298596</guid>
	<link>http://paddy3118.blogspot.com/2008/07/essence-of-duck.html</link>
	<description>A distillation of duck typing&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;margin-left: 40px;&quot;&gt;&lt;span style=&quot;font-family: Comic Sans MS; font-style: italic;&quot;&gt;&quot;Substitution
of an object with regard only of the function and signature &lt;/span&gt;&lt;span style=&quot;font-family: Comic Sans MS; font-style: italic;&quot;&gt;of
its run-time methods &lt;/span&gt;&lt;span style=&quot;font-family: Comic Sans MS; font-style: italic;&quot;&gt;&quot;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Lets
break it down:&lt;br /&gt;&lt;dl style=&quot;margin-left: 40px;&quot;&gt;&lt;dt style=&quot;font-family: Comic Sans MS; font-style: italic;&quot;&gt;Substitution&lt;/dt&gt;&lt;dd&gt;Its
about the later use of a new object type instead of another .&lt;/dd&gt;&lt;dt style=&quot;font-family: Comic Sans MS; font-style: italic;&quot;&gt;object&lt;/dt&gt;&lt;dd&gt;Its
about the use of data types.&lt;/dd&gt;&lt;dt style=&quot;font-family: Comic Sans MS; font-style: italic;&quot;&gt;regard&lt;/dt&gt;&lt;dd&gt;What
needs to be in place for things to work.&lt;/dd&gt;&lt;dt style=&quot;font-family: Comic Sans MS; font-style: italic;&quot;&gt;function&lt;/dt&gt;&lt;dd&gt;what
the substituting object has to do to fit in.&lt;/dd&gt;&lt;dt style=&quot;font-family: Comic Sans MS; font-style: italic;&quot;&gt;signature&lt;/dt&gt;&lt;dd&gt;the
substituting objects method signature  needed for
compatability.&lt;/dd&gt;&lt;dt style=&quot;font-family: Comic Sans MS; font-style: italic;&quot;&gt;run-time&lt;/dt&gt;&lt;dd&gt;It
is what actually happens at run time that matters without the
constraint of what can be determened at compile time.&lt;/dd&gt;&lt;/dl&gt;&lt;div style=&quot;margin-left: 40px;&quot;&gt;There is purposefully no mention
of type-checking, class hierarchy checking, in fact any 'look before
you leap' checks. Note too, that I purposefully put function before
signature - too many comments on duck typing  focus on issues
of signature and &lt;span style=&quot;font-style: italic;&quot;&gt;assume&lt;/span&gt;
programmer checks for correct substitutable function are &lt;span style=&quot;font-style: italic;&quot;&gt;not&lt;/span&gt; part of duck
typing.&lt;br /&gt;&lt;/div&gt;&lt;dl&gt;&lt;dt&gt;- Paddy.&lt;/dt&gt;&lt;dd&gt;&lt;/dd&gt;&lt;/dl&gt;</description>
	<pubDate>Fri, 04 Jul 2008 05:22:52 +0000</pubDate>
	<author>noreply@blogger.com (Paddy3118)</author>
</item>
<item>
	<title>Brian Jones: This is how I want all project web sites to look…</title>
	<guid isPermaLink="false">http://www.protocolostomy.com/?p=327</guid>
	<link>http://www.protocolostomy.com/2008/07/03/this-is-how-i-want-all-project-web-sites-to-look/</link>
	<description>&lt;p&gt;My brain has a set of rules that software project websites get tested against. Each time a project site fails to comply with a rule, I get ever-so-slightly more annoyed, and ever-so-slightly less likely to use the software in question (if there are alternatives, this is even maybe not so “slightly”). &lt;/p&gt;
&lt;p&gt;I thought I’d list these rules because I suspect others are like me: we’re extremely busy, we work too many hours, and are involved with too many projects to spend hours trying to figure out what some piece of code someone mentioned once in IRC actually &lt;em&gt;does&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;But first, know that &lt;a href=&quot;http://incubator.apache.org/couchdb/&quot;&gt;this site actually complies with just about every single rule&lt;/a&gt; there is, so it’s a great template to work from if your site needs brushing up. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First and foremost, tell me, right away, what this thing does, the problem it solves, and (at a high level) the approach taken to solve the problem. &lt;/li&gt;
&lt;li&gt;Tell me the language it’s written in. If it’s open source, and it’s written in a language I hack in, *and* it solves a problem I need solved, maybe I can help out, or be encouraged that if something flakes, I can fix it, or at least speak the developer’s language if I have to describe the issue to the folks upstream. &lt;/li&gt;
&lt;li&gt;Tell me what OS is required, and preferably what OS/version is tested with. &lt;/li&gt;
&lt;li&gt;Give me a full list of dependencies with links to go get them, or give me a link to “Dependencies”, or to an install document that lists them. &lt;/li&gt;
&lt;li&gt;Tell me the current version, and the date it was released. Beta versions and dates are nice too. If there is a timed release schedule, tell me that. &lt;/li&gt;
&lt;li&gt;Keep the information up-to-date. I shouldn’t have to wonder if your software is going to work under OS X 10.5 or RHEL 5, or if your plugin will work under the latest version of Drupal/Django/Moodle/MySQL/Joomla/Firefox…&lt;/li&gt;
&lt;li&gt;BONUS: a very simple architectural drawing that shows me exactly what components make up the whole. The one for &lt;a href=&quot;http://incubator.apache.org/couchdb/&quot;&gt;CouchDB&lt;/a&gt; is as good as any I’ve ever seen (assuming it’s accurate). &lt;/li&gt;
&lt;li&gt;BONUS: if screenshots are applicable, use them. They communicate a million times more information using a million times less real estate and bandwidth. They can communicate things you didn’t even know you were communicating. Of course, that could be good or bad, but it keeps you honest, and customers like that :-) &lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;For kicks, here are a few things I see sometimes on project web sites that I wish they *wouldn’t* do: &lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;DON’T require me to understand how something like Trac or some other tool works in order to get at the information about your software project. Navigation should not assume I’m a developer, it should assume I’m a prospective user who will leave if they can’t read the menu. If you want to use a project management tool to do your work, more power to you, but as a prospective customer, it’s none of my business — don’t drag me into your personal hell! I just want the software! &lt;/li&gt;
&lt;li&gt;DON’T be satisfied with the Sourceforge page as your project’s “homepage”. The problem with doing that is twofold: first, Sourceforge kinda sucks, and occasionally becomes unusable. Second, it doesn’t provide a simple way for you to give me information, nor a simple way for me to find it even if you produce said information using their tools. Also, it’s bad form. If you haven’t committed to the project enough to give it a proper site, well… &lt;/li&gt;
&lt;li&gt;DON’T put some kind of “Coming Soon” page with a bunch of information with *NO DATE*, because I’m going to go ahead and assume that this thing is vaporware, and that the “coming soon” post is 3 years old. Nothing in this world is more annoying than time-sensitive information being plastered on a web site with no date. &lt;/li&gt;
&lt;li&gt;DO NOT — I repeat — DO NOT force me to download a 20MB tarball to get at the documentation. That’s not how things work. I get to see what I’m downloading *before* I download it. You’ll save me some time, and save yourself some bandwidth, and you’ll have more accurate statistics about how many people download and use your software, because the numbers won’t be skewed by folks who were forced to download the package to get at the documentation. &lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;All of that said, I probably won’t use CouchDB, even though I love their project’s site. Javascript makes my brain explode, so mixing them with something like a database, which to me is the digital embodiment of sanity itself, is… insane. But if you’re someone who can deal with this concoction, I encourage you to check out CouchDB — at the very least, you can figure out if it &lt;em&gt;might&lt;/em&gt; be a fit for you without clicking from their home page a single time. That just rocks. &lt;/div&gt;
&lt;/div&gt;</description>
	<pubDate>Fri, 04 Jul 2008 00:42:47 +0000</pubDate>
</item>
<item>
	<title>Robert Brewer: Writing High-Efficiency Large Python Systems--Lesson #1: Transactions in tests</title>
	<guid isPermaLink="false">http://www.aminus.org/blogs/xmlsrv/982@http://www.aminus.org/blogs/</guid>
	<link>http://www.aminus.org/blogs/index.php/2008/07/03/writing-high-efficiency-large-python-sys?blog=2</link>
	<description>&lt;p&gt;Don't write your test suite to create and destroy databases for each run. Instead, make each test method start a transaction and roll it back. We just made that move at work on a DAL project, and the test suite went from 500+ seconds to run the whole thing down to around 100. It also allowed us to remove a lot of &quot;undo&quot; code in the tests.&lt;/p&gt;

&lt;p&gt;This means ensuring your test helpers always connect to their databases on the same connection (transactions are connection-specific). If you're using a connection pool where leased conns are bound to each thread, this means rewriting tests that start new threads (or leaving them &quot;the old way&quot;; that is, create/drop). It also means that, rather than running slightly different .sql files per test or module, you instead have a base of data and allow each test to add other data as needed. If your rollbacks work, these can't pollute other tests.&lt;/p&gt;

&lt;p&gt;Obviously, this is much harder if you're doing integration testing of sharded systems and the like. But for application logic, it'll save you a lot of headache to do this from the start.&lt;/p&gt;
&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.aminus.org/blogs/index.php/2008/07/03/writing-high-efficiency-large-python-sys?blog=2&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://b2evolution.net/&quot;&gt;b2evolution&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 03 Jul 2008 22:02:59 +0000</pubDate>
</item>
<item>
	<title>Duncan McGreggor: Divmod Tech: Making the &quot;Next Gen&quot; Grade</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8825992.post-241117163984824426</guid>
	<link>http://feeds.feedburner.com/~r/ElectricDuncan/~3/325760044/divmod-tech-making-next-gen-grade.html</link>
	<description>&lt;div&gt;Last night, after I already posted the latest &lt;a href=&quot;http://labs.twistedmatrix.com/2008/07/twisted-in-news.html&quot;&gt;Twisted in the News&lt;/a&gt;, I came across &lt;a href=&quot;http://psichron.za.net/wordpress/2008-07-02/next-gen-web-dev-playing-with-python-twistednevowathena/&quot;&gt;another post&lt;/a&gt; that would have made the list had I found it sooner. However, this is a good opportunity to give it a little extra attention.&lt;br /&gt;&lt;br /&gt;The title of the post is &quot;Next Gen Web Dev: Playing with Python Twisted/Nevow/Athena&quot; and I gotta say, that made my day :-) Between that post and Colin Alston's post that I mentioned in the News, Nevow had a good week. And people are appreciating it for the right reasons. It may not be the easiest web framework to use and certainly not the best documented, but when you need the flexibility to interact with your (Twisted) web server in particular ways as well as benefit from the functionality that COMET provides, Nevow comes out shining.&lt;br /&gt;&lt;br /&gt;It's also refreshing to see new developers entering the community who not only see the potential of these tools (designed with that potential in mind) but are capable of taking advantage of it immediately. If nothing else, the author of that post has motivated me to finally merge the Athena tutorial to trunk in order to bring the publicly available and published content in sync with the new code that's in the branch.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Update&lt;/span&gt;: Along similar lines, but with more details, Tristan has provided &lt;a href=&quot;http://mithrandi.vox.com/library/post/why-mantissa.html&quot;&gt;an excellent write-up &lt;/a&gt;for this motivation to use Twisted/Nevow/Axiom/Mantissa. Be sure to check it out!&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/ElectricDuncan/~4/325760044&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Thu, 03 Jul 2008 20:26:03 +0000</pubDate>
	<author>noreply@blogger.com (Duncan McGreggor)</author>
</item>
<item>
	<title>Atul Varma: Running C and Python Code on The Web</title>
	<guid isPermaLink="true">http://www.toolness.com/wp/?p=52</guid>
	<link>http://www.toolness.com/wp/?p=52</link>
	<description>&lt;p&gt;Last week, Scott Petersen from Adobe gave a talk at Mozilla on a toolchain he’s been creating—soon to be open-sourced—that allows C code to be targeted to the Tamarin virtual machine.  Aside from being a really interesting piece of technology, I thought its implications for the web were pretty impressive.&lt;/p&gt;
&lt;p&gt;Before reading this post, readers who aren’t familiar with Tamarin may want to read Frank Hecker’s excellent &lt;a href=&quot;http://hecker.org/mozilla/adobe-mozilla-and-tamarin&quot;&gt;Adobe, Mozilla, and Tamarin&lt;/a&gt; post from 2006 for some background on its goals and why it’s relevant to Mozilla and the open-source community in general.&lt;/p&gt;
&lt;p&gt;If I followed his presentation right, Petersen’s toolchain works something like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A special version of the GNU C Compiler—possibly &lt;a href=&quot;http://llvm.org/cmds/llvmgcc.html&quot;&gt;llvm-gcc&lt;/a&gt;—compiles C code into instructions for the &lt;a href=&quot;http://en.wikipedia.org/wiki/Llvm&quot;&gt;Low Level Virtual Machine&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The LLVM instructions are converted into opcodes for a custom Virtual Machine that runs in &lt;a href=&quot;http://en.wikipedia.org/wiki/Actionscript&quot;&gt;ActionScript&lt;/a&gt;, a variant of ECMAScript and sibling of JavaScript.&lt;/li&gt;
&lt;li&gt;The ActionScript is automatically compiled into Tamarin bytecode by Adobe Flash, which may be further compiled into native machine language by Tamarin’s Just-in-Time (JIT) compiler.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The toolchain includes lots of other details, such as a custom POSIX system call API and a C multimedia library that provides access to Flash.  And there’s some things that Petersen had to add to Tamarin, such as a native byte array that maps directly to RAM, thereby allowing the VM’s “emulation” of memory to have only a minor overhead over the real thing.&lt;/p&gt;
&lt;p&gt;The end result is the ability to run a wide variety of existing C code in Flash at acceptable speeds.  Petersen demonstrated a version of Quake running in a Flash app, as well as a C-based Nintendo emulator running Zelda; both were eminently playable, and included sound effects and music.&lt;/p&gt;
&lt;p&gt;So, once Petersen’s modifications to Tamarin make their way into the next version of Adobe Flash, we can expect to see older commercial games running in the browser.  Even more impressive, though, is the &lt;a href=&quot;http://www.ohloh.net/languages?query=&amp;amp;sort=projects&quot;&gt;sheer volume of existing code&lt;/a&gt; that can be made to run inside the browser: Petersen showed us the C-compiled versions of Lua, Ruby, Perl, and Python all running on the web in secure Flash sandboxes.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;What this means for Python&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The potential implications this has for Python are particularly interesting to me.  The ability to run Python on the web is exciting, to say the least; also interesting is the fact that by sandboxing CPython in a virtual machine, we solve a lot of the security issues that currently face the language when it comes to running untrusted code.&lt;/p&gt;
&lt;p&gt;Petersen’s work also resonates with a few goals of another project called &lt;a href=&quot;http://codespeak.net/pypy/dist/pypy/doc/home.html&quot;&gt;PyPy&lt;/a&gt;. I’m going to try to explain the idea behind PyPy in a later post; for the time being, the &lt;a href=&quot;http://www.toolness.com/arch/PyPyPresentation_Varma.pdf&quot;&gt;slides from my April 2007 ChiPy presentation on PyPy&lt;/a&gt; may serve as a passable introduction.&lt;/p&gt;
&lt;p&gt;In a nutshell, the difference in mindset between PyPy and Petersen’s work is that the former is radically innovative in scope and mission, while the latter is pragmatic.  PyPy’s goal is essentially to move the canonical implementation of Python from C to Python itself, and then use a pluggable toolchain to translate the Python interpreter to any platform with a configurable set of language and implementation features. In one fell swoop, this modularizes the composition of the Python interpreter in such a way that innovating and maintaining different ports and variants of Python like &lt;a href=&quot;http://en.wikipedia.org/wiki/Ironpython&quot;&gt;IronPython&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Jython&quot;&gt;Jython&lt;/a&gt;, and &lt;a href=&quot;http://en.wikipedia.org/wiki/Stackless&quot;&gt;Stackless&lt;/a&gt; no longer requires either writing an entire copy of the same interpreter in a different language or branching the CPython source code and making pervasive changes to it.&lt;/p&gt;
&lt;p&gt;Rather than focusing on innovation, Petersen’s work focuses on code reuse. Instead of moving a canonical interpreter implementation from C to a dynamic language, his strategy is to simply compile the existing C code to run in a virtual machine that’s implemented in a dynamic language.  Both approaches aim to obviate the necessity of “ports” of interpreters to different platforms, and as such their purposes intersect at a common subset of functionality.  But Petersen’s work can’t be used to facilitate the &lt;i&gt;innovation&lt;/i&gt; of the Python language and its implementation, while PyPy offers few or no tools to reuse existing non-Python code.  Perhaps it’s possible to combine the best of both worlds by taking PyPy’s generated C interpreter and using Petersen’s toolchain to allow it to be usable on the web and other places that Tamarin runs.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;What this means for the Open Web&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;To be honest, I’m not quite sure where the dividing line is between what of Petersen’s work is Flash-specific and what can be reused to benefit the Open Web.  Since ActionScript is a sibling language to JavaScript, it’s possible that the custom VM he created can be run in a browser with relatively few modifications—albeit much more slowly in Firefox at the time being, since SpiderMonkey-Tamarin integration is not yet complete.  Once that’s further along, though, I imagine it should be possible to create C “libraries” that can be used in the toolchain to allow sandboxed C code to interact with web pages rather than Flash apps.  Should this be feasible, I think it will possibly be the ultimate in a relatively recent string of &lt;a href=&quot;http://labs.mozilla.com/2008/06/next-generation-javascripting/&quot;&gt;next-generation Javascript virtual machines&lt;/a&gt; that allow existing code to run safely in browsers.&lt;/p&gt;
&lt;p&gt;Also, in the context of the web, download size is a significant concern because applications are essentially streamed to clients.  While Petersen’s toolchain means that it’s possible to instantly inherit most of CPython’s benefits on the web, it also means that we get all of its flaws along with it—such as the fact that the standard CPython distribution is a few megabytes large. But there’s ways to get around this.&lt;/p&gt;
&lt;p&gt;In any case, I’m really excited to see how both Petersen’s work and PyPy proceed. I just hope I haven’t mis-represented either one of them here due to a lack of understanding; I’ll try to correct this blog post as I become aware of my mistakes.&lt;/p&gt;</description>
	<pubDate>Thu, 03 Jul 2008 17:56:38 +0000</pubDate>
</item>
<item>
	<title>Wybiral: Fresh new look</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-6946125878559207247.post-8246104351762983653</guid>
	<link>http://davywybiral.blogspot.com/2008/07/fresh-new-look.html</link>
	<description>I gave &lt;a href=&quot;http://challenge-you.appspot.com/&quot;&gt;Challenge-You!&lt;/a&gt; a facelift this week to try to improve some of the design flaws in the original layout. Design is hard! I'm still looking for a CSS/HTML expert to help come up with and implement an interesting layout for the site (&lt;a href=&quot;http://challenge-you.appspot.com/feedback&quot;&gt;leave me feedback&lt;/a&gt; on the site if you're interested). I've improved some of the caching for the statistics and am working towards extending some of the core functionality (including branching out into other types of challenges).&lt;br /&gt;&lt;br /&gt;I've also learned a valuable lesson in Python design... Be careful with decorators. Sometimes it's better to just wrap your function calls. I ran into some issues with needing some of the functions for alternate purposes, but they had been decorated for a specific purpose which resulted in lots of rewriting. :( But, lesson learned...</description>
	<pubDate>Thu, 03 Jul 2008 16:56:43 +0000</pubDate>
	<author>noreply@blogger.com (Wybiral)</author>
</item>
<item>
	<title>Corey Goldberg: Searching For Your Open Source Code</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-5236867476487043111.post-829579029694380925</guid>
	<link>http://coreygoldberg.blogspot.com/2008/07/searching-for-your-open-source-code.html</link>
	<description>One cool thing about developing free open source software is seeing where your code ends up.  It is satisfying to know that bits of code you wrote end up in other projects and code bases.&lt;br /&gt;
&lt;br /&gt;
There are several online services that index source code from various places like websites and online svn/cvs repositories.  It makes searching for my code a breeze.  This is also useful for looking up examples of code I have written in the past that I want to copy from.&lt;br /&gt;
&lt;br /&gt;

&lt;li&gt;&lt;b&gt;Google Code Search:&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;http://www.google.com/codesearch?q=%22corey goldberg%22&quot;&gt;Search public source code for: &quot;corey goldberg&quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Koders Search:&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;http://www.koders.com/default.aspx?s=%22corey goldberg%22&quot;&gt;Search public source code for: &quot;corey goldberg&quot;&lt;/a&gt;&lt;/li&gt;            
&lt;li&gt;&lt;b&gt;Krugle Code Search:&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;http://www.krugle.com/kse/files?query=%22corey%20goldberg%22&quot;&gt;Search public source code for: &quot;corey goldberg&quot;&lt;/a&gt;&lt;/li&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description>
	<pubDate>Thu, 03 Jul 2008 14:09:43 +0000</pubDate>
	<author>noreply@blogger.com (Corey Goldberg)</author>
</item>
<item>
	<title>Christopher Lenz: The Truth About Unicode In Python</title>
	<guid isPermaLink="false">tag:www.cmlenz.net,2008-07-03:a2608fcc991a48a7bc3301fdfc9163c0</guid>
	<link>http://www.cmlenz.net/archives/2008/07/the-truth-about-unicode-in-python</link>
	<description>&lt;p&gt;The unicode support in Python is generally considered to be pretty good. And in comparison to many other languages, it's good indeed.&lt;p&gt;
&lt;p&gt;But compared to what is provided by the &lt;a href=&quot;http://icu-project.org/&quot;&gt;International Components for Unicode&lt;/a&gt; (ICU) project, there's also a lot missing, including &lt;a href=&quot;http://www.cmlenz.net/archives/python/feed.xml#collation&quot;&gt;collation&lt;/a&gt;, &lt;a href=&quot;http://www.cmlenz.net/archives/python/feed.xml#case-conversion&quot;&gt;special case conversions&lt;/a&gt;, &lt;a href=&quot;http://www.cmlenz.net/archives/python/feed.xml#regular-expressions&quot;&gt;regular expressions&lt;/a&gt;, &lt;a href=&quot;http://www.cmlenz.net/archives/python/feed.xml#text-segmentation&quot;&gt;text segmentation&lt;/a&gt;, and &lt;a href=&quot;http://www.cmlenz.net/archives/python/feed.xml#bidi-text&quot;&gt;bidirectional text handling&lt;/a&gt;. Not to mention extensive support for locale-specific formatting of dates and numbers and time calculations with different calendars.&lt;/p&gt;
&lt;p&gt;Basically what Python &lt;em&gt;does&lt;/em&gt; provide out of the box is “only” encoding/decoding, &lt;a href=&quot;http://unicode.org/faq/normalization.html&quot;&gt;normalization&lt;/a&gt;, and some other bits such as simple case conversion and splitting on whitespace. It's the absolute minimum you need to do anything useful with unicode, but often not enough to build truly internationalized applications. (Fortunately, most applications get away without true internationalization.)&lt;/p&gt;
&lt;p&gt;In this post, I'm going to talk about a couple of the problems with unicode in Python. Please note that this is not intended as a criticism of Python's unicode support or the people who designed and implemented it. Most of those people probably know a whole lot more about unicode than I do, and the limitations discussed here are the result of a pragmatic approach to implementing unicode support, rather than due to a lack of knowledge.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;
      &lt;p&gt;
        &lt;a href=&quot;http://www.cmlenz.net/archives/2008/07/the-truth-about-unicode-in-python#more&quot;&gt;read on …&lt;/a&gt;
      &lt;/p&gt;</description>
	<pubDate>Thu, 03 Jul 2008 13:32:31 +0000</pubDate>
</item>
<item>
	<title>Arthur Koziel: yml2tex presentation from UAS Dortmund</title>
	<guid isPermaLink="false">http://arthurkoziel.com/?p=96</guid>
	<link>http://arthurkoziel.com/2008/07/03/yml2tex-presentation-from-uas-dortmund/</link>
	<description>&lt;p&gt;I had the chance to give a small talk at the UAS Dortmund and introduce the &lt;a href=&quot;http://arthurkoziel.com/2008/06/23/latex-beamer-presentations-from-yaml-files/&quot;&gt;yml2tex Python script to generate LaTeX Beamer presentations out of YAML files&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Although the presentation is in German, I think it might help to better understand the syntax by seeing a practical example.&lt;/p&gt;
&lt;p&gt;The whole presentation with all the files needed to generate it can be &lt;a href=&quot;http://arthurkoziel.com/wp-content/uploads/2008/07/27-06-08_yml2tex_uas_dortmund.zip&quot;&gt;downloaded in a ZIP file&lt;/a&gt;.&lt;/p&gt;</description>
	<pubDate>Thu, 03 Jul 2008 13:11:46 +0000</pubDate>
</item>
<item>
	<title>Andrew Dalke: HAKMEM 169 and other popcount implementations</title>
	<guid isPermaLink="true">http://www.dalkescientific.com/writings/diary/archive/2008/07/03/hakmem_and_other_popcounts.html</guid>
	<link>http://www.dalkescientific.com/writings/diary/archive/2008/07/03/hakmem_and_other_popcounts.html</link>
	<description>&lt;p&gt;

This is part 6 of an on-going series dealing with molecular
fingerprints:
&lt;/p&gt;&lt;ol&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/06/26/fingerprint_background.html&quot;&gt;Molecular fingerprints, background&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/06/27/generating_fingerprints_with_openbabel.html&quot;&gt;Generating molecular fingerprints with OpenBabel&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/06/27/computing_tanimoto_scores.html&quot;&gt;Computing Tanimoto scores, quickly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/06/28/block_tanimoto_calculations.html&quot;&gt;Block Tanimoto calculations&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/07/01/faster_tanimtocat_search_search.html&quot;&gt;Faster block Tanimoto calculations&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;HAKMEM 169 and other popcount implementations&lt;/b&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;http://www.dalkescientific.com/writings/diary/archive/2008/07/05/bitslice_and_popcount.html&quot;&gt;Testing the bitslice algorithm for popcount&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;a href=&quot;http://dalkescientific.blogspot.com/2008/06/molecular-fingerprints.html&quot;&gt;Comments?&lt;/a&gt;

&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;HAKMEM&lt;/h2&gt;

&lt;p&gt;

Many other people have worked on doing high speed population counts.
In 1972 the AI Laboratory at MIT published &quot;&lt;a href=&quot;http://home.pipeline.com/~hbaker1/hakmem/hakmem.html&quot;&gt;HAKMEM&lt;/a&gt;&quot;,
or &quot;Artificial Intelligence Memo No. 239&quot;.  It is a collection of
algorithms, tricks, observations, and unsolved but interesting
problems.  One of which is to &quot;Solve Go.&quot;  &lt;a href=&quot;http://home.pipeline.com/~hbaker1/hakmem/hacks.html#item169&quot;&gt;Item
169&lt;/a&gt; is a PDP-6/10 assembly way to count the number of ones in a
word.  It was called &quot;count ones&quot; and is now called popcount.

&lt;/p&gt;&lt;p&gt;

I first came across HAKMEM Item 169 in 2005 when I last looked at
doing fast Tanimoto calculations.  I tried it and a few other
solutions but concluded that using special Altivec instructions were
the fastest solution for my PowerPC-based PowerBook.  I don't have a
PowerPC any more.  I bought a MacBook Pro last year with a 2.33 GHz
Intel Core 2 Duo.  I've been looking at the MMX instructions
quizzically trying to figure out if there's an equivalent solution.  I
am &lt;i&gt;not&lt;/i&gt; an assembly programmer.

&lt;/p&gt;&lt;p&gt;

The best I could find was an AMD &quot;&lt;a href=&quot;http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/22007.pdf&quot;&gt;x86
Code Optimization Guide&lt;/a&gt;&quot;.  It gives a 32-bit integer version using
normal Intel assembly and a 64-bit version using MMX which &quot;can do
popcounts about twice as fast as the integer version (for an identical
number of bits).&quot; 

&lt;/p&gt;&lt;p&gt;

The newer guide (I misplaced the URL) says to use the popcount instruction in SSE4a.

&lt;/p&gt;
&lt;h2&gt;Other popcount references&lt;/h2&gt;
&lt;p&gt;

Computing popcount is apparently very widely used.  You can find many
people have talked about it:

&lt;/p&gt;&lt;ul&gt;
 &lt;li&gt;&lt;a href=&quot;http://wiki.cs.pdx.edu/forge/popcount.html&quot;&gt;Bart
 Massey&lt;/a&gt;:&lt;br /&gt;
&lt;pre class=&quot;code&quot;&gt;popcount_naive: 1.6666e+07 iters in 688 msecs for 41.28 nsecs/iter
popcount_8: 1e+08 iters in 995 msecs for 9.95 nsecs/iter
popcount_6: 2e+08 iters in 1725 msecs for 8.625 nsecs/iter
popcount_hakmem: 2e+08 iters in 1411 msecs for 7.055 nsecs/iter
popcount_keane: 1e+09 iters in 6566 msecs for 6.566 nsecs/iter
popcount_3: 1e+09 iters in 6270 msecs for 6.27 nsecs/iter
popcount_2: 1e+09 iters in 5658 msecs for 5.658 nsecs/iter
popcount_mult: 1e+09 iters in 4169 msecs for 4.169 nsecs/iter
  ...
At the suggestion of Bill Trost, I added 8 and 16-bit table-driven
popcount implementations. These perform the fastest in the benchmark
test-stand, at about 3ns/iteration. They're about the same speed, so
one would obviously use the 8-bit version.
&lt;/pre&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href=&quot;http://popcnt.org/2007/09/magic-popcount-popcnt-command.html&quot;&gt;Majek&lt;/a&gt;
has pointers to code.  That's where I found the AMD optimization
guide link.&lt;/li&gt;

&lt;li&gt;Lauradoux Cédric's &lt;a href=&quot;http://www.princeton.edu/~claurado/hamming.html&quot;&gt;Hamming weight&lt;/a&gt;
page has &lt;a href=&quot;http://www.princeton.edu/~claurado/ham/overview.pdf&quot;&gt;an
overview&lt;/a&gt; of the topic.  He reports:

&lt;table style=&quot;margin-left: 20ex; border-bottom: 1px solid black;&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th style=&quot;border-bottom: 1px solid black;&quot;&gt;Algorithms    &lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid black;&quot;&gt;Throughput&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Naive &lt;/td&gt;&lt;td&gt;29.97 MB/s &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Kernighan &lt;/td&gt;&lt;td&gt; 33.34 MB/s &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Tree 1 &lt;/td&gt;&lt;td&gt; 122.97 MB/s &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Tree 2 &lt;/td&gt;&lt;td&gt; 130.60 MB/s &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Tree 3 &lt;/td&gt;&lt;td&gt; 125.57 MB/s &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Table 8 bits &lt;/td&gt;&lt;td&gt; 200.94 MB/s &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Table 16 bits &lt;/td&gt;&lt;td&gt; 244.64 MB/s &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

and nicely summarizes why few people use the fastest solution:

&lt;blockquote&gt;

The fastest solutions use pre-computation. However, you will never
find this two implementations in current software product (X11, linux
kernel. . . ). The reason of that is simple: the programmers are
reluctant to use solutions implying a big amount of memory since it
can affect the portability of the applications and their
performance. As a consequence, the algorithms based on tree are the
most popular.

&lt;/blockquote&gt;
&lt;/li&gt;

&lt;li&gt;There was a reddit thread in 2007 titled: &lt;a href=&quot;http://www.reddit.com/r/programming/info/22p5v/comments&quot;&gt;Popcount
- the &quot;NSA instruction&quot; missing from modern CPUs (or at least their
datasheets.)&lt;/a&gt;.  In it, a1k0n posted a link to a &lt;a href=&quot;http://www.a1k0n.net/temp/popcnt.c.txt&quot;&gt;popcount benchmark&lt;/a&gt;
he wrote.  After tweaking the 8-bit version slightly for better
performance I got:
&lt;pre class=&quot;code&quot;&gt;FreeBSD version 1   :  3784823 us; cnt=32511665
FreeBSD version 2   :  3421292 us; cnt=32511665
16-bit LUT          :  2068947 us; cnt=32511665
8-bit LUT           :  3632031 us; cnt=32511665
8x shift and add    : 21401951 us; cnt=32511665
32x shift and add   : 19419464 us; cnt=32511665
&lt;/pre&gt;
and he also found that lookups were the fastest solution.
&lt;/li&gt;

&lt;li&gt;There's a &lt;a href=&quot;http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36041&quot;&gt;gcc bug
report&lt;/a&gt; from April 2008 showing that that __builtin_popcount isn't
even as fast as other bit twiddling solutions.  Joseph Zbiciak &lt;a href=&quot;http://gcc.gnu.org/bugzilla/attachment.cgi?id=15529&amp;amp;action=view&quot;&gt;attached
a benchmark&lt;/a&gt;.  On my machine it shows that gcc's builtin solution
is about 1/3rd the speed of a better one:
&lt;pre class=&quot;code&quot;&gt;popcount64_1 = 4114 clocks   &lt;i&gt;gcc's __builtin_popcount&lt;/i&gt;
popcount64_2 = 1881 clocks 
popcount64_3 = 1627 clocks
popcount64_4 = 1381 clocks
&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;There's also a number of &lt;a href=&quot;http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive&quot;&gt;popcount
algorithms documented by Sean Eron Anderson&lt;/a&gt; including descriptions 
and further links.&lt;/li&gt;

&lt;li&gt;Cédric in private mail pointed out a nice &lt;a href=&quot;http://www.ciphersbyritter.com/NEWS4/BITCT.HTM&quot;&gt;collection of
popcount implementations&lt;/a&gt; from 1998/1999 including a cute 11 bit
lookup table and an implementation of Robert Harley's bit slice
solution, which is great when doing popcount across several words at a
time.&lt;/li&gt;

&lt;li&gt;Finally, you can fetch the &lt;a href=&quot;http://gmplib.org/&quot;&gt;GMP&lt;/a&gt;
package.  It contains hand-written assembly implementations for many
different architectures.  The Intel ones are based on bit twiddling
and do not use a lookup table.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;Benchmarking popcount in GMP&lt;/h2&gt;
&lt;p&gt;

Interesting.  Since I have &lt;a href=&quot;http://www.aleax.it/gmpy.html&quot;&gt;gmpy&lt;/a&gt; installed on this
machine I can figure out just how good gmp's hand-written bit
twiddling actually is.  Here's what I did, with commentary inserted.

&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;# Read the entire data file into memory
&amp;gt;&amp;gt;&amp;gt; s = open(&quot;nci.binary_fp&quot;).read()
&amp;gt;&amp;gt;&amp;gt; len(s)
155667200

# Convert each character into hex

&amp;gt;&amp;gt;&amp;gt; s = s.encode(&quot;hex&quot;)

# Convert the hex number into a gmp integer, using base 16

&amp;gt;&amp;gt;&amp;gt; import gmpy
&amp;gt;&amp;gt;&amp;gt; n = gmpy.mpz(s, 16)

# Do the popcount

&amp;gt;&amp;gt;&amp;gt; gmpy.popcount(n)
136963400

# How long did it take?

&amp;gt;&amp;gt;&amp;gt; import time
&amp;gt;&amp;gt;&amp;gt; t1 = time.time(); gmpy.popcount(n); t2 = time.time()  
136963400
&amp;gt;&amp;gt;&amp;gt; t2-t1
0.36236190795898438
&amp;gt;&amp;gt;&amp;gt; print (155667200/256)*(t2-t1), &quot;fingerprints per second&quot;
220343.217182 fingerprints per second

# Verify that I got the right answer by using an 8-bit lookup table

&amp;gt;&amp;gt;&amp;gt; bitcounts = (
... 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
... 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
... 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
... 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
... 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
... 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
... 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
... 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,)
&amp;gt;&amp;gt;&amp;gt; bitcount_table = dict((chr(i), count) for (i,count) in enumerate(bitcounts))

# Double-check the table creation -- this should be 2

&amp;gt;&amp;gt;&amp;gt; bitcount_table[&quot;A&quot;]
2

# Do the full popcount; this will take a while

&amp;gt;&amp;gt;&amp;gt; sum(bitcount_table[c] for c in s)
136963400
&amp;gt;&amp;gt;&amp;gt; 
&lt;/pre&gt;

GMP takes about 0.36 seconds to compute one popcount.  My C code
before loop unwinding using the 16-bit lookup table took 0.41 seconds
to compute two popcounts, or about 0.2 seconds for one popcount.  This
is in very good agreement with the numbers from a1k0n's benchmark (3.4
seconds vs. 2.1 seconds).

&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;Another popcount benchmark&lt;/h2&gt;
&lt;p&gt;

So many different algorithms and the benchmarks aren't compatible
enough that I could compare them.  I decided to expand a1k0n's
benchmark and include a few other implementations.  The result is &lt;a href=&quot;http://dalkescientific.com/writings/diary/popcnt.c&quot;&gt;popcnt.c&lt;/a&gt;.
Yes, I didn't even change the name.  It implements quite a few
algorithms but it's still incomplete.  Anyone want to contribute
assembly versions using MMX instructions?

&lt;/p&gt;&lt;p&gt;

Here's what my laptop reports.  It's a 2.33 GHz Intel Core 2 Duo and I
compiled with gcc 4.0.1:

&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;% cc popcnt.c -O3
% ./a.out
FreeBSD version 1   :  3828096 us; cnt=32511665
FreeBSD version 2   :  3474751 us; cnt=32511665
16-bit LUT          :  2095066 us; cnt=32511665
8-bit LUT           :  5329692 us; cnt=32511665
8-bit LUT v2        :  3691475 us; cnt=32511665
8x shift and add    : 21675609 us; cnt=32511665
32x shift and add   : 19687827 us; cnt=32511665
Wikipedia #2        :  5264710 us; cnt=32511665
Wikipedia #3        :  5037636 us; cnt=32511665
gcc popcount        :  6088138 us; cnt=32511665
gcc popcountll      :  7548551 us; cnt=32511665
naive               : 23647023 us; cnt=32511665
Wegner/Kernigan     : 15026099 us; cnt=32511665
Anderson            : 63285941 us; cnt=32511665
HAKMEM 169/X11      :  4205008 us; cnt=32511655
&lt;/pre&gt;

The fastest implementation is still the 16-bit lookup table, at 40%
faster than that fastest bit-twiddling code.  The &quot;8-bit LUT&quot;
implementation is by a1k0n.  I noticed it was a lot slower than my
code so I investigated.  The only difference was the order of
calculations for a simple addition.  The &quot;8-bit LUT v2&quot; is my version.
It's interesting to see that that minor change causes a major timing
difference.  And HAKMEM is holding its own; it's even better than the
Wikipedia ones, which I didn't expect.

&lt;p&gt;&lt;/p&gt;&lt;p&gt;

A Core 2 Duo is a 64-bit processor.  I can ask gcc to compile for
64-bits and see if that makes a difference.

&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;% cc popcnt.c -O3 -m64
% ./a.out
FreeBSD version 1   :  3882201 us; cnt=32511665
FreeBSD version 2   :  3382603 us; cnt=32511665
16-bit LUT          :  1562167 us; cnt=32511665
8-bit LUT           :  2013767 us; cnt=32511665
8-bit LUT v2        :  2054639 us; cnt=32511665
8x shift and add    : 21679291 us; cnt=32511665
32x shift and add   : 20050205 us; cnt=32511665
Wikipedia #2        :  2113876 us; cnt=32511665
Wikipedia #3        :  2102645 us; cnt=32511665
gcc popcount        :  8081774 us; cnt=32511665
gcc popcountll      :  4217908 us; cnt=32511665
naive               : 27717913 us; cnt=32511665
Wegner/Kernigan     : 16618378 us; cnt=32511665
Anderson            : 12300547 us; cnt=32511665
HAKMEM 169/X11      :  5643968 us; cnt=32511655
&lt;/pre&gt;

It does, for some things.  The lookup tables are faster (and the 8-bit
counts are now the same), and the 64-bit algorithms (Wikipedia, gcc
popcountll and Anderson) are much happier.  The parallel algorithm
used by the Wikipedia implementations are almost as fast as the 8-bit
lookup table and only 33% slower than the 16-bit lookup table.  While
HAKMEM got 25% slower.

&lt;p&gt;&lt;/p&gt;&lt;p&gt;

Is there any way I can ask gcc to use the 64-bit instructions but
still talk to a Python which was compiled for 32 bits?

&lt;/p&gt;
&lt;h2&gt;Profile-directed optimizations with gcc&lt;/h2&gt;
&lt;p&gt;

I recently learned how to do profile-directed optimizations with gcc
using the -fprofile-arcs and -fbranch-probabilities options.
Sometimes the compiler needs to make a guess on which assembly code is
best for a given circumstance.  For instance, if a branch for an 'if'
statement is usually taken then it might provide hints to the
processor pipline to optimistically assume the branch will be taken.
It can't guess correctly all the time.  Profile-directed optimizations
works by asking gcc during compilation to instrument the program,
running the program to get timings on how the code is actually used,
saving the results to a file, then recompiling while asking gcc to use
the instrumentation data.

&lt;/p&gt;&lt;p&gt;

Is it useful for my case?

&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;     &lt;i&gt;compile with instrumentation - these will be slower than usual!&lt;/i&gt;
% cc popcnt.c -O3 -fprofile-arcs
% ./a.out
FreeBSD version 1   :  4304773 us; cnt=32511665
FreeBSD version 2   :  4062710 us; cnt=32511665
16-bit LUT          :  2835959 us; cnt=32511665
8-bit LUT           :  5344514 us; cnt=32511665
8-bit LUT v2        :  4535290 us; cnt=32511665
8x shift and add    : 22246178 us; cnt=32511665
32x shift and add   : 19915850 us; cnt=32511665
Wikipedia #2        :  5626697 us; cnt=32511665
Wikipedia #3        :  5318770 us; cnt=32511665
gcc popcount        :  7005410 us; cnt=32511665
gcc popcountll      :  8173944 us; cnt=32511665
naive               : 62215630 us; cnt=32511665
Wegner/Kernigan     : 34541338 us; cnt=32511665
Anderson            : 65256755 us; cnt=32511665
HAKMEM 169/X11      :  4727297 us; cnt=32511665


      &lt;i&gt;See the profile data?&lt;/i&gt;
% ls -l popcnt.*
-rw-r--r--   1 dalke  staff  9177 Jul  3 05:01 popcnt.c
-rw-r--r--   1 dalke  staff  1816 Jul  3 04:43 popcnt.gcda
-rw-r--r--   1 dalke  staff  7872 Jul  3 04:43 popcnt.gcno

      &lt;i&gt;recompile using the profile data&lt;/i&gt;
% cc popcnt.c -O3 -fbranch-probabilities
% ./a.out
FreeBSD version 1   :  3815036 us; cnt=32511665
FreeBSD version 2   :  3477915 us; cnt=32511665
16-bit LUT          :  2251514 us; cnt=32511665
8-bit LUT           :  5291010 us; cnt=32511665
8-bit LUT v2        :  3936142 us; cnt=32511665
8x shift and add    : 21715704 us; cnt=32511665
32x shift and add   : 19708580 us; cnt=32511665
Wikipedia #2        :  5273262 us; cnt=32511665
Wikipedia #3        :  5074212 us; cnt=32511665
gcc popcount        :  6431689 us; cnt=32511665
gcc popcountll      :  7562124 us; cnt=32511665
naive               : 28044028 us; cnt=32511665
Wegner/Kernigan     : 15280455 us; cnt=32511665
Anderson            : 63431368 us; cnt=32511665
HAKMEM 169/X11      :  4209093 us; cnt=32511665
&lt;/pre&gt;

No significant differences over the normal 32-bit code.  Nor did I see
any real differences if I compiled with the architecture-specific
flags:

&lt;pre class=&quot;code&quot;&gt;cc popcnt.c -O3 -march=nocona
&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;Domain applicability&lt;/h2&gt;
&lt;p&gt;

I expect people will come across this page when looking for popcount
implementations, see my numbers, and end up using the 16-bit lookup
table.  That might be the right solution but bear in mind domain
applicability.  I plan to compute popcount over megabytes.  Most
people, like the proverbial implementation in X11, work on only a few
words.

&lt;/p&gt;&lt;p&gt;

It takes time to bring the lookup table into memory.  On modern
machines it's something like tens of instructions.  If you're only
doing a few popcounts, or a lot of popcounts but not all the time,
then it's probably best to use bit-twiddling.  It's easier to
implement and for that case likely faster.

&lt;/p&gt;</description>
	<pubDate>Thu, 03 Jul 2008 12:00:00 +0000</pubDate>
</item>
<item>
	<title>Dalius Dobravolskas: EuroPython 2008 - June 6th</title>
	<guid isPermaLink="true">http://blog.sandbox.lt/en/EuroPython+2008+-+June+6th</guid>
	<link>http://blog.sandbox.lt/en/EuroPython+2008+-+June+6th</link>
	<description>&lt;div class=&quot;document&quot;&gt;
&lt;p&gt;This year EuroPython begins on June 7th... but June 6th is public holiday in Lithuania. That means if you will arrive at EuroPython on June 6th or earlier don't miss some public events.&lt;/p&gt;
&lt;p&gt;In 1253 on June 6th the first and the only Lithuanian king was crowned. What kind of event you should expect:&lt;/p&gt;
&lt;ul class=&quot;simple&quot;&gt;
&lt;li&gt;In S. Daukantas square Lithuanian state and historic flags will be hoisted. Lithuanian president will give the speech.&lt;/li&gt;
&lt;li&gt;Mass will be held in Vilnius Cathedral.&lt;/li&gt;
&lt;li&gt;The live archeology days will happen in Kernavė. That's not in Vilnius so you will need to get there somehow. &lt;a href=&quot;http://aphex.wordpress.com/2006/07/08/gyvosios-archeologijos-dienos-kernaveje-ilsetis-neimanoma/&quot; class=&quot;reference&quot;&gt;Here&lt;/a&gt; and &lt;a href=&quot;http://15min.blogas.lt/269933/gyvosios-archeologijos-dienos-kernaveje.html&quot; class=&quot;reference&quot;&gt;here&lt;/a&gt; you can find some photos from this event in the past.&lt;/li&gt;
&lt;li&gt;In Sereikiškių park international folkloric town &quot;Baltica-2008&quot; will be build. You could attend concerts here, watch handicraft and traditions demonstrations, taste national food.&lt;/li&gt;
&lt;li&gt;Castle festival masters and musicians town will be build in Museum of theater, music and cinema.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is map with these events locations + EuroPython location:&lt;/p&gt;
&lt;br /&gt;&lt;small&gt;&lt;a style=&quot;color: #0000FF; text-align: left;&quot; href=&quot;http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=en&amp;amp;msa=0&amp;amp;msid=100008304315880675937.0004511c399027fb04a67&amp;amp;ll=54.684847,25.292501&amp;amp;spn=0.021881,0.051327&amp;amp;iwloc=0004511c8bf9853680e3f&amp;amp;source=embed&quot;&gt;View Larger Map&lt;/a&gt;&lt;/small&gt;&lt;p&gt;Link to map: &lt;a href=&quot;http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=en&amp;amp;msa=0&amp;amp;msid=100008304315880675937.0004511c399027fb04a67&amp;amp;ll=54.740875,25.214996&amp;amp;spn=0.349611,0.821228&amp;amp;z=11&amp;amp;iwloc=0004511c8bf9853680e3f&quot; class=&quot;reference&quot;&gt;http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=en&amp;amp;msa=0&amp;amp;msid=100008304315880675937.0004511c399027fb04a67&amp;amp;ll=54.740875,25.214996&amp;amp;spn=0.349611,0.821228&amp;amp;z=11&amp;amp;iwloc=0004511c8bf9853680e3f&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I will update this entry when I will have more information.&lt;/p&gt;
&lt;/div&gt;</description>
	<pubDate>Thu, 03 Jul 2008 08:17:45 +0000</pubDate>
</item>
<item>
	<title>Dalius Dobravolskas: EuroPython 2008 - July 6th</title>
	<guid isPermaLink="true">http://blog.sandbox.lt/en/EuroPython+2008+-+July+6th</guid>
	<link>http://blog.sandbox.lt/en/EuroPython+2008+-+July+6th</link>
	<description>&lt;div class=&quot;document&quot;&gt;
&lt;p&gt;This year EuroPython begins on July 7th... but July 6th is public holiday in Lithuania. That means if you will arrive at EuroPython on July 6th or earlier don't miss some public events.&lt;/p&gt;
&lt;p&gt;In 1253 on July 6th the first and the only Lithuanian king was crowned. What kind of event you should expect:&lt;/p&gt;
&lt;ul class=&quot;simple&quot;&gt;
&lt;li&gt;In S. Daukantas square Lithuanian state and historic flags will be hoisted. Lithuanian president will give the speech.&lt;/li&gt;
&lt;li&gt;Mass will be held in Vilnius Cathedral.&lt;/li&gt;
&lt;li&gt;The live archeology days will happen in Kernavė. That's not in Vilnius so you will need to get there somehow. &lt;a href=&quot;http://aphex.wordpress.com/2006/07/08/gyvosios-archeologijos-dienos-kernaveje-ilsetis-neimanoma/&quot; class=&quot;reference&quot;&gt;Here&lt;/a&gt; and &lt;a href=&quot;http://15min.blogas.lt/269933/gyvosios-archeologijos-dienos-kernaveje.html&quot; class=&quot;reference&quot;&gt;here&lt;/a&gt; you can find some photos from this event in the past. &lt;strong&gt;This event happens from July 5th to July 7th&lt;/strong&gt;. I have even find the whole program: &lt;a href=&quot;http://www.eb.lt/en.php3?vid=67&amp;amp;id=3860&quot; class=&quot;reference&quot;&gt;http://www.eb.lt/en.php3?vid=67&amp;amp;id=3860&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;In Sereikiškių park international folkloric town &quot;Baltica-2008&quot; will be build. You could attend concerts here, watch handicraft and traditions demonstrations, taste national food.&lt;/li&gt;
&lt;li&gt;Castle festival masters and musicians town will be build in Museum of theater, music and cinema.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is map with these events locations + EuroPython location:&lt;/p&gt;
&lt;br /&gt;&lt;small&gt;&lt;a style=&quot;color: #0000FF; text-align: left;&quot; href=&quot;http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=en&amp;amp;msa=0&amp;amp;msid=100008304315880675937.0004511c399027fb04a67&amp;amp;ll=54.684847,25.292501&amp;amp;spn=0.021881,0.051327&amp;amp;iwloc=0004511c8bf9853680e3f&amp;amp;source=embed&quot;&gt;View Larger Map&lt;/a&gt;&lt;/small&gt;&lt;p&gt;Link to map: &lt;a href=&quot;http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=en&amp;amp;msa=0&amp;amp;msid=100008304315880675937.0004511c399027fb04a67&amp;amp;ll=54.740875,25.214996&amp;amp;spn=0.349611,0.821228&amp;amp;z=11&amp;amp;iwloc=0004511c8bf9853680e3f&quot; class=&quot;reference&quot;&gt;http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=en&amp;amp;msa=0&amp;amp;msid=100008304315880675937.0004511c399027fb04a67&amp;amp;ll=54.740875,25.214996&amp;amp;spn=0.349611,0.821228&amp;amp;z=11&amp;amp;iwloc=0004511c8bf9853680e3f&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I will update this entry when I will have more information.&lt;/p&gt;
&lt;/div&gt;</description>
	<pubDate>Thu, 03 Jul 2008 08:17:45 +0000</pubDate>
</item>
<item>
	<title>Sean McGrath: Economic necessity is the mother of software reuse</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-3776799.post-2449388540659419463</guid>
	<link>http://feeds.feedburner.com/~r/SeanMcGrath/~3/325598604/economic-necessity-is-mother-of.html</link>
	<description>Even recessions have up-sides : &lt;a href=&quot;http://www.itworld.com/offbeat/53396/economic-necessity-mother-software-reuse&quot;&gt;Economic necessity is the mother of software reuse&lt;/a&gt;</description>
	<pubDate>Thu, 03 Jul 2008 08:01:00 +0000</pubDate>
	<author>noreply@blogger.com (Sean)</author>
</item>
<item>
	<title>Corey Goldberg: Twitter API vs. Yahoo Web Services - Performance and Reliability</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-5236867476487043111.post-6111209553289899929</guid>
	<link>http://coreygoldberg.blogspot.com/2008/07/twitter-api-vs-yahoo-web-services.html</link>
	<description>I've noticed the &lt;a href=&quot;http://groups.google.com/group/twitter-development-talk/web/api-documentation&quot;&gt;Twitter API&lt;/a&gt; is very slow and unreliable.  Requests often take 10+ seconds to return.  Sometimes they timeout with no response at all.&lt;br /&gt;
&lt;br /&gt;
I put together some monitoring tools to see exactly how slow and unreliable the API really is (when it is even available!).  This is obviously not a very scientific test; just a ballpark idea of performance.  The monitoring tools are built with Python and RRDTool.  To start with, I used a modified version of my rrdpy suite of tools (&lt;a href=&quot;http://code.google.com/p/rrdpy&quot;&gt;http://code.google.com/p/rrdpy&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
I ran a test for 2 hours, hitting the API's Test Method every 30 seconds.  The tools generated the following time-series graph of server response times:&lt;br /&gt;


&lt;a href=&quot;http://bp2.blogger.com/_k7-jvtv2cLo/SGva1l__PNI/AAAAAAAAAPs/7wE_dBA1Ygs/s1600-h/api_compare_twitter.rrd.png&quot;&gt;&lt;img src=&quot;http://bp2.blogger.com/_k7-jvtv2cLo/SGva1l__PNI/AAAAAAAAAPs/7wE_dBA1Ygs/s400/api_compare_twitter.rrd.png&quot; style=&quot;cursor: pointer; cursor: hand;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5218505207507270866&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;


&lt;br /&gt;
The average response was 2.53 seconds, and we see a *lot* of variance in the data samples.&lt;br /&gt;

&lt;br /&gt;
&lt;br /&gt;

In comparison, here is the same test run against the Yahoo Search REST API:&lt;br /&gt;

&lt;a href=&quot;http://bp2.blogger.com/_k7-jvtv2cLo/SGvbGENBAAI/AAAAAAAAAP0/_EqKYMcrFMc/s1600-h/api_compare_yahoo.rrd.png&quot;&gt;&lt;img src=&quot;http://bp2.blogger.com/_k7-jvtv2cLo/SGvbGENBAAI/AAAAAAAAAP0/_EqKYMcrFMc/s400/api_compare_yahoo.rrd.png&quot; style=&quot;cursor: pointer; cursor: hand;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5218505490492882946&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;

&lt;br /&gt;
Notice the small variance and the average server response time of 0.186 secs!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I would be interested in running these tests again in a few months to see if Twitter's API has become faster and more reliable.</description>
	<pubDate>Wed, 02 Jul 2008 19:48:14 +0000</pubDate>
	<author>noreply@blogger.com (Corey Goldberg)</author>
</item>
<item>
	<title>Paulo Nuin: Bioinformatics career survey</title>
	<guid isPermaLink="false">http://python.genedrift.org/?p=115</guid>
	<link>http://feeds.feedburner.com/~r/BeginningPythonForBioinformatics/~3/325028350/</link>
	<description>&lt;p&gt;Via &lt;a href=&quot;http://www.bioinformaticszen.com/2008/07/creating-a-picture-of-different-careers-in-bioinformatics/&quot;&gt;Bioinformatics Zen&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Loading…
&lt;/p&gt;&lt;div style=&quot;margin-top: 10px; height: 15px;&quot; class=&quot;zemanta-pixie&quot;&gt;&lt;a href=&quot;http://reblog.zemanta.com/zemified/8a05f950-5a39-4319-807f-7e15b5f3745b/&quot; class=&quot;zemanta-pixie-a&quot; title=&quot;Zemified by Zemanta&quot;&gt;&lt;img src=&quot;http://img.zemanta.com/reblog_e.png?x-id=8a05f950-5a39-4319-807f-7e15b5f3745b&quot; alt=&quot;Zemanta Pixie&quot; style=&quot;border: medium none ; float: right;&quot; class=&quot;zemanta-pixie-img&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;http://feeds.feedburner.com/~a/BeginningPythonForBioinformatics?a=jdKCJ5&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~a/BeginningPythonForBioinformatics?i=jdKCJ5&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~f/BeginningPythonForBioinformatics?a=D6VWdJ&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/BeginningPythonForBioinformatics?i=D6VWdJ&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~f/BeginningPythonForBioinformatics?a=64uFEj&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/BeginningPythonForBioinformatics?i=64uFEj&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~f/BeginningPythonForBioinformatics?a=LpAXMJ&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/BeginningPythonForBioinformatics?i=LpAXMJ&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~f/BeginningPythonForBioinformatics?a=pcrBeJ&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~f/BeginningPythonForBioinformatics?i=pcrBeJ&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/BeginningPythonForBioinformatics/~4/325028350&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Wed, 02 Jul 2008 16:48:07 +0000</pubDate>
</item>
<item>
	<title>IronPython Url's: Programming Languages @ PDC 08</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-3604515438787408842.post-9013555232188632193</guid>
	<link>http://feeds.feedburner.com/~r/IronpythonUrls/~3/324382315/programming-languages-pdc-08.html</link>
	<description>Harry Pierson (IronPython PM for Microsoft) has posted some of the programming language sessions that will be part of the &lt;a href=&quot;http://microsoftpdc.com/&quot;&gt;PDC 08&lt;/a&gt; conference.&lt;br /&gt;&lt;br /&gt;Naturally this includes a session on dynamic languages.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Deep Dive: Dynamic Languages in .NET &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;The CLR has great support for dynamic languages like IronPython. Learn how the new Dynamic Language Runtime (DLR) adds a shared dynamic type system, a standard hosting model, and support for generating fast dynamic code. Hear how these features enable languages that use the DLR to share code with other dynamic and static languages like VB.NET and C#.&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://devhawk.net/2008/07/01/Programming+Languages+PDC08.aspx&quot;&gt;Programming Languages @ PDC 08&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;For programming language geeks it looks like there is a lot to looks forward to at PDC, with sessions on F#, the future directions of both C# and VB.NET (both of which will include support for better working with dynamic languages), and C++.
&lt;p&gt;&lt;a href=&quot;http://feeds.feedburner.com/~a/IronpythonUrls?a=JFVv0Q&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~a/IronpythonUrls?i=JFVv0Q&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/IronpythonUrls/~4/324382315&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Tue, 01 Jul 2008 22:13:10 +0000</pubDate>
	<author>noreply@blogger.com (Fuzzyman)</author>
</item>
<item>
	<title>IronPython Url's: Python Generation using the Code Dom</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-3604515438787408842.post-3311053946367328404</guid>
	<link>http://feeds.feedburner.com/~r/IronpythonUrls/~3/324382313/python-generation-using-code-dom.html</link>
	<description>IronPython 1 has a CodeDom provider. This means that IronPython Studio can use it to generate Python code from the Windows Forms and WPF designers, and even generate executable files from Python projects.&lt;br /&gt;&lt;br /&gt;This is one feature that hasn't yet made it into IronPython 2, but there are strange rumblings from the IronPython team that it may just make it.&lt;br /&gt;&lt;br /&gt;In the meantime, 'tech-michael' has a blog entry showing how to use IronPython CodeDom to generate Python code from metadata.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://tech-michael.blogspot.com/2008/06/python-generation-using-code-dom.html&quot;&gt;Python Generation using the Code Dom&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://feeds.feedburner.com/~a/IronpythonUrls?a=IDc7DA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~a/IronpythonUrls?i=IDc7DA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/IronpythonUrls/~4/324382313&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Tue, 01 Jul 2008 22:12:22 +0000</pubDate>
	<author>noreply@blogger.com (Fuzzyman)</author>
</item>
<item>
	<title>Base-Art: Hiring at Flumotion</title>
	<guid isPermaLink="true">http://base-art.net/Articles/103/</guid>
	<link>http://base-art.net/Articles/103/</link>
	<description>&lt;p&gt;So &lt;a href=&quot;http://www.flumotion.com&quot; class=&quot;reference&quot;&gt;Flumotion&lt;/a&gt;, sister company of Fluendo Embedded where I work, &lt;a href=&quot;http://www.flumotion.com/en/hiring/&quot; class=&quot;reference&quot;&gt;is
looking for Python hackers&lt;/a&gt;. &lt;a href=&quot;mailto:thomas@flumotion.com&quot; class=&quot;reference&quot;&gt;Thomas&lt;/a&gt; will be at EuroPython, so if you
are interested in the available positions, be sure to get in touch
with him!&lt;/p&gt;
&lt;p&gt;Working at Fluendo is quite nice, conditions are great, people are
nice and smart :) The office is growing quickly and Barcelona is at
its awesomeness level!&lt;/p&gt;
&lt;p&gt;So if you are familiar with Twisted, Python, GStreamer and dealing
with high-traffic streaming (peaks at 6Gb/s these days), be sure to
contact Thomas, don't be shy! If you are not familiar with these
technologies but if you learn fast, contact Thomas anyway :)&lt;/p&gt;</description>
	<pubDate>Tue, 01 Jul 2008 20:13:50 +0000</pubDate>
</item>
<item>
	<title>Sylvain Hellegouarch: CherryPy 3.1 has been released</title>
	<guid isPermaLink="false">http://www.defuze.org/archives/22-guid.html</guid>
	<link>http://www.defuze.org/archives/22-CherryPy-3.1-has-been-released.html</link>
	<description>Yesterday &lt;a href=&quot;http://aminus.org/blogs/index.php/fumanchu&quot;&gt;Robert Brewer&lt;/a&gt; &lt;a href=&quot;http://groups.google.com/group/cherrypy-users/msg/5f3db867a2ca20f0&quot;&gt;released&lt;/a&gt; version 3.1 of the CherryPy product and I think this calls for a hurray! For those who've been using 3.0 they'll be happy to know that the &lt;a href=&quot;http://www.cherrypy.org/wiki/UpgradeTo31&quot;&gt;upgrade&lt;/a&gt; will be rather smooth and straightforward. The main API changes have taken place on the engine thanks to the new &lt;a href=&quot;http://www.cherrypy.org/wiki/WebSiteProcessBus&quot;&gt;process bus&lt;/a&gt; but the rest of the API is pretty much identical. Overall the fantastic work Robert and many contributors have done was to fix remaining and new bugs making this release the most stable and high-performance of the CherryPy releases. &lt;a href=&quot;http://www.cherrypy.org/wiki/CherryPyDownload&quot;&gt;Get it&lt;/a&gt; while it's hot.</description>
	<pubDate>Tue, 01 Jul 2008 19:46:28 +0000</pubDate>
	<author>nospam@example.com (Sylvain Hellegouarch)</author>
</item>
<item>
	<title>zzze