<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Leonardo Gregianin on Medium]]></title>
        <description><![CDATA[Stories by Leonardo Gregianin on Medium]]></description>
        <link>https://medium.com/@leogregianin?source=rss-d11676685b9a------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*6U_hIkGOumy2DWgsumTrLg.jpeg</url>
            <title>Stories by Leonardo Gregianin on Medium</title>
            <link>https://medium.com/@leogregianin?source=rss-d11676685b9a------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 12 Nov 2026 18:10:30 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@leogregianin/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[go is good (this is about golang)]]></title>
            <link>https://medium.com/@leogregianin/go-is-good-this-is-about-golang-f485c111ba76?source=rss-d11676685b9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/f485c111ba76</guid>
            <category><![CDATA[career-best-choice]]></category>
            <category><![CDATA[go]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[golang]]></category>
            <category><![CDATA[programming-languages]]></category>
            <dc:creator><![CDATA[Leonardo Gregianin]]></dc:creator>
            <pubDate>Mon, 31 Mar 2025 12:12:59 GMT</pubDate>
            <atom:updated>2025-03-31T13:07:34.661Z</atom:updated>
            <content:encoded><![CDATA[<h4>A few days ago, I came across the repository “<a href="https://github.com/ksimka/go-is-not-good">go-is-not-good</a>”, which contains several articles with negative views about Golang. After analyzing and reading all the points, I wrote this article highlighting the positive points of the language.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zWwsShL95qX3t19yxKMrkQ.jpeg" /></figure><p>Go, often called Golang, is a modern programming language that stands out for its simplicity, efficiency, and scalability. Designed by Google, Go was created to address common challenges in software development, making it an excellent choice for developers who need a powerful yet easy-to-use language. Here’s why Go is a fantastic programming language:</p><h3>1. Simplicity and Readability</h3><p>One of the most significant advantages of Go is its simplicity. Unlike many other languages that come with complex syntax and unnecessary features, Go focuses on keeping things straightforward. This simplicity makes Go easy to learn, read, and maintain, which is especially beneficial for teams and large-scale projects.</p><h3>2. Fast Compilation and Execution</h3><p>Go is a compiled language, meaning it translates code directly into machine code, resulting in fast execution. The Go compiler is incredibly efficient, enabling rapid compilation times that significantly boost development speed. This makes Go an excellent choice for performance-critical applications.</p><h3>3. Built-in Concurrency Support</h3><p>Concurrency is a first-class citizen in Go. With goroutines and channels, Go makes it easier than ever to write concurrent programs. Goroutines are lightweight threads managed by the Go runtime, allowing developers to efficiently handle multiple tasks at once without the complexity of traditional threading models.</p><h3>4. Strong Standard Library</h3><p>Go comes with a powerful standard library that covers a wide range of functionalities, including networking, file handling, and cryptography. The standard library is well-designed, reducing the need for third-party dependencies and ensuring consistency across projects.</p><h3>5. Garbage Collection for Memory Management</h3><p>Go’s garbage collector ensures that developers don’t have to manually manage memory, reducing the risk of memory leaks and improving application stability. The garbage collection mechanism is optimized for performance, making Go an excellent choice for applications that require efficient memory management.</p><h3>6. Static Typing with Simplicity</h3><p>Go is statically typed, which helps catch errors early in the development process. However, it avoids the verbosity of other statically typed languages, striking a balance between type safety and ease of use.</p><h3>7. Excellent Tooling and Ecosystem</h3><p>Go provides built-in tools for formatting, testing, and performance analysis. Features like go fmt, go test, and go vet streamline the development workflow, ensuring high code quality with minimal effort. The Go ecosystem also includes robust package management with go mod and a thriving community that continuously contributes to its growth.</p><h3>8. Cross-Platform Compilation</h3><p>Go’s ability to compile applications for different platforms (Windows, Linux, macOS) with a simple command makes it an attractive choice for developers building cross-platform applications. This feature eliminates the need for complex build processes and ensures seamless deployment across various environments.</p><h3>9. Cloud and Microservices-Friendly</h3><p>Go is widely used in cloud computing and microservices architectures due to its efficiency and scalability. Many modern cloud-native platforms, including Kubernetes and Docker, are written in Go, showcasing its suitability for building scalable and high-performance services.</p><h3>10. Backed by Google and a Strong Community</h3><p>Go is backed by Google, ensuring ongoing support and continuous improvement. Additionally, the Go community is active and supportive, providing a wealth of resources, open-source projects, and forums where developers can collaborate and learn from one another.</p><h3>Conclusion</h3><p>Go is a powerful and pragmatic programming language that excels in simplicity, performance, and scalability. Whether you’re building high-performance web services, cloud-native applications, or system-level utilities, Go provides the right balance of efficiency and ease of use. Its growing adoption in the tech industry is a testament to its strengths, making it a top choice for modern software development.</p><p>If you want to know more details about go features, see the repository and click on the star: <a href="https://github.com/leogregianin/go-is-good">https://github.com/leogregianin/go-is-good</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f485c111ba76" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kubernetes: o que é, quando e como aplicá-lo]]></title>
            <link>https://medium.com/@leogregianin/kubernetes-o-que-%C3%A9-quando-e-como-aplic%C3%A1-lo-38cc39d9629d?source=rss-d11676685b9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/38cc39d9629d</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[django-rest-framework]]></category>
            <category><![CDATA[django]]></category>
            <category><![CDATA[docker]]></category>
            <dc:creator><![CDATA[Leonardo Gregianin]]></dc:creator>
            <pubDate>Fri, 05 Jan 2024 01:57:23 GMT</pubDate>
            <atom:updated>2024-01-05T01:57:23.431Z</atom:updated>
            <content:encoded><![CDATA[<h3>O que é Kubernetes?</h3><p>Kubernetes é uma plataforma de orquestração de contêineres de código aberto. Ele automatiza o deploy, a escalabilidade e o gerenciamento de aplicativos em contêineres.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iaHH3yB7nEiQgBRRvGB8Ag.png" /></figure><h3>Qual a sua origem?</h3><p>O Kubernetes iniciou como um sistema interno de orquestração de contêineres no Google, chamado Borg, que gerenciava a implantação de milhares de aplicativos no Google. Em 2014, o Google abriu o código-fonte de uma versão do Borg e o denominou como Kubernetes, que em grego (<em>κυβερνήτης</em>) significa “timoneiro” ou “piloto” e agora é mantido pela Cloud Native Computing Foundation.</p><h3>Porque alguns o chamam de K8S?</h3><p>Esta é uma maneira um tanto nerd de abreviar palavras longas. O número 8 em K8S refere-se às oito letras entre a primeira letra K e a última letra S na palavra Kubernetes. Outros exemplos são I18N para internacionalização e L10N para localização.</p><h3>Quais as principais peças de um cluster K8S?</h3><p>Um cluster Kubernetes é um conjunto de máquinas chamadas “nós” que são usadas para executar aplicativos em contêineres. Existem duas peças principais em um cluster Kubernetes, vejamos:</p><ul><li>O primeiro é o <strong>plano de controle</strong> ou <strong>control plane</strong> que é responsável por gerenciar o estado do cluster. Em ambientes de produção, o control plane geralmente é executado em vários nós que abrangem diversas zonas do data center. Em ambientes on-premisse você mesmo deve ter o controle sobre ele, em ambientes cloud providers como AWS, Google Cloud ou Azure, a própria cloud gerencia o control plane.</li><li>O segundo é um conjunto de <strong>nós de trabalho</strong> ou <strong>worker</strong>. Esses nós executam as cargas de trabalho de aplicativos em contêineres. Os aplicativos em contêineres são executados em um “pod”. Os pods são as menores unidades de um cluster Kubernetes. Um pod hospeda um ou mais contêineres e fornece armazenamento compartilhado e rede para esses contêineres. Os pods são criados e gerenciados pelo control plane do Kubernetes. Eles são os blocos de construção básicos dos aplicativos Kubernetes.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/531/1*DXhDBzk8RCBLGgOvm5s7Sg.png" /></figure><h3>Control Plane</h3><p>Plano de Controle consiste em vários componentes principais. Eles são o Servidor API (<strong>API Server</strong>), o <strong>etcd</strong>, o agendador (<strong>Scheduler</strong>) e o gerenciador de controle (<strong>Controller Manager</strong>). O API Server é a principal interface de comunicação entre Control Plane e o restante do Cluster.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/845/1*hUyKaqp_54Gu2ie6rGjKkw.png" /></figure><p>O Control Plane expõe uma <strong>API</strong> RESTful que permite aos clientes interagir com o Control Plane e enviar solicitações para gerenciar o cluster.</p><p><strong>etcd</strong> é um armazenamento de chave-valor distribuído, ou seja, é o estado persistente do cluster. É utilizado pela API Server e outros componentes do Control Plane para armazenar e recuperar informações sobre o cluster.</p><p>O <strong>Scheduler</strong> é responsável por agendar pods nos nós dos workers do cluster. Ele usa informações sobre os recursos exigidos pelos pods e os recursos disponíveis nos nós do worker para tomar decisões.</p><p>O <strong>Controller Manager</strong> é responsável por executar controladores que gerenciam o estado do cluster, por exemplo, o controlador de réplicas, que garante que o número desejado de réplicas de um pod esteja em execução, e um controlador de deploy, que gerencia as atualizações contínuas e reversões de deploys.</p><h3>Worker</h3><p>Os principais componentes do Kubernetes executados nos worker nodes incluem <strong>kubelet</strong>, <strong>container runtime</strong> e o <strong>kubeproxy</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/346/1*SSLvSQfv_8kR0kn3E-6Ktg.png" /></figure><p>O <strong>kubelet</strong> é um daemon executado em cada worker node e é responsável pela comunicação com o Control Plane recebendo instruções de quais pods serão executados no nó e garante que o estado desejado dos pods seja mantido.</p><p>O <strong>Container runtime</strong> executa os contêineres nos worker nodes e é responsável por extrair as imagens dos contêineres de um registro, iniciar, parar e gerenciar os recursos dos contêineres.</p><p>O <strong>kubeproxy</strong> é um proxy de rede executado em cada wroker node e é responsável por rotear o tráfego para os pods corretos, realiza balanceamento de carga para os pods e garante que o tráfego seja distribuído uniformemente entre os pods.</p><h3>Vantagens</h3><p>Kubernetes é escalonável e altamente disponível, fornece recursos como autocorreção, reversões automáticas e dimensionamento horizontal. Isso torna mais fácil aumentar ou diminuir nosso aplicativo conforme necessário, permitindo-nos responder rapidamente às mudanças na demanda.</p><p>Kubernetes é portátil, nos ajuda a implantar e gerir aplicações de forma consistente e confiável, independentemente da infraestrutura. Ele é executado on-premise, em cloud ou em ambiente híbrido. Fornece uma maneira uniforme de empacotar, implantar e gerenciar aplicativos.</p><h3>Desvantagens</h3><p>A desvantagem número um é a complexidade. O Kubernetes é complexo de configurar e operar. O custo inicial é alto para formar uma equipe com conhecimento em orquestração de contêineres. Requer um alto nível de conhecimento e recursos para configurar e gerenciar um ambiente de produção do Kubernetes.</p><p>A segunda desvantagem é o custo. O Kubernetes requer um certo nível mínimo de recursos para funcionar, a fim de oferecer suporte a todos os recursos mencionados acima. Provavelmente é um exagero para aplicações menores.</p><h3>Opção razoável</h3><p>Uma opção popular que atinge um equilíbrio razoável é transferir o gerenciamento do control plane para um serviço gerenciado do Kubernetes em um cloud provider como Amazon EKS, GKE no Google Cloud e AKS no Azure. Esses serviços permitem que as organizações executem aplicativos Kubernetes sem se preocupar com a infraestrutura.</p><p>Eles cuidam de tarefas que exigem conhecimento profundo, como instalar e configurar o control plane, dimensionar o cluster e fornecer manutenção e suporte contínuos. Esta é uma opção razoável para uma organização de médio porte testar o Kubernetes.</p><h3>Exemplo em código</h3><p>Como exemplo, fizemos uma aplicação real chamada <strong>URL shorter</strong>, ou, <strong>Encurtador de URL</strong> que recebe uma URL e retorna um hash da URL original tornando uma URL curta, que ao ser acessada redireciona para a URL original e grava a quantidade de acessos a URL curta e a URL original.</p><p>Por exemplo, a URL de um dos meus artigos no Medium é essa: <a href="https://dev.to/leogregianin/python-e-facil-go-e-simples-simples-e-diferente-de-facil-5b9o%60"><em>https://dev.to/leogregianin/python-e-facil-go-e-simples-simples-e-diferente-de-facil-5b9o</em></a> e poderia ficar somente <a href="https://encurtador_de_url.com/abc123%60"><em>https://encurtador_de_url.com/abc123</em></a>.</p><p>O objetivo é mostrar como é possível criar uma aplicação utilizando as melhores práticas de desenvolvimento e deploy, utilizando as tecnologias <strong>Django</strong> para backend e frontend, <strong>Django Rest Framework</strong> para API, <strong>Postgres</strong> como banco de dados e <strong>Docker</strong> e <strong>Kubernetes</strong> para containerização e orquestração do deploy.</p><p>URL shorter é uma aplicação pequena e é utilizada para fins didáticos de como construir uma aplicação e escalar ela utilizando Kubernetes.</p><p>Um único pod:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KoePOATktqIXhryX911w2Q.png" /></figure><p>Escalando para 12 réplicas:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ibqBPaiafJBth2Ze8VHGLg.png" /></figure><p>App rodando:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/495/1*HONz_8PS5OoNPMWHEbdZTg.png" /></figure><p>O código da aplicação e os arquivos de configuração do Docker e Kubernetes estão em: <a href="https://github.com/leogregianin/kubernetes-workshop">https://github.com/leogregianin/kubernetes-workshop</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=38cc39d9629d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Python é fácil. Go é simples. Simples é diferente de fácil]]></title>
            <link>https://medium.com/@leogregianin/python-%C3%A9-f%C3%A1cil-go-%C3%A9-simples-simples-%C3%A9-diferente-de-f%C3%A1cil-c1777ff1ab7d?source=rss-d11676685b9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/c1777ff1ab7d</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[go]]></category>
            <category><![CDATA[django]]></category>
            <category><![CDATA[programming-languages]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Leonardo Gregianin]]></dc:creator>
            <pubDate>Mon, 11 Dec 2023 21:10:24 GMT</pubDate>
            <atom:updated>2023-12-11T21:10:24.864Z</atom:updated>
            <content:encoded><![CDATA[<p>Python e Go possuem qualidades distintas que podem se complementar.</p><blockquote><strong>Tradução livre do artigo “Python is Easy. Go is Simple. Simple != Easy” escrito por Preslav Rachev no seu blog. O artigo original pode ser lido em: </strong><a href="https://preslav.me/2023/11/27/python-is-easy-golang-is-simple-simple-is-not-easy/"><strong>https://preslav.me/2023/11/27/python-is-easy-golang-is-simple-simple-is-not-easy/</strong></a></blockquote><p>Existe um equívoco comum de que simples e fácil se referem à mesma coisa. Afinal, se algo é fácil de usar, seu funcionamento interno deve ser simples de entender, certo? Ou vice-versa? Na verdade, é exatamente o oposto. Embora os dois conceitos apontem para o mesmo resultado, fazer algo parecer fácil requer uma enorme complexidade.</p><p>Tomemos como exemplo o Python, uma linguagem conhecida por sua baixa barreira de entrada e, portanto, uma escolha favorita para linguagem de programação de entrada. Escolas, universidades, centros de pesquisa e um grande número de empresas em todo o mundo escolheram Python precisamente por causa de sua acessibilidade a qualquer pessoa, independentemente do seu nível de educação ou formação acadêmica (ou total falta dela). Raramente é necessária muita teoria de tipos ou compreensão de como e onde as coisas são armazenadas na memória, em quais threads algum trecho de código está sendo executado, etc. Além disso, Python é a porta de entrada para algumas das mais profundas bibliotecas científicas e de nível de sistema. Ser capaz de controlar essa quantidade de poder com uma única linha de código fala muito a favor de que ela se torne uma das linguagens de programação mais populares do planeta.</p><p>E aí vem o problema: a facilidade de expressar coisas em código Python tem um custo. Por baixo dos panos, o interpretador Python é enorme e muitas operações devem ocorrer para que até mesmo uma única linha de código seja executada. Quando você ouve alguém se referindo ao Python como uma linguagem “lenta”, grande parte da “lentidão” percebida vem do número de decisões que o interpretador toma em tempo de execução. Mas esse nem é o maior problema, na minha opinião. A complexidade do ecossistema de tempo de execução do Python, juntamente com algumas decisões liberais de design em torno do gerenciamento de pacotes, cria um ambiente muito frágil, e as atualizações geralmente levam a incompatibilidades e travamentos de tempo de execução. Não é incomum deixar um aplicativo Python para voltar a ele depois de alguns meses, apenas para perceber que o ambiente mudou o suficiente para que não seja mais possível nem mesmo iniciar o aplicativo.</p><p>Claro, isso é uma simplificação grosseira, e até as crianças de hoje em dia sabem que existem contêineres para resolver problemas como esse. Na verdade, graças ao Docker e similares, é possível “congelar” as dependências de uma base de código Python no tempo para que ela possa praticamente rodar para sempre. No entanto, isso tem o custo de transferir a responsabilidade e a complexidade para a infraestrutura do sistema operacional. Não é o fim do mundo, mas também não é algo que deva ser subestimado e ignorado.</p><h3><strong>Da facilidade à simplicidade</strong></h3><p>Se resolvêssemos os problemas com Python, acabaríamos com algo como Rust — extremamente performático, mas com uma barreira de entrada notoriamente alta. A ferrugem, na minha opinião, não é fácil de usar e, o que é mais importante, não é simples. Embora esteja em alta hoje em dia, apesar de 20 anos de programação e de ter dado meus primeiros passos em C e C++, não posso olhar para um pedaço de código Rust e dizer com certeza que entendo o que está acontecendo lá.</p><p>Descobri Go há cerca de cinco anos, enquanto trabalhava em um sistema baseado em Python. Embora tenha levado algumas tentativas para gostar da sintaxe, imediatamente caí na ideia de simplicidade. O objetivo do Go é ser simples de entender por qualquer pessoa em uma organização — desde o desenvolvedor júnior recém-saído da escola até o gerente de engenharia de nível sênior que apenas ocasionalmente olha o código. Além do mais, sendo uma linguagem simples, Go raramente recebe atualizações de sintaxe — a última significativa foi a adição de genéricos na v1.18, o que ocorre somente após uma década de discussões sérias. Na maior parte, quer você observe o código Go escrito há cinco dias ou cinco anos, ele é basicamente o mesmo e deve funcionar.</p><p>A simplicidade requer disciplina. Pode parecer limitante e até um tanto retrógrado no início. Especialmente quando comparado a uma expressão sucinta, como uma lista ou compreensão de dicionário em Python:</p><pre>temperatures = [<br>    {&quot;city&quot;: &quot;City1&quot;, &quot;temp&quot;: 19},<br>    {&quot;city&quot;: &quot;City2&quot;, &quot;temp&quot;: 22},<br>    {&quot;city&quot;: &quot;City3&quot;, &quot;temp&quot;: 21},<br>]<br><br>filtered_temps = {<br>    entry[&quot;city&quot;]: entry[&quot;temp&quot;] for entry in temperatures if entry[&quot;temp&quot;] &gt; 20<br>}</pre><p>O mesmo código em Go requer mais código, mas idealmente deve ser uma ideia mais próxima do que o interpretador Python está fazendo por baixo dos panos:</p><pre>type CityTemperature struct {<br>    City string<br>    Temp float64<br>}<br><br>// ...<br><br>temperatures := []CityTemperature{<br>    {&quot;City1&quot;, 19},<br>    {&quot;City2&quot;, 22},<br>    {&quot;City3&quot;, 21},<br>}<br><br>filteredTemps := make(map[string]float64)<br>for _, ct := range temperatures {<br>    if ct.Temp &gt; 20 {<br>        filteredTemps[ct.City] = ct.Temp<br>    }<br>}</pre><p>Embora você possa escrever código equivalente em Python, uma regra não escrita em programação diz que se a linguagem fornecer uma opção mais fácil (mais concisa, mais elegante), os programadores irão gravitar em torno dela. Mas fácil é subjetivo e simples deve ser igualmente aplicável a todos. A disponibilidade de alternativas para executar a mesma ação leva a diferentes estilos de programação, e muitas vezes é possível encontrar vários estilos na mesma base de código.</p><p>Como Go é prolixo e “chato”, ele naturalmente marca outra caixa — o compilador Go tem muito menos trabalho a fazer ao compilar um executável. Compilar e executar um aplicativo Go costuma ser tão rápido, ou até mais rápido, do que carregar o interpretador Python ou a máquina virtual Java antes mesmo de executar o aplicativo real. Não é de surpreender que ser um executável nativo seja tão rápido quanto um executável pode ser. Não é tão rápido quanto seus equivalentes em C/C++ ou Rust, mas com uma fração da complexidade do código. Estou disposto a negligenciar esta pequena “desvantagem” do Go. Por último, mas não menos importante, os binários Go são vinculados estaticamente, o que significa que você pode construir um em qualquer lugar e executá-lo no host de destino — sem quaisquer tempos de execução ou dependências de biblioteca. Por uma questão de conveniência, ainda agrupamos nossos aplicativos Go em contêineres Docker. Ainda assim, eles são significativamente menores e têm uma fração do consumo de memória e CPU de seus equivalentes Python ou Java.</p><h3><strong>Como usamos Python e Go a nosso favor</strong></h3><p>A solução mais pragmática que encontramos em nosso trabalho é combinar os poderes da facilidade do Python e da simplicidade do Go. Para nós, Python é um ótimo playground de prototipagem. É onde nascem as ideias e onde as hipóteses científicas são aceitas e rejeitadas. Python é uma escolha natural para ciência de dados e aprendizado de máquina e, como lidamos com muitas dessas coisas, não faz sentido tentar reinventar a roda com outra coisa. Python também tem o Django, que atende ao seu lema de permitir o desenvolvimento rápido de aplicativos como poucas outras ferramentas (é claro, Ruby on Rails e Elixir’s Phoenix merecem uma menção digna de nota aqui).</p><p>Suponha que um projeto precise de um mínimo de gerenciamento de usuários e administração interna de dados (como a maioria dos nossos projetos). Nesse caso, começaríamos com um esqueleto do Django por causa do seu Admin integrado, o que é fantástico. Uma vez que a prova de conceito com Django começa a se assemelhar a um produto, identificamos o quanto dele pode ser reescrito em Go. Como o aplicativo Django já definiu a estrutura do banco de dados e a aparência dos modelos de dados, escrever o código Go que o complementa é bastante fácil. Depois de algumas iterações, chegamos a uma simbiose, onde os dois lados coexistem pacificamente no mesmo banco de dados e usam mensagens básicas para se comunicarem. Eventualmente, o “shell” do Django se torna um orquestrador — ele serve aos nossos propósitos de administração e aciona tarefas que são então gerenciadas pela sua contraparte Go. A parte Go atende a todo o resto, desde APIs e endpoints até a lógica de negócios e processamento de trabalhos em background.</p><p>É uma simbiose que tem funcionado bem até agora e espero que continue assim no futuro. Em um post futuro, descreverei mais alguns detalhes sobre a arquitetura em si.</p><p>Obrigado por ler!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c1777ff1ab7d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Gerenciamento de ambientes e pacotes no Python]]></title>
            <link>https://medium.com/@leogregianin/gerenciamento-de-ambientes-e-pacotes-no-python-9a7afb6572ab?source=rss-d11676685b9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/9a7afb6572ab</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[python-packages]]></category>
            <category><![CDATA[python-path]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[python-3-tutorial]]></category>
            <dc:creator><![CDATA[Leonardo Gregianin]]></dc:creator>
            <pubDate>Wed, 29 Dec 2021 02:58:31 GMT</pubDate>
            <atom:updated>2021-12-29T02:58:31.590Z</atom:updated>
            <content:encoded><![CDATA[<p>Diferente de outras linguagens de programação como Go (<a href="https://golang.github.io/dep/docs/introduction.html"><em>mod</em></a>), Rust (<em>Cargo</em>), Elixir (<em>Hex</em>), Ruby (<em>Bundler</em>), PHP (<em>Composer</em>), Clojure (<em>Lein</em>), Nodejs (<em>Npm</em>) e outras tantas que tem seus sistemas de gerenciamento de pacotes e dependências “padronizados” ou nativos na linguagem, Python não tem um único “padrão”, longe disso: distutils, setuptools, easy_install, PyPI, twine, wheel, pip, requiments.txt, virtualenv, pipx, pipenv, Pipfile, pip-tools, flit, pdm, poetry, conda são algumas das ferramentas (<a href="https://packaging.python.org/en/latest/key_projects/">e tem mais</a>) que temos no ecossistema de gerenciamento de ambientes e pacotes no Python.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/506/1*3AddCGzLD_Ku16oV8Yg2QA.png" /></figure><h3>Como funciona o sistema de módulos</h3><p>O módulo nativo <a href="https://docs.python.org/3/library/sys.html">sys</a> fornece acesso a variáveis e funções ​​que interagem com o interpretador. O sys.path é uma variável dentro do módulo sysque contém uma lista de diretórios que o interpretador irá buscar quando algum módulo por requerido nos imports.</p><p>Exemplo do que temos dentro do sys.path:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/81e736f349e37c64033e50da17cda5b7/href">https://medium.com/media/81e736f349e37c64033e50da17cda5b7/href</a></iframe><p>Vou demonstrar dentro do projeto <a href="https://github.com/encode/httpx/">httpx</a> para explicar o que cada índice da lista representa:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/619/1*bNMO_rr7JTOW1C0sO6SFPw.png" /></figure><p>O que está demonstrado à direita da tela é o arquivo _main.pye ao lado esquerdo está a árvore de diretórios do projeto.</p><p>Portanto, _main.py faz diversos imports, de arquivos locais, de pasta diferentes dentro do projeto, de módulos nativos do Python como functools, json e sys e de outros projetos como click, httpcore e pygments.</p><p><strong>(Index 0)</strong> O primeiro índice é uma string em branco (‘ ’) e quer dizer que o Python irá buscar o arquivo do import no mesmo diretório que está sendo executado.</p><p>No exemplo _main.py está importando a classe Client do arquivo _client.py que está no mesmo diretório, por isso, utiliza-se o ponto (.), se estivesse em outra pasta, o importe seria: from other._client import Client<em>.</em></p><p><strong>(Index 1)</strong> O segundo índice do sys.path busca na biblioteca padrão (Stardard Library) de instalação, ou seja, irá buscar os módulos e funções nativas.</p><p>No mesmo exemplo, irá encontrar functools, json, sys e typing nesse diretório porque são funções nativas da linguagem.</p><p><strong>(Index 2)</strong> O terceiro índice buscará na pasta do usuário, cada usuário tem o seu system path e é nele onde o usuário instala os programas para não causar conflitos com programas instalados por outros usuários do sistema operacional.</p><p>E por fim, se não encontrar o módulo nos diretórios anteriores, buscará no <strong>(Index 3) </strong>diretório de bibliotecas do sistema, onde, geralmente, se encontra a maioria dos programas feitos em Python que o sistema operacional utiliza.</p><p>Caso não encontre nesses diretórios de exemplo, o Python mostrará uma exceção dizendo que não encontrou o módulo.</p><p>É possível adicionar outros diretórios no sys.path, é possível controlar os diretórios com variáveis de ambiente ou exportar o PYTHONPATH. Modifique, somente se souber exatamente o que está fazendo!</p><h3>O que precisamos</h3><p>Precisamos que uma única solução, simples, rápida e eficiente, que faça:</p><ul><li>Faça o download de um projeto no PyPI.</li><li>Instale o projeto e todas as suas dependências, sem que ocorra problemas de conflitos de versões das dependências.</li><li>Tenha a verificação de hashes de cada pacote.</li><li>Tenha um arquivo de configuração padronizado.</li><li>Fazer build e upload de um pacote para o PyPI.</li><li>Seja multiplataforma.</li><li>Seja sustentável financeiramente. Sugestão: Financiada pela <a href="https://www.python.org/psf/">Python Software Foundation</a> (PSF) (veja os patrocinadores da PSF <a href="https://www.python.org/psf/sponsors/">aqui</a>).</li></ul><h3>Evolução de 1991 a 2021</h3><p>A linguagem tem seu primeiro release lançado oficialmente em <strong>1991</strong>, e a primeira versão de uma ferramenta para distribuição de pacotes foi a <a href="https://github.com/pypa/distutils">distutils</a><em>, </em>lançada em setembro de <strong>2000 </strong>na <a href="https://www.python.org/download/releases/1.6/">versão 1.6</a>. O Distutils permite que você estruture seu projeto para que tenha um setup.pye, com isso, facilita a instalação e distribuição do projeto.</p><p>Nesse meio tempo, se quisesse instalar o código de outra pessoa, teria que baixar, instalar e adicioná-lo ao PYTHONPATH manualmente. Em <strong>2003 </strong>foi criado, o então cheeseshop e agora, <a href="https://pypi.org/">PyPI</a> (Python Package Index), que é um catálogo/repositório online de programas para qualquer pessoa baixar e instalar.</p><p>Com um repositório centralizado e milhares de projetos, muitos projetos começaram a ter mais e mais dependências e gerenciá-los era um novo desafio por haver a possibilidade de incompatibilidades e conflitos de versões.</p><p>Em <strong>2004 </strong>e nos anos seguintes, a comunidade começou a desenvolver um conjunto de ferramentas para extender o distutils para gerenciamento de dependências complexas, reconhecimento automatizado de precedência de versão e uma ferramenta de instalação automática chamada easy_install. Embora nunca tenha chegado à biblioteca padrão, <a href="https://github.com/pypa/setuptools">setuptools</a>tornou-se o meio principal para criar e distribuir pacotes.</p><p>Mesmo com todas as ferramentas úteis feitas com o setuptools e easy_install, o problemas de compartilhamento de pacotes e o conflitos de versões ainda ocorriam. Em <strong>2006 </strong>começou a ser discutido a possibilidade de construção de ambientes virtuais e em <strong>2007 </strong>foi lançado o <a href="https://github.com/pypa/virtualenv">virtualenv</a> que permitia construir ambientes isolados (ou virtuais) de um projeto a partir de uma instalação de sistema central de Python, com isso, o easy_install instala as dependências do projeto somente naquele ambiente isolado.</p><p>Em <strong>2008</strong>, o mesmo criador do virtualenv, em alternativa e correções ao easy_install, cria o <a href="https://github.com/pypa/pip">pip</a> para fácil instalação de pacotes e dependências. O pip utiliza o arquivo requirements.txt para gerenciar as dependências do pacotes.</p><p>Em <strong>2011</strong>, A Python Software Foundation cria um grupo de trabalho chamado <a href="https://www.pypa.io/en/latest/">Python Packaging Authority</a> (PyPA) responsável por padronizar o meio de distribuição de pacotes, manter o pip e o virtualenv e também, por manter a infraestrutura do PyPI. A linha do tempo da história do PyPA encontra-se <a href="https://www.pypa.io/en/latest/history/">aqui</a>.</p><p>Em <strong>2012</strong>, a empresa <a href="https://www.anaconda.com/">Anaconda Inc.</a> cria o gerenciador de pacote chamado Conda, voltado para a comunidade científica de desenvolvimento, criando uma infraestrutura totalmente separada do pip, virtualenv e PyPI.</p><p>Também em 2012, foi criado o <a href="https://github.com/jazzband/pip-tools/">pip-tools</a> que é um conjunto de ferramentas para gerenciar e manter compilações determinísticas especificando as dependências por meio de hash ( <em>— require-hashes que o pip implementou em 2016</em>).</p><p>Em <strong>2013</strong>, com a <a href="https://www.python.org/dev/peps/pep-0427/">PEP 427</a>, define-se que o formato binário padrão para distribuição dos pacotes é o formato <a href="https://github.com/pypa/wheel">wheel</a> e é criado o <a href="https://github.com/pypa/twine">twine</a> para interagir e realizar upload seguros de pacotes para o PyPI.</p><p>Em <strong>2014</strong>, a <a href="https://www.python.org/dev/peps/pep-0440/">PEP 440</a> descreve como identificar versões de pacotes com um novo schema de versionamento.</p><p>Em <strong>2015</strong>, é aprovadas a <a href="https://www.python.org/dev/peps/pep-0503/">PEP 503</a> e <a href="https://www.python.org/dev/peps/pep-0508/">PEP 508</a> que descrevem padrões para pacotes e para distribuição no PyPI.</p><p>Ainda em 2015, começa o desenvolvimento do <a href="https://github.com/pypa/flit">flit</a>, que pretendia ser o substituto de todo o ecossistema.</p><p>Em <strong>2016</strong> a <a href="https://www.python.org/dev/peps/pep-0518/">PEP 518</a> especifica um novo arquivo de configuração de pacotes chamado pyproject.toml que centraliza e padroniza todos os arquivos de configuração em um só.</p><p>Ainda em 2016, o pip lança uma nova versão com a implementação do hashes<em> </em>para cada dependência dentro do requirements.txt.</p><p>Em <strong>2017</strong> a <a href="https://www.python.org/dev/peps/pep-0517/">PEP 517</a> aprova builds independentes<em>. </em>Devido problemas antigos do distutils, e a tentativa de se fazer um <a href="https://pypi.org/project/Distutils2/">distutils2</a>, abrindo a possibilidade de não necessariamente utilizar distutils, ou seja, se você quiser usar distutils, ótimo; se você quiser usar outra coisa, isso deve ser fácil de fazer usando métodos padronizados.</p><p>Ainda em 2017 é lançado o <a href="https://github.com/pypa/pipx">pipx</a>, ferramenta para instalar e rodar programas sem causar conflitos de dependências com outros pacotes instalados no sistema.</p><blockquote><strong><em>Estamos em 2017, ou seja, 26 anos desde a criação da linguagem e ainda não temos uma solução única e completa para gerenciar e distribuir pacotes.</em></strong></blockquote><p>De acordo com a <a href="https://xkcd.com/1987/">sátira do xkcd</a>, como está nosso ambiente:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/492/1*mHrDuetdLskvNHYucD9u3g.png" /><figcaption>source: <a href="https://xkcd.com/1987/">xkcd</a></figcaption></figure><p><a href="https://github.com/pypa/pipenv">Pipenv</a> nasce ainda em <strong>2017</strong> como um projeto que visa agregar o pip, virtualenv e o Pipfile em um único conjunto de ferramentas para gerenciar ambientes, dependências e pacotes, cria e verifica hashes de arquivo para garantir a conformidade com dependências com os arquivos Pipfile e Pipfile.lock.</p><p>Em <strong>2018</strong> nasce o <a href="https://github.com/python-poetry/poetry">Poetry</a> com a proposta de substituir todas as ferramentas já existentes de empacotamento e distribuição existentes <em>(mesmo que, por debaixo dos panos, utiliza o </em><a href="https://github.com/python-poetry/poetry/blob/master/src/poetry/utils/pip.py"><em>pip</em></a><em> e o </em><a href="https://github.com/python-poetry/poetry/blob/master/src/poetry/utils/env.py"><em>virtualenv</em></a><em> para instalar e criar ambientes isolados), </em>ou seja, supre a necessidade do distutils, setuptools, virtualenv, pip, faz builds determinísticos igual o pip-tools e pip faz, segue o padrão da PEP 440 sobre semântica de versões, segue os padrão do PyPI da <a href="https://www.python.org/dev/peps/pep-0503/">PEP 503</a> e <a href="https://www.python.org/dev/peps/pep-0508/">PEP 508</a>, utiliza o padrão do pyproject.toml da PEP 518 e cria builds independentes da PEP 517.</p><blockquote>Portanto, o <strong>Poetry</strong> (em 2021), é o único projeto que abrange todos as ferramentas do ecossistema e segue todos os padrões definidos nas PEPs.</blockquote><p>Em <strong>2020</strong>, é lançada uma <a href="https://pip.pypa.io/en/latest/user_guide/#changes-to-the-pip-dependency-resolver-in-20-3-2020">nova versão do pip</a>, com um novo resolvedor de dependências.</p><p>Ainda em 2020, é criado o projeto <a href="https://github.com/pdm-project/pdm">pdm</a>, que atende a <a href="https://www.python.org/dev/peps/pep-0582/">PEP 582</a>, ou seja, não há de se criar ambientes virtuais, cria-se um diretório local de pacotes python para cada projeto chamado __pypackages__ para incluir todos lá dentro. Seguindo a mesma ideia do node_modules do Nodejs.</p><p>Em <strong>2021</strong>, ainda não temos uma ferramenta oficial, única e completa para todo o ecossistema (o poetry está perto disso) e que atenda todos os requisitos que escrevi no tópico logo acima chamado “O que precisamos”.</p><h3>Conclusão</h3><p>A <a href="https://github.com/pypa">organização PyPA no Github</a> mantém a maioria dos projetos de empacotamento e distribuição, na minha humilde opinião, são vários projetos muito parecidos e para um mesmo objetivo final que são propostos, não vale tal esforço humano e financeiro. Poderíamos aprender com as linguagens citadas na introdução.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9a7afb6572ab" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agregador de APIs de CEPs do Brasil com Golang]]></title>
            <link>https://medium.com/@leogregianin/agregador-de-apis-de-ceps-do-brasil-com-golang-2308a71eafcc?source=rss-d11676685b9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/2308a71eafcc</guid>
            <category><![CDATA[cep]]></category>
            <category><![CDATA[api-development]]></category>
            <category><![CDATA[golang]]></category>
            <category><![CDATA[go]]></category>
            <category><![CDATA[api]]></category>
            <dc:creator><![CDATA[Leonardo Gregianin]]></dc:creator>
            <pubDate>Wed, 22 Dec 2021 22:50:17 GMT</pubDate>
            <atom:updated>2021-12-22T22:50:17.628Z</atom:updated>
            <content:encoded><![CDATA[<p>“Código de Endereçamento Postal” mais conhecido como “CEP” é uma padronização de códigos para divisão do país em regiões postais que visa facilitar a identificação de cada localidade.</p><p>Os Correios são o órgão responsável por controlar os CEPs no Brasil e quem deveria, e não o faz, de prover a solução única, eficiente, rápida e de graça (já que são dados públicos) de ser consumida por sistemas e sites.</p><p>Por isso, existem diversas APIs que tentam suprir essa defasagem dos Correios, e com isso, surge outro problema: <strong>Qual API de CEP devo utilizar no meu sistema?</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/200/1*HJ90i_xxqvsVr8FKPfuyUg.png" /><figcaption>brcep</figcaption></figure><p>O intuito do projeto <a href="https://github.com/leogregianin/brcep"><strong>brcep</strong></a> é não depender que uma API específica esteja atualizada e online, e sim, utilizar o <strong>brcep</strong> para abstrair qualquer inconveniente de uma API e deixá-la que ela se responsabilize por consultar diversas fontes e <strong>retornar as informações do CEP de forma exata, rápida e fácil.</strong></p><p>Atualmente suporta as API dos <a href="http://viacep.com.br/">ViaCEP</a> , <a href="http://cepaberto.com/">CEPAberto</a> e <a href="https://apps.correios.com.br/">Correios</a>.</p><ul><li>Código-fonte: <a href="https://github.com/leogregianin/brcep">https://github.com/leogregianin/brcep</a></li><li>Docker image: <a href="https://hub.docker.com/r/leogregianin/brcep">https://hub.docker.com/r/leogregianin/brcep</a></li></ul><p>Sua ajuda é bem-vinda para implementar novas interfaces para outras APIs.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2308a71eafcc" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Guia da nossa engenharia de software]]></title>
            <link>https://medium.com/@leogregianin/guia-da-engenharia-c0bae6576ade?source=rss-d11676685b9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/c0bae6576ade</guid>
            <category><![CDATA[software]]></category>
            <category><![CDATA[programação]]></category>
            <category><![CDATA[culture]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Leonardo Gregianin]]></dc:creator>
            <pubDate>Wed, 22 Dec 2021 21:34:54 GMT</pubDate>
            <atom:updated>2021-12-23T12:03:04.169Z</atom:updated>
            <content:encoded><![CDATA[<p>Este é um documento vivo que se encontra no nosso <a href="https://github.com/lucrorural/guia-da-engenharia">repositório público no Github</a> e tem como base orientar nossas decisões durante o desenvolvimento da plataforma <a href="https://www.lucrorural.com.br/">Lucro Rural</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/238/1*FplcNYNzFVV_TEn8gDYS-A.png" /></figure><p>Esse guia é a espinha dorsal de nossa cultura de engenharia. Eles não são nada sofisticados, apenas um conjunto de expectativas básicas que tentamos seguir.</p><p>Esta lista ajuda a equipe a construir soluções melhores e com mais rapidez, não importa a idade ou o nível de senioridade.</p><h3>0. Datilografia != Engenharia de software</h3><p>Ir diretamente para a escrita de código, na maioria das vezes, leva a um código ruim e a uma engenharia ruim. A maioria das batalhas é vencida na mente e na caneta e no papel antes mesmo de começar.</p><p>As pessoas “datilógrafas” se concentram apenas em escrever código para fazer algo funcionar. As pessoas engenheiras de software têm uma visão muito mais ampla, concentrando-se no problema e em todos os aspectos da solução. Dividir a solução em componentes menores, tendo um panorama geral em mente e descobrir como tudo se encaixa no final.</p><p>As pessoas com a mente na engenharia do software constroem para escala e sustentabilidade, em vez de apenas criar uma solução de curto prazo.</p><h3>1. “import lib”</h3><p>A vida é curta demais para reinventar a roda.</p><p>Não perca tempo construindo suas próprias ferramentas ou bibliotecas se já houver algo que faça o mesmo trabalho. Sempre que possível, amplie as bibliotecas existentes e contribua de volta. Isso ajuda a obter uma imagem clara do que o trabalho de outras pessoas faz e como se encaixa no que estamos construindo. Também permite que outras pessoas se beneficiem de seu trabalho, assim como nós nos beneficiamos dos outros trabalhos.</p><h3>2. Com grandes poderes vêm grandes responsabilidades</h3><p>Não somente nossos clientes diretos são impactados pelo que geramos no Lucro Rural, o que fazemos trazem mudanças reais para milhões de pessoas.</p><p>Cada escolha que fazemos em nossa plataforma e cada recurso que criamos deve ser pensada com muita responsabilidade.</p><p>É importante questionar cada escolha, uma vez que afetará milhões de pessoas. Certifique-se de saber o que usar, quando usar e até mesmo por que está usando em primeiro lugar. Às vezes, os problemas mais difíceis têm as soluções mais simples.</p><h3>3. Fracasse rápido e continue aprendendo</h3><p>Temos problemas grandes para resolver e muitas maneiras possíveis de resolver cada um deles. A melhor maneira de descobrir qual solução é a melhor é agir rapidamente e testar várias soluções possíveis.</p><p>Fracassar rápido significa fazer várias iterações rápidas e aprender com cada uma, em vez de ficar preso/emperrado a uma solução ou decisão. (No entanto, não se trata de construir coisas sem conhecer suas limitações ou problemas!) Sempre que estiver preso/emperrado, converse com outras pessoas — elas podem ter uma solução alternativa mais rápida ou melhor.</p><h3>4. Conheça a sua casa</h3><p>“Conhecer sua casa” significa conheçer o problema que está resolvendo, conhecer a plataforma e conhecer os problemas reais dos produtores rurais, isto é uma parte crucial da engenharia.</p><p>Não é suficiente saber o que funcionará e quando funcionará. É tão importante saber o que não funciona e quando não funciona.</p><h3>5. “No meu computador funciona”</h3><p>Se algo está quebrando, há um problema no código. Nunca é um problema mágico ou uma ocorrência aleatória, porque não é assim que o código funciona. É uma ciência exata, lembra?</p><p>Esperamos que nossas pessoas da engenharia descubram o que causou a quebra, não limpem as mãos e passe o problema para outra pessoa. Pense no que está acontecendo por debaixo dos panos.</p><p>Essa ideia também é importante para a escolha de tecnologias ou ferramentas. Pense por que algo é melhor e o que o torna melhor. A ferramenta A pode ser boa para resolver o problema B, mas isso não significa que a transição para a ferramenta A resolverá magicamente todos os seus problemas. Geralmente há uma compensação envolvida.</p><h3>6. Meça o que for mensurável</h3><p>Medir o que construiu pode não parecer um bom uso do seu tempo, visto que poderia ser gasto na construção do próximo recurso/novidade para a plataforma. No entanto, configurar sistemas para medir um produto fornece dados reais com os quais trabalhar.</p><p>As medições também são cruciais quando se começa a construir em escala. Se não medirmos como o produto está respondendo a mais usuários ou solicitações, é fácil ocorrer problemas ocultos que o farão quebrar no futuro.</p><p>Depois de ter os dados, podemos usá-los para qualquer coisa — talvez isso nos ajude a decidir sobre o próximo recurso para seu produto ou mostre como otimizar uma determinada seção do produto. Não importa o que nós façamos com os dados, tê-los nos coloca um passo mais perto de tomar melhores decisões baseadas em dados.</p><h3>7. Automatize tudo o que for repetitivo</h3><p>Nossa tendência básica deve ser automatizar sempre que possível, em vez de fazer as tarefas manualmente.</p><p>A automação nos dá mais tempo para trabalhar na construção do produto real. Queremos que os sistemas façam nossas tarefas repetitivas e tediosas, em vez de ter humanos passando suas noites fazendo essas tarefas. No entanto, tome cuidado para não perder muito tempo com otimização!</p><h3>8. A otimização prematura é a raiz de todos os males</h3><p>A otimização é importante, mas não deve ser feita muito cedo. Escolha as batalhas certas para lutar na hora certa.</p><p>Se otimizarmos muito cedo, gastará e gastará novamente muito tempo e ainda assim não obterá a solução mais otimizada. Espere até que seu produto esteja totalmente “cozido” e “azeitado” (expressão nossa) e otimize o que precisa ser otimizado.</p><h3>9. Em caso de dúvida, pergunte!</h3><p>Emperrado ou confuso? Pergunte! Alguém terá uma solução, ou pelo menos uma ideia para você começar no caminho certo.</p><p>Apenas lembre-se, certifique-se de fazer sua pesquisa com antecedência e escolher os próximos passos cuidadosamente. Nunca opte por uma abordagem que você ou outra pessoa certamente pensa que funcionará sem saber por que funcionará ou sem quaisquer dados ou fatos objetivos para apoiá-la.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c0bae6576ade" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Buscando taxas oficiais do Banco Central do Brasil com Python]]></title>
            <link>https://medium.com/@leogregianin/buscando-taxas-oficiais-do-banco-central-do-brasil-com-python-1c76f031f8e8?source=rss-d11676685b9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/1c76f031f8e8</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[banco-central]]></category>
            <category><![CDATA[ações]]></category>
            <category><![CDATA[taxas]]></category>
            <category><![CDATA[finance]]></category>
            <dc:creator><![CDATA[Leonardo Gregianin]]></dc:creator>
            <pubDate>Sun, 07 Jul 2019 02:53:28 GMT</pubDate>
            <atom:updated>2019-07-07T02:53:28.536Z</atom:updated>
            <content:encoded><![CDATA[<h3>— python bancocentralbrasil</h3><p>A biblioteca <a href="https://github.com/leogregianin/bancocentralbrasil">bancocentralbrasil</a> criada por mim a alguns anos faz a busca das taxas oficiais de Inflação, Selic, Poupança, Dólar, Dólar PTAX, Euro e Euro PTAX atualizadas diariamente e diretamente do site do Banco Central do Brasil.</p><h3>Instalação</h3><p>A instalação da biblioteca segue o mesmo padrão da instalação de qualquer outra biblioteca Python, usamos o <em>pip</em> (<em>Python Package Index</em>):</p><pre>pip install bancocentralbrasil</pre><p>O <em>pip</em> instalará a única dependência que a biblioteca utiliza, que é a <em>requests</em>.</p><h3>Utilização</h3><p>Para importar a biblioteca e começar a utilizá-la:</p><pre><strong>import</strong> bancocentralbrasil</pre><p>Para buscar os dados do câmbio como o valor do dólar para compra e para venda:</p><pre>from bancocentral import Cambio</pre><pre>cambio = Cambio()<br>cambio.get_dolar_compra()<br>cambio.get_dolar_venda()</pre><p>Para buscar os dados da taxa Selic atual:</p><pre>from bancocentral import Selic</pre><pre>selic = Selic()<br>selic.get_selic_real()</pre><h3>Testes de qualidade do software</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/909/1*vm3truG5OpGlSF95KwvbYw.png" /></figure><p>A biblioteca contém um alto grau de <a href="https://en.wikipedia.org/wiki/Continuous_delivery">CD</a>/<a href="https://en.wikipedia.org/wiki/Continuous_integration">CI</a> (<em>Continuous delivery</em> e <em>Continuous integration</em>), os testes unitários estão integrados ao serviço do <a href="https://travis-ci.org/">TravisCI</a> e o <a href="https://en.wikipedia.org/wiki/Code_coverage">Code Coverage</a> está integrado ao serviço do <a href="https://codecov.io/">Codecov.io</a>.</p><blockquote>100% do código-fonte com testes unitários e com 100% de cobertura. \o/</blockquote><h3>Licença de Uso</h3><p>O software foi escrito sob a <a href="https://github.com/leogregianin/bancocentralbrasil/blob/master/LICENSE">licença MIT</a>, que dá a permissão para uso comercial, livre modificação e distribuição e ao uso privado do código-fonte.</p><h3>Mais informações</h3><p>Código-fonte da biblioteca: <a href="https://github.com/leogregianin/bancocentralbrasil">https://github.com/leogregianin/bancocentralbrasil</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1c76f031f8e8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[python ffn — Funções de Finanças]]></title>
            <link>https://medium.com/@leogregianin/https-medium-com-leogregianin-python-ffn-1b4078e88388?source=rss-d11676685b9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/1b4078e88388</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[finance]]></category>
            <category><![CDATA[finanças]]></category>
            <category><![CDATA[ações]]></category>
            <dc:creator><![CDATA[Leonardo Gregianin]]></dc:creator>
            <pubDate>Sat, 06 Jul 2019 21:12:41 GMT</pubDate>
            <atom:updated>2019-07-06T21:12:41.809Z</atom:updated>
            <content:encoded><![CDATA[<h3>python ffn — Funções de Finanças</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/150/1*Ri7XXxICStQ822czOnK5lQ.png" /></figure><p>A biblioteca “<a href="http://pmorissette.github.io/ffn">ffn</a> — <em>a financial function library for Python</em>” contém muitas funções úteis para se trabalhar com finanças quantitativas, fornecendo uma vasta gama de utilidades, desde medição e avaliação de desempenho até gráficos e transformações de dados.</p><p>O dados são obtidos do <a href="https://finance.yahoo.com/">Yahoo Finance</a> que fornece todos os dados históricos de todas as Ações, Stocks, FIIs, ETFs e Reits negociados em todas as Bolsas de Valores do mundo.</p><h3>Instalação</h3><p>A instalação da biblioteca segue o mesmo padrão da instalação de qualquer outra biblioteca Python, usamos o <em>pip</em> (<em>Python Package Index</em>):</p><pre>pip install ffn</pre><p>O <em>pip</em> instalará inicialmente todas as dependências da <em>ffn </em>até que tudo esteja instalado, inclusive a <em>ffn</em>.</p><p>Outra opção muito interessante é a instalação da distribuição <a href="https://store.continuum.io/cshop/anaconda/">Anaconda</a> onde ela já disponibiliza pre-instaladas todas as bibliotecas necessárias para análise de dados em geral, bibliotecas muito utilizadas para este fim como <em>Pandas</em>, <em>Numpy</em>, <em>Scipy </em>e outras. Com o Anaconda é possível utilizar o editor <em>Jupyter </em>para programar e trabalhar com o <em>ffn.</em></p><h3>Utilização</h3><p>Para importar a biblioteca e começar a utilizá-la:</p><pre><strong>import</strong> <strong>ffn</strong></pre><p>Para buscar os dados da Apple e da Microsoft desde 2010:</p><pre>price = ffn.get(&#39;aapl,msft&#39;, start=&#39;2010-01-01&#39;)</pre><p>Vamos comparar o desempenho relativo de cada ação graficamente:</p><pre>ax = prices.rebase().plot()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/370/1*yQx3E6FcKVjA-ljz7Oq5Mw.png" /></figure><p>Vamos analisar os dados quantitativos de quatro gigantes do mundo da tecnologia: Apple, Microsoft, Amazon e Google.</p><pre>price = ffn.get(&#39;aapl,msft,amzn,goog&#39;, start=&#39;2010-01-01&#39;)</pre><p>Análise da performance de cada uma:</p><pre>stats = price.calc_stats()<br>stats.display()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/566/1*-hYLBithonB4jiQ1VrxhPg.png" /></figure><p>As estatísticas acima nos mostram que, por exemplo, a Amazon retornou ao acionista 1351% de 04-jan-2010 até 05-set-2019 \o/</p><p>Falando em ações do Brasil…</p><p>Vamos analisar de maio de 2018 a julho de 2019 como alguns bancos brasileiros performaram.</p><p>Dois dos maiores bancos de varejo do Brasil: Itaú (ITUB4) e Bradesco (BBDC4) contra dois bancos digitais em crescente ascensão Banco Inter (BIDI4) e Banco Pan (BPAN4).</p><pre>import ffn<br>price = ffn.get(‘bidi4.sa,bpan4.sa,itub4.sa,bbdc4.sa’)<br>stats = price.calc_stats()<br>stats.display()</pre><p>O total de retorno ao acionista do Banco Inter foi de 377,24%, do Banco Pan 453,31% enquanto do Itaú foi de 20,43% e do Bradesco 50,73%.</p><h3>Mais informações sobre o ffn</h3><p>A documentação da biblioteca é vasta, existem muitos outros indicadores a analisar. Para visualizar todas as funções disponíveis consulte os links abaixo.</p><p>Site oficial: <a href="http://pmorissette.github.io/ffn/index.html">http://pmorissette.github.io/ffn/index.html</a></p><p>Código-fonte da biblioteca: <a href="https://github.com/pmorissette/ffn">https://github.com/pmorissette/ffn</a></p><p><em>Quickstart</em>: <a href="http://pmorissette.github.io/ffn/quick.html">http://pmorissette.github.io/ffn/quick.html</a></p><p>Documentação da API: <a href="http://pmorissette.github.io/ffn/ffn.html">http://pmorissette.github.io/ffn/ffn.html</a></p><h3>Para ir além</h3><p>A biblioteca bt (<a href="https://github.com/pmorissette/bt">https://github.com/pmorissette/bt</a>), que também utiliza a biblioteca ffn, é um framework Python para realizar <em>backtesting </em>de estratégias de <em>trades</em>. Falaremos mais sobre ela nos próximos artigos.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1b4078e88388" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Gerando API automaticamente com Django]]></title>
            <link>https://medium.com/@leogregianin/gerando-api-automaticamente-com-django-3d534ce20f91?source=rss-d11676685b9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/3d534ce20f91</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[django]]></category>
            <category><![CDATA[api-development]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[django-rest-framework]]></category>
            <dc:creator><![CDATA[Leonardo Gregianin]]></dc:creator>
            <pubDate>Fri, 29 Mar 2019 02:12:27 GMT</pubDate>
            <atom:updated>2019-03-29T02:12:27.599Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>Gerar uma API automaticamente? Existe isso? Sim! \o/</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*066LikveppDA1_rveua0gg.jpeg" /></figure><h3>Cenário</h3><p>A empresa utiliza um único banco de dados MySQL hospedado no Cloud da <a href="https://aws.amazon.com/">AWS</a> para todos os seus clientes. A aplicação conecta diretamente no banco de dados com o driver nativo da linguagem de programação.</p><h3>Qual o problema disso?</h3><p>As regras de negócio do software estão todas definidas na aplicação, intrinsecamente conectadas ao emarranhado e macarrônico código-fonte em um gigantesco <a href="https://en.wikipedia.org/wiki/Monolithic_application">monolito</a>.</p><p>Uma aplicação engessada para ser disponibilizada para outras plataformas como web, celulares ou <a href="https://en.wikipedia.org/wiki/Internet_of_things">IoT</a>.</p><p>Neste tipo de arquitetura de software não há separação de camadas e foi sendo melhorado e substituído pelos modelos de camadas <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a>, <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel">MVVM</a> ou <a href="https://djangobook.com/mdj2-django-structure/">MTV</a> (ou MVT) com grande ajuda do mapeamento objeto-relacional <a href="https://en.wikipedia.org/wiki/Object-relational_mapping">ORM</a>.</p><p>Além desses modelos, a arquitetura de <a href="https://www.thoughtworks.com/pt/insights/blog/microservices-nutshell">microserviços</a> e a construção de <a href="https://en.wikipedia.org/wiki/Application_programming_interface">API</a>s trouxe ainda mais separação. Podendo ter equipes completamente diversas de <em>backend </em>e <em>frontend </em>no desenvolvimento do mesmo projeto.</p><h3>Qual a necessidade do cliente?</h3><p>Antes de mais nada, a empresa necessitava de uma mudança do <em>mindset </em>e uma organização do método de programação adotado na sua equipe como: <a href="https://en.wikipedia.org/wiki/Software_design_pattern">padrões de projetos</a>, <a href="https://medium.com/mindorks/how-to-write-clean-code-lessons-learnt-from-the-clean-code-robert-c-martin-9ffc7aef870c">clean code</a>, <a href="https://en.wikipedia.org/wiki/Unit_testing">testes unitários</a> e <a href="https://en.wikipedia.org/wiki/Git">versionamento do código-fonte</a>.</p><p>O projeto necessitava:</p><blockquote>1— estar disponível na web.</blockquote><blockquote>2— estar disponível para integração com aplicativos nativos para Android e iOS.</blockquote><blockquote>3 — ter uma <a href="https://en.wikipedia.org/wiki/Representational_state_transfer">API REST</a> para integrar e ser integrada com outros serviços na nuvem.</blockquote><blockquote>4 — ser escalável.</blockquote><h3>Porque Python e Django?</h3><p><a href="https://en.wikipedia.org/wiki/Python_(programming_language)">Python</a> é uma linguagem de programação interpretada, de tipagem dinâmica (<a href="http://mypy-lang.org/">ou não</a>) e de propósito geral, ou seja, pode-se trabalhar com ela de diversas formas como ciência de dados, <a href="https://en.wikipedia.org/wiki/Web_scraping">raspagem de dados na web</a>, construção de sites web, desenvolvimento de jogos, construção de APIs, aplicações <em>desktop</em>, scripts para gerenciamento de servidores e muitas outras formas.</p><p>A filosofia da linguagem é ser de fácil legibilidade, poderosa e rápida, fácil de aprender e código-fonte aberto. Importe o pacote <em>this </em>para mais detalhes:</p><pre>&gt;&gt;&gt; import this</pre><p><a href="https://www.djangoproject.com/">Django</a> se descreve como:</p><blockquote>um framework web Python de alto nível que incentiva o rápido desenvolvimento e o design limpo e pragmático. Construído por desenvolvedores experientes, ele cuida de grande parte do trabalho de desenvolvimento da web, para que você possa se concentrar em escrever seu aplicativo sem precisar reinventar a roda. É grátis e de código aberto.</blockquote><p>Mas porque Python e Django?</p><p>Como vou demonstrar na continuidade deste artigo, o Django facilita muito o trabalho na geração dos <em>models</em> a partir do banco de dados já modelado<em>, </em>gerando as classes para cada tabela, além de gerar os <em>forms</em> automaticamente para todos os campos. E para complementar a construção do projeto usamos <a href="https://www.django-rest-framework.org/">Django REST Framework</a> para a construção da API.</p><h3>Porque substituir a linguagem de programação e o framework?</h3><p>A substituição da linguagem e do framework não é de um dia para outro. Não se apaga tudo e começa escrever de novo do zero.</p><p>A estratégia da empresa precisa ser muito bem pensada a longo prazo e a decisão não pode ser com base no último framework da moda.</p><blockquote><em>Django foi escolhido com responsabilidade para o desenvolvimento das APIs, dos novos projetos e na reescrita dos projetos legados.</em></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*N5Iep1wJY1iXgMzpHxzE8w.png" /></figure><h3>Instalação do Django e dos pacotes dependentes</h3><p>Faça o download e a instalação do <a href="https://www.python.org/downloads/">Python</a> conforme sua plataforma Windows, Mac OS ou Linux/UNIX.</p><p>Utilizamos Python 3.6.8, Django 2.1.7 e Django REST Framework 3.9.0</p><p>Inicie um ambiente virtual do Python <a href="https://virtualenv.pypa.io/en/latest/">virtualenv</a> para encapsular e isolar o gerenciamento do projeto:</p><ul><li>Windows:</li></ul><pre><em>virtualenv venv -p C:\Python36\python.exe<br>.\venv\Scripts\activate</em></pre><ul><li>Mac/Linux:</li></ul><pre>virtualenv venv<br>source /path/to/venv/bin/activate</pre><p>Instale os pacotes no ambiente virtual pelo gerenciador de pacotes PyPI.</p><pre>pip3 install django djangorestframework mysqlclient</pre><p>Você pode especificar a versão do pacote que deseja instalar. Fiz isso pois foi nestas versões dos pacotes que utilizei na implementação desse projeto:</p><pre>pip3 install django==2.1.7 djangorestframework==3.9.0 mysqlclient</pre><h3>Criação do projeto</h3><p>1 — Criar um novo projeto Django:</p><pre>django-admin startproject config .<br>python .\manage.py startapp projeto</pre><p>2 — Incluir o novo app no <em>settings.py</em></p><pre>INSTALLED_APPS = [<br> ‘django.contrib.admin’,<br> ‘django.contrib.auth’,<br> ‘django.contrib.contenttypes’,<br> ‘django.contrib.sessions’,<br> ‘django.contrib.messages’,<br> ‘django.contrib.staticfiles’,<br> ‘<strong>projeto</strong>’,<br>]</pre><p>3 — Configurar o acesso ao banco de dados MySQL no <em>settings.py</em>:</p><pre>DATABASES = {<br> ‘default’: {<br> ‘ENGINE’: ‘django.db.backends.mysql’, <br> ‘NAME’: ‘database_name’,<br> ‘USER’: ‘root’,<br> ‘PASSWORD’: ‘password’,<br> ‘HOST’: ‘localhost’,<br> ‘PORT’: ‘3306’,<br> }<br>}</pre><p>4 — Executar o <em>inspectdb </em>do Django:</p><pre>python .\manage.py inspectdb &gt; models.py</pre><p>O <a href="https://docs.djangoproject.com/en/2.1/howto/legacy-databases/"><em>inspectdb</em></a><em> </em>faz a leitura dos metadados do banco de dados e cria todas as classes do <em>model</em> do Django automaticamente. Mapeia todas as tabelas, colunas, tipos de dados, <em>primary keys</em> e <em>foreign keys</em>.</p><p>Substitua o arquivo <em>models.py</em> criado pelo <em>inspectdb </em>no lugar o <em>models.py</em> vazio que está no seu projeto.</p><p>5 — Registre as classes no django-admin</p><p>Após criadas as classes no <em>models.py</em> pelo <em>inspectdb</em>, registre as classes no <em>admin.py</em> para que o admin do Django consiga visualizar e gerenciar as novas classes.</p><p>Uma opção é registrar classe a classe:</p><pre>from django.contrib import admin<br>from .models import Classe1<br>from .models import Classe2<br>...</pre><pre>admin.site.register(Classe1)<br>admin.site.register(Classe2)<br>...</pre><p>Como o assunto deste post é <em>automatizar</em>, vamos automatizar isso também =)</p><pre>from django.contrib import admin<br>from django.apps import apps</pre><pre>app = apps.get_app_config(‘projeto’)</pre><pre>for model_name, model in app.models.items():<br>    admin.site.register(model)</pre><p>6 — Crie o usuário admin:</p><pre>python .\manage.py createsuperuser</pre><p>7 —Criar as migrações dos <em>Models </em>e aplique as alterações no banco de dados:</p><pre>python .\manage.py makemigrations<br>python .\manage.py migrate</pre><h3><strong>Criar a API com django-rest-framework</strong></h3><p>O Django REST Framework (DRF) é um projeto para a construção de APIs, open-source e mantido pela <a href="https://www.encode.io/">Encode OSS</a> e pela comunidade e <a href="https://fund.django-rest-framework.org/topics/funding/#our-sponsors">financiado por diversas empresas</a> que o utilizam.</p><p>O DRF é um projeto independente do <a href="https://www.djangoproject.com/">Django</a>. O Django foi escrito para servir e facilitar aplicações web tradicionais por meio de <em>templates</em>. Já o DRF foi desenvolvido a partir do Django mas com o propósito de construir web APIs.</p><p>Vamos automatizar a construção da API? \o/</p><p>Utilizamos o projeto <a href="https://pypi.org/project/drf-generators/">drf_generators</a> com modificações para funcionar nas versões Django 2.x e DRF 3.9.</p><p>Este projeto gera todas as <em>Views</em>, <em>Serializers </em>e as rotas (<em>URLs</em>) para a API a partir do <em>Models.py</em> do <em>Django</em>.</p><p>1 — Instalação</p><pre>pip install drf-generators</pre><p>2 — Incluir o <strong>rest_framework </strong>e o <strong>drf_generators</strong> no <em>settings.py</em></p><pre>INSTALLED_APPS = [<br> ‘django.contrib.admin’,<br> ‘django.contrib.auth’,<br> ‘django.contrib.contenttypes’,<br> ‘django.contrib.sessions’,<br> ‘django.contrib.messages’,<br> ‘django.contrib.staticfiles’,<br> <strong>‘</strong>projeto<strong>’</strong>,<br> ‘<strong>rest_framework</strong>’,<br> ‘<strong>drf_generators</strong>’,<br>]</pre><p>3— Executar o comando para a criação das <em>Views</em>, <em>Serializers </em>e <em>URLs</em>:</p><pre>python .\manage.py generate <strong>projeto</strong></pre><p>Magicamente está tudo pronto!! 🎉 😃 🍻</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*T0yCAqtK4R6ZAQeK_gacig.png" /><figcaption>Exemplo da interface do Django REST Framework para a model Transacao</figcaption></figure><p>Os principais verbos HTTP foram implementados (GET, POST, PUT e DELETE) para todas as classes do <em>Models</em>.</p><p>Mas <strong>ATENÇÃO</strong>, a intenção do projeto é iniciar o desenvolvimento da API e evitar o trabalho repetitivo na escrita de cada <em>model,</em> <em>view, serializers e rotas</em>. <strong>Não se acomode!</strong></p><p>Outras tarefas devem ser feitas a partir de agora, como por exemplo: Autenticação OAuth, JSON Web Token (JWT), documetação da API com Swagger e construir modelos de dados sólidos e robustos.</p><h3>Conclusão</h3><p>A decisão da reescrita de um projeto diga-se “legado” deve ser baseado no maior número de dados possível e com muita responsabilidade e deve ser estudado caso a caso, sem fanatismo de linguagem ou framework.</p><p><strong>Python</strong>, <strong>Django </strong>e <strong>Django REST Framework</strong> foram as melhores escolhas para o caso em questão.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3d534ce20f91" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[O paradoxo Python]]></title>
            <link>https://medium.com/@leogregianin/o-paradoxo-python-af9aaea6c65?source=rss-d11676685b9a------2</link>
            <guid isPermaLink="false">https://medium.com/p/af9aaea6c65</guid>
            <dc:creator><![CDATA[Leonardo Gregianin]]></dc:creator>
            <pubDate>Sun, 28 Oct 2018 05:37:06 GMT</pubDate>
            <atom:updated>2018-10-28T05:37:06.190Z</atom:updated>
            <content:encoded><![CDATA[<p>O texto chamado de “O Paradoxo Python” foi uma reflexão feita por <a href="https://en.wikipedia.org/wiki/Paul_Graham_(programmer)">Paul Graham</a> em 2004 publicada em seu <a href="http://www.paulgraham.com/pypar.html">blog</a>.</p><p>Paul coloca no título uma referência a linguagem de programação Python mas não se apegue a isso, de 2004 pra cá mudou muito na área de programação. Entenda a palavra “Python” como qualquer outra linguagem “esotérica”, como ele mesmo descreve.</p><p>A reflexão que Graham propõe é que as pessoas que estudam e se dedicam a aprender uma linguagem de programação que não é massivamente utilizada comercialmente, ou que não lhes garantirá um emprego, elas investem tempo nisso pois genuinamente gostam de programar e não estão satisfeitas com as linguagens de programação que elas já conhecem.</p><p>Segundo Graham, isso faz dessas pessoas exatamente o tipo de programadores que as empresas deveriam estar interessadas em contratar.</p><p>Não é difícil visualizar esse conceito em algumas empresas.</p><p>Empresas com a stack essencialmente em uma única linguagem de programação como a <a href="https://olist.com/trabalhe-conosco/">Olist </a>buscam programadores <a href="https://golang.org/">Go</a> e <a href="https://elixir-lang.org/">Elixir</a> para somar a equipe ou o <a href="https://careers.google.com/jobs#!t=jo&amp;jid=/google/software-engineer-1600-amphitheatre-pkwy-mountain-view-ca-6540009&amp;f=true&amp;">Google</a> que buscam programadores que tenham experiência em mais de uma linguagem de programação como requisito mínimo.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=af9aaea6c65" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>