<?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>For what IT worths &#187; python</title>
	<atom:link href="http://www.forwhatitworths.com/posts/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.forwhatitworths.com</link>
	<description>taking I.T. personally</description>
	<lastBuildDate>Thu, 20 May 2010 23:30:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Converting Project Gutenberg eTexts into BBeB eBooks</title>
		<link>http://www.forwhatitworths.com/posts/2007/11/converting-project-gutenberg-etexts-into-bbeb-ebooks/</link>
		<comments>http://www.forwhatitworths.com/posts/2007/11/converting-project-gutenberg-etexts-into-bbeb-ebooks/#comments</comments>
		<pubDate>Sun, 11 Nov 2007 08:29:53 +0000</pubDate>
		<dc:creator>tamasdecsi</dc:creator>
				<category><![CDATA[ebook]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.forwhatitworths.com/posts/2007/11/converting-project-gutenberg-etexts-into-bbeb-ebooks/</guid>
		<description><![CDATA[In my previous post I&#8217;ve shed some light on how the PRS505 ebook reader renders the various supported file formats. In the meantime, I couldn&#8217;t resist tinkering around with converting text ebooks into the better-rendering BBeB format.
While I see that creating quality ebooks this way is a long way ahead, a little piece of python [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous post I&#8217;ve shed some light on how the PRS505 ebook reader renders the various supported file formats. In the meantime, I couldn&#8217;t resist tinkering around with converting text ebooks into the better-rendering BBeB format.</p>
<p>While I see that creating quality ebooks this way is a long way ahead, a little piece of python script (<a href="http://files.forwhatitworths.com/gut2lrf.py">gut2lrf.py</a>) from my first attempt would certainly give <a href="http://www.gutenberg.org/"><img src="http://files.forwhatitworths.com/gutenberg_blog2.gif" alt="Project Gutenberg" width="80" height="15" /></a> eTexts a polish.</p>
<p>I started off checking the various existing tools to create BBeB (.lrf) files, and found <a href="http://www.sven.de/librie_files/makelrf3.zip">makelrf3</a> a simple yet good enough candidate to do the bytecode compilation with. In order to build a version running on linux, I needed to put together a small <a href="http://files.forwhatitworths.com/Makefile.makelrf3">Makefile</a>, but otherwise it compiled without problems.</p>
<p>Project Gutenberg, with more than 20,000 titles and growing, is an excellent source of free eTexts. However, in order to avoid file-format traps, the project has a strict policy of using plain text files for its text books. What more, there are some conventions keeping us from easily reflow the text within: <em>&#8220;Plain text eBooks should have line wraps at 72 characters and skip a line between paragraphs with no indentation.&#8221;</em></p>
<p>My little script &#8211; mentioned above &#8211; comes to aid here, as it preprocesses Project Gutenberg eTexts to remove unnecessary line breaks. It also fetches the Title and the Author of the book, and then calls makelrf3 to do the text to lrf conversion. Makelrf does a pretty good job splitting up the text to chapters, and quickly generates an lrf file.</p>
<p><img src="http://files.forwhatitworths.com/etext_before_and_after.jpg" alt="eText before and after" />The resulting eBook is in BBeB format, which means its file size is smaller than the original plain text document, and at the same time, it is laid out much better on the eBook reader, and also has some meta-info incorporated, which lets you find the book in the book list easier.</p>
<p>These compiled books are much better to read, yet they are still not perfect. They still lack the navigable Table of Contents, rich text formatting, such as stand-out Chapter headings, smaller spacings between paragraphs, words in italic or bold characters, illustrations, footnotes, as well as page headers and footers, so do expect some upgrades to my script down the line. Until that happens, I wish you happy reading on&#8230;</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F11%2Fconverting-project-gutenberg-etexts-into-bbeb-ebooks%2F&amp;title=Converting+Project+Gutenberg+eTexts+into+BBeB+eBooks" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F11%2Fconverting-project-gutenberg-etexts-into-bbeb-ebooks%2F&amp;title=Converting+Project+Gutenberg+eTexts+into+BBeB+eBooks" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F11%2Fconverting-project-gutenberg-etexts-into-bbeb-ebooks%2F&amp;title=Converting+Project+Gutenberg+eTexts+into+BBeB+eBooks" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F11%2Fconverting-project-gutenberg-etexts-into-bbeb-ebooks%2F&amp;title=Converting+Project+Gutenberg+eTexts+into+BBeB+eBooks" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F11%2Fconverting-project-gutenberg-etexts-into-bbeb-ebooks%2F&amp;title=Converting+Project+Gutenberg+eTexts+into+BBeB+eBooks', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F11%2Fconverting-project-gutenberg-etexts-into-bbeb-ebooks%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F11%2Fconverting-project-gutenberg-etexts-into-bbeb-ebooks%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F11%2Fconverting-project-gutenberg-etexts-into-bbeb-ebooks%2F&amp;title=Converting+Project+Gutenberg+eTexts+into+BBeB+eBooks" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F11%2Fconverting-project-gutenberg-etexts-into-bbeb-ebooks%2F&amp;title=Converting+Project+Gutenberg+eTexts+into+BBeB+eBooks" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://www.forwhatitworths.com/posts/2007/11/converting-project-gutenberg-etexts-into-bbeb-ebooks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A performance patch</title>
		<link>http://www.forwhatitworths.com/posts/2007/10/a-performance-patch/</link>
		<comments>http://www.forwhatitworths.com/posts/2007/10/a-performance-patch/#comments</comments>
		<pubDate>Sun, 28 Oct 2007 12:34:41 +0000</pubDate>
		<dc:creator>tamasdecsi</dc:creator>
				<category><![CDATA[profiling]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.forwhatitworths.com/posts/2007/10/a-performance-patch/</guid>
		<description><![CDATA[Back in May 2006, I needed to performance-tune a web application built on Plone. The symptom was an unacceptable 60 seconds delay upon creating a new user account on top of the already existing 10000 accounts. The source of the delay was very soon traced back by Zope&#8217;s built-in call profiler to GroupUserFolder, where the [...]]]></description>
			<content:encoded><![CDATA[<p>Back in May 2006, I needed to performance-tune a web application built on Plone. The symptom was an unacceptable 60 seconds delay upon creating a new user account on top of the already existing 10000 accounts. The source of the delay was very soon traced back by Zope&#8217;s built-in call profiler to <a href="http://ingeniweb.sourceforge.net/Products/GroupUserFolder/">GroupUserFolder</a>, where the solution was instantly obvious.</p>
<p>The original method was checking for existing users by using linear list lookup, which is known to be algorithmically slower than dictionary key lookup. Knowing that, the performance patch was a no-brainer, and, as expected, it eliminated the reported delay. I&#8217;ve sent this patch to <a href="http://www.ingeniweb.com/">ingeniweb</a> (the author of GroupUserFolder) in an email on 22 May 2006, but haven&#8217;t heard back from them since. Yet, the patch has been accepted, even got refined a bit and <a href="http://dev.plone.org/collective/changeset?new=GroupUserFolder%2Ftrunk%2FGroupUserFolder.py%4024794&amp;old=GroupUserFolder%2Ftrunk%2FGroupUserFolder.py%4024784">was applied</a> on the code trunk on 13 Jun 2006. From the one side, I&#8217;m happy to see it at least being fixed, while on the other side, I could have been more happy receiving a feedback on my report.</p>
<p>Nevertheless, I was still wondering how exactly the two lookup methods compare, so I&#8217;ve put together a <a href="http://files.forwhatitworths.com/haskey_vs_inlist.py">python script</a> to check how much we can actually gain on using <code>haystack_dict.has_key(needle)</code> instead of <code>needle in haystack_list</code>. I&#8217;ve compared them with small to larger sample sizes in small to larger sets (and lists) of samples.</p>
<p>I&#8217;ve used <a href="http://www.starlink.ac.uk/topcat">TOPCAT</a>, an excellent, yet easy to use visualization tool for tabular data, to graphically represent the results.</p>
<p><img src="http://files.forwhatitworths.com/haskey_vs_inlist.gif" alt="has_key vs in list" /></p>
<p>As you can see, even at the small sets of small samples region, has_key performs much faster, and with the growing set and sample sizes, it keeps performing equally well, while list lookup goes wild in the same time.</p>
<p>Can&#8217;t say I was surprised or learned anything by doing this, but thought I&#8217;d mention as it might turn out to be useful for someone out there, so let me know if you&#8217;ve found this useful.</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F10%2Fa-performance-patch%2F&amp;title=A+performance+patch" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F10%2Fa-performance-patch%2F&amp;title=A+performance+patch" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F10%2Fa-performance-patch%2F&amp;title=A+performance+patch" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F10%2Fa-performance-patch%2F&amp;title=A+performance+patch" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F10%2Fa-performance-patch%2F&amp;title=A+performance+patch', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F10%2Fa-performance-patch%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F10%2Fa-performance-patch%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F10%2Fa-performance-patch%2F&amp;title=A+performance+patch" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F10%2Fa-performance-patch%2F&amp;title=A+performance+patch" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://www.forwhatitworths.com/posts/2007/10/a-performance-patch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Phidgets</title>
		<link>http://www.forwhatitworths.com/posts/2007/08/phidgets/</link>
		<comments>http://www.forwhatitworths.com/posts/2007/08/phidgets/#comments</comments>
		<pubDate>Sun, 19 Aug 2007 09:27:20 +0000</pubDate>
		<dc:creator>tamasdecsi</dc:creator>
				<category><![CDATA[gadgets]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sensors]]></category>

		<guid isPermaLink="false">http://www.forwhatitworths.com/posts/2007/08/phidgets/</guid>
		<description><![CDATA[Phidget is a shorthand for &#8220;physical world widget&#8221;, which is some hardware sensor or controller connecting to a computer, originally created by students of University of Alberta, later packaged and distributed by Phidgets Inc..
Phidgets are a painless way to extend a USB-equipped computer&#8217;s interactions with the physical world, providing a wide range of sensors, displays, [...]]]></description>
			<content:encoded><![CDATA[<p>Phidget is a shorthand for &#8220;physical world widget&#8221;, which is some hardware sensor or controller connecting to a computer, originally created by students of University of Alberta, later packaged and distributed by <a href="http://www.phidgets.com/">Phidgets Inc.</a>.</p>
<p>Phidgets are a painless way to extend a USB-equipped computer&#8217;s interactions with the physical world, providing a wide range of sensors, displays, and controllers as simple as plugging them in. With an acceptable pricetag, phidgets open up a world of new possibilities for software developers with only limited skills in electronics, ultimately resulting in some <a href="http://www.phidgets.com/projects.php">fun projects</a>.</p>
<p>Phidgets Inc. provides software drivers and libraries for Windows, Windows CE, Mac OSX, and Linux, including driver source code (with a restrictive license, though). There are APIs for COM, Java, .Net, C, ActionScript, and bindings to a variety of languages to speed up development. Browsing the web and the <a href="http://www.phidgets.com/phpBB2/">forum for python support</a> I&#8217;ve also came across the <a href="http://packages.debian.org/stable/python/python-phidgets">python-phidgets</a> and the <a href="http://www.lothar.com/Projects/Phidgets/">phydget</a> projects that provide python bindings.</p>
<p>I decided to give phidgets a try, so I&#8217;ve purchased a 3-axis phidget accelerometer, a phidget interface kit with text-LCD, and a few analog sensors to measure temperature, magnetic fields, and light, and also a touch sensor. The sensors are going to be used in a home-automation project, while the accelerometer will somehow become an input device (thinking of something like the <a href="http://instruct1.cit.cornell.edu/courses/ee476/FinalProjects/s2005/mouse%20webpage%20KM249_AK288/">accelerometer mouse</a>).</p>
<p>With the limited time I have spent with my phidgets so far, I&#8217;ve added accelerometer support to <a href="http://www.lothar.com/Projects/Phidgets/">phydget</a> (should you be interested, here&#8217;s the source code for my <a href="http://files.forwhatitworths.com/phydgets-0.1.1.tar.gz">accelerometer-enabled version</a>), and created a minimalistic <a href="http://files.forwhatitworths.com/accelerometer-vpython.py">visualizer for the accelerometer readings</a> using the excellent <a href="http://www.vpython.org">vpython</a> library. More to come as soon as I could make some progress in either of my planned phidgets projects&#8230;</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F08%2Fphidgets%2F&amp;title=Phidgets" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F08%2Fphidgets%2F&amp;title=Phidgets" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F08%2Fphidgets%2F&amp;title=Phidgets" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F08%2Fphidgets%2F&amp;title=Phidgets" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F08%2Fphidgets%2F&amp;title=Phidgets', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F08%2Fphidgets%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F08%2Fphidgets%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F08%2Fphidgets%2F&amp;title=Phidgets" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F08%2Fphidgets%2F&amp;title=Phidgets" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://www.forwhatitworths.com/posts/2007/08/phidgets/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The FixedPointField bug</title>
		<link>http://www.forwhatitworths.com/posts/2007/07/the-fixedpointfield-bug/</link>
		<comments>http://www.forwhatitworths.com/posts/2007/07/the-fixedpointfield-bug/#comments</comments>
		<pubDate>Sun, 01 Jul 2007 09:39:35 +0000</pubDate>
		<dc:creator>tamasdecsi</dc:creator>
				<category><![CDATA[debugging]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.forwhatitworths.com/?p=7</guid>
		<description><![CDATA[Some time a year ago I have spent several unpleasant hours spread across two entire weeks tracing down a very nasty bug in FixedPointField, which is part of the Plone Archetypes code base. During the test phase of a web application built upon Plone, some of the numbers have mysteriously changed their signs. At first [...]]]></description>
			<content:encoded><![CDATA[<p>Some time a year ago I have spent several unpleasant hours spread across two entire weeks tracing down a very nasty bug in FixedPointField, which is part of the Plone Archetypes code base. During the test phase of a web application built upon Plone, some of the numbers have mysteriously changed their signs. At first sight it seemed totally indeterministic. At a second glance, it seemed that in all occurrences of the phenomenon, the numbers turned positive from negative. However, only a few numbers did this. I&#8217;ve spent several hours checking all related code for a wrong clause, all without success.</p>
<p>It took quite a time to realize that all the affected numbers are always small. Then I wrote unit tests to determine the range in which the numbers fail to keep their signs. That turned out to be the range of (-1.0 .. 0.0). That was the point when I was beginning to suspect that there&#8217;s something fishy in the underlying maths&#8230; so I descended to the realm of Plone and Archetypes code to narrow down the problematic part. It wasn&#8217;t too long before I found that the sign gets lost in the following piece of code from <a href="http://svn.plone.org/svn/archetypes/Archetypes/trunk/Field.py">Archetypes/Fields.py</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="python python" style="font-family:monospace;">value = value.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span><span style="color: black;">&#41;</span>
__traceback_info__ = <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, value<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>lt; <span style="color: #ff4500;">2</span>:
    value = <span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>, 0<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
    fra = value<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>:<span style="color: #008000;">self</span>.<span style="color: black;">precision</span><span style="color: black;">&#93;</span>
fra += <span style="color: #483d8b;">'0'</span> <span style="color: #66cc66;">*</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">precision</span> - <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>fra<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;">#handle leading comma e.g. .36</span>
<span style="color: #ff7700;font-weight:bold;">if</span> value<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span>==<span style="color: #483d8b;">''</span>:
    value<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span>=<span style="color: #483d8b;">'0'</span>
    value = <span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>fra<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">return</span> value</pre></div></div>

<p>Arrgh. Too bad. I wish I had never seen this code. Archetypes has reinvented fixed point storage and handling in a very &#8211; hmm &#8211; &#8220;clever&#8221; way. For those the problem still isn&#8217;t obvious, let&#8217;s see how, say, &#8220;-0.5&#8243; gets handled: as a string it gets split into whole and fraction at the decimal separator, and only then it gets converted into integer. Too bad there&#8217;s no difference between -0 and 0, isn&#8217;t it? So &#8220;-0.5&#8243; becomes (&#8221;-0&#8243;,&#8221;5&#8243;), and finally ending up as (0,5), which equals to &#8220;0.5&#8243;.</p>
<p>The fix, from here, is obvious, though it raises some concerns. First I thought the sign need to be stored separately in the value tuple, however, that would mean tuples from there on will consist of 3 items, so the code becomes incompatible with already existing FixedPointField values in the world, which is a big no-no. This leaves us with the sole chance of applying sign to the fraction when in range (-1..0). Let&#8217;s see how much of the code need to be changed for that:</p>

<div class="wp_syntax"><div class="code"><pre class="python python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#handle leading comma e.g. .36</span>
<span style="color: #ff7700;font-weight:bold;">if</span> value<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span>==<span style="color: #483d8b;">''</span> <span style="color: #ff7700;font-weight:bold;">or</span> value<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span>==<span style="color: #483d8b;">'-'</span>:
    value<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span>+=<span style="color: #483d8b;">'0'</span>
value = <span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>fra<span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>,-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>value<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span>==<span style="color: #483d8b;">'-0'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Since this stores &#8220;-0.5&#8243; as (0,-5), we also need to change the get() method:</p>

<div class="wp_syntax"><div class="code"><pre class="python python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> get<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, instance, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
    template = <span style="color: #483d8b;">'%%d.%%0%dd'</span> <span style="color: #66cc66;">%</span> <span style="color: #008000;">self</span>.<span style="color: black;">precision</span>
    value = ObjectField.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, instance, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>
    __traceback_info__ = <span style="color: black;">&#40;</span>template, value<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> value <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>: <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">getDefault</span><span style="color: black;">&#40;</span>instance<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>value, <span style="color: #008000;">basestring</span><span style="color: black;">&#41;</span>: value = <span style="color: #008000;">self</span>._to_tuple<span style="color: black;">&#40;</span>instance, value<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> template <span style="color: #66cc66;">%</span> value</pre></div></div>

<p>To something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="python python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> get<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, instance, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
     template = <span style="color: #483d8b;">'%%s%%d.%%0%dd'</span> <span style="color: #66cc66;">%</span> <span style="color: #008000;">self</span>.<span style="color: black;">precision</span>
     value = ObjectField.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, instance, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>
     __traceback_info__ = <span style="color: black;">&#40;</span>template, value<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> value <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>: <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">getDefault</span><span style="color: black;">&#40;</span>instance<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>value, <span style="color: #008000;">basestring</span><span style="color: black;">&#41;</span>:
        value = <span style="color: #008000;">self</span>._to_tuple<span style="color: black;">&#40;</span>instance, value<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> template <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">''</span>,<span style="color: #483d8b;">'-'</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>value<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">&amp;</span>lt;0<span style="color: black;">&#93;</span>,value<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span>,<span style="color: #008000;">abs</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>And we&#8217;re done. Nevertheless, code quality remains questionable. (how do you change precision on the fly, for example. And I dare not mention performance issues of all those unnecessary string to integer and vice versa conversions.)</p>
<p>Unfortunately, submitting this bug report and patch isn&#8217;t so obvious as the fix. <a href="http://dev.plone.org/archetypes/">Archetypes trac</a> only accepts new issues from registered members, but doesn&#8217;t provide a link to register. The Plone support page mentions the <a href="http://dev.plone.org/plone">Plone issue tracker</a>, which does link to a page where you can register, but registration for some reason failed in my case, because either the e-mail or the user name was considered wrong, even after several different attempts. And finally, nobody really cared on the Plone support mailing list either. Sorry guys, you lost my vote there and then. Recent svn still has the bug, and it is unlikely to be fixed without being reported.</p>
<p>The lessons to be learned here are:</p>
<ol>
<li>for me not to take any &#8220;complete&#8221; frameworks granted as bug-free, even in the basics.</li>
<li>for developers in general, that no matter how clever you&#8217;re trying to reinvent the wheel, it is almost certain that there will be something overlooked, potentially causing nasty corner case bugs, so unless there is a rock solid reason behind reworking basic methods from scratch, it does not worth the potential havoc it surely going to wreak.</li>
<li>for the Plone project to set up at least one obvious, and working channel to submit bug reports and patches.</li>
</ol>
<p><em>UPDATE 05 Sep 2008: the above fix has finally been integrated into plone codebase, <a href="http://dev.plone.org/plone/ticket/7549">changelog here</a>. Thanks, Maurits! </em></pre>
</pre>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F07%2Fthe-fixedpointfield-bug%2F&amp;title=The+FixedPointField+bug" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F07%2Fthe-fixedpointfield-bug%2F&amp;title=The+FixedPointField+bug" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F07%2Fthe-fixedpointfield-bug%2F&amp;title=The+FixedPointField+bug" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F07%2Fthe-fixedpointfield-bug%2F&amp;title=The+FixedPointField+bug" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F07%2Fthe-fixedpointfield-bug%2F&amp;title=The+FixedPointField+bug', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F07%2Fthe-fixedpointfield-bug%2F" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F07%2Fthe-fixedpointfield-bug%2F" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F07%2Fthe-fixedpointfield-bug%2F&amp;title=The+FixedPointField+bug" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.forwhatitworths.com%2Fposts%2F2007%2F07%2Fthe-fixedpointfield-bug%2F&amp;title=The+FixedPointField+bug" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://www.forwhatitworths.com/posts/2007/07/the-fixedpointfield-bug/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
