<?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>DestaqueBlog &#187; Programming</title>
	<atom:link href="http://weblog.destaquenet.com/category/en/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.destaquenet.com</link>
	<description>Blog da equipe Destaquenet.</description>
	<lastBuildDate>Tue, 23 Nov 2010 17:06:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Understanding Open Source Licenses with Clojure</title>
		<link>http://weblog.destaquenet.com/2010/10/05/understanding-open-source-licenses-with-clojure/</link>
		<comments>http://weblog.destaquenet.com/2010/10/05/understanding-open-source-licenses-with-clojure/#comments</comments>
		<pubDate>Tue, 05 Oct 2010 12:52:51 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[appengine]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[compojure]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[licensator]]></category>
		<category><![CDATA[licenses]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[project]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=1236</guid>
		<description><![CDATA[You only know how cool it is to develop or contribute to an open source project until you do so. The worst part is to define which license to use, and this task is frequently neglected by software developers. Recently &#8230; <a href="http://weblog.destaquenet.com/2010/10/05/understanding-open-source-licenses-with-clojure/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>You only know how cool it is to develop or contribute to an open source project until you do so. The worst part is to define which license to use, and this task is frequently neglected by software developers.</p>
<p>Recently we released <a href="http://licensator.appspot.com">Licensator</a>, a simple web application that gathers information on the most popular open source licenses and helps you choose the right license for your own projects.</p>
<p>The language behind Licensator is <a href="http://clojure.org">Clojure</a>, which proved to be great to solve this sort of problem. We&#8217;ll see today how the application&#8217;s main algorithm works.</p>
<p><span id="more-1236"></span></p>
<h3>REPL: where it all begins</h3>
<p>One of the strengths of dynamic languages is how easily we can transform ideas into working code, and Clojure is no exception. In fact, I decided to write Licensator in one of these coding sessions in the <a href="http://clojure.org/repl_and_main">REPL</a>, Clojure&#8217;s interactive shell. After a few minutes playing with it I saw the problem was indeed easy to solve.</p>
<p>Despite the huge number of licenses, we can easily extract information common to all of them, i.e., if it&#8217;s copyleft, or if a licensed work can be used by closed source software, etc.</p>
<p>Let&#8217;s take the <a href="http://www.opensource.org/licenses/apache2.0.php">Apache v2.0</a> license:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def *licenses*
     <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #555;">id</span> <span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">long-</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Apache License v2.0&quot;</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">short-</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Apache v2.0&quot;</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">url</span> <span style="color: #ff0000;">&quot;http://www.opensource.org/licenses/apache2.0.php&quot;</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">copyright</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">patent</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">closed-source-linking</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">derivative-work</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">affero</span> false
       <span style="color: #66cc66;">:</span><span style="color: #555;">copyleft</span> false
       <span style="color: #66cc66;">:</span><span style="color: #555;">charge-for-distribution</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">charge-for-use</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">afl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">freebsd</span>
                         <span style="color: #66cc66;">:</span><span style="color: #555;">new-bsd</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mit</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mpl-v11</span> <span style="color: #66cc66;">:</span><span style="color: #555;">public-domain</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>You can see the remaining licenses <a href="http://github.com/danielfm/licensator/blob/master/src/licensator/licenses.clj">here</a>.</p>
<p>Considering all licenses have the same set of information, how can we find the licenses that are not reciprocal and have explicit copyright terms?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span>
  <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">copyright</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">copyleft</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">afl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">freebsd</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mit</span> <span style="color: #66cc66;">:</span><span style="color: #555;">new-bsd</span> <span style="color: #66cc66;">:</span><span style="color: #555;">bsd</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>If you know a little bit about functional programming, this code should be easy to follow. In any case, what this code does is return the <code>:id</code> of all licenses where <code>:copyright</code> is <code>true</code> and <code>:copyleft</code> is <code>false</code>.</p>
<p>Another example: which licenses are compatible with Apache v2.0 and <a href="http://www.opensource.org/licenses/cddl1.php">CDDL v1.0</a>?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>use 'clojure<span style="color: #66cc66;">.</span><span style="color: #b1b100;">set</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span>
  <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
                    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Here we used the <a href="http://clojure.github.com/clojure/clojure.set-api.html">clojure.set</a> namespace, which provides a few useful functions to deal with relational algebra. The code is very similar to the previous one; the only difference is that now we used the <code>subset?</code> function to get the licenses compatible with <code>[:apl-v20 :cddl-v10]</code>.</p>
<p>One last example: which reciprocal licenses are compatible with Apache v2.0?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span>
  <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">copyleft</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">agpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">gpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">lgpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mpl-v11</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>At this point we can see that there is no magic behind the algorithm; what it does is to filter the list of licenses based on a function.</p>
<h3>The solution</h3>
<p>The code we saw up until now works fine, but it&#8217;s not appropriate to solve the problem since the matching logic is spread all over the place.</p>
<p>It would be better to express the search criteria as a map object&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def cmap
     <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #555;">patent</span> true<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">closed-source-linking</span> true<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">mit</span> <span style="color: #66cc66;">:</span><span style="color: #555;">new-bsd</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>&#8230;so we need a function to filter the licenses based on that input, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn find-matches <span style="color: #66cc66;">&#91;</span>cmap data<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>filter <span style="color: #66cc66;">&#40;</span>where cmap<span style="color: #66cc66;">&#41;</span> data<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Here we have <code>where</code>, yet to be coded, that returns a function that filters the elements (licenses) in <code>data</code> according to the criteria map <code>cmap</code>.</p>
<p>First things first. Which conditions of <code>cmap</code> match the Apache v2.0 license?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn criteria-matches? <span style="color: #66cc66;">&#91;</span>license <span style="color: #66cc66;">&#91;</span>kval cval<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
  <span style="color: #ff0000;">&quot;Checks whether the criteria condition centry is true for license.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>lval <span style="color: #66cc66;">&#40;</span>kval license<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">nil</span>? cval<span style="color: #66cc66;">&#41;</span>
      true
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>coll? lval<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> cval<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> cval lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">&#40;</span>partial criteria-matches? apl-v20<span style="color: #66cc66;">&#41;</span> cmap<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span>true true true<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>A license can only be considered compatible with the given criteria if the list only yields <code>true</code>. Therefore, in this case, the Apache v2.0 license is considered to be compatible:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>every? true? <span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">&#40;</span>partial criteria-matches? apl-v20<span style="color: #66cc66;">&#41;</span> cmap<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> true</pre></div></div>

<p>Given all this, a possible implementation of the <code>where</code> function might be:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn where
  <span style="color: #ff0000;">&quot;Returns a function that checks whether all conditions in cmap match for license lentry.&quot;</span>
  <span style="color: #66cc66;">&#91;</span>cmap<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>fn <span style="color: #66cc66;">&#91;</span>lentry<span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>res <span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">&#40;</span>fn <span style="color: #66cc66;">&#91;</span>centry<span style="color: #66cc66;">&#93;</span>
		     <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>cval <span style="color: #66cc66;">&#40;</span>val centry<span style="color: #66cc66;">&#41;</span>
			   lval <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>key centry<span style="color: #66cc66;">&#41;</span> lentry<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
		       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">nil</span>? cval<span style="color: #66cc66;">&#41;</span>
			 true
			 <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>coll? lval<span style="color: #66cc66;">&#41;</span>
			   <span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> cval<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
			   <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> cval lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> cmap<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
      <span style="color: #66cc66;">&#40;</span>every? true? res<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>This code is a combination of the previous two snippets; <code>where</code> gets the criteria map <code>cmap</code> and returns a second function, which in turn gets a license entry <code>lentry</code> and checks whether all criteria conditions match.</p>
<p>Since <code>where</code> is used along with <code>filter</code> in <code>find-matches</code>, all licenses compatible with the criteria map <code>cmap</code> are returned:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span> <span style="color: #66cc66;">&#40;</span>find-matches cmap *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">afl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">lgpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mpl-v11</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>What I like about Clojure &#8212; and functional programming languages in general &#8212; is the ridiculous amount of code it takes to solve certain problems. This algorithm, for example, has only 15 (really short) lines of code. Where is your God now?! <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
<p>You can see <a href="http://github.com/danielfm/licensator">the whole thing</a> in Github.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/10/05/understanding-open-source-licenses-with-clojure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django For Mobile Devices</title>
		<link>http://weblog.destaquenet.com/2010/07/12/django-for-mobile-devices/</link>
		<comments>http://weblog.destaquenet.com/2010/07/12/django-for-mobile-devices/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 11:00:00 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[device]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[wsgi]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=932</guid>
		<description><![CDATA[We are living what some people call the &#8220;mobile explosion&#8221;, a time where an increasing number of portable devices &#8212; like tablets and smartphones &#8212; are becoming a significant part of the Web. This is the reason why having your &#8230; <a href="http://weblog.destaquenet.com/2010/07/12/django-for-mobile-devices/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We are living what some people call the &#8220;mobile explosion&#8221;, a time where an increasing number of portable devices &#8212; like tablets and smartphones &#8212; are becoming a significant part of the Web. This is the reason why having your website tailored for these devices is becoming increasingly important.</p>
<p>Fortunately, <a href="http://djangoproject.com/">Django</a> is one of the few web frameworks that makes this an easy problem to solve.</p>
<p><span id="more-932"></span></p>
<h3>How we solved it</h3>
<p>A simple way is to create a separate settings module for the mobile version. Doing this, we&#8217;re able to run two different webapps while reusing the existing codebase. Also, each version can have its own template directory, URL root configuration, etc.</p>
<p>Let&#8217;s do this. In the project root directory, create a file <code>m_settings.py</code> with the following content:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># File: myproject/m_settings.py</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;&quot;Django settings for the mobile-specific website.
&quot;&quot;&quot;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Load the default settings</span>
<span style="color: #ff7700;font-weight:bold;">from</span> settings <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Domain &quot;m.mydomain.com&quot;</span>
SITE_ID = <span style="color: #ff4500;">2</span>
PREPEND_WWW = <span style="color: #008000;">False</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Used elsewhere to determine which version is running</span>
DEFAULT_VERSION = <span style="color: #008000;">False</span>
MOBILE_VERSION  = <span style="color: #008000;">True</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># URLs for the mobile version</span>
ROOT_URLCONF  = <span style="color: #483d8b;">'myproject.m_urls'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Templates for the mobile version</span>
TEMPLATE_DIRS = <span style="color: black;">&#40;</span>
    <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">normpath</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span> + <span style="color: #483d8b;">'/template/mobile'</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Other settings...</span></pre></div></div>

<p>These two webapps share the same codebase, but that doesn&#8217;t mean they have to use the same URL root configuration. In fact, websites suitable for mobile devices are usually simpler, with fewer URL mappings.</p>
<p>To define separate URL root configuration for the mobile version, create a file <code>m_urls.py</code> with the following content:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># File: myproject/m_urls.py</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;&quot;Mobile-specific URL definition.
&quot;&quot;&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span> <span style="color: #ff7700;font-weight:bold;">import</span> settings
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span>.<span style="color: black;">urls</span>.<span style="color: black;">defaults</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #808080; font-style: italic;"># from django.contrib import admin</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># admin.autodiscover()</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Error page handlers</span>
handler404 = <span style="color: #483d8b;">'website.views.error_404_handler'</span>
handler500 = <span style="color: #483d8b;">'website.views.error_500_handler'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Root URL patterns</span>
urlpatterns = patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>,
    <span style="color: #808080; font-style: italic;"># I18N</span>
    <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^i18n/'</span>, include<span style="color: black;">&#40;</span><span style="color: #483d8b;">'django.conf.urls.i18n'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
&nbsp;
    <span style="color: #808080; font-style: italic;"># Internal apps</span>
    <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^contact/'</span>, include<span style="color: black;">&#40;</span><span style="color: #483d8b;">'contact.urls'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
&nbsp;
    <span style="color: #808080; font-style: italic;"># (r'^admin/doc/', include('django.contrib.admindocs.urls')),</span>
    <span style="color: #808080; font-style: italic;"># (r'^admin/', include(admin.site.urls)),</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Other settings...</span>
<span style="color: black;">&#41;</span></pre></div></div>

<p>Note that, in this particular example, the <a href="http://docs.djangoproject.com/en/dev/ref/contrib/admin/">Admin app</a> isn&#8217;t accessible from mobile version. This just shows that we can structure each webapp differently without too much trouble.</p>
<h3>Developing</h3>
<p>You already know how to run the development server for the default version. Most people don&#8217;t know, however, that it&#8217;s possible to choose a different port number and settings module, which allows us to launch one development server for each webapp version:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Terminal window 1: default version</span>
$ python manage.py runserver <span style="color: #000000;">8000</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Terminal window 2: mobile version</span>
$ python manage.py runserver <span style="color: #660033;">--settings</span>=m_settings <span style="color: #000000;">8001</span></pre></div></div>

<p>Just develop your stuff and see the results in both versions right away. Easy peasy.</p>
<h3>Testing</h3>
<p>You probably noticed that we have two settings that can be used to identify what webapp version is being run, <code>DEFAULT_VERSION</code> and <code>MOBILE_VERSION</code>. </p>
<p>So it&#8217;s just a matter of checking those settings when you need to do different things in each webapp version. This is particularly useful when you use an app in both versions and want to create separate tests for each version:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># File: myproject/myapp/tests/__init__.py</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;&quot;Unit tests module for MyApp.
&quot;&quot;&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span> <span style="color: #ff7700;font-weight:bold;">import</span> settings
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>settings, <span style="color: #483d8b;">'DEFAULT_VERSION'</span>, <span style="color: #008000;">False</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># Tests the default version</span>
    <span style="color: #ff7700;font-weight:bold;">from</span> default_models_tests <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
    <span style="color: #ff7700;font-weight:bold;">from</span> default_navigation_tests <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>settings, <span style="color: #483d8b;">'MOBILE_VERSION'</span>, <span style="color: #008000;">False</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># Tests the mobile version</span>
    <span style="color: #ff7700;font-weight:bold;">from</span> mobile_models_tests <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
    <span style="color: #ff7700;font-weight:bold;">from</span> mobile_navigation_tests <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span></pre></div></div>

<p>We can run the tests for each version in a similar way we did before with the <code>runserver</code> command:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Default version</span>
$ python manage.py <span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>appname...<span style="color: #7a0874; font-weight: bold;">&#93;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Mobile version</span>
$ python manage.py <span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #660033;">--settings</span>=m_settings <span style="color: #7a0874; font-weight: bold;">&#91;</span>appname...<span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<h3>Deploying</h3>
<p>Despite what you may think, this is the easy part.</p>
<p>Since <a href="http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/">deploying Django</a> with <a href="http://apache.org/">Apache</a> and <a href="http://code.google.com/p/modwsgi/">mod_wsgi</a> is the recommended way to get Django into production, it&#8217;s likely that you already have a WSGI file like this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span>
&nbsp;
APPS_PATH   = <span style="color: #483d8b;">'/home/user/wsgi_apps'</span>
MYPROJECT_PATH = <span style="color: #483d8b;">'%s/myproject'</span> <span style="color: #66cc66;">%</span> APPS_PATH
&nbsp;
<span style="color: #808080; font-style: italic;"># Third-party eggs</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">site</span>
<span style="color: #dc143c;">site</span>.<span style="color: black;">addsitedir</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/home/user/.python/lib'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span> += <span style="color: black;">&#91;</span>APPS_PATH, MYPROJECT_PATH<span style="color: black;">&#93;</span>
<span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'DJANGO_SETTINGS_MODULE'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'myproject.settings'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span>.<span style="color: black;">wsgi</span>
application = django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span>.<span style="color: black;">wsgi</span>.<span style="color: black;">WSGIHandler</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>All we need to do is configure another WSGI-enabled subdomain on our server, e.g. m.mywebsite.com, that refers to another WSGI file like this one:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span>
&nbsp;
APPS_PATH   = <span style="color: #483d8b;">'/home/user/wsgi_apps'</span>
MYPROJECT_PATH = <span style="color: #483d8b;">'%s/myproject'</span> <span style="color: #66cc66;">%</span> APPS_PATH
&nbsp;
<span style="color: #808080; font-style: italic;"># Third-party eggs</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">site</span>
<span style="color: #dc143c;">site</span>.<span style="color: black;">addsitedir</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/home/user/.python/lib'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span> += <span style="color: black;">&#91;</span>APPS_PATH, MYPROJECT_PATH<span style="color: black;">&#93;</span>
<span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'DJANGO_SETTINGS_MODULE'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'myproject.m_settings'</span> <span style="color: #808080; font-style: italic;"># This line</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span>.<span style="color: black;">wsgi</span>
application = django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span>.<span style="color: black;">wsgi</span>.<span style="color: black;">WSGIHandler</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>The only difference between these two WSGI files is that each one points to a different settings module. And no, you don&#8217;t need to have a separate copy for each version. We are using the same codebase for both versions, remember? <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h3>Minimizing the traffic</h3>
<p>Amazingly, not everyone has access ultra-fast internet connections on their devices, so it&#8217;s very important to keep your sites as lightweight as possible.</p>
<p>There are several open source projects that try to address this problem. One of them is <a href="http://code.google.com/p/django-compress/">django-compress</a>, a Django app that provides an automated system for compressing CSS and JavaScript files.</p>
<p>In fact, doesn&#8217;t matter if your websites target mobile devices or not; you should <em>always</em> try to minimize the amount of traffic.</p>
<h3>What&#8217;s left?</h3>
<p>There&#8217;s one small problem though: when someone visit the regular website from a mobile device, or vice-versa, they are not redirected to the appropriate version. But this is a topic for another article!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/07/12/django-for-mobile-devices/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>At World Cup Season&#8230;</title>
		<link>http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/</link>
		<comments>http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 16:42:02 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[bet]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[football]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[meme]]></category>
		<category><![CDATA[pool]]></category>
		<category><![CDATA[program]]></category>
		<category><![CDATA[soccer]]></category>
		<category><![CDATA[sweepstakes]]></category>
		<category><![CDATA[world cup]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=909</guid>
		<description><![CDATA[Some people think &#8212; and I agree &#8212; that the UEFA Champions League is a more relevant tournament than the World Cup itself, but we cannot deny that an event of this magnitude is really awesome to keep an eye &#8230; <a href="http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Some people think &#8212; and I agree &#8212; that the <a href="http://www.uefa.com/uefachampionsleague/index.html">UEFA Champions League</a> is a more relevant tournament than the <a href="http://www.fifa.com/worldcup/index.html">World Cup</a> itself, but we cannot deny that an event of this magnitude is really awesome to keep an eye on. Even those who doesn&#8217;t love the sport tend to follow the teams, the matches, the celebration.</p>
<p>And with the World Cup comes the sweepstakes. Lots of.</p>
<p>Although the rules might change from one place to another, these are the ones we use the most here in Brazil:</p>
<ol>
<li>Everyone try to predict the score of a particular match, paying a fixed amount for each guess (eg $1.00).</li>
<li>At the end, the ammount collected is divided equally among the winners. If there are no winners: (a) the sweepstake &#8220;accumulates&#8221;<sup class='footnote'><a href='#fn-909-1' id='fnref-909-1'>1</a></sup>, or (b) everyone get their money back, or (c) you-crazy-rule-here.</li>
</ol>
<p>I like this kind of sweepstake, but it could be better in some respects.</p>
<p>First, not everybody has the habit of carrying small bills around, so the sweepstakes manager (a.k.a. YOU) loses a lot of time chasing change. Besides, I think the fixed-valued bet is kind of boring since the amount collected is divided equally among the winners. I think things get more exciting when people can choose how much to pay for each guess, so the amount collected is divided <strong>proportionally</strong> among the winners. In this case, when several people win, earns more who bets more.</p>
<p>Since I don&#8217;t like to do the math myself, here&#8217;s the challenge: create a program that receives a list with all guesses and returns the list of winners along with the proportional amount to be paid to each one of them.</p>
<p>So, shall we?</p>
<p><span id="more-909"></span></p>
<h3>Solving the problem&#8230; with Clojure</h3>
<p>Write more code than necessary is going out of style these days, so I decided to code a solution in <a href="http://clojure.org">Clojure</a>, a functional programming language that makes this sort of &#8220;problem&#8221; really easy to solve. Just launch <a href="http://clojure.org/repl_and_main">the REPL</a> and profit!</p>
<p>The first thing to do is define how to represent each guess:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>All guesses has the same information. That&#8217;s why we defined a <a href="http://clojure.org/data_structures#Data%20Structures-StructMaps">StructMap</a> with the keys <code>:name</code>, <code>:amount</code>, <code>:guess</code>, and <code>:rate</code>.</p>
<p>A list of possible guesses might be:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def pool
     <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Daniel&quot;</span> <span style="color: #cc66cc;">2.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Daniel bets $2.00 on score 2x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;John&quot;</span>   <span style="color: #cc66cc;">4.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; John bets $4.00 on score 0x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Maria&quot;</span>  <span style="color: #cc66cc;">1.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Maria bets $1.00 on score 2x0</span>
     <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Okay, we already know how each guess is represented. Now, how to find the sweepstake&#8217;s total amount? Simple, all we have to do is to sum the amount of all guesses:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-amount <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testing</span>
<span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #cc66cc;">7.0</span></pre></div></div>

<p>Great, but how much each guess represent in relation to the whole, that is, what&#8217;s the proportion of each guess? All we have to do is to divide the amount of each guess by the sweepstake&#8217;s total amount:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-rates <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testing</span>
<span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>pool-rates pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.285</span> <span style="color: #66cc66;">...,</span> <span style="color: #cc66cc;">0.571</span> <span style="color: #66cc66;">...,</span> <span style="color: #cc66cc;">0.142</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>pool-rates pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #cc66cc;">1.0</span></pre></div></div>

<p>Note that, if everyone wins, the amount earned by John would be the double of the amount earned by Daniel, which would be the double of the amount earned by Maria. Justice, finally!</p>
<p>To finish the code, we just need a function that filters the winners and calculates how much to pay to each winner:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-winners <span style="color: #66cc66;">&#91;</span>poolseq result<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span>
        winners <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">&#40;</span>double <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testing</span>
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; no winners</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; just one winner</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;John&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">7.0</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">1.0</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; several winners</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Daniel&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">4.66</span> <span style="color: #66cc66;">...,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">0.66</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Maria&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">2.33</span> <span style="color: #66cc66;">...,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">0.33</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>A major advantage of this solution is that it allows you to bet on anything. Want to bet on the sex of a baby shortly after the good news (or bad news, whatever)?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def pool <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Daniel&quot;</span> <span style="color: #cc66cc;">3.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">male</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;John&quot;</span>   <span style="color: #cc66cc;">5.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Maria&quot;</span>  <span style="color: #cc66cc;">1.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;John&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">7.5</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Maria&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">1.5</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>There you go, a simple solution for a simple problem.</p>
<h3>The code</h3>
<p>Although it&#8217;s possible to solve this problem in Lisp/Clojure with a one-liner (<a href="http://clojure.org/reader">the Reader</a> works with <strong>data structures</strong> after all), I decided to write a code that is as readable as possible for those who are starting with Clojure:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-amount <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-rates <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-winners <span style="color: #66cc66;">&#91;</span>poolseq result<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span>
        winners <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">&#40;</span>double <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<h3>Your turn</h3>
<p>Do you program in Haskell? Python? Ruby? <a href="http://en.wikipedia.org/wiki/Brainfuck">Brainfuck</a>? How would you solve such problem in your favorite programming language?</p>
<p><strong>Update (Nov 3, 2010).</strong> Common Lisp solution, using <code>copy-*</code> to avoid changes in state:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #b1b100;">name</span> amount guess rate<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-amount <span style="color: #66cc66;">&#40;</span>pool<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>reduce #'+ <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> #'bet-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-rates <span style="color: #66cc66;">&#40;</span>pool<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>bet<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>copy-bet bet<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">&#40;</span>bet-rate x<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span>bet-amount x<span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-winners <span style="color: #66cc66;">&#40;</span>pool result<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>winners <span style="color: #66cc66;">&#40;</span>loop for bet in pool <span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">equal</span> <span style="color: #66cc66;">&#40;</span>bet-guess bet<span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> collect bet<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>winner<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>copy-bet winner<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">&#40;</span>bet-amount x<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span>bet-rate x<span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-909-1'>The amount collected remains available for the next match&#8217;s sweepstakes, but everyone must pay again for a new guess. <span class='footnotereverse'><a href='#fnref-909-1'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django-Flash and Django&#8217;s New Messages Framework</title>
		<link>http://weblog.destaquenet.com/2010/05/21/django-flash-and-djangos-new-messages-framework/</link>
		<comments>http://weblog.destaquenet.com/2010/05/21/django-flash-and-djangos-new-messages-framework/#comments</comments>
		<pubDate>Fri, 21 May 2010 02:31:59 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[django-flash]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=881</guid>
		<description><![CDATA[Earlier this week, after several months of hard work and some delay, Django 1.2 was finally released. This is probably the most exciting release since Django&#8217;s debut, and brings long waited features, like multi-db support and a user &#8220;messages&#8221; framework. &#8230; <a href="http://weblog.destaquenet.com/2010/05/21/django-flash-and-djangos-new-messages-framework/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Earlier this week, after several months of hard work and some delay, <a href="http://www.djangoproject.com/download/">Django 1.2 was finally released</a>. This is probably the most exciting release since Django&#8217;s debut, and brings long waited features, like <a href="http://docs.djangoproject.com/en/dev/releases/1.2/#support-for-multiple-databases">multi-db support</a> and a <a href="http://docs.djangoproject.com/en/dev/releases/1.2/#messages-framework">user &#8220;messages&#8221; framework</a>.</p>
<p>Yes, I said Django 1.2 comes with built-in user &#8220;messages&#8221; framework. Great, isn&#8217;t it? Django really needed a built-in contrib app to solve this problem. This doesn&#8217;t mean, however, that <a href="http://djangoflash.destaquenet.com/">Django-Flash</a> will be discontinued or abandoned.</p>
<p>So, if you use Django-Flash in your projects, don&#8217;t worry! Nothing will change. Django-Flash is already compatible with Django 1.2, and we&#8217;ll keep improving Django-Flash for a number of reasons.</p>
<p>First of all, we care about the people who use our software. We won&#8217;t break your stuff if you decide to upgrade to a newer version of Django &#8211; or if you decide to keep using the previous version.</p>
<p>Also, freedom of choice is a good thing. You know, there&#8217;s not only one true way to solve every problem. People should be free to choose whatever tool they think is right in a given situation.</p>
<p>For example, based on my first impressions, there are a couple of things I didn&#8217;t like at all about the new user &#8220;messages&#8221; framework:</p>
<ol>
<li>It&#8217;s verbose even for the simple cases</li>
<li>It ties messages to priority numbers, encouraging you to use it like a logging/debugging framework. I mean, a user &#8220;messages&#8221; framework is not a logging/debugging framework, right?</li>
</ol>
<p>But that&#8217;s just my opinion. I guess this is what makes open source so great!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/05/21/django-flash-and-djangos-new-messages-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python for S60: A Work in Progress?</title>
		<link>http://weblog.destaquenet.com/2010/02/17/python-for-s60-a-work-in-progress/</link>
		<comments>http://weblog.destaquenet.com/2010/02/17/python-for-s60-a-work-in-progress/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 12:10:28 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[cellphone]]></category>
		<category><![CDATA[nokia]]></category>
		<category><![CDATA[pys60]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[python for s60]]></category>
		<category><![CDATA[smartphone]]></category>
		<category><![CDATA[symbian]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=827</guid>
		<description><![CDATA[I was one of the lucky ones who lost their cellphones a few months ago, during that crazy AC/DC concert. Surprisingly, that didn&#8217;t upset me at all; although I&#8217;m not a heavy user, that was the perfect opportunity for me &#8230; <a href="http://weblog.destaquenet.com/2010/02/17/python-for-s60-a-work-in-progress/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was one of the lucky ones who lost their cellphones a few months ago, during that <a href="http://weblog.destaquenet.com/2009/10/12/using-web-scraping-to-follow-your-orders-on-ticketmaster/">crazy AC/DC concert</a>. Surprisingly, that didn&#8217;t upset me at all; although I&#8217;m not a heavy user, that was the perfect opportunity for me to get my first smartphone.</p>
<p>I ended up with a <a href="http://europe.nokia.com/find-products/devices/nokia-5800-xpressmusic">Nokia 5800 XpressMusic</a>, a relatively cheap smartphone with a nice feature set. Specifically, what took me for granted was the ability to run <a href="http://python.org">Python</a> applications in it!</p>
<p>But what exactly can we do with <a href="https://garage.maemo.org/projects/pys60/">Python for S60</a>? Well, to answer that question, I decided to implement a non-trivial app to see exactly what it has to offer. The app in question is a Bluetooth remote control called <a href="http://github.com/danielfm/pytriloquist">Pytriloquist</a>. (see also <a href="http://www.flickr.com/photos/daniel_tritone/4313716091/in/set-72157623183881993/">screenshots</a> and a <a href="http://www.youtube.com/watch?v=2IVXMAJHwI8">video</a> demonstration.)</p>
<p><span id="more-827"></span></p>
<h3>What&#8217;s Good</h3>
<p><strong>Platform Independence.</strong> The <a href="http://www.forum.nokia.com/Tools_Docs_and_Code/Tools/Platforms/S60_Platform_SDKs/">S60 SDK</a> is for Windows only (what a surprise). This is obviously bad for those who use other operating systems. Fortunately, you don&#8217;t need a massive SDK to develop and deploy S60 apps if you write them in Python; all you need is Python for S60, a text editor, and a device for testing.</p>
<p><strong>Language and Standard Library.</strong> Python is a terrific language: compact, beautiful, powerful, and have an <em>amazing</em> standard library. The good news is that the most popular modules work great on S60. For example, it&#8217;s even possible to localize your apps using the <code>gettext</code> module!</p>
<h3>What&#8217;s Bad</h3>
<p><strong>Work in Progress.</strong> Python for S60, as long as I know, is a work in progress. This means the language itself works fine, but you can expect missing modules or <a href="https://garage.maemo.org/tracker/?atid=3201&#038;group_id=854&#038;func=browse">some bugs</a> in standard library. For example, when writing the Bluetooth client code for my app, I encountered <a href="https://garage.maemo.org/tracker/index.php?func=detail&#038;aid=3947&#038;group_id=854&#038;atid=3201">a very annoying bug</a> in which you can only call <code>btsocket.bt_discover()</code> once!</p>
<p><strong>Multi-Module Code.</strong> If you are testing your app with Python ScriptShell, everything will work out-of-the-box as long as keep your whole code inside a single massive module. If you break up your code into several modules (or worse, packages) you won&#8217;t be able to have modules importing each other unless you adjust the <code>PYTHON_PATH</code> accordingly.</p>
<p><strong>Incomplete and Outdated Documentation.</strong> There are some PDFs and API documentation pages available, but they are incomplete and outdated, and this is a bad thing when it comes to dynamic languages; we don&#8217;t have a compiler to tell us what&#8217;s wrong with our code. This is why Python programmers are so careful about documentation in the first place.</p>
<h3>What&#8217;s Ugly</h3>
<p><strong>Limited Access to Native Features.</strong> Specially regarding the native UI system: you cannot change the label of the two standard soft keys, nor add other soft keys, nor add more than two tabs in a tabbed UI, nor have an empty <code>Listbox</code>, nor lots of other things. You can write simple UIs without much effort, that&#8217;s true, but those shortcomings just make Python for S60 unusable for more complex projects.</p>
<p><strong>Project Inactivity.</strong> The project appears to be on hold. New bug reports are submitted every now and then, but no bugs are closed for <a href="https://garage.maemo.org/project/stats/?group_id=854">six months</a>.</p>
<h3>Conclusion</h3>
<p>Let&#8217;s hope things change for the better after the last <a href="http://www.symbian.org/symbian-feature-set/symbian-is-open-source">announcement</a> made by the Symbian Foundation, but in the meantime, if you pretend to create serious apps for S60, do it in C++.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/02/17/python-for-s60-a-work-in-progress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Templates in 10 minutes with JSP and tag files</title>
		<link>http://weblog.destaquenet.com/2009/12/17/templates-in-10-minutes-with-jsp-and-tag-files/</link>
		<comments>http://weblog.destaquenet.com/2009/12/17/templates-in-10-minutes-with-jsp-and-tag-files/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 12:30:06 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jsp]]></category>
		<category><![CDATA[layout]]></category>
		<category><![CDATA[servlet]]></category>
		<category><![CDATA[tag]]></category>
		<category><![CDATA[tagfiles]]></category>
		<category><![CDATA[taglib]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=822</guid>
		<description><![CDATA[Have you ever seen JSPs full of Aramaic-like scriptlets, crazy includes, duplicated code and no taglibs beyond that provided by the web framework in use? Are you staring at one right now? This is a fairly common thing, at least &#8230; <a href="http://weblog.destaquenet.com/2009/12/17/templates-in-10-minutes-with-jsp-and-tag-files/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Have you ever seen JSPs full of Aramaic-like scriptlets, crazy includes, duplicated code and no taglibs beyond that provided by the web framework in use? Are you staring at one right now?</p>
<p>This is a fairly common thing, at least for the companies I worked for so far, and that&#8217;s what scares me the most. Hopefully, you can easily make things better if you want to.</p>
<p>In this post, I&#8217;ll show you a few techniques that can be used to write clean JSPs without resorting to any kind of templating system whatsoever.</p>
<p><span id="more-822"></span></p>
<h3>An example</h3>
<p>The first step is to define the base template for the application pages. Consider the following XHTML example and its graphic representation:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">http-equiv</span>=<span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;keyword1, keyword2, keyword3&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Page title<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Essential scripts --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;link</span> <span style="color: #000066;">rel</span>=<span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;css/style.css&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/query.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Extra header --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;wrapper&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;content&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;footer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            // Other scripts (e.g. Google Analytics)
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<div id="attachment_803" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2009/12/layout.gif"><img src="http://weblog.destaquenet.com/wp-content/uploads/2009/12/layout-300x156.gif" alt="Template graphic representation" title="layout" width="300" height="156" class="size-medium wp-image-803" /></a><p class="wp-caption-text">Template graphic representation</p></div>
<p>What usually happens, even with a simple template such as this, is a high level of code duplication among the different pages due to the heavy use of <a href="http://en.wikipedia.org/wiki/Copy_and_paste_programming">Copy and Paste Programming</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">http-equiv</span>=<span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span>    <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;keyword1, keyword2, keyword3&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Page title<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Essential scripts --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:include</span> <span style="color: #000066;">page</span>=<span style="color: #ff0000;">&quot;scripts.jsp&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Extra header --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;wrapper&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:include</span> <span style="color: #000066;">file</span>=<span style="color: #ff0000;">&quot;header.jsp&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;content&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Page content here<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:include</span> <span style="color: #000066;">page</span>=<span style="color: #ff0000;">&quot;footer.jsp&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            // Other scripts
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>See? Why break the template into small pieces if you are going keep duplicating code anyway? The best thing to do is to translate that template into something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">tagdir</span>=<span style="color: #ff0000;">&quot;/WEB-INF/tags/layout&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:page</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Title&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> <span style="color: #000066;">keywords</span>=<span style="color: #ff0000;">&quot;keyword1, keyword2, keyword3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        // Other scripts (e.g. Google Analytics)
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        Page content here
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/layout:page<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<h3>Content reuse with tag files</h3>
<p>There are three types of JSP tags, each with its own strengths and weaknesses: <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaow.html#bnaoy">classic tag handlers</a>, <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnann.html">simple tag handlers</a> and <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnama.html">tag files</a>. Today I&#8217;ll cover the basics of tag files, but every Java developer should learn when and how to use the other two.</p>
<p>The first thing we need to do is create the <code>WEB-INF/tags/layout</code> directory, which will keep the tag files we are about to create. Now, create two files inside this directory, one for the header and the other for the footer:</p>
<p><strong>header.tag</strong></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ tag <span style="color: #000066;">body-content</span>=<span style="color: #ff0000;">&quot;empty&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Header tag file&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #808080; font-style: italic;">&lt;!-- Header section here --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><strong>footer.tag</strong></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ tag <span style="color: #000066;">body-content</span>=<span style="color: #ff0000;">&quot;empty&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Footer tag file&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;footer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #808080; font-style: italic;">&lt;!-- Footer section here --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>As we can see, tag files are just like JSPs, but with some special properties.</p>
<p>The last tag file, <strong>page.tag</strong>, defines the overall page structure:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ tag <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;title&quot;</span>       <span style="color: #000066;">required</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page title&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span>    <span style="color: #000066;">required</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page keywords to improve SEO&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">required</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Extra code to put before &lt;/head&gt;</span></span>&quot; %&gt;
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Extra code to put before &lt;/body&gt;</span></span>&quot; %&gt;
&nbsp;
<span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">tagdir</span>=<span style="color: #ff0000;">&quot;/WEB-INF/tags/layout&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
<span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">http-equiv</span>=<span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Displaying the attributes using EL --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span>    <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;${keywords}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;${description}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>${title}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Essential scripts --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;link</span> <span style="color: #000066;">rel</span>=<span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;css/style.css&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/query.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Process the given input fragment --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:invoke</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;wrapper&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- Renders the page header --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:header</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
            <span style="color: #808080; font-style: italic;">&lt;!-- Renders the tag body inside a DIV --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;content&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;jsp:doBody</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
            <span style="color: #808080; font-style: italic;">&lt;!-- Renders the page footer --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:footer</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Process the given input fragment --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:invoke</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>This last tag file is more complex than the other two, because you can pass to it both values and <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaln.html#bnalq">fragments</a>. Besides, this tag accepts a body, which gets executed with <code>&lt;jsp:doBody/&gt;</code>.</p>
<p>Of course, the example shown here is fairly simple, so we didn&#8217;t have to use more advanced features like <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaln.html#bnaly">variables</a> and <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaln.html#bnaly">dynamic attributes</a>. Be that as it may, it&#8217;s a good idea to know what the technology has to offer. You&#8217;ll never know when a feature will be useful until you need it.</p>
<h3>Usage</h3>
<p>Now, let&#8217;s put those tag files to use:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">tagdir</span>=<span style="color: #ff0000;">&quot;/WEB-INF/tags/layout&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">uri</span>=<span style="color: #ff0000;">&quot;http://java.sun.com/jsp/jstl/core&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;c&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:page</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Index page&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;This is the index page of my amazing app&quot;</span> <span style="color: #000066;">keywords</span>=<span style="color: #ff0000;">&quot;amazing, app&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/some_jquery_plugin.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        $(function() {
            // Call some JQuery function here, specific for this page
        });
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        Welcome to my amazing app!<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        1+1 = ${1+1}
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;c:forEach</span> <span style="color: #000066;">items</span>=<span style="color: #ff0000;">&quot;${objects}&quot;</span> <span style="color: #000066;">var</span>=<span style="color: #ff0000;">&quot;obj&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>${obj.attr}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/c:forEach<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/layout:page<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Although the application as a whole follow the same visual standard, each page may need additional resources (JavaScript, CSS, etc.). This is hardly a problem because our template allows us to include extra content if necessary.</p>
<p>The other advantage is that tag files allow the use of custom tags and <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnahq.html">unified EL</a>, but <strong>deny the use of scriptlets</strong>, which is a good thing if you want to get rid of messy JSPs.</p>
<h3>Recommended reading</h3>
<ul>
<li><a href="http://java.sun.com/javaee/5/docs/tutorial/doc/">The Java EE 5 Tutorial</a>;</li>
<li><a href="http://www.amazon.com/Head-First-Servlets-JSP-Certified/dp/0596516681/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1260993372&#038;sr=8-1">Head First Servlets &#038; JSP</a>;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/12/17/templates-in-10-minutes-with-jsp-and-tag-files/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using web scraping to follow your orders on Ticketmaster</title>
		<link>http://weblog.destaquenet.com/2009/10/12/using-web-scraping-to-follow-your-orders-on-ticketmaster/</link>
		<comments>http://weblog.destaquenet.com/2009/10/12/using-web-scraping-to-follow-your-orders-on-ticketmaster/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 16:07:10 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[acdc]]></category>
		<category><![CDATA[brasil]]></category>
		<category><![CDATA[concert]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[pynotify]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[scraping]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[ticketmaster]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=760</guid>
		<description><![CDATA[The legendary rock&#8217;n'roll band AC/DC will land on brazilian soil for the second time in November, for what is considered to be the show of the decade around here! The tickets for their single concert, sold by the brazilian Ticketmaster, &#8230; <a href="http://weblog.destaquenet.com/2009/10/12/using-web-scraping-to-follow-your-orders-on-ticketmaster/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The legendary rock&#8217;n'roll band <a href="http://acdc.com/">AC/DC</a> will land on brazilian soil for the second time in November, for what is considered to be the show of the decade around here! The tickets for their single concert, sold by the <a href="http://www.ticketmaster.com.br/">brazilian Ticketmaster</a>, ran out in less than 48 hours. This concert is going to be amazing!</p>
<p>A lot of things happened during those 48 hous. The Ticketmaster staff had trouble to keep the website on-line, and due to the enormous load, it&#8217;s possible that only a few thousands of people had enough luck to buy their tickets via the website.</p>
<p>Also, Ticketmaster admits that the notification e-mails may not reach, which means we cannot rely on those to follow our orders. In fact, they recomend that customers check their orders manually once a day. Oh boy&#8230;</p>
<p>I hate to do certain tasks manually, specially the ones that can be automated. So, in this post I&#8217;ll show you a very simple <a href="http://www.python.org">Python</a>-based command-line tool that displays the status of your Ticketmaster<sup class='footnote'><a href='#fn-760-1' id='fnref-760-1'>1</a></sup> orders on the screen<sup class='footnote'><a href='#fn-760-2' id='fnref-760-2'>2</a></sup>, using a technique known as <a href="http://en.wikipedia.org/wiki/Web_scraping">web scraping</a>.</p>
<p><span id="more-760"></span></p>
<p>The code, which is also <a href="http://github.com/danielfm/ticketmaster-order-status">on Github</a>, can be seen below:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #808080; font-style: italic;">#-*- coding:utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib2</span>
<span style="color: #ff7700;font-weight:bold;">import</span> pynotify
&nbsp;
&nbsp;
_BASE_URL  = <span style="color: #483d8b;">'https://ticketing.ticketmaster.com.br'</span>
_LOGIN_URI = <span style="color: #483d8b;">'%s/shwLogin.cfm'</span> <span style="color: #66cc66;">%</span> _BASE_URL
_ORDER_URI = <span style="color: #483d8b;">'%s/shwCompraDetalhe.cfm?pedidoID=%%s'</span> <span style="color: #66cc66;">%</span> _BASE_URL
&nbsp;
_ORDERS_LINK = <span style="color: #483d8b;">'&lt;a href=&quot;%s&quot;&gt;More...&lt;/a&gt;'</span> <span style="color: #66cc66;">%</span> _LOGIN_URI
&nbsp;
_PRIORITY_LOW      = pynotify.<span style="color: black;">URGENCY_LOW</span>
_PRIORITY_NORMAL   = pynotify.<span style="color: black;">URGENCY_NORMAL</span>
_PRIORITY_CRITICAL = pynotify.<span style="color: black;">URGENCY_CRITICAL</span>
&nbsp;
_NOTIFICATION_TITLE = <span style="color: #483d8b;">'Ticketmaster Order %s'</span>
_STATUS_CODES = <span style="color: black;">&#123;</span>
    <span style="color: #483d8b;">'Livre'</span>      : <span style="color: black;">&#40;</span><span style="color: #483d8b;">'Not processed yet'</span>      , _PRIORITY_LOW<span style="color: black;">&#41;</span>,
    <span style="color: #483d8b;">'StdReserva'</span> : <span style="color: black;">&#40;</span><span style="color: #483d8b;">'Reserving your tickets'</span> , _PRIORITY_NORMAL<span style="color: black;">&#41;</span>,
    <span style="color: #483d8b;">'StdCobranca'</span>: <span style="color: black;">&#40;</span><span style="color: #483d8b;">'Charging your tickets'</span>  , _PRIORITY_NORMAL<span style="color: black;">&#41;</span>,
    <span style="color: #483d8b;">'VendaOk'</span>    : <span style="color: black;">&#40;</span><span style="color: #483d8b;">'Billed'</span>                 , _PRIORITY_CRITICAL<span style="color: black;">&#41;</span>,
    <span style="color: #483d8b;">'Recusada'</span>   : <span style="color: black;">&#40;</span><span style="color: #483d8b;">'Rejected'</span>               , _PRIORITY_CRITICAL<span style="color: black;">&#41;</span>
<span style="color: black;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> initialize_notification_system<span style="color: black;">&#40;</span>app_title<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> pynotify.<span style="color: black;">init</span><span style="color: black;">&#40;</span>app_title<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
        <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> display_message<span style="color: black;">&#40;</span>title, message, priority=_PRIORITY_CRITICAL<span style="color: black;">&#41;</span>:
    message = pynotify.<span style="color: black;">Notification</span><span style="color: black;">&#40;</span>title, message<span style="color: black;">&#41;</span>
    message.<span style="color: black;">set_urgency</span><span style="color: black;">&#40;</span>priority<span style="color: black;">&#41;</span>
    message.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> check_orders<span style="color: black;">&#40;</span><span style="color: #dc143c;">email</span>, password, order_ids<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        opener = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">build_opener</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">urllib2</span>.<span style="color: black;">HTTPCookieProcessor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        login<span style="color: black;">&#40;</span>opener, <span style="color: #dc143c;">email</span>, password<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            <span style="color: #ff7700;font-weight:bold;">for</span> order_id <span style="color: #ff7700;font-weight:bold;">in</span> order_ids:
                show_order_status<span style="color: black;">&#40;</span>opener, order_id<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span>:
            title = _NOTIFICATION_TITLE <span style="color: #66cc66;">%</span> order_id
            display_message<span style="color: black;">&#40;</span>title, <span style="color: #483d8b;">'Cannot check status'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span>:
        display_message<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Ticketmaster'</span>, <span style="color: #483d8b;">'Login failed'</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> login<span style="color: black;">&#40;</span>opener, <span style="color: #dc143c;">email</span>, password<span style="color: black;">&#41;</span>:
    params = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'email'</span>: <span style="color: #dc143c;">email</span>, <span style="color: #483d8b;">'senha'</span>: password<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
    response = opener.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s?tentaLogin=1'</span> <span style="color: #66cc66;">%</span> _LOGIN_URI, params<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Invalid credentials check</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> response.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'senha incorreta'</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span>= <span style="color: #ff4500;">0</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> show_order_status<span style="color: black;">&#40;</span>opener, order_id<span style="color: black;">&#41;</span>:
    response = opener.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span>_ORDER_URI <span style="color: #66cc66;">%</span> order_id<span style="color: black;">&#41;</span>
    content = response.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Search for the order status codes</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> key, value <span style="color: #ff7700;font-weight:bold;">in</span> _STATUS_CODES.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> content.<span style="color: black;">find</span><span style="color: black;">&#40;</span>key<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span>= <span style="color: #ff4500;">0</span>:
            title = _NOTIFICATION_TITLE <span style="color: #66cc66;">%</span> order_id
            message = <span style="color: #483d8b;">'%s. %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>value<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, _ORDERS_LINK<span style="color: black;">&#41;</span>
            display_message<span style="color: black;">&#40;</span>title, message, value<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">break</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        display_message<span style="color: black;">&#40;</span>_NOTIFICATION_TITLE <span style="color: #66cc66;">%</span> order_id, <span style="color: #483d8b;">'Status not found'</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    initialize_notification_system<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Ticketmaster Order Status&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">optparse</span>
    p = <span style="color: #dc143c;">optparse</span>.<span style="color: black;">OptionParser</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Required command line options</span>
    p.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'--email'</span>    , <span style="color: #483d8b;">'-e'</span>,
        <span style="color: #008000;">help</span>=<span style="color: #483d8b;">'E-mail address used in your Ticketmaster credentials.'</span><span style="color: black;">&#41;</span>
    p.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'--password'</span> , <span style="color: #483d8b;">'-p'</span>,
        <span style="color: #008000;">help</span>=<span style="color: #483d8b;">'Password used in your Ticketmaster credentials.'</span><span style="color: black;">&#41;</span>
    p.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'--order-ids'</span>, <span style="color: #483d8b;">'-o'</span>,
        <span style="color: #008000;">help</span>=<span style="color: #483d8b;">'Order IDs to be checked, separated by collons.'</span><span style="color: black;">&#41;</span>
&nbsp;
    options = p.<span style="color: black;">parse_args</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> options.<span style="color: #dc143c;">email</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #ff7700;font-weight:bold;">not</span> options.<span style="color: black;">password</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #ff7700;font-weight:bold;">not</span> options.<span style="color: black;">order_ids</span>:
        p.<span style="color: black;">print_help</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        order_ids = <span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> s: s.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, options.<span style="color: black;">order_ids</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">','</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        check_orders<span style="color: black;">&#40;</span>options.<span style="color: #dc143c;">email</span>, options.<span style="color: black;">password</span>, order_ids<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>The reason I&#8217;ve used web scrapping is because the brazilian Ticketmaster doesn&#8217;t seem to provide an API the way <a href="http://flickr.com">Flickr</a> does, for example. Nevertheless, the code is quite simple.</p>
<p>As you can see, it first fires a HTTP request to the login URI in order to validate the user credentials. If the authentication succeeds, our cookie-aware <code>opener</code> will get the session cookies from the server and use them on the following requests, which extract the current order status for each order ID.</p>
<p>Now, let&#8217;s give it a spin:</p>
<div id="attachment_763" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2009/10/order_status1.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2009/10/order_status1-300x104.png" alt="Current order status" title="order_status" width="300" height="104" class="size-medium wp-image-763" /></a><p class="wp-caption-text">Current order status</p></div>
<p>Finally, add a new entry to your <code>crontab</code> to run the script whenever you want (e.g. every 10 minutes):</p>
<pre>*/10 * * * * python ticketmaster_order_status.py --email=your@email.com --password=passwd --order-ids=1234</pre>
<p>Good luck and let there be rock! <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-760-1'>The script only works for the <a href="http://www.ticketmaster.com.br/">brazilian Ticketmaster</a> website. <span class='footnotereverse'><a href='#fnref-760-1'>&#8617;</a></span></li>
<li id='fn-760-2'>The script uses <a href="http://www.galago-project.org/news/index.php">libnotify</a> to display notifications on the screen, so don&#8217;t forget to install it. <span class='footnotereverse'><a href='#fnref-760-2'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/10/12/using-web-scraping-to-follow-your-orders-on-ticketmaster/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

