<?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>~Nacho/blog &#187; Software</title>
	<atom:link href="http://criptonita.com/~nacho/blog/category/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://criptonita.com/~nacho/blog</link>
	<description>the cutting edge of my mind!</description>
	<lastBuildDate>Fri, 22 Apr 2011 14:01:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Local public transportation in my pocket</title>
		<link>http://criptonita.com/~nacho/blog/2011/03/29/local-public-pocket/</link>
		<comments>http://criptonita.com/~nacho/blog/2011/03/29/local-public-pocket/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 12:08:51 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/?p=417</guid>
		<description><![CDATA[I&#8217;ve lately spent some time developing a webapp for mobile devices to interact with some of the data published by the Gijón City Council. More specifically, data about local public land transportation schedule and live arrivals. The way they are presenting that information for mobile devices at the moment is very very heavy and slow, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve lately spent some time developing a webapp for mobile devices to interact with some of the data published by <a href="http://www.gijon.es">the Gijón City Council</a>. More specifically, data about local public land transportation schedule and live arrivals. The way they are presenting that information for mobile devices at the moment is very very heavy and slow, so I thought it may be useful to do something simpler for personal usage.</p>
<p>Basically, it is a simple web service that intensively caches data (to avoid stressing the data origin with many requests) and a fancy AJAX-powered frontend with some CSS with mobile browsers in mind (works flawlessly on Android&#8217;s browser and Mobile Safari). Additionally, if you add it as a bookmark to your iPhone&#8217;s home screen it behaves like a native application (you know, splash screen, custom icon, taskbar and so on).</p>
<p>I&#8217;m now working on client-side caching using HTML5 caching for offline usage. This way the application will boot way faster. It&#8217;s almost done, but it still needs some debugging.</p>
<p>I don&#8217;t intend to make it public for now. However, if you find it useful feel free to drop me a line. Beta testers are always welcome (but unfortunately won&#8217;t be rewarded).</p>
<p>This is how it looks like at the moment. The source will be released soon.</p>
<p><strong>Update (23:26):</strong> Android screenshots provided by <a href="http://pozueco.net/">Javier Pozueco</a>. Thanks buddy!</p>
<p><a href="http://criptonita.com/~nacho/blog/wp-content/uploads/2011/03/c1.png"><img class="alignleft size-full wp-image-418" title="c1" src="http://criptonita.com/~nacho/blog/wp-content/uploads/2011/03/c1.png" alt="" width="320" height="480" /></a><a href="http://criptonita.com/~nacho/blog/wp-content/uploads/2011/03/c2.png"><img class="alignright size-full wp-image-419" title="c2" src="http://criptonita.com/~nacho/blog/wp-content/uploads/2011/03/c2.png" alt="" width="320" height="480" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><a href="http://criptonita.com/~nacho/blog/wp-content/uploads/2011/03/c4.png"><img class="alignleft size-full wp-image-448" title="c4" src="http://criptonita.com/~nacho/blog/wp-content/uploads/2011/03/c4.png" alt="" width="320" height="480" /></a><a href="http://criptonita.com/~nacho/blog/wp-content/uploads/2011/03/c5.png"><img class="alignright size-full wp-image-449" title="c5" src="http://criptonita.com/~nacho/blog/wp-content/uploads/2011/03/c5.png" alt="" width="320" height="480" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><a href="http://criptonita.com/~nacho/blog/wp-content/uploads/2011/03/c3.jpg"><img class="aligncenter size-full wp-image-420" title="c3" src="http://criptonita.com/~nacho/blog/wp-content/uploads/2011/03/c3.jpg" alt="" width="480" height="320" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2011/03/29/local-public-pocket/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Search term completion using a search tree</title>
		<link>http://criptonita.com/~nacho/blog/2011/03/24/term-completion-using-a-pythonic-search-tree/</link>
		<comments>http://criptonita.com/~nacho/blog/2011/03/24/term-completion-using-a-pythonic-search-tree/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 11:31:36 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/?p=363</guid>
		<description><![CDATA[*lol* Nowadays it&#8217;s very usual to find websites offering hints while you&#8217;re typing on a search box. Google is a pretty good example of it. But, how could it be implemented? This feature could be implemented either in the client side or in the server side. If the word list is big (usually it is), [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter" title="Google search box completion" src="http://s4.hubimg.com/u/2092171_f520.jpg" alt="Google search box completion" width="520" height="378" /></p>
<p><strong>*lol*</strong></p>
<p>Nowadays it&#8217;s very usual to find websites offering hints while you&#8217;re typing on a search box. Google is a pretty good example of it. But, how could it be implemented?</p>
<p>This feature could be implemented either in the client side or in the server side. If the word list is big (usually it is), it&#8217;s recommended to keep the lookup logic in the server side to save some bytes while transferring the page to the client and also to save some computing power using server-side caches (cool when you plan to serve many requests).</p>
<p>Either way, there should be a data structure somewhere containing the word list and an algorithm to do the lookup. The simplest approach may be to use a list to store the words and issue something like this when you want to get a list of hints for a given prefix:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">filter</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x: x.<span style="color: black;">startsWith</span><span style="color: black;">&#40;</span>prefix<span style="color: black;">&#41;</span>, word_list<span style="color: black;">&#41;</span></pre></div></div>

<p>That&#8217;s Python&#8217;s <em>filter</em>, but it works the same way the well-known Haskell&#8217;s first-order function <em>filter</em> does. It builds a new list with the elements of the original list (word_list) that match the predicate (the lambda function).</p>
<p>Although the results can (and should) be cached, the very first lookup (or when the cache expires) would be very inefficient because the entire list must be traversed and that operation will take linear time. Not bad, but when the size of the problem gets bigger (i.e. more and more words in the database) the lookup process may be too slow, especially whether you&#8217;re serving several users at the same time. If the list was sorted, the execution time could be improved a little bit by writing a more sophisticated algorithm, but let&#8217;s keep it that way for now.</p>
<p>Fortunately, there are better and faster ways to face the problem. If you don&#8217;t want to write code (usually the best choice) you may use some high-performance indexing engine such as Apache Lucene. But if you prefer the &#8216;do-it-yourself&#8217; way (for learning purposes), a search tree (more specifically, a <em>trie</em> or a prefix tree) is a good approach.</p>
<p>I&#8217;ve poorly benchmarked both alternatives (the list and the tree) and as expected the tree is pretty quicker generating hints. What I did was to feed both data structures with the content of an American English word list holding ~640k words (debian package <em>wamerican-insane</em>).</p>
<p>So, assuming four is a reasonable minimum prefix length, I measured the time it would take to get a list of words prefixed by <em>hous</em> (yes, just one, remember I said this was a poor benchmark? ;). Unsurprisingly, it took around 230 times longer for the list alternative to generate the hints (438.96 ms vs 1.92 ms). Wow.</p>
<p>My implementation of the tree is as follows. The API is quite straightforward, the &#8220;hot&#8221; methods are <em>put</em> and <em>get_hints</em>. I&#8217;ve stripped off the test suite for space reasons.</p>
<p>Usage example:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> tree = HintSearchTree<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">put</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nacho&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">put</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nachos&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">put</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nachete&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">get_hints</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nach&quot;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'nachete'</span>, <span style="color: #483d8b;">'nacho'</span>, <span style="color: #483d8b;">'nachos'</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">get_hints</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nacho&quot;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'nacho'</span>, <span style="color: #483d8b;">'nachos'</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">delete</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nacho&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">get_hints</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nacho&quot;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'nachos'</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">count_words</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">2</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">get_hints</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;n&quot;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'nachete'</span>, <span style="color: #483d8b;">'nachos'</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">is_indexed</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nachete&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">True</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">is_indexed</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nach&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">False</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tree.<span style="color: black;">empty</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">False</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> HintSearchTreeNode<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
<span style="color: #ff7700;font-weight:bold;">class</span> HintSearchTreeNode<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent=<span style="color: #008000;">None</span>, terminal=<span style="color: #008000;">False</span><span style="color: black;">&#41;</span>:
    <span style="color: #008000;">self</span>._children = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    <span style="color: #008000;">self</span>._terminal = terminal
    <span style="color: #008000;">self</span>._parent = parent
&nbsp;
  @<span style="color: #008000;">property</span>
  <span style="color: #ff7700;font-weight:bold;">def</span> children<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._children
&nbsp;
  @<span style="color: #008000;">property</span>
  <span style="color: #ff7700;font-weight:bold;">def</span> terminal<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._terminal
&nbsp;
  @terminal.<span style="color: black;">setter</span>
  <span style="color: #ff7700;font-weight:bold;">def</span> terminal<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, value<span style="color: black;">&#41;</span>:
    <span style="color: #008000;">self</span>._terminal = value
&nbsp;
  @<span style="color: #008000;">property</span>
  <span style="color: #ff7700;font-weight:bold;">def</span> parent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._parent
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> HintSearchTree<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
    <span style="color: #008000;">self</span>._root = HintSearchTreeNode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> put<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, word<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Adds a word to the tree.&quot;&quot;&quot;</span>
    <span style="color: #808080; font-style: italic;"># TODO: Sanitize 'word'</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>word<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>gt<span style="color: #66cc66;">;</span> <span style="color: #ff4500;">0</span>:
      <span style="color: #008000;">self</span>._put<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._root, word<span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> count_words<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Retrieves the number of indexed words in the tree.&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._count_words<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._root<span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> is_indexed<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, word<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Returns True if 'word' is indexed.&quot;&quot;&quot;</span>
    node = <span style="color: #008000;">self</span>._find<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._root, word<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> node <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span> <span style="color: #ff7700;font-weight:bold;">and</span> node.<span style="color: black;">terminal</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">True</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> get_hints<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, prefix<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Returns a list of words prefixed by 'prefix'.&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._match_prefix<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._root, prefix<span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> delete<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, word<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Deletes 'word' (if exists) from the tree.&quot;&quot;&quot;</span>
    terminal = <span style="color: #008000;">self</span>._find<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._root, word<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> terminal <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
      terminal.<span style="color: black;">terminal</span> = <span style="color: #008000;">False</span>
      <span style="color: #008000;">self</span>._prune<span style="color: black;">&#40;</span>terminal.<span style="color: black;">parent</span>, word<span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> empty<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Returns True if the tree contains no elements.&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._root.<span style="color: black;">children</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> _put<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, node, word, depth=<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
    next_node = node.<span style="color: black;">children</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span>word<span style="color: black;">&#91;</span>depth<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> next_node <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
      next_node = HintSearchTreeNode<span style="color: black;">&#40;</span>parent=node<span style="color: black;">&#41;</span>
      node.<span style="color: black;">children</span><span style="color: black;">&#91;</span>word<span style="color: black;">&#91;</span>depth<span style="color: black;">&#93;</span><span style="color: black;">&#93;</span> = next_node
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>word<span style="color: black;">&#41;</span>-<span style="color: #ff4500;">1</span> == depth:
      next_node.<span style="color: black;">terminal</span> = <span style="color: #008000;">True</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
      <span style="color: #008000;">self</span>._put<span style="color: black;">&#40;</span>next_node, word, depth+<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> _count_words<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, node<span style="color: black;">&#41;</span>:
    words = <span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">if</span> node.<span style="color: black;">terminal</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">True</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> node.<span style="color: black;">children</span>:
      words += <span style="color: #008000;">self</span>._count_words<span style="color: black;">&#40;</span>node.<span style="color: black;">children</span><span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> words
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> _match_prefix<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, node, prefix<span style="color: black;">&#41;</span>:
    terminal = <span style="color: #008000;">self</span>._find<span style="color: black;">&#40;</span>node, prefix<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> terminal <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
      <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._harvest_node<span style="color: black;">&#40;</span>terminal, prefix<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
      <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> _harvest_node<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, node, prefix, path=<span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>:
    hints = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> node.<span style="color: black;">terminal</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">True</span>:
      hints.<span style="color: black;">append</span><span style="color: black;">&#40;</span>prefix + path<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> node.<span style="color: black;">children</span>:
      hints.<span style="color: black;">extend</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._harvest_node<span style="color: black;">&#40;</span>node.<span style="color: black;">children</span><span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span>, prefix, path+k<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> hints
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> _find<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, node, word, depth=<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> depth == <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>word<span style="color: black;">&#41;</span>:
      <span style="color: #ff7700;font-weight:bold;">return</span> node
    <span style="color: #ff7700;font-weight:bold;">else</span>:
      child = node.<span style="color: black;">children</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span>word<span style="color: black;">&#91;</span>depth<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
      <span style="color: #ff7700;font-weight:bold;">if</span> child <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._find<span style="color: black;">&#40;</span>child, word, depth+<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
      <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> _prune<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, node, word<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>._count_words<span style="color: black;">&#40;</span>node.<span style="color: black;">children</span><span style="color: black;">&#91;</span>word<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>:
      <span style="color: #ff7700;font-weight:bold;">del</span> node.<span style="color: black;">children</span><span style="color: black;">&#91;</span>word<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>
      <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>node.<span style="color: black;">children</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">and</span> node.<span style="color: black;">parent</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span> \
          <span style="color: #ff7700;font-weight:bold;">and</span> node.<span style="color: black;">terminal</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">True</span>:
        <span style="color: #008000;">self</span>._prune<span style="color: black;">&#40;</span>node.<span style="color: black;">parent</span>, word<span style="color: black;">&#91;</span>:-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>The code is released in the public domain.</p>
]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2011/03/24/term-completion-using-a-pythonic-search-tree/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some Perl to redirect HTTP requests</title>
		<link>http://criptonita.com/~nacho/blog/2011/02/24/some-perl-bits-to-redirect-http-requests/</link>
		<comments>http://criptonita.com/~nacho/blog/2011/02/24/some-perl-bits-to-redirect-http-requests/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 21:55:33 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/?p=325</guid>
		<description><![CDATA[After almost a year without publishing a single post, it seems this week I&#8217;m going to beat all my records. A week ago, I wanted to prank my brother for a while. Nothing sophisticated&#8230; just some Iptables rules, Tinyproxy and HTTP magic. To go ahead with my evil plans, I needed &#8220;something&#8221; able to redirect [...]]]></description>
			<content:encoded><![CDATA[<p>After almost a year without publishing a single post, it seems this week I&#8217;m going to beat all my records.</p>
<p>A week ago, I wanted to prank my brother for a while. Nothing sophisticated&#8230; just some Iptables rules, Tinyproxy and HTTP magic. To go ahead with my evil plans, I needed &#8220;something&#8221; able to redirect a HTTP request. Actually, there are several ways to do that: Apache redirects, Tornado, Netcat* and so on. These alternatives are fast, bulletproof and time-saving, but not fun.</p>
<p>As many of you probably know, I didn&#8217;t get a job yet. That necessary means that I&#8217;ve got plenty of free time to waste. So&#8230; what did I do? I wrote some Perl and today I&#8217;m publishing the source code just in case someone finds it useful somehow. Like the previous entry, it&#8217;s published in the public domain.</p>
<p>The script just collects connections, issues <em>301</em> back (Moved Permanently) and sets <em>Location</em> to the URI specified as a command line argument (option -u). It lacks some security checks (left as an exercise to the reader) but it does what it is supposed to do. You may likely spot some silly bugs as I haven&#8217;t spent much time reading it again. Reports are welcome!</p>
<p>For those wondering, the prank was a big success. I&#8217;m afraid I can&#8217;t spare any detail by now but it turns out my bro is still thinking that his computer has been cracked.</p>
<p>Example invocation:</p>
<blockquote><p>$ <strong>perl redir.pl -p 7070 -v -t 3 -u http://31337.pl</strong><br />
2011/02/24 21:41:54 Listening on port 7070<br />
2011/02/24 21:41:54 Redirecting HTTP requests to: &#8216;http://31337.pl&#8217;<br />
2011/02/24 21:41:54 3 thread(s) working under the hood<br />
&#8230;</p></blockquote>
<p>And finally the source code:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> threads<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> Thread<span style="color: #339933;">::</span><span style="color: #006600;">Queue</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> POSIX<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> IO<span style="color: #339933;">::</span><span style="color: #006600;">Socket</span><span style="color: #339933;">::</span><span style="color: #006600;">INET</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> HTTP<span style="color: #339933;">::</span><span style="color: #006600;">Request</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> HTTP<span style="color: #339933;">::</span><span style="color: #006600;">Status</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>constants status_message<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> Getopt<span style="color: #339933;">::</span><span style="color: #006600;">Long</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DateTime<span style="color: #339933;">::</span><span style="color: #006600;">Format</span><span style="color: #339933;">::</span><span style="color: #006600;">HTTP</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Data<span style="color: #339933;">::</span><span style="color: #006600;">Validate</span><span style="color: #339933;">::</span><span style="color: #006600;">URI</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>is_http_uri<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Log<span style="color: #339933;">::</span><span style="color: #006600;">Log4perl</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>easy<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> constant MAX_THREADS <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> constant MAX_LEN_HEADERS_BUFFER <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">1024</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> constant DEFAULT_REDIRECT_URI <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;http://www.example.org&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> constant DEFAULT_PORT <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">80</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> constant DEFAULT_POOL_SIZE <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$redir_uri</span> <span style="color: #339933;">=</span> DEFAULT_REDIRECT_URI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$server_port</span> <span style="color: #339933;">=</span> DEFAULT_PORT<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$thread_pool_size</span> <span style="color: #339933;">=</span> DEFAULT_POOL_SIZE<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$verbose</span><span style="color: #339933;">;</span>
&nbsp;
GetOptions<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'url=s'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">\$redir_uri</span><span style="color: #339933;">,</span> 
           <span style="color: #ff0000;">'port=i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">\$server_port</span><span style="color: #339933;">,</span>
           <span style="color: #ff0000;">'threads=i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">\$thread_pool_size</span><span style="color: #339933;">,</span>
           <span style="color: #ff0000;">'verbose'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">\$verbose</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">or</span> <span style="color: #000066;">exit</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;Invalid redirect URI (e.g. http://www.example.org)<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #b1b100;">unless</span> is_http_uri<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$redir_uri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;Invalid port (e.g. 8080)<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #b1b100;">unless</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000ff;">$server_port</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #0000ff;">$server_port</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">**</span><span style="color: #cc66cc;">16</span><span style="color: #339933;">;</span>
<span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;Invalid pool size (should be in [1..&quot;</span><span style="color: #339933;">.</span>MAX_THREADS<span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;])<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> 
            <span style="color: #b1b100;">unless</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000ff;">$thread_pool_size</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #0000ff;">$thread_pool_size</span> <span style="color: #339933;">&lt;=</span> MAX_THREADS<span style="color: #339933;">;</span>
&nbsp;
Log<span style="color: #339933;">::</span><span style="color: #006600;">Log4perl</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">easy_init</span><span style="color: #009900;">&#40;</span> level <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$verbose</span><span style="color: #339933;">?</span> <span style="color: #0000ff;">$DEBUG</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">$INFO</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$pending</span> <span style="color: #339933;">=</span> Thread<span style="color: #339933;">::</span><span style="color: #006600;">Queue</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$lsock</span> <span style="color: #339933;">=</span> IO<span style="color: #339933;">::</span><span style="color: #006600;">Socket</span><span style="color: #339933;">::</span><span style="color: #006600;">INET</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span> LocalPort <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$server_port</span><span style="color: #339933;">,</span>
                                   Proto <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'tcp'</span><span style="color: #339933;">,</span>
                                   Listen <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
                                   Reuse <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">or</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;Couldn't bind listening socket ($!)<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> 
&nbsp;
INFO<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Listening on port $server_port<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
INFO<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Redirecting HTTP requests to: '$redir_uri'<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@workers</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">..</span><span style="color: #0000ff;">$thread_pool_size</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$thread</span> <span style="color: #339933;">=</span> threads<span style="color: #339933;">-&gt;</span><span style="color: #006600;">create</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;worker&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@workers</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$thread</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
DEBUG<span style="color: #009900;">&#40;</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d thread(s) working under the hood<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$#workers</span><span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Set a tidy shutdown just in case an external agent SIG{INT,TERM}s the process</span>
<span style="color: #0000ff;">$SIG</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'INT'</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$SIG</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'TERM'</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;"># Dirty hack. threads-&gt;kill() does not wake up the thread :(</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">..</span><span style="color: #0000ff;">@workers</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #0000ff;">$pending</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">enqueue</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@workers</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        DEBUG<span style="color: #009900;">&#40;</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Worker %d terminated: %d clients served<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$_</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">tid</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$_</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">join</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$lsock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #000066;">exit</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> 
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$csock</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$lsock</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">accept</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">or</span> <span style="color: #b1b100;">next</span><span style="color: #339933;">;</span>
    <span style="color: #0000ff;">$pending</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">enqueue</span><span style="color: #009900;">&#40;</span>POSIX<span style="color: #339933;">::</span><span style="color: #006600;">dup</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">fileno</span> <span style="color: #0000ff;">$csock</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    DEBUG<span style="color: #009900;">&#40;</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;New client enqueued: %s:%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$csock</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">peerhost</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$csock</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">peerport</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$csock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> worker <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$clients_served</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$fd</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$pending</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">dequeue</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #666666; font-style: italic;"># API promises thread safety :-)</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$fd</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066;">return</span> <span style="color: #0000ff;">$clients_served</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sock</span> <span style="color: #339933;">=</span> IO<span style="color: #339933;">::</span><span style="color: #006600;">Socket</span><span style="color: #339933;">::</span><span style="color: #006600;">INET</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new_from_fd</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$fd</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;r+&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        DEBUG<span style="color: #009900;">&#40;</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Dequeued client %s:%d by worker %d.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$sock</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">peerhost</span><span style="color: #339933;">,</span>
                            <span style="color: #0000ff;">$sock</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">peerport</span><span style="color: #339933;">,</span> threads<span style="color: #339933;">-&gt;</span><span style="color: #006600;">tid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$buf</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&lt;</span><span style="color: #0000ff;">$sock</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;"># CAUTION: there isn't any self protection against very long lines</span>
            <span style="color: #b1b100;">last</span> <span style="color: #b1b100;">if</span> <span style="color: #009966; font-style: italic;">/^\r\n$/</span><span style="color: #339933;">;</span>
            <span style="color: #0000ff;">$buf</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">$_</span><span style="color: #339933;">;</span>
            <span style="color: #000066;">goto</span> BYE <span style="color: #b1b100;">if</span> <span style="color: #000066;">length</span> <span style="color: #0000ff;">$buf</span> <span style="color: #339933;">&gt;</span> MAX_LEN_HEADERS_BUFFER<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$request</span> <span style="color: #339933;">=</span> HTTP<span style="color: #339933;">::</span><span style="color: #006600;">Request</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">parse</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$buf</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            INFO<span style="color: #009900;">&#40;</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;[%s] %s {%s}<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">method</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">uri</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$sock</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">peerhost</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000066;">printf</span> <span style="color: #0000ff;">$sock</span> <span style="color: #ff0000;">&quot;HTTP/1.1 %d %s<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> 
            HTTP_MOVED_PERMANENTLY<span style="color: #339933;">,</span> status_message<span style="color: #009900;">&#40;</span>HTTP_MOVED_PERMANENTLY<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">printf</span> <span style="color: #0000ff;">$sock</span> <span style="color: #ff0000;">&quot;Date: %s<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> DateTime<span style="color: #339933;">::</span><span style="color: #006600;">Format</span><span style="color: #339933;">::</span><span style="color: #006600;">HTTP</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">format_datetime</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">print</span> <span style="color: #0000ff;">$sock</span> <span style="color: #ff0000;">&quot;Location: $redir_uri<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">print</span> <span style="color: #0000ff;">$sock</span> <span style="color: #ff0000;">&quot;Server: Simple HTTP Redirection/0.1 ($^O)<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">print</span> <span style="color: #0000ff;">$sock</span> <span style="color: #ff0000;">&quot;Connection: close<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">print</span> <span style="color: #0000ff;">$sock</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
BYE<span style="color: #339933;">:</span>  
        <span style="color: #0000ff;">$clients_served</span><span style="color: #339933;">++;</span>
        <span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sock</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>(*) just an approach, may drop connections:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; 
 <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;HTTP/1.1 301 Moved Permanently<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>Location: http://31337.pl<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> nc <span style="color: #660033;">-l</span> <span style="color: #000000;">7070</span>; 
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2011/02/24/some-perl-bits-to-redirect-http-requests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reverse Polish Notation Evaluation in Python</title>
		<link>http://criptonita.com/~nacho/blog/2011/02/23/reverse-polish-notation-evaluation-in-python/</link>
		<comments>http://criptonita.com/~nacho/blog/2011/02/23/reverse-polish-notation-evaluation-in-python/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 00:03:21 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Math]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/?p=305</guid>
		<description><![CDATA[This introduction is followed by some Python code (function evaluate_postfix_expr) to evaluate expressions (only integers, but may be extended with ease) in Reverse Polish Notation (RPN). Some simple tests are also included in the bundle. I agree it&#8217;s a little useless, but I thought it might be useful for someone (CS students maybe?). If you [...]]]></description>
			<content:encoded><![CDATA[<p>This introduction is followed by some Python code (function evaluate_postfix_expr) to evaluate expressions (only integers, but may be extended with ease) in Reverse Polish Notation (RPN). Some simple tests are also included in the bundle.</p>
<p>I agree it&#8217;s a little useless, but I thought it might be useful for someone (CS students maybe?). If you want to examine the stack in each iteration you only have to turn debugging on. That can be accomplished by changing <em>logging.INFO</em> to <em>logging.DEBUG</em> (line 7).</p>
<p>Copy, distribute or do whatever you want with it. It&#8217;s released in the public domain.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">logging</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">unittest</span>
&nbsp;
<span style="color: #dc143c;">logging</span>.<span style="color: black;">basicConfig</span><span style="color: black;">&#40;</span>level=<span style="color: #dc143c;">logging</span>.<span style="color: black;">INFO</span><span style="color: black;">&#41;</span>
&nbsp;
operators_table = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'+'</span>: <span style="color: #008000;">int</span>.<span style="color: #0000cd;">__add__</span>, 
             <span style="color: #483d8b;">'-'</span>: <span style="color: #008000;">int</span>.<span style="color: #0000cd;">__sub__</span>,
             <span style="color: #483d8b;">'*'</span>: <span style="color: #008000;">int</span>.<span style="color: #0000cd;">__mul__</span>,
             <span style="color: #483d8b;">'/'</span>: <span style="color: #008000;">int</span>.<span style="color: #0000cd;">__div__</span>,
             <span style="color: #483d8b;">'^'</span>: <span style="color: #008000;">int</span>.<span style="color: #0000cd;">__pow__</span><span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> ExpressionError<span style="color: black;">&#40;</span><span style="color: #008000;">Exception</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, message<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>._message = <span style="color: #483d8b;">&quot;Expression error: %s&quot;</span> <span style="color: #66cc66;">%</span> message
    <span style="color: #ff7700;font-weight:bold;">def</span> _get_message<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>: 
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._message
    message = <span style="color: #008000;">property</span><span style="color: black;">&#40;</span>_get_message<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> TestEvaluation<span style="color: black;">&#40;</span><span style="color: #dc143c;">unittest</span>.<span style="color: black;">TestCase</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> test_correct<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">666</span>, evaluate_postfix_expr<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;666&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span>+<span style="color: #ff4500;">3</span>-<span style="color: #ff4500;">6</span>, evaluate_postfix_expr<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;2 3 + 6 -&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">3</span>+<span style="color: #ff4500;">4</span>, evaluate_postfix_expr<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;2 3 * 4 +&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">*</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>+<span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>, evaluate_postfix_expr<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;2 3 4 + *&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">**</span><span style="color: #ff4500;">4</span>, evaluate_postfix_expr<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;3   3  *     3  *      3 *&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">7</span>/<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">**</span><span style="color: #ff4500;">4</span>, evaluate_postfix_expr<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;7 2 / 4 ^&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">**</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">**</span><span style="color: #ff4500;">4</span>, evaluate_postfix_expr<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;2 3 ^ 4 ^&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span>+<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>+<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>-<span style="color: #ff4500;">3</span>, evaluate_postfix_expr<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;5 1 2 + 4 * 3 - +&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> test_malformed<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">assertRaises</span><span style="color: black;">&#40;</span>ExpressionError, evaluate_postfix_expr, <span style="color: #483d8b;">&quot;+&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertRaises</span><span style="color: black;">&#40;</span>ExpressionError, evaluate_postfix_expr, <span style="color: #483d8b;">&quot;2 +&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertRaises</span><span style="color: black;">&#40;</span>ExpressionError, evaluate_postfix_expr, <span style="color: #483d8b;">&quot;+ 2 2&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertRaises</span><span style="color: black;">&#40;</span>ExpressionError, evaluate_postfix_expr, <span style="color: #483d8b;">&quot;2 2&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertRaises</span><span style="color: black;">&#40;</span>ExpressionError, evaluate_postfix_expr, <span style="color: #483d8b;">&quot;2 2 + -&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertRaises</span><span style="color: black;">&#40;</span>ExpressionError, evaluate_postfix_expr, <span style="color: #483d8b;">&quot;a 2 -&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> evaluate_postfix_expr<span style="color: black;">&#40;</span>expr<span style="color: black;">&#41;</span>:
    atoms = <span style="color: #dc143c;">re</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\s</span>+&quot;</span>, expr<span style="color: black;">&#41;</span>
    stack = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span> 
    <span style="color: #ff7700;font-weight:bold;">for</span> atom <span style="color: #ff7700;font-weight:bold;">in</span> atoms:
        <span style="color: #ff7700;font-weight:bold;">if</span> atom <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;+&quot;</span>, <span style="color: #483d8b;">&quot;-&quot;</span>, <span style="color: #483d8b;">&quot;*&quot;</span>, <span style="color: #483d8b;">&quot;/&quot;</span>, <span style="color: #483d8b;">&quot;^&quot;</span><span style="color: black;">&#93;</span>:
            <span style="color: #ff7700;font-weight:bold;">try</span>:
                op2 = stack.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                op1 = stack.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IndexError</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> ExpressionError<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Too few operands (unbalanced)&quot;</span><span style="color: black;">&#41;</span>
            <span style="color: #dc143c;">logging</span>.<span style="color: black;">debug</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Calculating %d %s %d&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>op1, atom, op2<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            atom = operators_table<span style="color: black;">&#91;</span>atom<span style="color: black;">&#93;</span><span style="color: black;">&#40;</span>op1, op2<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #ff7700;font-weight:bold;">try</span>:
                atom = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>atom<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> ExpressionError<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Unable to parse '%s' as integer&quot;</span> <span style="color: #66cc66;">%</span> atom<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            stack.<span style="color: black;">append</span><span style="color: black;">&#40;</span>atom<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">MemoryError</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> ExpressionError<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Too long expression&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #dc143c;">logging</span>.<span style="color: black;">debug</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Pushed element %d. Stack status: %s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>atom, stack<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>stack<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">1</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> stack.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> ExpressionError<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Too many operands (unbalanced)&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    <span style="color: #dc143c;">unittest</span>.<span style="color: black;">main</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2011/02/23/reverse-polish-notation-evaluation-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Music spotted!</title>
		<link>http://criptonita.com/~nacho/blog/2009/01/29/music-spotted/</link>
		<comments>http://criptonita.com/~nacho/blog/2009/01/29/music-spotted/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 23:19:29 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/?p=246</guid>
		<description><![CDATA[Doh! A new piece of software I couldn&#8217;t live without: Spotify.]]></description>
			<content:encoded><![CDATA[<p>Doh! A new piece of software I couldn&#8217;t live without: <a href="http://www.spotify.com">Spotify</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2009/01/29/music-spotted/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Free 1Password Licenses!</title>
		<link>http://criptonita.com/~nacho/blog/2008/12/28/free-1password-licenses/</link>
		<comments>http://criptonita.com/~nacho/blog/2008/12/28/free-1password-licenses/#comments</comments>
		<pubDate>Sun, 28 Dec 2008 12:42:50 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/?p=232</guid>
		<description><![CDATA[1Password is a very powerful application for OSX to keep safe your passwords and identities. It works as a standalone application and as a series of plugins for several Internet browsers. It is capable of, among other things, autofill registration forms and save you a lot of time filling in the same personal information again [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://agilewebsolutions.com/products/1Password">1Password</a> is a very powerful application for OSX to keep safe your passwords and identities. It works as a standalone application and as a series of plugins for several Internet browsers. It is capable of, among other things, autofill registration forms and save you a lot of time filling in the same personal information again and again. To autofill a login form, just click the 1P browser menu bar icon, choose a previously recorded identity and voila, 1Password logins in <em>automagically </em>with no further interaction.</p>
<p>All the harvested information is stored in a different keychain unlocked by a master key placed in the login keychain (See &#8220;Keychain access.app&#8221; for more information).</p>
<p><a href="http://www.macheist.com/">Macheist</a>, in collaboration with Agile Web Solutions, is offering free licenses as a Christmas present <a href="http://givingtree.macheist.com/">here</a>. You only have to create and account and click in the links below the tree to get your free license.</p>
]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2008/12/28/free-1password-licenses/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

