<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Log4Dev &#187; Desenvolvimento</title>
	<atom:link href="http://log4dev.com/category/desenvolvimento/feed/" rel="self" type="application/rss+xml" />
	<link>http://log4dev.com</link>
	<description></description>
	<lastBuildDate>Mon, 03 Oct 2011 22:20:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
	<div id='fb-root'></div>
					<script type='text/javascript'>
						window.fbAsyncInit = function()
						{
							FB.init({appId: null, status: true, cookie: true, xfbml: true});
						};
						(function()
						{
							var e = document.createElement('script'); e.async = true;
							e.src = document.location.protocol + '//connect.facebook.net/pt_BR/all.js';
							document.getElementById('fb-root').appendChild(e);
						}());
					</script>	
						<item>
		<title>Bitbucket com Git. Existe?</title>
		<link>http://log4dev.com/2011/10/03/bitbucket-com-git-existe/</link>
		<comments>http://log4dev.com/2011/10/03/bitbucket-com-git-existe/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 22:20:13 +0000</pubDate>
		<dc:creator>Miguel Galves</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Ferramentas]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=880</guid>
		<description><![CDATA[A partir de hoje existe. Segue um trecho do anúncio no blog do Bitbucket: You’ve been asking for it, we’ve even joked about it – now it’s here (for real): for the one year anniversary of Bitbucket joining Atlassian, we are happy to announce Git support. All your source, all in one-place Whether you are using Hg [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2011/10/03/bitbucket-com-git-existe/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>A partir de hoje existe. Segue um trecho do anúncio no <a href="http://blog.bitbucket.org/2011/10/03/bitbucket-now-rocks-git/">blog do Bitbucket</a>:
<blockquote>You’ve been asking for it, we’ve even <a rel="nofollow" href="http://blog.bitbucket.org/2009/04/01/announcing-git-support/">joked about it</a> – now it’s here (for real): for the one year anniversary of Bitbucket joining Atlassian, we are happy to announce <strong>Git support</strong>.
<h3 id="Gitbucketpublicblog-Allyoursourceallinone-place">All your source, all in one-place</h3>
Whether you are using Hg or Git, you can now keep all of your code in one place with your preferred DVCS format. If you have existing code you would like to migrate, you can easily <strong><a rel="nofollow" href="https://bitbucket.org/repo/import">import your Git, Mercurial or Subversion source code</a></strong>. We have added a new importer for GitHub to our existing site importers which include SourceForge, Google Code and Codeplex.</blockquote>
Além disso, eles anunciam 350 novidades e bugfixes.</p>

<p>Mas daí você me pergunta: &#8220;Porque usar o <strong>Bitbucket</strong> para armazenar meus repositórios <strong>Git</strong> em vez de usar o tradicional <strong>GitHub</strong>?&#8221;</p>

<p>Bom, se você está desenvolvendo projetos <strong>Open Source</strong>, provavelmente o <strong>GitHub</strong> seja uma opção mais apropriada, já que ele se tornou referência. Muitas empresas pedem que candidatos adicionem o seu endereço GitHub nos currículos. Já BitBucket eu nunca vi.</p>

<p>Em compensação, se você está desenvolvendo projetos fechados, aí o Bitbucket é vantajoso. Em todos os planos, o número de repositórios privados é ilimitados. Na conta gratuíta, a limitação fica por conta do número de usuários: 5 no máximo, o que é mais do que suficiente para 99% das startups (o <a href="http://siga.st">SIGA</a> é uma delas). Já para empresas maiores, por 80 dólares por mês você tem direito ao <a href="https://bitbucket.org/plans">plano UNLIMITED</a>: repositórios ilimitados e usuários ilimitados! No GitHub <a href="https://github.com/plans">o maior plano custa 200 dólares mensais</a>, e dá direito a no máximo 125 repositórios privados.</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2011/10/03/bitbucket-com-git-existe/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Você está tentando implementar Sign In com Twitter em um iFrame?</title>
		<link>http://log4dev.com/2011/07/27/voce-esta-tentando-implementar-sign-in-com-twitter-em-um-iframe/</link>
		<comments>http://log4dev.com/2011/07/27/voce-esta-tentando-implementar-sign-in-com-twitter-em-um-iframe/#comments</comments>
		<pubDate>Wed, 27 Jul 2011 15:49:25 +0000</pubDate>
		<dc:creator>Miguel Galves</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=875</guid>
		<description><![CDATA[Então desista já. Não perca tempo (como eu perdi algumas várias horas)! Não funciona! Fazendo uma rápida pesquisa na internet, descobrimos que o Twitter implementou um Javascript que impede a página de login de ser exibida caso esteja dentro de um iFrame (pode tentar, o resultado final será uma página em branco). O motivo: questões [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2011/07/27/voce-esta-tentando-implementar-sign-in-com-twitter-em-um-iframe/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>Então desista já. Não perca tempo (como eu perdi algumas várias horas)!</p>

<p>Não funciona!</p>

<p>Fazendo uma rápida pesquisa na internet, descobrimos que o <strong>Twitter</strong> implementou um <strong>Javascript</strong> que impede a página de login de ser exibida caso esteja dentro de um <strong>iFrame</strong> (pode tentar, o resultado final será uma página em branco). O motivo: questões de segurança.</p>

<p>Portanto, ou exiba a página na janela principal do seu navegador, ou use um popup.</p>

<p>E tenho dito.</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2011/07/27/voce-esta-tentando-implementar-sign-in-com-twitter-em-um-iframe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uma idéia na cabeça, um laptop na mão.</title>
		<link>http://log4dev.com/2011/07/06/uma-ideia-na-cabeca-um-laptop-na-mao/</link>
		<comments>http://log4dev.com/2011/07/06/uma-ideia-na-cabeca-um-laptop-na-mao/#comments</comments>
		<pubDate>Wed, 06 Jul 2011 20:40:21 +0000</pubDate>
		<dc:creator>Miguel Galves</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Ferramentas]]></category>
		<category><![CDATA[Idéias]]></category>
		<category><![CDATA[Produto]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=865</guid>
		<description><![CDATA[Pessoas tem idéias de produtos ou soluções para problemas todos os dias. Muitas destas idéias são de fato interessante. Algumas pessoas possuem o conhecimento necessário para fazer com que esta idéia se torne realidade. Quase ninguém tem a persistência e a força de vontade necessárias para colocar a idéia no ar. Dos vários aspectos que me impressionaram e [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2011/07/06/uma-ideia-na-cabeca-um-laptop-na-mao/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>Pessoas tem idéias de produtos ou soluções para problemas todos os dias. Muitas destas idéias são de fato interessante. Algumas pessoas possuem o conhecimento necessário para fazer com que esta idéia se torne realidade. Quase ninguém tem a persistência e a força de vontade necessárias para colocar a idéia no ar.</p>

<p>Dos vários aspectos que me impressionaram e agradaram na minha curta passagem pelo <a href="http://apontador.com.br">Apontador</a>, um que me agradou muito foi a concentração de pessoas boas que tinham projetos pessoais interessantes e funcionando, com pinta de sistema profissional. Corroborou mais uma das minhas teorias sobre empresas PONTOCOM: atraem pessoas diferentes, que gostam de criar e resolver problemas.</p>

<p>Eu gostaria de citar dois destes projetos, que eu usei e que realmente me ajudaram.</p>

<p>O primeiro é o <a href="http://www.cruzalinhas.com/">Cruzalinhas</a>, desenvolvido pelo <a href="http://chester.blog.br/sobre">Chester</a>. Parafraseando o site, o Cruzalinhas permite que uma pessoa &#8220;<em>saiba quais linhas de ônibus, trem ou metrô passam perto de um lugar em São Paulo&#8221;. </em>A interface não poderia ser mais intuitiva: clique em um ponto do mapa da cidade, e veja todas as linhas de ônibus e metrô que passam por perto. Clique em um segundo ponto, e veja todas as linhas que podem potencialmente levá-lo de um lugar para o outro.</p>

<p>O segundo é o <a href="http://www.encontreseupacote.com.br/">Encontre Seu Pacote</a>, criado pelo Thiago Ganzarolli, colega de UNICAMP. O sistema permite rastrear os pacotes enviados por SEDEX em um mapa, por RSS ou via Direct Message do Twitter. O screencast deles, plagiado abaixo, explica melhor o funcionamento.</p>

<p><object width="640" height="390"><param name="movie" value="http://www.youtube.com/v/NGJJXL_308M&amp;hl=en_US&amp;feature=player_embedded&amp;version=3" /><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><embed type="application/x-shockwave-flash" width="640" height="390" src="http://www.youtube.com/v/NGJJXL_308M&amp;hl=en_US&amp;feature=player_embedded&amp;version=3" allowfullscreen="true" allowscriptaccess="always"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2011/07/06/uma-ideia-na-cabeca-um-laptop-na-mao/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Python Hack of The Day</title>
		<link>http://log4dev.com/2011/02/02/python-hack-of-the-day/</link>
		<comments>http://log4dev.com/2011/02/02/python-hack-of-the-day/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 16:54:32 +0000</pubDate>
		<dc:creator>Miguel Galves</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=843</guid>
		<description><![CDATA[Da série &#8220;coisas bobas que me fazem gostar mais ainda de Python&#8220;&#8230; Problema a ser resolvido: gerar uma sequência aleatória de digitos e caracteres ASCII para criação de senhas automáticas. Solução: ''.join(random.choice(string.asciiuppercase + string.digits + string.asciilowercase) for x in range(8))]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2011/02/02/python-hack-of-the-day/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>Da série &#8220;coisas bobas que me fazem gostar mais ainda de <strong>Python</strong>&#8220;&#8230;</p>

<p><strong>Problema a ser resolvido: </strong>gerar uma sequência aleatória de digitos e caracteres ASCII para criação de senhas automáticas.</p>

<p><strong>Solução:</strong>
<pre>''.join(random.choice(string.ascii<em>uppercase + string.digits + string.ascii</em>lowercase) for x in range(8))</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2011/02/02/python-hack-of-the-day/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Projectional Language Workbenches</title>
		<link>http://log4dev.com/2011/01/16/projectional-language-workbenches/</link>
		<comments>http://log4dev.com/2011/01/16/projectional-language-workbenches/#comments</comments>
		<pubDate>Sun, 16 Jan 2011 18:56:43 +0000</pubDate>
		<dc:creator>Thiago Bartolomei</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Ferramentas]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=820</guid>
		<description><![CDATA[Eu pensei bastante em como traduzir esse nome, mas não gostei de &#8220;Bancada Projecional de Linguagens&#8221;, então me perdoem mas vou usar em inglês mesmo. Projectional Language Workbench é um termo cunhado pelo Martin Fowler pra descrever um novo tipo de ferramenta usada em programação orientada a linguagens. A idéia deste post é apresentar brevemente [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2011/01/16/projectional-language-workbenches/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>Eu pensei bastante em como traduzir esse nome, mas não gostei de &#8220;Bancada Projecional de Linguagens&#8221;, então me perdoem mas vou usar em inglês mesmo. <a href="http://martinfowler.com/articles/languageWorkbench.html">Projectional Language Workbench</a> é um termo cunhado pelo <a href="http://martinfowler.com">Martin Fowler</a> pra descrever um novo tipo de ferramenta usada em programação orientada a linguagens. A idéia deste post é apresentar brevemente os principais conceitos por traz disso. Eu aconselho os interessados a ler os artigos do Martin Fowler e o <a href="http://confluence.jetbrains.net/display/MPSD1/MPS+User%27s+Guide">guia do MPS</a> (em inglês).</p>

<p>Programação orientada a linguagens é um termo pra descrever a idéia de usar várias linguagens específicas de domínio (domain specific languages, DSLs) para desenvolver software. DSLs são linguagens criadas com um escopo limitado, o &#8220;domínio&#8221;. A vantagem de uma DSL é que ela contém abstrações bem próximas ao domínio, então em teoria usuários conseguem se expressar mais facilmente do que em uma linguagem de propósito geral (general purpose language, GPL). Por exemplo, <a href="http://dinosaur.compilertools.net/">lex e yacc</a> são DSLs para descrever lexers e parsers, respectivamente. Você não vai escrever o compilador inteiro com elas, mas são ótimas, concisas, pra descrever aquele domínio específico. Se você fez um curso de compiladores sabe muito bem o trabalho que daria pra escrever o lexer e o parser &#8220;na mão&#8221;.</p>

<p>Um problema de se usar várias DSLs pra desenvolver um sistema é que nem sempre os domínios de cada DSL são tão bem separados como no caso de lexers, parsers e o backend do compilador. Muitas vezes as linguagens precisam interagir mais. Por exemplo, imagine que você tem um programa em Java e em alguma parte precisa definir uma máquina de estado. Um jeito é implementar a máquina de estado direto em Java. Outro jeito é criar uma DSL pra máquinas de estado, vamos chamar de SML (state machine language), que você pode reusar em vários projetos e que esconde detalhes da implementação Java. Mas então o código fonte teria que conter código Java e código escrito em SML. O problema é que as duas linguagens interagem, e escrever um compilador que entenda Java e SML é complicado.</p>

<p>É aí que entram projectional language workbenches. A idéia principal, a meu ver, é que o sistema é apresentado e desenvolvido por intermédio de projeções. DSLs são utilizadas pra descrever projeções do sistema e elas são compostas como meta-modelos. Por exemplo, você pode ver e manipular a sua máquina de estado usando uma projeção em Java ou uma projeção em SML. A sintaxe concreta usada pra cada projeção é definida por editores e você pode ter diversos editores pra uma linguagem. Por exemplo, SML pode ter uma sintaxe textual pra máquinas de estado, ou pode ter uma linguagem visual que mostre os estados e as transições como nós e setas. O que importa é que quando se manipula os conceitos no editor, se está manipulando o sistema através dessa projeção.</p>

<p>E qual é a vantagem? A principal, eu acho, é que se elimina o frontend do compilador e com isso vários dos problemas de se combinar linguagens. Ou seja, não existem mais lexers ou parsers, tudo o que existe é a abstract syntax tree (AST). O editor de Java não é um editor de texto, é um editor estruturado que permite manipular a AST diretamente. Dessa maneira, editores de diferentes linguagens podem ser compostos. Por exemplo, no seu editor de Java você pode visualizar a máquina de estados com o editor de SML.</p>

<p>E as desvantagens? Bom, eu acho que ainda existem muitos problemas. Não está claro ainda se desenvolvedores vão ser produtivos em editores estruturados. O fonte do sistema fica dependente de uma certa ferramenta (não se tem mais texto que pode ser compilado por diferentes ferramentas, se tem a descrição do sistema usando o meta-modelo específico daquela ferramenta). Além disso, ainda não está claro que tipo de problemas vão ocorrer agora que estamos compondo linguagens em um nível mais alto de abstração.</p>

<p>E onde pode-se ver esses conceitos em ação? Eu aconselho dar uma brincada com <a href="http://www.jetbrains.com/mps/">MPS</a>. MPS é uma implementação bastante sólida de projectional language workbenches sendo desenvolvida pela <a href="http://www.jetbrains.com">Jetbrains</a> (que faz o IntelliJ IDEA). Em MPS você pode criar DSLs e combinar com Java e outras DSLs. O <a href="http://www.voelter.de/">Markus Voelter</a> criou também uma implementacão em C pra desenvolver sistemas embarcados, num projeto chamado <a href="http://mbeddr.wordpress.com/">mbeddr</a>.</p>

<p>Será que projectional language workbenches vai ser o jeito de se programar no futuro? Não sei (provavelmente não), mas vale a pena observar o que está sendo experimentado, pois com certeza é um paradigma interessante e que pode trazer bons insights. E se tudo o que eu escrevi aqui parece abstrato demais, dê uma lida nos textos do Martin Fowler pois ele entra em detalhes. E também não hesite em fazer perguntas (eu tenho um pouco de experiência com MPS e posso tentar ajudar).</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2011/01/16/projectional-language-workbenches/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Curso de HTML5 em São Paulo</title>
		<link>http://log4dev.com/2010/08/31/curso-de-html5-em-sao-paulo/</link>
		<comments>http://log4dev.com/2010/08/31/curso-de-html5-em-sao-paulo/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 12:57:02 +0000</pubDate>
		<dc:creator>Miguel Galves</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Formação]]></category>
		<category><![CDATA[Notícias]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=823</guid>
		<description><![CDATA[A W3C Brasil irá oferecer um curso de HTML 5 em São Paulo, entre os dias 21 e 23 de setembro. Segundo um email que eu recebi ontem, O programa do curso abrange as principais novidades da versão 5 da linguagem HTML até o momento e priorizará a apresentação dos novos elementos com o debate [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2010/08/31/curso-de-html5-em-sao-paulo/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>A <a href="http://www.w3c.br/">W3C Brasil</a> irá oferecer um curso de <strong>HTML 5</strong> em São Paulo, entre os dias 21 e 23 de setembro.</p>

<p><a href="http://www.w3c.br/cursos/html5/"><img class="aligncenter" title="Curso de HTML 5" src="http://www.w3c.br/cursos/html5/images/nome-evento.gif" alt="" width="486" height="185" /></a></p>

<p>Segundo um email que eu recebi ontem,
<blockquote>O programa do curso abrange as principais novidades da versão 5 da linguagem HTML até o momento e priorizará a apresentação dos novos elementos com o debate em classe da nova semântica. Alguns exercícios serão aplicados com o intuito de demonstrar as novas implementações. Nossa estrutura infelizmente não comporta a formação de diversas turmas do curso de HTML5 que nos permita atender o grande número de solicitações de interessados, inclusive para outras cidades. Por isso faremos uma seleção dos participantes segundo os critérios de compromissos:</p>

<ul>
<li>com a replicação do conteúdo do curso;</li>
<li>com a publicação livre das aplicações geradas;</li>
<li>com um projeto real de uso do HTML5;</li>
<li>e com a participação efetiva em uma comunidade dedicada à melhoria da linguagem.</li>
</ul>

<p>O propósito do W3C Brasil, mais do que treinar no uso da nova versão, é o de organizar uma rede de interlocutores, formadores e multiplicadores preparados para os debates em torno dos padrões web, gerando massa crítica na formulação das novas recomendações.</blockquote>
Para saber mais sobre o curso, acesse <a href="http://www.w3c.br/cursos/html5/">http://www.w3c.br/cursos/html5/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2010/08/31/curso-de-html5-em-sao-paulo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Olimpiada International de Informatica</title>
		<link>http://log4dev.com/2010/08/26/olimpiada-international-de-informatica/</link>
		<comments>http://log4dev.com/2010/08/26/olimpiada-international-de-informatica/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 12:00:15 +0000</pubDate>
		<dc:creator>Thiago Bartolomei</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Formação]]></category>
		<category><![CDATA[Notícias]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=791</guid>
		<description><![CDATA[A 22a Olimpíada Internacional de Informática (IOI) ocorreu semana passada aqui em Waterloo, Canadá. É uma competição de programação para alunos de (no máximo) colegial. A olimpíada acontece anualmente e nessa edição contou com equipes de 83 países, incluindo o Brasil. Apesar de cada país poder enviar uma equipe de até 4 competidores, a competição [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2010/08/26/olimpiada-international-de-informatica/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>A <a href="http://www.ioi2010.org">22a Olimpíada Internacional de Informática</a> (IOI) ocorreu semana passada aqui em Waterloo, Canadá. É uma competição de programação para alunos de (no máximo) colegial. A olimpíada acontece anualmente e nessa edição contou com equipes de 83 países, incluindo o Brasil. Apesar de cada país poder enviar uma equipe de até 4 competidores, a competição é individual. Portanto, é bem diferente da competição da <a href="http://cm.baylor.edu/welcome.icpc">ACM ICPC</a>, para equipes de universitários.</p>

<p>Eu tive o prazer de servir de guia para a delegação brasileira, novamente liderada pelo <a href="http://www.ic.unicamp.br/~ranido/">Prof. Anido</a> da UNICAMP. Como o Canadá é um país de imigrantes, a organização tentou encontrar guias que falassem fluentemente a língua de cada país. Eles dizem que conseguiram, mas eu vi alguns guias que tiveram que se virar em inglês mesmo. Mas a idéia de ter um guia que conhece ambos os países é a de dar uma perspectiva mais compatível com os alunos sobre Waterloo e principalmente sobre o Canadá. Eu espero ter conseguido mostrar os lados positivos e negativos daqui, além de levá-los às compras, é claro. Ah, e o lado divertido da semana (pros guias pelo menos) foi &#8220;ter&#8221; que ir junto ao <a href="http://www.canadaswonderland.com">Canada&#8217;s Wonderland</a> e ao  <a href="http://www.maidofthemist.com">Maid of the Mist</a> em Niagara Falls.</p>

<p>Mas voltando à competição, que imagino ser a parte divertida pros alunos, a primeira coisa que tive que aprender foi como funciona a premiação. Existem medalhas de ouro, prata e bronze, sendo que metade dos +/- 300 competidores recebem alguma medalha (1/12 ouro, 1/6 prata e 1/4 bronze). A equipe brasileira recebeu 1 prata e 2 bronzes, o que é bastante bom dado o nível elevado da competição.</p>

<p>E esse é o ponto principal desse post. Eu fiquei impressionado com o nível de conhecimento de algoritmos dos competidores. A equipe brasileira é jovem e 3 dos 4 competidores ainda tem idade pra voltar algumas vezes pro IOI. Esses meninos de 15, 16 anos manjam algoritmos e estruturas de dados que eu só fui aprender no 2o. ano de faculdade. E eles <strong>dominam</strong> o assunto! O campeão desse ano foi um bielorusso de 15 anos. Ele compete desde os 11 e já ganhou 1 prata e 4 ouros, sendo 2 vezes como campeão. Os dois pais do garoto são programadores, obviamente.</p>

<p>Se você duvida da complexidade das tarefas, tente resolver você mesmo, já que elas <a href="http://www.ioi2010.org/CompetitionTask.shtml">estão online</a>. Cada dia de competição era uma prova com 4 tarefas pra serem resolvidas em 5 horas. Normalmente uma tarefa era bem fácil, só pra não desmotivar competidores menos treinados (tente fazer o Memory ou o Cluedo primeiro). Mas pra se ter uma idéia, a primeira submissão correta do Cluedo foi em menos de 3 minutos (eu nem consigo ler o enunciado nesse tempo!). Nesse ano algumas tarefas envolviam heurísticas (como Language) e algumas que pareciam triviais eram bem complicadinhas de resolver com pontos máximos (veja hotter/colder).</p>

<p>Parabéns ao time brasileiro e à <a href="http://www.fcc.org.br/">Fundação Carlos Chagas</a> que patrocina as <a href="http://olimpiada.ic.unicamp.br/">seletivas</a>, treinamentos e viagens! E toca preparar pra Tailândia ano que vem!</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2010/08/26/olimpiada-international-de-informatica/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Filtros no Admin do Django</title>
		<link>http://log4dev.com/2010/08/25/filtros-no-admin-do-django/</link>
		<comments>http://log4dev.com/2010/08/25/filtros-no-admin-do-django/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 13:37:54 +0000</pubDate>
		<dc:creator>Miguel Galves</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=800</guid>
		<description><![CDATA[O Admin automático do Django é uma mão na roda. Já disse isso. Mas nada é perfeito! Algo que me incomodava bastante era o fato da barra de filtros que aparece do lado direito da tela de listagem ser uma lista de links. Funciona muito bem quando a lista é pequena (10, no máximo 20 [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2010/08/25/filtros-no-admin-do-django/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div><a href="http://www.djangoproject.com/"><img class="aligncenter" title="Django" src="http://media.djangoproject.com/img/site/hdr_logo.gif" alt="" width="117" height="41" /></a></p>

<p>O Admin automático do Django é uma mão na roda. Já disse isso. Mas nada é perfeito!</p>

<p>Algo que me incomodava bastante era o fato da barra de filtros que aparece do lado direito da tela de listagem ser uma lista de links. Funciona muito bem quando a lista é pequena (10, no máximo 20 elementos). Mas quando a lista é muito grande, ou então pode ter tamanho variável, a coisa fica fora de controle. Meu sonho era poder colocar uma caixa de seleção.</p>

<p>Esta semana, resolvi fuçar um pouco e entender como funciona. E não é que é fácil?</p>

<p>Resumindo: o responsável por renderizar o filtro é um arquivo chamado filter.html, que fica na pasta de templates do admin (django/contrib/admin/templates/admin). O jeito então é substituir o arquivo, e o jeito elegante de fazer esta substituição é criar uma pasta admin dentro da pasta de templates do seu projeto e criar o arquivo filter.html lá.</p>

<p>Para aqueles que tem preguiça de pesquisar como colocar uma caixa de seleção, eis o código que eu usei:
<pre>{% load i18n %}
&lt;h3&gt;{% blocktrans with title as filter<em>title %} By {{ filter</em>title }} {% endblocktrans %}&lt;/h3&gt;
&lt;ul&gt;
&lt;select onchange='window.location=this.value;'&gt;
{% for choice in choices %}
&lt;option value="{{ choice.query_string|iriencode }}" 
{% if choice.selected %}selected{% endif %}&gt;{{ choice.display }}
&lt;/option&gt;
{% endfor %}
&lt;/select&gt;
&lt;/ul&gt;
</pre>
O resultado final é esse:</p>

<div id="attachment_801" class="wp-caption aligncenter" style="width: 169px"><a href="http://log4dev.com/wp-content/uploads/2010/08/filtro.png"><img class="size-full wp-image-801" title="Filtro de listagem com Caixa de Seleção" src="http://log4dev.com/wp-content/uploads/2010/08/filtro.png" alt="" width="159" height="226" /></a><p class="wp-caption-text">Filtro de listagem com Caixa de Seleção</p></div>

<p>Pra quem quiser aprender um pouco mais sobre customizações do admin do django, a fonte boa é esta: <a href="http://docs.djangoproject.com/en/1.2/obsolete/admin-css/">http://docs.djangoproject.com/en/1.2/obsolete/admin-css/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2010/08/25/filtros-no-admin-do-django/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>OAuth</title>
		<link>http://log4dev.com/2010/06/23/oauth/</link>
		<comments>http://log4dev.com/2010/06/23/oauth/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 11:59:03 +0000</pubDate>
		<dc:creator>Miguel Galves</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[Segurança]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=756</guid>
		<description><![CDATA[No dia 31 de Maio do ano do Senhor de 2010, por volta das 15h, o meu caro amigo Lullis me mandou uma singela mensagem no GTalk dizendo algo como &#8220;Você viu que o sistema de Basic Auth do Twitter para de funcionar hoje né? E que daqui pra frente só com OAuth né?&#8221;. A [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2010/06/23/oauth/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>No dia 31 de Maio do ano do Senhor de 2010, por volta das 15h, o meu caro amigo Lullis me mandou uma singela mensagem no GTalk dizendo algo como &#8220;Você viu que o sistema de Basic Auth do <a href="http://twitter.com">Twitter</a> para de funcionar hoje né? E que daqui pra frente só com OAuth né?&#8221;. A frase, descontextualizada, pode parecer apenas mais uma curiosidade geek. O Twitter já vinha anunciando esta migração de modelo de autenticação há um certo tempo.</p>

<p>Mas no mundo de Miguel, isso caiu como uma bomba atômica.</p>

<p><a href="http://delamagente.files.wordpress.com/2009/08/network_security.jpg"><img class="aligncenter" src="http://delamagente.files.wordpress.com/2009/08/network_security.jpg" alt="" width="306" height="228" /></a></p>

<p>Resumindo: o mecanismo de autenticação usado pelo <a href="http://job4dev.com">Job4Dev</a> e pelo <a href="http://www.sigaseutime.com.br">SigaSeuTime</a> simplesmente deixaria de funcionar em algumas horas. No caso do SigaSeuTime, isto era uma catástrofe de proporções enormes, já que boa parte do nosso público vem do Twtter. Uma longa noite me aguardava&#8230;até que percebemos que Lullis havia falado besteira, e que na verdade o prazo máximo era 31 de junho. Ufa.</p>

<p>Tive então tempo de estudar um pouco o protocolo, e fazer uma implementação usando algumas libs. Por sorte a documentação do próprio <a href="http://apiwiki.twitter.com/">Wiki do Twitter</a> é bem interessante. Gostaria de compartilhar alguns pontos aqui.
<h2>Basic Auth</h2>
É o maior lixo já inventado para autenticação. Basicamente, você adiciona no header da sua requisição um campo cujo valor é o seu username e a sua senha simplesmente codificados em <a href="http://en.wikipedia.org/wiki/Base64">Base 64</a>. Resumindo, senha em claro. Mais básico e inseguro que isso, impossível.
<h2>OAuth &#8211; Idéia básica</h2>
A idéia do <a href="http://oauth.net/">OAuth</a> é permitir que o provedor de um serviço permita o acesso a certos recursos a usuários sem precisar dar a senha principal. No caso do Twitter, isto é bem útil, já que a grande maioria dos usuários interagem com o sistema usando aplicativos externos.</p>

<p>Com este protocolo, seria possível permitir que por exemplo o Job4Dev atualizasse a sua timeline, de forma segura e autenticada, sem que eu precisasse guardar a sua senha na minha base de dados. Conveniente!
<h2>OAuth &#8211; O protocolo</h2>
<a href="http://oauth.net"><img class="alignnone" src="http://oauth.net/images/oauth-logo.png" alt="Logo OAuth" width="200" height="60" /></a></p>

<p>Vou tentar tornar esta descrição a mais simples possível.</p>

<p>OAuth usa um mecanismo de pares de chaves públicas e privadas para gerar assinaturas, permitindo uma identificação inequivoca da origem de cada requisição. Simples demais?</p>

<p>Ok</p>

<p>Vamos supor que o usuário @mgalves queria que o Job4Dev publique vagas na sua timeline, usando um app que algum dia será criado. Este app possui duas chaves, geradas pelo @job4dev: um consumer key e um consumer secret (que como seu nome diz, deve ser guardada de forma secreta). O passo a passo seria mais ou menos o seguinte:
<ul>
    <li>O app gera uma requisição especial HTTP, usando as duas chaves citadas acima, para obter um token de request temporário.</li>
    <li>Com este token em mãos, o app gera uma requisição HTTP de autorização de acesso para o Twitter. Esta requisição passa como parâmetros o token, o consumer key e uma assinatura gerada a partir de um hash (SHA) de uma string composta pelo token, pelo consumer key e pelo consumer secret key. Portanto, é única, e apenas o app do Job4Dev é capaz de gerar (comprovando assim a procedência da chamada).</li>
    <li>O Twitter já sabe, a partir da assinatura, que quem está pedindo permissão de acesso é o Job4Dev. Falta saber qual usuário irá autorizar o acesso: para isso o site pede que eu, @mgalves, efetue o login e explicitamente autorize o acesso.</li>
    <li>Autorizado o acesso, o Twitter envia para o app um novo par de chaves que serão utilizados para assinar as demais requisições, e que mapeiam de forma única a permissão de acesso do app job4dev aos recursos da conta de @mgalves. Caso eu resolva REVOGAR o acesso, basta invalidar estas novas chaves.</li>
</ul>
Melhorou? Espero que sim.</p>

<p>Um ponto importante deve ser ressaltado quanto ao último passo. O retorno do novo par de chaves pode ser feito de duas formas: callback e PIN code. Callback é a forma padrão descrita no protocolo do OAuth, e simplemente consiste em definir um callback HTTP no app que está pedindo acesso, que será chamado pelo provedor (no caso o Twitter) ao final do processo passando as chaves por parâmero POST.</p>

<p>Mas isso apenas funciona se o app em questão for web, e puder responder a uma requisição HTTP. Caso isto não aconteça (como no Tweetdeck por exemplo), o Twitter exibe na tela um código numérico único chamado PIN CODE: o app deve receber este PIN code (copy &amp; paste) e gerar uma nova requisição passando o token, o pin code e a assinatura, cujo retorno é o par de chaves.
<h2>E o TweetDeck?</h2>
Depois de ter lido e entendido o tema, a seguinte dúvida me veio a cabeça: e o TweetDeck, como faz? E nenhum momento eu autorizei o acesso aos meus recursos, e ainda assim, as coisas funcionam. Será que no final de junho ele para de funcionar?</p>

<p>Fucei a documentação do Twitter e achei uma extensão ao protocolo chamada de XAuth, uma pequena variação que permite que as chaves de acesso sejam obtidas através de uma requisição especial contendo username e senha do usuário. Isso evita a necessidade do protocolo definido acima, e funciona bem em casos onde quem vai acessar os recursos é o dono da conta.</p>

<p>Mas segundo o Twitter, para que um app que queira usar este protocolo deve entrar em contato diretamente com eles, explicando a real necessidade.</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2010/06/23/oauth/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>langs, bashes e encodings da vida</title>
		<link>http://log4dev.com/2010/02/24/langs-bashes-e-encodings-da-vida/</link>
		<comments>http://log4dev.com/2010/02/24/langs-bashes-e-encodings-da-vida/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 13:04:08 +0000</pubDate>
		<dc:creator>Miguel Galves</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://log4dev.com/?p=732</guid>
		<description><![CDATA[Acho que posso dizer sem medo de errar que na lista de dores de cabeças que meus projetos pessoais e startups me trouxeram, a questão da codificação de strings está tranquilamente entre os TOP 3. E quando eu achei que tudo nesta área estava resolvido, eis que me apareceu um novo bug do nada que [...]]]></description>
			<content:encoded><![CDATA[<p><div class='wpfblike' style='height: 40px;'><fb:like href='http://log4dev.com/2010/02/24/langs-bashes-e-encodings-da-vida/' layout='button_count' show_faces='true' width='400' action='like' colorscheme='light' send='true' /></div>Acho que posso dizer sem medo de errar que na lista de dores de cabeças que meus projetos pessoais e startups me trouxeram, a questão da <strong>codificação de strings</strong> está tranquilamente entre os TOP 3. E quando eu achei que tudo nesta área estava resolvido, eis que me apareceu um novo bug do nada que me fez perder algumas horas de mal humor. Porque coisas que funcionam por meses e de repente param de funcionar sem motivo aparente em geral me tiram do sério.</p>

<p>O <a href="http://www.sigaseutime.com.br">SigaSeuTime</a> (cujo novo site acaba de estrear, se me permitem o autojabá) possui dois bots IM, <strong>GTalk</strong> e <strong>MSN</strong>, que fazem parte do conjunto de plataformas para distribuição de contéudo. Ambos os bots são escritos em <strong>Java</strong>, e a plataforma é escrita em Python. Para fazer a comunicação entre os subsistemas eu uso ou <strong>REST</strong> ou comunicação via <strong>UDP</strong>. No caso das notícias em tempo real, acabei optando por UDP para evitar pooling desnecessário. E isso funcionou perfeitamente nos últimos 6 meses: um agente se encarrega de puxar as notícias, processar, filtrar e gravar na base de dados. Outro agente lê as notícias novas e manda pros bots via UDP, para envio aos usuários online. .</p>

<p>Até que de repente, as mensagens começaram a aparecer tanto no MSN quanto no GTalk  com a <strong>acentuação</strong> totalmente errada. Típico resultado de strings codificadas de um jeito e interpretadas de outro (<a href="http://log4dev.com/2009/05/18/identificacao-de-charsets/">tinha que existir um jeito fácil e direto de se descobrir a codificação de uma string sem a necessidade de metadados</a>)! Olhando para o histórico do meu SVN vi que as últimas modificações em códigos relativos aos componentes envolvidos neste processo datavam de no mínimo 3 meses.</p>

<p>Ou seja, só podia ser culpa do meu servidor, ou do alinhamento planetário, ou então do Bush! Não não&#8230;a culpa, obviamente era minha. Sempre é, por mais que a gente lute contra isso.</p>

<p>A causa do problema estava em um script <strong>SHELL</strong> que eu criei recentemente cujo objetivo é de reiniciar os bots em caso de falha de comunicação com os servidores. Até então, o processo de reboot era manual, feito por mim mesmo via shell SSH, e a função deste script é de automatizar o processo, matando e executando novamente o bot.</p>

<p>Inofensivo certo? Nem tanto. O script é executado periódicamente pelo crontab do sistema operacional, e foi aí que o problema nasceu: as variáveis de ambiente do cronjob são diferentes das variáveis de ambiente do SHELL SSH, e em particular o segundo possui a variável <strong>LANG=en_us.UTF-8</strong>, que é justamente a codificação usada internamente pelo sistema. Vivendo e aprendendo: isto influi diretamente na JRE, e a falta da variável fez com que o sistema assumisse outra codificação (provavelmente <strong>ISO Latin 1</strong>). A solução foi exportar a variável no meu script.</p>
]]></content:encoded>
			<wfw:commentRss>http://log4dev.com/2010/02/24/langs-bashes-e-encodings-da-vida/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

