<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Rot-13</title>
	<atom:link href="https://ivnaan.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://ivnaan.wordpress.com</link>
	<description>____________</description>
	<lastBuildDate>Mon, 13 Feb 2023 20:49:54 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<site xmlns="com-wordpress:feed-additions:1">9376208</site><cloud domain='ivnaan.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>https://s0.wp.com/i/buttonw-com.png</url>
		<title>Rot-13</title>
		<link>https://ivnaan.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="https://ivnaan.wordpress.com/osd.xml" title="Rot-13" />
	<atom:link rel='hub' href='https://ivnaan.wordpress.com/?pushpress=hub'/>
	<item>
		<title>Match ain&#8217;t Switch</title>
		<link>https://ivnaan.wordpress.com/2023/02/13/match-aint-switch/</link>
					<comments>https://ivnaan.wordpress.com/2023/02/13/match-aint-switch/#respond</comments>
		
		<dc:creator><![CDATA[João Bernardo]]></dc:creator>
		<pubDate>Mon, 13 Feb 2023 20:48:30 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">http://ivnaan.wordpress.com/?p=716</guid>

					<description><![CDATA[A foolish consistency is the hobgoblin of little minds&#8211; Emerson O Python 3.10 lançado em 2021 conta com uma nova declaração chamada match que, à primeira vista, parece visualmente bastante com um switch que a gente conhece do C, inclusive utilizando a palavra case para processar as opções, além do fato do C também não [&#038;hellip]]></description>
										<content:encoded><![CDATA[
<p><em>A foolish consistency is the hobgoblin of little minds</em><br>&#8211; Emerson<br><br>O Python 3.10 lançado em 2021 conta com uma nova declaração chamada <code>match</code> que, à primeira vista, parece visualmente bastante com um <code>switch</code> que a gente conhece do C, inclusive utilizando a palavra <code>case</code> para processar as opções, além do fato do C também não utilizar { e } na maioria dos cases.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
match coisa:
    case "A": 
        print("Muito bom")
    case "B":
        print("Tá ok")
    case "C":
        print("Não gostei")
    case "D":
        print("Péssimo")
</pre></div>


<p>Eu diria que as semelhanças param por aqui. Em C você permite o compilador otimizar a busca usando table lookup para as posições de memória de cada case e ele executa até achar um <code>break;</code>, mesmo que isso signifique entrar no case seguinte.</p>



<p>Em Python, o match executa cada case sequencialmente e verifica se ele bate com o objeto de entrada e executa somente aquele bloco. O problemas é que ele usa uma sintaxe que parece Python, mas não é válida em outros locais para executar esse match. </p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
match coisa:
    case x, y:
        print(f"coisa {x} e coisa {y}")
    case x:
        print(f"somente uma coisa {x}")
</pre></div>


<p>Acima foram introduzidas variáveis <code>x</code> e <code>y</code> nos cases do match. Elas não existem fora dos blocos em que executa. O interpretador desconstrói <code>case x, y</code> em algo como<code>:</code></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
if isinstance(coisa, (list, tuple)) and len(coisa) == 2:
    x, y = coisa.
</pre></div>


<p>Se essa condição é válida, ele faz um tuple-unpacking e cria as variáveis x e y dentro daquele bloco.</p>



<p>Como se fosse uma regex para estruturas de dados.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
coisa = '(a, b)'
re.match(r'\((\w+),\s*(\w+)\)', coisa).groups() == ('a', 'b')
</pre></div>


<p>Se você começar a ver todas as regras de casamento de expressões vai ver que complicaram bastante algo que antes você fazia com if-elif-else e acho bem difícil que isso seja utilizado pra algo além de verificar elementos numa lista ou no máximo chaves num dicionário.</p>



<p>Dentro das expressões, você tem valores literais, que são validados por igualdade exceto True, False e None que são por identidade e também nomes. Então se você misturar os dois, ele valida uma parte por igualdade e assinala valores aos nomes. Por fim existe um nome coringa que é o underscore (_) onde ele não assinala valor e este pode ser repetido na regra para delimitar tamanho das estruturas, sem se importar com o conteúdo. Também é utilizado para substituir o caso <code>default</code> existente no switch do C, sendo que você pode na verdade escolher qualquer nome.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
match coisa:
    case "selecionar", cor, _:
        print("Lista de 3 elementos: o último não interessa") 
    case {"ação": "selecionar", "cor": cor,  "outro": _}:
        print("Basicamente o mesmo, mas dentro de um dicionário.")
        print("O 'outro' não me importa, mas precisa existir")
    case _:
        print("Todo o resto")
</pre></div>


<p>Agora onde a cobra começa a fumar.<br><br>Em C, para ter múltiplas opções executando um mesmo códido, você iria escrever:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: cpp; title: ; notranslate">
switch (valores) {
    case 1:
    case 2:
        printf("coisa 1 ou 2");
        break;
    case 3:
        printf("coisa 3");
        break;
}
</pre></div>


<p>Em Python você usa uma barra vertical como <code>case 1 | 2:</code>.<br>Isso é inconsistente com o <code>or</code> lógico que é escrito por extenso e confunde on o <code>bitwise or</code> que usa esse mesmo operador tanto em Python como em C.</p>



<p>A partir daí, você pode fazer uma lambança de misturar estruturas, com &#8220;or&#8221; dentro e fora, com e sem parêntesis, além de capturar qualquer elemento específico dentro de qualquer parte da estrutura. Você pode repetir nomes de variáveis caso elas estejam em lados diferentes de um &#8220;or&#8221;. Também é possível usar asteriscos para capturar sub listas, também conhecido como starred assigned em Python normal.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
match coisa:
    case &#91;1, *x] | &#91;*x, 2]:
        print(x)
</pre></div>


<p>Este exemplo acima gera as seguintes instruções para a máquina virtual do Python (VM).<br></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
              2 LOAD_FAST                   0 (coisa)
  7           4 COPY                              1
              6 MATCH_SEQUENCE
  8 POP_JUMP_FORWARD_IF_FALSE    13 (to 36)
             10 GET_LEN
             12 LOAD_CONST               1 (1)
             14 COMPARE_OP               5 (&gt;=)
             20 POP_JUMP_FORWARD_IF_FALSE     7 (to 36)
             22 UNPACK_EX                1
             24 LOAD_CONST               1 (1)
             26 COMPARE_OP               2 (==)
             32 POP_JUMP_FORWARD_IF_FALSE     1 (to 36)
             34 JUMP_FORWARD            23 (to 82)
        &gt;&gt;   36 POP_TOP
             38 COPY                     1
             40 MATCH_SEQUENCE
             42 POP_JUMP_FORWARD_IF_FALSE    15 (to 74)
             44 GET_LEN
             46 LOAD_CONST               1 (1)
             48 COMPARE_OP               5 (&gt;=)
             54 POP_JUMP_FORWARD_IF_FALSE     9 (to 74)
             56 EXTENDED_ARG             1
             58 UNPACK_EX              256
             60 SWAP                     2
             62 LOAD_CONST               2 (2)
             64 COMPARE_OP               2 (==)
             70 POP_JUMP_FORWARD_IF_FALSE     1 (to 74)
72 JUMP_FORWARD             4 (to 82)
        &gt;&gt;   74 POP_TOP
             76 POP_TOP
             78 LOAD_CONST               0 (None)
             80 RETURN_VALUE
        &gt;&gt;   82 STORE_FAST               1 (x)
             84 POP_TOP
</pre></div>


<p>As instruções de 6 até 26 (coluna da esquerda) calculam a primeira metade da expressão do case, onde ele verifica que o objeto é uma sequência (list, tuple etc), pega o tamanho e vê se é maior ou igual a 1, faz um unpack da lista na pilha do interpretador retirando o primeiro elemento do resto, compara esse elemento com o valor 1 e salva o resto da lista na variável x (instrução 82).</p>



<p>A segunda parte são as instruções de 40 a 72, onde faz a mesmas verificações de sequência e seu tamanho, faz um unpack dessa vez pegando o último elemento (0x0100 == 256 significa 1 elemento no final, oposto de 0x0001 que significa 1 elemento no início) da lista e comparando este com o número 2. Novamente salva o resto na variável x (na mesma instrução 82).</p>



<p>Podemos ver que o interpretador trata cada parte do &#8220;or&#8221; como sua própria expressão e a única garantia é que ele obriga todas as partes a capturarem os mesmos nomes de variável. </p>



<p>Ao meu ver isso tudo são modificações talvez desnecessárias da linguagem para criar algo que se parece com Python (familiaridade), mas funciona de forma diferente o suficiente para encucar mesmo os macacos velhos, ou talvez só esses mesmo. Isso lembra bastante o <em>modus operandi</em> do Ruby, onde a linguagem dá acesso a tantas transformações na execução que você pode escrever DSLs que nada se parecem com Ruby, mas as vezes presas a problemas inerentes da linguagem.</p>



<p>Podemos lembrar que essa não é a primeira vez que Python cria artefatos que imitam parte da sintaxe.</p>



<ol class="wp-block-list">
<li>Ellipsis. Em Python 2 só era possível utilizar as reticências dentro de um índice de lista/array, como <code>minha_array[1,...]</code> simbolizando que qualquer coisa, como uma dimensão extra, deve ser retornada além do índice 1. Comum em NumPy, por exemplo. No Python 3, foi criado um objeto <code>"..."</code> que traduz para um singleton a fim de acabar com essas inconsistências e também permitir você utilizar em outros locais com ideias similares.</li>



<li>Quando foi criada a sintaxe <code>format</code> de interpolação de strings, no Python 2.6 e 3.0, você era obrigado a enumerar as variáveis ou passar por nome, também havia limitação de indexar variáveis dentro da formatação onde qualquer texto era tratado como string, mas números eram convertidos pra inteiro. <code>"text: {0[foo]}".format({"foo": "bar"}</code>)<br>Isso foi posteriormente removido nas f-strings que, à primeira vista, parecem ser a mesma coisa, mas estas quebram a string em substrings e executam o texto dentro dos colchetes como código Python antes de converter para string. Dicionários também não era possíveis de se definir pelo reuso dos colchetes.</li>



<li>Ainda na formatação de strings, as f-strings mudam a sintaxe no caso acima, mas ainda mantém a sub sintaxe de formatação, tipo `f'{x:.2f}&#8221; que mostra um float só até 2 casas decimais, além de permitir a formatação obscura de <code>f'{x!r}</code> onde &#8220;!r&#8221; converte a string para sua representação, que contém aspas. Isso foi criado na era anterior pela limitação de que você podia colocar variáveis na string, mas não podia fazer operações. Com essa nova possibilidade, você não precisa necessariamente mais disso, apesar de ser prático.</li>



<li>As f-strings, agora processadas pelo interpretador e não mais analisadas em tempo de execução, em teoria seriam uma cópia fiel do Python, mas por problemas de gramática, elas ainda diferem do original por não permitir a contra-barra <code>\</code> para escapar caracteres dentro dos blocos de código. Dicionários podem ser colocados dentro dos blocos de variáveis, mas existe ambiguidade (exemplo: <code>f'{{3:{1:2}}}' == '{3: 1}'</code>) &#8212; De qualquer forma, vimos que existiu convergência dela nas suas várias iterações.</li>



<li>Um outro momento em que Python criou sintaxe específica para um sub conjunto da linguagem, tentando fingir que era a mesma foi dentro dos argumentos de uma função, na hora da definição. Durante certo tempo havia limitação entre o que você podia escrever com asterisco para fazer star unpacking e posição dos argumentos. Mesmo com a capacidade de ter argumentos keyword-only, os problemas trazidos do Python 2 ainda enrijeciam a interface. Mesmo depois da remoção de tuple unpacking dentro dos argumentos. Exemplo: <code>def f(x, /, y, *args, z=1, w=2, k, **kw): ...</code></li>
</ol>



<p>Por que eu trouxe esses exemplos especificamente? Na sintaxe de casamento do match, estamos novamente convertendo o que parece ser uma pseudo linguagem para código da mesma VM do Python. </p>



<ol class="wp-block-list">
<li>Por quê o underscore precisa existir se já temos a Ellipsis (<code>...</code>) ou o próprio asterisco sozinho? Menos teclas a clicar?</li>



<li>Por quê o &#8220;or&#8221; usa apenas uma barra vertical que vai contra a política de escrever inglês do Python? Utilizar múltiplos cases, como em C, não seria viável já que você pode colocá-lo dentro de partes da estrutura.</li>



<li>Mais uma vez existe mistura entre sintaxe que define estruturas e que separa partes da sub-sintaxe.</li>



<li>Existe real necessidade de casar certas estruturas com o match? Como por exemplo objetos de classes que não sejam listas e dicionários? Sim tem uma forma de fazer isso no match:</li>
</ol>



<p>No caso de outros objetos, você usa um nome com parêntesis e o interpretador valida se a coisa é objeto de uma classe com aquele nome e verifica se &#8220;os argumentos&#8221; daquela classe batem com valores de atributos do objeto!</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
match coisa:
    case Bagulho(x=1, y=2):
        print(f'{coisa.x} = 1 e {coisa.y} = 2')
</pre></div>


<p>Brutal&#8230; Será que compensa aprender uma nova sintaxe só para fazer `coisa.x == 1 and coisa.y == 2` ?</p>



<p>Vocês querem mais, crianças?</p>



<p>Sim, tem mais. Após cada expressão no case você pode inserir um <code>if alguma coisa</code> que nada mais é que uma expressão normal em Python que valida algo mais que não pode ser expresso apenas pela estrutura. Na documentação, eles chamas essa funcionalidade de &#8220;flag&#8221; para desabilitar um match, mas ao meu ver isso basicamente transforma o case num if-elif-else, que o pessoal do Python dizia ser terminantemente contra, ao implementar a funcionalidade.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate">
match coisa:
    case x, y if x &gt; y:
        ...
    case x, _ if x &lt; 20:
        ...
    case x if len(x) == 100:
        # Seria deselegante escrever (_, _, _, ...) com 100 itens
    case _, if flag:
        ...
</pre></div>


<p>Não vou me repetir aqui, mas outra vez ficou confuso. Pelo menos o if não foi tão massacrado, já que ele existe também nessa posição dentro das list comprehensions. </p>



<p>Espero que um dia o match no Python amadureça para ficar mais conciso com o resto da linguagem e talvez incorporar o <code>if</code> de forma mais elegante, possivelmente como o <a href="https://kotlinlang.org/docs/control-flow.html#when-expression">Kotlin</a> faz na sua expressão <code>when</code>. Até lá, acredito que eu o evite a não ser para usar como um <code>switch</code>.</p>



<p></p>



<p></p>



<p></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://ivnaan.wordpress.com/2023/02/13/match-aint-switch/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">716</post-id>
		<media:content url="https://0.gravatar.com/avatar/964470d348778265033e55b2fc933f931ade7f668d7e371e6eb16b7e6dc4ddcb?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">Vianna</media:title>
		</media:content>
	</item>
		<item>
		<title>Recortando vídeo com FFmpeg</title>
		<link>https://ivnaan.wordpress.com/2013/10/13/recortando-video-com-ffmpeg/</link>
					<comments>https://ivnaan.wordpress.com/2013/10/13/recortando-video-com-ffmpeg/#comments</comments>
		
		<dc:creator><![CDATA[João Bernardo]]></dc:creator>
		<pubDate>Sun, 13 Oct 2013 02:01:35 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[FFmpeg]]></category>
		<category><![CDATA[video]]></category>
		<guid isPermaLink="false">http://ivnaan.wordpress.com/?p=707</guid>

					<description><![CDATA[O FFmpeg é um software bastante completo para trabalhar com vídeo na linha de comando. Aqui coloco um breve tutorial para recortar um vídeo e remover trechos que não são desejados. Por exemplo, em um vídeo de 30 minutos, eu quero os trechos: 0 a 10 minutos, 11 a 16 minutos e 18 minutos até [&#038;hellip]]></description>
										<content:encoded><![CDATA[<p>O <a href="https://ffmpeg.org/" target="_blank">FFmpeg</a> é um software bastante completo para trabalhar com vídeo na linha de comando. Aqui coloco um breve tutorial para recortar um vídeo e remover trechos que não são desejados.</p>
<p>Por exemplo, em um vídeo de 30 minutos, eu quero os trechos: 0 a 10 minutos, 11 a 16 minutos e 18 minutos até o fim. Primeiro, é preciso criar os 3 segmentos, aqui chamados de &#8220;part%02d.mp4&#8221;.</p>
<pre class="brush: bash; title: ; toolbar: false; notranslate">
ffmpeg -i video.mp4 -t 00:10:00 -c copy part01.mp4
ffmpeg -ss 00:11:00 -i video.mp4 -t 00:05:00 -c copy part02.mp4
ffmpeg -ss 00:18:00 -i video.mp4 -c copy part03.mp4
</pre>
<p>Comandos utilizados:<code><br />
-i  ARQUIVO_DE_INPUT<br />
-ss TEMPO_DE_SEEK<br />
-t  DURAÇÃO_DO_SEGMENTO</code></p>
<p>O uso de <code>-c copy</code> faz com que não seja realizada transcodificação do vídeo, mas apenas cópia de arquivo. Entretanto, isso faz com que os cortes não sejam precisos e determinados pelos <em>keyframes</em> do vídeo, ficando possivelmente maiores que o pedido. Se for preciso fazer cortes com precisão, é preciso recodificar o segmento (e mover o comando &#8220;-ss&#8221; para depois do arquivo de input).</p>
<p>Para juntar os pedaços, crie um arquivo de texto, por exemplo &#8220;lista.txt&#8221; com o seguinte conteúdo:</p>
<p><code>file 'part01.mp4'<br />
file 'part02.mp4'<br />
file 'part03.mp4'<br />
</code></p>
<p>Agora é só executar:</p>
<pre class="brush: bash; title: ; toolbar: false; notranslate">
ffmpeg -f concat -i lista.txt -c copy video_final.mp4
</pre>
<p>Funciona com qualquer formato/codec suportado pelo FFmpeg. Se o seu programa não suportar algum dos comandos, provavelmente é uma versão antiga. Utilize 1.0 ou superior.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ivnaan.wordpress.com/2013/10/13/recortando-video-com-ffmpeg/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">707</post-id>
		<media:content url="https://0.gravatar.com/avatar/964470d348778265033e55b2fc933f931ade7f668d7e371e6eb16b7e6dc4ddcb?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">Vianna</media:title>
		</media:content>
	</item>
		<item>
		<title>Criador de Funções com Metaclasses</title>
		<link>https://ivnaan.wordpress.com/2012/07/13/criador-de-funcoes-com-metaclasses/</link>
					<comments>https://ivnaan.wordpress.com/2012/07/13/criador-de-funcoes-com-metaclasses/#respond</comments>
		
		<dc:creator><![CDATA[João Bernardo]]></dc:creator>
		<pubDate>Fri, 13 Jul 2012 08:00:51 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[metaclass]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Python 3]]></category>
		<category><![CDATA[Recursividade]]></category>
		<guid isPermaLink="false">http://ivnaan.wordpress.com/?p=630</guid>

					<description><![CDATA[Esse é um projeto que fiz meses atrás para gerar funções em Python com operadores matemáticos usando metaclasses. Com isso, você pode fazer: O código abaixo é uma versão (muito) simplificada do módulo que coloquei no GitHub, mas serve como exemplo de uso de metaclasses em Python (neste caso, Python 3): Em duas situações é [&#038;hellip]]></description>
										<content:encoded><![CDATA[<p>Esse é um projeto que fiz meses atrás para gerar funções em Python com operadores matemáticos usando metaclasses.<br />
Com isso, você pode fazer:</p>
<pre class="brush: python; title: ; toolbar: false; notranslate">
g = f ** 2 + 1   #função que eleva ao quadrado e soma 1
g(10) == 101
</pre>
<p>O código abaixo é uma versão (muito) simplificada do módulo que coloquei no <a href="https://github.com/jbvsmo/funcbuilder/blob/master/funcbuilder.py" target="_blank">GitHub</a>, mas serve como exemplo de uso de metaclasses em Python (neste caso, Python 3):</p>
<pre class="brush: python; title: ; notranslate">
import operator

class MetaFuncBuilder(type):
    def __init__(self, *args, **kw):
        super().__init__(*args, **kw)
        attr = '__{0}{1}__'

        for op in (x for x in dir(operator) if not x.startswith('__')):
            oper = getattr(operator, op)
            op = op.rstrip('_') #special case for keywords: and_, or_

            def func(self, *n, oper=oper):
                return type(self)(lambda x: oper(self.func(x), *n),
                                  self.op + [(oper.__name__, n[0])
                                             if n else oper.__name__])
            def rfunc(self, n, *, oper=oper):
                return type(self)(lambda x: oper(n, self.func(x)),
                                  self.op + [(n, oper.__name__)])
           
            setattr(self, attr.format('', op), func)
            setattr(self, attr.format('r', op), rfunc)

class FuncBuilder(metaclass=MetaFuncBuilder):
    def __init__(self, func=None, op=None):
        self.op = op if op else []
        self.func = func if func else lambda x: x

    def __repr__(self):
        return '&lt;var %s&gt;' % self.op

    def __call__(self, *args):
        if not args:
            return self.func() #unary operators
        required, *args = args
        out = self.func(required)
        return out(*args) if args else out

f = FuncBuilder()

</pre>
<p>Em duas situações é comum o uso de metaclasses em Python: para que um certa classe tenha propriedades novas ou para automatizar algum mecanismo nas classes. Neste caso, usei para automatizar a criação de métodos para cada operador em Python, com ajuda do módulo <code>operator</code>.</p>
<p>Em Python, os operadores matemáticos binários existem nas formas <code>__op__, __rop__ e __iop__</code>, onde <code>op</code> é o nome, <code>r</code> significa que o objeto é o segundo operador e <code>i</code> significa <em>in-place</em>. Outros operadores existem em apenas uma forma.<br />
Assim, o código pega os operadores e cria as três formas de cada um (os que existem em apenas uma forma ficam com 2 formas extras que não causam problema algum, já que não são nunca chamadas) e todos os operadores, ao invés de executar a operação designada, apenas criam uma novo objeto-função que pode ser chamado ou ter novas funções adicionadas.</p>
<p>O módulo no <a href="https://github.com/jbvsmo/funcbuilder/blob/master/funcbuilder.py" target="_blank">GitHub</a> tem uma centena de outras funcionalidades para gerar essas funções, mas ele sofre de um problema que pode ser bem sério: Chamadas de função em Python são caras!</p>
<p>Basicamente, cada objeto do tipo <code>FuncBuilder</code> guarda a operação que tem que executar e o próximo da lista. Isso gera um monte de chamadas de função em cima dos operadores, o que pode deixar o código muito mais lento.</p>
<p>Minha próxima alteração pra esse código seria juntar todas as operações numa só chamada de função, o que não vai permitir extrair uma função de dentro de outra (como é possível agora por meio de closures), mas vai reduzir o custo para apenas uma chamada de função, como seria natural. Isso não vai ser tão simples por causa dessa estrutura recursiva da classe, mas quando tiver tempo, eu faço.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ivnaan.wordpress.com/2012/07/13/criador-de-funcoes-com-metaclasses/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">630</post-id>
		<media:content url="https://0.gravatar.com/avatar/964470d348778265033e55b2fc933f931ade7f668d7e371e6eb16b7e6dc4ddcb?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">Vianna</media:title>
		</media:content>
	</item>
		<item>
		<title>Otimização 0.1</title>
		<link>https://ivnaan.wordpress.com/2012/06/29/otimizacao-0-1/</link>
					<comments>https://ivnaan.wordpress.com/2012/06/29/otimizacao-0-1/#comments</comments>
		
		<dc:creator><![CDATA[João Bernardo]]></dc:creator>
		<pubDate>Sat, 30 Jun 2012 01:03:51 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[Assembly]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Otimização]]></category>
		<category><![CDATA[Programação]]></category>
		<guid isPermaLink="false">http://ivnaan.wordpress.com/?p=634</guid>

					<description><![CDATA[Achei bem interessante que nesse tempo que fiquei sem escrever, o blog teve uma quantidade de acessos maior que em tempos de atividade. De qualquer forma, um post de vez em quando não faz mal a ninguém :). Tem um site de tirinhas chamado Vida de Programador que posta situações corriqueiras (as vezes) de forma [&#038;hellip]]></description>
										<content:encoded><![CDATA[<p>Achei bem interessante que nesse tempo que fiquei sem escrever, o blog teve uma quantidade de acessos maior que em tempos de atividade. De qualquer forma, um post de vez em quando não faz mal a ninguém :).</p>
<p>Tem um site de tirinhas chamado <a href="http://vidadeprogramador.com.br" title="Vida de Programador | Home" target="_blank">Vida de Programador</a> que posta situações corriqueiras (as vezes) de forma engraçada.</p>
<p>Na tirinha de hoje, ele mostrava o código de um programador iniciante:</p>
<pre class="brush: cpp; title: ; notranslate">
bool isValid;
...
switch(isValid) {
case true: ...
case false: ...
}
</pre>
<p>Claro que não faz sentido tanta verborragia pra algo tão simples como uma variável booleana. No entanto, as pessoas se esquecem que os compiladores atuais são muito bons e não vão deixar seu código lento só porque você preferiu que ele fosse &#8220;mais legível&#8221;.</p>
<p>Uma excelente ferramenta online chamada <a href="http://gcc.godbolt.org/" target="_blank">GCC Explorer</a> mostra a saída assembly do seu compilador preferido com diversos níveis de otimização.</p>
<p>Independente do nível de otimização, o código gerado para o trecho acima será extamente o mesmo que para &#8220;<code>if...else</code>&#8221; ou o operador ternário &#8220;<code>? :</code>&#8220;.</p>
<pre class="brush: cpp; title: ; notranslate">
int testFunction(bool x) {
  switch (x) {
    case true:
        return 10;
        break;
    case false:
        return 12;
  }
}

int testFunction2(bool x) {
  return x? 10 : 12;
}
</pre>
<p>E o Assembly gerado (com -O2) será:</p>
<pre class="brush: perl; title: ; notranslate">
testFunction(bool):
	cmpb	$1, %dil
	sbbl	%eax, %eax
	andl	$2, %eax
	addl	$10, %eax
	ret
testFunction2(bool):
	cmpb	$1, %dil
	sbbl	%eax, %eax
	andl	$2, %eax
	addl	$10, %eax
	ret
</pre>
<p>Se você olhar, não há nenhum jump no assembly gerado. Ele compara a variável com o número 1, subtrai o registro de retorno dele mesmo com borrow, faz um AND com o 2 e depois soma 10. Você não ia pensar que retornar 12 ou 10 significa colocar 2 ou 0 numa variável e depois somar 10, mas o compilador sabe que lógica AND e OR para números inteiros é muito mais rápida que jumps e faz tudo sem que você se preocupe. Esse código seria semelhante a:</p>
<pre class="brush: cpp; title: ; notranslate">
int testFunction3(bool x) {
  return 10 + (2 &amp; -(1-x));
}
</pre>
<p>Mas o GCC consegue diminuir ainda mais o assembly!</p>
<pre class="brush: perl; title: ; notranslate">
testFunction3(bool):
	leal	3(%rdi), %eax
	andl	$2, %eax
	addl	$10, %eax
	ret
</pre>
<p>Só que ninguém vai querer ler um código tão feio assim que apenas poupa 1 nanossegundo.</p>
<p>Sem dar razão à pessoa que fez um switch para um bool, se o código não é o gargalo do seu programa, não há motivo para mudar. Como escreveu Donald Knuth: <a href="http://c2.com/cgi/wiki?PrematureOptimization">otimização prematura é a raiz de todo o mal</a>. </p>
]]></content:encoded>
					
					<wfw:commentRss>https://ivnaan.wordpress.com/2012/06/29/otimizacao-0-1/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">634</post-id>
		<media:content url="https://0.gravatar.com/avatar/964470d348778265033e55b2fc933f931ade7f668d7e371e6eb16b7e6dc4ddcb?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">Vianna</media:title>
		</media:content>
	</item>
		<item>
		<title>Blender 2.60 e Cycles</title>
		<link>https://ivnaan.wordpress.com/2011/11/30/blender-2-60-e-cycles/</link>
					<comments>https://ivnaan.wordpress.com/2011/11/30/blender-2-60-e-cycles/#comments</comments>
		
		<dc:creator><![CDATA[João Bernardo]]></dc:creator>
		<pubDate>Wed, 30 Nov 2011 21:13:55 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[Blender]]></category>
		<category><![CDATA[Cycles]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[Ray Tracer]]></category>
		<guid isPermaLink="false">http://ivnaan.wordpress.com/?p=612</guid>

					<description><![CDATA[Há alguns meses eu ouvi falar do Cycles que é um novo renderizador para o Blender 2.6x (versão &#8220;estável&#8221; do programa depois da grande mudança de interface) e, depois de descobrir que não precisa de uma GPU com CUDA, resolvi testar o seu poder. O Blender ficou muito mais prático com essa interface, mas é [&#038;hellip]]></description>
										<content:encoded><![CDATA[<p>Há alguns meses eu ouvi falar do Cycles que é um novo renderizador para o Blender 2.6x (versão &#8220;estável&#8221; do programa depois da grande mudança de interface) e, depois de descobrir que não precisa de uma GPU com CUDA, resolvi testar o seu poder.</p>
<p>O Blender ficou muito mais prático com essa interface, mas é preciso se acostumar com os novos comandos e a posição dos botões e menus. No site Blender Guru tem uma <a href="http://www.blenderguru.com/wp-content/uploads/Exclusive/Blender_Cheat_Sheet.pdf" title="Blender cheat sheet" target="_blank">cola dos comandos</a> que é bastante completa.</p>
<p>Sobre o Cycles, ele é um Ray tracer de verdade e produz imagens muito mais reais que o renderizador interno (Internal), além de trazer a possibilidade de editar a cena e produzir imagens ao mesmo tempo.</p>
<p>O modo de funcionamento do Cycles é bem diferente do Internal pois ele não divide a imagens em quadrados e renderiza cada um numa thread. Ele gera a imagem inteira de uma vez e vai aprimorando o resultado a cada iteração, o que é um pouco estranho já que a renderização só acaba após o número de passos que for definido.</p>
<p>Em alguns testes que fiz, de 10 a 50 passos, já é razoável para ver o que está acontecendo na imagem (bom para editar em tempo real), mas para uma boa qualidade de imagem são precisos de 1000 a 4000 passos, algo que pode demorar horas, mesmo para uma cena razoavelmente simples (no meu Core i5).</p>
<p>Pode parecer que o Cycles é uma faca de dois gumes, já que permite visualizar o resultado praticamente em tempo real, mas demora pra produzir uma imagem final com pouca granularidade. Na verdade, o Cycles traz ainda mais um diferencial: a possibilidade de renderizar a imagem via GPU com CUDA/OpenCL, o que pode ter um ganho alto de desempenho, além de deixar a CPU livre para outras tarefas. Pena que minha placa de vídeo é bem ruim (a Intel não aprende mesmo&#8230;) e não serve para o propósito.</p>
<p>Abaixo um vídeo do Cycles em ação:<br />
<iframe class="youtube-player" width="420" height="315" src="https://www.youtube.com/embed/8bDaRXvXG0E?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=pt-br&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe></p>
<p>De cara dá pra perceber que a qualidade de imagem é muito maior que se fosse renderizado com o Internal, principalmente quando se pensa em iluminação. Antigamente, você precisaria colocar umas 3 lâmpadas, no mínimo, e fazer centenas de ajustes para conseguir um efeito legal. Agora você pode adicionar apenas um objeto com o material &#8220;Emission&#8221; e você tem uma fonte de luz que reflete nas superfícies e produz um efeito muito bom.</p>
<p>Outra coisa que sempre foi praticamente impossível de fazer direito no Blender é vidro ou qualquer coisa transparente. No Cycles, ao escolher o material Glass, você tem de cara um vidro de alta qualidade sem precisar fazer qualquer ajuste. Para outros materiais, basta ajustar o índice de refração (IOR) para o valor real do mesmo.</p>
<p>Em cinco minutos coloquei 3 planos, um cubo e um chimpanzé (Suzanne + subsurf) numa cena iluminada por outros dois planos e modifiquei os materiais. Depois de meia hora renderizando em torno de 1000 passos, fiquei com uma imagem que demoraria horas para ajustar a iluminação e ter um efeito parecido.</p>
<p><a href="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/untitled.png"><img data-attachment-id="613" data-permalink="https://ivnaan.wordpress.com/2011/11/30/blender-2-60-e-cycles/untitled/" data-orig-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/untitled.png" data-orig-size="960,540" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="untitled" data-image-description="" data-image-caption="" data-medium-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/untitled.png?w=300" data-large-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/untitled.png?w=510" src="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/untitled.png" alt="" title="untitled" width="510" height="286" class="aligncenter size-full wp-image-613" srcset="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/untitled.png?w=510&amp;h=287 510w, https://ivnaan.wordpress.com/wp-content/uploads/2011/11/untitled.png?w=150&amp;h=84 150w, https://ivnaan.wordpress.com/wp-content/uploads/2011/11/untitled.png?w=300&amp;h=169 300w, https://ivnaan.wordpress.com/wp-content/uploads/2011/11/untitled.png?w=768&amp;h=432 768w, https://ivnaan.wordpress.com/wp-content/uploads/2011/11/untitled.png 960w" sizes="(max-width: 510px) 100vw, 510px" /></a></p>
<p>Não é nenhuma obra de arte, mas mostra como é fácil ter efeitos interessantes sem perder muito tempo.</p>
<p>A única diferença entre o uso do Blender Internal e o Cycles é a janela de edição de materiais que, por enquanto, é um pouco pobre em usabilidade e obriga o uso de Composite Nodes para coisas não básicas. De qualquer forma, não deixa de ser algo bom pois o uso do Node editor não é complicado e acaba sendo prático.</p>
<p><a href="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/nodeed.png"><img data-attachment-id="618" data-permalink="https://ivnaan.wordpress.com/2011/11/30/blender-2-60-e-cycles/nodeed/" data-orig-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/nodeed.png" data-orig-size="511,277" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="nodeed" data-image-description="" data-image-caption="" data-medium-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/nodeed.png?w=300" data-large-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/nodeed.png?w=510" src="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/nodeed.png" alt="" title="nodeed" width="510" height="276" class="aligncenter size-full wp-image-618" srcset="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/nodeed.png?w=510&amp;h=276 510w, https://ivnaan.wordpress.com/wp-content/uploads/2011/11/nodeed.png?w=150&amp;h=81 150w, https://ivnaan.wordpress.com/wp-content/uploads/2011/11/nodeed.png?w=300&amp;h=163 300w, https://ivnaan.wordpress.com/wp-content/uploads/2011/11/nodeed.png 511w" sizes="(max-width: 510px) 100vw, 510px" /></a></p>
<p>Uma coisa que senti falta é a pré-visualização do material, mas com a renderização em tempo quase real, acaba não sendo tão ruim.</p>
<p>Como o Cycles ainda não está oficialmente incorporado ao Blender, é preciso pegar um build que tenha sido feito recentemente no SVN do projeto para poder usar. No site <a href="http://graphicall.org/" title="Graphic All" target="_blank">GraphicAll.org</a> tem vários e só precisa escolher o sistema operacional e arquitetura.</p>
<p>De acordo com o roadmap do Blender, o Cycles deve chegar no Blender 2.61 em dezembro.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ivnaan.wordpress.com/2011/11/30/blender-2-60-e-cycles/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">612</post-id>
		<media:content url="https://0.gravatar.com/avatar/964470d348778265033e55b2fc933f931ade7f668d7e371e6eb16b7e6dc4ddcb?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">Vianna</media:title>
		</media:content>

		<media:content url="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/untitled.png" medium="image">
			<media:title type="html">untitled</media:title>
		</media:content>

		<media:content url="https://ivnaan.wordpress.com/wp-content/uploads/2011/11/nodeed.png" medium="image">
			<media:title type="html">nodeed</media:title>
		</media:content>
	</item>
		<item>
		<title>Recuperando dados de partições Ext3 e Ext4</title>
		<link>https://ivnaan.wordpress.com/2011/11/21/recuperando-dados-de-particoes-ext3-e-ext4/</link>
					<comments>https://ivnaan.wordpress.com/2011/11/21/recuperando-dados-de-particoes-ext3-e-ext4/#respond</comments>
		
		<dc:creator><![CDATA[João Bernardo]]></dc:creator>
		<pubDate>Mon, 21 Nov 2011 22:08:40 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[ext3]]></category>
		<category><![CDATA[ext4]]></category>
		<category><![CDATA[extundelete]]></category>
		<category><![CDATA[recuperar]]></category>
		<category><![CDATA[sistema de arquivos]]></category>
		<guid isPermaLink="false">http://ivnaan.wordpress.com/?p=601</guid>

					<description><![CDATA[Nessa semana tive que recuperar um arquivo deletado acidentalmente num servidor rodando CentOS com sistema de arquivos Ext4. A fração de segundo depois que você aperta Enter e percebe seu erro, mas é tarde demais, você acabou de excluir um arquivo ou diretório valioso e não existia nenhum backup. Ou talvez você tinha um backup, [&#038;hellip]]></description>
										<content:encoded><![CDATA[<p>Nessa semana tive que recuperar um arquivo deletado acidentalmente num servidor rodando CentOS com sistema de arquivos Ext4.</p>
<blockquote><p>A fração de segundo depois que você aperta Enter e percebe seu erro, mas é tarde demais, você acabou de excluir um arquivo ou diretório valioso e não existia nenhum backup. Ou talvez você tinha um backup, mas é de um mês atrás&#8230;<br />
E em estado de choque que você vê num flash o último mês passar diante de seus olhos e percebe a dor que vai dar para fazer tudo de novo&#8230;<br />
<a href="http://carlo17.home.xs4all.nl/howto/undelete_ext3.html" title="Undelete Ext3" target="_blank">Carlo Wood</a></p></blockquote>
<p>Recuperar dados de partições Ext3 e 4 é bastante complicado, como explicado com muitos detalhes <a href="http://carlo17.home.xs4all.nl/howto/undelete_ext3.html" title="Undelete Ext3" target="_blank">neste link</a>.</p>
<p>A primeira coisa a fazer é desmontar a partição afetada ou, se não for possível, desligar o computador e usar um LiveCD de alguma distribuição Linux (usei Ubuntu num pendrive) ou colocar o HD dentro de outra máquina.</p>
<p>Para resolver o problema, eu testei sem sucesso duas ferramentas (foremost e scalpel) que fazem análise sequencial dos blocos do HD procurando por padrões conhecidos, algo que demorou uma eternidade para verificar toda a partição de 1TB que eu tinha e &#8220;recuperou&#8221; centenas de arquivos corrompidos com nomes do tipo &#8220;100201234.jpg&#8221; e nada do que eu queria.</p>
<p>Talvez o fato da minha partição ser <a href="http://en.wikipedia.org/wiki/Logical_Volume_Manager_%28Linux%29" title="Logical Volume Manager" target="_blank">LVM</a> e a real partição Ext4 estivesse dentro do volume lógico os programas não funcionaram, mas de qualquer forma existe uma solução melhor.</p>
<p>Uma ferramenta chamada <a href="http://extundelete.sourceforge.net/" title="Extundelete" target="_blank">Extundelete</a> foi quem salvou meu dia. Ela acessa o journal do sistema de arquivos e consegue achar novamente os arquivos com os nomes originais e, no meu caso, até manteve a estrutura de diretórios de onde estava o arquivo.</p>
<p>Pra usar, instale o &#8220;Extundelete&#8221; pelo gerenciador de pacotes da distribuição usada (para Ubuntu):<br />
<code># apt-get install extundelete</code></p>
<p>ou pegue o código fonte do site e compile com<br />
<code># ./configure<br />
# make<br />
# make install</code></p>
<p>Para executar, é preciso passar a partição a ser usada para que o programa monte em modo <em>read only</em> (se for LVM, como no meu caso, vai ser necessário seguir <a href="http://quonn.wordpress.com/2010/12/01/how-to-mount-lvm-partition-on-ubuntu/" title="Montar LVM" target="_blank">mais alguns passos</a>).<br />
<code># extundelete /dev/nome_da_particao --restore-all</code></p>
<p>Em menos de um minuto, o comando acima restaurou centenas de arquivos, incluindo o que eu queria.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ivnaan.wordpress.com/2011/11/21/recuperando-dados-de-particoes-ext3-e-ext4/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">601</post-id>
		<media:content url="https://0.gravatar.com/avatar/964470d348778265033e55b2fc933f931ade7f668d7e371e6eb16b7e6dc4ddcb?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">Vianna</media:title>
		</media:content>
	</item>
		<item>
		<title>Escolhendo o canal do Wi-Fi</title>
		<link>https://ivnaan.wordpress.com/2011/10/11/escolhendo-o-canal-do-wi-fi/</link>
					<comments>https://ivnaan.wordpress.com/2011/10/11/escolhendo-o-canal-do-wi-fi/#comments</comments>
		
		<dc:creator><![CDATA[João Bernardo]]></dc:creator>
		<pubDate>Tue, 11 Oct 2011 21:30:06 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[wireless]]></category>
		<guid isPermaLink="false">http://ivnaan.wordpress.com/?p=589</guid>

					<description><![CDATA[Algo muito comum é instalar um roteador Wi-Fi num ambiente pequeno e, ainda assim, ter problemas com a velocidade da conexão. Pode acontecer de existirem vários outros roteadores de vizinhos usando o mesmo canal e possivelmente com um sinal mais forte (aquele povo que compra antenas enormes na Uruguaiana ou Santa Ifigênia) estarem fazendo a [&#038;hellip]]></description>
										<content:encoded><![CDATA[<p>Algo muito comum é instalar um roteador Wi-Fi num ambiente pequeno e, ainda assim, ter problemas com a velocidade da conexão.</p>
<p>Pode acontecer de existirem vários outros roteadores de vizinhos usando o mesmo canal e possivelmente com um sinal mais forte (aquele povo que compra antenas enormes na Uruguaiana ou Santa Ifigênia) estarem fazendo a sua placa wireless perder muitos pacotes.</p>
<p>Todo roteador Wi-Fi vem com uma página de configuração que permite escolher o canal da faixa de 2.4GHz em que vai operar.<br />
Caso não se lembre como acessar ou se não foi você quem instalou, provavelmente olhando qual o gateway da sua máquina você acha o IP do roteador (algo como 192.168.0.1).</p>
<p>Na hora de escolher o canal ideal para sua conexão, é preciso saber que parte da banda os roteadores mais próximos estão localizados e, para isso, existe um excelente aplicativo gratuito chamado <a href="http://www.metageek.net/support/downloads/" target="_blank">InSSIDer</a> que fornece informações bem detalhadas.</p>
<p><a href="https://ivnaan.wordpress.com/wp-content/uploads/2011/10/wifi.png"><img data-attachment-id="590" data-permalink="https://ivnaan.wordpress.com/2011/10/11/escolhendo-o-canal-do-wi-fi/wifi/" data-orig-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/10/wifi.png" data-orig-size="527,355" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="wifi" data-image-description="" data-image-caption="" data-medium-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/10/wifi.png?w=300" data-large-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/10/wifi.png?w=510" src="https://ivnaan.wordpress.com/wp-content/uploads/2011/10/wifi.png" alt="" title="wifi" width="510" height="343" class="aligncenter size-full wp-image-590" srcset="https://ivnaan.wordpress.com/wp-content/uploads/2011/10/wifi.png?w=510&amp;h=344 510w, https://ivnaan.wordpress.com/wp-content/uploads/2011/10/wifi.png?w=150&amp;h=101 150w, https://ivnaan.wordpress.com/wp-content/uploads/2011/10/wifi.png?w=300&amp;h=202 300w, https://ivnaan.wordpress.com/wp-content/uploads/2011/10/wifi.png 527w" sizes="(max-width: 510px) 100vw, 510px" /></a></p>
<p>Em uma das abas do programa, ele mostra os canais das redes ao alcance, assim como suas intensidades. Ele também mostra a intensidade ao longo do tempo além de outras informações como fabricante, velocidade da rede, largura do canal etc.</p>
<p>Assim, é fácil escolher o canal do seu Wi-Fi apenas verificando qual está menos utilizado (geralmente as extremidades).</p>
<p>Outra coisa é, se você tem um Wi-Fi 802.11n de 300mpbs (bastante comum nos roteadores de 2011) ele pode ocupar o dobro da banda no espectro por utilizar 2 canais, o que melhora a qualidade geral da sua internet, mas causa mais interferência na dos outros :).</p>
<p>Esse é um programa que vale a pena ter instalado.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ivnaan.wordpress.com/2011/10/11/escolhendo-o-canal-do-wi-fi/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">589</post-id>
		<media:content url="https://0.gravatar.com/avatar/964470d348778265033e55b2fc933f931ade7f668d7e371e6eb16b7e6dc4ddcb?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">Vianna</media:title>
		</media:content>

		<media:content url="https://ivnaan.wordpress.com/wp-content/uploads/2011/10/wifi.png" medium="image">
			<media:title type="html">wifi</media:title>
		</media:content>
	</item>
		<item>
		<title>Python 3 &#8211; exec e outras mudanças</title>
		<link>https://ivnaan.wordpress.com/2011/10/06/python-3-exec-e-outras-mudancas/</link>
					<comments>https://ivnaan.wordpress.com/2011/10/06/python-3-exec-e-outras-mudancas/#comments</comments>
		
		<dc:creator><![CDATA[João Bernardo]]></dc:creator>
		<pubDate>Thu, 06 Oct 2011 18:59:31 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[exec]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Python 3]]></category>
		<guid isPermaLink="false">http://ivnaan.wordpress.com/?p=572</guid>

					<description><![CDATA[Já tem um tempo que tento usar somente Python 3 para meus projetos em Python, mas, como muita gente ainda está presa em versões antigas (como o pessoal do CentOS que há um mês mudou do Python 2.4 para o ainda defasado 2.6), sou obrigado a trabalhar com os dois ambientes. Portar pequenos programas de [&#038;hellip]]></description>
										<content:encoded><![CDATA[<p>Já tem um tempo que tento usar somente Python 3 para meus projetos em Python, mas, como muita gente ainda está presa em versões antigas (como o pessoal do CentOS que há um mês mudou do Python 2.4 para o ainda defasado 2.6), sou obrigado a trabalhar com os dois ambientes.</p>
<p>Portar pequenos programas de uma versão para outra pode ser bastante simples (como no <a href="http://txt2tags.org/" target="_blank">Txt2Tags</a> que precisei de umas 2 ou 3hs para fazer funcionar) quando já se conhece os possíveis problemas e suas soluções, mas nem tudo está bem documentado.</p>
<p>Claro que tudo isso seria muito mais difícil se não houvesse script chamado <code><a href="http://docs.python.org/library/2to3.html" target="_blank">2to3.py</a></code> que vem junto com as versões mais novas do interpretador para automatizar o processo. O problema que existem coisas que ele é incapaz de traduzir ou que precisam de mudanças mais bruscas no código para que funcionem.</p>
<p><del datetime="2011-12-07T16:45:19+00:00">Por algum motivo, o site &#8220;<a href="http://diveintopython3.org" target="_blank">Dive into Python 3</a>&#8221; que tinha uma versão online do <a href="http://www.amazon.com/Dive-Into-Python-Books-Professionals/dp/1430224150" target="_blank">livro homônimo</a> foi removido do ar e perdi a melhor referência para o tópico que existia</del>, ** Encontrei um novo mirror do <a href="http://www.getpython3.com/diveintopython3/" title="Dive into Python 3">Dive into Python 3</a> **</p>
<p>Também existem <a href="http://wiki.python.org/moin/PortingPythonToPy3k">outros</a> <a href="http://docs.python.org/dev/howto/pyporting.html">bons</a> <a href="http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/" target="_blank">textos</a> por ai.</p>
<p>Algumas das <a href="http://docs.python.org/release/3.0.1/whatsnew/3.0.html">mudanças</a> mais importantes na nova versão são os iteradores usados em lugares que antes retornavam listas, o uso de unicode por padrão (que na minha opinião já vale por todo o trabalho de portar código) e a troca de algumas palavras-chaves (statements) por funções e vice-versa.</p>
<p>Sobre essa última mudança, as palavras-chave tem o poder de mudar o local em que se encontram enquanto outros nomes podem significar qualquer coisa que o programador queira e só podem ser verificados em tempo de execução, não podendo transformar o ambiente.</p>
<p>Por exemplo, o comando <code>yield</code> faz com que o a função que o contenha seja transformada num <a href="http://wiki.python.org/moin/Generators">gerador</a> mesmo que ele nunca seja executado ou tenha bytecode para isso!</p>
<pre class="brush: python; title: ; notranslate">
def gerador():
    if 0:
        yield
</pre>
<p>Neste código acima, o interpretador vai ver que o <code>if</code> nunca será executado e não vai gerar bytecode para nada dentro dele (no caso o yield), mas a função não vai retornar o implícito None quando for chamada. Ela vai retornar um gerador vazio que pode ser usado num <code>loop for</code>.</p>
<p>Usando o módulo <code>dis</code> para desmontar bytecode vemos que a função só retorna None, mas ela vai ter um flag para mostrar sua utilidade:</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; dis.dis(gerador)
  2           0 LOAD_CONST               0 (None)
              3 RETURN_VALUE
</pre>
<p>Ainda sobre isso, <code>True</code>, <code>False</code> e <code>None</code> agora são palavras reservadas e que não podem ser modificadas, fazendo com que, se o exemplo acima fosse feito com <code>False</code> ao invés de <code>0</code>, ele geraria bytecode no Python 2, mas não no Python 3!</p>
<p>No sentido contrário, as palavras-chave <code>print</code> e <code>exec</code> do Python 2 agora são funções e não podem mais alterar seu ambiente.</p>
<p>No caso do <code>print</code>, não tem problema algum e a sintaxe ficou bem melhor, mas o <code>exec</code> (que normalmente seu uso não é uma boa prática de programação) pode ter um comportamento bem diferente nas duas versões do interpretador.</p>
<p>Essa informação não vai ser encontrada na documentação do Python (apenas <a href="http://docs.python.org/dev/library/functions.html#exec" target="_blank">alguns avisos</a> que não explicam bem a situação) e geralmente a pessoa vai procurar saber disso quando bater de cara com esse problema e nada funcionar.</p>
<p>Olhe o código abaixo (Não tome como exemplo de boa programação):</p>
<pre class="brush: python; title: ; notranslate">
a = 1
def f():
    exec(&quot;a = 2&quot;)
    print(a)

f()
print(a)
</pre>
<p>No Python 2, a função vai imprimir &#8220;2&#8221; e o outro print vai imprimir &#8220;1&#8221;, como esperado. No Python 3, o número &#8220;1&#8221; vai ser impresso nos dois casos.</p>
<p>O que aconteceu?</p>
<p>O meu amigo <code>dis</code> mostra como a variável &#8220;<code>a</code>&#8221; é chamada no bytecode para impressão dentro da função:</p>
<p>Python 2:</p>
<pre class="brush: python; title: ; notranslate">
3            8 LOAD_NAME                0 (a)
</pre>
<p>Python 3:</p>
<pre class="brush: python; title: ; notranslate">
3           13 LOAD_GLOBAL              2 (a)
</pre>
<p>Como o Python 3 não consegue ver nenhum <code>a</code> dentro da função, ele assume que é uma palavra definida globalmente e vai embora. No Python 2, é percebida a existência da palavra <code>exec</code> e transforma a busca por um nome sendo primeiro no namespace local e, se não encontrar, no namespace global.</p>
<p>O que, por um lado traz o resultado &#8220;desejado&#8221;, também faz todos os acessos a funções e variáveis serem mais lento.</p>
<p>Soluções:<br />
 1 &#8211; Não usar <code>exec</code>.</p>
<p>Praticamente sempre é possível fazer uma solução sem <code>exec</code> que seja simples, mas se for necessário, é preciso tomar cuidado com essa mudança ou passar um segundo parâmetro para a função dizendo em que namespace você quer se o resultado seja avaliado e usar a informação nele.</p>
<p>Normalmente, ninguém usa <code>exec</code> para situações como a que eu mostrei, mas para gerar conteúdo (funções, classes, subclasses, etc) em tempo de execução e muitas vezes existem ferramentas melhores, como as <a href="http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python/6581949#6581949" title="Excelente texto sobre metaclasses" target="_blank">metaclasses</a> e os <a href="http://stackoverflow.com/questions/739654/understanding-python-decorators/1594484#1594484" title="Melhor texto sobre decoradores que se pode encotrar" target="_blank">decoradores</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ivnaan.wordpress.com/2011/10/06/python-3-exec-e-outras-mudancas/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">572</post-id>
		<media:content url="https://0.gravatar.com/avatar/964470d348778265033e55b2fc933f931ade7f668d7e371e6eb16b7e6dc4ddcb?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">Vianna</media:title>
		</media:content>
	</item>
		<item>
		<title>ZZ no Python</title>
		<link>https://ivnaan.wordpress.com/2011/05/09/zz-no-python/</link>
					<comments>https://ivnaan.wordpress.com/2011/05/09/zz-no-python/#comments</comments>
		
		<dc:creator><![CDATA[João Bernardo]]></dc:creator>
		<pubDate>Mon, 09 May 2011 21:19:37 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[Funções ZZ]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[zz]]></category>
		<guid isPermaLink="false">http://ivnaan.wordpress.com/?p=561</guid>

					<description><![CDATA[Pra quem não conhece, existe um conjunto de mini-programas para shell muito legal chamado Funções ZZ, criado pelo Aurélio Jargas (@oreio). [Atualizado!] &#8211; Veja as novas funcionalidades no fim Não sei se alguém já fez, mas criei um wrapper para essas funções em python, para os que já tem o ícone do Python no desktop [&#038;hellip]]></description>
										<content:encoded><![CDATA[<p>Pra quem não conhece, existe um conjunto de mini-programas para shell muito legal chamado <a href="http://funcoeszz.net/" target="_blank">Funções ZZ</a>, criado pelo Aurélio Jargas (@<a href="http://twitter.com/#!/oreio" target="_blank">oreio</a>).</p>
<p><strong>[Atualizado!]</strong> &#8211; Veja as novas funcionalidades no fim</p>
<p>Não sei se alguém já fez, mas criei um wrapper para essas funções em python, para os que já tem o ícone do Python no desktop e não querem abrir um terminal :).</p>
<p>Disponível em <a href="http://dl.dropbox.com/u/6016495/zz.py" target="_blank">http://dl.dropbox.com/u/6016495/zz.py</a>. Funciona tanto em Python 2 como em Python 3.</p>
<p>Exemplos:</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; import zz
&gt;&gt;&gt; int(zz.calcula('19+23'))
42
&gt;&gt;&gt; zz.senha()
'k23Civ'
&gt;&gt;&gt; zz.ramones()
'Come back baby, come back'
&gt;&gt;&gt; zz.dolar
09/05/2011 compra   venda   hora
Comercial   1,618   1,620   17:01   +0,18
Paralelo    1,700   1,820   20/2/2011   0,00
Turismo     1,560   1,730   16:16   +0,58

&gt;&gt;&gt; print(zz.loteria('megasena'))
megasena:
   08 - 11 - 14 - 30 - 36 - 38 
   Concurso 1281 (07/05/2011)
   Acumulado em R$ 2.000.000,00 para 11/05/2011

&gt;&gt;&gt; zz.cpf('11111111111')
'CPF válido'
&gt;&gt;&gt; zz.converte('cf', 32)
'32 C = 89.60 F'

</pre>
<p><strong>[Novo!]</strong><br />
Agora também funciona com Pipes, podendo encadear funções ZZ e usar STDIN!<br />
Mais exemplos:</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; '1+2+3+4' | zz.calcula
'10'
&gt;&gt;&gt; print('a\nb\nc\nd\na\nb\nc' | zz.uniq)
a
b
c
d
&gt;&gt;&gt; 'oi, beleza?, oi, e ai, oi io, oi' | zz.contapalavra('oi', pipe=True)
'4'

</pre>
<p>Note que, se quiser ter uma chamada de função junto com o pipe, tem que adicionar o argumento &#8220;pipe=True&#8221;, senão ele calcula primeiro a resposta e tenta fazer a operação &#8216;or&#8217; entre as strings. Podia ser esse segundo o comportamento padrão, mas teria que usar sempre um pipe pra pegar o valor final, que não é minha intenção.</p>
<p>A ideia de usar o operador &#8216;or&#8217; pra fazer ligação entre chamadas de funções eu peguei desse site: <a href="http://dev-tricks.net/pipe-infix-syntax-for-python" target="_blank">http://dev-tricks.net/pipe-infix-syntax-for-python</a></p>
<p>Se quiser usar, pode colocar diretamente na pasta de módulos do Python, como por exemplo (no Linux):<br />
/usr/local/lib/python<em>X.Y</em>/dist-packages</p>
<p>Bônus:<br />
E, pra quem quiser, apresento o modo mais estranho de calcular 2+2+2+2:</p>
<pre class="brush: python; title: ; notranslate">
&gt;&gt;&gt; int((zz.calcula('2+2')[:-1]+'+2' | zz.calcula(pipe=True))[:-1] + '+2' | zz.calcula)
8
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://ivnaan.wordpress.com/2011/05/09/zz-no-python/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">561</post-id>
		<media:content url="https://0.gravatar.com/avatar/964470d348778265033e55b2fc933f931ade7f668d7e371e6eb16b7e6dc4ddcb?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">Vianna</media:title>
		</media:content>
	</item>
		<item>
		<title>Python e Qt</title>
		<link>https://ivnaan.wordpress.com/2011/03/26/python-e-qt/</link>
					<comments>https://ivnaan.wordpress.com/2011/03/26/python-e-qt/#comments</comments>
		
		<dc:creator><![CDATA[João Bernardo]]></dc:creator>
		<pubDate>Sat, 26 Mar 2011 06:11:38 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[PyQt]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Serial]]></category>
		<guid isPermaLink="false">http://ivnaan.wordpress.com/?p=545</guid>

					<description><![CDATA[Esse post não se chama Python + Arduino (Parte 3) porque agora estou usando outro microcontrolador, um Cortex M3. Aliás, a ideia aqui é mostrar o uso de PyQt, um binding para usar Qt com Python. Após baixar e instalar, você pode começar a programar interfaces no método convencional ou usar o QtDesigner (ferramenta do [&#038;hellip]]></description>
										<content:encoded><![CDATA[<p>Esse post não se chama Python + Arduino (Parte 3) porque agora estou usando outro microcontrolador, um Cortex M3.<br />
Aliás, a ideia aqui é mostrar o uso de PyQt, um binding para usar Qt com Python.</p>
<p>Após <a href="http://www.riverbankcomputing.co.uk/software/pyqt/download">baixar</a> e instalar, você pode começar a programar interfaces no método convencional ou usar o QtDesigner (ferramenta do Qt) para fazer isso.</p>
<p>Por exemplo, você pode fazer assim:</p>
<p>Abra o QtDesigner e crie um novo projeto. Pode ser Widget ou MainWindow, faz pouca diferença no arquivo gerado.<br />
<a href="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/vazio.png"><img loading="lazy" data-attachment-id="554" data-permalink="https://ivnaan.wordpress.com/2011/03/26/python-e-qt/vazio/" data-orig-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/vazio.png" data-orig-size="703,527" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="vazio" data-image-description="" data-image-caption="" data-medium-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/vazio.png?w=300" data-large-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/vazio.png?w=510" src="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/vazio.png" alt="" title="vazio" width="510" height="382" class="aligncenter size-full wp-image-554" srcset="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/vazio.png?w=510&amp;h=382 510w, https://ivnaan.wordpress.com/wp-content/uploads/2011/03/vazio.png?w=150&amp;h=112 150w, https://ivnaan.wordpress.com/wp-content/uploads/2011/03/vazio.png?w=300&amp;h=225 300w, https://ivnaan.wordpress.com/wp-content/uploads/2011/03/vazio.png 703w" sizes="(max-width: 510px) 100vw, 510px" /></a></p>
<p>Coloque seus botões, labels, caixas, etc:</p>
<p><a href="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/btn1.png"><img loading="lazy" data-attachment-id="551" data-permalink="https://ivnaan.wordpress.com/2011/03/26/python-e-qt/btn1/" data-orig-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/btn1.png" data-orig-size="436,358" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="btn1" data-image-description="" data-image-caption="" data-medium-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/btn1.png?w=300" data-large-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/btn1.png?w=436" src="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/btn1.png" alt="" title="btn1" width="436" height="358" class="aligncenter size-full wp-image-551" srcset="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/btn1.png 436w, https://ivnaan.wordpress.com/wp-content/uploads/2011/03/btn1.png?w=150&amp;h=123 150w, https://ivnaan.wordpress.com/wp-content/uploads/2011/03/btn1.png?w=300&amp;h=246 300w" sizes="(max-width: 436px) 100vw, 436px" /></a></p>
<p>Junte os sinais que não precisam de código. Aqui eu coloquei a caixa e o slider para um atualizar o valor do outro e o checkbox para desativar ou ativar o frame contendo a caixa e o slider.</p>
<p><a href="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/sinais.png"><img loading="lazy" data-attachment-id="553" data-permalink="https://ivnaan.wordpress.com/2011/03/26/python-e-qt/sinais/" data-orig-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/sinais.png" data-orig-size="423,360" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="sinais" data-image-description="" data-image-caption="" data-medium-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/sinais.png?w=300" data-large-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/sinais.png?w=423" src="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/sinais.png" alt="" title="sinais" width="423" height="360" class="aligncenter size-full wp-image-553" srcset="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/sinais.png 423w, https://ivnaan.wordpress.com/wp-content/uploads/2011/03/sinais.png?w=150&amp;h=128 150w, https://ivnaan.wordpress.com/wp-content/uploads/2011/03/sinais.png?w=300&amp;h=255 300w" sizes="(max-width: 423px) 100vw, 423px" /></a></p>
<p>Agora, você vai salvar um arquivo no formato .ui, que é um XML que vai ser usado para gerar o nosso programa.</p>
<p>Dentro da pasta de instalação do PyQt, que fica dentro do diretório do Python, existe uma ferramenta chamada pyuic4, que faz a conversão. No Linux, você pode rodar o programa diretamente, mas no Windows é uma boa criar um arquivo .bat contendo o comando que vai ser usado para converter o arquivo XML em código Python.</p>
<blockquote><p>@&#8221;C:\Python32\python&#8221; &#8220;C:\Python32\Lib\site-packages\PyQt4\uic\pyuic.py&#8221; controle.ui &gt; form.py</p></blockquote>
<p>Verifique a pasta de instalação e escolha o nome do arquivo que você salvou e salve isso num arquivo com extensão .bat.<br />
Agora é só dar dois cliques que deve surgir um arquivo chamado form.py, que contem uma classe para modificar uma janela que você tenha criado.</p>
<p>Agora você tem que criar um outro arquivo Python para ser seu programa a ser executado e criar alguns objetos. Existem bons tutoriais de PyQt4 pela internet, então não vou ficar detalhando muito.</p>
<p>Basicamente, você tem que criar um QApplication, uma janela (QWidget ou QMainWindow) e passar essa janela para a função do arquivo form.py que vai criar os botões, etc.</p>
<p>Após isso, você tem que conectar os sinais e os slots dos seus objetos para criar as funcionalidades desejadas. Neste caso, a cada evento no slider ou na caixa, um sinal serial está sendo enviado para o microcontrolador.</p>
<p>Cada slot é um novo método que você deve criar ou então usar de um artifício que são as funções lambda do Python.<br />
Imagem do programa sendo executado:<br />
<a href="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/exec.png"><img loading="lazy" data-attachment-id="552" data-permalink="https://ivnaan.wordpress.com/2011/03/26/python-e-qt/exec/" data-orig-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/exec.png" data-orig-size="719,542" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="exec" data-image-description="" data-image-caption="" data-medium-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/exec.png?w=300" data-large-file="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/exec.png?w=510" src="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/exec.png" alt="" title="exec" width="510" height="384" class="aligncenter size-full wp-image-552" srcset="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/exec.png?w=510&amp;h=384 510w, https://ivnaan.wordpress.com/wp-content/uploads/2011/03/exec.png?w=150&amp;h=113 150w, https://ivnaan.wordpress.com/wp-content/uploads/2011/03/exec.png?w=300&amp;h=226 300w, https://ivnaan.wordpress.com/wp-content/uploads/2011/03/exec.png 719w" sizes="(max-width: 510px) 100vw, 510px" /></a></p>
<p>Abaixo um exemplo de código:<br />
Qualquer dúvida, faça um comentário!</p>
<pre class="brush: python; title: ; notranslate">

from PyQt4 import QtGui, QtCore
import sys, serial 
import scan, form

class Main():
    def __init__(self):
        self.app = QtGui.QApplication(sys.argv)
        self.janela = QtGui.QMainWindow()
        self.ui = form.Ui_Form()  #Referências para elementos da janela
        self.ui.setupUi(self.janela)
        self.cria_slots()
        self.encontra_portas()
        self.janela.show()

    def cria_slots(self):
        self.ui.bt_conectar.clicked.connect(self.slot_conexao)
        self.ui.box_valor.valueChanged.connect(self.envia_info)
        self.ui.ck_ativar.clicked.connect(self.set_on_off)

    def encontra_portas(self):
        for porta in scan.scan():
            self.ui.box_porta.addItem(porta[0])

    #Criar outros métodos aqui

if __name__ == '__main__':
    prog = Main()
    prog.app.exec_()

</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://ivnaan.wordpress.com/2011/03/26/python-e-qt/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">545</post-id>
		<media:content url="https://0.gravatar.com/avatar/964470d348778265033e55b2fc933f931ade7f668d7e371e6eb16b7e6dc4ddcb?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">Vianna</media:title>
		</media:content>

		<media:content url="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/vazio.png" medium="image">
			<media:title type="html">vazio</media:title>
		</media:content>

		<media:content url="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/btn1.png" medium="image">
			<media:title type="html">btn1</media:title>
		</media:content>

		<media:content url="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/sinais.png" medium="image">
			<media:title type="html">sinais</media:title>
		</media:content>

		<media:content url="https://ivnaan.wordpress.com/wp-content/uploads/2011/03/exec.png" medium="image">
			<media:title type="html">exec</media:title>
		</media:content>
	</item>
	</channel>
</rss>
