<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>Destaqueblog</title>
	
	<link>http://weblog.destaquenet.com</link>
	<description>Blog da equipe Destaquenet.</description>
	<lastBuildDate>Sun, 15 Aug 2010 03:14:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Destaqueblog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="destaqueblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Clojure Invade o Dev In Sampa</title>
		<link>http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/</link>
		<comments>http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 11:30:34 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[Português]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[devinsampa]]></category>
		<category><![CDATA[encontro]]></category>
		<category><![CDATA[evento]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[palestra]]></category>
		<category><![CDATA[sao paulo]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=1062</guid>
		<description><![CDATA[No próximo sábado, dia 14/08, acontecerá em São Paulo o 2º Dev In Sampa, um encontro de desenvolvedores de software que não faz propaganda do governo nem apresenta palestras com foco em um único fornecedor. Já era hora! Infelizmente, por &#8230; <a href="http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>No próximo sábado, dia 14/08, acontecerá em São Paulo o 2º <a href="http://devinsampa.com.br/">Dev In Sampa</a>, um encontro de desenvolvedores de software que não <a href="http://fisl.softwarelivre.org/">faz propaganda do governo</a> nem apresenta palestras com <a href="http://www.oracle.com/us/javaonedevelop/index.html">foco em um único fornecedor</a>. Já era hora!</p>
<p>Infelizmente, por <a href="http://weblog.destaquenet.com/2009/10/05/use-web-scraping-para-acompanhar-seus-pedidos-na-ticketmaster/">razões de força maior</a> eu não pude comparecer na primeira edição do evento, mas este ano eu estarei presente, e ainda por cima <a href="http://devinsampa.com.br/palestras#presentation-3">como palestrante</a>.</p>
<p>Por isso, antes de mais nada, eu gostaria de agradecer àqueles que votaram na minha palestra. Isso mostra que <a href="http://clojure.org/">Clojure</a> anda despertando o interesse da rapazeada também no Brasil, o que é muito bom.</p>
<p><strong>Update:</strong> Apresentação e códigos-fonte <a href="http://github.com/danielfm/clojure-devinsampa">disponíveis para download</a>.</p>
<p><span id="more-1062"></span></p>
<h3>Sobre a palestra</h3>
<p>Apresentar uma linguagem de programação numa palestra de 50 minutos é sempre uma tarefa complicada, especialmente se essa linguagem de programação traz consigo uma <a href="http://clojure.org/rationale">bagagem</a> que vai muito além da sintaxe.</p>
<p>Quando eu assisto uma palestra sobre linguagens de programação, existem duas coisas que me irritam. A primeira é quando o palestrante soca um monte de código e se limita à sintaxe, explicando tudo vírgula por vírgula, sem nenhum contexto. A outra é quando o palestrante fala sobre uma linguagem mas não mostra nenhum exemplo.</p>
<p>Para não repetir esses erros, eu optei por um estilo diferente, onde a linguagem é abordada e explorada aos poucos, mas sempre seguindo uma linha para que haja um começo, um meio e um fim.</p>
<p>Meu objetivo não será ensinar ninguém a programar em Clojure, e sim mostrar alguns dos recursos que eu considero importantes. Assim, quem se interessar pode pesquisar mais por conta própria. Afinal, não somos todos auto-didatas?</p>
<p>Quem tiver dúvidas ao final da palestra, ou quiser apenas jogar conversa fora, é só me chamar pelo <a href="http://twitter.com/danielfmt">Twitter</a>. Também não irei reclamar se alguém quiser pagar meu almoço. <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>O &#8220;pós-evento&#8221;</h3>
<p>Ao final, a apresentação será disponibilizada para download no <a href="http://github.com/danielfm">GitHub</a>, juntamente com os <em>muitos</em> exemplos de código. Os slides virão acompanhados de notas que poderão ser lidas como uma espécie de artigo.</p>
<p>Deixarei os comentários deste post habilitados para quem quiser deixar dúvidas ou mensagens sobre a palestra.</p>
<p>É isso aí. Nos encontramos lá!</p>
<img src="http://feeds.feedburner.com/~r/Destaqueblog/~4/iDY5ojdcyNc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Crie seu próprio pendrive USB multi-boot salvador da pátria</title>
		<link>http://weblog.destaquenet.com/2010/08/02/crie-seu-proprio-pendrive-usb-multi-boot-salvador-da-patria/</link>
		<comments>http://weblog.destaquenet.com/2010/08/02/crie-seu-proprio-pendrive-usb-multi-boot-salvador-da-patria/#comments</comments>
		<pubDate>Mon, 02 Aug 2010 11:20:50 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[boot]]></category>
		<category><![CDATA[clonezilla]]></category>
		<category><![CDATA[drive]]></category>
		<category><![CDATA[ferramentas]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[gparted]]></category>
		<category><![CDATA[grub]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[memtest]]></category>
		<category><![CDATA[mint]]></category>
		<category><![CDATA[multi-boot]]></category>
		<category><![CDATA[pendrive]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[usb]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=1060</guid>
		<description><![CDATA[Não preciso convencê-lo de que carregar algumas distribuições Linux com você pode fazer a diferença entre a vida e a morte. Bem, é claro que eu estou sendo um pouco dramático, mas é realmente muito bom poder rodar um teste &#8230; <a href="http://weblog.destaquenet.com/2010/08/02/crie-seu-proprio-pendrive-usb-multi-boot-salvador-da-patria/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Não preciso convencê-lo de que carregar algumas distribuições Linux com você pode fazer a diferença entre a vida e a morte. Bem, é claro que eu estou sendo um pouco dramático, mas é realmente muito bom poder rodar um teste de memória numa máquina que insiste em jogar erros estranhos na sua cara, ou mesmo copiar discos ou partições importantes quando você está por aí.</p>
<p>Para mim, algumas ferramentas e distribuições são particularmente úteis:</p>
<ul>
<li><a href="http://clonezilla.org/">Clonezilla</a>. Ferramenta muito boa para clonagem de disco/partição. Leva algum tempo para iniciantes se acostumarem com ela, mas vale o esforço. Já fui salvo por esta ferramenta mais de uma vez.</li>
<li><a href="http://gparted.sourceforge.net/">GParted</a>. Excelente ferramenta para particionamento de disco.</li>
<li><a href="http://linuxmint.com/">Linux Mint</a>. Distribuição Linux baseada no Ubuntu muito fácil de usar. Eu gosto muito da edição Live-DVD, que inclui softwares como <a href="http://www.videolan.org/vlc/">VLC</a>, <a href="http://www.openoffice.org/">OpenOffice</a> e <a href="http://java.com/">Java</a>.</li>
<li><a href="http://ubuntu.com/">Ubuntu</a>. Uma das distribuições Linux mais populares hoje em dia.</li>
<li><a href="http://www.memtest.org/">Memtest86+</a>. Ferramenta para teste de memória incluída na maioria das distribuições Linux modernas. Indispensável.</li>
</ul>
<p>Agora, em vez de queimar um CD/DVD com cada uma dessas ferramentas, nós iremos usar um pendrive USB multi-boot.</p>
<p><span id="more-1060"></span></p>
<h3>Preparando a pendrive</h3>
<p>O primeiro passo é instalar um bootloader na pendrive para possamos escolher qual distribuição carregar quando bootando a partir dela. Sorte minha que a distribuição Linux que uso, Ubuntu, já vem com o Grub2 pré-instalado. Esta versão do <a href="http://www.gnu.org/software/grub/">Grub</a> em particular é necessária, já que ela nos permite montar e bootar imagens .ISO.</p>
<p>Uma vez que você esteja com o Grub2 instalado, plugue sua pendrive e se certifique de que sua partição principal seja bootável, e que ela esteja formatada com FAT32 (<code>vfat</code>).</p>
<p>Então, rode este comando para instalar o Grub2 no pendrive:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> grub-install <span style="color: #660033;">--no-floppy</span> <span style="color: #660033;">--root-directory</span>=<span style="color: #000000; font-weight: bold;">/</span>media<span style="color: #000000; font-weight: bold;">/</span>PENDRIVE <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sdX</pre></div></div>

<p>Lembre de fazer com que <code>root-directory</code> aponte para o caminho onde o pendrive está montado, e <code>/dev/sdX</code> para o dispositivo em si. Por favor, verifique os parâmetros duas vezes antes de rodar o comando, ou você corre o risco de fazer algo de que se arrependerá depois!</p>
<h3>Configurando o Grub2</h3>
<p>Agora é hora de baixar as imagens .ISO das distribuições mencionadas anteriormente e colocá-las no diretório <code>/boot/iso</code> dentro da pendrive. Então, crie o arquivo <code>/boot/grub/grub.cfg</code> com o seguinte conteúdo:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">menuentry <span style="color: #ff0000;">&quot;Linux Mint 9 x86&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #007800;">isofile</span>=<span style="color: #ff0000;">&quot;/boot/iso/linuxmint-9-gnome-dvd-i386.iso&quot;</span>
  loopback loop <span style="color: #007800;">$isofile</span>
  linux <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>casper<span style="color: #000000; font-weight: bold;">/</span>vmlinuz <span style="color: #007800;">boot</span>=casper iso-scan<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">filename</span>=<span style="color: #007800;">$isofile</span> noeject noprompt <span style="color: #660033;">--</span>
  initrd <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>casper<span style="color: #000000; font-weight: bold;">/</span>initrd.lz
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
menuentry <span style="color: #ff0000;">&quot;Ubuntu 10.04 Desktop x86&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #007800;">isofile</span>=<span style="color: #ff0000;">&quot;/boot/iso/ubuntu-10.04-desktop-i386.iso&quot;</span>
  loopback loop <span style="color: #007800;">$isofile</span>
  linux <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>casper<span style="color: #000000; font-weight: bold;">/</span>vmlinuz <span style="color: #007800;">boot</span>=casper iso-scan<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">filename</span>=<span style="color: #007800;">$isofile</span> noeject noprompt <span style="color: #660033;">--</span>
  initrd <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>casper<span style="color: #000000; font-weight: bold;">/</span>initrd.lz
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
menuentry <span style="color: #ff0000;">&quot;Clonezilla Live 1.2.5-17 x86&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #007800;">isofile</span>=<span style="color: #ff0000;">&quot;/boot/iso/clonezilla-live-1.2.5-17-i686.iso&quot;</span>
  loopback loop <span style="color: #007800;">$isofile</span> 
  linux <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>live<span style="color: #000000; font-weight: bold;">/</span>vmlinuz <span style="color: #007800;">boot</span>=live <span style="color: #007800;">union</span>=aufs nolocales noprompt <span style="color: #007800;">ip</span>=frommedia <span style="color: #007800;">toram</span>=filesystem.squashfs <span style="color: #007800;">findiso</span>=<span style="color: #007800;">$isofile</span> 
  initrd <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>live<span style="color: #000000; font-weight: bold;">/</span>initrd.img
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
menuentry <span style="color: #ff0000;">&quot;GParted Live 0.5.2-9 x86&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #007800;">isofile</span>=<span style="color: #ff0000;">&quot;/boot/iso/gparted-live-0.5.2-9.iso&quot;</span>
  loopback loop <span style="color: #007800;">$isofile</span> 
  linux <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>live<span style="color: #000000; font-weight: bold;">/</span>vmlinuz <span style="color: #007800;">boot</span>=live <span style="color: #007800;">union</span>=aufs nolocales noprompt <span style="color: #007800;">ip</span>=frommedia <span style="color: #007800;">toram</span>=filesystem.squashfs <span style="color: #007800;">findiso</span>=<span style="color: #007800;">$isofile</span> 
  initrd <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>live<span style="color: #000000; font-weight: bold;">/</span>initrd.img
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
menuentry <span style="color: #ff0000;">&quot;Memory test (memtest86+)&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  linux16 <span style="color: #000000; font-weight: bold;">/</span>boot<span style="color: #000000; font-weight: bold;">/</span>iso<span style="color: #000000; font-weight: bold;">/</span>memtest86+.bin
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Não se esqueça de alterar o valor as variáveis <code>isofile</code>, se necessário.</p>
<h3>Ressalva</h3>
<p>Esse negócio todo é novo, e existem apenas algumas  distribuições que podem ser bootadas dessa forma. Caso queira testar outras distribuições, você provavelmente terá que descobrir quais opções de Kernel usar em cada uma delas.</p>
<img src="http://feeds.feedburner.com/~r/Destaqueblog/~4/NQf8syLEWt8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/08/02/crie-seu-proprio-pendrive-usb-multi-boot-salvador-da-patria/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Create your own save-your-ass multi-boot USB stick</title>
		<link>http://weblog.destaquenet.com/2010/08/02/create-your-own-save-your-ass-multi-boot-usb-stick/</link>
		<comments>http://weblog.destaquenet.com/2010/08/02/create-your-own-save-your-ass-multi-boot-usb-stick/#comments</comments>
		<pubDate>Mon, 02 Aug 2010 11:15:46 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[boot]]></category>
		<category><![CDATA[clonezilla]]></category>
		<category><![CDATA[drive]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[gparted]]></category>
		<category><![CDATA[grub]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[memtest]]></category>
		<category><![CDATA[mint]]></category>
		<category><![CDATA[multi-boot]]></category>
		<category><![CDATA[rescue]]></category>
		<category><![CDATA[stick]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[usb]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=1043</guid>
		<description><![CDATA[I don&#8217;t have to convince you that carry around a couple of Linux distros can mean the difference between life and death. Well, of course I&#8217;m being a little bit melodramatic here, but it&#8217;s really nice to have the ability &#8230; <a href="http://weblog.destaquenet.com/2010/08/02/create-your-own-save-your-ass-multi-boot-usb-stick/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t have to convince you that carry around a couple of Linux distros can mean the difference between life and death. Well, of course I&#8217;m being a little bit melodramatic here, but it&#8217;s really nice to have the ability to quickly run a memory test on a machine that insists to misbehave, or even backup important stuff when you are on the go.</p>
<p>For me, some tools and distros are particularly useful:</p>
<ul>
<li><a href="http://clonezilla.org/">Clonezilla</a>. Very nice disk/partition cloning tool. It takes some time for beginners to get used to it, but it&#8217;s worth the effort. This tool saved my life more than once.</li>
<li><a href="http://gparted.sourceforge.net/">GParted</a>. Great tool for disk partitioning.</li>
<li><a href="http://linuxmint.com/">Linux Mint</a>. Very easy to use Ubuntu-based Linux distro. I particularly like the Live-DVD edition, which includes useful software like <a href="http://www.videolan.org/vlc/">VLC</a>, <a href="http://www.openoffice.org/">OpenOffice</a> and <a href="http://java.com/">Java</a>.</li>
<li><a href="http://ubuntu.com/">Ubuntu</a>. One of the most popular Linux distros nowadays.</li>
<li><a href="http://www.memtest.org/">Memtest86+</a>. Memory testing tool bundled in most Linux distros. Indispensable.</li>
</ul>
<p>Now, instead of burning one CD/DVD for each one of these tools, we&#8217;re going to use one multi-boot USB stick.</p>
<p><span id="more-1043"></span></p>
<h3>Preparing the flash drive</h3>
<p>The first step is to install a bootloader on the USB stick, so we can choose which distro/tool to load when booting from it. Lucky for me that my Linux distro of choice, Ubuntu, already comes with Grub2 pre-installed. This particular version of <a href="http://www.gnu.org/software/grub/">Grub</a> is required since it allows us to mount and boot .ISO images.</p>
<p>Once you have Grub2 installed, plug in your USB stick and make sure that its main partition is bootable and is formated with FAT32 (<code>vfat</code>).</p>
<p>Then, run this command to install Grub2 on the stick:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> grub-install <span style="color: #660033;">--no-floppy</span> <span style="color: #660033;">--root-directory</span>=<span style="color: #000000; font-weight: bold;">/</span>media<span style="color: #000000; font-weight: bold;">/</span>USB_STICK <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sdX</pre></div></div>

<p>Remember to make <code>root-directory</code> point to the path where the flash drive is mounted, and change <code>/dev/sdX</code> to the actual device. Please double-check the parameters to avoid messing with the wrong disk!</p>
<h3>Configuring Grub2</h3>
<p>It&#8217;s time to download the .ISO images for one or more of the aforementioned distros and put them all inside the directory <code>/boot/iso/</code> inside flash drive. Then, create the file <code>/boot/grub/grub.cfg</code> with the following content:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">menuentry <span style="color: #ff0000;">&quot;Linux Mint 9 x86&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #007800;">isofile</span>=<span style="color: #ff0000;">&quot;/boot/iso/linuxmint-9-gnome-dvd-i386.iso&quot;</span>
  loopback loop <span style="color: #007800;">$isofile</span>
  linux <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>casper<span style="color: #000000; font-weight: bold;">/</span>vmlinuz <span style="color: #007800;">boot</span>=casper iso-scan<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">filename</span>=<span style="color: #007800;">$isofile</span> noeject noprompt <span style="color: #660033;">--</span>
  initrd <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>casper<span style="color: #000000; font-weight: bold;">/</span>initrd.lz
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
menuentry <span style="color: #ff0000;">&quot;Ubuntu 10.04 Desktop x86&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #007800;">isofile</span>=<span style="color: #ff0000;">&quot;/boot/iso/ubuntu-10.04-desktop-i386.iso&quot;</span>
  loopback loop <span style="color: #007800;">$isofile</span>
  linux <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>casper<span style="color: #000000; font-weight: bold;">/</span>vmlinuz <span style="color: #007800;">boot</span>=casper iso-scan<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">filename</span>=<span style="color: #007800;">$isofile</span> noeject noprompt <span style="color: #660033;">--</span>
  initrd <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>casper<span style="color: #000000; font-weight: bold;">/</span>initrd.lz
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
menuentry <span style="color: #ff0000;">&quot;Clonezilla Live 1.2.5-17 x86&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #007800;">isofile</span>=<span style="color: #ff0000;">&quot;/boot/iso/clonezilla-live-1.2.5-17-i686.iso&quot;</span>
  loopback loop <span style="color: #007800;">$isofile</span> 
  linux <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>live<span style="color: #000000; font-weight: bold;">/</span>vmlinuz <span style="color: #007800;">boot</span>=live <span style="color: #007800;">union</span>=aufs nolocales noprompt <span style="color: #007800;">ip</span>=frommedia <span style="color: #007800;">toram</span>=filesystem.squashfs <span style="color: #007800;">findiso</span>=<span style="color: #007800;">$isofile</span> 
  initrd <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>live<span style="color: #000000; font-weight: bold;">/</span>initrd.img
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
menuentry <span style="color: #ff0000;">&quot;GParted Live 0.5.2-9 x86&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #007800;">isofile</span>=<span style="color: #ff0000;">&quot;/boot/iso/gparted-live-0.5.2-9.iso&quot;</span>
  loopback loop <span style="color: #007800;">$isofile</span> 
  linux <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>live<span style="color: #000000; font-weight: bold;">/</span>vmlinuz <span style="color: #007800;">boot</span>=live <span style="color: #007800;">union</span>=aufs nolocales noprompt <span style="color: #007800;">ip</span>=frommedia <span style="color: #007800;">toram</span>=filesystem.squashfs <span style="color: #007800;">findiso</span>=<span style="color: #007800;">$isofile</span> 
  initrd <span style="color: #7a0874; font-weight: bold;">&#40;</span>loop<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span>live<span style="color: #000000; font-weight: bold;">/</span>initrd.img
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
menuentry <span style="color: #ff0000;">&quot;Memory test (memtest86+)&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  linux16 <span style="color: #000000; font-weight: bold;">/</span>boot<span style="color: #000000; font-weight: bold;">/</span>iso<span style="color: #000000; font-weight: bold;">/</span>memtest86+.bin
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Don&#8217;t forget to change each <code>isofile</code> variable to match the downloaded images.</p>
<h3>Caveat</h3>
<p>This stuff is new, and there are only a few distros that can be booted that way. If you want to try this with other distros than the ones listed here, you&#8217;d probably need to Google for the right Kernel options to use.</p>
<img src="http://feeds.feedburner.com/~r/Destaqueblog/~4/L4cZNCN-pak" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/08/02/create-your-own-save-your-ass-multi-boot-usb-stick/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Django Para Dispositivos Móveis</title>
		<link>http://weblog.destaquenet.com/2010/07/12/django-para-dispositivos-moveis/</link>
		<comments>http://weblog.destaquenet.com/2010/07/12/django-para-dispositivos-moveis/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 11:10:21 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[configuração]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[dispositivo]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[móvel]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[wsgi]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=944</guid>
		<description><![CDATA[Estamos vivendo o que alguns chamam de &#8220;explosão mobile&#8221;, um tempo onde um número cada vez maior de dispositivos móveis &#8212; como tablets e smartphones &#8212; se tornam parte significante da Web. Esta é a razão pela qual ter seu &#8230; <a href="http://weblog.destaquenet.com/2010/07/12/django-para-dispositivos-moveis/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Estamos vivendo o que alguns chamam de &#8220;explosão mobile&#8221;, um tempo onde um número cada vez maior de dispositivos móveis &#8212; como tablets e smartphones &#8212; se tornam parte significante da Web. Esta é a razão pela qual ter seu website preparado para tais dispositivos é cada vez mais importante.</p>
<p>Felizmente, <a href="http://djangoproject.com/">Django</a> é um dos poucos frameworks web que tornam este um problema simples de solucionar.</p>
<p><span id="more-944"></span></p>
<h3>Como resolvemos este problema</h3>
<p>Um jeito simples é criar um módulo <code>settings.py</code> separado para a versão &#8220;mobile&#8221;. Isso nos permite rodar dois sites diferentes reusando a mesma base de código. Além disso, cada versão pode ter seu próprio diretório de templates, configurações de URL, etc.</p>
<p>Vamos fazer isso. No diretório-raíz do projeto, crie um arquivo <code>m_settings.py</code> com o seguinte conteúdo:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #808080; font-style: italic;"># Arquivo: myproject/m_settings.py</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;&quot;Configurações para a versão &quot;mobile&quot; do website.
&quot;&quot;&quot;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Carrega as configurações padrão</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;"># Domínio &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;"># Usado em outras partes do código para determinar qual versão está rodando</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 para a versão mobile</span>
ROOT_URLCONF  = <span style="color: #483d8b;">'myproject.m_urls'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Templates para a versão mobile</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;"># Outras configurações...</span></pre></div></div>

<p>O fato de os dois sites compartilharem a mesma base de código não significa que eles devem ter as mesmas configurações de URL. Aliás, o normal é que versões próprias para dispositivos móveis sejam mais simples, com uma quantidade reduzida de mapeamentos de URLs.</p>
<p>Para definir as configurações de URL da versão mobile, crie um arquivo <code>m_urls.py</code> com o seguinte conteúdo:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #808080; font-style: italic;"># Arquivo: myproject/m_urls.py</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;&quot;Mapeamentos de URL para a versão &quot;mobile&quot;.
&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;
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;"># URLs</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;"># Apps internas</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;"># Outras configurações...</span>
<span style="color: black;">&#41;</span></pre></div></div>

<p>Perceba que, neste exemplo em particular, a <a href="http://docs.djangoproject.com/en/dev/ref/contrib/admin/">app Admin</a> não é acessível através da versão mobile. Isso apenas serve para mostrar que temos total liberdade para estruturar ambas as versões de diferentes formas, sem muitas dificuldades.</p>
<h3>Desenvolvendo</h3>
<p>Você certamente já sabe como rodar o servidor de desenvolvimento para a versão padrão. O que a maioria dos desenvolvedores desconhece, entretanto, é que é possível escolher qual a porta e/ou módulo <code>settings.py</code> deve ser usado pelo script, o que nos permite rodar um servidor para cada versão do nosso site:</p>

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

<p>Pronto, agora é só continuar com o desenvolvimento da forma que você já está acostumado.</p>
<h3>Testando</h3>
<p>Você provavelmente notou que temos duas configurações que podem ser usadas para determinar qual versão do site está rodando, <code>DEFAULT_VERSION</code> e <code>MOBILE_VERSION</code>. </p>
<p>Por isso, é só uma questão de checar tais configurações quando for necessário fazer coisas diferentes em cada uma das versões do site. Isso é particularmente útil quando você tem uma app usada em ambas as versões e quer criar testes para cada uma das versões:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #808080; font-style: italic;"># Arquivo: myproject/myapp/tests/__init__.py</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;&quot;Testes para 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;"># Testa a versão padrão</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;"># Testa a versão mobile</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>Você pode rodar os testes para cada versão de uma forma semelhante a que fizemos com o comando <code>runserver</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash"><span style="color: #666666; font-style: italic;"># Versão padrão</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;"># Versão mobile</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>Colocando em produção</h3>
<p>Apesar do que você possa achar, esta é a parte fácil.</p>
<p>Uma vez que a forma recomendada de <a href="http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/">colocar Django em produção</a> é com <a href="http://apache.org">Apache</a> e <a href="http://code.google.com/p/modwsgi/">mod_wsgi</a>, é possível que você já tenha um arquivo WSGI parecido com o seguinte:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><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;"># Eggs de terceiros</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>Tudo que precisamos fazer é configurar um outro sub-domínio WSGI no nosso servidor (ex: m.mywebsite.com) que referencia o seguinte arquivo de configurações WSGI:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><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;"># Eggs de terceiros</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;"># Esta linha</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>A única diferença entre esses dois arquivos WSGI é que cada um aponta para um módulo <code>settings.py</code> diferente. E não, você não precisa ter uma cópia do site para cada versão, afinal estamos usando a mesma base de código para ambas as versões, lembra? <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h3>Minimizando o tráfego</h3>
<p>Por incrível que pareça, nem todo mundo dispõe de conexões ultra-rápidas. Por isso, é muito importante que você mantenha seus sites tão leves quanto possível.</p>
<p>Existem vários projetos open source que podem ajudar nessa parte. Um deles é o <a href="http://code.google.com/p/django-compress/">django-compress</a>, uma app Django que fornece um sistema automatizado para compressão de arquivos CSS e JavaScript.</p>
<p>Aliás, não importa se seus websites são para dispositivos móveis ou não; você deve <em>sempre</em> tentar minimizar o tráfego.</p>
<h3>O que falta?</h3>
<p>Ainda temos um pequeno problema: quando alguém visita a versão padrão do site através de um dispositivo móvel, ou vice-versa, eles não são redirecionados para a versão apropriada. Mas isso é assunto para um próximo artigo!</p>
<img src="http://feeds.feedburner.com/~r/Destaqueblog/~4/PsANAB2koPA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/07/12/django-para-dispositivos-moveis/feed/</wfw:commentRss>
		<slash:comments>4</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"><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"><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"><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"><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"><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"><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"><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>
<img src="http://feeds.feedburner.com/~r/Destaqueblog/~4/wi1xMucOjC8" height="1" width="1"/>]]></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>Servidor De Email Local No Ubuntu Com Exim</title>
		<link>http://weblog.destaquenet.com/2010/06/25/servidor-de-email-local-no-ubuntu-com-exim/</link>
		<comments>http://weblog.destaquenet.com/2010/06/25/servidor-de-email-local-no-ubuntu-com-exim/#comments</comments>
		<pubDate>Fri, 25 Jun 2010 11:10:07 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[ambiente]]></category>
		<category><![CDATA[configuração]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[exim]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[sendmail]]></category>
		<category><![CDATA[servidor]]></category>
		<category><![CDATA[smtp]]></category>
		<category><![CDATA[telnet]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=981</guid>
		<description><![CDATA[Vimos em um post anterior como criar testes para código Java que envia e-mails. Agora o assunto é outro. Exim é um MTA open source que pode ser usado como alternativa ao Sendmail em sistemas operacionais Unix. Eu não tenho &#8230; <a href="http://weblog.destaquenet.com/2010/06/25/servidor-de-email-local-no-ubuntu-com-exim/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Vimos em um post anterior como criar testes para <a href="http://weblog.destaquenet.com/2008/09/20/2-boas-formas-de-testar-clientes-javamail/">código Java que envia e-mails</a>. Agora o assunto é outro.</p>
<p><a href="http://www.exim.org/">Exim</a> é um <acronym title="Mail Transfer Agent">MTA</acronym> open source que pode ser usado como alternativa ao <a href="http://www.sendmail.org/">Sendmail</a> em sistemas operacionais Unix. Eu não tenho idéia de qual é a melhor alternativa disponível, mas se você procura por um servidor de relay para instalar na sua configuração de desenvolvimento, Exim é provavelmente a opção mais simples para começar.</p>
<p>Neste artigo, veremos como configurar o Exim para enviar mensagens através do <a href="http://gmail.com/">Gmail</a>.</p>
<p><span id="more-981"></span></p>
<h3>Instalando o Exim</h3>
<p>Primeiro precisamos instalar o Exim e suas dependências, o que é algo bastante trivial em distribuições Linux modernas como <a href="http://www.ubuntu.com/">Ubuntu</a>/<a href="http://www.debian.org/">Debian</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> exim4</pre></div></div>

<h3>Usando Exim como servidor de relay</h3>
<p>Existe um assistente que nos ajuda a fazer as configurações básicas; rode o comando abaixo para abrí-lo e preencha cada tela como segue:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> dpkg-reconfigure exim4-config</pre></div></div>

<ol>
<li><strong>General type of mail configuration:</strong> mail sent by smarthost; received via SMTP or fetchmail</li>
<li><strong>System mail name:</strong> seudominio.com</li>
<li><strong>IP-addresses to listen on for incoming connections:</strong> 127.0.0.1 ; ::1</li>
<li><strong>Other destinations for which mail is accepted:</strong> Deixe em branco</li>
<li><strong>Machines to relay mail for:</strong> Deixe em branco</li>
<li><strong>Host name for the outgoing smarthost:</strong> smtp.gmail.com:587</li>
<li><strong>Hide local mail name in outgoing mail:</strong> Yes</strong></li>
<li><strong>Visible domain name for local users:</strong> seudominio.com</li>
<li><strong>Keep number of DNS-queries minimal:</strong> No</li>
<li><strong>Delivery method for local mail:</strong> mbox format in /var/mail/</li>
<li><strong>Split configuration into small files:</strong> Yes</li>
<li><strong>Root and postmaster mail recipient:</strong> Deixe em branco</li>
</ol>
<p>Agora precisamos configurar as credenciais do usuário no arquivo <code>/etc/exim4/passwd.client</code> adicionando a seguinte linha:</p>
<pre>
# Troque [username] e [password] pelos dados corretos
*.google.com:[username]:[password]
</pre>
<p>Agora basta rodar o comando abaixo para terminar as configurações:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> update-exim4.conf</pre></div></div>

<h3>Testando o servidor</h3>
<p>Um jeito simples &#8212; e nerd &#8212; de testar se as configurações estão corretas é usar o comando <code>telnet</code>:</p>
<pre>
$ telnet localhost 25
    Trying ::1...
    Connected to localhost.
    Escape character is '^]'.
    220 localhost ESMTP Exim 4.71 Wed, 23 Jun 2010 22:28:56 -0300
HELO localhost
    250 localhost Hello localhost [::1]
MAIL FROM: usuario@seudominio.com
    250 OK
RCPT TO: destino@email.com
    250 Accepted
DATA
    354 Enter message, ending with "." on a line by itself
SUBJECT: Assunto da mensagem
Testando Exim via Telnet. Massa!
.
    250 OK id=1ORbG5-0005uh-EF
QUIT
    221 localhost closing connection
    Connection closed by foreign host.
</pre>
<p>Abra os arquivos de log em <code>/var/log/exim4</code> para ver se a mensagem foi transmitida sem erros. Uma tentativa bem sucedida se parece com o seguinte:</p>
<pre>
2010-06-23 22:29:47 1ORbG5-0005uh-EF <= local@seudominio.com H=localhost [::1] P=smtp S=345
2010-06-23 22:29:50 1ORbG5-0005uh-EF => destino@email.com R=smarthost T=remote_smtp_smarthost H=gmail-smtp-msa.l.google.com [74.125.45.109] ..."
2010-06-23 22:29:50 1ORbG5-0005uh-EF Completed
</pre>
<p>Caso você não receba a mensagem e os logs não acusem nenhum erro, verifique se a mensagem não foi parar na caixa de spam antes que você mude quaisquer configurações.</p>
<img src="http://feeds.feedburner.com/~r/Destaqueblog/~4/WyRIxCyQJ1Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/06/25/servidor-de-email-local-no-ubuntu-com-exim/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Setting Up A Local Mail Server With Exim And Ubuntu</title>
		<link>http://weblog.destaquenet.com/2010/06/25/setting-up-a-local-mail-server-with-exim-and-ubuntu/</link>
		<comments>http://weblog.destaquenet.com/2010/06/25/setting-up-a-local-mail-server-with-exim-and-ubuntu/#comments</comments>
		<pubDate>Fri, 25 Jun 2010 11:00:08 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[environment]]></category>
		<category><![CDATA[exim]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[sendmail]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[smtp]]></category>
		<category><![CDATA[telnet]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=936</guid>
		<description><![CDATA[Exim is an open source MTA that can be used as a drop-in replacement for Sendmail on Unix-like operating systems. I have no idea what&#8217;s the best mail server out there, but if you are looking for a relay-only server &#8230; <a href="http://weblog.destaquenet.com/2010/06/25/setting-up-a-local-mail-server-with-exim-and-ubuntu/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.exim.org/">Exim</a> is an open source <acronym title="Mail Transfer Agent">MTA</acronym> that can be used as a drop-in replacement for <a href="http://www.sendmail.org/">Sendmail</a> on Unix-like operating systems. I have no idea what&#8217;s the best mail server out there, but if you are looking for a relay-only server to install on your development setup, Exim is probably the easiest to get started with.</p>
<p>In this article I&#8217;ll show you how to configure Exim to send messages through <a href="http://gmail.com/">Gmail</a>.</p>
<p><span id="more-936"></span></p>
<h3>Installing Exim</h3>
<p>First we need to install Exim and its dependencies, which is a simple task in modern Linux distros like <a href="http://www.ubuntu.com/">Ubuntu</a>/<a href="http://www.debian.org/">Debian</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> exim4</pre></div></div>

<h3>Configuring Exim as a relay server</h3>
<p>There&#8217;s a wizard that helps us with the basic setup; run the following command line to open it and fill each screen as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> dpkg-reconfigure exim4-config</pre></div></div>

<ol>
<li><strong>General type of mail configuration:</strong> mail sent by smarthost; received via SMTP or fetchmail</li>
<li><strong>System mail name:</strong> yourdomain.com</li>
<li><strong>IP-addresses to listen on for incoming connections:</strong> 127.0.0.1 ; ::1</li>
<li><strong>Other destinations for which mail is accepted:</strong> Leave it blank</li>
<li><strong>Machines to relay mail for:</strong> Leave it blank</li>
<li><strong>Host name for the outgoing smarthost:</strong> smtp.gmail.com:587</li>
<li><strong>Hide local mail name in outgoing mail:</strong> Yes</strong></li>
<li><strong>Visible domain name for local users:</strong> yourdomain.com</li>
<li><strong>Keep number of DNS-queries minimal:</strong> No</li>
<li><strong>Delivery method for local mail:</strong> mbox format in /var/mail/</li>
<li><strong>Split configuration into small files:</strong> Yes</li>
<li><strong>Root and postmaster mail recipient:</strong> Leave it blank</li>
</ol>
<p>Now we have to configure the user credentials in the file <code>/etc/exim4/passwd.client</code> by adding the following line:</p>
<pre>
# Replace [username] and [password] by your account's credentials
*.google.com:[username]:[password]
</pre>
<p>Let&#8217;s finish the configuration by running the following command line:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> update-exim4.conf</pre></div></div>

<h3>Testing the setup</h3>
<p>Here&#8217;s an old-s<strong>c</strong>h<strong>ool</strong> way to test if our setup is working &#8212; with <code>telnet</code> command:</p>
<pre>
$ telnet localhost 25
    Trying ::1...
    Connected to localhost.
    Escape character is '^]'.
    220 localhost ESMTP Exim 4.71 Wed, 23 Jun 2010 22:28:56 -0300
HELO localhost
    250 localhost Hello localhost [::1]
MAIL FROM: username@yourdomain.com
    250 OK
RCPT TO: destination@email.com
    250 Accepted
DATA
    354 Enter message, ending with "." on a line by itself
SUBJECT: Message subject
Testing Exim via telnet. w00t!
.
    250 OK id=1ORbG5-0005uh-EF
QUIT
    221 localhost closing connection
    Connection closed by foreign host.
</pre>
<p>Open the log files at <code>/var/log/exim4</code> to see if the message relayed correctly. This is how a successful attempt looks like:</p>
<pre>
2010-06-23 22:29:47 1ORbG5-0005uh-EF <= local@yourdomain.com H=localhost [::1] P=smtp S=345
2010-06-23 22:29:50 1ORbG5-0005uh-EF => destination@email.com R=smarthost T=remote_smtp_smarthost H=gmail-smtp-msa.l.google.com [74.125.45.109] ..."
2010-06-23 22:29:50 1ORbG5-0005uh-EF Completed
</pre>
<p>If the log looks good and you didn&#8217;t get the message, it&#8217;s a good idea to check the spam box of the destination email before you change any configuration.</p>
<img src="http://feeds.feedburner.com/~r/Destaqueblog/~4/iXx3RWVEwG0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/06/25/setting-up-a-local-mail-server-with-exim-and-ubuntu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>At World Cup Season…</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"><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"><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"><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"><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"><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"><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"><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?
<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>
<img src="http://feeds.feedburner.com/~r/Destaqueblog/~4/U5_ux_uo-DY" height="1" width="1"/>]]></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>Em Tempos de Copa do Mundo…</title>
		<link>http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/</link>
		<comments>http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 11:00:16 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[aposta]]></category>
		<category><![CDATA[bolão]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[copa do mundo]]></category>
		<category><![CDATA[futebol]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[meme]]></category>
		<category><![CDATA[programa]]></category>
		<category><![CDATA[solução]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=898</guid>
		<description><![CDATA[Há quem ache &#8212; e eu concordo &#8212; que a UEFA Champions League é um torneio mais relevante do que a Copa do Mundo, mas não podemos negar que o Mundial mexe com a nossa rotina. Mesmo quem não é &#8230; <a href="http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Há quem ache &#8212; e eu concordo &#8212; que a <a href="http://www.uefa.com/uefachampionsleague/index.html">UEFA Champions League</a> é um torneio mais relevante do que a <a href="http://www.fifa.com/worldcup/index.html">Copa do Mundo</a>, mas não podemos negar que o Mundial mexe com a nossa rotina. Mesmo quem não é apaixonado pelo esporte passa a prestar atenção nas seleções, nas partidas, na festa.</p>
<p>E com a Copa do Mundo vem os bolões. Muitos bolões.</p>
<p>Todo mundo já sabe como funciona um bolão, embora a mecânica possa mudar de um lugar para outro:</p>
<ol>
<li>Cada palpite tem um valor fixo (ex: R$2,00).</li>
<li>Cada um pode dar quantos palpites quiser.</li>
<li>No final, o montante arrecadado é dividido igualmente entre os vencedores. Se não houverem vencedores: (a) o bolão &#8220;acumula&#8221;<sup class='footnote'><a href='#fn-898-1' id='fnref-898-1'>1</a></sup>, ou (b) todo mundo recebe seu dinheiro de volta, ou (c) sua-regra-maluca-aqui.</li>
</ol>
<p>Esse tipo de bolão é interessante, mas ele podia ser melhor em alguns aspectos.</p>
<p>Primeiro, o organizador acaba perdendo muito tempo correndo atrás de troco, afinal não é todo mundo que anda com dinheiro trocado na carteira. Além disso, valor fixo de palpite é muito chato, pois o valor arrecadado é dividido por igual entre os ganhadores. O bolão fica muito mais interessante quando o valor do palpite é variável e o valor arrecadado é dividido proporcionalmente entre os ganhadores. Assim, no caso de vários ganhadores, ganha mais quem apostar mais.</p>
<p>O problema de se fazer bolões com palpite variável é ter que ficar calculando o valor proporcional a ser dado a cada ganhador. Portanto eis o desafio: criar um programa que receba uma lista com todos os palpites e retorne uma lista com os palpites vencedores juntamente com o valor proporcional a ser pago a cada ganhador.</p>
<p>E aí, topa?</p>
<p><span id="more-898"></span></p>
<h3>Resolvendo o problema&#8230; em Clojure</h3>
<p>Como escrever mais código do que necessário está saindo de moda, optei por codificar uma possível solução em <a href="http://clojure.org">Clojure</a>. Por ser uma <a href="http://weblog.destaquenet.com/2009/06/16/programacao-funcional-vale-a-pena-aprender/">linguagem funcional</a>, Clojure é excelente para esse tipo de tarefa. Basta iniciar o <a href="http://clojure.org/repl_and_main">REPL</a> e mãos à obra!</p>
<p>Primeiramente, devemos definir como um palpite deve ser representado:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp"><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>Todos os palpites possuem o mesmo conjunto de informações, por isso definimos um <a href="http://clojure.org/data_structures#Data%20Structures-StructMaps">StructMap</a> com as chaves <code>:name</code>, <code>:amount</code>, <code>:guess</code> e <code>:rate</code>.</p>
<p>Abaixo, uma possível lista de palpites:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp"><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 aposta R$2,00 no placar 2x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Antônio&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;">;; Antônio aposta R$4,00 no placar 0x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Marcela&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;">;; Marcela aposta R$1,00 no placar 2x0</span>
     <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Certo, já sabemos como os palpites são representados. Agora, como saber o montante total de uma lista de palpites (a.k.a. bolão)? Simples, basta calcular o somatório dos valores de todos os palpites:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp"><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;">;; testando</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>Beleza, mas quanto cada palpite representa em relação ao total arrecadado? Afinal, precisamos calcular o valor proporcional a ser pago a cada ganhador.</p>
<p>Sem problemas, basta dividir o valor de cada palpite pelo montante total:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp"><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;">;; testando</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>Repare que, se todos os participantes ganhassem um bolão, o valor recebido pelo Antônio seria o dobro do valor recebido pelo Daniel, que seria o dobro do valor recebido pela Marcela. Justiça, finalmente!</p>
<p>Pronto, agora só falta uma função para filtrar os ganhadores da lista de participantes e calcular o valor proporcional a ser pago a cada um deles:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp"><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;">;; testando</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;">;; sem ganhadores</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;">;; apenas um ganhador</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;Antônio&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;">;; vários ganhadores</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;Marcela&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>Uma grande vantagem dessa solução é que ela permite que você aposte em qualquer coisa. Quer apostar no sexo de um bebê logo após a boa notícia (ou má notícia, sei lá)?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp"><span style="color: #808080; font-style: italic;">;; :male = masculino, :female = feminino</span>
<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;Antônio&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;Fran&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: #808080; font-style: italic;">;; testando</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;Antônio&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;Fran&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>Aí está, uma solução simples para um problema simples. Como deveria ser sempre.</p>
<h3>Minha solução, na íntegra</h3>
<p>Embora seja possível resolver isso com um one-liner em Lisp/Clojure (afinal o <a href="http://clojure.org/reader">Reader</a> não trabalha com linhas, mas com <strong>estruturas de dados</strong>), eu optei por escrever um código que fosse o mais legível possível para quem não conhece ou está aprendendo Clojure:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp"><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>Levando adiante</h3>
<p>Você programa em Haskell? Python? Ruby? <a href="http://en.wikipedia.org/wiki/Brainfuck">Brainfuck</a>? Qual seria a sua solução para este problema de extrema importância para o desenvolvimento da raça humana? <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-898-1'>Todo o montante recebido continua disponível no próximo bolão, mas os participantes devem pagar um novo palpite. <span class='footnotereverse'><a href='#fnref-898-1'>&#8617;</a></span></li>
</ol>
</div>
<img src="http://feeds.feedburner.com/~r/Destaqueblog/~4/rI2JyKxdxwY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django-Flash e o Novo Framework de Mensagens</title>
		<link>http://weblog.destaquenet.com/2010/05/21/django-flash-e-o-novo-framework-de-mensagens/</link>
		<comments>http://weblog.destaquenet.com/2010/05/21/django-flash-e-o-novo-framework-de-mensagens/#comments</comments>
		<pubDate>Fri, 21 May 2010 02:36:14 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></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=890</guid>
		<description><![CDATA[No começo da semana, depois de vários meses de trabalho duro e algum atraso, a versão 1.2 do Django foi finalmente lançada. Este talvez seja o lançamento mais aguardado do framework desde seu surgimento, e inclui recursos há muito aguardados, &#8230; <a href="http://weblog.destaquenet.com/2010/05/21/django-flash-e-o-novo-framework-de-mensagens/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>No começo da semana, depois de vários meses de trabalho duro e algum atraso, a versão 1.2 do Django <a href="http://www.djangoproject.com/download/">foi finalmente lançada</a>. Este talvez seja o lançamento mais aguardado do framework desde seu surgimento, e inclui recursos há muito aguardados, como <a href="http://docs.djangoproject.com/en/dev/releases/1.2/#support-for-multiple-databases">suporte a múltiplos bancos de dados</a> e um <a href="http://docs.djangoproject.com/en/dev/releases/1.2/#messages-framework">framework de &#8220;mensagens&#8221;</a>.</p>
<p>Sim, eu disse que o Django 1.2 traz incluso um framework de &#8220;mensagens&#8221;. Bom, né? Django realmente precisava vir acompanhado de uma app para resolver essa questão. Isso não significa, no entanto, que <a href="http://djangoflash.destaquenet.com/">Django-Flash</a> será descontinuado ou abandonado.</p>
<p>Então, se você usa Django-Flash em seus projetos, não se preocupe! Nada mudará. Django-Flash já é compatível com Django 1.2, e nós ocontinuaremos a mantê-lo por algumas razões.</p>
<p>A primeira delas é que nos importamos com quem usa nosso software. Nós não quebraremos seus projetos se você decidir fazer o upgrade para uma versão mais recente do Django &#8211; ou se decidir continuar usando uma versão anterior.</p>
<p>A outra é a liberdade de escolha. Você sabe, não existe uma única forma de se resolver todos os problemas. As pessoas devem ser livres para escolher a ferramenta apropriada a uma determinada situação.</p>
<p>Por exemplo, baseado nas minhas primeiras impressões, existem algumas coisas que eu realmente não gostei no novo framework de &#8220;mensagens&#8221;:</p>
<ol>
<li>Ele é <em>verboso</em> mesmo nos casos de uso mais simples</li>
<li>Ele associa mensagens a números de prioridade, encorajando os usuários a usá-lo como um framework de logging/debugging. Quero dizer, um framework de &#8220;mensagens&#8221; não é um framework de logging/debugging, certo?</li>
</ol>
<p>Mas essa é apenas a minha opinião. Talvez seja isso que faz do open source algo tão formidável!</p>
<img src="http://feeds.feedburner.com/~r/Destaqueblog/~4/GpJayf1eJwY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/05/21/django-flash-e-o-novo-framework-de-mensagens/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic page generated in 1.637 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-09-01 00:57:45 --><!-- Compression = gzip -->
