<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="atom.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt-BR">
    <title>Blog Eduardo Klosowski</title>
    <link rel="self" type="application/atom+xml" href="https://eduardoklosowski.github.io/blog/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-09-25T00:00:00+00:00</updated>
    <id>https://eduardoklosowski.github.io/blog/atom.xml</id>
    <entry xml:lang="pt-BR">
        <title>Branch para deploy de validação</title>
        <published>2025-09-25T00:00:00+00:00</published>
        <updated>2025-09-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/branch-para-deploy-de-validacao/"/>
        <id>https://eduardoklosowski.github.io/blog/branch-para-deploy-de-validacao/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/branch-para-deploy-de-validacao/">&lt;p&gt;Em um projeto de software é comum precisar testar uma funcionalidade que está sendo ou foi desenvolvida. Nos projetos em que o código roda em um servidor, isso pode envolver o deploy em algum ambiente específico, permitindo assim testar uma versão específica do código interagindo com as aplicações cliente ou demais serviços. Porém quando mais de uma funcionalidade é desenvolvida ao mesmo tempo em branches diferentes do git, muitas vezes por pessoas diferentes, testar duas ou mais funcionalidades ao mesmo tempo pode não ser trivial.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;exemplificando-o-problema&quot;&gt;Exemplificando o problema&lt;&#x2F;h2&gt;
&lt;p&gt;Um fluxo bastante comum usado no git é criar uma branch para desenvolver uma funcionalidade. Quando essa funcionalidade estiver pronta, e preferencialmente testada, é feito o merge para a branch principal do projeto. Isso permite que diferentes funcionalidades sejam desenvolvidas em paralelo, seguindo cada uma as etapas do seu fluxo de trabalho, sem ou com a menor interferência possível, assim como também permite desistir do desenvolvimento de uma funcionalidade ou recomeçá-lo.&lt;&#x2F;p&gt;
&lt;p&gt;Um exemplo de diferentes branches do git pode ser visto a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
    gitGraph
    commit id: &amp;quot;0&amp;quot;
    branch feature-1
    commit id: &amp;quot;1&amp;quot;
    commit id: &amp;quot;2&amp;quot;
    checkout main
    branch feature-2
    commit id: &amp;quot;3&amp;quot;
    commit id: &amp;quot;4&amp;quot;
&lt;&#x2F;pre&gt;
&lt;p&gt;Se considerar que o projeto é o código de uma API Rest que é executado em um servidor, e que existem alguns ambientes diferentes como:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Produção&lt;&#x2F;code&gt;: ambiente em que o projeto está de fato sendo utilizado. Deploy realizado a partir da branch &lt;code&gt;main&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Homologação&lt;&#x2F;code&gt;: ambiente para validação antes de ir para produção. Deploy realizado a partir da branch &lt;code&gt;main&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Desenvolvimento&lt;&#x2F;code&gt;: ambiente para testar as coisas pelos desenvolvedores, sem necessariamente se comprometer em levar para produção o que é feito aqui. Deploy realizado a partir de qualquer branch.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Caso as pessoas que desenvolveram as branches &lt;code&gt;feature-1&lt;&#x2F;code&gt; e &lt;code&gt;feature-2&lt;&#x2F;code&gt; queiram testar seus códigos no ambiente &lt;code&gt;Desenvolvimento&lt;&#x2F;code&gt;, apenas uma versão (branch) poderá ser testada por vez, já que ao realizar o deploy da versão do commit &lt;code&gt;4&lt;&#x2F;code&gt;, ele substituirá o deploy da versão do commit &lt;code&gt;2&lt;&#x2F;code&gt;, por exemplo, e vice-versa.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;proposta-de-solucao&quot;&gt;Proposta de solução&lt;&#x2F;h2&gt;
&lt;p&gt;Uma forma de abordar esse problema é através da criação uma versão com todas as funcionalidades que se deseja testar. No git isso pode ser feito criando outra branch para reunir as branches desejadas (fazer merge delas). Por exemplo, executando os seguintes comandos:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; checkout&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; desenvolvimento main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; merge&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --no-ff&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; feature-1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; merge&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --no-ff&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; feature-2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;O que geraria o seguinte histórico no git:&lt;&#x2F;p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
    gitGraph
    commit id: &amp;quot;0&amp;quot;
    branch feature-1 order: 2
    commit id: &amp;quot;1&amp;quot;
    commit id: &amp;quot;2&amp;quot;
    checkout main
    branch feature-2 order: 3
    commit id: &amp;quot;3&amp;quot;
    commit id: &amp;quot;4&amp;quot;
    checkout main
    branch desenvolvimento order: 1
    merge feature-1 id: &amp;quot;5&amp;quot;
    merge feature-2 id: &amp;quot;6&amp;quot;
&lt;&#x2F;pre&gt;
&lt;p&gt;Assim ao realizar o deploy no ambiente &lt;code&gt;Desenvolvimento&lt;&#x2F;code&gt; sempre a partir da branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt;, isso permite testar todas as funcionalidades desejadas ao mesmo tempo, nesse caso as funcionalidades presentes nas branches &lt;code&gt;feature-1&lt;&#x2F;code&gt; e &lt;code&gt;feature-2&lt;&#x2F;code&gt;. Porém essas funcionalidades ainda terão suas respectivas branches separadas para continuar seu fluxo de trabalho, como abertura de pull request (PR) ou merge request (MR), revisão de código e demais etapas que podem existir sem se misturar com as outras, não se importando com a branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; ainda poderá receber novas funcionalidades de outras branches, alterações das branches que já havia feito o merge anteriormente. Ou seja, novas versões podem ser feitas nessa branch conforme a necessidade. Um exemplo é um teste de alteração na &lt;code&gt;feature-1&lt;&#x2F;code&gt; (commit &lt;code&gt;7&lt;&#x2F;code&gt;), que foi feito o merge e deploy (versão no commit &lt;code&gt;8&lt;&#x2F;code&gt;), e se não teve o resultado esperado, poderá ser revertido:&lt;&#x2F;p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
    gitGraph
    commit id: &amp;quot;0&amp;quot;
    branch feature-1 order: 2
    commit id: &amp;quot;1&amp;quot;
    commit id: &amp;quot;2&amp;quot;
    checkout main
    branch feature-2 order: 3
    commit id: &amp;quot;3&amp;quot;
    commit id: &amp;quot;4&amp;quot;
    checkout main
    branch desenvolvimento order: 1
    merge feature-1 id: &amp;quot;5&amp;quot;
    merge feature-2 id: &amp;quot;6&amp;quot;
    checkout feature-1
    commit id: &amp;quot;7&amp;quot;
    checkout desenvolvimento
    merge feature-1 id: &amp;quot;8&amp;quot;
    commit id: &amp;quot;REVERTE-8&amp;quot; type: REVERSE
&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;entrega-das-funcionalidades&quot;&gt;Entrega das funcionalidades&lt;&#x2F;h3&gt;
&lt;p&gt;Quando uma funcionalidade for validada e estiver dada como pronta, poderá seguir seu fluxo de trabalho normal, sendo feito o merge de sua branch com a &lt;code&gt;main&lt;&#x2F;code&gt;, como se a branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; não existisse. Desta forma apenas essa funcionalidade integrará a branch &lt;code&gt;main&lt;&#x2F;code&gt;, podendo ser validada no ambiente &lt;code&gt;Homologação&lt;&#x2F;code&gt; e chegar a &lt;code&gt;Produção&lt;&#x2F;code&gt;, sem as demais funcionalidades que ainda estão sendo testadas no ambiente &lt;code&gt;Desenvolvimento&lt;&#x2F;code&gt;. E ela pode se juntar a outras funcionalidades, como uma pequena correção que foi aplicada diretamente na branch &lt;code&gt;main&lt;&#x2F;code&gt;(ambientes &lt;code&gt;Homologação&lt;&#x2F;code&gt; e &lt;code&gt;Produção&lt;&#x2F;code&gt;), sem ter passado pela branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
    gitGraph
    commit id: &amp;quot;0&amp;quot;
    branch feature-1 order: 2
    commit id: &amp;quot;1&amp;quot;
    commit id: &amp;quot;2&amp;quot;
    checkout main
    branch feature-2 order: 3
    commit id: &amp;quot;3&amp;quot;
    commit id: &amp;quot;4&amp;quot;
    checkout main
    branch desenvolvimento order: 1
    merge feature-1 id: &amp;quot;5&amp;quot;
    merge feature-2 id: &amp;quot;6&amp;quot;
    checkout feature-1
    commit id: &amp;quot;7&amp;quot;
    checkout desenvolvimento
    merge feature-1 id: &amp;quot;8&amp;quot;
    commit id: &amp;quot;REVERTE-8&amp;quot; type: REVERSE
    checkout feature-1
    commit id: &amp;quot;REVERTE-7&amp;quot; type: REVERSE
    checkout main
    branch fix-3 order: 4
    commit id: &amp;quot;9&amp;quot;
    checkout main
    merge fix-3 id: &amp;quot;10&amp;quot;
    merge feature-2 id: &amp;quot;11&amp;quot;
&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;limpeza-da-branch&quot;&gt;Limpeza da branch&lt;&#x2F;h3&gt;
&lt;p&gt;A funcionalidade foi testada na branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; e entregue na branch &lt;code&gt;main&lt;&#x2F;code&gt;, porém é possível observar que com o passar do tempo pode a surgir diferenças entre o código das branches &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; e &lt;code&gt;main&lt;&#x2F;code&gt;. Um caso foi a correção &lt;code&gt;fix-3&lt;&#x2F;code&gt;, que foi aplicada diretamente na &lt;code&gt;main&lt;&#x2F;code&gt;, sem passar pela &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt;, e outro caso poderia ser a &lt;code&gt;feature-1&lt;&#x2F;code&gt;, se seu desenvolvimento for pausado ou cancelado. Isso é ruim, pois poderia gerar código que funciona na &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt;, mas não na &lt;code&gt;main&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Desta forma é recomendável fazer limpeza da branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt;, que seria uma ressincronização com a branch &lt;code&gt;main&lt;&#x2F;code&gt; da onde ela surgiu. Ao fazer isso, serão removidas dela todas as funcionalidades que não chegaram na branch &lt;code&gt;main&lt;&#x2F;code&gt;, porém como essas funcionalidades ainda terão suas branches individuais, seus merges podem ser refeitos com a branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; se ainda for relevante e seu teste estiver ocorrendo. E se não, essa funcionalidade deixará de influenciar nos testes das demais.&lt;&#x2F;p&gt;
&lt;p&gt;Essa limpeza pode ser efetuada simplesmente recriando a branch, por exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; checkout&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -B&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; desenvolvimento main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;E ao unir a &lt;code&gt;feature-1&lt;&#x2F;code&gt; para testes na &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt;, o histórico seria o seguinte:&lt;&#x2F;p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
    gitGraph
    commit id: &amp;quot;0&amp;quot;
    branch feature-1 order: 2
    commit id: &amp;quot;1&amp;quot;
    commit id: &amp;quot;2&amp;quot;
    checkout main
    branch feature-2 order: 3
    commit id: &amp;quot;3&amp;quot;
    commit id: &amp;quot;4&amp;quot;
    checkout feature-1
    commit id: &amp;quot;7&amp;quot;
    commit id: &amp;quot;REVERTE-7&amp;quot; type: REVERSE
    checkout main
    branch fix-3 order: 4
    commit id: &amp;quot;9&amp;quot;
    checkout main
    merge feature-2 id: &amp;quot;10&amp;quot;
    merge fix-3 id: &amp;quot;11&amp;quot;
    branch desenvolvimento order: 1
    merge feature-1 id: &amp;quot;13&amp;quot;
&lt;&#x2F;pre&gt;
&lt;p&gt;Embora essa limpeza seja boa para manter as branches &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; e &lt;code&gt;main&lt;&#x2F;code&gt; semelhantes, evitando assim alguns problemas, uma frequência muito grande também pode dificultar os testes, uma vez que desativará as funcionalidades que estão em teste. Desta forma é necessário encontrar um equilíbrio, seja uma vez por dia ou semana, e isso pode mudar conforme o projeto. Outra opção é a criação de um &quot;botão de manual&quot;, que poderia ser usado sempre que se achar necessário, e que pode até trabalhar em conjunto com algum agendamento.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;como-implementar&quot;&gt;Como implementar?&lt;&#x2F;h2&gt;
&lt;p&gt;Os comandos sugeridos anteriormente funcionam no repositório local. Para integrar com um repositório remoto é necessário algumas adaptações.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;criando-ou-limpando-a-branch&quot;&gt;Criando ou limpando a branch&lt;&#x2F;h3&gt;
&lt;p&gt;Para criar ou limpar a branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; é necessário ter a branch &lt;code&gt;main&lt;&#x2F;code&gt; atualizada, criar a branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; e enviar para o servidor sobreescrevendo a atual. Isso pode ser feito com a seguinte sequência de comandos:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; fetch origin main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; checkout&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -B&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; desenvolvimento origin&#x2F;main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; push origin +desenvolvimento&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;merge-de-funcionalides-para-teste&quot;&gt;Merge de funcionalides para teste&lt;&#x2F;h3&gt;
&lt;p&gt;Para adicionar uma funcionalidade na branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; é necessário ter as branches &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; e da funcionalidade desejada atualizada, após isso é necessário fazer o merge e enviar para o servidor. Isso pode ser feito com a seguinte sequência de comandos:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; fetch origin desenvolvimento feature-1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; checkout&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -B&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; desenvolvimento origin&#x2F;desenvolvimento&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; merge&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --no-ff&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; origin&#x2F;feature-1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; push origin desenvolvimento&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Caso alterações sejam feitas na branch da funcionalidade depois disso, é possível fazer um novo merge.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;revertendo-alteracoes&quot;&gt;Revertendo alterações&lt;&#x2F;h3&gt;
&lt;p&gt;Caso alguma funcionalidade apresente erro, ou se deseja removê-la sem mexer nas demais, é possível reverter um merge na &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt;. A forma para ter isso é ter a branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; atualiza e usar o próprio git para gerar um commit desfazendo as alterações do merge. Isso pode ser feito com a seguinte sequência de comandos informando o hash do commit de merge:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; fetch origin desenvolvimento&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; checkout&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -B&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; desenvolvimento origin&#x2F;desenvolvimento&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -m 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; aa9ff52&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Um ponto a se observar é que ao fazer um commit revertendo as alterações de um merge, não será mais possível fazer o merge dessa funcionalidade até a branch &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt; ser limpa, uma vez que os commits da branch dessa funcionalidade já estão no histórico da &lt;code&gt;desenvolvimento&lt;&#x2F;code&gt;. Porém é possível reverter um commit que reverteu o merge, trazendo a funcionalidade de volta.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;onde-executar&quot;&gt;Onde executar?&lt;&#x2F;h3&gt;
&lt;p&gt;Uma forma de executar essas sequências de comandos é através de um script, onde quem desejar poderia executá-lo e passar qual a operação desejada, branch e afins.&lt;&#x2F;p&gt;
&lt;p&gt;Outra opção é utilizar alguma ferramenta de integração contínua (CI), assim bastaria executar um job passando as mesmas informações como parâmetro. Caso não tenha alguma ferramenta de CI e o deploy da aplicação for feito no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kubernetes.io&#x2F;pt-br&#x2F;&quot;&gt;Kubernetes&lt;&#x2F;a&gt;, é possível utilizar o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tekton.dev&#x2F;&quot;&gt;Tekton&lt;&#x2F;a&gt; para isso, ele irá executar o job usando o próprio Kubernetes para isso.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Não existe uma forma trivial de testar diferentes branches juntas, porém é possível fazer um fluxo com uma branch a parte para isso, sendo que essa branch não vai interferir no fluxo de trabalho anterior, ficando apenas como um passo opcional. Porém é necessário implementar algumas funcionalidades com sequências de comandos para isso.&lt;&#x2F;p&gt;
&lt;p&gt;O fluxo apresentado visa fazer um único deploy com todas as funcionalidades desejadas. Outra opção seria fazer um deploy separado para cada branch, dando um endereço diferente para acessá-los. Essa outra forma permitiria testar as funcionalidades de forma isolada, porém cada deploy consumiria recursos e poderia ter dificuldades caso seja necessário integrar esse novo deploy em algum serviço, como receber eventos ou mensagens de outros serviços.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Testando código que chama serviços da AWS</title>
        <published>2025-02-04T00:00:00+00:00</published>
        <updated>2025-02-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/testes-aws/"/>
        <id>https://eduardoklosowski.github.io/blog/testes-aws/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/testes-aws/">&lt;p&gt;Eu desenvolvo sistemas que utilizam os serviços da &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;pt&#x2F;&quot;&gt;AWS&lt;&#x2F;a&gt; faz algum tempo, e ao longo desse tempo houve mudanças na forma como escrevo testes de código que fazem chamadas a seus serviços. Esse texto tem como objetivo apresentar algumas abordagens para escrita de testes que utilizei, e discutir o que motivou suas evoluções, destacando características de cada abordagem. Ao final, pretendo apresentar um padrão que acredito ser uma forma bastante prática de escrever testes de código que interage com serviços da AWS, usando uma biblioteca em &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.python.org&#x2F;&quot;&gt;Python&lt;&#x2F;a&gt; que desenvolvi implementando esse padrão, mas que também poderia ser adaptado para outros contextos (serviços) e linguagens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;codigo-a-ser-testado&quot;&gt;Código a ser testado&lt;&#x2F;h2&gt;
&lt;p&gt;Antes de iniciar a discussão sobre os testes, quero apresentar um exemplo de código para ser testado. Ele é uma função que deve consumir mensagens enviadas para uma fila &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;pt&#x2F;sqs&#x2F;&quot;&gt;SQS&lt;&#x2F;a&gt;, realizar um processamento com a informação contida nas mensagens, e enviar o resultado para outra fila SQS.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; funcao1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;cliente_sqs&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; fila1_url&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; fila2_url&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Recebe até 10 mensagens do SQS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    msgs_recebidas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;receive_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;        QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila1_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;        MaxNumberOfMessages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Percorre as mensagens recebidas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; msgs_recebidas.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Messages&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, []):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Recupera valor da mensagem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        corpo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; json.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;loads&lt;&#x2F;span&gt;&lt;span&gt;(msg[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Body&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; corpo[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Processa valor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        resultado&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        resposta&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: resultado}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Envia mensagem com resultado&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;send_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila2_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            MessageBody&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;json.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;dumps&lt;&#x2F;span&gt;&lt;span&gt;(resposta),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Apaga mensagem atual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;delete_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila1_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            ReceiptHandle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;msg[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;ReceiptHandle&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse código é uma função que recebe um objeto para interagir com o serviço SQS (&lt;code&gt;cliente_sqs&lt;&#x2F;code&gt;) e a URL de duas filas (&lt;code&gt;fila1_url&lt;&#x2F;code&gt; e &lt;code&gt;fila2_url&lt;&#x2F;code&gt;). Ele busca até 10 mensagens da &lt;code&gt;fila1_url&lt;&#x2F;code&gt; (o máximo permitido por chamada), cada mensagem é um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;pt-BR&#x2F;docs&#x2F;Learn_web_development&#x2F;Core&#x2F;Scripting&#x2F;JSON&quot;&gt;JSON&lt;&#x2F;a&gt; que possui um número no campo &lt;code&gt;n&lt;&#x2F;code&gt;. Após recuperar esse valor, um processamento é feito (nesse caso multiplicar o valor por &lt;code&gt;2&lt;&#x2F;code&gt;), um novo JSON é gerado e enviado para a &lt;code&gt;fila2_url&lt;&#x2F;code&gt;. Se tudo isso ocorrer conforme esperado, a mensagem processada é removida da &lt;code&gt;fila1_url&lt;&#x2F;code&gt;, evitando que ela volte para a fila e eventualmente ser feito uma nova tentativa de processá-la. Esse processo é repetido para cada mensagem recebida.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;teste-unitario-com-mock&quot;&gt;Teste unitário com &lt;em&gt;mock&lt;&#x2F;em&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Uma forma bastante simples de testar é fazer testes unitários (também chamados de &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Teste_de_unidade&quot;&gt;testes de unidade&lt;&#x2F;a&gt;) e usar &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Objeto_mock&quot;&gt;&lt;em&gt;mocks&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. Para o código de exemplo é possível criar um objeto que simula (&lt;em&gt;mock&lt;&#x2F;em&gt;) o &lt;code&gt;cliente_sqs&lt;&#x2F;code&gt; passado para a função, e registre as funções chamadas dele. Depois de executar a função a ser testada, basta verificar as chamadas feitas no objeto simulado, e assim validar se a função está se comportando como o esperado.&lt;&#x2F;p&gt;
&lt;p&gt;Na biblioteca padrão do Python existe o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3.13&#x2F;library&#x2F;unittest.mock.html&quot;&gt;&lt;code&gt;MagicMock&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, que facilita a criação de &lt;em&gt;mocks&lt;&#x2F;em&gt;. Bastando definir o que deve ser retornando em cada função (se ela tiver retorno), e depois verificar como suas funções foram chamadas (&lt;code&gt;assert&lt;&#x2F;code&gt;). Caso espera-se que uma função tenha sido chamada de determinada forma e isso não ocorreu, o teste falhará.&lt;&#x2F;p&gt;
&lt;p&gt;Segue a baixo um exemplo de teste unitário com &lt;em&gt;mock&lt;&#x2F;em&gt; para o código apresentado anteriormente:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; exemplo.codigo1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; funcao1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; unittest.mock&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; MagicMock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; uuid&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; uuid4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; test_funcao1&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Mensagens com valores de entrada e resultados esperados&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    msgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    respostas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Define outros valores auxiliares para o teste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fila1_url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;http:&#x2F;&#x2F;sqs.aws&#x2F;fila1&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fila2_url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;http:&#x2F;&#x2F;sqs.aws&#x2F;fila2&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    msgs_mockadas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;            &amp;#39;ReceiptHandle&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; uuid4&lt;&#x2F;span&gt;&lt;span&gt;().hex,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;            &amp;#39;Body&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: json.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;dumps&lt;&#x2F;span&gt;&lt;span&gt;(msg),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; msgs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Cria e configura mock do SQS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mock_cliente_sqs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; MagicMock&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mock_cliente_sqs.receive_message.return_value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;        &amp;#39;Messages&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: msgs_mockadas,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Chama função a ser testada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    funcao1&lt;&#x2F;span&gt;&lt;span&gt;(mock_cliente_sqs, fila1_url, fila2_url)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Verifica se a função buscou as mensagens na fila 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mock_cliente_sqs.receive_message.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;assert_called_once_with&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;        QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila1_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;        MaxNumberOfMessages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Verifica se as mensagens da fila 1 foram apagadas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; mock_cliente_sqs.delete_message.call_count&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; == len&lt;&#x2F;span&gt;&lt;span&gt;(msgs)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; msgs_mockadas:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mock_cliente_sqs.delete_message.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;assert_any_call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila1_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            ReceiptHandle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;msg[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;ReceiptHandle&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Verifica se as respostas estão corretas na fila 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; mock_cliente_sqs.send_message.call_count&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; == len&lt;&#x2F;span&gt;&lt;span&gt;(respostas)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; esperado&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; respostas:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mock_cliente_sqs.send_message.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;assert_any_call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila2_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            MessageBody&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;json.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;dumps&lt;&#x2F;span&gt;&lt;span&gt;(esperado),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essa abordagem tem algumas vantagens, como: Não precisar configurar e acessar o serviço SQS para rodar os testes, executando tudo localmente; E testa um trecho de código de forma isolada (uma função nesse caso), independente de outras partes do código, como o &lt;code&gt;cliente_sqs&lt;&#x2F;code&gt;. Porém esse método também apresenta desvantagens, como: Ao isolar uma parte do código, perde-se a certeza se ele funcionará junto com as demais partes do sistema, uma vez que podem existir diferenças entre uma resposta real e a resposta do &lt;em&gt;mock&lt;&#x2F;em&gt; (nesse teste o &lt;code&gt;msgs_mockadas&lt;&#x2F;code&gt; possui apenas duas chaves, quando numa resposta verdadeira existiriam várias outras também); Além de ser necessário definir toda vez qual o retorno das funções e validar se elas foram chamadas conforme o esperado; Também é possível fazer um &lt;em&gt;mock&lt;&#x2F;em&gt; que aceite uma chamada inválida para o serviço real; E como a mensagem enviada é uma string com JSON, a ordem dos campos pode mudar, assim como sua formatação, o que pode causar un falso negativo no teste. Então qualquer alteração de parâmetros da função ou resposta, pode gerar uma incompatibilidade do &lt;em&gt;mock&lt;&#x2F;em&gt; com o comportamento real do sistema.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;teste-de-integracao-com-uma-reimplementacao&quot;&gt;Teste de integração com uma reimplementação&lt;&#x2F;h2&gt;
&lt;p&gt;Partindo mais para uma abordagem de testes de integração, existe uma reimplementação dos serviços da AWS em Python para ser usada em testes chamada &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;getmoto&#x2F;moto&quot;&gt;Moto&lt;&#x2F;a&gt; (que também pode ser utilizada em outras linguagens no seu &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.getmoto.org&#x2F;en&#x2F;latest&#x2F;docs&#x2F;server_mode.html&quot;&gt;modo servidor&lt;&#x2F;a&gt;, semelhante ao &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.localstack.cloud&#x2F;&quot;&gt;LocalStack&lt;&#x2F;a&gt;). Assim também é possível rodar os testes localmente, uma vez que ele simula o comportamento dos serviços da AWS. Um exemplo de teste utilizando essa biblioteca pode ser visto a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; boto3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; exemplo.codigo1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; funcao1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; moto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; mock_aws&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;@mock_aws&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; test_funcao1&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Mensagens com valores de entrada e resultados esperados&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    msgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    respostas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Conecta no SQS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cliente_sqs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; boto3.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;client&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;sqs&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; region_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;us-east-1&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Cria filas de teste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fila1_url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;create_queue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;QueueName&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;fila1&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;QueueUrl&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fila2_url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;create_queue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;QueueName&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;fila2&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;QueueUrl&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Envia mensagens de teste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; msgs:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;send_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila1_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            MessageBody&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;json.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;dumps&lt;&#x2F;span&gt;&lt;span&gt;(msg),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Chama função a ser testada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    funcao1&lt;&#x2F;span&gt;&lt;span&gt;(cliente_sqs, fila1_url, fila2_url)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Verifica se a função buscou e apagou as mensagens na fila 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; sum&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;(attr)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; attr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;get_queue_attributes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;        QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila1_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;        AttributeNames&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;            &amp;#39;ApproximateNumberOfMessages&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;            &amp;#39;ApproximateNumberOfMessagesNotVisible&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Attributes&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;values&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Verifica se as respostas estão corretas na fila 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    msgs_de_resposta&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;receive_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;        QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila2_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;        MaxNumberOfMessages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Messages&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; msgs_de_resposta:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;delete_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila2_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            ReceiptHandle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;msg[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;ReceiptHandle&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        json.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;loads&lt;&#x2F;span&gt;&lt;span&gt;(msg[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Body&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; msgs_de_resposta&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; respostas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Remove filas de teste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;delete_queue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila1_url)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;delete_queue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila2_url)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Diferente do teste anterior, neste não é necessário se preocupar em montar os retornos dos serviços acessados, porém é necessário conhecer melhor o serviço para criar os recursos utilizados pela função a ser testada. Também não existe uma forma de fazer um &lt;code&gt;assert&lt;&#x2F;code&gt; para verificar se uma mensagem foi enviada, é necessário buscá-las da fila, e nesse caso, também chamar a função para removê-las, de forma que elas não voltem para a fila, evitando comportamentos não esperados (embora não seja obrigatório ao usar o Moto como um decorador, mas é bom para evitar problemas). E mesmo que possa existir alguma diferença entre o serviço real e sua reimplementação, espera-se que ele seja confiável, e ao atualizar o Moto, todos os testes já serão validados com os novos comportamentos, terceirizando essa responsabilidade do teste.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;interagindo-com-outro-servico-sns&quot;&gt;Interagindo com outro serviço (SNS)&lt;&#x2F;h2&gt;
&lt;p&gt;Pensando em testar outro serviço da AWS, pode-se trocar a fila SQS para qual a resposta do código é enviada por um tópico &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;pt&#x2F;sns&#x2F;&quot;&gt;SNS&lt;&#x2F;a&gt;. O código a ser testado então fica:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; funcao2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;cliente_sqs&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; cliente_sns&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; fila_url&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; topico_arn&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Recebe até 10 mensagens do SQS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    msgs_recebidas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;receive_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;        QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;        MaxNumberOfMessages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Percorre as mensagens recebidas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; msgs_recebidas.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Messages&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, []):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Recupera valor da mensagem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        corpo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; json.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;loads&lt;&#x2F;span&gt;&lt;span&gt;(msg[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Body&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; corpo[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Processa valor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        resultado&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        resposta&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: resultado}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Publica mensagem com resultado&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cliente_sns.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;publish&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            TopicArn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;topico_arn,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            Message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;json.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;dumps&lt;&#x2F;span&gt;&lt;span&gt;(resposta),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Apaga mensagem atual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;delete_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            ReceiptHandle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;msg[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;ReceiptHandle&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Seu teste pode seguir uma estrutura bastante similar:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; boto3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; exemplo.codigo2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; funcao2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; moto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; mock_aws&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;@mock_aws&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; test_funcao2&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Mensagens com valores de entrada e resultados esperados&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    msgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    respostas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;result&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;result&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;result&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Conecta no SQS e SNS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cliente_sqs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; boto3.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;client&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;sqs&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; region_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;us-east-1&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cliente_sns&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; boto3.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;client&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;sns&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; region_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;us-east-1&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Cria fila e tópico de teste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fila_url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;create_queue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;QueueName&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;fila&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;QueueUrl&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    topico_arn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cliente_sns.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;create_topic&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;Name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;topico&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;TopicArn&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Envia mensagens de teste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; msgs:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;send_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;            MessageBody&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;json.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;dumps&lt;&#x2F;span&gt;&lt;span&gt;(msg),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Chama função a ser testada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    funcao2&lt;&#x2F;span&gt;&lt;span&gt;(cliente_sqs, cliente_sns, fila_url, topico_arn)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Como fazer um assert das mensagens publicadas no SNS?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Remove fila e tópico de teste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cliente_sqs.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;delete_queue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;QueueUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;fila_url)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cliente_sns.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;delete_topic&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;TopicArn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;topico_arn)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Porém como verificar o que foi enviado para o tópico SNS? Como &lt;em&gt;mocks&lt;&#x2F;em&gt; não estão sendo utilizados, não tem como fazer um &lt;code&gt;assert&lt;&#x2F;code&gt; para verificar se a função foi chamada e com quais parâmetros. O SNS também não tem uma forma direta de recuperar as mensagens publicadas nele. Uma solução possível é criar uma fila SQS, assinar o tópico SNS, de forma que tudo que for enviado para o tópico seja encaminhado para a fila SQS, e validar o tópico SNS a partir da fila SQS (e após a execução do teste, remover a assinatura, fila e tópico). Embora possível, essa solução é bastante trabalhosa e repetitiva, ainda mais se considerar que isso precisará ser refeito em cada teste do projeto que chamar o SNS.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;simplificando-e-padronizando-repensando-os-testes&quot;&gt;Simplificando e padronizando (repensando os testes)&lt;&#x2F;h2&gt;
&lt;p&gt;Embora a solução apresentada tenha o problema da repetição de código, ela funciona, e para os testes não importa saber criar uma fila ou tópico e removê-los depois (que é uma parte considerável do que é repetido), só importa usá-los. É totalmente plausível (pelo menos na ideia), de na hora de rodar o teste, só perguntar por alguma fila disponível que possa ser utilizada, e depois devolvê-la. Então seria bom se tivesse uma forma de pegar filas e tópicos emprestados para os testes, ou até mesmo criá-los e removê-los, o teste em si não precisa saber o que acontecerá com esses recursos depois de utilizá-los. Na verdade, o teste nem precisaria saber do detalhe de que é necessário primeiro buscar uma mensagem da fila do SQS, e depois deletar essa mensagem, nem de que a mensagem publicada em um tópico SNS precisou passar por uma fila SQS para ser validada.&lt;&#x2F;p&gt;
&lt;p&gt;Pensando dessa forma, só é necessário executar algum código antes do teste para criar os recursos (filas, tópicos...) que serão utilizados, e executar algum código depois dos testes para remover esses recursos criados anteriormente. Além disso, alguma abstração poderia ser criada para simplificar a interação com esses recursos na parte dos testes para facilitar a verificação de sua utilização, que é justamente a parte que importa dos testes.&lt;&#x2F;p&gt;
&lt;p&gt;Para executar algum código antes e depois de algo, no Python pode-se ser usado um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3.13&#x2F;library&#x2F;stdtypes.html#typecontextmanager&quot;&gt;contexto gerenciado&lt;&#x2F;a&gt; (aquele criado com a estrutura &lt;code&gt;with ...&lt;&#x2F;code&gt;), que poderia criar os recursos, passá-lo para o teste, e assim que ele acabar, fazer sua remoção. Porém, o que ele deveria retornar?&lt;&#x2F;p&gt;
&lt;p&gt;Para testar um código que envia mensagens para uma fila SQS, só é necessário saber qual a fila e alguma forma de receber as mensagens enviadas. A identificação de uma fila no SQS se dá através de uma URL, e um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3.13&#x2F;glossary.html#term-generator&quot;&gt;gerador&lt;&#x2F;a&gt; poderia ser criado para abstrair toda a lógica de consumir a fila. Já para testar um código que recebe mensagens de uma fila SQS é necessário saber a URL da fila, e uma função para enviar as mensagens que serão consumidas pelo código a ser testado.&lt;&#x2F;p&gt;
&lt;p&gt;Agora considerando o caso do tópico SNS, toda vez que um tópico for criado, também poderia se criar uma fila SQS que assina esse tópico. A função geradora também poderia buscar nessa fila as mensagens. Isso deixaria o SQS totalmente transparente para os testes (o teste nem saberia que tem uma fila SQS sendo utilizada). Porém para fazer a assinatura, a URL da fila não serve, é necessário seu &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;pt_br&#x2F;IAM&#x2F;latest&#x2F;UserGuide&#x2F;reference-arns.html&quot;&gt;ARN&lt;&#x2F;a&gt;, em outros contextos pode ser necessário o nome e não URL ou ARN.&lt;&#x2F;p&gt;
&lt;p&gt;Para o contexto retornar mais de uma coisa, pode-se utilizar as &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3.13&#x2F;library&#x2F;stdtypes.html#tuple&quot;&gt;tuplas&lt;&#x2F;a&gt; do Python. Porém a questão continua, o que estará nessa tupla? URL da fila? ARN da fila? Nome? Função para enviar mensagens? Gerador para consumir mensagens? Para não ser necessário criar diferentes tuplas para cada caso, pode-se criar uma tupla retornando tudo. Mas pode ser complicado lembrar em que posição está cada coisa, e um código que recebe uma tupla com vários valores e não utiliza a maioria pode gerar confusão. Então em vez de usar tuplas, pode-se criar um objeto seguindo o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3.13&#x2F;reference&#x2F;datamodel.html&quot;&gt;modelo de dados do Python&lt;&#x2F;a&gt;, assim informações (como nome, ARN e URL) podem ir como atributos, a função para enviar mensagens poderia ser um método, e esse objeto também poderia se comportar como um iterador, que é um comportamento do gerador. E por seguir o modelo de dados do Python, isso tudo ainda pareceria algo nativo do Python, onde um objeto abstrairia a fila SQS ou tópico SNS (algo semelhante ao &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=WhZHZ_RYzxw&amp;amp;list=PLOQgLBuj2-3LqnMYKZZgzeC7CKCPF375B&amp;amp;index=18&quot;&gt;&lt;em&gt;page object&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; apresentado no curso de Selenium do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;dunossauro.com&#x2F;&quot;&gt;Dunossauro&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;E para facilitar ainda mais, esses contextos que criam os recursos podem se tornar &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.pytest.org&#x2F;en&#x2F;stable&#x2F;explanation&#x2F;fixtures.html&quot;&gt;&lt;em&gt;fixtures&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pytest.org&#x2F;&quot;&gt;pytest&lt;&#x2F;a&gt;, assim bastaria informar o nome da &lt;em&gt;fixture&lt;&#x2F;em&gt; como parâmetro da função de teste que o recurso já seria criado, e assim que o teste terminar, removido.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementando-esses-padroes-nos-testes&quot;&gt;Implementando esses padrões nos testes&lt;&#x2F;h2&gt;
&lt;p&gt;Os padrões apresentados foram implementados numa biblioteca chamada &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;pytest-moto-fixtures&quot;&gt;pytest-moto-fixtures&lt;&#x2F;a&gt; (também publicada no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pypi.org&#x2F;project&#x2F;pytest-moto-fixtures&#x2F;&quot;&gt;PyPI&lt;&#x2F;a&gt;), assim é possível reutilizá-lo em diferentes testes. Para códigos que utilizam SQS, segue a implementação do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;pytest-moto-fixtures&#x2F;blob&#x2F;3cdc5b18d6126fca6b78f0f9962bcdbf928ac77f&#x2F;src&#x2F;pytest_moto_fixtures&#x2F;services&#x2F;sqs.py#L17-L107&quot;&gt;objeto da fila SQS&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;pytest-moto-fixtures&#x2F;blob&#x2F;3cdc5b18d6126fca6b78f0f9962bcdbf928ac77f&#x2F;src&#x2F;pytest_moto_fixtures&#x2F;services&#x2F;sqs.py#L110-L140&quot;&gt;contexto para criar fila SQS&lt;&#x2F;a&gt; e &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;pytest-moto-fixtures&#x2F;blob&#x2F;3cdc5b18d6126fca6b78f0f9962bcdbf928ac77f&#x2F;src&#x2F;pytest_moto_fixtures&#x2F;fixtures.py#L40-L44&quot;&gt;&lt;em&gt;fixture&lt;&#x2F;em&gt; da fila SQS&lt;&#x2F;a&gt; no repositório. Da mesma forma, para códigos que utilizam SNS, segue a implementação do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;pytest-moto-fixtures&#x2F;blob&#x2F;3cdc5b18d6126fca6b78f0f9962bcdbf928ac77f&#x2F;src&#x2F;pytest_moto_fixtures&#x2F;services&#x2F;sns.py#L43-L126&quot;&gt;objeto do tópico SNS&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;pytest-moto-fixtures&#x2F;blob&#x2F;3cdc5b18d6126fca6b78f0f9962bcdbf928ac77f&#x2F;src&#x2F;pytest_moto_fixtures&#x2F;services&#x2F;sns.py#L129-L168&quot;&gt;contexto para criar tópico SNS&lt;&#x2F;a&gt; e &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;pytest-moto-fixtures&#x2F;blob&#x2F;3cdc5b18d6126fca6b78f0f9962bcdbf928ac77f&#x2F;src&#x2F;pytest_moto_fixtures&#x2F;fixtures.py#L60-L64&quot;&gt;&lt;em&gt;fixture&lt;&#x2F;em&gt; do tópico SNS&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Após instalar a biblioteca, o teste da função que recebe mensagens de uma fila SQS e publica a resposta em um tópico SNS fica da seguinte forma:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; exemplo.codigo2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; funcao2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; test_funcao2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;sqs_queue&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sns_topic&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Mensagens com valores de entrada e resultados esperados&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    msgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    respostas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Envia mensagens de teste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; msgs:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sqs_queue.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;send_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;msg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Chama função a ser testada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    funcao2&lt;&#x2F;span&gt;&lt;span&gt;(sqs_queue.client, sns_topic.client, sqs_queue.url, sns_topic.arn)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Verifica se a função buscou e apagou as mensagens na fila do SQS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(sqs_queue)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Verifica se as respostas estão corretas no tópico SNS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(sns_topic)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; == len&lt;&#x2F;span&gt;&lt;span&gt;(respostas)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        json.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;loads&lt;&#x2F;span&gt;&lt;span&gt;(msg[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Message&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; sns_topic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; respostas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse teste ficou muito mais simples, focando no que realmente importa para validar se o código está se comportando como deveria, e se aproveita de recursos do Python, como a função &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3.13&#x2F;library&#x2F;functions.html#len&quot;&gt;&lt;code&gt;len&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; e &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3.13&#x2F;tutorial&#x2F;datastructures.html#list-comprehensions&quot;&gt;compreensões de lista&lt;&#x2F;a&gt;. Toda a criação da fila SQS e tópico SNS se resumiu em adicionar as &lt;em&gt;fixtures&lt;&#x2F;em&gt; &lt;code&gt;sqs_queue&lt;&#x2F;code&gt; e &lt;code&gt;sns_topic&lt;&#x2F;code&gt; como argumentos da função de teste, assim como sua remoção posteriormente.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;quando-precisa-de-multiplos-recursos-do-mesmo-tipo&quot;&gt;Quando precisa de múltiplos recursos do mesmo tipo&lt;&#x2F;h2&gt;
&lt;p&gt;O teste anterior foi simples porque precisou de apenas um recurso de cada tipo. Porém se voltar a primeira função, aquela que recebe mensagens de uma fila SQS e envia o resultado para outra fila SQS, é necessário duas filas, mas a biblioteca entrega apenas uma &lt;em&gt;fixture&lt;&#x2F;em&gt; que cria uma única fila SQS. Uma opção seria criar outras &lt;em&gt;fixtures&lt;&#x2F;em&gt; para criar outras filas, porém quantas? Se criar poucas &lt;em&gt;fixtures&lt;&#x2F;em&gt; continuaria faltando filas, se criar muitas elas seriam carregadas sem necessidade.&lt;&#x2F;p&gt;
&lt;p&gt;Outra opção é dar um passo a traz, usando diretamente os contextos gerenciados em vez usá-los através de &lt;em&gt;fixtures&lt;&#x2F;em&gt;. O código de teste fica um pouco mais poluído, com comandos para criar as filas, porém possibilita uma maior flexibilidade também, como: Criar mais de uma fila para o teste; Criar filas com nomes específicos (ou que o nome siga um determinado padrão); E controlar quando a fila será criada e removida (ao sair do contexto). Segue um exemplo do teste:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; exemplo.codigo1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; funcao1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; pytest_moto_fixtures.services.sqs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; sqs_create_queue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; test_funcao1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;sqs_client&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Mensagens com valores de entrada e resultados esperados&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    msgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;n&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    respostas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;resultado&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Cria filas de teste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    with&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        sqs_create_queue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;sqs_client&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;sqs_client)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; fila1,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        sqs_create_queue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;sqs_client&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;sqs_client)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; fila2,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Envia mensagens de teste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; msgs:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fila1.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;send_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;body&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;msg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Chama função a ser testada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        funcao1&lt;&#x2F;span&gt;&lt;span&gt;(sqs_client, fila1.url, fila2.url)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Verifica se a função buscou e apagou as mensagens na fila1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(fila1)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # Verifica se as respostas estão corretas na fila2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(fila2)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; == len&lt;&#x2F;span&gt;&lt;span&gt;(respostas)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            json.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;loads&lt;&#x2F;span&gt;&lt;span&gt;(msg[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Body&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; fila2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; respostas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;consideracoes-finais&quot;&gt;Considerações finais&lt;&#x2F;h2&gt;
&lt;p&gt;Esse texto apresentou uma sequência de passos e pensamentos que levaram até a criação da biblioteca &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pypi.org&#x2F;project&#x2F;pytest-moto-fixtures&#x2F;&quot;&gt;pytest-moto-fixtures&lt;&#x2F;a&gt; para auxiliar na escrita de testes de código que utilizam serviços da AWS. Também apresentou como sua arquitetura foi surgindo das necessidades, sempre com o foco em simplificação, e como resolveu essas necessidades.&lt;&#x2F;p&gt;
&lt;p&gt;A biblioteca também possui algumas facilidades que deixaram o código de teste bastante simples, como o uso das &lt;em&gt;fixtures&lt;&#x2F;em&gt; para criação de recursos. Junto com o uso das funcionalidades da própria linguagem, isso permitiu um código de teste bastante simples e direto, sem precisar expor detalhes dos serviços utilizados. E para coisas mais complexas ou específicas, a biblioteca também permite utilizar manualmente algumas de suas camadas mais profundas, porém ainda assim de forma simplificada, sem sujar o código tanto quando sua versão sem o uso da biblioteca.&lt;&#x2F;p&gt;
&lt;p&gt;Outra lição que fica é a possibilidade de criarmos bibliotecas para facilitar as coisas repetitivas do dia a dia, e não só usar as feitas por terceiros. Porém isso deve ser feito com estudo para realmente simplificar, caso contrário poderia trazer mais ou outras dificuldades para as atividades. Nessa forma, essa biblioteca seguiu a linha voltada para os testes de integração, outra biblioteca poderia surgir seguindo a ideia de uso de &lt;em&gt;mocks&lt;&#x2F;em&gt;, possuindo características diferentes.&lt;&#x2F;p&gt;
&lt;p&gt;Obs: O projeto com os códigos desse artigo pode ser acessado &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;testes-aws&#x2F;testes-aws.tar.gz&quot;&gt;aqui&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Discussão sobre o Advent of Code 2023 - Dia 6: Modelando problema com matemática</title>
        <published>2023-12-12T00:00:00+00:00</published>
        <updated>2023-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/advent-of-code-2023-dia-06/"/>
        <id>https://eduardoklosowski.github.io/blog/advent-of-code-2023-dia-06/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/advent-of-code-2023-dia-06/">&lt;p&gt;O problema do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2023&#x2F;day&#x2F;6&quot;&gt;dia 6 do Advent of Code desse ano&lt;&#x2F;a&gt; pode ser resolvido usando matemática. Então resolvi testando o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.sympy.org&#x2F;pt&#x2F;&quot;&gt;SymPy&lt;&#x2F;a&gt; e ver o quanto ele facilita nas análises e contas. O resultado encontra-se no &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;advent-of-code-2023-dia-06&#x2F;analise.ipynb&quot;&gt;seguinte notebook&lt;&#x2F;a&gt; (que também pode ser visualizado &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;blog&#x2F;blob&#x2F;main&#x2F;content&#x2F;2023-12-12-advent-of-code-2023-dia-06&#x2F;analise.ipynb&quot;&gt;aqui&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Discussão sobre o Advent of Code 2022 - Dia 11: Complexidade de operações com números grandes</title>
        <published>2023-03-19T00:00:00+00:00</published>
        <updated>2023-03-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-11/"/>
        <id>https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-11/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-11/">&lt;p&gt;No décimo primeiro dia do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&quot;&gt;Advent of Code de 2022&lt;&#x2F;a&gt; tem um problema interessante para discutir sobre a complexidade de operações com números grandes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;o-problema-do-dia-11&quot;&gt;O problema do dia 11&lt;&#x2F;h2&gt;
&lt;p&gt;O problema do dia 11, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&#x2F;day&#x2F;11&quot;&gt;&quot;macaco no meio&quot;&lt;&#x2F;a&gt;, consiste em seguir uma sequência de passos, que pode ser implementada em código, para simular o ocorrido e calcular a resposta. Recomendo tentar resolvê-lo primeiro.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resolucao-da-parte-1&quot;&gt;Resolução da parte 1&lt;&#x2F;h2&gt;
&lt;p&gt;Não existe nenhuma pegadinha na parte 1 do problema. Talvez a parte mais difícil possa ser ler a entrada, porém como o programa não precisa ser dinâmico, os dados dessa entrada podem estar fixos dentro do código, não sendo necessário ler o arquivo da entrada, simplificando o código. No demais é escrever um código que itere sobre os valores e tome as ações conforme descrito no problema.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resolucao-da-parte-2&quot;&gt;Resolução da parte 2&lt;&#x2F;h2&gt;
&lt;p&gt;A parte 2 é igual à parte 1, mas com duas diferenças: o valor de preocupação com o item não é divido por 3 e devem ser calculado mais rodadas (passando de 20 para 10.000). Esses ajustes são simples de fazer no código, porém na hora de executar o programa ele fica calculando e não termina. O gráfico a baixo mostra o tempo que a solução que implementei leva para calcular cada rodada até a 135 no meu computador:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;advent-of-code-2022-dia-11&#x2F;tempos.svg&quot; alt=&quot;Tempo de cálculo de cada rodada&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;No gráfico pode ser visto que as primeiras rodadas tiveram um tempo relativamente baixo, porém com o passar do tempo, aparecem picos cada vez mais altos, e os vales também estão subindo, ou seja, o tempo para se calcular uma nova rodada está crescendo conforme as rodadas foram passando. A pergunta que fica é porque isso ocorre se as operações são as mesmas e a quantidade de itens também não varia? O que está deixando o código mais lento?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bibliotecas-para-numeros-grandes&quot;&gt;Bibliotecas para números grandes&lt;&#x2F;h3&gt;
&lt;p&gt;Como eu fiz o meu programa em Python esse foi o comportamento do meu código, porém em outras linguagens poderia dar erro, ou até rodar relativamente rápido, mas apresentar resultados incorretos. Isso ocorre porque, como um valor manipulado pelo programa cresce, ele deixa de caber no espaço de uma variável de alguns bits (normalmente 16, 32, ou até 64 bits), ocorrendo um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Integer_overflow&quot;&gt;&lt;em&gt;overflow&lt;&#x2F;em&gt; de inteiro&lt;&#x2F;a&gt;. Uma forma de lidar com isso é utilizando bibliotecas que consigam alocar mais espaço para as variáveis, e no Python, por exemplo, isso já é implementado nativamente. Mas por que fica cada vez mais lento?&lt;&#x2F;p&gt;
&lt;p&gt;A pergunta que pode esclarecer o que está ocorrendo é: qual a complexidade de tempo para operações básicas (soma, subtração, multiplicação e divisão)? Para o tipo inteiro essas operações têm tempo constante (&lt;code&gt;O(1)&lt;&#x2F;code&gt;), porém quando o valor deixa de caber num inteiro, usando o espaço de memória de múltiplos inteiros, essa operação deixa de ser contante. Imagine fazer a soma &lt;code&gt;139 + 183&lt;&#x2F;code&gt; manualmente, é possível começar somando as unidades (&lt;code&gt;9 + 3&lt;&#x2F;code&gt;), depois as dezenas (&lt;code&gt;3 + 8 + 1&lt;&#x2F;code&gt;, considerando o &lt;code&gt;1&lt;&#x2F;code&gt; a dezena da soma nas unidades), depois as centenas. Dessa forma é possível observar que quanto mais casas os números tiverem, mas operações precisam ser feitas, assim essa soma tem complexidade linear a quantidade de casas do valor (&lt;code&gt;O(n)&lt;&#x2F;code&gt;). E embora o computador use os números em binário, essa lógica se repete para as bibliotecas que lidam com números grandes, mesmo operando um ou até quatro bytes por vez, só muda a base numérica. Então pelo fato dos valores não caberem mais em um número pequeno de bits a complexidade do algoritmo aumenta junto com o aumento dos valores.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reduzindo-o-valor-a-ser-tratado&quot;&gt;Reduzindo o valor a ser tratado&lt;&#x2F;h3&gt;
&lt;p&gt;Porém ainda é necessário resolver a parte 2, e embora essas bibliotecas permitam com que o código execute corretamente, elas não fazem o mesmo rodar em tempo hábil. Então como isso pode ser feito? Aqui pode ser utilizado um pouco de matemática para evitar que os números cresçam de mais. Como o valor da preocupação utilizado no algoritmo não importa de fato, e sim o resto da divisão dele por outro número, isso pode ser utilizado para reduzir o valor da preocupação que o algoritmo precisa lidar, uma vez que os valores dessa operação ficam dentro de uma faixa menor e se repetem, mesmo que cresçam até o infinito, isso permite descartar parte da preocupação. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 % 4 == 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 % 4 == 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 % 4 == 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 % 4 == 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 % 4 == 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 % 4 == 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 % 4 == 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 % 4 == 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8 % 4 == 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9 % 4 == 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;39 % 4 == 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;40 % 4 == 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;41 % 4 == 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4000 % 4 == 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Porém a lógica apresentada considera apenas um único número (o &lt;code&gt;4&lt;&#x2F;code&gt; nesse exemplo). Para que isso possa ser aplicada para dois ou mais números é necessário encontrar um valor que possa dividir a preocupação de forma que esse ciclo continue se repetindo normalmente, da mesma forma que ocorreu no exemplo anterior. Uma forma simples de fazer isso é multiplicando todos as bases das divisões que o algoritmo precisa fazer, e toda vez que uma nova preocupação for calculada, basta guardar na variável o resto da divisão dela por esse valor calculado.&lt;&#x2F;p&gt;
&lt;p&gt;Dessa forma os valores da preocupação não crescem até o infinito, e a parte 2 é calculada rapidamente.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Um algoritmo pode ter sua complexidade alterada apenas por ter que lidar com inteiros que podem estar além de uma quantidade fixa de bits. E não é eficiente aumentar essa quantidade de bits para todos os números, visto que se o processador não conseguir operar todos de uma vez, terá que fazer diversas operações para chegar no resultado, isso deixaria o código mais lento em sua execução e precisaria de mais memória, mesmo que os números não usem todos os bits disponíveis para a variável.&lt;&#x2F;p&gt;
&lt;p&gt;Nesse texto foi considerado a multiplicação dos valores da base das divisões como fator para reduzir os valores da preocupação. Porém nem sempre ele será o valor mais otimizado, para ter a garantia de optimização desse fator pode ser utilizado o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;M%C3%ADnimo_m%C3%BAltiplo_comum&quot;&gt;mínimo múltiplo comum&lt;&#x2F;a&gt; desses valores. Porém como no caso da minha entrada todos os valores eram primos, o mínimo múltiplo comum e a multiplicação dos valores da o mesmo resultado, não alterando o desempenho do código. E ainda sobre esse assunto, é interessante como uma representação gráfica desse ciclo do resto das divisões pode ser:&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-dnt=&quot;true&quot; data-theme=&quot;light&quot;&gt;
    &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;abakcus&#x2F;status&#x2F;1613206756217290756&quot;&gt;Tweet&lt;&#x2F;a&gt;
&lt;&#x2F;blockquote&gt;
&lt;script async src=&quot;https:&#x2F;&#x2F;platform.twitter.com&#x2F;widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Discussão sobre o Advent of Code 2022 - Dia 10: Divisão de responsabilidades em geradores</title>
        <published>2023-03-05T00:00:00+00:00</published>
        <updated>2023-03-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-10/"/>
        <id>https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-10/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-10/">&lt;p&gt;No décimo dia do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&quot;&gt;Advent of Code de 2022&lt;&#x2F;a&gt; tem um problema interessante para discutir sobre divisão de responsabilidades de funções geradoras.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;o-problema-do-dia-10&quot;&gt;O problema do dia 10&lt;&#x2F;h2&gt;
&lt;p&gt;O problema do dia 10, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&#x2F;day&#x2F;10&quot;&gt;&quot;tubo de raios catódicos&quot;&lt;&#x2F;a&gt;, consiste em implementar um emulador simples. Na parte 1 deve ser feito a decodificação e execução de instruções de um processador, enquanto na parte 2 deve-se implementar uma saída de vídeo. Recomendo tentar resolvê-lo primeiro.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resolucao-da-parte-1&quot;&gt;Resolução da parte 1&lt;&#x2F;h2&gt;
&lt;p&gt;A parte 1 pede para ler as instruções da entrada, executá-las considerando a quantidade de ciclos que cada tipo de instrução leva, e em determinados ciclos fazer um calculo para obter a resposta, guardando o resultado em um acumulador. Nessa descrição podem ser identificado três responsabilidades diferentes: ler e tratar as instruções da entrada; controlar a execução das instruções no processador e seus ciclos necessários; e controlar o ciclo atual, fazendo o cálculo do valor desejado. Uma forma de escrever funções separando essas responsabilidades é utilizando geradores do Python, que como eles permitem executar um trecho de código, parar e voltar depois, isso permite com que cada função foque apenas na sua responsabilidade, sem precisar misturá-las.&lt;&#x2F;p&gt;
&lt;p&gt;A função para tratar a entrada pode ser feita como um gerador que lê um arquivo e retorna cada instrução com seus valores já convertidos (quando a instrução possui valores extras). No caso da instrução &lt;code&gt;noop&lt;&#x2F;code&gt;, seria apenas a informação que é uma instrução &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;NOP&quot;&gt;NOOP&lt;&#x2F;a&gt;. Enquanto a instrução &lt;code&gt;addx&lt;&#x2F;code&gt; tem também um valor inteiro a ser somado no registrador &lt;code&gt;x&lt;&#x2F;code&gt;. Segue um exemplo onde cada valor retornado pelo gerador é uma lista contendo a instrução na primeira posição e o inteiro associado a ela, quando presente, na segunda posição:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ler_instrucoes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; linha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; entrada:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        instrucao&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; linha.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;strip&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(instrucao)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            instrucao[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = int&lt;&#x2F;span&gt;&lt;span&gt;(instrucao[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        yield&lt;&#x2F;span&gt;&lt;span&gt; instrucao&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse gerador permite com que a entrada possa ser carregada e tradada conforme as instruções forem sendo executadas, não sendo necessário carregar tudo para a memória, nem tratar toda a entrada primeiro, antes de seguir para a próxima parte do problema. Além de simplificar o processo para quem for executar as operações, onde não será necessário se preocupar com conversão de tipos, por exemplo.&lt;&#x2F;p&gt;
&lt;p&gt;A execução das instruções também pode ser feita através de um gerador. Como um gerador permite executar um trecho de código e parar, isso pode ser utilizado para simular os ciclos do processador, onde cada valor retornado pelo gerador (&lt;code&gt;yield&lt;&#x2F;code&gt;) representar o estado no processador naquele ciclo, que nesse problema se resume ao valor do registrador &lt;code&gt;x&lt;&#x2F;code&gt;, que pode ser implementado como uma variável local da função geradora. Segue um exemplo de código:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; processador&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;instrucoes&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; instrucao&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; instrucoes:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; instrucao[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;noop&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            yield&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        elif&lt;&#x2F;span&gt;&lt;span&gt; instrucao[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;addx&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            yield&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            yield&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; instrucao[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essa função itera sobre um conjunto de instruções recebida como argumento (gerador apresentado anteriormente) e executa essas instruções. No caso de instruções &lt;code&gt;noop&lt;&#x2F;code&gt;, nada é feito, porém o &lt;code&gt;yield x&lt;&#x2F;code&gt; faz com que o gerador pare nesse ponto, sendo necessário a leitura do próximo valor do gerador do processador para a continuação da execução desse código, simulando o ciclo do processador. Já as instruções &lt;code&gt;addx&lt;&#x2F;code&gt;, como possuem dois &lt;code&gt;yield x&lt;&#x2F;code&gt;, faz com que seja necessário mais leitura de valores para que finalmente o valor da instrução seja adicionado ao registrador &lt;code&gt;x&lt;&#x2F;code&gt;, simulando o processador parado dois ciclos, para só no final deles a instrução ser completada.&lt;&#x2F;p&gt;
&lt;p&gt;Com a decodificação das instruções e o processador feitos, basta instanciar um gerador da função &lt;code&gt;ler_instrucoes&lt;&#x2F;code&gt; e um da função &lt;code&gt;processador&lt;&#x2F;code&gt;, passando o primeiro como argumento para o segundo. Como o segundo gerador é o responsável por iterar sobre o primeiro (ele faz um &lt;code&gt;for&lt;&#x2F;code&gt; nesse iterador), basta iterar sobre o segundo para simular os ciclos e execução das instruções, e ao utilizar um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;library&#x2F;functions.html#enumerate&quot;&gt;&lt;code&gt;enumerate&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; é possível saber em que ciclo a execução se encontra e realizar as operações desejadas para se calcular o valor pedido pelo problema. Segue um exemplo de código:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; processador&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ler_instrucoes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;entrada.txt&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; i, x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span&gt;(p,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        total&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 220&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(total)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;resolucao-da-parte-2&quot;&gt;Resolução da parte 2&lt;&#x2F;h2&gt;
&lt;p&gt;Entendido como decodificar as instruções e controlar os ciclos para a execução das mesmas, a parte 2 pede para simular uma tela de tubo de raios catódicos. Essa tela possui algumas regras, como mostrar um pixel por vez, e a cada 40 pixeis, ir para a linha a baixo, reiniciando o processo. Isso também pode ser implementado como um gerador, encapsulando essas regras, porém em vez de retornar valores, ele deve receber valores, o que também é chamado de consumidor, mas tem a mesma sintaxe, com a diferença que em vez de usar &lt;code&gt;yield x&lt;&#x2F;code&gt; para retornar um valor &lt;code&gt;x&lt;&#x2F;code&gt;, é usado &lt;code&gt;x = yield&lt;&#x2F;code&gt; para guardar numa variável o valor recebido, e ainda continua possuindo a função de parar a execução do código, nesse caso aguardando o próximo valor. Segue um exemplo de implementação:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; crt&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; True&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; yield&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;                print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\u2588&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;                print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essa função é um &lt;em&gt;loop&lt;&#x2F;em&gt; infinito, que percorre 40 valores imprimindo na tela um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;unicodeplus.com&#x2F;U+2588&quot;&gt;bloco preenchido&lt;&#x2F;a&gt; ou um espaço (fiz essa mudança uma vez que facilitou a visualização do resultado), conforme o valor do registrador &lt;code&gt;x&lt;&#x2F;code&gt; recebido, e após isso faz uma quebra de linha.&lt;&#x2F;p&gt;
&lt;p&gt;Como as funções &lt;code&gt;ler_instrucoes&lt;&#x2F;code&gt; e &lt;code&gt;processador&lt;&#x2F;code&gt; já estão implementadas, e não é necessário nenhuma alteração em suas lógicas, basta acoplar o consumidor &lt;code&gt;crt&lt;&#x2F;code&gt; com elas para ter o resultado desejado. Porém como ao criar um gerador, nenhum código do mesmo é executado até que seu primeiro valor seja lido, é necessário instanciar o consumidor &lt;code&gt;crt&lt;&#x2F;code&gt; e fazer uma primeira execução para que o mesmo pare no &lt;code&gt;yield&lt;&#x2F;code&gt; e esteja pronto para receber o primeiro valor, o que pode ser feito utilizando a função &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;library&#x2F;functions.html#next&quot;&gt;&lt;code&gt;next&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, assim como é possível fazer para recuperar um valor do gerador. Segue um exemplo dessa implementação:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tela&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; crt&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;next&lt;&#x2F;span&gt;&lt;span&gt;(tela)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; processador&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ler_instrucoes&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;entrada.txt&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tela.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span&gt;(x)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;A utilização de geradores permitiu a implementação do código separando responsabilidades em diferentes funções, além de encapsular regras de controle do processador numa função e da tela em outra, sem misturar as duas coisas, deixando-as desacopladas e que poderiam ser utilizadas separadamente. E embora as lógicas estejam separadas, a execução intercala elas, como se o código fosse um &lt;em&gt;loop&lt;&#x2F;em&gt; que lê uma instrução, executado ela e mostrado na tela o caractere resultante, para então repetir essas ações, o que permite ser eficiente em relação ao uso de memória, como já comentado anteriormente nessa série.&lt;&#x2F;p&gt;
&lt;p&gt;Geradores também são a forma como corrotinas ou funções assíncronas eram feitas em Python antes deles entrarem como um recurso da linguagem, recomendo a série &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;playlist?list=PLOQgLBuj2-3J4IRxalwXhRMU6UPoaigf9&quot;&gt;&quot;Geradores e uma Introdução histórica à corrotinas com Python&quot;&lt;&#x2F;a&gt; do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;dunossauro&quot;&gt;Dunossauro&lt;&#x2F;a&gt; sobre o assunto.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Discussão sobre o Advent of Code 2022 - Dia 8: Valor da constante de um algoritmo linear</title>
        <published>2023-02-14T00:00:00+00:00</published>
        <updated>2023-02-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-08/"/>
        <id>https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-08/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-08/">&lt;p&gt;No oitavo dia do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&quot;&gt;Advent of Code de 2022&lt;&#x2F;a&gt; tem um problema interessante para discutir sobre o termo constante na complexidade de um algoritmo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;o-problema-do-dia-8&quot;&gt;O problema do dia 8&lt;&#x2F;h2&gt;
&lt;p&gt;O problema do dia 8, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&#x2F;day&#x2F;8&quot;&gt;&quot;casa nas copas das árvores&quot;&lt;&#x2F;a&gt;, consiste em analisar as alturas das árvores e contá-las. Na parte 1 isso deve ser feito olhando de fora da floresta, enquanto na parte 2 deve-se olhar do topo de cada árvore. Recomendo tentar resolvê-lo primeiro.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resolucao-da-parte-1&quot;&gt;Resolução da parte 1&lt;&#x2F;h2&gt;
&lt;p&gt;A parte 1 do problema pergunta quantas árvores são visível de fora da floresta. É possível resolvê-lo com um algoritmo de complexidade linear ao número de árvores, e uma das formas de fazer isso é analisando a partir de cada orientação (norte, sul, leste e oeste) guardando quais foram as árvores visíveis para não contar a mesma árvore mais de uma vez. Isso faz com que todas as árvores sejam analisadas quatro vezes (uma vez a partir de cada direção), mas mesmo percorrendo todas as árvores quatro vezes, não tira a característica linear do algoritmo, uma vez que a complexidade &lt;code&gt;O(4*n)&lt;&#x2F;code&gt; é considerado igual a &lt;code&gt;O(n)&lt;&#x2F;code&gt;, só mudando a constante que multiplica a complexidade, e essa constante normalmente é omitida na notação.&lt;&#x2F;p&gt;
&lt;p&gt;Um exemplo de implementação desse algoritmo pode ser visto a baixo, onde é possível percorrer todas as direções mexendo nos laços das variáveis &lt;code&gt;x&lt;&#x2F;code&gt; e &lt;code&gt;y&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;entrada&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;(i)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; line.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;rstrip&lt;&#x2F;span&gt;&lt;span&gt;()]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; line&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;largura&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = len&lt;&#x2F;span&gt;&lt;span&gt;(entrada[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;altura&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = len&lt;&#x2F;span&gt;&lt;span&gt;(entrada)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;arvores_visiveis&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = set&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Análise do oeste para leste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(altura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    maior_tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(largura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entrada[y][x]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; maior_tamanho:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            arvores_visiveis.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;((x, y))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            maior_tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Análise do leste para o oeste&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(altura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    maior_tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; reversed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;range&lt;&#x2F;span&gt;&lt;span&gt;(largura)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entrada[y][x]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; maior_tamanho:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            arvores_visiveis.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;((x, y))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            maior_tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Análise do norte para o sul&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(largura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    maior_tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(altura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entrada[y][x]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; maior_tamanho:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            arvores_visiveis.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;((x, y))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            maior_tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Análise do sul para o norte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(largura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    maior_tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; reversed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;range&lt;&#x2F;span&gt;&lt;span&gt;(altura)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entrada[y][x]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; maior_tamanho:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            arvores_visiveis.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;((x, y))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            maior_tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;(arvores_visiveis))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ainda seria possível fazer uma otimização, como verificar se o maior tamanho de árvore já foi encontrado, o que impediria de encontrar outra árvore visível naquela linha ou coluna, e nesse caso o laço mais interno poderia ser interrompido (&lt;code&gt;if maior_tamanho == 9: break&lt;&#x2F;code&gt;). Isso pode reduz o número de análises para alguns problemas, mas não reduz a complexidade do algoritmo, que continua sendo linear, até porque essa otimização não vai conseguir melhorar o desempenho para todas as entradas, um caso é uma entrada que não tenha árvores de altura 9, por exemplo.&lt;&#x2F;p&gt;
&lt;p&gt;Também é possível utilizar outra matriz para guardar as árvores visíveis em vez do conjunto utilizado no exemplo (&lt;code&gt;set()&lt;&#x2F;code&gt;), iniciando todas as árvores como não visíveis e quando se encontra uma visível, troca-se seu estado. E para saber quantas árvores são visíveis bastaria percorrer essa segunda matriz para contá-las, o que faria ser necessário percorrer a matriz mais uma vez, porém ainda manteria a complexidade linear do algoritmo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resolucao-da-parte-2&quot;&gt;Resolução da parte 2&lt;&#x2F;h2&gt;
&lt;p&gt;Na parte 2 do problema, a visibilidade deve ser feita a partir de cada árvore. Uma implementação simples disso é olhar as quatro direções para cada árvore. Considerando &lt;code&gt;l&lt;&#x2F;code&gt; a quantidade de árvores de leste para oeste e &lt;code&gt;h&lt;&#x2F;code&gt; de note para sul, a complexidade dessa solução simples seria &lt;code&gt;O(n*l)&lt;&#x2F;code&gt; ou &lt;code&gt;O(n*h)&lt;&#x2F;code&gt;, o que for maior. Porém existe um algoritmo capaz de resolver esse problema de forma linear (&lt;code&gt;O(n)&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Para resolver esse problema de forma linear são necessários ajustes na estratégia da parte 1, uma vez que a mudança do referencial pode fazer com que árvores que não eram visíveis antes se tornem visíveis, ou que eram visíveis não sejam mais. Uma estratégia é considerar todas as alturas possíveis para cada árvore que está sendo analisada, somando 1 no contador dessa possível altura caso seja visível, ou reiniciando o contador caso a visão esteja obstruída, e na hora de analisar uma direção, fazer isso de trás para frente. Assim é possível dizer para cada árvore sua visão naquela direção, e aproveitar esses dados para o cálculo de visão de cada próxima árvore. E para o cálculo da pontuação de cada árvore, como é a multiplicação da visibilidade nas quatro direções, pode-se iniciar com pontuação 1 para cada árvore e ir multiplicando conforme se calcula a visibilidade nas direções.&lt;&#x2F;p&gt;
&lt;p&gt;Um exemplo desse algoritmo pode ser visto a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;entrada&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;(i)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; line.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;rstrip&lt;&#x2F;span&gt;&lt;span&gt;()]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; line&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;largura&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = len&lt;&#x2F;span&gt;&lt;span&gt;(entrada[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;altura&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = len&lt;&#x2F;span&gt;&lt;span&gt;(entrada)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tamanhos&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pontuacoes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(largura)]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(altura)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(altura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tamanho_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    visibilidade_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(tamanhos)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(largura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entrada[y][x]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        visibilidade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(tamanhos):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; tamanho_anterior:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                visibilidade.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(visibilidade_anterior[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                visibilidade.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pontuacoes[y][x]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *=&lt;&#x2F;span&gt;&lt;span&gt; visibilidade[tamanho]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        visibilidade_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; visibilidade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(altura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tamanho_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    visibilidade_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(tamanhos)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; reversed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;range&lt;&#x2F;span&gt;&lt;span&gt;(largura)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entrada[y][x]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        visibilidade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(tamanhos):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; tamanho_anterior:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                visibilidade.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(visibilidade_anterior[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                visibilidade.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pontuacoes[y][x]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *=&lt;&#x2F;span&gt;&lt;span&gt; visibilidade[tamanho]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        visibilidade_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; visibilidade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(largura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tamanho_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    visibilidade_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(tamanhos)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(altura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entrada[y][x]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        visibilidade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(tamanhos):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; tamanho_anterior:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                visibilidade.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(visibilidade_anterior[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                visibilidade.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pontuacoes[y][x]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *=&lt;&#x2F;span&gt;&lt;span&gt; visibilidade[tamanho]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        visibilidade_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; visibilidade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(largura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tamanho_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    visibilidade_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(tamanhos)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; reversed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;range&lt;&#x2F;span&gt;&lt;span&gt;(altura)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entrada[y][x]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        visibilidade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(tamanhos):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; tamanho_anterior:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                visibilidade.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(visibilidade_anterior[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                visibilidade.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pontuacoes[y][x]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *=&lt;&#x2F;span&gt;&lt;span&gt; visibilidade[tamanho]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tamanho_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; tamanho&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        visibilidade_anterior&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; visibilidade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;maior_pontuacao&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(altura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(largura):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pontuacao&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pontuacoes[y][x]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; pontuacao&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; maior_pontuacao:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            maior_pontuacao&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pontuacao&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(maior_pontuacao)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse algoritmo também percorre todas as árvores quatro vezes para calcular a visibilidade, porém toda vez que analisa uma árvore em uma determinada direção, o faz dez vezes, uma para cada tamanho possível, resultando em 40 análises por árvore (&lt;code&gt;O(40*n)&lt;&#x2F;code&gt;), além de percorrer todas as árvores uma vez a mais para encontrar a maior pontuação. Como a quantidade de tamanhos possíveis é fixa, não variando conforme a entrada do problema, isso não muda a complexidade do algoritmo, que se mantem linar (&lt;code&gt;O(n)&lt;&#x2F;code&gt;). Também seria possível calcular a maior pontuação junto do cálculo da visibilidade da última direção, isso removeria o último laço do algoritmo, porém só deslocaria as instruções da comparação da pontuação de um laço para o outro, cada instrução ainda precisaria ser executada (menos as instruções de controle do laço de repetição), não tendo grandes ganhos de desempenho e misturaria coisas diferentes no laço, o que o deixaria mais difícil de ler.&lt;&#x2F;p&gt;
&lt;p&gt;Outra coisa que pode ser observada nesse algoritmo é a quantidade de memória necessária para executá-lo. Ele cria uma cópia da matriz para guardar a pontuação calculada, e quando está calculando as direções, precisa manter um contador diferente para cada tamanho possível. E diferente da parte 1 onde é possível guardar só as árvores visíveis, o que reduz o consumo de memória ao usar um conjunto (&lt;code&gt;set&lt;&#x2F;code&gt;) para isso, na parte 2 é necessário guardar a pontuação parcial de cada árvore, uma vez que não é possível calcular a pontuação final de cada árvore, uma a uma, sem mexer na complexidade do algoritmo, mas isso permitiria guardar em memória apenas a maior pontuação encontrada até então, por exemplo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Foi possível encontrar algoritmos com complexidade linear para as partes desse problema, porém devido ao fato de ter uma quantidade de direções e tamanhos fixos para o problema. Se tivesse variações como para certas entradas incluir visibilidade nas diagonais também e para outras entradas não, ou mudar a diferença entre a maior e menor altura das árvores, isso teria que aparecer como uma variável multiplicando a complexidade do algoritmo, e não como uma constante, já que isso alteraria a quantidade de análises que precisariam ser feitas.&lt;&#x2F;p&gt;
&lt;p&gt;Como esses algoritmos têm complexidade linear de execução, isso os tornam uma boa opção para grandes entradas. Porém caso as entradas sejam pequenas, um algoritmo com complexidade superior poderia rodar mais rápido devido as grandes constantes que multiplicam a complexidade das soluções lineares. Isso deve ser levado em consideração na hora da escolha do algoritmo a ser utilizado para resolver o problema.&lt;&#x2F;p&gt;
&lt;p&gt;Para esses algoritmos foi necessário carregar toda a matriz em memória, uma vez que os dados eram lidos diversas vezes, e em diversas ordens. Assim não foi possível ler a entrada sob-demanda para reduzir o consumo de memória como nos problemas dos dias anteriores. Se o tamanho da entrada fosse muito grande, impossibilitando guardar tudo em memória, ainda seria possível guardar os dados em arquivos, calculando a posição do dado a ser lido ou escrito e usando funções como &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;io.html#io.IOBase.seek&quot;&gt;&lt;code&gt;seek&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; para ir direto para o dado desejado, mas considerando que o acesso ao HD ou SSD é mais lento que a memória RAM, isso deixaria a execução mais lenta. E nesse caso talvez outros algoritmos, mesmo com complexidades maiores poderiam lidar melhor com esse problema.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Discussão sobre o Advent of Code 2022 - Dia 6: Otimizando o algoritmo e utilização de estruturas de dados</title>
        <published>2022-12-12T00:00:00+00:00</published>
        <updated>2022-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-06/"/>
        <id>https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-06/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-06/">&lt;p&gt;O sexto dia do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&quot;&gt;Advent of Code deste ano&lt;&#x2F;a&gt; tem um problema interessante para discutir sobre otimização do algoritmo e utilização de estruturas de dados.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;o-problema-do-dia-6&quot;&gt;O problema do dia 6&lt;&#x2F;h2&gt;
&lt;p&gt;O problema do dia 6 &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&#x2F;day&#x2F;6&quot;&gt;&quot;problema de sintonização&quot;&lt;&#x2F;a&gt; consiste em encontrar uma subsequência onde não existam elementos repetidos. Recomendo tentar resolvê-lo primeiro.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;solucao-simples&quot;&gt;Solução simples&lt;&#x2F;h2&gt;
&lt;p&gt;Uma forma simples de resolver os problemas no Advent of Code é encontrar soluções simples que não tenham grandes complicações. Para esse problema, uma solução baseada em força bruta, que consiste em testar todas as possíveis subsequências, atende esse requisito. Ela pode ser implementada percorrendo a entrada do problema, extraindo as subsequências e verificando se nelas todos os elementos são únicos, esse último pode ser feito utilizando a estrutura de conjuntos (comentado no problema do &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;advent-of-code-2022-dia-03&#x2F;&quot;&gt;dia 3&lt;&#x2F;a&gt;) verificando se o tamanho do mesmo é igual da subsequência, uma vez que a estrutura de conjuntos &quot;remove&quot; elementos duplicados. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; itertools&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; count&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    subsequencia&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entrada[i:i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; tamanho]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;set&lt;&#x2F;span&gt;&lt;span&gt;(entrada[i:i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; tamanho]))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; tamanho:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        # resposta encontrada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;1a-questao-desempenho&quot;&gt;1ª Questão - Desempenho&lt;&#x2F;h2&gt;
&lt;p&gt;A solução apresentada funciona, porém ela percorre toda a entrada, e para cada posição da entrada, precisa executar mais uma quantidade de operações igual ao tamanho da subsequência desejada (&lt;code&gt;O(n * tamanho)&lt;&#x2F;code&gt;). Isso pode deixar esse algoritmo cada vez mais lento conforme se deseja uma subsequência maior.&lt;&#x2F;p&gt;
&lt;p&gt;O ideal seria um algoritmo que conseguisse depender apenas do tamanho da entrada (&lt;code&gt;O(n)&lt;&#x2F;code&gt;), para isso é preciso desenvolver algum mecanismo para guardar quais caracteres estão na subsequência, verificar se o novo caractere lido está nela ou não e descartar o caractere que saiu da subsequência ao ler esse novo caractere da entrada, tudo isso em tempo constante (&lt;code&gt;O(1)&lt;&#x2F;code&gt;). Se pensarmos em guardar a posição que tal caractere apareceu pela última vez, é fácil responder se ele se encontra dentro ou já está fora da subsequência olhando pelo tamanho dela e posição do caractere lido. E ao guardamos a posição em que a última duplicidade foi encontrada é fácil determinarmos quantos caracteres foram lidos sem duplicidade, desta forma, ao atingir o tamanho desejado, a resposta é encontrada. Juntando esses pensamentos, temos o seguinte algoritmo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;posicao_das_letras&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ultima_duplicidade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; i, c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span&gt;(entrada):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; posicao_das_letras.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(c,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ultima_duplicidade:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ultima_duplicidade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; posicao_das_letras.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(c,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; ultima_duplicidade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; tamanho:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;            # resposta encontrada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    posicao_das_letras[c]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Considerando que a implementação de dicionário do Python utiliza uma &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Tabela_de_dispers%C3%A3o&quot;&gt;tabela de espalhamento&lt;&#x2F;a&gt;, e que as operações para guardar e recuperar um valor espera-se que ocorram em tempo constante (&lt;code&gt;O(1)&lt;&#x2F;code&gt;), temos como resultado um algoritmo em tempo linear (&lt;code&gt;O(n)&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2a-questao-estrutura-de-dados&quot;&gt;2ª Questão - Estrutura de dados&lt;&#x2F;h2&gt;
&lt;p&gt;Porém tabelas de espalhamento podem ter problemas com colisão de hash, além de ter uma implementação relativamente complexa. Como nesse problema existe um conjunto relativamente restrito de chaves, 256 caracteres considerando todos os valores possíveis em 1 Byte (ou ainda 26 caracteres, considerando apenas as letras de &lt;code&gt;a&lt;&#x2F;code&gt; até &lt;code&gt;z&lt;&#x2F;code&gt;), e que esses valores podem ser facilmente interpretados como números, é possível utilizar uma simples lista no lugar do dicionário, usando a posição da lista como sua chave. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tamanho&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;posicao_das_letras&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;256&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ultima_duplicidade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; i, c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;ord&lt;&#x2F;span&gt;&lt;span&gt;(c)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; entrada):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; posicao_das_letras[c]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ultima_duplicidade:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ultima_duplicidade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; posicao_das_letras[c]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; ultima_duplicidade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; tamanho:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;            # resposta encontrada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    posicao_das_letras[c]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Desta forma é utilizado uma estrutura de dados muito mais simples, e obtendo o mesmo resultado. Essa abordagem também não vai ter problemas com colisão de hash, e nem problemas com o tempo de cálculo do mesmo, uma vez que não utiliza funções de hash, deixando o algoritmo menos suscetível a problemas.&lt;&#x2F;p&gt;
&lt;p&gt;Um outro desafio que observei onde a utilização de estruturas de dados mais simples é possível foi no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.beecrowd.com.br&#x2F;repository&#x2F;UOJ_2376.html&quot;&gt;2376 da beecrowd&lt;&#x2F;a&gt;, que se resume a montar uma chave de um campeonato, dizendo no final o vencedor. Por ter uma estrutura visual bastante semelhante a uma árvore, um primeiro impulso resolvê-lo implementando uma, porém olhando a sequência dos jogos, é possível resolver esse problema utilizando uma fila, e que pode ser até mais fácil de implementar uma vez que não é necessário se preocupar em que profundidade da árvore está se processando.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Nem todo problema é possível resolver em tempo linear, e quando é, pode-se exigir um pouco mais de estudo sobre o problema e busca da melhor estrutura de dados.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Discussão sobre o Advent of Code 2022 - Dia 4: Algebra booliana e ordenação</title>
        <published>2022-12-07T00:00:00+00:00</published>
        <updated>2022-12-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-04/"/>
        <id>https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-04/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-04/">&lt;p&gt;Quarto dia do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&quot;&gt;Advent of Code deste ano&lt;&#x2F;a&gt;, o problema desse dia é bastante interessante para discutir sobre álgebra booliana e ordenação completa ou parcial, e como ela é implementado em linguagens como &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;pt-BR&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;o-problema-do-dia-4&quot;&gt;O problema do dia 4&lt;&#x2F;h2&gt;
&lt;p&gt;O problema do dia 4 &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&#x2F;day&#x2F;4&quot;&gt;&quot;limpeza do acampamento&quot;&lt;&#x2F;a&gt; consiste em ler uma sequência de intervalos e encontrar se eles se sobrepõem. Novamente, recomendo que tentem resolvê-lo primeiro, mas se tiver dificuldades pode seguir com a leitura desse texto.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1a-questao-algebra-booliana&quot;&gt;1ª Questão - Álgebra booliana&lt;&#x2F;h2&gt;
&lt;p&gt;A parte 1 do problema pede para encontrar sobreposições completas, algo como um dos dois casos da imagem a baixo, que mostra as bordas dos dois conjuntos em ordem numérica:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;advent-of-code-2022-dia-04&#x2F;sobreposicao-completa.png&quot; alt=&quot;Sobreposição completa&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Visualizando a imagem é fácil chegar a conclusão de que a condição para uma sobreposição completa é &lt;code&gt;(b[0] &amp;lt;= a[0] &amp;lt;= a[1] &amp;lt;= b[1]) || (a[0] &amp;lt;= b[0] &amp;lt;= b[1] &amp;lt;= a[1])&lt;&#x2F;code&gt; já que é a ordem em que elas aparecem na imagem.&lt;&#x2F;p&gt;
&lt;p&gt;A parte 2 do problema pode para encontrar sobreposições parciais também, novamente uma imagem pode ajudar:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;advent-of-code-2022-dia-04&#x2F;sobreposicao-parcial.png&quot; alt=&quot;Sobreposição parcial&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Na imagem vemos as ordens &lt;code&gt;(a[0] &amp;lt;= b[0] &amp;lt;= a[1] &amp;lt;= b[1]) || (b[0] &amp;lt;= a[0] &amp;lt;= b[1] &amp;lt;= a[1])&lt;&#x2F;code&gt;. Pegando apenas o primeiro caso para analisar, nessa parte do problema condições como &lt;code&gt;a[0] &amp;lt;= b[0] &amp;lt;= a[1] &amp;lt;= b[1]&lt;&#x2F;code&gt; (sobreposição parcial) e &lt;code&gt;a[0] &amp;lt;= b[0] &amp;lt;= b[1] &amp;lt;= a[1]&lt;&#x2F;code&gt; (sobreposição completa) são as procuradas. Analisando um pouco, pode-se observar que &lt;code&gt;b[1]&lt;&#x2F;code&gt; não importa tanto para essa condição, já que ele pode estar tanto antes quanto depois de &lt;code&gt;a[1]&lt;&#x2F;code&gt;, sendo assim, pode-se removê-lo da condição: &lt;code&gt;a[0] &amp;lt;= b[0] &amp;lt;= a[1]&lt;&#x2F;code&gt;. E isso se repete para o segundo caso, chegando na condição final &lt;code&gt;(a[0] &amp;lt;= b[0] &amp;lt;= a[1]) || (b[0] &amp;lt;= a[0] &amp;lt;= b[1])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Porém essa é apenas uma das formas a se chegar a condição. Outra forma que pode ser interessante para a parte 2 é pensar o oposto, o que seria uma não sobreposição:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;advent-of-code-2022-dia-04&#x2F;nao-sobreposicao.png&quot; alt=&quot;Não sobreposição&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Esse caso é muito mais simples, bastando observar que se &lt;code&gt;a[1] &amp;lt; b[0] || b[1] &amp;lt;= a[0]&lt;&#x2F;code&gt; não existe nenhum tipo de sobreposição, e para encontrar uma sobreposição basta inverter essa condição, negando-a: &lt;code&gt;!(a[1] &amp;lt; b[0] || b[1] &amp;lt; a[0])&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Ainda existe a possibilidade de trabalhar com essa condição utilizando &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;%C3%81lgebra_booliana&quot;&gt;álgebra booliana&lt;&#x2F;a&gt; para remover a negação, (eu já comentei sobre isso nesse &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;algebra-booliana&#x2F;&quot;&gt;texto&lt;&#x2F;a&gt;, recomendo a leitura), e isso permite chegar na condição &lt;code&gt;a[1] &amp;gt;= b[0] &amp;amp;&amp;amp; b[1] &amp;gt;= a[0]&lt;&#x2F;code&gt;, que é mais simples do que &lt;code&gt;(a[0] &amp;lt;= b[0] &amp;lt;= a[1]) || (b[0] &amp;lt;= a[0] &amp;lt;= b[1])&lt;&#x2F;code&gt; que havia sido encontrado anteriormente.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2a-questao-ordenacao&quot;&gt;2ª Questão - Ordenação&lt;&#x2F;h2&gt;
&lt;p&gt;Em toda essa discussão assumi que &lt;code&gt;a[0] &amp;lt;= a[1]&lt;&#x2F;code&gt; e &lt;code&gt;b[0] &amp;lt;= b[1]&lt;&#x2F;code&gt;, e que o problema nos garante isso (pelo menos não existe caso onde isso não seja válido na entrada dada). Isso permite que não seja necessário verificar se o intervalo está invertido, e assumir que se &lt;code&gt;a &amp;lt; b&lt;&#x2F;code&gt; e &lt;code&gt;b &amp;lt; c&lt;&#x2F;code&gt; então &lt;code&gt;a &amp;lt; c&lt;&#x2F;code&gt;, uma vez que está lidando com números inteiros que também tem essa propriedade.&lt;&#x2F;p&gt;
&lt;p&gt;Voltando ao problema do &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;advent-of-code-2022-dia-02&#x2F;&quot;&gt;&quot;pedra papel tesoura&quot; do dia 2&lt;&#x2F;a&gt;, também poderia se utilizar das operações de maior e menor para dizer quem ganha ou perde de quem, exemplo: &lt;code&gt;pedra &amp;lt; papel&lt;&#x2F;code&gt; e &lt;code&gt;papel &amp;lt; tesoura&lt;&#x2F;code&gt;, porém observe que isso não nos permite assumir que &lt;code&gt;pedra &amp;lt; tesoura&lt;&#x2F;code&gt;, visto que o correto seria &lt;code&gt;tesoura &amp;lt; padra&lt;&#x2F;code&gt;. Quando isso ocorre, temos um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Conjunto_parcialmente_ordenado&quot;&gt;conjunto parcialmente ordenado&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Embora isso não faça diferença para a resolução do problema do Advent of Code, permite entender a diferença entre as traits &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;cmp&#x2F;trait.Ord.html&quot;&gt;&lt;code&gt;Ord&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; e &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;cmp&#x2F;trait.PartialOrd.html&quot;&gt;&lt;code&gt;PartialOrd&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; do Rust, onde se quiser comparar valores com &lt;code&gt;&amp;gt;&lt;&#x2F;code&gt; e &lt;code&gt;&amp;lt;&lt;&#x2F;code&gt;, deve-se implementar a &lt;code&gt;PartialOrd&lt;&#x2F;code&gt;, e se for seguro assumir que se &lt;code&gt;a &amp;lt; b&lt;&#x2F;code&gt; e &lt;code&gt;b &amp;lt; c&lt;&#x2F;code&gt; então &lt;code&gt;a &amp;lt; c&lt;&#x2F;code&gt; pode-se implementar também a &lt;code&gt;Ord&lt;&#x2F;code&gt;, e essa é a diferença entre elas. Isso também ocorre de forma análoga para as comparações com as traits &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;cmp&#x2F;trait.Eq.html&quot;&gt;&lt;code&gt;Eq&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; e &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;cmp&#x2F;trait.PartialEq.html&quot;&gt;&lt;code&gt;PartialEq&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; (se &lt;code&gt;a == b&lt;&#x2F;code&gt; e &lt;code&gt;b == c&lt;&#x2F;code&gt; então &lt;code&gt;a == c&lt;&#x2F;code&gt;, pode-se implementar também a &lt;code&gt;Eq&lt;&#x2F;code&gt;). Apesar de não fazer parte do problema, fica como curiosidade e conhecimento.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Se estiver difícil de escrever ou entender alguma condição, às vezes vale a pena pensar o oposto e negá-la, sendo opcional o trabalho com a álgebra booliana para tentar reduzir a quantidade de operações.&lt;&#x2F;p&gt;
&lt;p&gt;Quando estiver trabalhando com comparações (maior, menor, igualdade, diferença) vale a pena observar se ela é uma comparação apenas parcial, ou se pode-se assumir outras condições a partir do que já foi verificado. Algoritmos de ordenação, por exemplo, tiram bastante proveito disso para reduzir seus tempos de execução. Quando aplicado, pode ser algo trabalhado no algoritmo para buscar melhorar sua performance.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Discussão sobre o Advent of Code 2022 - Dia 3: Complexidade de operações em estruturas de dados</title>
        <published>2022-12-06T00:00:00+00:00</published>
        <updated>2022-12-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-03/"/>
        <id>https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-03/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-03/">&lt;p&gt;Terceiro dia do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&quot;&gt;Advent of Code deste ano&lt;&#x2F;a&gt;, o problema desse dia é bastante interessante para discutir sobre a complexidade de operações em estruturas de dados.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;o-problema-do-dia-3&quot;&gt;O problema do dia 3&lt;&#x2F;h2&gt;
&lt;p&gt;O problema do dia 3 &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&#x2F;day&#x2F;3&quot;&gt;&quot;reorganização da mochila&quot;&lt;&#x2F;a&gt; consiste em encontrar elementos repetidos em diferentes coleções de valores. Novamente, recomendo que tentem resolvê-lo primeiro, e o vídeo do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;rochacbruno&quot;&gt;Bruno Rocha&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;iframe
    width=&quot;640&quot;
    height=&quot;360&quot;
    src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;QROejIb9Zqc&quot;
    allowfullscreen
    style=&quot;border: 0; max-width: 100%;&quot;
&gt;&lt;&#x2F;iframe&gt;
&lt;iframe
    width=&quot;640&quot;
    height=&quot;360&quot;
    src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;qd_MOTS2gOo&quot;
    allowfullscreen
    style=&quot;border: 0; max-width: 100%;&quot;
&gt;&lt;&#x2F;iframe&gt;
&lt;h2 id=&quot;questao-estrutura-de-dados-e-complexidade-de-operacoes&quot;&gt;Questão - Estrutura de dados e complexidade de operações&lt;&#x2F;h2&gt;
&lt;p&gt;Uma forma bastante simples de representar os compartimentos das mochilas na primeira parte, ou as mochilas na segunda parte, é com uma lista ou array, onde cada posição é um item. E isso é bastante direto e prático, já que muitas linguagens permitem acessar o caractere de uma posição da string, fazendo a string já se comportar como uma lista de certa forma.&lt;&#x2F;p&gt;
&lt;p&gt;Para encontrar os itens em comum em duas strings bastaria comparar todos seus elementos. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;itens_em_comum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; compartimento1:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; compartimento2:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; b:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            itens_em_comum.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Isso ainda pode ser simplificado para o código a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; compartimento1:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; compartimento2:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        itens_em_comum.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Apensar da mudança, o código vai executar exatamente os mesmos passos, que são comparar cada item do &lt;code&gt;compartimento1&lt;&#x2F;code&gt; com cada item do &lt;code&gt;compartimento2&lt;&#x2F;code&gt;. Isso faz com que sejam necessárias &lt;code&gt;n * m&lt;&#x2F;code&gt; comparações, sendo &lt;code&gt;n&lt;&#x2F;code&gt; a quantidade de itens no &lt;code&gt;compartimento1&lt;&#x2F;code&gt; e &lt;code&gt;m&lt;&#x2F;code&gt; a quantidade de itens no &lt;code&gt;compartimento2&lt;&#x2F;code&gt;, que como na parte 1 os dois compartimentos têm a mesma quantidade de itens (&lt;code&gt;n = m&lt;&#x2F;code&gt;), é possível afirmar que são &lt;code&gt;n²&lt;&#x2F;code&gt; comparações (&lt;code&gt;O(n²)&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Porém listas não são a única estrutura de dados que poderiam representar os compartimentos. Como nesse problema itens repetidos no mesmo compartimento e sua ordem não são importantes, é possível utilizar conjuntos (conhecidos como &lt;em&gt;set&lt;&#x2F;em&gt; em algumas linguagens de programação) e que podem ser implementados com uma &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;%C3%81rvore_bin%C3%A1ria_de_busca&quot;&gt;árvore de busca binária&lt;&#x2F;a&gt; ou &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Tabela_de_dispers%C3%A3o&quot;&gt;tabela de espalhamento&lt;&#x2F;a&gt;. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;compartimento2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = set&lt;&#x2F;span&gt;&lt;span&gt;(compartimento2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; compartimento1:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; compartimento2:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        itens_em_comum.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Uma vantagem de se utilizar um conjunto é que itens repetidos são removidos, ou seja, uma mesma comparação não é feita com outra cópia do mesmo item. Outra vantagem é que a operação para verificar se um item existe em outro conjunto, quando implementado em uma árvore de busca binária, reduz o espaço de busca pela metade a cada comparação, sendo assim aproximadamente &lt;code&gt;n * log2(n)&lt;&#x2F;code&gt; comparações para se encontrar todos os itens repetidos, que é menor que &lt;code&gt;n²&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Entretanto, enquanto numa lista, para adicionar um item basta copiá-lo no final da mesma (&lt;code&gt;O(1)&lt;&#x2F;code&gt;), para adicionar um item em uma árvore de busca binária é necessário encontrar a posição para aquele item na árvore (&lt;code&gt;O(log2(n))&lt;&#x2F;code&gt;), e isso se repete para cada item, além de as vezes ser necessário rebalancear a árvore. Resumidamente existe algum processamento para se construir a árvore, e isso deve ser levado em consideração. Porém como a construção da árvore tem a mesma complexidade da busca que ocorre depois (&lt;code&gt;O(n * log2(n))&lt;&#x2F;code&gt;), faz compensar para uma grande quantidade de itens, mas pode não compensar para uma baixa quantidade, veja a baixo um gráfico comparando a quantidade de comparações para ambos os casos.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;advent-of-code-2022-dia-03&#x2F;comparacoes.svg&quot; alt=&quot;Gráfico da quantidade de comparações&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Uma mesma operação pode ter complexidades diferentes para diferentes estruturas de dados, como no caso a função para verificar se um item existe em outra coleção (&lt;code&gt;O(n²)&lt;&#x2F;code&gt; na lista, e &lt;code&gt;O(n * log2(n))&lt;&#x2F;code&gt; no conjunto). Porém além da operação, pode ser necessário considerar a construção da estrutura de dados, que neste caso compensa para muitos itens, mas pode não compensar para quantidades pequenas.&lt;&#x2F;p&gt;
&lt;p&gt;Ainda existem outras opções para resolver esse problema, como converter os dois compartimentos para conjuntos e utilizar funções que busquem a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Interse%C3%A7%C3%A3o&quot;&gt;interseção&lt;&#x2F;a&gt; dos mesmos (o que foi feito pelo Bruno Rocha nos seus vídeos). Porém isso obriga a construção de mais um conjunto, e se o algoritmo não tirar vantagem dessa estrutura de dados, como percorrer os itens de uma coleção buscando se existe na outra, que é o que ocorre usando uma lista para um compartimento e um conjunto para outro, isso pode não mudar a complexidade ciclomática do algoritmo e deixa o código mais lento.&lt;&#x2F;p&gt;
&lt;p&gt;Também pode ser analisado a complexidade ao utilizar uma &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Tabela_de_dispers%C3%A3o&quot;&gt;tabela de espalhamento&lt;&#x2F;a&gt; para implementar os conjuntos (o Python faz isso), que traria outra complexidade para essas operações, podendo ter ou não um melhor desempenho, como já discutido no &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;advent-of-code-2022-dia-02&#x2F;&quot;&gt;dia 2&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Ou ainda trabalhando com as listas, poderia ser ordenados os itens, o que permitiria fazer uma &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Pesquisa_bin%C3%A1ria&quot;&gt;busca binária&lt;&#x2F;a&gt; na lista (recomendo esse &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=JNXE4lbwIZs&quot;&gt;vídeo sobre o assunto&lt;&#x2F;a&gt;), isso não removeria os itens duplicados no processamento, porém visto a complexidade &lt;code&gt;O(n * log2(n))&lt;&#x2F;code&gt; dos algoritmos de ordenação e &lt;code&gt;O(log2(n))&lt;&#x2F;code&gt; da busca binária, teria uma eficiência do algoritmo similar as outras opções analisadas (&lt;code&gt;O(n * log2(n))&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Discussão sobre o Advent of Code 2022 - Dia 2: Sequência de condições</title>
        <published>2022-12-02T00:00:00+00:00</published>
        <updated>2022-12-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-02/"/>
        <id>https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-02/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-02/">&lt;p&gt;Segundo dia do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&quot;&gt;Advent of Code deste ano&lt;&#x2F;a&gt;, na questão de optimização do algoritmo, ele tem bastante semelhança com o &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;advent-of-code-2022-dia-01&#x2F;&quot;&gt;dia 1&lt;&#x2F;a&gt; sobre tratar a entrada, mas tem uma questão que acredito que vale uma observação no seu processamento.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;o-problema-do-dia-2&quot;&gt;O problema do dia 2&lt;&#x2F;h2&gt;
&lt;p&gt;O problema do dia 2 &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&#x2F;day&#x2F;2&quot;&gt;&quot;pedra papel tesoura&quot;&lt;&#x2F;a&gt; consiste basicamente em transcrever as &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Pedra,_papel_e_tesoura&quot;&gt;regras do jogo de mesmo nome&lt;&#x2F;a&gt; para um algoritmo que processe seus resultados. Novamente recomendo que tentem resolver o desafio primeiro, e o vídeo do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;rochacbruno&quot;&gt;Bruno Rocha&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;iframe
    width=&quot;640&quot;
    height=&quot;360&quot;
    src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;jANYXhnDsZM&quot;
    allowfullscreen
    style=&quot;border: 0; max-width: 100%;&quot;
&gt;&lt;&#x2F;iframe&gt;
&lt;h2 id=&quot;questao-sequencia-de-condicoes&quot;&gt;Questão - Sequência de condições&lt;&#x2F;h2&gt;
&lt;p&gt;Na solução apresentada pelo Bruno Rocha foi utilizado o &lt;code&gt;match&lt;&#x2F;code&gt; do Rust para definir a pontuação ganha em cada rodada. Nem todas as linguagens têm essa estrutura de controle (ou um &lt;code&gt;switch ... case&lt;&#x2F;code&gt; que poderia substituí-lo em alguns casos), mas é possível fazer algo similar utilizando &lt;code&gt;if&lt;&#x2F;code&gt;. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Y&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;B&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;B&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Y&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;B&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;C&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;C&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Y&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;C&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Um ponto dessa abordagem é que para resultados que tem sua condição verificada mais no início, como &lt;code&gt;A X&lt;&#x2F;code&gt;, tendem a ser computados mais rápido que condições verificadas mais para o final, como &lt;code&gt;C Z&lt;&#x2F;code&gt;. Dependendo do ambiente, se confidencialidade for importante, por exemplo, medir o tempo de cálculo poderia vazar quais foram as opções escolhidas, quebrando a confidencialidade (mas não é o caso aqui). Isso pode ser contornado trocando todos os &lt;code&gt;elif&lt;&#x2F;code&gt; para &lt;code&gt;if&lt;&#x2F;code&gt;, o que faria todas as opções ficarem mais lentas iguais, já que toda vez todas as condições seriam verificadas.&lt;&#x2F;p&gt;
&lt;p&gt;Mas considerando reduzir o tempo de execução, usar &lt;code&gt;if&lt;&#x2F;code&gt; aninhados é uma outra abordagem possível. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Y&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;B&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Y&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;elif&lt;&#x2F;span&gt;&lt;span&gt; oponente&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;C&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Y&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span&gt; voce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Assim, em vez de ter que passar por 9 condições até chegar na opção &lt;code&gt;C Z&lt;&#x2F;code&gt; (pior caso), seriam necessário apenas 6 condições, sendo que as demais combinações também tem ganhos.&lt;&#x2F;p&gt;
&lt;p&gt;Outra abordagem em vez de usar &lt;code&gt;if&lt;&#x2F;code&gt;, como o Bruno comentou, seria utilizando estruturas como mapas ou dicionários (o nome varia de acordo com a linguagem). Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;scores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Y&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;B&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;B&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Y&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;B&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;C&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;C&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Y&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;C&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Z&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;score&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; scores[oponente, voce]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;O desempenho dessa solução depende da estrutura de dados utilizada para implementar o mapa&#x2F;dicionário. Se ele for implementado em cima de uma &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;%C3%81rvore_bin%C3%A1ria_de_busca&quot;&gt;árvore de busca binária&lt;&#x2F;a&gt; (algo com alguma semelhante a uma &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;collections&#x2F;struct.BTreeMap.html&quot;&gt;&lt;code&gt;BTreeMap&lt;&#x2F;code&gt; do Rust&lt;&#x2F;a&gt;) teria um desempenho semelhante a solução de &lt;code&gt;if&lt;&#x2F;code&gt; anilhados, se for implementado em cima de uma &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Tabela_de_dispers%C3%A3o&quot;&gt;tabela de espalhamento&lt;&#x2F;a&gt; (estrutura &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;collections&#x2F;hash_map&#x2F;struct.HashMap.html&quot;&gt;&lt;code&gt;HashMap&lt;&#x2F;code&gt; do Rust&lt;&#x2F;a&gt;) se resumiria a calcular um hash em cima dos dados e acessar diretamente o valor desejado, o que poderia ser um desempenho ótimo para todas as condições, só dependendo da eficiência do cálculo da hash.&lt;&#x2F;p&gt;
&lt;p&gt;Olhando para a questão do Rust agora, é possível que &lt;code&gt;BTreeMap&lt;&#x2F;code&gt; tenha um desempenho melhor do que o &lt;code&gt;HashMap&lt;&#x2F;code&gt;, por ser poucos dados e não precisar chamar a função de hash. E sobre o &lt;code&gt;match&lt;&#x2F;code&gt;, não sei como ele foi implementado na linguagem, se ele seguiria uma ordem sequencial, como na primeira abordagem mostrada, ou se conseguiria fazer alguma otimização como no &lt;code&gt;if&lt;&#x2F;code&gt; aninhado. Porém para as poucas condições do problema a diferença no tempo seria mínima.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Nos exemplos foram utilizados valores 0, por não ser o foco da discussão, e seus valores mudar na parte 1 e 2, mas uma implementação real para resolver o problema traria os pontos ganhos em cada condição.&lt;&#x2F;p&gt;
&lt;p&gt;Para um universo de 9 possibilidades diferentes, como no problema do dia 2 do Advent of Code, qualquer uma das soluções apresentadas vai conseguir atender. Porém isso não muda o fato de algumas serem mais otimizadas que outras, e que a lógica utilizada poderiam ser reaproveitada, e que conseguiriam lidar melhor com problemas onde existem muito mais possibilidades a serem analisadas.&lt;&#x2F;p&gt;
&lt;p&gt;Também existe uma discussão se seria mais eficiente tratar a string inteira (&lt;code&gt;&#x27;A X&#x27;&lt;&#x2F;code&gt;), ou processar isso e tratar como tuplas (&lt;code&gt;(&#x27;A&#x27;, &#x27;X&#x27;)&lt;&#x2F;code&gt;). Em outros casos poderia ser tratar direto a string, ou converter para um número inteiro. Quanto menos conversões necessárias melhor, porém as vezes isso poderia mudar a complexidade de uma operação como comparação, o que valeria pagar o custo para converter o dado.&lt;&#x2F;p&gt;
&lt;p&gt;Infelizmente no Python não existe a possibilidade de escolher a implementação do dicionário, ele sempre funcionará como uma tabela de espalhamento, e por isso valores que não podem ser convertidos para hash não podem ser utilizados como chaves (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;library&#x2F;stdtypes.html#mapping-types-dict&quot;&gt;documentação oficial&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;E todas essas otimizações fazem pouquíssima diferença para esse problema, mas essas mesmas ideias podem ser aplicadas a outros problemas e lá trazerem diferenças significativas. Estou usando esse problema só como desculpa para falar desses detalhes.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Discussão sobre o Advent of Code 2022 - Dia 1: Processando lista de valores</title>
        <published>2022-12-01T00:00:00+00:00</published>
        <updated>2022-12-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-01/"/>
        <id>https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-01/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/advent-of-code-2022-dia-01/">&lt;p&gt;Começou o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&quot;&gt;Advent of Code deste ano&lt;&#x2F;a&gt;, que embora tenha uma competição de quem resolve primeiro os problemas propostos, também é uma oportunidade para se desafiar e treinar o entendimento e a resolução de problemas. Porém aqui não quero discutir como resolver os problemas, mas sim pensar sobre os algoritmos usados para resolvê-los.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;o-problema-do-dia-1&quot;&gt;O problema do dia 1&lt;&#x2F;h2&gt;
&lt;p&gt;Para quem não viu, ou se quiser relembrar, o problema do dia 1 é o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&#x2F;day&#x2F;1&quot;&gt;&quot;contando calorias&quot;&lt;&#x2F;a&gt;, e que consiste basicamente de somar grupos de números e encontrar as maiores somas.&lt;&#x2F;p&gt;
&lt;p&gt;Recomendo primeiramente tentar resolver esse problema. Se tiver dificuldades, ou se quiser ter uma ideia melhor da linha de pensamento que vou usar como base da discussão, recomendo o vídeo do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;rochacbruno&quot;&gt;Bruno Rocha&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;iframe
    width=&quot;640&quot;
    height=&quot;360&quot;
    src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;lzD2geCWjB4&quot;
    allowfullscreen
    style=&quot;border: 0; max-width: 100%;&quot;
&gt;&lt;&#x2F;iframe&gt;
&lt;h2 id=&quot;1a-questao-uso-de-memoria&quot;&gt;1ª Questão - Uso de memória&lt;&#x2F;h2&gt;
&lt;p&gt;Muitas soluções mais simplistas e rápidas de se programar acabam criando várias cópias dos valores em memória, por exemplo: guardando todo o conteúdo do arquivo de entrada em uma variável, criando uma lista (ou array) com todo os valores, outra lista com os valores convertidos para inteiro, outra com a soma dos valores... Para exemplificar em Python, seria algo como:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;entrada1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;entrada.txt&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;read&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;entrada2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; entrada.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;strip&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;entrada3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [e.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; entrada2]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;entrada4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;(f)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; e]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; entrada3]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;entrada5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;(e)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; entrada4]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse exemplo estou exagerando em criar várias variáveis, muitas dessas instruções poderiam ser feitas juntas de outras, economizando algumas linhas (e variáveis também). Porém a questão que quero apontar aqui é que todos os dados são carregados para a memória do computador de uma vez só, e depois são criadas várias cópias ligeiramente diferentes do mesmo dado (convertido de string para inteiro, lista da soma dos valores no lugar da lista de lista...).&lt;&#x2F;p&gt;
&lt;p&gt;Isso pode ser um problema quando existem muitos dados para tratar, como no caso de arquivos com gigabytes de dados, ou quando se tem uma quantidade limitada de memória RAM, como em um dispositivo embarcado ou um AWS Lambda. E isso continua sendo um problema mesmo reduzindo a quantidade de cópias dos valores para duas, ou até mesmo uma única cópia em memória, só será necessário mais dados para o problema ocorrer.&lt;&#x2F;p&gt;
&lt;p&gt;A solução apresentada pelo Bruno Rocha é bastante interessante nesse ponto, que pelo menos para a parte 1 do problema, vai lendo, processando e descartando dados conforme eles são e deixam de ser necessários, com a exceção da entrada que é lida inteira, mas poderia ser adaptada para uma solução com um buffer que leia poucos bytes por vez, ou conforme for necessário. O código dele se aproveita bastante das funcionalidades do Rust para isso, mas também é possível fazer algo semelhante sem essas funcionalidades, ou em outras linguagens, exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;max_calorias&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;calorias&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; linha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; open&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;entrada.txt&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    linha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; linha.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;strip&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; linha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        max_calorias&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = max&lt;&#x2F;span&gt;&lt;span&gt;(calorias, max_calorias)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        calorias&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        calorias&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; += int&lt;&#x2F;span&gt;&lt;span&gt;(linha)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;max_calorias&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = max&lt;&#x2F;span&gt;&lt;span&gt;(calorias, max_calorias)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(max_calorias)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nessa solução apresentada ainda existe alguma duplicidade de valores na memória, como ter ao mesmo tempo o valor como string e inteiro, mas se limita apenas ao que está sendo tratando no momento e não tudo, não usa nenhuma lista, por exemplo. Ela também permite tratar arquivos de qualquer tamanho com pouca memória RAM, até mesmo com uma quantidade de memória RAM menor do que o tamanho do arquivo de entrada.&lt;&#x2F;p&gt;
&lt;p&gt;Entretanto a parte 2 do problema exige um pouco mais de memória, já que não busca só o maior valor, vou discutir sobre isso junto com a próxima questão.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2a-questao-ordenacao&quot;&gt;2ª Questão - Ordenação&lt;&#x2F;h2&gt;
&lt;p&gt;A parte 2 do problema pede a soma dos 3 maiores valores, uma forma de resolver isso é gerar uma lista com as somas dos valores, ordenar eles e pegar os 3 maiores. Além dessa solução precisar de mais memória conforme a quantidade de valores, ela também irá ordenar todos os valores, sendo que precisamos apenas dos 3 primeiros (ou últimos, dependendo da lógica e ponto de vista). Isso é um problema porque algoritmos de ordenação tendem a ter complexidade ciclomática &lt;code&gt;O(n * log2(n))&lt;&#x2F;code&gt;, que basicamente diz que o tempo para ordenar os valores cresce (demora mais para rodar) conforme tem mais valores para ordenar (&lt;code&gt;n&lt;&#x2F;code&gt; é igual a quantidade de valores nesse caso), devido a maior quantidade de comparações de valores necessárias para isso.&lt;&#x2F;p&gt;
&lt;p&gt;Considerando &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&#x2F;day&#x2F;1&#x2F;input&quot;&gt;a entrada presente no problema&lt;&#x2F;a&gt;, são 241 somas que devem ser ordenadas para se buscar as 3 maiores, isso da algo em torno da grandeza de 1900 comparações (&lt;code&gt;241 * log2(241)&lt;&#x2F;code&gt;) para se ordenar essa lista com um algoritmo como o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Quicksort&quot;&gt;quick sort&lt;&#x2F;a&gt;, que é largamente utilizado. Porém olhando o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Bubble_sort&quot;&gt;bubble sort&lt;&#x2F;a&gt;, que embora seja conhecidamente mais lento que o quick sort na maioria dos casos, e por isso normalmente não utilizado quando se precisa de desempenho, ele permite interromper sua execução logo após a ordenação dos 3 valores desejados, sem precisar ordenar desnecessariamente os demais. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;...&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; j&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(valores)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; valores[j]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; valores[i]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            aux&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; valores[i]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            valores[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; valores[j]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            valores[j]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; aux&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(valores[:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Isso faria a ordenação apenas dos 3 valores desejados com 717 comparações, algo em torno da grandeza de &lt;code&gt;O(3 * n)&lt;&#x2F;code&gt;, sendo 3 o número de valores desejados (&lt;code&gt;3 * 241 = 723&lt;&#x2F;code&gt; apenas para comparação). Desta forma são menos comparações que o quick sort, e bem menos do que as 28920 comparações que a execução completa do bubble sort levaria.&lt;&#x2F;p&gt;
&lt;p&gt;Entretanto o problema aqui está no tamanho da lista a ser ordenada. Imagine que se em vez de ordenar a lista só no final, toda vez que um valor fosse inserido na lista isso já fosse feito de forma ordenada, e descartando os valores desnecessários (menores que os 3 maiores já encontrados até aquele momento). Isso reduziria muito a lista a ser ordenada (4 valores, os 3 maiores e o valor sendo processado), e sabendo que os valores que estão na lista já estão ordenados, não é necessário ordená-los novamente, só inserir o novo valor no local certo. Desta forma seria necessário menos comparações, o código rodaria mais rápido, e com o descarte dos valores menores, voltaria a ser possível executá-lo com uma quantidade reduzida de memória RAM.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Nesse texto discuti sobre variações de algoritmos que resolvem o problema visando tempo de execução e consumo de memória, que é um foco diferente da competição do Advent of Code em si, que é de quem dá a resposta certa mais próximo da liberação do problema. Também é diferente do foco das competições de programação que visam apenas tempo de execução (e não consideram uso de memória).&lt;&#x2F;p&gt;
&lt;p&gt;Para a competição do Advent of Code, uma solução mais rápida de programar pode ser mais interessante, mesmo que em alguns casos ela demore mais para executar, visto que a velocidade do processador pode compensar o tempo que uma pessoa levaria para pensar e implementar um algoritmo mais otimizado. Isso mostra que dependendo da onde for utilizado, nem sempre uma solução mais otimizada para o computador é a melhor.&lt;&#x2F;p&gt;
&lt;p&gt;Outro ponto positivo de participar do Advent of Code são os exercícios de tentar entender o problema e de tentar pensar em como representar os dados para que um algoritmo possa processá-los, mesmo sem conseguir encontrar a resposta, só de pensar nas estruturas de dados e organização deles pode ser um ótimo exercício.&lt;&#x2F;p&gt;
&lt;p&gt;Eu não pretendo fazer uma análise dessa de cada dia, até porque são bastantes problemas, e os mais avançados tendem a ser mais complexos e misturar várias coisas. Esses pontos que levantei provavelmente vão se repetir nos próximos problemas, o que ficaria redundante também. Mas volto a escrever outro texto se eu observar alguma questão que seja interessante trazer para a discussão.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Questões para estudo de algoritmos</title>
        <published>2022-10-17T00:00:00+00:00</published>
        <updated>2022-10-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/questoes-para-estudo-de-algoritmos/"/>
        <id>https://eduardoklosowski.github.io/blog/questoes-para-estudo-de-algoritmos/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/questoes-para-estudo-de-algoritmos/">&lt;p&gt;Recentemente li o texto do Maycon Alves, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mayconbalves.com.br&#x2F;3-algoritmos-para-voc%C3%AA-sua-l%C3%B3gica&#x2F;&quot;&gt;&quot;3 algoritmos para você sua lógica&quot;&lt;&#x2F;a&gt;, onde são apresentados 3 problemas para treinar a lógica e escrita de algoritmos: &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Fatorial&quot;&gt;cálculo de fatorial&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;N%C3%BAmero_primo&quot;&gt;identificar se um número é primo&lt;&#x2F;a&gt;, e &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Sequ%C3%AAncia_de_Fibonacci&quot;&gt;calcular os valores da sequência de Fibonacci&lt;&#x2F;a&gt;. São problemas interessantes, e após resolvê-los, pode-se fazer outras perguntas que levam a um entendimento mais profundo desses algoritmos. Eu recomendo que leiam o texto do Maycon primeiro e tentem implementar uma solução para esses problemas propostos, e com isso feito, vamos discutir um pouco sobre eles.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;analisando-as-solucoes&quot;&gt;Analisando as soluções&lt;&#x2F;h2&gt;
&lt;p&gt;No texto do Maycon, tem uma dica sobre o problema da sequência de Fibonacci, onde é dito que ele pode ser resolvido usando recursividade ou &lt;em&gt;loops&lt;&#x2F;em&gt;. Vamos analisar essas opções.&lt;&#x2F;p&gt;
&lt;p&gt;Uma solução recursiva pode ser implementada como a baixo. O código dessa solução é simples e se aproxima bastante da descrição matemática do problema.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fibonacci&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fibonacci&lt;&#x2F;span&gt;&lt;span&gt;(n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fibonacci&lt;&#x2F;span&gt;&lt;span&gt;(n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Enquanto uma solução iterativa (com &lt;em&gt;loop&lt;&#x2F;em&gt;) pode ser um pouco mais complicada de se ler:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fibonacci&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        a, b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; b, a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essas mesmas técnicas podem ser utilizadas para resolver o cálculo do fatorial. Onde uma implementação recursiva e outra iterativa podem ser vistas a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fatorial&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fatorial&lt;&#x2F;span&gt;&lt;span&gt;(n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fatorial&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *=&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Com essas soluções implementadas, vem uma pergunta: Existe alguma diferença entre elas, além da diferença de como isso está expresso no código? Um primeiro teste que pode ser feito é de desempenho visando observar quanto tempo cada implementação leva para calcular a resposta. Os testes foram executados em um notebook com processador Intel Core i7-6500U CPU @ 2.50GHz, memória RAM DDR4 2133MHz, no Python 3.9.2 do Debian 11, desativamente o &lt;em&gt;garbage collector&lt;&#x2F;em&gt; do Python durante a execução das funções para ter um resultado com menos variação, apresentados como uma média de 10 execuções (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;blog&#x2F;tree&#x2F;main&#x2F;content&#x2F;2022-10-17-questoes-para-estudo-de-algoritmos&quot;&gt;código utilizado&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;O gráfico a baixo mostra o tempo de execução das implementações que calculam os valores da sequência de Fibonacci, onde é possível observar que a implementação iterativa mantém uma linearidade do tempo conforme vai se pedindo números maiores da sequência, diferente da implementação recursiva, que a cada valor quase dobra o tempo de execução.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;questoes-para-estudo-de-algoritmos&#x2F;fibonacci.svg&quot; alt=&quot;Gráfico do tempo de execução Fibonacci&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;E a baixo pode-se observar o gráfico para as implementações que calculam o fatorial, que devido aos tempos serem mais baixos, possui uma variação um pouco maior, e é possível observar uma tendência de reta para as duas implementações, com a implementação recursiva tendo um ângulo um pouco mais íngreme, implicando em um algoritmo mais lento.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;questoes-para-estudo-de-algoritmos&#x2F;fatorial.svg&quot; alt=&quot;Gráfico do tempo de execução fatorial&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A partir desses dois gráficos algumas perguntas podem ser feitas: Por que a implementação recursiva do Fibonacci apresentou uma curva que se aproxima de uma exponencial e não de uma reta como as demais? Qual a diferença para a implementação recursiva do fatorial que explicar isso? Implementações recursivas são sempre piores que as implementações iterativas, ou existem casos em elas superem ou se equivalem as iterativas?&lt;&#x2F;p&gt;
&lt;p&gt;Saindo um pouco desses gráficos, outras questões podem ser levantadas, como: Existe mais algum aspecto ou característica além do tempo de execução (e facilidade de leitura do código) para a escolha entre uma implementação ou outra? Considerando que essas funções vão rodar em um servidor, existe alguma coisa que possa ser feita para melhorar a performance dessas funções, como reaproveitar resultados já calculados para se calcular novos resultados? Como isso poderia ser feito? Quais são as desvantagens dessa abordagem?&lt;&#x2F;p&gt;
&lt;p&gt;Olhando para o problema de verificar se um número é primo, existe o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Crivo_de_Erat%C3%B3stenes&quot;&gt;crivo de Eratóstenes&lt;&#x2F;a&gt;, ele é uma implementação eficiente? Existem casos em que ele pode ser uma boa solução ou não? O exemplo a baixo (retirado da Wikipédia) mostra o processo para encontrar todos os números primos até 120, existe alguma forma de adaptá-lo para executar diversas vezes reaproveitando o que já foi calculado, como sempre retornar o próximo número primo?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;upload.wikimedia.org&#x2F;wikipedia&#x2F;commons&#x2F;8&#x2F;8c&#x2F;New_Animation_Sieve_of_Eratosthenes.gif&quot; alt=&quot;Exemplo do crivo de Eratóstenes&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Se você nunca se deparou com perguntas desse tipo, seja bem-vindo a área de análise de algoritmos, onde após se ter uma solução, busca-se analisar e descrever o comportamento do algoritmo, e até a busca de algoritmos mais eficientes. E trazendo para o dia a dia de um desenvolvedor, essas questões podem ser a resposta do motivo do código funcionar muito bem no computador de quem desenvolveu, mas demorar muito ou apresentar problemas para rodar no servidor de produção, ou com o tempo (e crescimento do volume de dados) começar a dar problemas.&lt;&#x2F;p&gt;
&lt;p&gt;Nesse artigo eu apenas levantei as perguntas, deixo que cada um busque as respostas, que existem. Sintam-se livres para me procurar para discutir alguma questão ou orientações para encontrar as respostas, seja nos comentários do texto no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;dev.to&#x2F;eduardoklosowski&#x2F;questoes-para-estudo-de-algoritmos-5dab&quot;&gt;dev.to&lt;&#x2F;a&gt; ou no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;eduklosowski&quot;&gt;Twitter&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Criando e executando contêineres Docker ARM em arquitetura AMD64</title>
        <published>2022-03-01T00:00:00+00:00</published>
        <updated>2022-03-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/docker-arm-em-amd64/"/>
        <id>https://eduardoklosowski.github.io/blog/docker-arm-em-amd64/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/docker-arm-em-amd64/">&lt;p&gt;Cada vez é mais comum encontrar ambientes com a arquitetura &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Arquitetura_ARM&quot;&gt;ARM&lt;&#x2F;a&gt;, seja um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.raspberrypi.org&#x2F;&quot;&gt;Raspberry Pi&lt;&#x2F;a&gt; ou &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.oracle.com&#x2F;br&#x2F;cloud&#x2F;compute&#x2F;arm&#x2F;&quot;&gt;servidores na nuvem&lt;&#x2F;a&gt; buscando reduzir custos, ou até mesmo no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Apple_M1&quot;&gt;Apple M1&lt;&#x2F;a&gt;. Ela difere da arquitetura mais comumente encontrada nos computadores (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;AMD64&quot;&gt;AMD64&lt;&#x2F;a&gt; também conhecido por x86_64). Essa diferença gera dificuldades para criar e executar contêineres de um ambiente em outro, dado que essas arquiteturas não possuem nativamente um modo de compatibilidade. Esse texto discutirá como executar programas para a arquitetura ARM em computadores AMD64, e como isso pode ser utilizado para gerar e executar imagens &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.docker.com&#x2F;&quot;&gt;Docker&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;como-executando-programas-de-outra-arquitetura&quot;&gt;Como executando programas de outra arquitetura?&lt;&#x2F;h2&gt;
&lt;p&gt;Para se executar algo em qualquer arquitetura deve existir um programa com instruções que a CPU entenda. Operações similares podem ter instruções completamente diferentes em diferentes arquiteturas, e as arquiteturas podem ter desenhos diferentes de hardware, como variação na quantidade e tamanho dos registradores. Essas diferenças geram incompatibilidades e não permitem que um programa compilado para uma arquitetura seja executado em outra.&lt;&#x2F;p&gt;
&lt;p&gt;Porém, como existem operações similares, ou formas de se conseguir resultados equivalentes em diferentes arquiteturas, é possível adicionar uma camada que traduza as instruções de uma arquitetura para seu equivalente na arquitetura da CPU onde deseja-se executar o programa.&lt;&#x2F;p&gt;
&lt;p&gt;Um programa que faz essa tradução das instruções é o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.qemu.org&#x2F;&quot;&gt;QEMU&lt;&#x2F;a&gt;, que pode ser usado tanto para emular ou virtualizar tanto uma máquina inteira (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;M%C3%A1quina_virtual&quot;&gt;máquina virtual&lt;&#x2F;a&gt;) quanto apenas um processo. Nesse caso, como serão executados apenas programas para &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Linux&quot;&gt;Linux&lt;&#x2F;a&gt; trocando a arquitetura do processador, é possível emular apenas um processador ARM para esses programas, sem a necessidade de emular ou virtualizar uma máquina virtual inteira, o que incluiria até o sistema operacional.&lt;&#x2F;p&gt;
&lt;p&gt;Para instalar esse emular no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.debian.org&#x2F;&quot;&gt;Debian&lt;&#x2F;a&gt; (ou derivados como &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ubuntu.com&#x2F;&quot;&gt;Ubuntu&lt;&#x2F;a&gt;) existe o pacote &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;packages.debian.org&#x2F;stable&#x2F;qemu-user&quot;&gt;&lt;code&gt;qemu-user&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, porém ele é compilado de forma a carregar diversos arquivos &lt;code&gt;.so&lt;&#x2F;code&gt; (o equivalente as &lt;code&gt;.dll&lt;&#x2F;code&gt; do Windows), e como deseja-se executar contêineres, que fazem &lt;code&gt;chroot&lt;&#x2F;code&gt; como já expliquei na série &lt;a
    href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;series&#x2F;isolamento-de-aplicacoes&#x2F;&quot;
&gt;Isolamento de aplicações&lt;&#x2F;a&gt;
, deve-se optar pela opção que inclui as funções dos &lt;code&gt;.so&lt;&#x2F;code&gt; no próprio binário, oferecida pelo pacote &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;packages.debian.org&#x2F;stable&#x2F;qemu-user-static&quot;&gt;&lt;code&gt;qemu-user-static&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. Isso permite executar um programa compilado para ARM 32 bits chamando o emulador e passando o binário como argumento, exemplo &lt;code&gt;qemu-arm-static .&#x2F;programa&lt;&#x2F;code&gt;, ou &lt;code&gt;qemu-aarch64-static .&#x2F;programa&lt;&#x2F;code&gt; para ARM 64 bits.&lt;&#x2F;p&gt;
&lt;p&gt;Também é possível usar a interface do módulo &lt;code&gt;binfmt_misc&lt;&#x2F;code&gt; para informar ao kernel Linux, que quando for solicitado para ele executar um programa para ARM, isso deve ser feito através desse emulador. No Debian essa configuração é feita automaticamente pelo pacote do QEMU, bastando ter o pacote &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;packages.debian.org&#x2F;stable&#x2F;binfmt-support&quot;&gt;&lt;code&gt;binfmt-support&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; instalado (ele também pode ser instalado depois do QEMU). Para verificar essa configuração é possível executar o comando &lt;code&gt;update-binfmts --display qemu-arm&lt;&#x2F;code&gt; como &lt;code&gt;root&lt;&#x2F;code&gt;, ou ler o arquivo &lt;code&gt;&#x2F;proc&#x2F;sys&#x2F;fs&#x2F;binfmt_misc&#x2F;qemu-arm&lt;&#x2F;code&gt; com qualquer usuário, e trocando &lt;code&gt;qemu-arm&lt;&#x2F;code&gt; para &lt;code&gt;qemu-aarch64&lt;&#x2F;code&gt; para testar a configuração de 64 bits. Segue um exemplo dessas configurações (observe o interpretador configurado, que é um link simbólico para o QEMU):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# update-binfmts --display qemu-arm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;qemu-arm (enabled):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     package = qemu-user-static&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        type = magic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      offset = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       magic = \x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mask = \xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; interpreter = &#x2F;usr&#x2F;libexec&#x2F;qemu-binfmt&#x2F;arm-binfmt-P&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    detector =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ cat &#x2F;proc&#x2F;sys&#x2F;fs&#x2F;binfmt_misc&#x2F;qemu-arm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;enabled&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;interpreter &#x2F;usr&#x2F;libexec&#x2F;qemu-binfmt&#x2F;arm-binfmt-P&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flags: POCF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;offset 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;magic 7f454c4601010100000000000000000002002800&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mask ffffffffffffff00fffffffffffffffffeffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ls -la &#x2F;usr&#x2F;libexec&#x2F;qemu-binfmt&#x2F;arm-binfmt-P&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 25 set 29 07:14 &#x2F;usr&#x2F;libexec&#x2F;qemu-binfmt&#x2F;arm-binfmt-P -&amp;gt; ..&#x2F;..&#x2F;bin&#x2F;qemu-arm-static&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Assim ao executar o comando &lt;code&gt;apt install qemu-user-static binfmt-support&lt;&#x2F;code&gt; se torna possível executar um programa compilado para ARM de forma transparente, como se fosse nativo, exemplo &lt;code&gt;.&#x2F;programa&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;criando-e-executando-conteineres-docker&quot;&gt;Criando e executando contêineres Docker&lt;&#x2F;h2&gt;
&lt;p&gt;Se a instalação e configuração do QEMU foi feita corretamente, já é possível usar contêineres ARM, bastando informar a arquitetura com o parâmetro &lt;code&gt;--platform linux&#x2F;arm64&lt;&#x2F;code&gt; ao executar os comandos do Docker, exemplo &lt;code&gt;docker run --platform linux&#x2F;arm64 -it --rm alpine&lt;&#x2F;code&gt;. Isso pode ser confirmado executado o comando &lt;code&gt;uname -m&lt;&#x2F;code&gt; dentro e fora do contêiner mostrando qual a arquitetura do sistema.&lt;&#x2F;p&gt;
&lt;p&gt;Caso ao executar algum comando do Docker ocorra um erro parecido com &lt;code&gt;standard_init_linux.go:228: exec user process caused: exec format error&lt;&#x2F;code&gt;, recomendo voltar e revisar a configuração do QEMU e &lt;code&gt;binfmt_misc&lt;&#x2F;code&gt;, visto que o Docker não conseguiu executar o programa dentro do contêiner.&lt;&#x2F;p&gt;
&lt;p&gt;Um detalhe a ser observado é que existe uma imagem chamada &lt;code&gt;alpine:latest&lt;&#x2F;code&gt; para AMD64 e outra para ARM, e ao fazer o pull de uma, ela vai retirar a tag da outra se existir no sistema, então é sempre bom verificar antes qual a imagem que existe localmente ou fazer pull para evitar misturar as imagens, o que causaria erros. A baixo um exemplo do &lt;code&gt;docker image ls&lt;&#x2F;code&gt; ao executar o pull tanto da imagem ARM quanto AMD64:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;REPOSITORY   TAG       IMAGE ID       CREATED        SIZE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;alpine       &amp;lt;none&amp;gt;    8e1d7573f448   3 months ago   5.33MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;alpine       latest    c059bfaa849c   3 months ago   5.59MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Seguindo o que foi visto até aqui, para se criar uma imagem para ARM pode-se utilizar o comando &lt;code&gt;docker build --platform linux&#x2F;arm64 --pull -t &amp;lt;nome_imagem&amp;gt; .&lt;&#x2F;code&gt;, e trocando &lt;code&gt;linux&#x2F;arm64&lt;&#x2F;code&gt; por &lt;code&gt;linux&#x2F;amd64&lt;&#x2F;code&gt; criar a mesma imagem para AMD64, desde que no repositório de imagens (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;&quot;&gt;Docker Hub&lt;&#x2F;a&gt; por exemplo) existam as imagens usadas como base para ambas arquiteturas com o mesmo nome e tag. Também é válido observar que se as imagens geradas tiverem o mesmo nome, a última imagem gerada vai sobrescrever a tag da anterior, que se torna acessível apenas pelo ID.&lt;&#x2F;p&gt;
&lt;p&gt;Uma alternativa ao parâmetro &lt;code&gt;--platform&lt;&#x2F;code&gt; é a variável de ambiente &lt;code&gt;DOCKER_DEFAULT_PLATFORM&lt;&#x2F;code&gt;. A vantagem dessa opção é que ela pode ser definida em algum arquivo de configuração, como no &lt;code&gt;~&#x2F;.bashrc&lt;&#x2F;code&gt;, adicionado &lt;code&gt;export DOCKER_DEFAULT_PLATFORM=linux&#x2F;arm64&lt;&#x2F;code&gt;, e deixa de ser necessário informar o parâmetro &lt;code&gt;--platform&lt;&#x2F;code&gt; toda vez que o Docker for executado.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Embora as arquiteturas AMD64 e ARM não sejam compatíveis é possível utilizar o QEMU para fazer a execução de programas ARM em CPUs da arquitetura AMD64. Porém, como isso é feito por software, e não pelo hardware, pode ocorrer problemas de desempenho, o qual ainda deve ser verificado.&lt;&#x2F;p&gt;
&lt;p&gt;Dado que o sistema consegue executar programas ARM de forma transparente, isso se reflete no Docker, permitindo tanto criar imagens para ARM, quanto executá-las, bastando observar a limitação da lincagem dinâmica com arquivos &lt;code&gt;.so&lt;&#x2F;code&gt; devido ao &lt;code&gt;chroot&lt;&#x2F;code&gt; que ocorre.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Exemplo de AWS API Gateway com Lambda pelo Terraform</title>
        <published>2021-09-07T00:00:00+00:00</published>
        <updated>2021-09-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/exemplo-aws-api-gateway/"/>
        <id>https://eduardoklosowski.github.io/blog/exemplo-aws-api-gateway/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/exemplo-aws-api-gateway/">&lt;p&gt;Estou estudando sobre a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;pt&#x2F;&quot;&gt;AWS&lt;&#x2F;a&gt; e algumas ferramentas. Para praticar o aprendido resolvi montar de exemplo uma &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.restapitutorial.com&#x2F;&quot;&gt;API Rest&lt;&#x2F;a&gt; utilizando o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;apigateway&#x2F;&quot;&gt;API Gateway&lt;&#x2F;a&gt; rodando o código em &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;lambda&#x2F;&quot;&gt;lambdas&lt;&#x2F;a&gt;, e para criar o ambiente optei pelo &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.terraform.io&#x2F;&quot;&gt;Terraform&lt;&#x2F;a&gt; conectando no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;localstack.cloud&#x2F;&quot;&gt;LocalStack&lt;&#x2F;a&gt; (já que esse pode rodar localmente e não exige uma conta na AWS). Nesse texto descreverei o processo e quais tecnologias utilizei.&lt;&#x2F;p&gt;
&lt;p&gt;Primeiramente, para organizar o que precisaria implementar na &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.restapitutorial.com&#x2F;&quot;&gt;API Rest&lt;&#x2F;a&gt; utilizei o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.openapis.org&#x2F;&quot;&gt;OpenAPI&lt;&#x2F;a&gt;, que já serve de documentação da API também. O resultado &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;exemplo-aws-api-gateway&#x2F;blob&#x2F;main&#x2F;openapi.yml&quot;&gt;foi um YAML&lt;&#x2F;a&gt; que pode ser visualizado em algum editor que segue o padrão do OpenAPI, como o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;editor.swagger.io&#x2F;&quot;&gt;Swagger Editor&lt;&#x2F;a&gt; (que atualmente apresenta alguns erros por não implementar ainda a versão utilizada da especificação).&lt;&#x2F;p&gt;
&lt;p&gt;Com a documentação da API pronta, o próximo passo foi subir o ambiente de nuvem, que optei pelo &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;localstack.cloud&#x2F;&quot;&gt;LocalStack&lt;&#x2F;a&gt; que eu poderia rodar no meu próprio computador. Porém a versão gratuita do LocalStack não oferece suporte ao &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;rds&#x2F;&quot;&gt;RDS&lt;&#x2F;a&gt; para criar o banco de dados, então resolvi rodar o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.postgresql.org&#x2F;&quot;&gt;PostgreSQL&lt;&#x2F;a&gt; por fora do ambiente de nuvem simulado pelo LocalStack. Para rodar tanto o PostgreSQL quanto o LocalStack optei por executá-los através de contêineres gerenciados pelo &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.docker.com&#x2F;compose&#x2F;&quot;&gt;Docker Compose&lt;&#x2F;a&gt;, que também é feito através de um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;exemplo-aws-api-gateway&#x2F;blob&#x2F;main&#x2F;docker-compose.yml&quot;&gt;YAML&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Com o LocalStack rodando é necessário uma forma de interagir com ele, uma delas é através do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;cli&#x2F;&quot;&gt;AWS CLI&lt;&#x2F;a&gt;, porém optei pelo &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;localstack&#x2F;awscli-local&quot;&gt;LocalStack AWS CLI&lt;&#x2F;a&gt; que já configura os parâmetros necessários para se conectar no LocalStack em vez da AWS. Sua instalação pode ser feita através do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pip.pypa.io&#x2F;en&#x2F;stable&#x2F;&quot;&gt;pip&lt;&#x2F;a&gt; com o pacote &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pypi.org&#x2F;project&#x2F;awscli-local&#x2F;&quot;&gt;awscli-local&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Para processar as requisições optei por utilizar &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;lambda&#x2F;&quot;&gt;lambdas&lt;&#x2F;a&gt;, que nada mais são do que um serviço da AWS que permite a execução de funções sem precisar se preocupar com o servidor (máquina virtual) onde rodarão. Visando ter um código o mais simples possível, utilizei diretamente o driver do PostgreSQL para Python (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.psycopg.org&#x2F;&quot;&gt;psycopg2&lt;&#x2F;a&gt;), onde cada endereço da API seria &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;exemplo-aws-api-gateway&#x2F;blob&#x2F;main&#x2F;tarefa.py&quot;&gt;respondido pela execução de uma função distinta&lt;&#x2F;a&gt; (O readme do projeto detalha mais sobre os &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;exemplo-aws-api-gateway#lambdas&quot;&gt;comandos para interagir com os lambdas&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Com os lambdas prontos, é necessário disponibilizar sua execução através de endereços HTTP, que é justamente o que o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;apigateway&#x2F;&quot;&gt;API Gateway&lt;&#x2F;a&gt; faz. Nesse caso é necessário criar uma API, os caminhos dessa API e dizer quais métodos estão disponíveis, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;exemplo-aws-api-gateway#api-gateway&quot;&gt;associando-os aos lambdas&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Porém eu gostaria de utilizar também o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.terraform.io&#x2F;&quot;&gt;Terraform&lt;&#x2F;a&gt; para criar esses recursos no LocalStack, então optei por recomeçar a configuração do zero. Para &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;exemplo-aws-api-gateway#deploy-com-terraform&quot;&gt;configurar o ambiente pelo Terraform&lt;&#x2F;a&gt; basta criar um arquivo que descreva os &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;exemplo-aws-api-gateway#deploy-com-terraform&quot;&gt;recursos desejados&lt;&#x2F;a&gt;, porém por questão de organização optei por &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;exemplo-aws-api-gateway&#x2F;tree&#x2F;main&#x2F;terraform&quot;&gt;dividir em módulos&lt;&#x2F;a&gt; e com o arquivo de estado do Terraform em um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;s3&#x2F;&quot;&gt;bucket S3&lt;&#x2F;a&gt; simulando um ambiente que permite sua execução em computadores distintos.&lt;&#x2F;p&gt;
&lt;p&gt;Finalmente ao executar o Terraform obtive uma URL como &lt;code&gt;http:&#x2F;&#x2F;localhost:4566&#x2F;restapis&#x2F;mea14qi3dw&#x2F;main&#x2F;_user_request_&lt;&#x2F;code&gt; onde pude acessar a API a partir dela, o qual realizei testes usando o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;httpie.io&#x2F;&quot;&gt;HTTPie&lt;&#x2F;a&gt; devido a sua facilidade de uso, ou através da interface disponibilizada pelo Swagger Editor que já é integrado na documentação.&lt;&#x2F;p&gt;
&lt;p&gt;Caso deseje visualizar o processo de deploy com Terraform, segue um vídeo do procedimento sendo executado:&lt;&#x2F;p&gt;
&lt;script
    id=&quot;asciicast-433410&quot;
    src=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;433410.js&quot;
    async
&gt;&lt;&#x2F;script&gt;
&lt;p&gt;O repositório com o código utilizado está no meu &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;exemplo-aws-api-gateway&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Isolamento de aplicações: Docker</title>
        <published>2021-06-19T00:00:00+00:00</published>
        <updated>2021-06-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/aplicacao-isolamento-com-docker/"/>
        <id>https://eduardoklosowski.github.io/blog/aplicacao-isolamento-com-docker/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/aplicacao-isolamento-com-docker/">&lt;p&gt;Nos textos anteriores dessa série vimos como isolar uma aplicação nos contextos de sistema de arquivos, tabela de processos e pilha de rede. Porém isso pode se tornar um pouco complexo para ser gerenciado na mão, precisando executar algo como &lt;code&gt;ip netns exec app1 unshare -fp --mount-proc chroot &#x2F;media&#x2F;sistema bash&lt;&#x2F;code&gt; apenas para rodar um terminal dentro de determinados espaços de nomes, sem contar toda a configuração necessária para isso. Mas existem ferramentas que facilitam criar e executar aplicações dentre de espaço de nomes, o que hoje são conhecidas como contêineres.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;o-que-e-um-conteiner&quot;&gt;O que é um contêiner&lt;&#x2F;h2&gt;
&lt;p&gt;Contêiner é uma forma padronizada de entregar e executar uma aplicação, utilizando-se dos conceitos de espaço de nomes para criar um ambiente isolado para rodar a aplicação, dependendo o mínimo possível do sistema operacional do computador onde será executado, e para isso deve providenciar todos os arquivos e bibliotecas necessários para sua execução, o que normalmente é chamado de imagem.&lt;&#x2F;p&gt;
&lt;p&gt;A seguir serão discutidos como os conceitos visto até então de isolamento de aplicações são aplicados no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.docker.com&#x2F;&quot;&gt;Docker&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;isolamento-de-sistema-de-arquivos&quot;&gt;Isolamento de sistema de arquivos&lt;&#x2F;h3&gt;
&lt;p&gt;No texto sobre &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;aplicacao-isolamento-de-sistema-de-arquivos&#x2F;&quot;&gt;isolamento de sistema de arquivos&lt;&#x2F;a&gt; foi apresentado o uso do &lt;code&gt;debootstrap&lt;&#x2F;code&gt; para criar um diretório com a estrutura de um sistema operacional e o &lt;code&gt;chroot&lt;&#x2F;code&gt; para utilizá-lo como se fosse a raiz do sistema.&lt;&#x2F;p&gt;
&lt;p&gt;No Docker também é necessário uma estrutura de sistema de arquivos, contendo as dependências da aplicação, como bibliotecas e ferramentas. Olhando o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;debuerreotype&#x2F;docker-debian-artifacts&#x2F;tree&#x2F;dist-amd64&#x2F;buster&quot;&gt;repositório da imagem oficial do Debian para o Docker&lt;&#x2F;a&gt;, pode-se observar a existência de um arquivo &lt;code&gt;Dockerfile&lt;&#x2F;code&gt; que é o responsável por dizer como construir a imagem desse contêiner, e que utiliza um arquivo &lt;code&gt;rootfs.tar.xz&lt;&#x2F;code&gt;, ou seja, um arquivo que contem todo o sistema de arquivos necessário para o contêiner.&lt;&#x2F;p&gt;
&lt;p&gt;É possível repetir esse processo com o sistema criado pelo &lt;code&gt;debootstrap&lt;&#x2F;code&gt;, para isso basta navegar até o diretório onde ele foi criado e gerar um arquivo &lt;code&gt;tar&lt;&#x2F;code&gt; com seu conteúdo, compactando-o ou não.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &#x2F;media&#x2F;sistema&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;tar&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -cvf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; ..&#x2F;rootfs.tar .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Isso gerará um arquivo &lt;code&gt;rootfs.tar.xz&lt;&#x2F;code&gt; que deve ser colocado em um diretório junto com o arquivo &lt;code&gt;Dockerfile&lt;&#x2F;code&gt; a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; scratch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ADD&lt;&#x2F;span&gt;&lt;span&gt; rootfs.tar &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;CMD&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;bash&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Com esses dois arquivos prontos, para gerar a imagem do contêiner basta executar &lt;code&gt;docker build -t sistema .&lt;&#x2F;code&gt;, que gerará uma imagem com o nome de &lt;code&gt;sistema&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sending build context to Docker daemon  317.4MB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Step 1&#x2F;3 : FROM scratch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; ---&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Step 2&#x2F;3 : ADD rootfs.tar &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; ---&amp;gt; e8ca0bcee43d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Step 3&#x2F;3 : CMD [&amp;quot;bash&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; ---&amp;gt; Running in 84d7a3d758f9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Removing intermediate container 84d7a3d758f9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; ---&amp;gt; 94cdf37927fa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Successfully built 94cdf37927fa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Successfully tagged sistema:latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Com a imagem pronta, para iniciar um contêiner basta executar &lt;code&gt;docker run -it --rm sistema bash&lt;&#x2F;code&gt;. A principal vantagem dessa abordagem é a possibilidade de abrir um outro terminal, executar o mesmo comando e ter outro ambiente isolado, o qual pode ser repetido diversas vezes. Ou como será mostrado mais para frente, executar outro processo dentro do mesmo espaço de nomes.&lt;&#x2F;p&gt;
&lt;p&gt;Vale observar também como funciona o sistema de arquivos nas imagens dos contêineres. Sempre existe uma imagem base, que nesse caso foi a &lt;code&gt;scratch&lt;&#x2F;code&gt; que é um nome reservado para uma imagem em branco (sem nada dentro), e a partir dela cada comando do &lt;code&gt;Dockerfile&lt;&#x2F;code&gt; criou outra camada em cima dela. Imagine como se a imagem base fosse um desenho em uma folha de papel, e as camadas posteriores fossem um plástico transparente colocado por cima desse desenho, seria possível ver o desenho e desenhar em cima dele, porém tudo que for desenhado estaria no plástico e não no papel de baixo, e ao colocar outra camada, seria possível ver o plástico em baixo, e o papel ao fundo, mas tudo que fosse desenhado agora estaria no novo plástico colocado. Essa é a ideia de &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;C%C3%B3pia_em_grava%C3%A7%C3%A3o&quot;&gt;&lt;em&gt;copy-on-write&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; (COW), onde é possível ler o que estiver nas camadas mais a baixo, desde que elas não forem sobrescritas por algo nas camadas superiores, mas a gravação sempre ocorre na última camada.&lt;&#x2F;p&gt;
&lt;p&gt;E embora funcional, como o &lt;code&gt;debootstrap&lt;&#x2F;code&gt; gera um sistema operacional para ser instalado em um computador, ele adiciona diversos arquivos que não são necessários para o contêiner. Nesse exemplo o &lt;code&gt;rootfs.tar&lt;&#x2F;code&gt; gerado pelo &lt;code&gt;debootstrap&lt;&#x2F;code&gt; tem 302,7MiB contra 113,7MiB do mesmo arquivo no repositório da imagem Debian quando descompactado, e 59,4MiB contra 28,7MiB quando se compara os dois arquivos compactados (nesse caso o arquivo foi compactado com &lt;code&gt;xz -9 -e rootfs.tar&lt;&#x2F;code&gt;, a forma mais otimizada possível). Desta forma é recomendável utilizar a imagem oficial, que além de poupar o trabalho, é mais otimizada em relação ao espaço.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;isolamento-de-tabela-de-processos&quot;&gt;Isolamento de tabela de processos&lt;&#x2F;h2&gt;
&lt;p&gt;Além do isolamento de sistema de arquivos, o Docker também oferece o &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;aplicacao-isolamento-de-tabela-de-processos&#x2F;&quot;&gt;isolamento da tabela de processos&lt;&#x2F;a&gt;. Para visualizar isso é possível executar um processo como o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;nginx.org&#x2F;&quot;&gt;Nginx&lt;&#x2F;a&gt; dentro do contêiner com &lt;code&gt;nginx -g &#x27;daemon off;&#x27;&lt;&#x2F;code&gt; (depois de instalado com &lt;code&gt;apt install nginx&lt;&#x2F;code&gt;, por exemplo), e em outro terminal executar &lt;code&gt;docker exec -it gifted_darwin bash&lt;&#x2F;code&gt; para abrir um Bash dentro desse mesmo contêiner, e assim ser possível verificar os processos em execução dentro desse contêiner com &lt;code&gt;ps aux&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root         1  0.0  0.0   3988  3240 pts&#x2F;0    Ss   11:28   0:00 bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root       825  0.0  0.0  67700 12572 pts&#x2F;0    S+   11:30   0:00 nginx: master process nginx -g daemon off;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data   826  0.0  0.0  68084  3444 pts&#x2F;0    S+   11:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data   827  0.0  0.0  68084  3444 pts&#x2F;0    S+   11:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data   828  0.0  0.0  68084  3444 pts&#x2F;0    S+   11:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data   829  0.0  0.0  68084  3444 pts&#x2F;0    S+   11:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data   830  0.0  0.0  68084  3444 pts&#x2F;0    S+   11:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data   831  0.0  0.0  68084  3444 pts&#x2F;0    S+   11:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data   832  0.0  0.0  68084  3444 pts&#x2F;0    S+   11:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data   833  0.0  0.0  68084  3444 pts&#x2F;0    S+   11:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root       834  0.2  0.0   3868  3268 pts&#x2F;1    Ss   11:32   0:00 bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root       840  0.0  0.0   7640  2692 pts&#x2F;1    R+   11:32   0:00 ps aux&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Porém ao executar um &lt;code&gt;ps aux | grep nginx&lt;&#x2F;code&gt; fora do contêiner, os mesmos processos são visualizados, porém com os seus números de processos reais, uma vez que o Nginx está executando de verdade no kernel da máquina física.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root     14505  0.0  0.0  67700 12572 pts&#x2F;0    S+   08:30   0:00 nginx: master process nginx -g daemon off;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data 14506  0.0  0.0  68084  3444 pts&#x2F;0    S+   08:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data 14507  0.0  0.0  68084  3444 pts&#x2F;0    S+   08:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data 14508  0.0  0.0  68084  3444 pts&#x2F;0    S+   08:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data 14509  0.0  0.0  68084  3444 pts&#x2F;0    S+   08:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data 14510  0.0  0.0  68084  3444 pts&#x2F;0    S+   08:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data 14511  0.0  0.0  68084  3444 pts&#x2F;0    S+   08:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data 14512  0.0  0.0  68084  3444 pts&#x2F;0    S+   08:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;www-data 14513  0.0  0.0  68084  3444 pts&#x2F;0    S+   08:30   0:00 nginx: worker process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;isolamento-de-pilha-de-rede&quot;&gt;Isolamento de pilha de rede&lt;&#x2F;h3&gt;
&lt;p&gt;Em relação ao &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;aplicacao-isolamento-de-pilha-de-rede&#x2F;&quot;&gt;isolamento da pilha de rede&lt;&#x2F;a&gt;, o Docker apresenta algumas opções, como não permitir acesso a rede (&lt;code&gt;null&lt;&#x2F;code&gt;), utilizar a mesma pilha do sistema (&lt;code&gt;host&lt;&#x2F;code&gt;), ou utilizar uma rede virtual semelhante a feita anteriormente de forma manual (&lt;code&gt;bridge&lt;&#x2F;code&gt;). Por padrão todos os contêineres são executados dentro da rede &lt;code&gt;bridge&lt;&#x2F;code&gt;, porém é possível criar redes distintas para alguns contêineres também.&lt;&#x2F;p&gt;
&lt;p&gt;As redes disponíveis podem ser verificadas com o comando &lt;code&gt;docker network ls&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NETWORK ID     NAME                DRIVER    SCOPE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1e363194a6f7   bridge              bridge    local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;44ff21ce424a   host                host      local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;e69eb4f8b6e8   none                null      local&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Fora do contêiner é possível verificar os endereços que o computador tem em cada rede através do comando &lt;code&gt;ip addr&lt;&#x2F;code&gt;, procurando as interfaces de rede começando com &lt;code&gt;docker&lt;&#x2F;code&gt; seguida de algum número. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6: docker0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    link&#x2F;ether 02:42:05:6f:f2:38 brd ff:ff:ff:ff:ff:ff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    inet 172.17.0.1&#x2F;16 brd 172.17.255.255 scope global docker0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       valid_lft forever preferred_lft forever&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    inet6 fe80::42:5ff:fe6f:f238&#x2F;64 scope link&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       valid_lft forever preferred_lft forever&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ao executar o mesmo comando dentro do contêiner são exibidos seus endereços da pilha de rede:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    link&#x2F;loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    inet 127.0.0.1&#x2F;8 scope host lo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       valid_lft forever preferred_lft forever&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11: eth0@if12: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    link&#x2F;ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    inet 172.17.0.2&#x2F;16 brd 172.17.255.255 scope global eth0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       valid_lft forever preferred_lft forever&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Porém caso queira não criar uma nova pilha de rede para o contêiner, é possível adicionar o parâmetro &lt;code&gt;--network host&lt;&#x2F;code&gt; ao comando &lt;code&gt;docker run&lt;&#x2F;code&gt; (exemplo &lt;code&gt;docker run -it --rm --network host sistema bash&lt;&#x2F;code&gt;). Assim ao executar &lt;code&gt;ip addr&lt;&#x2F;code&gt; serão exibidas as mesmas interfaces de rede da máquina, não aplicando essa técnica de isolamento.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;outros-isolamentos&quot;&gt;Outros isolamentos&lt;&#x2F;h3&gt;
&lt;p&gt;Ainda existem outros tipos de isolamento de espaço de nomes aplicados pelo Docker, e eles podem ser listados através do comando &lt;code&gt;ls -la &#x2F;proc&#x2F;self&#x2F;ns&lt;&#x2F;code&gt; que quando executado dentro do contêiner, lista exatamente os mesmos espaços de nomes que quando executado fora do contêiner informando o número do processo, como &lt;code&gt;ls -la &#x2F;proc&#x2F;15277&#x2F;ns&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dr-x--x--x 2 root root 0 jun 13 08:37 .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dr-xr-xr-x 9 root root 0 jun 13 08:37 ..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 jun 13 08:40 cgroup -&amp;gt; &amp;#39;cgroup:[4026531835]&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 jun 13 08:40 ipc -&amp;gt; &amp;#39;ipc:[4026532573]&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 jun 13 08:40 mnt -&amp;gt; &amp;#39;mnt:[4026532571]&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 jun 13 08:37 net -&amp;gt; &amp;#39;net:[4026532576]&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 jun 13 08:40 pid -&amp;gt; &amp;#39;pid:[4026532574]&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 jun 13 08:43 pid_for_children -&amp;gt; &amp;#39;pid:[4026532574]&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 jun 13 08:40 user -&amp;gt; &amp;#39;user:[4026531837]&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 0 jun 13 08:40 uts -&amp;gt; &amp;#39;uts:[4026532572]&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;O Docker é uma ferramenta que torna muito mais prático a execução de processos dentro de espaços de nome do kernel, além de automatizar muito do trabalho de suas configurações. Também apresenta alguns diferenciais do processo manual demonstrado, como as camadas aplicadas no sistema de arquivos, o que permite que várias imagens compartilhem algumas camadas, e que mais de um contêiner possa ser executado a partir do mesmo sistema de arquivos, onde cada contêiner teria sua última camada de forma particular.&lt;&#x2F;p&gt;
&lt;p&gt;Com o processo manual, também fica mais evidente do motivo do Docker no Windows rodar dentro de um ambiente virtualizado, uma vez que é necessário um kernel Linux em execução, visto que os programas do contêiner normalmente esperam se comunicar com um kernel Linux. Embora também exista alguns &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;_&#x2F;microsoft-windows&quot;&gt;contêineres específicos para Windows&lt;&#x2F;a&gt;, e que neste caso específico exigem o kernel do Windows. Assim como as arquiteturas, um contêiner feito para x86_64 não vai funcionar em um hardware ARM, a menos que uma virtualização de espaço de usuário, como a oferecida pelo &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.qemu.org&#x2F;&quot;&gt;QEMU&lt;&#x2F;a&gt;, seja utilizada.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Isolamento de aplicações: Pilha de rede</title>
        <published>2021-06-12T00:00:00+00:00</published>
        <updated>2021-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/aplicacao-isolamento-de-pilha-de-rede/"/>
        <id>https://eduardoklosowski.github.io/blog/aplicacao-isolamento-de-pilha-de-rede/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/aplicacao-isolamento-de-pilha-de-rede/">&lt;p&gt;Uma das formas de comunicação mais comum entre processos é através da rede, o que permite tanto a comunicação de processos no mesmo computador, quanto em diferentes computadores. A comunicação pela rede normalmente utiliza portas &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Transmission_Control_Protocol&quot;&gt;TCP&lt;&#x2F;a&gt; ou &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;User_Datagram_Protocol&quot;&gt;UDP&lt;&#x2F;a&gt;, porém algumas aplicações podem querer utilizar a mesma porta de rede, como a porta 80 TCP que é a porta padrão para serviços &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Hypertext_Transfer_Protocol&quot;&gt;HTTP&lt;&#x2F;a&gt;, ou 443 TCP para &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Hyper_Text_Transfer_Protocol_Secure&quot;&gt;HTTPS&lt;&#x2F;a&gt;, o que geraria conflitos.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;solucoes-possiveis&quot;&gt;Soluções possíveis&lt;&#x2F;h2&gt;
&lt;p&gt;Existem algumas formas de lidar com essa questão:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definindo-o-numero-da-porta&quot;&gt;Definindo o número da porta&lt;&#x2F;h3&gt;
&lt;p&gt;A solução mais simples para o caso de dois processos quererem utilizar o mesmo número de porta é alterar a porta utilizada por algum dos processos. Isso normalmente envolve alterar a configuração da aplicação, e torna obrigatório informar o endereço da porta para acessar o serviço, uma vez que ele não se encontra mais em sua porta padrão. Um exemplo é &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:8080&#x2F;&lt;&#x2F;code&gt;, onde esse endereço informa para conectar na porta 8080 em vez da porta 80 (padrão). Porém algumas aplicações não foram feitas pensando na possibilidade de executar em outra porta, e mesmo se configuradas para tal, podem não funcionar corretamente, como um sistema web, onde são utilizados endereços fixos que assumem que o serviço esteja rodando na porta padrão e acabam redirecionando o usuário para ela.&lt;&#x2F;p&gt;
&lt;p&gt;Para os sistemas que puderem ser executados em outras portas, essa configuração variará conforme o programa. Mas para verificar quais portas estão sendo utilizadas é possível executar o comando &lt;code&gt;ss -nltup&lt;&#x2F;code&gt; que lista todas as portas que estão no modo de escuta (aguardando uma conexão no caso do TCP, ou esperando receber dados no caso do UDP) assim como o processo que está utilizando cada porta, facilitando tanto encontrar um número de porta disponível, quanto identificar qual outra aplicação está utilizando a porta desejada. Porém com essa configuração, além do endereço do servidor, também será necessário lembrar em qual porta que o serviço está rodando para conseguir acessá-lo.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definindo-outro-endereco-ip&quot;&gt;Definindo outro endereço IP&lt;&#x2F;h3&gt;
&lt;p&gt;Embora muitas vezes se pense em um serviço ouvindo apenas uma porta (ou mais de uma porta, dependendo da aplicação), para o sistema operacional cada processo ouve uma porta de um endereço de rede. Desta forma é possível que dois serviços utilizem a mesma porta TCP ou UDP, porém desde que em endereços de rede diferentes, sendo necessário configurar um segundo endereço no computador (adicionando um novo endereço na interface no caso do IPv6, ou criando um &lt;em&gt;alias&lt;&#x2F;em&gt; para a interface no caso do IPv4), ou configurar para um serviço ser disponibilizado para o endereço de uma interface de rede, e outro serviço para o endereço de outra interface de rede.&lt;&#x2F;p&gt;
&lt;p&gt;Com a configuração dos endereços de rede feita, na configuração da aplicação é necessário informar em qual endereço de rede e porta que ela deverá aguardar conexões, e isso novamente varia conforme o programa. Porém quando estiver em execução, o mesmo também pode ser visto pelo comando &lt;code&gt;ss -nltup&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;O exemplo a baixo mostra um computador com dois servidores de nomes (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Sistema_de_Nomes_de_Dom%C3%ADnio&quot;&gt;DNS&lt;&#x2F;a&gt;) em execução. O primeiro ouvindo no IP 127.0.0.1 e porta 53, tanto TCP, quanto UDP. Esse serviço, por utilizar o endereço de &lt;em&gt;loopback&lt;&#x2F;em&gt;, é acessível apenas da máquina local. O segundo servidor de nomes ouve no IP 192.168.122.1 e porta 53, também nos protocolos TCP e UDP. Nesse caso, o serviço está disponível para uma rede de &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;M%C3%A1quina_virtual&quot;&gt;máquinas virtuais&lt;&#x2F;a&gt; do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;libvirt.org&#x2F;&quot;&gt;libvirt&lt;&#x2F;a&gt;. Em ambos os casos, esse serviço está atribuído a um endereço de rede específico, diferente do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Secure_Shell&quot;&gt;SSH&lt;&#x2F;a&gt; que ouve em qualquer endereço de rede (0.0.0.0 no caso de IPv4 e [::] no caso de IPv6) na porta 22 apenas TCP.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Netid     State       Recv-Q      Send-Q            Local Address:Port            Peer Address:Port&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;udp       UNCONN      0           0                     127.0.0.1:53                   0.0.0.0:*         users:((&amp;quot;dnsmasq&amp;quot;,pid=994,fd=4))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;udp       UNCONN      0           0                 192.168.122.1:53                   0.0.0.0:*         users:((&amp;quot;dnsmasq&amp;quot;,pid=838,fd=5))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tcp       LISTEN      0           32                    127.0.0.1:53                   0.0.0.0:*         users:((&amp;quot;dnsmasq&amp;quot;,pid=994,fd=5))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tcp       LISTEN      0           32                192.168.122.1:53                   0.0.0.0:*         users:((&amp;quot;dnsmasq&amp;quot;,pid=838,fd=6))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tcp       LISTEN      0           128                     0.0.0.0:22                   0.0.0.0:*         users:((&amp;quot;sshd&amp;quot;,pid=695,fd=3))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tcp       LISTEN      0           128                        [::]:22                      [::]:*         users:((&amp;quot;sshd&amp;quot;,pid=695,fd=4))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;outra-pilha-de-rede&quot;&gt;Outra pilha de rede&lt;&#x2F;h3&gt;
&lt;p&gt;Outra opção é utilizar instâncias diferentes da pilha de rede do sistema operacional para cada aplicação, onde cada instância teria suas interfaces e endereços de rede, e assim uma não conflitaria com a outra. Uma forma de fazer isso é através do espaço de nomes, e informado que tal processo será executado dentro de tal espaço.&lt;&#x2F;p&gt;
&lt;p&gt;Todo o controle do espaço de nomes (criação, configuração e execução de processos) pode ser feito através do comando &lt;code&gt;ip&lt;&#x2F;code&gt; que faz parte do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;wiki.linuxfoundation.org&#x2F;networking&#x2F;iproute2&quot;&gt;iproute2&lt;&#x2F;a&gt;, que substitui o antigo &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sourceforge.net&#x2F;projects&#x2F;net-tools&#x2F;&quot;&gt;net-tools&lt;&#x2F;a&gt;. Nesse exemplo ele será utilizado para criar um espaço de nomes (&lt;code&gt;app1&lt;&#x2F;code&gt;), criar duas interfaces virtuais conectadas entre si (&lt;code&gt;veth0&lt;&#x2F;code&gt; e &lt;code&gt;veth1&lt;&#x2F;code&gt;), atribuir uma interface ao espaço de nomes da aplicação (&lt;code&gt;veth1&lt;&#x2F;code&gt;), configurado os endereços de rede, e por fim, executado um processo dentro desse espaço:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Cria espaço de nomes app1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; netns add app1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Cria interfaces de redes virtuais&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; link add veth0 type veth peer name veth1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Atribui uma interface de rede para a aplicação&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; link set veth1 netns app1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Define endereços de rede das interfaces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; addr add 10.1.1.1&#x2F;30 dev veth0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; netns exec app1 ip addr add 10.1.1.2&#x2F;30 dev veth1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Liga as interfaces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; link set veth0 up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; netns exec app1 ip link set veth1 up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; netns exec app1 ip link set lo up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Configura gateway para a interface da aplicação&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; netns exec app1 ip route add default via&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10.1.1.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Executa processo do Bash dentro do espaço de nomes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; netns exec app1 bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse último comando abrirá um terminal do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;tiswww.case.edu&#x2F;php&#x2F;chet&#x2F;bash&#x2F;bashtop.html&quot;&gt;Bash&lt;&#x2F;a&gt; que terá acesso à outra pilha de rede, sendo possível executar comandos como &lt;code&gt;ping 10.1.1.1&lt;&#x2F;code&gt; para verificar a comunicação com a pilha de rede que está rodando fora desse espaço de nomes. O Bash também pode ser substituído por outro processo, como o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;nginx.org&#x2F;&quot;&gt;NGINX&lt;&#x2F;a&gt; (exemplo &lt;code&gt;ip netns exec app1 nginx -g &#x27;daemon off;&#x27;&lt;&#x2F;code&gt;), e que assim poderia ser acessado pelo navegador através do endereço &lt;code&gt;http:&#x2F;&#x2F;10.1.1.2&#x2F;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Para que esse serviço possa ser acessado de outro computador, ainda é necessário fazer algumas configurações adicionais, como configurar a rota para a rede das interfaces virtuais nos dispositivos de rede, ou alguma tradução de endereços (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Network_address_translation&quot;&gt;NAT&lt;&#x2F;a&gt;) ou porta (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Port_address_translation&quot;&gt;PAT&lt;&#x2F;a&gt;), uma vez que a pilha de rede padrão funcionará como um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Roteador&quot;&gt;roteador&lt;&#x2F;a&gt; ou &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Firewall&quot;&gt;firewall&lt;&#x2F;a&gt; para a segunda pilha criada desta forma.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;A criação de espaços de nomes de rede pode ser bastante interessante para isolar aplicações para que elas não conflitem pelo uso de alguma porta, mas também pode ser utilizada para isolar a comunicação entre processos, de tal forma que a rede entre eles não seja acessível por terceiros. Um exemplo que isola a comunicação entre os processos em redes diferentes é o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.openstack.org&#x2F;&quot;&gt;OpenStack&lt;&#x2F;a&gt;, que é uma solução para a criação de nuvens privadas (criar um ambiente de nuvem dentro de seu próprio &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Centro_de_processamento_de_dados&quot;&gt;&lt;em&gt;data center&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;), onde alguns desses comandos do &lt;code&gt;ip netns&lt;&#x2F;code&gt; aparecem no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.openstack.org&#x2F;operations-guide&#x2F;ops-network-troubleshooting.html#dealing-with-network-namespaces&quot;&gt;guia para soluções de problemas de rede&lt;&#x2F;a&gt;, permitindo assim executar comando com acessos as redes virtuais da nuvem, o qual não seria possível normalmente.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Isolamento de aplicações: Tabela de processos</title>
        <published>2021-06-05T00:00:00+00:00</published>
        <updated>2021-06-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/aplicacao-isolamento-de-tabela-de-processos/"/>
        <id>https://eduardoklosowski.github.io/blog/aplicacao-isolamento-de-tabela-de-processos/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/aplicacao-isolamento-de-tabela-de-processos/">&lt;p&gt;Todo serviço é um processo que está em execução no sistema operacional, e é possível extrair informações de um processo, ou até mesmo interagir com ele através de sinais, como o enviado para que um serviço releia suas configurações, sem precisar parar e iniciá-lo novamente para aplicar as alterações, ou para pedir que ele finalize (pare de executar). Um processo poderia se aproveitar desses mecanismos para obter informações, ou causar uma indisponibilidade.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;obtendo-informacoes&quot;&gt;Obtendo informações&lt;&#x2F;h2&gt;
&lt;p&gt;Uma forma de se obter informações através dos processos é simplesmente listando-os, onde seria possível visualizar serviços em execução, o que permitira identificar outras possibilidades de ataque. Isso pode ser feito utilizando o comando &lt;code&gt;ps ax&lt;&#x2F;code&gt;, que poderia listar que existe um servidor &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;httpd.apache.org&#x2F;&quot;&gt;Apache&lt;&#x2F;a&gt;, por exemplo, onde o atacante poderia se focar em tentar explorar vulnerabilidades desse serviço específico, ou qualquer outro que esteja em execução.&lt;&#x2F;p&gt;
&lt;p&gt;Outro ponto que pode ser importante são os argumentos dos processos, que podem possuir alguma informação sensível. Muitas vezes senhas são passadas como argumento de um comando, como &lt;code&gt;mysql -uroot -psecreta&lt;&#x2F;code&gt;, que possui usuário (&lt;code&gt;root&lt;&#x2F;code&gt;) e senha (&lt;code&gt;secreta&lt;&#x2F;code&gt;) utilizados para conectar no banco de dados. Enquanto esse comando estiver em execução, ao listar os processos, seria possível obter essas informações.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;interagindo-com-processos&quot;&gt;Interagindo com processos&lt;&#x2F;h2&gt;
&lt;p&gt;Embora possa existir alguma segurança, ao executar os processos de cada aplicação com usuários diferentes, se isso não for feito, uma aplicação poderia pedir para o processo de outra aplicação ser finalizado. Mesmo se o processo for reiniciado logo em seguida por um supervisor (systemd, por exemplo), vai haver algum momento de indisponibilidade, principalmente se o serviço demora para iniciar. Isso derrubaria qualquer cliente que esteja conectado, e faria com que fosse necessário algum tempo até que os clientes possam se reconectar.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;isolando-processos&quot;&gt;Isolando processos&lt;&#x2F;h2&gt;
&lt;p&gt;Uma forma de resolver esses problemas é impedindo com que um processo possa enxergar toda a tabela de processos do sistema operacional, permitindo visualizar apenas os processos relativos ao seu serviço (como processos filhos). Isso pode ser feito criando um espaço de nomes para os processos, onde qualquer processo dentro de um desses espaços veria apenas os processos do seu espaço, que inclusive podem possuir um número de identificador diferente (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Identificador_de_processo&quot;&gt;pid&lt;&#x2F;a&gt;), tendo um identificador dentro do espaço, porém mapeado para um identificador real que seria visível apenas pelos processos de fora desse espaço de nomes.&lt;&#x2F;p&gt;
&lt;p&gt;Esse espaço de nomes pode ser criado adicionando &lt;code&gt;unshare -fp --mount-proc&lt;&#x2F;code&gt; na frente do comando a ser executado, assim ao executar &lt;code&gt;unshare -fp --mount-proc &#x2F;bin&#x2F;bash&lt;&#x2F;code&gt; o processo do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;tiswww.case.edu&#x2F;php&#x2F;chet&#x2F;bash&#x2F;bashtop.html&quot;&gt;Bash&lt;&#x2F;a&gt; aberto não conseguiria ver os demais processos do sistema ao executar &lt;code&gt;ps ax&lt;&#x2F;code&gt;. E ao executar um processo em segundo plano, como &lt;code&gt;python3 -m http.server &amp;amp;&lt;&#x2F;code&gt;, ele seria listado no &lt;code&gt;ps ax&lt;&#x2F;code&gt; com um pid (exemplo &lt;code&gt;3&lt;&#x2F;code&gt;), porém ao executar &lt;code&gt;ps ax&lt;&#x2F;code&gt; em outro Bash, fora desse espaço de nomes, ele apareceria com outro pid (exemplo &lt;code&gt;13682&lt;&#x2F;code&gt;), onde dentro do espaço de nomes esse processo poderia ser finalizado com &lt;code&gt;kill 3&lt;&#x2F;code&gt;, mas fora desse espaço seria &lt;code&gt;kill 13682&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;A criação de espaços de nomes de processos (tabelas de processos) do sistema operacional reduz as possibilidades de uma aplicação interferir em outra, adicionando uma camada a mais de isolamento. Isso também impede que um processo de dentro de um espaço de nomes consiga obter informações de processos ou envie sinais para processos de outros espaços de nomes. Porém aqueles processos executados fora de um espaço de nomes definido terá acesso aos processos de todos os espaços de nomes, podendo listá-los, ver seus argumentos e lhes enviar sinais.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Isolamento de aplicações: Sistema de arquivos</title>
        <published>2021-05-29T00:00:00+00:00</published>
        <updated>2021-05-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/aplicacao-isolamento-de-sistema-de-arquivos/"/>
        <id>https://eduardoklosowski.github.io/blog/aplicacao-isolamento-de-sistema-de-arquivos/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/aplicacao-isolamento-de-sistema-de-arquivos/">&lt;p&gt;Aplicações são desenvolvidas e muitas vezes executadas como serviços em servidores, os quais podem rodar uma única aplicação, ou compartilhar seus recursos de &lt;em&gt;hardware&lt;&#x2F;em&gt; entre diversas aplicações. Entretanto podem existir conflitos entre as aplicações, como requisitarem a mesma porta de rede, exigirem versões diferentes de biblioteca e afins, além de questões de segurança. Nesse primeiro texto será abordado como isolar o sistema de arquivos entre os processos dessas aplicações, de forma que um processo não consiga visualizar os arquivos referentes a outra aplicação.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;arquitetura-do-sistema&quot;&gt;Arquitetura do sistema&lt;&#x2F;h2&gt;
&lt;p&gt;Antes de entrar em detalhes de como fazer esse isolamento, vamos entender a arquitetura do sistema onde os processos são executados. Dividindo a arquitetura em camadas, indo da mais baixa para a mais alta, temos:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Hardware:&lt;&#x2F;strong&gt; Que é o computador ou servidor onde o processo da aplicação será executado. Normalmente inclui processador, memória RAM, espaço de armazenamento (HD ou SSD), placa de rede e demais dispositivos.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Kernel:&lt;&#x2F;strong&gt; Parte do sistema operacional, responsável por gerenciar tanto o &lt;em&gt;hardware&lt;&#x2F;em&gt; quanto os processos das aplicações que serão executados. Essa série se focará no &lt;em&gt;kernel&lt;&#x2F;em&gt; Linux.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Bibliotecas:&lt;&#x2F;strong&gt; São diversos arquivos com rotinas comuns entre os processos, assim como também disponibilizam funções para interagir com o &lt;em&gt;kernel&lt;&#x2F;em&gt; do sistema. Nesse ambiente são comumente arquivos binários &lt;code&gt;.so&lt;&#x2F;code&gt;, semelhante aos &lt;code&gt;.dll&lt;&#x2F;code&gt; do Windows, e normalmente se encontram em diretórios como &lt;code&gt;&#x2F;usr&#x2F;lib&lt;&#x2F;code&gt; e &lt;code&gt;&#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&lt;&#x2F;code&gt;. Porém podem estar em outros diretórios como &lt;code&gt;&#x2F;usr&#x2F;lib&#x2F;php&lt;&#x2F;code&gt; que são bibliotecas específicas do PHP, ou &lt;code&gt;&#x2F;usr&#x2F;lib&#x2F;python3&#x2F;dist-packages&lt;&#x2F;code&gt; que são os módulos do Python 3, que nesse caso também não precisam ser arquivos binários.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Aplicações:&lt;&#x2F;strong&gt; São os diversos processos das aplicações que estão em execução no servidor, podendo utilizar as bibliotecas disponíveis no sistema.&lt;&#x2F;p&gt;
&lt;p&gt;Um desenho das camadas dessa arquitetura pode ser vista a seguir:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;aplicacao-isolamento-de-sistema-de-arquivos&#x2F;arquitetura.png&quot; alt=&quot;Arquitetura do sistema&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;problema-de-um-sistema-de-arquivos-compartilhado&quot;&gt;Problema de um sistema de arquivos compartilhado&lt;&#x2F;h2&gt;
&lt;p&gt;Porém, como já foi mencionado, podem ocorrer problemas nesse sistema, como uma aplicação precisar de uma biblioteca em uma versão, enquanto outra aplicação precisar de uma versão diferente da mesma biblioteca, e se essas versões forem incompatíveis entre si, não seria possível rodar as duas aplicações. Algumas linguagens apresentam soluções para esse problema criando outros diretórios onde as bibliotecas são procuradas, como o Python com o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;library&#x2F;venv.html&quot;&gt;ambiente virtual&lt;&#x2F;a&gt;, ou informando o sistema para procurar as bibliotecas &lt;code&gt;.so&lt;&#x2F;code&gt; em outro diretório com a variável de ambiente &lt;code&gt;LD_LIBRARY_PATH&lt;&#x2F;code&gt;. Entretanto, cada caso de linguagem vai exigir uma solução diferente, e pode ocorrer o caso de alguma não possuir uma solução para isso.&lt;&#x2F;p&gt;
&lt;p&gt;Outro problema é que uma aplicação poderia acessar os arquivos da outra, tanto lendo dados que não poderia, quanto alterando-os. Isso é preocupante do ponto de vista de segurança, onde uma aplicação poderia ser invadida, e através dela, acessar os dados de outra, ou causar a falha de uma aplicação, inserindo algum código malicioso para outra aplicação executar, ou simplesmente apagando seus dados.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;enjaulando-uma-aplicacao&quot;&gt;Enjaulando uma aplicação&lt;&#x2F;h2&gt;
&lt;p&gt;Uma opção para resolver esses problemas é o enjaulamento (isolamento) de uma aplicação, restringindo o acesso dos processos a apenas uma parte do sistema de arquivos, como se um diretório específico fosse a raiz do sistema para os processos de uma aplicação. Isso exigiria criar toda a estrutura de diretório do sistema operacional, assim como ter uma cópia de bibliotecas e demais arquivos dentro desse diretório. Desta forma teria um único &lt;em&gt;kernel&lt;&#x2F;em&gt; em execução, porém para alguns processos a raiz do sistema de arquivos (&lt;code&gt;&#x2F;&lt;&#x2F;code&gt;) seria a raiz de fato, e para outros processos veriam um diretório (como &lt;code&gt;&#x2F;media&#x2F;sistema&lt;&#x2F;code&gt;) como a raiz do sistema de arquivos. Isso duplicaria as camadas de bibliotecas e aplicação do sistema:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;aplicacao-isolamento-de-sistema-de-arquivos&#x2F;arquitetura-chroot.png&quot; alt=&quot;Arquitetura com chroot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Isso também permite acessar e rodar programas instalados em outras distribuições GNU&#x2F;Linux que possam existir no computador, visto que as bibliotecas e aplicações conseguem executar em diferentes versões do &lt;em&gt;kernel&lt;&#x2F;em&gt;, porém se tentasse executar diretamente, poderia falhar devido a falta de alguma dependência. Inclusive algumas distros, como o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.funtoo.org&#x2F;&quot;&gt;Funtoo&lt;&#x2F;a&gt;, disponibilizam formas de usar o &lt;em&gt;kernel&lt;&#x2F;em&gt; compilado de outras distribuições, como no caso &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.funtoo.org&#x2F;Funtoo_Linux_Kernels&#x2F;pt-br&quot;&gt;o &lt;em&gt;kernel&lt;&#x2F;em&gt; compilado pelo Debian&lt;&#x2F;a&gt;. Além de também ser possível utilizar o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;GNU_Linux-libre&quot;&gt;Linux-libre&lt;&#x2F;a&gt; no lugar do &lt;em&gt;kernel&lt;&#x2F;em&gt; Linux da distro.&lt;&#x2F;p&gt;
&lt;p&gt;Essa solução também está presente dentro de algumas aplicações, como o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.isc.org&#x2F;bind&#x2F;&quot;&gt;Bind9&lt;&#x2F;a&gt; que é um servidor &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Sistema_de_Nomes_de_Dom%C3%ADnio&quot;&gt;DNS&lt;&#x2F;a&gt;, e utiliza essa técnica para mitigar problemas de segurança. Uma forma de utilizá-la pode ser vista na &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;wiki.debian.org&#x2F;Bind9#Bind_Chroot&quot;&gt;Wiki do Debian&lt;&#x2F;a&gt;. E por estar dentro da aplicação, também exige menos coisas dentro dessa &quot;jaula&quot;, ocupando menos espaço.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;criacao-de-uma-jaula&quot;&gt;Criação de uma jaula&lt;&#x2F;h3&gt;
&lt;p&gt;Para criar uma jaula contendo toda a estrutura de uma distribuição, é possível utilizar seu próprio processo de instalação. Nesse caso será utilizado o processo de &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.debian.org&#x2F;releases&#x2F;stable&#x2F;amd64&#x2F;apds03.pt.html&quot;&gt;instalação do Debian a partir de outra distribuição&lt;&#x2F;a&gt;, que consiste em instalar o utilitário &lt;code&gt;debootstrap&lt;&#x2F;code&gt; (pacote &lt;code&gt;debootstrap&lt;&#x2F;code&gt; no Debian e derivados, ou seguindo os passos presentes no guia de instalação para extrair o script do pacote &lt;code&gt;.deb&lt;&#x2F;code&gt;), e utilizá-lo para criar toda a estrutura do Debian dentro de um diretório. Com o &lt;code&gt;debootstrap&lt;&#x2F;code&gt; instalado, basta executá-lo informando a versão desejada, diretório onde o a estrutura deve ser criada, e opcionalmente o endereço do repositório que deve ser utilizado. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;debootstrap&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; buster &#x2F;media&#x2F;sistema http:&#x2F;&#x2F;ftp.br.debian.org&#x2F;debian&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Assim que o comando finalizar, já será possível acessar a estrutura presente em &lt;code&gt;&#x2F;media&#x2F;sistema&lt;&#x2F;code&gt;, porém esse caminho precisaria ser sempre utilizado como prefixo para acessar qualquer arquivo. Para fazer com que isso ocorra de forma transparante, &quot;enjaulando&quot; uma aplicação nesse diretório, o comando &lt;code&gt;chroot&lt;&#x2F;code&gt; pode ser utilizado. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;chroot&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &#x2F;media&#x2F;sistema&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A partir desse ponto, tudo que executar através desse terminal, ao tentar criar um arquivo como &lt;code&gt;&#x2F;arquivo.txt&lt;&#x2F;code&gt;, para o que estiver dentro da jaula parecerá que está acessando um arquivo na raiz do sistema de arquivos, porém para outros processos (fora da jaula) esse arquivo estará na verdade em &lt;code&gt;&#x2F;media&#x2F;sistema&#x2F;arquivo.txt&lt;&#x2F;code&gt;. E qualquer aplicação poderá ser instalada com o &lt;code&gt;apt&lt;&#x2F;code&gt; dentro dessa jaula, mesmo se a distribuição utilizada não for um Debian ou derivados, visto que para os processos dentro dessa jaula enxergariam o sistema Debian.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;O isolamento do sistema de arquivos (jaula) é bastante interessante para limitar os arquivos que um processo pode acessar, assim como para executar programas que estão instalados em outras distribuições presentes no computador. Porém ela exige a instalação quase que completa de uma distribuição, só não precisando coisas relacionadas ao &lt;em&gt;kernel&lt;&#x2F;em&gt;, uma vez que é utilizado o &lt;em&gt;kernel&lt;&#x2F;em&gt; que já está em execução no computador, utilizando apenas um espaço de nomes (&lt;em&gt;namespace&lt;&#x2F;em&gt;) diferente para o sistema de arquivos.&lt;&#x2F;p&gt;
&lt;p&gt;Entretanto esse isolamento ainda não é completo, uma vez que existem outras coisas compartilhas entre os processos de dentro da jaula com os de fora da jaula, como tabela de processos e pilha de rede.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Liberar acesso ao servidor SSH pelas chaves do GitHub</title>
        <published>2021-05-22T00:00:00+00:00</published>
        <updated>2021-05-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/liberar-acesso-ssh-pelo-github/"/>
        <id>https://eduardoklosowski.github.io/blog/liberar-acesso-ssh-pelo-github/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/liberar-acesso-ssh-pelo-github/">&lt;p&gt;Uma das formas mais utilizadas para acessar servidores GNU&#x2F;Linux é através do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Secure_Shell&quot;&gt;SSH&lt;&#x2F;a&gt;. Esse acesso pode ocorrer através de usuário e senha ou de um par de chaves criptográfica, normalmente &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;RSA_(sistema_criptogr%C3%A1fico)&quot;&gt;RSA&lt;&#x2F;a&gt; ou mais recente &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;ECDSA&quot;&gt;Ed25519&lt;&#x2F;a&gt;, que são chaves assimétricas, onde a chave pública é copiada para o servidor e a privada fica no cliente que está pedindo acesso. Esse processo é o mesmo que ocorre no GitHub para permitir o acesso aos repositórios através de SSH, e é possível se aproveitar disso.&lt;&#x2F;p&gt;
&lt;p&gt;Caso tenha alguma dúvida para criar chaves, ou mesmo queira verificar como configurar o cliente SSH, recomendo dar uma olhada no meu texto sobre &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;&quot;&gt;configuração do Git&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;permitindo-acesso-atraves-da-chave&quot;&gt;Permitindo acesso através da chave&lt;&#x2F;h2&gt;
&lt;p&gt;Primeiramente, para permitir o acesso a um servidor por chave criptográfica, basta adicionar a chave pública no arquivo &lt;code&gt;~&#x2F;.ssh&#x2F;authorized_keys&lt;&#x2F;code&gt;, onde &lt;code&gt;~&lt;&#x2F;code&gt; é a home do usuário no servidor ao qual deseja-se permitir o acesso remoto. Desta forma, basta conseguir uma cópia da chave pública para permitir o acesso. Lembrando que o serviço do SSH deve estar em execução nesse servidor (para Debian e derivados basta instalar o pacote &lt;code&gt;openssh-server&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acessando-a-chave-publica-no-github&quot;&gt;Acessando a chave pública no GitHub&lt;&#x2F;h2&gt;
&lt;p&gt;Como a chave pública não é uma informação sensível, e pode ser divulgada, o GitHub lista as chaves públicas cadastradas dos usuários ao adicionar &lt;code&gt;.keys&lt;&#x2F;code&gt; ao final do link do perfil. Exemplo: &lt;code&gt;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski.keys&lt;&#x2F;code&gt;. Assim ao acessar essa URL será listada todas as chaves públicas cadastradas para a conta, em vez de mostrar o perfil do usuário. Desta forma, basta adicionar essas chaves ao final do arquivo &lt;code&gt;~&#x2F;.ssh&#x2F;authorized_keys&lt;&#x2F;code&gt; e o dono dessa conta já poderá acessar o servidor.&lt;&#x2F;p&gt;
&lt;p&gt;Esse processo também poderia ser feito através da linha de comando, não sendo necessário copiar e colar as chaves, bastando executar um dos comandos abaixo (de acordo com a ferramenta que estiver disponível no servidor):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski.keys&lt;&#x2F;span&gt;&lt;span&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; ~&#x2F;.ssh&#x2F;authorized_keys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Ou&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;wget&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -qO&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; - https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski.keys&lt;&#x2F;span&gt;&lt;span&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; ~&#x2F;.ssh&#x2F;authorized_keys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Muitos desenvolvedores possuem conta no GitHub, e adicionaram suas chaves públicas a sua conta. Então fazer esse processo permite liberar o acesso a um servidor de forma fácil e segura (desde que o dono da conta mantenha sua chave privada de forma segura). Uma aplicação bastante interessante disso é na criação de servidores para &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Programa%C3%A7%C3%A3o_pareada&quot;&gt;pair programming&lt;&#x2F;a&gt;, onde um servidor pode ser criado e as pessoas que forem programar podem compartilhar o terminal através do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tmux.github.io&#x2F;&quot;&gt;tmux&lt;&#x2F;a&gt;, sendo necessário se conhecer apenas o nome de usuário do GitHub, em vez de criar uma senha e compartilhá-la, ou pedir e aguardar a outra pessoa enviar sua chave pública.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Álgebra booliana</title>
        <published>2021-05-15T00:00:00+00:00</published>
        <updated>2021-05-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/algebra-booliana/"/>
        <id>https://eduardoklosowski.github.io/blog/algebra-booliana/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/algebra-booliana/">&lt;p&gt;Há algum tempo, quando a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;bug_elseif&quot;&gt;bug_elseif&lt;&#x2F;a&gt; ainda estava fazendo &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;wiki.python.org.br&#x2F;ListaDeExercicios&quot;&gt;listas de exercícios em Python&lt;&#x2F;a&gt;, apareceu um problema que envolvia verificar se um ano era bissexto ou não. Embora a construção de uma expressão para verificar se um ano é bissexto seja até intuitiva, como estávamos utilizando a condição invertida (verificar se o ano não era bissexto), sua construção não estava sendo fácil, porém é possível usar um pouco de matemática para chegar nela.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;construcao-da-expressao&quot;&gt;Construção da expressão&lt;&#x2F;h2&gt;
&lt;p&gt;Primeiramente vamos construir uma expressão para verificar se um ano é bissexto. Para isso, ele deve ser múltiplo de 4, porém se o ano terminar com 00, ele também deve ser múltiplo de 400. Para verificar se um número termina com 00, basta verificar se ele é múltiplo de 100, e para verificar se um número é múltiplo de outro, podemos verificar o resto da divisão ou módulo (quem sabe falo sobre matemática modular em outro artigo), caso o resultado dessa operação seja 0, o primeiro número é divisível pelo segundo, e caso seja qualquer outro valor, o primeiro número não é divisível pelo segundo (ou não possui uma divisão inteira).&lt;&#x2F;p&gt;
&lt;p&gt;Assim, a expressão para verificar se o ano é bissexto pode ser construída como:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(ano % 4 == 0 &amp;amp;&amp;amp; ano % 100 != 0) || ano % 400 == 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A primeira coisa a ser observada é que existem duas subexpressões com o conectivo disjuntivo (&quot;ou&quot; &lt;code&gt;||&lt;&#x2F;code&gt;), ou seja, para um ano ser bissexto basta ele cumprir uma das duas condições (subexpressões). A primeira condição também é dividida em outras duas subexpressões, porém dessa vez com o conectivo conjuntivo (&quot;e&quot; &lt;code&gt;&amp;amp;&amp;amp;&lt;&#x2F;code&gt;), assim é necessário que as duas condições sejam verdadeiras para que o seu valor seja considerado verdadeiro, onde a primeira verifica se o ano é divisível por 4 (resto da divisão é igual a 0), e a segunda verifica se ele não é divisível por 100 (resto da divisão é diferente de 0). Essa é a primeira possibilidade para um ano ser bissexto. A outra possibilidade é se ele for divisível por 400 (resto da divisão é igual a zero).&lt;&#x2F;p&gt;
&lt;p&gt;Assim, essa expressão retorna verdadeiro se o ano for bissexto, e falso caso ele não for.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;invertendo-a-expressao&quot;&gt;Invertendo a expressão&lt;&#x2F;h2&gt;
&lt;p&gt;Porém na ocasião, a expressão que estávamos usando deveria retornar verdadeiro caso o ano não fosse bissexto, e falso caso ele fosse bissexto (o contrário da expressão apresentada). Isso poderia ser feito negando a expressão anterior, ou escrevendo uma expressão de tal forma que retorne o oposto, e era justamente essa segunda opção que estávamos tentando fazer.&lt;&#x2F;p&gt;
&lt;p&gt;Entretanto, existe uma forma matemática de trabalhar com a negação da expressão, alteando-a até que ela chegue próximo ou a exata expressão que estávamos construindo. Isso é possível através de propriedades das operações boolianas, substituindo parte da expressão a cada vez que uma propriedade por aplicada. Sendo as mais comuns para esse tipo de operação as propriedades de negação da negação (&lt;code&gt;!!a = a&lt;&#x2F;code&gt;), distributiva (&lt;code&gt;a || (b &amp;amp;&amp;amp; c) = (a || b) &amp;amp;&amp;amp; (a || c)&lt;&#x2F;code&gt; e &lt;code&gt;a &amp;amp;&amp;amp; (b || c) = (a &amp;amp;&amp;amp; b) || (a &amp;amp;&amp;amp; c)&lt;&#x2F;code&gt;, que lembra a distributiva da matemática &lt;code&gt;2 * (3 + 4) = (2 * 3) + (2 * 4)&lt;&#x2F;code&gt;), e as leis de De Morgan (&lt;code&gt;!(a || b) = !a &amp;amp;&amp;amp; !b&lt;&#x2F;code&gt; e &lt;code&gt;!(a &amp;amp;&amp;amp; b) = !a || !b&lt;&#x2F;code&gt;). Para mais propriedades veja a página sobre o assunto na &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;%C3%81lgebra_booliana&quot;&gt;Wikipédia&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Para esse caso é necessário aplicar apenas as leis de De Morgan. Partindo da negação da expressão, aplicando-a passo a passo, temos:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;!((ano % 4 == 0 &amp;amp;&amp;amp; ano % 100 != 0) || ano % 400 == 0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;!(ano % 4 == 0 &amp;amp;&amp;amp; ano % 100 != 0) &amp;amp;&amp;amp; !(ano % 400 == 0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(!(ano % 4 == 0) || !(ano % 100 != 0)) &amp;amp;&amp;amp; !(ano % 400 == 0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(ano % 4 != 0 || ano % 100 == 0) &amp;amp;&amp;amp; ano % 400 != 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Onde essa última expressão é a que precisávamos para o código.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Álgebra booliana é interessante para trabalhar condições como de &lt;code&gt;if&lt;&#x2F;code&gt; e laços de repetições dos códigos, seja para otimizá-la ou inverter os blocos de código do &lt;code&gt;if&lt;&#x2F;code&gt; e &lt;code&gt;else&lt;&#x2F;code&gt;, por exemplo, o que pode ser utilizado para deixar o código mais fácil de entender, colocando os blocos de código em uma ordem que faça mais sentido para a leitura. Ela também pode ser utilizada para facilitar a construção de expressões, como no caso apresentando, onde é muito mais fácil e intuitivo escrever uma expressão que verifica se o ano é bissexto do que um ano que não é, onde essa última pode até ser contraintuitiva, onde a álgebra booliana permite partir da expressão mais fácil para a mais difícil.&lt;&#x2F;p&gt;
&lt;p&gt;E para quem quiser se aprofundar nesse assunto, recomendo as &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;playlist?list=PL8iUCCJD339ezAJWqFaKriz_9tyBw6hE-&quot;&gt;aulas do RiverFount&lt;&#x2F;a&gt;, que é professor de filosofia.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Orientação a objetos de outra forma: Property</title>
        <published>2021-05-08T00:00:00+00:00</published>
        <updated>2021-05-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-6/"/>
        <id>https://eduardoklosowski.github.io/blog/oo-de-outra-forma-6/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-6/">&lt;p&gt;Seguindo com a série, chegou a hora de discutir sobre encapsulamento, ou seja, ocultar detalhes de implementação de uma classe do resto do código. Em algumas linguagens de programação isso é feito utilizando &lt;code&gt;protected&lt;&#x2F;code&gt; ou &lt;code&gt;private&lt;&#x2F;code&gt;, e às vezes o acesso aos atributos é feito através de funções &lt;em&gt;getters&lt;&#x2F;em&gt; e &lt;em&gt;setters&lt;&#x2F;em&gt;. Nesse texto vamos ver como o Python lida com essas questões.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;metodos-protegidos-e-privados&quot;&gt;Métodos protegidos e privados&lt;&#x2F;h2&gt;
&lt;p&gt;Diferente de linguagens como Java e PHP que possuem palavras-chave como &lt;code&gt;protected&lt;&#x2F;code&gt; e &lt;code&gt;private&lt;&#x2F;code&gt; para impedir que outras classes acessem determinados métodos ou atributos, Python deixa tudo como público. Porém isso não significa que todas as funções de uma classe podem ser chamadas por outras, ou todos os atributos podem ser lidos e alterados sem cuidados.&lt;&#x2F;p&gt;
&lt;p&gt;Para que quem estiver escrevendo um código saiba quais as funções ou atributos que não deveriam ser acessados diretamente, segue-se o padrão de começá-los com &lt;code&gt;_&lt;&#x2F;code&gt;, de forma similar aos arquivos ocultos em sistemas UNIX, que começam com &lt;code&gt;.&lt;&#x2F;code&gt;. Esse padrão já foi seguido na classe &lt;code&gt;AutenticavelComRegistro&lt;&#x2F;code&gt; da postagem sobre &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;oo-de-outra-forma-4&#x2F;&quot;&gt;mixins&lt;&#x2F;a&gt;, onde a função que pega a data do sistema foi nomeada &lt;code&gt;_get_data&lt;&#x2F;code&gt;. Entretanto isso é apenas uma sugestão, nada impede dela ser chamada, como no exemplo a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; datetime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; datetime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Exemplo&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; _get_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; datetime.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;now&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;strftime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;%d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&#x2F;%m&#x2F;%Y %T&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;obj&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Exemplo&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(obj.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;_get_data&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Porém algumas bibliotecas também utilizam o &lt;code&gt;_&lt;&#x2F;code&gt; para indicar outras informações como metadados do objeto, e que podem ser acessados sem muitos problemas. Assim é possível utilizar esse símbolo duas vezes (&lt;code&gt;__&lt;&#x2F;code&gt;) para indicar que realmente essa variável ou função não deveria ser acessada de fora da classe, apresentando erro de que o atributo não foi encontrado ao tentar executar a função, porém ela ainda pode ser acessada:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; datetime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; datetime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Exemplo&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; __get_data&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; datetime.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;now&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;strftime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;%d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&#x2F;%m&#x2F;%Y %T&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;obj&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Exemplo&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(obj.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;__get_data&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # AttributeError&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(obj.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;_Exemplo__get_data&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Executa a função&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;property&quot;&gt;Property&lt;&#x2F;h2&gt;
&lt;p&gt;Os &lt;em&gt;getters&lt;&#x2F;em&gt; e &lt;em&gt;setters&lt;&#x2F;em&gt; muitas vezes são usados para impedir que determinadas variáveis sejam alteradas, ou validar o valor antes de atribuir a variável, ou ainda processar um valor a partir de outras variáveis. Porém como o Python incentiva o acesso direto as variáveis, existe a &lt;em&gt;property&lt;&#x2F;em&gt;, que ao tentar acessar uma variável ou alterar um valor, uma função é chamada. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;._nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;._idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;property&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;._nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;property&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @nome_completo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;setter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; valor.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;._nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; valor[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; valor[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;property&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;._idade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @idade&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;setter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span&gt; ValueError&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;._idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fazer_aniversario&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse código algumas variáveis são acessíveis através de &lt;em&gt;properties&lt;&#x2F;em&gt;, de forma geral, as variáveis foram definidas começando com &lt;code&gt;_&lt;&#x2F;code&gt; e com uma &lt;em&gt;property&lt;&#x2F;em&gt; de mesmo nome (sem o &lt;code&gt;_&lt;&#x2F;code&gt;). O primeiro caso é o &lt;code&gt;nome&lt;&#x2F;code&gt;, que possui apenas o &lt;em&gt;getter&lt;&#x2F;em&gt;, sendo possível o seu acesso como &lt;code&gt;obj.nome&lt;&#x2F;code&gt;, porém ao tentar atribuir um valor, será lançado um erro (&lt;code&gt;AttributeError: can&#x27;t set attribute&lt;&#x2F;code&gt;). Em relação ao &lt;code&gt;sobrenome&lt;&#x2F;code&gt;, como não é necessário nenhum tratamento especial, não foi utilizado um &lt;em&gt;property&lt;&#x2F;em&gt;, porém futuramente pode ser facilmente substituído por um sem precisar alterar os demais códigos. Porém a função &lt;code&gt;nome_completo&lt;&#x2F;code&gt; foi substituída por um &lt;em&gt;property&lt;&#x2F;em&gt;, permitindo tanto o acesso ao nome completo da pessoa, como se fosse uma variável, quanto trocar &lt;code&gt;nome&lt;&#x2F;code&gt; e &lt;code&gt;sobrenome&lt;&#x2F;code&gt; ao atribuir um novo valor para essa &lt;em&gt;property&lt;&#x2F;em&gt;. Quanto a &lt;code&gt;idade&lt;&#x2F;code&gt; utiliza o &lt;em&gt;setter&lt;&#x2F;em&gt; do &lt;em&gt;property&lt;&#x2F;em&gt; para validar o valor recebido, retornando erro para idades inválidas (negativas).&lt;&#x2F;p&gt;
&lt;p&gt;Vale observar também que todas as funções de &lt;em&gt;getter&lt;&#x2F;em&gt; não recebem nenhum argumento (além do &lt;code&gt;self&lt;&#x2F;code&gt;), enquanto as funções de &lt;em&gt;setter&lt;&#x2F;em&gt; recebem o valor atribuído à variável.&lt;&#x2F;p&gt;
&lt;p&gt;Utilizando a &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;oo-de-outra-forma-5&#x2F;&quot;&gt;ABC&lt;&#x2F;a&gt;, ainda é possível informar que alguma classe filha deverá implementar alguma &lt;em&gt;property&lt;&#x2F;em&gt;. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; abc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ABC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;ABC&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;property&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Brasileiro&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;property&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Japones&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;property&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Diferente de algumas linguagens que ocultam as variáveis dos objetos, permitindo o seu acesso apenas através de funções, Python seguem no sentido contrário, acessando as funções de &lt;em&gt;getter&lt;&#x2F;em&gt; e &lt;em&gt;setter&lt;&#x2F;em&gt; como se fossem variáveis, isso permite começar com uma classe simples e ir adicionando funcionalidades conforme elas forem necessárias, sem precisar mudar o código das demais partes da aplicação, além de deixar transparente para quem desenvolve, não sendo necessário lembrar se precisa usar &lt;em&gt;getteres&lt;&#x2F;em&gt; e &lt;em&gt;setteres&lt;&#x2F;em&gt; ou não.&lt;&#x2F;p&gt;
&lt;p&gt;De forma geral, programação orientada a objetos consiste em seguir determinados padrões de código, e as linguagens que implementam esse paradigma oferecem facilidades para escrever código seguindo esses padrões, e às vezes até ocultando detalhes complexos de suas implementações. Nesse contexto, eu recomendo a palestra do autor do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;htop.dev&#x2F;&quot;&gt;htop&lt;&#x2F;a&gt; feita no FISL 16, onde ele comenta como usou &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;hemingway.softwarelivre.org&#x2F;fisl16&#x2F;high&#x2F;41f&#x2F;sala_41f-high-201507091200.ogv&quot;&gt;orientação a objetos em C&lt;&#x2F;a&gt;. E para quem ainda quiser se aprofundar no assunto de orientação a objetos no Python, recomendo os vídeos do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;playlist?list=PLOQgLBuj2-3L_L6ahsBVA_SzuGtKre3OK&quot;&gt;Eduardo Mendes&lt;&#x2F;a&gt; (também conhecido como dunossauro).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Orientação a objetos de outra forma: ABC</title>
        <published>2021-05-01T00:00:00+00:00</published>
        <updated>2021-05-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-5/"/>
        <id>https://eduardoklosowski.github.io/blog/oo-de-outra-forma-5/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-5/">&lt;p&gt;Na discussão sobre &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;oo-de-outra-forma-4&#x2F;&quot;&gt;herança e mixins&lt;&#x2F;a&gt; foram criadas várias classes, como &lt;code&gt;Autenticavel&lt;&#x2F;code&gt; e &lt;code&gt;AutenticavelComRegistro&lt;&#x2F;code&gt; que adicionam funcionalidades a outras classes e implementavam tudo o que precisavam para seu funcionamento. Entretanto podem existir casos em que não seja possível implementar todas as funções na própria classe, deixando com que as classes que a estende implemente essas funções. Uma forma de fazer isso é través das &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;library&#x2F;abc.html&quot;&gt;ABC&lt;&#x2F;a&gt; (&lt;em&gt;abstract base classes&lt;&#x2F;em&gt;, ou classes base abstratas).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sem-uso-de-classes-base-abstratas&quot;&gt;Sem uso de classes base abstratas&lt;&#x2F;h2&gt;
&lt;p&gt;Um exemplo de classe que não é possível implementar todas as funcionalidades foi dada no texto &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;encapsulamento-da-logica-do-algoritmo&#x2F;&quot;&gt;Encapsulamento da lógica do algoritmo&lt;&#x2F;a&gt;, que discutia a leitura de valores do teclado até que um valor válido fosse lido (ou que repete a leitura caso um valor inválido tivesse sido informado). Nesse caso a classe &lt;code&gt;ValidaInput&lt;&#x2F;code&gt; implementava a lógica base de funcionamento, porém eram suas classes filhas (&lt;code&gt;ValidaNomeInput&lt;&#x2F;code&gt; e &lt;code&gt;ValidaNotaInput&lt;&#x2F;code&gt;) que implementavam as funções para tratar o que foi lido do teclado e verificar se é um valor válido ou não.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Valor inválido!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;(prompt)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span&gt; NotImplementedError&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span&gt; NotImplementedError&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __call__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; True&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(prompt))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(valor):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            except&lt;&#x2F;span&gt;&lt;span&gt; ValueError:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;                ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.mensagem_valor_invalido)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaNomeInput&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Nome inválido!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; entrada.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;strip&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;title&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaNotaInput&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Nota inválida!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; float&lt;&#x2F;span&gt;&lt;span&gt;(entrada)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Entretanto, esse código permite a criação de objetos da classe &lt;code&gt;ValidaInput&lt;&#x2F;code&gt; mesmo sem ter uma implementação das funções &lt;code&gt;transformar_entrada&lt;&#x2F;code&gt; e &lt;code&gt;validar_valor&lt;&#x2F;code&gt;. E a única mensagem de erro ocorreria ao tentar executar essas funções, o que poderia estar longe do problema real, que é a criação de um objeto a partir de uma classe que não prove todas as implementações das suas funções, o que seria semelhante a uma classe abstrata em outras linguagens.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;obj&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Diversas linhas de código&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;obj&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Entrada: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Exceção NotImplementedError lançada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;com-uso-de-classes-base-abstratas&quot;&gt;Com uso de classes base abstratas&lt;&#x2F;h2&gt;
&lt;p&gt;Seguindo a documentação da &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;library&#x2F;abc.html&quot;&gt;ABC&lt;&#x2F;a&gt;, para utilizá-las é necessário informar a metaclasse &lt;code&gt;ABCMeta&lt;&#x2F;code&gt; na criação da classe, ou simplesmente estender a classe &lt;code&gt;ABC&lt;&#x2F;code&gt;, e decorar com &lt;code&gt;abstractmethod&lt;&#x2F;code&gt; as funções que as classes que a estenderem deverão implementar. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; abc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ABC&lt;&#x2F;span&gt;&lt;span&gt;, abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;ABC&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Valor inválido!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;(prompt)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __call__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; True&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(prompt))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(valor):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            except&lt;&#x2F;span&gt;&lt;span&gt; ValueError:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;                ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.mensagem_valor_invalido)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Desta forma, ocorrerá um erro já ao tentar criar um objeto do tipo &lt;code&gt;ValidaInput&lt;&#x2F;code&gt;, dizendo quais são as funções que precisam ser implementadas. Porém funcionará normalmente ao criar objetos a partir das classes &lt;code&gt;ValidaNomeInput&lt;&#x2F;code&gt; e &lt;code&gt;ValidaNotaInput&lt;&#x2F;code&gt; visto que elas implementam essas funções.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;obj&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Exceção TypeError lançada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nome_input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ValidaNomeInput&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Objeto criado&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nota_input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ValidaNotaInput&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Objeto criado&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Como essas funções não utilizam a referência ao objeto (&lt;code&gt;self&lt;&#x2F;code&gt;), ainda é possível decorar as funções com &lt;code&gt;staticmethod&lt;&#x2F;code&gt;, como:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; abc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ABC&lt;&#x2F;span&gt;&lt;span&gt;, abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;ABC&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Valor inválido!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;(prompt)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __call__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; True&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(prompt))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(valor):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            except&lt;&#x2F;span&gt;&lt;span&gt; ValueError:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;                ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.mensagem_valor_invalido)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaNomeInput&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Nome inválido!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; entrada.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;strip&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;title&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaNotaInput&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Nota inválida!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; float&lt;&#x2F;span&gt;&lt;span&gt;(entrada)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Isso também seria válido para funções decoradas com &lt;code&gt;classmethod&lt;&#x2F;code&gt;, que receberiam a referência a classe (&lt;code&gt;cls&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Não é necessário utilizar ABC para fazer o exemplo discutido, porém ao utilizar essa biblioteca ficou mais explícito quais as funções que precisavam ser implementados nas classes filhas, ainda mais que sem utilizar ABC a classe base poderia nem ter as funções, com:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Valor inválido!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;(prompt)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __call__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; True&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(prompt))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(valor):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            except&lt;&#x2F;span&gt;&lt;span&gt; ValueError:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;                ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.mensagem_valor_invalido)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Como Python possui &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;glossary.html#term-duck-typing&quot;&gt;duck-typing&lt;&#x2F;a&gt;, não é necessário uma grande preocupação com os tipos, como definir e utilizar interfaces presentes em outras implementações de orientação a objetos, porém devido à herança múltipla, ABC pode ser utilizada como interface que não existe em Python, fazendo com que as classes implementem determinadas funções. Para mais a respeito desse assunto, recomendo as duas lives do dunossauro sobre ABC (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=yLHV1__nZZw&quot;&gt;1&lt;&#x2F;a&gt; e &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=erAXvsuihPQ&quot;&gt;2&lt;&#x2F;a&gt;), e a apresentação do Luciano Ramalho sobre &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=AJK2LqrlnTE&quot;&gt;type hints&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Uma classe filha também não é obrigada a implementar todas as funções decoradas com &lt;code&gt;abstractmethod&lt;&#x2F;code&gt;, mas assim como a classe pai, não será possível criar objetos a partir dessa classe, apenas de uma classe filha dela que implemente as demais funções. Como se ao aplicar um &lt;code&gt;abstractmethod&lt;&#x2F;code&gt; tornasse a classe abstrata, e qualquer classe filha só deixasse de ser abstrata quando a última função decorada com &lt;code&gt;abstractmethod&lt;&#x2F;code&gt; for sobrescrita. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; abc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ABC&lt;&#x2F;span&gt;&lt;span&gt;, abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; A&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;ABC&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; func1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @abstractmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; func2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; B&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;A&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; func1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;1&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; C&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; func2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;2&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; A&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Erro por não implementar func1 e func2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; B&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Erro por não implementar func2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; C&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Objeto criado&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Orientação a objetos de outra forma: Herança múltiplas e mixins</title>
        <published>2021-04-24T00:00:00+00:00</published>
        <updated>2021-04-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-4/"/>
        <id>https://eduardoklosowski.github.io/blog/oo-de-outra-forma-4/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-4/">&lt;p&gt;No &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;oo-de-outra-forma-3&#x2F;&quot;&gt;texto anterior&lt;&#x2F;a&gt; foi apresentando o conceito de herança, que herda toda a estrutura e comportamento de uma classe, podendo estendê-la com outros atributos e comportamentos. Esse texto apresentará a ideia de &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Heran%C3%A7a_m%C3%BAltipla&quot;&gt;herança múltipla&lt;&#x2F;a&gt;, e uma forma para se aproveitar esse recurso, através de mixins.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;heranca-multiplas&quot;&gt;Herança múltiplas&lt;&#x2F;h2&gt;
&lt;p&gt;Voltando ao sistema para lidar com dados das pessoas, onde algumas dessas pessoas possuem a possibilidade de acessar o sistema através de usuário e senha, também deseja-se permitir que outros sistemas autentiquem e tenham acesso os dados através de uma &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Interface_de_programa%C3%A7%C3%A3o_de_aplica%C3%A7%C3%B5es&quot;&gt;API&lt;&#x2F;a&gt;. Isso pode ser feito criando uma classe para representar os sistemas que terão permissão para acessar os dados. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Sistema&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; autenticar&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Porém, esse código repete a implementação feita para &lt;code&gt;PessoaAutenticavel&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PessoaAutenticavel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;span&gt;(nome, sobrenome, idade)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; autenticar&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Aproveitando que Python, diferente de outras linguagens, possui herança múltipla, é possível extrair essa lógica das classes, centralizando a implementação em uma outra classe e simplesmente herdá-la. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Autenticavel&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;, **&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;kwargs&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;span&gt;(*args, **kwargs)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; autenticar&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PessoaAutenticavel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Autenticavel&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Sistema&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Autenticavel&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; PessoaAutenticavel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;                       usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;joao&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;secreta&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A primeira coisa a ser observada são os argumentos &lt;code&gt;*args&lt;&#x2F;code&gt; e &lt;code&gt;**kwargs&lt;&#x2F;code&gt; no &lt;code&gt;__init__&lt;&#x2F;code&gt; da classe &lt;code&gt;Autenticavel&lt;&#x2F;code&gt;, eles são usados uma vez que não se sabe todos os argumentos que o &lt;code&gt;__init__&lt;&#x2F;code&gt; da classe que estenderá o &lt;code&gt;Autenticavel&lt;&#x2F;code&gt; espera receber, funcionando de forma dinâmica (mais sobre esse recurso pode ser visto na &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;tutorial&#x2F;controlflow.html#more-on-defining-functions&quot;&gt;documentação do Python&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;A segunda coisa a ser verificada é que para a classe &lt;code&gt;PessoaAutenticavel&lt;&#x2F;code&gt;, agora cria em seus objetos, a estrutura tanto da classe &lt;code&gt;Pessoa&lt;&#x2F;code&gt;, quanto &lt;code&gt;Autenticavel&lt;&#x2F;code&gt;. Algo similar a versão sem orientação a objetos a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Arquivo: pessoa_autenticavel.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; autenticavel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pessoa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(p, nome, sobrenome, idade)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    autenticavel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(p, usuario, senha)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Também vale observar que as classes &lt;code&gt;PessoaAutenticavel&lt;&#x2F;code&gt; e &lt;code&gt;Sistema&lt;&#x2F;code&gt; não precisam definir nenhuma função, uma vez que elas cumprem seus papéis apenas herdando outras classes, porém seria possível implementar funções específicas dessas classes, assim como sobrescrever as funções definidas por outras classes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ordem-de-resolucao-de-metodos&quot;&gt;Ordem de resolução de métodos&lt;&#x2F;h2&gt;
&lt;p&gt;Embora herança múltiplas sejam interessantes, existe um problema, se ambas as classes pai possuírem uma função com um mesmo nome, a classe filha deveria chamar qual das funções? A do primeiro pai? A do último? Para lidar com esse problema o Python usa o MRO (&lt;em&gt;method resolution order&lt;&#x2F;em&gt;, ordem de resolução do método), que consiste em uma tupla com a ordem de qual classe o Python usará para encontrar o método a ser chamado. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(PessoaAutenticavel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;__mro__&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# (&amp;lt;class &amp;#39;__main__.PessoaAutenticavel&amp;#39;&amp;gt;, &amp;lt;class &amp;#39;__main__.Autenticavel&amp;#39;&amp;gt;, &amp;lt;class &amp;#39;__main__.Pessoa&amp;#39;&amp;gt;, &amp;lt;class &amp;#39;object&amp;#39;&amp;gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Por esse motivo que também foi possível chamar o &lt;code&gt;super().__init__&lt;&#x2F;code&gt; dentro de &lt;code&gt;Autenticavel&lt;&#x2F;code&gt;, que devido ao MRO, o Python chama o &lt;code&gt;__init__&lt;&#x2F;code&gt; da outra classe pai da classe que estendeu &lt;code&gt;Autenticavel&lt;&#x2F;code&gt;, em vez de precisar fazer um método &lt;code&gt;__init__&lt;&#x2F;code&gt; em &lt;code&gt;PessoaAutenticavel&lt;&#x2F;code&gt; chamando o &lt;code&gt;__init__&lt;&#x2F;code&gt; de todas as suas classes pais, como foi feito na versão sem orientação a objetos. E por isso a ordem &lt;code&gt;Autenticavel&lt;&#x2F;code&gt; e &lt;code&gt;Pessoa&lt;&#x2F;code&gt; na herança de &lt;code&gt;PessoaAutenticavel&lt;&#x2F;code&gt;, para fazer o MRO procurar os métodos primeiro em &lt;code&gt;Autenticavel&lt;&#x2F;code&gt; e depois em &lt;code&gt;Pessoa&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Para tentar fugir da complexidade que pode ser herança múltipla, é possível escrever classes que tem por objetivo unicamente incluir alguma funcionalidade em outra, como o caso da classe &lt;code&gt;Autenticavel&lt;&#x2F;code&gt;, que pode ser herdada por qualquer outra classe do sistema para permitir o acesso ao sistema. Essas classes recebem o nome de mixins, e adiciona uma funcionalidade bem definida.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;estendendo-mixins&quot;&gt;Estendendo mixins&lt;&#x2F;h2&gt;
&lt;p&gt;Imagine se além de permitir o acesso ao sistema, também gostaríamos de registrar algumas tentativas de acesso, informando quando houve a tentativa e se o acesso foi concedido ou não. Como &lt;code&gt;Autenticavel&lt;&#x2F;code&gt; é uma classe, é possível extendê-la para implementar essa funcionalidade na função &lt;code&gt;autenticar&lt;&#x2F;code&gt;. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; datetime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; datetime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; AutenticavelComRegistro&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Autenticavel&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; _get_data&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; datetime.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;now&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;strftime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;%d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&#x2F;%m&#x2F;%Y %T&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; autenticar&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;_get_data&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; Tentativa de acesso de &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        acesso&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = super&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;autenticar&lt;&#x2F;span&gt;&lt;span&gt;(usuario, senha)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; acesso:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            acesso_str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;permitido&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            acesso_str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;negado&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;_get_data&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; Acesso de &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span&gt;acesso_str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; acesso&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PessoaAutenticavelComRegistro&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;AutenticavelComRegistro&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SistemaAutenticavelComRegistro&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;AutenticavelComRegistro&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Sistema&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; PessoaAutenticavelComRegistro&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;    nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;    usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;joao&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;secreta&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;autenticar&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;joao&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;secreta&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Saída na tela:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# 23&#x2F;04&#x2F;2021 16:56:58 Tentativa de acesso de joao&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# 23&#x2F;04&#x2F;2021 16:56:58 Acesso de joao permitido&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essa implementação utiliza-se do &lt;code&gt;super()&lt;&#x2F;code&gt; para acessar a função &lt;code&gt;autenticar&lt;&#x2F;code&gt; da classe &lt;code&gt;Autenticavel&lt;&#x2F;code&gt; para não precisar reimplementar a autenticação. Porém, antes de chamá-la, manipula seus argumentos para registrar quem tentou acessar o sistema, assim como também manipula o seu retorno para registrar se o acesso foi permitido ou não.&lt;&#x2F;p&gt;
&lt;p&gt;Essa classe também permite analisar melhor a ordem em que as classes são consultadas quando uma função é chamada:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(PessoaAutenticavelComRegistro.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;__mro__&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# (&amp;lt;class &amp;#39;__main__.PessoaAutenticavelComRegistro&amp;#39;&amp;gt;, &amp;lt;class &amp;#39;__main__.AutenticavelComRegistro&amp;#39;&amp;gt;, &amp;lt;class &amp;#39;__main__.Autenticavel&amp;#39;&amp;gt;, &amp;lt;class &amp;#39;__main__.Pessoa&amp;#39;&amp;gt;, &amp;lt;class &amp;#39;object&amp;#39;&amp;gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Que também pode ser visto na forma de um digrama de classes:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;oo-de-outra-forma-4&#x2F;mro.png&quot; alt=&quot;Diagrama de classes&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Onde é feito uma &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Busca_em_profundidade&quot;&gt;busca em profundidade&lt;&#x2F;a&gt;, como se a função fosse chamada no primeiro pai, e só se ela não for encontrada, busca-se no segundo pai e assim por diante. Também é possível observar a classe &lt;code&gt;object&lt;&#x2F;code&gt;, que sempre será a última classe, e é a classe pai de todas as outras classes do Python quando elas não possuirem um pai declarado explicitamente.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Herança múltipla pode dificultar bastante o entendimento do código, principalmente para encontrar onde determinada função está definida, porém pode facilitar bastante o código. Um exemplo que usa bastante herança e mixins são as &lt;em&gt;views&lt;&#x2F;em&gt; baseadas em classe do django (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.djangoproject.com&#x2F;pt-br&#x2F;3.2&#x2F;topics&#x2F;class-based-views&#x2F;&quot;&gt;&lt;em&gt;class-based views&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;), porém para facilitar a visualização existe o site &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ccbv.co.uk&#x2F;&quot;&gt;Classy Class-Based Views&lt;&#x2F;a&gt; que lista todas as classes, e os mixins utilizados em cada uma, como pode ser visto em &quot;Ancestors&quot; como na &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ccbv.co.uk&#x2F;projects&#x2F;Django&#x2F;3.1&#x2F;django.views.generic.edit&#x2F;UpdateView&#x2F;&quot;&gt;UpdateView&lt;&#x2F;a&gt;, que é usado para criar uma página com formulário para editar um registro já existente no banco, assim ela usa mixins para pegar um objeto do banco (&lt;code&gt;SingleObjectMixin&lt;&#x2F;code&gt;), processar formulário baseado em uma tabela do banco (&lt;code&gt;ModelFormMixin&lt;&#x2F;code&gt;) e algumas outras funcionalidades necessárias para implementar essa página.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Orientação a objetos de outra forma: Herança</title>
        <published>2021-04-17T00:00:00+00:00</published>
        <updated>2021-04-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-3/"/>
        <id>https://eduardoklosowski.github.io/blog/oo-de-outra-forma-3/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-3/">&lt;p&gt;Algo que ajuda no desenvolvimento é a reutilização de código. Em orientação a objetos, essa reutilização pode ocorrer através de herança, onde um objeto pode se comportar como um objeto da sua própria classe, como também da classe que herdou.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;adicionando-funcionalidades&quot;&gt;Adicionando funcionalidades&lt;&#x2F;h2&gt;
&lt;p&gt;Uma das utilidades da herança é estender uma classe para adicionar funcionalidades. Pensando no contexto das postagens anteriores, poderíamos querer criar um usuário e senha para algumas pessoas poderem acessar o sistema. Isso poderia ser feito adicionando atributos usuário e senha para as pessoas, além de uma função para validar se os dados estão corretos, e assim permitir o acesso ao sistema. Porém isso não pode ser feito para todas as pessoas, e sim apenas para aqueles que possuem permissão de acesso.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sem-orientacao-a-objetos&quot;&gt;Sem orientação a objetos&lt;&#x2F;h3&gt;
&lt;p&gt;Voltando a solução com dicionários (sem utilizar orientação a objetos), isso consistiria em criar um dicionário com a estrutura de uma pessoa, e em seguida estender essa estrutura com os novos campos de usuário e senha nesse mesmo dicionário, algo como:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Arquivo: pessoa.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;pessoa&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;sobrenome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;idade&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span&gt;pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;sobrenome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Arquivo: pessoa_autenticavel.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;pessoa&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;usuario&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;senha&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; autenticar&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;pessoa&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;usuario&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;senha&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pessoa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pessoa_autenticavel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(p,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pessoa_autenticavel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(p,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;joao&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;secreta&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(p))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(pessoa_autenticavel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;autenticar&lt;&#x2F;span&gt;&lt;span&gt;(p,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;joao&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;secreta&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Porém nessa solução é possível que o programador esqueça de chamar as duas funções &lt;code&gt;init&lt;&#x2F;code&gt; diferentes, e como queremos que todo dicionário com a estrutura de &lt;code&gt;pessoa_autenticavel&lt;&#x2F;code&gt; contenha também a estrutura de &lt;code&gt;pessoa&lt;&#x2F;code&gt;, podemos chamar o &lt;code&gt;init&lt;&#x2F;code&gt; de pessoa dentro do &lt;code&gt;init&lt;&#x2F;code&gt; de &lt;code&gt;pessoa_autenticavel&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Arquivo: pessoa_autenticavel.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pessoa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(p, nome, sobrenome, idade)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    p[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;usuario&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    p[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;senha&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Demais funções&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pessoa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pessoa_autenticavel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pessoa_autenticavel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(p,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;joao&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;secreta&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(p))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(pessoa_autenticavel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;autenticar&lt;&#x2F;span&gt;&lt;span&gt;(p,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;joao&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;secreta&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse caso foi necessário alterar o nome do argumento &lt;code&gt;pessoa&lt;&#x2F;code&gt; da função &lt;code&gt;pessoa_autenticavel.init&lt;&#x2F;code&gt; para não conflitar com o outro módulo importado com esse mesmo nome. Porém ao chamar um &lt;code&gt;init&lt;&#x2F;code&gt; dentro de outro, temos a garantia de que o dicionário será compatível tanto com a estrutura pedida para ser criada pelo programador, quanto pelas estruturas pais dela.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;com-orientacao-a-objetos&quot;&gt;Com orientação a objetos&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PessoaAutenticavel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, nome, sobrenome, idade)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; autenticar&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; PessoaAutenticavel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;joao&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;secreta&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(Pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(p))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(PessoaAutenticavel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;autenticar&lt;&#x2F;span&gt;&lt;span&gt;(p,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;joao&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;secreta&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A principal novidade desse exemplo é que ao declarar a classe &lt;code&gt;PessoaAutenticavel&lt;&#x2F;code&gt; (filha), foi declarado a classe &lt;code&gt;Pessoa&lt;&#x2F;code&gt; (pai) entre parênteses, isso faz o interpretador Python criar uma cópia dessa classe estendendo-a com as novas funções que estamos criando. Porém pode ser um pouco redundante chamar &lt;code&gt;Pessoa.__init__&lt;&#x2F;code&gt; dentro da função &lt;code&gt;__init__&lt;&#x2F;code&gt; sendo que já foi declarado que ela estende &lt;code&gt;Pessoa&lt;&#x2F;code&gt;, podendo ser trocado por &lt;code&gt;super()&lt;&#x2F;code&gt;, que aponta para a classe que foi estendida. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PessoaAutenticavel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; usuario&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; senha&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;span&gt;(nome, sobrenome, idade)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.usuario&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; usuario&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; senha&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Demais funções&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Assim se evita repetir o nome da classe, e já passa automaticamente a referência para &lt;code&gt;self&lt;&#x2F;code&gt;, assim como quando usamos o açúcar sintático apresentado na primeira postagem dessa série. E esse açúcar sintática também pode ser usado para chamar tanto as funções declaradas em &lt;code&gt;Pessoa&lt;&#x2F;code&gt; quanto em &lt;code&gt;PessoaAutenticavel&lt;&#x2F;code&gt;. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; PessoaAutenticavel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;joao&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;secreta&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nome_completo&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;autenticar&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;joao&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;secreta&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse método também facilita a utilização das funções, uma vez que não é necessário lembrar em qual classe que cada função foi declarada. Na verdade, como &lt;code&gt;PessoaAutenticavel&lt;&#x2F;code&gt; estende &lt;code&gt;Pessoa&lt;&#x2F;code&gt;, seria possível executar também &lt;code&gt;PessoaAutenticavel.nome_completo&lt;&#x2F;code&gt;, porém eles apontam para a mesma função.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sobrescrevendo-uma-funcao&quot;&gt;Sobrescrevendo uma função&lt;&#x2F;h2&gt;
&lt;p&gt;A classe &lt;code&gt;Pessoa&lt;&#x2F;code&gt; possui a função &lt;code&gt;nome_completo&lt;&#x2F;code&gt; que retorna uma &lt;code&gt;str&lt;&#x2F;code&gt; contento nome e sobrenome. Porém no Japão, assim como em outros países asiáticos, o sobrenome vem primeiro, e até &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;noticias.uol.com.br&#x2F;ultimas-noticias&#x2F;efe&#x2F;2019&#x2F;06&#x2F;24&#x2F;japao-quer-voltar-a-ordem-tradicional-dos-nomes-abe-shinzo-nao-shinzo-abe.htm&quot;&gt;estão pedindo para seguir a tradição deles ao falarem os nomes de japoneses&lt;&#x2F;a&gt;, como o caso do primeiro-ministro, mudando de Shinzo Abe para Abe Shinzo.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;com-orientacao-a-objetos-1&quot;&gt;Com orientação a objetos&lt;&#x2F;h3&gt;
&lt;p&gt;Isso também pode ser feito no sistema usando herança, porém em vez de criar uma nova função com outro nome, é possível criar uma função com o mesmo nome, sobrescrevendo a anterior, porém apenas para os objetos da classe filha. Algo semelhante ao que já foi feito com a função &lt;code&gt;__init__&lt;&#x2F;code&gt;. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Japones&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Japones&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Shinzo&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Abe&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 66&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p1.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nome_completo&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # João da Silva&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p2.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nome_completo&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Abe Shinzo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essa relação de herança traz algo interessante, todo objeto da classe &lt;code&gt;Japones&lt;&#x2F;code&gt; se comporta como um objeto da classe &lt;code&gt;Pessoa&lt;&#x2F;code&gt;, porém a relação inversa não é verdade. Assim como podemos dizer que todo japonês é uma pessoa, mas nem todas as pessoas são japonesas. Ser japonês é um caso mais específico de pessoa, assim como as demais nacionalidades.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sem-orientacao-a-objetos-1&quot;&gt;Sem orientação a objetos&lt;&#x2F;h3&gt;
&lt;p&gt;Esse comportamento de sobrescrever a função &lt;code&gt;nome_completo&lt;&#x2F;code&gt; não é tão simples de replicar em uma estrutura de dicionário, porém é possível fazer. Porém como uma pessoa pode ser tanto japonês quanto não ser, não é possível saber de antemão para escrever no código &lt;code&gt;pessoa.nome_completo&lt;&#x2F;code&gt; ou &lt;code&gt;japones.nome_completo&lt;&#x2F;code&gt;, que diferente do exemplo da autenticação, agora são duas funções diferentes, isso precisa ser descoberto dinamicamente quando se precisar chamar a função.&lt;&#x2F;p&gt;
&lt;p&gt;Uma forma de fazer isso é guardar uma referência para a função que deve ser chamada dentro da própria estrutura. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Arquivo: pessoa.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;pessoa&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;sobrenome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;idade&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome_completo&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome_completo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span&gt;pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;sobrenome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Arquivo: japones.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pessoa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;japones&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    pessoa&lt;&#x2F;span&gt;&lt;span&gt;(japones, nome, sobrenome, idade)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    japones[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome_completo&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome_completo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;japones&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;sobrenome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span&gt;pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pessoa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; japones&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(p1,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;japones.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(p2,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Shinzo&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Abe&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 66&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p1[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome_completo&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;](p1))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # João da Silva&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p2[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome_completo&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;](p2))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Abe Shinzo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Perceba que a forma de chamar a função foi alterada. O que acontece na prática é que toda função que pode ser sobrescrita não é chamada diretamente, e sim a partir de uma referência, e isso gera um custo computacional adicional. Como esse custo não é tão alto (muitas vezes sendo quase irrelevante), esse é o comportamento adotado em várias linguagens, porém em C++, por exemplo, existe a palavra-chave &lt;code&gt;virtual&lt;&#x2F;code&gt; para descrever quando uma função pode ser sobrescrita ou não.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Herança é um mecanismo interessante para ser explorado com o objetivo de reaproveitar código e evitar repeti-lo. Porém isso pode vir com alguns custos, seja computacional durante sua execução, seja durante a leitura do código, sendo necessário verificar diversas classes para saber o que de fato está sendo executado, porém isso também pode ser usado para ocultar e abstrair lógicas mais complicadas, como eu já comentei em outra &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;encapsulamento-da-logica-do-algoritmo&#x2F;&quot;&gt;postagem&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Herança também permite trabalhar com generalização e especialização, podendo descrever o comportamento mais geral, ou mais específico. Ou simplesmente só adicionar mais funcionalidades a uma classe já existente.&lt;&#x2F;p&gt;
&lt;p&gt;Assim como foi utilizado o &lt;code&gt;super()&lt;&#x2F;code&gt; para chamar a função &lt;code&gt;__init__&lt;&#x2F;code&gt; da classe pai, é possível utilizá-lo para chamar qualquer outra função. Isso permite, por exemplo, tratar os argumentos da função, aplicando modificações antes de chamar a função original, ou seu retorno, executando algum processamento em cima do retorno dela, não precisando rescrever toda a função.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Orientação a objetos de outra forma: Métodos estáticos e de classes</title>
        <published>2021-04-10T00:00:00+00:00</published>
        <updated>2021-04-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-2/"/>
        <id>https://eduardoklosowski.github.io/blog/oo-de-outra-forma-2/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-2/">&lt;p&gt;Na &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;oo-de-outra-forma-1&#x2F;&quot;&gt;postagem anterior&lt;&#x2F;a&gt; foi apresentado o &lt;code&gt;self&lt;&#x2F;code&gt;, nessa postagem será discutido mais a respeito desse argumento, considerando opções para ele e suas aplicações.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;metodos-estaticos&quot;&gt;Métodos estáticos&lt;&#x2F;h2&gt;
&lt;p&gt;Nem todas as funções de uma classe precisam receber uma referência de um objeto para lê-lo ou alterá-lo, muitas vezes uma função pode fazer o seu papel apenas com os dados passados como argumento, por exemplo, receber um nome e validar se ele possui pelo menos três caracteres sem espaço. Dessa forma, essa função poderia ser colocada fora do escopo da classe, porém para facilitar sua chamada, e possíveis alterações (que será discutido em outra postagem), é possível colocar essa função dentro da classe e informar que ela não receberá o argumento &lt;code&gt;self&lt;&#x2F;code&gt; com o decorador &lt;code&gt;@staticmethod&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Demais funções&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; valida_nome&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;nome&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(nome)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; not in&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Dessa forma, essa função pode ser chamada diretamente de um objeto pessoa, ou até mesmo diretamente da classe, sem precisar criar um objeto primeiro:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Chamando diretamente da classe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(Pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;valida_nome&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Chamando através de um objeto do tipo Pessoa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p1.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;valida_nome&lt;&#x2F;span&gt;&lt;span&gt;(p1.nome))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;E essa função também pode ser utilizada dendro de outras funções, como validar o nome na criação de uma pessoa, de forma que caso o nome informado seja válido, será criado um objeto do tipo Pessoa, e caso o nome seja inválido, será lançado uma exceção:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;valida_nome&lt;&#x2F;span&gt;&lt;span&gt;(nome):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span&gt; ValueError(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Nome inválido&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Demais funções&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;staticmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; valida_nome&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;nome&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; len&lt;&#x2F;span&gt;&lt;span&gt;(nome)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; not in&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Cria objeto&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;a&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Lança ValueError: Nome inválido&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;metodos-da-classe&quot;&gt;Métodos da classe&lt;&#x2F;h2&gt;
&lt;p&gt;Entretanto algumas funções podem precisar de um meio termo, necessitar acessar o contexto da classe, porém sem necessitar de um objeto. Isso é feito através do decorador &lt;code&gt;@classmethod&lt;&#x2F;code&gt;, onde a função decorada com ele, em vez de receber um objeto como primeiro argumento, recebe a própria classe.&lt;&#x2F;p&gt;
&lt;p&gt;Para demonstrar essa funcionalidade será implementado um &lt;em&gt;id&lt;&#x2F;em&gt; auto incremental para os objetos da classe &lt;code&gt;Pessoa&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    total_de_pessoas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;classmethod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; novo_id&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;cls&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        cls&lt;&#x2F;span&gt;&lt;span&gt;.total_de_pessoas&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; cls&lt;&#x2F;span&gt;&lt;span&gt;.total_de_pessoas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;novo_id&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p1.id)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Imprime 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Maria&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;dos Santos&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p2.id)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Imprime 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(Pessoa.total_de_pessoas)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Imprime 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p1.total_de_pessoas)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Imprime 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p2.total_de_pessoas)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Imprime 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse código é criado uma variável &lt;code&gt;total_de_pessoas&lt;&#x2F;code&gt; dentro do escopo da classe &lt;code&gt;Pessoas&lt;&#x2F;code&gt;, e que é compartilhado tanto pela classe, como pelos objetos dessa classe, diferente de declará-la com &lt;code&gt;self.&lt;&#x2F;code&gt; dentro do &lt;code&gt;__init__&lt;&#x2F;code&gt;, onde esse valor pertenceria apenas ao objeto, e não é compartilhado com os demais objetos. Declarar variáveis dentro do contexto da classe é similar ao se declarar variáveis com &lt;code&gt;static&lt;&#x2F;code&gt; em outras linguagens, assim como o &lt;code&gt;@classmethod&lt;&#x2F;code&gt; é semelhante a declaração de funções com &lt;code&gt;static&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;As funções declaradas com &lt;code&gt;@classmethod&lt;&#x2F;code&gt; também podem ser chamadas sem a necessidade de se criar um objeto, como &lt;code&gt;Pessoa.novo_id()&lt;&#x2F;code&gt;, embora que para essa função específica isso não faça muito sentido, ou receber outros argumentos, tudo depende do que essa função fará.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Embora possa parecer confuso identificar a diferença de uma função de um objeto (função sem decorador), função de uma classe (com decorador &lt;code&gt;@classmethod&lt;&#x2F;code&gt;) e função sem acesso a nenhum outro contexto (com decorador &lt;code&gt;@staticmethod&lt;&#x2F;code&gt;), essa diferença fica mais clara ao se analisar o primeiro argumento recebido por cada tipo de função. Podendo ser a referência a um objeto (&lt;code&gt;self&lt;&#x2F;code&gt;) e assim necessitando que um objeto seja criado anteriormente, ser uma classe (&lt;code&gt;cls&lt;&#x2F;code&gt;) e não necessitando receber um objeto, ou simplesmente não recebendo nenhum argumento especial, apenas os demais argumentos necessários para a função. Sendo diferenciados pelo uso dos decoradores.&lt;&#x2F;p&gt;
&lt;p&gt;Na orientação a objetos implementada pelo Python, algumas coisas podem ficar confusas quando se mistura com nomenclaturas de outras linguagens que possuem implementações diferentes. A linguagem Java, por exemplo, utiliza a palavra-chave &lt;code&gt;static&lt;&#x2F;code&gt; para definir os atributos e métodos de classe, enquanto no Python um método estático é aquele que não acessa nem um objeto, nem uma classe, devendo ser utilizado o escopo da classe e o decorador &lt;code&gt;@classmethod&lt;&#x2F;code&gt; para se criar atributos e métodos da classe.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Orientação a objetos de outra forma: Classes e objetos</title>
        <published>2021-04-04T00:00:00+00:00</published>
        <updated>2021-04-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-1/"/>
        <id>https://eduardoklosowski.github.io/blog/oo-de-outra-forma-1/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/oo-de-outra-forma-1/">&lt;p&gt;Nas poucas e raríssimas lives que eu fiz na &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;eduardoklosowski&quot;&gt;Twitch&lt;&#x2F;a&gt;, surgiu a ideia de escrever sobre programação orientada a objetos em &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.python.org&#x2F;&quot;&gt;Python&lt;&#x2F;a&gt;, principalmente por algumas diferenças de como ela foi implementada nessa linguagem. Aproveitando o tema, vou fazer uma série de postagens dando uma visão diferente sobre orientação a objetos. E nessa primeira postagem falarei sobre classes e objetos.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;usando-um-dicionario&quot;&gt;Usando um dicionário&lt;&#x2F;h2&gt;
&lt;p&gt;Entretanto, antes de começar com orientação a objetos, gostaria de apresentar e discutir alguns exemplos sem utilizar esse paradigma de programação.&lt;&#x2F;p&gt;
&lt;p&gt;Pensando em um sistema que precise manipular dados de pessoas, é possível utilizar os &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;library&#x2F;stdtypes.html#mapping-types-dict&quot;&gt;dicionários&lt;&#x2F;a&gt; do Python para agrupar os dados de uma pessoa em uma única variável, como no exemplo a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pessoa&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;    &amp;#39;nome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;    &amp;#39;sobrenome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;    &amp;#39;idade&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Onde os dados poderiam ser acessados através da variável e do nome do dado desejado, como:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Imprimindo João&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Assim, todos os dados de uma pessoa ficam agrupados em uma variável, o que facilita bastante a programação, visto que não é necessário criar uma variável para cada dado, e quando se manipula os dados de diferentes pessoas fica muito mais fácil identificar de qual pessoa aquele dado se refere, bastando utilizar variáveis diferentes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;funcao-para-criar-o-dicionario&quot;&gt;Função para criar o dicionário&lt;&#x2F;h3&gt;
&lt;p&gt;Apesar de prático, é necessário replicar essa estrutura de dicionário toda vez que se desejar utilizar os dados de uma nova pessoa. Para evitar a repetição de código, a criação desse dicionário pode ser feita dentro de uma função que pode ser colocada em um módulo &lt;code&gt;pessoa&lt;&#x2F;code&gt; (arquivo, nesse caso com o nome de &lt;code&gt;pessoa.py&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Arquivo: pessoa.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nova&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;        &amp;#39;nome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: nome,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;        &amp;#39;sobrenome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: sobrenome,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;        &amp;#39;idade&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;: idade,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;E para criar o dicionário que representa uma pessoa, basta importar esse módulo (arquivo) e chamar a função &lt;code&gt;nova&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pessoa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nova&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nova&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Maria&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;dos Santos&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Desta forma, garante-se que todos os dicionários representando pessoas terão os campos desejados e devidamente preenchidos.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;funcao-com-o-dicionario&quot;&gt;Função com o dicionário&lt;&#x2F;h3&gt;
&lt;p&gt;Também é possível criar algumas funções para executar operações com os dados desses dicionários, como pegar o nome completo da pessoa, trocar o seu sobrenome, ou fazer aniversário (o que aumentaria a idade da pessoa em um ano):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Arquivo: pessoa.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nova&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Código abreviado&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span&gt;pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;sobrenome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; trocar_sobrenome&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;pessoa&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;sobrenome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fazer_aniversario&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;pessoa&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;idade&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;E sendo usado como:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pessoa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nova&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;trocar_sobrenome&lt;&#x2F;span&gt;&lt;span&gt;(p1,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;dos Santos&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(p1))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;fazer_aniversario&lt;&#x2F;span&gt;&lt;span&gt;(p1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p1[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;idade&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse caso, pode-se observar que todas as funções aqui implementadas seguem o padrão de receber o dicionário que representa a pessoa como primeiro argumento, podendo ter outros argumentos ou não conforme a necessidade, acessando e alterando os valores desse dicionário.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;versao-com-orientacao-a-objetos&quot;&gt;Versão com orientação a objetos&lt;&#x2F;h2&gt;
&lt;p&gt;Antes de entrar na versão orientada a objetos propriamente dita dos exemplos anteriores, vou fazer uma pequena alteração para facilitar o entendimento posterior. A função &lt;code&gt;nova&lt;&#x2F;code&gt; será separada em duas partes, a primeira que criará um dicionário, e chamará uma segunda função (&lt;code&gt;init&lt;&#x2F;code&gt;), que receberá esse dicionário como primeiro argumento (seguindo o padrão das demais funções) e criará sua estrutura com os devidos valores.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Arquivo: pessoa.py&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;pessoa&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;nome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;sobrenome&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;idade&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nova&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pessoa&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    init&lt;&#x2F;span&gt;&lt;span&gt;(pessoa, nome, sobrenome, idade)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; pessoa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Demais funções do arquivo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Porém isso não muda a forma de uso:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; pessoa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nova&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;funcao-para-criar-uma-pessoa&quot;&gt;Função para criar uma pessoa&lt;&#x2F;h3&gt;
&lt;p&gt;A maioria das linguagens de programação que possuem o paradigma de programação orientado a objetos faz o uso de classes para definir a estrutura dos objetos. O Python também utiliza classes, que podem ser definidas com a palavra-chave &lt;code&gt;class&lt;&#x2F;code&gt; seguidas de um nome para ela. E dentro dessa estrutura, podem ser definidas funções para manipular os objetos daquela classe, que em algumas linguagens também são chamadas de métodos (funções declaradas dentro do escopo uma classe).&lt;&#x2F;p&gt;
&lt;p&gt;Para converter o dicionário para uma classe, o primeiro passo é implementar uma função para criar a estrutura desejada. Essa função deve possui o nome &lt;code&gt;__init__&lt;&#x2F;code&gt;, e é bastante similar a função &lt;code&gt;init&lt;&#x2F;code&gt; do código anterior:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As diferenças são que agora o primeiro parâmetro se chama &lt;code&gt;self&lt;&#x2F;code&gt;, que é um padrão utilizado no Python, e em vez de usar colchetes e aspas para acessar os dados, aqui basta utilizar o ponto e o nome do dado desejado (que aqui também pode ser chamado de atributo, visto que é uma variável do objeto). A função &lt;code&gt;nova&lt;&#x2F;code&gt; implementada anteriormente não é necessária, a própria linguagem cria um objeto e passa ele como primeiro argumento para o &lt;code&gt;__init__&lt;&#x2F;code&gt;. E assim para se criar um objeto da classe &lt;code&gt;Pessoa&lt;&#x2F;code&gt; basta chamar a classe como se fosse uma função, ignorando o argumento &lt;code&gt;self&lt;&#x2F;code&gt; e informando os demais, como se estivesse chamando a função &lt;code&gt;__init__&lt;&#x2F;code&gt; diretamente:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;da Silva&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse caso, como a própria classe cria um contexto diferente para as funções (escopo ou &lt;em&gt;namespace&lt;&#x2F;em&gt;), não está mais sendo utilizado arquivos diferentes, porém ainda é possível fazê-lo, sendo necessário apenas fazer o &lt;code&gt;import&lt;&#x2F;code&gt; adequado. Mas para simplificação, tanto a declaração da classe, como a criação do objeto da classe &lt;code&gt;Pessoa&lt;&#x2F;code&gt; podem ser feitas no mesmo arquivo, assim como os demais exemplos dessa postagem.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;outras-funcoes&quot;&gt;Outras funções&lt;&#x2F;h3&gt;
&lt;p&gt;As demais funções feitas anteriormente para o dicionário também podem ser feitas na classe &lt;code&gt;Pessoa&lt;&#x2F;code&gt;, seguindo as mesmas diferenças já apontadas anteriormente:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; idade&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; idade&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; trocar_sobrenome&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; sobrenome&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.sobrenome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sobrenome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fazer_aniversario&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.idade&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Para se chamar essas funções, basta acessá-las através do contexto da classe, passando o objeto criado anteriormente como primeiro argumento:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Pessoa&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;João&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;dos Santos&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;trocar_sobrenome&lt;&#x2F;span&gt;&lt;span&gt;(p1,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;dos Santos&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(Pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nome_completo&lt;&#x2F;span&gt;&lt;span&gt;(p1))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Pessoa.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;fazer_aniversario&lt;&#x2F;span&gt;&lt;span&gt;(p1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p1.idade)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essa sintaxe é bastante semelhante a versão sem orientação a objetos implementada anteriormente. Porém quando se está utilizando objetos, é possível chamar essas funções com uma outra sintaxe, informando primeiro o objeto, seguido de ponto e o nome da função desejada, com a diferença de que não é mais necessário informar o objeto como primeiro argumento. Como a função foi chamada através de um objeto, o próprio Python se encarrega de passá-lo para o argumento &lt;code&gt;self&lt;&#x2F;code&gt;, sendo necessário informar apenas os demais argumentos:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;trocar_sobrenome&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;dos Santos&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p1.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nome_completo&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;p1.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;fazer_aniversario&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(p1.idade)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Existem algumas diferenças entre as duas sintaxes, porém isso será tratado posteriormente. Por enquanto a segunda sintaxe pode ser vista como um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;A%C3%A7%C3%BAcar_sint%C3%A1tico&quot;&gt;açúcar sintático&lt;&#x2F;a&gt; da primeira, ou seja, uma forma mais rápida e fácil de fazer a mesma coisa que a primeira, e por isso sendo a recomendada.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Como visto nos exemplos, programação orientada a objetos é uma técnica para juntar variáveis em uma mesma estrutura e facilitar a escrita de funções que seguem um determinado padrão, recebendo a estrutura como argumento, porém a sintaxe mais utilizada no Python para chamar as funções de um objeto (métodos) posiciona a variável que guarda a estrutura antes do nome da função, em vez do primeiro argumento.&lt;&#x2F;p&gt;
&lt;p&gt;No Python, o argumento da estrutura ou objeto (&lt;code&gt;self&lt;&#x2F;code&gt;) aparece explicitamente como primeiro argumento da função, enquanto em outras linguagens essa variável pode receber outro nome (como &lt;code&gt;this&lt;&#x2F;code&gt;) e não aparece explicitamente nos argumentos da função, embora essa variável tenha que ser criada dentro do contexto da função para permitir manipular o objeto.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Funções in place ou cópia de valor</title>
        <published>2021-03-27T00:00:00+00:00</published>
        <updated>2021-03-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/funcao-inplace-ou-copia-de-valor/"/>
        <id>https://eduardoklosowski.github.io/blog/funcao-inplace-ou-copia-de-valor/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/funcao-inplace-ou-copia-de-valor/">&lt;p&gt;Eventualmente observo dificuldades de algumas pessoas em usar corretamente alguma função, seja porque a função deveria ser executada isoladamente, e utilizado a própria variável que foi passada como argumento posteriormente, seja porque deveria se atribuir o retorno da função a alguma variável, e utilizar essa nova variável. No Python, essa diferença pode ser observada nos métodos das listas &lt;code&gt;sort&lt;&#x2F;code&gt; e &lt;code&gt;reverse&lt;&#x2F;code&gt; para as funções &lt;code&gt;sorted&lt;&#x2F;code&gt; e &lt;code&gt;reversed&lt;&#x2F;code&gt;, que são implementadas com padrões diferentes, &lt;em&gt;in place&lt;&#x2F;em&gt; e cópia de valor respectivamente. Assim pretendo discutir esses dois padrões de funções, comentando qual a diferença e o melhor caso de aplicação de cada padrão.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;funcao-de-exemplo&quot;&gt;Função de exemplo&lt;&#x2F;h2&gt;
&lt;p&gt;Para demonstrar como esses padrões funcionam, será implementado uma função que recebe uma lista e calcula o dobro dos valores dessa lista. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;entrada&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Execução da função&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;resultado&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;funcao-com-in-place&quot;&gt;Função com in place&lt;&#x2F;h3&gt;
&lt;p&gt;A ideia do padrão &lt;em&gt;in place&lt;&#x2F;em&gt; é alterar a própria variável recebida pela função (ou o próprio objeto, caso esteja lidando com orientação a objetos). Neste caso, bastaria calcular o dobro do valor de cada posição da lista, e sobrescrever a posição com seu resultado. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; typing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; dobro_inplace&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;lista&lt;&#x2F;span&gt;&lt;span&gt;: List[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;(lista)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        lista[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; lista[i]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;retorno&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; dobro_inplace&lt;&#x2F;span&gt;&lt;span&gt;(valores)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Variável: valores | Tipo: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(valores)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; | Valor: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Variável: retorno | Tipo: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(retorno)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; | Valor: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;retorno&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Resultado da execução:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Variável: valores | Tipo: &amp;lt;class &amp;#39;list&amp;#39;&amp;gt; | Valor: [10, 4, 16, 12, 8]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Variável: retorno | Tipo: &amp;lt;class &amp;#39;NoneType&amp;#39;&amp;gt; | Valor: None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Com essa execução é possível observar que os valores da lista foram alterados, e que o retorno da função é nulo (&lt;code&gt;None&lt;&#x2F;code&gt;), ou seja, a função alterou a própria lista passada como argumento. Outro ponto importante a ser observado é a assinatura da função (tipo dos argumentos e do retorno da função), que recebe uma lista de inteiros e não tem retorno ou é nulo (&lt;code&gt;None&lt;&#x2F;code&gt;). Dessa forma embora seja possível chamar essa função diretamente quando está se informando os argumentos de outra função, como &lt;code&gt;print(dobro_inplace(valores))&lt;&#x2F;code&gt;, a função &lt;code&gt;print&lt;&#x2F;code&gt; receberia &lt;code&gt;None&lt;&#x2F;code&gt; e não a lista como argumento.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;funcao-com-copia-de-valor&quot;&gt;Função com cópia de valor&lt;&#x2F;h3&gt;
&lt;p&gt;A ideia do padrão cópia de valor é criar uma cópia do valor passado como argumento e retornar essa cópia, sem alterar a variável recebida (ou criando um novo objeto, no caso de orientação a objetos). Neste caso, é necessário criar uma nova lista e adicionar nela os valores calculados. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; typing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; dobro_copia&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;lista&lt;&#x2F;span&gt;&lt;span&gt;: List[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]) -&amp;gt; List[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    nova_lista&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;(lista)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        nova_lista.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; lista[i])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; nova_lista&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;retorno&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; dobro_copia&lt;&#x2F;span&gt;&lt;span&gt;(valores)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Variável: valores | Tipo: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(valores)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; | Valor: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Variável: retorno | Tipo: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(retorno)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; | Valor: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;retorno&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Resultado da execução:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Variável: valores | Tipo: &amp;lt;class &amp;#39;list&amp;#39;&amp;gt; | Valor: [5, 2, 8, 6, 4]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Variável: retorno | Tipo: &amp;lt;class &amp;#39;list&amp;#39;&amp;gt; | Valor: [10, 4, 16, 12, 8]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Com essa execução é possível observar que a variável &lt;code&gt;valores&lt;&#x2F;code&gt; continua com os valores que tinha antes da execução da função, e a variável retorno apresenta uma lista com os dobros, ou seja, a função não altera a lista passada como argumento e retorna uma nova lista com os valores calculados. Observado a assinatura da função, ela recebe uma lista de inteiros e retorna uma lista de inteiros. Isso permite chamar essa função diretamente nos argumentos para outra função, como &lt;code&gt;print(dobro_copia(valores))&lt;&#x2F;code&gt;, nesse caso a função &lt;code&gt;print&lt;&#x2F;code&gt; receberia a lista de dobros como argumento. Porém caso o retorno da função não seja armazenado, parecerá que a função não fez nada, ou não funcionou. Então em alguns casos, quando o valor anterior não é mais necessário, pode-se reatribuir o retorno da função a própria variável passada como argumento:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; dobro_copia&lt;&#x2F;span&gt;&lt;span&gt;(valores)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;funcao-hibrida&quot;&gt;Função híbrida&lt;&#x2F;h3&gt;
&lt;p&gt;Ainda é possível mesclar os dois padrões de função, alterando o valor passado e retornando-o. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; typing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; List&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; dobro_hibrido&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;lista&lt;&#x2F;span&gt;&lt;span&gt;: List[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]) -&amp;gt; List[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;(lista)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        lista[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; lista[i]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; lista&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;retorno&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; dobro_hibrido&lt;&#x2F;span&gt;&lt;span&gt;(valores)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Variável: valores | Tipo: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(valores)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; | Valor: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Variável: retorno | Tipo: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(retorno)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; | Valor: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;retorno&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Resultado da execução:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Variável: valores | Tipo: &amp;lt;class &amp;#39;list&amp;#39;&amp;gt; | Valor: [10, 4, 16, 12, 8]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Variável: retorno | Tipo: &amp;lt;class &amp;#39;list&amp;#39;&amp;gt; | Valor: [10, 4, 16, 12, 8]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse caso, pode-se apenas chamar a função, como também utilizá-la nos argumentos de outras funções. Porém para se ter os valores originais, deve-se fazer uma cópia manualmente antes de executar a função.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;exemplo-na-biblioteca-padrao&quot;&gt;Exemplo na biblioteca padrão&lt;&#x2F;h2&gt;
&lt;p&gt;Na biblioteca padrão do Python, existem os métodos &lt;code&gt;sort&lt;&#x2F;code&gt; e &lt;code&gt;reverse&lt;&#x2F;code&gt; que seguem o padrão &lt;em&gt;in place&lt;&#x2F;em&gt;, e as funções &lt;code&gt;sorted&lt;&#x2F;code&gt; e &lt;code&gt;reversed&lt;&#x2F;code&gt; que seguem o padrão cópia de valor, podendo ser utilizados para ordenar e inverter os valores de uma lista, por exemplo. Quando não é mais necessário uma cópia da lista com a ordem original, é preferível utilizar funções &lt;em&gt;in place&lt;&#x2F;em&gt;, que alteram a própria lista, e como não criam uma cópia da lista, utilizam menos memória. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sort&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;reverse&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(valores)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Se for necessário manter uma cópia da lista inalterada, deve-se optar pelas funções de cópia de valor. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;novos_valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = reversed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;sorted&lt;&#x2F;span&gt;&lt;span&gt;(valores))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(novos_valores)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Porém esse exemplo cria duas cópias da lista, uma em cada função. Para criar apenas uma cópia, pode-se misturar funções &lt;em&gt;in place&lt;&#x2F;em&gt; com cópia de valor. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;novos_valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = sorted&lt;&#x2F;span&gt;&lt;span&gt;(valores)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;novos_valores.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;reverse&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(novos_valores)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Também vale observar que algumas utilizações dessas funções podem dar a impressão de que elas não funcionaram, como:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;sorted&lt;&#x2F;span&gt;&lt;span&gt;(valores)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(valores)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Imprime a lista original, e não a ordenada&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(valores.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sort&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Imprime None e não a lista&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Nem sempre é possível utilizar o padrão desejado, &lt;em&gt;strings&lt;&#x2F;em&gt; no Python (&lt;code&gt;str&lt;&#x2F;code&gt;) são imutáveis, logo todas as funções que manipulam elas seguiram o padrão cópia de valor, e para outros tipos, pode ocorrer de só existir funções &lt;em&gt;in place&lt;&#x2F;em&gt;, sendo necessário fazer uma cópia manualmente antes de chamar a função, caso necessário. Para saber qual padrão a função implementa, é necessário consultar sua documentação, ou verificando sua assinatura, embora ainda possa existir uma dúvida entre cópia de valor e híbrida, visto que a assinatura dos dois padrões são iguais.&lt;&#x2F;p&gt;
&lt;p&gt;Os exemplos aqui dados são didáticos. Caso deseja-se ordenar de forma reversa, tanto o método &lt;code&gt;sort&lt;&#x2F;code&gt;, quanto a função &lt;code&gt;sorted&lt;&#x2F;code&gt; podem receber como argumento &lt;code&gt;reverse=True&lt;&#x2F;code&gt;, e assim já fazer a ordenação reversa. Assim como é possível criar uma nova lista já com os valores, sem precisar adicionar manualmente item por item, como os exemplos:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;partes_dos_valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; valores[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;:]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;novos_valores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; valores]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Configuração básica do Git e GitHub</title>
        <published>2021-03-22T00:00:00+00:00</published>
        <updated>2021-03-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/configuracao-basica-do-git-e-github/"/>
        <id>https://eduardoklosowski.github.io/blog/configuracao-basica-do-git-e-github/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/configuracao-basica-do-git-e-github/">&lt;p&gt;O &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;&quot;&gt;GitHub&lt;&#x2F;a&gt; é um serviço bastante popular para hospedar repositórios &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;git-scm.com&#x2F;&quot;&gt;Git&lt;&#x2F;a&gt;. Porém para conseguir utilizá-lo, e de forma segura, existem diversas configurações que podem ser feitas. Nesse texto pretendo mostrar como fazer algumas configurações como &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;#2fa&quot;&gt;autenticação de dois fatores (2FA)&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;#chave-ssh&quot;&gt;chave SSH&lt;&#x2F;a&gt;, utilizar &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;#chave-ssh-multiplas&quot;&gt;diferentes chaves SSH&lt;&#x2F;a&gt; para diferentes contas no mesmo computador, e assinar &lt;em&gt;commits&lt;&#x2F;em&gt; e &lt;em&gt;tags&lt;&#x2F;em&gt; com &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;#chave-pgp&quot;&gt;PGP&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conta-no-github&quot;&gt;Conta no GitHub&lt;&#x2F;h2&gt;
&lt;p&gt;Para poder utilizar o GitHub, o primeiro passo é ter uma conta. Uma conta pode ser criada preenchendo o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;join&quot;&gt;formulário de cadastro&lt;&#x2F;a&gt;, que é bastante simples, requisitando um nome de usuário, e-mail e senha.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;nova-conta-1.png&quot; alt=&quot;Formulário de cadastro&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Assim que enviado o formulário, será necessário confirmar o endereço de e-mail, que é feito abrindo o link enviado para o e-mail informado no cadastro.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;nova-conta-2.png&quot; alt=&quot;E-mail de confirmação&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2fa&quot;&gt;Autenticação de dois fatores&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Two-factor_authentication&quot;&gt;autenticação de dois fatores (2FA)&lt;&#x2F;a&gt; não é obrigatória, mas bastante recomendada por questões de segurança. Ela consiste em usar, além de usuário e senha, uma senha de uso único válida apenas por um curto período de tempo. Em &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.github.com&#x2F;pt&#x2F;github&#x2F;authenticating-to-github&#x2F;countries-where-sms-authentication-is-supported#supported-countries-for-sms-authentication&quot;&gt;alguns países&lt;&#x2F;a&gt; é possível receber essas senhas via SMS. Quando essa opção não está disponível, ou como alternativa a ela, pode-se utilizar algum programa que gera senhas &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Time-based_One-Time_Password&quot;&gt;TOTP (Time-based One-Time Password)&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Uma opção para utilizar no computador é o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;keepassxc.org&#x2F;&quot;&gt;KeePassXC&lt;&#x2F;a&gt;, que possui uma versão para celular chamada &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.keepassdx.com&#x2F;&quot;&gt;KeePassDX&lt;&#x2F;a&gt;. Para utilizá-lo, basta instalar o programa, criar um banco de dados (arquivo criptografado), e adicionar uma entrada para o GitHub, que pode ser usada para guardar a senha também se desejar, embora se alguém tiver acesso ao arquivo e conseguir descriptografá-lo, conseguirá ter acesso a conta, visto que teria os dois fatores necessários para autenticar.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;2fa-1.png&quot; alt=&quot;Criando entrada para o GitHub&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Com o programa para gerar as senhas TOTP pronto, basta habilitar a autenticação de dois fatores na conta. Isso pode ser feito acessando a opção correspondente nas &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;settings&#x2F;two_factor_authentication&#x2F;intro&quot;&gt;configurações&lt;&#x2F;a&gt;, que apresentará as opções, que neste caso será via &lt;em&gt;app&lt;&#x2F;em&gt; (&lt;em&gt;&quot;Set up using an app&quot;&lt;&#x2F;em&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;2fa-2.png&quot; alt=&quot;Opções para autenticação em duas etapas&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Primeiro serão exibidas chaves de recuperação, que funcionam como qualquer outra senha TOTP, e podem ser usadas uma única vez cada, útil quando não foi possível gerar uma senha TOTP. É recomendável guardar essas senhas em lugar seguro, e utilizá-las para recuperar o acesso a conta se houver algum problema com o dispositivo usado para gerar as senhas TOTP. Escolha uma das opções disponíveis para guardar essas chaves.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;2fa-3.png&quot; alt=&quot;Chaves de recuperação&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Na tela seguinte será pedido para escanear o código &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;C%C3%B3digo_QR&quot;&gt;QR&lt;&#x2F;a&gt; com o dispositivo, o que pode ser feito caso esteja utilizando o celular. Se estiver utilizando o computador (ou tenha problemas com a câmera), basta clicar em &lt;em&gt;&quot;enter this text code&quot;&lt;&#x2F;em&gt; e copiá-lo.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;2fa-4.png&quot; alt=&quot;Código para ativar o TOTP&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Agora basta voltar ao KeePass, clicar com o botão direito em cima da entrada feita para o GitHub, ir na opção &quot;Senha única baseada em tempo&quot; e &quot;Configurar TOTP...&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;2fa-5.png&quot; alt=&quot;Acessando a configuração do TOTP no KeePassXC&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Na tela de configuração basta colar o código copiado do GitHub no campo &quot;Chave&quot;, as demais opções podem ser deixadas em branco.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;2fa-6.png&quot; alt=&quot;Configuração do TOTP&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Agora é necessário gerar uma senha TOTP e usá-la no GitHub para que ele saiba que o processo foi feito corretamente. Existem algumas formas para gerar uma senha TOTP: clicar com o botão direito, &quot;Senha única baseada em tempo&quot; e &quot;Copiar TOTP&quot; para copiar a senha para a área de transferência, ou &quot;Mostrar TOTP&quot; para exibir a senha na tela (útil quando se está fazendo o login em algum outro dispositivo), ou mesmo clicar no relógio ao final da lista de entradas, conforme a imagem a baixo para gerar e exibir a senha ao lado.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;2fa-7.png&quot; alt=&quot;Gerando senha TOTP&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Ao inseri-la no GitHub (o caractere de espaço não é necessário), o processo será terminado e a autenticação em duas etapas estará habilitada.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chave-ssh&quot;&gt;Chave SSH&lt;&#x2F;h2&gt;
&lt;p&gt;Uma das formas mais seguras para enviar &lt;em&gt;commits&lt;&#x2F;em&gt; para o GitHub é através de uma conexão &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Secure_Shell&quot;&gt;SSH&lt;&#x2F;a&gt;, o qual pode ser autenticada através de uma chave criptográfica. Para isso é necessário gerar uma chave localmente, e adicioná-la à conta do GitHub.&lt;&#x2F;p&gt;
&lt;p&gt;O programa que gera chaves criptográficas é distribuído junto com o cliente SSH, que em sistemas &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.debian.org&#x2F;&quot;&gt;Debian&lt;&#x2F;a&gt; e derivados (como &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ubuntu.com&#x2F;&quot;&gt;Ubuntu&lt;&#x2F;a&gt;), pode ser instalado através do pacote &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;packages.debian.org&#x2F;stable&#x2F;openssh-client&quot;&gt;&lt;code&gt;openssh-client&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; que se encontra no repositório da distribuição.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Caso você não saiba instalar pacotes, em sistemas que utilizam o APT e tiver o &lt;code&gt;sudo&lt;&#x2F;code&gt; configurado (padrão do Ubuntu), basta executar os seguintes comandos:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; apt update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; apt install openssh-client&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;blockquote&gt;
&lt;p&gt;No Windows, é possível utilizar o cliente que vem junto ao instalar o Git, bastando acessar o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;git-scm.com&#x2F;download&#x2F;win&quot;&gt;site&lt;&#x2F;a&gt;, fazer o download, instalá-lo e utilizar o terminal do Git Bash.&lt;&#x2F;p&gt;
&lt;p&gt;As chaves utilizadas por padrão pelo cliente SSH ficam em diferentes arquivos no diretório &lt;code&gt;.ssh&lt;&#x2F;code&gt; que está na &lt;em&gt;home&lt;&#x2F;em&gt; do usuário. Por padrão, os arquivos &lt;code&gt;id_&amp;lt;algoritmo&amp;gt;&lt;&#x2F;code&gt; são as chaves privadas, que não devem ser compartilhadas com ninguém (o ideal é que ela nem mesmo seja copiada para outro dispositivo), e os arquivos &lt;code&gt;id_&amp;lt;algoritmo&amp;gt;.pub&lt;&#x2F;code&gt; são as chaves públicas, sendo apenas esse arquivo que deve ser copiado para o GitHub, podendo existir diversas chaves, cada uma utilizando diferentes algoritmos. Para verificar se já existe alguma chave é possível executar o comando &lt;code&gt;ls -1 ~&#x2F;.ssh&#x2F;id_*&lt;&#x2F;code&gt; para listar os arquivos (o exemplo a baixo mostra duas chaves).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;user@pc:~$ ls -1 ~&#x2F;.ssh&#x2F;id_*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;home&#x2F;user&#x2F;.ssh&#x2F;id_ed25519&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;home&#x2F;user&#x2F;.ssh&#x2F;id_ed25519.pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;home&#x2F;user&#x2F;.ssh&#x2F;id_rsa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;home&#x2F;user&#x2F;.ssh&#x2F;id_rsa.pub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Para criar uma nova chave, basta executar o comando &lt;code&gt;ssh-keygen&lt;&#x2F;code&gt; informando o algoritmo desejado, a quantidade de bits (quando aplicável, conforme o algoritmo) e um nome para a chave, que normalmente é um endereço de e-mail. Para criar uma chave com o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;ECDSA&quot;&gt;Ed25519&lt;&#x2F;a&gt;, que é o algoritmo mais indicado atualmente, basta executar &lt;code&gt;ssh-keygen -t ed25519 -C &#x27;user@email.com&#x27;&lt;&#x2F;code&gt;, será perguntado sobre o local onde a chave deve ser salva, basta apartar &lt;code&gt;Enter&lt;&#x2F;code&gt; para aceitar o padrão (isso sobrescreverá a chave, se já existir alguma chave nesse arquivo), e informar uma senha para criptografar a chave, repetindo ela em seguida.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;user@pc:~$ ssh-keygen -t ed25519 -C &amp;#39;user@email.com&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Generating public&#x2F;private ed25519 key pair.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter file in which to save the key (&#x2F;home&#x2F;user&#x2F;.ssh&#x2F;id_ed25519):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter passphrase (empty for no passphrase):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter same passphrase again:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Your identification has been saved in &#x2F;home&#x2F;user&#x2F;.ssh&#x2F;id_ed25519.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Your public key has been saved in &#x2F;home&#x2F;user&#x2F;.ssh&#x2F;id_ed25519.pub.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;The key fingerprint is:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHA256:j5DuwjiW&#x2F;FVudh0ENVEofbWxnIGYiDdhvLdXrOY4Lxc user@email.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;The key&amp;#39;s randomart image is:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+--[ED25519 256]--+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|        oo+o*+o+.|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       ..=.+ooo *|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|        . o....= |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|       . . o   o |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|      o S . o o  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|     . + o o E   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| . +  o = o * .  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  * oo o . + o   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| . o...     =.   |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+----[SHA256]-----+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Também é possível gerar uma chave &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;RSA_(sistema_criptogr%C3%A1fico)&quot;&gt;RSA&lt;&#x2F;a&gt; caso o sistema não suporte Ed25519. Por padrão são gerados chaves com 2048 bits, mas atualmente recomenda-se criar chaves com 3072 ou mesmo 4096 bits, o que pode ser feito com o comando &lt;code&gt;ssh-keygen -t rsa -b 4096 -C &#x27;seu@email.com&#x27;&lt;&#x2F;code&gt;, respondendo as mesmas perguntas do Ed25519.&lt;&#x2F;p&gt;
&lt;p&gt;Com a chave crida, é necessário adicionar a chave pública à conta do usuário no GitHub, o que pode ser feito nas &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;settings&#x2F;keys&quot;&gt;configurações&lt;&#x2F;a&gt;, clicando em &lt;em&gt;&quot;New SSH key&quot;&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;ssh-1.png&quot; alt=&quot;Opção para adicionar chave SSH&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Nessa tela basta colar o conteúdo da chave pública no campo &lt;em&gt;&quot;Key&quot;&lt;&#x2F;em&gt;, o que pode ser conseguido executando no terminal o comando &lt;code&gt;cat ~&#x2F;.ssh&#x2F;id_ed25519.pub&lt;&#x2F;code&gt;. O campo &lt;em&gt;&quot;Title&quot;&lt;&#x2F;em&gt; é opcional, e caso não seja informado, será utilizado o mesmo nome (e-mail no caso) utilizado para gerar a chave.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;ssh-2.png&quot; alt=&quot;Formulário para adicionar chave SSH&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Para testar o acesso SSH, é possível utilizar o comando &lt;code&gt;ssh -T git@github.com&lt;&#x2F;code&gt;. Caso tudo tenha sido configurado corretamente, no terminal será exibido uma mensagem com o seu nome de usuário:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Hi &amp;lt;username&amp;gt;! You&amp;#39;ve successfully authenticated, but GitHub does not provide shell access.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;No primeiro acesso a algum servidor através de SSH, é possível que alguma mensagem como a abaixo seja exibida:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;The authenticity of host &amp;#39;github.com (140.82.113.4)&amp;#39; can&amp;#39;t be established.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Are you sure you want to continue connecting (yes&#x2F;no)?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse caso basta confirmar com &lt;code&gt;yes&lt;&#x2F;code&gt; para que o seu cliente SSH adicione esse servidor a lista de servidores conhecidos, e continue com o processo de conexão.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Caso algum problema ocorra e a conexão não tenha sido feita, é possível utilizar o modo verboso do SSH para verificar o processo e tentar identificar o problema, exemplo: &lt;code&gt;ssh -vT git@github.com&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nao-precisar-repetir-a-senha&quot;&gt;Não precisar repetir a senha&lt;&#x2F;h3&gt;
&lt;p&gt;Caso a chave SSH tenha sido criada com alguma senha, toda vez que ela for utilizada para se conectar no servidor será necessário informar essa senha. Uma forma de evitar isso é usando o &lt;code&gt;ssh-agent&lt;&#x2F;code&gt; para armazenar em memória essa senha, e enquanto o processo do &lt;code&gt;ssh-agent&lt;&#x2F;code&gt; estiver rodando, o cliente SSH utilizará essa chave sem pedir a senha novamente.&lt;&#x2F;p&gt;
&lt;p&gt;Para adicionar uma chave ao &lt;code&gt;ssh-agent&lt;&#x2F;code&gt; basta executar o comando &lt;code&gt;ssh-add &amp;lt;caminho-da-chave&amp;gt;&lt;&#x2F;code&gt; informando o arquivo que contem a chave privada, caso a chave esteja no caminho padrão, basta executar &lt;code&gt;ssh-add&lt;&#x2F;code&gt; para carregar todas as chaves padrões.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Caso o comando &lt;code&gt;ssh-add&lt;&#x2F;code&gt; apresente alguma mensagem de que não foi possível conectar ao &lt;code&gt;ssh-agent&lt;&#x2F;code&gt;, o mesmo pode ser iniciado com o comando &lt;code&gt;eval &quot;$(ssh-agent -s)&quot;&lt;&#x2F;code&gt;. Porém recomendo verificar como ativar esse serviço por padrão, de forma que todos os terminais consigam utilizar o mesmo agente, essa configuração varia de ambiente para ambiente.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Outra forma de adicionar a chave ao &lt;code&gt;ssh-agent&lt;&#x2F;code&gt; é configurando o cliente SSH para fazer isso automaticamente, o que pode ser feito adicionando o parâmetro &lt;code&gt;AddKeysToAgent yes&lt;&#x2F;code&gt; na sua configuração que fica em &lt;code&gt;~&#x2F;.ssh&#x2F;config&lt;&#x2F;code&gt;. A baixo seguem um exemplo utilizando esse parâmetro, assim como outros parâmetros específicos para o GitHub (usuário &lt;code&gt;git&lt;&#x2F;code&gt; por padrão e autenticação apenas pela chave Ed25519).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;ssh-config&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;Host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; github.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  User&lt;&#x2F;span&gt;&lt;span&gt; git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  IdentitiesOnly&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  IdentityFile&lt;&#x2F;span&gt;&lt;span&gt; ~&#x2F;.ssh&#x2F;id_ed25519&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;Host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  AddKeysToAgent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Para mais detalhes sobre esse arquivo de configuração consulte sua &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;manpages.debian.org&#x2F;stable&#x2F;ssh_config&quot;&gt;manpage&lt;&#x2F;a&gt; (&lt;code&gt;man ssh_config&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;chave-ssh-multiplas&quot;&gt;Múltiplas chaves&lt;&#x2F;h3&gt;
&lt;p&gt;Eventualmente pode existir a necessidade de utilizar duas ou mais contas do GitHub no mesmo computador, como uma conta pessoal e outra do trabalho. Para que o acesso SSH seja possível, é necessário criar uma chave diferente para cada conta, o que se resume a executar o comando já informado, apenas informar um caminho ou nome de arquivo diferente.&lt;&#x2F;p&gt;
&lt;p&gt;Porém para o cliente SSH utilizar uma chave diferente é necessário informar essa nova chave, como &lt;code&gt;ssh -i ~&#x2F;.ssh&#x2F;id_ed25519_empresa -T git@github.com&lt;&#x2F;code&gt;. Para facilitar o acesso, é possível criar um apelido para o GitHub, e dizer que todo o acesso feito através desse apelido usará outra chave, como com a configuração a baixo do arquivo &lt;code&gt;~&#x2F;.ssh&#x2F;config&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;ssh-config&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;Host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; github.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  User&lt;&#x2F;span&gt;&lt;span&gt; git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  IdentitiesOnly&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  IdentityFile&lt;&#x2F;span&gt;&lt;span&gt; ~&#x2F;.ssh&#x2F;id_ed25519&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;Host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; empresa.github.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  HostName&lt;&#x2F;span&gt;&lt;span&gt; github.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  User&lt;&#x2F;span&gt;&lt;span&gt; git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  IdentitiesOnly&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  IdentityFile&lt;&#x2F;span&gt;&lt;span&gt; ~&#x2F;.ssh&#x2F;id_ed25519_empresa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;Host&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  AddKeysToAgent&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Assim todo acesso feito para &lt;code&gt;github.com&lt;&#x2F;code&gt; usará a chave padrão, enquanto &lt;code&gt;empresa.github.com&lt;&#x2F;code&gt; usará outra chave, se cada chave estiver cadastrada para diferentes usuários, seus nomes devem aparecer ao executar &lt;code&gt;ssh -T git@github.com&lt;&#x2F;code&gt; e &lt;code&gt;ssh -T git@empresa.github.com&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Ainda é possível configurar o Git para passar a chave como parâmetro para o cliente SSH com o comando &lt;code&gt;git config core.sshCommand &#x27;ssh -i ~&#x2F;.ssh&#x2F;id_ed25519_empresa&#x27;&lt;&#x2F;code&gt;, porém seria necessário fazer isso individualmente para cada repositório, além de dificultar o processo de clone do repositório, visto que seria necessário criar um repositório vazio, fazer essa configuração para aquele repositório, e só então fazer o clone manualmente (adicionando a URL remota e fazendo o &lt;code&gt;fetch&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chave-pgp&quot;&gt;Chave PGP&lt;&#x2F;h2&gt;
&lt;p&gt;O Git permite assinar digitalmente &lt;em&gt;commits&lt;&#x2F;em&gt; e &lt;em&gt;tags&lt;&#x2F;em&gt;, o que permitiria a qualquer pessoa verificar se realmente quem as fez foi seu autor, e que não houve nenhuma modificação por terceiros. Para isso é possível utilizar chaves &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Pretty_Good_Privacy&quot;&gt;PGP&lt;&#x2F;a&gt;, que as vezes são chamadas de chaves GPG devido ao nome do programa utilizado para isso (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.gnupg.org&#x2F;&quot;&gt;GNU Privacy Guard&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Em sistemas Debian e derivados, basta instalar o pacote &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;packages.debian.org&#x2F;stable&#x2F;gnupg&quot;&gt;&lt;code&gt;gnupg&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, enquanto no Windows ele é instalado junto com o Git, e está disponível no terminal Git Bash.&lt;&#x2F;p&gt;
&lt;p&gt;Para verificar as chaves PGP existentes, pode-se utilizar o comando &lt;code&gt;gpg --list-secret-keys --keyid-format LONG&lt;&#x2F;code&gt;, que listará todas as chaves privadas existentes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;user@pc:&#x2F;$ gpg --list-secret-keys --keyid-format LONG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;home&#x2F;user&#x2F;.gnupg&#x2F;pubring.kbx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sec   rsa4096&#x2F;F1EFDB0A94CDCE4F 2021-03-17 [SC]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      08955621A4971CD813051D4CF1EFDB0A94CDCE4F&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uid                 [ultimate] Seu Nome &amp;lt;user@email.com&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ssb   rsa4096&#x2F;40629AC8A26C0D62 2021-03-17 [E]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Onde o código de identificação da chave (&lt;code&gt;id_chave&lt;&#x2F;code&gt;) é exibido na linha &lt;code&gt;sec&lt;&#x2F;code&gt;, logo após o algoritmo utilizado pela chave, que nesse caso é &lt;code&gt;F1EFDB0A94CDCE4F&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Para se gerar uma nova chave PGP, pode-se utilizar o comando &lt;code&gt;gpg --full-generate-key&lt;&#x2F;code&gt; e responder as perguntas feitas.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;user@pc:~$ gpg --full-generate-key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gpg (GnuPG) 2.2.12; Copyright (C) 2018 Free Software Foundation, Inc.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;This is free software: you are free to change and redistribute it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;There is NO WARRANTY, to the extent permitted by law.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Please select what kind of key you want:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   (1) RSA and RSA (default)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   (2) DSA and Elgamal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   (3) DSA (sign only)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   (4) RSA (sign only)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Your selection? 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RSA keys may be between 1024 and 4096 bits long.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;What keysize do you want? (3072) 4096&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Requested keysize is 4096 bits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Please specify how long the key should be valid.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         0 = key does not expire&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;n&amp;gt;  = key expires in n days&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;n&amp;gt;w = key expires in n weeks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;n&amp;gt;m = key expires in n months&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;lt;n&amp;gt;y = key expires in n years&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Key is valid for? (0) 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Key does not expire at all&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Is this correct? (y&#x2F;N) y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;GnuPG needs to construct a user ID to identify your key.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Real name: Seu Nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Email address: user@email.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Comment:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;You selected this USER-ID:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;quot;Seu Nome &amp;lt;user@email.com&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Change (N)ame, (C)omment, (E)mail or (O)kay&#x2F;(Q)uit? o&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;We need to generate a lot of random bytes. It is a good idea to perform&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;some other action (type on the keyboard, move the mouse, utilize the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;disks) during the prime generation; this gives the random number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;generator a better chance to gain enough entropy.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;We need to generate a lot of random bytes. It is a good idea to perform&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;some other action (type on the keyboard, move the mouse, utilize the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;disks) during the prime generation; this gives the random number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;generator a better chance to gain enough entropy.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gpg: key F1EFDB0A94CDCE4F marked as ultimately trusted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gpg: revocation certificate stored as &amp;#39;&#x2F;home&#x2F;user&#x2F;.gnupg&#x2F;openpgp-revocs.d&#x2F;08955621A4971CD813051D4CF1EFDB0A94CDCE4F.rev&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;public and secret key created and signed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pub   rsa4096 2021-03-17 [SC]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      08955621A4971CD813051D4CF1EFDB0A94CDCE4F&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uid                      Seu Nome &amp;lt;user@email.com&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sub   rsa4096 2021-03-17 [E]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Para testar a chave PGP, basta criar um arquivo qualquer, e executar o comando &lt;code&gt;gpg -sbu &amp;lt;id_chave&amp;gt; &amp;lt;arquivo&amp;gt;&lt;&#x2F;code&gt;, e para verificar a assinatura executar o comando &lt;code&gt;gpg --verify &amp;lt;arquivo&amp;gt;.sig&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;user@pc:~$ gpg -sbu F1EFDB0A94CDCE4F arquivo.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;user@pc:~$ gpg --verify arquivo.txt.sig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gpg: assuming signed data in &amp;#39;arquivo.txt&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gpg: Signature made dom 21 mar 2021 21:19:07 -03&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gpg:                using RSA key 08955621A4971CD813051D4CF1EFDB0A94CDCE4F&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gpg: Good signature from &amp;quot;Seu Nome &amp;lt;user@email.com&amp;gt;&amp;quot; [ultimate]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A configuração de qual chave o Git deverá utilizar será discutido na seção seguinte. Porém para utilizar a chave para assinar um &lt;em&gt;commit&lt;&#x2F;em&gt; basta acrescentar o parâmetro &lt;code&gt;-S&lt;&#x2F;code&gt; no comando &lt;code&gt;git commit&lt;&#x2F;code&gt;, e para assinar uma &lt;em&gt;tag&lt;&#x2F;em&gt; basta acrescentar o parâmetro &lt;code&gt;-s&lt;&#x2F;code&gt; no comando &lt;code&gt;git tag&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Para adicionar a chave PGP no GitHub, basta acessar a opção nas &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;settings&#x2F;keys&quot;&gt;configurações&lt;&#x2F;a&gt;, clicando em &lt;em&gt;&quot;New GPG key&quot;&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;ssh-1.png&quot; alt=&quot;Opção para adicionar chave PGP&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Nessa tela basta colar o conteúdo da chave pública no campo &lt;em&gt;&quot;Key&quot;&lt;&#x2F;em&gt;, o que pode ser conseguido executando no terminal o comando &lt;code&gt;gpg --armor --export &amp;lt;id_chave&amp;gt;&lt;&#x2F;code&gt; (exemplo &lt;code&gt;gpg --armor --export F1EFDB0A94CDCE4F&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;configuracao-basica-do-git-e-github&#x2F;gpg-2.png&quot; alt=&quot;Formulário para adicionar chave PGP&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configuracao-do-git&quot;&gt;Configuração do Git&lt;&#x2F;h2&gt;
&lt;p&gt;Para utilizar o Git em sistemas Debian e derivados, é necessário instalar o pacote &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;packages.debian.org&#x2F;stable&#x2F;git&quot;&gt;&lt;code&gt;git&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. No Windows, a instalação pode ser feita como já apresentado anteriormente.&lt;&#x2F;p&gt;
&lt;p&gt;Em relação a configuração do Git, ela pode ser feita com &lt;code&gt;git config&lt;&#x2F;code&gt; e aplicada em 3 níveis: Sistema, que é aplicável a qualquer repositório de qualquer usuário. Global, que é aplicável a qualquer repositório de um usuário específico. E local, que se aplica apenas ao repositório onde a configuração foi feita. A configuração do sistema fica em &lt;code&gt;&#x2F;etc&#x2F;gitconfig&lt;&#x2F;code&gt; e pode ser acessada com o parâmetro &lt;code&gt;--system&lt;&#x2F;code&gt;, mas normalmente não é utilizada. A configuração global fica em &lt;code&gt;~&#x2F;.gitconfig&lt;&#x2F;code&gt; ou &lt;code&gt;~&#x2F;.config&#x2F;git&#x2F;config&lt;&#x2F;code&gt; e pode ser acessada com o parâmetro &lt;code&gt;--global&lt;&#x2F;code&gt;. E a configuração local fica em &lt;code&gt;.git&#x2F;config&lt;&#x2F;code&gt; dentro de cada repositório, podendo ser acessada com o parâmetro &lt;code&gt;--local&lt;&#x2F;code&gt; ou não informando outro nível (nível padrão).&lt;&#x2F;p&gt;
&lt;p&gt;Duas configurações obrigatórias para usar o Git são &lt;code&gt;user.name&lt;&#x2F;code&gt;, que é o nome do usuário, e &lt;code&gt;user.email&lt;&#x2F;code&gt;, que é o endereço de e-mail, ambos utilizados como autor ao se fazer um &lt;em&gt;commit&lt;&#x2F;em&gt;. Para evitar o trabalho de reconfigurá-los toda hora, essa configuração normalmente é feita em nível global, como no exemplo a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --global&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; user.name &amp;quot;Seu Nome&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --global&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; user.email &amp;quot;user@email.com&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Porém caso deseja-se utilizar um nome ou e-mail diferente em determinado repositório, esses comandos podem ser usados dentro do repositório sem o parâmetro &lt;code&gt;--global&lt;&#x2F;code&gt;, como no caso de usar o e-mail da empresa em vez do e-mail pessoal.&lt;&#x2F;p&gt;
&lt;p&gt;Ainda existem outros parâmetros, como &lt;code&gt;user.signingkey&lt;&#x2F;code&gt; que informa qual chave PGP deve ser utilizada, &lt;code&gt;core.editor&lt;&#x2F;code&gt; que informa o editor a ser utilizado para editar mensagens de &lt;em&gt;commit&lt;&#x2F;em&gt;, por exemplo (substituindo o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.vim.org&#x2F;&quot;&gt;vim&lt;&#x2F;a&gt; caso queira utilizar outro editor). Mais informações podem ser vistas na sua &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;manpages.debian.org&#x2F;stable&#x2F;git-config&quot;&gt;manpage&lt;&#x2F;a&gt; (&lt;code&gt;man git-config&lt;&#x2F;code&gt;), assim como uma descrição do formato do arquivo de configuração, que pode ser editador, ou simplesmente visualizado para verificar as configurações aplicadas, como o exemplo a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;[user]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; Seu Nome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    email&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; user@email.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    signingkey&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; F1EFDB0A94CDCE4F&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;[core]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    editor&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; vim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;branch-padrao&quot;&gt;Branch padrão&lt;&#x2F;h3&gt;
&lt;p&gt;Seguindo a nomenclatura do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.bitkeeper.org&#x2F;&quot;&gt;Bitkeeper&lt;&#x2F;a&gt;, a &lt;em&gt;branch&lt;&#x2F;em&gt; padrão do Git é a &lt;code&gt;master&lt;&#x2F;code&gt;, porém aos poucos está sendo alterado para &lt;code&gt;main&lt;&#x2F;code&gt;. No GitHub essa mudança já &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;github&#x2F;renaming&quot;&gt;foi feita&lt;&#x2F;a&gt; e qualquer novo repositório criado pela interface com um arquivo de licença ou &lt;em&gt;readme&lt;&#x2F;em&gt; terá a branch &lt;code&gt;main&lt;&#x2F;code&gt;, embora esse nome possa ser alterado nas &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;settings&#x2F;repositories&quot;&gt;configurações&lt;&#x2F;a&gt;. O &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;&quot;&gt;GitLab&lt;&#x2F;a&gt; também segue pelo &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;about.gitlab.com&#x2F;blog&#x2F;2021&#x2F;03&#x2F;10&#x2F;new-git-default-branch-name&#x2F;&quot;&gt;mesmo caminho&lt;&#x2F;a&gt;. Porém no Git essa mudança ainda não se tornou o padrão, mas a partir da versão 2.28.0, foi acrescentado um parâmetro para definir o nome padrão da &lt;em&gt;branch&lt;&#x2F;em&gt; ao se criar um repositório (&lt;code&gt;init.defaultBranch&lt;&#x2F;code&gt;). Então caso deseja que ao executar um &lt;code&gt;git init&lt;&#x2F;code&gt; seja criado a branch &lt;code&gt;main&lt;&#x2F;code&gt; em vez da &lt;code&gt;master&lt;&#x2F;code&gt;, basta alterar as configurações com &lt;code&gt;git config --global init.defaultBranch main&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linha-de-comando&quot;&gt;Linha de comando&lt;&#x2F;h3&gt;
&lt;p&gt;Uma configuração bastante útil do Git é mostrar a &lt;em&gt;branch&lt;&#x2F;em&gt; atual o estado do repositório na linha de comando. No Git Bash isso já vem ativo por padrão, porém em outros ambientes é necessário ativar. O &lt;em&gt;script&lt;&#x2F;em&gt; responsável por isso é o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git&#x2F;git&#x2F;blob&#x2F;master&#x2F;contrib&#x2F;completion&#x2F;git-prompt.sh&quot;&gt;&lt;code&gt;git-prompt&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, e no Debian e derivados já é instalado junto com o Git, porém dependendo do pacote &lt;code&gt;bash-completion&lt;&#x2F;code&gt; para ser carregado e que seja habilitado na variável de ambiente &lt;code&gt;PS1&lt;&#x2F;code&gt;. A baixo segue um exemplo de configuração que pode ser adicionado ao arquivo &lt;code&gt;~&#x2F;.bashrc&lt;&#x2F;code&gt; para habilitá-lo, junto com alguns de seus parâmetros de configuração:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;PS1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;${&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;PS1&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\\\$&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;__git_ps1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\\\$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;}&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;GIT_PS1_SHOWDIRTYSTATE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;GIT_PS1_SHOWSTASHSTATE&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;GIT_PS1_SHOWUNTRACKEDFILES&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;GIT_PS1_SHOWUPSTREAM&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;auto&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;GIT_PS1_SHOWCOLORHINTS&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Embora esse texto se focou no GitHub, ele também pode ser aplicado para outros sistemas, como o GitLab. Algumas partes, como a configuração do SSH pode ser reaproveitada para acesso a servidores, e o KeePass para a autenticação em duas etapas de outros sites.&lt;&#x2F;p&gt;
&lt;p&gt;Por questões de segurança, todas as chaves geradas durante a criação desse texto foram apagadas, assim como a conta criada no GitHub.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Complexidade do algoritmo em relação à memória</title>
        <published>2021-03-14T00:00:00+00:00</published>
        <updated>2021-03-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/complexidade-de-memoria/"/>
        <id>https://eduardoklosowski.github.io/blog/complexidade-de-memoria/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/complexidade-de-memoria/">&lt;p&gt;Recentemente o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;profbrunolopes&quot;&gt;ProfBrunoLopes&lt;&#x2F;a&gt; fez uma live com a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;morgiovanelli&quot;&gt;morgiovanelli&lt;&#x2F;a&gt; falando sobre a complexidade dos algoritmos, onde era discutido, de forma matemática, como identificar qual algoritmo era mais eficiente dado o crescimento de seu tempo de execução em relação ao tamanho da entrada. Nesse texto, quero expandir essa análise para outros aspectos, como o uso de memória.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;complexidade-da-funcao-fibonacci&quot;&gt;Complexidade da função &lt;code&gt;fibonacci&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Como uma breve revisão, será feita a análise da complexidade do tempo de execução de algoritmos para o cálculo de valores da &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Sequ%C3%AAncia_de_Fibonacci&quot;&gt;sequência de Fibonacci&lt;&#x2F;a&gt;, que é uma sequência onde os dois primeiros valores são 1, e os demais é a soma dos dois valores anteriores. Um exemplo de algoritmo que faz esse cálculo usando recursividade é:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FibonacciRecursivo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public static int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fibonacci&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; n&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; n;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fibonacci&lt;&#x2F;span&gt;&lt;span&gt;(n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fibonacci&lt;&#x2F;span&gt;&lt;span&gt;(n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Todas as instruções dessa função, menos as chamadas recursivas, tem complexidade constante (&lt;code&gt;O(1)&lt;&#x2F;code&gt;), ou seja, o tempo de execução dessas instruções não variam conforme a posição a ser calculada (tamanho da entrada). Em relação a complexidade das chamadas recursivas, é possível verificar que cada chamada, executa novamente a função outras duas vezes (menos quando atinge o caso base), reduzindo o tamanho do problema a ser resolvido em uma e duas unidades, gerando algo parecido com o diagrama a baixo:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;complexidade-de-memoria&#x2F;chamadas-fibonacci-recursivo.png&quot; alt=&quot;Chamadas recursivas da função fibonacci&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Dessa forma é possível dizer que a complexidade desse algoritmo é exponencial (&lt;code&gt;O(2^n)&lt;&#x2F;code&gt;), visto que a chamada recursiva não altera a grandeza do tamanho do problema a ser resolvido a cada chamada. E devido a sua complexidade exponencial, esse algoritmo é considerado ineficiente para grandes valores.&lt;&#x2F;p&gt;
&lt;p&gt;Porém uma vez que um valor da sequência de Fibonacci foi calculado, ele pode ser guardado em memória e reutilizado, em vez de precisar calculá-lo toda vez. E é necessário saber apenas os últimos dois valores da sequência para se calcular o próximo. Assim pode-se implementar um algoritmo iterativo (que itera, utiliza um laço de repetição), como:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FibonacciIterativo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public static int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fibonacci&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; n&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; n; ++i) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; aux&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            b &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; aux;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse algoritmo, assim como o anterior, todas as instruções possuem complexidade constante, com exceção do laço de repetição, que faz o seu bloco interno ser executado &lt;code&gt;n - 1&lt;&#x2F;code&gt; vezes. Dessa forma esse algoritmo possui complexidade linear (&lt;code&gt;O(n)&lt;&#x2F;code&gt;, visto que seriam &lt;code&gt;n - 1&lt;&#x2F;code&gt; vezes um bloco de complexidade &lt;code&gt;O(1)&lt;&#x2F;code&gt;), sendo bem mais eficiente que a opção anterior.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;complexidade-da-funcao-fatorial&quot;&gt;Complexidade da função &lt;code&gt;fatorial&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Outro problema que pode ser analisado é o cálculo do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Fatorial&quot;&gt;fatorial&lt;&#x2F;a&gt; de um número. O fatorial de um número é a multiplicação dele por todos os seus antecessores até o 1, ou simplesmente a multiplicação de um número pelo fatorial do seu antecessor, sendo que o fatorial de 1 é 1. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4! = 4 * 3!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4! = 4 * 3 * 2!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4! = 4 * 3 * 2 * 1!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4! = 4 * 3 * 2 * 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Novamente é possível implementar um algoritmo que resolva esse problema usando recursividade:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FatorialRecursivo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public static int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fatorial&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; n&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fatorial&lt;&#x2F;span&gt;&lt;span&gt;(n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Onde as chamadas recursivas geram algo parecido com o diagrama a baixo:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;complexidade-de-memoria&#x2F;chamadas-fatorial-recursivo.png&quot; alt=&quot;Chamadas recursivas da função fatorial&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Vale observar que novamente todas as instruções possuem complexidade constante, menos as chamadas recursivas, que por sua vez, chama a função mais uma vez, com um problema de tamanho com uma unidade a menos, o que repete a função o mesmo número de vezes do fatorial a ser calculado, portando possui complexidade linear.&lt;&#x2F;p&gt;
&lt;p&gt;Também é possível fazer um algoritmo iterativo para resolver esse problema, como:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FatorialIterativo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public static int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fatorial&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; n&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; fatorial&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; n; ++i) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            fatorial &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;*=&lt;&#x2F;span&gt;&lt;span&gt; i;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; fatorial;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse código é possível identificar o laço de repetição executando &lt;code&gt;n - 1&lt;&#x2F;code&gt; vezes seu bloco de código de complexidade constante, fazendo com que esse algoritmo tenha complexidade linear em seu tempo de execução.&lt;&#x2F;p&gt;
&lt;p&gt;Embora que para esse problema, tanto o algoritmo recursivo, quanto o algoritmo iterativo apresentem a mesma complexidade no tempo de execução, os dois algoritmos possuem diferenças em relação ao uso de memória. Enquanto o algoritmo iterativo utiliza apenas três variáveis (uma do argumento da função e duas no código), a versão recursiva usa uma só (argumento da função), porém isso se repete para cada chamada da função, e como isso fica em memória até que a última função seja chamada, essa variável chega a existir &lt;code&gt;n&lt;&#x2F;code&gt; vezes na memória ao mesmo tempo, uma em cada contexto da função, como no exemplo de execução do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onlinegdb.com&#x2F;&quot;&gt;GDB online Debugger&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;complexidade-de-memoria&#x2F;stack-fatorial-recursivo.png&quot; alt=&quot;Stack de execução do fatorial recursivo&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Dessa forma é possível dizer que existe uma diferença na complexidade desses código em relação ao uso de memória, com o algoritmo recursivo usando memória de forma linear ao tamanho da entrada, e a versão iterativa usando memória de forma constante. E essa análise tem o mesmo resultado se feita nos algoritmos para o cálculo da sequência de Fibonacci.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;complexidade-para-se-percorrer-uma-arvore&quot;&gt;Complexidade para se percorrer uma árvore&lt;&#x2F;h2&gt;
&lt;p&gt;É possível armazenar dados em uma estrutura que recebe o nome de &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;%C3%81rvore_bin%C3%A1ria&quot;&gt;árvore binária&lt;&#x2F;a&gt;, que consiste em organizar todos os valores menores que um determinado valor a esquerda, e todo os valores maiores a direita, formando algo que lembra uma árvore com ramificações. Exemplo:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;complexidade-de-memoria&#x2F;arvore-binaria.png&quot; alt=&quot;Árvore binária&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;É possível utilizar recursividade para percorrer em ordem crescente essa árvore e imprimir na tela seus valores. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; esquerda&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; direita&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; esquerda&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; direita&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;esquerda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; esquerda;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; valor;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;direita&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; direita;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreRecursiva&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; raiz&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreRecursiva&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        raiz &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;                2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;            4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;                6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    private void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; printAux&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (valor &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        printAux&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;esquerda&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        System&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;println&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        printAux&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;direita&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; print&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        printAux&lt;&#x2F;span&gt;&lt;span&gt;(raiz);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse caso foram criadas duas funções, a &lt;code&gt;printAux&lt;&#x2F;code&gt; que percorre a árvore de forma recursiva, e a &lt;code&gt;print&lt;&#x2F;code&gt; que expõe essa função, para ser chamada externamente de forma mais simples. Em relação ao tempo de execução, esse algoritmo possui complexidade linear, uma vez que percorre todos os valores da árvore, e em relação ao uso de memória, como só é necessário manter as variáveis de um ramo da árvore por vez em memória, ele cresce de forma logarítmica em relação a quantidade de valores da árvore (&lt;code&gt;O(log2 n)&lt;&#x2F;code&gt;), igual a altura da árvore, considerando que a mesma esteja balanceada (com ramos aproximadamente do mesmo tamanho).&lt;&#x2F;p&gt;
&lt;p&gt;É possível pensar em um algoritmo iterativo para esse problema. Porém como deve-se passar uma vez pelos valores a esquerda e outra pelos valores a direita de cada valor da árvore, para controlar o estado e saber qual lado deve-se percorrer, cria-se uma estrutura com essa informação. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; java.util.ArrayList&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; java.util.List&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; esquerda&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; direita&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; esquerda&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; direita&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;esquerda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; esquerda;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; valor;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;direita&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; direita;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreLado&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;    Esquerda&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;    Direita&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Estado&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    ArvoreLado&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lado&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Estado&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreLado&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; lado&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; valor;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;lado&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; lado;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreIterativa&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; raiz&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreIterativa&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        raiz &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;                2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;            4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;                6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ArvoreValor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;null&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; print&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        List&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Estado&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; estados&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArrayList&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Estado&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        estados&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Estado&lt;&#x2F;span&gt;&lt;span&gt;(raiz,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreLado&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Esquerda&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;estados&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;isEmpty&lt;&#x2F;span&gt;&lt;span&gt;()) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            Estado&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; estado&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; estados&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;remove&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;estados&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;size&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            ArvoreValor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; estado&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (valor &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                continue&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            switch&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;estado&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;lado&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                case&lt;&#x2F;span&gt;&lt;span&gt; Esquerda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;                    estado&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;lado&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreLado&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Direita&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;                    estados&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(estado);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;                    estados&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Estado&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;esquerda&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreLado&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Esquerda&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                case&lt;&#x2F;span&gt;&lt;span&gt; Direita&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;                    System&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;out&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;println&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;                    estados&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Estado&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;valor&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;direita&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArvoreLado&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Esquerda&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Em relação ao tempo de execução, esse algoritmo apresenta uma complexidade linear, e em relação ao uso de memória, como é necessário manter os estados de um ramo da árvore, a complexidade é logarítmica, assim como as complexidades do algoritmo utilizando recurção. Nesse caso a lista de estados criados funciona de forma análoga a pilha de execução, utilizada pelo algoritmo recursivo. Essa solução é melhor do que manter o estado de todo os valores em memória, que teria complexidade linear de uso da memória, conforme a quantidade de valores na árvore. E mesmo em relação a pilha de execução também acaba ocupando menos memória, visto que não é necessário manter o estado de todos os valores do ramo, apenas daqueles que ainda possuem alguma direção (esquerda ou direita) a serem processados. Porém essa solução, embora use um pouco menos de memória por causa disso, possui a mesma complexidade em relação ao uso de memória, sendo um código mais difícil de ler e dar manutenção para se conseguir isso.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Um algoritmo pode ser classificado de diferentes formas em relação ao seu desempenho conforme o crescimento do tamanho do problema a ser tratado, como tempo de execução e uso de memória. Embora algoritmos iterativos pareçam mais interessantes a primeira vista, quando comparados aos algoritmos recursivos, para alguns problemas os algoritmos iterativos não apresentam vantagens claras, além de serem mais complexos de implementar.&lt;&#x2F;p&gt;
&lt;p&gt;Os exemplos apresentados também consideram que todos os valores cabem dentro de um &lt;code&gt;int&lt;&#x2F;code&gt;. Quando se trabalha com valores maiores, por exemplo, utilizando vários &lt;code&gt;int&lt;&#x2F;code&gt; para representar um número, onde cada &lt;code&gt;int&lt;&#x2F;code&gt; representa uma parte do valor, operações de soma deixam de ter complexidade de tempo constante para ter complexidade linear a quantidade de &lt;code&gt;int&lt;&#x2F;code&gt; que representam o número, visto que deve-se executar uma operação de soma para cada &lt;code&gt;int&lt;&#x2F;code&gt;, o que poderia alterar a complexidade do algoritmo.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Encapsulamento da lógica do algoritmo</title>
        <published>2021-03-01T00:00:00+00:00</published>
        <updated>2021-03-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/encapsulamento-da-logica-do-algoritmo/"/>
        <id>https://eduardoklosowski.github.io/blog/encapsulamento-da-logica-do-algoritmo/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/encapsulamento-da-logica-do-algoritmo/">&lt;p&gt;Muitas listas de exercícios de lógica de programação pedem em algum momento que um valor seja lido do teclado, e caso esse valor seja inválido, deve-se avisar, e repetir a leitura até que um valor válido seja informado. Utilizando a ideia de &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;otimizando-o-algoritmo&#x2F;&quot;&gt;otimização do algoritmo passo a passo&lt;&#x2F;a&gt;, começando com uma solução simples, pretendo estudar como reduzir a duplicação de código alterando o algoritmo, encapsulando a lógica em funções, e encapsulando em classes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;exercicio&quot;&gt;Exercício&lt;&#x2F;h2&gt;
&lt;p&gt;Um exemplo de exercício que pede esse tipo de validação é a leitura de notas, que devem estar entre 0 e 10. A solução mais simples, consiste em ler um valor, e enquanto esse valor for inválido, dar o aviso e ler outro valor. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = float&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Digite a nota: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; or&lt;&#x2F;span&gt;&lt;span&gt; nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Nota inválida&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = float&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Digite a nota: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse algoritmo funciona, porém existe uma duplicação no código que faz a leitura da nota (uma antes do &lt;em&gt;loop&lt;&#x2F;em&gt; e outra dentro). Caso seja necessário uma alteração, como a mudança da nota para um valor inteiro entre 0 e 100, deve-se alterar os dois lugares, e se feito em apenas um lugar, o algoritmo poderia processar valores inválidos.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alterando-o-algoritmo&quot;&gt;Alterando o algoritmo&lt;&#x2F;h3&gt;
&lt;p&gt;Visando remover a repetição de código, é possível unificar a leitura do valor dentro do &lt;em&gt;loop&lt;&#x2F;em&gt;, uma vez que é necessário repetir essa instrução até que o valor válido seja obtido. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; True&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = float&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Digite a nota: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Nota inválida!&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Dessa forma, não existe mais a repetição de código. A condição de parada, que antes verificava se o valor era inválido (o que pode ter uma leitura não tão intuitiva), agora verifica se é um valor válido (que é geralmente é mais fácil de ler e escrever a condição). E a ordem dos comandos dentro do &lt;em&gt;loop&lt;&#x2F;em&gt;, que agora estão em uma ordem que facilita a leitura, visto que no algoritmo anterior era necessário tem em mente o que era executado antes do &lt;em&gt;loop&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Porém esses algoritmos validam apenas o valor lido, apresentando erro caso seja informado um valor com formato inválido, como letras em vez de números. Isso pode ser resolvido tratando as exceções lançadas. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; True&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = float&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Digite a nota: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    except&lt;&#x2F;span&gt;&lt;span&gt; ValueError:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Nota inválida!&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;encapsulamento-da-logica-em-funcao&quot;&gt;Encapsulamento da lógica em função&lt;&#x2F;h3&gt;
&lt;p&gt;Caso fosse necessário ler várias notas, com os algoritmos apresentados até então, seria necessário repetir todo esse trecho de código, ou utilizá-lo dentro de uma estrutura de repetição. Para facilitar sua reutilização, evitando a duplicação de código, é possível encapsular esse algoritmo dentro de uma função. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nota_input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; True&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = float&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;(prompt))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        except&lt;&#x2F;span&gt;&lt;span&gt; ValueError:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;            ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Nota inválida!&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; nota&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nota1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nota_input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Digite a primeira nota: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nota2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nota_input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Digite a segunda nota: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;encapsulamento-da-logica-em-classes&quot;&gt;Encapsulamento da lógica em classes&lt;&#x2F;h3&gt;
&lt;p&gt;Em vez de encapsular essa lógica em uma função, é possível encapsulá-la em uma classe, o que permitiria separar cada etapa do algoritmo em métodos, assim como ter um método responsável por controlar qual etapa deveria ser chamada em qual momento. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaNotaInput&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Nota inválida!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;(prompt)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; float&lt;&#x2F;span&gt;&lt;span&gt;(entrada)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; validar_nota&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; nota&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __call__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; True&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(prompt))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;validar_nota&lt;&#x2F;span&gt;&lt;span&gt;(nota):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            except&lt;&#x2F;span&gt;&lt;span&gt; ValueError:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;                ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.mensagem_valor_invalido)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; nota&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nota_input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ValidaNotaInput&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nota_input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Digite a nota: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Vale observar que o método &lt;code&gt;__call__&lt;&#x2F;code&gt; permite que o objeto criado a partir dessa classe seja chamado como se fosse uma função. Nesse caso ele é o responsável por chamar cada etapa do algoritmo, como: &lt;code&gt;ler_entrada&lt;&#x2F;code&gt; que é responsável por ler o que foi digitado no teclado, &lt;code&gt;transformar_entrada&lt;&#x2F;code&gt; que é responsável por converter o texto lido para o tipo desejado (converter de &lt;code&gt;str&lt;&#x2F;code&gt; para &lt;code&gt;float&lt;&#x2F;code&gt;), e &lt;code&gt;validar_nota&lt;&#x2F;code&gt; que é responsável por dizer se o valor é válido ou não. Vale observar que ao dividir o algoritmo em métodos diferentes, seu código principal virou uma espécie de código comentado, descrevendo o que está sendo feito e onde está sendo feito.&lt;&#x2F;p&gt;
&lt;p&gt;Outra vantagem de encapsular a lógica em classe, em vez de uma função, é a possibilidade de generalizá-la. Se fosse necessário validar outro tipo de entrada, encapsulando em uma função, seria necessário criar outra função repetindo todo o algoritmo, alterando apenas a parte referente a transformação do valor lido, e validação, o que gera uma espécie de repetição de código. Ao encapsular em classes, é possível se aproveitar dos mecanismos de herança para evitar essa repetição. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Valor inválido!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;(prompt)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span&gt; NotImplementedError&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span&gt; NotImplementedError&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; __call__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; prompt&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; True&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ler_entrada&lt;&#x2F;span&gt;&lt;span&gt;(prompt))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(valor):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                    break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            except&lt;&#x2F;span&gt;&lt;span&gt; ValueError:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;                ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.mensagem_valor_invalido)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaNomeInput&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Nome inválido!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; entrada.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;strip&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;title&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ValidaNotaInput&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ValidaInput&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mensagem_valor_invalido&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Nota inválida!&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transformar_entrada&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; entrada&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; float&lt;&#x2F;span&gt;&lt;span&gt;(entrada)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; validar_valor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt; valor&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; valor&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nome_input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ValidaNomeInput&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nota_input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ValidaNotaInput&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nome_input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Digite o nome: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nota&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; nota_input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;Digite a nota: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Dessa forma, é possível reutilizar o código já existente para criar outras validações, sendo necessário implementar apenas como converter a &lt;code&gt;str&lt;&#x2F;code&gt; lida do teclado para o tipo desejado, e como esse valor deve ser validado. Não é necessário entender e repetir a lógica de ler o valor, validá-lo, imprimir a mensagem de erro, e repetir até que seja informado um valor válido.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;É possível encapsular a lógica de um algoritmo em funções ou em classes. Embora para fazê-lo em uma classe exija conhecimentos de programação orientada a objetos, o seu reaproveitamento é facilitado, abstraindo toda a complexidade do algoritmo, que pode ser disponibilizado através de uma biblioteca, exigindo apenas a implementações de métodos simples por quem for a utilizar.&lt;&#x2F;p&gt;
&lt;p&gt;Ainda poderia ser discutido outras formas de fazer essa implementação, como passar funções como parâmetro e a utilização de &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;library&#x2F;asyncio-task.html&quot;&gt;corrotinas&lt;&#x2F;a&gt; no encapsulamento do algoritmo em função, assim como a utilização de &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;library&#x2F;functions.html#classmethod&quot;&gt;classmethod&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;library&#x2F;functions.html#staticmethod&quot;&gt;staticmethod&lt;&#x2F;a&gt; e &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;pt-br&#x2F;3&#x2F;library&#x2F;abc.html&quot;&gt;ABC&lt;&#x2F;a&gt; no encapsulamento do algoritmo em classes.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Formatação para o URI</title>
        <published>2021-02-07T00:00:00+00:00</published>
        <updated>2021-02-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/formatacao-uri/"/>
        <id>https://eduardoklosowski.github.io/blog/formatacao-uri/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/formatacao-uri/">&lt;p&gt;A &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;levxyca&quot;&gt;levxyca&lt;&#x2F;a&gt; estava resolvendo exercícios do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.urionlinejudge.com.br&#x2F;&quot;&gt;URI&lt;&#x2F;a&gt; em live, e teve alguma dificuldade, não com o exercício, mas com a leitura da entrada e a formatação da saída. Então resolvi descrever um pouco esse processo, que pode ajudar tanto quem for resolver os desafios do URI, como também quem deseja entender mais sobre o funcionamento dos processos em si.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fluxos-padroes-do-processo&quot;&gt;Fluxos padrões do processo&lt;&#x2F;h2&gt;
&lt;p&gt;O primeiro passo é entender como funcionam as entradas e saídas dos processos. Em sistemas UNIX (que provavelmente é o ambiente onde o URI valida os códigos enviados) todos os processos possuem três fluxos padrões: &lt;code&gt;stdin&lt;&#x2F;code&gt; (&lt;em&gt;standart input stream&lt;&#x2F;em&gt;, fluxo de entrada padrão) que por padrão é o teclado, &lt;code&gt;stdout&lt;&#x2F;code&gt; (&lt;em&gt;standart output stream&lt;&#x2F;em&gt;, fluxo de saída padrão) que por padrão é a tela, e &lt;code&gt;stderr&lt;&#x2F;code&gt; (&lt;em&gt;standart error stream&lt;&#x2F;em&gt;, fluxo de erro padrão) que por padrão também é a tela. Exemplificado como a baixo:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;formatacao-uri&#x2F;processo.png&quot; alt=&quot;Processo com stdin, stdout e stderr&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;No Linux eles também podem ser visualizados dentro do diretório de dispositivos (&lt;code&gt;&#x2F;dev&lt;&#x2F;code&gt;) com &lt;code&gt;ls -la &#x2F;dev&#x2F;std{in,out,err}&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 15 fev  6 10:07 &#x2F;dev&#x2F;stderr -&amp;gt; &#x2F;proc&#x2F;self&#x2F;fd&#x2F;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 15 fev  6 10:07 &#x2F;dev&#x2F;stdin -&amp;gt; &#x2F;proc&#x2F;self&#x2F;fd&#x2F;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 root root 15 fev  6 10:07 &#x2F;dev&#x2F;stdout -&amp;gt; &#x2F;proc&#x2F;self&#x2F;fd&#x2F;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse comando apresenta uma informação interessante, eles são &lt;em&gt;links&lt;&#x2F;em&gt; simbólicos para &lt;code&gt;&#x2F;proc&#x2F;self&#x2F;fd&#x2F;*&lt;&#x2F;code&gt;, onde &lt;code&gt;&#x2F;proc&lt;&#x2F;code&gt; é o diretório com informações sobre os processos, &lt;code&gt;self&lt;&#x2F;code&gt; é referente ao processo atual, &lt;code&gt;fd&lt;&#x2F;code&gt; são &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Descritor_de_arquivo&quot;&gt;&lt;em&gt;file descriptor&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, que nada mais são que arquivos abertos pelo processo, numerados de 0, 1 e 2. Quando se usa um comando como &lt;code&gt;grep eduardo &amp;lt; entrada.txt &amp;gt; saida.txt 2&amp;gt; erros.txt&lt;&#x2F;code&gt;, manipula-se o &lt;code&gt;stdin&lt;&#x2F;code&gt; para ler do arquivo &lt;code&gt;entrada.txt&lt;&#x2F;code&gt; em vez do teclado, o &lt;code&gt;stdout&lt;&#x2F;code&gt; para escrever no arquivo &lt;code&gt;saida.txt&lt;&#x2F;code&gt; em vez da tela, e o &lt;code&gt;stderr&lt;&#x2F;code&gt; para escrever no arquivo &lt;code&gt;erros.txt&lt;&#x2F;code&gt;. Esse comando também poderia ser escrito como &lt;code&gt;grep eduardo 0&amp;lt; entrada.txt 1&amp;gt; saida.txt 2&amp;gt; erros.txt&lt;&#x2F;code&gt;, ou seja, os comandos &lt;code&gt;&amp;lt;&lt;&#x2F;code&gt; (ou &lt;code&gt;0&amp;lt;&lt;&#x2F;code&gt;), &lt;code&gt;&amp;gt;&lt;&#x2F;code&gt; (ou &lt;code&gt;1&amp;gt;&lt;&#x2F;code&gt;) e &lt;code&gt;2&amp;gt;&lt;&#x2F;code&gt; manipulando os &lt;em&gt;file descriptors&lt;&#x2F;em&gt; 0, 1 e 2 do processo, inclusive é possível abrir outros arquivos, como &lt;code&gt;3&amp;lt;&lt;&#x2F;code&gt; para abrir um arquivo como leitura ou &lt;code&gt;3&amp;gt;&lt;&#x2F;code&gt; como escrita.&lt;&#x2F;p&gt;
&lt;p&gt;Também é possível ligar o &lt;code&gt;stdout&lt;&#x2F;code&gt; de um processo com o &lt;code&gt;stdin&lt;&#x2F;code&gt; de outro, como &lt;code&gt;cat &amp;lt; entrada.txt | grep eduardo | wc -l &amp;gt; saida.txt&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;formatacao-uri&#x2F;pipeline.png&quot; alt=&quot;Pipeline de processos&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Assim a entrada do primeiro processo é o arquivo &lt;code&gt;entrada.txt&lt;&#x2F;code&gt;, a saída do primeiro processo é ligado na entrada do segundo, e a saída do segundo é ligado na entrada do terceiro, e a saída do terceiro é ligado ao arquivo &lt;code&gt;saida.txt&lt;&#x2F;code&gt;. Também vale observar que como o &lt;code&gt;stderr&lt;&#x2F;code&gt; não é tratado, qualquer mensagem que um processo mandar para ele, será exibido na tela, e não encaminhado para o processo seguindo ou arquivo &lt;code&gt;saida.txt&lt;&#x2F;code&gt;. Porém seria possível mandar as mensagens do &lt;code&gt;stderr&lt;&#x2F;code&gt; junto no &lt;code&gt;stdout&lt;&#x2F;code&gt; para o próximo processo ou arquivo com &lt;code&gt;cat &amp;lt; entrada.txt |&amp;amp; grep eduardo |&amp;amp; wc -l &amp;amp;&amp;gt; saida.txt&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fluxos-dentro-do-processo&quot;&gt;Fluxos dentro do processo&lt;&#x2F;h2&gt;
&lt;p&gt;Quem já programou em C, provavelmente já usou as funções &lt;code&gt;printf&lt;&#x2F;code&gt; e &lt;code&gt;scanf&lt;&#x2F;code&gt;, usadas respectivamente para escrever na tela e ler do teclado. Na verdade o que essas funções fazem é escrever no &lt;code&gt;stdout&lt;&#x2F;code&gt; e ler do &lt;code&gt;stdin&lt;&#x2F;code&gt;. Para quem já manipulou arquivos, provavelmente usou as funções &lt;code&gt;fprintf&lt;&#x2F;code&gt; e &lt;code&gt;fscanf&lt;&#x2F;code&gt;, que fazem o mesmo das funções já descritas, porém escrevendo e lendo de um arquivo aberto anteriormente, porém é possível em vez de passar a referência a um arquivo (&lt;em&gt;file descriptor&lt;&#x2F;em&gt;), informar &lt;code&gt;stdout&lt;&#x2F;code&gt;, &lt;code&gt;stderr&lt;&#x2F;code&gt; e &lt;code&gt;stdin&lt;&#x2F;code&gt;, exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;lt;stdio.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; argc&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; char *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;argv&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;[]&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; nota1, nota2;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    float&lt;&#x2F;span&gt;&lt;span&gt; media;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    printf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;Digite a primeira nota: &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    scanf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;%d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;nota1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    fprintf&lt;&#x2F;span&gt;&lt;span&gt;(stdout,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Digite a segunda nota: &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    fscanf&lt;&#x2F;span&gt;&lt;span&gt;(stdin,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;%d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;nota2);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    media &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; (nota1 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; nota2)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2.0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    fprintf&lt;&#x2F;span&gt;&lt;span&gt;(stderr,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;A média é &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;%.2f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, media);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Entretanto algumas funções do C, como &lt;code&gt;puts&lt;&#x2F;code&gt; que recebe um ponteiro de &lt;code&gt;char&lt;&#x2F;code&gt; e imprime na tela, pulando linha ao final, é diferente da função &lt;code&gt;fputs&lt;&#x2F;code&gt; que recebe um arquivo e um ponteiro de &lt;code&gt;char&lt;&#x2F;code&gt;, mas não pula linha (mais informações sobre essas funções podem ser consultadas &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cplusplus.com&#x2F;reference&#x2F;cstdio&#x2F;&quot;&gt;aqui&lt;&#x2F;a&gt;). Algo semelhante à diferença que existe nas funções &lt;code&gt;System.out.println&lt;&#x2F;code&gt; e &lt;code&gt;System.out.print&lt;&#x2F;code&gt; do Java (presentes na classe &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.oracle.com&#x2F;en&#x2F;java&#x2F;javase&#x2F;15&#x2F;docs&#x2F;api&#x2F;java.base&#x2F;java&#x2F;io&#x2F;PrintStream.html&quot;&gt;&lt;code&gt;PrintStream&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;), onde a primeira pula linha ao final e a segunda não. De forma geral, algumas linguagens e bibliotecas trazem mais facilidades para tratar entradas de dados e formatar a saída que outras.&lt;&#x2F;p&gt;
&lt;p&gt;Entretanto formatações como abaixo, referente a execução do código a cima, são só visuais.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Digite a primeira nota: 10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Digite a segunda nota: 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A média é 7.50&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nesse exemplo estão misturados na tela o &lt;code&gt;stdin&lt;&#x2F;code&gt;, o &lt;code&gt;stdout&lt;&#x2F;code&gt; e o &lt;code&gt;stderr&lt;&#x2F;code&gt;, visto que para facilitar a digitação, normalmente é feito um eco do que é digitado na tela. Gerando um arquivo &lt;code&gt;entrada.txt&lt;&#x2F;code&gt; com o conteúdo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;E executado algo como &lt;code&gt;.&#x2F;programa &amp;lt; entrada.txt &amp;gt; saida.txt 2&amp;gt; erros.txt&lt;&#x2F;code&gt;, no arquivo &lt;code&gt;saida.txt&lt;&#x2F;code&gt; teria:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Digite a primeira nota: Digite a segunda nota:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;E no arquivo &lt;code&gt;erros.txt&lt;&#x2F;code&gt; teria:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A média é 7.50&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Repare que o &lt;code&gt;saida.txt&lt;&#x2F;code&gt; não tem uma quebra da linha no final do arquivo, e &lt;code&gt;erros.txt&lt;&#x2F;code&gt; começa com uma linha em branco. Na verdade, a quebra de linha é um caractere como outro qualquer, porém o sistema, em vez de mostrar algo, ele pula para a linha de baixo naquele ponto. Entretanto existem diferenças nas formas como o Windows e sistemas UNIX fazem essa quebra de linha. Em sistemas UNIX é usado o caractere &lt;code&gt;\n&lt;&#x2F;code&gt;, enquanto no Windows são usados os caracteres &lt;code&gt;\r\n&lt;&#x2F;code&gt; também para pular uma única linha. Um visualizador hexadecimal, como o &lt;code&gt;hexdump&lt;&#x2F;code&gt; (ou seu alias &lt;code&gt;hd&lt;&#x2F;code&gt;), que mostra na primeira coluna o endereço dos bytes do arquivo, no centro a representação em hexadecimal dos arquivos, e no final a representação &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;ASCII&quot;&gt;ASCII&lt;&#x2F;a&gt; desses bytes, permite uma visão mais detalhada desses arquivos, onde &lt;code&gt;0a&lt;&#x2F;code&gt; é a representação do &lt;code&gt;\n&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;formatacao-uri&#x2F;hexdump.png&quot; alt=&quot;Exemplo do hexdump&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Entretanto, se o arquivo de entrada for feito no Windows (ou configurado o editor para isso), a quebra de linha seria feita com &lt;code&gt;\r\n&lt;&#x2F;code&gt;, veja esse exemplo (onde &lt;code&gt;0d&lt;&#x2F;code&gt; representa o &lt;code&gt;\r&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;formatacao-uri&#x2F;hexdump2.png&quot; alt=&quot;Exemplo do hexdump para o formato do Windows&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Perceba que os dois arquivos &lt;code&gt;entrada.txt&lt;&#x2F;code&gt; possuem conteúdos diferentes, apesar de semelhantes. Essa diferença pode gerar resultados diferentes dependendo do que o programa espera tratar na entrada, por exemplo o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;pt-BR&#x2F;docs&#x2F;Web&#x2F;JavaScript&quot;&gt;JavaScript&lt;&#x2F;a&gt;, como é sugerido pelo próprio URI:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;var&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;fs&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;readFileSync&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&#x2F;dev&#x2F;stdin&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;utf8&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;var&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lines&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Onde &lt;code&gt;input&lt;&#x2F;code&gt; seria uma string com todo o conteúdo recebido pelo &lt;code&gt;stdin&lt;&#x2F;code&gt;, e &lt;code&gt;lines&lt;&#x2F;code&gt; um array onde cada elemento seria o conteúdo de uma linha, porém como o método &lt;code&gt;split&lt;&#x2F;code&gt; está sendo executado sobre o caractere &lt;code&gt;\n&lt;&#x2F;code&gt;, caso o formato utilizado seja o do Windows, cada posição do array teria um &lt;code&gt;\r&lt;&#x2F;code&gt; no final, com exceção da última linha, o que poderia gerar problemas ao tentar converter essas string para número, visto que existe um caractere que não é numérico na string (o que seria necessário para a entrada que vem sendo utilizada até aqui, visto que a operação &lt;code&gt;+&lt;&#x2F;code&gt; no JavaScript com strings é a concatenação e não a soma matemática). O mesmo pode ocorrer na saída do programa, um &lt;code&gt;\r&lt;&#x2F;code&gt; poderia gerar uma saída diferente, assim como a falta da quebra de linha no final da saída, impossibilitando a leitura correta do arquivo por um processo automatizado, por exemplo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;simulando-o-uri&quot;&gt;Simulando o URI&lt;&#x2F;h2&gt;
&lt;p&gt;Basicamente o que o URI faz é interagir com o programa que foi submetido para ele através do &lt;code&gt;stdin&lt;&#x2F;code&gt; e &lt;code&gt;stdout&lt;&#x2F;code&gt;, o que facilita o suporte a várias linguagens que eles possuem, e até onde eu já vi, considerando o formato de quebra de linha do UNIX (&lt;code&gt;\n&lt;&#x2F;code&gt;). Sendo possível gerar arquivos com os exemplos de entradas na descrição dos problemas ou presentes em sites como &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.udebug.com&#x2F;&quot;&gt;uDebug&lt;&#x2F;a&gt;, e executado com &lt;code&gt;.&#x2F;programa &amp;lt; entrada.txt &amp;gt; saida.txt&lt;&#x2F;code&gt; ou &lt;code&gt;node programa.js &amp;lt; entrada.txt &amp;gt; saida.txt&lt;&#x2F;code&gt; para ler essa entrada e gerar um arquivo contendo a saída do programa, que pode ser comparada com o comando &lt;code&gt;diff&lt;&#x2F;code&gt; para verificar as diferenças com o exemplo de saída esperada (exemplo: &lt;code&gt;diff saida.txt esperado.txt&lt;&#x2F;code&gt;). Embora isso possa ser trabalhoso para programas pequenos, conforme a complexidade dos problemas aumentem, e com diversos casos a serem testados, isso pode facilitar bastante, principalmente os exemplos do uDebug, cobrindo algum caso especial que não foi coberto pelos exemplos do próprio URI.&lt;&#x2F;p&gt;
&lt;p&gt;Uma recomendação minha é utilizar o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;editorconfig.org&#x2F;&quot;&gt;EditorConfig&lt;&#x2F;a&gt; para facilitar a configuração do seu editor. Basta instalar o plugin, se o seu editor não tiver o suporte nativo, e ele lerá o arquivo &lt;code&gt;.editorconfig&lt;&#x2F;code&gt; quando aberto, já aplicando a configuração correta para formatar os arquivos, que podem ser diferentes para cada projeto, inclusive optando entre tab e espaço (quantidade de espaços também). A configuração mínima que recomendo para esse caso é:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;root&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;[*]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;end_of_line&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; lf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;trim_trailing_whitespace&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;insert_final_newline&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Assim é usado o formato do UNIX (&lt;code&gt;lf&lt;&#x2F;code&gt; ou &lt;em&gt;line feed&lt;&#x2F;em&gt; é o nome do caractere &lt;code&gt;\n&lt;&#x2F;code&gt;), ele terminará sempre o arquivo com uma quebra de linha, e remover os espaços em branco no final das linhas, que também podem fazer diferença, e nem sempre são tão visíveis.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Muitas vezes a maior dificuldades das pessoas com o URI, não são seus problemas, mas seguir corretamente e de forma precisa a formatação da saída, e tratar e converter os dados na entrada, visto que muitas vezes é necessário converter de string para inteiro, e esses caracteres não visíveis podem causar diversos erros, ou funcionar no computador com Windows, uma vez que é possível fazer o programa esperar que a entrada tenha &lt;code&gt;\r\n&lt;&#x2F;code&gt; como quebra de linhas, mas não rodar corretamente na hora do URI validar a resposta, uma vez que eles lidam com formatos diferentes de entrada.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Otimizando o algoritmo passo a passo</title>
        <published>2021-02-03T00:00:00+00:00</published>
        <updated>2021-02-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/otimizando-o-algoritmo/"/>
        <id>https://eduardoklosowski.github.io/blog/otimizando-o-algoritmo/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/otimizando-o-algoritmo/">&lt;p&gt;Acompanhando as lives da &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;bug_elseif&quot;&gt;bug_elseif&lt;&#x2F;a&gt;, no meia das &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;wiki.python.org.br&#x2F;ListaDeExercicios&quot;&gt;listas de exercícios que ela estava fazendo&lt;&#x2F;a&gt; tem um exercício pedindo para verificar se um número informado pelo usuário é primo ou não. No chat, muitos faziam sugestões para que o primeiro código feito já fosse o mais otimizado possível, e isso é interessante quando já se sabe a solução do problema. Porém quando não se sabe essa solução, seria possível chegar nela também? É possível otimizar o código pouco a pouco?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;primeira-solucao&quot;&gt;Primeira solução&lt;&#x2F;h2&gt;
&lt;p&gt;A solução mais simples possível é fazer um algoritmo que leia um número, e verifique se ele é divisível apenas por 1 e por ele mesmo (condição para um número ser primo). Para verificar se um número é divisível por outro, basta verificar o resto da divisão, se o resto da divisão for 0, significa que o primeiro número é divisível pelo segundo, se for diferente de 0, o primeiro número não é divisível pelo segundo. Para verificar a divisibilidade do número lido por todos os números, basta testar número por número da sequência de 1 até o número lido, contando a quantidade de vezes que foi possível dividi-lo. Se ao final desse processo, o número foi divisível apenas por dois números (1 e ele mesmo), ele é primo, caso tenha sido dividido por mais de dois números, ele não é primo.&lt;&#x2F;p&gt;
&lt;p&gt;Para implementar esse algoritmo foi escolhida a linguagem &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.php.net&#x2F;&quot;&gt;PHP&lt;&#x2F;a&gt; em homenagem ao matemático &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;pokemaobr&quot;&gt;pokemaobr&lt;&#x2F;a&gt;, que inclusive falou numa live que já esteve em uma competição de código mais eficiente para verificar se um número é primo durante a faculdade. A implementação dessa primeira solução é:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = fopen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;php:&#x2F;&#x2F;stdin&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;r&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Digite um número: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = trim&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fgets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$divisores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span&gt;++) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        $divisores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$divisores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; não é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fclose&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Para executar esse código, basta salvá-lo no computador, atribuir permissão de execução (exemplo: &lt;code&gt;chmod +x verificaprimo&lt;&#x2F;code&gt;), e executá-lo (&lt;code&gt;.&#x2F;verificaprimo&lt;&#x2F;code&gt;), visto que a primeira linha já informa ao sistema qual interpretador deve ser utilizado (essa linha é chamada de &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Shebang&quot;&gt;shebang&lt;&#x2F;a&gt;). Caso essa linha não existisse, seria necessário chamar o código através do interpretador do PHP de forma explícita (&lt;code&gt;php verificaprimo&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Em relação a eficiência, esse código verificará exatamente o mesmo número de divisões do número lido para dar a resposta se o número informado é primo ou não.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;segunda-solucao&quot;&gt;Segunda solução&lt;&#x2F;h2&gt;
&lt;p&gt;A primeira solução funciona, porém para quem olha o código, existe um número mágico (&lt;code&gt;$divisores == 2&lt;&#x2F;code&gt;), que é proveniente da definição (o número deve ser divisível apenas por 1 e por ele mesmo), porém não faz muito sentido para quem não sabe ou não lembra do raciocínio que resulta nesse número. Como todos os números serão divisíveis por 1 e por ele mesmo, não é necessário fazer essa verificação, que pode ser assumida.&lt;&#x2F;p&gt;
&lt;p&gt;Para remover a verificação da divisibilidade pelo 1 e pelo próprio número, é necessário alterar a condição no &lt;code&gt;for&lt;&#x2F;code&gt; e ajustar o &lt;code&gt;if&lt;&#x2F;code&gt; final, considerando casos especiais que surgem com essa solução. Essas melhorias podem ser verificadas a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = fopen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;php:&#x2F;&#x2F;stdin&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;r&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Digite um número: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = trim&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fgets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$divisores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span&gt;++) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        $divisores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$divisores&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; não é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fclose&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Em relação a eficiência, essa solução precisa fazer dois testes de divisibilidade a menos que a primeira solução, portanto um pouco mais eficiente, visto que não é necessário fazer a operação de divisão nesses casos (apenas a comparação). Porém não resolve de fato o problema do número mágico utilizado no código, apenas troca &lt;code&gt;2&lt;&#x2F;code&gt; por &lt;code&gt;0&lt;&#x2F;code&gt;, o que já fica um pouco mais simples de ler, mas ainda é um número mágico para quem não acompanhar a lógica.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;terceira-solucao&quot;&gt;Terceira solução&lt;&#x2F;h2&gt;
&lt;p&gt;Considerando que agora o algoritmo precisa verificar apenas se o contador &lt;code&gt;$divisores&lt;&#x2F;code&gt; foi incrementado alguma vez, é possível trocá-lo por um booleano. Para esse booleano fazer mais sentido, é possível utilizá-lo para dizer o estado do número, assumindo que ele é primo, até descobrir um divisor que prove que ele não é primo, resultando a seguinte implementação:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = fopen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;php:&#x2F;&#x2F;stdin&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;r&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Digite um número: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = trim&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fgets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span&gt;++) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        $primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; não é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fclose&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essa solução remove totalmente o número mágico. Em relação a eficiência, a quantidade de verificações continua a mesma. Mas enquanto a segunda solução precisava ler o valor do contador &lt;code&gt;$divisores&lt;&#x2F;code&gt;, somar e guardar o novo valor nessa variável, nessa solução só o último passo (atribuir valor) é executado.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;quarta-solucao&quot;&gt;Quarta solução&lt;&#x2F;h2&gt;
&lt;p&gt;Entretanto a terceira solução, mesmo após descobrir um caso que prova que o número lido não é primo, continua verificando todos os possíveis divisores. Porém uma vez que é descoberto um caso que prova que o número não é primo, não é necessário continuar verificando os demais. No código isso pode ser visto na variável &lt;code&gt;$primo&lt;&#x2F;code&gt;, que uma vez definida como &lt;code&gt;false&lt;&#x2F;code&gt;, não existe uma condição que a faça voltar para &lt;code&gt;true&lt;&#x2F;code&gt;, sendo possível criar uma interrupção no fluxo de execução (&lt;code&gt;break&lt;&#x2F;code&gt;), saindo do &lt;code&gt;for&lt;&#x2F;code&gt; sem verificar os demais divisores. Essa implementação fica assim:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = fopen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;php:&#x2F;&#x2F;stdin&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;r&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Digite um número: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = trim&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fgets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span&gt;++) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        $primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; não é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fclose&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A eficiência do código continua a mesma para quando o número for primo. Porém quando o número não for primo, assim que for identificado o primeiro divisor, já se terá a resposta.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;quinta-solucao&quot;&gt;Quinta solução&lt;&#x2F;h2&gt;
&lt;p&gt;Considerando que a divisão pode ser desfeita (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Fun%C3%A7%C3%A3o_inversa&quot;&gt;função inversa&lt;&#x2F;a&gt;) através de uma multiplicação, é possível descrever esse problema como a busca por dois números inteiros que multiplicados tem como resultado o número lido (&lt;code&gt;a * b == $numero&lt;&#x2F;code&gt;), também conhecido como &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Fatora%C3%A7%C3%A3o&quot;&gt;fatoração&lt;&#x2F;a&gt;. Testar todos os possíveis divisores, significa testar todos esses valores como &lt;code&gt;a&lt;&#x2F;code&gt; e verificar se o valor usado para &lt;code&gt;b&lt;&#x2F;code&gt; seria um número inteiro, onde o valor de &lt;code&gt;b&lt;&#x2F;code&gt; diminuirá conforme o valor de &lt;code&gt;a&lt;&#x2F;code&gt; crescer para que o número lido como resultado da multiplicação. Considerando a propriedade da comutatividade da multiplicação (&lt;code&gt;a * b == b * a&lt;&#x2F;code&gt;), existirá um ponto onde os valores de &lt;code&gt;a&lt;&#x2F;code&gt; e &lt;code&gt;b&lt;&#x2F;code&gt; são iguais e depois dele serão testados novamente as multiplicações já feitas, apenas trocando os valores de &lt;code&gt;a&lt;&#x2F;code&gt; e &lt;code&gt;b&lt;&#x2F;code&gt;. O ponto onde esses valores são iguais é a raiz do número lido (&lt;code&gt;sqrt($numero) * sqrt($numero) == $numero&lt;&#x2F;code&gt;), então só seria necessário verificar até ele, e não até o valor lido:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = fopen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;php:&#x2F;&#x2F;stdin&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;r&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Digite um número: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = trim&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fgets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;= sqrt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span&gt;++) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        $primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; não é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fclose&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essa solução mantém a mesma eficiência para números não primos da anterior. Mas melhora para os números primos, visto que reduz os divisores testados.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sexta-solucao&quot;&gt;Sexta solução&lt;&#x2F;h2&gt;
&lt;p&gt;Embora a solução anterior seja boa, e muitos acabem sugerindo ela, existe algo a ser observado nela. Para cada vez que o &lt;code&gt;for&lt;&#x2F;code&gt; é executado, sua condição de repetição é avaliada, e assim calcula-se novamente a raiz do número (&lt;code&gt;$i &amp;lt;= sqrt($numero)&lt;&#x2F;code&gt;). O valor da raiz poderia ser guardado em uma variável, e utilizada essa variável para a comparação, visto que o resultado dessa função não muda conforme a execução do código, o que evitaria recalculá-la a cada verificação. Ficando assim:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = fopen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;php:&#x2F;&#x2F;stdin&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;r&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Digite um número: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = trim&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fgets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$raiz&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = sqrt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $raiz&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span&gt;++) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        $primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; não é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fclose&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;outras-solucoes&quot;&gt;Outras soluções&lt;&#x2F;h2&gt;
&lt;p&gt;Ainda existem outras otimizações possíveis. Sabendo que o 2 é o único número primo par, seria possível verificar a divisão por ele, e após isso só testar divisores ímpares, reduzindo assim pela metade a quantidade de divisores testados (considerando também a otimização da raiz quadrada):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = fopen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;php:&#x2F;&#x2F;stdin&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;r&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Digite um número: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = trim&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fgets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    $primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    $raiz&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = sqrt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $raiz&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;            $primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; não é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fclose&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Essas são otimizações considerando apenas o código. Ainda é possível considerar a arquitetura do computador onde ele será executando, buscando instruções mais rápida, ou que consomem menos energia (aumentando o tempo de bateria), para aquele processador. Outro tipo de otimização seria tentar reduzir a quantidade de memória utilizada, por exemplo, utilizando a variável que guarda o resultado para raiz como a variável de controle do &lt;code&gt;for&lt;&#x2F;code&gt;, percorrendo os números de forma inversa, como nessa implementação:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = fopen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;#39;php:&#x2F;&#x2F;stdin&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;r&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Digite um número: &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = trim&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fgets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; = floor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;sqrt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span&gt;--) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;        $primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        break&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$primo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;O número &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$numero&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; não é primo!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;fclose&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$stdin&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Foi possível, partindo de uma solução não otimizada, fazer pequenas otimizações e chegar a uma solução bastante otimizada. Esse processo pode ser repetido em qualquer código, basta fazer uma solução simples que funciona, após isso estudar como melhorá-la, o que é um bom incentivo para voltar para o código depois dele ter funcionado.&lt;&#x2F;p&gt;
&lt;p&gt;Algumas otimizações melhoraram a legibilidade do código, deixando-o muito mais simples de entender posteriormente, removendo valores que parecem ser arbitrários do código (números mágicos). Enquanto outras otimizações aumentam a complexidade, criando uma escolha entre ter um código mais performático, ou mais fácil de entender.&lt;&#x2F;p&gt;
&lt;p&gt;Ainda sobre esse assunto, eu recomendo a palestra do Jon &quot;MadDog&quot; Hall no FISL 15, &quot;Performance: More Than Just Speed&quot;:&lt;&#x2F;p&gt;
&lt;video
    src=&quot;http:&#x2F;&#x2F;hemingway.softwarelivre.org&#x2F;fisl15&#x2F;high&#x2F;40t&#x2F;sala40t-high-201405081059.ogv&quot;
    controls
    style=&quot;max-width: 100%; height: 360px&quot;
&gt;&lt;&#x2F;video&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Como roubar no random?</title>
        <published>2021-01-13T00:00:00+00:00</published>
        <updated>2021-01-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/roubar-random/"/>
        <id>https://eduardoklosowski.github.io/blog/roubar-random/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/roubar-random/">&lt;p&gt;Recentemente o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;vitthin&quot;&gt;vitthin&lt;&#x2F;a&gt; implementou o comando &lt;code&gt;!amizade &amp;lt;username&amp;gt;&lt;&#x2F;code&gt; em seu bot, que recebe o nome de outro usuário como parâmetro, respondendo no chat uma porcentagem randômica para qual seria sua amizade com aquela pessoa, apenas por diversão (e algumas brigas também, quem sabe?). Porém os resultados estavam questionáveis, principalmente se não existiria algum &lt;code&gt;if&lt;&#x2F;code&gt; no código para favorecer ou desfavorecer determinados usuários.&lt;&#x2F;p&gt;
&lt;p&gt;Existe um problema sobre a distribuição dos valores randômicos, principalmente quando se utiliza o resto da divisão, como demonstrado &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitismyth.wordpress.com&#x2F;2020&#x2F;02&#x2F;14&#x2F;o-problema-da-solucao-ingenua-da-obtencao-de-valores-aleatorios&#x2F;&quot;&gt;neste artigo&lt;&#x2F;a&gt;. Porém isso só é observado quando se tem muitas execuções, e não é uma manipulação ativa do valor randômico, como estávamos questionando.&lt;&#x2F;p&gt;
&lt;p&gt;Para demonstrar que era possível manipular a mensagem enviada pelo bot, sem que isso apareça no código, eu fiz a demonstração a baixo:&lt;&#x2F;p&gt;
&lt;script
    id=&quot;asciicast-383797&quot;
    src=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;383797.js&quot;
    async
&gt;&lt;&#x2F;script&gt;
&lt;p&gt;Ou seja, é possível fazer essa manipulação. A questão que o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;vitthin&quot;&gt;vitthin&lt;&#x2F;a&gt; não conseguiu responder foi: como isso foi feito?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;como-manipular-o-codigo&quot;&gt;Como manipular o código?&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;atraves-do-decorador&quot;&gt;Através do decorador&lt;&#x2F;h3&gt;
&lt;p&gt;Na própria live, enquanto estávamos discutindo, eu comentei que o decorador utilizado na função implementada pelo &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;vitthin&quot;&gt;vitthin&lt;&#x2F;a&gt; poderia manipular o resultado. Algo como o código a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; decorator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;font-style: italic;&quot;&gt;funcao&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; wrapper&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Tchau&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; wrapper&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;@decorator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; cumprimentar&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39;Oi&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;cumprimentar&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  # Resultado: Tchau&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ou como demonstrado pelo Fernando Masanori:&lt;&#x2F;p&gt;
&lt;iframe
    width=&quot;640&quot;
    height=&quot;360&quot;
    src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;Wnc6McPpmUg&quot;
    allowfullscreen
    style=&quot;border: 0; max-width: 100%;&quot;
&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;Com esse método, é realmente possível alterar o comportamento do código, porém fica explícito no código a existência desse decorador, o que pode facilmente levantar suspeitas. Porém não foi o caso da minha demonstração, uma vez que eu também mostro o código desse decorador, e não tem nada lá fazendo essa manipulação.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alterar-a-biblioteca-padrao&quot;&gt;Alterar a biblioteca padrão&lt;&#x2F;h3&gt;
&lt;p&gt;Em outra demonstração também feita pelo Fernando Masanori, ele altera a biblioteca padrão do Python, no caso alterando o código da função &lt;code&gt;randint&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;iframe
    width=&quot;640&quot;
    height=&quot;360&quot;
    src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;0KU2ntx0MZc&quot;
    allowfullscreen
    style=&quot;border: 0; max-width: 100%;&quot;
&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;Com esse método também é possível alterar o comportamento do código, mas diferente do anterior, não deixa explícito a manipulação que foi feita. Porém na minha demonstração, o comportamento da função muda conforme o nome de usuário informado, o qual não é acessível dentro da função &lt;code&gt;randint&lt;&#x2F;code&gt;, apenas se mudasse a assinatura da função para receber o nome do usuário também, mas isso seria visível no código, então não seria possível fazer a mesma coisa que na demonstração.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alterar-de-onde-carregar-bibliotecas&quot;&gt;Alterar de onde carregar bibliotecas&lt;&#x2F;h3&gt;
&lt;p&gt;Durante uma apresentação no FISL 14, o Cascardo comentou sobre o desafio de fazer um programa Java aceitar outro certificado (começando a discussão aos 23:05), onde de 26:43 até 28:50 ele comentou como trocou a classe utilizada pelo Java, retomando ao assunto aos 37:29 até 37:55:&lt;&#x2F;p&gt;
&lt;video
    src=&quot;http:&#x2F;&#x2F;hemingway.softwarelivre.org&#x2F;fisl14&#x2F;high&#x2F;41b&#x2F;sala41b-high-201307031502.ogg&quot;
    controls
    style=&quot;max-width: 100%; height: 360px&quot;
&gt;&lt;&#x2F;video&gt;
&lt;p&gt;Essa opção funciona para o Java (pergunto se funcionaria para o Kotlin também &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;morgiovanelli&quot;&gt;morgiovanelli&lt;&#x2F;a&gt;?). No Python, esse comportamento pode ser replicado utilizando a variável de ambiente &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;using&#x2F;cmdline.html?highlight=pythonpath#envvar-PYTHONPATH&quot;&gt;&lt;code&gt;PYTHONPATH&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, bastando criar uma cópia alterada da biblioteca em outro lugar, e informando isso nessa variável de ambiente quando fosse executado o código.&lt;&#x2F;p&gt;
&lt;p&gt;Esse método também permite alterar o comportamento do código, mas apenas para bibliotecas em outros diretórios, como a biblioteca padrão e de terceiros, o que é demonstrado a baixo pela ordem de precedência dos diretórios, onde a string vazia (&lt;code&gt;&#x27;&#x27;&lt;&#x2F;code&gt;) representa o diretório atual:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; pprint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; pprint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;pprint&lt;&#x2F;span&gt;&lt;span&gt;(sys.path)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Resultado:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# [&amp;#39;&amp;#39;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#  &amp;#39;&#x2F;home&#x2F;eduardo&#x2F;pythonlibmod&amp;#39;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#  &amp;#39;&#x2F;usr&#x2F;lib&#x2F;python37.zip&amp;#39;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#  &amp;#39;&#x2F;usr&#x2F;lib&#x2F;python3.7&amp;#39;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#  &amp;#39;&#x2F;usr&#x2F;lib&#x2F;python3.7&#x2F;lib-dynload&amp;#39;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#  &amp;#39;&#x2F;usr&#x2F;local&#x2F;lib&#x2F;python3.7&#x2F;dist-packages&amp;#39;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;#  &amp;#39;&#x2F;usr&#x2F;lib&#x2F;python3&#x2F;dist-packages&amp;#39;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Em relação ao código da minha demonstração, ele só permitiria alterar a função &lt;code&gt;randint&lt;&#x2F;code&gt;, que como já foi discutido, não permitiria repetir o mesmo comportamento da demonstração. Como a biblioteca &lt;code&gt;lib&lt;&#x2F;code&gt; encontra-se no mesmo diretório da aplicação, não seria possível utilizar esse método para alterá-la.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;comprometendo-o-kernel&quot;&gt;Comprometendo o kernel&lt;&#x2F;h3&gt;
&lt;p&gt;Outra técnica seria comprometendo o sistema, alterando diretamente o kernel onde o código é executado, como feito pelo Seth Schoen numa apresentação no FISL 15 dos 25:17 até 33:03:&lt;&#x2F;p&gt;
&lt;video
    src=&quot;http:&#x2F;&#x2F;hemingway.softwarelivre.org&#x2F;fisl15&#x2F;high&#x2F;40t&#x2F;sala40t-high-201405071559.ogv&quot;
    controls
    style=&quot;max-width: 100%; height: 360px&quot;
&gt;&lt;&#x2F;video&gt;
&lt;p&gt;Definitivamente esse método permite alterar o comportamento do código e é o mais difícil de se detectar. Porém no final da minha demonstração eu usei o próprio Python para ler e exibir o arquivo, então seria possível reproduzir o comportamento do código, porém a alteração seria visível ao imprimir o código na tela pelo Python.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;edicao-de-video&quot;&gt;Edição de vídeo&lt;&#x2F;h3&gt;
&lt;p&gt;É possível que o comportamento da minha demonstração seja uma edição de vídeo, ainda mais que ele foi gravado com o asciinema, bastando trocar os resultados conforme desejado, visto que ele está em &lt;em&gt;plaintext&lt;&#x2F;em&gt; no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;383797.cast?dl=1&quot;&gt;arquivo&lt;&#x2F;a&gt;. Porém isso não seria aplicável ao chat na Twitch, como estava sendo usado, apenas no vídeo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;como-foi-feito&quot;&gt;Como foi feito&lt;&#x2F;h2&gt;
&lt;p&gt;Para fazer isso, eu primeiramente olhei no &lt;code&gt;python -h&lt;&#x2F;code&gt;, onde foi possível encontrar algumas opções interessantes para interagir como o interpretador do Python, onde o parâmetro &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;using&#x2F;cmdline.html?highlight=pythonstartup#envvar-PYTHONSTARTUP&quot;&gt;&lt;code&gt;PYTHONSTARTUP&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; permitiria que código de outro lugar fosse executádo automaticamente, sem que fosse visto na tela.&lt;&#x2F;p&gt;
&lt;p&gt;Desta forma fiz o seguinte &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;roubar-random&#x2F;codigo.tar.gz&quot;&gt;código&lt;&#x2F;a&gt;, que para executá-lo basta entrar no diretório &lt;code&gt;botmod&#x2F;meubot&lt;&#x2F;code&gt; e rodar &lt;code&gt;PYTHONSTARTUP=..&#x2F;editlib.py python3&lt;&#x2F;code&gt;, ou ainda definir a variável de anteriormente, com &lt;code&gt;export PYTHONSTARTUP=..&#x2F;editlib.py&lt;&#x2F;code&gt;, assim ao executar &lt;code&gt;python3&lt;&#x2F;code&gt; o meu script carregaria a biblioteca e faria &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.stackoverflow.com&#x2F;questions&#x2F;285190&#x2F;o-que-%C3%A9-monkey-patch#305084&quot;&gt;monkey patching&lt;&#x2F;a&gt; para aplicar a alteração na &lt;code&gt;lib&lt;&#x2F;code&gt; (o que lembra da discussão sobre macacos digitando na live da &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;bug_elseif&quot;&gt;bug_elseif&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;A minha demonstração é verdadeira e facilmente reproduzível, sem a utilização de algum recurso como edição de vídeo. Embora não foi possível fazer a mesma demonstração com os outros métodos mostrados, eles também permitem fazer manipulação no comportamento do código, podendo serem utilizados em outros casos. A área de metaprogramação trabalha bastante com técnicas apresentadas, e recomendo &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;hemingway.softwarelivre.org&#x2F;fisl14&#x2F;high&#x2F;41d&#x2F;sala41d-high-201307031001.ogg&quot;&gt;essa palestra&lt;&#x2F;a&gt; sobre o assunto.&lt;&#x2F;p&gt;
&lt;p&gt;É importante observar também as implicações de segurança das demonstrações. Na mesma apresentação do Seth, ele comenta outras questões bastante interessantes, como aos 19:00 sobre a possibilidade do compilador inserir falhas de segurança nos programas, ou erros como descrito aos 13:38, que podem atingir linguagens de mais alto nível como o próprio Python. Também sobre uma falha de segurança no OpenSSH, que a correção consistia na diferença de apenas um bit no código binário. Vale observar também que muitas vezes um programa malicioso pode não ter permissão para fazer alguma operação, mas se aproveitar de permissões incorretas de arquivos e diretórios (principalmente &lt;code&gt;chmod 777&lt;&#x2F;code&gt;) para criar códigos, que poderiam ser executados sem perceber por outros usuários, onde esses teriam permissão para fazer a operação.&lt;&#x2F;p&gt;
&lt;p&gt;Felizmente ou infelizmente não é possível para um terceiro alterar o comportamento do random de um bot diretamente com o uso desses métodos, ele precisaria de acesso ao ambiente onde o código é executado, mas é possível para o dono do bot.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>PHP: Interpretação de variáveis em string ou concatenação?</title>
        <published>2020-12-29T00:00:00+00:00</published>
        <updated>2020-12-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/php-interpretacao-concatenacao/"/>
        <id>https://eduardoklosowski.github.io/blog/php-interpretacao-concatenacao/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/php-interpretacao-concatenacao/">&lt;p&gt;Na live do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;pokemaobr&quot;&gt;pokemaobr&lt;&#x2F;a&gt;, durante o desenvolvimento de uma funcionalidade do bot, ocorreu uma discussão a respeito de usar &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.php.net&#x2F;manual&#x2F;pt_BR&#x2F;language.types.string.php#language.types.string.parsing&quot;&gt;interpretação de variáveis dentro da string&lt;&#x2F;a&gt; ou concatenar, tanto em relação a desempenho, quanto legibilidade. Eu fiquei curioso em relação ao desempenho, então resolvi fazer alguns testes estatísticos para verificar isso.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experimento&quot;&gt;Experimento&lt;&#x2F;h2&gt;
&lt;p&gt;Para fazer um teste estatístico, o primeiro passo é adquirir os dados. Para esse caso, bastaria implementar as diferentes opções e medir o desempenho de cada uma. Então fiz um código que gere uma string a partir de 10 variáveis, repetindo a instrução que gera a string 1 milhão de vezes, o que faz com que a execução do código leve um tempo razoável para ser medido. Então a estrutura do experimento ficou assim:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$g&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$j&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$k&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $k&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1000000&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $k&lt;&#x2F;span&gt;&lt;span&gt;++) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    # Código que gera a string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A primeira opção a ser testado é a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.php.net&#x2F;manual&#x2F;pt_BR&#x2F;language.types.string.php#language.types.string.parsing.simple&quot;&gt;interpretação simples de variáveis&lt;&#x2F;a&gt;, que consiste em usar as variáveis diretamente entre aspas duplas (&lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;codigo1.php&quot;&gt;código completo&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$a $b $c $d $e $f $g $h $i $j&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A segunda opção é a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.php.net&#x2F;manual&#x2F;pt_BR&#x2F;language.types.string.php#language.types.string.parsing.complex&quot;&gt;interpretação complexa de variáveis&lt;&#x2F;a&gt;, que é semelhante a primeira, porém coloca a variável entre chaves (&lt;code&gt;{}&lt;&#x2F;code&gt;) (&lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;codigo2.php&quot;&gt;código completo&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$g&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;} {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$j&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A terceira opção é a concatenação de strings utilizando aspas duplas (&lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;codigo3.php&quot;&gt;código completo&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $a&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $b&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $c&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $d&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $e&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $f&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $g&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $h&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $j&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;E a quarta e última opção é a concatenação de strings utilizando aspas simples (&lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;codigo4.php&quot;&gt;código completo&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $a&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $b&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $c&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $d&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $e&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $f&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $g&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $h&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $i&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;#39; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $j&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ainda é necessário uma forma de medir o desempenho desses códigos. Por ter optado em executá-los diretamente no terminal (para não ter interferência de algum servidor web, por exemplo), é possível medir o desempenho do processo diretamente. Uma ferramenta que faz isso é o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;time&#x2F;&quot;&gt;GNU Time&lt;&#x2F;a&gt;, que pode ser instalado no &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.debian.org&#x2F;&quot;&gt;Debian&lt;&#x2F;a&gt; com &lt;code&gt;apt install time&lt;&#x2F;code&gt;. Porém o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;bash&#x2F;&quot;&gt;Bash&lt;&#x2F;a&gt; também possui um comando interno chamado &lt;code&gt;time&lt;&#x2F;code&gt;, sendo necessário informar o caminho completo do executável (&lt;code&gt;&#x2F;usr&#x2F;bin&#x2F;time&lt;&#x2F;code&gt;) para que ele seja executado, em vez do comando interno do Bash.&lt;&#x2F;p&gt;
&lt;p&gt;Para facilitar o processo de análise, criei um shell script (&lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;run.sh&quot;&gt;run.sh&lt;&#x2F;a&gt;) que executa cada código alternadamente 100 vezes, gerando uma boa quantidade de dados para que possa ser feita uma análise estatística, e de forma que outros processos que executem durante algum teste não interfira tanto nos resultados. A saída do script é um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Comma-separated_values&quot;&gt;CSV&lt;&#x2F;a&gt; com os valores medidos, semelhante aos &lt;code&gt;.txt&lt;&#x2F;code&gt; utilizados pelo bot já citado. Porém também comprimi o arquivo com &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.gzip.org&#x2F;&quot;&gt;Gzip&lt;&#x2F;a&gt; para reduzir o tamanho do mesmo, embora não fosse realmente necessário para essa pequena base, mas isso é bastante feito para bases CSV grandes, visto a boa taxa de compressão para arquivos de texto, que é o caso do CSV, economizando alguns &lt;em&gt;gigabytes&lt;&#x2F;em&gt; em muitos casos. O resultado final está disponível &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;dados.csv.gz&quot;&gt;aqui&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A versão do PHP utilizada foi a 7.3.19-1~deb10u1, que é a versão mais recente disponível no repositório &lt;em&gt;stable&lt;&#x2F;em&gt; do Debian, que estava na versão 10.7 (Buster) no dia da escrita desse artigo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;analise-do-tempo-de-execucao&quot;&gt;Análise do tempo de execução&lt;&#x2F;h2&gt;
&lt;p&gt;Para fazer a análise, optei por utilizar a linguagem &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.r-project.org&#x2F;&quot;&gt;R&lt;&#x2F;a&gt;, que é voltada para estatísticas, dentro de um notebook do &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;jupyter.org&#x2F;&quot;&gt;Jupyter&lt;&#x2F;a&gt;, que facilita a execução e replicação dos testes, podendo ser acessado &lt;a href=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;analise.ipynb&quot;&gt;aqui&lt;&#x2F;a&gt; (ou visualizado &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoklosowski&#x2F;blog&#x2F;blob&#x2F;main&#x2F;content&#x2F;2020-12-29-php-interpretacao-concatenacao&#x2F;analise.ipynb&quot;&gt;aqui&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Para visualizar os dados foi escolhido o &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Diagrama_de_caixa&quot;&gt;&lt;em&gt;boxplot&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, que consiste em um gráfico como qualquer outro, porém em vez de um ponto no plano cartesiano, apresenta a figura a baixo. Essa figura indica qual é o maior e menor valor, mediana (50% dos dados estão a baixo dessa linha e 50% a cima), 1º quartil (25% dos dados estão a baixo dessa linha e 75% a cima) e 3º quartil (75% dos dados estão a baixo dessa linha e 25% dos dados estão a cima). Essas linhas podem estar mais próximas ou distantes conforme a distribuição dos valores representado pelo &lt;em&gt;boxplot&lt;&#x2F;em&gt;. A aparição de algum ponto, além da figura do &lt;em&gt;boxplot&lt;&#x2F;em&gt;, representa um &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Outlier&quot;&gt;&lt;em&gt;outlier&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, que é um valor bastante diferente dos demais, neste caso, o mais provável é que alguma outra coisa executou no computador e interferiu na execução do código a ser testado.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;boxplot.png&quot; alt=&quot;Boxplot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A baixo está o &lt;em&gt;boxplot&lt;&#x2F;em&gt; do tempo de execução dos diferentes códigos implementados:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;tempo-boxplot.png&quot; alt=&quot;Boxplot do tempo de execução&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;É possível observar uma tendência de tempo menor nas implementações de interpretação de variáveis que nas implementações com concatenação, provavelmente devido a essas últimas precisarem fazer várias operações de concatenações, que por sua vez podem gerar diferentes strings intermediárias. Na linguagem Java, por exemplo, existe a classe &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.w3cub.com&#x2F;openjdk~11&#x2F;java.base&#x2F;java&#x2F;lang&#x2F;string&quot;&gt;&lt;code&gt;String&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, e a classe &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.w3cub.com&#x2F;openjdk~11&#x2F;java.base&#x2F;java&#x2F;lang&#x2F;stringbuilder&quot;&gt;&lt;code&gt;StringBuilder&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, que é semelhante a primeira, porém mutável, sendo muito mais rápida para fazer diversas concatenações, uma vez que não precisa gerar diversas strings intermediárias, e depois pode ser convertida para uma &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.w3cub.com&#x2F;openjdk~11&#x2F;java.base&#x2F;java&#x2F;lang&#x2F;string&quot;&gt;&lt;code&gt;String&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; propriamente dita.&lt;&#x2F;p&gt;
&lt;p&gt;Para verificar se essas diferenças nos tempos de execução é estatisticamente significativa, é possível aplicar um teste &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;An%C3%A1lise_de_vari%C3%A2ncia&quot;&gt;ANOVA&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             Df Sum Sq Mean Sq F value Pr(&amp;gt;F)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;codigo        3 2.5462  0.8487    2425 &amp;lt;2e-16 ***&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Residuals   396 0.1386  0.0003&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;O teste apresenta um valor P bastante significativo (&lt;code&gt;Pr&lt;&#x2F;code&gt; na tabela a cima), indicando que existem diferenças estatisticamente significativas. Para encontrar que diferenças são essas, é possível aplicar um teste de &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tukey%27s_range_test&quot;&gt;Tukey&lt;&#x2F;a&gt;. Uma forma de representá-lo é através de um gráfico com intervalos das diferenças entre os valores medidos, onde as diferenças estatisticamente significativas não incluirão o 0 no intervalo. A baixo esse gráfico com &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pt.wikipedia.org&#x2F;wiki&#x2F;Intervalo_de_confian%C3%A7a&quot;&gt;nível de confiança&lt;&#x2F;a&gt; de 95% (para entender mais sobre nível ou intervalo de confiança recomendo esse &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=GsnnsmZAi5Y&quot;&gt;vídeo&lt;&#x2F;a&gt;, e lembrar um pouco da &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.twitch.tv&#x2F;unnskyld2&quot;&gt;unnskyld2&lt;&#x2F;a&gt; também):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;tempo-tukey.png&quot; alt=&quot;Teste de Tukey para o tempo de execução&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Esse gráfico demonstra que existem diferenças estatisticamente significativas entre as implementações com interpretação de variáveis das com concatenação, porém entras as implementações de interpretação de variáveis e entre as com concatenação não foi encontrado diferenças estatisticamente significativas, não sendo possível afirmar qual entre cada grupo é a melhor, se é existe diferença de desempenho.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;uso-de-memoria-ram&quot;&gt;Uso de memória RAM&lt;&#x2F;h2&gt;
&lt;p&gt;Outra coisa que também foi medido pelo &lt;code&gt;time&lt;&#x2F;code&gt; é o uso de memória RAM. Repetindo o processo efetuado com o tempo de execução, temos o &lt;em&gt;boxplot&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;memoria-boxplot.png&quot; alt=&quot;Boxplot do uso de memória&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Nesse gráfico não é possível verificar nenhuma grande diferença de uso de memória entre as implementações, o que é corroborado pelo teste ANOVA, que também não apresenta diferenças, com valor P (0.206) a cima de 0.05 (valor usado para o intervalo de confiança de 95%).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             Df  Sum Sq Mean Sq F value Pr(&amp;gt;F)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;codigo        3   88864   29621   1.531  0.206&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Residuals   396 7663691   19353&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Como não foi encontrado diferenças estatisticamente significativas, não é necessário aplicar o teste de Tukey. Mas por curiosidade, segue a baixo:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;eduardoklosowski.github.io&#x2F;blog&#x2F;php-interpretacao-concatenacao&#x2F;memoria-tukey.png&quot; alt=&quot;Teste de Tukey do uso de memória&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Em relação a discussão inicial, este texto verifica apenas a questão do desempenho, não abordando a questão de legibilidade. Dentro da questão de desempenho, foi verificado que a utilização de interpretação de variável é mais rápida que a concatenação, e essa diferença é estatisticamente significativa. Porém não foi observado nenhuma diferença em relação ao uso de memória RAM, tendo a diferença se restringindo ao tempo de execução.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="pt-BR">
        <title>Diferentes formas de expressar em código</title>
        <published>2020-12-14T00:00:00+00:00</published>
        <updated>2020-12-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Eduardo Klosowski
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://eduardoklosowski.github.io/blog/expressar-em-codigo/"/>
        <id>https://eduardoklosowski.github.io/blog/expressar-em-codigo/</id>
        
        <content type="html" xml:base="https://eduardoklosowski.github.io/blog/expressar-em-codigo/">&lt;p&gt;Existem diferentes formas de se programar algo, mesmo quando usa-se a mesma linguagem de programação. Embora esses códigos possam ser considerados equivalentes, uma vez que apresentam o mesmo resultado, eles tem suas particularidades, podendo facilitar ou dificultar sua leitura e manutenção. Usando como exemplo a impressão dos valores de uma lista (ou array) no terminal utilizando a linguagem &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;pt-BR&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt;, pretendo mostrar essas diferenças na prática, de forma que também possa ser abstraído para outras lógicas e linguagens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;problema-proposto&quot;&gt;Problema proposto&lt;&#x2F;h2&gt;
&lt;p&gt;Dado uma lista:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Deseja-se imprimir no terminal o índice e valor de cada elemento, conforme a baixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0 =&amp;gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 =&amp;gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2 =&amp;gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3 =&amp;gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 =&amp;gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 =&amp;gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Uma forma de se resolver esse problema é iterando sobre os elementos da lista, imprimindo os índices e valores.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;codigo-1-acesso-direto&quot;&gt;Código 1: Acesso direto&lt;&#x2F;h2&gt;
&lt;p&gt;Uma primeira forma de resolver esse problema é acessando cada valor diretamente no código. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;{} =&amp;gt; {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;{} =&amp;gt; {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;{} =&amp;gt; {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;{} =&amp;gt; {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;{} =&amp;gt; {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;{} =&amp;gt; {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse código é simples e direto, tendo como resultado da sua execução o resultado desejado. Porém apresenta dois pontos principais: ele é fixo para 6 elementos, sendo necessário sua alteração caso a quantidade de elementos da lista seja alterado; também existe uma repetição no código, sendo necessário alterar todos os &lt;code&gt;println!(...)&lt;&#x2F;code&gt; caso deseja-se mudar a saída.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;codigo-2-while&quot;&gt;Código 2: &lt;code&gt;while&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;É possível escrever o código de forma que ele se adapte a quantidade de elementos da lista, sendo necessário uma estrutura de repetição para isso. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;{} =&amp;gt; {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse código utiliza a estrutura de repetição &lt;code&gt;while&lt;&#x2F;code&gt; para melhorar os dois pontos destacados no código anterior, verificando o tamanho da lista em tempo de execução, e evitando a repetição do &lt;code&gt;println!(...)&lt;&#x2F;code&gt;. Porém isso vem com o custo adicional de uma variável e alguns ciclos de processamento adicionais para fazer o controle da estrutura de repetição (acessar o tamanho da lista e compará-lo a variável de controle).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;codigo-3-for&quot;&gt;Código 3: &lt;code&gt;for&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Outra forma possível é a utilização da estrutura de repetição &lt;code&gt;for&lt;&#x2F;code&gt;. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;lista&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;{} =&amp;gt; {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse código, assim como o anterior, necessita de uma variável para o controle da estrutura de repetição. Entretanto, o controle desta variável fica a cargo da linguagem e não do programador, não sendo necessário incrementá-lo manualmente, e fica mais claro no código como a estrutura de repetição está sendo controlada. Um ponto negativo é que não é possível alterar essa variável diretamente, o que possibilitaria imprimir os valores em outra ordem, com alguma lógica mais elaborada, como seria possível no Código 2.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;codigo-4-iterando-com-for&quot;&gt;Código 4: Iterando com &lt;code&gt;for&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Em Rust é possível iterar diretamente os valores de uma lista utilizando o &lt;code&gt;for&lt;&#x2F;code&gt;. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;_ =&amp;gt; {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; v&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Embora esse seja o código mais simples usando uma estrutura de repetição, e fica claro no código de que a interação está ocorrendo em cima dos valores da lista, não é possível mostrar o índice do valor no &lt;code&gt;println!(...)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;codigo-5-iterando-com-for-e-enumerate&quot;&gt;Código 5: Iterando com &lt;code&gt;for&lt;&#x2F;code&gt; e &lt;code&gt;.enumerate()&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Para permitir que o índice seja mostrado, é possível enumerar os valores da lista. Desta forma, em vez de iterar nos elementos da lista diretamente, o &lt;code&gt;for&lt;&#x2F;code&gt; itera em tuplas com o valor dado pelo &lt;code&gt;.enumerate()&lt;&#x2F;code&gt; e o elemento da lista. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span&gt;, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;v&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; lista&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;enumerate&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;{} =&amp;gt; {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; v&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse código se assemelha ao anterior em simplificação, porém permitindo que o índice seja impresso no terminal. Embora ele seja bem parecido com o Código 3, seu &lt;code&gt;for&lt;&#x2F;code&gt; deixa claro que a estrutura de repetição está iterando sobre os valores da lista, enquanto o &lt;code&gt;for&lt;&#x2F;code&gt; do Código 3 apenas diz que está sendo iterado sobre seus índices, necessitando verificar o bloco de código do &lt;code&gt;for&lt;&#x2F;code&gt; para entender no que o índice está sendo usado, e necessitando acessar manualmente os valores da lista, o que poderia dificultar a alteração do nome da variável da lista, por exemplo, uma vez que o mesmo precisaria ser alterado em diversos lugares.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;codigo-6-for-each&quot;&gt;Código 6: &lt;code&gt;.for_each()&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Rust também permite que o código seja feito utilizando funções em vez de uma estrutura de repetição (embora a estrutura de repetição seja usada internamente por essas funções). Para esse caso foi utilizado a função &lt;code&gt;.for_each()&lt;&#x2F;code&gt; do iterador, que permite chamar uma função passada por argumento para cada valor da lista. Exemplo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;lista&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;enumerate&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;for_each&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span&gt;, &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;v&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;{} =&amp;gt; {}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; v&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esse código está dividido em várias linhas apenas para facilitar sua leitura, podendo estar em uma única linha. O compilador do Rust também consegue otimizar esse código deixando-o mais performático que a versão utilizando o &lt;code&gt;for&lt;&#x2F;code&gt;. Porém a versão com &lt;code&gt;for&lt;&#x2F;code&gt; deixa explícito no código a iteração dos elementos da lista, o que poderia facilitar a sua leitura. Nesse código também não é possível utilizar comandos como &lt;code&gt;continue&lt;&#x2F;code&gt; e &lt;code&gt;break&lt;&#x2F;code&gt; para controlar a estrutura de repetição, necessitando utilizar outras &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;iter&#x2F;trait.Iterator.html#required-methods&quot;&gt;funções do iterador&lt;&#x2F;a&gt; para comportamentos distintos.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consideracoes&quot;&gt;Considerações&lt;&#x2F;h2&gt;
&lt;p&gt;Com exceção do Código 4, todos os outros têm o mesmo resultado no terminal, sendo opções de código viáveis de resolução do problema proposto. Cada código possui suas diferenças, variando em legibilidade e flexibilidade. Pensando em percorrer os elementos da lista para resolver o problema, essa lógica pode ser expressa de diferentes formas, como visto nos diferentes códigos apresentados, assim como em português é possível transmitir uma mesma ideia com diferentes frases.&lt;&#x2F;p&gt;
&lt;p&gt;Abstraindo para um sistema, existem diferentes formas de resolver as pequenas partes do sistema, e muitas vezes essas pequenas partes podem apresentar similaridades. Quando essas partes são resolvidas utilizando a mesma técnica, isso pode facilitar a leitura e manutenção do código, uma vez que fica mais fácil de pressupor o que o código está fazendo conforme o programador se habitua com ele. Assim como, ao se terminar uma alteração, é possível fazer uma análise, verificando se não existe uma melhor forma de expressar a lógica já implementada, deixando o código mais organizado, o que facilitaria a leitura do mesmo.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
