<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Eli Bendersky's website</title>
	<atom:link href="http://eli.thegreenplace.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://eli.thegreenplace.net</link>
	<description>Eli Bendersky's personal website</description>
	<lastBuildDate>Wed, 10 Mar 2010 04:07:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>My favorite freeware programs for Windows</title>
		<link>http://eli.thegreenplace.net/2010/03/10/my-favorite-freeware-programs-for-windows/</link>
		<comments>http://eli.thegreenplace.net/2010/03/10/my-favorite-freeware-programs-for-windows/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 04:07:57 +0000</pubDate>
		<dc:creator>eliben</dc:creator>
				<category><![CDATA[Software & Tools]]></category>

		<guid isPermaLink="false">http://eli.thegreenplace.net/?p=2109</guid>
		<description><![CDATA[For a long time I wanted to sit and write down a list of all the great freeware programs I use or have used in the past on my Windows machine. So here it is.
The goal of this post is threefold:

People often ask me about the tools I use &#8211; this page will be the [...]


Related posts:<ol><li><a href='http://eli.thegreenplace.net/2007/08/08/windows-automation-with-autohotkey/' rel='bookmark' title='Permanent Link: Windows automation with AutoHotKey'>Windows automation with AutoHotKey</a> <small>AutoHotKey (called AHK by its fans) is a scripting language,...</small></li><li><a href='http://eli.thegreenplace.net/2009/07/31/listing-all-serial-ports-on-windows-with-python/' rel='bookmark' title='Permanent Link: Listing all serial ports on Windows with Python'>Listing all serial ports on Windows with Python</a> <small> There are several methods for getting a list of...</small></li><li><a href='http://eli.thegreenplace.net/2007/10/31/conveniently-tiling-windows-on-the-screen/' rel='bookmark' title='Permanent Link: Conveniently tiling windows on the screen'>Conveniently tiling windows on the screen</a> <small>As I wrote before, one of my purposes for buying...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>For a long time I wanted to sit and write down a list of all the great freeware programs I use or have used in the past on my Windows machine. So here it is.</p>
<p>The goal of this post is threefold:</p>
<ol class="arabic simple">
<li>People often ask me about the tools I use &#8211; this page will be the answer I can point them to.</li>
<li>To combat the effects of age on my memory &#8211; I don&#8217;t want to keep looking for hours &quot;for that cool program I love and don&#8217;t remember its name&quot; after the next reinstall.</li>
<li>As a way to say thanks to the creators of these programs &#8211; kudos to all the diligent programmers who create great tools and release them for free (as in beer, and most of all, as in speech), and also kudos to companies that provide versions of their programs for free.</li>
</ol>
<p>My main PC at home runs Windows XP Home edition (SP3). It also has MS Office 2007 and MS Visio 2007 installed &#8211; these are the only programs that I actually bought for this computer &#8211; the rest are free.</p>
<div class="section" id="the-list">
<h3>The list</h3>
<p>Here&#8217;s the whole list, sorted alphabetically by program name.</p>
<ul class="simple">
<li><a class="reference external" href="http://www.7-zip.org/">7-Zip</a> &#8211; for manipulating all kinds of archives</li>
<li><a class="reference external" href="http://audacity.sourceforge.net/">Audacity</a> &#8211; editing and recording audio files</li>
<li><a class="reference external" href="http://www.autohotkey.com/">AutoHotkey</a> &#8211; great for automating various aspects of Windows</li>
<li><a class="reference external" href="http://cdburnerxp.se/">CDBurnerXP</a> &#8211; burning CDs and DVDs</li>
<li><a class="reference external" href="http://cdexos.sourceforge.net/">CDex</a> &#8211; for easy ripping of your old music CDs into MP3</li>
<li><a class="reference external" href="http://com0com.sourceforge.net/">com0com</a> &#8211; virtual serial port driver. Useful for developing applications that communicate on the serial port</li>
<li><a class="reference external" href="http://www.nirsoft.net/utils/cports.html">CurrPorts</a> &#8211; monitoring TCP/IP network connections</li>
<li><a class="reference external" href="http://www.nirsoft.net/utils/dll_export_viewer.html">DLL Export Viewer</a> &#8211; view a list of exported functions in a Windows DLL</li>
<li><a class="reference external" href="http://filezilla-project.org/">Filezilla</a> &#8211; FTP client and server</li>
<li><a class="reference external" href="http://www.mozilla.com/en-US/firefox/firefox.html">Firefox</a> &#8211; is my main browser for about 5 years (since one of its first versions). I use other browsers for testing and web development (Chrome, Safari), but Firefox is still the main workhorse of my internet experience. Some of its plugins, like <a class="reference external" href="http://www.nirsoft.net/utils/dll_export_viewer.html">Firebug</a>, are useful applications in their own right</li>
<li><a class="reference external" href="http://frhed.sourceforge.net/">Frhed</a> &#8211; hex editor</li>
<li><a class="reference external" href="http://www.inkscape.org/">Inkscape</a> &#8211; for drawing. I wish I had the artistic talents necessary to use it really well</li>
<li><a class="reference external" href="http://www.irfanview.com/">Irfanview</a> &#8211; photo &amp; image viewer</li>
<li><a class="reference external" href="http://keepass.info/">Keepass</a> &#8211; for storing all your passwords securely in a single place</li>
<li><a class="reference external" href="http://launchy.net/">Launchy</a> &#8211; once I&#8217;ve found it, I can&#8217;t live without it. An amazing productivity tool</li>
<li><a class="reference external" href="http://www.mingw.org">MinGW</a> &#8211; a native Windows port of GCC and related tools</li>
<li><a class="reference external" href="http://www.utorrent.com/">µTorrent</a> &#8211; a sweet little torrent client. I&#8217;m amazed by the amount of functionality packed into a single tiny executable</li>
<li><a class="reference external" href="http://www.getpaint.net/">Paint.NET</a> &#8211; a replacement of mspaint, capable of much more. I use it mainly for screenshot and image manipulation (cropping, resizing, stitching a few together, etc.)</li>
<li><a class="reference external" href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx">Processexplorer</a> &#8211; a powerful tool for examining what the various processes on your Windows box are up to</li>
<li><a class="reference external" href="http://www.chiark.greenend.org.uk/~sgtatham/putty/">Putty</a> &#8211; Telnet/SSH client (with its auxiliary tools like Pageant)</li>
<li><a class="reference external" href="http://www.python.org/">Python</a> &#8211; quite obvious for the readers of my blog, but I just had to put it here. I use the <a class="reference external" href="http://www.activestate.com/activepython/">ActivePython</a> implementation of CPython</li>
<li><a class="reference external" href="http://www.rapidee.com/en/about">RapidEE</a> &#8211; the ultimate viewer &amp; editor for environment variables</li>
<li><a class="reference external" href="http://www.realvnc.com/">RealVNC</a> &#8211; a VNC client I use to remotely control my Asus EEE Linux laptop</li>
<li><a class="reference external" href="http://www.nirsoft.net/utils/regscanner.html">Regscanner</a> &#8211; great for finding stuff in the Windows registry quickly</li>
<li><a class="reference external" href="http://www.scintilla.org/SciTE.html">Scite</a> &#8211; a great text editor suitable for programming. It&#8217;s my main editor for 90% of my development needs both at home and at work, heavily scripted and extended with Lua and Python scripts</li>
<li><a class="reference external" href="http://www.nirsoft.net/utils/shexview.html">Shexview</a> &#8211; Windows shell extensions management</li>
<li><a class="reference external" href="http://www.gtopala.com/">SIW</a> &#8211; System Information for Windows</li>
<li><a class="reference external" href="http://code.google.com/p/spyderlib/">Spyder</a> &#8211; comes as a Python library, but I use it as a stand-alone application so it&#8217;s in this list. This is a great Python shell &#8211; I use it as a general-purpose calculator and for simple computations that don&#8217;t deserve a script of their own</li>
<li><a class="reference external" href="http://www.sqlite.org/">SQLite</a> &#8211; apart from its various programming language bindings, I also use the SQLite command-line tools to help me with development needs (debugging, updating and creating test DBs, etc.)</li>
<li><a class="reference external" href="http://www.mlin.net/StartupCPL.shtml">Startup Control Panel</a> &#8211; a lightweight tool for managing the processes that are run on start-up</li>
<li><a class="reference external" href="http://www.tucows.com/preview/213160">Sygate Personal Firewall</a> &#8211; I still use version 5.5 and it works great for my firewalling needs</li>
<li><a class="reference external" href="http://tortoisesvn.tigris.org/">TortoiseSVN</a> &#8211; Subversion client embedded into Windows Explorer</li>
<li><a class="reference external" href="http://www.jam-software.com/freeware/index.shtml">Treesize</a> &#8211; very useful for finding out the sizes of various folders and files on your PC in a simple way</li>
<li><a class="reference external" href="http://www.truecrypt.org/">Truecrypt</a> &#8211; a complete solution for encrypting anything from simple files to whole hidden hard-drive partitions</li>
<li><a class="reference external" href="http://www.virtualbox.org/">VirtualBox</a> &#8211; great free alternative to VMWare. I use it to run an Ubuntu Linux image on top of my Windows PC &#8211; works like a charm</li>
<li><a class="reference external" href="http://magnifier.sourceforge.net/">Virtual Magnifying Glass</a> &#8211; for easy zooming of areas on the screen &#8211; very useful for any graphic work like GUI development</li>
<li><a class="reference external" href="http://www.microsoft.com/exPress/">Visual Studio Express</a> &#8211; nice of Microsoft to release a very functional version of their excellent Visual Studio IDE for free. Indispensable for serious C/C++ development for Windows</li>
<li><a class="reference external" href="http://www.videolan.org/vlc/">VLC</a> &#8211; I just can&#8217;t believe people are still using the Windows media player with its codec hell. Once I installed VLC (years ago) I forgot about codecs and about any other problems with playing videos</li>
<li><a class="reference external" href="http://www.winamp.com/">Winamp</a> &#8211; still using version 5.04 to listen to MP3s, seeing no reason to upgrade to anything else</li>
<li><a class="reference external" href="http://winmerge.org/">Winmerge</a> &#8211; graphical diff and merge tool</li>
<li><a class="reference external" href="http://www.wireshark.org/">Wireshark</a> &#8211; network protocol analyzer</li>
</ul>
</div>
<img src="http://eli.thegreenplace.net/?ak_action=api_record_view&id=2109&type=feed" alt="" />

<p>Related posts:<ol><li><a href='http://eli.thegreenplace.net/2007/08/08/windows-automation-with-autohotkey/' rel='bookmark' title='Permanent Link: Windows automation with AutoHotKey'>Windows automation with AutoHotKey</a> <small>AutoHotKey (called AHK by its fans) is a scripting language,...</small></li><li><a href='http://eli.thegreenplace.net/2009/07/31/listing-all-serial-ports-on-windows-with-python/' rel='bookmark' title='Permanent Link: Listing all serial ports on Windows with Python'>Listing all serial ports on Windows with Python</a> <small> There are several methods for getting a list of...</small></li><li><a href='http://eli.thegreenplace.net/2007/10/31/conveniently-tiling-windows-on-the-screen/' rel='bookmark' title='Permanent Link: Conveniently tiling windows on the screen'>Conveniently tiling windows on the screen</a> <small>As I wrote before, one of my purposes for buying...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://eli.thegreenplace.net/2010/03/10/my-favorite-freeware-programs-for-windows/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The server-side Javascript meme</title>
		<link>http://eli.thegreenplace.net/2010/03/06/the-server-side-javascript-meme/</link>
		<comments>http://eli.thegreenplace.net/2010/03/06/the-server-side-javascript-meme/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 15:29:58 +0000</pubDate>
		<dc:creator>eliben</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://eli.thegreenplace.net/?p=2106</guid>
		<description><![CDATA[In the past few months a new meme seems to be very vibrant in the world of web-development: server-side Javascript. The idea certainly isn&#8217;t new &#8211; Netscape had offered JS on the server-side sometime in the 1990s. Since then, powerful dynamic languages like PHP, Python and Ruby along with Java and ASP have taken over [...]


Related posts:<ol><li><a href='http://eli.thegreenplace.net/2010/02/24/a-simple-canvas-based-javascript-game-with-a-django-back-end/' rel='bookmark' title='Permanent Link: A simple canvas-based Javascript game, with a Django back-end'>A simple canvas-based Javascript game, with a Django back-end</a> <small>A few years ago I&#8217;ve released a clone of the...</small></li><li><a href='http://eli.thegreenplace.net/2008/10/11/should-i-learn-javascript/' rel='bookmark' title='Permanent Link: Should I learn Javascript ?'>Should I learn Javascript ?</a> <small>It&#8217;s some time now that I&#8217;m wondering whether I should...</small></li><li><a href='http://eli.thegreenplace.net/2010/02/13/finding-out-the-mouse-click-position-on-a-canvas-with-javascript/' rel='bookmark' title='Permanent Link: Finding out the mouse click position on a canvas with Javascript'>Finding out the mouse click position on a canvas with Javascript</a> <small>I&#8217;m playing around with the HTML5 &lt;canvas&gt; element. One interesting...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>In the past few months a new meme seems to be very vibrant in the world of web-development: server-side Javascript. The idea certainly isn&#8217;t new &#8211; Netscape had offered JS on the server-side sometime in the 1990s. Since then, powerful dynamic languages like PHP, Python and Ruby along with Java and ASP have taken over the server-side development scene. So what has happened recently to stir the balance?</p>
<p>It&#8217;s hard to tell, I can only guess:</p>
<ul class="simple">
<li>Javascript is growing in popularity as more and more powerful applications get written in it to run in the browser. This increases the amount of programmers interested in it, as well as the total amount of Javascript code out there in the wild.</li>
<li>A zoo of new and powerful implementations has appeared recently. A real arms race between Google&#8217;s V8, Mozilla&#8217;s TraceMonkey and WebKit&#8217;s Squirrelfish boosted the performance of Javascript engines considerably in the past couple of years.</li>
</ul>
<p>The first reason, in particular, is very important. These days a web-developer has to constantly switch between two programming languages &#8211; Javascript for the client, and his server-side language of choice for the server. Many people started feeling that this is a useless split of attention, and using a single language both for the client and the server is a good idea <a class="footnote-reference" href="#id4" id="id1">[1]</a>.</p>
<div class="section" id="why-it-s-bad">
<h3>Why it&#8217;s bad</h3>
<p>First of all, further fragmentation of the server-side development community. Aren&#8217;t there enough ways to write web-applications as it stands? Multiple languages to choose from, multiple frameworks to use once you&#8217;ve chosen a language. Do we need another language &amp; platform for server-side development? What&#8217;s so bad with having two tools, each suitable for its domain?</p>
<p>The other reason I see is more controversial. Javascript is far from being an ideal language. While it has a good core in it <a class="footnote-reference" href="#id5" id="id2">[2]</a>, there are also a lot of quirks and design faults. Oh, and there&#8217;s a ton of horrible code out there that just gets copy-pasted from project to project. I&#8217;ll stop here since I don&#8217;t want to turn this post into a language flame-war, but I&#8217;ll do say that I&#8217;d prefer coding in Python or Ruby over Javascript, and thus it&#8217;s disturbing that Javascript starting to take a share of the server-side cake.</p>
</div>
<div class="section" id="why-it-s-good">
<h3>Why it&#8217;s good</h3>
<p>Just as the rise in popularity of JS in the browser brought us faster engines that make the internet experience more pleasant, I think that examining new approaches is generally healthy. There&#8217;s a lot of excitement around this issue lately &#8211; excitement that brings talented developers in, places them in <em>the zone</em> for productive hacking, and overall provides a fresh perspective on things.</p>
<p>For example, one of the most exciting tools in this scene is <a class="reference external" href="http://nodejs.org/">Node.js</a>. It&#8217;s a Javascript interpreter built on top of V8 <a class="footnote-reference" href="#id6" id="id3">[3]</a>. What&#8217;s really cool about Node.js is that it&#8217;s completely event-based, designed and tuned for asynchronous non-blocking I/O. Asynchronous non-blocking I/O seems to be all the rage recently, as it was found to be greatly enhancing the performance of servers, allowing to handle huge loads of concurrent connections within a single process, without using threads.</p>
<p>This approach isn&#8217;t new. <a class="reference external" href="http://twistedmatrix.com/trac/">Twisted</a> is a venerable and powerful event I/O library for Python, for example. However, when you code with Twisted you have to be careful to use only very specific Python modules &#8211; use one that is blocking and you&#8217;ve ruined the whole model. Node.js, on the other hand, comes with its own standard library that was designed from the ground-up to be 100% non-blocking.</p>
<p>It&#8217;s only fair to note that in this area of event-based programming, Javascript actually has an advantage. The language&#8217;s simple built-in way of creating anonymous functions is very helpful in this aspect. As a matter of fact, everyone who&#8217;s written AJAX code and has used a library like jQuery (which these days covers a high percentage of serious JS developers), is already used to the event model of programming. AJAX is all about asynchronous events for which you register an anonymous callback function to handle the result when it arrives.</p>
<p>Node.js isn&#8217;t the only general-purpose implementation of Javascript suitable for server-side development. Mozilla&#8217;s Java-based <a class="reference external" href="http://en.wikipedia.org/wiki/Rhino_%28JavaScript_engine%29">Rhino</a> is an alternative, and there are <a class="reference external" href="http://en.wikipedia.org/wiki/List_of_JavaScript_engines">many others</a>. As expected, we can see a lot of fragmentation between the communities since Javascript doesn&#8217;t even have a commonly accepted standard library. Recent projects like <a class="reference external" href="http://commonjs.org/">CommonJS</a> come to fix this situation, however.</p>
<p>On yet another hand, making one process run as fast as possible is a lofty goal, but what about true parallel programming? Event loops such as the ones offered by Node.js don&#8217;t scale to multi-CPU machines, so I wonder how this situation will be handled. My bet would be on relatively independent processes communicating via message-passing and talking to mutual data stores via TCP.</p>
</div>
<div class="section" id="conclusion">
<h3>Conclusion</h3>
<p>These are exciting times. The vibrancy reminds me of the Rails hype of a few years ago. As I&#8217;ve mentioned, from my point of view this situation has its pros and cons, but the pros outweigh the cons. Being locked in narrow directions hasn&#8217;t been historically fruitful. Mutual enrichment between communities and arms races are a much more viable way to progress.</p>
<p>It will be interesting to see where we&#8217;ll be a year from now &#8211; I wager that many things are yet to change. In any case, if you&#8217;re looking for a spot in an exciting niche of programming where you can make a difference, it seems that server-side Javascript, especially with event-based models like Node.js, fits the bill.</p>
<div align="center" class="align-center"><img alt="http://eli.thegreenplace.net/wp-content/uploads/hline.jpg" class="align-center" src="http://eli.thegreenplace.net/wp-content/uploads/hline.jpg" style="width: 320px; height: 5px;" /></div>
<table class="docutils footnote" frame="void" id="id4" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id1">[1]</a></td>
<td>As always happens, the solutions come from several sides. Technologies like <a class="reference external" href="http://en.wikipedia.org/wiki/Microsoft_Silverlight">Silverlight</a> allow running C# and Python in the client, while cool projects like <a class="reference external" href="http://pyjs.org/">Pyjamas</a> compile Python to Javascript allowing to write client-side code in Python and running it natively in the browser.</td>
</tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id5" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id2">[2]</a></td>
<td>If you restrain yourself to the subset described in the <em>&quot;Javascript, the Good Parts&quot;</em> book. A review is due, I know&#8230;</td>
</tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id6" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id3">[3]</a></td>
<td>Which, by the way, was specifically designed by Google to serve as an embeddable engine.</td>
</tr>
</tbody>
</table>
</div>
<img src="http://eli.thegreenplace.net/?ak_action=api_record_view&id=2106&type=feed" alt="" />

<p>Related posts:<ol><li><a href='http://eli.thegreenplace.net/2010/02/24/a-simple-canvas-based-javascript-game-with-a-django-back-end/' rel='bookmark' title='Permanent Link: A simple canvas-based Javascript game, with a Django back-end'>A simple canvas-based Javascript game, with a Django back-end</a> <small>A few years ago I&#8217;ve released a clone of the...</small></li><li><a href='http://eli.thegreenplace.net/2008/10/11/should-i-learn-javascript/' rel='bookmark' title='Permanent Link: Should I learn Javascript ?'>Should I learn Javascript ?</a> <small>It&#8217;s some time now that I&#8217;m wondering whether I should...</small></li><li><a href='http://eli.thegreenplace.net/2010/02/13/finding-out-the-mouse-click-position-on-a-canvas-with-javascript/' rel='bookmark' title='Permanent Link: Finding out the mouse click position on a canvas with Javascript'>Finding out the mouse click position on a canvas with Javascript</a> <small>I&#8217;m playing around with the HTML5 &lt;canvas&gt; element. One interesting...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://eli.thegreenplace.net/2010/03/06/the-server-side-javascript-meme/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Zipped dump of a SQLite database with Python</title>
		<link>http://eli.thegreenplace.net/2010/03/05/zipped-dump-of-a-sqlite-database-with-python/</link>
		<comments>http://eli.thegreenplace.net/2010/03/05/zipped-dump-of-a-sqlite-database-with-python/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 10:59:18 +0000</pubDate>
		<dc:creator>eliben</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://eli.thegreenplace.net/?p=2102</guid>
		<description><![CDATA[Suppose you manage some data in a SQLite DB within a Python application. How can you dump the DB into a SQL dump file? Better yet, how can you directly create a zipped dump file (dumps tend to be big, and since they&#8217;re SQL code, can be compressed very nicely).
Here&#8217;s the code:

import sqlite3, sys, zipfile

dbname [...]


Related posts:<ol><li><a href='http://eli.thegreenplace.net/2009/05/29/storing-blobs-in-a-sqlite-db-with-pythonpysqlite/' rel='bookmark' title='Permanent Link: Storing BLOBs in a SQLite DB with Python/pysqlite'>Storing BLOBs in a SQLite DB with Python/pysqlite</a> <small>I must be looking in all the wrong places, but...</small></li><li><a href='http://eli.thegreenplace.net/2009/09/23/compiling-sqlite-on-windows/' rel='bookmark' title='Permanent Link: Compiling SQLite on Windows'>Compiling SQLite on Windows</a> <small>Here&#8217;s a short guide to compiling SQLite on Windows using...</small></li><li><a href='http://eli.thegreenplace.net/2008/10/14/database-n00b/' rel='bookmark' title='Permanent Link: Database n00b'>Database n00b</a> <small>When it comes to databases, I&#8217;m a complete n00b. It&#8217;s...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Suppose you manage some data in a SQLite DB within a Python application. How can you dump the DB into a SQL dump file? Better yet, how can you directly create a zipped dump file (dumps tend to be big, and since they&#8217;re SQL code, can be compressed very nicely).</p>
<p>Here&#8217;s the code:</p>
<div class="highlight">
<pre><span style="color: #00007f; font-weight: bold">import</span> <span style="color: #00007f">sqlite3</span>, <span style="color: #00007f">sys</span>, <span style="color: #00007f">zipfile</span>

dbname = sys.argv[<span style="color: #007f7f">1</span>] <span style="color: #00007f; font-weight: bold">if</span> <span style="color: #00007f">len</span>(sys.argv) &gt; <span style="color: #007f7f">1</span> <span style="color: #00007f; font-weight: bold">else</span> <span style="color: #7f007f">&#39;testdb.db&#39;</span>

<span style="color: #007f00"># Open the db and dump all its data into the &#39;data&#39; buffer</span>
con = sqlite3.connect(dbname)
data = <span style="color: #7f007f">&#39;\n&#39;</span>.join(con.iterdump())
con.close()

<span style="color: #007f00"># Create a zip file and write add the dump into it as</span>
<span style="color: #007f00"># a new file</span>
zf = zipfile.ZipFile(<span style="color: #7f007f">&#39;dump.zip&#39;</span>,
                     mode=<span style="color: #7f007f">&#39;w&#39;</span>,
                     compression=zipfile.ZIP_DEFLATED)
zf.writestr(<span style="color: #7f007f">&#39;dump.sql&#39;</span>, data)
zf.close()
</pre>
</div>
<p>It will work with Python 2.6 and later, since the <tt class="docutils literal"><span class="pre">iterdump</span></tt> method of <cite>sqlite3</cite> is only available since that version.</p>
<p>Note that the <tt class="docutils literal"><span class="pre">.zip</span></tt> file is created on the fly from a buffer, without a real <tt class="docutils literal"><span class="pre">dump.sql</span></tt> file being created on the disk.</p>
<img src="http://eli.thegreenplace.net/?ak_action=api_record_view&id=2102&type=feed" alt="" />

<p>Related posts:<ol><li><a href='http://eli.thegreenplace.net/2009/05/29/storing-blobs-in-a-sqlite-db-with-pythonpysqlite/' rel='bookmark' title='Permanent Link: Storing BLOBs in a SQLite DB with Python/pysqlite'>Storing BLOBs in a SQLite DB with Python/pysqlite</a> <small>I must be looking in all the wrong places, but...</small></li><li><a href='http://eli.thegreenplace.net/2009/09/23/compiling-sqlite-on-windows/' rel='bookmark' title='Permanent Link: Compiling SQLite on Windows'>Compiling SQLite on Windows</a> <small>Here&#8217;s a short guide to compiling SQLite on Windows using...</small></li><li><a href='http://eli.thegreenplace.net/2008/10/14/database-n00b/' rel='bookmark' title='Permanent Link: Database n00b'>Database n00b</a> <small>When it comes to databases, I&#8217;m a complete n00b. It&#8217;s...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://eli.thegreenplace.net/2010/03/05/zipped-dump-of-a-sqlite-database-with-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Book review: &#8220;Nonzero: The Logic of Human Destiny&#8221; by Robert Wright</title>
		<link>http://eli.thegreenplace.net/2010/03/04/book-review-nonzero-the-logic-of-human-destiny-by-robert-wright/</link>
		<comments>http://eli.thegreenplace.net/2010/03/04/book-review-nonzero-the-logic-of-human-destiny-by-robert-wright/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 18:27:57 +0000</pubDate>
		<dc:creator>eliben</dc:creator>
				<category><![CDATA[Book reviews]]></category>

		<guid isPermaLink="false">http://eli.thegreenplace.net/?p=2095</guid>
		<description><![CDATA[Robert Wright is the author of &#8220;The Moral Animal&#8221;, which is a great book on the topic of evolutionary psychology I&#8217;ve very much enjoyed to read a few years ago. As a result, I had quite high expectations from &#8220;Nonzero&#8221;. It&#8217;s probably because of these expectations that I was disappointed by the book. It&#8217;s not [...]


Related posts:<ol><li><a href='http://eli.thegreenplace.net/2005/04/09/book-review-the-moral-animal-by-robert-wright/' rel='bookmark' title='Permanent Link: Book review: &#8220;The Moral Animal&#8221; by Robert Wright'>Book review: &#8220;The Moral Animal&#8221; by Robert Wright</a> <small>In this book the author tries to explain the new...</small></li><li><a href='http://eli.thegreenplace.net/2006/01/11/book-review-guns-germs-and-steel-by-jared-diamond/' rel='bookmark' title='Permanent Link: Book review: &#8220;Guns, germs and steel&#8221; by Jared Diamond'>Book review: &#8220;Guns, germs and steel&#8221; by Jared Diamond</a> <small>&#8220;Guns germs and steel&#8221; (GGS in short) is a widely...</small></li><li><a href='http://eli.thegreenplace.net/2005/07/15/book-review-shadows-of-forgotten-ancestors-by-carl-sagan/' rel='bookmark' title='Permanent Link: Book review: &#8220;Shadows of forgotten ancestors&#8221; by Carl Sagan'>Book review: &#8220;Shadows of forgotten ancestors&#8221; by Carl Sagan</a> <small>(co-authored by Carl Sagan and Ann Druyan) &#8220;If it ain&#8217;t...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Robert Wright is the author of &#8220;The Moral Animal&#8221;, which is a great book on the topic of evolutionary psychology I&#8217;ve very much <a href="http://eli.thegreenplace.net/2005/04/09/book-review-the-moral-animal-by-robert-wright/">enjoyed to read</a> a few years ago. As a result, I had quite high expectations from &#8220;Nonzero&#8221;. It&#8217;s probably because of these expectations that I was disappointed by the book. It&#8217;s not a bad book, but it just isn&#8217;t what I expected.</p>
<p>As far as I understand, what Wright tries to do is to lay out a unified theory linking cultural and biological evolution together, using game theory. Nonzero is his buzzword for non-zero games &#8220;played&#8221; by biological and cultural entities (such as the commonly (ab)used Prisoner&#8217;s Dilemma). The first part of the book deals with cultural evolution, examining historical societies on various stages of development (from hunter gatherers to modern times). The author demonstrates how non-zero-sum-game thinking can explain the behavior of these societies, both internal and external.</p>
<p>Next, the book tackles biological evolution. Here again, Wright uses the nonzero theory to explain how organisms interact, and even how genes inside organisms can interact.</p>
<p>I guess I&#8217;ve found this book disappointing because there was nothing new in it. The first (historical) part is much better covered by other authors, like Jared Diamond. There&#8217;s nothing particularly innovative in the application of game theory to understand the dynamics of societies throughout history. The second (biological) part is just a much smaller-scale (and worse, IMHO) retelling of some chapters from &#8220;The Moral Animal&#8221;.</p>
<p>So if you&#8217;ve never read any book on such topics before, &#8220;Nonzero&#8221; can be a good choice &#8211; it&#8217;s written quite well and has enough information to make you think. But if you&#8217;ve read other books on the subject, or plan to do a wider reading overall, I think it&#8217;s safe to stay away. Read &#8220;Guns, Germs and Steel&#8221; and &#8220;The Moral Animal&#8221; instead &#8211; it will take thrice as long, but the gain of information and insight is going to be at least tenfold.</p>
<img src="http://eli.thegreenplace.net/?ak_action=api_record_view&id=2095&type=feed" alt="" />

<p>Related posts:<ol><li><a href='http://eli.thegreenplace.net/2005/04/09/book-review-the-moral-animal-by-robert-wright/' rel='bookmark' title='Permanent Link: Book review: &#8220;The Moral Animal&#8221; by Robert Wright'>Book review: &#8220;The Moral Animal&#8221; by Robert Wright</a> <small>In this book the author tries to explain the new...</small></li><li><a href='http://eli.thegreenplace.net/2006/01/11/book-review-guns-germs-and-steel-by-jared-diamond/' rel='bookmark' title='Permanent Link: Book review: &#8220;Guns, germs and steel&#8221; by Jared Diamond'>Book review: &#8220;Guns, germs and steel&#8221; by Jared Diamond</a> <small>&#8220;Guns germs and steel&#8221; (GGS in short) is a widely...</small></li><li><a href='http://eli.thegreenplace.net/2005/07/15/book-review-shadows-of-forgotten-ancestors-by-carl-sagan/' rel='bookmark' title='Permanent Link: Book review: &#8220;Shadows of forgotten ancestors&#8221; by Carl Sagan'>Book review: &#8220;Shadows of forgotten ancestors&#8221; by Carl Sagan</a> <small>(co-authored by Carl Sagan and Ann Druyan) &#8220;If it ain&#8217;t...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://eli.thegreenplace.net/2010/03/04/book-review-nonzero-the-logic-of-human-destiny-by-robert-wright/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A simple canvas-based Javascript game, with a Django back-end</title>
		<link>http://eli.thegreenplace.net/2010/02/24/a-simple-canvas-based-javascript-game-with-a-django-back-end/</link>
		<comments>http://eli.thegreenplace.net/2010/02/24/a-simple-canvas-based-javascript-game-with-a-django-back-end/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 17:17:37 +0000</pubDate>
		<dc:creator>eliben</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://eli.thegreenplace.net/?p=2090</guid>
		<description><![CDATA[A few years ago I&#8217;ve released a clone of the &#34;Colorful lines&#34; game (called GLines on Gnome), named Perlines. It still works quite well and is available from the Programs and code section of the website.
In the past couple of weeks I&#8217;ve implemented a web-based version the game, using Javascript and the HTML5 canvas element [...]


Related posts:<ol><li><a href='http://eli.thegreenplace.net/2010/02/13/finding-out-the-mouse-click-position-on-a-canvas-with-javascript/' rel='bookmark' title='Permanent Link: Finding out the mouse click position on a canvas with Javascript'>Finding out the mouse click position on a canvas with Javascript</a> <small>I&#8217;m playing around with the HTML5 &lt;canvas&gt; element. One interesting...</small></li><li><a href='http://eli.thegreenplace.net/2010/03/06/the-server-side-javascript-meme/' rel='bookmark' title='Permanent Link: The server-side Javascript meme'>The server-side Javascript meme</a> <small>In the past few months a new meme seems to...</small></li><li><a href='http://eli.thegreenplace.net/2009/10/11/porting-from-turbogears-to-django-a-personal-experience/' rel='bookmark' title='Permanent Link: Porting from Turbogears to Django &#8211; a personal experience'>Porting from Turbogears to Django &#8211; a personal experience</a> <small> Introduction About a year ago, I taught myself Turbogears...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>A <a class="reference external" href="http://eli.thegreenplace.net/2003/05/30/perlines/">few years ago</a> I&#8217;ve released a clone of the &quot;Colorful lines&quot; game (called <em>GLines</em> on Gnome), named Perlines. It still works quite well and is available from the <a class="reference external" href="http://eli.thegreenplace.net/programs-and-code/">Programs and code</a> section of the website.</p>
<p>In the past couple of weeks I&#8217;ve implemented a web-based version the game, using Javascript and the HTML5 canvas element for the game itself, and a Django back-end server for storing high-scores in a centralized manner.</p>
<p>Here&#8217;s a screenshot:</p>
<p><img alt="http://eli.thegreenplace.net/wp-content/uploads/2010/02/linesshot.png" src="http://eli.thegreenplace.net/wp-content/uploads/2010/02/linesshot.png" /></p>
<p>And the game itself is <a class="reference external" href="http://apps.thegreenplace.net/colorful_lines/">available for playing here</a>. Note that due to its use of the canvas element, it doesn&#8217;t support Internet Explorer. I tested it in Firefox, Safari and Chrome.</p>
<p>Some observations on the development of the game:</p>
<ul class="simple">
<li>It&#8217;s really the first time I&#8217;ve written a large amount of Javascript code. It was an interesting experience about which I have mixed feelings &#8211; so I think it deserves a separate post.</li>
<li>The HTML5 canvas element is really nice and works just like any other canvas / graphical device context in a GUI framework. It has nice performance and an intuitive API.</li>
<li>It&#8217;s also the first time I&#8217;ve actually done any serious AJAX. It turned out to be pretty straightforward on the client, with the generous help of jQuery. On the server side it&#8217;s even simpler.</li>
<li>I was surprised how easy it is to craft a simple DB-backed server for storing the high-scores using Django. It was probably the most effortless part of the project &#8211; Django really does make server development in Python ridiculously simple.</li>
</ul>
<p>I will play with it myself for a few more days and then release all its source code to the public domain. Naturally, the client-side code is accessible even now by viewing the source of the page in your browser.</p>
<p>P.S. There seems to be at least <a class="reference external" href="http://www.mclean.net.nz/jslines/index.html">one other</a> Javascript clone of the lines game online, but it doesn&#8217;t use <tt class="docutils literal"><span class="pre">canvas</span></tt> and doesn&#8217;t have a global high-scores table.</p>
<img src="http://eli.thegreenplace.net/?ak_action=api_record_view&id=2090&type=feed" alt="" />

<p>Related posts:<ol><li><a href='http://eli.thegreenplace.net/2010/02/13/finding-out-the-mouse-click-position-on-a-canvas-with-javascript/' rel='bookmark' title='Permanent Link: Finding out the mouse click position on a canvas with Javascript'>Finding out the mouse click position on a canvas with Javascript</a> <small>I&#8217;m playing around with the HTML5 &lt;canvas&gt; element. One interesting...</small></li><li><a href='http://eli.thegreenplace.net/2010/03/06/the-server-side-javascript-meme/' rel='bookmark' title='Permanent Link: The server-side Javascript meme'>The server-side Javascript meme</a> <small>In the past few months a new meme seems to...</small></li><li><a href='http://eli.thegreenplace.net/2009/10/11/porting-from-turbogears-to-django-a-personal-experience/' rel='bookmark' title='Permanent Link: Porting from Turbogears to Django &#8211; a personal experience'>Porting from Turbogears to Django &#8211; a personal experience</a> <small> Introduction About a year ago, I taught myself Turbogears...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://eli.thegreenplace.net/2010/02/24/a-simple-canvas-based-javascript-game-with-a-django-back-end/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Book review: &#8220;Shogun&#8221; by James Clavell</title>
		<link>http://eli.thegreenplace.net/2010/02/20/book-review-shogun-by-james-clavell/</link>
		<comments>http://eli.thegreenplace.net/2010/02/20/book-review-shogun-by-james-clavell/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 12:30:23 +0000</pubDate>
		<dc:creator>eliben</dc:creator>
				<category><![CDATA[Book reviews]]></category>

		<guid isPermaLink="false">http://eli.thegreenplace.net/?p=2086</guid>
		<description><![CDATA[A short and informal review for this one.
Nice book, very well written. Lots of fun to read &#8211; the plot is gripping, the characters are well developed, and the historical background is fascinating. Japanese customs are very unusual, very interesting, very inspiring. Though they don&#8217;t always make sense, the author did a great job promoting [...]


Related posts:<ol><li><a href='http://eli.thegreenplace.net/2003/10/23/book-review-finite-and-infinite-games-by-james-carse/' rel='bookmark' title='Permanent Link: Book review: &#8220;Finite and infinite games&#8221; by James Carse'>Book review: &#8220;Finite and infinite games&#8221; by James Carse</a> <small>This book&#8217;s title immediately caught my attention. That &#8220;life is...</small></li><li><a href='http://eli.thegreenplace.net/2003/11/17/book-review-the-ambassadors-by-henry-james/' rel='bookmark' title='Permanent Link: Book review: &#8220;The ambassadors&#8221; by Henry James'>Book review: &#8220;The ambassadors&#8221; by Henry James</a> <small>This book appears on that top 100 list I&#8217;m always...</small></li><li><a href='http://eli.thegreenplace.net/2004/11/12/book-review-dubliners-by-james-joyce/' rel='bookmark' title='Permanent Link: Book review: &#8220;Dubliners&#8221; by James Joyce'>Book review: &#8220;Dubliners&#8221; by James Joyce</a> <small>They say that if you want to start reading Joyce,...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>A short and informal review for this one.</p>
<p>Nice book, very well written. Lots of fun to read &#8211; the plot is gripping, the characters are well developed, and the historical background is fascinating. Japanese customs are very unusual, very interesting, very inspiring. Though they don&#8217;t always make sense, the author did a great job promoting mutual tolerance in conflicting issues. Not all western customs make sense either&#8230; Moreover, he excellently presents the mind-blowingly complex politics in which the various rulers of Japan were involved. It&#8217;s fun to read how smart one should&#8217;ve been to succeed in that world.</p>
<p>One gripe though &#8211; the book is too long, almost 1200 pages. Could&#8217;ve been shorter, although not by much.</p>
<img src="http://eli.thegreenplace.net/?ak_action=api_record_view&id=2086&type=feed" alt="" />

<p>Related posts:<ol><li><a href='http://eli.thegreenplace.net/2003/10/23/book-review-finite-and-infinite-games-by-james-carse/' rel='bookmark' title='Permanent Link: Book review: &#8220;Finite and infinite games&#8221; by James Carse'>Book review: &#8220;Finite and infinite games&#8221; by James Carse</a> <small>This book&#8217;s title immediately caught my attention. That &#8220;life is...</small></li><li><a href='http://eli.thegreenplace.net/2003/11/17/book-review-the-ambassadors-by-henry-james/' rel='bookmark' title='Permanent Link: Book review: &#8220;The ambassadors&#8221; by Henry James'>Book review: &#8220;The ambassadors&#8221; by Henry James</a> <small>This book appears on that top 100 list I&#8217;m always...</small></li><li><a href='http://eli.thegreenplace.net/2004/11/12/book-review-dubliners-by-james-joyce/' rel='bookmark' title='Permanent Link: Book review: &#8220;Dubliners&#8221; by James Joyce'>Book review: &#8220;Dubliners&#8221; by James Joyce</a> <small>They say that if you want to start reading Joyce,...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://eli.thegreenplace.net/2010/02/20/book-review-shogun-by-james-clavell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Finding out the mouse click position on a canvas with Javascript</title>
		<link>http://eli.thegreenplace.net/2010/02/13/finding-out-the-mouse-click-position-on-a-canvas-with-javascript/</link>
		<comments>http://eli.thegreenplace.net/2010/02/13/finding-out-the-mouse-click-position-on-a-canvas-with-javascript/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 13:06:04 +0000</pubDate>
		<dc:creator>eliben</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://eli.thegreenplace.net/?p=2082</guid>
		<description><![CDATA[I&#8217;m playing around with the HTML5 &#60;canvas&#62; element. One interesting thing to do is interact with the canvas using the mouse.
First we attach the mouse click event to the canvas (suppose we have an HTML page with a canvas element named canvas, and Game is a global &#34;namespace object&#34;):

Game.canvas = document.getElementById(&#39;canvas&#39;);
Game.canvas.addEventListener(&#39;click&#39;, on_canvas_click, false);


Now, in the [...]


Related posts:<ol><li><a href='http://eli.thegreenplace.net/2010/02/24/a-simple-canvas-based-javascript-game-with-a-django-back-end/' rel='bookmark' title='Permanent Link: A simple canvas-based Javascript game, with a Django back-end'>A simple canvas-based Javascript game, with a Django back-end</a> <small>A few years ago I&#8217;ve released a clone of the...</small></li><li><a href='http://eli.thegreenplace.net/2010/03/06/the-server-side-javascript-meme/' rel='bookmark' title='Permanent Link: The server-side Javascript meme'>The server-side Javascript meme</a> <small>In the past few months a new meme seems to...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m playing around with the HTML5 <tt class="docutils literal"><span class="pre">&lt;canvas&gt;</span></tt> element. One interesting thing to do is interact with the canvas using the mouse.</p>
<p>First we attach the mouse click event to the canvas (suppose we have an HTML page with a canvas element named <tt class="docutils literal"><span class="pre">canvas</span></tt>, and <tt class="docutils literal"><span class="pre">Game</span></tt> is a global &quot;namespace object&quot;):</p>
<div class="highlight">
<pre>Game.canvas = <span style="color: #00007f">document</span>.getElementById(<span style="color: #7f007f">&#39;canvas&#39;</span>);
Game.canvas.addEventListener(<span style="color: #7f007f">&#39;click&#39;</span>, on_canvas_click, <span style="color: #00007f; font-weight: bold">false</span>);
</pre>
</div>
<p>Now, in the event handler function, we can play with the event object. It has the <tt class="docutils literal"><span class="pre">clientX</span></tt> and <tt class="docutils literal"><span class="pre">clientY</span></tt> properties for finding out where the mouse was clicked, but these give imprecise results!</p>
<p>The reason for that is that the canvas itself isn&#8217;t placed at <tt class="docutils literal"><span class="pre">0,0</span></tt> on the client area. Therefore, we have to subtract its offset from the event&#8217;s coordinates, like this:</p>
<div class="highlight">
<pre><span style="color: #00007f; font-weight: bold">function</span> on_canvas_click(ev) {
    <span style="color: #00007f; font-weight: bold">var</span> x = ev.clientX - Game.canvas.offsetLeft;
    <span style="color: #00007f; font-weight: bold">var</span> y = ev.clientY - Game.canvas.offsetTop;

    <span style="color: #007f00">// ... x,y are the click coordinates relative to the</span>
    <span style="color: #007f00">// canvas itself</span>
}
</pre>
</div>
<img src="http://eli.thegreenplace.net/?ak_action=api_record_view&id=2082&type=feed" alt="" />

<p>Related posts:<ol><li><a href='http://eli.thegreenplace.net/2010/02/24/a-simple-canvas-based-javascript-game-with-a-django-back-end/' rel='bookmark' title='Permanent Link: A simple canvas-based Javascript game, with a Django back-end'>A simple canvas-based Javascript game, with a Django back-end</a> <small>A few years ago I&#8217;ve released a clone of the...</small></li><li><a href='http://eli.thegreenplace.net/2010/03/06/the-server-side-javascript-meme/' rel='bookmark' title='Permanent Link: The server-side Javascript meme'>The server-side Javascript meme</a> <small>In the past few months a new meme seems to...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://eli.thegreenplace.net/2010/02/13/finding-out-the-mouse-click-position-on-a-canvas-with-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Removing epsilon productions from context free grammars</title>
		<link>http://eli.thegreenplace.net/2010/02/08/removing-epsilon-productions-from-context-free-grammars/</link>
		<comments>http://eli.thegreenplace.net/2010/02/08/removing-epsilon-productions-from-context-free-grammars/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 04:53:22 +0000</pubDate>
		<dc:creator>eliben</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Compilation]]></category>

		<guid isPermaLink="false">http://eli.thegreenplace.net/?p=2074</guid>
		<description><![CDATA[
Background
epsilon productions are very useful to express many grammars in a compact way. For example, take these simple function call productions in some imaginary C-like language:

func_call:: identifier &#39;(&#39; arguments_opt &#39;)&#39;
arguments_opt:: arguments_list &#124; eps
arguments_list:: argument &#124; argument &#39;,&#39; arguments_list


When composing grammars by hand, simplicity matters. It&#8217;s very useful to be able to look at arguments_opt and [...]


Related posts:<ol><li><a href='http://eli.thegreenplace.net/2010/01/28/generating-random-sentences-from-a-context-free-grammar/' rel='bookmark' title='Permanent Link: Generating random sentences from a context free grammar'>Generating random sentences from a context free grammar</a> <small>Sometimes it&#8217;s interesting to randomly generate a large amount of...</small></li><li><a href='http://eli.thegreenplace.net/2007/11/24/the-context-sensitivity-of-cs-grammar/' rel='bookmark' title='Permanent Link: The context sensitivity of C&#8217;s grammar'>The context sensitivity of C&#8217;s grammar</a> <small>Context free grammars (CFGs) are a valuable theoretical tool on...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<div class="section" id="background">
<h3>Background</h3>
<p>epsilon productions are very useful to express many grammars in a compact way. For example, take these simple function call productions in some imaginary C-like language:</p>
<div class="highlight">
<pre>func_call:: identifier &#39;(&#39; arguments_opt &#39;)&#39;
arguments_opt:: arguments_list | eps
arguments_list:: argument | argument &#39;,&#39; arguments_list
</pre>
</div>
<p>When composing grammars by hand, simplicity matters. It&#8217;s very useful to be able to look at <tt class="docutils literal"><span class="pre">arguments_opt</span></tt> and know that it&#8217;s an optional list of arguments. The same non-terminal can be reused in several other productions.</p>
<p>However, epsilon productions pose a problem for several algorithms that act on grammars. Therefore, prior to running these algorithms, epsilon productions have to be removed. Fortunately, this can be done relatively effortlessly in an automatic way.</p>
<p>Here I want to present an algorithm and a simple implementation for epsilon production removal.</p>
</div>
<div class="section" id="the-algorithm">
<h3>The algorithm</h3>
<p>Intuitively, it&#8217;s quite simple to remove epsilon productions. Consider the grammar for function calls presented above. The <tt class="docutils literal"><span class="pre">argument_opt</span></tt> nonterminal in <tt class="docutils literal"><span class="pre">func_call</span></tt> is just a short way of saying that there either is an argument list inside those parens or nothing. In other words, it can be rewritten as follows:</p>
<div class="highlight">
<pre>func_call:: identifier &#39;(&#39; arguments_opt &#39;)&#39;
          | identifier &#39;(&#39; &#39;)&#39;
arguments_opt:: arguments_list
arguments_list:: argument | argument &#39;,&#39; arguments_list
</pre>
</div>
<p>This duplication of productions for <tt class="docutils literal"><span class="pre">func_call</span></tt> will have to be repeated for every other production that had <tt class="docutils literal"><span class="pre">arguments_opt</span></tt> in it. This grammar looks somewhat strange, as <tt class="docutils literal"><span class="pre">arguments_opt</span></tt> is now identical to <tt class="docutils literal"><span class="pre">arguments_list</span></tt>. It is correct, however.</p>
<p>A more interesting case occurs when the epsilon production is in a nonterminal that appears more than once in some other production <a class="footnote-reference" href="#id4" id="id1">[1]</a>. Consider:</p>
<div class="highlight">
<pre>B:: A z A
A:: a | eps
</pre>
</div>
<p>When we remove the epsilon production from <tt class="docutils literal"><span class="pre">A</span></tt>, we have to duplicate the productions that have <tt class="docutils literal"><span class="pre">A</span></tt> in them, but the production for <tt class="docutils literal"><span class="pre">B</span></tt> has two <tt class="docutils literal"><span class="pre">A</span></tt>. Since either of the <tt class="docutils literal"><span class="pre">A</span></tt> instances in the production can be empty, the only proper way to do this is go over all the combinations:</p>
<div class="highlight">
<pre>B:: z | A z | z A | A z A
A:: a
</pre>
</div>
<p>In the general case, if <tt class="docutils literal"><span class="pre">A</span></tt> appears <tt class="docutils literal"><span class="pre">k</span></tt> times in some production, this production will be replicated <tt class="docutils literal"><span class="pre">2^k</span></tt> times, each time with a different combination <a class="footnote-reference" href="#id5" id="id2">[2]</a>.</p>
<p>This leads us to the algorithm:</p>
<ol class="arabic simple">
<li>Pick a nonterminal <tt class="docutils literal"><span class="pre">A</span></tt> with an epsilon production</li>
<li>Remove that epsilon production</li>
<li>For each production containing <tt class="docutils literal"><span class="pre">A</span></tt>: Replicate it <tt class="docutils literal"><span class="pre">2^k</span></tt> times where <tt class="docutils literal"><span class="pre">k</span></tt> is the number of <tt class="docutils literal"><span class="pre">A</span></tt> instances in the production, such that all combinations of <tt class="docutils literal"><span class="pre">A</span></tt> being there or not will be represented.</li>
<li>If there are still epsilon productions in the grammar, go back to step 1.</li>
</ol>
<p>A couple of points to pay attention to:</p>
<ul class="simple">
<li>It&#8217;s obvious that a step of the algorithm can create new epsilon productions <a class="footnote-reference" href="#id6" id="id3">[3]</a>. This is handled correctly, as it works iteratively until all epsilon productions are removed.</li>
<li>The only place where an epsilon production cannot be removed is at the start symbol. If the grammar can generate an empty string, we can&#8217;t ruin that. A special case will have to handle this case.</li>
</ul>
</div>
<div class="section" id="implementation">
<h3>Implementation</h3>
<p>Here&#8217;s an implementation of this algorithm in Python:</p>
<div class="highlight">
<pre><span style="color: #00007f; font-weight: bold">from</span> <span style="color: #00007f">collections</span> <span style="color: #00007f; font-weight: bold">import</span> defaultdict

<span style="color: #00007f; font-weight: bold">class</span> <span style="color: #00007f">CFG</span>(<span style="color: #00007f">object</span>):
    <span style="color: #00007f; font-weight: bold">def</span> <span style="color: #00007f">__init__</span>(<span style="color: #00007f">self</span>):
        <span style="color: #00007f">self</span>.prod = defaultdict(<span style="color: #00007f">list</span>)
        <span style="color: #00007f">self</span>.start = <span style="color: #00007f">None</span>

    <span style="color: #00007f; font-weight: bold">def</span> <span style="color: #00007f">set_start_symbol</span>(<span style="color: #00007f">self</span>, start):
        <span style="color: #7f007f">&quot;&quot;&quot; Set the start symbol of the grammar.</span>
<span style="color: #7f007f">        &quot;&quot;&quot;</span>
        <span style="color: #00007f">self</span>.start = start

    <span style="color: #00007f; font-weight: bold">def</span> <span style="color: #00007f">add_prod</span>(<span style="color: #00007f">self</span>, lhs, rhs):
        <span style="color: #7f007f">&quot;&quot;&quot; Add production to the grammar. &#39;rhs&#39; can</span>
<span style="color: #7f007f">            be several productions separated by &#39;|&#39;.</span>
<span style="color: #7f007f">            Each production is a sequence of symbols</span>
<span style="color: #7f007f">            separated by whitespace.</span>
<span style="color: #7f007f">            Empty strings are interpreted as an eps-production.</span>

<span style="color: #7f007f">            Usage:</span>
<span style="color: #7f007f">                grammar.add_prod(&#39;NT&#39;, &#39;VP PP&#39;)</span>
<span style="color: #7f007f">                grammar.add_prod(&#39;Digit&#39;, &#39;1|2|3|4&#39;)</span>

<span style="color: #7f007f">                # Optional Digit: digit or eps</span>
<span style="color: #7f007f">                grammar.add_prod(&#39;Digit_opt&#39;, Digit |&#39;)</span>
<span style="color: #7f007f">        &quot;&quot;&quot;</span>
        <span style="color: #007f00"># The internal data-structure representing productions.</span>
        <span style="color: #007f00"># maps a nonterminal name to a list of productions, each</span>
        <span style="color: #007f00"># a list of symbols. An empty list [] specifies an</span>
        <span style="color: #007f00"># eps-production.</span>
        <span style="color: #007f00">#</span>
        prods = rhs.split(<span style="color: #7f007f">&#39;|&#39;</span>)
        <span style="color: #00007f; font-weight: bold">for</span> prod <span style="color: #0000aa">in</span> prods:
            <span style="color: #00007f">self</span>.prod[lhs].append(prod.split())

    <span style="color: #00007f; font-weight: bold">def</span> <span style="color: #00007f">remove_eps_productions</span>(<span style="color: #00007f">self</span>):
        <span style="color: #7f007f">&quot;&quot;&quot; Removes epsilon productions from the grammar.</span>

<span style="color: #7f007f">            The algorithm:</span>

<span style="color: #7f007f">            1. Pick a nonterminal p_eps with an epsilon production</span>
<span style="color: #7f007f">            2. Remove that epsilon production</span>
<span style="color: #7f007f">            3. For each production containing p_eps, replace it</span>
<span style="color: #7f007f">               with several productions such that all the</span>
<span style="color: #7f007f">               combinations of p_eps being there or not will be</span>
<span style="color: #7f007f">               represented.</span>
<span style="color: #7f007f">            4. If there are still epsilon productions in the</span>
<span style="color: #7f007f">               grammar, go back to step 1</span>

<span style="color: #7f007f">            The replication can be demonstrated with an example.</span>
<span style="color: #7f007f">            Suppose that A contains an epsilon production, and</span>
<span style="color: #7f007f">            we&#39;ve found a production B:: [A, k, A]</span>
<span style="color: #7f007f">            Then this production of B will be replaced with these:</span>
<span style="color: #7f007f">            [A, k], [k], [k, A], [A, k, A]</span>
<span style="color: #7f007f">        &quot;&quot;&quot;</span>
        <span style="color: #00007f; font-weight: bold">while</span> <span style="color: #00007f">True</span>:
            <span style="color: #007f00"># Find an epsilon production</span>
            <span style="color: #007f00">#</span>
            p_eps, index = <span style="color: #00007f">self</span>._find_eps_production()

            <span style="color: #007f00"># No epsilon productions? Then we&#39;re done...</span>
            <span style="color: #007f00">#</span>
            <span style="color: #00007f; font-weight: bold">if</span> p_eps <span style="color: #0000aa">is</span> <span style="color: #00007f">None</span>:
                <span style="color: #00007f; font-weight: bold">break</span>

            <span style="color: #007f00"># Remove the epsilon production</span>
            <span style="color: #007f00">#</span>
            <span style="color: #00007f; font-weight: bold">del</span> <span style="color: #00007f">self</span>.prod[p_eps][index]

            <span style="color: #007f00"># Now find all the productions that contain the</span>
            <span style="color: #007f00"># production that removed.</span>
            <span style="color: #007f00"># For each such production, replicate it with all</span>
            <span style="color: #007f00"># the combinations of the removed production.</span>
            <span style="color: #007f00">#</span>
            <span style="color: #00007f; font-weight: bold">for</span> lhs <span style="color: #0000aa">in</span> <span style="color: #00007f">self</span>.prod:
                prods = []

                <span style="color: #00007f; font-weight: bold">for</span> lhs_prod <span style="color: #0000aa">in</span> <span style="color: #00007f">self</span>.prod[lhs]:
                    num_p_eps = lhs_prod.count(p_eps)
                    <span style="color: #00007f; font-weight: bold">if</span> num_p_eps == <span style="color: #007f7f">0</span>:
                        prods.append(lhs_prod)
                    <span style="color: #00007f; font-weight: bold">else</span>:
                        prods.extend(<span style="color: #00007f">self</span>._create_prod_combinations(
                            prod=lhs_prod,
                            nt=p_eps,
                            count=num_p_eps))

                <span style="color: #007f00"># Remove duplicates</span>
                <span style="color: #007f00">#</span>
                prods = sorted(prods)
                prods = [prods[i] <span style="color: #00007f; font-weight: bold">for</span> i <span style="color: #0000aa">in</span> <span style="color: #00007f">xrange</span>(<span style="color: #00007f">len</span>(prods))
                                  <span style="color: #00007f; font-weight: bold">if</span> i == <span style="color: #007f7f">0</span> <span style="color: #0000aa">or</span> prods[i] != prods[i-<span style="color: #007f7f">1</span>]]

                <span style="color: #00007f">self</span>.prod[lhs] = prods

    <span style="color: #00007f; font-weight: bold">def</span> <span style="color: #00007f">_find_eps_production</span>(<span style="color: #00007f">self</span>):
        <span style="color: #7f007f">&quot;&quot;&quot; Finds an epsilon production in the grammar. If such</span>
<span style="color: #7f007f">            a production is found, returns the pair (lhs, index):</span>
<span style="color: #7f007f">            the name of the non-terminal that has an epsilon</span>
<span style="color: #7f007f">            production and its index in lhs&#39;s list of productions.</span>
<span style="color: #7f007f">            If no epsilon productions were found, returns the</span>
<span style="color: #7f007f">            pair (None, None).</span>

<span style="color: #7f007f">            Note: eps productions in the start symbol will be</span>
<span style="color: #7f007f">            ignored, because we don&#39;t want to remove them.</span>
<span style="color: #7f007f">        &quot;&quot;&quot;</span>
        <span style="color: #00007f; font-weight: bold">for</span> lhs <span style="color: #0000aa">in</span> <span style="color: #00007f">self</span>.prod:
            <span style="color: #00007f; font-weight: bold">if</span> <span style="color: #0000aa">not</span> <span style="color: #00007f">self</span>.start <span style="color: #0000aa">is</span> <span style="color: #00007f">None</span> <span style="color: #0000aa">and</span> lhs == <span style="color: #00007f">self</span>.start:
                <span style="color: #00007f; font-weight: bold">continue</span>

            <span style="color: #00007f; font-weight: bold">for</span> i, p <span style="color: #0000aa">in</span> <span style="color: #00007f">enumerate</span>(<span style="color: #00007f">self</span>.prod[lhs]):
                <span style="color: #00007f; font-weight: bold">if</span> <span style="color: #00007f">len</span>(p) == <span style="color: #007f7f">0</span>:
                    <span style="color: #00007f; font-weight: bold">return</span> lhs, i

        <span style="color: #00007f; font-weight: bold">return</span> <span style="color: #00007f">None</span>, <span style="color: #00007f">None</span>

    <span style="color: #00007f; font-weight: bold">def</span> <span style="color: #00007f">_create_prod_combinations</span>(<span style="color: #00007f">self</span>, prod, nt, count):
        <span style="color: #7f007f">&quot;&quot;&quot; prod:</span>
<span style="color: #7f007f">                A production (list) that contains at least one</span>
<span style="color: #7f007f">                instance of &#39;nt&#39;</span>
<span style="color: #7f007f">            nt:</span>
<span style="color: #7f007f">                The non-terminal which should be replicated</span>
<span style="color: #7f007f">            count:</span>
<span style="color: #7f007f">                The amount of times &#39;nt&#39; appears in &#39;lhs_prod&#39;.</span>
<span style="color: #7f007f">                Assumed to be &gt;= 1</span>

<span style="color: #7f007f">            Returns the generated list of productions.</span>
<span style="color: #7f007f">        &quot;&quot;&quot;</span>
        <span style="color: #007f00"># The combinations are a kind of a powerset. Membership</span>
        <span style="color: #007f00"># in a powerset can be checked by using the binary</span>
        <span style="color: #007f00"># representation of a number.</span>
        <span style="color: #007f00"># There are 2^count possibilities in total.</span>
        <span style="color: #007f00">#</span>
        numset = <span style="color: #007f7f">1</span> &lt;&lt; count
        new_prods = []

        <span style="color: #00007f; font-weight: bold">for</span> i <span style="color: #0000aa">in</span> <span style="color: #00007f">xrange</span>(numset):
            nth_nt = <span style="color: #007f7f">0</span>
            new_prod = []

            <span style="color: #00007f; font-weight: bold">for</span> s <span style="color: #0000aa">in</span> prod:
                <span style="color: #00007f; font-weight: bold">if</span> s == nt:
                    <span style="color: #00007f; font-weight: bold">if</span> i &amp; (<span style="color: #007f7f">1</span> &lt;&lt; nth_nt):
                        new_prod.append(s)
                    nth_nt += <span style="color: #007f7f">1</span>
                <span style="color: #00007f; font-weight: bold">else</span>:
                    new_prod.append(s)

            new_prods.append(new_prod)

        <span style="color: #00007f; font-weight: bold">return</span> new_prods
</pre>
</div>
<p>And here are the results with some of the sample grammars presented earlier in the article:</p>
<div class="highlight">
<pre>cfg = CFG()
cfg.add_prod(<span style="color: #7f007f">&#39;identifier&#39;</span>, <span style="color: #7f007f">&#39;( arguments_opt )&#39;</span>)
cfg.add_prod(<span style="color: #7f007f">&#39;arguments_opt&#39;</span>, <span style="color: #7f007f">&#39;arguments_list | &#39;</span>)
cfg.add_prod(<span style="color: #7f007f">&#39;arguments_list&#39;</span>, <span style="color: #7f007f">&#39;argument | argument , arguments_list&#39;</span>)

cfg.remove_eps_productions()
<span style="color: #00007f; font-weight: bold">for</span> p <span style="color: #0000aa">in</span> cfg.prod:
    <span style="color: #00007f; font-weight: bold">print</span> p, <span style="color: #7f007f">&#39;:: &#39;</span>, [<span style="color: #7f007f">&#39; &#39;</span>.join(pr) <span style="color: #00007f; font-weight: bold">for</span> pr <span style="color: #0000aa">in</span> cfg.prod[p]]
</pre>
</div>
<p>Produces:</p>
<div class="highlight">
<pre>func_call ::  [&#39;identifier ( )&#39;, &#39;identifier ( arguments_opt )&#39;]
arguments_list ::  [&#39;argument&#39;, &#39;argument , arguments_list&#39;]
arguments_opt ::  [&#39;arguments_list&#39;]
</pre>
</div>
<p>As expected. And:</p>
<div class="highlight">
<pre>cfg = CFG()
cfg.add_prod(<span style="color: #7f007f">&#39;B&#39;</span>, <span style="color: #7f007f">&#39;A z A&#39;</span>)
cfg.add_prod(<span style="color: #7f007f">&#39;A&#39;</span>, <span style="color: #7f007f">&#39;a | &#39;</span>)

cfg.remove_eps_productions()
<span style="color: #00007f; font-weight: bold">for</span> p <span style="color: #0000aa">in</span> cfg.prod:
    <span style="color: #00007f; font-weight: bold">print</span> p, <span style="color: #7f007f">&#39;:: &#39;</span>, [<span style="color: #7f007f">&#39; &#39;</span>.join(pr) <span style="color: #00007f; font-weight: bold">for</span> pr <span style="color: #0000aa">in</span> cfg.prod[p]]
</pre>
</div>
<p>Produces:</p>
<div class="highlight">
<pre>A ::  [&#39;a&#39;]
B ::  [&#39;A z&#39;, &#39;A z A&#39;, &#39;z&#39;, &#39;z A&#39;]
</pre>
</div>
<p>The implementation isn&#8217;t tuned for efficiency, but for simplicity. Luckily, CFGs are usually small enough to make the runtime of this implementation manageable. Note that the preservation of epsilon productions in the start rule is implemented in the <tt class="docutils literal"><span class="pre">_find_eps_production</span></tt> method.</p>
<div align="center" class="align-center"><img alt="http://eli.thegreenplace.net/wp-content/uploads/hline.jpg" class="align-center" src="http://eli.thegreenplace.net/wp-content/uploads/hline.jpg" style="width: 320px; height: 5px;" /></div>
<table class="docutils footnote" frame="void" id="id4" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id1">[1]</a></td>
<td>From here on, lowercase letters early in the alphabet (a, b, c&#8230;) are terminals. Early uppercase letters (A, B, C&#8230;) are nonterminals, and letters late in the alphabet (z, y, x&#8230;) are arbitrary strings of terminals and nonterminals.</td>
</tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id5" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id2">[2]</a></td>
<td>If this sounds like generating a <a class="reference external" href="http://en.wikipedia.org/wiki/Powerset">powerset</a>, you&#8217;re right.</td>
</tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id6" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id3">[3]</a></td>
<td>Consider the productions:</td>
</tr>
</tbody>
</table>
<div class="highlight">
<pre>A:: a | eps
B:: b | A
</pre>
</div>
<p>After removing the epsilon production from <tt class="docutils literal"><span class="pre">A</span></tt> we&#8217;ll have:</p>
<div class="highlight">
<pre>A:: a
B:: b | A | eps
</pre>
</div>
</div>
<img src="http://eli.thegreenplace.net/?ak_action=api_record_view&id=2074&type=feed" alt="" />

<p>Related posts:<ol><li><a href='http://eli.thegreenplace.net/2010/01/28/generating-random-sentences-from-a-context-free-grammar/' rel='bookmark' title='Permanent Link: Generating random sentences from a context free grammar'>Generating random sentences from a context free grammar</a> <small>Sometimes it&#8217;s interesting to randomly generate a large amount of...</small></li><li><a href='http://eli.thegreenplace.net/2007/11/24/the-context-sensitivity-of-cs-grammar/' rel='bookmark' title='Permanent Link: The context sensitivity of C&#8217;s grammar'>The context sensitivity of C&#8217;s grammar</a> <small>Context free grammars (CFGs) are a valuable theoretical tool on...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://eli.thegreenplace.net/2010/02/08/removing-epsilon-productions-from-context-free-grammars/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Generating random sentences from a context free grammar</title>
		<link>http://eli.thegreenplace.net/2010/01/28/generating-random-sentences-from-a-context-free-grammar/</link>
		<comments>http://eli.thegreenplace.net/2010/01/28/generating-random-sentences-from-a-context-free-grammar/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 13:13:28 +0000</pubDate>
		<dc:creator>eliben</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Compilation]]></category>

		<guid isPermaLink="false">http://eli.thegreenplace.net/?p=2070</guid>
		<description><![CDATA[Sometimes it&#8217;s interesting to randomly generate a large amount of valid sentences from a context free grammar. The best use for this is automated stress-testing of parsers for those grammars [1].
So how would you generate sentences?

Simple recursive algorithm
The first approach that springs to mind is a simple recursive traversal of the grammar, choosing productions at [...]


Related posts:<ol><li><a href='http://eli.thegreenplace.net/2010/02/08/removing-epsilon-productions-from-context-free-grammars/' rel='bookmark' title='Permanent Link: Removing epsilon productions from context free grammars'>Removing epsilon productions from context free grammars</a> <small> Background epsilon productions are very useful to express many...</small></li><li><a href='http://eli.thegreenplace.net/2007/11/24/the-context-sensitivity-of-cs-grammar/' rel='bookmark' title='Permanent Link: The context sensitivity of C&#8217;s grammar'>The context sensitivity of C&#8217;s grammar</a> <small>Context free grammars (CFGs) are a valuable theoretical tool on...</small></li><li><a href='http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/' rel='bookmark' title='Permanent Link: Recursive descent, LL and predictive parsers'>Recursive descent, LL and predictive parsers</a> <small> Introduction Although I&#8217;ve written some recursive-descent (RD) parsers by...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Sometimes it&#8217;s interesting to randomly generate a large amount of valid sentences from a <a class="reference external" href="http://en.wikipedia.org/wiki/Context_free_grammar/">context free grammar</a>. The best use for this is automated stress-testing of parsers for those grammars <a class="footnote-reference" href="#id4" id="id1">[1]</a>.</p>
<p>So how would you generate sentences?</p>
<div class="section" id="simple-recursive-algorithm">
<h3>Simple recursive algorithm</h3>
<p>The first approach that springs to mind is a simple recursive traversal of the grammar, choosing productions at random. Here&#8217;s the algorithm with some infrastructure:</p>
<div class="highlight">
<pre><span style="color: #00007f; font-weight: bold">class</span> <span style="color: #00007f">CFG</span>(<span style="color: #00007f">object</span>):
    <span style="color: #00007f; font-weight: bold">def</span> <span style="color: #00007f">__init__</span>(<span style="color: #00007f">self</span>):
        <span style="color: #00007f">self</span>.prod = defaultdict(<span style="color: #00007f">list</span>)

    <span style="color: #00007f; font-weight: bold">def</span> <span style="color: #00007f">add_prod</span>(<span style="color: #00007f">self</span>, lhs, rhs):
        <span style="color: #7f007f">&quot;&quot;&quot; Add production to the grammar. &#39;rhs&#39; can</span>
<span style="color: #7f007f">            be several productions separated by &#39;|&#39;.</span>
<span style="color: #7f007f">            Each production is a sequence of symbols</span>
<span style="color: #7f007f">            separated by whitespace.</span>

<span style="color: #7f007f">            Usage:</span>
<span style="color: #7f007f">                grammar.add_prod(&#39;NT&#39;, &#39;VP PP&#39;)</span>
<span style="color: #7f007f">                grammar.add_prod(&#39;Digit&#39;, &#39;1|2|3|4&#39;)</span>
<span style="color: #7f007f">        &quot;&quot;&quot;</span>
        prods = rhs.split(<span style="color: #7f007f">&#39;|&#39;</span>)
        <span style="color: #00007f; font-weight: bold">for</span> prod <span style="color: #0000aa">in</span> prods:
            <span style="color: #00007f">self</span>.prod[lhs].append(<span style="color: #00007f">tuple</span>(prod.split()))

    <span style="color: #00007f; font-weight: bold">def</span> <span style="color: #00007f">gen_random</span>(<span style="color: #00007f">self</span>, symbol):
        <span style="color: #7f007f">&quot;&quot;&quot; Generate a random sentence from the</span>
<span style="color: #7f007f">            grammar, starting with the given</span>
<span style="color: #7f007f">            symbol.</span>
<span style="color: #7f007f">        &quot;&quot;&quot;</span>
        sentence = <span style="color: #7f007f">&#39;&#39;</span>

        <span style="color: #007f00"># select one production of this symbol randomly</span>
        rand_prod = random.choice(<span style="color: #00007f">self</span>.prod[symbol])

        <span style="color: #00007f; font-weight: bold">for</span> sym <span style="color: #0000aa">in</span> rand_prod:
            <span style="color: #007f00"># for non-terminals, recurse</span>
            <span style="color: #00007f; font-weight: bold">if</span> sym <span style="color: #0000aa">in</span> <span style="color: #00007f">self</span>.prod:
                sentence += <span style="color: #00007f">self</span>.gen_random(sym)
            <span style="color: #00007f; font-weight: bold">else</span>:
                sentence += sym + <span style="color: #7f007f">&#39; &#39;</span>

        <span style="color: #00007f; font-weight: bold">return</span> sentence
</pre>
</div>
<p><tt class="docutils literal"><span class="pre">CFG</span></tt> represents a context free grammar. It holds productions in the <tt class="docutils literal"><span class="pre">prod</span></tt> attribute, which is a dictionary mapping a symbol to a list of its possible productions. Each production is a tuple of symbols. A symbol can either be a terminal or a nonterminal. Those are distinguished as follows: nonterminals have entries in <tt class="docutils literal"><span class="pre">prod</span></tt>, terminals do not.</p>
<p><tt class="docutils literal"><span class="pre">gen_random</span></tt> is a simple recursive algorithm for generating a sentence starting with the given grammar symbol. It selects one of the productions of <tt class="docutils literal"><span class="pre">symbols</span></tt> randomly and iterates through it, recursing into nonterminals and emitting terminals directly.</p>
<p>Here&#8217;s an example usage of the class with a very simple natural-language grammar:</p>
<div class="highlight">
<pre>cfg1 = CFG()
cfg1.add_prod(<span style="color: #7f007f">&#39;S&#39;</span>, <span style="color: #7f007f">&#39;NP VP&#39;</span>)
cfg1.add_prod(<span style="color: #7f007f">&#39;NP&#39;</span>, <span style="color: #7f007f">&#39;Det N | Det N&#39;</span>)
cfg1.add_prod(<span style="color: #7f007f">&#39;NP&#39;</span>, <span style="color: #7f007f">&#39;I | he | she | Joe&#39;</span>)
cfg1.add_prod(<span style="color: #7f007f">&#39;VP&#39;</span>, <span style="color: #7f007f">&#39;V NP | VP&#39;</span>)
cfg1.add_prod(<span style="color: #7f007f">&#39;Det&#39;</span>, <span style="color: #7f007f">&#39;a | the | my | his&#39;</span>)
cfg1.add_prod(<span style="color: #7f007f">&#39;N&#39;</span>, <span style="color: #7f007f">&#39;elephant | cat | jeans | suit&#39;</span>)
cfg1.add_prod(<span style="color: #7f007f">&#39;V&#39;</span>, <span style="color: #7f007f">&#39;kicked | followed | shot&#39;</span>)

<span style="color: #00007f; font-weight: bold">for</span> i <span style="color: #0000aa">in</span> <span style="color: #00007f">xrange</span>(<span style="color: #007f7f">10</span>):
    <span style="color: #00007f; font-weight: bold">print</span> cfg1.gen_random(<span style="color: #7f007f">&#39;S&#39;</span>)
</pre>
</div>
<p>And here are some sample statements generated by it:</p>
<div class="highlight">
<pre>the suit kicked my suit
she followed she
she shot a jeans
he shot I
a elephant followed the suit
he followed he
he shot the jeans
his cat kicked his elephant
I followed Joe
a elephant shot Joe
</pre>
</div>
</div>
<div class="section" id="the-problem-with-the-simple-algorithm">
<h3>The problem with the simple algorithm</h3>
<p>Consider the following grammar:</p>
<div class="highlight">
<pre>cfgg = CFG()
cfgg.add_prod(<span style="color: #7f007f">&#39;S&#39;</span>, <span style="color: #7f007f">&#39;S S S S | a&#39;</span>)
</pre>
</div>
<p>It has a single nonterminal, <tt class="docutils literal"><span class="pre">S</span></tt> and a single terminal <tt class="docutils literal"><span class="pre">a</span></tt>. Trying to generate a random sentence from it sometimes results in a <tt class="docutils literal"><span class="pre">RuntimeError</span></tt> exception being thrown: <tt class="docutils literal"><span class="pre">maximum</span> <span class="pre">recursion</span> <span class="pre">depth</span> <span class="pre">exceeded</span> <span class="pre">while</span> <span class="pre">calling</span> <span class="pre">a</span> <span class="pre">Python</span> <span class="pre">object</span></tt>. Why is that?</p>
<p>Consider what happens when <tt class="docutils literal"><span class="pre">gen_random</span></tt> runs on this grammar. In the first call, it has a 50% chance of selecting the <tt class="docutils literal"><span class="pre">S</span> <span class="pre">S</span> <span class="pre">S</span> <span class="pre">S</span></tt> production and a 50% chance of selecting <tt class="docutils literal"><span class="pre">a</span></tt>. If <tt class="docutils literal"><span class="pre">S</span> <span class="pre">S</span> <span class="pre">S</span> <span class="pre">S</span></tt> is selected, the algorithm will now recurse 4 times into each <tt class="docutils literal"><span class="pre">S</span></tt>. The chance of all those calls resulting in <tt class="docutils literal"><span class="pre">a</span></tt> is just 0.0625, and there&#8217;s a 0.9375 chance that at least one will result in <tt class="docutils literal"><span class="pre">S</span></tt> and generate <tt class="docutils literal"><span class="pre">S</span> <span class="pre">S</span> <span class="pre">S</span> <span class="pre">S</span></tt> again. As this process continues, chances get slimmer and slimmer that the algorithm will ever terminate. This isn&#8217;t good.</p>
<p>You may now think that this is a contrived example and real-life grammars are more well-behaved. Unfortunately this isn&#8217;t the case. Consider this (rather ordinary) arithmetic expression grammar:</p>
<div class="highlight">
<pre>cfg2 = CFG()
cfg2.add_prod(<span style="color: #7f007f">&#39;EXPR&#39;</span>, <span style="color: #7f007f">&#39;TERM + EXPR&#39;</span>)
cfg2.add_prod(<span style="color: #7f007f">&#39;EXPR&#39;</span>, <span style="color: #7f007f">&#39;TERM - EXPR&#39;</span>)
cfg2.add_prod(<span style="color: #7f007f">&#39;EXPR&#39;</span>, <span style="color: #7f007f">&#39;TERM&#39;</span>)
cfg2.add_prod(<span style="color: #7f007f">&#39;TERM&#39;</span>, <span style="color: #7f007f">&#39;FACTOR * TERM&#39;</span>)
cfg2.add_prod(<span style="color: #7f007f">&#39;TERM&#39;</span>, <span style="color: #7f007f">&#39;FACTOR / TERM&#39;</span>)
cfg2.add_prod(<span style="color: #7f007f">&#39;TERM&#39;</span>, <span style="color: #7f007f">&#39;FACTOR&#39;</span>)
cfg2.add_prod(<span style="color: #7f007f">&#39;FACTOR&#39;</span>, <span style="color: #7f007f">&#39;ID | NUM | ( EXPR )&#39;</span>)
cfg2.add_prod(<span style="color: #7f007f">&#39;ID&#39;</span>, <span style="color: #7f007f">&#39;x | y | z | w&#39;</span>)
cfg2.add_prod(<span style="color: #7f007f">&#39;NUM&#39;</span>, <span style="color: #7f007f">&#39;0|1|2|3|4|5|6|7|8|9&#39;</span>)
</pre>
</div>
<p>When I try to generate random sentences from it, less than 30% percent of the runs terminate <a class="footnote-reference" href="#id5" id="id2">[2]</a>.</p>
<p>The culprit here is the <tt class="docutils literal"><span class="pre">(</span> <span class="pre">EXPR</span> <span class="pre">)</span></tt> production of <tt class="docutils literal"><span class="pre">FACTOR</span></tt>. An expression can get expanded into several factors, each of which can once again result in a whole new expression. Just a couple of such derivations can be enough for the whole generation process to diverge. And there&#8217;s no real way to get rid of this, because <tt class="docutils literal"><span class="pre">(</span> <span class="pre">EXPR</span> <span class="pre">)</span></tt> is an essential derivation of <tt class="docutils literal"><span class="pre">FACTOR</span></tt>, allowing us to parse expressions like <tt class="docutils literal"><span class="pre">5</span> <span class="pre">*</span> <span class="pre">(1</span> <span class="pre">+</span> <span class="pre">x)</span></tt>.</p>
<p>Thus, even for real-world grammars, the simple recursive approach is an inadequate solution. <a class="footnote-reference" href="#id6" id="id3">[3]</a></p>
</div>
<div class="section" id="an-improved-generator-convergence">
<h3>An improved generator: convergence</h3>
<p>We can employ a clever trick to make the generator always converge (in the mathematical sense). Think of the grammar as representing an infinite tree:</p>
<p><img alt="http://eli.thegreenplace.net/wp-content/uploads/2010/01/expr1.png" src="http://eli.thegreenplace.net/wp-content/uploads/2010/01/expr1.png" /></p>
<p>The bluish nodes represent nonterminals, and the greenish nodes represent possible productions. If we think of the grammar this way, it is obvious that the <tt class="docutils literal"><span class="pre">gen_random</span></tt> method presented earlier is a simple n-nary tree walk.</p>
<p>The idea of the algorithm is to attach weights to each possible production and select the production according to these weights. Once a production is selected, its weight is decreased and passed recursively down the tree. Therefore, once the generator runs into the same nonterminal and considers these productions again, there will be a lower chance for the same recursion to occur. A diagram shows this best:</p>
<p><img alt="http://eli.thegreenplace.net/wp-content/uploads/2010/01/expr2.png" src="http://eli.thegreenplace.net/wp-content/uploads/2010/01/expr2.png" /></p>
<p>Note that initially all the productions of <tt class="docutils literal"><span class="pre">expr</span></tt> have the same weight, and will be selected with equal probability. Once <tt class="docutils literal"><span class="pre">term</span> <span class="pre">-</span> <span class="pre">expr</span></tt> is selected, the algorithm takes note of this. When the same choice is presented again, the weight of <tt class="docutils literal"><span class="pre">term</span> <span class="pre">-</span> <span class="pre">expr</span></tt> is decreased by some factor (in this case by a factor of 2). Note that it can be selected once again, but then for the next round its weight will be 0.25. This of course only applies to the same tree branch. If <tt class="docutils literal"><span class="pre">term</span> <span class="pre">-</span> <span class="pre">expr</span></tt> is selected in some other, unrelated branch, its weight is unaffected by this selection.</p>
<p>This improvement solves the divergence problem of the naive recursive algorithm. Here&#8217;s its implementation (it&#8217;s a method of the same <tt class="docutils literal"><span class="pre">CFG</span></tt> class presented above):</p>
<div class="highlight">
<pre><span style="color: #00007f; font-weight: bold">def</span> <span style="color: #00007f">gen_random_convergent</span>(<span style="color: #00007f">self</span>,
      symbol,
      cfactor=<span style="color: #007f7f">0.25</span>,
      pcount=defaultdict(<span style="color: #00007f">int</span>)
  ):
  <span style="color: #7f007f">&quot;&quot;&quot; Generate a random sentence from the</span>
<span style="color: #7f007f">      grammar, starting with the given symbol.</span>

<span style="color: #7f007f">      Uses a convergent algorithm - productions</span>
<span style="color: #7f007f">      that have already appeared in the</span>
<span style="color: #7f007f">      derivation on each branch have a smaller</span>
<span style="color: #7f007f">      chance to be selected.</span>

<span style="color: #7f007f">      cfactor - controls how tight the</span>
<span style="color: #7f007f">      convergence is. 0 &lt; cfactor &lt; 1.0</span>

<span style="color: #7f007f">      pcount is used internally by the</span>
<span style="color: #7f007f">      recursive calls to pass on the</span>
<span style="color: #7f007f">      productions that have been used in the</span>
<span style="color: #7f007f">      branch.</span>
<span style="color: #7f007f">  &quot;&quot;&quot;</span>
  sentence = <span style="color: #7f007f">&#39;&#39;</span>

  <span style="color: #007f00"># The possible productions of this symbol are weighted</span>
  <span style="color: #007f00"># by their appearance in the branch that has led to this</span>
  <span style="color: #007f00"># symbol in the derivation</span>
  <span style="color: #007f00">#</span>
  weights = []
  <span style="color: #00007f; font-weight: bold">for</span> prod <span style="color: #0000aa">in</span> <span style="color: #00007f">self</span>.prod[symbol]:
      <span style="color: #00007f; font-weight: bold">if</span> prod <span style="color: #0000aa">in</span> pcount:
          weights.append(cfactor ** (pcount[prod]))
      <span style="color: #00007f; font-weight: bold">else</span>:
          weights.append(<span style="color: #007f7f">1.0</span>)

  rand_prod = <span style="color: #00007f">self</span>.prod[symbol][weighted_choice(weights)]

  <span style="color: #007f00"># pcount is a single object (created in the first call to</span>
  <span style="color: #007f00"># this method) that&#39;s being passed around into recursive</span>
  <span style="color: #007f00"># calls to count how many times productions have been</span>
  <span style="color: #007f00"># used.</span>
  <span style="color: #007f00"># Before recursive calls the count is updated, and after</span>
  <span style="color: #007f00"># the sentence for this call is ready, it is rolled-back</span>
  <span style="color: #007f00"># to avoid modifying the parent&#39;s pcount.</span>
  <span style="color: #007f00">#</span>
  pcount[rand_prod] += <span style="color: #007f7f">1</span>

  <span style="color: #00007f; font-weight: bold">for</span> sym <span style="color: #0000aa">in</span> rand_prod:
      <span style="color: #007f00"># for non-terminals, recurse</span>
      <span style="color: #00007f; font-weight: bold">if</span> sym <span style="color: #0000aa">in</span> <span style="color: #00007f">self</span>.prod:
          sentence += <span style="color: #00007f">self</span>.gen_random_convergent(
                              sym,
                              cfactor=cfactor,
                              pcount=pcount)
      <span style="color: #00007f; font-weight: bold">else</span>:
          sentence += sym + <span style="color: #7f007f">&#39; &#39;</span>

  <span style="color: #007f00"># backtracking: clear the modification to pcount</span>
  pcount[rand_prod] -= <span style="color: #007f7f">1</span>
  <span style="color: #00007f; font-weight: bold">return</span> sentence
</pre>
</div>
<p>An auxiliary <tt class="docutils literal"><span class="pre">weighted_choice</span></tt> function is used:</p>
<div class="highlight">
<pre><span style="color: #00007f; font-weight: bold">def</span> <span style="color: #00007f">weighted_choice</span>(weights):
    rnd = random.random() * <span style="color: #00007f">sum</span>(weights)
    <span style="color: #00007f; font-weight: bold">for</span> i, w <span style="color: #0000aa">in</span> <span style="color: #00007f">enumerate</span>(weights):
        rnd -= w
        <span style="color: #00007f; font-weight: bold">if</span> rnd &lt; <span style="color: #007f7f">0</span>:
            <span style="color: #00007f; font-weight: bold">return</span> i
</pre>
</div>
<p>Note the <tt class="docutils literal"><span class="pre">cfactor</span></tt> parameter of the algorithm. This is the <em>convergence factor</em> &#8211; the probability by which a weight is multiplied each time it&#8217;s been selected. Having been selected <tt class="docutils literal"><span class="pre">N</span></tt> times, the weight becomes <tt class="docutils literal"><span class="pre">cfactor</span></tt> to the power <tt class="docutils literal"><span class="pre">N</span></tt>. I&#8217;ve plotted the average length of the generated sentence from the expression grammar as a function of <tt class="docutils literal"><span class="pre">cfactor</span></tt>:</p>
<p><img alt="http://eli.thegreenplace.net/wp-content/uploads/2010/01/cfactor_plot.png" src="http://eli.thegreenplace.net/wp-content/uploads/2010/01/cfactor_plot.png" /></p>
<p>As expected, the average length grows with <tt class="docutils literal"><span class="pre">cfactor</span></tt>. If we set <tt class="docutils literal"><span class="pre">cfactor</span></tt> to 1.0, this becomes the naive algorithm where all the productions are always of equal weight.</p>
</div>
<div class="section" id="conclusion">
<h3>Conclusion</h3>
<p>While the naive algorithm is suitable for some simplistic cases, for real-world grammars it&#8217;s inadequate. A generalization that employs weighted selection using a convergence factor provides a much better solution that generates sentences from grammars with guaranteed termination. This is a sound and relatively efficient method that can be used in real-world applications to generate complex random test cases for parsers.</p>
<div align="center" class="align-center"><img alt="http://eli.thegreenplace.net/wp-content/uploads/hline.jpg" class="align-center" src="http://eli.thegreenplace.net/wp-content/uploads/hline.jpg" style="width: 320px; height: 5px;" /></div>
<table class="docutils footnote" frame="void" id="id4" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id1">[1]</a></td>
<td>Another could be some rudimentary form of random text generation, although the resulting text isn&#8217;t very comprehensible. Markov chains are much better for this.</td>
</tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id5" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id2">[2]</a></td>
<td>A larger percentage can be achieved by increasing Python&#8217;s recursion depth limit, but this is not the point.</td>
</tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id6" rules="none">
<colgroup>
<col class="label" />
<col /></colgroup>
<tbody valign="top">
<tr>
<td class="label"><a class="fn-backref" href="#id3">[3]</a></td>
<td>Some algorithms, like <a class="reference external" href="http://www.stonehenge.com/merlyn/LinuxMag/col04.html">this one</a> by Randal Schwartz, assign fixed weights to each production. While it could be used to decrease the chances of divergence, it&#8217;s not a really good general solution for our problem. However, it works great for simple, non-recursive grammars like the one presented in his article.</td>
</tr>
</tbody>
</table>
</div>
<img src="http://eli.thegreenplace.net/?ak_action=api_record_view&id=2070&type=feed" alt="" />

<p>Related posts:<ol><li><a href='http://eli.thegreenplace.net/2010/02/08/removing-epsilon-productions-from-context-free-grammars/' rel='bookmark' title='Permanent Link: Removing epsilon productions from context free grammars'>Removing epsilon productions from context free grammars</a> <small> Background epsilon productions are very useful to express many...</small></li><li><a href='http://eli.thegreenplace.net/2007/11/24/the-context-sensitivity-of-cs-grammar/' rel='bookmark' title='Permanent Link: The context sensitivity of C&#8217;s grammar'>The context sensitivity of C&#8217;s grammar</a> <small>Context free grammars (CFGs) are a valuable theoretical tool on...</small></li><li><a href='http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/' rel='bookmark' title='Permanent Link: Recursive descent, LL and predictive parsers'>Recursive descent, LL and predictive parsers</a> <small> Introduction Although I&#8217;ve written some recursive-descent (RD) parsers by...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://eli.thegreenplace.net/2010/01/28/generating-random-sentences-from-a-context-free-grammar/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Book review: &#8220;Matplotlib for Python developers&#8221; by Sandro Tosi</title>
		<link>http://eli.thegreenplace.net/2010/01/27/book-review-matplotlib-for-python-developers-by-sandro-tosi/</link>
		<comments>http://eli.thegreenplace.net/2010/01/27/book-review-matplotlib-for-python-developers-by-sandro-tosi/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 14:32:12 +0000</pubDate>
		<dc:creator>eliben</dc:creator>
				<category><![CDATA[Book reviews]]></category>

		<guid isPermaLink="false">http://eli.thegreenplace.net/?p=2064</guid>
		<description><![CDATA[Disclaimer: this book (in electronic format) was provided to me for review by Packt publishing
matplotlib is the most popular plotting library for Python, and rightly so. It produces extremely high-quality plots suitable for publication, and thus, coupled with numpy and scipy is one of the major driving forces in the scientific Python community, which gets [...]


Related posts:<ol><li><a href='http://eli.thegreenplace.net/2008/07/26/matplotlib-plotting-with-python/' rel='bookmark' title='Permanent Link: matplotlib &#8211; plotting with Python'>matplotlib &#8211; plotting with Python</a> <small>matplotlib is a: python 2D plotting library which produces publication...</small></li><li><a href='http://eli.thegreenplace.net/2009/06/05/plotting-in-python-matplotlib-vs-pyqwt/' rel='bookmark' title='Permanent Link: Plotting in Python: matplotlib vs. PyQwt'>Plotting in Python: matplotlib vs. PyQwt</a> <small>When it comes to plotting and drawing graphs, Python has...</small></li><li><a href='http://eli.thegreenplace.net/2008/08/01/matplotlib-with-wxpython-guis/' rel='bookmark' title='Permanent Link: matplotlib with wxPython GUIs'>matplotlib with wxPython GUIs</a> <small>As I wrote in the last post, I found matplotlib...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><em>Disclaimer: this book (in electronic format) was provided to me for review by Packt publishing</em></p>
<p>matplotlib is the most popular plotting library for Python, and rightly so. It produces extremely high-quality plots suitable for publication, and thus, coupled with numpy and scipy is one of the major driving forces in the scientific Python community, which gets more and more active in the past few years.</p>
<p>The library has a comprehensive reference documentation, but few high-quality tutorials. This is the niche this book attempts to fill. It is divided into two main parts. The first (about 1/3 of the book) serves as a tutorial to matplotlib, presenting its various features in an increasing level of complexity. The second part consists of:</p>
<ul>
<li>Tutorials on integrating matplotlib with the major GUI frameworks used for Python &#8211; there are chapters for GTK+, wxPython and PyQt. These topics are commonly sought by beginning Python programmers (as the logs of my blog clearly show).</li>
<li>A chapter about &#8220;matplotlib on the web&#8221;, which is somewhat useless in my opinion, because it teaches absolutely nothing new about matplotlib.</li>
<li>A chapter called &#8220;matplotlib in the real world&#8221; which is a hodgepodge of data munging and plotting examples, which is either useful or not, depending on your experience and needs.</li>
</ul>
<p>The book could clearly use some editing of the English (the author is not a native speaker, which is fine, but means that the editors should have done a more thorough job). Also, it has a peculiar organization &#8211; sub-chapters and sections aren&#8217;t numbered, which is very unusual and confusing, and makes cross references impossible.</p>
<p>All in all, I can see how this book could be useful to some users. Mainly, I think, for scientists who don&#8217;t want to google everything and to wade through docs and tutorials and want everything in a single place. But for Python hackers seeking to just make some plots, I doubt it&#8217;s of great value. All the information is available online, and if you know how to look for it, there will be no trouble finding what you need, way faster than reading through this book.</p>
<img src="http://eli.thegreenplace.net/?ak_action=api_record_view&id=2064&type=feed" alt="" />

<p>Related posts:<ol><li><a href='http://eli.thegreenplace.net/2008/07/26/matplotlib-plotting-with-python/' rel='bookmark' title='Permanent Link: matplotlib &#8211; plotting with Python'>matplotlib &#8211; plotting with Python</a> <small>matplotlib is a: python 2D plotting library which produces publication...</small></li><li><a href='http://eli.thegreenplace.net/2009/06/05/plotting-in-python-matplotlib-vs-pyqwt/' rel='bookmark' title='Permanent Link: Plotting in Python: matplotlib vs. PyQwt'>Plotting in Python: matplotlib vs. PyQwt</a> <small>When it comes to plotting and drawing graphs, Python has...</small></li><li><a href='http://eli.thegreenplace.net/2008/08/01/matplotlib-with-wxpython-guis/' rel='bookmark' title='Permanent Link: matplotlib with wxPython GUIs'>matplotlib with wxPython GUIs</a> <small>As I wrote in the last post, I found matplotlib...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://eli.thegreenplace.net/2010/01/27/book-review-matplotlib-for-python-developers-by-sandro-tosi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
