<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Lucas Nobre Barbosa</title>
    <description>The latest articles on Forem by Lucas Nobre Barbosa (@nobrelucas).</description>
    <link>https://forem.com/nobrelucas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1027378%2Fefe71abb-83c6-4104-9eee-56d036b1c930.jpeg</url>
      <title>Forem: Lucas Nobre Barbosa</title>
      <link>https://forem.com/nobrelucas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nobrelucas"/>
    <language>en</language>
    <item>
      <title>Uptrain como ferramenta de avaliação de aplicações de LLMs</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Thu, 26 Feb 2026 14:31:26 +0000</pubDate>
      <link>https://forem.com/nobrelucas/uptrain-como-ferramenta-de-avaliacao-de-aplicacoes-de-llms-mog</link>
      <guid>https://forem.com/nobrelucas/uptrain-como-ferramenta-de-avaliacao-de-aplicacoes-de-llms-mog</guid>
      <description>&lt;p&gt;A avaliação de aplicações de LLMs é um dos campos mais desafiadores da contemporânea Engenharia de Inteligência Artificial (IA). A autora Chip Huyen define que o metodismo ao avaliar uma aplicação de IA generativa é de suma importância, mas também que o esforço de pensar no sistema de avaliação pode custar mais da metade do tempo de desenvolvimento.&lt;/p&gt;

&lt;p&gt;Pensando em mitigar o esforço gasto nessa atividade, a plataforma uptrain surge como uma poderosa aliada nesse processo.&lt;/p&gt;

&lt;p&gt;De código aberto, a plataforma oferece ferramentas para avaliação de aplicações de LLM, além de uma ferramenta de dashboards auto-hospedada para monitoramento dessas aplicações, embora essa última aparenta ainda estar prematura e incompleta.&lt;/p&gt;

&lt;p&gt;Como ferramenta de avaliação, uptrain apresenta um framework enxuto, mas expansível, com uma classe &lt;code&gt;EvalLLM&lt;/code&gt;, com um método &lt;code&gt;evaluate&lt;/code&gt; que só precisa, como parâmetros, de um tipo de avaliação (o qual o framework apresenta 17 pré-definidos e prontos para uso) e pelo menos três colunas de dados:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;question: a pergunta feita ao modelo;&lt;/li&gt;
&lt;li&gt;context: o contexto relevante para aquela pergunta; e&lt;/li&gt;
&lt;li&gt;response: a resposta do modelo àquela pergunta.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Algumas avaliações pedem mais algumas colunas, essas são chamadas de avaliações paramétricas.&lt;/p&gt;

&lt;p&gt;Por ser de código aberto, a plataforma permite que seus usuários desenvolvam suas próprias métricas e que contribuam com o projeto, tendo assim grandíssimo potencial no mercado e na academia.&lt;/p&gt;

&lt;p&gt;Para finalizar, convido vocês a visitar a documentação da plataforma em: &lt;a href="https://dev.tolink-documenta%C3%A7%C3%A3o-plataforma-uptrain"&gt;https://docs.uptrain.ai/getting-started/introduction&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>llm</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Mais dados é melhor que um algoritmo mais eficiente</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Fri, 01 Dec 2023 10:58:52 +0000</pubDate>
      <link>https://forem.com/nobrelucas/mais-dados-e-melhor-que-um-algoritmo-mais-eficiente-40mk</link>
      <guid>https://forem.com/nobrelucas/mais-dados-e-melhor-que-um-algoritmo-mais-eficiente-40mk</guid>
      <description>&lt;p&gt;Recentemente li um texto de blog do &lt;a href="https://anand.typepad.com/datawocky/anand-rajaraman.html" rel="noopener noreferrer"&gt;Anand Rajaraman&lt;/a&gt; no qual ele descreve uma atividade que ele passou para seus alunos na Universidade de Stanford na qual eles deveriam realizar qualquer tarefa de data mining não trivial, onde a maioria decidiu tentar resolver o “Netflix Chalenge”, um desafio no qual o candidato deve fazer um algoritmo de recomendação de filmes melhor que o da plataforma.&lt;/p&gt;

&lt;p&gt;O desafio consiste em usar um dataset enviado pela empresa onde várias pessoas deram notas para filmes e o desafio é predizer a nota de filmes sem notas dadas. Um clássico problema de receber um dataset de treino, treinar um modelo com esses dados e testar esse mesmo modelo em um dataset de teste. Se você conseguir uma acurácia superior à do algoritmo da netflix respeitando uma determinada margem você leva para casa um prêmio de 1 milhão de dólares.&lt;/p&gt;

&lt;p&gt;Continuando na descrição de sua experiência em sua aula, Rajaraman comenta que vários alunos experimentaram diversas abordagens. Entre elas, podemos destacar duas: um time A experimentou um algoritmo extremamente elaborado para resolver o problema e um time B fundiu o dataset da Netflix com dados fornecidos pelo IMDB (Internet Movie Data Base).&lt;/p&gt;

&lt;p&gt;Resumindo a história, o time B conseguiu melhores resultados e quase alcançou a acurácia da Netflix, mesmo com um algoritmo mais simples que o do time A, que não foi muito longe. &lt;/p&gt;

&lt;h2&gt;
  
  
  Minha experiência no Curso de Ciência da Computação
&lt;/h2&gt;

&lt;p&gt;Em uma disciplina chamada  “Informática e Sociedade”, na UFPA, tínhamos aulas muito mais próximas da filosofia, onde éramos convidados a debater sobre diversos assuntos referentes aos impactos da computação na sociedade. Acredito que foi uma boa experiência para mim.&lt;/p&gt;

&lt;p&gt;Nessa disciplina, uma das aulas era sobre dados e o professor trouxe uma provocação: “Dados são realmente o novo petróleo?”. Eu não tenho certeza absoluta se essa foi a fonte que ele nos passou para discutirmos em aula, mas eu creio que era. Segue o link:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kenwayconsulting.com/blog/data-is-the-new-oil/" rel="noopener noreferrer"&gt;Is Data Really The New Oil?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lembro que eu fui o mais engajado naquela aula, até mesmo por sempre ser entusiasmado com dados. Eu realmente discordava com o ponto do professor. Para ele, na verdade, o novo petróleo eram os algoritmos que tratavam esses dados e não os dados em si.&lt;/p&gt;

&lt;p&gt;Entretanto, para mim a analogia sempre foi bem clara: dados são a matéria prima, sem ele nada é feito. Além disso, assim como petróleo é inútil sem o processamento que ele passa, dados não servem para nada se estiverem espalhados e sujos, se não são processados e se não agregamos valor para o mesmo através de processos industriais.&lt;/p&gt;

&lt;p&gt;O artigo do Anand Rajaraman me lembrou essa discussão novamente, me fazendo acreditar ainda mais que mais dados no fim resolvem problemas melhor que algoritmos extremamente elaborados. &lt;/p&gt;

&lt;p&gt;Claro que isso não é um incentivo a deixar de estudar algoritmos, afinal de contas, tendo uma mesma quantidade X de dados, um algoritmo melhor vai fazer um trabalho melhor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Esse foi um tema que passou pela minha cabeça nos últimos dias e me deixou curioso para ouvir a opinião de outras pessoas. Peço desculpas se cometi algum erro ao comentar sobre petróleo, estou longe de ser um especialista no assunto, diferente do querido Sérgio Sacani do Space Today.&lt;/p&gt;

&lt;p&gt;Ademais, espero que tenham gostado da leitura. Críticas, sugestões e correções são muito bem vindas na sessão de comentários abaixo. Vejo vocês no meu próximo artigo.&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>data</category>
      <category>dataengineering</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>PostgreSQL: Tipos de Dados</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Sat, 25 Nov 2023 02:12:39 +0000</pubDate>
      <link>https://forem.com/nobrelucas/postgresql-tipos-de-dados-1la3</link>
      <guid>https://forem.com/nobrelucas/postgresql-tipos-de-dados-1la3</guid>
      <description>&lt;p&gt;O PostgreSQL, carinhosamente chamado de postgres, é um dos SGBDs (Sistemas Gerenciadores de Banco de Dados) mais famosos hoje em dia, sendo o SGBD open source mais querido pelos programadores atualmente.&lt;/p&gt;

&lt;p&gt;Nesse artigo busco apresentar os tipos de dados mais comuns suportados pelo postgres como ferramenta de consulta rápida e direta para outros desenvolvedores. Sem mais delongas, vamos ao conteúdo&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de Dados
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Numéricos
&lt;/h3&gt;

&lt;p&gt;Inclui desde inteiros até números de ponto flutuante&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;smallint&lt;/code&gt;: armazena valores inteiros com sinal com até 2 bytes de tamanho&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;integer&lt;/code&gt;: armazena valores inteiros com sinal com até 4 bytes de tamanho&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bigint&lt;/code&gt;: armazena valores inteiros com sinal com até 8 bytes de tamanho&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;decimal&lt;/code&gt;: armazena valores com muitos dígitos. Geralmente usado para armazenar valores financeiros. O desenvolvedor pode especificar a precisão e a escala para esse tipo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;numeric&lt;/code&gt;: um apelido para o tipo de dados &lt;code&gt;decimal&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;real&lt;/code&gt;: armazena valores de ponto flutuante com 4 bytes e precisão de 6 dígitos decimais&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;double precision&lt;/code&gt;: armazena valores de ponto flutuante com 8 bytes e precisão de 15 dígitos decimais&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Caractere
&lt;/h3&gt;

&lt;p&gt;Usados para lidar com alfanumérico e com textos&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;char(n)&lt;/code&gt; : armazena strings de tamanho fixo com um tamanho &lt;code&gt;n&lt;/code&gt; específico&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;varchar(n)&lt;/code&gt; : armazena strings de tamanho variável com com um tamanho &lt;code&gt;n&lt;/code&gt; máximo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;text&lt;/code&gt; : armazena strings de tamanho variável sem tamanho máximo&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Binários
&lt;/h3&gt;

&lt;p&gt;Inclui basicamente o tipo de dados Byte&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bytea&lt;/code&gt; : armazena uma string de binários com tamanho variável, sem tamanho máximo&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Data e Tempo
&lt;/h3&gt;

&lt;p&gt;Diversas formas para lidar com datas e tempo&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;date&lt;/code&gt; : armazena datas sem informação de time zone (YYYY-MM-DD)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;time&lt;/code&gt; : armazena valores de tempo sem informação de time zone (HH:MM:SS)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;timestamp&lt;/code&gt; : armazena valores de tempo e de data sem informações de time zone&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;timestamptz&lt;/code&gt; : armazena valores de tempo e de data com informação de time zone&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;interval&lt;/code&gt; : um intervalo de tempo, como a diferença de dois timestamps&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Booleano
&lt;/h3&gt;

&lt;p&gt;Um tipo de dados para lidar com verdadeiro e falso&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Enumerado
&lt;/h3&gt;

&lt;p&gt;Criação de tipos de dados customizados, que consistem de um conjunto de valores ordenado e estático&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CREATE TYPE AS ENUM&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TYPE&lt;/span&gt; &lt;span class="n"&gt;mood&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="nb"&gt;ENUM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'sad'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ok'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'happy'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dados Geométricos e de Rede
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;point&lt;/code&gt;, &lt;code&gt;line&lt;/code&gt;, &lt;code&gt;lseg&lt;/code&gt;, &lt;code&gt;box&lt;/code&gt;, &lt;code&gt;polygon&lt;/code&gt;, &lt;code&gt;path&lt;/code&gt;, &lt;code&gt;circle&lt;/code&gt;: armazena pontos, linhas e várias outras formas&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;inet&lt;/code&gt;, &lt;code&gt;cidr&lt;/code&gt;: armazena endereços IP e subredes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Com esse guia você tem uma referência inicial para conhecer os principais tipos de dados suportados pelo postgres, podendo seguir seus estudos a partir daqui dependendo da sua necessidade.&lt;/p&gt;

&lt;p&gt;Esse artigo é um guia rápido para se orientar quando precisar achar um tipo de dados específico;.&lt;/p&gt;

&lt;p&gt;Dúvidas, sugestões e correções de conteúdo são sempre muito bem vindas. Espero que você tenha gostado do conteúdo. Espero te ver no meu próximo artigo. Até lá!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>O problema de SQL que quase me enlouqueceu</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Fri, 17 Nov 2023 12:54:53 +0000</pubDate>
      <link>https://forem.com/nobrelucas/o-problema-de-sql-que-quase-me-enlouqueceu-2j6f</link>
      <guid>https://forem.com/nobrelucas/o-problema-de-sql-que-quase-me-enlouqueceu-2j6f</guid>
      <description>&lt;p&gt;Estou me preparando para algumas vagas de Engenheiro de Dados e para isso, é claro, eu preciso dominar SQL. Só ficar lendo livros de SQL não me ajuda nisso e por esse motivo eu gosto de ficar fazendo questões em sites como o &lt;a href="http://hackerrank.com" rel="noopener noreferrer"&gt;hackerrank&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Costumo fazer umas questões toda quarta para me desafiar e em uma semana dessas eu encontrei o que, para mim, é a questão mais desafiadora que já enfrentei. Embora ela esteja classificada como “média” no site, eu demorei um certo tempo para resolver ela.&lt;/p&gt;

&lt;p&gt;Se estou aqui agora é porque eu consegui e tenho como objetivo, nesse artigo, mostrar o passo a passo que tomei para resolver esse problema. O problema em si está no link a seguir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.hackerrank.com/challenges/occupations/problem" rel="noopener noreferrer"&gt;Occupations | HackerRank&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 Se desafie a tentar resolver o problema sem ler o artigo primeiro. Caso não consiga, volte aqui e veja o meu passo a passo para comparar 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  Passo 1: Entendendo o Problema
&lt;/h2&gt;

&lt;p&gt;Nesse desafio, nos é dado uma tabela chamada “OCCUPATIONS” com duas colunas: “Name” e “Occupation”. A primeira coluna é auto explicativa, nos dá o nome de uma pessoa. A segunda coluna nos apresenta a profissão da pessoa com nome definido na coluna anterior.&lt;/p&gt;

&lt;p&gt;As profissões disponíveis na tabela são “Doctor”, “Actor”, “Singer” e “Professor”.&lt;/p&gt;

&lt;p&gt;Nos é pedido para “Pivotar” a coluna “Occupations”, de forma que os nomes das pessoas sejam ordenados de forma alfabética e mostrados abaixo de sua profissão correspondente, sendo que no header devemos ter, respectivamente: Doctor, Professor, Singer e Actor.&lt;/p&gt;

&lt;p&gt;Devemos mostrar &lt;strong&gt;NULL&lt;/strong&gt; se não há mais nomes correspondentes para uma ocupação&lt;/p&gt;

&lt;p&gt;💡 Pivot não tem uma tradução óbvia para o português, por isso é comum ouvir “Pivotar”, mas dá para entender como algo do tipo “girar a tabela” ou “tabela virada”.&lt;/p&gt;

&lt;p&gt;Efetivamente, se recebemos a seguinte tabela:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Occupation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Samantha&lt;/td&gt;
&lt;td&gt;Doctor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Julia&lt;/td&gt;
&lt;td&gt;Actor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maria&lt;/td&gt;
&lt;td&gt;Actor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Meera&lt;/td&gt;
&lt;td&gt;Singer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ashley&lt;/td&gt;
&lt;td&gt;Professor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ketty&lt;/td&gt;
&lt;td&gt;Professor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Christeen&lt;/td&gt;
&lt;td&gt;Professor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jane&lt;/td&gt;
&lt;td&gt;Actor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jenny&lt;/td&gt;
&lt;td&gt;Doctor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Priya&lt;/td&gt;
&lt;td&gt;Singer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Devemos retornar com a nossa query a seguinte tabela:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Doctor&lt;/th&gt;
&lt;th&gt;Professor&lt;/th&gt;
&lt;th&gt;Singer&lt;/th&gt;
&lt;th&gt;Actor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Jenny&lt;/td&gt;
&lt;td&gt;Ashley&lt;/td&gt;
&lt;td&gt;Meera&lt;/td&gt;
&lt;td&gt;Jane&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Samantha&lt;/td&gt;
&lt;td&gt;Christeen&lt;/td&gt;
&lt;td&gt;Priya&lt;/td&gt;
&lt;td&gt;Julia&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;Ketty&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;Maria&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Passo 2: Abstraindo o Problema
&lt;/h2&gt;

&lt;p&gt;Antes de falar sobre ferramenta e quais comandos usar para resolver o problema, vamos abstrair ele. Se você é de computação você deve saber quanto a palavra “abstrair” é famosa na área.&lt;/p&gt;

&lt;p&gt;Seguindo um passo a passo, temos a seguinte abstração para resolver o problema:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Separar as pessoas por profissão&lt;/li&gt;
&lt;li&gt;Ordenar as pessoas de cada profissão por nome&lt;/li&gt;
&lt;li&gt;Selecionar as pessoas na profissão “Doctor” e colocar na primeira coluna&lt;/li&gt;
&lt;li&gt;Selecionar as pessoas na profissão “Professor” e colocar na segunda coluna&lt;/li&gt;
&lt;li&gt;Selecionar as pessoas na profissão “Singer” e colocar na terceira coluna&lt;/li&gt;
&lt;li&gt;Selecionar as pessoas na profissão “Actor” e colocar na última coluna&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Seguindo esse algoritmo nós resolvemos o problema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passo 3: Entender quais técnicas usar para resolver o problema.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Passos 1 e 2 da abstração
&lt;/h3&gt;

&lt;p&gt;💡 Para fins de implementação, estou usando comandos do MySQL. Pode ser que esses comandos existam ou não em outros SGBDs, ou podem ter seus próprios comandos que implementam a mesma ideia.&lt;/p&gt;

&lt;p&gt;Seguindo o algoritmo que definimos no passo anterior, as etapas 1 e 2 podem ser facilmente resolvidas por um SELECT, usando também uma função muito interessante: a função row_number(), que retorna um número para cada linha em uma dada partição.&lt;/p&gt;

&lt;p&gt;💡 Para saber mais sobre a função row_number() acesse o link &lt;a href="https://www.javatpoint.com/mysql-row_number-function" rel="noopener noreferrer"&gt;https://www.javatpoint.com/mysql-row_number-function&lt;/a&gt; ou busque outras fontes de sua preferência&lt;/p&gt;

&lt;p&gt;Dessa forma, escrevendo a query da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
    &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;partition&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sequential_num&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;Occupations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Teremos como retorno a tabela:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Occupation&lt;/th&gt;
&lt;th&gt;s_no&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Jane&lt;/td&gt;
&lt;td&gt;Actor&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Julia&lt;/td&gt;
&lt;td&gt;Actor&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maria&lt;/td&gt;
&lt;td&gt;Actor&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jenny&lt;/td&gt;
&lt;td&gt;Doctor&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Samantha&lt;/td&gt;
&lt;td&gt;Doctor&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ashley&lt;/td&gt;
&lt;td&gt;Professor&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Christeen&lt;/td&gt;
&lt;td&gt;Professor&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ketty&lt;/td&gt;
&lt;td&gt;Professor&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Meera&lt;/td&gt;
&lt;td&gt;Singer&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Priya&lt;/td&gt;
&lt;td&gt;Singer&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;row_number() vai iterar sobre (over) uma partição. Nesse caso, estamos iterando sobre a partição occupation (partition by occupation), e dessa forma separando as pessoas por profissão. Além disso, estamos ordenando as pessoas por nome (order by name).&lt;/p&gt;

&lt;p&gt;Ótimo, com essa primeira query já resolvemos os dois primeiros passos da abstração. O passo 3 até o 6, agora, só são casos de seleção dentro dessa tabela que criamos anteriormente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Passos 3 a 6 da abstração
&lt;/h3&gt;

&lt;p&gt;Com todas as pessoas organizadas por profissão e por ordem alfabética, podemos selecionar todas as pessoas de determinada profissão com um select case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Doctor'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Professor'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Singer'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Actor'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;partition&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sequential_num&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;Occupations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entretanto, essa query irá nos retornar uma lista muito longa e vai listar primeiro os atores, depois os médicos, depois os professores e por último os cantores tendo 3 NULL em cada linha e somente um nome de pessoa e não é isso que queremos. &lt;/p&gt;

&lt;p&gt;O que queremos é que toda linha esteja preenchida com nomes de pessoas e que NULL só apareça caso não tenham mais pessoas em uma profissão.&lt;/p&gt;

&lt;p&gt;Como queremos manter a ordem alfabética na nossa última seleção, vamos selecionar a primeira pessoa em cada lista de profissões, ou seja: &lt;code&gt;min(case when occupation = '{profissão}' then name end&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;
    &lt;span class="k"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Doctor'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Professor'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Singer'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Actor'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;partition&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sequential_num&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;Occupations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Além de adicionar o uso da função min para selecionar a primeira pessoa de cada lista, por determinação do SQL, toda tabela derivada (nosso select interior) precisa ter um apelido e eu chamei ele de “P”, para “Pivot”.&lt;/p&gt;

&lt;p&gt;Com isso temos a primeira linha da nossa lista. Só falta conseguir as demais linhas e para isso usamos um famoso GROUP BY.&lt;/p&gt;

&lt;p&gt;Pelo o que agrupamos? Pelo número de sequência que foi obtido com nosso row_number()&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;
    &lt;span class="k"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Doctor'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Professor'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Singer'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Actor'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;partition&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sequential_num&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;Occupations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;
&lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sequential_num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E pronto! Temos nosso resultado do jeitinho que queríamos.&lt;/p&gt;

&lt;p&gt;Se você quiser ver a mágica que o GROUP BY causou, experimenta adicionar &lt;code&gt;P.sequential_num as seq_num&lt;/code&gt;  logo após o select e antes do primeiro min(…). Você vai ter algo semelhante a isso:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;seq_num&lt;/th&gt;
&lt;th&gt;Doctor&lt;/th&gt;
&lt;th&gt;Professor&lt;/th&gt;
&lt;th&gt;Singer&lt;/th&gt;
&lt;th&gt;Actor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Jenny&lt;/td&gt;
&lt;td&gt;Ashley&lt;/td&gt;
&lt;td&gt;Meera&lt;/td&gt;
&lt;td&gt;Jane&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Samantha&lt;/td&gt;
&lt;td&gt;Christeen&lt;/td&gt;
&lt;td&gt;Priya&lt;/td&gt;
&lt;td&gt;Julia&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;Ketty&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;Maria&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Lindo, não é?&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Com esse artigo pude explicar passo a passo meu processo de raciocínio para resolver esse problema bem desafiante e interessante. &lt;/p&gt;

&lt;p&gt;Com ele eu espero ter te ajudado a aprender algo novo em SQL e até mesmo ter te incentivado a experimentar um pouco de “programação competitiva” em sites como o hackerrank.&lt;/p&gt;

&lt;p&gt;Dúvidas, sugestões, críticas e comentários são muito bem vindo na sessão de comentários abaixo.  Agradeço muito pelo tempo investido aqui e espero te ver nos próximos artigos. Até a próxima 🙂.&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>sql</category>
      <category>competativeprogramming</category>
    </item>
    <item>
      <title>Criando Ambientes Virtuais com Venv</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Thu, 09 Nov 2023 14:18:23 +0000</pubDate>
      <link>https://forem.com/nobrelucas/criando-ambientes-virtuais-com-venv-14c0</link>
      <guid>https://forem.com/nobrelucas/criando-ambientes-virtuais-com-venv-14c0</guid>
      <description>&lt;p&gt;Desenvolvedores de Software precisam constantemente aprender novas tecnologias e fazer novos projetos. Quanto mais se faz isso e mais tempo passa, maiores são as chances de um conflito de bibliotecas ou erros de uma nova versão de código acontecer.&lt;/p&gt;

&lt;p&gt;No ecossistema Python isso é resolvido com a abordagem dos ambientes virtuais. No primeiro artigo que escrevi sobre o assunto em &lt;a href="https://dev.to/nobrelucas/administrando-ambientes-virtuais-com-conda-54l9"&gt;https://dev.to/nobrelucas/administrando-ambientes-virtuais-com-conda-54l9&lt;/a&gt; falei mais profundamente sobre esse assunto e introduzi o administrador de ambientes virtuais Conda.&lt;/p&gt;

&lt;p&gt;Nesse artigo, busco introduzir um &lt;strong&gt;criador&lt;/strong&gt; de ambientes virtuais muito mais simples que serve para a maioria dos projetos de pequeno e médio porte, o Venv.&lt;/p&gt;

&lt;p&gt;Note que diferente do Conda, ele não oferece nenhum suporte para a administração dos ambientes virtuais, somente para a sua criação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalação
&lt;/h2&gt;

&lt;p&gt;Primeira vantagem do Venv: ele já vem instalado com o Python, então nada mais é preciso ser feito para usar ele 🙂.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando ambiente virtual
&lt;/h2&gt;

&lt;p&gt;Para criar um ambiente virtual com Venv basta usar um comando muito simples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv &lt;span class="o"&gt;{&lt;/span&gt;nome_do_env&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos explorar esse comando por partes:&lt;/p&gt;

&lt;p&gt;→ python3 invoca o interpretador Python que será responsável por executar o código do módulo venv&lt;/p&gt;

&lt;p&gt;→ -m indica que o código que vai ser executado pelo interpretador Python será um módulo&lt;/p&gt;

&lt;p&gt;→ venv é o módulo venv, responsável pela criação do ambiente virtual&lt;/p&gt;

&lt;p&gt;→ {nome_do_env}, como auto explicativo, nomeia o diretório onde o ambiente virtual vai ser criado&lt;/p&gt;

&lt;p&gt;E assim temos nosso ambiente virtual. Vamos fazer algo prático&lt;/p&gt;

&lt;h2&gt;
  
  
  Na prática
&lt;/h2&gt;

&lt;p&gt;Vamos criar um ambiente chamado “teste” em um diretório de estudo “criando-venv”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv teste
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você estiver em um ambiente Linux, digite &lt;code&gt;ls&lt;/code&gt; no terminal para ver o diretório com o ambiente criado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34a6gzbduuczpsak8y1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34a6gzbduuczpsak8y1g.png" alt="criando ambiente virtual " width="367" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para ativar o ambiente, basta usar o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source &lt;/span&gt;teste/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvx4oquh28129a66by0bt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvx4oquh28129a66by0bt.png" alt="ativando o ambiente virtual " width="605" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para sair do ambiente basta escrever o comando &lt;code&gt;deactivate&lt;/code&gt; no terminal ou fechar o terminal:&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalando bibliotecas
&lt;/h2&gt;

&lt;p&gt;Note que as bibliotecas instaladas são somente as básicas para começar a instalar outras, ou seja o seu ambiente está limpo e livre, pronto para começar a ser configurado com novas bibliotecas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fta5j12cikvx3rpb47nck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fta5j12cikvx3rpb47nck.png" alt="lista de pacotes pip antes de instalar os novos" width="509" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então agora é só instalar as bibliotecas que você precisa para o seu projeto.&lt;/p&gt;

&lt;p&gt;Digamos que vamos fazer uma API com Flask e instalamos ele com pip:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;Flask
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após a instalação, nosso ambiente terá as seguintes bibliotecas:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhn2ddi13xevyig9vt41s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhn2ddi13xevyig9vt41s.png" alt="lista de pacotes pip depois de instalar Flask" width="509" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora é só programar&lt;/p&gt;

&lt;h2&gt;
  
  
  Persistindo o ambiente
&lt;/h2&gt;

&lt;p&gt;Para que você possa trabalhar colaborativamente com outros desenvolvedores. Eles vão precisar criar um ambiente virtual e instalar as exatas mesmas bibliotecas que você, na exata mesma versão. &lt;/p&gt;

&lt;p&gt;Ao invés de você mandar um print como o que eu mostrei anteriormente para instalar manualmente cada biblioteca, uma de cada vez, você pode criar um arquivo de requerimentos, o requirements.txt. Para isso, basta usar o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso vai criar um arquivo txt com todas as bibliotecas que você está usando no projeto. Lembre de sempre atualizar seu requirements.txt com as novas bibliotecas que você instalar no caminho.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalando as bibliotecas do requirements.txt
&lt;/h2&gt;

&lt;p&gt;Caso você seja o outro desenvolvedor que recebeu o requirements.txt. Para instalar essas bibliotecas basta você primeiro criar um ambiente virtual na sua máquina, ativar ele e depois usar o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E você já está pronto para trabalhar também&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Com esse artigo você já é capaz de usar o Venv para criar ambientes virtuais para projetos de pequeno e médio porte. &lt;/p&gt;

&lt;p&gt;Se você quiser saber mais sobre ambientes virtuais, meu primeiro artigo sobre o assunto tem mais detalhes sobre eles.&lt;/p&gt;

&lt;p&gt;Dúvidas, sugestões, correções e críticas são muito bem vindas na sessão de comentários abaixo. Espero poder encontrar você nos meus próximos artigos 😀. Até a próxima!&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>python</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Concept Drift em Aprendizado de Máquina - Uma Introdução</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Wed, 01 Nov 2023 13:19:55 +0000</pubDate>
      <link>https://forem.com/nobrelucas/concept-drift-em-aprendizado-de-maquina-uma-introducao-46pf</link>
      <guid>https://forem.com/nobrelucas/concept-drift-em-aprendizado-de-maquina-uma-introducao-46pf</guid>
      <description>&lt;p&gt;Os dados de um cenário qualquer estão sempre evoluindo, faz parte da natureza de qualquer conjunto de dados. Entretanto, quando essa evolução invalida um modelo de aprendizado de máquina, nós temos o que chamamos de Concept Drift.&lt;/p&gt;

&lt;p&gt;A tradução literal de Concept Drift seria “Desvio de Conceito”. Entretanto, por não ser um termo amplamente usado, nesse artigo irei me referir a esse termo somente em inglês.&lt;/p&gt;

&lt;p&gt;Esse fenômeno acontece quando as propriedades estatísticas de uma variável alvo, que o modelo está tentando predizer, mudam de uma forma inesperada.&lt;/p&gt;

&lt;p&gt;Em modelos tradicionais, isso faz com que as predições se tornem menos acuradas conforme o tempo passa. Sendo assim, a detecção de Concept Drift e a adaptação a esse fenômeno são primordiais em qualquer aplicação com dados e modelos que mudem dinamicamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplos de Concept Drift
&lt;/h2&gt;

&lt;p&gt;Existem muitos cenários em que esse fenômeno acontece constantemente. Entre eles podemos citar, por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Demanda elétrica de uma cidade ao longo do ano&lt;/li&gt;
&lt;li&gt;Mercado de ações&lt;/li&gt;
&lt;li&gt;Preferências de compra&lt;/li&gt;
&lt;li&gt;Probabilidade de sucesso de filmes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em qualquer um desses cenários, o valor das predições de um modelo tradicional começa a decair conforme o tempo passa. &lt;/p&gt;

&lt;p&gt;Vamos explorar os cenários de demanda elétrica e de preferência de compras.&lt;/p&gt;

&lt;p&gt;Quando a pandemia de Covid-19 começou, entre vários outros efeitos, dois cenários mudaram muito rapidamente. Primeiro que o número de pessoas em casa em horários de trabalho aumentou consideravelmente. Também, a busca por máscaras e por álcool em gel aumentaram mais consideravelmente ainda.&lt;/p&gt;

&lt;p&gt;Dessa forma, com o advento da pandemia, tanto a demanda energética residencial quanto a busca por produtos específicos aumentou de uma hora para a outra, causando desabastecimento desses produtos (energia elétrica residencial, máscaras e álcool em gel) para muitas pessoas.&lt;/p&gt;

&lt;p&gt;Modelos de predição de série histórica para abastecimento energético e modelos de predição de estoque tradicionais sofreram muito com esse Concept Drift, tendo suas predições quase que totalmente invalidadas nesse novo cenário.&lt;/p&gt;

&lt;h2&gt;
  
  
  Possíveis Soluções
&lt;/h2&gt;

&lt;p&gt;Para resolver o problema de Concept Drift, há duas principais abordagens: soluções reativas e soluções de rastreamento.&lt;/p&gt;

&lt;h3&gt;
  
  
  Soluções Reativas
&lt;/h3&gt;

&lt;p&gt;A principal solução reativa para lidar com o fenômeno de mudança abrupta de cenário é treinar o modelo novamente, desde o início, com os dados novos, em reação a um mecanismo de acionamento, como um teste de detecção de alterações estatísticas.&lt;/p&gt;

&lt;p&gt;Chamam-se de soluções reativas porque só resolvem o problema depois de ele acontecer, o que pode ser tarde demais em alguns cenários.&lt;/p&gt;

&lt;h3&gt;
  
  
  Soluções de Rastreamento
&lt;/h3&gt;

&lt;p&gt;Soluções, geralmente, mais maduras envolvem rastrear constantemente esse desvio e resolver o problema antes de ele acontecer, com técnicas como, por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Atualização constante do modelo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aprendizado de Máquina Online&lt;/strong&gt; (minha solução favorita)&lt;/li&gt;
&lt;li&gt;Retreinamento constante com as amostras mais recentes&lt;/li&gt;
&lt;li&gt;Treinar um classificador com dados novos e substituir o anterior&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Nesse artigo introduzi o conceito de Concept Drift no contexto de aprendizado de máquina. Apresentei alguns exemplos e possíveis soluções para lidar com esse comportamento.&lt;/p&gt;

&lt;p&gt;Em futuros artigos busco me aprofundar na solução de Concept Drift com Aprendizado de Máquina Online. Para se introduzir no assunto, leia meus outros artigos de aprendizado de máquina online em: &lt;a href="https://dev.to/nobrelucas/introducao-ao-aprendizado-de-maquina-online-3ocm"&gt;https://dev.to/nobrelucas/introducao-ao-aprendizado-de-maquina-online-3ocm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Se gostou desse artigo, por favor avalie ele de alguma forma. Comentários, críticas, sugestões e correções são muito bem-vindas. Agradeço pelo seu tempo. Até a próxima! 😊&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>River na Prática: Resolvendo um problema de classificação com Aprendizado de Máquina Online</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Tue, 24 Oct 2023 14:14:03 +0000</pubDate>
      <link>https://forem.com/nobrelucas/river-na-pratica-resolvendo-um-problema-de-classificacao-com-aprendizado-de-maquina-online-2afj</link>
      <guid>https://forem.com/nobrelucas/river-na-pratica-resolvendo-um-problema-de-classificacao-com-aprendizado-de-maquina-online-2afj</guid>
      <description>&lt;h2&gt;
  
  
  Requisitos
&lt;/h2&gt;

&lt;p&gt;Para seguir esse tutorial espera-se que você tenha conhecimento suficiente da linguagem de programação Python e do uso de ferramentas como Google Colab ou Jupyter-notebook.&lt;/p&gt;

&lt;p&gt;Ter lido os dois primeiros artigos da série de artigos sobre River que eu escrevi é desejável.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalação
&lt;/h2&gt;

&lt;p&gt;A biblioteca River é feita para funcionar a partir do Python 3.8. A instalação pode ser feita usando o gerenciador de pacotes pip:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Via notebook&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;river

&lt;span class="c"&gt;# Via terminal&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;river
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Problema de Classificação
&lt;/h2&gt;

&lt;p&gt;Nesse tutorial vamos explorar um problema de classificação usando o famoso dataset titanic.&lt;/p&gt;

&lt;p&gt;💡 O motivo de eu usar um dataset tradicional e em lote para um tutorial de aprendizado em streaming é puramente educacional. Além disso, como dito no artigo anterior, a biblioteca River tem ferramentas para ler conjuntos de dados em lote no formato de streaming para avaliação do modelo e para propósitos de estudo, como o desse tutorial.&lt;/p&gt;

&lt;p&gt;💡 Esse dataset poderia ser considerado um dataset proativo, pois temos controle direto sobre os dados. Para saber mais confira o artigo de introdução ao River: &lt;a href="https://dev.to/nobrelucas/river-aprendizado-de-maquina-online-com-python-uma-introducao-conceitual-3bb2"&gt;https://dev.to/nobrelucas/river-aprendizado-de-maquina-online-com-python-uma-introducao-conceitual-3bb2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instale os três arquivos do dataset no link: &lt;a href="https://www.kaggle.com/competitions/titanic/data" rel="noopener noreferrer"&gt;https://www.kaggle.com/competitions/titanic/data&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adicione o dataset no seu workspace e vamos começar a trabalhar.&lt;/p&gt;

&lt;p&gt;💡 Recomendo criar uma pasta “data” no seu workspace para adicionar todos os dados&lt;/p&gt;

&lt;h3&gt;
  
  
  Preparação dos Dados
&lt;/h3&gt;

&lt;p&gt;Com o seu notebook aberto, vamos ao código. Começamos criando um DataFrame pandas com os dados de treino e observando as cinco primeiras linhas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;dataframe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data/train.csv&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso deve mostrar o seguinte resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F369qde6ll0byb7ervrar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F369qde6ll0byb7ervrar.png" alt="Cinco primeiras linhas do conjunto de treino" width="800" height="135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 Os detalhes de cada coluna desse dataset podem ser encontrados no link no qual você baixou o conjunto de dados.&lt;/p&gt;

&lt;p&gt;Vamos nos concentrar em fazer um modelo simples. Nesse caso, as colunas que mais nos interessam são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Survived (Alvo): É uma coluna categórica com duas classes (1 para sobreviventes e 0 para não sobreviventes)&lt;/li&gt;
&lt;li&gt;Pclass: É uma coluna categórica com três classes (1 para primeira classe, 2 para segunda classe e 3 para terceira classe)&lt;/li&gt;
&lt;li&gt;Sex: Coluna categórica indicando o sexo do passageiro&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Escolhi as features Pclass e Sex porque, historicamente, mulheres ricas foram as pessoas que mais sobreviveram.&lt;/p&gt;

&lt;p&gt;Vamos filtrar essas colunas que são as únicas que nos interessam no momento&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;dataframe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Survived&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Pclass&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Sex&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mostrando o seguinte resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1rkr69uf5x84y5fql7nw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1rkr69uf5x84y5fql7nw.png" alt="cinco primeiras linhas do conjunto de treino após filtrado" width="187" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos transformar a coluna Sex em uma coluna numérica (1 para male e 2 para female)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Sex&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Sex&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;male&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;female&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obtendo como resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l1j904xm5dho091ijcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l1j904xm5dho091ijcb.png" alt="Cinco primeiras linhas do conjunto de treino após mudança na coluna de sexo do passageiro" width="187" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por fim precisamos separar o dataset em features de treino e alvo (target). No nosso caso, Survived é o alvo e as demais colunas são as features de treino. Também irei transformar a coluna alvo de numérica para booleana para se adaptar ao modelo e a forma que o River trabalha.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;features&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Pclass&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Sex&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Survived&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com todos nossos dados estando no formato desejado e separados em features e target, podemos começar a efetivamente trabalhar com o modelo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criação e treinamento do modelo online
&lt;/h3&gt;

&lt;p&gt;O objetivo de um classificador é predizer qual a categoria de uma determinada amostra, predizer um alvo y para um conjunto de características x. Vamos fazer isso usando um modelo de regressão logística.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;river&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;linear_model&lt;/span&gt;

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;linear_model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LogisticRegression&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com o código acima nós instanciamos o modelo.&lt;/p&gt;

&lt;p&gt;💡 Eu irei frequentemente instanciar o modelo do começo para treiná-lo de formas diferentes.&lt;/p&gt;

&lt;p&gt;Para treinar o modelo, basta alimentar ele com uma amostra dos dados por vez, mas como fazer isso se nossos dados são um grande lote? O módulo &lt;code&gt;stream&lt;/code&gt; do River nos ajuda a lidar com isso e tem uma função chamada iter_pandas, que nos permite iterar um dataframe ou uma série pandas como se os dados estivessem chegando para nós em stream.&lt;/p&gt;

&lt;p&gt;Experimente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;river&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iter_pandas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada print vai mostrar um dicionário com as features e um valor para cada uma delas e ao lado o valor do target para aquela amostra.&lt;/p&gt;

&lt;p&gt;Mas o que queremos não é simplesmente ver as amostras e sim ensinar ao modelo a predizer se dada uma amostra um passageiro sobreviveu ou não.&lt;/p&gt;

&lt;p&gt;Para isso, podemos usar o método &lt;code&gt;learn_one(X, y)&lt;/code&gt;. Entretanto, vamos criar um objeto iterável chamado “stream_dataset” ao invés de chamar a função iter_pandas diretamente no laço de repetição. A motivação para isso vai ficar mais clara futuramente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;river&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;
&lt;span class="n"&gt;stream_dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iter_pandas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;stream_dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;learn_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como estamos em um ambiente de aprendizado, vamos usar o mesmo dataframe para testar o modelo. Para um primeiro teste, vamos tentar predizer a primeira amostra do dataframe (homem que estava na terceira classe do navio e que não sobreviveu).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;stream_dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iter_pandas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream_dataset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 Notem que eu instancio o objeto stream_dataset novamente para poder iterar ele novamente desde o início. Isso irá se repetir durante o resto do tutorial para experimentar diversas abordagens de treino e de validação.&lt;/p&gt;

&lt;p&gt;O resultado do código acima deve ser &lt;code&gt;false&lt;/code&gt; pois de fato esse passageiro não sobreviveu.&lt;/p&gt;

&lt;p&gt;Verificar o que o modelo prediz uma amostra de cada vez não é uma boa estratégia, então vamos avaliar o modelo de uma forma bem comum para iniciantes em aprendizado de máquina: armazenando a predição do modelo para cada iteração e verificar a classe real para aquela amostra e depois calcular uma certa “acurácia” para essas predições.&lt;/p&gt;

&lt;p&gt;💡 Nesse tutorial vou usar como métrica o ROC AUC, uma métrica muito comum para modelos de classificação. Você pode saber mais sobre essa métrica no link: &lt;a href="https://mariofilho.com/guia-completo-sobre-roc-auc-em-machine-learning/" rel="noopener noreferrer"&gt;https://mariofilho.com/guia-completo-sobre-roc-auc-em-machine-learning/&lt;/a&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;river&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;

&lt;span class="n"&gt;metric&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ROCAUC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n_thresholds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;stream_dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iter_pandas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;stream_dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;y_pred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict_proba_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;learn_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_pred&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;metric&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O resultado do código acima deve retornar algo por volta de 81%, o que não é um valor a se jogar fora. Mas vamos experimentar uma outra abordagem, mais próxima do padrão de treinamento e de validação do River.&lt;/p&gt;

&lt;p&gt;A biblioteca River permite criar um modelo como uma Pipeline, ou seja, um processo de passos para o treinamento. Isso é feito simplesmente adicionando “|” entre os processos desejados. &lt;/p&gt;

&lt;p&gt;Além disso, como dito no artigo de introdução do River, o aprendizado e a inferência acontecem na mesma ordem que acontece no ambiente de produção e para isso a biblioteca usa a função progressive_val_score, que recebe o dataset em formato de stream, o modelo e a métrica usada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;river&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;evaluate&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;river&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;optim&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;river&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;preprocessing&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;river&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;compose&lt;/span&gt;

&lt;span class="n"&gt;stream_dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iter_pandas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;preprocessing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StandardScaler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;linear_model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LogisticRegression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;optim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SGD&lt;/span&gt;&lt;span class="p"&gt;(.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;metric&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ROCAUC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n_thresholds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;progressive_val_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream_dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para otimizar o modelo, antes de os dados alimentarem o modelo, eles são redimensionados com o StandardScaler(). O modelo recebe um otimizador do tipo SGD para descida de gradiente estocástica simples. Por fim avaliamos o modelo com progressive_val_score.&lt;/p&gt;

&lt;p&gt;O resultado retornado pela função na última linha deve ser por volta de 82%. Uma melhora não tão considerável em comparação à nossa versão anterior, mas uma melhora é uma melhora.&lt;/p&gt;

&lt;p&gt;Por fim, caso você queira identificar com mais facilidade os elementos do seu pipeline do modelo, basta digitar &lt;code&gt;model&lt;/code&gt; em uma célula do seu notebook e ver a imagem que define o pipeline. No nosso caso, por exemplo, temos:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fncr9o020alovbaj3vuz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fncr9o020alovbaj3vuz1.png" alt="desenho esquemático mostrando o Scaler acima do modelo de LogisticRegression" width="298" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Com esse artigo você é capaz de experimentar várias das formas de trabalhar com a biblioteca River para treinar e avaliar modelos de aprendizado de máquina online. Você limpou um conjunto de dados e aprendeu desde como lidar com dados em lote para que funcionem como dados em streaming até como construir e avaliar um modelo de aprendizado online.&lt;/p&gt;

&lt;p&gt;Se esse conteúdo foi do seu interesse, não esqueça de avaliá-lo de alguma forma e de me seguir para acompanhar os próximos artigos.&lt;/p&gt;

&lt;p&gt;Dúvidas, sugestões ou correções são muito bem-vindas na seção de comentários abaixo. Até a próxima.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>River: Aprendizado de Máquina Online com Python, uma Introdução Conceitual</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Tue, 17 Oct 2023 13:05:29 +0000</pubDate>
      <link>https://forem.com/nobrelucas/river-aprendizado-de-maquina-online-com-python-uma-introducao-conceitual-3bb2</link>
      <guid>https://forem.com/nobrelucas/river-aprendizado-de-maquina-online-com-python-uma-introducao-conceitual-3bb2</guid>
      <description>&lt;p&gt;No último artigo da série tivemos uma introdução ao aprendizado de máquina online como uma alternativa ao aprendizado de máquina tradicional (também chamado de aprendizado de máquina offline), que funciona com dados em lote.&lt;/p&gt;

&lt;p&gt;Hoje, vamos explorar a biblioteca River em nível conceitual, apresentando suas principais características e alguns conceitos básicos que a biblioteca usa ao trabalhar com dados em streaming e modelos de aprendizado de máquina online.&lt;/p&gt;

&lt;h2&gt;
  
  
  Características do River
&lt;/h2&gt;

&lt;p&gt;As principais características do River são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A biblioteca funciona de forma incremental, podendo ser usada para processar dados em streaming&lt;/li&gt;
&lt;li&gt;O River é adaptável, permitindo trabalhar em um ambiente em constante mudança&lt;/li&gt;
&lt;li&gt;É de propósito geral, funcionando para problemas de classificação, de regressão e de clusterização, incluindo aprendizado supervisionado e aprendizado não supervisionado&lt;/li&gt;
&lt;li&gt;É eficiente e fácil de aprender, possuindo uma API semelhante ao do scikit-learn&lt;/li&gt;
&lt;li&gt;Tem uma comunidade e mantenedores dedicados&lt;/li&gt;
&lt;li&gt;Possui conjuntos de dados de fácil acesso que podem ser lidos em forma de streaming para treinamento e avaliação do modelo em um ambiente de estudo. Além de funções para leitura de conjuntos de dados tradicionais em forma de streaming&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Entretanto, vale destacar algumas desvantagens que podem ser essenciais para decidir entre essa biblioteca ou outras ferramentas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A biblioteca não está nem na versão 1.0 ainda&lt;/li&gt;
&lt;li&gt;Poucas pessoas fazem praticamente todo o trabalho, “carregando o projeto nas costas”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Isso abre margem para um receio que o projeto fracasse e seja descontinuado. Entretanto, é ainda a melhor alternativa para se trabalhar com aprendizado de máquina online em Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conceitos Básicos
&lt;/h2&gt;

&lt;p&gt;Antes de colocar a mão na massa, é muito importante conhecer um pouco mais sobre os termos que o River usa para entender melhor quais problemas ele resolve.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Streams
&lt;/h3&gt;

&lt;p&gt;No geral, esse ainda é um termo muito vago e não consolidado, entretanto seguindo a documentação oficial do River, um data stream é uma sequência individual de elementos. Mais especificamente é um conjunto de características comumente chamada de features no jargão de aprendizado de máquina, ou seja, é como se fosse uma única linha de um CSV. A biblioteca chama essa linha única de características de “amostra”&lt;/p&gt;

&lt;p&gt;Vale destacar que toda amostra pode possuir sempre a mesma estrutura e as mesmas features, mas também features novas podem surgir ou sumir, isso depende da aplicação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Streams Reativos e Proativos
&lt;/h3&gt;

&lt;p&gt;Até mesmo dentro do conceito de data streams é possível classificá-lo de duas formas diferentes. Os data streams reativos são aqueles que veem até a gente e que não possuímos muito ou até nenhum controle sobre eles. Note que quando os dados chegam ao modelo vindos da aplicação, como quando um usuário aperta um botão ou quando ele preenche um formulário, não temos controle sobre quando o dado chega e nem qual a velocidade de chegada de novos dados.&lt;/p&gt;

&lt;p&gt;Os data streams proativos, por outro lado são o oposto, como quando estamos lendo um arquivo e controlamos o fluxo de dados. Nesse caso, temos controle sobre a velocidade de leitura e até mesmo da ordem que o arquivo é lido.&lt;/p&gt;

&lt;h3&gt;
  
  
  Processamento Online
&lt;/h3&gt;

&lt;p&gt;Processamento online é o ato de processar os data stream com uma amostra de cada vez, linha a linha. Esse é o maior diferencial do aprendizado online que se opõe ao aprendizado tradicional, no qual se lê um lote inteiro de dados de uma única vez.&lt;/p&gt;

&lt;p&gt;Dessa forma, um modelo online é um objeto stateful e dinâmico. Ele continua sempre aprendendo e não precisa revisitar dados antigos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Propósito Geral
&lt;/h3&gt;

&lt;p&gt;O aprendizado de máquina busca resolver vários problemas, incluindo classificação, regressão, detecção de anomalias, previsão de séries temporais etc. River busca ser uma biblioteca genérica para resolver qualquer tarefa ou problema envolvendo aprendizado de máquina, mas de uma forma online, ou seja, com dados em streaming. Inclusive, muitos algoritmos clássicos que funcionam com dados em lote já possuem suas versões online.&lt;/p&gt;

&lt;p&gt;O River também permite realizar tarefas ainda mais simples, como calcular uma média sobre dados em streaming. Ou seja, ele vai além de uma biblioteca de aprendizado de máquina online e se torna uma biblioteca para processamento de dados em streaming.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dicionários por toda parte
&lt;/h3&gt;

&lt;p&gt;A biblioteca tem como bloco construtor básico o uso de dicionários. Os mantenedores decidiram seguir essa abordagem porque a vetorização não traz nenhum ganho considerável de velocidade no contexto de aprendizado online. Na verdade, bibliotecas de processamento numérico como numpy e PyTorch trazem muito overhead. Usar dicionários nativos do Python é mais rápido.&lt;/p&gt;

&lt;h3&gt;
  
  
  Datasets
&lt;/h3&gt;

&lt;p&gt;Uma das grandes vantagens do aprendizado de máquina online usando River é a capacidade de fazer o design de modelos que podem fazer predições ao mesmo tempo que aprendem conforme os dados fluem.&lt;/p&gt;

&lt;p&gt;Entretanto, durante o desenvolvimento do modelo, você normalmente não vai ter acesso a esses dados em tempo real para avaliar o seu modelo, portanto a biblioteca disponibiliza conjuntos de dados que já podem ser lidos de forma online, ou seja, com uma amostra de cada vez.&lt;/p&gt;

&lt;p&gt;A biblioteca também apresenta funções que convertem um conjunto de dados tradicional, um DataFrame pandas por exemplo, em um conjunto de dados processável via streaming.&lt;/p&gt;

&lt;h3&gt;
  
  
  Avaliação do Modelo
&lt;/h3&gt;

&lt;p&gt;A avaliação do modelo usando River, com aprendizado de máquina online, difere da sua contraparte em lote. Nessa última, você vai geralmente realizar validação cruzada, com seus dados sendo divididos em um conjunto de treino e outro de teste.&lt;/p&gt;

&lt;p&gt;O aprendizado online não utiliza esse processo e a avaliação envolve o aprendizado e a inferência na mesma ordem que ela acontece em um ambiente de produção. Isso permite que você simule um cenário de produção e avalie o seu modelo com uma fidelidade maior que na validação cruzada.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concept Drift
&lt;/h3&gt;

&lt;p&gt;A principal razão para um modelo offline não performar como esperado em produção é por conta do desvio de conceito. Entretanto isso também é verdade para modelos online.&lt;/p&gt;

&lt;p&gt;A grande vantagem dos modelos online em relação aos modelos offline é que eles podem lidar com esse desvio. Na verdade, justamente por continuar sempre aprendendo, esses modelos podem se adaptar ao desvio de conceito de uma forma contínua, diferente de modelos tradicionais que precisam ser restringidos desde o começo.&lt;/p&gt;

&lt;p&gt;Falaremos mais sobre desvio de conceito em tutoriais futuros.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Nesse artigo pudemos explorar os principais conceitos que a biblioteca River aborda de forma a nos preparar para os conteúdos de cunho mais prático que virão em futuros artigos. Com essa base de conhecimento é possível colocar a mão na massa e implementar nosso primeiro modelo de aprendizado de máquina online usando a biblioteca River. &lt;/p&gt;

&lt;p&gt;Se este conteúdo lhe interessou, não esqueça de avaliá-lo de alguma forma e de me seguir para acompanhar os próximos artigos. Dúvidas, sugestões ou correções são muito bem-vindas na seção de comentários abaixo. Até a próxima&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Introdução ao Aprendizado de Máquina Online</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Thu, 05 Oct 2023 14:41:27 +0000</pubDate>
      <link>https://forem.com/nobrelucas/introducao-ao-aprendizado-de-maquina-online-3ocm</link>
      <guid>https://forem.com/nobrelucas/introducao-ao-aprendizado-de-maquina-online-3ocm</guid>
      <description>&lt;p&gt;A cada dia, a geração de dados no mundo cresce, com a previsão de atingir 163 zettabytes (1 trilhão de gigabytes) até o fim de 2025.&lt;/p&gt;

&lt;p&gt;Com a disponibilidade desse vasto volume de dados em um fluxo cada vez maior, negócios em todas as indústrias estão migrando do processamento de dados em lote para o processamento de dados em streaming.&lt;/p&gt;

&lt;p&gt;O aprendizado de máquina tradicional é ineficaz nesse cenário, dando origem a uma nova abordagem chamada Aprendizado de Máquina Online (ou Aprendizado de Máquina com Dados em Streaming), que alimenta os modelos de forma incremental.&lt;/p&gt;

&lt;p&gt;Neste primeiro artigo, apresentarei uma visão superficial do aprendizado de máquina online, explorando os principais conceitos básicos.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Aprendizado de Máquina Online vs. Aprendizado de Máquina Offline&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Aprendizado de Máquina Offline&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Quando se fala sobre Aprendizado de Máquina Offline, está-se referindo à abordagem tradicional na qual o modelo aprende com todos os dados de uma vez, carregados na memória. Essa abordagem apresenta algumas desvantagens ao trabalhar com dados em streaming, incluindo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modelo não aprende incrementalmente&lt;/li&gt;
&lt;li&gt;Usa muitos recursos de processamento e de memória&lt;/li&gt;
&lt;li&gt;Leva muito tempo para executar quando o volume de dados é muito grande&lt;/li&gt;
&lt;li&gt;É necessário treinar o modelo do zero sempre que novos dados chegam&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Aprendizado de Máquina Online&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O aprendizado de máquina online, também conhecido como aprendizado de máquina com dados em streaming, pode ser encontrado na Internet com esses dois nomes, e a verdade é que não parece haver um consenso sobre a nomenclatura. No entanto, o segundo nome demonstra claramente sua orientação para trabalhar com dados em streaming, possuindo muitas vantagens em comparação com modelos offline, incluindo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O modelo é alimentado continuamente sempre que os dados chegam da fonte&lt;/li&gt;
&lt;li&gt;Economiza recursos de processamento e memória (pois os dados não são todos carregados de uma única vez)&lt;/li&gt;
&lt;li&gt;Sempre que novos dados chegam, não é necessário treinar o modelo do zero&lt;/li&gt;
&lt;li&gt;Previne desvios de conceitos (falarei mais sobre isso em outro artigo)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Casos de Uso para Aprendizado de Máquina Online&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Como acontece com toda tecnologia, não é suficiente apenas aplicá-la sem analisar criticamente as demandas dos seus problemas de negócio. O aprendizado de máquina online possui muitas vantagens ao abordar problemas em que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Os dados são sem fim e efetivamente contínuos&lt;/li&gt;
&lt;li&gt;Os dados são sensíveis ou privados e não podem ser armazenados&lt;/li&gt;
&lt;li&gt;Há uma impossibilidade lógica (requisitos de negócio como os do item anterior) ou física (espaço de armazenamento limitado ou rede indisponível) para armazenar ou transferir os dados&lt;/li&gt;
&lt;li&gt;A quantidade de dados é grande demais para caber na memória para o treinamento.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Além disso, deve-se considerar antes de implementar um modelo online:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como lidar com os altos volumes de dados em tempo real&lt;/li&gt;
&lt;li&gt;A velocidade de criação, de distribuição e de coleta dos dados&lt;/li&gt;
&lt;li&gt;A variedade dos dados (texto, vídeo, imagem, áudio, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusão&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Se este conteúdo lhe interessou, não esqueça de avaliá-lo de alguma forma e de me seguir para acompanhar os próximos artigos. Dúvidas, sugestões ou correções são muito bem-vindas na seção de comentários abaixo. No próximo artigo, apresentarei uma biblioteca em Python para lidar com modelos de aprendizado de máquina online. Obrigado pela atenção.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Administrando Ambientes Virtuais com Conda</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Tue, 26 Sep 2023 13:01:35 +0000</pubDate>
      <link>https://forem.com/nobrelucas/administrando-ambientes-virtuais-com-conda-54l9</link>
      <guid>https://forem.com/nobrelucas/administrando-ambientes-virtuais-com-conda-54l9</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;O dia a dia de um desenvolvedor está interligado ao uso de dezenas de bibliotecas e frameworks para as mais diversas funções. Algumas das bibliotecas mais famosas no ecossistema Python para Ciência de Dados são Pandas, Numpy, Matplotlib, Seaborn, Scikit-Learn, Tensorflow, entre outras. Todavia, conforme o profissional vai trabalhando em diversos projetos e atualizando essas bibliotecas, ele pode acabar caindo no problema de incompatibilidade de pacotes.&lt;/p&gt;

&lt;p&gt;Suponhamos que há 10 anos um desenvolvedor chamado Carlos fez um projeto usando Python 2.7, mas hoje em dia já usa o Python 3.9. No entanto, por algum motivo, ele precisa revisitar aquele trabalho antigo. Quando vai tentar rodá-lo, se depara com algum tipo de erro, como um comando de Python 2.7 que não funciona mais em Python 3.9.&lt;/p&gt;

&lt;p&gt;Como Carlos poderia resolver esse problema? Talvez nunca mais atualizando as bibliotecas que ele usa? Essa definitivamente não é uma solução satisfatória, então o que fazer? É aí que ambientes virtuais entram. Um ambiente virtual é como um espaço onde você pode guardar as versões de softwares que você quer que rode nele. De forma mais técnica, um ambiente virtual é um diretório com arquivos python executáveis e outros tipos de arquivo que indicam que ele é um ambiente virtual.&lt;/p&gt;

&lt;p&gt;Com um desses, Carlos tem mais controle sobre quais pacotes estão sendo usados e em qual versão eles estão, pois sempre que um script for rodado dentro de um ambiente virtual, o script vai rodar com as exatas mesmas versões que foram configuradas na hora de escrevê-lo, a menos que o contrário seja especificado.&lt;/p&gt;

&lt;p&gt;Mas como usar isso? Na verdade, existem várias ferramentas para usar as "virtual envs" (ambientes virtuais), tais como o venv, o pyenv e o que será o nosso foco nesse artigo, o conda. Conda é um gerenciador de pacotes das linguagens Python e R, mas também é muito conhecido como um gerenciador de ambientes virtuais. Ele faz parte do Anaconda, um conjunto de ferramentas muito usado por cientistas de dados, como o Jupyter-Notebook, por exemplo.&lt;/p&gt;

&lt;p&gt;Nesse artigo, iremos pular a etapa de instalação do Anaconda, pois imagina-se que a maioria dos profissionais e estudantes da área de dados já o use. Esse artigo é feito usando terminal de comandos Linux Fedora, mas funciona na maioria das distribuições Linux.&lt;/p&gt;

&lt;h2&gt;
  
  
  O ambiente padrão
&lt;/h2&gt;

&lt;p&gt;Se você é um iniciante na área de computação ou veio de um background diferente da tecnologia, suas primeiras experiências com o terminal de comando Linux podem ter sido assustadoras. Ao instalar o Anaconda pela primeira vez em sua distribuição favorita, pode ter se deparado com o marcador "(base)" antes do seu nome de usuário e do nome da sua máquina na linha de comando BASH, como mostrado a seguir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;base&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;user@machine ~]&lt;span class="nv"&gt;$ &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seu primeiro reflexo pode ter sido reiniciar o terminal ou pesquisar como tirar esse (base) estranho dele no Google, mas na verdade, isso já é um ambiente virtual - o ambiente padrão do conda. Nele, estão incluídos todos os pacotes que o conda imagina que você usará como cientista de dados.&lt;/p&gt;

&lt;p&gt;“Então, já posso programar à vontade nesse ambiente?”&lt;br&gt;
Calma, por mais que este seja um ambiente virtual, ele é bastante genérico. Experimente rodar o comando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;base&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;user@machine ~]&lt;span class="nv"&gt;$ &lt;/span&gt;conda list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e veja a quantidade de pacotes existentes. Há muitos pacotes que você pode não precisar ou pode precisar em outra versão. Programar nesse ambiente não faz muita diferença em relação a programar sem nenhum ambiente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando um ambiente a partir da linha de comando
&lt;/h2&gt;

&lt;p&gt;Vamos criar nosso próprio ambiente. Vamos supor que você precisa de um ambiente para um projeto que usa Python, Pandas e Numpy, todos em suas últimas versões, nesse caso, digite o comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;base&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;user@machine ~]&lt;span class="nv"&gt;$ &lt;/span&gt;conda create &lt;span class="nt"&gt;--name&lt;/span&gt; teste1 python pandas numpy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Comando grande, mas fácil de entender, &lt;code&gt;conda create&lt;/code&gt; é o comando para criar um novo ambiente virtual, a flag &lt;code&gt;--name&lt;/code&gt; e o texto que vem em seguida servem para definir qual será o nome desse novo ambiente (o nome do ambiente padrão é base, por exemplo) e todos as palavras a seguir são as bibliotecas, linguagens e frameworks que você quer nesse ambiente, no nosso caso python, pandas e numpy. Após esse comando, uma mensagem semelhante a essa vai aparecer:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vjz8weisxm06w1zk0cw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vjz8weisxm06w1zk0cw.png" alt="lista de pacotes que serão instalados" width="799" height="945"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basta você digitar “y” e apertar ENTER que todos os pacotes necessários serão instalados nesse novo ambiente, mas você ainda vai estar no ambiente padrão. Digite o comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;base&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;user@machine ~]&lt;span class="nv"&gt;$ &lt;/span&gt;conda info &lt;span class="nt"&gt;--envs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu0q8zm2r1ogy7ecmwzm7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu0q8zm2r1ogy7ecmwzm7.png" alt="ambientes virtuais criados na máquina" width="640" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se tudo deu certo, você vai ter como resposta algo semelhante ou idêntico a isso. Para entrar no ambiente novo criado, basta digitar o comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;base&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;user@machine ~]&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source &lt;/span&gt;activate teste1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E pronto, você está no ambiente virtual selecionado, com as bibliotecas, linguagens e frameworks que você especificou. Para ter certeza que você está no ambiente correto, você pode ter dois tipos de feedback. Digitando novamente o comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;teste1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;user@machine ~]&lt;span class="nv"&gt;$ &lt;/span&gt;conda info &lt;span class="nt"&gt;--envs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# conda environments:&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
base                     /home/user/anaconda3
teste1                &lt;span class="k"&gt;*&lt;/span&gt;  /home/user/anaconda3/envs/teste1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note que tem um asterisco (*) ao lado de teste1 ao invés de base, e, se você for atento já pode ter percebido, que (teste1) está escrito no começo da última linha do terminal de comando, enquanto antes era (base). Agora é só desenvolver sua aplicação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Especificando as versões que você quer
&lt;/h2&gt;

&lt;p&gt;Você pode também deixar explicito quais versões das bibliotecas, linguagens e frameworks você quer. Basta especificar essas versões logo após o nome da biblioteca e de um igual, dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;teste1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;user@machine ~]&lt;span class="nv"&gt;$ &lt;/span&gt;conda create &lt;span class="nt"&gt;-n&lt;/span&gt; teste2 &lt;span class="nv"&gt;python&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.6 pandas &lt;span class="nv"&gt;numpy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note que, como no caso do pandas, quando a versão não é especificada, a última versão é a instalada. Note também que você pode simplificar a flag &lt;code&gt;--name&lt;/code&gt; como &lt;code&gt;-n&lt;/code&gt;, isso serve para a maioria das flags, fica a seu critério.&lt;/p&gt;

&lt;h2&gt;
  
  
  Administrando Pacotes
&lt;/h2&gt;

&lt;p&gt;Após criar um ambiente virtual, você pode precisar instalar algum outro pacote ou mesmo atualizar um já instalado (cuidado com o problema de compatibilidade, não jogue fora o potencial dos ambientes virtuais). Nesse caso, você pode procurar se um pacote está disponível com o comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;teste1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;user@machine ~]&lt;span class="nv"&gt;$ &lt;/span&gt;conda search beautifulsoup4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com ele, o conda vai listar todos os pacotes disponíveis com esse nome, em todas as versões disponíveis no repositório Anaconda. Assim, sabemos se ele está disponível. Você pode escolher uma das versões que aparecem para você, ou somente instalar a versão mais recente com&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;teste1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;user@machine ~]&lt;span class="nv"&gt;$ &lt;/span&gt;conda &lt;span class="nb"&gt;install &lt;/span&gt;beautifulsoup4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse pacote vai ser instalado somente no ambiente virtual em que você está, e você pode ver se ele foi instalado corretamente usando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;teste1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;user@machine ~]&lt;span class="nv"&gt;$ &lt;/span&gt;conda list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Pudemos ver que com poucos comandos, que são muito intuitivos, podemos construir um ambiente virtual completo usando conda. Como dito no começo do artigo, existem outros gerenciados de ambientes virtuais para Python e muitos outros para outras linguagens. &lt;/p&gt;

&lt;p&gt;O conda e o próprio Anaconda são muito mais completos que os primeiros comandos que ensinei por aqui, mas espero que eles tenham servido de base para futuros aprendizados. Obrigado pela leitura atenciosa, espero vocês no próximo artigo.&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Linux PATH: O que é e como usar</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Tue, 19 Sep 2023 11:31:39 +0000</pubDate>
      <link>https://forem.com/nobrelucas/linux-path-o-que-e-e-como-usar-o33</link>
      <guid>https://forem.com/nobrelucas/linux-path-o-que-e-e-como-usar-o33</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introdução&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;No nosso último artigo nós exploramos de forma bem geral as variáveis de ambiente Linux. Descobrimos como criar variáveis de ambiente temporárias, persistentes para um usuário e variáveis globais. No meio desse processo, citei uma variável de ambiente muito importante e que deve ser conhecida de muitos de vocês, a variável PATH.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A Variável de Ambiente PATH&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;PATH é uma variável de ambiente que guarda um conjunto ordenado de caminhos (ou paths) onde o Linux vai procurar por executáveis, ou seja, ao executar um comando, não precisamos passar para o terminal um caminho absoluto e somente o nome do comando.&lt;/p&gt;

&lt;p&gt;Um exemplo disso seria o comando echo do Linux. Vamos escrever um “Hello World” no BASH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse comando simplesmente mostra na tela o que está entre parênteses. Nós só podemos usá-lo diretamente, assim, porque o caminho para ele está no PATH, mais precisamente, ele está em /usr/bin/. Dessa forma, não precisamos escrever /usr/bin/echo “Hello World” por mais que dessa forma também funcione.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;O que está no PATH?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Para saber o que está no seu PATH, basta usar o comando echo dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lista de caminhos será mostrada no seguinte formato:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/algum/caminho/qualquer:/outro/caminho/qualquer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O caractere “:” simboliza o fim de um caminho e o início de outro. Procure o caminho /usr/bin onde está o nosso comando echo.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Como adicionar um novo caminho ao PATH?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Para adicionar um novo caminho ao PATH, como /algum/novo/caminho, usaremos o comando export como mostrado a seguir (checar tutorial sobre variáveis de ambiente para mais detalhes sobre esse comando).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:/algum/novo/caminho
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Da mesma forma que vimos no artigo sobre variáveis de ambiente, o que estamos fazendo é dar um novo valor à variável de ambiente PATH. Esse novo valor nada mais é que seu antigo valor ($PATH) com o seu novo caminho anexado ao final, após o separador “:”.&lt;/p&gt;

&lt;p&gt;Não esqueça de depois escrever o comando “echo $PATH” para ver se o seu caminho foi adicionado corretamente ao final do PATH.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Adicionando um novo caminho ao PATH de forma persistente entre sessões de um mesmo usuário&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Caso você tenha lido o artigo sobre variáveis de ambiente, você vai lembrar que só usar o export no terminal vai criar ou alterar o valor de uma variável de ambiente de forma efêmera, ou seja, quando você reiniciar a sessão aquela variável vai ter sumido. Para adicionar nosso novo caminho de forma permanente para um usuário, vamos adicionar o export no final do arquivo ~/.bash_profile. Primeiro abra ele no seu editor de texto, no meu caso será o vim.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois, adicione o comando export da forma que fizemos anteriormente em algum lugar do arquivo, preferencialmente no final. Após isso, só salve o arquivo e para ativá-lo na sessão atual use o comando a seguir no terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Adicionando um novo caminho ao PATH de forma global&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Seguindo a mesma lógica de variáveis de ambiente, vamos criar um &lt;a href="http://arquivo.sh/" rel="noopener noreferrer"&gt;arquivo.sh&lt;/a&gt; em /etc/profile.d&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; /etc/profile.d/exemplo.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com o arquivo criado, vamos editá-lo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim /etc/profile.d/exemplo.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No final do arquivo, adicionamos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:/algum/novo/caminho
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E pronto, temos o que queríamos. Um novo caminho que vai funcionar para todos os usuários da máquina.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Removendo um caminho do PATH&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Tenha muito cuidado ao fazer isso, mas se você tem certeza que deseja remover, digamos, um/caminho/errado que esteja no final do seu PATH, você pode escrever o seguinte comando no terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'s|:um/caminho/errado$||'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Novamente, considere que essa alternativa só funciona caso o caminho esteja no final do PATH. Caso não, uma abordagem menos elegante é:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;printe o seu PATH na tela usando echo $PATH;&lt;/li&gt;
&lt;li&gt;copie e cole o conteúdo printado em algum arquivo em um local seguro&lt;/li&gt;
&lt;li&gt;apague o caminho que você deseja remover no arquivo&lt;/li&gt;
&lt;li&gt;copie o novo PATH e substitua no seu PATH colando o conteúdo após “PATH=”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Obs: Os passos 1 e 2 podem ser feitos mais facilmente com o comando echo $PATH &amp;gt; caminhos.txt, no terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusão&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Nesse artigo aprendemos o que é a variável de ambiente PATH, qual é a sua utilidade e como configurar ela para atender nossas necessidades. Algumas etapas de explicação foram puladas, pois espera-se que você tenha conhecimento de variáveis de ambiente, mas caso não o tenha, você pode checar meu artigo sobre esse assunto nessa mesma plataforma. Obrigado pela leitura.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>braziliandevs</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Uma Introdução a Variáveis de Ambiente em Linux</title>
      <dc:creator>Lucas Nobre Barbosa</dc:creator>
      <pubDate>Mon, 11 Sep 2023 12:55:35 +0000</pubDate>
      <link>https://forem.com/nobrelucas/uma-introducao-a-variaveis-de-ambiente-em-linux-58hj</link>
      <guid>https://forem.com/nobrelucas/uma-introducao-a-variaveis-de-ambiente-em-linux-58hj</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introdução&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Em sua jornada pelo Linux você já deve ter ouvido falar sobre variáveis de ambiente, como uma das mais famosa delas, a variável de ambiente PATH. Mas, o que são essas variáveis? Para o que elas são úteis? São difíceis de aprender? Nesse artigo eu espero te ajudar a responder essas perguntas e talvez até mesmo atiçar sua curiosidade para se aprofundar nesse conteúdo.&lt;/p&gt;

&lt;p&gt;Observe que esse artigo é sobre variáveis de ambiente de forma bem genérica, não falaremos de forma aprofundada sobre PATH, todavia escreverei um outro artigo inteiramente sobre essa variável de ambiente tão importante e famosa.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;O que são Variáveis de Ambiente?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Nas linguagens de programação existem as variáveis, espaços de memória o qual damos nomes e um valor, como preco = 5.32, em Python. Variáveis de Ambiente são como constantes, que são definidas fora do programa através de alguns comandos ou configurando alguns arquivos.&lt;/p&gt;

&lt;p&gt;Elas são muito úteis para esconder informações importantes como senhas, porque colocar essas senhas direto na aplicação é uma péssima ideia (principalmente quando se trata de um repositório público). Definir as senhas em variáveis de ambiente ajuda a esconder elas de pessoas mal intencionadas. Variáveis de Ambiente também são úteis para auxiliar na manutenção do código, pois centralizam algumas configurações em um único lugar e evitam acidentes durante a edição do código. Algumas aplicações são: nomes de domínios, grupo de emails ou URLs/URIs de APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Criando Variáveis de Ambiente&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Em linux, para configurar variáveis de ambiente, normalmente é usado o comando export.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;VALUE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O comando é simples de entender, ao usar ele, você cria uma variável de ambiente com nome NAME e valor VALUE. Por exemplo, podemos criar a variável de ambiente MAX_NUMBER_FILES, que define o número máximo de arquivos que uma aplicação suporta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MAX_NUMBER_FILES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para verificar o valor da variável de ambiente, basta usar o comando echo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$MAX_NUMBER_FILES&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se a variável não existir, uma linha em braco vai aparecer no terminal.&lt;/p&gt;

&lt;p&gt;Outro exemplo seria passar o caminho comumente usado para seus projetos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CAMINHO_DADOS_VENDAS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"~/algum/caminho/valido/dados_vendas"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Apagando Variáveis de Ambiente&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Tão simples quanto criar uma variável de ambiente é apagá-la, mas também não se engane, não basta reconfigurá-la com um valor “vazio”, ela vai continuar lá, só que sem valor. A forma correta de apagar uma variável de ambiente é através do comando unset&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;unset &lt;/span&gt;MAX_NUMBER_FILES
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simples assim você apagou sua variável de ambiente. Todavia, cuidado com o que apaga.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Listando as Variáveis de Ambiente&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Quer saber quais variáveis de ambiente já existem no seu sistema ou verificar se as que você criou estão configuradas corretamente? O comando para isso é set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O output para isso vai ser &lt;strong&gt;gigantesco&lt;/strong&gt;, então não se assuste, mas com um pouco de paciência você encontra o que quer.&lt;/p&gt;

&lt;p&gt;Um outro comando que só mostra as variáveis exportadas é o export&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você pode usar a flag -p para mostrar somente as variáveis de ambiente exportadas nessa sessão&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Procurando com atenção você verá as duas variáveis de ambiente que criamos&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Variáveis de Ambiente Persistentes entre Sessões de um Usuário&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Quando um usuário cria variáveis de ambiente através do terminal de comando linux SHELL, essas variáveis vão existir enquanto a sessão do usuário estiver ativa. Se você quiser que essas variáveis continuem existindo sempre que o sistema for inicializado, você precisa colocar elas em um arquivo de configuração.&lt;/p&gt;

&lt;p&gt;O arquivo bash_profile é um excelente candidato para isso, ele armazena diversas configurações do bash shell e também variáveis de ambiente padrão ou que o usuário define. Use o editor de texto de sua preferência, no meu caso será o vim.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No final do arquivo, adicione&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CAMINHO_DADOS_VENDAS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"~/algum/caminho/valido/dados_vendas"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Salve o arquivo, no caso do vim isso se faz com :w (e :q para sair do editor), e assim você tem uma variável de ambiente que vai ser inicializada sempre que a sua sessão como usuário iniciar.&lt;/p&gt;

&lt;p&gt;Observe que ao fazer isso, a variável de ambiente não vai ser inicializada automaticamente, pois esse arquivo roda quando uma sessão de usuário inicia. Se você quiser já usar essa variável de ambiente, rode também o comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Variáveis de Ambiente Persistentes entre Sessões de todos os Usuários&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Por fim, supondo que você precise de uma variável de ambiente que funcione para todo e qualquer usuário que use o mesmo computador ou servidor(chamadas de variáveis de ambiente globais), você precisa criar um arquivo tipo shell no diretório /etc/profile.d. Os passos são simples:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Crie um novo arquivo em /etc/profile.d para armazenar as variáveis de ambiente globais. É recomendado que o nome desse arquivo seja contextualizado com as variáveis de ambiente que ele vai armazenar.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo touch&lt;/span&gt; /etc/profile.d/http_proxy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Abra o arquivo criado usando um editor de texto
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vim /etc/profile.d/http_proxy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Adicione as variáveis de ambientes no arquivo
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HTTP_PROXY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://my.proxy:8080
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HTTPS_PROXY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://my.proxy:8080
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;NO_PROXY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;localhost,::1,.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Salve suas alterações e saia do editor de texto.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusão&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Variáveis de ambiente são ferramentas extremamente poderosas e têm o potencial de aprimorar e muito o seu processo de Desenvolvimento, de Ciência de Dados ou de engenharia de Machine Learning. Nesse artigo você aprendeu como criar variáveis de ambiente temporárias, persistentes para um usuário e variáveis de ambiente globais. A partir daqui, continue seus estudos para dominar essa ferramenta. Obrigado pela leitura.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>linux</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
