<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Python - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Python - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 22 May 2026 15:17:00 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/tag/python/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ PySpark para iniciantes – como processar dados com o Apache Spark e o Python ]]>
                </title>
                <description>
                    <![CDATA[ Se você está mergulhando no mundo do big data, provavelmente, já ouviu falar no termo PySpark. O PySpark é uma ferramenta que permite gerenciar e analisar grandes conjuntos de dados de uma maneira mais fácil. Neste artigo, veremos o básico do PySpark, seus benefícios e como você pode começar a ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/pyspark-para-iniciantes-como-processar-dados-com-o-apache-spark-e-o-python/</link>
                <guid isPermaLink="false">667c49e2963dbc0470cd3136</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Gabriel &quot;Zendefta&quot; Balbueno ]]>
                </dc:creator>
                <pubDate>Sun, 07 Jul 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/pyspark.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/pyspark-for-beginners/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">PySpark for Beginners – How to  Process Data with Apache Spark &amp; Python</a>
      </p><p>Se você está mergulhando no mundo do <em>big data</em>, provavelmente, já ouviu falar no termo PySpark.</p><p>O PySpark é uma ferramenta que permite gerenciar e analisar grandes conjuntos de dados de uma maneira mais fácil. Neste artigo, veremos o básico do PySpark, seus benefícios e como você pode começar a usá-lo.</p><h2 id="o-que-o-pyspark">O que é o PySpark?</h2><p>PySpark é a API do Python para <a href="https://spark.apache.org/" rel="noopener">Apache Spark</a>, um <em>framework</em> de processamento de <em>big data</em>.</p><p>O PySpark é feito para trabalhar com processamento de dados em grande escala e tarefas de aprendizado de máquina. Com o PySpark, você pode escrever aplicações Spark usando o Python.</p><p>Uma das razões principais para usar o PySpark é a velocidade. O PySpark pode processar dados muito mais rápido que os <em>frameworks </em>tradicionais de processamento de dados. Isso ocorre porque o PySpark distribui as tarefas entre várias máquinas, tornando-o incrivelmente eficiente.</p><p>Outra vantagem é a facilidade de uso. Se você tem familiaridade com o Python, vai achar o PySpark fácil de aprender. Ele usa sintaxes e bibliotecas do Python bastante conhecidas, fazendo com que você torne seu trabalho mais rápido.</p><p>Escalabilidade é outro benefício chave do PySpark. Esteja você trabalhando com um conjunto de dados pequeno ou gigante, o PySpark consegue dar conta de tudo.</p><p>O PySpark escala de uma única máquina para um conjunto de milhares de máquinas. Isso significa que você pode começar pequeno e expandir à medida que seus dados expandem.</p><p>O PySpark também trabalha bem com outras ferramentas de <em>big data</em> como o Hadoop e o Apache Hive. Isso o torna uma escolha versátil para tarefas de engenharia de dados.</p><h2 id="como-trabalhar-com-o-pyspark">Como trabalhar com o PySpark</h2><p>Agora, vamos falar sobre como começar a usar o PySpark.</p><p>Antes de começar, você deve ter o Python e Java instalados em seu sistema. Você também precisará instalar o Apache Spark. Você pode baixá-lo diretamente do site oficial do Spark.</p><p>Tendo concluído esses pré-requisitos, você pode instalar o PySpark usando o <code>pip</code>, o instalador de pacotes do Python.</p><pre><code>pip install pyspark</code></pre><p>Após instalar o PySpark, você pode começar a usá-lo para processar dados.</p><p>Você pode criar uma sessão do Spark, que é o ponto de partida para qualquer aplicação Spark. A partir disso, você pode carregar seus dados em um <em>DataFrame</em> do Python.</p><p>Um <em>DataFrame</em> é uma coleção de dados distribuída em colunas nomeadas. <em>DataFrames</em> são parecidos com tabelas em um banco de dados, tornando mais fácil a manipulação de dados.</p><p>Você pode realizar várias operações em <em>DataFrames</em>, como filtragem, agrupamento e agregação de dados. O PySpark fornece uma grande quantidade de funções para ajudar você com essas tarefas.</p><p>Para dar um gostinho do PySpark, vamos examinar um exemplo simples.</p><p>Digamos que você tenha um arquivo CSV com alguns dados. Você pode carregar esses dados em um <em>DataFrame </em>e realizar operações básicas nele.</p><p>Primeiro, crie uma sessão:</p><pre><code>from pyspark.sql import SparkSessionspark = SparkSession.builder.appName("exemplo").getOrCreate()</code></pre><p>Depois, carregue seu arquivo CSV em um <em>DataFrame</em>:</p><pre><code>df = spark.read.csv("caminho/para/o/arquivo.csv", header=True, inferSchema=True)</code></pre><p>Você pode realizar operações nesse <em>DataFrame</em>. Por exemplo, para filtrar dados onde uma coluna específica tem certo valor, você pode usar:</p><pre><code>filtered_df = df.filter(df["nome_da_coluna"] == "valor")</code></pre><p>Você também pode agrupar os dados de uma coluna e calcular agregados, como o valor médio de outra coluna:</p><pre><code>grouped_df = df.groupBy("nome_da_coluna").agg({"outra_coluna": "media"})</code></pre><p>Esses são apenas alguns exemplos do que você pode fazer com o PySpark. A biblioteca é muito poderosa e oferece diversas funções para auxiliar você a processar e analisar seus dados.</p><h2 id="conclus-o">Conclusão</h2><p>Concluindo, o PySpark é uma ferramenta fantástica para qualquer pessoa trabalhando com <em>big data</em>. Ele é rápido, fácil de usar, escalável e trabalha bem com outras ferramentas de <em>big data</em>.</p><p>Aprendendo PySpark, você pode destravar o potencial máximo do Apache Spark e levar suas habilidades de processamento de dados para o próximo nível.</p><p>Então, dê uma chance ao PySpark. Você vai se impressionar com o quanto que ele pode fazer. Espero que você tenha gostado desse artigo. Para mais artigos sobre IA, visite <a href="http://turingtalks.ai/" rel="noopener">turingtalks.ai</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python para finanças – tutorial de negociação algorítmica para iniciantes ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Harshit Tyagi [https://www.freecodecamp.org/news/author/harshit/] A tecnologia se tornou um ativo nas finanças. As instituições financeiras estão agora evoluindo para empresas de tecnologia, em vez de se concentrarem apenas nos aspectos financeiros do setor.  Os algoritmos matemáticos trazem inovação e rapidez. Eles podem nos ajudar a obter uma vantagem ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/python-para-financas-tutorial-de-negociacao-algoritmica-para-iniciantes/</link>
                <guid isPermaLink="false">6659ba76e669e903cefde4a2</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Marcelo Pena ]]>
                </dc:creator>
                <pubDate>Tue, 25 Jun 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/image-27.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/algorithmic-trading-in-python/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python for Finance – Algorithmic Trading Tutorial for Beginners</a>
      </p><p>Escrito por: <a href="https://www.freecodecamp.org/news/author/harshit/">Harshit Tyagi</a></p><p>A tecnologia se tornou um ativo nas finanças. As instituições financeiras estão agora evoluindo para empresas de tecnologia, em vez de se concentrarem apenas nos aspectos financeiros do setor. </p><p>Os algoritmos matemáticos trazem inovação e rapidez. Eles podem nos ajudar a obter uma vantagem competitiva no mercado. </p><p>A velocidade e a frequência das transações financeiras, juntamente com os grandes volumes de dados, têm atraído muita atenção para a tecnologia por parte de todas as grandes instituições financeiras.</p><p>A negociação algorítmica ou quantitativa é o processo de concepção e desenvolvimento de estratégias de negociação com base em análises matemáticas e estatísticas. É uma área extremamente sofisticada das finanças.</p><p>Este tutorial serve como um guia para iniciantes em negociação quantitativa com Python. Você achará este artigo muito útil se for:</p><ol><li>Um estudante ou alguém que aspira a se tornar um analista quantitativo (quant) em um fundo ou banco.</li><li>Alguém que planeja iniciar seu próprio negócio de negociação quantitativa.</li></ol><p>Neste artigo, abordaremos os seguintes tópicos:</p><ul><li>Princípios básicos de ações e negociação</li><li>Extração de dados da API da Quandl</li><li>Análise exploratória de dados sobre preços de ações</li><li>Médias móveis</li><li>Formulação de uma estratégia de negociação com Python</li><li>Visualização do desempenho da estratégia</li></ul><p>Antes de mergulharmos nos detalhes e na dinâmica dos dados de preços de ações, primeiro precisamos entender os princípios básicos das finanças. Se você já está familiarizado com finanças e com a maneira como as negociações funcionam, pode pular esta seção e passar para a próxima.</p><h2 id="o-que-s-o-a-es-o-que-a-negocia-o-de-a-es"><strong>O que são ações<strong>? </strong>O que é a negociação de ações<strong>?</strong></strong></h2><h3 id="a-es"><strong>Ações</strong></h3><p>Uma ação é a representação de uma participação na propriedade de uma corporação, emitida por um determinado valor. É um tipo de título financeiro que estabelece sua reivindicação sobre os ativos e o desempenho de uma empresa.</p><p>Uma organização ou empresa emite ações para arrecadar mais fundos/capital com o objetivo de expandir e se envolver em mais projetos. Essas ações ficam então disponíveis ao público e são compradas e vendidas.</p><h3 id="negocia-o-de-a-es-e-estrat-gia-de-negocia-o">Negociação de ações e estratégia de negociação</h3><p>O processo de compra e venda de ações existentes e previamente emitidas é chamado de negociação de ações. Existe um preço pelo qual uma ação pode ser comprada e vendida. Esse preço continua a flutuar dependendo da demanda e da oferta no mercado de ações.</p><p>Dependendo do desempenho e das medidas tomadas pela empresa, os preços das ações podem subir ou descer, mas o movimento do preço das ações não se limita ao desempenho da empresa.</p><p>Os negociadores pagam dinheiro em troca de participação na empresa, esperando fazer negociações lucrativas e vender as ações a um preço mais alto.</p><p>Outra técnica importante que os negociadores seguem é a venda a descoberto. Isso envolve pegar emprestado ações e vendê-las imediatamente, na esperança de comprá-las posteriormente a um preço mais baixo, devolvê-las ao credor e obter a margem de lucro.</p><p>Assim, a maioria dos negociadores segue um plano e um modelo para negociar. Isso é conhecido como estratégia de negociação.</p><p>Negociadores quantitativos em fundos <em>hedge</em> e bancos de investimento projetam e desenvolvem essas estratégias de negociação e estruturas para testá-las. Isso requer um profundo conhecimento em programação e compreensão das linguagens necessárias para construir sua própria estratégia.</p><p>Python é uma das linguagens de programação mais populares usadas, junto com C++, Java, R e MATLAB. Está sendo amplamente adotada em todas as áreas, especialmente em ciência de dados, devido à sua sintaxe fácil, grande comunidade e suporte de terceiros.</p><p>Você precisará estar familiarizado com Python e estatísticas para aproveitar ao máximo este tutorial. Certifique-se de revisar seus conhecimentos em Python e verificar os <a href="https://archive.org/details/FundamentalsOfMathematicalStatisticsGuptaKapoor/page/n9/mode/2up">fundamentos das estatísticas</a> (texto em inglês).</p><h2 id="extraindo-dados-da-api-da-quandl"><strong><strong>Extra</strong>indo dados da API da <strong>Quandl</strong></strong></h2><p>Para extrair dados de preços de ações, usaremos a <a href="https://docs.data.nasdaq.com/">API da Quandl</a>. Antes, porém, vamos configurar o ambiente de trabalho. Veja como:</p><ol><li>No seu terminal, crie um diretório para o projeto (nomeie-o como quiser):</li></ol><pre><code>mkdir &lt;nome_do_diretorio&gt;</code></pre><ol><li>Certifique-se de ter o <a href="https://www.python.org/downloads/">Python 3</a> e o <a href="https://pypi.org/project/virtualenv/">virtualenv</a> instalados em sua máquina.</li><li>Crie um virtualenv de Python 3 usando <code>virtualenv &lt;nome_do_env&gt;</code> e ative-o usando <code>source &lt;nome_do_env&gt;/bin/activate</code>.	</li><li>Agora, instale o Jupyter Notebook usando o pip, e digite <code>pip install jupyter-notebook</code> no terminal.</li><li>Da mesma maneira, instale os pacotes <code>pandas</code>, <code>quandl</code> e <code>numpy</code>.</li><li>Abra o seu <code>jupyter-notebook</code> pelo terminal</li></ol><p>Agora, o seu notebook deve estar rodando no localhost, como mostra a captura de tela abaixo:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/1-1.png" class="kg-image" alt="1-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/06/1-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/06/1-1.png 800w" width="800" height="138" loading="lazy"></figure><p>Você pode criar seu primeiro notebook clicando no menu suspenso <code>New</code> (Novo) à direita. Certifique-se de ter criado uma conta na <a href="https://docs.quandl.com/">Quandl</a> (texto em inglês). Siga os passos mencionados <a href="https://docs.quandl.com/docs/python-installation">aqui</a> (texto em inglês) para criar sua chave de API.</p><p>Uma vez que você esteja pronto, vamos mergulhar de cabeça:</p><pre><code># importando os pacotes necessários</code></pre><pre><code>import pandas as pd
import quandl as q</code></pre><p>O Pandas será o pacote mais exaustivamente utilizado neste tutorial, pois faremos muitas manipulações de dados e plotagens. </p><p>Depois que os pacotes forem importados, faremos solicitações à API do Quandl usando o pacote Quandl:</p><pre><code># define a chave da API
q.ApiConfig.api_key = "&lt;API key&gt;"</code></pre><pre><code># envia uma solicitação GET para consultar os preços de fechamento diário das
# ações da Microsoft de 1º de janeiro de 2010 a 1º de janeiro de 2019

msft_data = q.get("EOD/MSFT", start_date="2010-01-01", end_date="2019-01-01")</code></pre><pre><code># visualizar as primieras 5 linhas dos dataframe

msft_data.head()</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/2-3.png" class="kg-image" alt="2-3" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/06/2-3.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/06/2-3.png 800w" width="800" height="170" loading="lazy"></figure><p>Aqui temos os dados de preços de fechamento diário das ações EOD (de <em>end of the day</em>, em inglês) da Microsoft dos últimos 9 anos. Tudo o que você precisava fazer era chamar o método <code>get</code> do pacote Quandl e fornecer o símbolo da ação, MSFT, e o período de tempo dos dados que você precisa. Isso foi realmente simples, não foi? Vamos avançar para entender e explorar esses dados mais a fundo.</p><h2 id="an-lise-explorat-ria-em-dados-de-pre-os-de-a-es"><strong>Análise exploratória em dados de preços de ações</strong></h2><p>Com os dados em mãos, a primeira coisa que devemos fazer é entender o que eles representam e que tipo de informação eles trazem.</p><p>Imprimindo as informações do DataFrame, podemos ver tudo que ele contém:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/3-1.png" class="kg-image" alt="3-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/06/3-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/06/3-1.png 800w" width="800" height="242" loading="lazy"></figure><p>Como visto na captura de tela acima, o DataFrame contém DatetimeIndex, o que significa que estamos lidando com dados de séries temporais.</p><p>Um índice pode ser considerado como uma estrutura de dados que nos ajuda a modificar ou referenciar os dados. Dados de séries temporais são uma sequência de registros instantâneos de preços tirados em intervalos de tempo consecutivos e igualmente espaçados.</p><p>Na negociação, os dados de preços de fechamento diário capturam o movimento de certos parâmetros sobre uma ação, como o preço da ação, ao longo de um período especificado de tempo, com pontos de dados registrados em intervalos regulares.</p><h3 id="terminologia-importante"><strong>Terminologia importante</strong></h3><p>Olhando para outras colunas, vamos tentar entender o que cada coluna representa:</p><ul><li>Open/Close  —  captura o preço de abertura/fechamento das ações</li><li>Adj_Open/Adj_Close — um preço de abertura/fechamento ajustado é o preço de uma ação em qualquer dia de negociação que foi revisado para incluir quaisquer distribuições de dividendos, desdobramentos de ações e outras ações corporativas que ocorreram a qualquer momento antes da abertura do dia seguinte.</li><li>Volume — registra o número de ações que estão sendo negociadas em qualquer dia de negociação.</li><li>High/Low — rastreia o preço mais alto e o mais baixo da ação durante um determinado dia de negociação.</li></ul><p>Essas são as colunas importantes nas quais vamos focar neste momento.</p><p>Podemos aprender sobre as estatísticas resumidas dos dados, que nos mostram o número de linhas, média, máximo, desvios padrão e assim por diante. Tente executar a seguinte linha de código na célula do IPython:</p><pre><code>msft_data.describe()</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/4-1.png" class="kg-image" alt="4-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/06/4-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/06/4-1.png 800w" width="800" height="229" loading="lazy"></figure><h3 id="resample-"><strong><strong>resample()</strong></strong></h3><p>O método <code>resample()</code> do Pandas é usado para facilitar o controle e a flexibilidade na conversão de frequência dos dados de séries temporais. Podemos especificar os intervalos de tempo para reamostrar (mudar a frequência de amostragem) os dados para mensal, trimestral ou anual, além de realizar a operação necessária sobre eles.</p><pre><code>msft_data.resample('M').mean()</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/5-1.png" class="kg-image" alt="5-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/06/5-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/06/5-1.png 800w" width="800" height="176" loading="lazy"></figure><p>Essa é uma maneira interessante de analisar o desempenho das ações em diferentes períodos de tempo.</p><h3 id="calculando-retornos">Calculando retornos</h3><p>O retorno financeiro é simplesmente o dinheiro ganho ou perdido em um investimento. Um retorno pode ser expressado nominalmente como a variação no valor de um investimento ao longo do tempo. Pode ser calculado como a porcentagem derivada da razão entre o lucro e o investimento.</p><p>Temos o <code>pct_change()</code> à nossa disposição para esse propósito. Aqui está como você pode calcular os retornos:</p><pre><code># Importa o pacote do numpy
import numpy as np</code></pre><pre><code># atribui 'Adj_Close' a 'daily_close'
daily_close = msft_data[['Adj_Close']]</code></pre><pre><code># retorna como variação em percentual
daily_return = daily_close.pct_change()</code></pre><pre><code># substitui valores NA por 0
daily_return.fillna(0, inplace=True)</code></pre><pre><code>print(daily_return)</code></pre><p>Isso imprimirá os retornos que a ação vem gerando diariamente. Multiplicando o número por 100, você obterá a mudança percentual.</p><p>A fórmula usada em <code>pct_change()</code> é:</p><p>Retorno = {(Preço em t) — (Preço em t-1)} / {Preço em t-1}</p><p>Agora, para calcular retornos mensais, tudo que precisa fazer é:</p><pre><code>mdata = msft_data.resample('M').apply(lambda x: x[-1])

monthly_return = mdata.pct_change()</code></pre><p>Após reamostrar os dados para meses (considerando apenas os dias úteis), podemos obter o último dia de negociação no mês usando a função <code>apply()</code>.</p><p><code>apply()</code> recebe uma função e a aplica a cada linha da série Pandas. A função <code>lambda</code> é uma função anônima em Python que pode ser definida sem um nome e só aceita expressões no seguinte formato:</p><pre><code>Lambda: espressão</code></pre><p>Por exemplo, <code>lambda x: x * 2</code> é uma função lambda. Aqui, x é o argumento e <code>x * 2</code> é a espressão avaliada e retornada.</p><h2 id="m-dias-m-veis-no-mercado-financeiro"><strong><strong>Mé</strong>dias móveis no mercado financeiro</strong></h2><p>O conceito de médias móveis vai estabelecer a base para nossa estratégia de negociação baseada em <em>momentum</em>.</p><p>No campo financeiro, os analistas frequentemente têm que avaliar métricas estatísticas continuamente ao longo de uma janela de tempo móvel, o que é chamado de cálculos de janela móvel.</p><p>Vamos ver como podemos calcular a média móvel ao longo de uma janela de 50 dias e deslizar a janela por 1 dia.</p><h3 id="rolling-"><strong><strong>rolling()</strong></strong></h3><p>Esta é a função mágica que faz os truques para nós:</p><pre><code># atribuindo os preços de fechamento ajustados a
adj_pricesadj_price = msft_data['Adj_Close']</code></pre><pre><code># calcular a média móvel
mav = adj_price.rolling(window=50).mean()</code></pre><pre><code># imprime o result
print(mav[-10:])</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/6-1.png" class="kg-image" alt="6-1" width="485" height="223" loading="lazy"></figure><p>Você verá a média móvel em uma janela de 50 dias (aproximadamente 2 meses). As médias móveis ajudam a suavizar qualquer flutuação ou pico nos dados, proporcionando uma curva mais suave para o desempenho da empresa.</p><p>Podemos traçar um gráfico e ver a diferença:</p><pre><code># importa o pacote matplotlib para visualizar o gráfico
import matplotlib.pyplot as plt

adj_price.plot()</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/7-1.png" class="kg-image" alt="7-1" width="405" height="254" loading="lazy"></figure><p>Você pode traçar o gráfico da média móvel:</p><pre><code>mav.plot()</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/8-1.png" class="kg-image" alt="8-1" width="438" height="261" loading="lazy"></figure><p>Você também pode ver a diferença por si mesmo, como os picos nos dados são suavizados para fornecer uma ideia geral sobre o desempenho da ação.</p><h2 id="formulando-uma-estrat-gia-de-negocia-o"><strong><strong>Formula</strong>ndo uma estratégia de negociação</strong></h2><p>Aqui vem a parte final e mais interessante: desenhar e criar a estratégia de negociação. Este será um guia passo a passo para desenvolver uma estratégia de Cruzamento de Média Móvel Simples (<em>Simple Moving Average Crossover</em> - SMAC) baseada em <em>momentum</em>.</p><p>Estratégias baseadas em <em>momentum </em>são fundamentadas em um indicador técnico que capitaliza a continuidade da tendência do mercado. Compramos valores mobiliários que mostram uma tendência de alta e vendemos a descoberto valores mobiliários que mostram uma tendência de baixa.</p><p>A estratégia SMAC é uma estratégia de <em>momentum </em>bem conhecida. É uma estratégia apenas de compra. Aqui, o <em>momentum </em>é o retorno total da ação, incluindo os dividendos, nos últimos <em><strong>n</strong></em> meses. Esse período de <em><strong>n</strong></em> meses é chamado de período de observação. </p><p>Existem 3 principais tipos de períodos de observação: curto prazo, médio prazo e longo prazo. Precisamos definir 2 diferentes períodos de observação de uma série temporal específica. </p><p>Um sinal de compra é gerado quando a média móvel (ou média móvel simples) de período curto ultrapassa a média móvel de período longo. Um sinal de venda ocorre quando a média móvel de período curto cai abaixo da média móvel de período longo. </p><p>Agora, vamos ver como será o código para essa estratégia:</p><pre><code># passo 1: inicialize os períodos de observação curto e longo.

short_lb = 50
long_lb = 120</code></pre><pre><code># passo 2: Inicialize um novo DataFrame chamado signal_df 
#          com uma coluna de sinal.

signal_df = pd.DataFrame(index=msft_data.index)
signal_df['signal'] = 0.0</code></pre><pre><code># Passo 3: crie uma média móvel simples curta 
#          sobre o período de observação curto.

signal_df['short_mav'] = msft_data['Adj_Close'].rolling(window=short_lb,                                     min_periods=1, center=False).mean()</code></pre><pre><code># Passo 4: crie uma média móvel simples longa 
#          sobre o período de observação longo.

signal_df['long_mav'] = msft_data['Adj. Close'].rolling(window=long_lb, min_periods=1, center=False).mean()</code></pre><pre><code># Passo 5: gere os sinais com base na declaração condicional.

signal_df['signal'][short_lb:] = np.where(signal_df['short_mav'][short_lb:] &gt; signal_df['long_mav'][short_lb:], 1.0, 0.0)</code></pre><pre><code># Passo 6: crie as ordens de negociação com base na coluna de posições.

signal_df['positions'] = signal_df['signal'].diff()
signal_df[signal_df['positions'] == -1.0]</code></pre><p>Vamos ver o que está acontecendo aqui. Criamos 2 períodos de observação. O período de observação curto, <code>short_lb</code>, é de 50 dias, e o período de observação mais longo para a média móvel longa é definido como <code>long_lb</code> de 120 dias.</p><p>Criamos um DataFrame projetado para capturar os sinais. Esses sinais são gerados sempre que a média móvel curta cruza a média móvel longa usando <code>np.where</code>. Ele atribui <code>1.0</code> para verdadeiro e <code>0.0</code> se a condição for falsa.</p><p>As colunas <code>positions</code> no DataFrame nos informam se há um sinal de compra, um sinal de venda, ou se deve-se manter a posição. Basicamente, estamos calculando a diferença na coluna de sinais em relação à linha anterior usando <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.diff.html">diff</a>.</p><p>Lá, temos nossa estratégia implementada em apenas 6 passos usando o Pandas. Fácil, não é?</p><p>Agora, vamos tentar visualizar isso usando o Matplotlib. Tudo que precisamos fazer é inicializar um gráfico, adicionar os preços de fechamento ajustados, as médias móveis curtas e longas ao gráfico. Em seguida, fazemos o gráfico (<em>plot</em>) dos sinais de compra e venda usando a coluna de posições no <code>signal_df</code> acima:</p><pre><code># Inicialize o gráfico usando plt.
fig = plt.figure()</code></pre><pre><code># Adicione um subgráfico e rótulo para o eixo y.
plt1 = fig.add_subplot(111,  ylabel='Preço em $')</code></pre><pre><code>msft_data['Adj. Close'].plot(ax=plt1, color='r', lw=2.)</code></pre><pre><code># Plote as médias móveis de curto e longo prazo.
signal_df[['short_mav', 'long_mav']].plot(ax=plt1, lw=2., figsize=(12,8))</code></pre><pre><code># Plotando os sinais de venda.
plt1.plot(signal_df.loc[signal_df.positions == -1.0].index,
			signal_df.short_mav[signal_df.positions == -1.0],'v',
            	markersize=10, color='k')</code></pre><pre><code># Plotando os sinais de compra.
plt1.plot(signal_df.loc[signal_df.positions == 1.0].index,
			signal_df.short_mav[signal_df.positions == 1.0],
			'^',
          	markersize=10, color='m')</code></pre><p>Executando as células acima no Jupyter Notebook resultaria em um gráfico como o abaixo:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/image-2.png" class="kg-image" alt="image-2" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/06/image-2.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/06/image-2.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/06/image-2.png 1003w" sizes="(min-width: 720px) 720px" width="1003" height="617" loading="lazy"></figure><p>Agora, você pode ver claramente que sempre que a linha azul (média móvel curta) ultrapassa e vai além da linha laranja (média móvel longa), há um marcador rosa para cima indicando um sinal de compra.</p><p>Um sinal de venda é indicado por um marcador preto para baixo sempre que houver uma queda da média móvel curta (<code>short_mav</code>) abaixo da média móvel longa (<code>long_mav</code>).</p><h2 id="visualize-o-desempenho-da-estrat-gia-no-quantopian">Visualize o desempenho da estratégia no Quantopian</h2><p>O <a href="https://community.quantopian.com/home">Quantopian</a> (texto em inglês) é uma plataforma alimentada por Zipline que possui diversos casos de uso. Você pode escrever seus próprios algoritmos, acessar dados gratuitos, testar sua estratégia, contribuir para a comunidade e colaborar com o Quantopian se precisar de capital.</p><p>Escrevemos um algoritmo para testar nossa estratégia de SMA e aqui estão os resultados:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/10-1.png" class="kg-image" alt="10-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/06/10-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/06/10-1.png 800w" width="800" height="321" loading="lazy"></figure><p>Aqui está uma explicação das métricas acima:</p><ul><li><em>Total return</em>: é a porcentagem total de retorno do portfólio desde o início até o final do <em>backtest</em>.</li><li><em>Specific return</em>: é a diferença entre os retornos totais do portfólio e os retornos comuns.</li><li><em>Common return</em>: são retornos atribuíveis a fatores de risco comuns. Existem 11 fatores de risco setoriais e 5 de estilo que compõem esses retornos. Os gráficos de Exposição Setorial e Exposição de Estilo na seção de Risco fornecem mais detalhes sobre esses fatores.</li><li><em>Sharpe</em>: é o <em>sharpe ratio</em> de 6 meses consecutivos. É uma medida de investimento ajustada ao risco. É calculado dividindo os retornos excedentes do portfólio sobre a taxa livre de risco pelo desvio padrão do portfólio.</li><li><em>Max Drawdown</em>: é a maior queda de todo o movimento do pico ao ponto mais baixo na história do portfólio.</li><li><em>Volatility</em>: é o desvio padrão dos retornos do portfólio.</li></ul><p>Parabéns! Você implementou com sucesso sua estratégia de <em>trading</em> quantitativo.</p><h2 id="para-onde-ir-a-partir-daqui"><strong>Para onde ir a partir daqui<strong>?</strong></strong></h2><p>Agora que seu algoritmo está pronto, você precisará realizar <em>backtests</em> dos resultados e avaliar as <a href="https://www.investopedia.com/ask/answers/041415/what-are-some-common-measures-risk-used-risk-management.asp">métricas que mapeiam o risco</a> (texto em inglês) envolvido na estratégia e na ação. Novamente, você pode usar o <a href="https://blueshift.quantinsti.com/">BlueShift</a> e o <a href="https://community.quantopian.com/home">Quantopian</a> para aprender mais sobre <em>backtesting</em> e estratégias de negociação (textos dos links em inglês).</p><p><strong>Recursos adicionais</strong></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/06/Quantra-logo-Black.png" class="kg-image" alt="Quantra-logo-Black" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/06/Quantra-logo-Black.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/06/Quantra-logo-Black.png 608w" width="608" height="623" loading="lazy"><figcaption>https://quantra.quantinsti.com/learning-track/algorithmic-trading-for-everyone?utm_source=harshit_tyagi&amp;utm_medium=affiliate&amp;utm_campaign=lt_everyone</figcaption></figure><p><a href="https://quantra.quantinsti.com/learning-track/algorithmic-trading-for-everyone?utm_source=harshit_tyagi&amp;utm_medium=affiliate&amp;utm_campaign=lt_everyone">Quantra</a> (texto em inglês) é uma criação da QuantInsti. Com uma variedade de cursos gratuitos e pagos ministrados por especialistas na área, a Quantra oferece um guia completo sobre diversas estratégias de negociação, tanto básicas quanto avançadas.</p><ul><li><a href="https://quantra.quantinsti.com/course/introduction-to-data-science?utm_source=harshit_tyagi&amp;utm_medium=affiliate&amp;utm_campaign=data_science" rel="noopener">Curso de Ciência de Dados </a> (texto em inglês) — eles lançaram um curso introdutório sobre Ciência de Dados que ajuda a construir uma base sólida para projetos na área.</li><li><a href="https://quantra.quantinsti.com/learning-track/algorithmic-trading-for-everyone?utm_source=harshit_tyagi&amp;utm_medium=affiliate&amp;utm_campaign=lt_everyone" rel="noopener">Curso de Negociação para iniciantes</a> (texto em inglês)  — desde negociação por <em>momentum</em> até estratégias de negociação baseadas em aprendizado de máquina e <em>deep learning</em> (aprendizagem profunda), pesquisadores renomados no mundo da negociação, como o Dr. Ernest P. Chan, são os autores desses cursos especializados.</li></ul><h4 id="recursos-gratu-tos"><strong>Recursos gratuítos</strong></h4><p>Para aprender mais sobre algoritmos de negociação, confira esses blogs:</p><ul><li><a href="https://www.quantstart.com/" rel="noopener">Quantstart</a>  (texto em inglês) — eles abrangem uma ampla gama de algoritmos de <em>backtesting</em>, guias para iniciantes e muito mais.</li><li><a href="https://www.investopedia.com/" rel="noopener">Investopedia</a> (texto em inglês) — tudo o que você deseja saber sobre investimentos e finanças.</li><li><a href="https://quantivity.wordpress.com/" rel="noopener">Quantivity</a> (texto em inglês)  — explicações matemáticas detalhadas dos algoritmos, bem como suas vantagens e desvantagens.</li></ul><p>Warren Buffet diz que lê cerca de 500 páginas por <em>dia</em>, o que indica que a leitura é essencial para ter sucesso na área de finanças.</p><p>Embarque nesta jornada de negociação e você poderá levar uma vida cheia de emoção, paixão e matemática.</p><h1 id="ci-ncia-de-dados-com-harshit"><strong><a href="https://www.youtube.com/c/DataSciencewithHarshit?sub_confirmation=1">Ciência de Dados com <strong>Harshit</strong></a></strong></h1><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/_ANbV9lVA-M?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" title="How to build an Effective Data Science Portfolio" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><p>Com este canal, estou planejando lançar uma <a href="https://towardsdatascience.com/hitchhikers-guide-to-learning-data-science-2cc3d963b1a2?source=---------8------------------">série de vídeos que cobrirá todo o espaço da ciência de dados</a> (em inglês). Aqui está o motivo pelo qual você deve se inscrever no <a href="https://www.youtube.com/channel/UCH-xwLTKQaABNs2QmGxK2bQ">canal</a> (texto em inglês):</p><ul><li>Essas séries abordarão todos os tutoriais de qualidade necessários sobre cada um dos tópicos e subtópicos, como <a href="https://towardsdatascience.com/python-fundamentals-for-data-science-6c7f9901e1c8?source=---------5------------------">fundamentos de Python para Ciência de Dados</a> (texto em inglês).</li><li>Explicações <a href="https://towardsdatascience.com/practical-reasons-to-learn-mathematics-for-data-science-1f6caec161ea?source=---------9------------------">matemáticas e derivações</a> (texto em inglês) sobre o porquê fazemos o que fazemos em aprendizagem de máquina e Deep Learning.</li><li><a href="https://www.youtube.com/watch?v=a2pkZCleJwM&amp;t=2s">Podcasts com Cientistas de Dados e Engenheiros</a> (texto em inglês) do Google, Microsoft, Amazon etc., além de CEOs de grandes empresas orientadas por dados.</li><li><a href="https://towardsdatascience.com/building-covid-19-analysis-dashboard-using-python-and-voila-ee091f65dcbb?source=---------2------------------">Projetos e instruções</a> para implementar os tópicos aprendidos até agora. Saiba mais sobre novas certificações, bootcamps e recursos para conquistar essas certificações, como o <a href="https://youtu.be/yapSsspJzAw"><strong>Exame de Certificação de Desenvolvedor TensorFlow do Google</strong></a> (texto em inglês).</li></ul><p>Se este tutorial foi útil, confira meus cursos de ciência de dados e aprendizagem de máquina na <a href="https://www.wiplane.com/">Wiplane Academy</a> (texto em inglês). Eles são abrangentes, porém compactos, ajudando a construir uma base sólida de trabalho para mostrar.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como instalar o TensorFlow e o Keras usando o Anaconda Navigator — sem a linha de comando ]]>
                </title>
                <description>
                    <![CDATA[ Diga não ao pip install na linha de comando! Esta é uma maneira alternativa de instalar TensorFlow em sua máquina local em 3 etapas. Por que estou escrevendo isso? Brinquei com o pip install com múltiplas configurações por várias horas, tentando descobrir como configurar corretamente meu ambiente do Python para ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-instalar-o-tensorflow-e-o-keras-usando-o-anaconda-navigator-sem-a-linha-de-comando/</link>
                <guid isPermaLink="false">65dc9c1dcd7ddc0407292bf2</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isabel Cristina Nunes de Sousa ]]>
                </dc:creator>
                <pubDate>Mon, 03 Jun 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/5f9ca140740569d1a4ca4d8c.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/install-tensorflow-and-keras-using-anaconda-navigator-without-command-line/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to install TensorFlow and Keras using Anaconda Navigator — without the command line</a>
      </p><p>Diga não ao <em>pip install </em>na linha de comando! Esta é uma maneira alternativa de instalar TensorFlow<em> </em>em sua máquina local em 3 etapas.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-239.png" class="kg-image" alt="image-239" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/image-239.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/image-239.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-239.png 1080w" sizes="(min-width: 720px) 720px" width="1080" height="810" loading="lazy"></figure><h1 id="por-que-estou-escrevendo-isso">Por que estou escrevendo isso?</h1><p>Brinquei com o <em>pip install</em> com múltiplas configurações por várias horas, tentando descobrir como configurar corretamente meu ambiente do Python para o TensorFlow e o Keras.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-31.png" class="kg-image" alt="image-31" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/image-31.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-31.png 967w" sizes="(min-width: 720px) 720px" width="967" height="367" loading="lazy"><figcaption>Por que o tensorflow é tão difícil de instalar — mais de 600 mil resultados</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-32.png" class="kg-image" alt="image-32" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/image-32.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/image-32.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-32.png 1050w" sizes="(min-width: 720px) 720px" width="1050" height="431" loading="lazy"><figcaption>Não foi possível instalar o tensorflow no windows site:stackoverflow.com — mais de 26 mil resultados</figcaption></figure><h1 id="pouco-antes-de-desistir-descobri-isso-">Pouco antes de desistir, descobri isso…</h1><p><em><a href="https://www.anaconda.com/blog/tensorflow-in-anaconda?source=post_page-">"Um dos principais benefícios da instalação do TensorFlow usando conda em vez de pip é o resultado do sistema de gerenciamento de pacotes do conda. Quando o TensorFlow é instalado usando conda, o conda também instala todas as dependências necessárias e compatíveis para os pacotes."</a></em></p><p>Este artigo orientará você no processo de instalação do TensorFlow e do Keras usando a versão GUI do Anaconda. Presumo que você já tenha baixado e instalado o <a href="https://www.anaconda.com/distribution/?source=post_page---------------------------">Anaconda Navigator</a>.</p><h1 id="vamos-come-ar-">Vamos começar!</h1><ol><li>Inicie o Anaconda Navigator. Vá para a guia Ambientes (<em>Environments</em>) e clique em '<em>Create</em>'.</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-33.png" class="kg-image" alt="image-33" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/image-33.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/image-33.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-33.png 1050w" sizes="(min-width: 720px) 720px" width="1050" height="501" loading="lazy"><figcaption>Vá para a guia 'Environments’, clique em ‘Create’</figcaption></figure><p>2. Insira um novo nome de ambiente - (eu coloquei 'tensorflow_env'). <strong>Certifique-se de selecionar <strong>Python 3.6 </strong>aqui<strong>! </strong></strong>Em seguida, clique em 'Create' – o processo pode levar alguns minutos.</p><blockquote>Nota da tradução: o Python, atualmente, está na versão 3.12. O Anaconda também possui novas versões capazes de instalar algo nas versões mais recentes do Python. Caso você queira, pode testar a instalação com versões mais novas.</blockquote><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-34.png" class="kg-image" alt="image-34" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/image-34.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-34.png 629w" width="629" height="368" loading="lazy"><figcaption>Certifique-se de selecionar Python 3.6</figcaption></figure><p>3. Em seu novo ambiente 'tensorflow_env', selecione 'Not installed' e digite 'tensorflow'. Em seguida, marque 'tensorflow' e clique em 'Apply'. A janela de <em>pop-up</em> aparecerá. Vá em frente e clique em 'Apply'. Esse processo pode levar vários minutos.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-35.png" class="kg-image" alt="image-35" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/image-35.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/image-35.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-35.png 1050w" sizes="(min-width: 720px) 720px" width="1050" height="551" loading="lazy"></figure><p>Faça o mesmo para o 'keras'.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-36.png" class="kg-image" alt="image-36" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/image-36.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/image-36.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-36.png 1050w" sizes="(min-width: 720px) 720px" width="1050" height="546" loading="lazy"></figure><p>Verifique sua instalação importando os pacotes. Se tudo estiver bem, o comando não retornará nada. Se a instalação não for bem-sucedida, você receberá um erro.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-37.png" class="kg-image" alt="image-37" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/image-37.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-37.png 780w" sizes="(min-width: 720px) 720px" width="780" height="194" loading="lazy"><figcaption>Sem pop-up de erro — Sucesso!</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-38.png" class="kg-image" alt="image-38" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/image-38.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/image-38.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-38.png 1050w" sizes="(min-width: 720px) 720px" width="1050" height="588" loading="lazy"><figcaption>Você também pode tentar com o Spyder.</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-39.png" class="kg-image" alt="image-39" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/image-39.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/image-39.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/image-39.png 1050w" sizes="(min-width: 720px) 720px" width="1050" height="387" loading="lazy"><figcaption>Sem pop-up de erro — Sucesso!</figcaption></figure><p>Está feito! Você pode seguir <a href="https://towardsdatascience.com/how-to-build-a-neural-network-with-keras-e8faa33d0ae4?source=post_page---------------------------">este artigo</a> (em inglês) para testar seus pacotes recém-instalados. 🙂</p><p>Obrigado pela leitura. Faça os testes!</p><p>Considere seguir o autor no <a href="https://github.com/ekapope?source=post_page---------------------------">GitHub</a>, no <a href="https://medium.com/@ekapope.v?source=post_page---------------------------">Medium</a> e no <a href="https://twitter.com/EkapopeV?source=post_page---------------------------">Twitter</a> para obter mais artigos e tutoriais em seu <em>feed</em>, se gostou do artigo. 🙂</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como usar Django com MongoDB adicionando apenas uma linha de código ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Siddy Zen Para usar o MongoDB como banco de dados de back-end em seu projeto em Django, basta adicionar esta única linha em seu arquivo settings.py: DATABASES = {'default': {      'ENGINE': 'djongo',      'NAME': 'nome-do-banco',   }} É ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-usar-django-com-mongodb-adicionando-apenas-uma-linha-de-codigo/</link>
                <guid isPermaLink="false">651f1882bb3de103e1f88710</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Luis felipe L. C. ]]>
                </dc:creator>
                <pubDate>Wed, 29 May 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_eu9UNWEULdOQb9K1XvDmhg.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/using-django-with-mongodb-by-adding-just-one-line-of-code-c386a298e179/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to use Django with MongoDB by adding just one line of code.</a>
      </p><p>Escrito por: Siddy Zen</p><p>Para usar o MongoDB como banco de dados de <em>back-end</em> em seu projeto em Django, basta adicionar <strong>esta<strong> </strong>única linha</strong> em seu arquivo <code>settings.py</code>:</p><pre><code>DATABASES = {'default': {      'ENGINE': 'djongo',      'NAME': 'nome-do-banco',   }}</code></pre><p>É muito simples!</p><p>A seguir, faça login no home admin (localhost:8000/admin/) e comece a adicionar "<em>embedded documents</em>" (documentos incorporados, em português) no MongoDB usando a interface gráfica de administrador:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_ZkPNUvkWB5VoMn6bEoKxPA.jpeg" class="kg-image" alt="1_ZkPNUvkWB5VoMn6bEoKxPA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_ZkPNUvkWB5VoMn6bEoKxPA.jpeg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_ZkPNUvkWB5VoMn6bEoKxPA.jpeg 800w" sizes="(min-width: 720px) 720px" width="600" height="400" loading="lazy"></figure><p>Em outubro de 2017, o MongoDB concluiu a última fase para se tornar uma companhia de capital aberto, abrindo seu <a href="https://www.mongodb.com/press/mongodb-inc-announces-pricing-of-initial-public-offering" rel="noopener">IPO com um preço inicial de $24 </a>e conseguindo $192 milhões no processo. O capital da empresa vem crescendo desde então.</p><p>O MongoDB oferece um software de banco de dados de código aberto. Ele é muito útil para <em>start-ups</em> que estão buscando iniciar nos negócios apesar do pouco orçamento inicial disponível. Uma análise no Google Trends das pesquisas pelo termo MongoDB revelam um aumento constante na busca do termo.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_76GlEAQiLFt4eGsFaiJIIw.jpeg" class="kg-image" alt="1_76GlEAQiLFt4eGsFaiJIIw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_76GlEAQiLFt4eGsFaiJIIw.jpeg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_76GlEAQiLFt4eGsFaiJIIw.jpeg 800w" sizes="(min-width: 720px) 720px" width="600" height="400" loading="lazy"><figcaption>Google Trends — Termo pesquisado: MongoDB</figcaption></figure><p>O MongoDB tem se tornado um banco de dados cada vez mais popular. Bancos de dados e sistemas de gerenciamento de bancos de dados (SGBDs) existem há mais de cinco décadas. Surgiram no início dos anos 1960 e a opção mais popular foi o banco de dados relacional.</p><p>Porém, o MongoDB vem se intitulando como um sistema de banco de dados "não-relacional" e tem feito uma grande propaganda sobre essa abordagem de armazenamento de dados que utiliza. Então, o que exatamente é importante aqui?</p><h4 id="mongodb-x-sql"><strong>MongoDB x SQL</strong></h4><p>Praticamente todos os sistemas de bancos de dados relacionais utilizam a Linguagem de Consulta Estruturada (SQL), ou uma versão otimizada dela, para se comunicar com o software de gerenciamento de dados. Muitos cursos universitários são dedicados exclusivamente à compreensão e domínio da sintaxe do SQL.</p><p>O SQL tornou-se a linguagem padrão para o trabalho com qualquer software de banco de dados, seja ele proprietário ou de código aberto. Então, surgiu o MongoDB e decidiu demonstrar um completo desrespeito a essa linguagem ancestral de poder, criando sua própria sintaxe de consulta.</p><blockquote>A língua é a de Mordor, a qual não vou pronunciar aqui., mas isto em língua comum quer dizer, aproximadamente: "Um anel para todos governar, um anel para encontrá-los, um anel para todos trazer e na escuridão aprisioná-los." – Gandalf (de O Senhor dos Anéis<em><em>)</em></em></blockquote><p><strong><strong>MongoDB </strong>sem esquemas<strong> </strong>x esquemas do<strong> SQL:</strong> </strong>em um banco de dados em SQL, é impossível adicionar dados enquanto você não definir tabelas e tipos de campos no que é chamado de esquema (em inglês, <em>schema</em>). Em um banco de dados do MongoDB, os dados podem ser adicionados em qualquer lugar, a qualquer momento. Não há necessidade de especificar com antecedência um documento de design ou mesmo uma coleção de documentos.</p><p><strong>Documentos do <strong>MongoDB &nbsp;</strong>x<strong> </strong>tabelas do <strong>SQL:</strong> </strong>bancos de dados em SQL fornecem uma coleção de tabelas de dados relacionados. Cada linha é um registro diferente. O design é rígido: não podemos usar a mesma tabela para armazenar informações diferentes ou inserir uma string onde um número é esperado.</p><p>O banco de dados do MongoDB armazena apenas documentos de pares campo-valor, semelhantes ao formato JSON. Documentos similares podem ser armazenados em uma coleção de documentos, que é análoga a uma tabela do SQL. Entretanto, você pode armazenar qualquer tipo de dado em um documento — o MongoDB não vai reclamar. As tabelas em SQL implementam um modelo de dados rígido, o que torna mais difícil que erros sejam cometidos. O MongoDB é mais flexível e permissivo, mas a possibilidade de armazenar qualquer tipo de dado em qualquer lugar pode levar a erros de consistência.</p><p>Existe uma infinidade de conteúdo na internet argumentando que o MongoDB não é um superconjunto do SQL. Softwares que rodam em SQL não podem ser migrados para MongoDB. Vou me arriscar aqui afirmando que, no contexto do Django, <strong><strong>MongoDB </strong>é um superconjunto do<strong> SQL</strong></strong>.</p><p>Então, por que essa crença popular de que MongoDB não é um superconjunto do SQL existe, para começo de conversa?</p><p><strong>O <strong>MongoDB </strong>requer<strong> </strong>desnormalização<strong> </strong>de dados<strong>:</strong></strong> o MongoDb não oferece suporte a JOIN. Isso significa que vamos precisar desnormalizar nossos documentos. Documentos desnormalizados implicam maior velocidade nas consultas, mas atualizar informações nos campos do documento, em múltiplos documentos desnormalizados, é significativamente mais lento.</p><p><strong>Não existem<strong> JOINs</strong></strong>: consultas do SQL oferecem uma poderosa cláusula JOIN. Podemos obter dados relacionados em várias tabelas usando uma única instrução SQL. Em bancos de dados não relacionais como o MongoDB, não existem JOINs. Isso que dizer que você precisa executar muitas consultas e depois fazer a união dos dados manualmente em seu código.</p><p><strong>Sem transações:</strong> em bancos de dados SQL, duas ou mais atualizações podem ser executadas em uma transação – um invólucro que segue o princípio do "tudo ou nada", que garante sucesso ou falha das operações. Se executarmos duas atualizações individualmente, uma pode ter sucesso e a outra pode falhar – deixando nossos dados fora de sincronia. Colocar as mesmas atualizações em uma transação garante que ambas tenham sucesso ou ambas falhem.</p><p><strong>Sem restrições de chave estrangeira:</strong> a maioria dos bancos de dados de SQL permite que você assegure a integridade dos dados usando restrições de chave estrangeira. Isso garante que todas as linhas tenham uma chave estrangeira válida no código que corresponde a uma entrada na tabela de <em>join</em>, e garante que um registro da tabela de <em>join</em> não seja removido caso uma ou mais linhas ainda possuam referência a ele.</p><p>O esquema impõe essas regras ao banco de dados. É impossível que desenvolvedores e usuários adicionem, editem, ou removam registros, o que poderia resultar em dados inválidos ou registros órfãos. As mesmas opções para integridade de dados não estão disponíveis no MongoDB. Você pode armazenar o que quiser, independentemente de quaisquer outros documentos. Idealmente, um único documento serviria como a única fonte de informação sobre um item.</p><h4 id="a-necessidade-de-um-modelo-de-banco-de-dados"><strong>A necessidade de um modelo de banco de dados</strong></h4><p>Objetos são a abstração de dados que Python usa. Todos os dados em um programa em Python são representados por objetos ou pelas relações que eles têm entre si. Embora objetos sejam uma boa maneira de representar dados, um problema surge quando queremos <strong>tornar os dados persistentes.</strong> A quantidade de dados pode ser enorme, e precisa ser recuperada da memória persistente de maneira rápida e eficiente. Logo, será necessário usar um software de banco de dados para armazenar esses objetos. Um possível software de banco de dados é um que seja relacional, baseado em SQL.</p><p>Um mapeador objeto-relacional (ORM) é uma biblioteca de código que automatiza a transferência de dados armazenados em tabelas de banco de dados relacionais em objetos Python que são usados no código Python. ORMs fornecem uma abstração em alto nível de um banco de dados relacional, o que permite que um desenvolvedor digite código Python em vez de sintaxe SQL para criar, ler, atualizar e excluir dados e esquemas de seu banco de dados. Desenvolvedores podem usar linguagem de programação Python, com a qual estão familiarizados, ao invés de escrever declarações em SQL ou procedimentos armazenados.</p><p>Um exemplo de <em>framework</em> ORM para Python é o SQLAlchemy. Esse ORM possui um método de associar classes definidas pelo usuário em Python a tabelas de banco de dados, e instâncias dessas classes (objetos) a linhas em suas respectivas tabelas. Ele também possui um sistema que, de modo transparente, sincroniza todas as alterações de estado entre objetos e linhas que estão a eles relacionadas. <em>Frameworks</em> para a web, como o Flask, usam o SQLAlchemy para armazenar dados de maneira persistente.</p><p><strong>Django ORM:</strong> o Django vem com seu próprio ORM, ou modelo, para ser mais específico . O modelo é a única fonte definitiva de informações sobre seus dados. Ele contém os campos e comportamentos essenciais dos dados que você está armazenando. Geralmente, cada modelo mapeia para uma única tabela de banco de dados. O modelo também torna possível alternar entre vários bancos de dados relacionais, como Oracle SQL, MySQL ou MSSQL.</p><h4 id="usando-o-orm-do-django-para-adicionar-documentos-ao-mongodb"><strong>Usando o ORM do Django para adicionar documentos ao MongoDB</strong></h4><p>Digamos que você deseja criar uma plataforma de blogs usando Django e MongoDB como <em>back-end</em>.</p><p>No arquivo <code>app/models.py</code> do blog, defina o modelo <code>BlogContent</code>:</p><pre><code>from djongo import modelsfrom djongo.models import forms</code></pre><pre><code>class BlogContent(models.Model):    comment = models.CharField(max_length=100)    author = models.CharField(max_length=100)    class Meta:        abstract = True</code></pre><p>Para acessar o modelo usando o Django Admin, você precisa de uma definição de formulário para o modelo acima. Defina desta maneira:</p><pre><code>class BlogContentForm(forms.ModelForm):    class Meta:        model = BlogContent        fields = (            'comment', 'author'        )</code></pre><p>Agora, incorpore seu <code>BlogContent</code> dentro de um <code>BlogPost</code> usando o <code>EmbeddedModelField</code>, assim:</p><pre><code>class BlogPost(models.Model):    h1 = models.CharField(max_length=100)    content = models.EmbeddedModelField(        model_container=BlogContent,        model_form=BlogContentForm    )   </code></pre><p>Pronto! Rode o Django Admin em localhost:8000/admin/ e essa tela vai aparecer:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_ZkPNUvkWB5VoMn6bEoKxPA--1-.jpeg" class="kg-image" alt="1_ZkPNUvkWB5VoMn6bEoKxPA--1-" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_ZkPNUvkWB5VoMn6bEoKxPA--1-.jpeg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_ZkPNUvkWB5VoMn6bEoKxPA--1-.jpeg 800w" sizes="(min-width: 720px) 720px" width="600" height="400" loading="lazy"></figure><p>Depois, assuma que você quer "estender" o campo <code>author</code> para conter mais informações além do nome. Suponhamos que você precise tanto do nome quanto do e-mail. Basta tornar o campo <code>author</code> em um campo "embedded" ao invés de &nbsp;"char":</p><pre><code>class Author(models.Model):    name = models.CharField(max_length=100)    email = models.CharField(max_length=100)    class Meta:        abstract = Trueclass AuthorForm(forms.ModelForm):    class Meta:        model = Author        fields = (            'name', 'email'        )</code></pre><pre><code>class BlogContent(models.Model):    comment = models.CharField(max_length=100)    author = models.EmbeddedModelField(        model_container=Author,        model_form=AuthorForm    )    class Meta:        abstract = True</code></pre><p>Se um post de blog tiver conteúdo diverso de vários autores, defina um novo modelo:</p><pre><code>class MultipleBlogPosts(models.Model):    h1 = models.CharField(max_length=100)    content = models.ArrayModelField(        model_container=BlogContent,        model_form=BlogContentForm    )</code></pre><p>Rode o Django Admin com as atualizações. Agora você tem:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_9ckp5M7dit8F_U9A78FrMA.jpeg" class="kg-image" alt="1_9ckp5M7dit8F_U9A78FrMA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_9ckp5M7dit8F_U9A78FrMA.jpeg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_9ckp5M7dit8F_U9A78FrMA.jpeg 800w" sizes="(min-width: 720px) 720px" width="600" height="400" loading="lazy"></figure><h4 id="formas-de-integrar-django-ao-mongodb"><strong>Formas de integrar Django ao MongoDB</strong></h4><p>O ORM do Django consiste em várias camadas de abstração empilhadas uma em cima da outra.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_l41TRyQAGHD5lg0LHXzzag.png" class="kg-image" alt="1_l41TRyQAGHD5lg0LHXzzag" width="600" height="400" loading="lazy"><figcaption>Diagrama do Django ORM</figcaption></figure><p>Como desenvolvedor para a web, você pode encarar o desafio de conectar o Django ao MongoDB de duas maneiras. Dê uma olhada na <em>stack</em> do <em>framework</em> Django acima para tentar adivinhar possíveis pontos de conexão.</p><h4 id="use-um-modelo-compat-vel-com-o-mongodb"><strong>Use um modelo compatível com o MongoDB</strong></h4><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_dGgjMqDl6dzrVHJZdiPbfw.png" class="kg-image" alt="1_dGgjMqDl6dzrVHJZdiPbfw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_dGgjMqDl6dzrVHJZdiPbfw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_dGgjMqDl6dzrVHJZdiPbfw.png 800w" sizes="(min-width: 720px) 720px" width="600" height="400" loading="lazy"><figcaption>Mudança de um modelo Django para um ODM</figcaption></figure><p>Você pode evitar completamente o uso de modelos Django "com tudo incluso" em seu projeto. Em vez disso, use um <em>framework </em>de terceiros como MongoEngine ou Ming em seus projetos do Django.</p><p>Tenha em mente, porém, que escolher um modelo diferente significa perder:</p><ul><li>Mais de 1500 desenvolvedores que contribuem no núcleo do projeto</li><li><a href="https://dashboard.djangoproject.com/">Correções a cada hora e resolução de chamados</a></li></ul><p>Você então diminuiria a <em>expertise</em> nos modelos existentes do Django e aumentaria no novo <em>framework </em>de modelos. Talvez a maior desvantagem, no entanto, resida no fato de que seu projeto não vai poder usar nenhum dos pacotes do django.contrib! Esqueça o uso de Admin, Sessions, Users, Auth e outros módulos desse pacote em seu projeto.</p><p>Algumas dessas desvantagens são compensadas quando bifurcamos uma nova ramificação no próprio Django. O <a href="https://github.com/django-nonrel">Django-nonrel</a>, por exemplo, é uma ramificação independente que adiciona ao Django suporte a banco de dados NoSQL. Ele permite que aplicações do Django portáteis sejam escritas. Entretanto, a interface admin não funciona completamente. Além disso, não existe uma comunidade ativa de fato desenvolvendo o projeto.</p><p><a href="https://django-mongodb-engine.readthedocs.io/en/latest/" rel="noopener">Django MongoDB Engine</a> é outro <em>back-end</em> com MongoDB para Django, que é uma bifurcação do MongoEngine ODM.</p><h4 id="djongo-transpilador-de-django-sql-para-mongodb"><strong><a href="https://www.djongomapper.com/">Djongo</a> – transpilador de Django SQL para MongoDB</strong></h4><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_QpOq4GaUl_wX4_F6JYkQTA.png" class="kg-image" alt="1_QpOq4GaUl_wX4_F6JYkQTA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/1_QpOq4GaUl_wX4_F6JYkQTA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/1_QpOq4GaUl_wX4_F6JYkQTA.png 800w" sizes="(min-width: 720px) 720px" width="600" height="400" loading="lazy"><figcaption>Djongo — O transpilador de SQL para MongoDB</figcaption></figure><p>Outra abordagem é traduzir a sintaxe da consulta SQL gerada pelo ORM do Django em comandos do <code>pymongo</code>. O <a href="https://www.djongomapper.com/">Djongo</a> é um desses compiladores de consultas SQL para MongoDB. Ele traduz toda <em>string</em> de consulta SQL em um documento de consulta do mongoDB. O resultado é que todos os modelos do Django e modelos relacionados funcionam assim. Por conta disso, temos as seguintes vantagens:</p><ul><li><strong>Reuso dos modelos<strong> Djang</strong>o<strong>: </strong></strong>o Django é um <em>framework</em> estável em contínuo desenvolvimento e aprimoramento. O ORM do Django é um tanto quanto extenso e dotado de vários recursos . Definir um ORM de terceiros para trabalhar com o MongoDB significa reproduzir todo o ORM do Django novamente. O novo ORM precisa se alinhar constantemente com o ORM do Django. Diversas funcionalidades do Django nunca vão ser incluídas em um ORM de terceiros. A ideia com o Djongo é <strong>reutilizar </strong>recursos existentes do ORM do Django, traduzindo então consultas SQL para a sintaxe do MongoDB.</li><li><strong>A sintaxe do <strong>SQL</strong> nunca vai mudar:<strong> </strong></strong> independentemente de futuras adições no Django, com o Djongo, seu projeto não vai ter problemas no futuro!</li></ul><h4 id="fazendo-o-django-funcionar-com-o-mongodb"><strong>Fazendo o Django funcionar com o MongoDB</strong></h4><p><strong><strong>Emula</strong>ndo o esquema<strong> </strong>no<strong> MongoDB:</strong></strong> embora não haja suporte a esquemas no MongoDB, isso pode ser emulado. O Djongo fornece o suporte a esquemas necessário no Django, usando e definindo uma combinação de regras de validação do MongoDB e criando uma coleção <code>__schema__</code>. A coleção __schema__ armazena informações para suportar recursos como a chave SQL AUTOINCREMENT.</p><p><strong>Suporte a <strong>JOIN</strong> no<strong> MongoDB:</strong></strong> na versão 3.2, o MongoDB introduziu o operador <code>$lookup</code>. Ele realiza um <code>left outer join</code> com uma coleção no mesmo banco de dados para filtrar documentos da coleção "unida" (em inglês, <em>joined</em>) para processamento. A etapa de <code>$lookup</code> faz uma correspondência de igualdade entre um campo dos documentos de entrada e um campo dos documentos da coleção "unida".</p><p>Para cada documento de entrada, a fase de <code>$lookup</code> adiciona um campo array cujos elementos são os documentos correspondentes da coleção "unida". A fase de <code>$lookup</code> passa, então, &nbsp;esses documentos remodelados para a próxima etapa.</p><p>O Djongo usa o operador de agregação <code>$lookup</code> para realizar todas as consultas de JOIN relacionadas ao Django. É assim que ele faz o módulo admin e os outros módulos contrib funcionarem.</p><p><strong>Suporte a transações no<strong> MongoDB: </strong></strong>apesar do poder das operações atômicas de um único documento, existem casos onde transações multidocumento são necessárias. Ao se executar uma transação composta por operações sequenciais, certos problemas surgem, como nos casos em que, se operação falhar, a operação anterior dentro da transação precisa voltar a seu estado anterior — ou seja, &nbsp;"tudo ou nada".</p><p>Para situações que exigem transações multidocumento, o Djongo implementa o <a href="https://www.mongodb.com/docs/manual/core/transactions/">padrão de confirmação de duas fases</a> (documentação em inglês), fornecendo suporte para essas atualizações multidocumento. O uso de confirmação de duas fases garante a consistência dos dados e, em caso de erro , o estado que precedeu a transação pode ser recuperado.</p><p>O Djongo surgiu com seu próprio conjunto de preceitos, na verdade. Então, quais são as desvantagens de se optar pelo uso do Djongo em seu projeto Django?</p><p><strong>Desempenho<strong>:</strong></strong> o ORM do Django faz o trabalho pesado de converter manipulações complexas de objeto em strings de consulta no padrão SQL. Se o banco de dados do seu <em>back-end</em> fosse baseado em SQL, você poderia passar essa string de consulta diretamente para ele sem quase nenhum pós-processamento. Usando Djongo, entretanto, a string de consulta precisará ser convertida em um documento de consulta do MongoDB.</p><p>Isso vai exigir alguns ciclos de CPU. Porém, se ciclos adicionais de CPU são realmente um problema, você não deveria estar usando Python em primeiro lugar.</p><h4 id="conclus-o"><strong>Conclusão</strong></h4><p>Apresentei diversas maneiras de se integrar Django ao MongoDB. Você encontrará uma infinidade de literatura on-line descrevendo a MongoEngine e outras variantes para fazer isso.</p><p>Concentrei-me no <a href="https://www.djongomapper.com/">Djongo</a>, que é um novo conector que torna isso possível de uma maneira diferente, é fácil de usar e simplifica o processo de migração de um <em>back-end</em> com SQL para o MongoDB, <strong>adicionando apenas uma linha de código</strong>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como usar os buffers de protocolo do Google em Python ]]>
                </title>
                <description>
                    <![CDATA[ Quando as pessoas que falam idiomas diferentes estão juntas e conversam, elas tentam usar uma linguagem que todos do grupo possam entender. Para isso, todos precisam traduzir seus pensamentos, que normalmente estão na sua língua nativa, para todos do grupo. Essa "codificação e decodificação" do idioma, no entanto, leva a ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-usar-os-buffers-de-protocolo-do-google-em-python/</link>
                <guid isPermaLink="false">65a66ac70cfcc403cf789d0b</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Sabrina ]]>
                </dc:creator>
                <pubDate>Sun, 26 May 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/unnamed-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/googles-protocol-buffers-in-python/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Use Google's Protocol Buffers in Python</a>
      </p><p>Quando as pessoas que falam idiomas diferentes estão juntas e conversam, elas tentam usar uma linguagem que todos do grupo possam entender.</p><p>Para isso, todos precisam traduzir seus pensamentos, que normalmente estão na sua língua nativa, para todos do grupo. Essa "codificação e decodificação" do idioma, no entanto, leva a uma perda de eficiência, velocidade e precisão.<br><br>O mesmo conceito está presente nos sistemas do computador e em seus componentes. Por que deveríamos enviar dados em XML, JSON, ou em outra linguagem de humanos se não precisamos entender diretamente sobre o que eles estão falando? Basta que possamos traduzir para o formato da linguagem humana se precisarmos.<br><br>Os buffers de protocolo são uma forma de codificar dados antes do transporte, o que reduz de maneira eficiente os blocos de dados e, portanto, aumenta a velocidade de envio. Eles abstraem os dados em um formato neutro em termos de linguagem e plataforma.</p><h3 id="-ndice"><strong>Índice</strong></h3><ul><li><a href="https://www.freecodecamp.org/portuguese/news/como-usar-os-buffers-de-protocolo-do-google-em-python/#por-que-precisamos-dos-buffers-de-protocolo">Por que precisamos dos buffers de protocolo?</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-usar-os-buffers-de-protocolo-do-google-em-python/#o-que-s-o-os-buffers-de-protocolo-e-como-eles-funcionam">O que são os buffers de protocolo e como eles funcionam?</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-usar-os-buffers-de-protocolo-do-google-em-python/#buffers-de-protocolo-com-o-python">Buffers de protocolo com o Python</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-usar-os-buffers-de-protocolo-do-google-em-python/#considera-es-finais">Considerações finais</a></li></ul><h2 id="por-que-precisamos-dos-buffers-de-protocolo"><strong>Por que precisamos dos buffers de protocolo?</strong></h2><p>O objetivo inicial dos buffers de protocolos foi o de simplificar o trabalho com protocolos de solicitação/resposta. Antes do ProtoBuf, O Google usou um formato diferente para solicitação adicional de manipulação do <a href="https://pt.wikipedia.org/wiki/Marshalling">marshaling</a> para o envio de mensagens.</p><p>Além disso, as novas versões dos formatos anteriores exigiam que os desenvolvedores tivessem a certeza de que as novas versões fossem entendidas antes de substituir as antigas, tornando o trabalho com elas um problema. </p><p>Isso motivou a Google a projetar uma interface que resolvesse precisamente esses problemas.</p><p>Os buffers do protocolo permitem alterações no protocolo sem interferir na compatibilidade. Além disso, servidores podem transmitir os dados e executar operações de leitura nos dados sem modificar o conteúdo.</p><p>Como o formato se autodescreve, o ProtoBuf é usado como base para geração automática de código para serializadores e desserializadores.</p><p>Outro caso de uso interessante é como a Google o usa para <a href="https://searchapparchitecture.techtarget.com/definition/Remote-Procedure-Call-RPC">chamadas de procedimento remoto</a> (RPC – texto em inglês) de curta duração e para armazenar dados persistentemente na Bigtable. Devido ao seu caso de uso especifico, eles integraram interfaces de RPC aos buffers de protocolo. Isso permite a geração rápida e direta de códigos <em>stub</em> que podem ser usados como pontos de partidas para a implementação real (mais a respeito de ProtoBuf RPC <a href="https://medium.com/@EmperorRXF/evaluating-performance-of-rest-vs-grpc-1b8bdf0b22da">aqui</a> – texto em inglês).</p><p>Outros exemplos de onde o ProtoBuf pode ser usado são os dispositivos IoT conectados através de redes móveis, nas quais a quantidade de dados enviadas deve ser pequena ou para aplicações de países onde larguras de banda altas ainda são raras. O envio de cargas úteis, otimizada em formatos binários, pode levar a diferenças perceptíveis no custo e na velocidade de operação.</p><p>Usar a compactação <code>gzip</code> em sua comunicação por HTTPS pode melhorar ainda mais essas métricas.</p><h2 id="o-que-s-o-os-buffers-de-protocolo-e-como-eles-funcionam"><strong>O que são os buffers de protocolo e como eles funcionam?</strong></h2><p>De modo geral, os buffers de protocolo podem ser definidos como uma interface para serialização de dados estruturados. Isso define uma forma normalizada de comunicação, totalmente independente de linguagens e plataformas. </p><p>O Google anuncia o buffer de protocolo <a href="https://developers.google.com/protocol-buffers">como</a>:</p><blockquote><em>Buffers de protocolo são os mecanismo extensível, neutro em termos de linguagem e de plataforma do Google para serializar dados estruturados<em> – </em>pense no<em> XML, </em>mas menor<em>,</em> mais rápido e mais simples. Você define como deseja que seus dados sejam estruturados uma vez<em>…</em></em></blockquote><p>A interface ProtoBuf descreve a estrutura de dados a serem enviados. As estruturas de cargas útil são definidas como "mensagens" no que é chamado de Proto-Arquivo. Esses arquivos sempre terminam com a extensão <code>.proto</code><strong><strong> </strong></strong><br><br>Por exemplo, a estrutura básica de um arquivo <strong><strong>todolist.proto</strong></strong> é semelhante a que vemos a seguir. Também veremos um exemplo completo na próxima seção.</p><pre><code class="language-javascript">syntax = "proto3";

// Não é necessário para Python, ainda deve ser declarado para evitar colisões de nomes
// no namespace Protocol Buffers e em linguagens além do Python

package protoblog;

message TodoList {
   // Os elementos da lista de tarefas serão definidos aqui
      ...
}</code></pre><p>Esses arquivos são, então, usados para gerar classes de integração ou <em>stubs</em> para a linguagem de sua escolha usando geradores de código dentro do compilador protoc. A versão atual, Proto3, já suporta todas as principais linguagens de programação. A comunidade oferece suporte a muito mais implementações de código aberto de terceiros.</p><p>As classes geradas são os elementos principais dos buffers de protocolo. Eles permitem a criação de elementos instanciando novas mensagens, baseadas nos arquivos <code>.proto</code>, que são, então, utilizados para serialização. Veremos em detalhes como isso é feito com Python na próxima seção.</p><p>Independentemente da linguagem de serialização, as mensagens são serializadas em um formato binário, não auto descritivo, que é bastante inútil sem a definição inicial da estrutura.</p><p>Os dados binários podem, então, ser armazenados, enviados pela rede e usados de qualquer outra forma que os dados legíveis por humanos, como JSON ou XML, sejam. Após a transmissão ou armazenamento, o fluxo de bytes pode ser desserializado e restaurado usando <strong>qualquer</strong> classe protobuf compilada específica da linguagem que geramos a partir do arquivo .proto.<br><br>Usando Python como exemplo, o processo poderia ser mais ou menos assim:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/protobuf_arch.png" class="kg-image" alt="protobuf_arch" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/protobuf_arch.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/protobuf_arch.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/protobuf_arch.png 1600w" sizes="(min-width: 720px) 720px" width="1600" height="529" loading="lazy"></figure><p>Primeiro, criamos uma lista de tarefas e a preenchemos com algumas tarefas. Essa lista de tarefas é, então, serializada e enviada pela rede, salva em um arquivo ou armazenada persistentemente em um banco de dados.</p><p>O fluxo de bytes enviado é desserializado usando o método <em>parse</em> de nossa classe compilada específica da linguagem.<br><br>A maioria das arquiteturas e infraestruturas atuais, especialmente microsserviços, é baseada em comunicação REST, WebSockets ou GraphQL. No entanto, quando a velocidade e a eficiência são essenciais, os RPCs de baixo nível podem fazer uma enorme diferença.</p><p>Em vez de protocolos de alta sobrecarga, podemos usar uma forma rápida e compacta de mover dados entre as diferentes entidades para o nosso serviço sem desperdiçar muitos recursos.</p><h3 id="por-que-isso-ainda-n-o-usado-em-todos-os-lugares"><strong>P<strong>or que </strong>isso <strong>ainda não é usado em todos os lugares?</strong></strong></h3><p>Os buffers de protocolo são um pouco mais complicados do que outros formatos legíveis por humanos. Isso os torna comparativamente mais difíceis de depurar e integrar em suas aplicações.</p><p>Os tempos de iteração na engenharia também tendem a aumentar, pois as atualizações nos dados exigem a atualização dos arquivos proto antes do uso.</p><p>Considerações cuidadosas devem ser feitas, uma vez que o ProtoBuf pode ser uma solução com excesso de engenharia em muitos casos.</p><h3 id="que-alternativas-eu-tenho"><strong>Que alternativas eu tenho?</strong></h3><p>Vários projetos adotam uma abordagem semelhante aos buffers de protocolo do Google.</p><p>Os <a href="https://google.github.io/flatbuffers/">Flatbuffer</a> do Google e uma implementação de terceiros, chamada Cap’n Proto, estão mais focados em remover a etapa de análise e descompactação, que é necessária para acessar os dados reais ao usar ProtoBufs. Eles foram projetados explicitamente para aplicações de desempenho crítico, tornando-os ainda mais rápidos e mais eficientes em termos de memória do que o ProtoBuf.<br><br>Ao focar nos recursos RPC do ProtoBuf (usado com gRPC), existem projetos de outras grandes empresas como Facebook (Apache Thrift) ou Microsoft (protocolos Bond) que podem oferecer alternativas.</p><h2 id="buffers-de-protocolo-com-o-python"><strong>Buffers de protocolo com o Python</strong></h2><p>O Python já fornece algumas formas de persistência de dados usando decapagem. A decapagem é útil em aplicações que tenham somente Python. Ela não é adequada para cenários mais complexos onde está envolvido o compartilhamento de dados com outras linguagens ou a alteração de esquemas.<br><br>Os buffers de protocolo, por outro lado, são desenvolvidos exatamente para esses cenários. O arquivo <code>.proto</code>, que abordamos rapidamente antes, permite ao usuário gerar código para muitas linguagens suportadas.</p><p>Para compilar o arquivo <code>.proto</code> para a classe de linguagem de nossa escolha, usamos <strong>protoc</strong>, o compilador proto.<br><br>Se você não possui o compilador protoc instalado, existem excelentes guias sobre como fazer isso:</p><ul><li><a href="http://google.github.io/proto-lens/installing-protoc.html">MacOS/Linux</a> (em inglês)</li><li><a href="https://github.com/protocolbuffers/protobuf/blob/master/src/README.md#c-installation---windows">Windows</a> (em inglês)</li></ul><p>Depois de instalar o protoc em nosso sistema, podemos usar um exemplo estendido de nossa estrutura de lista de tarefas anterior e gerar a classe de integração Python a partir dele.</p><pre><code class="language-javascript">syntax = "proto3";

// Não necessário para o Python, mas ainda deve ser declarado para evitar colisões de nome 
// no namespace dos Buffers de Protocolo e em linguagens que não sejam o Python
package protoblog;

// O guia de estilo prefere a prefixação de valores de enum em vez de cercá-los
// com uma mensagem de fechamento
enum TaskState {
    TASK_OPEN = 0;
    TASK_IN_PROGRESS = 1;
    TASK_POST_PONED = 2;
    TASK_CLOSED = 3;
    TASK_DONE = 4;
}

message TodoList {
    int32 owner_id = 1;
    string owner_name = 2;

    message ListItems {
        TaskState state = 1;
        string task = 2;
        string due_date = 3;
    }

    repeated ListItems todos = 3;
}
</code></pre><p>Vamos dar uma olhada mais detalhada na estrutura do arquivo &nbsp;<code>.proto</code> &nbsp;para entendê-lo. Na primeira linha do arquivo proto, definimos se estamos usando Proto2 ou 3. Nesse caso, estamos usando <a href="https://developers.google.com/protocol-buffers/docs/proto3">Proto3</a>.</p><p>Os elementos mais incomuns dos arquivos proto são os números atribuídos a cada entidade de uma mensagem. Esses números dedicados tornam cada atributo único e são usados para identificar os campos atribuídos na saída codificada em binário.</p><p>Um conceito importante de se entender é que apenas os valores de 1 a 15 são codificados com um byte a menos (Hex), o que é útil de entender para que possamos atribuir números mais altos às entidades usadas com menos frequência. Os números <strong>não definem a ordem</strong> de codificação <strong>nem a posição</strong> do atributo fornecido na mensagem codificada.</p><p>A definição do pacote ajuda a evitar conflitos de nomes. Em Python, os pacotes são definidos por seu diretório. Portanto, fornecer um atributo de pacote não tem nenhum efeito no código em Python gerado.</p><p>Observe que os pacotes ainda devem ser declarados para evitar colisões de nomes relacionadas ao buffer de protocolo e para outras linguagens como Java.</p><p>Enumerações são listagens simples de valores possíveis para uma determinada variável. Nesse caso, definimos um Enum para os possíveis estados de cada tarefa na lista de tarefas. Veremos como usá-los daqui a pouco, quando observarmos o uso em Python.<br><br>Como podemos ver no exemplo, também podemos aninhar mensagens dentro de mensagens. Se quisermos, por exemplo, ter uma lista de todos os dados associados a uma determinada lista de tarefas, podemos usar a palavra-chave <strong>repeated</strong>, que é comparável a <em>arrays</em> de tamanho dinâmico .</p><p>Para gerar código de integração utilizável, usamos o compilador proto, que compila um determinado arquivo .proto em classes de integração específicas da linguagem. No nosso caso, usamos o argumento <strong><strong>--python-out</strong></strong> para gerar código específico em Python.</p><p><code>protoc -I=. --python_out=. ./todolist.proto</code></p><p>No terminal, invocamos o compilador do protocolo com três parâmetros:</p><ol><li><strong><strong>-I</strong></strong>: define o diretório onde procuramos quaisquer dependências (usamos <code>.</code>, que é o diretório atual)</li><li><strong><strong>--python_out</strong></strong>: define o local onde queremos gerar uma classe de integração do Python (novamente usamos <code>.</code>, que é o diretório atual)</li><li>O último <strong>parâmetro sem nome</strong> define o arquivo .proto que será compilado (usamos o arquivo todolist.proto, no diretório atual)</li></ol><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/protoc.png" class="kg-image" alt="protoc" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/protoc.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/protoc.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/protoc.png 1162w" sizes="(min-width: 720px) 720px" width="1162" height="602" loading="lazy"></figure><p>Isso cria um novo arquivo em Python chamado &lt;nome_do_arquivo_proto&gt;_pb2.py. No nosso caso, é todolist_pb2.py. Ao examinar esse arquivo mais de perto, não seremos capazes de entender muito sobre sua estrutura imediatamente.</p><p>Isso ocorre porque o gerador não produz elementos de acesso direto aos dados, mas abstrai ainda mais a complexidade usando metaclasses e descritores para cada atributo. Eles descrevem como uma classe se comporta em vez de cada instância dessa classe.<br><br>A parte mais interessante é como usar esse código gerado para criar, construir e serializar dados. Uma integração direta feita com nossa classe gerada recentemente é vista a seguir:</p><pre><code class="language-python">import todolist_pb2 as TodoList

my_list = TodoList.TodoList()
my_list.owner_id = 1234
my_list.owner_name = "Tim"

first_item = my_list.todos.add()
first_item.state = TodoList.TaskState.Value("TASK_DONE")
first_item.task = "Teste de ProtoBuf para o Python"
first_item.due_date = "31.10.2019"

print(my_list)</code></pre><p>Ele apenas cria uma lista de tarefas e adiciona um item a ela. Em seguida, imprimimos o próprio elemento da lista de tarefas e podemos ver a versão não binária e não serializada dos dados que acabamos de definir em nosso script.</p><pre><code class="language-json">owner_id: 1234
owner_name: "Tim"
todos {
  state: TASK_DONE
  task: "Teste de ProtoBuf para o Python"
  due_date: "31.10.2019"
}</code></pre><p>Cada classe <em>Protocol Buffer</em> possui métodos para ler e escrever mensagens usando uma &nbsp;<a href="https://developers.google.com/protocol-buffers/docs/encoding">codificação específica do buffer de protocolo</a> (texto em inglês), que codifica mensagens em formato binário. Esses dois métodos são <code>SerializeToString()</code> e <code>ParseFromString()</code>.</p><pre><code class="language-python">import todolist_pb2 as TodoList

my_list = TodoList.TodoList()
my_list.owner_id = 1234

# ...

with open("./serializedFile", "wb") as fd:
    fd.write(my_list.SerializeToString())


my_list = TodoList.TodoList()
with open("./serializedFile", "rb") as fd:
    my_list.ParseFromString(fd.read())

print(my_list)</code></pre><p>No exemplo de código acima, escrevemos a string serializada de bytes em um arquivo usando os sinalizadores <strong>wb</strong>.</p><p>Como já escrevemos o arquivo, podemos ler o conteúdo e analisá-lo usando ParseFromString. ParseFromString chama uma nova instância de nossa classe serializada usando os sinalizadores <strong>rb </strong>e a analisa.</p><p>Se serializarmos essa mensagem e se a imprimimos no console, obteremos a representação de bytes semelhante a esta.</p><p><code>b'\x08\xd2\t\x12\x03Tim\x1a(\x08\x04\x12\x18Teste de ProtoBuf para o Python\x1a\n31.10.2019'</code></p><p>Observe o b na frente das aspas. Isso indica que a string a seguir é composta de octetos de bytes em Python.</p><p>Se compararmos isso diretamente com, por exemplo, XML, podemos ver o impacto que a serialização do ProtoBuf tem no tamanho.</p><pre><code class="language-xml">&lt;todolist&gt;
	&lt;owner_id&gt;1234&lt;/owner_id&gt;
	&lt;owner_name&gt;Tim&lt;/owner_name&gt;
	&lt;todos&gt;
		&lt;todo&gt;
			&lt;state&gt;TASK_DONE&lt;/state&gt;
			&lt;task&gt;Teste de ProtoBuf para o Python&lt;/task&gt;
			&lt;due_date&gt;31.10.2019&lt;/due_date&gt;
		&lt;/todo&gt;
	&lt;/todos&gt;
&lt;/todolist&gt;</code></pre><p>A representação JSON, ajustada, ficaria assim.</p><pre><code class="language-json">{
	"todoList": {
		"ownerId": "1234",
		"ownerName": "Tim",
		"todos": [
			{
				"state": "TASK_DONE",
				"task": "Teste de ProtoBuf para o Python",
				"dueDate": "31.10.2019"
			}
		] 
	}
}</code></pre><p>Julgando os diferentes formatos apenas pelo número total de bytes utilizados, ignorando a memória necessária para o <em>overhead</em> de formatação, podemos obviamente ver a diferença.<br><br>Além da memória utilizada para os dados, no entanto, também temos <strong>12 bytes extras no ProtoBuf</strong> para formatação de dados serializados. Comparando isso com XML, temos <strong>171 bytes extras em XML</strong> para formatar dados serializados.</p><p>Sem um esquema, precisamos de <strong>136 bytes extras em JSON</strong> para formatar dados serializados.</p><p>Se estamos falando de milhares de mensagens enviadas pela rede ou armazenadas em disco, o ProtoBuf pode fazer a diferença.</p><p>Há uma questão importante, no entanto. A plataforma Auth0.com criou uma extensa comparação entre ProtoBuf e JSON. Ela mostra que, quando comprimido, a diferença de tamanho entre os dois pode ser mínima (apenas cerca de 9%).</p><p>Se você estiver interessado nos números exatos, consulte o <a href="https://auth0.com/blog/beating-json-performance-with-protobuf/">artigo completo</a> (em inglês), que fornece uma análise detalhada de vários fatores como tamanho e velocidade.</p><p>Uma observação interessante é que cada tipo de dados possui um valor padrão. Se os atributos não forem atribuídos ou alterados, eles manterão os valores padrão. No nosso caso, se não alterarmos o TaskState de um ListItem, ele terá o estado "TASK_OPEN" por padrão. A vantagem significativa disso é que os valores não definidos não são serializados, economizando espaço adicional.</p><p>Se, por exemplo, alterarmos o estado da nossa tarefa de TASK_DONE para TASK_OPEN, ela não será serializada.</p><pre><code class="language-json">owner_id: 1234
owner_name: "Tim"
todos {
  task: "Teste de ProtoBuf para o Python"
  due_date: "31.10.2019"
}</code></pre><p><code>b'\x08\xd2\t\x12\x03Tim\x1a&amp;\x12\x18Teste de ProtoBuf para o Python\x1a\n31.10.2019'</code></p><h2 id="considera-es-finais"><strong>Considerações finais</strong></h2><p>Como vimos, os buffers de protocolo são bastante úteis quando se trata de velocidade e eficiência ao trabalhar com dados. Devido à sua natureza poderosa, pode levar algum tempo para se acostumar com o sistema ProtoBuf, embora a sintaxe para definir novas mensagens seja simples.</p><p>Como última observação, quero salientar que houve/há discussões em andamento sobre a "utilidade" dos buffers de protocolo para aplicações regulares. Eles foram desenvolvidos explicitamente para problemas que o Google tinha em mente.<br><br>Se você tiver alguma dúvida ou <em>feedback</em>, sinta-se à vontade para entrar em contato com o autor em qualquer mídia social, como o <a href="https://twitter.com/timigrossmann">Twitter</a> ou por <a href="mailto:contact.timgrossmann@gmail.com">e-mail</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como aprender Python facilmente (e não do jeito que eu aprendi) ]]>
                </title>
                <description>
                    <![CDATA[ Acredita-se que o Python seja uma das linguagens de programação mais fáceis de aprender. Saber disso fez com que eu me sentisse muito mal na primeira vez que tentei e não consegui aprender. Foi ainda pior na segunda vez em que eu tentei. Acontece, no entanto — e eu só ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-aprender-python-facilmente-e-nao-do-jeito-que-eu-aprendi/</link>
                <guid isPermaLink="false">66454c681cbb6103cd309918</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Thu, 16 May 2024 00:39:39 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/matias-malka-TZIH-fDKzvY-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/learn-python-the-easy-way/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Learn Python The Easy Way (And Not the Way I Did)</a>
      </p><p>Acredita-se que o Python seja uma das linguagens de programação mais fáceis de aprender. Saber disso fez com que eu me sentisse muito mal na primeira vez que tentei e não consegui aprender. Foi ainda pior na segunda vez em que eu tentei.</p><p>Acontece, no entanto — e eu só aprendi isso na terceira tentativa — que o Python pode ser bastante acessível, mesmo para um amante da área de humanidades e não programador como eu. Baste que você aborde a linguagem do modo certo.</p><h2 id="como-eu-n-o-consegui-aprender-python-na-primeira-tentativa"><strong>Como eu não consegui aprender Python… na primeira tentativa</strong></h2><p>A primeira vez em que tentei aprender Python foi há quase uma década. Eu não tinha certeza do que eu queria fazer com ele – talvez automatizar parte do meu trabalho, talvez escrever uma aplicação pequena. Parecia apenas uma habilidade que seria bom saber.</p><p>Então, eu peguei uma cópia do livro <em><em>Learn Python the Hard Way</em></em> (Aprenda Python da maneira difícil, eu português) em PDF e comecei a tentar ler do início ao fim.</p><p>A primeira barreira que encontrei foi configurar o Python no meu próprio sistema. Especialmente naquela época, a maioria das instruções sobre como fazer isso estavam escritas para programadores experientes. Eu levei uma eternidade para passar por tudo.</p><p>Eu queria aprender a escrever código em Python. Meu primeiro passo foi passar cinco horas lutando com a linha de comando. Eu estava desmotivado antes mesmo de começar.</p><p>Quando, finalmente, consegui configurar tudo, pude escrever código junto com o livro. Eu fiz isso, por um tempo, criando lentamente um jogo de aventura de texto muito simples.</p><p>Porém, quando cheguei no meu primeiro desafio real – aqueles momentos que sempre vêm na programação em que algo não funciona e você simplesmente não consegue descobrir o porquê – eu desisti.</p><p>Eu tinha coisas mais importantes para fazer do que bater a cabeça contra o teclado e desvendar um quebra-cabeça de mensagens de erro inescrutáveis, especialmente quando meu objetivo final era fazer um jogo de aventura de texto com o qual eu não me importava e que ninguém jamais jogaria.</p><h2 id="como-eu-n-o-consegui-aprender-python-na-segunda-tentativa"><strong>Como eu não consegui aprender Python… na segunda tentativa</strong></h2><p>Alguns anos depois, tentei novamente. Naquela época, eu estava trabalhando como jornalista e me interessei por jornalismo de dados e, em particular, por <em>web scraping</em>.</p><p>Eu sabia que ter habilidades de programação em Python seria necessário, então encontrei uma plataforma de educação <em>on-line</em> – não vou dizer qual – e comecei um curso de Python para iniciantes.</p><p>Como a maioria dos MOOCs (<em>Massive Open Online Course</em>, ou, em português, curso on-line aberto e para o grande público), este curso foi baseado em vídeo. Eu assistia a uma aula sobre um tópico relacionado ao Python, respondia a um questionário no site do curso para confirmar que havia aprendido o assunto e, em seguida, passava para o próximo módulo.</p><p>Programadores experientes provavelmente já podem adivinhar o que aconteceu a seguir: quando fui tentar escrever código em Python para mim, não consegui fazer nada.</p><p>Ver outra pessoa programar em vídeos e ouvir suas explicações me fez achar que estava aprendendo a fazer isso por mim mesmo. Os testes de múltipla escolha e preenchimento de espaços em branco que eu estava respondendo 100% corretamente pareciam confirmar que eu havia entendido o assunto.</p><p>Naturalmente, na hora de aplicar por conta própria, não consegui. Eu podia assistir os vídeos do início ao fim e copiar o que o professor fazia, mas tinha muita dificuldade em aplicar qualquer coisa que eu tinha aprendido aos meus próprios projetos.</p><p>Também foi difícil me manter motivado, porque eu estava trabalhando em coisas que não pareciam relevantes.</p><p>Eu queria aprender <em>web scraping</em>. Em vez disso, eu estava lutando para entender as videoaulas sobre o conceito de programação orientada a objetos (OOP). O que isso tem a ver com meus objetivos? Eu não tinha certeza, e isso facilitou a desistência mais uma vez.</p><h2 id="por-que-eu-n-o-consegui"><strong>Por que eu não consegui?</strong></h2><p>Olhando para trás, não é muito difícil descobrir o porquê. Na primeira vez, meus grandes erros foram:</p><ol><li><strong><strong>N</strong>ã<strong>o</strong> ter um objetivo claro</strong>. Por que eu estava aprendendo Python? Eu realmente não sabia. Isso torna muito fácil desistir quando as coisas ficam difíceis – o que sempre acontecerá, mais cedo ou mais tarde.</li><li><strong>Muitos desafios logo de início</strong>. Mais cedo ou mais tarde, eu teria de aprender a absorver o Python de algum jeito, mas configurar tudo tendo <em><em>zero</em></em> de experiência, mesmo antes de ter escrito um simples <code>print("Olá, mundo!")</code> Foi tudo o que eu precisava para não conseguir aprender e desistir.</li></ol><p>Quando você está aprendendo algo desafiador, especialmente quando se está começando do zero, você precisa de sucesso cedo para ajudá-lo a acreditar que você pode realmente fazer isso.</p><p>Começar com um desafio frustrante que nem envolvia a programação em si garantiu que eu não conseguisse aquelas vitórias precoces motivadoras e afirmativas.</p><p>Na segunda vez, eu evitei esses erros, mas acabei cometendo erros novos:</p><ol><li><strong>Eu não estava aprendendo através da prática<strong>. </strong></strong>Assistir a vídeos e passar em testes estava me fazendo <em>sentir</em> que poderia programar, mas, na verdade, eu não estava programando. Quando eu <em>tentei </em>(e não consegui) escrever código, foi ainda mais frustrante porque eu achava que já entendia. Além disso, eu tive que clicar diversas vezes em cada vídeo para reassistir a seções diferentes e reaprender as coisas.</li><li><strong>Eu tinha um objetivo claro<strong>, </strong>mas não um caminho claro para chegar a ele<strong>.</strong></strong> Eu sabia que queria fazer jornalismo de dados e <em>web scraping</em>, mas estava fazendo um curso genérico de Python. Isso significava que eu estava aprendendo lições que poderiam ter sido fundamentais para o desenvolvimento de software, mas não eram tão relevantes para o jornalismo de dados. Muitas vezes, tive dificuldade em conectar os fundamentos que estava aprendendo nas aulas com o que eu realmente queria estar fazendo com o código.</li></ol><p>Ao longo de tudo isso, eu também estava cometendo outro grande erro mental. Eu estava pensando em aprender Python como se fosse oito ou oitenta. Eu tinha "aprendido Python" – tudo de Python – ou não tinha.</p><p>Isso tornou a perspectiva de aprendizado realmente intimidante. Sempre que eu chegava em um desafio, tudo ficava pior pelo fato de que eu estava pensando em alguma "linha de chegada" imaginária do Python que ainda estava muito, <em>muito</em> longe.</p><p>Isso é um erro, é claro. Assim como ocorre com um idioma, Python (e outras linguagens de programação) não são algo que você realmente <em>termine </em>de aprender. Da mesma maneira que os idiomas, você não precisa ser fluente em Python para fazer coisas com ele.</p><p>Como qualquer intercambista do primeiro ano pode confirmar, a simples capacidade de perguntar "Quanto isso custa?" e "Onde fica o banheiro?" no idioma local pode <em>realmente </em>afetar sua qualidade de vida.</p><p>A mesma coisa vale para o Python. Você não precisa saber <em>tudo</em> – nem mesmo <em>tanto</em>, necessariamente – para que isso faça uma diferença real em sua própria vida.</p><p>Essa, porém, é uma lição que só aprendi por acaso.</p><h2 id="como-eu-aprendi-de-fato-alguma-coisa-de-python"><strong>Como eu aprendi, de fato, (alguma coisa de) Python</strong></h2><p>Em 2018, eu já havia desistido de aprender Python. Eu tinha tentado duas vezes e não conseguido duas vezes! Fui, então, contratado pela Dataquest, uma empresa que ensina habilidades em ciência de dados – incluindo programação em Python – <em>on-line</em>.</p><p>Meu novo emprego não exigia nenhuma habilidade em programação, mas achei que ainda precisava dar uma chance à plataforma de aprendizagem. Eu precisava entender nosso produto e o que nossos alunos sentiam que estavam experimentando. Talvez, pensei, eu pudesse até aprender o suficiente para fazer algum <em>web scraping</em>, como eu tinha planejado antes.</p><p>Então, com alguma apreensão, criei uma conta e iniciei meu caminho de curso de Python para Ciência de Dados.</p><p>Para minha surpresa, parecia divertido e fácil. Para minha maior surpresa, não demorou muito para que eu sentisse que podia criar alguns projetos por conta própria.</p><p>Eu escrevi um <em>script</em> pequeno para classificar e-mails. Eu usei Python para analisar rapidamente alguns dados de pesquisa. Aos trancos e barrancos, construí o grande projeto de <em>web scraping</em> e análise com o qual sonhava quando era jornalista.</p><p>Eu estava – e ainda estou – usando Python para facilitar meu trabalho e melhorar minha vida. Alguns anos depois, ainda sou um programador novato, mas posso criar <em>scripts</em> pequenos para facilitar as coisas e resolver problemas de análise de dados que tenho no trabalho usando Python.</p><p>Isso aconteceu porque, mais por acaso do que por planejamento de fato, eu havia me deparado com uma maneira de aprender Python que evitava quase todos os erros que eu havia cometido com meus esforços anteriores:</p><ul><li>Eu comecei com um objetivo claro – aprender Python o suficiente para ser capaz de trabalhar um pouco com dados para que eu pudesse entender melhor nossos clientes.</li><li>Eu evitei o desafio inicial de instalar o Python completamente, porque a Dataquest permite que você aprenda e escreva código diretamente em uma janela do navegador.</li><li>Eu estava aprendendo a programar escrevendo código em vez de ver outra pessoa fazendo isso.</li><li>Eu estava aprendendo em uma trilha projetada para o trabalho com dados em Python, especificamente. Então, tudo o que eu estava aprendendo e cada exercício que eu fazia parecia relevante.</li><li>Eu estava simplesmente tentando aprender o que <em>eu</em> precisava, em vez de tentar aprender tudo em Python.</li></ul><h2 id="como-tornar-o-aprendizado-de-python-mais-f-cil"><strong>Como tornar o aprendizado de Python mais fácil</strong></h2><p>Olhando para os meus erros e, depois, para o meu sucesso acidental, acho que tudo se resume a algumas conclusões simples:</p><p>Primeiro, começar tendo um objetivo. Por que você quer aprender Python? O que, especificamente, você quer criar com ele? Se você não tiver uma boa resposta para essa pergunta, será muito difícil se manter motivado.</p><p>Em segundo lugar, encontre uma maneira de aprender fazendo o que você realmente quer fazer. Se você puder encontrar um recurso de aprendizado direcionado, como uma plataforma que ensina Python especificamente para desenvolvimento de jogos, isso é ótimo. Os recursos gerais de aprendizagem, no entanto, também podem funcionar, desde que você esteja aplicando o que aprendeu com <a href="https://www.dataquest.io/blog/python-projects-for-beginners/">alguns projetos para iniciantes em Python</a> (link em inglês) enquanto estuda.</p><p>Aprender a programar tem que incluir realmente escrever código – e tem que ser realmente código que faz algo em que você está interessado.</p><p>Em terceiro lugar, evite o desafio inicial de configurar o Python e suas várias bibliotecas em seu sistema local.</p><p>Existem muitas plataformas <em>on-line</em> agora que permitem que você escreva e execute código em um navegador, ou você pode escrever e executar código em um <em>notebook</em> no <a href="https://colab.research.google.com/notebooks/intro.ipynb">Google Colab</a> ou em uma plataforma semelhante. Apenas tente tornar o início o mais fácil possível. Você pode se preocupar com sua configuração local mais tarde.</p><p>Em quarto lugar, não tente "aprender Python". Esse é um objetivo enorme, de longo prazo, que é indiscutivelmente meio inatingível – mesmo os melhores desenvolvedores de Python não sabem literalmente tudo sobre ele.</p><p>Em vez disso, tente aprender a usar Python para criar uma versão simples do projeto que é o seu objetivo, ou uma parte desse projeto. Em seguida, aprenda a usar Python para aumentar esse projeto ou como passar para a próxima etapa.</p><p>Divida grandes tarefas em partes menores e concentre seus objetivos em construir algo para que dê a você a recompensa psicológica de ter construído algo atingir um objetivo.</p><p>Siga estas dicas independentemente do seu motivo pessoal para aprender Python e não tenho dúvidas de que você será capaz de alcançar seus objetivos sem ter que falhar e desistir duas vezes ao longo do seu caminho!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Os melhores tutoriais de Python ]]>
                </title>
                <description>
                    <![CDATA[ > Traduzido em português europeu. O Python [https://www.python.org/] é uma linguagem de programação de utilização geral, que é escrita e interpretada dinamicamente, conhecida pela sua fácil legibilidade com ótimos princípios de design. O freeCodeCamp tem um dos cursos mais populares sobre Python. É completamente gratuito (e também não tem quaisquer ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/os-melhores-tutoriais-em-python/</link>
                <guid isPermaLink="false">653f765441517403e4ea52c6</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Afonso Branco ]]>
                </dc:creator>
                <pubDate>Wed, 01 May 2024 01:50:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/5f9c9ef5740569d1a4ca4014.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/best-python-tutorial/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Best Python Tutorials</a>
      </p><blockquote>Traduzido em português europeu.</blockquote><p>O <a href="https://www.python.org/" rel="nofollow">Python</a> é uma linguagem de programação de utilização geral, que é escrita e interpretada dinamicamente, conhecida pela sua fácil legibilidade com ótimos princípios de design.</p><p>O freeCodeCamp tem um dos cursos mais populares sobre Python. É completamente gratuito (e também não tem quaisquer anúncios, basta estar conectado à plataforma). Podes, também, <a href="https://www.youtube.com/watch?v=rfscVS0vtbw">assistir ao curso no YouTube</a>.</p><h2 id="queres-aprender-mais"><strong>Queres aprender mais<strong><strong>?</strong></strong></strong></h2><p>A internet é um sítio vasto, existe muito mais para explorar (links em inglês):</p><ul><li>Livro prático de Python: <a href="http://anandology.com/python-practice-book/index.html">http://anandology.com/python-practice-book/index.html</a></li><li>Pensa em Python: <a href="http://greenteapress.com/thinkpython/html/index.html">http://greenteapress.com/thinkpython/html/index.html</a></li><li>Python prático para negócios: <a href="http://pbpython.com/">http://pbpython.com/</a></li><li>Outro curso: <a href="https://realpython.com/?utm_source=fsp&amp;utm_medium=promo&amp;utm_campaign=bestresources">https://realpython.com/?utm<em><em>source=fsp&amp;utm</em></em>medium=promo&amp;utm_campaign=bestresources</a></li><li>Generalidade: <a href="https://www.fullstackpython.com/">https://www.fullstackpython.com/</a></li><li>Aprenda os fundamentos: <a href="https://www.codecademy.com/learn/learn-python">https://www.codecademy.com/learn/learn-python</a></li><li>Ciência computacional utilizando Python: <a href="https://www.edx.org/course/introduction-computer-science-mitx-6-00-1x-11?ref=hackernoon#!">https://www.edx.org/course/introduction-computer-science-mitx-6-00-1x-11?ref=hackernoon#!</a></li><li>Lista de mais recursos para aprender Python: <a href="https://github.com/vinta/awesome-python">https://github.com/vinta/awesome-python</a></li><li>Python interativo: <a href="http://interactivepython.org/runestone/static/thinkcspy/index.html">http://interactivepython.org/runestone/static/thinkcspy/index.html</a></li><li>Manual do programador para Python: <a href="https://devguide.python.org/">https://devguide.python.org/</a></li></ul><h2 id="para-que-utilizado-o-python"><strong>Para que é utilizado o<strong><strong> Python?</strong></strong></strong></h2><p>O Python pode ser facilmente utilizado para projetos pequenos, grandes, on-line e off-line. As melhores opções para utilizar Python são a programação para a web, criação simples de <em>scripts</em> e análise de dados. Abaixo estão alguns exemplos do que o Python permitirá fazer:</p><h5 id="programa-o-para-a-web-"><strong>Programação para a w<strong><strong>eb:</strong></strong></strong></h5><p>Podes utilizar o Python para criar aplicações para a web de vários níveis de complexidade. Existem muitas <em>frameworks</em> de Python para a web, incluindo Pyramid, Django e Flask, para mencionar algumas.</p><h5 id="an-lise-de-dados-"><strong>Análise de dados<strong><strong>:</strong></strong></strong></h5><p>O Python é a principal escolha em termos de linguagem para muitos cientistas de dados. O Python cresceu em popularidade neste ramo devido à disponibilidade de várias bibliotecas excelentes focadas em ciências de dados (das quais, NumPy e Pandas são duas das mais conhecidas) e visualização de dados (como Matplotlib e Seaborn). O Python tornou o processamento de dados interessante com todas as suas inúmeras bibliotecas disponíveis. Ipython com JupyterLab é outra forma de Python que melhora a utilização de Python no ramo da ciência de dados.</p><h5 id="automatiza-o-"><strong><strong><strong>Automati</strong></strong>zação<strong><strong>:</strong></strong></strong></h5><p>Python é uma linguagem muito flexível que pode ser utilizada para automatizar tarefas aborrecidas e repetitivas. Administradores de sistemas utilizam-na geralmente ao escrever scripts que podem ser facilmente executados no terminal. O Python também pode ser utilizado para criar <em>bots</em> que automatizam algumas das nossas tarefas diárias.</p><h5 id="intelig-ncia-artificial-"><strong>Inteligência artificial<strong><strong>:</strong></strong></strong></h5><p>O Python também é utilizado extensivamente no ramo emergente da Inteligência Artificial (IA). A Google selecionou o Python como uma das primeiras linguagens de programação bem suportadas para treinar e interagir com modelos, utilizando o Tensorflow.</p><h4 id="desenvolvimento-de-aplica-es-para-dispositivos-m-veis"><strong>Desenvolvimento de aplicações para dispositivos móveis</strong></h4><p>Podem ser criadas aplicações para dispositivos móveis e jogos com Python através da utilização de Kivy, Pygame e PyQt.</p><h4 id="seguran-a-e-rede-"><strong>Segurança e rede<strong><strong>:</strong></strong></strong></h4><p>O Python é utilizado para criar ferramentas de rede e segurança que são utilizadas amplamente. A automatização remota do Python é a mais segura, rápida e eficaz para testes de <em>frameworks </em>na <em>cloud</em>. É por isso que programadores profissionais utilizam Python para criar as <em>frameworks </em>mais seguras e para programação de sockets.</p><h5 id="machine-learning-deep-learning"><strong><strong><strong>Machine Learning, Deep Learning</strong></strong></strong></h5><p>Python é uma das melhores linguagens adequadas para <em>machine learning</em>, <em>deep learning</em> e análises de dados, com uma forte eficácia em todos eles.</p><p>Existem linguagens especializadas mais adequadas para vários papéis, como R e MATLAB, mas, no que diz respeito a combinar vários ramos de aplicações, o Python vence facilmente devido à sua flexibilidade, rápida criação de protótipos e disponibilidade de bibliotecas.</p><h4 id="desenvolvimento-de-bots-para-o-telegram"><strong>Desenvolvimento de bots para o <strong><strong>Telegram</strong></strong></strong></h4><p>Podes utilizar Python e algumas bibliotecas do Python para desenvolver os teus próprios <a href="https://core.telegram.org/bots" rel="nofollow">Bots do Telegram</a> (link em inglês).</p><h4 id="obten-o-de-dados-atrav-s-de-gathering-e-scraping"><strong>Obtenção de dados através de<strong><strong> </strong></strong><em>g</em><strong><strong><em>athering</em> </strong></strong>e<strong><strong> <em>scraping</em></strong></strong></strong></h4><p>O Python também pode ser utilizado para analisar o código-fonte das páginas e obter a sua informação. Utilizar alguns módulos do Python, tais como o Scrapy e também (para algumas páginas que utilizam JavaScript) o Selenium deve resolver o problema!</p><h4 id="o-python-geralmente-utilizado-para-"><strong>O <strong><strong>Python é</strong></strong> geralmente utilizado para:</strong></h4><ul><li>Desenvolvimento para a web e Internet</li><li>Progresso educacional</li><li>Estudos/computações científicos</li><li>Desenvolvimento para desktop</li><li>Computação numérica</li><li>Desenvolvimento de software</li><li>Desenvolvimento de aplicações empresariais</li><li>Machine Learning</li><li>IOT (Internet Of Things)</li><li>Desenvolvimento de jogos</li><li>Prototipagem rápida</li><li>Automatização de browser</li><li>Análise de dados</li><li>Obter dados de websites</li><li>Processamento de imagens</li></ul><h4 id="alguns-artigos-que-abordam-a-utilidade-do-python"><strong>Alguns artigos que abordam a utilidade do<strong><strong> python</strong></strong></strong></h4><ul><li><a href="http://www.dummies.com/programming/python/10-major-uses-of-python/" rel="nofollow">10 Major Uses of Python</a> (10 principais utilizações do Python, link em inglês)</li><li><a href="https://www.python.org/about/apps/" rel="nofollow">Applications for Python</a> (Aplicações para Python, link em inglês)</li><li><a href="https://stackoverflow.com/questions/3043085/where-is-python-language-used" rel="nofollow">Where is the Python Language Used?</a> (Onde é utilizada a linguagem Python?, link em inglês)</li><li><a href="https://stackoverflow.com/questions/1909512/what-is-python-used-for" rel="nofollow">What is Python used for?</a> (Para que é utilizado o Python?, link em inglês)</li></ul><p>O índice oficial de pacotes para o Python está <a href="https://pypi.python.org/pypi" rel="nofollow">aqui</a> (link em inglês).</p><h2 id="deves-utilizar-python-2-ou-python-3"><strong>Deves utilizar<strong><strong> Python 2 o</strong></strong>u<strong><strong> Python 3?</strong></strong></strong></h2><p>As duas versões são semelhantes. Se conheceres uma delas, trocar para escrever código na outra é fácil.</p><ul><li><a href="https://www.python.org/dev/peps/pep-0373/" rel="nofollow">Python 2.x não recebe mais manutenção desde 2020</a> (link em inglês).</li><li>3.x está em desenvolvimento ativo. Isto quer dizer que todas as melhorias recentes de bibliotecas predefinidas, por exemplo, estão apenas disponíveis por defeito na versão Python 3.x.</li><li>O ecossistema do Python acumulou uma quantidade significativa de software de qualidade ao longo dos anos. A desvantagem de quebrar a compatibilidade com versões anteriores ao 3.x é que alguns desses softwares (especialmente software interno em empresas) ainda não funcionam na versão 3.x.</li></ul><h2 id="instala-o"><strong>Instalação</strong></h2><p>A maior parte dos sistemas operativos com base *nix já trazem o Python instalado (geralmente o Python 2, ou Python 3 nos mais recentes). Substituir a instalação predefinida do Python no teu sistema não é recomendado e pode causar problemas. No entanto, podem ser instaladas diferentes versões do Python em segurança, juntamente com a versão predefinida do teu sistema. Ver <a href="https://docs.python.org/3/using/index.html" rel="nofollow">Configuração do Python e utilização</a> (link em inglês).</p><p>O Windows não vem com o Python instalado, mas o instalador e as instruções de instalação podem ser encontradas <a href="https://docs.python.org/3/using/windows.html" rel="nofollow">aqui</a> (link em inglês).</p><h2 id="int-rprete-de-python"><strong>Intérprete de <strong><strong>Python</strong></strong></strong></h2><p>O intérprete de Python é o que é utilizado para executar scripts de Python.</p><p>Se este estiver disponível e no caminho de pesquisa da linha da shell do Unix, é possível iniciá-lo ao escrever o comando <code>python</code>, seguido pelo nome do script. Isto invocará o intérprete e executar o script.</p><p><code>hello_campers.py</code></p><pre><code class="language-python">print('Hello campers!')</code></pre><p>A partir do terminal:</p><pre><code class="language-text">$ python hello_campers.py
Hello campers!</code></pre><p>Quando estão instaladas várias versões do Python, é possível chamar o intérprete por versão, dependendo da configuração da instalação. No ambiente personalizado do IDE Cloud9, podem ser invocados da seguinte forma:</p><pre><code class="language-text">$ python --version
Python 2.7.6
$ python3 --version
Python 3.4.3
$ python3.5 --version
Python 3.5.1
$ python3.6 --version
Python 3.6.2 
$ python3.7 --version
Python 3.7.1</code></pre><h2 id="modo-interativo-do-int-rprete-de-python"><strong>Modo interativo do intérprete de <strong><strong>Python</strong></strong></strong></h2><p>O modo interativo pode ser iniciado ao invocar o intérprete de Python com a flag <code>-i</code> ou sem qualquer argumento.</p><p>O modo interativo tem uma <em>prompt</em> onde podem ser inseridos e executados comandos de Python:</p><pre><code class="language-text">$ python3.5
Python 3.5.1 (default, Dec 18 2015, 00:00:00)
GCC 4.8.4 on linux
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; print("Hello campers!")
Hello campers!
&gt;&gt;&gt; 1 + 2
3
&gt;&gt;&gt; exit()
$</code></pre><h2 id="o-zen-do-python"><strong>O<strong><strong> Zen </strong></strong>do<strong><strong> Python</strong></strong></strong></h2><p>Alguns dos princípios que influenciaram o design do Python estão incluídos como extra e podem ser lidos ao utilizar o comando dentro do modo interativo do intérprete de Python:</p><pre><code class="language-text">&gt;&gt;&gt; import this
O Zen do Python, escrito por Tim Peters

Bonito é melhor que feio.
Explícito é melhor que implícito.
Simples é melhor que complexo.
Complexo é melhor que complicado.
Linear é melhor do que aninhado.
Esparso é melhor que denso.
Legibilidade conta.
Casos especiais não são especiais o bastante para quebrar as regras.
Ainda que praticidade vença a pureza.
Erros nunca devem passar silenciosamente.
A menos que sejam explicitamente silenciados.
Diante da ambiguidade, recuse a tentação de adivinhar.
Deveria haver um — e preferencialmente só um — modo óbvio para fazer algo.
Embora esse modo possa não ser óbvio a princípio a menos que você seja holandês.
Agora é melhor que nunca.
Embora nunca frequentemente seja melhor que já.
Se a implementação é difícil de explicar, é uma má ideia.
Se a implementação é fácil de explicar, pode ser uma boa ideia.
Namespaces são uma grande ideia — vamos ter mais dessas!</code></pre><h2 id="pr-s-e-contras-do-python"><strong><strong><strong>Prós </strong></strong>e contras do<strong><strong> Python</strong></strong></strong></h2><h3 id="pr-s"><strong><strong><strong>Prós</strong></strong></strong></h3><ol><li>Linguagem interativa com suporte de módulo para quase todas as funcionalidades.</li><li>Código aberto: portanto, podes contribuir para a comunidade com as funções que desenvolveres para utilização futura e para ajudar outros.</li><li>Muitos bons intérpretes e notebooks disponíveis para uma melhor experiência, como o Jupyter Notebook.</li></ol><h4 id="contras"><strong>Contras</strong></h4><ol><li>Sendo de código aberto, foram desenvolvidas muitas formas diferentes das mesmas funções ao longo dos anos. Isso, por vezes, cria caos quando outras pessoas leem o código de outra pessoa.</li><li>É uma linguagem lenta. Por isso, é uma linguagem muito má para desenvolver algoritmos comuns.</li></ol><h2 id="documenta-o"><strong><strong><strong>Documenta</strong></strong>ção</strong></h2><p>O <a href="https://docs.python.org/3/" rel="nofollow">Python está bem documentado</a> (link em inglês). Esses documentos incluem tutoriais, guias, referências e informações chave da linguagem.</p><p>Outra referência importante são as <em>Python Enhancement Proposals</em> (<a href="https://www.python.org/dev/peps/" rel="nofollow">PEPs</a> –Propostas de Melhoria do Python, em português). Incluído nas PEPs está um guia de estilos para escrever código Python, o <a href="https://www.python.org/dev/peps/pep-0008/" rel="nofollow"><code>PEP 8</code></a> (link em inglês).</p><h2 id="depura-o"><strong>Depuração</strong></h2><p>Podem ser utilizadas instruções <code>print</code> em linha para depurações simples:</p><blockquote><strong><strong><strong><strong>… </strong></strong></strong>por vezes, a forma mais rápida de depurar um programa é adicionar algumas instruções<strong><strong><strong> print </strong></strong></strong>ao código<strong><strong><strong>: </strong></strong></strong>o ciclo rápido de <strong><strong><strong>edi</strong></strong></strong>ção<strong><strong><strong>-test</strong></strong></strong>e<strong><strong><strong>-de</strong></strong></strong>puração<strong><strong><strong> </strong></strong></strong>torna esta abordagem muito eficaz<strong><strong><strong>.</strong></strong></strong></strong><br><br><a href="https://www.python.org/doc/essays/blurb/" rel="nofollow">Sumário executivo</a> (link em inglês)</blockquote><p>O Python também inclui ferramentas mais potentes para depuração, tais como:</p><ul><li>módulo de registo, <a href="https://docs.python.org/3/library/logging.html" rel="nofollow"><em><em>logging</em></em></a><em> </em>(link em inglês)</li><li>módulo de depuração, <a href="https://docs.python.org/3/library/pdb.html" rel="nofollow"><em><em>pdb</em></em></a><em> </em>(link em inglês)</li></ul><p>Por enquanto, tem apenas em mente que elas existem.</p><h2 id="ol-mundo-"><strong>Olá, mundo<strong><strong>!</strong></strong></strong></h2><p>Voltando à documentação, podemos ler sobre a função <a href="https://docs.python.org/3/library/functions.html#print" rel="nofollow"><code>print</code></a>, uma <a href="https://docs.python.org/3/library/functions.html" rel="nofollow"><em>função integrada</em></a><em> </em>(link em inglês) da <a href="https://docs.python.org/3/library/index.html" rel="nofollow">Biblioteca Predefinida do Python</a> (link em inglês).</p><pre><code class="language-text">print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)</code></pre><p>As funções integradas estão listadas por ordem alfabética. O nome é seguido por uma lista entre parênteses de parâmetros formais com valores predefinidos opcionais. Por baixo disso, é fornecida uma breve descrição da função e dos seus parâmetros e existe, ocasionalmente, um exemplo.</p><p>A função <a href="https://docs.python.org/3/library/functions.html#print" rel="nofollow"><code>print</code></a> do Python 3 substitui a instrução <a href="https://docs.python.org/2/reference/simple_stmts.html#print" rel="nofollow"><code>print</code></a> do Python 2.</p><pre><code class="language-text">&gt;&gt;&gt; print("Olá, mundo!")
Olá, mundo!</code></pre><p>Uma função é chamada quando o nome da função é seguido por <code>()</code>. Para o exemplo Olá, mundo!, a função <em>print</em> é chamada com uma string como argumento para o primeiro parâmetro. Para os restantes parâmetros, são utilizados os valores predefinidos.</p><p>O argumento com que chamamos a função <code>print</code> é um objeto <code>str</code>, ou <em><em>string</em></em>, um dos <em><a href="https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str" rel="nofollow">tipos integrados</a> </em>do<em> </em>Python. Além disso, a coisa mais importante sobre Python é que não precisas de especificar o tipo de dados quando declaras uma variável. O compilador do Python, ele próprio, fará isso com base no tipo do valor atribuído.</p><p>O parâmetro <code>objects</code> tem um <code>*</code> como prefixo, que indica que a função receberá um número arbitrário de argumentos para esse parâmetro.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como embutir visualizações interativas em seu site com Python e Matplotlib ]]>
                </title>
                <description>
                    <![CDATA[ Em um tutorial anterior do freeCodeCamp, expliquei como criar visualizações de dados com atualizações automáticas em Python [https://www.freecodecamp.org/news/how-to-create-auto-updating-data-visualizations-in-python-with-matplotlib-and-aws/]  (texto em inglês). Alguns leitores perguntaram se havia algum modo de tornar as visualizações interativas. Felizmente, uma solução fácil já está disponível! Neste tutorial, vou ensinar como você pode criar visualizações ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-embutir-visualizacoes-interativas-em-seu-site-com-python-e-matplotlib/</link>
                <guid isPermaLink="false">650995fcade67a03f81e5383</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isabel Cristina Nunes de Sousa ]]>
                </dc:creator>
                <pubDate>Thu, 04 Apr 2024 12:27:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/bank_data.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-embed-interactive-python-visualizations-on-your-website-with-python-and-matplotlib/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Embed Interactive Python Visualizations on Your Website with Python and Matplotlib</a>
      </p><p>Em um tutorial anterior do freeCodeCamp, expliquei <a href="https://www.freecodecamp.org/news/how-to-create-auto-updating-data-visualizations-in-python-with-matplotlib-and-aws/">como criar visualizações de dados com atualizações automáticas em Python</a> (texto em inglês).</p><p>Alguns leitores perguntaram se havia algum modo de tornar as visualizações interativas. Felizmente, uma solução fácil já está disponível!</p><p>Neste tutorial, vou ensinar como você pode criar visualizações interativas de dados em Python. Essas visualizações são excelentes candidatas para incorporação em seu blog ou site.</p><h2 id="a-visualiza-o-de-dados-espec-fica-com-a-qual-trabalharemos"><strong>A visualização de dados específica com a qual trabalharemos</strong></h2><p>Em vez de construir uma visualização de dados inteira do zero neste artigo, trabalharemos com a visualização que criamos em meu último tutorial.</p><p>A visualização usa <a href="https://nickmccullum.com/advanced-python/pandas-dataframes/">pandas</a>, <a href="https://nickmccullum.com/python-visualization/how-to-import-matplotlib/">matplotlib</a> e <a href="https://nickmccullum.com/advanced-python/">Python</a> para apresentar vários pontos de dados dos 5 maiores bancos de capital aberto dos Estados Unidos.</p><p>Aqui está uma imagem estática da visualização que criamos:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/image-55.png" class="kg-image" alt="image-55" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/image-55.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/03/image-55.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/image-55.png 1246w" sizes="(min-width: 720px) 720px" width="600" height="400" loading="lazy"></figure><p>O código real para a visualização está incluído abaixo. Abordamos isso no último tutorial, mas observe que você precisará gerar sua própria chave de API IEX Cloud e incluí-la na variável <code>IEX_API_Key</code> para que o script funcione.</p><pre><code class="language-python">############################
#Importação das dependências
############################

import pandas as pd
import matplotlib.pyplot as plt

###############################
#Importação e limpeza dos dados
###############################

IEX_API_Key = ''

tickers = [
            'JPM',
            'BAC',
            'C',
            'WFC',
            'GS',
            ]

#Crie uma string vazia chamada `ticker_string`, a qual adicionaremos tickers e vírgulas
ticker_string = ''

#Percorra cada elemento de `tickers` e adicione-os com uma vírgula a ticker_string
for ticker in tickers:
    ticker_string += ticker
    ticker_string += ','
    
#Remova a última vírgula de `ticker_string`
ticker_string = ticker_string[:-1]

#Crie as strings endpoint e years
endpoints = 'chart'
years = '5'

#Faça a interpolação das strings endpoint em HTTP_request string
HTTP_request = f'https://cloud.iexapis.com/stable/stock/market/batch?symbols={ticker_string}&amp;types={endpoints}&amp;range={years}y&amp;cache=true&amp;token={IEX_API_Key}'

#Envie a solicitação HTTP à API IEX Cloud e armazene a resposta em um DataFrame do pandas
bank_data = pd.read_json(HTTP_request)

#Crie uma lista vazia, onde adicionaremos uma série do pandas de dados de preços de ações
series_list = []

#Percorra cada um dos tickers e mostre uma série do pandas com seus preços ao encerramento da bolsa nos últimos 5 anos
for ticker in tickers:
    series_list.append(pd.DataFrame(bank_data[ticker]['chart'])['close'])

#Adicione a coluna dates (datas)
series_list.append(pd.DataFrame(bank_data['JPM']['chart'])['date'])

#Copie a lista 'tickers' que aparece anteriormente no script e adicione um novo elemento chamado 'Date'. 
#Esses elementos serão os nomes das colunas de nosso DataFrame do pandas posteriormente.
column_names = tickers.copy()
column_names.append('Date')

#Concatene as séries do pandas Series em um único DataFrame
bank_data = pd.concat(series_list, axis=1)

#Nomeie as colunas do DataFrame e defina a coluna 'Date' como o índice
bank_data.columns = column_names
bank_data.set_index('Date', inplace = True)

########################
#Crie a imagem do Python
########################

#Defina o tamanho do canvas do matplotlib
fig = plt.figure(figsize = (18,8))

################################################
################################################
#Crie subgráficos no Python
################################################
################################################

########################
#Subgráfico 1
########################
plt.subplot(2,2,1)

#Gere o diagrama de caixas (boxplot)
plt.boxplot(bank_data.transpose())

#Adicione títulos ao gráfico e aos eixos
plt.title('Boxplot of Bank Stock Prices (5Y Lookback)')
plt.xlabel('Bank')
plt.ylabel('Stock Prices')

#Adicione os rótulos a cada diagrama de caixas individual no canvas
ticks = range(1, len(bank_data.columns)+1)
labels = list(bank_data.columns)
plt.xticks(ticks,labels)

########################
#Subgráfico 2
########################
plt.subplot(2,2,2)

#Crie os dados do eixo x
dates = bank_data.index.to_series()
dates = [pd.to_datetime(d) for d in dates]

#Crie os dados do eixo y
WFC_stock_prices =  bank_data['WFC']

#Gere o gráfico de dispersão (scatterplot)
plt.scatter(dates, WFC_stock_prices)

#Adicione títulos ao gráfico e aos eixos
plt.title("Wells Fargo Stock Price (5Y Lookback)")
plt.ylabel("Stock Price")
plt.xlabel("Date")

########################
#Subgráfico 3
########################
plt.subplot(2,2,3)

#Crie os dados do eixo x
dates = bank_data.index.to_series()
dates = [pd.to_datetime(d) for d in dates]

#Crie os dados do eixo y
BAC_stock_prices =  bank_data['BAC']

#Gere o gráfico de dispersão (scatterplot)
plt.scatter(dates, BAC_stock_prices)

#Adicione títulos ao gráfico e aos eixos
plt.title("Bank of America Stock Price (5Y Lookback)")
plt.ylabel("Stock Price")
plt.xlabel("Date")

########################
#Subgráfico 4
########################
plt.subplot(2,2,4)

#Gere o histograma
plt.hist(bank_data.transpose(), bins = 50)

#Adicione uma legenda ao histograma
plt.legend(bank_data.columns,fontsize=10)

#Adicione títulos ao gráfico e aos eixos
plt.title("A Histogram of Daily Closing Stock Prices for the 5 Largest Banks in the US (5Y Lookback)")
plt.ylabel("Observations")
plt.xlabel("Stock Prices")

plt.tight_layout()

################################################
#Salve a imagem em sua máquina local
################################################

plt.savefig('bank_data.png')</code></pre><p>Agora que entendemos a visualização específica com a qual trabalharemos, vamos falar sobre o que significa uma visualização ser interativa.</p><h2 id="o-que-significa-uma-visualiza-o-ser-interativa"><strong>O que significa uma visualização ser interativa<strong>?</strong></strong></h2><p>Existem dois tipos de visualizações de dados que são úteis para embutir em seu site.</p><p>O primeiro tipo é uma visualização estática. Esta é basicamente uma imagem - pense em arquivos <code>.png</code> ou <code>.jpg</code>.</p><p>O segundo tipo é uma visualização dinâmica. Essas visualizações mudam em resposta ao comportamento do usuário, geralmente via panorâmica ou zoom. As visualizações dinâmicas não são armazenadas em arquivos <code>.png</code> ou <code>.jpg</code>, mas geralmente em tags <code>svg</code> ou <code>iframe</code>.</p><p>Este tutorial é sobre criação de visualizações dinâmicas de dados. Especificamente, a visualização que queremos criar terá as seguintes características:</p><ol><li>Você clicará em um botão no canto inferior esquerdo para ativar o modo dinâmico.</li><li>Depois que o modo dinâmico estiver ativado, você poderá ampliar e deslocar a visualização com o mouse.</li><li>Você também pode cortar e dar zoom em uma seção específica da visualização.</li></ol><p>Na próxima seção deste tutorial, você aprenderá como instalar e importar a biblioteca <code>mpld3</code>, que é a dependência do Python que usaremos para criar nossos gráficos interativos.</p><h2 id="como-importar-a-biblioteca-mpld3"><strong>Como importar a biblioteca<strong> mpld3</strong></strong></h2><p>Para usar a biblioteca <code>mpld3</code> em nossa aplicação do Python, há duas etapas que precisamos concluir primeiro:</p><ol><li>Instalar a biblioteca <code>mpld3</code> na máquina em que estamos trabalhando.</li><li>Importar a biblioteca <code>mpld3</code> em nosso script do Python.</li></ol><p>Primeiro, vamos instalar o <code>mpld3</code> em nossa máquina local.</p><p>A maneira mais fácil de fazer isso é usando o gerenciador de pacotes <code>pip</code> para Python3. Se você já tem o <code>pip</code> instalado em sua máquina, você pode fazer isso executando a seguinte declaração na sua linha de comando:</p><pre><code class="language-bash">pip3 install mpld3</code></pre><p>Agora que o <code>mpld3</code> está instalado em sua máquina, podemos importá-lo para nosso script do Python com a seguinte declaração:</p><pre><code class="language-python">import mpld3</code></pre><p>Para facilitar a leitura, é considerada uma prática recomendada incluir essa importação junto com o restante das importações na parte superior de seu script. Isso significa que agora sua seção de importação ficará assim:</p><pre><code class="language-python">############################
#Importação das dependências
############################

import pandas as pd
import matplotlib.pyplot as plt
import mpld3</code></pre><h2 id="como-transformar-uma-visualiza-o-est-tica-do-matplotlib-em-uma-visualiza-o-interativa-de-dados"><strong>Como transformar uma visualização estática do <strong><code>matplotlib</code> </strong>em uma visualização interativa de dados</strong></h2><p>A principal funcionalidade da biblioteca <code>mpld3</code> é pegar uma visualização <code>matplotlib</code> existente e transformá-la em algum código HTML que você pode embutir em seu site.</p><p>A ferramenta que usamos para isso é o arquivo <code>fig_to_html</code> do <code>mpld3</code>, que aceita um objeto <code>figure</code> do <code>matplotlib</code> como seu único argumento e retorna HTML.</p><p>Para usar o método <code>fig_to_html</code> para nosso propósito, basta adicionar o seguinte código ao final do nosso script do Python:</p><pre><code class="language-python">html_str = mpld3.fig_to_html(fig)
Html_file= open("index.html","w")
Html_file.write(html_str)
Html_file.close()</code></pre><p>Este código gera o HTML e o salva com o nome de arquivo <code>index.html</code> em seu diretório de trabalho atual. Esta é a aparência disso quando renderizado em uma página da web:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/03/Screenshot-from-2024-03-24-14-28-48.png" class="kg-image" alt="Screenshot-from-2024-03-24-14-28-48" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/03/Screenshot-from-2024-03-24-14-28-48.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/03/Screenshot-from-2024-03-24-14-28-48.png 962w" width="600" height="400" loading="lazy"></figure><p>Ao passar o mouse sobre esta visualização, três ícones aparecerão no canto inferior esquerdo. O ícone esquerdo retorna a visualização à sua aparência padrão. O ícone do meio ativa o modo dinâmico. O ícone direito permite cortar e aplicar zoom em um ponto específico da visualização.</p><h2 id="um-erro-comum-ao-trabalhar-com-pandas-e-mpld3"><strong>Um erro comum ao trabalhar com<strong> pandas </strong>e<strong> mpld3</strong></strong></h2><p>Ao criar a visualização interativa neste tutorial, você pode encontrar o seguinte erro gerado pelo <code>mpld3</code>:</p><pre><code>TypeError: array([ 1.]) is not JSON serializable</code></pre><p>Felizmente, existe uma solução bem documentada para esse erro no <a href="https://github.com/mpld3/mpld3/issues/441">GitHub</a>.</p><p>Você precisa editar o arquivo _display.py encontrado em Lib\site-packages\mpld3 e substituir a classe NumpyEncoder por esta:</p><pre><code>class NumpyEncoder(json.JSONEncoder):
    """ Special json encoder for numpy types """

    def default(self, obj):
        if isinstance(obj, (numpy.int_, numpy.intc, numpy.intp, numpy.int8,
            numpy.int16, numpy.int32, numpy.int64, numpy.uint8,
            numpy.uint16,numpy.uint32, numpy.uint64)):
            return int(obj)
        elif isinstance(obj, (numpy.float_, numpy.float16, numpy.float32, 
            numpy.float64)):
            return float(obj)
        try: # Added by ceprio 2018-04-25
            iterable = iter(obj)
        except TypeError:
            pass
        else:
            return list(iterable)
         # Let the base class default method raise the TypeError
        return json.JSONEncoder.default(self, obj)</code></pre><p>Depois que essa substituição for feita, seu código deverá funcionar corretamente e seu arquivo <code>index.html</code> deverá ser gerado com êxito.</p><h2 id="reflex-es-finais"><strong>Reflexões finais</strong></h2><p>Neste tutorial, você aprendeu como criar visualizações interativas de dados em Python usando as bibliotecas matplotlib e mpld3. Aqui está um resumo específico do que abordamos:</p><ol><li>A definição de uma visualização dinâmica de dados</li><li>Como instalar e importar a biblioteca <code>mpld3</code> em Python</li><li>Como usar a biblioteca <code>mpld3</code> para transformar uma visualização do <code>matplotlib</code> em uma visualização dinâmica que você pode embutir em seu site</li><li>Como corrigir um erro comum que os usuários da biblioteca <code>mpld3</code> enfrentam</li></ol><p>Este tutorial foi escrito por <a href="https://nickmccullum.com/">Nick McCullum</a>, que ensina desenvolvimento em <a href="https://nickmccullum.com/advanced-python/">Python</a> e <a href="https://nickmccullum.com/javascript/">JavaScript</a> em seu site.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como criar uma API de JSON com Python ]]>
                </title>
                <description>
                    <![CDATA[ A especificação de APIs com JSON [https://jsonapi.org/] é uma maneira poderosa de habilitar a comunicação entre client e servidor. Ela especifica a estrutura das solicitações e respostas enviadas entre os dois, usando o formato JSON. Como formato de dados, o JSON tem as vantagens de ser leve e legível. Isso ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-criar-uma-api-de-json-com-python/</link>
                <guid isPermaLink="false">6567256613a65603e6502546</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Wed, 29 Nov 2023 12:50:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/5f9ca129740569d1a4ca4d0e.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/build-a-simple-json-api-in-python/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to build a JSON API with Python</a>
      </p><p>A especificação de <a href="https://jsonapi.org/">APIs com JSON</a> é uma maneira poderosa de habilitar a comunicação entre <em>client</em> e servidor. Ela especifica a estrutura das solicitações e respostas enviadas entre os dois, usando o formato JSON.</p><p>Como formato de dados, o JSON tem as vantagens de ser leve e legível. Isso torna muito fácil trabalhar com rapidez e produtividade. A especificação foi projetada para minimizar o número de solicitações e a quantidade de dados que precisam ser enviados entre o <em>client</em> e o servidor.</p><p>Aqui, você pode aprender a criar uma API em JSON básica usando Python e Flask. Em seguida, o resto do artigo mostrará como experimentar alguns dos recursos que a especificação da API em JSON tem a oferecer.</p><p>O <a href="https://flask.palletsprojects.com/en/2.3.x/">Flask é uma biblioteca do Python</a> que fornece um "<em>microframework</em>" para o desenvolvimento para a web. É ótimo para desenvolvimento rápido, pois vem com uma funcionalidade básica simples, mas extensível.</p><p>Um exemplo bastante simples de como enviar uma resposta em JSON usando Flask é vista abaixo:</p><pre><code class="language-python">from flask import Flask

app = Flask(__name__)

@app.route('/')
def example():
   return '{"name":"Bob"}'

if __name__ == '__main__':
    app.run()</code></pre><p>Este artigo usará dois <em>add-ons</em> para o Flask:</p><ul><li><a href="https://flask-rest-jsonapi.readthedocs.io/en/latest/">Flask-REST-JSONAPI</a> ajudará a desenvolver uma API que siga de perto a especificação de APIs em JSON.</li><li><a href="https://flask-sqlalchemy.palletsprojects.com/en/2.x/">Flask-SQLAlchemy</a> usará <a href="https://www.sqlalchemy.org/">SQLAlchemy</a> para tornar a criação e a interação com um banco de dados simples bastante rápida.</li></ul><h3 id="o-cen-rio-geral"><strong>O cenário geral</strong></h3><p>O objetivo final é criar uma API que permita a interação do lado do <em>client</em> com um banco de dados subjacente. Haverá algumas camadas entre o banco de dados e o <em>client</em> – uma camada de abstração de dados e uma camada de gerenciador de recursos.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/flow.png" class="kg-image" alt="flow" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/11/flow.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/11/flow.png 729w" sizes="(min-width: 720px) 720px" width="729" height="357" loading="lazy"></figure><p>Aqui temos uma visão geral das etapas envolvidas:</p><ol><li>Defina um banco de dados usando o Flask-SQLAlchemy</li><li>Crie uma abstração dos dados com <a href="https://marshmallow-jsonapi.readthedocs.io/en/latest/">Marshmallow-JSONAPI</a></li><li>Crie os gerentes de recurso com a Flask-REST-JSONAPI</li><li>Crie os endpoints de URL e inicie o servidor com o Flask</li></ol><p>Este exemplo usará um esquema simples descrevendo artistas modernos e suas relações com diferentes obras de arte.</p><h3 id="instale-tudo"><strong>Instale tudo</strong></h3><p>Antes de começar, você precisará configurar o projeto. Isso envolve a criação de um espaço de trabalho e ambiente virtual, a instalação dos módulos necessários e a criação dos principais arquivos do Python e do banco de dados para o projeto.</p><p>Na linha de comando, crie um diretório e navegue para ele.</p><pre><code>$ mkdir flask-jsonapi-demo
$ cd flask-jsonapi-demo/</code></pre><p>É bom praticar a <a href="https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/">criação de ambientes virtuais</a> (texto em inglês) para cada um de seus projetos em Python. Você pode ignorar essa etapa, mas ela é bastante recomendada.</p><pre><code>$ python -m venv .venv
$ source .venv/bin/activate
</code></pre><p>Uma vez que seu ambiente virtual tenha sido criado e ativado, você pode instalar os módulos necessários para este projeto.</p><pre><code>$ pip install flask-rest-jsonapi flask-sqlalchemy</code></pre><p>Tudo o que você precisará será instalado conforme os requisitos para essas duas extensões. Isso inclui o próprio Flask e o SQLAlchemy.</p><p>A próxima etapa é criar um arquivo Python e um banco de dados para o projeto.</p><pre><code>$ touch application.py artists.db</code></pre><h3 id="crie-o-esquema-do-banco-de-dados"><strong>Crie o esquema do banco de dados</strong></h3><p>Aqui, você começa a modificar a <code>application.py</code> para definir e criar o esquema do banco de dados para o projeto.</p><p>Abra <code>application.py</code> no seu editor de texto favorito. Comece a importar os módulos. Para ser claro, os módulos serão importados conforme avançamos.</p><p>Em seguida, crie um objeto chamado <code>app</code> como instância da classe Flask.</p><p>Depois, use o SQLAlchemy para conectar com o arquivo de banco de dados que você criou. A etapa final é definir e criar uma tabela chamada <code>artists</code>.</p><pre><code class="language-python">from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# Criar a aplicação em Flask
app = Flask(__name__)

# Configurar o SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////artists.db'
db = SQLAlchemy(app)

# Definir uma classe para a tabela Artist
class Artist(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    birth_year = db.Column(db.Integer)
    genre = db.Column(db.String)

# Criar a tabela
db.create_all()</code></pre><h3 id="cria-o-da-camada-de-abstra-o"><strong>Criação da camada de abstração</strong></h3><p>A próxima etapa usa o módulo <a href="https://marshmallow-jsonapi.readthedocs.io/en/latest/">Marshmallow-JSONAPI</a> para criar uma abstração de dados lógica sobre as tabelas que acabamos de definir.</p><p>A razão para criar essa camada de abstração é simples. Ela oferece mais controle sobre como seus dados subjacentes são expostos por meio da API. Pense nessa camada como uma lente através da qual o consumidor da API pode visualizar os dados subjacentes claramente e apenas as partes que eles precisam ver.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/Untitled-Diagram-Page-2.png" class="kg-image" alt="Untitled-Diagram-Page-2" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/11/Untitled-Diagram-Page-2.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/11/Untitled-Diagram-Page-2.png 646w" width="646" height="361" loading="lazy"></figure><p>No código abaixo, a camada de abstração de dados é definida como uma classe que herda da classe <code>Schema</code> de Marshmallow-JSONAPI. Ela dará acesso por meio da API a registros únicos ou múltiplos da tabela <code>artists</code>.</p><p>Neste bloco, a classe <code>Meta</code> define alguns metadados. Especificamente, o nome do <em>endpoint</em> de URL para a interação com registros simples será <code>artist_one</code>, onde cada artista será identificado com um parâmetro <code>&lt;id&gt;</code> de URL. O nome do <em>endpoint</em> para a interação com diversos registros será <code>artist_many</code>.</p><p>Os demais atributos definidos referem-se às colunas na tabela <code>artists</code>. Aqui, você pode controlar ainda mais como cada um é exposto por meio da API.</p><p>Por exemplo, ao fazer solicitações de POST para adicionar novos artistas ao banco de dados, você pode garantir que o campo <code>name</code> seja obrigatório definindo <code>required=True</code>.</p><p>Se, por alguma razão, você não quiser que o campo <code>birth_year</code> seja retornado ao fazer solicitações de GET, é possível especificar isso com <code>load_only=True</code>.</p><pre><code class="language-python">from marshmallow_jsonapi.flask import Schema
from marshmallow_jsonapi import fields

# Criar a camada de abstração de dados
class ArtistSchema(Schema):
    class Meta:
        type_ = 'artist'
        self_view = 'artist_one'
        self_view_kwargs = {'id': '&lt;id&gt;'}
        self_view_many = 'artist_many'

    id = fields.Integer()
    name = fields.Str(required=True)
    birth_year = fields.Integer(load_only=True)
    genre = fields.Str()
</code></pre><h3 id="criar-os-gerentes-de-recursos-e-os-endpoints-de-url"><strong>Criar os gerentes de recursos e os <em>endpoints </em>de URL</strong></h3><p>A peça final do quebra-cabeça é criar um gerente de recursos e o <em>endpoint</em> correspondente para cada uma das rotas, <code>/artists</code> e <code>/artists/id</code>.</p><p>Cada gerente de recursos é definido como uma classe que herda das classes <code>ResourceList</code> e <code>ResourceDetail</code> da Flask-REST-JSONAPI.</p><p>Eles recebem dois atributos. <code>schema</code> é usado para indicar a camada de abstração de dados que o gerente de recursos utiliza, enquanto <code>data_layer</code> indica a sessão e o modelo de dados que será usado para a camada de dados.</p><p>Em seguida, definimos <code>api</code> como uma instância da classe <code>Api</code> de Flask-REST-JSONAPI e criamos as rotas para a API com <code>api.route()</code>. Esse método recebe três argumentos – a classe da camada de abstração de dados, o nome do <em>endpoint</em> e o caminho do URL.</p><p>A última etapa é escrever um <em>loop </em>principal para iniciar a aplicação no modo de depuração quando o script é executado diretamente. O modo de depuração é ótimo para desenvolvimento, mas não é adequado para execução em produção.</p><pre><code class="language-python"># Criar gerentes de recursos e endpoints

from flask_rest_jsonapi import Api, ResourceDetail, ResourceList

class ArtistMany(ResourceList):
    schema = ArtistSchema
    data_layer = {'session': db.session,
                  'model': Artist}

class ArtistOne(ResourceDetail):
    schema = ArtistSchema
    data_layer = {'session': db.session,
                  'model': Artist}

api = Api(app)
api.route(ArtistMany, 'artist_many', '/artists')
api.route(ArtistOne, 'artist_one', '/artists/&lt;int:id&gt;')

# loop principal para executar a aplicação em modo de depuração
if __name__ == '__main__':
    app.run(debug=True)</code></pre><h3 id="fazer-solicita-es-de-get-e-de-post"><strong>Fazer solicitações de GET e de POST</strong></h3><p>Agora, você pode começar a usar a API para <a href="https://restfulapi.net/http-methods/">fazer solicitações em HTTP</a> (texto em inglês). Isso pode ocorrer por meio de um navegador da web, com uma ferramenta de linha de comando, como o curl, ou a partir de outro programa (por exemplo, um script do Python usando a biblioteca <code>Requests</code>).</p><p>Para iniciar o servidor, execute o script <code>application.py</code>:</p><pre><code>$ python application.py</code></pre><p>No seu navegador, vá para <a href="http://localhost:5000/artists">http://localhost:5000/artists</a>. &nbsp;Você verá um resultado em JSON de todos os registros no banco de dados até o momento. Porém, agora, o banco está vazio.</p><p>Para começar a adicionar registros ao banco de dados, você pode fazer uma solicitação de POST. Uma maneira de se fazer isso é a partir da linha de comando usando a ferramenta <code>curl</code>. Como alternativa, você pode usar a ferramenta <a href="https://insomnia.rest/">Insomnia</a> ou criar uma interface de usuário simples em HTML que publique os dados usando um formulário.</p><p>Com o <a href="https://curl.haxx.se/">curl</a>, na linha de comando, você pode inserir o seguinte:</p><pre><code>curl -i -X POST -H 'Content-Type: application/json' -d '{"data":{"type":"artist", "attributes":{"name":"Salvador Dali", "birth_year":1904, "genre":"Surrealism"}}}' http://localhost:5000/artists</code></pre><p>Se você navegar até <a href="http://localhost:5000/artists">http://localhost:5000/artists</a>, verá o registro que acaba de adicionar. Se for adicionar mais registros, eles também aparecerão aqui, pois o caminho do URL chama o <em>endpoint</em> <code>artists_many</code>.</p><p>Para ver apenas um único artista pelo <code>id</code>, navegue até o URL relevante. Por exemplo, para ver o primeiro artista, experimente <a href="http://localhost:5000/artists/1">http://localhost:5000/artists/1</a>.</p><h3 id="filtragem-e-ordena-o"><strong>Filtragem e ordenação</strong></h3><p>Um dos recursos interessantes da especificação de APIs em JSON é a capacidade de retornar a resposta de maneiras mais úteis, definindo alguns parâmetros no URL. Por exemplo, você pode classificar os resultados de acordo com um campo escolhido ou filtrar com base em alguns critérios.</p><p>O Flask-REST-JSONAPI vem com isso incorporado.</p><p>Para ordenar os artistas por ano de nascimento, navegue para <a href="http://localhost:5000/artists?sort=birth_year">http://localhost:5000/artists?sort=birth_year</a>. Em uma aplicação da web, isso evitaria que você precisasse ordenar os resultados do lado do <em>client</em>, o que demandaria bastante em termos de desempenho e causaria um impacto na experiência do usuário.</p><p>A filtragem também é fácil. Anexe ao URL os critérios pelos quais você deseja filtrar, contidos por colchetes. Há três informações para incluir:</p><ul><li>"name" – o campo pelo qual você está filtrando (por exemplo, <code>birth_year</code>)</li><li>"op" - a operação de filtro ("maior que", "menor que", "igual a" etc.)</li><li>"val" - o valor com relação à operação de filtro (por exemplo, 1900)</li></ul><p>O URL abaixo filtra artistas cuja data de nascimento é após 1900:</p><p><a href="http://localhost:5000/artists?filter=[{%22name%22:%22birth_year%22,%22op%22:%22gt%22,%22val%22:1900}]">http://localhost:5000/artists?filter=[{"name":"birth_year","op":"gt","val":1900}]</a></p><p>Essa funcionalidade torna muito mais fácil recuperar apenas informações relevantes ao chamar a API. Isso é valioso para melhorar o desempenho, especialmente ao recuperar volumes potencialmente grandes de dados em uma conexão lenta.</p><h3 id="pagina-o"><strong>Paginação</strong></h3><p>Outro recurso da especificação da API em JSON que auxilia o desempenho é a paginação. É quando grandes respostas são enviadas em várias "páginas", em vez de todas de uma só vez. Você pode controlar o tamanho da página e o número da página solicitada no URL.</p><p>Assim, por exemplo, você pode receber 100 resultados em 10 páginas em vez de carregar todos os 100 de uma só vez. A primeira página conteria resultados de 1 a 10, a segunda página conteria resultados de 11 a 20 e assim por diante.</p><p>Para especificar o número de resultados que você deseja receber por página, você pode adicionar o parâmetro ?page[size]=X para o URL, onde X é o número de resultados por página. O Flask-REST-JSONAPI usa 30 como o tamanho de página padrão.</p><p>Para solicitar um determinado número de página, você pode adicionar o parâmetro ?page[number]=X, onde X é o número da página. Você pode combinar os dois parâmetros, como vemos aqui:</p><p><a href="http://localhost:5000/artists?page[size]=2&amp;page[number]=1">http://localhost:5000/artists?page[size]=2&amp;page[number]=2</a></p><p>Esse URL define o tamanho da página como sendo de dois resultados por página, pedindo pela segunda página de resultados. Isso retornará o terceiro e o quarto resultados da resposta completa.</p><h3 id="relacionamentos"><strong>Relacionamentos</strong></h3><p>Quase sempre, os dados em uma tabela estarão relacionados aos dados armazenados em outra. Por exemplo, se você tem uma tabela de artistas, é provável que você também queira uma tabela de obras de arte. Cada obra está relacionada ao artista que a criou.</p><p>A especificação da API em JSON permite que você trabalhe com dados relacionais facilmente. O Flask-REST-JSONAPI permite que você aproveite isso. Aqui, isso será demonstrado adicionando uma tabela de obras de arte (<code>artworks</code>) ao banco de dados e incluindo relacionamentos entre artista e obra de arte.</p><p>Para implementar o exemplo de obras de arte, será necessário fazer algumas alterações no código em <code>application.py</code>.</p><p>Primeiro, fazemos algumas importações adicionais, e criamos uma tabela que relacione cada obra de arte a um artista:</p><pre><code class="language-python">from marshmallow_jsonapi.flask import Relationship
from flask_rest_jsonapi import ResourceRelationship


# Definir a tabela Artwork
class Artwork(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String)
    artist_id = db.Column(db.Integer, 
        db.ForeignKey('artist.id'))
    artist = db.relationship('Artist',
        backref=db.backref('artworks'))</code></pre><p>Em seguida, refazemos a camada de abstração:</p><pre><code class="language-python"># Criar a abstração de dados
class ArtistSchema(Schema):
    class Meta:
        type_ = 'artist'
        self_view = 'artist_one'
        self_view_kwargs = {'id': '&lt;id&gt;'}
        self_view_many = 'artist_many'

    id = fields.Integer()
    name = fields.Str(required=True)
    birth_year = fields.Integer(load_only=True)
    genre = fields.Str()
    artworks = Relationship(self_view = 'artist_artworks',
        self_view_kwargs = {'id': '&lt;id&gt;'},
        related_view = 'artwork_many',
        many = True,
        schema = 'ArtworkSchema',
        type_ = 'artwork')

class ArtworkSchema(Schema):
    class Meta:
        type_ = 'artwork'
        self_view = 'artwork_one'
        self_view_kwargs = {'id': '&lt;id&gt;'}
        self_view_many = 'artwork_many'

    id = fields.Integer()
    title = fields.Str(required=True)
    artist_id = fields.Integer(required=True)
</code></pre><p>Isso define uma camada de abstração para a tabela <code>artwork</code> e adiciona uma relação entre artista e obra de arte à classe <code>ArtistSchema</code>.</p><p>Em seguida, defina novos gerentes de recursos para acessar várias obras de arte de uma vez e uma por vez, bem como para acessar os relacionamentos entre artista e obra de arte.</p><pre><code class="language-python">class ArtworkMany(ResourceList):
    schema = ArtworkSchema
    data_layer = {'session': db.session,
                  'model': Artwork}

class ArtworkOne(ResourceDetail):
    schema = ArtworkSchema
    data_layer = {'session': db.session,
                  'model': Artwork}

class ArtistArtwork(ResourceRelationship):
    schema = ArtistSchema
    data_layer = {'session': db.session,
                  'model': Artist}</code></pre><p>Por fim, adicionamos alguns <em>endpoints </em>novos:</p><pre><code class="language-python">api.route(ArtworkOne, 'artwork_one', '/artworks/&lt;int:id&gt;')
api.route(ArtworkMany, 'artwork_many', '/artworks')
api.route(ArtistArtwork, 'artist_artworks',
    '/artists/&lt;int:id&gt;/relationships/artworks')</code></pre><p>Executamos <code>application.py</code> e, ao tentar publicar alguns dados a partir da linha de comando usando a ferramenta <code>curl</code>, temos:</p><pre><code>curl -i -X POST -H 'Content-Type: application/json' -d '{"data":{"type":"artwork", "attributes":{"title":"The Persistance of Memory", "artist_id":1}}}' http://localhost:5000/artworks</code></pre><p>Isso criará uma obra de arte relacionada ao artista com o <code>id=1</code>.</p><p>No navegador, vá para <a href="http://localhost:5000/artists/1/relationships/artworks">http://localhost:5000/artists/1/relationships/artworks</a>. Isso deve mostrar as obras relacionadas ao artista com <code>id=1</code>. Isso evita que você escreva um URL mais complexo com parâmetros para filtrar trabalhos artísticos por seu campo <code>artist_id</code>. Você pode listar rapidamente todas as relações entre um determinado artista e suas obras de arte.</p><p>Outro recurso é a capacidade de incluir resultados relacionados na resposta à chamada do <em>endpoint</em> <code>artists_one</code>:</p><p><a href="http://localhost:5000/artists/1?include=artworks">http://localhost:5000/artists/1?include=artworks</a></p><p>Isso retornará a resposta comum para o endpoint <code>artists</code>, além dos resultados para cada uma das obras desse artista.</p><h3 id="campos-esparsos"><strong>Campos esparsos</strong></h3><p>Um último recurso que vale a pena mencionar – campos esparsos. Ao trabalhar com grandes recursos de dados com muitos relacionamentos complexos, os tamanhos de resposta podem crescer muito rapidamente. É útil recuperar apenas os campos em que você está interessado.</p><p>A especificação da API em JSON permite que você faça isso adicionando um parâmetro <code>fields</code> ao URL. Por exemplo, o URL abaixo obtém a resposta para um determinado artista e suas obras de arte relacionadas. No entanto, em vez de retornar todos os campos para a obra de arte fornecida, ele retorna apenas o título.</p><p><a href="http://localhost:5000/artists/1?include=artworks&amp;fields[artwork]=title">http://localhost:5000/artists/1?include=artworks&amp;fields[artwork]=title</a></p><p>Isso é muito útil para melhorar o desempenho, especialmente em conexões lentas. Como regra geral, você só deve fazer solicitações de e para o servidor com a quantidade mínima de dados necessária.</p><h3 id="coment-rios-finais"><strong>Comentários finais</strong></h3><p>A especificação de APIs em JSON é um framework bastante útil para o envio de dados entre servidor e <em>client </em>em um formato limpo e flexível. Este artigo forneceu uma visão geral do que você pode fazer com ele, com um exemplo trabalhado em Python usando a biblioteca Flask-REST-JSONAPI.</p><p>Então, o que você vai fazer a seguir? As possibilidades são muitas. O exemplo neste artigo foi simples, com apenas duas tabelas e uma única relação entre elas. Você pode desenvolver uma aplicação tão sofisticada quanto quiser e criar uma API poderosa para interagir com a aplicação usando todas as ferramentas fornecidas aqui.</p><p>Obrigado pela leitura e uma ótima programação em Python para você!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como criar um bot e automatizar seu trabalho diário ]]>
                </title>
                <description>
                    <![CDATA[ A maioria dos trabalhos tem tarefas repetitivas que você pode automatizar, o que libera parte do seu tempo precioso. Isso torna a automação uma habilidade fundamental a ser adquirida. Um pequeno grupo de engenheiros de automação qualificados e especialistas em domínio pode ser capaz de automatizar muitas das tarefas mais ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-criar-um-bot-e-automatizar-seu-trabalho-diario/</link>
                <guid isPermaLink="false">65518be1f2994303ed343273</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Mon, 13 Nov 2023 04:09:05 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/freecodecamp_cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/building-bots" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Build a Bot and Automate your Everyday Work</a>
      </p><p>A maioria dos trabalhos tem tarefas repetitivas que você pode automatizar, o que libera parte do seu tempo precioso. Isso torna a automação uma habilidade fundamental a ser adquirida.</p><p>Um pequeno grupo de engenheiros de automação qualificados e especialistas em domínio pode ser capaz de automatizar muitas das tarefas mais tediosas de equipes inteiras.</p><p>Neste artigo, exploraremos os conceitos básicos da automação de fluxo de trabalho usando o Python – uma linguagem de programação poderosa e fácil de aprender. Usaremos o Python para escrever um script de automação fácil e útil que limpará uma pasta específica e colocará cada arquivo em sua pasta correspondente.</p><p>Nosso objetivo não será escrever código perfeito ou criar arquiteturas ideais no início. Também não vamos criar nada "ilegal". Em vez disso, veremos como criar um script que limpa automaticamente uma determinada pasta e todos os seus arquivos.</p><h1 id="sum-rio"><strong>Sumário</strong></h1><p>1. <a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-bot-e-automatizar-seu-trabalho-diario/#-reas-de-automa-o-e-por-onde-come-ar">Áreas de automação e por onde começar</a></p><p>1.1 Automação simples</p><p>1.2 Automação com API pública</p><p>1.3 Engenharia reversa de API</p><p>2. <a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-bot-e-automatizar-seu-trabalho-diario/#considera-es-ticas-sobre-a-automa-o">Considerações éticas sobre a automação</a></p><p>3. <a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-bot-e-automatizar-seu-trabalho-diario/#cria-o-de-um-script-de-limpeza-de-um-diret-rio">Criação de um script de limpeza de um diretório</a></p><p>4. <a href="https://www.freecodecamp.org/portuguese/news/como-criar-um-bot-e-automatizar-seu-trabalho-diario/#um-guia-completo-para-a-cria-o-de-bots-e-a-automa-o-do-seu-trabalho-di-rio">Um guia completo sobre a criação de bots e como automatizar seu trabalho diário</a></p><h2 id="-reas-de-automa-o-e-por-onde-come-ar"><strong>Áreas de automação e por onde começar</strong></h2><p>Vamos começar definindo que tipo de automações existem.</p><p>A arte da automação se aplica à maioria dos setores. Para começar, ela ajuda com tarefas como extrair endereços de e-mail de diversos documentos para que você possa fazer um envio em massa de e-mails. Abordagens mais complexas, como a otimização de fluxos de trabalho e processos dentro de grandes corporações, também podem ter a automação como auxílio.</p><p>É claro que passar de pequenos scripts pessoais para grandes infraestruturas de automação que substituem pessoas reais envolve um processo de aprendizado e melhoria. Então, vamos ver onde você pode começar sua jornada.</p><h3 id="automa-o-simples"><strong>Automação simples</strong></h3><p>Automações simples permitem um ponto de entrada rápido e direto. Isso pode abranger pequenos processos independentes, como limpezas de projetos e reestruturação de arquivos dentro de diretórios, ou partes de um fluxo de trabalho, como redimensionar automaticamente arquivos já salvos.</p><h3 id="automa-o-de-api-p-blica"><strong>Automação de API pública</strong></h3><p>As automações de API pública são o modo mais comum de automação, uma vez que podemos acessar a maioria das funcionalidades usando solicitações HTTP para APIs hoje em dia. Por exemplo, se você quiser automatizar a maneira como regar seu jardim inteligente em casa.</p><p>Para fazer isso, você quer verificar o tempo do dia atual para ver se você precisa regar ou se há chuva chegando.</p><h3 id="engenharia-reversa-de-api"><strong>Engenharia reversa de API</strong></h3><p>A automação baseada em engenharia reversa de API é mais comum em bots reais e na seção "Bot Imposter" (impostor de bot, em inglês) do gráfico na seção "Considerações éticas" abaixo.</p><p>Através da engenharia reversa de uma API, entendemos o fluxo de usuários das aplicações. Um exemplo pode ser o login em um jogo de navegador on-line.</p><p>Ao entender o processo de login e autenticação, podemos duplicar esse comportamento com nosso próprio script. Em seguida, podemos criar nossa própria interface para trabalhar com a aplicação, mesmo que os próprios criadores não a forneçam.</p><p>Seja qual for a abordagem que você está buscando, sempre considere se ela é legal ou não.</p><p>Você não quer se meter em problemas, não é?</p><h2 id="considera-es-ticas-sobre-a-automa-o"><strong>Considerações éticas sobre a automação</strong></h2><p>Alguém no GitHub, um dia, entrou em contato comigo e me disse:</p><blockquote>"Curtidas e engajamento são a moeda digital e você está desvalorizando essa moeda."</blockquote><p>Isso ficou comigo e me fez questionar a ferramenta que construí exatamente para esse propósito.</p><p>O fato de que essas interações e o engajamento podem ser automatizados e "falsificados" cada vez mais leva a um sistema de redes social distorcido e quebrado.</p><p>Pessoas que produzem conteúdo valioso e bom são invisíveis para outros usuários e empresas de publicidade se não usarem bots e outros sistemas de engajamento. Um amigo meu criou a seguinte associação com os "Nove Círculos do Inferno", de Dante, onde, a cada passo, mais perto de se tornar um influenciador social você fica e cada vez menos consciente de como todo esse sistema realmente está quebrado.</p><p>Quero compartilhar isso com vocês aqui, pois acho que é uma representação extremamente precisa do que testemunhei enquanto trabalhava ativamente com influenciadores com o InstaPy.</p><p><strong>Nível<strong> 1: Limbo </strong></strong>–<strong><strong> </strong></strong>quando você não usa bots</p><p><strong>Nível<strong> 2: Fl</strong>erte </strong>– quando você dá as curtidas e segue manualmente quantas pessoas puder para que elas sigam você de volta/curtam suas publicações</p><p><strong>Nível<strong> 3: Conspira</strong>ção<strong> </strong></strong>– quando você se junta a um grupo no Telegram para dar curtidas e comentar em 10 fotos para que outras 10 pessoas curtam e comentem em sua foto</p><p><strong>Nível<strong> 4: Infideli</strong>dade</strong> – quando você usa um assistente virtual de baixo custo para dar curtidas e seguir em seu nome</p><p><strong>Nível<strong> 5: </strong>Lascívia<strong> </strong>– </strong>quando você usa um bot para dar curtidas, sem receber curtidas de volta (mas sem pagar por isso – como, por exemplo, com uma extensão do Chrome)</p><p><strong>Nível<strong> 6: Promiscui</strong>dade<strong> </strong>–<strong> </strong></strong>quando você usa um bot para dar 50 ou mais curtidas para receber 50 ou mais curtidas, mas sem pagar por isso – como, por exemplo, com uma extensão do Chrome</p><p><strong>Nível<strong> 7: Ava</strong>reza ou ganância em excesso<strong> </strong></strong>– quando você usa um bot para dar curtidas/seguir/comentar em torno de 200 a 700 fotos, ignorando a chance de ser banido</p><p><strong>Nível<strong> 8: Prostitu</strong>ição<strong> </strong></strong>– quando você paga por um serviço de terceiros desconhecidos para dar reciprocidade às curtidas/seguidas automatizadas por você, mas esse serviço usa sua conta para dar curtidas/seguir de volta</p><p><strong>Nível<strong> 9: Fraud</strong>e<strong>/Heres</strong>ia<strong> </strong></strong>– quando você compra seguidores e curtidas e tenta se vender para as marcas como um <em>influencer</em></p><p>O nível de uso de bots nas redes sociais é tanto que, <strong>se você não usar <strong>bot</strong>s<strong>, </strong>estará preso no nível <strong>1, </strong>o <strong>Limbo</strong></strong>, sem crescimento no número de seguidores e com baixo engajamento com relação aos seus pares.</p><p>Na teoria econômica, isso é conhecido como o <strong><strong>dilema </strong>do prisioneiro e como jogo da soma zero</strong>. Se você não usar bots e eu usar, eu ganho. Se ninguém usar, todos ganham. Como, porém, não há incentivo para que todos não usem bots, todos usam bots. Assim, ninguém ganha.</p><blockquote>Cuidado com isso e nunca se esqueça das implicações que todo esse ferramental tem nas redes sociais.</blockquote><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/spectrum-bot-intent-ebook.png" class="kg-image" alt="spectrum-bot-intent-ebook" srcset="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/spectrum-bot-intent-ebook.png 600w" width="600" height="323" loading="lazy"><figcaption>Fonte: SignalSciences.com</figcaption></figure><p>Queremos evitar lidar com implicações éticas e ainda trabalhar em um projeto de automação aqui. É por isso que criaremos um script de limpeza de diretório simples, que ajuda você a organizar suas pastas bagunçadas.</p><h2 id="cria-o-de-um-script-de-limpeza-de-um-diret-rio"><strong>Criação de um script de limpeza de um diretório</strong></h2><p>Agora, queremos examinar um script bastante simples. Ele limpa automaticamente um determinado diretório, movendo esses arquivos para pastas de acordo com a extensão do arquivo.</p><p>Então, tudo o que queremos fazer é o seguinte:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/directory_clean_img.png" class="kg-image" alt="directory_clean_img" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/11/directory_clean_img.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/11/directory_clean_img.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/11/directory_clean_img.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w2400/2023/11/directory_clean_img.png 2400w" sizes="(min-width: 1200px) 1200px" width="3460" height="2218" loading="lazy"></figure><h3 id="configurando-o-analisador-de-argumentos"><strong>Configurando o analisador de argumentos</strong></h3><p>Como estamos trabalhando com uma funcionalidade do sistema operacional, como mover arquivos, precisamos importar a biblioteca <code>os</code>. Além disso, queremos dar ao usuário algum controle sobre qual pasta é limpa. Usaremos a biblioteca <code>argparse</code> para isso.</p><pre><code class="language-python">import os
import argparse</code></pre><p>Depois de importar as duas bibliotecas, vamos primeiro configurar o analisador de argumentos. Certifique-se de fornecer uma descrição e um texto de ajuda para cada argumento adicionado para auxiliar o usuário quando ele digitar <code>--help</code>.</p><p>Nosso argumento será chamado de <code>--path</code>. Os traços duplos na frente do nome informam à biblioteca que esse é um argumento opcional. Por padrão, queremos usar o diretório atual, então defina o valor padrão como <code>"."</code>.</p><pre><code class="language-python">parser = argparse.ArgumentParser(
    description="Limpa o diretório e coloca os arquivos nas respectivas pastas."
)

parser.add_argument(
    "--path",
    type=str,
    default=".",
    help="Caminho do diretório a ser limpo",
)

# analisa os argumentos dados pelo usuário e extrai o caminho
args = parser.parse_args()
path = args.path

print(f"Limpando o diretório {path}")</code></pre><p>Isso já termina a seção de análise de argumentos – é bem simples e legível, certo?</p><p>Vamos executar o nosso script e ver se tem erros.</p><pre><code class="language-bash">python directory_clean.py --path ./test 

=&gt; Limpando o diretório ./test</code></pre><p>Uma vez executado, podemos ver o nome do diretório sendo impresso no console. Ótimo!<br>Vamos usar a biblioteca <code>os</code> para obter os arquivos no caminho fornecido.</p><h3 id="obtendo-uma-lista-de-arquivos-da-pasta"><strong>Obtendo uma lista de arquivos da pasta</strong></h3><p>Ao usar o método <code>os.listdir(path)</code> e fornecer a ele um caminho válido, obtemos uma lista de todos os arquivos e pastas dentro desse diretório.</p><p>Depois de listar todos os elementos na pasta, queremos diferenciar entre arquivos e pastas, pois não queremos limpar as pastas, apenas os arquivos.</p><p>Nesse caso, usamos uma compreensão de lista do Python para iterar todos os elementos e colocá-los nas novas listas se eles atenderem ao requisito dado de ser um arquivo ou pasta.</p><pre><code class="language-python"># obter todos os arquivos de um diretório
dir_content = os.listdir(path)

# criar um caminho relativo a partir do caminho do arquivo e o nome do documento
path_dir_content = [os.path.join(path, doc) for doc in dir_content]

# filtrar o conteúdo do nosso diretório em uma lista de documentos e pastas
docs = [doc for doc in path_dir_content if os.path.isfile(doc)]
folders = [folder for folder in path_dir_content if os.path.isdir(folder)]

# contador para registrar a quantidade de arquivos movidos 
# e a lista das pastas já criadas para evitar a criação de diversas pastas iguais
moved = 0
created_folders = []

print(f"Limpando {len(docs)} de {len(dir_content)} elementos.")</code></pre><p>Como sempre, vamos garantir que nossos usuários recebam feedback. Portanto, adicionamos uma instrução de impressão que dê ao usuário uma indicação sobre quantos arquivos serão movidos.</p><pre><code class="language-bash">python directory_clean.py --path ./test 

=&gt; Limpando o diretório ./test
=&gt; Limpando 60 de 60 elementos.</code></pre><p>Depois de executar novamente o script do Python, agora, podemos ver que a pasta /test que criei contém 60 arquivos que serão movidos.</p><h3 id="cria-o-de-uma-pasta-para-cada-extens-o-de-arquivo"><strong>Criação de uma pasta para cada extensão de arquivo</strong></h3><p>O próximo – e mais importante – passo é criar a pasta para cada uma das extensões de arquivo. Queremos fazer isso passando por todos os nossos arquivos filtrados e, se eles tiverem uma extensão para a qual ainda não há uma pasta, criamos uma.</p><p>A biblioteca <code>os</code> nos ajuda com funcionalidades mais interessantes, como a divisão do tipo de arquivo e caminho de um determinado documento, extraindo o próprio caminho e o nome do documento.</p><pre><code class="language-python"># percorre todos os arquivos e os move para as pastas certas
for doc in docs:
    # separar o nome da extensão do arquivo
    full_doc_path, filetype = os.path.splitext(doc)
    doc_path = os.path.dirname(full_doc_path)
    doc_name = os.path.basename(full_doc_path)

	print(filetype)
    print(full_doc_path)
    print(doc_path)
    print(doc_name)
    
    break</code></pre><p>A instrução <code>break</code> ao final do código acima garante que nosso terminal não fique travado se nosso diretório tiver centenas de arquivos.</p><p>Depois de definirmos isso, vamos executar nosso script e ver um resultado semelhante a este:</p><pre><code class="language-bash">python directory_clean.py --path ./test 

=&gt; ...
=&gt; .pdf
=&gt; ./test/test17
=&gt; ./test
=&gt; test17</code></pre><p>Podemos ver que a implementação acima divide o tipo de arquivo e, em seguida, extrai as partes do caminho completo.</p><p>Como temos o tipo de arquivo, agora podemos verificar se já existe uma pasta com o nome desse tipo.</p><p>Antes de fazermos isso, queremos ter certeza de pular alguns arquivos. Se usarmos o diretório atual <code>"."</code> como caminho, precisamos evitar mover o próprio script do Python. Uma condição simples cuida disso.</p><p>Além disso, não queremos mover <a href="https://www.lifewire.com/what-is-a-hidden-file-2625898">arquivos ocultos</a> (texto em inglês). Vamos, então, incluir todos os arquivos que comecem com um ponto. O arquivo <code>.DS_Store</code> no macOS é um exemplo de arquivo oculto.</p><pre><code class="language-python">	# ignore este arquivo quando ele estiver no diretório
    if doc_name == "directory_clean" or doc_name.startswith('.'):
        continue

    # obtenha o nome da subpasta e crie a pasta se ela não existir
    subfolder_path = os.path.join(path, filetype[1:].lower())

    if subfolder_path not in folders:
    	# cria a pasta</code></pre><p>Depois de cuidarmos do script do Python e dos arquivos ocultos, podemos passar para a criação das pastas no sistema.</p><p>Além da nossa verificação, se a pasta já estava lá quando lemos o conteúdo do diretório, no início, precisamos de uma maneira de rastrear as pastas que já criamos. Essa foi a razão pela qual declaramos a lista <code>created_folders = []</code>. Ela servirá como a memória para acompanhar os nomes das pastas.</p><p>Para criar outra pasta, a biblioteca <code>os</code> fornece um método chamado <code>os.mkdir(caminho_da_pasta)</code>, que recebe um caminho e cria a pasta com o nome dado ali.</p><p>Esse método pode lançar uma exceção, nos dizendo que a pasta já existe. Assim, vamos garantir que capturamos esse erro.</p><pre><code class="language-python">if subfolder_path not in folders and subfolder_path not in created_folders:
        try:
            os.mkdir(subfolder_path)
            created_folders.append(subfolder_path)
            print(f"Pasta {subfolder_path} criada.")
        except FileExistsError as err:
            print(f"Pasta já existe em {subfolder_path}... {err}")</code></pre><p>Depois de definir a criação da pasta, vamos executar novamente nosso script.</p><pre><code class="language-bash">python directory_clean.py --path ./test 

=&gt; ...
=&gt; Pasta ./test/pdf criada.</code></pre><p>Na primeira passagem da execução, podemos ver uma lista de logs nos informando que as pastas com tipos determinados de extensões de arquivo foram criadas.</p><h3 id="movendo-cada-arquivo-para-a-subpasta-correta"><strong>Movendo cada arquivo para a subpasta correta</strong></h3><p>A última etapa agora é realmente mover os arquivos para suas novas pastas pai.</p><p>Uma coisa importante a entender ao trabalhar com operações de <code>os</code> é que, às vezes, as operações não podem ser desfeitas. É o caso, por exemplo, da exclusão. Portanto, faz sentido primeiro apenas registrar o comportamento que nosso script alcançaria se o executássemos.</p><p>É por isso que o método <code>os.rename(...)</code> foi comentado aqui.</p><pre><code class="language-python"># Obtém o caminho da nova pasta e move o arquivo
    new_doc_path = os.path.join(subfolder_path, doc_name) + filetype
    # os.rename(doc, new_doc_path)
    moved += 1
    
    print(f"Arquivo {doc} movido para {new_doc_path}")</code></pre><p>Depois de executar nosso script e ver o registro correto, agora podemos remover a <em>hashtag </em>de comentário antes do nosso método <code>os.rename()</code> e dar a ele a sua vez.</p><pre><code class="language-python"># Obtém o caminho da nova pasta e move o arquivo
    new_doc_path = os.path.join(subfolder_path, doc_name) + filetype
    os.rename(doc, new_doc_path)
    moved += 1

    print(f"Arquivo {doc} movido para {new_doc_path}")

print(f"Renomeados {moved} de {len(docs)} arquivos.")</code></pre><pre><code class="language-bash">python directory_clean.py --path ./test 

=&gt; ...
=&gt; Arquivo ./test/test17.pdf movido para ./test/pdf/test17.pdf
=&gt; ...
=&gt; Renomeados 60 de 60 arquivos.</code></pre><p>Essa execução final, agora, moverá todos os arquivos para suas pastas apropriadas e nosso diretório estará limpo, sem a necessidade de ações manuais.</p><p>Na próxima etapa, poderíamos usar o script que criamos acima e, por exemplo, programá-lo para ser executado todas as segundas-feiras para limpar nossa pasta de Downloads para obter uma estrutura melhor.</p><p><strong>É exatamente por isso que estamos criando uma continuação dentro de nosso curso da Udemy, chamado <strong><a href="https://www.udemy.com/course/the-complete-guide-to-bot-creation/">Bot Creation and Workflow Automation</a></strong> </strong>(em português, criação de bots e automação de fluxos de trabalho)<strong><strong>.</strong></strong></p><h2 id="um-guia-completo-para-a-cria-o-de-bots-e-a-automa-o-do-seu-trabalho-di-rio"><strong><a href="https://www.udemy.com/course/the-complete-guide-to-bot-creation/">Um guia completo para a criação de bots e a automação do seu trabalho diário</a></strong></h2><p>Felix e eu criamos um<strong> curso em vídeo <strong>on</strong>-<strong>line </strong>para ensinar para você a criação de bots, </strong>com base no que você aprendeu criando o <strong><strong>InstaPy</strong></strong> e o <strong><strong>Travian-Bot</strong></strong>. De fato, ele foi, inclusive, <strong>forçado a derrubar o bot por ser eficaz até demais<strong>.</strong></strong></p><h3 id="junte-se-a-n-s-e-comece-a-aprender-curso-da-udemy-em-ingl-s-pago-"><strong><a href="https://www.udemy.com/course/the-complete-guide-to-bot-creation/">Junte-se a nós e comece a aprender</a> (curso da Udemy em inglês, pago).</strong></h3><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/zw20WBPjsr0?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="The Complete Guide to Bot Creation and Automating your Everyday Work" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><p>Se tiver perguntas ou feedback, fique à vontade para entrar em contato conosco pelo <a href="https://twitter.com/timigrossmann">Twitter</a> ou diretamente pela <a href="https://www.udemy.com/course/the-complete-guide-to-bot-creation/">seção de discussão do curso</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tutorial de scraping de dados da Web com Python – como fazer scraping de dados de um site da web ]]>
                </title>
                <description>
                    <![CDATA[ O Python é uma linguagem linda de se programar. Com um ecossistema de pacotes maravilhoso, nela, há bem menos ruído que em outras linguagens, além de ser muito fácil de usar. O Python pode ser usado para várias coisas – desde a análise de dados até a programação em back-end. ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/tutorial-de-scraping-de-dados-da-web-com-python-como-fazer-scraping-de-dados-de-um-site-da-web/</link>
                <guid isPermaLink="false">645432b0e704550645dffe6e</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Barbara Reis Bayer ]]>
                </dc:creator>
                <pubDate>Sun, 22 Oct 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/webscrapingposter.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/web-scraping-python-tutorial-how-to-scrape-data-from-a-website/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Web Scraping Python Tutorial – How to Scrape Data From A Website</a>
      </p><p>O Python é uma linguagem linda de se programar. Com um ecossistema de pacotes maravilhoso, nela, há bem menos ruído que em outras linguagens, além de ser muito fácil de usar. &nbsp;</p><p>O Python pode ser usado para várias coisas – desde a análise de dados até a programação em <em>back-end</em>. Dentre todas as opções, uma das maneiras mais empolgantes de se usar o Python é o <em>scraping </em>(em português, algo como "raspagem" ou extração) de dados na web.</p><p>Neste artigo, abordaremos como utilizar a linguagem Python para fazer <em>scraping</em> na web. Também trabalharemos com uma aula prática e interativa, guiando você à medida que avançamos neste artigo.</p><p><em>Observação: faremos scraping em um site da web hospedado por mim. Assim, poderemos aprender a fazê-lo em segurança. Muitas empresas não permitem o scraping de dados em seus sites. Então, essa será uma boa maneira de aprender. Certifique-se de checar isso antes de começar um scraping de dados na web.</em></p><h2 id="introdu-o-aula-de-scraping-de-dados-na-web"><strong>Introdução à aula de <em>scraping</em> de dados na web</strong></h2><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/screenzy-1601054558203.png" class="kg-image" alt="screenzy-1601054558203" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/screenzy-1601054558203.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/09/screenzy-1601054558203.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/09/screenzy-1601054558203.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/screenzy-1601054558203.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1272" loading="lazy"><figcaption>Pré-visualização de uma sala de aula no Codedamn.</figcaption></figure><p>Se você quiser programar em paralelo no decorrer deste artigo, pode usar <a href="https://codedamn.com/practice/web-scraping-python-beautifulsoup">esta aula no codedamn</a>, que consiste em diversos laboratórios que ajudam você a fazer o <em>scraping</em> de dados. Será um exercício prático e interativo no codedamn, muito similar à maneira que você aprende no freeCodeCamp.</p><p>Nesta aula, você utilizará essa página para testar o <em>scraping </em>de dados: </p><p><a href="https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/">https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/</a> &nbsp;(em inglês)</p><p>A aula é composta por sete laboratórios. Você resolverá o que há em cada um ao longo deste artigo. Usaremos o Python 3.8 e o BeautifulSoup 4 para o <em>scraping</em> de dados. </p><h2 id="parte-1-carregando-p-ginas-da-web-com-request-"><strong>Parte 1: carregando páginas da web com 'request' </strong></h2><p>Este é o <a href="https://codedamn.com/practice/web-scraping-python-beautifulsoup/a674e637-d958-4527-8930-cc53d1fb68e9">link deste laboratório</a>.</p><p>O módulo <code>requests</code> permite que você envie solicitações de HTTP usando o Python. </p><p>A solicitação de HTTP retorna um objeto <code>response</code> com todos os dados de resposta (conteúdo, código, status e assim por diante). Aqui vai um exemplo ao pegar HTML de uma página:</p><pre><code class="language-py">import requests

res = requests.get('https://codedamn.com')

print(res.text)
print(res.status_code)</code></pre><h3 id="requerimentos-necess-rios-"><strong>Requerimentos necessários: &nbsp;</strong></h3><ul><li>Pegar o conteúdo do URL a seguir usando o módulo <code>requests</code>: <strong><strong>https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/</strong></strong></li><li>Armazenar a resposta recebida (como demonstrado logo abaixo) em uma variável chamada <code>txt</code> &nbsp; &nbsp; </li><li>Armazenar o código do status (como demonstrado abaixo) em uma variável chamada <code>status</code> </li><li>Imprimir <code>txt</code> e <code>status</code> usando a função <code>print</code> &nbsp;</li></ul><p>Uma vez que você esteja entendendo o que está acontecendo no código abaixo, será bastante simples para você completar este laboratório. Aqui está a solução para ele: &nbsp;</p><pre><code class="language-py">import requests
# Faça uma solicitação para https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/
# Armazene o resultado na variável 'res'
res = requests.get(
    'https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/')
txt = res.text
status = res.status_code
# Imprima o resultado
print(txt, status)</code></pre><p>Vamos prosseguir para a parte 2 agora. Nela, você poderá programar mais, aproveitando o código que já fez até o momento.</p><h2 id="parte-2-extraindo-o-t-tulo-com-beautifulsoup"><strong>Parte 2: extraindo o título com BeautifulSoup &nbsp;</strong></h2><p>Este é o <a href="https://codedamn.com/practice/web-scraping-python-beautifulsoup/e55282e8-8481-4fb9-9a95-5df4d4a526ce">link para o laboratório</a>. </p><p>Em toda esta lição, você usará uma biblioteca chamada <code>BeautifulSoup</code> no Python para fazer o <em>scraping </em>de dados na web. Algumas funcionalidades que fazem o BeautifulSoup ser uma solução poderosa são: </p><ol><li>Fornecer muitos métodos simples e expressões "Pythônicas" para a navegação, pesquisa e modificação da árvore do DOM. Não é necessário programar muito para escrever uma aplicação. </li><li>O BeautifulSoup fica no topo dos analisadores (do inglês, <em>parsers</em>) mais populares de Python, como lxml e html5lib, permitindo que você teste diferentes estratégias de análise ou que faça uma troca entre velocidade e flexibilidade.</li></ol><p>Basicamente, o BeautifulSoup pode analisar qualquer coisa que tenha na página da web fornecida.</p><p>Aqui está um exemplo simples do BeautifulSoup: </p><pre><code class="language-py">from bs4 import BeautifulSoup

page = requests.get("https://codedamn.com")
soup = BeautifulSoup(page.content, 'html.parser')
title = soup.title.text # Obtém o texto que está entre as tags &lt;title&gt;(...)&lt;/title&gt;</code></pre><h3 id="requerimentos-necess-rios--1"><strong>Requerimentos necessários:</strong></h3><ul><li>Utilizar o pacote <code>requests</code> para pegar o título do URL: https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/</li><li>Utilizar o BeautifulSoup para armazenar o título dessa página dentro de uma variável chamada <code>page_title</code> </li></ul><p>Vendo o exemplo abaixo, você pode notar que, uma vez inserido o <code>page.content</code> dentro do BeautifulSoup, você poderá começar a trabalhar com a análise da árvore do DOM de uma maneira bem típica do Python. A solução para o laboratório seria:</p><pre><code class="language-py">import requests
from bs4 import BeautifulSoup

# Fazer uma solicitação para https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/
page = requests.get(
    "https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')

# Extrair o título da página
page_title = soup.title.text

# Imprimir o resultado
print(page_title)</code></pre><p>Esse foi um laboratório simples, onde tivemos que mudar o URL e imprimir o título da página. O código acima passaria nesse laboratório.</p><h2 id="parte-3-extraindo-body-e-head"><strong>Parte 3: &nbsp;extraindo <em>body </em>e <em>head</em></strong></h2><p>Aqui está o <a href="https://codedamn.com/practice/web-scraping-python-beautifulsoup/a91108fd-2f13-4640-ac62-d7877235376a">link para este laboratório</a>. &nbsp;</p><p>No último laboratório, você viu como extrair o <code>title</code> da página. Da mesma maneira, seria fácil extrair seções mais específicas.</p><p>Você também viu que deve usar <code>.text</code> nelas para obter a <em>string</em>, mas você também pode imprimi-las sem utilizar o <code>.text</code>. Isso dará a você a marcação completa. Tente rodar o exemplo abaixo:</p><pre><code class="language-py">import requests
from bs4 import BeautifulSoup

# Fazer uma solicitação
page = requests.get(
    "https://codedamn.com")
soup = BeautifulSoup(page.content, 'html.parser')

# Extrair o título da página
page_title = soup.title.text

# Extrair o body da página
page_body = soup.body

# Extrair a head da página
page_head = soup.head

# Imprimir o resultado
print(page_body, page_head)</code></pre><p>Vamos ver como você pode extrair as seções <code>body</code> e <code>head</code> de suas páginas.</p><h3 id="requerimentos-necess-rios--2"><strong>Requerimentos necessários:</strong></h3><ul><li>Repetir o experimento com o URL: <code>https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/</code></li><li>Armazenar o título da página (sem usar o .text) do URL em <code>page_title</code> </li><li>Armazenar o conteúdo do <code>body</code> (sem usar o .text) do URL em <code>page_body</code> </li><li>Armazenar o conteúdo da <code>head</code> (sem usar o .text) do URL em <code>page_head</code> </li></ul><p>Quando você tentar imprimir <code>page_body</code> ou <code>page_head</code>, verá que eles estarão impressos como <code>strings</code>. Na verdade, porém, quando você colocar <code>print(type page_body)</code>, verá que não é exatamente uma <em>string</em>. Mesmo assim, isso funcionará bem.</p><p>A solução desse exemplo seria simples, baseada no código abaixo:</p><pre><code class="language-py">import requests
from bs4 import BeautifulSoup

# Fazer uma solicitação
page = requests.get(
    "https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')

# Extrair o título da página
page_title = soup.title

# Extrair o body da página
page_body = soup.body

# Extrair a head da página
page_head = soup.head

# Imprimir o resultado
print(page_title, page_head)</code></pre><h2 id="parte-4-selecionando-com-o-beautifulsoup"><strong>Parte 4: selecionando com o BeautifulSoup</strong></h2><p>Aqui está o <a href="https://codedamn.com/practice/web-scraping-python-beautifulsoup/0ee9fa0e-e7ac-4afa-ad8a-b4b3d16900ef">link para este laboratório.</a></p><p>Agora que você já explorou algumas partes do BeautifulSoup, veremos como você pode selecionar elementos do DOM com métodos do BeautifulSoup.</p><p>Uma vez que você tenha a variável <code>soup</code> (como nos laboratórios anteriores), você pode trabalhar com <code>.select</code> nela, um seletor de CSS dentro do BeautifulSoup. Ou seja, você pode ter acesso à arvore do DOM do mesmo modo como você selecionaria elementos com CSS. Vejamos um exemplo:</p><pre><code class="language-py">import requests
from bs4 import BeautifulSoup

# Fazer uma solicitação
page = requests.get(
    "https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')

# Extrair o texto do primeiro &lt;h1&gt;(...)&lt;/h1&gt;
first_h1 = soup.select('h1')[0].text</code></pre><p>O <code>.select</code> retorna uma lista em Python de todos os elementos. Essa é a razão pela qual você selecionou apenas o primeiro elemento aqui com o índice <code>[0]</code>. &nbsp;</p><h3 id="requerimentos-necess-rios--3"><strong>Requerimentos necessários:</strong></h3><ul><li>Criar uma variável <code>all_h1_tags</code>. Colocá-la em uma lista vazia. </li><li>Usar <code>.select</code> para selecionar todas as tags <code>&lt;h1&gt;</code> e armazenar seus textos dentro da lista <code>all_h1_tags</code>. </li><li>Criar uma variável <code>seventh_p_text</code> e armazenar o texto do 7º elemento &nbsp;<code>p</code> &nbsp;(índice 6) dentro dela.</li></ul><p>A solução do laboratório é:</p><pre><code class="language-py">import requests
from bs4 import BeautifulSoup
# Fazer uma solicitação
page = requests.get(
    "https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')

# Criar all_h1_tags como uma lista vazia
all_h1_tags = []

# Definir all_h1_tags como todas as tags h1 de soup
for element in soup.select('h1'):
    all_h1_tags.append(element.text)

# Criar seventh_p_text e defini-lo como o texto do 7º elemento p da página
seventh_p_text = soup.select('p')[6].text

print(all_h1_tags, seventh_p_text)
</code></pre><p>Vamos continuar. </p><h2 id="parte-5-fazendo-o-scraping-dos-itens-que-est-o-no-topo">Parte 5: fazendo o scraping dos itens que estão no topo</h2><p>Aqui está o <a href="https://codedamn.com/practice/web-scraping-python-beautifulsoup/0f404796-1b8f-491b-9b50-9e47893d2e47">link deste laboratório</a>. </p><p>Agora, extrairemos os itens do topo retirados por <em>scraping</em> do URL https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/</p><p>Se você abrir essa página da web em uma nova guia, verá alguns itens no topo dela. Nesse laboratório, sua tarefa é pegar (ou fazer o <em>scraping </em>de) seus nomes e armazená-los em uma lista chamada <code>top_items</code>. Você também extrairá as suas avaliações.</p><p>Para concluir esse desafio, preste atenção nos seguintes pontos:</p><ul><li>Use o <code>.select</code> para obter os títulos. (Dica: um seletor para os títulos dos produtos poderia ser <code>a.title</code>)</li><li>Use <code>.select</code> para obter o rótulo de contagem de comentários para esses títulos de produtos.</li><li>Use <code>.select</code> para extrair o contador de avaliações dos títulos desses produtos. (Dica: um seletor para as avaliações poderia ser <code>div.ratings</code> ) Observação: esse é um rótulo completo (ou seja, 2 avaliações), não só um número.</li><li>Crie um dicionário nesse formato: </li></ul><pre><code class="language-py">info = {
   "title": 'Asus AsusPro Adv...   '.strip(),
   "review": '2 reviews\n\n\n'.strip()
}</code></pre><ul><li>Note que você está usando o método <code>strip</code> para remover quaisquer linhas extras ou espaços em branco que possam aparecer no resultado. Isso é algo <strong>importante</strong> para avançar nesse laboratório.</li><li>Use <code>.append</code> para adicionar esse dicionário em uma lista chamada <code>top_items</code>.</li><li>Imprima essa lista no final usando <code>print</code>.</li></ul><p>Há algumas tarefas a serem completadas nesse desafio. Vamos, primeiramente, dar uma olhada na solução para entendermos o que está acontecendo aqui: </p><pre><code class="language-py">import requests
from bs4 import BeautifulSoup
# Fazer uma solicitação
page = requests.get(
    "https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')

# Criar top_items como uma lista vazia
top_items = []

# Extrair e armazenar em top_items de acordo com as instruções
products = soup.select('div.thumbnail')
for elem in products:
    title = elem.select('h4 &gt; a.title')[0].text
    review_label = elem.select('div.ratings')[0].text
    info = {
        "title": title.strip(),
        "review": review_label.strip()
    }
    top_items.append(info)

print(top_items)</code></pre><p>Note que essa é apenas uma das soluções. Fique à vontade para tentar de outras maneiras. Nessa solução:</p><ol><li>Primeiro, você selecionará todos os elementos em <code>div.thumbnail</code>, obtendo uma lista de produtos individuais </li><li>Depois, você realiza uma iteração neles. </li><li>Você pode usar <code>select</code> outra vez para obter o título, já que ele permite iterar sobre ele mesmo.</li><li>Note que, agora que você já está rodando um laço para <code>div.thumbnail</code>, o seletor <code>h4 &gt; a.title</code> daria somente um resultado dentro de uma lista. O que você deve fazer é selecionar o elemento de número 0 dessa lista e, então, extrair o seu texto. </li><li>Agora, você já pode usar <code>strip</code> para remover quaisquer espaços extras contidos no texto e adicionar o texto à sua lista utilizando <code>append</code>.</li></ol><p>Simples, não é mesmo?</p><h2 id="parte-6-extraindo-links"><strong><strong>Parte 6: </strong>e<strong>xtraindo </strong>l<strong>inks </strong></strong></h2><p>Aqui está o <a href="https://codedamn.com/practice/web-scraping-python-beautifulsoup/be9b007a-ff03-45d5-ad44-1adecdb21e2a">link deste laboratório</a> &nbsp;</p><p>Até agora, você viu como é possível extrair o texto, ou <code>innerText</code>, dos elementos. Veremos em seguida como é possível extrair os atributos por meio da extração dos links da página. </p><p>Aqui está um exemplo de como extrair toda a informação de imagem da página:</p><pre><code class="language-py">import requests
from bs4 import BeautifulSoup
# Fazer uma solicitação
page = requests.get(
    "https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')

# Criar top_items como uma lista vazia
image_data = []

# Extrair e armazenar em top_items de acordo com as instruções
images = soup.select('img')
for image in images:
    src = image.get('src')
    alt = image.get('alt')
    image_data.append({"src": src, "alt": alt})

print(image_data)</code></pre><p>Nesse laboratório, sua tarefa é extrair o atributo <code>href</code> dos links e seus respectivos textos <code>text</code>. Certifique-se das seguintes coisas:</p><ul><li>Você terá que criar uma lista chamada <code>all_links</code></li><li>Nessa lista, armazene toda a informação do link. Isso deverá ficar no seguinte formato:</li></ul><pre><code class="language-py">info = {
   "href": "&lt;link here&gt;",
   "text": "&lt;link text here&gt;"
}</code></pre><ul><li>Certifique-se que o seu <code>text</code> esteja sem nenhum espaço em branco. </li><li>Certifique-se de checar se o seu <code>.text</code> é <code>None</code> antes de usar o <code>.strip()</code> nele. </li><li>Armazene todos esses dicionários em <code>all_links</code> </li><li>Use <code>print</code> para imprimir essa lista no final.</li></ul><p>Você extrairá os valores dos atributos da mesma maneira que você extrai os valores de um dicionário, usando a função <code>get</code>. Veremos agora a solução para esse laboratório:</p><pre><code class="language-py">import requests
from bs4 import BeautifulSoup
# Fazer uma solicitação
page = requests.get(
    "https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')

# Criar top_items como uma lista vazia
all_links = []

# Extrair e armazenar em top_items de acordo com as instruções
links = soup.select('a')
for ahref in links:
    text = ahref.text
    text = text.strip() if text is not None else ''

    href = ahref.get('href')
    href = href.strip() if href is not None else ''
    all_links.append({"href": href, "text": text})

print(all_links)</code></pre><p>Aqui, você extrairá o atributo <code>href</code> do mesmo modo que você fez no caso da imagem. A única coisa que você fará de diferente é conferir se ele é <code>None</code>, tal qual fizemos anteriormente. Queremos defini-lo como uma <em>string </em>vazia. Caso contrário, tiraremos o espaço em branco. </p><h2 id="parte-7-gerando-csv-a-partir-de-dados"><strong><strong>Parte 7: </strong>g<strong>erando CSV a partir de dados</strong></strong></h2><p>Aqui está o <a href="https://codedamn.com/practice/web-scraping-python-beautifulsoup/a10e33c1-7780-40bc-a541-adc632fab185">link deste laboratório</a></p><p>Por fim, vamos entender como gerar CSV a partir de um conjunto de dados. Você criará um CSV com os seguintes tópicos:</p><ol><li>Nome do produto</li><li>Preço</li><li>Descrição</li><li>Avaliações</li><li>Imagem do produto</li></ol><p>Esses produtos estão localizados em <code>div.thumbnail</code>. O padrão do CSV está logo abaixo:</p><pre><code class="language-py">import requests
from bs4 import BeautifulSoup
import csv
# Fazer uma solicitação
page = requests.get(
    "https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')

all_products = []

products = soup.select('div.thumbnail')
for product in products:
    # TODO: Trabalho
    print("Trabalho com o produto aqui")


keys = all_products[0].keys()

with open('products.csv', 'w', newline='') as output_file:
    dict_writer = csv.DictWriter(output_file, keys)
    dict_writer.writeheader()
    dict_writer.writerows(all_products)
</code></pre><p>Você deverá extrair os dados do site da web e gerar o CSV para três produtos.</p><h3 id="requerimentos-necess-rios--4"><strong><strong>Requerimentos necessários: </strong></strong></h3><ul><li>O nome do produto é a versão com o espaço em branco cortado do nome do item (exemplo - Asus AsusPro Adv.) </li><li>Preço é o espaço em branco cortado mas com o rótulo do preço inteiro (exemplo - $1101.83) </li><li>A descrição é a versão com o espaço em branco cortado da descrição do produto (exemplo - Asus AsusPro Advanced BU401LA-FA271G Dark Grey, 14", Core i5-4210U, 4GB, 128GB SSD, Win7 Pro)</li><li>Avaliações são as versões com o espaço em branco cortado do produto (exemplo - 7 avaliações) </li><li>Imagem do produto é o URL (atributo src) da imagem do produto (exemplo - /webscraper-python-codedamn-classroom-website/cart2.png)</li><li>O nome do arquivo CSV deve ser <strong><strong>products.csv</strong></strong> e deve ser armazenado na mesma pasta que o seu arquivo <strong><strong>script.py.</strong></strong></li></ul><p>Aqui está a solução para esse laboratório: </p><pre><code class="language-py">import requests
from bs4 import BeautifulSoup
import csv
# Fazer uma solicitação
page = requests.get(
    "https://codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/")
soup = BeautifulSoup(page.content, 'html.parser')

# Criar top_items como uma lista vazia
all_products = []

# Extrair e armazenar em top_items de acordo com as instruções
products = soup.select('div.thumbnail')
for product in products:
    name = product.select('h4 &gt; a')[0].text.strip()
    description = product.select('p.description')[0].text.strip()
    price = product.select('h4.price')[0].text.strip()
    reviews = product.select('div.ratings')[0].text.strip()
    image = product.select('img')[0].get('src')

    all_products.append({
        "name": name,
        "description": description,
        "price": price,
        "reviews": reviews,
        "image": image
    })


keys = all_products[0].keys()

with open('products.csv', 'w', newline='') as output_file:
    dict_writer = csv.DictWriter(output_file, keys)
    dict_writer.writeheader()
    dict_writer.writerows(all_products)
</code></pre><p>O bloco <code>for</code> é o mais interessante aqui. Você extrai todos os elementos e atributos de tudo o que já foi aprendido até agora em todos os laboratórios.</p><p>Quando você rodar esse código, terá um bom arquivo CSV. Isso é praticamente todo o básico de <em>scraping </em>de dados com o BeautifulSoup!</p><h2 id="conclus-o"><strong><strong>Conclusão </strong></strong></h2><p>Eu espero que essa aula interativa do <a href="https://codedamn.com/">codedamn</a> tenha ajudado você a entender o básico de <em>scraping </em>de dados com o Python. </p><p>Se você gostou desta aula e deste artigo, o autor pede que compartilhe com ele sya opinião no <a href="https://twitter.com/mehulmpt">Twitter</a> e no <a href="https://instagram.com/mehulmpt">Instagram</a> do autor. Ele adoraria ter o seu feedback!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Se você tiver loops lentos em Python, você pode consertá-los…até não poder mais ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Maxim Mamaev Vamos pegar um problema computacional como exemplo, escrever o código e ver como podemos melhorar o tempo de execução. Aqui vamos nós. Montando a cena: o problema da mochila Este é o problema computacional que usaremos como exemplo: O problema da mochila [https://pt.wikipedia.org/wiki/Problema_da_mochila] é um problema ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/se-voce-tiver-loops-lentos-em-python-pode-tentar-conserta-los/</link>
                <guid isPermaLink="false">64b01e8eb04bf0067ce23b23</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isabel Cristina Nunes de Sousa ]]>
                </dc:creator>
                <pubDate>Wed, 13 Sep 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_t5vZrkc3PdQZ78RX7Jx8Lg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/if-you-have-slow-loops-in-python-you-can-fix-it-until-you-cant-3a39e03b6f35/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">If you have slow loops in Python, you can fix it…until you can’t</a>
      </p><p>Escrito por: Maxim Mamaev</p><p>Vamos pegar um problema computacional como exemplo, escrever o código e ver como podemos melhorar o tempo de execução. Aqui vamos nós.</p><h3 id="montando-a-cena-o-problema-da-mochila">Montando a cena: o problema da mochila</h3><p>Este é o problema computacional que usaremos como exemplo:</p><p>O <a href="https://pt.wikipedia.org/wiki/Problema_da_mochila">problema da mochila</a> é um problema bem conhecido em otimização combinatória. Nesta seção, revisaremos seu tipo mais comum, o <strong>problema da mochila <strong>0–1</strong></strong>, e sua solução por meio de programação dinâmica. Se você estiver familiarizado com o assunto, pode pular essa parte.</p><p>Você recebe uma mochila de capacidade <strong><strong>C<em><em> </em></em></strong></strong>e uma coleção de <strong><strong>N</strong></strong> itens. Cada item tem peso <strong><strong>w[i]</strong></strong> e valor <strong><strong>v[i]</strong></strong>. Sua tarefa é arrumar a mochila com os itens mais valiosos. Em outras palavras, você deve maximizar o valor total dos itens que coloca na mochila, com uma restrição: o peso total dos itens levados <strong>não pode</strong> exceder a capacidade da mochila.</p><p>Depois de obter uma solução, o peso total dos itens na mochila é chamado de "peso da solução" e seu valor total é o "valor da solução".</p><p>O problema tem muitas aplicações práticas. Por exemplo, você decidiu investir R$ 1.600 em uma famosa ação da FAANG (nome coletivo das ações do Facebook, Amazon, Apple, Netflix e Google, também conhecida como Alphabet). Cada ação tem um preço de mercado atual e a estimativa de preço de um ano. A partir de um dia em 2018, eles são os seguintes:</p><pre><code>========= ======= ======= ==========
Empresa   Ticker   Preço  Estimativa
========= ======= ======= ==========
Alphabet  GOOG    1030    1330
Amazon    AMZN    1573    1675
Apple     AAPL    162     193 
Facebook  FB      174     216 
Netflix   NFLX    312     327
========= ======= ======= ==========</code></pre><p>Para simplificar o exemplo, vamos supor que você nunca colocaria todos os seus ovos na mesma cesta. Você está disposto(a) a comprar <strong><strong>n</strong>ão<strong> m</strong>ais</strong> do que uma ação de cada. Quais ações você compra para maximizar seu lucro?</p><p>Esse é um problema da mochila. Seu orçamento (R$ 1.600) é a <strong><strong>capaci</strong>dade<strong> (C)</strong></strong> de armazenamento. As ações são os itens a serem embalados. Os preços atuais são os <strong>p<strong>es</strong>os<strong> (w)</strong></strong>. As estimativas de preços são os <strong><strong>val</strong>or<strong>es</strong></strong>. O problema parece trivial. No entanto, a solução não é evidente à primeira vista – se você deve comprar uma ação da Amazon, ou uma ação do Google mais uma de alguma combinação de Apple, Facebook, ou Netflix.</p><p>Claro que, nesse caso, você pode fazer cálculos rápidos à mão e chegar na solução: você deve comprar Google, Netflix, e Facebook. Desse modo, você gasta R$ 1.516 e espera ganhar R$ 1.873.</p><p>Agora, você acredita que descobriu uma mina de outro. Você destrói seu cofrinho e recebe R$ 10.000. Apesar de sua empolgação, você permanece inflexível com a regra "uma ação – uma compra". Portanto, com esse orçamento maior, você tem que ampliar suas opções. Você decide considerar todas as 100 ações da lista da NASDAQ como candidatas para compra.</p><p>O futuro nunca foi tão brilhante, mas, de repente, você percebe que, para identificar sua carteira de investimentos ideal, você terá que verificar cerca de 2¹⁰⁰ combinações. Mesmo que você seja superotimista com a iminência e a onipresença da economia digital, qualquer economia requer — no mínimo — um universo onde funcione. Infelizmente, em alguns trilhões de anos, quando sua computação terminar, nosso universo provavelmente não existirá.</p><h4 id="algoritmo-de-programa-o-din-mica"><strong>Algoritmo de programação dinâmica</strong></h4><p>Temos que abandonar a abordagem de força bruta e programar alguma solução inteligente. Pequenos problemas de mochila (e o nosso é pequeno, acredite ou não) são resolvidos por programação dinâmica. A ideia básica é partir de um problema trivial cuja solução conhecemos e depois adicionaremos complexidade passo a passo.</p><p>Se você achar as explicações a seguir muito abstratas, aqui está uma <a href="https://github.com/mmamaev/looping_python/blob/master/ks_dp_example.pdf" rel="noopener">ilustração comentada</a> da solução para um problema de mochila bem pequeno. Isso ajudará você a visualizar o que está acontecendo.</p><p>Suponha que, dados os primeiros<strong> </strong>itens <strong><strong>i</strong></strong> da coleção, nós saibamos os valores de solução <strong><strong>s(i, k)</strong> </strong>para todas as capacidades de mochila <strong><strong>k</strong></strong> no intervalo de 0 a <strong><strong>C</strong></strong>.</p><p>Em outras palavras, costuramos mochilas "auxiliares" <strong><strong>C+1</strong></strong> de todos os tamanhos de 0 a <strong><strong>C</strong></strong>. Em seguida, organizamos nossa coleção, pegamos o primeiro item <strong><strong>i</strong> </strong>e temporariamente separamos todo o resto. E agora assumimos que, por alguma mágica, nós sabemos como embalar de maneira ideal cada um dos pacotes desse conjunto funcional de <strong><strong>i</strong></strong> itens. Os itens que escolhemos do conjunto funcional podem ser diferentes para pacotes diferentes, mas no momento não estamos interessados em quais itens pegamos ou pulamos. É apenas o valor da solução <strong><strong>s(i, k)</strong></strong> que registramos para cada um de nosso pacotes recém costurados.</p><p>Agora, buscamos o próximo item <strong><strong>(i+1)</strong></strong>º da coleção e adicionamos ao conjunto funcional. Vamos encontrar valores de solução para todas as mochilas auxiliares com esse novo conjunto funcional. Em outras palavras, nós encontramos <strong><strong>s(i+1, k)</strong> </strong>para todo <strong><strong>k=0..C</strong> </strong>dado <strong><strong>s(i, k)</strong></strong>.</p><p>Se <strong><strong>k</strong></strong> for menor que o peso do novo item <strong><strong>w[i+1]</strong></strong>, não podemos pegar esse item. De fato, mesmo que pegássemos <strong>apenas</strong><em><em> </em></em>esse item, ele sozinho não caberia na mochila. Portanto, <strong><strong>s(i+1, k) = s(i, k)</strong></strong> para todo <strong>k &lt; w[i+1]</strong>.</p><p>Para os valores <strong>k &gt;= w[i+1]</strong> temos que fazer uma escolha: ou colocamos o novo item na mochila de capacidade <strong>k</strong> ou o pulamos. Temos que avaliar essas duas opções para determinar qual delas nos dá mais valor embalado no pacote.</p><p>Se pegarmos o <strong><strong>(i+1)</strong></strong>º item, adquirimos o valor <strong><strong>v[i+1]</strong></strong> e consumimos a parte da capacidade da mochila para acomodar o peso <strong><strong>w[i+1]</strong></strong>. Isso nos deixa com a capacidade <strong><strong>k–w[i+1]</strong></strong><em><em> </em></em>que devemos preencher de modo otimizado usando (alguns dos) primeiros<em> </em><strong><strong>i</strong></strong> itens. Esse preenchimento otimizado tem o valor de solução <strong><strong>s(i, k–w[i+1])</strong></strong>. Esse número já é conhecido por nós porque, por suposição, conhecemos todos os valores de solução para o conjunto funcional de <strong><strong>i</strong></strong> itens. Portanto, o valor da solução candidata para a mochila <strong><strong>k</strong></strong> com o item <strong><strong>i+1</strong></strong> levado seria<br><strong><strong>s(i+1, k | i+1 </strong>levado<strong>) = v[i+1] + s(i, k–w[i+1])</strong></strong>.</p><p>A outra opção seria pular o item <strong>i+1</strong>. Nesse caso, nada muda em nossa mochila, e o valor da solução candidata seria o mesmo que <strong>s(i, k)</strong>.</p><p>Para decidir sobre a melhor opção, comparamos os dois candidatos para os valores da solução:</p><p><strong><strong>s(i+1, k | i+1 </strong>levado<strong>) = v[i+1] + s(i, k–w[i+1])</strong></strong><br><strong><strong>s(i+1, k | i+1 </strong>ignorado<strong>) = s(i, k)</strong></strong></p><p>O máximo destes torna-se a solução <strong><strong>s(i+1, k)</strong></strong>.</p><p>Resumindo:</p><pre><code>if k &lt; w[i+1]:
	s(i+1, k) = s(i, k)
else:
	s(i+1, k) = max( v[i+1] + s(i, k-w[i+1]), s(i, k) )</code></pre><p>Agora, podemos resolver o problema da mochila passo a passo. Começamos com o conjunto de trabalho vazio <strong><strong>(<em><em>i=0</em></em>)</strong></strong>. Obviamente, <strong><strong>s(0, k) = 0</strong> </strong>para qualquer <strong><strong>k</strong></strong>. Em seguida, avançamos adicionando itens ao conjunto de trabalho e encontrando os valores de solução <strong><strong>s(i, k)</strong> </strong>até chegarmos a <strong><strong>s(i+1=N, k=C)</strong></strong>, que é o valor de solução do problema original.</p><p>Observe que, ao fazer isso, construímos a grade de valores da solução <strong><strong><em><em>NxC</em></em></strong></strong>.</p><p>No entanto, apesar de ter aprendido o valor da solução, não sabemos exatamente quais itens foram colocados na mochila. Para descobrir isso, retrocedemos a grade. Partindo de <strong><strong>s(i=N, k=C)</strong></strong>, comparamos <strong><strong>s(i, k)</strong></strong> com<strong><strong> s(i–1, k)</strong></strong>.</p><p>Se <strong><strong>s(i, k) = s(i–1, k)</strong></strong>, o <strong><strong>i</strong></strong>-ésimo item não foi considerado. Nós reiteramos com <strong><strong>i=i–1</strong></strong> mantendo o valor de <strong><strong>k</strong></strong> inalterado. Caso contrário, o <strong><strong>i</strong></strong>-ésimo item foi retirado e, para a próxima etapa de exame, encolhemos a mochila em <strong><strong>w[i] </strong></strong>— definimos <strong><strong>i=i–1, k=k–w[i]</strong></strong>.</p><p>Desse modo, examinamos todos os itens do <strong><strong>N</strong></strong>-ésimo ao primeiros e determinamos quais deles foram colocados na mochila. Isso nos dá a solução para o problema da mochila.</p><h3 id="c-digo-e-an-lise"><strong><strong>C</strong>ódigo e análise</strong></h3><p>Como temos o algoritmo, vamos comparar várias implementações, começando por uma simples. O código está disponível no <a href="https://github.com/mmamaev/looping_python/blob/master/ks_dp_solvers.py" rel="noopener">GitHub</a>.</p><p>Os dados são a lista <strong><strong>Nasdaq 100</strong></strong>, contendo preços atuais e estimativas de preços para cem ações (até um dia em 2018). Nosso orçamento de investimento é de R$ 10.000.</p><p>Lembre-se que preços de ações não são números redondos em reais, mas vêm com centavos. Portanto, para obter a solução exata, temos que contar tudo em centavos — definitivamente queremos evitar números float. Portanto, a capacidade de nossa mochila é ($)10.000 x 100 centavos = ($)1.000.000, e o tamanho total de nosso problema <strong><strong>N x C</strong></strong> = 1.000.000.</p><p>Com um inteiro ocupando 4 bytes de memória, esperamos que o algoritmo vá consumir aproximadamente 400 MB de RAM. Portanto, a memória não será uma limitação. É com o tempo de execução que devemos no preocupar.</p><p>Claro, todas as nossas implementações produzirão a mesma solução. Para referência, o investimento (o peso da solução) é 999930 (R$ 9.999,30) e o retorno esperado (o valor da solução) é 1219475 (R$ 12.194,75). A lista de ações a comprar é bem longa (80 de 100 itens). Você pode obtê-la rodando o código.</p><p>Lembre-se de que <strong>este é um exercício de programação, não um conselho de investimento</strong>. Quando você for ler esse artigo, os preços e as estimativas terão mudado em relação ao que é usado aqui como exemplo.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_SEihq9zvMPCd8qLZHaUHIg.jpg" class="kg-image" alt="1_SEihq9zvMPCd8qLZHaUHIg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/1_SEihq9zvMPCd8qLZHaUHIg.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_SEihq9zvMPCd8qLZHaUHIg.jpg 720w" sizes="(min-width: 720px) 720px" width="720" height="480" loading="lazy"><figcaption>Crédito: <a href="https://www.snapwi.re/user/mavoro" rel="noopener ugc nofollow">Martin von Rotz</a></figcaption></figure><h4 id="os-bons-e-velhos-loops-do-tipo-for"><strong>Os bons e velhos<strong> l</strong>oops<strong> </strong>do tipo "<strong>for</strong>"</strong></h4><p>A implementação direta do algoritmo é dada abaixo.</p><pre><code>def solve_naive(capacity, items, weights, values):

    grid = [[0] * (capacity+1)]
    for item in range(items):
        grid.append(grid[item].copy())
        for k in range(weights[item], capacity+1):
            grid[item + 1][k] = max(grid[item][k], grid[item][k-weights[item]] + values[item])

    solution_value = grid[items][capacity]
    solution_weight = 0
    taken = []
    k = capacity
    for item in range(items, 0, -1):
        if grid[item][k] != grid[item-1][k]:
            taken.append(item - 1)
            k -= weights[item - 1]
            solution_weight += weights[item-1]

    return solution_value, solution_weight, taken</code></pre><p>Existem duas partes.</p><p>Na primeira parte (linhas 3-7 acima), dois loops <code>for</code> aninhados são usados para construir a grade da solução.</p><p>O loop externo adiciona itens ao conjunto de trabalho até atingirmos <strong><strong>N</strong></strong><em><em> </em></em>(o valor de <strong><strong>N</strong></strong><em><em> </em></em>é passado no parâmetro <code>items</code>). A linha de valores de solução para cada novo conjunto de trabalho é inicializada com os valores calculados para o conjunto de trabalho anterior.</p><p>O loop interno para cada conjunto de trabalho itera os valores de <code>k</code> do peso do <code>item</code> recém adicionado a <strong><strong>C</strong></strong> (o valor de <strong><strong>C</strong></strong><em><em> </em></em>é passado no parâmetro <code>capacity</code>).</p><p>Note que não precisamos iniciar o loop de <strong><strong>k=0</strong></strong><em><em>. </em></em>Quando <code>k</code><em><em> </em></em>é menor do que o peso do<em> </em><code>item</code>, os valores da solução são sempre os mesmos calculados para o conjunto de trabalho anterior. Esses números já foram copiados para a linha atual pela inicialização.</p><p>Quando os loops são concluídos, temos a grade e o valor da solução.</p><p>A segunda parte (linhas 9-17) é um único loop <code>for</code> de <strong><strong>N</strong></strong><em><em> </em></em>iterações. Ele retrocede a grade para descobrir quais itens foram levados pela mochila.</p><p>Mais adiante, nos concentraremos exclusivamente na primeira parte do algoritmo, já que este possui complexidade de tempo e espaço <strong><strong>O(N*C)</strong></strong>. A parte de retrocesso requer apenas tempo <strong><strong>O(N)</strong> </strong>e não gasta nenhuma memória adicional – seu consumo de recursos é relativamente insignificante.</p><p>A implementação direta leva <strong><strong>180 </strong>segundos</strong> para resolver o problema da mochila <strong><strong>Nasdaq 100</strong></strong> no meu computador.</p><p>Isso é muito ruim? Por um lado, com as velocidades da era moderna, não estamos acostumados a passar três minutos esperando que um computador faça as coisas. Por outro lado, o tamanho do problema - cem milhões - parece realmente intimidador, então, talvez, três minutos seja ok?</p><p>Para obter algum <em>benchmark</em>, vamos programar o mesmo algoritmo em outra linguagem. Precisamos de uma linguagem compilada estaticamente tipada para garantir a velocidade de computação. Não, não C. Não é chique. Vamos seguir a moda e escrever em Go:</p><pre><code>func solver(capacity, items int, weights, values []int) (int, int, []int) {
    
    grid :=  make([][]int, items+1, items+1)
    grid[0] = make([]int, capacity+1, capacity+1) 

    for item := 0; item &lt; items; item++ {

        grid[item+1] = make([]int, capacity+1, capacity+1)
        for k:=0; k&lt;weights[item]; k++ {
            grid[item + 1][k] = grid[item][k]
        }
        for k:=weights[item]; k &lt;= capacity; k++ {
            grid[item + 1][k] = max(grid[item][k], grid[item][k-weights[item]] + values[item])
        }
    } 

    solution_value := grid[items][capacity]
    solution_weight := 0
    var taken []int
    k := capacity
    for item := items; item &gt; 0; item-- {
        if grid[item][k] != grid[item-1][k] {
            taken = append(taken, item-1)
            k -= weights[item - 1]
            solution_weight += weights[item-1]
        }
    }

    return solution_value, solution_weight, taken
}</code></pre><p>Como você pode ver, o código Go é bem similar ao do Python. Até copiei e colei uma linha, a mais longa, como está.</p><p>Qual é o tempo de execução? <strong><strong>400</strong> milissegundos</strong>! Em outras palavras, o Python foi 500 vezes mais lento do que o Go. A lacuna provavelmente será ainda maior se tentarmos em C. Isso é definitivamente um desastre para o Python.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_lmi8rlKeei1hcMRkeShzIw.jpg" class="kg-image" alt="1_lmi8rlKeei1hcMRkeShzIw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/1_lmi8rlKeei1hcMRkeShzIw.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/09/1_lmi8rlKeei1hcMRkeShzIw.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_lmi8rlKeei1hcMRkeShzIw.jpg 1100w" sizes="(min-width: 720px) 720px" width="1100" height="733" loading="lazy"><figcaption>"Honestamente, se você fosse mais lento, estaria andando para trás." Citação de "Harry Potter e a Câmara Secreta" <a href="https://pixabay.com/en/snail-rainy-day-spring-animal-slow-3385348/" rel="noopener ugc nofollow">Fonte da imagem original</a>.</figcaption></figure><p>Para descobrir o que torna o código Python mais lento, vamos executá-lo com o <a href="https://github.com/rkern/line_profiler" rel="noopener"><em>line profiler</em></a>. Você pode encontrar a saída do <em>profiler </em>para esta implementação e as subsequentes do algoritmo no <a href="https://github.com/mmamaev/looping_python/blob/master/ks_dp_solvers_profiles.txt" rel="noopener">GitHub</a>.</p><p>No solucionador direto, 99,7% do tempo de execução é gasto em duas linhas. Essas duas linhas compõem o loop interno, que é executado 98 milhões de vezes:</p><pre><code>Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    ...
    42       101        170.0      1.7      0.0  for item in range(items):
    43       100    1457275.0  14572.8      0.3      grid.append(grid[item].copy())
    44  98387558  121134401.0      1.2     26.4      for k in range(weights[item], capacity+1):
    45  98387458  336078747.0      3.4     73.3          grid[item + 1][k] = max(grid[item][k], grid[item][k-weights[item]] + values[item])
    ...
</code></pre><p>Peço desculpas pelas linhas excessivamente longas, mas o <em>line profiler</em> não pode lidar adequadamente com quebras de linha na mesma instrução.</p><p>Ouvi dizer que o operador <code>for</code> do Python é lento, mas, curiosamente, a maior parte do tempo não é gasta na linha <code>for</code> mas no corpo do <em>loop</em>.</p><p>Podemos dividir o corpo do <em>loop </em>em operações individuais para ver se alguma operação específica é muito lenta:</p><pre><code>Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    ...
    67       101        196.0      1.9      0.0      for item in range(items):
    68       100    1454886.0  14548.9      0.2          grid.append(grid[item].copy())
    69       100       1463.0     14.6      0.0          wi = weights[item]
    70       100        323.0      3.2      0.0          vi = values[item]
    71  98387558  133663554.0      1.4     16.7          for k in range(wi, capacity+1):
    72  98387458  156110242.0      1.6     19.4              a = grid[item][k]
    73  98387458  194935490.0      2.0     24.3              b = grid[item][k-wi] + vi
    74  98387458  138902753.0      1.4     17.3              if b &gt; a:
    75  60782758  109728042.0      1.8     13.7                  grid[item + 1][k] = b
    76                                                       else:
    77  37604700   67944391.0      1.8      8.5                  grid[item + 1][k] = a
    ...</code></pre><p>Parece que nenhuma operação em particular se destaca. Os tempos de execução das operações individuais dentro do <em>loop </em>interno são praticamente os mesmos que os tempos de execução de operações análogas em outras partes do código.</p><p>Observe como quebrar o código aumentou o tempo total de execução. O <em>loop </em>interno agora leva 99,9% do tempo de execução. Quanto mais burro seu código Python, mais lento ele fica. Interessante, não é?</p><h4 id="fun-o-map-integrada"><strong>Função<strong> <em>map </em></strong>integrada</strong></h4><p>Vamos tornar o código mais otimizado e substituir o <em>loop </em><code>for</code> interno por uma função <code>map()</code> integrada:</p><pre><code>def solve_map(capacity, items, weights, values):
  
    grid = [[0] * (capacity+1)]
    for item in range(items):
        grid.append(grid[item].copy())
        this_weight = weights[item]
        this_value = values[item]
        
        grid[item+1][this_weight:] = 
            list(map(lambda k: max(grid[item][k], 
                                   grid[item][k - this_weight] + this_value), 
                     range(this_weight, capacity+1)))
        
    solution_value = grid[items][capacity]
    solution_weight = 0
    taken = []
    k = capacity
    for item in range(items, 0, -1):
        if grid[item][k] != grid[item-1][k]:
            taken.append(item - 1)
            k -= weights[item - 1]
            solution_weight += weights[item-1]

    return solution_value, solution_weight, taken</code></pre><p>O tempo de execução desse código é de <strong>102 segundos</strong>, estando 78 segundos abaixo da pontuação da implementação direta. De fato, <code>map()</code> é executado visivelmente, mas não excessivamente, mais rápido.</p><h4 id="list-comprehension"><strong><strong><em>List comprehension</em></strong></strong></h4><p>Você deve ter notado que cada execução do <em>loop </em>interno produz uma lista (que é adicionada à grade de solução como uma nova linha). O jeito do Python de criar listas é, claro, <em>list comprehension</em>. Vamos tentar isso, em vez de <code>map()</code>.</p><pre><code>def solve_list_comp(capacity, items, weights, values):

    grid = [[0] * (capacity+1)]
    for item in range(items):
        grid.append(grid[item].copy())
        this_weight = weights[item]
        this_value = values[item]
        
        grid[item+1][this_weight:] = 
            [max(grid[item][k], grid[item][k - this_weight] + this_value) 
             for k in range(this_weight, capacity+1)]
        
    solution_value = grid[items][capacity]
    solution_weight = 0
    taken = []
    k = capacity
    for item in range(items, 0, -1):
        if grid[item][k] != grid[item-1][k]:
            taken.append(item - 1)
            k -= weights[item - 1]
            solution_weight += weights[item-1]

    return solution_value, solution_weight, taken</code></pre><p>O programa terminou em <strong><strong>81 se</strong>gu<strong>nd</strong>o<strong>s</strong></strong>. Conseguimos outra melhoria e reduzimos o tempo de execução pela metade em comparação à implementação direta (180 s). Fora de contexto, isso seria elogiado como um progresso significativo. Infelizmente, ainda estamos a anos-luz do nosso <em>benchmark</em> de 0,4 s.</p><h4 id="arrays-do-numpy"><strong>Arrays do <strong>NumPy</strong></strong></h4><p>Por fim, esgotamos as ferramentas integradas do Python. Sim, posso ouvir o rugido do público cantando "NumPy! NumPy!" Mas, para apreciar a eficiência do NumPy, devemos colocá-lo em contexto, tentando <code>for</code>, <code>map()</code> e <em>list comprehension</em> de antemão.</p><p>Ok, agora é a hora do NumPy. Então, abandonamos as listas e colocamos nossos dados em <em>arrays</em> do NumPy:</p><pre><code>def solve_list_comp_numpy(capacity, items, weights, values):

    grid = np.empty((items + 1, capacity + 1), dtype=int)
    grid[0] = 0
    for item in range(items):
        grid[item+1] = grid[item]
        this_weight = weights[item]
        this_value = values[item]
        
        grid[item+1, this_weight:] = 
            [max(grid[item, k], grid[item, k - this_weight] + this_value) 
             for k in range(this_weight, capacity+1)]

    solution_value = grid[items, capacity]
    solution_weight = 0
    taken = []
    k = capacity
    for item in range(items, 0, -1):
        if grid[item, k] != grid[item-1, k]:
            taken.append(item - 1)
            k -= weights[item - 1]
            solution_weight += weights[item-1]

    return solution_value, solution_weight, taken</code></pre><p>De repente, o resultado é desencorajador. Este código é executado 1,5 vezes mais devagar do que a solução sem graça por <em>list comprehension</em> (<strong><strong>123 s</strong></strong> em comparação com os 81 s). Como isso?</p><p>Vamos examinar os perfis de linha para ambos solucionadores.</p><pre><code>Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
Vanilla list comprehension

   245         1       8212.0   8212.0      0.0  grid = [[0] * (capacity+1)]
   246
   247       101       1654.0     16.4      0.0  for item in range(items):
   248       100    1452204.0  14522.0      0.7      grid.append(grid[item].copy())
   249       100       1603.0     16.0      0.0      this_weight = weights[item]
   250       100        272.0      2.7      0.0      this_value = values[item]
   251
   252       100  202696910.0 2026969.1     99.3     grid[item+1][this_weight:] = [max(grid[item][k], grid[item][k - this_weight] + this_value) for k in range(this_weight, capacity+1)]

Using numpy arrays

   273         1         42.0     42.0      0.0  grid = np.empty((items + 1, capacity + 1), dtype=int)
   274         1       2527.0   2527.0      0.0  grid[0] = 0
   275       101       1427.0     14.1      0.0  for item in range(items):
   276       100     322952.0   3229.5      0.1      grid[item+1] = grid[item]
   277       100       1341.0     13.4      0.0      this_weight = weights[item]
   278       100        266.0      2.7      0.0      this_value = values[item]
   279       100  311244493.0 3112444.9     99.9     grid[item+1, this_weight:] = [max(grid[item, k], grid[item, k - this_weight] + this_value) for k in range(this_weight, capacity+1)]
</code></pre><p>A inicialização do <code>grid[0]</code> como um <em>array</em> do NumPy (linha 274) é três vezes mais rápida do que quando é feita com uma lista do Python (linha 245). Dentro do <em>loop </em>externo, a inicialização do <code>grid[item+1]</code> é 4,5 vezes mais rápida para um <em>array </em>do NumPy (linha 276) do que para uma lista (linha 248). Até agora, tudo bem.</p><p>No entanto, a execução da linha 279 é 1,5 vezes mais lenta do que seu análogo sem o NumPy na linha 252. O problema é que <em>list comprehension </em>cria uma <strong>lista</strong> de valores, mas armazenamos esses valores em um <strong>array do NumPy</strong> que é encontrado no lado esquerdo da expressão. Portanto, essa linha adiciona implicitamente uma sobrecarga de conversão de uma lista em um <em>array</em> do NumPy. Com a linha 279 respondendo por 99,9% do tempo de execução, todas as vantagens do NumPy observadas anteriormente tornam-se insignificantes.</p><p>Ainda precisamos, porém, de uma maneira de<strong> iterar </strong>por meio de <em>arrays </em>para fazer cálculos. Já aprendemos que <em>list comprehension </em>é a ferramenta de iteração mais rápida. A propósito, se você tentar construir um <em>array </em>do NumPy dentro de um bom e velho <em>loop </em><code>for</code>, evitando a conversão de lista para <em>array</em> do NumPy, obterá o impressionante tempo de execução de 295 segundos. Então, estamos travados e o NumPy é inútil? Claro que não.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_0yrZox6O3EEEKregnri0Vw.jpg" class="kg-image" alt="1_0yrZox6O3EEEKregnri0Vw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/1_0yrZox6O3EEEKregnri0Vw.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_0yrZox6O3EEEKregnri0Vw.jpg 720w" sizes="(min-width: 720px) 720px" width="720" height="480" loading="lazy"><figcaption>Crédito: <a href="https://www.pexels.com/@taras-makarenko-188506" rel="noopener ugc nofollow">Taras Makarenko</a></figcaption></figure><h4 id="uso-adequado-do-numpy"><strong>Uso adequado do<strong> NumPy</strong></strong></h4><p>Apenas armazenar dados em <em>arrays </em>do NumPy não adianta. O verdadeiro poder do NumPy vem com as funções que executam cálculos em <em>arrays </em>do NumPy. Elas pegam <em>arrays </em>como parâmetros e retornam <em>arrays </em>como resultados.</p><p>Por exemplo, existe a função <code>where()</code>, que recebe três <em>arrays </em>como parâmetros: <code>condition</code>, <code>x</code>, e <code>y</code>, e retorna um <em>array </em>construído pela seleção de elementos de <code>x</code> ou de <code>y</code>. O primeiro parâmetro, <code>condition</code>, é um <em>array</em> de booleanos. Ele diz de onde escolher: se um elemento de <code>condition</code> for avaliado como <code>True</code>, o elemento correspondente de <code>x</code> é enviado para a saída, caso contrário, o elemento de <code>y</code> é selecionado.</p><p>Observe que a função do NumPy faz tudo isso em uma única chamada. Percorrer os <em>arrays </em>passa a ser um processo integrado.</p><p>É assim que usamos <code>where()</code> como um substituto do <em>loop </em><code>for</code> interno no primeiro solucionador ou, respectivamente, o <em>list comprehension</em> do último:</p><pre><code>def solve_numpy_func(capacity, items, weights, values):

    grid = np.empty((items + 1, capacity + 1), dtype=int)
    grid[0] = 0
    for item in range(items):
        this_weight = weights[item]
        this_value = values[item]
        grid[item+1, :this_weight] = grid[item, :this_weight]
        temp = grid[item, :-this_weight] + this_value
        grid[item + 1, this_weight:] = 
            np.where(temp &gt; grid[item, this_weight:], 
                     temp, 
                     grid[item, this_weight:])

    solution_value = grid[items, capacity]
    solution_weight = 0
    taken = []
    k = capacity
    for item in range(items, 0, -1):
        if grid[item][k] != grid[item - 1][k]:
            taken.append(item - 1)
            k -= weights[item - 1]
            solution_weight += weights[item-1]

    return solution_value, solution_weight, taken</code></pre><p>Existem três trechos de códigos interessantes: linha 8, linha 9 e linhas 11-13, conforme numeradas acima. Juntas, elas substituem o <em>loop </em>interno que percorreria todos os tamanhos possíveis de mochilas para encontrar os valores da solução.</p><p>Até que a capacidade da mochila atinja o peso do item recém adicionado ao conjunto de trabalho (<code>this_weight</code>), devemos ignorar esse item e definir os valores da solução para os do conjunto de trabalho anterior. Isso é bastante direto (linha 8):</p><pre><code>grid[item+1, :this_weight] = grid[item, :this_weight]</code></pre><p>Em seguida, construímos um <em>array </em>auxiliar <code>temp</code> (linha 9):</p><pre><code>temp = grid[item, :-this_weight] + this_value</code></pre><p>Esse código é análogo, mas muito mais rápido do que:</p><pre><code>[grid[item, k — this_weight] + this_value
for k in range(this_weight, capacity+1)]</code></pre><p>Ele calcula possíveis valores de solução se o novo item for levado para cada uma das mochilas que podem acomodar esse item.</p><p>Observe como o <em>array </em><code>temp</code> é construído adicionando um <strong>escalar </strong>a um <em>array</em>. Esse é outro recurso poderoso do NumPy chamado "<em>broadcasting</em>". Quando o NumPy vê operandos com dimensões diferentes, ele tenta expandir (ou seja, "transmitir" – em inglês, <em>broadcast</em>) o operando de baixa dimensão para corresponder às dimensões do outro. Em nosso caso, o escalar é expandido para um <em>array </em>do mesmo tamanho que <code>grid[item, :-this_weight]</code> e esses dois <em>arrays </em>são somados. Como resultado, o valor de <code>this_value</code> é adicionado a cada elemento de <code>grid[item, :-this_weight]</code> — nenhum <em>loop </em>é necessário.</p><p>Na próxima parte (linhas 10–13), usamos a função <code>where()</code>, que faz exatamente o que é exigido pelo algoritmo: compara dois possíveis valores de solução para cada tamanho de mochila e seleciona aquele que é maior.</p><pre><code>grid[item + 1, this_weight:] =             
    np.where(temp &gt; grid[item, this_weight:],
             temp,
             grid[item, this_weight:])</code></pre><p>A comparação é feita pelo parâmetro <code>condition</code>, que é calculado como <code>temp &gt; grid[item, this_weight:]</code>. Essa é uma operação elementar que produz um <em>array </em>de valores booleanos, um para cada tamanho de uma mochila auxiliar. Um valor <code>True</code> significa que o item correspondente deve ser colocado na mochila. Portanto, o valor da solução obtido do <em>array </em>é o segundo argumento da função <code>temp</code>. Caso contrário, o item deve ser ignorado, e o valor da solução é copiado da linha anterior da grade - o terceiro argumento da função <code>where()</code>.</p><p>Por fim, o motor de dobra foi ativado! Esse solucionador é executado em <strong>0,55 s</strong>. Isso é 145 vezes mais rápido que o solucionador baseado em <em>list comprehension </em>e 329 vezes mais rápido que o código utilizando o <em>loop </em><code>for</code>. Embora não tenhamos ultrapassado o solucionador escrito em Go (0,4 s), chegamos bem perto disso.</p><h4 id="alguns-loops-s-o-pra-ficar"><strong>Alguns <em>loops </em>são pra ficar</strong></h4><p>Espere, mas e o <em>loop </em><code>for</code> externo?</p><p>Em nosso exemplo, o código do <em>loop </em>externo, que não faz parte do <em>loop </em>interno, é executado apenas 100 vezes, para que possamos escapar sem mexer nele. No entanto, outras vezes, o <em>loop </em>externo pode ser tão longo quanto o interno.</p><p>Podemos reescrever o <em>loop </em>externo usando uma função do NumPy de maneira semelhante ao que fizemos para o <em>loop </em>interno? A resposta é não.</p><p>Apesar de ambos serem <em>loops </em><code>for</code>, os <em>loops </em>externo e interno são bem diferentes no que fazem.</p><p>O <em>loop </em>interno produz um <em>array </em>1D baseado em outro<em> array </em>1D cujos elementos são <strong>todos conhecidos</strong> quando o <em>loop </em>começa. É essa disponibilidade prévia dos dados de entrada que nos permitiu substituir o <em>loop </em>interno por <code>map()</code>, <em>list comprehension</em> ou uma função do NumPy.</p><p>O <em>loop </em>externo produz um <em>array </em>2D a partir de um<em> array </em>1D, cujos elementos <strong>não</strong> são conhecidos quando o <em>loop </em>começa. Além disso, esses componentes de <em>arrays </em>são calculados por um algoritmo recursivo: podemos encontrar os elementos <strong><strong>(i+1)</strong></strong>º do <em>array </em>somente depois de encontrarmos o <strong><strong>i</strong></strong>º.</p><p>Suponha que o <em>loop </em>externo possa ser apresentado como uma função:<br><code>grid = g(row0, row1, … rowN)</code><br>Todos os parâmetros da função devem ser avaliados antes que a função seja chamada, mas somente <code>row0</code> é conhecida de antemão. Como o cálculo da <strong><strong>(i+1)</strong></strong>ª linha depende da disponibilidade da <strong>i</strong>-ésima, precisamos de um <em>loop </em>indo de <code>1</code> a <code>N</code> para calcular todos os parâmetros da linha. Portanto, para substituir o <em>loop </em>externo com uma função, precisamos de outro <em>loop </em>que avalie os parâmetros dessa função. Esse outro <em>loop </em>é exatamente o <em>loop </em>que estamos tentando substituir.</p><p>A outra maneira de evitar o <em>loop </em><code>for</code> externo é usar recursão. Pode-se facilmente escrever a função recursiva <code>calculate(i)</code> que produz a <strong>i</strong>-ésima linha da grade. Para fazer o trabalho, a função precisa conhecer a<strong> (i-1)</strong>ª linha, portanto, chama a si mesma como <code>calculate(i-1)</code> e, em seguida, calcula a <strong>i</strong>-ésima linha usando as funções do NumPy como fizemos anteriormente. Todo o <em>loop </em>externo pode então ser substituído por <code>calculate(N)</code>. Para tornar a imagem completa, um solucionador de mochila recursivo pode ser encontrado no código-fonte que acompanha este artigo no <a href="https://github.com/mmamaev/looping_python/blob/master/ks_dp_solvers.py" rel="noopener">GitHub</a>.</p><p>No entanto, a abordagem recursiva claramente não é escalável. O Python não é otimizado para a <a href="https://pt.wikipedia.org/wiki/Recursividade_(ci%C3%AAncia_da_computa%C3%A7%C3%A3o)#Fun%C3%A7%C3%B5es_recursivas_em_cauda">recursão de cauda</a>. A profundidade da pilha de recursão é, por padrão, limitada pela ordem de mil. Esse limite é certamente conservador, mas, quando exigimos uma profundidade de milhões, o estouro da pilha é altamente provável. Além disso, o experimento mostra que a recursão nem mesmo fornece uma vantagem de desempenho sobre um solucionador baseado em NumPy com o <em>loop </em><code>for</code> externo.</p><p>É aqui que esgotamos as ferramentas fornecidas pelo Python e suas bibliotecas (pelo que sei). Se for absolutamente necessário acelerar o <em>loop</em> que implementa um algoritmo recursivo, será preciso recorrer ao Cython, ou a uma versão do Python compilada em JIT, ou a outra linguagem.</p><h3 id="aprendizados"><strong>Aprendizado<strong>s</strong></strong></h3><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_YvnvnzC2wMwZ_EF3qFHBcg.png" class="kg-image" alt="1_YvnvnzC2wMwZ_EF3qFHBcg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/1_YvnvnzC2wMwZ_EF3qFHBcg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_YvnvnzC2wMwZ_EF3qFHBcg.png 800w" sizes="(min-width: 720px) 720px" width="800" height="325" loading="lazy"><figcaption>Tempos de execução das soluções do problema da mochila</figcaption></figure><ul><li>Faça cálculos numéricos com as funções do Numpy. Elas são duas ordens de magnitude mais rápidas do que as ferramentas integradas do Python.</li><li>Das ferramentas integradas do Python, <em>list comprehension</em> é mais rápida que <code>map()</code>, que é significativamente mais rápido que <code>for</code>.</li><li>Para algoritmos profundamente recursivos, os <em>loops </em>são mais eficientes do que as chamadas recursivas de funções.</li><li>Você não pode substituir <em>loops </em>recursivos por <code>map()</code>, <em>list comprehension</em> ou uma função do NumPy.</li><li>O código "burro" (dividido em operações elementares) é o mais lento. Use funções e ferramentas integradas.</li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Instalação de várias versões do Python no Windows usando o Virtualenv ]]>
                </title>
                <description>
                    <![CDATA[ Você está aqui porque:  1. Está usando o Windows 10, 11 ou superior  2. Gostaria de usar diversas versões do Python no mesmo computador  3. Está cansado de ver a internet dizer "basta usar o Virtualenv, ora" Versão resumida  1. Abra o prompt de comando e ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/instalacao-de-varias-versoes-do-python-no-windows-usando-o-virtualenv/</link>
                <guid isPermaLink="false">64a471c5d4e9dc0571a407e2</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Thu, 06 Jul 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/download-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/installing-multiple-python-versions-on-windows-using-virtualenv/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Installing Multiple Python Versions on Windows Using Virtualenv</a>
      </p><p>Você está aqui porque:</p><ol><li>Está usando o Windows 10, 11 ou superior</li><li>Gostaria de usar diversas versões do Python no mesmo computador</li><li>Está cansado de ver a internet dizer "basta usar o Virtualenv, ora"</li></ol><h3 id="vers-o-resumida"><strong>Versão resumida</strong></h3><ol><li>Abra o <code>prompt de comando</code> e digite <code>pip install virtualenv</code></li><li>Faça o download da versão que quer do <code>python</code> (NÃO a adicione ao PATH!), e lembre-se do <code>caminho\para\o\novo\executavel\do\python.exe</code> para a versão recém-instalada</li><li>Para criar um virtualenv (ambiente virtual), abra o <code>prompt de comando</code> e digite<br><code>virtualenv \caminho\para\o\novo\executavel\do\python.exe</code></li><li>Se estiver usando o <code>PyCharm</code>, atualize o <code>interpretador de projetos</code> e a <code>inspeção de compatibilidade de código</code>.</li><li>Para instalar os pacotes:<br>(I) Ative o virtualenv: abra o <code>prompt de comando</code> e digite <code>caminho\para\o\env\Scripts\activate.bat</code><br>(II) &nbsp;Instale os pacotes desejados<br>(III) &nbsp;Desative com <code>deactivate</code>.</li></ol><h3 id="vers-o-estendida"><strong>Versão estendida</strong></h3><h4 id="pr-logo"><strong>Prólogo</strong></h4><p>Se estiver usando a <a href="https://www.anaconda.com/download#downloads">aplicação Anaconda</a>, &nbsp;este processo pode ser mais fácil usando a GUI de lá. Eu não tentei. Se alguém tentar, ficaria feliz de saber o resultado. 🙂</p><h4 id="1-instale-o-virtualenv"><strong>1. Instale o virtualenv</strong></h4><p>Se já estiver usando ambientes virtuais ou se estiver usando o Anaconda, certifique-se de que as próximas etapas estejam sendo realizadas <strong>fora</strong> de todos esses ambientes.</p><h4 id="2-instale-o-python"><strong>2. Instale o Python</strong></h4><p>Você pode baixar o Python do <a href="https://www.python.org/downloads/">site oficial</a>. Se quiser a versão <code>python3.7.3</code>, por exemplo, você pode baixá-la <a href="https://www.python.org/downloads/release/python-373/">aqui</a>.</p><blockquote>Nota da tradução: a versão 3.7.3 acima é apenas um exemplo e era, possivelmente, a versão mais recente do Python quando a autora lançou este artigo. A versão mais recente (no momento da tradução) é a 3.11.4 e você pode baixá-la para o Windows <a href="https://www.python.org/ftp/python/3.11.4/python-3.11.4-amd64.exe">aqui</a>.</blockquote><p>O arquivo que você baixará será um <code>instalador executável do Windows versão x86–64</code> ou <code>instalador executável do Windows x86</code> se, por algum motivo, você estiver usando uma versão do Windows de 32 bits.</p><p>Depois de concluir o download, abra o arquivo executável e um prompt de instalação se abrirá.</p><ul><li>Você NÃO deseja adicionar o novo Python ao seu PATH, pois vamos ter diversas versões do Python no mesmo computador. Queremos que cada aplicação conheça apenas uma versão do Python.</li><li>Use o local padrão sugerido para o novo Python ou forneça um local que quiser. Seja como for, guarde bem esse local, o qual passaremos a chamar daqui para diante de <code>C:\&lt;um_caminho_qualquer&gt;\Python37</code> .</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/1_6TY68J0S0Mls0m3fthyaCg.png" class="kg-image" alt="1_6TY68J0S0Mls0m3fthyaCg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/07/1_6TY68J0S0Mls0m3fthyaCg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/07/1_6TY68J0S0Mls0m3fthyaCg.png 1000w" sizes="(min-width: 720px) 720px" width="1000" height="610" loading="lazy"><figcaption>Caixa verde: "Pressione aqui" | Caixa azul: "Lembre-se deste caminho" | Caixa vermelha: "Não marque esta caixa"&nbsp;</figcaption></figure><h4 id="3-crie-um-virtualenv"><strong>3. Crie um virtualenv</strong></h4><p>Abra o <code>prompt de commando</code> ou, se estiver usando o Anaconda, abra o <code>prompt do Anaconda</code>.</p><p>Decida onde você quer que seu virtualenv esteja, por exemplo,<br><code>C:\Users\&lt;seu_nome_de_usuário&gt;\Anaconda3\envs\&lt;nome_do_ambiente&gt;</code> .</p><p>Digite:</p><p><code>virtualenv C:\Users\&lt;seu_nome_de_usuário&gt;\Anaconda3\envs\&lt;nome_do_ambiente&gt; -p C:\&lt;um_caminho_qualquer&gt;\Python37\python.exe</code></p><h4 id="4-atualize-o-interpretador-do-pycharm"><strong>4. Atualize o interpretador do PyCharm</strong></h4><p>Se estiver usando o PyCharm, abra o projeto no qual você gostaria de trabalhar (quer dizer, aquele que será escrito nessa nova versão do Python) e vá em <code>File -&gt; Settings -&gt; Project -&gt; Project Interpreter</code>. Pressione o ícone da engrenagem e, a seguir, em <code>Add...</code>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/image-43.png" class="kg-image" alt="image-43" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/07/image-43.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/07/image-43.png 794w" sizes="(min-width: 720px) 720px" width="794" height="340" loading="lazy"></figure><p>Isso abrirá uma janela do prompt que permitirá a você definir um novo interpretador:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/1_EyUVRuDrL1NtI-6kyAylpw.png" class="kg-image" alt="1_EyUVRuDrL1NtI-6kyAylpw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/07/1_EyUVRuDrL1NtI-6kyAylpw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/07/1_EyUVRuDrL1NtI-6kyAylpw.png 1000w" sizes="(min-width: 720px) 720px" width="1000" height="343" loading="lazy"><figcaption>Na parte 3, insira o caminho para o interpretador</figcaption></figure><p>Assumindo que você está usando as inspeções de código (em inglês, <em>Code Inspections</em>), pode ser que você precise dizer ao PyCharm qual versão do Python ele deve inspecionar. Acesse <code>File -&gt; Settings-&gt; Editor -&gt; Inspections -&gt; Python -&gt; Code compatibility Inspection</code>, garanta que a caixa na parte superior indica o projeto específico no qual você está trabalhando e marque a caixa de sua versão do Python.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/1_vHL71y1uLNsUGPOEOrFmkQ.png" class="kg-image" alt="1_vHL71y1uLNsUGPOEOrFmkQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/07/1_vHL71y1uLNsUGPOEOrFmkQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/07/1_vHL71y1uLNsUGPOEOrFmkQ.png 985w" sizes="(min-width: 720px) 720px" width="985" height="696" loading="lazy"><figcaption>Se não ver sua versão do Python na lista Options (número 6), também pode ser o momento de atualizar o PyCharm... e, sim, foi o que aconteceu comigo</figcaption></figure><h4 id="5-instale-os-pacotes"><strong>5. Instale os pacotes</strong></h4><p>No momento, seu <code>virtualenv</code> contém apenas os pacotes cruciais, <code>pip</code> e <code>setuptools</code>. Para instalar mais pacotes:</p><ol><li>Abra o <code>prompt de comando</code> ou o <code>prompt do Anaconda</code> e <strong><strong>ative</strong></strong> seu virtualenv digitando<br><code>C:\Users\&lt;seu_nome_de_usuário&gt;\Anaconda3\envs\&lt;nome_do_ambiente&gt;\activate.bat</code></li><li>Use o <code>pip</code> para instalar os pacotes, como você faz normalmente.</li><li><strong><strong>De</strong>sativ<strong>e</strong></strong> seu virtualenv digitando <code>deactivate</code> .</li></ol><h3 id="ep-logo"><strong>Epílogo</strong></h3><p>Hoje de manhã, quando decidi abrir um novo projeto com uma versão diferente do Python, pensei, "É isso! Basta usar o virtualenv", porque a internet disse que eu podia "simplesmente fazer isso".</p><p>Bem, está funcionando agora. Então, nada de rancor, querida internet, mas, vamos combinar, o "simplesmente" não foi um pouco demais, não? Em que parte <em><em>reinstal</em>ar<em>-</em>o-<em>PyCharm-</em>somente<em>-</em>porque<em>-</em>eu<em>-</em>quero<em>-</em>ter<em>-</em>inspeção-de-código-decente</em> se ajusta à categoria do "simplesmente"? Simples para quem?</p><p>Seja como for, durante o percurso, eu encontrei diversos guias úteis, mas cada um me conduziu "simplesmente" por uma etapa. Foi aí que decidi colocar tudo em um único lugar.</p><p>Espero que minha jornada tenha ajudado você com a sua e que possamos nos divertir com a programação, com o mínimo de atrito relacionado à instalação e configuração de coisas quanto possível. 😀</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/07/0_vaVbNQubipSg57aI.jpg" class="kg-image" alt="0_vaVbNQubipSg57aI" width="577" height="433" loading="lazy"><figcaption>Em português: "Não sei bem se está tudo funcionando finalmente ou se quebrei tudo de uma vez"</figcaption></figure> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 11 projetos em Python para desenvolvedores juniores praticarem ]]>
                </title>
                <description>
                    <![CDATA[ É necessário construir projetos para dominar o desenvolvimento de software. Não um. Nem dois. Muitos projetos! No entanto, você deve começar da maneira correta. Se você começar qualquer projeto aleatório como desenvolvedor iniciante ou júnior, não apenas se sentirá perdido como também começará a questionar se programação é para você. ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/11-projetos-em-python-para-desenvolvedores-juniores-praticarem/</link>
                <guid isPermaLink="false">6480ca573aab28058e381432</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ João Eduardo Gomes ]]>
                </dc:creator>
                <pubDate>Wed, 28 Jun 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/602164960a2838549dcc1147.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/python-projects-junior-developers/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">11 Python Projects Junior Developers Can Build for Coding Practice</a>
      </p><p>É necessário construir projetos para dominar o desenvolvimento de software.</p><p>Não um.</p><p>Nem dois.</p><p>Muitos projetos!</p><p>No entanto, você deve começar da maneira correta. Se você começar qualquer projeto aleatório como desenvolvedor iniciante ou júnior, não apenas se sentirá perdido como também começará a questionar se programação é para você. Portanto, trabalhe de maneira inteligente.</p><p>Comece do mais simples.</p><p>Primeiro, melhore sua confiança a partir de um projeto pequeno. Depois, de outro projeto pequeno. Depois de vários desses projetos pequenos, passe para algo maior e vá tão longe quanto sua imaginação permitir.</p><h2 id="antes-de-construir-qualquer-projeto-aprenda-o-b-sico"><strong>Antes de construir qualquer projeto, aprenda o básico</strong></h2><p>Se você não aprender o básico, você estará construindo sobre uma base frágil.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-307.png" class="kg-image" alt="image-307" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/06/image-307.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/06/image-307.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/06/image-307.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-307.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1333" loading="lazy"></figure><p>Independentemente do nível de domínio que você espera alcançar em Python, você precisará desses fundamentos antes de começar qualquer projeto.</p><p>Você precisa saber como:</p><ul><li>declarar variáveis</li><li>receber dados inseridos pelo usuário</li><li>armazenar informações</li><li>repetir uma ação através de laços de repetição</li><li>escrever funções para reaproveitar blocos de código</li></ul><p>É basicamente isso.</p><p>Naturalmente, há mais a ser aprendido em Python, mas esse é o básico que você precisa saber. Será suficiente para você começar projetos para iniciantes.</p><p>Há aquela sensação tentadora de que você precisa terminar diversos tutoriais em Python antes de trabalhar em qualquer projeto.</p><p>Não siga por esse caminho.</p><blockquote><em>Muitos caem na armadilha de seguir um tutorial atrás do outro até se sentirem ultrapreparados. Em vez disso, aprenda o básico primeiro. Em seguida, construa alguns projetos pequenos. Feito isso, volte a aprender com mais tutoriais.</em></blockquote><p>Vá por mim, você pode terminar 100 tutoriais e ainda sentir que não está pronto para construir projeto algum.</p><p>Estudar por conta própria não é suficiente.</p><p>Você precisa aplicar o que aprendeu.</p><h2 id="como-fazer-uso-desses-projetos"><strong>Como fazer uso desses projetos</strong></h2><ul><li>Primeiro, leia as instruções e certifique-se de que as entendeu. Tente expressar com suas próprias palavras o que tiver entendido delas.</li><li>Tente solucionar o problema por conta própria sem buscar um tutorial no YouTube ou um código semelhante no GitHub. Provavelmente, vai ser difícil. Tudo bem. Dê o seu melhor. Essa é a ideia de <a href="https://fs.blog/2012/07/what-is-deliberate-practice/">prática deliberada</a> (texto em inglês) da Psicologia Comportamental.</li><li>Se você não conseguiu progredir por conta própria, assista ao tutorial do YouTube e veja o código de exemplo. Você também pode pesquisar na internet por mais tutoriais de exemplo e outros códigos em Python que visam resolver o mesmo problema.</li><li>Depois disso, tente dar um passo atrás e escrever o código sozinho sem olhar o tutorial. De novo: dê o seu melhor. Esse é o chamado <strong><em>grit</em></strong> (às vezes traduzido como <em>garra</em>), também da <a href="https://www.youtube.com/watch/H14bBuluwB8">Psicologia Comportamental</a> (vídeo com legenda em português disponível). Você precisa disso.</li><li>Em hipótese alguma você deve copiar cegamente o código do tutorial e se dar por satisfeito. Você até pode terminar o projeto rapidamente, mas a realidade é que você não aprendeu nada.</li><li>Se você por acaso sentir que está travado após várias tentativas, faça uma pausa. <a href="https://www.sciencefriday.com/articles/how-pinball-helps-explain-ways-we-think-and-learn/">Sabemos pelas pesquisas neurocientíficas</a> (texto em inglês) que o nosso subconsciente continua aprendendo mesmo quando paramos. Isso acontece porque nossa mente muda do modo focado para o modo difuso.</li><li>Quando conseguir resolver um problema, comemore! É importante ter esse reforço positivo para construir referências do seu sucesso. No futuro, quando sua mente disser <code>"Você não vai conseguir"</code> e fizer você duvidar do seu potencial, você pode responder a ela: <code>"não é verdade; e eis a prova de que consegui no passado e vou conseguir agora também"</code>.</li><li>Repita, repita, repita.</li></ul><p>Você também poderá usar essas dicas para outros projetos além dos que serão listados abaixo. Agora, vamos aos projetos em Python.</p><h2 id="projetos-para-desenvolvedores-juniores-de-python"><strong>Projetos para desenvolvedores juniores de Python</strong></h2><p>Aqui estão alguns projetos amigáveis para iniciantes que você pode desenvolver:</p><ol><li>Par ou ímpar</li><li>Jogo Mad Libs</li><li>Contador de palavras</li><li>Informações biográficas</li><li>Qual é a sigla?</li><li>Pedra, papel, tesoura</li><li>Adivinhar o número</li><li>Verificador de palíndromo</li><li>Calculadora de gorjeta</li><li>Divisor de e-mail</li><li>Gerador de letras de música</li></ol><h3 id="par-ou-mpar"><strong>Par ou ímpar</strong></h3><p>Dê boas-vindas ao usuário e peça-o para inserir um número de 1 a 1000.</p><p>Depois de o usuário informar o número, verifique se ele é par ou ímpar e diga ao usuário.</p><p>Exemplo:</p><ul><li>Mensagem: <code>Em qual número você pensou?</code></li><li>Entrada: <code>25</code></li><li>Saída: <code>Esse é um número ímpar! Gostaria de verificar outro?</code></li></ul><h3 id="jogo-mad-libs"><strong>Jogo Mad Libs</strong></h3><p>Peça ao usuário para informar alguns valores.</p><p>Eles podem ser qualquer coisa como um nome, um adjetivo, um pronome ou mesmo uma ação. Uma vez recebidos esses valores, reorganize-os e crie uma história.</p><ul><li>Aqui temos um <a href="https://www.youtube.com/watch?v=u7g9mRzQLYE">tutorial no YouTube de como criar um jogo Mab Libs usando o Python</a> (vídeo em inglês).</li><li>Aqui, você verá &nbsp;um <a href="https://github.com/ChalzZy/Mad-Libs-Generator/blob/master/Mad_Libs_Generator/main.py">código de exemplo</a> no Github.</li></ul><h3 id="contador-de-palavras"><strong>Contador de palavras</strong></h3><p>Peça ao usuário que informe em uma frase algo em que ele pensou. Depois, conte o número de palavras na sentença informada e mostre esse valor na tela.</p><p>Examplo:</p><ul><li>Mensagem: <code>Informe em uma frase algo em que você pensou hoje</code> .</li><li>Entrada: <code>Bem, é só mais um dia para eu ser um profissional em programação</code> .</li><li>Saída: <code>Legal! Você acabou de me dizer no que pensou usando 13 palavras!</code></li></ul><p>Para dar um passo mais adiante: abra um arquivo com conteúdo textual nele, conte o número de palavras no texto e mostre esse valor na tela.</p><p>Eis aqui <a href="https://gist.github.com/fdb/1c7234fb49757df588c1302f44f0f125">um código de exemplo</a> no Github.</p><h3 id="informa-es-biogr-ficas"><strong>Informações biográficas</strong></h3><p>Faça algumas perguntas pedindo informações sobre o usuário. Em seguida, verifique se as informações inseridas são válidas. Por fim, mostre um resumo de todas as informações que foram introduzidas.</p><p>Exemplo: Qual é o seu nome? Se o usuário informar <code>*</code>, a aplicação deve informar que esse é um nome inválido e pedir que o usuário informe um nome válido.</p><p>Ao final, deve ser exibido na tela um resumo como este:</p><pre><code>- Nome: João da Silva
- Data de nascimento: 1 de Janeiro de 1954
- Endereço: Avenida das flores, 1500, São Paulo
- Objetivos: Ser o melhor programador que já existiu.
</code></pre><h3 id="qual-a-sigla"><strong>Qual é a sigla?</strong></h3><p>Peça ao usuário para informar um conceito ou o nome de alguma organização. A aplicação deve retornar uma sigla adequada. Por exemplo:</p><ul><li>Entrada -&gt; <code>O Mais Rápido Possível</code>. Saída -&gt; <code>OMRP</code>.</li><li>Entrada -&gt; <code>Organização Mundial da Saúde</code>. Saída -&gt; <code>OMS</code>.</li><li>Entrada -&gt; <code>Ausência Sem Justificativa</code>. Saída -&gt; <code>ASJ</code>.</li></ul><h3 id="pedra-papel-tesoura"><strong>Pedra, papel, tesoura</strong></h3><p>Esta é uma brincadeira popular entre duas pessoas. Cada jogador usa uma das mãos para formar uma das seguintes opções:</p><ul><li><code>pedra</code> (mão fechada)</li><li><code>papel</code> (mão aberta)</li><li><code>tesoura</code> (estender apenas os dedos indicador e médio da mão em formato de V)</li></ul><p>Veja aqui um <a href="https://www.youtube.com/watch?v=5wfxO_juzYM">tutorial no YouTube sobre como programar um jogo de pedra-papel-tesoura em Python</a> (vídeo em inglês).</p><h3 id="adivinhar-o-n-mero"><strong>Adivinhar o número</strong></h3><p>A aplicação deve pedir ao usuário para adivinhar um número entre 1 e 50.</p><p>Se o usuário informar um número fora desse intervalo, deve ser exibida uma mensagem de erro lembrando-o dos valores aceitos.</p><p>Sempre que o usuário errar o número, a aplicação deve perguntar se ele gostaria de tentar novamente ou de desistir.</p><p>Se o jogador conseguir acertar o número, parabenize-o e exiba o número de tentativas que ele fez até acertar.</p><p>Você pode conferir aqui <a href="https://www.youtube.com/watch?v=2sWTNMi4XpE">um tutorial no YouTube para programar um jogo de adivinhar o número em Python</a> (vídeo em inglês).</p><h3 id="verificador-de-pal-ndromo"><strong>Verificador de palíndromo</strong></h3><p>Peça ao usuário que informe cinco palavras. Em seguida, verifique se alguma das cinco palavras é um palíndromo.</p><p>Um palíndromo é uma palavra que permanece a mesma, caso seja lida da esquerda para a direita ou no sentido inverso.</p><p>Exemplo:</p><ul><li><code>radar</code> é um palíndromo.</li><li><code>salas</code> também é.</li><li><code>geeks</code> não é.</li></ul><p>Aqui temos <a href="https://github.com/kuzmicheff/palindrome/blob/master/palindrome.py">um código de exemplo</a> no Github para esse projeto.</p><h3 id="calculadora-de-gorjeta"><strong>Calculadora de gorjeta</strong></h3><p>O objetivo dessa aplicação é calcular o quanto de gorjeta deve-se pagar pelo serviço. Nesse cenário, é preciso pedir pelo valor total da conta. Depois, é preciso exibir na tela as opções de gorjeta: 18%, 20% ou 25% do valor total da conta.</p><p>Exemplo:</p><ul><li>Mensagem: <code>Qual o valor total da conta?</code></li><li>Entrada: <code>R$ 55,87</code></li><li>Saída: <code>18% de gorjeta equivale a R$ 10,06; o que aumenta o total a ser pago para R$65,93</code></li></ul><p>Lembre-se de arredondar os valores para cima para ter números mais amigáveis. Se quiser ir mais além, pode perguntar o número de pessoas envolvidas para dividir igualmente o valor da conta e da gorjeta entre eles.</p><p>Se quiser ir mais longe ainda, faça essa divisão de valores de maneira proporcional. Por exemplo: uma pessoa paga 70% do valor e outra paga 30%.</p><h3 id="divisor-de-e-mail"><strong>Divisor de e-mail</strong></h3><p>Receba o endereço de e-mail do usuário e verifique se ele tem um domínio próprio ou popular. Por exemplo:</p><ul><li>Entrada: <code>mary.jane@gmail.com</code></li><li>Saída: <code>Olá, Mary. Vejo que seu e-mail está registrado no Google. Que bacana!</code>.</li><li>Entrada: <code>peter.pan@myfantasy.com</code></li><li>Saída: <code>Oi, Peter. Parece que você tem sua própria configuração personalizada no MyFantasy. Impressionante!</code>.</li></ul><p>Esse é um projeto em Python bem útil e que pode ser bastante usado futuramente. O programa ajuda a obter o nome de usuário e o nome do domínio de um endereço de e-mail.</p><p>Se quiser ir mais adiante, você pode personalizar a aplicação para enviar uma mensagem para o host com essa informação.</p><p>Você pode conferir <a href="https://www.youtube.com/watch?v=mVpcbF3Q5wE&amp;feature=emb_title">este tutorial no YouTube</a> (vídeo em inglês) e <a href="https://gist.github.com/TomColBee/4cf607f2e5b0e7b703b4d343d6a6c4e8">este exemplo de código</a> no Github sobre o projeto.</p><h3 id="gerador-de-letras-de-m-sica"><strong>Gerador de letras de música</strong></h3><p>Peça ao usuário para escolher uma música de uma lista de 10 músicas exibidas. Depois de o usuário fazer isso, exiba a letra da música selecionada.</p><p>Exemplo:</p><pre><code>Seja bem-vindo. Por favor, selecione uma dentre as 10 músicas a seguir:

1. Baby, de Justin Bieber
2. Hotline Bling, de Drake
3. Flawless, de Beyonce
4. Fall, de Eminem</code></pre><pre><code>Você escolheu Flawless, de Beyonce. Aqui está a letra da música:

---------- Flawless, de Beyonce ------------
I'm out that H, town coming coming down
I'm coming down, drippin' candy on the ground
H, Town, Town, I'm coming down, coming down
Drippin' candy on the ground...

Pressione * para escolher outra música.</code></pre><p>Para desenvolver mais o projeto, tenha pelo menos 3 músicas para cada artista.</p><p>Assim, peça para o usuário escolher pelo nome do artista e depois selecionar uma música daquele mesmo artista. Assim, o usuário pode escolher uma música específica da lista exibida.</p><h2 id="finalizando"><strong>Finalizando</strong></h2><p>Trabalhando nesses projetos, você pode se deparar com alguns obstáculos e ficar completamente desanimado. Mantenha a calma. Você consegue.</p><p>Lembre-se: faça uma pausa e tente de novo mais tarde. Você também pode ler <a href="https://lifetechpsych.com/developer-stories">estas histórias de diversos programadores</a> (texto em inglês) que conseguiram manter a motivação e seguir adiante.</p><p>Desenvolvimento de software é uma área difícil, mas tem muitas recompensas.</p><p>Se tantos outros conseguiram, você também consegue.</p><h2 id="obrigado-pela-leitura"><strong>Obrigado pela leitura</strong></h2><p>Se gostou deste texto, pode conferir outros como ele.</p><ul><li><a href="https://lifetechpsych.ck.page/">Junte-se à comunidade do autor via e-mail</a>: lá, ele compartilha técnicas para que novos programadores e desenvolvedores juniores cresçam mais rapidamente e melhorem sua confiança. Se tiver interesse, <a href="https://lifetechpsych.ck.page/">faça parte da comunidade</a>.</li><li><a href="https://twitter.com/LifeTechPsych">Siga o autor no Twitter</a>: Quer mais dicas rápidas? Ou, por acaso, tem alguma pergunta? O autor é bastante ativo no Twitter, então fique à vontade para <a href="https://twitter.com/LifeTechPsych">entrar em contato com ele</a>. Ele deixa a &nbsp;DM aberta para conversas.</li></ul><p><em>Atenção</em> — o autor é apaixonado por pesquisa. Por isso, ele adverte que tem uma tendência a usar abordagens e conceitos da Psicologia Comportamental e da Neurociência.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Substrings em Python — como recortar uma string ]]>
                </title>
                <description>
                    <![CDATA[ Em Python, uma string é uma sequência de caracteres que podem ser especiais ou alfanuméricos. Um exemplo de string é: "nos vemos na sexta-feira" (em inglês, we meet on Friday ). Você pode acessar subpartes específicas da string, que são popularmente conhecidas como substrings. Podemos definir uma substring como sendo ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/substrings-em-python-como-recortar-uma-string-2/</link>
                <guid isPermaLink="false">64529b2ae704550645dff76e</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ João Eduardo Gomes ]]>
                </dc:creator>
                <pubDate>Tue, 23 May 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/pexels-hitesh-choudhary-7775640.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/python-substring-how-to-slice-a-string/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python Substring – How to Slice a String</a>
      </p><p>Em Python, uma <em>string</em> é uma sequência de caracteres que podem ser especiais ou alfanuméricos.</p><p>Um exemplo de <em>string </em>é: <em>"nos vemos na sexta-feira</em>" (em inglês, <em>we meet on Friday</em>). Você pode acessar subpartes específicas da <em>string</em>, que são popularmente conhecidas como <em>substrings</em>.</p><p>Podemos definir uma <em>substring </em>como sendo uma sequência de caracteres dentro de uma <em>string</em>. Usemos a frase anterior como exemplo. No Python, poderíamos considerar como <em>substrings </em>as partes "sexta-feira", "na" e "vemos".</p><h2 id="como-criar-uma-substring-em-python"><strong>Como criar uma <em>substring</em> em Python</strong></h2><p>O Python nos fornece diferentes maneiras e métodos para criarmos uma <em>substring</em>, para verificarmos se uma <em>substring </em>está presente, para obtermos o índice de uma <em>substring</em>, entre outras funcionalidades.</p><p>Você pode extrair uma <em>substring </em>de uma <em>string </em>recortando-a com índices que obtêm sua <em>substring </em>da seguinte maneira:</p><p><code>string[começo:fim:passo]</code></p><ul><li><strong>começo </strong>— O índice inicial da <em>substring</em>. O caractere deste índice estará incluso no recorte.</li><li><strong>parada </strong>— O índice final da <em>substring</em>. O caractere deste índice serve apenas como ponto de parada e não estará incluso no recorte.</li><li><strong>passo </strong>— O número que determina o intervalo do recorte. O valor padrão é 1.</li></ul><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/image--2-.png" class="kg-image" alt="image--2-" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/05/image--2-.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/05/image--2-.png 798w" sizes="(min-width: 720px) 720px" width="798" height="184" loading="lazy"></figure><p>Os valores dos índices podem ser positivos ou negativos. Índices positivos começam do início e vão até o final da <em>string</em>, enquanto que índices negativos começam do final e vão até o início da <em>string</em>.</p><p>Neste artigo, você aprenderá como executar várias operações relacionadas às <em>substrings </em>em Python.</p><h2 id="como-obter-os-primeiros-n-caracteres-de-uma-string-em-python"><strong>Como obter os primeiros n caracteres de uma <em>string </em>em Python</strong></h2><p>Este exemplo nos mostra como recortar os primeiros 5 caracteres da <em>string</em>:</p><pre><code class="language-python">string = "hello world"
print(string[:5])
</code></pre><p>Aqui definimos o índice de parada como 5. O índice de começo é 0 por padrão.</p><p>A saída é: <code>'hello'</code>.</p><h2 id="como-obter-os-caracteres-do-meio-de-uma-string-usando-substrings-em-python"><strong>Como obter os caracteres do meio de uma <em>string </em>usando <em>substrings </em>em Python</strong></h2><p>Este exemplo nos mostra como recortar os caracteres a partir do índice 3 até o índice 5 de uma <em>string</em>:</p><pre><code class="language-python">string = "hello world"
print(string[3:5])
</code></pre><p>A saída é: <code>'lo'</code>.</p><h2 id="como-obter-o-ltimo-caractere-de-uma-string-em-python"><strong>Como obter o último caractere de uma <em>string </em>em Python</strong></h2><p>Para obter o último caractere, basta usar o índice -1 (índice negativo). Vejamos o seguinte exemplo:</p><pre><code class="language-python">string = "freecodecamp"
print(string[-1])
</code></pre><p>A saída será: <code>'p'</code>.</p><h2 id="como-obter-os-ltimos-n-caracteres-de-uma-string-em-python"><strong>Como obter os últimos n caracteres de uma <em>string </em>em Python</strong></h2><p>Neste exemplo, recortaremos os últimos 4 caracteres da <em>string</em>. Aqui, usamos o índice negativo para começarmos o recorte a partir do final da <em>string</em>.</p><pre><code class="language-python">string = "freecodecamp"
print(string[-4:])
</code></pre><p>A saída será: <code>'camp'</code>.</p><h2 id="como-recortar-a-string-com-passos-usando-substrings-em-python"><strong>Como recortar a <em>string </em>com passos usando <em>substrings </em>em Python</strong></h2><p>Podemos indicar o passo no recorte da <em>string </em>após indicarmos os índices de começo e de parada. Por padrão, o passo tem valor 1. No exemplo a seguir, porém, usaremos o passo com valor 2.</p><pre><code class="language-python">string = "welcome to freecodecamp"
print(string[::2])
</code></pre><p>A saída será: <code>'wloet fecdcm'</code>. Isso porque, com passo 2, recortamos de 2 em 2 caracteres.</p><h2 id="como-verificar-se-uma-substring-est-presente-em-uma-string-em-python"><strong>Como verificar se uma <em>substring </em>está presente em uma <em>string </em>em Python</strong></h2><p>Às vezes, gostaríamos de verificar se uma <em>substring </em>está presente em uma <em>string</em>. O exemplo a seguir verificará se a <em>substring</em> 'code' faz parte da <em>string</em>:</p><pre><code class="language-python">substring = "code"
string = "welcome to freecodecamp"
print(substring in string)
</code></pre><p>Se a <em>substring </em>definida estiver presente na <em>string</em>, o retorno será <code>True</code>. Do contrário, será <code>False</code>.<br><br>Nesse caso, a saída será: <code>True</code>. Isso acontece porque '<strong>code</strong>' faz parte de 'free<strong>code</strong>camp'.</p><h2 id="outra-maneira-de-verificar-se-uma-substring-est-presente-em-uma-string-em-python"><strong>Outra maneira de verificar se uma <em>substring </em>está presente em uma <em>string </em>em Python</strong></h2><p>Podemos usar o método <code>find()</code> para verificar se encontramos a <em>substring </em>desejada na <em>string</em>.</p><p>Vejamos o seguinte exemplo:</p><pre><code class="language-python">substring = "zz"
string = "hello world"
print(string.find(substring))
</code></pre><p>Se a <em>substring </em>for encontrada na <em>string</em>, o retorno será o índice em que a <em>substring </em>começa. Se não for encontrada, o método retorna -1.</p><p>Neste caso, a saída é: <code>-1</code>. Isso significa que "<strong>zz</strong>" não está faz parte de "hello world".</p><h2 id="como-obter-o-caractere-de-um-determinado-ndice-em-uma-string-em-python"><strong>Como obter o caractere de um determinado índice em uma <em>string </em>em Python</strong></h2><p>Podemos passar o índice de um caractere específico para recortá-lo.</p><pre><code class="language-python">string ="hello world"
print(string[4])
</code></pre><p>A saída será: <code>'O'</code>, que é o caractere presente na posição 4.</p><h2 id="como-criar-uma-lista-de-substrings-a-partir-de-uma-string-em-python"><strong>Como criar uma lista de <em>substrings </em>a partir de uma <em>string </em>em Python</strong></h2><p>Podemos usar o método <code>split()</code><strong><strong> </strong></strong>para criarmos uma lista de <em>substrings</em>. Vejamos sua aplicação no seguinte exemplo:</p><pre><code class="language-python">string = "welcome to freecodecamp platform"
print(string.split())
</code></pre><p>A saída será: <code>['welcome', 'to', 'freecodecamp', 'platform']</code>.</p><h2 id="como-inverter-uma-string-em-python-usando-passo-negativo"><strong>Como inverter uma <em>string </em>em Python usando passo negativo</strong></h2><p>Para inverter a <em>string</em>, o passo deve ter um valor negativo, por exemplo: -1.</p><pre><code class="language-python">string = "welcome to freecodecamp"
print(string[::-1])
</code></pre><p>A saída será: <code>'pmacedoceerf ot emoclew'</code>.</p><h2 id="como-contar-quantas-vezes-uma-substring-est-presente-em-uma-string-em-python"><strong>Como contar quantas vezes uma <em>substring</em> está presente em uma <em>string </em>em Python</strong></h2><p>Podemos usar o método <code>count()</code> para sabermos quantas vezes uma determinada <em>substring </em>aparece em uma <em>string</em>.</p><pre><code class="language-python">string = "we will have a quick coding lesson this afternoon"
print(string.count('noon'))
</code></pre><p>A saída será: 1.</p><h2 id="considera-es-finais-sobre-substrings-em-python"><strong>Considerações finais sobre <em>substrings </em>em Python</strong></h2><p>Parabéns por chegar ao final deste artigo. 👏👏 Espero que você tenha aprendido algo novo sobre <em>substrings </em>em Python.</p><p>Se você, de fato, aprendeu algo novo ou se gostou de ler este artigo, compartilhe-o para que outras pessoas também possam lê-lo. Até lá, nos vemos no próximo artigo!</p><p>Você também pode encontrar o autor no <a href="https://twitter.com/Davis_McDavid?ref=hackernoon.com">Twitter</a> e ler mais artigos como este <a href="https://hackernoon.com/u/davisdavid?ref=hackernoon.com">aqui</a> (textos em inglês).</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
