<?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>Profissionais TI - Pra quem respira informação &#187; Python</title>
	<atom:link href="http://www.profissionaisti.com.br/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.profissionaisti.com.br</link>
	<description>Pra quem respira informação</description>
	<lastBuildDate>Fri, 10 Feb 2012 16:02:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Assegure a qualidade do seu código Python &#8211; pep8</title>
		<link>http://www.profissionaisti.com.br/2011/08/assegure-a-qualidade-do-seu-codigo-python-pep8/</link>
		<comments>http://www.profissionaisti.com.br/2011/08/assegure-a-qualidade-do-seu-codigo-python-pep8/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 16:04:11 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Qualidade]]></category>
		<category><![CDATA[pep8]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=19170</guid>
		<description><![CDATA[Convenções de código! Já tive a oportunidade de escrever sobre elas no Profissionais TI. Benção ou maldição? Há quem goste, há quem ache uma perda de tempo&#8230; Acredito muito que a organização e a qualidade do código são benéficas para qualquer projeto, principalmente para aqueles que possuem alta rotatividade de profissionais. Padrões de projetos, padrões estruturais [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Convenções de código! Já tive a oportunidade de <a title="Codifique como um verdadeiro Pythonista" href="http://www.profissionaisti.com.br/2009/06/codifique-como-um-verdadeiro-pythonista/">escrever sobre elas no <em>Profissionais TI</em></a>. Benção ou maldição? Há quem goste, há quem ache uma perda de tempo&#8230;</p>
<p style="text-align: justify;">Acredito muito que a organização e a qualidade do código são benéficas para qualquer projeto, principalmente para aqueles que possuem alta rotatividade de profissionais. Padrões de projetos, padrões estruturais e de escrita facilitam a &#8220;assimilação&#8221; do que já foi produzido, facilita a manutenção e &#8220;orienta&#8221; as novas produções.</p>
<p style="text-align: justify;">Se você tem problemas em decorar convenções e boas práticas, não desanime! O <em><a title="Leia mais sobre Python" href="http://www.profissionaisti.com.br/tag/python/">Python</a> </em>possui algumas ferramentas &#8220;bacanudas&#8221; que vão te auxiliar a deixar o <em>software </em>mais próximo do &#8220;estado da arte&#8221;, seja garantindo as convenções de código, seja avaliando a qualidade do mesmo.</p>
<h3 style="text-align: justify;">Python Enhancement Proposals</h3>
<p style="text-align: justify;">As &#8220;<em>PEPs</em>&#8220; (<em>Python Enhancement Proposal</em>) são documentos que geralmente abordam alguma nova funcionalidade da linguagem, propósitos, procedimentos ou ambiente. Em suma, são &#8220;<em>guidelines</em>&#8221; que te orientam num melhor uso da linguagem e suas funcionalidades, bem como podem ajudar em questões como arquitetura, ambiente ou processos de sua aplicação.</p>
<p style="text-align: justify;">Para saber mais sobre <em>PEP</em>s<em>, </em><a title="PEP1 - PEP Purpose and Guidelines" href="http://www.python.org/dev/peps/pep-0001/">acesse a </a><em><a title="PEP1 - PEP Purpose and Guidelines" href="http://www.python.org/dev/peps/pep-0001/">PEP 1</a> </em>que é justamente um documento explicando o que são e o que fazem as <em>Python Enhancement Proposals</em>.</p>
<h3 style="text-align: justify;">pep8</h3>
<p style="text-align: justify;">O <strong><em>pep8 </em></strong>é uma ferramenta simples (e muito eficaz) que analisa o seu código <em>Python </em>segundo as convenções de código descritas na <em><a title="PEP 8 - Style Guide for Python Code" href="http://www.python.org/dev/peps/pep-0008/">PEP 8</a></em>.</p>
<p style="text-align: justify;">Vamos analisar o código do <em><a title="Repositório no GitHub do site do Django no Brasil" href="https://github.com/djangobrasil/djangobrasil.org">Django Brasil</a> </em>(você não sabia? O <em>site </em>é <em>open source</em>!), mais especificamente o arquivo <em><strong>models.py </strong></em>da <em>app blog</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ pep8 src<span style="color: #000000; font-weight: bold;">/</span>djangobrasil<span style="color: #000000; font-weight: bold;">/</span>apps<span style="color: #000000; font-weight: bold;">/</span>blog<span style="color: #000000; font-weight: bold;">/</span>models.py
&nbsp;
src<span style="color: #000000; font-weight: bold;">/</span>djangobrasil<span style="color: #000000; font-weight: bold;">/</span>apps<span style="color: #000000; font-weight: bold;">/</span>blog<span style="color: #000000; font-weight: bold;">/</span>models.py:<span style="color: #000000;">42</span>:<span style="color: #000000;">65</span>: W291 trailing whitespace
src<span style="color: #000000; font-weight: bold;">/</span>djangobrasil<span style="color: #000000; font-weight: bold;">/</span>apps<span style="color: #000000; font-weight: bold;">/</span>blog<span style="color: #000000; font-weight: bold;">/</span>models.py:<span style="color: #000000;">62</span>:<span style="color: #000000;">1</span>: E302 expected <span style="color: #000000;">2</span> blank lines, found <span style="color: #000000;">1</span>
src<span style="color: #000000; font-weight: bold;">/</span>djangobrasil<span style="color: #000000; font-weight: bold;">/</span>apps<span style="color: #000000; font-weight: bold;">/</span>blog<span style="color: #000000; font-weight: bold;">/</span>models.py:<span style="color: #000000;">105</span>:<span style="color: #000000;">80</span>: E501 line too long <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">89</span> characters<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p style="text-align: justify;">Como podemos ver, a ferramenta nos mostra a linha e coluna onde o problema foi encontrado, apresentando uma breve descrição da incoerência que estamos cometendo em relação às recomendações da <em>PEP 8</em>.</p>
<p style="text-align: justify;">Para obter uma resposta mais &#8220;<em>verbose</em>&#8220;, podemos passar alguns parâmetros para o <em><strong>pep8</strong></em>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ pep8 src<span style="color: #000000; font-weight: bold;">/</span>djangobrasil<span style="color: #000000; font-weight: bold;">/</span>apps<span style="color: #000000; font-weight: bold;">/</span>blog<span style="color: #000000; font-weight: bold;">/</span>models.py <span style="color: #660033;">--show-source</span> <span style="color: #660033;">--show-pep8</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#40;</span>...<span style="color: #7a0874; font-weight: bold;">&#41;</span>
src<span style="color: #000000; font-weight: bold;">/</span>djangobrasil<span style="color: #000000; font-weight: bold;">/</span>apps<span style="color: #000000; font-weight: bold;">/</span>blog<span style="color: #000000; font-weight: bold;">/</span>models.py:<span style="color: #000000;">105</span>:<span style="color: #000000;">80</span>: E501 line too long <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">89</span> characters<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  <span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #ff0000;">'/weblog/%s/%s/'</span> <span style="color: #000000; font-weight: bold;">%</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>self.pub_date.strftime<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">'%Y/%m/%d'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>.lower<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>, self.slug<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                                                                               ^
  Limit all lines to a maximum of <span style="color: #000000;">79</span> characters.
&nbsp;
  There are still many devices around that are limited to <span style="color: #000000;">80</span> character
  lines; plus, limiting windows to <span style="color: #000000;">80</span> characters makes it possible to have
  several windows side-by-side.  The default wrapping on such devices looks
  ugly.  Therefore, please limit all lines to a maximum of <span style="color: #000000;">79</span> characters.
  For flowing long blocks of text <span style="color: #7a0874; font-weight: bold;">&#40;</span>docstrings or comments<span style="color: #7a0874; font-weight: bold;">&#41;</span>, limiting the
  length to <span style="color: #000000;">72</span> characters is recommended.</pre></div></div>

<p style="text-align: justify;">Viu só?! Dessa forma podemos aprender sobre a <em>PEP 8 </em>enquanto &#8220;ferimos&#8221; as convenções de código em nossos projetos <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p style="text-align: justify;">Para finalizar, podemos contar as ocorrências de problemas com a <em>PEP 8</em> em determinada região do projeto:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ pep8 src<span style="color: #000000; font-weight: bold;">/</span>djangobrasil<span style="color: #000000; font-weight: bold;">/</span>apps<span style="color: #000000; font-weight: bold;">/</span>blog<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #660033;">--statistics</span> <span style="color: #660033;">-qq</span> <span style="color: #660033;">--filename</span>=<span style="color: #000000; font-weight: bold;">*</span>.py
&nbsp;
<span style="color: #000000;">1</span>       E225 missing whitespace around operator
<span style="color: #000000;">7</span>       E302 expected <span style="color: #000000;">2</span> blank lines, found <span style="color: #000000;">1</span>
<span style="color: #000000;">1</span>       E303 too many blank lines <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000;">11</span>      E501 line too long <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">89</span> characters<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000;">4</span>       W291 trailing whitespace
<span style="color: #000000;">2</span>       W391 blank line at end of <span style="color: #c20cb9; font-weight: bold;">file</span></pre></div></div>

<p style="text-align: justify;">Nenhum problema muito grave de convenções de código na <em>app blog </em>do <em>DjangoBrasil </em> <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align: justify;"><strong>Confira: </strong><em><a title="Repositório no GitHub do pep8" href="https://github.com/jcrocholl/pep8/" target="_blank">pep8 &#8211; Python style guide checker</a>.</em></p>
<h3 style="text-align: justify;">Referências</h3>
<ul style="text-align: justify;">
<li><a title="Conheça os tipos de PEPs e quais os seus propósitos" href="http://www.python.org/dev/peps/" target="_blank"><em>Python.org - Index of Python Enhancement Proposals (PEPs)</em></a></li>
<li><a title="Saiba o que é, o que faz, e como é feita uma PEP" href="http://www.python.org/dev/peps/pep-0001/" target="_blank"><em>Python.org - PEP 1: Purpose and Guidelines</em></a></li>
<li><a title="Conheça as convenções de código Python" href="http://www.python.org/dev/peps/pep-0008/" target="_blank"><em>Python.org &#8211; PEP 8: Style Guide for Python Code</em></a></li>
<li><a title="Artigo do Viva o Linux que é uma adaptação para o Português da PEP 8" href="http://www.vivaolinux.com.br/artigo/PEP-8-Guia-de-estilo-para-codigo-Python" target="_blank"><em>Viva o Linux &#8211; PEP 8</em>: Guia de estilo para código <em>Python</em></a></li>
<li><a title="Repositório no GitHub do projeto pep8" href="https://github.com/jcrocholl/pep8/" target="_blank"><em>GitHub &#8211; pep8</em></a></li>
</ul>
<p style="text-align: justify;">Nos próximos <em>posts</em>, vamos dar uma pincelada no <em>pylint</em>, <em>pyflakes </em>e <em>clone digger</em>.</p>
<p style="text-align: justify;"><strong>Fonte: </strong><a title="Assegure a qualidade do seu código Python – pep8" href="http://www.klauslaube.com.br/2011/08/assegure-qualidade-seu-codigo-python-pep/" target="_blank">Klaus Laube</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2011/08/assegure-a-qualidade-do-seu-codigo-python-pep8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Decorators em Python</title>
		<link>http://www.profissionaisti.com.br/2011/08/decorators-em-python/</link>
		<comments>http://www.profissionaisti.com.br/2011/08/decorators-em-python/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 21:58:30 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[decorator]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=18778</guid>
		<description><![CDATA[E na mesma linha dos closures, eu passei a saber realmente o que são decorators depois de utilizar a framework Django. Se você está trabalhando com Orientação a Objetos e até agora não se deparou com este recurso, te garanto que um dia você precisará dele&#8230; afinal, é um dos Design Patterns mais bacanas (e [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">E na mesma linha dos <em><a title="Afinal, o que são Closures?" href="http://www.profissionaisti.com.br/2011/06/afinal-o-que-sao-closures/">closures</a></em>, eu passei a saber realmente o que são <em>decorators </em>depois de utilizar a <em>framework <a title="Leia mais sobre Django" href="http://www.profissionaisti.com.br/tag/django/">Django</a></em>. Se você está trabalhando com Orientação a Objetos e até agora não se deparou com este recurso, te garanto que um dia você precisará dele&#8230; afinal, é um dos <em><a title="Conheça os Design Patterns" href="http://pt.wikipedia.org/wiki/Padr%C3%A3o_de_projeto_de_software">Design Patterns</a> </em>mais bacanas (e úteis) que já vi.</p>
<p style="text-align: justify;">Vamos lá &#8220;decorar&#8221; nossos métodos <em><a title="Leia mais sobre Python" href="http://www.profissionaisti.com.br/tag/python/">Python</a></em>!</p>
<h3 style="text-align: justify;">Decoradores? <em>Really?</em></h3>
<p style="text-align: justify;">Eu não saberia explicar de uma forma melhor do que foi explicado pela <em><a title="Leia mais sobre o pattern Decorator" href="http://pt.wikipedia.org/wiki/Decorator">Wikipedia</a>, </em>o que é o padrão <em>decorator</em>:</p>
<ul style="text-align: justify;">
<li><strong>Intenção:</strong> Acrescentar responsabilidades a um objeto dinamicamente. Prover alternativa flexível ao uso de subclasses para se estender a funcionalidade de uma classe;</li>
<li><strong>Motivação:</strong> Objeto usado possui as funcionalidades básicas, mas é necessário adicionar funcionalidades adicionais a ele que podem ocorrer antes ou depois da funcionalidade básica. Funcionalidades devem ser adicionadas em instancias individuais e não na classe;</li>
<li><strong>Consequências:</strong> Mais flexibilidade do que herança.</li>
</ul>
<p style="text-align: justify;">Encontramos na <a title="Wiki oficial da linguagem Python" href="http://wiki.python.org/moin/FrontPage"><em>Wiki</em> do </a><em><a title="Wiki oficial da linguagem Python" href="http://wiki.python.org/moin/FrontPage">Python</a> </em>uma explicação mais objetiva e esclarecedora:</p>
<blockquote>
<p lang="text">Decorators alteram dinamicamente a funcionalidade de uma função, método ou classe, sem uso direto de subclasses ou alterando o código-fonte da função &#8220;decorada&#8221;.</p>
</blockquote>
<h3 style="text-align: justify;">O uso de <em>decorators </em>em <em>Python</em></h3>
<p style="text-align: justify;">O <em>Python </em>começou a dar suporte a <em>decorators </em>a partir da <strong>versão 2.4</strong>.</p>
<p style="text-align: justify;">Você terá a sua disposição alguns decoradores <em>built-in</em> e também poderá criar os seus próprios sem muito dificuldade. É possível identificar um <em>decorator </em>através do caractere <strong>@</strong>, por exemplo, a instrução abaixo declara o método <strong>say_hello </strong>da classe <strong>People </strong>como estático:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> People:
    @<span style="color: #008000;">staticmethod</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> say_hello<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Hello!'</span></pre></div></div>

<p style="text-align: justify;">Vale notar que podemos reproduzir o comportamento acima sem utilizar a sintaxe especial de <em>decorators </em>(mas não deixamos de utilizar o conceito):</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> People:
    <span style="color: #ff7700;font-weight:bold;">def</span> say_hello<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Hello!'</span>
    say_hello = <span style="color: #008000;">staticmethod</span><span style="color: black;">&#40;</span>say_hello<span style="color: black;">&#41;</span></pre></div></div>

<p style="text-align: justify;">Quer conhecer mais sobre <em>decorators </em>em <em>Python</em>? Leia a <em><a title="Leia mais sobre a PEP318" href="http://www.python.org/dev/peps/pep-0318/" target="_blank">PEP 318 &#8211; Decorators for functions and methods</a></em>.</p>
<h3 style="text-align: justify;">Um pouco de prática</h3>
<p style="text-align: justify;">Vamos por a mão na massa e criar o nosso próprio <em>decorator</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># meu_decorator.py</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> meu_decorador<span style="color: black;">&#40;</span>alvo<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> wrapper<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Chamando a funcao &quot;%s&quot;'</span> <span style="color: #66cc66;">%</span> alvo.__name__
        <span style="color: #ff7700;font-weight:bold;">return</span> alvo<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> wrapper
&nbsp;
@meu_decorador
<span style="color: #ff7700;font-weight:bold;">def</span> meu_alvo<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Eu sou um alvo!'</span>
&nbsp;
meu_alvo<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p style="text-align: justify;">Chamando o script acima, teremos o seguinte resultado:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ python meu_decorator.py
&nbsp;
Chamando a funcao <span style="color: #ff0000;">&quot;meu_alvo&quot;</span>
Eu sou um alvo<span style="color: #000000; font-weight: bold;">!</span></pre></div></div>

<p style="text-align: justify;">Vou tentar seguir um fluxo que deixe claro o que o procedimento está realizando.</p>
<p style="text-align: justify;">O comportamento da função <em><strong>meu_alvo </strong></em>é muito simples: imprimir <strong><em>&#8220;Eu sou um alvo!&#8221; </em></strong>na tela. Mas o <strong><em>@meu_decorador </em></strong>está lá para complicar a nossa vida <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p style="text-align: justify;">Com a chamada de <em><strong>@meu_decorador </strong></em>logo acima de <em><strong>meu_alvo</strong></em>, fica claro que na verdade estamos passando <strong><em>meu_alvo </em></strong>como um parâmetro (<strong><em>alvo</em></strong>) para o método <strong><em>meu_decorador</em></strong>, encontrado logo no início do arquivo. Note que o método retorna <strong><em>wrapper </em></strong>sem os parênteses no final (que caracterizam uma chamada de função), ele está retornando apenas a referência ao método <strong><em>wrapper</em></strong>, que será de fato &#8220;executado&#8221; externamente.</p>
<p style="text-align: justify;">Dentro da função <strong><em>wrapper </em></strong>temos a impressão da string <em><strong>&#8216;Chamando a funcao &#8220;meu_alvo&#8221;&#8216; </strong></em>e a execução de <em><strong>meu_alvo</strong></em>. Isto deve-se ao fato de que <strong><em>alvo </em></strong>nada mais é que uma referência a função <strong><em>meu_alvo</em></strong>, que passamos como argumento para <strong><em>meu_decorador </em></strong>através do <strong><em>@meu_decorador </em></strong>logo acima da função <strong><em>meu_alvo</em></strong>, certo?</p>
<p style="text-align: justify;">Então resumindo isso tudo, o resultado final é que <strong><em>meu_alvo() </em></strong>no final do arquivo na verdade é a execução da referência a <strong><em>wrapper</em></strong>, ou seja, é o mesmo que ler &#8220;<strong><em>wrapper()</em></strong>&#8220;. Ele fará o <em><strong>print </strong></em>e posteriormente retornará o resultado de <em><strong>meu_alvo</strong></em>, que nada mais é que a impressão de <em><strong>&#8220;Eu sou um alvo!&#8221;</strong></em>.</p>
<p style="text-align: justify;">Bacana não? Aqui vai mais um para deixar as coisas um pouco mais claras&#8230; vamos simular o esquema de roteamento de uma <em>framework Web</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">rotas = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> rota<span style="color: black;">&#40;</span>endereco<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> wrapper<span style="color: black;">&#40;</span>fn<span style="color: black;">&#41;</span>:
        rotas.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>endereco, fn<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> wrapper
&nbsp;
@rota<span style="color: black;">&#40;</span><span style="color: #483d8b;">'/index/'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> home_view<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'Pagina inicial'</span>
&nbsp;
@rota<span style="color: black;">&#40;</span><span style="color: #483d8b;">'/contato/'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> contato_view<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'Pagina de contato'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> rotas<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;"># Pagina inicial</span>
<span style="color: #ff7700;font-weight:bold;">print</span> rotas<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>  <span style="color: #808080; font-style: italic;"># Pagina de contato</span>
<span style="color: #ff7700;font-weight:bold;">print</span> rotas          <span style="color: #808080; font-style: italic;"># [('/index/', &lt; function home_view at 0xb736580c &gt;),</span>
                     <span style="color: #808080; font-style: italic;">#  ('/contato/', &lt; function contato_view at 0xb7365b8c &gt;)]</span></pre></div></div>

<h3 style="text-align: justify;">Referências</h3>
<ul style="text-align: justify;">
<li><a title="Walter Cruz em um excelente post sobre Decorators em Python" href="http://devlog.waltercruz.com/python_decorators" target="_blank">Devlog &#8211; @decorators</a></li>
<li><a title="Uma introdução rápida aos decorators em Python. Muito bom!" href="http://www.fiveminutes.eu/a-quick-introduction-to-python-decorators/" target="_blank">Five Minutes &#8211; A quick introduction to Python decorators</a></li>
<li><a title="Padrões de Projetos em Python." href="http://www.python.org/workshops/1997-10/proceedings/savikko.html" target="_blank">Python.org &#8211; Design Patterns in Python</a></li>
<li><a title="Decorators em Python, direto da Wiki oficial do Python" href="http://wiki.python.org/moin/PythonDecorators" target="_blank">Python.org &#8211; Python Decorators</a></li>
<li><a title="Decorators em Python não precisam ser assustadores. Um ótimo artigo." href="http://www.siafoo.net/article/68" target="_blank">Siafoo &#8211; Python Decorators Don&#8217;t Have to be (that) Scary</a></li>
<li><a title="Leia mais na Wikipedia sobre Decorators" href="http://pt.wikipedia.org/wiki/Decorator">Wikipedia &#8211; Decorator</a></li>
</ul>
<p style="text-align: justify;">Até a próxima&#8230;</p>
<p style="text-align: justify;"><strong>Fonte: </strong><a title="Decorators em Python" href="http://www.klauslaube.com.br/2011/08/decorators-em-python/" target="_blank">Klaus Laube</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2011/08/decorators-em-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ferramentas de testes em Django &#8211; Parte 2</title>
		<link>http://www.profissionaisti.com.br/2011/08/ferramentas-de-testes-em-django-parte-2/</link>
		<comments>http://www.profissionaisti.com.br/2011/08/ferramentas-de-testes-em-django-parte-2/#comments</comments>
		<pubDate>Fri, 12 Aug 2011 11:14:14 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Utilidades]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testes]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=18777</guid>
		<description><![CDATA[No post anterior, conhecemos as ferramentas default para construção de testes automatizados em Django. Acontece que você pode &#8220;sair um pouco da caixa&#8221; e usufruir de ferramentas &#8220;third-party&#8220;, que enriquecerão o seu ambiente de desenvolvimento e lhe trarão maior segurança em seus testes de software. splinter &#8211; Testando a sua aplicação com um navegador É [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><img class="alignleft size-full wp-image-18780" style="margin-left: 5px; margin-right: 5px;" title="boneco-testes" src="http://www.profissionaisti.com.br/wp-content/uploads/2011/08/boneco-testes.jpg" alt="" width="154" height="108" />No <a title="Ferramentas de testes em Django - Parte 1" href="http://www.klauslaube.com.br/2011/07/ferramentas-de-testes-em-django-parte-1/"><em>post </em>anterior</a>, conhecemos as ferramentas <em>default </em>para construção de testes automatizados em <em><a title="Leia mais sobre Django" href="http://www.profissionaisti.com.br/tag/django/">Django</a></em>. Acontece que você pode &#8220;sair um pouco da caixa&#8221; e usufruir de ferramentas &#8220;<em>third-party</em>&#8220;, que enriquecerão o seu ambiente de desenvolvimento e lhe trarão maior segurança em seus <a title="Leia mais sobre testes" href="http://www.profissionaisti.com.br/tag/testes/">testes de <em>software</em></a>.</p>
<h3 style="text-align: justify;"><em>splinter</em> &#8211; Testando a sua aplicação com um navegador</h3>
<p style="text-align: justify;">É perfeitamente possível criar testes de aceitação em<em> Django </em>com a <em><a title="Testando aplicações web com test client em Django" href="https://docs.djangoproject.com/en/dev/topics/testing/#module-django.test.client">TestClient</a> </em>e <em><a title="Faça parser XML e HTML com lxml" href="http://lxml.de/">lxml</a></em>. Mas vamos ser sinceros, é deveras trabalhoso &#8220;parsear&#8221; os resultados das suas <em>views</em>.</p>
<p style="text-align: justify;">Com a <em><a title="Visite a documentação oficial da Splinter" href="http://splinter.cobrateam.info/">Splinter</a></em>, uma ferramenta para testes de aplicações <em>web</em>, você pode automatizar ações executadas por navegadores, como visitar uma página, preencher um formulário ou clicar em um <em>link</em>; tudo isso sem preocupar-se com <em>parsing</em>, nós, <em>DOM</em>, nem nada do tipo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> splinter.<span style="color: black;">browser</span> <span style="color: #ff7700;font-weight:bold;">import</span> Browser
browser = Browser<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># Visitar uma URL</span>
url = <span style="color: #483d8b;">&quot;http://search.twitter.com&quot;</span>
browser.<span style="color: black;">visit</span><span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>
browser.<span style="color: black;">fill</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'q'</span>, <span style="color: #483d8b;">&quot;#cobrateam&quot;</span><span style="color: black;">&#41;</span> 
&nbsp;
<span style="color: #808080; font-style: italic;"># Procurar e clicar no botão 'search'</span>
button = browser.<span style="color: black;">find_by_css</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;#searchButton input&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">first</span> 
&nbsp;
<span style="color: #808080; font-style: italic;"># Interagir com os elementos</span>
button.<span style="color: black;">click</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">if</span> browser.<span style="color: black;">is_text_present</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;No results for #cobrateam&quot;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;nobody likes us =(&quot;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;we're popular =)&quot;</span></pre></div></div>

<p style="text-align: justify;">O que eu acho mais bacana nesta ferramenta são os seletores, facilitam muito na hora de checar resultados e comportamentos.</p>
<p style="text-align: justify;">A comunidade em volta desta ferramenta está em constante crescimento e atividade. Portanto, caso você queira contribuir com o projeto, vá agora mesmo para o <a title="Repositório da Splinter no GitHub" href="https://github.com/cobrateam/splinter">repositório no <em>GitHub </em>e colabore</a>.</p>
<h3 style="text-align: justify;"><em>nose</em> &#8211; Caçando testes em seu projeto (<em>Python</em>)</h3>
<p style="text-align: justify;">E quando queremos fugir da regra? Aposto que chegará um momento em que a estrutura de diretórios padrão, necessária para a execução dos seus testes em <em>Django</em>, não te satisfará mais. O que fazer neste caso? Simples, recorra ao <em>Nose</em>!</p>
<p style="text-align: justify;">O <em><a title="Nose - is nicer testing for Python" href="http://somethingaboutorange.com/mrl/projects/nose/1.0.0/">Nose</a> </em>estende os recursos da <em>unittest </em>e facilita a escrita e carregamento dos testes em projetos <em><a title="Leia mais sobre Python" href="http://www.profissionaisti.com.br/tag/python/">Python</a></em>. De uma forma mais detalhada, ele percorre o seu projeto (ou uma determinada região de seu escolha) executando subclasses da <em>unittest.TestCase </em>ou funções que contenham &#8220;<em>test&#8221;</em>. Por exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># test_subclasse.py</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">unittest</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SubclasseTest<span style="color: black;">&#40;</span><span style="color: #dc143c;">unittest</span>.<span style="color: black;">TestCase</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> test_um_eh_verdadeiro<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">assertTrue</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># test_funcao.py</span>
<span style="color: #ff7700;font-weight:bold;">def</span> test_zero_eh_falso<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #ff4500;">0</span> == <span style="color: #008000;">False</span></pre></div></div>

<p style="text-align: justify;">Ao executar o comando <em><strong>nosetests </strong></em>o <em>nose </em>se encarregará de procurar e carregar os testes:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ nosetests
..
<span style="color: #660033;">----------------------------------------------------------------------</span>
Ran <span style="color: #000000;">2</span> tests <span style="color: #000000; font-weight: bold;">in</span> 0.005s
&nbsp;
OK</pre></div></div>

<p style="text-align: justify;">É claro que existe uma &#8220;mágica&#8221; aí. Na verdade o <em>nose </em>pesquisará por arquivos <em>Python </em>com &#8220;<em>test</em>&#8221; em seu nome, por funções com &#8220;<em>test</em>&#8221; em seu enunciado, e por classes<em> </em>com métodos &#8220;<em>test</em>&#8221; em sua declaração. Ele age mesmo como um &#8220;<em>runner</em>&#8220;, tendo a capacidade de lidar com testes escritos com <em>unittest </em>ou não.</p>
<p style="text-align: justify;">Essa é só a ponta do <em>iceberg</em>. É possível construir <em>plugins </em>para o <em>nose</em>, permitindo melhorar ainda mais o seu ambiente de testes (como por exemplo, permitir que o <a title="Conheça o nosepipe" href="http://pypi.python.org/pypi/nosepipe/"><em>nose </em>funcione em <em>subprocess </em>separados</a>).</p>
<p style="text-align: justify;"><strong>Caçando testes em seu projeto (<em>Django</em>)</strong></p>
<p style="text-align: justify;">Para facilitar ainda mais a escrita de testes em <em>Django </em>existem <em>plugins </em>como o <em><a title="Utilize o nose em seus projetos Django" href="http://pypi.python.org/pypi/django-nose">django-nose</a></em>, que permite que você substitua o <em>Test Runner </em>padrão da <em>framework </em>por um específico que utiliza o <em>nose</em>, unindo assim a facilidade e &#8220;<em>add-ons</em>&#8221; do <em>nose </em>com o ambiente de testes do <em>Django</em>.</p>
<h3 style="text-align: justify;"><em>lettuce</em> - <em>BDD</em> em <em>Django</em></h3>
<p style="text-align: justify;">E se você estava se perguntando sobre <em><a title="Leia mais sobre BDD" href="http://www.profissionaisti.com.br/2010/01/bdd-desenvolvimento-orientado-a-comportamento/">BDD</a> </em>em <em>Django</em>, eu apresento a <em><a title="Saiba mais sobre a lettuce" href="http://lettuce.it/intro/overview.html#intro-overview">Lettuce</a></em>!</p>
<p style="text-align: justify;">Esta ferramenta, baseada na <em><a title="Cucumber - Making BDD fun" href="http://cukes.info/">Cucumber</a></em>, permite com que você escreva estórias utilizando linguagem ubíqua, mais próxima da área de negócios do que da área técnica, e automatize a validação delas.</p>
<p style="text-align: justify;">O mais bacana é que ela já vem preparada para o <em>Django</em>, permitindo que a gente execute os testes de comportamento de forma fácil e rápida:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Feature: Rocking with lettuce and django
&nbsp;
    Scenario: Simple Hello World
        Given I access the url &quot;/&quot;
        Then I see the header &quot;Hello World&quot;
&nbsp;
    Scenario: Hello + capitalized name
        Given I access the url &quot;/some-name&quot;
        Then I see the header &quot;Hello Some Name&quot;</pre></div></div>

<p style="text-align: justify;" lang="python">Estória escrita, vamos escrever o <em>script Python </em>que validará se está tudo de acordo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> lettuce <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">from</span> lxml <span style="color: #ff7700;font-weight:bold;">import</span> html
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: #dc143c;">test</span>.<span style="color: black;">client</span> <span style="color: #ff7700;font-weight:bold;">import</span> Client
&nbsp;
@before.<span style="color: #008000;">all</span>
<span style="color: #ff7700;font-weight:bold;">def</span> set_browser<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    world.<span style="color: black;">browser</span> = Client<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
@step<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'I access the url &quot;(.*)&quot;'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> access_url<span style="color: black;">&#40;</span>step, url<span style="color: black;">&#41;</span>:
    response = world.<span style="color: black;">browser</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>
    world.<span style="color: black;">dom</span> = html.<span style="color: black;">fromstring</span><span style="color: black;">&#40;</span>response.<span style="color: black;">content</span><span style="color: black;">&#41;</span>
&nbsp;
@step<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'I see the header &quot;(.*)&quot;'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> see_header<span style="color: black;">&#40;</span>step, text<span style="color: black;">&#41;</span>:
    header = world.<span style="color: black;">dom</span>.<span style="color: black;">cssselect</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'h1'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">assert</span> header.<span style="color: black;">text</span> == text</pre></div></div>

<p style="text-align: justify;">Basta executá-lo da seguinte maneira:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ python manage.py harvest</pre></div></div>

<p style="text-align: justify;"><a title="Django + Lettuce, uma dupla interessante!" href="http://lettuce.it/recipes/django-lxml.html#recipes-django-lxml">Confira mais informações sobre como utilizar o <em>lettuce </em>com <em>Django</em></a>.</p>
<h3 style="text-align: justify;"><em>fudge</em> &#8211; Ajude o <em>Python </em>a mentir</h3>
<p style="text-align: justify;">O <em><a title="Fudge, criando objetos mentirosos" href="http://farmdev.com/projects/fudge/">Fudge</a></em> é um módulo <em>Python </em>que auxilia na construção de objetos &#8220;dublês&#8221; (<a title="Mocks não são Stubs" href="http://www.infoq.com/br/articles/mocks-Arent-Stubs"><em>mocks </em>e <em>stubs</em></a>), que permitem escrever testes sem necessariamente possuir um serviço ativo ou um objeto construído.</p>
<p style="text-align: justify;">Um caso comum: Você está construindo uma <em>API </em>que autentica via <em>OAuth </em>ao<em> Twitter </em>e está utilizando testes para guiar o seu desenvolvimento. Não é interessante que nossos testes sejam dependentes da disponibilidade do serviço do <em>Twitter</em>, portanto, escrevemos um &#8220;objeto mentiroso&#8221;, que simulará este serviço, aceitando uma entrada e gerando um saída:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> fudge
@fudge.<span style="color: black;">patch</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'oauthtwitter.OAuthApi'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #dc143c;">test</span><span style="color: black;">&#40;</span>FakeOAuthApi<span style="color: black;">&#41;</span>:
        <span style="color: black;">&#40;</span>FakeOAuthApi.<span style="color: black;">expects_call</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            .<span style="color: black;">with_args</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>, <span style="color: #483d8b;">''</span>,
                         <span style="color: #483d8b;">''</span>, <span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span>
            .<span style="color: black;">returns_fake</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            .<span style="color: black;">expects</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'UpdateStatus'</span><span style="color: black;">&#41;</span>.<span style="color: black;">with_arg_count</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
post_msg_to_twitter<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;hey there fellow testing freaks!&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p style="text-align: justify;">Pronto! Sabendo que valores serão passados, e quais os resultados, podemos simular o comportamento daquele serviço. Prático, não?</p>
<h3 style="text-align: justify;">Considerações finais</h3>
<p style="text-align: justify;">Estas são as ferramentas que eu costumo utilizar em meus projetos <em>Python/Django</em>. É claro que existem outras, na verdade existem várias. Tenha em mente que a ferramenta é apenas um meio de garantir, através de testes, que você está guiando a sua aplicação para o lugar certo. Os testes automatizados no final servem para garantir que ela ainda segue este caminho, que contribuições realizadas tardiamente não &#8220;quebraram&#8221; o comportamento que você escreveu no início do desenvolvimento.</p>
<p style="text-align: justify;">Tenho a intenção de escrever um <em>post </em>mais prático sobre testes e <em>Django</em>. Fiquem no aguardo <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align: justify;">E você? Tem alguma ferramenta para recomendar? Utilize os comentários abaixo para compartilhá-la.</p>
<h3 style="text-align: justify;">Referências</h3>
<ul style="text-align: justify;">
<li><em><a title="Leia sobre Django, BDD, Lettuce e Splinter" href="http://cilliano.com/blog/2011/02/07/django-bdd-with-lettuce-and-splinter/" target="_blank">CillianO &#8211; Django Full Stack Testing and BDD with Lettuce and Splinter</a></em></li>
<li><em><a title="Não sabe o que é BDD? Conheça neste artigo de Danilo Sato" href="http://www.dtsato.com/blog/work/introduzindo_desenvolvimento_orientado_comportamento_bdd/">Danilo Sato &#8211; Introduzindo Desenvolvimento Orientado por Comportamento (BDD)</a></em></li>
<li><em><a title="Visite o repositório do django-nose no GitHub" href="https://github.com/jbalogh/django-nose">django-nose &#8211; GitHub repository</a></em></li>
<li><em><a title="Documentação oficial do Fudge" href="http://farmdev.com/projects/fudge/using-fudge.html#fudging-a-web-service">Fudge &#8211; Using Fudge</a></em></li>
<li><em><a title="Testes em Python passam a ser mais fáceis com nose" href="http://jpz-log.info/archives/2010/06/08/nose-testing-in-python-made-easy/">JPz&#8217;log &#8211; nose: Testing in Python made easy</a></em></li>
<li><em><a title="Aprenda a escrever testes Python com o Nose" href="http://somethingaboutorange.com/mrl/projects/nose/1.0.0/writing_tests.html">Nose &#8211; Writing tests</a></em></li>
<li><em><a title="Conheça o projeto Splinter, e envolva-se" href="http://splinter.cobrateam.info/">Splinter &#8211; Test framework for web applications</a></em></li>
</ul>
<p style="text-align: justify;">Até a próxima&#8230;</p>
<p style="text-align: justify;"><strong>Fonte: </strong><a title="Ferramentas de testes em Django - Parte 2" href="http://www.klauslaube.com.br/2011/07/ferramentas-de-testes-em-django-parte-2/" target="_blank">Klaus Laube</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2011/08/ferramentas-de-testes-em-django-parte-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ferramentas de testes em Django &#8211; Parte 1</title>
		<link>http://www.profissionaisti.com.br/2011/08/ferramentas-de-testes-em-django-parte-1/</link>
		<comments>http://www.profissionaisti.com.br/2011/08/ferramentas-de-testes-em-django-parte-1/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 15:44:55 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Utilidades]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testes]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=18776</guid>
		<description><![CDATA[Dando continuidade à série de posts sobre Django, vou indicar algumas ferramentas de testes para que você também possa deixar com que os testes guiem o desenvolvimento de suas aplicações. Afinal, testar é preciso &#160; Testar em Django é possível? Sem dúvida nenhuma! Mas não espere que o framework adeque-se a você, você precisa ter [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><img class="alignleft size-full wp-image-18779" style="margin-left: 5px; margin-right: 5px;" title="gm_test_500_2-300x189" src="http://www.profissionaisti.com.br/wp-content/uploads/2011/08/gm_test_500_2-300x189.jpg" alt="" width="180" height="113" />Dando continuidade à série de <em>posts </em>sobre <em><a title="Leia mais sobre Django" href="http://www.profissionaisti.com.br/tag/django/">Django</a></em>, vou indicar algumas ferramentas<em> </em>de testes para que você também possa deixar com que os <a title="TDD: Desenvolvimento Orientado a Testes" href="http://www.profissionaisti.com.br/2009/11/tdd-desenvolvimento-orientado-a-testes/">testes guiem o desenvolvimento de suas aplicações</a>.</p>
<p style="text-align: justify;">Afinal, testar é preciso <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align: justify;">&nbsp;</p>
<h3 style="text-align: justify;">Testar em <em>Django</em> é possível?</h3>
<p style="text-align: justify;">Sem dúvida nenhuma! Mas não espere que o <em>framework </em>adeque-se a você, você precisa ter a iniciativa de tentar compreender as melhores maneiras para escrever testes em <em>Django</em>.</p>
<p style="text-align: justify;">Por exemplo, se você tem por hábito isolar os modelos para <a title="Leia mais sobre testes" href="http://www.profissionaisti.com.br/tag/testes/">testá-los</a> de forma unitária, pode passar por certa dor de cabeça com o <em><a title="Leia mais sobre Python" href="http://www.profissionaisti.com.br/tag/python/">Python</a></em>/<em><a title="Leia mais sobre Django" href="http://www.profissionaisti.com.br/tag/django/">Django</a></em>. Não que seja impossível, mas o comportamento <em>default </em>do <em>framework</em> é criar uma base de dados &#8220;<em>fake</em>&#8221; para você não precisar ter este trabalho.</p>
<p style="text-align: justify;">Enfim, talvez a forma de <strong>utilizar</strong> estas ferramentas <strong>caiba em um outro <em>post</em></strong>, o objetivo deste é <strong>apenas apresentá-las</strong>.</p>
<h3 style="text-align: justify;"><em>unittest</em> &#8211; Testando unidades através de classes</h3>
<p style="text-align: justify;">A <em><a title="unittest — Unit testing framework" href="http://docs.python.org/library/unittest.html" target="_blank">unittest</a> </em>é uma biblioteca padrão do <em>Python </em>que ajuda (e muito) a escrever testes automatizados com a linguagem.</p>
<p style="text-align: justify;">Os testes são escritos através de classes, onde utilizamos os esquemas de <em><a title="Veja a lista de asserts da unittest" href="http://docs.python.org/library/unittest.html#assert-methods" target="_blank">assertions</a></em> para garantir o comportamento do código testado (nenhuma novidade até aqui). Para quem utiliza testes unitários no <em>Java</em> não vai sentir grandes mudanças na abordagem, já que a <em>unittest </em>é inspirada na <em><a title="Leia mais sobre a JUnit" href="http://javafree.uol.com.br/wiki/JUnit" target="_blank">JUnit</a></em><em> </em>(sendo muitas vezes até chamada de <em>PyUnit</em>):</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">unittest</span>
<span style="color: #ff7700;font-weight:bold;">from</span> myapp.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Animal
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> AnimalTestCase<span style="color: black;">&#40;</span><span style="color: #dc143c;">unittest</span>.<span style="color: black;">TestCase</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> setUp<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">lion</span> = Animal.<span style="color: black;">objects</span>.<span style="color: black;">create</span><span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">&quot;lion&quot;</span>, sound=<span style="color: #483d8b;">&quot;roar&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">cat</span> = Animal.<span style="color: black;">objects</span>.<span style="color: black;">create</span><span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">&quot;cat&quot;</span>, sound=<span style="color: #483d8b;">&quot;meow&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> testSpeaking<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEquals</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">lion</span>.<span style="color: black;">speak</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'The lion says &quot;roar&quot;'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEquals</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">cat</span>.<span style="color: black;">speak</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'The cat says &quot;meow&quot;'</span><span style="color: black;">&#41;</span></pre></div></div>

<p style="text-align: justify;">O <em>test runner</em> padrão do <em>Django</em> irá procurar por subclasses de <em>unittest.TestCase </em>nos arquivos <em>models.py </em>e <em>tests.py</em>. A suíte de testes tenta facilitar ao máximo a sua vida&#8230; execute a seguinte instrução e confira se a sua aplicação está <em>ok </em>ou não:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ python manage.py <span style="color: #7a0874; font-weight: bold;">test</span></pre></div></div>

<p style="text-align: justify;"><strong>Peraí que não acabou! Apresentando a <em>TestCase</em></strong></p>
<p style="text-align: justify;">Testar aplicações <em>Web </em>com a<em> unittest </em>pode ser dureza. Pensando nisso o <em>Django </em>disponibiliza a <em>TestCase</em>, que estende a <em>unittest</em> adicionando funcionalidades como carregamento de <em>fixtures</em>, roteamento de <em>urls </em>e um <em>client</em> para fazer requisições <em>Web </em>e testar as suas <em>views </em>(o <em>TestClient</em>, detalhado mais abaixo).</p>
<h3 style="text-align: justify;"><em>doctest</em> &#8211; Testando através de <em>docstrings</em></h3>
<p style="text-align: justify;">Admito que escrever documentação de <em>software </em>não é o meu forte&#8230; mas com <em>doctests </em>pode-se documentar métodos ao mesmo tempo em que escreve-se testes!</p>
<p style="text-align: justify;">A <em><a title="Leia mais sobre a doctest" href="http://docs.python.org/library/doctest.html" target="_blank">doctest</a> </em>é uma biblioteca padrão do <em>Python </em>que procura e interpreta <em>docstrings </em>na aplicação. A sintaxe nesses trechos de <em><a title="Entenda o que é uma docstring" href="http://www.python.org/dev/peps/pep-0257/">docstrings</a> </em>é diferenciada, simulando um interpretador interativo do <em>Python</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># models.py</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span> <span style="color: #ff7700;font-weight:bold;">import</span> models
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Animal<span style="color: black;">&#40;</span>models.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    An animal that knows how to make noise
&nbsp;
    # Create some animals
    &gt;&gt;&gt; lion = Animal.objects.create(name=&quot;lion&quot;, sound=&quot;roar&quot;)
    &gt;&gt;&gt; cat = Animal.objects.create(name=&quot;cat&quot;, sound=&quot;meow&quot;)
&nbsp;
    # Make 'em speak
    &gt;&gt;&gt; lion.speak()
    'The lion says &quot;roar&quot;'
    &gt;&gt;&gt; cat.speak()
    'The cat says &quot;meow&quot;'
    &quot;&quot;&quot;</span>
    name = models.<span style="color: black;">CharField</span><span style="color: black;">&#40;</span>max_length=<span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span>
    sound = models.<span style="color: black;">CharField</span><span style="color: black;">&#40;</span>max_length=<span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> speak<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'The %s says &quot;%s&quot;'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">name</span>, <span style="color: #008000;">self</span>.<span style="color: black;">sound</span><span style="color: black;">&#41;</span></pre></div></div>

<p style="text-align: justify;">Assim como com a <em>unittest</em>, o <em>test runner </em>padrão do <em>Django </em>procurará por ocorrências de <em>docstests </em>em <em>models.py </em>e <em>tests.py</em>.</p>
<h3 style="text-align: justify;"><em>Django Test Client</em> &#8211; Testando a sua aplicação como se fosse um navegador</h3>
<p style="text-align: justify;">E como fazer para testar requisições <em>Web</em>? Por exemplo, você não quer testar a sua <em>view </em>de forma isolada, quer testar desde a parte de roteamento ao comportamento com o banco de dados, como se você se estivesse realmente visitando a página. Neste caso entra a <em><a title="Testando aplicações Django com requisições Web falsas" href="https://docs.djangoproject.com/en/dev/topics/testing/#module-django.test.client">test client</a></em>.</p>
<p style="text-align: justify;">Toda a classe <em>TestCase </em>possui uma instância da <em>Django Test Client</em>. Então escrever testes com requisições à sua aplicação fica muito simples utilizando classes:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: #dc143c;">test</span> <span style="color: #ff7700;font-weight:bold;">import</span> TestCase
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SimpleTest<span style="color: black;">&#40;</span>TestCase<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> test_details<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        response = <span style="color: #008000;">self</span>.<span style="color: black;">client</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/customer/details/'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span>response.<span style="color: black;">status_code</span>, <span style="color: #ff4500;">200</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> test_index<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        response = <span style="color: #008000;">self</span>.<span style="color: black;">client</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/customer/index/'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span>response.<span style="color: black;">status_code</span>, <span style="color: #ff4500;">200</span><span style="color: black;">&#41;</span></pre></div></div>

<p style="text-align: justify;">É perfeitamente possível utilizar a <em>test client </em>em <em>doctests </em>também:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #483d8b;">&quot;&quot;&quot;
&gt;&gt;&gt; from django.test.client import Client
&gt;&gt;&gt; c = Client()
&gt;&gt;&gt; response = c.post('/login/', {'username': 'john',
...        'password': 'smith'})
&gt;&gt;&gt; response.status_code
200
&quot;&quot;&quot;</span></pre></div></div>

<h3 style="text-align: justify;">Considerações finais</h3>
<p style="text-align: justify;">Particularmente, tive a oportunidade de implementar testes unitários já no início do meu aprendizado em <em>Django</em>. Deixar os testes te guiarem é uma prática excelente!</p>
<p style="text-align: justify;">Tudo parte do bom senso, óbvio. Nenhum processo ou ferramenta deveria substituir o &#8220;<em>feeling</em>&#8221; do profissional&#8230; também não é muito sadio ser extremamente &#8220;<em>by the book</em>&#8220;. Mas se puder utilizar testes para guiar o seu desenvolvimento, use-os!</p>
<p style="text-align: justify;">Na segunda parte deste <em>post</em> pretendo apresentar algumas ferramentas que irão turbinar ainda mais o seu desenvolvimento orientado a testes.</p>
<p style="text-align: justify;">Até lá!</p>
<h3 style="text-align: justify;">Referências</h3>
<ul style="text-align: justify;">
<li><a title="Leia direto da fonte como escrever testes em Django" href="https://docs.djangoproject.com/en/1.1/topics/testing/#writing-unit-tests"><em>Django Documentation &#8211; Writing unit tests</em></a></li>
<li><a title="Leia direto da fonte sobre como escrever testes com docstrings" href="https://docs.djangoproject.com/en/1.1/topics/testing/#writing-doctests"><em>Django Documentation &#8211; Writing doctests</em></a></li>
<li><em><a title="Entenda a diferença entre unittest do Python e o TestCase do Django" href="https://docs.djangoproject.com/en/1.1/topics/testing/#testcase">Django Documentation &#8211; TestCase</a></em></li>
<li><em><a title="Leia sobre a unittest direto da documentação do Python" href="http://docs.python.org/library/unittest.html">Python Documentation &#8211; unittest: Unit testing framework</a></em></li>
<li><em><a title="Aprenda a testar a sua primeira aplicação em Django" href="http://dougalmatthews.com/articles/2010/jan/20/testing-your-first-django-app/">Dougal Matthews &#8211; Testing your first Django app</a></em></li>
<li><a title="O Konrad apresenta algumas ferramentas muito boas para testes com Django" href="&amp; kokoko.fluxionary.net/testing-django-part-1-nose"><em>Konrad&#8217;s Kode, Konfigs &amp; Konstructions &#8211; Testing Django</em></a></li>
<li><a title="Aprenda Django de uma forma divertida com o Marinho" href="http://www.marinhobrandao.com/blog/programacao-dirigida-a-testes-no-django/">Marinho Brandão &#8211; Programação dirigida a testes no <em>Django</em></a></li>
</ul>
<p style="text-align: justify;"><strong>Fonte: </strong><a title="Ferramentas de testes em Django - Parte 1" href="http://www.klauslaube.com.br/2011/07/ferramentas-de-testes-em-django-parte-1/" target="_blank">Klaus Laube</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2011/08/ferramentas-de-testes-em-django-parte-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python/Django: Quando usar gettext e gettext_lazy?</title>
		<link>http://www.profissionaisti.com.br/2011/06/pythondjango-quando-usar-gettext-e-gettext_lazy/</link>
		<comments>http://www.profissionaisti.com.br/2011/06/pythondjango-quando-usar-gettext-e-gettext_lazy/#comments</comments>
		<pubDate>Fri, 17 Jun 2011 16:00:07 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Papinho de TI]]></category>
		<category><![CDATA[Dica]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=17349</guid>
		<description><![CDATA[Olá pessoas! Para vocês que desenvolvem em Python e Django preocupando-se com internacionalização, já devem ter feito a seguinte pergunta: Quando usar gettext e gettext_lazy? Acredito que antes de responder esta pergunta, temos que responder outra questão pertinente: Devo utilizar gettext ou ugettext? gettext vs ugettext Essas duas funções seguem o mesmo princípio dos métodos [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Olá pessoas!</p>
<p style="text-align: justify;">Para vocês que desenvolvem em <em><a title="Leia mais sobre Python" href="http://www.profissionaisti.com.br/tag/python/">Python</a> </em>e<em> <a title="Leia mais sobre Django" href="http://www.profissionaisti.com.br/tag/django/">Django</a> </em>preocupando-se com internacionalização, já devem ter feito a seguinte pergunta: <em>Quando usar gettext e gettext_lazy? </em></p>
<p style="text-align: justify;">Acredito que antes de responder esta pergunta, temos que responder outra questão pertinente: <em>Devo utilizar gettext ou ugettext?<br />
</em></p>
<h3 style="text-align: justify;"><em>gettext </em>vs <em>ugettext</em></h3>
<p style="text-align: justify;">Essas duas funções seguem o mesmo princípio dos métodos mágicos <em>__str__ </em>e <em>__unicode__</em>. Onde <em>gettext </em>retornará um texto traduzido como uma <em>string </em>&#8220;comum&#8221;, e <em>ugettext </em>retornará um texto traduzido como uma <em>string Unicode</em>.</p>
<p style="text-align: justify;">Como nosso idioma nativo abusa do uso de caracteres especiais, aconselho sempre que possível a utilização do <em>ugettext</em>. Na verdade, é uma forma de garantir sucesso na tradução de qualquer idioma sem quebrar a cabeça com <em>encoding</em> (já que o <em>Unicode </em>tem uma ampla tabela  de caracteres).</p>
<p style="text-align: justify;">Além disso, passe a mensagem como <em>Unicode </em>para a função sempre que necessário:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">texto_traduzido = ugettext<span style="color: black;">&#40;</span>u<span style="color: #483d8b;">'Descrição do produto em estoque'</span><span style="color: black;">&#41;</span></pre></div></div>

<h3 style="text-align: justify;"><em>ugettext </em>vs <em>ugettext_lazy</em></h3>
<p style="text-align: justify;">A principal diferença entre <em>ugettext </em>e <em>ugettext_lazy </em>é que o último é literalmente um preguiçoso. Ele faz uma referência para a <em>string </em>(e não necessariamente para a tradução), fazendo com que a operação seja executada apenas quando a renderização da <em>string </em>é necessária (ao contrário de <em>ugettext </em>que é processado assim que a expressão é interpretada).</p>
<p style="text-align: justify;">Confuso? Talvez o <em><a title="Aprendendo Django no Planeta Terra - O mesmo site em vários idiomas" href="http://www.aprendendodjango.com/o-mesmo-site-em-varios-idiomas/" target="_blank">Marinho Brandão</a> </em>possa ser mais claro:</p>
<pre>A função <strong>"ugettext_lazy()"</strong> é <strong>preguiçosa</strong>. Isso significa que a 
tradução é feita somente quando ela é requisitada, o que é
relativamente melhor para o caso de classes de modelo, pois elas
são constantemente utilizadas sem que a tradução de um termo seja
necessário de fato.

Por outro lado a função <strong>"ugettext()"</strong> traduz a string
instantaneamente, o que é melhor para casos como o de formulários
dinâmicos e <em>views</em>, pois eles não são usados de maneira tão constante
quanto classes de modelo.</pre>
<p style="text-align: justify;">Então&#8230; utilize <em>ugettext_lazy </em>nos campos e meta-informações dos modelos (onde a tradução pode ser feita sob demanda), e <em>ugettext </em>em métodos, funções e <em>views </em>(onde a tradução tem quer ser &#8220;instantânea&#8221;).</p>
<h3 style="text-align: justify;">Referências</h3>
<ul style="text-align: justify;">
<li><em><a title="gettext - Multilingual internationalization services" href="http://docs.python.org/library/gettext.html" target="_blank">Python Documentation &#8211; gettext</a></em></li>
<li><em><a title="Django Docs - Lazy Translation" href="https://docs.djangoproject.com/en/dev/topics/i18n/internationalization/#lazy-translation" target="_blank">Django Documentation &#8211; Internationalization</a></em></li>
<li><em><a title="The Django Book - i18n" href="http://www.djangobook.com/en/1.0/chapter18/" target="_blank">The Django Book &#8211; Internationalization</a></em></li>
<li><a title="Aprendendo Django - O mesmo site em vários idiomas" href="http://www.aprendendodjango.com/o-mesmo-site-em-varios-idiomas/" target="_blank">Aprendendo <em>Django </em>no Planeta Terra &#8211; O mesmo site em vários idiomas</a></li>
</ul>
<p style="text-align: justify;">Até a próxima&#8230;</p>
<p style="text-align: justify;"><strong>Fonte: </strong><a title="Quando usar gettext e gettext_lazy?" href="http://www.klauslaube.com.br/2011/06/quando-usar-gettext-gettext_lazy/">Blog Klaus Laube</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2011/06/pythondjango-quando-usar-gettext-e-gettext_lazy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Como organizar seus projetos Django</title>
		<link>http://www.profissionaisti.com.br/2011/04/como-organizar-seus-projetos-django/</link>
		<comments>http://www.profissionaisti.com.br/2011/04/como-organizar-seus-projetos-django/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 14:20:50 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[programação]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=16696</guid>
		<description><![CDATA[Olá pessoas! Pretendo compartilhar com vocês a forma que venho utilizando para organizar meus projetos Django com o uso do virtualenv. Não entrarei em muitos detalhes, até porque você verá que é um procedimento muito simples, mas que poderá garantir melhor organização dos seus projetos e dos seus ambientes de desenvolvimento. É interessante que você [...]]]></description>
			<content:encoded><![CDATA[<p>Olá pessoas!</p>
<p style="text-align: justify;">Pretendo compartilhar com vocês a forma que venho utilizando para organizar meus projetos <em><a title="Leia mais sobre Django" href="http://www.profissionaisti.com.br/tag/django/" target="_blank">Django</a></em> com o uso do <em><a title="Leia mais sobre virtualenv" href="http://www.profissionaisti.com.br/tag/virtualenv/" target="_blank">virtualenv</a></em>. Não entrarei em muitos detalhes, até porque você verá que é um procedimento muito simples, mas que poderá garantir melhor organização dos seus projetos e dos seus ambientes de desenvolvimento.</p>
<p style="text-align: justify;">É interessante que você leia o <em>post</em> &#8220;<a title="Leia mais sobre a tríade Python, Django e virtualenv" href="http://www.profissionaisti.com.br/?p=16201"><em>Python</em>, <em>Django</em> e <em>virtualenv</em></a>&#8221; antes de continuar.</p>
<p style="text-align: justify;"><strong>Simplesmente um projeto <em>Django</em></strong></p>
<p style="text-align: justify;">Antes de conhecer (e utilizar) o <em>virtualenv</em>, utilizei algo parecido com o modelo &#8220;tradicional&#8221;  de organização de pastas e códigos em um projeto <em>Django</em>. Ou seja, parecido com aquela estrutura padrão gerada pelo comando <em>django-admin.py startproject</em><em>. </em></p>
<p style="text-align: justify;">O modelo é bom, e funcionou para mim durante muito tempo. Mas de uns tempos para cá venho utilizando o esquema abaixo (<a title="Estrutura de pastas de um TCC que fiz utilizando Django" href="https://bitbucket.org/kplaube/social-portal-for-soccer-players/src" target="_blank">confira um exemplo real</a>):</p>
<pre>mysite/
    apps/
        __init__.py
        eggs/
            fixtures/
                eggs_testdata.json
            tests/
                __init__.py
                models.py
                views.py
            __init__.py
            models.py
            urls.py
            views.py
    core/
        __init__.py
        extras.py
    __init__.py
    manage.py
    settings.py
    urls.py</pre>
<p style="text-align: justify;">A diferença principal está na utilização da pasta <strong>apps </strong>para encapsular as aplicações do projeto, e a criação de uma pasta (ou pacote, como preferir) <strong>core</strong>. Nesta última, gosto de armazenar <em>snippets </em>de código que serão aproveitados pelo projeto inteiro.</p>
<p style="text-align: justify;">Outro ponto que vale ser notado é a criação de uma pasta chamada <strong>tests </strong>para cada <em>app</em>. Embora haja casos em que um arquivo <strong>tests.py </strong>seja o suficiente, podemos nos deparar com um arquivo gigantesco testando vários aspectos de uma <em>app </em>(o que pode dificultar a legibilidade de código). Categorizar os testes por tipo, e em arquivos separados, irá facilitar a adição de novos testes e funcionalidades.</p>
<p style="text-align: justify;">A abordagem dos testes também pode ser utilizada para o <strong>urls.py</strong>. Quando o seu arquivo de roteamento ficar muito grande, crie uma pasta <strong>urls </strong>e &#8220;quebre&#8221; suas rotas em arquivos diferentes. Categorize-os, sinta-se &#8220;<em>zen</em>&#8221; e nunca mais tenha medo de criar <em>URLs </em>novamente <img src='http://www.profissionaisti.com.br/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p style="text-align: justify;">Comecei a utilizar esta estrutura após &#8220;xeretar&#8221; alguns projetos <em>Django open source</em>. Posso dizer por experiência própria que é uma prática interessante, e que tem me ajudado muito na organização de código.</p>
<p style="text-align: justify;"><strong>O projeto <em>Django</em> com o <em>virtualenv</em></strong></p>
<p style="text-align: justify;">Tratando-se do ambiente de desenvolvimento (construído pelo <em>virtualenv</em>), já utilizei-o de duas formas:</p>
<ul style="text-align: justify;">
<li><strong>O <em>environment </em>em uma pasta separada do projeto:</strong> Você pode possuir uma pasta &#8220;<em>environments</em>&#8221; e lá ter diferentes ambientes para diferentes projetos.</li>
<li><strong>O projeto <em>Django </em>ficar dentro da pasta de <em>environment</em>:</strong> Você primeiramente constrói um ambiente com o <em>virtualenv</em>, e depois cria um projeto dentro dessa mesma pasta (como demonstrado <a title="Trabalhando com Python e Django à moda Osvaldo" href="http://blog.triveos.com.br/2010/04/25/trabalhando-com-python-e-django/">neste <em>post </em>do <em>Osvaldo Santana</em></a>).</li>
</ul>
<p style="text-align: justify;">Particularmente eu prefiro a segunda opção (nunca precisei de 2 <em>environments </em>idênticos). Além de manter todo o seu projeto agrupado, fica mais fácil para criação de <em>scripts </em>de automatização de <em>deploy</em>, por exemplo.</p>
<p style="text-align: justify;">No fim das contas, geralmente a estrutura de pastas dos projetos <em>Django </em>fica assim:</p>
<pre>MySiteProject/
    bin/
    include/
    lib/
    mysite/
        apps/
            __init__.py
            eggs/
                fixtures/
                    eggs_testdata.json
                tests/
                    __init__.py
                    models.py
                    views.py
                __init__.py
                models.py
                urls.py
                views.py
        core/
            __init__.py
            extras.py
        __init__.py
        manage.py
        settings.py
        urls.py</pre>
<p style="text-align: justify;">E você? De que forma organiza os seus projetos em <em>Django</em>? Conte-nos através dos comentários abaixo!</p>
<p style="text-align: justify;">Até a próxima&#8230;</p>
<p style="text-align: justify;"><strong>Fonte: </strong><a href="http://www.klauslaube.com.br/2011/04/como-organizar-seus-projetos-django/" target="_blank">Blog Klaus Laube</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2011/04/como-organizar-seus-projetos-django/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Python, Django e virtualenv</title>
		<link>http://www.profissionaisti.com.br/2011/04/python-django-e-virtualenv/</link>
		<comments>http://www.profissionaisti.com.br/2011/04/python-django-e-virtualenv/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 13:48:28 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Utilidades]]></category>
		<category><![CDATA[Ambiente]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=16201</guid>
		<description><![CDATA[Olá pessoas! Você está começando em Python e vive ouvindo falar sobre um tal de virtualenv? Pois bem, vamos aproveitar para dar uma pincelada nesta útil ferramenta, e como usá-la com nossos amigos Python e Django. Python Conheça alguns motivos que lhe convencerão a usar Python. O Python já vem instalado na maioria das distribuições Linux. [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Olá pessoas!</p>
<p style="text-align: justify;">Você está começando em <em><a title="Leia mais sobre Python" href="http://www.profissionaisti.com.br/tag/python/">Python</a> </em>e vive ouvindo falar sobre um tal de <em><a title="Leia mais sobre virtualenv" href="http://www.profissionaisti.com.br/tag/virtualenv/">virtualenv</a></em>? Pois bem, vamos aproveitar para dar uma pincelada nesta útil ferramenta, e como usá-la com nossos amigos <em>Python </em>e <em><a title="Leia mais sobre Django" href="http://www.profissionaisti.com.br/tag/django/">Django</a></em>.</p>
<p style="text-align: justify;"><strong>Python</strong></p>
<p style="text-align: justify;"><a title="10 motivos para se usar Python" href="http://www.profissionaisti.com.br/2009/01/10-motivos-para-voce-aprender-a-programar-em-python/">Conheça alguns motivos que lhe convencerão a usar <em>Python</em></a>.</p>
<p style="text-align: justify;">O <em>Python</em> já vem instalado na maioria das distribuições <em><a title="Leia mais sobre Linux" href="http://www.profissionaisti.com.br/tag/linux/">Linux</a></em>. Na verdade, até hoje nunca usei uma distro <em>Linux</em> que não tivesse o <em>Python</em> préviamente instalado. No <em>Slackware 13.1</em>, o <em>Python</em> está na versão 2.6.4. No <em>Debian 6</em>, o <em>Python</em> está na versão 2.6.6.</p>
<p style="text-align: justify;">O portal <em>Python Brasil</em> possui um excelente material para você <a title="Inicie-se no Python" href="http://www.python.org.br/wiki/InicieSe">instalar</a> e dar os <a title="Aprenda mais sobre Python" href="http://www.python.org.br/wiki/AprendaMais">primeiros passos</a> com <em>Python</em>.</p>
<p style="text-align: justify;"><strong>virtualenv</strong></p>
<p style="text-align: justify;">A linguagem <em>Python</em> não vem &#8220;de bobeira&#8221; nas distribuições <em>Linux</em>, ela faz parte delas, sendo utilizada para criação de uma série de <em>scripts</em> fundamentais. Passei por uma situação peculiar com o <em>Python</em>: estava usando o <em>OpenSuse</em> (não recordo a versão) e decidi atualizar a versão do <em>Python</em> utilizando o sistema de pacotes da distro&#8230; confirmei algumas operações de remoção (que não deveria ter autorizado) e acabei danificando minha instalação do <em>SO</em>.</p>
<p style="text-align: justify;">Então, para aqueles que programam em computadores pessoais, e não querem comprometer tanto o <em>SO</em> quanto o <em>workspace</em>, podem criar <strong>ambientes isolados</strong> para os projetos utilizando o <em><a title="Virtual Python Environment Builder" href="http://pypi.python.org/pypi/virtualenv">virtualenv</a></em>.</p>
<p style="text-align: justify;">No <em>Slackware</em> vamos instalar o <em><a title="Download, build, install, upgrade, and uninstall Python packages" href="http://pypi.python.org/pypi/setuptools">setuptools</a></em>, que é um <em>framework</em> que facilita a instalação e criação de pacotes <em>Python</em>:</p>
<pre>wget http://peak.telecommunity.com/dist/ez_setup.py</pre>
<p style="text-align: justify;">Para instalá-lo é necessário ser <strong><em>root</em></strong>:</p>
<pre>python ez_setup.py</pre>
<p style="text-align: justify;">Em seguida, vamos instalar o <em>virtualenv</em> com a ajuda do <strong><em>easy_install </em></strong>(que faz parte do pacote <em>setuptools</em>):</p>
<pre>easy_install virtualenv</pre>
<p style="text-align: justify;">Esta é uma forma interessante para você instalar módulos <em>Python</em> em seu sistema sem recorrer ao sistema de pacotes do <em>SO</em>.</p>
<p style="text-align: justify;">Agora, como um <strong>usuário comum</strong>, vamos criar um ambiente em nosso <em>home</em> para testarmos o <strong><em>virtualenv</em></strong>:</p>
<pre>virtualenv ~/projeto_django</pre>
<p style="text-align: justify;">Entrando nesta pasta, você irá se deparar com três diretórios:</p>
<ul style="text-align: justify;">
<li><strong>bin:</strong> Os executáveis do seu ambiente isolado estarão aí. Você poderá notar o executável <em>python</em>, o <em>easy_install</em>, o <em>pip</em> e um carinha chamado &#8220;<em>activate</em>&#8221; (falaremos deste mais tarde).</li>
<li><strong>lib:</strong> Nesta pasta você encontrará os módulos e bibliotecas <em>Python</em> utilizadas por este ambiente.</li>
<li><strong>include:</strong> Segundo o <em><a title="Ambiente Isolado para Python com virtualenv" href="http://blog.triveos.com.br/2008/03/03/ambiente-isolado-para-python-com-virtualenv/">Osvaldo Santana</a></em>, dentro desse diretório estão os <em>links</em> simbólicos para todos os headers do Python que são necessário para se compilar extensões escritas em <em>C</em> para ele.</li>
</ul>
<p style="text-align: justify;">Você apenas criou seu ambiente&#8230; para ativá-lo basta dar o seguinte comando:</p>
<pre>source ~/projeto_django/bin/activate</pre>
<p style="text-align: justify;">Pronto! Se você executar o <em>Python</em> agora, você estará utilizando as <em>libs</em> <strong>deste ambiente</strong>. Isso pode permitir que você mova este ambiente entre máquinas, que você instale <em>libs</em> somente neste ambiente (deixando o <em>Python</em> do seu <em>SO</em> &#8220;limpo&#8221;, isso pode te garantir maior performance da distro) e que você tenha um controle maior sobre as dependências do seu projeto.</p>
<p style="text-align: justify;">Para &#8220;sair&#8221; do ambiente, basta executar o comando <strong><em>deactivate</em></strong>:</p>
<pre>deactivate</pre>
<p style="text-align: justify;">Pronto&#8230; muito simples, não?</p>
<p style="text-align: justify;"><strong>Django</strong></p>
<p style="text-align: justify;"><a title="Programando Python para Web" href="http://www.profissionaisti.com.br/2009/02/programando-python-para-a-web/">Saiba um pouco mais sobre a programação <em>Python </em>para <em>Web</em></a>.</p>
<p style="text-align: justify;">Vamos instalar o <em>Django</em> neste <strong>ambiente isolado</strong>. Ativaremos novamente o <strong><em>virtualenv</em></strong> e usaremos o <strong><em>easy_install</em></strong> para nos ajudar com esta tarefa:</p>
<pre>source ~/projeto_django/bin/activate 
easy_install django</pre>
<p style="text-align: justify;">No final da operação, você irá se deparar com uma saída similar a esta:</p>
<pre>Installed /home/user/projeto_django/lib/python2.6/site-packages/
Django-1.2.5-py2.6.egg 
Processing dependencies for django 
Finished processing dependencies for django</pre>
<p style="text-align: justify;">Isto é a garantia que o <em>Django</em> foi <strong>instalado dentro deste ambiente</strong>, e não está visível para o escopo global da distribuição. Tente importa o <em>django</em> no terminal interativo do <em>Python</em> da sua distro e do <em>Python</em> do seu ambiente isolado e veja o que acontece&#8230;</p>
<p style="text-align: justify;"><a title="Entendendo o Django" href="http://www.profissionaisti.com.br/2009/04/entendendo-o-django/">Entenda o que é o <em>Django </em>e como ele funciona</a>.</p>
<p style="text-align: justify;">Até a próxima&#8230;</p>
<p style="text-align: justify;"><strong>Fonte: </strong><a href="http://www.klauslaube.com.br/2011/03/python-django-virtualenv/" target="_blank">Blog Klaus Laube</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2011/04/python-django-e-virtualenv/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tiobe elege o Python como a linguagem de programação de 2010</title>
		<link>http://www.profissionaisti.com.br/2011/01/tiobe-elege-o-python-como-a-linguagem-de-programacao-de-2010/</link>
		<comments>http://www.profissionaisti.com.br/2011/01/tiobe-elege-o-python-como-a-linguagem-de-programacao-de-2010/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 17:48:29 +0000</pubDate>
		<dc:creator>Klaus Peter Laube</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Notícias de TI]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[TIOBE]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=14928</guid>
		<description><![CDATA[Não é de hoje que Python conquistou o respeito dos mais diversos entusiastas do mercado de Tecnologia da Informação de todo o mundo&#8230; e era questão de tempo para que esse reconhecimento fosse &#8220;sacramentado&#8221;. O Henrique Bastos divulgou na lista de discussão do Django a notícia que a Tiobe elegeu o Python como linguagem de 2010. O Python agora ocupa a quinta colocação [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-14929" style="margin-top: 5px; margin-bottom: 5px; margin-left: 10px; margin-right: 10px;" title="python-logo" src="http://www.profissionaisti.com.br/wp-content/uploads/2011/01/python-logo.png" alt="Logotipo da linguagem Python" width="310" height="97" />Não é de hoje que <em><a title="Leia mais sobre Python no ProfissionaisTI" href="http://www.profissionaisti.com.br/tag/python/">Python</a></em> conquistou o respeito dos mais diversos entusiastas do mercado de Tecnologia da Informação de todo o mundo&#8230; e era questão de tempo para que esse reconhecimento fosse &#8220;sacramentado&#8221;.</p>
<p>O <a title="Python é eleito a linguagem de 2010" href="http://henriquebastos.net/2011/01/09/python-e-eleito-a-linguagem-de-2010/" target="_blank"><em>Henrique Bastos</em></a> divulgou na <a title="Grupo de discussão Django Brasil" href="http://groups.google.com/group/django-brasil" target="_blank">lista de discussão do <em>Django</em></a> a notícia que a <a title="January Headline: Python wins the TIOBE Programming Language Award of 2010!" href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html" target="_blank"><em>Tiobe</em> elegeu o <em>Python</em> como linguagem de 2010</a>.</p>
<p>O Python agora ocupa a quinta colocação da tabela da Tiobe, atrás somente de <em><a title="Leia mais sobre Java no ProfissionaisTI" href="http://www.profissionaisti.com.br/tag/java/">Java</a></em>, <em><a title="Leia mais sobre C no ProfissionaisTI" href="http://www.profissionaisti.com.br/tag/c/">C</a></em>, <em><a title="Leia mais sobre C++ no ProfissionaisTI" href="http://www.profissionaisti.com.br/tag/c++/">C++</a></em> e <em><a title="Leia mais sobre PHP no ProfissionaisTI" href="http://www.profissionaisti.com.br/tag/php/">PHP</a></em>.</p>
<p>O sucesso deve-se desde a rica documentação, até as excepcionais <em>frameworks</em> que tornam a linguagem uma das ferramentas modernas mais poderosas (e ágeis) para desenvolvimento de <em>software</em>.</p>
<p><strong>Fonte: </strong><em><a title="Tiobe elege o Python como a linguagem de programação de 2010" href="http://www.klauslaube.com.br/2011/01/tiobe-elege-python-como-linguagem-de-programacao-de-2010/" target="_blank">Klaus Laube</a></em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2011/01/tiobe-elege-o-python-como-a-linguagem-de-programacao-de-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introdução à programação com Python</title>
		<link>http://www.profissionaisti.com.br/2010/11/livro-introducao-a-programacao-com-python/</link>
		<comments>http://www.profissionaisti.com.br/2010/11/livro-introducao-a-programacao-com-python/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 00:34:32 +0000</pubDate>
		<dc:creator>Profissionais TI</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Livros]]></category>
		<category><![CDATA[Livro]]></category>
		<category><![CDATA[programação]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=14254</guid>
		<description><![CDATA[Autor: Nilo Ney Coutinho Menezes ISBN: 978-85-7522-250-8 Páginas: 224 Compre este livro com 20% de desconto (código PTI20)! Este livro é orientado ao iniciante em programação. Os conceitos básicos de programação, como expressões, variáveis, repetições, decisões, listas, funções e arquivos, são apresentados um a um com exemplos e exercícios. A obra visa explorar a programação [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" style="margin-left: 5px; margin-right: 5px;" title="Introdução à programação com Python" src="http://www.profissionaisti.com.br/wp-content/uploads/2010/11/9788575222508.gif" alt="" width="120" height="173" />Autor: Nilo Ney Coutinho Menezes <br />
 ISBN: 978-85-7522-250-8 <br />
 Páginas: 224</p>
<p><a href="http://novatec.com.br/livros/intropython/?idA=182" target="_blank">Compre este livro</a> com 20% de desconto (código PTI20)!</p>
<p>Este livro é orientado ao iniciante em programação. Os conceitos básicos de programação, como expressões, variáveis, repetições, decisões, listas, funções e arquivos, são apresentados um a um com exemplos e exercícios. A obra visa explorar a programação de computadores como ferramenta do dia a dia. Ela pode ser lida durante um curso de introdução à programação de computadores e usada como guia de estudo para autodidatas. Para aproveitamento pleno do conteúdo, conhecimentos básicos de informática, como digitar textos, abrir e salvar arquivos, são suficientes. Todo software utilizado no livro pode ser baixado gratuitamente, sendo executado em Windows, Linux e Mac OS X.</p>
<p>Embora a linguagem Python (versão 3.x) seja muito poderosa e repleta de recursos modernos de programação, este livro não pretende ensinar a linguagem em si, mas ensinar a programar. Alguns recursos da linguagem não foram utilizados para privilegiar os exercícios de lógica de programação e oferecer uma preparação mais ampla ao leitor para outras linguagens. Essa escolha não impediu a apresentação de recursos poderosos da linguagem, embora o livro não seja fundamentalmente uma obra de referência.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2010/11/livro-introducao-a-programacao-com-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Concorra a uma vaga para o treinamento de desenvolvimento web com Python em SP</title>
		<link>http://www.profissionaisti.com.br/2010/08/concorra-a-uma-vaga-para-o-treinamento-de-desenvolvimento-web-com-python-em-sp/</link>
		<comments>http://www.profissionaisti.com.br/2010/08/concorra-a-uma-vaga-para-o-treinamento-de-desenvolvimento-web-com-python-em-sp/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 11:11:33 +0000</pubDate>
		<dc:creator>Bruno Rocha</dc:creator>
				<category><![CDATA[Cursos/Treinamentos]]></category>
		<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Promoções]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Sorteio]]></category>
		<category><![CDATA[web2py]]></category>

		<guid isPermaLink="false">http://www.profissionaisti.com.br/?p=12702</guid>
		<description><![CDATA[Para participar da promoção é fácil: Basta seguir o twitter @web2pybrasil e @treventos e tuitar a seguinte mensagem: Quero ganhar uma vaga para o treinamento de Python e web2py - http://migre.me/16VWO @treventos @web2pybrasil Importante: a URL http://migre.me/16VWO deve constar no tweet. Data do sorteio: Quinta Feira : 26 de agosto O sorteio será feito através da ferramenta: http://sorteie.me O contato de [...]]]></description>
			<content:encoded><![CDATA[<p>Para participar da promoção é fácil:</p>
<p>Basta seguir o twitter <a href="http://twitter.com/web2pybrasil" target="_blank">@web2pybrasil</a> e <a href="http://twitter.com/treventos" target="_blank">@treventos</a> e tuitar a seguinte mensagem:</p>
<blockquote><p>Quero ganhar uma vaga para o treinamento de Python e web2py - http://migre.me/16VWO @treventos @web2pybrasil</p>
</blockquote>
<p><strong>Importante:</strong> a URL <a href="http://migre.me/16VWO" target="_blank">http://migre.me/16VWO</a> deve constar no tweet.</p>
<hr />
<p>Data do sorteio: Quinta Feira : 26 de agosto</p>
<p>O sorteio será feito através da ferramenta: <a href="http://sorteie.me">http://sorteie.me</a></p>
<p>O contato de aviso com o ganhador(a) será através de direct message. Assim, é importante que você seja um seguidor(a) da @web2pybrasil</p>
<p><strong>O sortudo(a) ganhará:</strong></p>
<ul>
<li>A inscrição para o evento</li>
<li>Coffee Break (2)</li>
<li>Certificado de Participação em papel especial</li>
<li>Material Didático (apostila impressa, bloco de anotações e caneta)</li>
<li>Oportunidade de conhecer profissionais do mercado com interesses similares ao seus, ou seja: ampliar sua rede de relacionamento.</li>
<li>Pós-Evento: Download do material .pdf disponibilizado na apostila</li>
<li>Oportunidade de dirimir dúvidas, pós evento, com o Especialista, via email, referente ao conteúdo apresentado.</li>
</ul>
<p><strong>Importante:</strong></p>
<ul>
</ul>
<ul>
<li>O prêmio é intransferível</li>
<li>É necessário que o contemplado seja seguidor do @web2pybrasil e @treventos no twitter</li>
<li>A realização do treinamento está vinculada a um quórum mínimo de participantes, considerando que não haja este quórum, a pessoa que ganhar o sorteio será notificada sobre a nova data da realização da atividade com pelo menos 15 dias de antecedência para que possa se agendar.</li>
</ul>
<p>Boa Sorte!</p>
<ul>
</ul>
<ul>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.profissionaisti.com.br/2010/08/concorra-a-uma-vaga-para-o-treinamento-de-desenvolvimento-web-com-python-em-sp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

