{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[]},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"},"gpuClass":"standard"},"cells":[{"cell_type":"markdown","source":["# **Aula 3 - 21/08 - Funções, Métodos, Módulos, Bibliotecas e Numpy**\n","\n"],"metadata":{"id":"_ns7mAL7Sqmm"}},{"cell_type":"markdown","source":["

Quando começamos a desenvolver programas mais complexos, logo percebemos que repetir trechos de código leva a redundâncias e dificulta a manutenção. É aí que as funções entram em cena. Elas nos permitem agrupar um conjunto de instruções relacionadas em um único bloco, tornando nosso código mais organizado, legível e reutilizável. Imagine poder chamar uma função bem nomeada em vez de reescrever o mesmo código repetidamente.\n","\n","

Além disso, exploraremos como usar módulos em Python. Os módulos são como pastas de ferramentas que contêm conjuntos específicos de funções e classes. Eles nos permitem organizar nosso código em arquivos separados, facilitando a colaboração e a manutenção. Além disso, podemos aproveitar a rica biblioteca de módulos da comunidade Python para adicionar funcionalidades especializadas aos nossos programas.\n","\n","

Por fim, entraremos no mundo da computação numérica eficiente com o NumPy. Esta biblioteca poderosa oferece estruturas de dados otimizadas para operações matemáticas em arrays multidimensionais. Se você já trabalhou com matrizes ou dados científicos, você vai adorar as capacidades que o NumPy traz para suas aplicações.\n"],"metadata":{"id":"WbPvhjqETV7N"}},{"cell_type":"markdown","source":["### 1. Funções\n","\n"],"metadata":{"id":"D0rD_ajPUnll"}},{"cell_type":"markdown","source":["

Em Python, uma função é um bloco de código autônomo que realiza uma tarefa específica. Elas nos permitem agrupar um conjunto de instruções relacionadas sob um único nome, que pode ser chamado sempre que necessário. Em outras palavras, as funções promovem a reutilização de código, melhoram a legibilidade e reduzem erros."],"metadata":{"id":"sw2sE3Gw6Umh"}},{"cell_type":"markdown","source":["

Ao longo das aulas, já utilizamos algumas funções *built-in* do python, como o len(), print(), etc. Para mais informações sobre as funções que já vem com o Python, acesse o link"],"metadata":{"id":"4N0fcsyt3amT"}},{"cell_type":"markdown","source":["**Vantagens das Funções:**\n","\n","* Reutilização de Código: Você pode definir uma função uma vez e usá-la em várias partes do seu programa, evitando duplicação de código.\n","* Organização: Funções permitem que você divida seu programa em partes menores e mais gerenciáveis. Cada função pode se concentrar em uma tarefa específica.\n","* Manutenção: Se você precisa fazer uma alteração em uma parte do código, alterar apenas uma função afeta todas as ocorrências em que ela é chamada.\n","* Legibilidade: Ao dar nomes descritivos às funções, seu código se torna mais legível e autoexplicativo."],"metadata":{"id":"ldffHFkAruxV"}},{"cell_type":"markdown","source":["Exemplo simples da sintaxe de uma função:"],"metadata":{"id":"-GH1Gq8z9PiT"}},{"cell_type":"code","source":["def saudacao(nome):\n"," print(\"Olá,\", nome, \"!\")"],"metadata":{"id":"hD2aeWAxsJ0m"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["

Neste exemplo, definimos a função utilizando \"def\", a chamando de \"saudacao\", e ela recebe um parâmetro/argumento \"nome\" e imprime uma mensagem utilizando ele. No entanto, ao rodar esta célula, nada acontece além de salvar a função dentro do Python. Você precisa também chamar a função, e atribuir algum valor ao argumento \"nome\""],"metadata":{"id":"alSi3RSz5h42"}},{"cell_type":"code","source":["saudacao(\"José\")\n"],"metadata":{"id":"hYUmRAmU5ay5","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1692279125443,"user_tz":180,"elapsed":284,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"145fe92c-160f-4fb9-c22f-4945ac2a49bb"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Olá, José !\n"]}]},{"cell_type":"markdown","source":["Outro exemplo de função pode ser o de pegar dois números como argumentos ('x' e 'y') e fazer a soma deles:"],"metadata":{"id":"o_U7KmyI8Yhq"}},{"cell_type":"code","source":["def soma(x,y):\n"," return x+y\n","\n","\n","soma(2,1)"],"metadata":{"id":"uHZIckGA-QRv","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1692279284627,"user_tz":180,"elapsed":2,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"053beebc-5035-42ad-d070-dd332a689150"},"execution_count":null,"outputs":[{"output_type":"execute_result","data":{"text/plain":["3"]},"metadata":{},"execution_count":5}]},{"cell_type":"markdown","source":["Se você fizer uma função sem utilizar o return, ela vai retornar um valor *None*\n","\n"],"metadata":{"id":"lnQmA6sctNVT"}},{"cell_type":"code","source":["def imprima(x):\n"," print(x)\n","\n","imprima(\"Olá\")\n","\n","resultado = imprima(\"Olá\")\n","\n","print(resultado)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"BBY2JAp1tTgf","executionInfo":{"status":"ok","timestamp":1692279401459,"user_tz":180,"elapsed":245,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"49473116-cbf6-4fc2-f5d9-7e884029d226"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Olá\n","Olá\n","None\n"]}]},{"cell_type":"markdown","source":["

Você também pode definir valores padrões para determinados argumentos se achar necessário. Imagine que estamos criando uma função que calcula o preço total de uma compra, considerando um desconto opcional. Vamos definir um valor padrão para o desconto, caso ele não seja especificado:"],"metadata":{"id":"1IOuK9irtuDR"}},{"cell_type":"code","source":["def calcular_preco_total(valor_produto, desconto=0):\n"," preco_com_desconto = valor_produto - (valor_produto * desconto / 100)\n"," return preco_com_desconto\n","\n","# Chamando a função com desconto padrão de 0%\n","preco_final1 = calcular_preco_total(100)\n","print(\"Preço com desconto padrão:\", preco_final1)\n","\n","# Chamando a função com desconto de 10%\n","preco_final2 = calcular_preco_total(100, 10)\n","print(\"Preço com desconto de 10%:\", preco_final2)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"Gakm2eJ8t4jq","executionInfo":{"status":"ok","timestamp":1692279925108,"user_tz":180,"elapsed":246,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"943b1781-01e7-4a67-d348-574ba9af2b7b"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Preço com desconto padrão: 100.0\n","Preço com desconto de 10%: 90.0\n"]}]},{"cell_type":"markdown","source":["#### Docstrings"],"metadata":{"id":"u1gnj0aGyWtS"}},{"cell_type":"markdown","source":["

Pensando tanto na legibilidade quanto no seu \"eu futuro\", uma boa prática pode ser a de utilizar docstrings em suas funções. As docstrings são strings de documentação que fornecem informações sobre módulos, funções, classes ou métodos em Python. Elas são usadas para descrever o propósito, o funcionamento e os parâmetros de uma entidade do código, tornando o código mais compreensível e autoexplicativo.\n","\n","

As docstrings são delimitadas por três aspas (simples ou duplas) no início e no final da definição de uma entidade. Aqui está um exemplo de uma docstring para uma função:"],"metadata":{"id":"0AGr7r_OyYTB"}},{"cell_type":"code","source":["def calcular_media(valores):\n"," \"\"\"\n"," Calcula a média dos valores em uma lista.\n","\n"," Args:\n"," valores (list): Uma lista de valores numéricos.\n","\n"," Returns:\n"," float: A média dos valores.\n","\n"," Exemplo:\n"," >>> calcular_media([1, 2, 3, 4, 5])\n"," 3.0\n"," \"\"\"\n"," total = sum(valores)\n"," media = total / len(valores)\n"," return media"],"metadata":{"id":"mPvlxEm5y-DN"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["Veja que a função ainda funciona da forma desejada."],"metadata":{"id":"MLEJBt22zK9I"}},{"cell_type":"code","source":["calcular_media([1,2,3,4,5])"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"sdma-dhDzBa1","executionInfo":{"status":"ok","timestamp":1692280847136,"user_tz":180,"elapsed":3,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"4c23423c-33ac-41f8-dc81-7545508de0f2"},"execution_count":null,"outputs":[{"output_type":"execute_result","data":{"text/plain":["3.0"]},"metadata":{},"execution_count":12}]},{"cell_type":"markdown","source":["Para consultar a documentação da função, pode se utilizar o atributo '\\_\\_doc\\_\\_'."],"metadata":{"id":"Gd5a5aoxzPKU"}},{"cell_type":"code","source":["print(calcular_media.__doc__)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"l2PgSQAgzXKA","executionInfo":{"status":"ok","timestamp":1692280912551,"user_tz":180,"elapsed":245,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"34251011-f52a-4160-8a5a-633b29e775a2"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["\n"," Calcula a média dos valores em uma lista.\n","\n"," Args:\n"," valores (list): Uma lista de valores numéricos.\n","\n"," Returns:\n"," float: A média dos valores.\n","\n"," Exemplo:\n"," >>> calcular_media([1, 2, 3, 4, 5])\n"," 3.0\n"," \n"]}]},{"cell_type":"markdown","source":["#### Métodos"],"metadata":{"id":"tzseg0Huz6by"}},{"cell_type":"markdown","source":["

Métodos são funções que estão associadas a objetos em Python. Eles permitem que você defina ações que um objeto pode realizar ou comportamentos que ele pode ter. Em termos simples, métodos são funções que são definidas dentro de uma classe e são acessadas através das instâncias dessa classe.\n","\n","

O conceito de classes é muito avançado para o intuito dessa aula. Mas o que importa destacar é a diferença entre funções no python, como len(), print(), input(), e métodos de objetos, como list.append(), list.extend(), list.insert(), etc. Todos os objetos em python possuem métodos próprios associados à eles, e é necessário sempre consultar a documentação para entender quais estão ao seu dispor. Por exemplo, olhe os métodos disponíveis para listas em Python. Também é possível consultar a documentação de determinado método utilizando o \"__doc__\"\n"],"metadata":{"id":"n8Z09J_x3RcF"}},{"cell_type":"code","source":["print(list.append.__doc__)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"WpKRbNIb6Myu","executionInfo":{"status":"ok","timestamp":1692282734222,"user_tz":180,"elapsed":285,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"b98ae500-e5d3-4e60-8917-962590599cb0"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Append object to the end of the list.\n"]}]},{"cell_type":"markdown","source":["Se quiser, também pode listar todos os métodos e atributos de um objeto em Python utilizando o dir:"],"metadata":{"id":"Vpp1VtJ9Ogw1"}},{"cell_type":"code","source":["# Métodos e atributos do dicionário\n","\n","dicionario = {\"nome\":'josé'}\n","\n","dir(dicionario)"],"metadata":{"id":"cktm3ez0Om24","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1692288174688,"user_tz":180,"elapsed":3,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"0615be68-b619-400c-a16e-7b39af24b9df"},"execution_count":null,"outputs":[{"output_type":"execute_result","data":{"text/plain":["['__class__',\n"," '__class_getitem__',\n"," '__contains__',\n"," '__delattr__',\n"," '__delitem__',\n"," '__dir__',\n"," '__doc__',\n"," '__eq__',\n"," '__format__',\n"," '__ge__',\n"," '__getattribute__',\n"," '__getitem__',\n"," '__gt__',\n"," '__hash__',\n"," '__init__',\n"," '__init_subclass__',\n"," '__ior__',\n"," '__iter__',\n"," '__le__',\n"," '__len__',\n"," '__lt__',\n"," '__ne__',\n"," '__new__',\n"," '__or__',\n"," '__reduce__',\n"," '__reduce_ex__',\n"," '__repr__',\n"," '__reversed__',\n"," '__ror__',\n"," '__setattr__',\n"," '__setitem__',\n"," '__sizeof__',\n"," '__str__',\n"," '__subclasshook__',\n"," 'clear',\n"," 'copy',\n"," 'fromkeys',\n"," 'get',\n"," 'items',\n"," 'keys',\n"," 'pop',\n"," 'popitem',\n"," 'setdefault',\n"," 'update',\n"," 'values']"]},"metadata":{},"execution_count":46}]},{"cell_type":"markdown","source":["#### Escopo de Variáveis\n","\n","O escopo de variáveis em Python se refere à região do código onde uma variável pode ser acessada e manipulada. O escopo determina onde uma variável é válida e em quais partes do programa ela pode ser utilizada.\n","\n","Existem dois principais tipos de escopo em Python:"],"metadata":{"id":"t3xq-yFNBcbC"}},{"cell_type":"markdown","source":["##### Escopo Local"],"metadata":{"id":"5UtZeve0BtTs"}},{"cell_type":"markdown","source":["Variáveis definidas dentro de uma função têm escopo local, o que significa que elas só podem ser acessadas dentro dessa função. Elas são visíveis apenas para o bloco de código em que foram definidas. Uma vez que a execução da função é concluída, as variáveis locais não podem mais ser acessadas."],"metadata":{"id":"dBJzvT0uBw8v"}},{"cell_type":"code","source":["def minha_funcao():\n"," variavel_local = 10\n"," print(variavel_local) # Acesso dentro da função\n","\n","minha_funcao()\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"__omNnw0Bwed","executionInfo":{"status":"ok","timestamp":1692284726322,"user_tz":180,"elapsed":429,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"90bd951b-8877-43b6-817d-105616db1f87"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["10\n"]}]},{"cell_type":"code","source":["# Agora, se eu tentar imprimir o valor da variável local, veja o que acontece:\n","\n","print(variavel_local)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":210},"id":"zIORotwIB5-g","executionInfo":{"status":"error","timestamp":1692284727146,"user_tz":180,"elapsed":3,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"c5f61488-1a43-4148-cfe5-38fab81ce3a2"},"execution_count":null,"outputs":[{"output_type":"error","ename":"NameError","evalue":"ignored","traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)","\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Agora, se eu tentar imprimir o valor da variável local, veja o que acontece:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvariavel_local\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m","\u001b[0;31mNameError\u001b[0m: name 'variavel_local' is not defined"]}]},{"cell_type":"markdown","source":["##### Escopo Global\n","\n","Variáveis definidas fora de qualquer função ou bloco de código têm escopo global. Elas podem ser acessadas de qualquer parte do código, incluindo dentro de funções. No entanto, se você deseja modificar uma variável global de dentro de uma função, precisa usar a palavra-chave global para indicar que está se referindo à variável global, em vez de criar uma nova variável local com o mesmo nome. No entanto, isso não é recomendado, pois pode gerar problemas no seu código se outras partes dele dependem do valor da variável global do modo como está."],"metadata":{"id":"bdXz0vT-B8Q2"}},{"cell_type":"code","source":["variavel_global = 20\n","\n","def minha_funcao():\n"," global variavel_global\n"," variavel_global += 1\n"," print(variavel_global) # Acesso e modificação dentro da função\n","\n","minha_funcao()\n","print(variavel_global) # Acesso fora da função"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"Q1j4w5YVCI8H","executionInfo":{"status":"ok","timestamp":1692284788859,"user_tz":180,"elapsed":248,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"8a7351fe-6a92-4a2f-f931-c2be8ac17417"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["21\n","21\n"]}]},{"cell_type":"markdown","source":["É importante entender o escopo das variáveis, pois ajuda a evitar bugs e problemas de lógica no código. Variáveis locais são úteis para manter um contexto limitado a uma função, enquanto variáveis globais podem ser usadas para compartilhar informações entre várias partes do programa. É recomendável usar variáveis locais sempre que possível, pois isso ajuda a manter o código mais fácil de entender."],"metadata":{"id":"4HM68f_gCM60"}},{"cell_type":"markdown","source":["#### Funções Lambda"],"metadata":{"id":"llTf_GFqGNxo"}},{"cell_type":"markdown","source":["Funções lambda, também conhecidas como funções anônimas, são funções pequenas e simples que podem ser criadas de forma concisa usando a expressão lambda em Python. Elas são especialmente úteis quando você precisa de uma função temporária para um cálculo rápido e não deseja definir uma função completa usando a declaração def.\n","\n","A sintaxe básica de uma função lambda é a seguinte:"],"metadata":{"id":"1KeF4hsxGSeT"}},{"cell_type":"code","source":["lambda argumentos: expressao"],"metadata":{"id":"gQgQeawYGTFY"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["As funções lambda têm as seguintes características:\n","\n","* Anonimato: As funções lambda são anônimas, o que significa que você não atribui um nome a elas como faz com as funções definidas com def.\n","\n","* Expressão Única: A expressão lambda deve ser uma única expressão que é avaliada e retornada quando a função é chamada. Não é possível incluir várias instruções ou blocos de código.\n","\n","* Uso Geral: As funções lambda são mais comumente usadas em situações onde uma função simples é necessária como argumento para outras funções, como map, filter e sorted.\n","\n","\n","Exemplo:"],"metadata":{"id":"yShAVlJEGUg3"}},{"cell_type":"code","source":["# Usando uma função lambda para calcular o quadrado de um número\n","quadrado = lambda x: x ** 2\n","\n","print(quadrado(5)) # Saída: 25\n","\n","# Usando uma função lambda como argumento para a função map\n","numeros = [1, 2, 3, 4, 5]\n","quadrados = list(map(lambda x: x ** 2, numeros))\n","print(quadrados) # Saída: [1, 4, 9, 16, 25]"],"metadata":{"id":"a2kTYlBMGjFf"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["A função map é mais avançada. Se tiver interesse, pode descobrir mais sobre ela no [link](https://docs.python.org/3/library/functions.html?highlight=map#map).\n","\n","De forma geral, as expressões lambda são utilizadas quando não parece ser proveitoso fazer a definição de uma função completa."],"metadata":{"id":"Z3-nZIDTGnrw"}},{"cell_type":"markdown","source":["#### Imports"],"metadata":{"id":"TNmdzH4Ilytf"}},{"cell_type":"markdown","source":["O import em Python é uma construção que permite que você acesse funcionalidades de módulos externos ou bibliotecas para estender as capacidades do Python. Módulos são arquivos Python que contêm definições e declarações que podem ser reutilizadas em diferentes partes do seu programa. Importar um módulo permite que você use suas funções, classes e variáveis em seu próprio código.\n","\n","Existem diferentes maneiras de usar o import. Você pode importar um módulo inteiro usando a palavra-chave import. Por exemplo:\n"],"metadata":{"id":"uF3l5X3Kl0Ag"}},{"cell_type":"code","source":["import math\n","print(math.sqrt(25)) # Usando a função sqrt do módulo math"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"iSMAlHvWl5yQ","executionInfo":{"status":"ok","timestamp":1692294178622,"user_tz":180,"elapsed":4,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"9382cbff-a50d-410e-ce65-23074b4c9c38"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["5.0\n"]}]},{"cell_type":"markdown","source":["Se você quiser importar apenas partes específicas de um módulo, pode usar a instrução from ... import .... Por exemplo:"],"metadata":{"id":"CStbnWhhl--f"}},{"cell_type":"code","source":["from math import sqrt\n","print(sqrt(25)) # Não é necessário usar math.sqrt, apenas sqrt"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"-8bpTLK4mBPh","executionInfo":{"status":"ok","timestamp":1692294201407,"user_tz":180,"elapsed":257,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"416e965d-f48a-4a7a-db66-72db308a00ff"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["5.0\n"]}]},{"cell_type":"markdown","source":["Você também pode renomear módulos ao importá-los usando a palavra-chave as. Isso é útil quando o nome do módulo é longo ou pode causar conflitos com outros nomes."],"metadata":{"id":"bATVHSPtmGBv"}},{"cell_type":"code","source":["import numpy as np"],"metadata":{"id":"OjJNW2_2mHdJ"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["Principais Imports Utilizados:\n","\n","Existem muitos módulos populares e bibliotecas externas em Python que estendem suas funcionalidades. Alguns dos principais módulos e suas funcionalidades incluem:\n","\n","* math: Fornece funções matemáticas como trigonometria, logaritmo e mais.\n","* random: Gera números aleatórios.\n","* datetime: Manipula datas e horas.\n","* os: Fornece funcionalidades para interagir com o sistema operacional.\n","* sys: Fornece acesso a variáveis e funções específicas do interpretador Python.\n","* json: Lida com a codificação e decodificação de dados JSON.\n","* requests: Faz solicitações HTTP para interagir com APIs da web.\n","* numpy: Biblioteca para computação numérica eficiente com arrays multidimensionais.\n","* pandas: Biblioteca para análise e manipulação de dados tabulares.\n","* matplotlib: Biblioteca para criação de gráficos e visualizações.\n","\n","\n","Esses são apenas alguns exemplos de módulos populares. O Python tem uma ampla variedade de bibliotecas para diferentes finalidades, e você pode encontrar mais de acordo com as necessidades específicas do seu projeto."],"metadata":{"id":"bKr_b8iPoQD6"}},{"cell_type":"markdown","source":["### Exercícios"],"metadata":{"id":"xS640Eo_B_A_"}},{"cell_type":"markdown","source":["1 - Crie uma função que recebe 3 números como parâmetros e exiba a soma entre eles. Depois, faça uma chamada à função."],"metadata":{"id":"TIwStOxHUTai"}},{"cell_type":"code","source":["def soma(n1, n2, n3):\n"," print(n1 + n2 + n3)\n","\n","\n","soma(2, 1, 3)"],"metadata":{"id":"6UVus0k3TOLV","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1692283534140,"user_tz":180,"elapsed":240,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"a94bd34d-eeb4-487d-ea32-eb92a33508bf"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["6\n"]}]},{"cell_type":"markdown","source":["2 - Crie uma função que receba 2 números. O primeiro é um valor e o segundo um percentual (ex. 10%). Retorne (return) o valor do primeiro número somado do aumento percentual do mesmo. Execute a função para ver se o resultado está correto."],"metadata":{"id":"8MNj4OSyU8Us"}},{"cell_type":"code","source":["def perc(n1, n2):\n"," return n1 + (n1 * n2 / 100)\n","\n","print(perc(100,50))"],"metadata":{"id":"y_fLjaLvTOEy","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1692283800096,"user_tz":180,"elapsed":2,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"36fdce65-1644-4240-cd42-31423700c104"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["150.0\n"]}]},{"cell_type":"markdown","source":["3 - Vá na documentação de strings no python ([Link](https://docs.python.org/3/library/stdtypes.html?highlight=upper#string-methods)). Com isso em mãos, crie uma função que recebe uma string como argumento e que deixa o primeiro caractere em maiúsculo. Chame a função ao final da célula."],"metadata":{"id":"YCLW__joVLop"}},{"cell_type":"code","source":["def capitaliza(str1):\n"," return str1.capitalize()\n","\n","\n","capitaliza(\"josé amava lírios.\")"],"metadata":{"id":"TWbms9g7TN-I","colab":{"base_uri":"https://localhost:8080/","height":35},"executionInfo":{"status":"ok","timestamp":1692284071094,"user_tz":180,"elapsed":6,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"15622a29-1e28-4700-d691-a80ebbe420a8"},"execution_count":null,"outputs":[{"output_type":"execute_result","data":{"text/plain":["'José amava lírios.'"],"application/vnd.google.colaboratory.intrinsic+json":{"type":"string"}},"metadata":{},"execution_count":21}]},{"cell_type":"markdown","source":["4 - Crie uma função que recebe uma lista de strings e as retorna totalmente em letras minúsculas."],"metadata":{"id":"g04JWLs3DBTt"}},{"cell_type":"code","source":["# Com List Comprehension\n","\n","def converter_para_lower(strings):\n"," strings_lower = [s.lower() for s in strings]\n"," return strings_lower\n","\n","# Ou\n","\n","def converter_para_lower2(strings):\n","\n"," strings_lower = []\n","\n"," for s in strings:\n"," strings_lower.append(s.lower())\n"," return strings_lower\n","\n","\n","# Lista de strings de exemplo\n","lista_strings = [\"Python\", \"É\", \"Uma\", \"Linguagem\", \"De\", \"Programação\"]\n","\n","# Chamando a função e imprimindo o resultado 1\n","strings_lower1 = converter_para_lower(lista_strings)\n","print(strings_lower1)\n","\n","# Chamando a função e imprimindo o resultado 2\n","strings_lower2 = converter_para_lower2(lista_strings)\n","print(strings_lower2)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"o8shTSEQDWzY","executionInfo":{"status":"ok","timestamp":1692285338109,"user_tz":180,"elapsed":254,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"3c5329fd-4cb6-4695-c6d5-6f7d74df7bc1"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["['python', 'é', 'uma', 'linguagem', 'de', 'programação']\n","['python', 'é', 'uma', 'linguagem', 'de', 'programação']\n"]}]},{"cell_type":"markdown","source":["5 - Crie uma função que receba três listas como argumentos e as junte em um dicionário. A função deve retornar o dicionário final. Execute a função utilizando as três listas abaixo, apresentando o resultado final em um print. Lembre-se, cada elemento da lista deve estar associado ao seu equivalente dentro do dicionário (i.e. \"Alice\" com \"Jonhson\" com \"alice@example.com\"). Dica: você vai precisar da função [zip](https://docs.python.org/3/library/functions.html?highlight=zip#zip) e revisar um pouco mais de [dicionários](https://docs.python.org/3/tutorial/datastructures.html?highlight=dictionaries#dictionaries)."],"metadata":{"id":"EVFVGeJ7Vfza"}},{"cell_type":"code","source":["# Listas de teste\n","primeiros_nomes = [\"Alice\", \"Bob\", \"Carol\", \"David\", \"Eve\"]\n","ultimos_nomes = [\"Johnson\", \"Smith\", \"Williams\", \"Brown\", \"Davis\"]\n","emails = [\"alice@example.com\", \"bob@example.com\", \"carol@example.com\", \"david@example.com\", \"eve@example.com\"]\n","\n","\n","def listas_em_dicionario(nomes, sobrenomes, emails):\n"," dicionario = {}\n"," for nome, sobrenome, email in zip(nomes, sobrenomes, emails):\n"," dicionario[nome] = {\"sobrenome\": sobrenome, \"email\": email}\n"," return dicionario\n","\n","\n","\n","dicionario = listas_em_dicionario(primeiros_nomes,ultimos_nomes, emails)\n","\n","\n","# Exemplo de como imprimir os valores de um dicionário depois do resultado da função.\n","\n","for nome, info in dicionario.items():\n"," print(f\"Nome: {nome}, Sobrenome: {info['sobrenome']}, Email: {info['email']}\")\n","\n","\n","\n","\n","\n"],"metadata":{"id":"NO3cS6etWG5V","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1692288681023,"user_tz":180,"elapsed":252,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"eeb18aeb-3403-4c48-870c-e9f511d5c987"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Nome: Alice, Sobrenome: Johnson, Email: alice@example.com\n","Nome: Bob, Sobrenome: Smith, Email: bob@example.com\n","Nome: Carol, Sobrenome: Williams, Email: carol@example.com\n","Nome: David, Sobrenome: Brown, Email: david@example.com\n","Nome: Eve, Sobrenome: Davis, Email: eve@example.com\n"]}]},{"cell_type":"markdown","source":["6 - Abaixo você encontra uma lista com temperaturas em graus Celsius. Crie uma função anônima que converta cada temperatura para Fahrenheit. Dica: para conseguir realizar este exercício, você deve criar sua função lambda, dentro de uma função. Fórmula: F = (C * 1,8) + 32"],"metadata":{"id":"KeELXjCYWZpy"}},{"cell_type":"code","source":["Celsius = [35, 25, 17, 28.5]\n","\n","# Modo conciso (tem exemplo parecido acima)\n","Fahrenheit = map(lambda x: (float(9)/5)*x + 32, Celsius)\n","\n","# Definindo a função\n","\n","def c_para_f(temps):\n"," fahrenheit = list(map(lambda x: (float(9)/5)*x + 32, temps))\n"," return fahrenheit\n","\n","\n","# Resultado do Modo extenso\n","\n","resultado = c_para_f(Celsius)\n","\n","print(list(resultado))\n","\n","# Resultado do modo conciso\n","print(list(Fahrenheit))\n","\n","# [95.0, 77.0, 62.6, 83.30000000000001]"],"metadata":{"id":"Sr0mYe09TN3y","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1692287215300,"user_tz":180,"elapsed":2,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"38ebf83c-19cb-4aa9-d5b3-242d3879eb07"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[95.0, 77.0, 62.6, 83.30000000000001]\n","[95.0, 77.0, 62.6, 83.30000000000001]\n"]}]},{"cell_type":"markdown","source":["7 - Crie uma função que receba uma lista de números. Com essa lista, a função deve calcular média, moda, mediana e desvio padrão. Ao fim, deve imprimir cada um desses valores em linhas separadas. [Dica](https://docs.python.org/3/library/statistics.html?highlight=mean#statistics.mean)"],"metadata":{"id":"IPQxiTmqgmoD"}},{"cell_type":"code","source":["\n","import statistics as stat\n","\n","lista_nums = [72,42,24,48,124,23]\n","\n","def estatisticas(nums):\n"," media = stat.mean(nums)\n"," moda = stat.mode(nums)\n"," mediana = stat.median(nums)\n"," desvpad = stat.stdev(nums)\n","\n"," print(f'A média da lista é: {media}')\n"," print(f'A moda da lista é: {moda}')\n"," print(f'A mediana da lista é: {mediana}')\n"," print(f'O desvio padrão da lista é: {desvpad}')\n","\n","\n","estatisticas(lista_nums)\n","\n","\n","\n","\n","\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"VQ-CTfIrjqvk","executionInfo":{"status":"ok","timestamp":1692294413301,"user_tz":180,"elapsed":234,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"dc7ad671-96e2-4252-c551-6ef4e6608cc6"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["A média da lista é: 55.5\n","A moda da lista é: 72\n","A mediana da lista é: 45.0\n","O desvio padrão da lista é: 38.082804518575045\n"]}]},{"cell_type":"markdown","source":["8 - Calculadora Simples: Crie uma calculadora simples com funções para realizar operações de adição, subtração, multiplicação e divisão. A função principal deve pedir ao usuário qual operação deseja realizar e, em seguida, solicitar os números para a operação."],"metadata":{"id":"2Nw4AaC3WviX"}},{"cell_type":"code","source":["def adicao(a, b):\n"," return a + b\n","\n","def subtracao(a, b):\n"," return a - b\n","\n","def multiplicacao(a, b):\n"," return a * b\n","\n","def divisao(a, b):\n"," if b != 0:\n"," return a / b\n"," else:\n"," return \"Não é possível dividir por zero.\"\n","\n","def calculadora():\n"," print(\"Escolha a operação:\")\n"," print(\"1. Adição\")\n"," print(\"2. Subtração\")\n"," print(\"3. Multiplicação\")\n"," print(\"4. Divisão\")\n"," print(\"===================\")\n"," print(\" \")\n","\n"," escolha = input(\"Digite o número da operação desejada: \")\n","\n"," num1 = float(input(\"Digite o primeiro número: \"))\n"," num2 = float(input(\"Digite o segundo número: \"))\n","\n"," print(\" \")\n"," print(\"###### Resultado ######\")\n","\n"," if escolha == \"1\":\n"," resultado = adicao(num1, num2)\n"," elif escolha == \"2\":\n"," resultado = subtracao(num1, num2)\n"," elif escolha == \"3\":\n"," resultado = multiplicacao(num1, num2)\n"," elif escolha == \"4\":\n"," resultado = divisao(num1, num2)\n"," else:\n"," resultado = \"Operação inválida.\"\n","\n"," print(\"Resultado:\", resultado)\n","\n","# Chamar a função calculadora para realizar uma operação\n","calculadora()"],"metadata":{"id":"IHVI6n3EWZIb","colab":{"base_uri":"https://localhost:8080/"},"outputId":"4e474105-b034-4615-8f92-3835fade01e0","executionInfo":{"status":"ok","timestamp":1692295063370,"user_tz":180,"elapsed":4244,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}}},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Escolha a operação:\n","1. Adição\n","2. Subtração\n","3. Multiplicação\n","4. Divisão\n","===================\n"," \n","Digite o número da operação desejada: 1\n","Digite o primeiro número: 1\n","Digite o segundo número: 1\n"," \n","###### Resultado ######\n","Resultado: 2.0\n"]}]},{"cell_type":"markdown","source":["### 2. Numpy"],"metadata":{"id":"FpvzYRmGtMfz"}},{"cell_type":"markdown","source":["NumPy (Numerical Python) é uma biblioteca fundamental em Python para computação numérica e científica. Ela fornece estruturas de dados eficientes para trabalhar com arrays multidimensionais e matrizes, além de funções matemáticas para operações numéricas de alta performance. NumPy é amplamente utilizado em áreas como análise de dados, aprendizado de máquina, visualização de dados e mais.\n","\n","**Principais Recursos e Vantagens do NumPy:**\n","\n","* Arrays Multidimensionais: O NumPy introduz o objeto ndarray, que é uma estrutura de dados eficiente para representar arrays multidimensionais. Isso permite que você realize operações numéricas em arrays de maneira eficiente.\n","\n","* Operações Numéricas Eficientes: NumPy oferece funções matemáticas e operadores para realizar operações elementares (adição, subtração, multiplicação, etc.) em arrays inteiros de maneira otimizada.\n","\n","* Broadcasting: NumPy permite que você realize operações entre arrays de diferentes formas e tamanhos, por meio do mecanismo de broadcasting, que automaticamente alinha as dimensões dos arrays.\n","\n","* Funções Matemáticas Avançadas: A biblioteca inclui funções para álgebra linear, transformada de Fourier, estatísticas, entre outras operações matemáticas complexas.\n","\n","* Integração com Outras Bibliotecas: NumPy é frequentemente usado como base para outras bibliotecas e bibliotecas de análise de dados, como Pandas, SciPy e Matplotlib.\n","\n","* Eficiência: As operações em NumPy são implementadas em C, o que garante alta eficiência computacional."],"metadata":{"id":"9hNLrbJTllgz"}},{"cell_type":"markdown","source":["Para importar a biblioteca, pode-se usar o seguinte código:"],"metadata":{"id":"9UjCIEbOvuMk"}},{"cell_type":"code","source":["import numpy as np"],"metadata":{"id":"GOERUpk5vxK8"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["É convencionado dar um \"apelido\" à certas bibliotecas utilizando o \"as\" depois do import. Abaixo estão as conveções das principais bibliotecas para análises de dados:"],"metadata":{"id":"d2ZmWlxcvz42"}},{"cell_type":"code","source":["import numpy as np\n","import pandas as pd\n","import matplotlib.pyplot as plt"],"metadata":{"id":"P1uAIBF_wrt4"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["Essas convenções são úteis para reduzir a digitação das funções dentro de cada uma dessas bibliotecas e são também amplamente reconhecidas por outros usuários."],"metadata":{"id":"maiaPuvBw1jA"}},{"cell_type":"markdown","source":["Para se ter uma noção da vantagem de se utilizar o Numpy, peguemos o exemplo de McKinney (2022, p. 85). Primeiro vamos gerar uma lista de um milhão de números:"],"metadata":{"id":"JIvUkuM1zwke"}},{"cell_type":"code","source":["array_milhao = np.arange(1_000_000)\n","lista_milhao = list(range(1_000_000))\n","\n"],"metadata":{"id":"UEBYU9n3z4N9","colab":{"base_uri":"https://localhost:8080/","height":211},"executionInfo":{"status":"error","timestamp":1692646349367,"user_tz":180,"elapsed":453,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"fa36005e-e026-4ac0-b7c1-30b8a1d882b6"},"execution_count":null,"outputs":[{"output_type":"error","ename":"NameError","evalue":"ignored","traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)","\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0marray_milhao\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1_000_000\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mlista_milhao\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1_000_000\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31mNameError\u001b[0m: name 'np' is not defined"]}]},{"cell_type":"markdown","source":["Multiplicando cada número da lista por 2 sem o numpy"],"metadata":{"id":"y56TWM3Z0QgX"}},{"cell_type":"code","source":["%%time\n","\n","my_list = []\n","\n","for i in lista_milhao:\n"," i = i * 2\n"," my_list.append(i)\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"8V1IbZ6e1mlK","executionInfo":{"status":"ok","timestamp":1692298330748,"user_tz":180,"elapsed":674,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"c48bc39c-7ce8-49ee-aaf0-5ec08671a037"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["CPU times: user 351 ms, sys: 31 ms, total: 382 ms\n","Wall time: 407 ms\n"]}]},{"cell_type":"markdown","source":["Sem o numpy, mas com list comprehension"],"metadata":{"id":"qx6AOT-R1kwC"}},{"cell_type":"code","source":["%%time\n","\n","my_list2 = [x* 2 for x in lista_milhao]"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"fQXMqP4h0PnT","executionInfo":{"status":"ok","timestamp":1692298333892,"user_tz":180,"elapsed":242,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"0328913d-ee41-434f-9ec2-ab24f99e066c"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["CPU times: user 57 ms, sys: 29.9 ms, total: 86.9 ms\n","Wall time: 92 ms\n"]}]},{"cell_type":"markdown","source":["Agora, utilizando o numpy:"],"metadata":{"id":"TT-JLEFq0ebn"}},{"cell_type":"code","source":["%%time\n","\n","array_milhao = array_milhao * 2"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"52Qx10UJ0f3k","executionInfo":{"status":"ok","timestamp":1692298335851,"user_tz":180,"elapsed":379,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"fb1c3b88-e2c1-496f-bedc-65f0f3e81a5b"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["CPU times: user 1.91 ms, sys: 0 ns, total: 1.91 ms\n","Wall time: 1.93 ms\n"]}]},{"cell_type":"markdown","source":["Percebe-se que é uma diferença considerável, e isso se torna cada vez mais importante conforme o tamanho do banco de dados que estamos trabalhando, se é texto ou não, e o nível de complexo do modelo de aprendizado de máquina, especialmente se ele for de *deep learning* com múltiplas camadas e epochs."],"metadata":{"id":"CNyLx3qL1IGT"}},{"cell_type":"markdown","source":["#### Criando um numpy array.\n","\n","existem várias maneiras de criar um array NumPy. Aqui estão algumas das principais formas de fazer isso:\n","\n","* 1 - Usando uma Lista Python:"],"metadata":{"id":"jC5uHVXd2NO3"}},{"cell_type":"code","source":["\n","lista = [1, 2, 3, 4, 5]\n","array = np.array(lista)\n","\n","print(array, type(array))"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"IMSMIxon3RVE","executionInfo":{"status":"ok","timestamp":1692298728475,"user_tz":180,"elapsed":262,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"48987bf2-fb06-416a-f83a-ac6cdfa02325"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[1 2 3 4 5] \n"]}]},{"cell_type":"markdown","source":["* 2 - Usando a Função numpy.array():"],"metadata":{"id":"mreG6S9O3e3L"}},{"cell_type":"code","source":["\n","array = np.array([1, 2, 3, 4, 5])\n","\n","print(array, type(array))"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"aGgpAQoB3gYT","executionInfo":{"status":"ok","timestamp":1692298784429,"user_tz":180,"elapsed":250,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"ce4689ba-d205-4794-db0b-8e5801bf049f"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[1 2 3 4 5] \n"]}]},{"cell_type":"markdown","source":["* 3 - Usando a Função numpy.arange(), como visto acima:"],"metadata":{"id":"diQk-yhh3m84"}},{"cell_type":"code","source":["array = np.arange(1, 11) # Cria um array com os números de 1 a 10\n","\n","print(array, type(array))"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"cIbkhKBM3qs5","executionInfo":{"status":"ok","timestamp":1692298826847,"user_tz":180,"elapsed":259,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"186fd6b2-405b-4723-9a67-e799688a5327"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[ 1 2 3 4 5 6 7 8 9 10] \n"]}]},{"cell_type":"markdown","source":["* 4 - Usando a Função numpy.linspace():"],"metadata":{"id":"h6qjfUXC3wYv"}},{"cell_type":"code","source":["array = np.linspace(0, 1, num=20) # Cria um array com 20 elementos igualmente espaçados entre 0 e 1\n","\n","print(array, type(array))"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"Q688Z-UB3xxl","executionInfo":{"status":"ok","timestamp":1692298878248,"user_tz":180,"elapsed":241,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"214ed030-4cb5-4bae-eb8e-146de8bc26f8"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[0. 0.05263158 0.10526316 0.15789474 0.21052632 0.26315789\n"," 0.31578947 0.36842105 0.42105263 0.47368421 0.52631579 0.57894737\n"," 0.63157895 0.68421053 0.73684211 0.78947368 0.84210526 0.89473684\n"," 0.94736842 1. ] \n"]}]},{"cell_type":"markdown","source":["* 5 - Usando a Função numpy.zeros():"],"metadata":{"id":"lfadhPj04Bnb"}},{"cell_type":"code","source":["array = np.zeros(45) # Cria um array com 45 elementos, todos iguais a 0\n","\n","print(array, type(array))"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"O0koyN--4D9B","executionInfo":{"status":"ok","timestamp":1692298935012,"user_tz":180,"elapsed":243,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"59ebd5a7-17ce-499f-bf11-e3ac0a67394d"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n"," 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] \n"]}]},{"cell_type":"markdown","source":["* 6 - Usando a Função numpy.ones():"],"metadata":{"id":"CcN84dvr4L3d"}},{"cell_type":"code","source":["array = np.ones(5) # Cria um array com 5 elementos, todos iguais a 1\n","\n","print(array, type(array))"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"hs7EogXM4OaM","executionInfo":{"status":"ok","timestamp":1692298971669,"user_tz":180,"elapsed":244,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"ab74ca13-8082-42d5-a721-6d9bad58fd35"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[1. 1. 1. 1. 1.] \n"]}]},{"cell_type":"markdown","source":["* 7 - Usando a Função numpy.eye():"],"metadata":{"id":"tB4Qb6yv5KYm"}},{"cell_type":"code","source":["array = np.eye(3) # Cria uma matriz identidade 3x3\n","\n","\n","print(array)\n","print(type(array), array.shape, array.dtype)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"8SNU9j095LiK","executionInfo":{"status":"ok","timestamp":1692299253921,"user_tz":180,"elapsed":307,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"8613cd31-3b14-417b-aa22-6f5959c882a2"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[[1. 0. 0.]\n"," [0. 1. 0.]\n"," [0. 0. 1.]]\n"," (3, 3) float64\n"]}]},{"cell_type":"markdown","source":["* 8 - Usando a Função numpy.random.rand()"],"metadata":{"id":"kBE2zP4F5qvb"}},{"cell_type":"code","source":["array = np.random.rand(5) # Cria um array com 5 números aleatórios entre 0 e 1\n","\n","print(array)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"zEcdipxE5reg","executionInfo":{"status":"ok","timestamp":1692299503618,"user_tz":180,"elapsed":249,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"c6694295-ea87-49a9-e617-022ee15d2db9"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[0.40700543 0.93275918 0.00383884 0.07621278 0.14420141]\n"]}]},{"cell_type":"markdown","source":["* 9 - Usando a Função numpy.random.randint()"],"metadata":{"id":"SVNj5-796VyD"}},{"cell_type":"code","source":["array = np.random.randint(1, 100, size=50) # Cria um array com 50 números inteiros aleatórios entre 1 e 99\n","\n","print(array)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"8wlYsNki6WEM","executionInfo":{"status":"ok","timestamp":1692299569638,"user_tz":180,"elapsed":260,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"1d1a9da7-b307-419a-917b-96bd8403172b"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[41 16 99 32 50 77 17 24 38 43 29 67 32 94 73 84 32 70 60 24 86 9 90 30\n"," 33 74 41 24 2 72 4 47 79 47 89 12 86 63 32 87 55 35 63 82 96 52 99 9\n"," 48 18]\n"]}]},{"cell_type":"markdown","source":["* 10 - Por fim, criando um Array Vazio:"],"metadata":{"id":"Oupg-XrM6kVp"}},{"cell_type":"code","source":["array = np.empty(5) # Cria um array vazio com 5 elementos (valores não inicializados)\n","\n","print(array)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"UehfCmA76oS8","executionInfo":{"status":"ok","timestamp":1692299607760,"user_tz":180,"elapsed":245,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"76bc139a-2a9f-4329-b07f-70b83aeb9487"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[3.5e-323 9.9e-324 4.0e-323 2.5e-323 4.4e-323]\n"]}]},{"cell_type":"markdown","source":["Essas são apenas algumas das maneiras de criar arrays NumPy. Dependendo da situação, você pode escolher a abordagem mais adequada às suas necessidades."],"metadata":{"id":"HhMdjsS36oqZ"}},{"cell_type":"markdown","source":["#### Tipos de dados e Numpy"],"metadata":{"id":"xp2iHrX-7Nkd"}},{"cell_type":"markdown","source":["NumPy oferece suporte a uma ampla variedade de tipos de dados que podem ser usados em arrays e matrizes multidimensionais. Os tipos de dados em NumPy são mais eficientes em termos de uso de memória e desempenho do que os tipos de dados padrão do Python. Além dos tipos numéricos como inteiros e ponto flutuante, NumPy inclui tipos complexos, booleanos e tipos especiais para lidar com datas e horas. Essa diversidade de tipos de dados permite a manipulação eficiente e precisa de dados em aplicações científicas, matemáticas e de análise de dados, garantindo que os cálculos sejam executados de maneira otimizada e precisa.\n","\n","De forma geral os principais tipos de dados ainda são os básicos do python: int, float, e string. Não é necessário se preocupar agora com os outros tipos apresentados na tabela 4-2 de Mckinney (2022, p.89), como o int8, int32, etc. Como dito pelo autor, isso só deve gerar preocupações \"when you need more control over how data is stored in memory and on disk, especially large datasets\"."],"metadata":{"id":"sjPffsC87PBB"}},{"cell_type":"markdown","source":["Para verificar o tipo de dado presente em um array, pode se utilizar o dtype:"],"metadata":{"id":"c_8SJucw75JE"}},{"cell_type":"code","source":["# Int\n","\n","array = np.array([1, 2, 3, 4, 5])\n","\n","print(array.dtype)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"8rQSjoS-8Qie","executionInfo":{"status":"ok","timestamp":1692300040423,"user_tz":180,"elapsed":294,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"723b398e-e38a-4285-8610-b64d5a80da75"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["int64\n"]}]},{"cell_type":"code","source":["# Float\n","\n","array = np.array([1.53213,7.4312423,6.412312,5.213123,2.3254325234])\n","\n","\n","print(array.dtype)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"kyy35zWk8YKJ","executionInfo":{"status":"ok","timestamp":1692300076729,"user_tz":180,"elapsed":2,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"2d133f7d-e175-48be-9715-6a8796faf033"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["float64\n"]}]},{"cell_type":"markdown","source":["Para converter um array de um tipo para outro, pode se usar o astype"],"metadata":{"id":"ShJrMG4l8ihL"}},{"cell_type":"code","source":["# Float para int\n","\n","array = np.array([1.53213,7.4312423,6.412312,5.213123,2.3254325234])\n","\n","array_int = array.astype(np.int64)\n","\n","print(array_int)\n","print(array_int.dtype)\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"lWUSdnxo8uqK","executionInfo":{"status":"ok","timestamp":1692300257257,"user_tz":180,"elapsed":240,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"04fe1a41-ae76-4011-85d7-591b693cca93"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[1 7 6 5 2]\n","int64\n"]}]},{"cell_type":"code","source":["# Int para float\n","\n","array = np.array([1, 2, 3, 4, 5])\n","\n","array_float = array.astype(np.float64)\n","\n","print(array_float)\n","print(array_float.dtype)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"cIUB-ajN9NNH","executionInfo":{"status":"ok","timestamp":1692300291046,"user_tz":180,"elapsed":381,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"a4f21834-16a3-4ff1-9d5c-3a4564309138"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[1. 2. 3. 4. 5.]\n","float64\n"]}]},{"cell_type":"code","source":["# str para float\n","\n","array = np.array(['5.0', '7.5', '8.5', '9.0'])\n","\n","array_float = array.astype(np.float64)\n","\n","print(array_float)\n","print(array_float.dtype)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"iuVhCUO39lOU","executionInfo":{"status":"ok","timestamp":1692300422263,"user_tz":180,"elapsed":242,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"f5cb9c1d-69c1-4407-bea8-73c8f2fa5fca"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[5. 7.5 8.5 9. ]\n","float64\n"]}]},{"cell_type":"markdown","source":["#### Operações Aritméticas com Arrays"],"metadata":{"id":"rOJa6HRm-Atd"}},{"cell_type":"markdown","source":["Operações aritméticas com arrays são uma parte essencial do NumPy, permitindo realizar cálculos elementares de forma eficiente em arrays multidimensionais. NumPy facilita a execução de operações entre arrays de diferentes formas e tamanhos, usando o conceito de broadcasting para alinhar automaticamente as dimensões dos arrays quando necessário. Aqui estão as principais operações aritméticas suportadas pelo NumPy:"],"metadata":{"id":"YxvvMXhr-DvU"}},{"cell_type":"markdown","source":["* 1 - Adição"],"metadata":{"id":"kbS-2Dlo-HqF"}},{"cell_type":"code","source":["array1 = np.array([1, 2, 3])\n","array2 = np.array([4, 5, 6])\n","resultado = array1 + array2\n","\n","print(resultado)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"SlZcmAZ3-C50","executionInfo":{"status":"ok","timestamp":1692300523800,"user_tz":180,"elapsed":277,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"9d83c6f4-5d2f-476c-a890-047d80e66ca8"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[5 7 9]\n"]}]},{"cell_type":"markdown","source":["Veja que o numpy facilita a operação, somando cada elemento do array1 com seu correspondente de índice no array 2."],"metadata":{"id":"NVd5rRCJ-gCA"}},{"cell_type":"markdown","source":["* 2 - Subtração:"],"metadata":{"id":"qTOinDbl-nUP"}},{"cell_type":"code","source":["resultado = array1 - array2\n","\n","print(resultado)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"xduyZ3R--pgi","executionInfo":{"status":"ok","timestamp":1692300657006,"user_tz":180,"elapsed":282,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"3c1cf47d-b0e7-4ebf-8b48-2a3c49793b7c"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[-3 -3 -3]\n"]}]},{"cell_type":"markdown","source":["* 3 - Multiplicação:\n","\n","Assim como em matrizes, pode se multiplicar um array por um escalar ou por outro array:"],"metadata":{"id":"Qpwct8Vk-yEL"}},{"cell_type":"code","source":["# Escalar\n","\n","resultado = array1 * 10\n","\n","print(resultado)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"ivEwXIn6-3Tq","executionInfo":{"status":"ok","timestamp":1692300720186,"user_tz":180,"elapsed":2,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"2fe0d477-c665-4d51-eb77-b485d2ba0adf"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[10 20 30]\n"]}]},{"cell_type":"code","source":["# Array com array\n","\n","resultado = array1 * array2\n","\n","print(resultado)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"oldIZCvZ-8kE","executionInfo":{"status":"ok","timestamp":1692300742410,"user_tz":180,"elapsed":2,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"b77e98d4-46e6-4518-8450-434931241394"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[ 4 10 18]\n"]}]},{"cell_type":"markdown","source":["Não se pode multiplicar arrays com dimensões diferentes"],"metadata":{"id":"9wWIdvos_C7w"}},{"cell_type":"code","source":["array3 = np.array([1,2])\n","\n","resultado = array1 * array3\n","\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":227},"id":"3VxYwQUO_G5E","executionInfo":{"status":"error","timestamp":1692300788532,"user_tz":180,"elapsed":379,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"a9b9161a-7c1c-47b6-8f3c-0820d906a457"},"execution_count":null,"outputs":[{"output_type":"error","ename":"ValueError","evalue":"ignored","traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)","\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0marray3\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mresultado\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0marray1\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0marray3\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31mValueError\u001b[0m: operands could not be broadcast together with shapes (3,) (2,) "]}]},{"cell_type":"markdown","source":["* 4 - Divisão\n","\n","Realiza divisão elemento a elemento ou divisão por um escalar."],"metadata":{"id":"V119fOJa_NDr"}},{"cell_type":"code","source":["resultado = array1 / array2\n","resultado_div_escalar = array1 / 2\n","\n","print(resultado)\n","print(resultado_div_escalar)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"Ut0yGO9Q_QqI","executionInfo":{"status":"ok","timestamp":1692300826664,"user_tz":180,"elapsed":248,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"896a3911-49bb-436b-c514-05c435f762d6"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[0.25 0.4 0.5 ]\n","[0.5 1. 1.5]\n"]}]},{"cell_type":"markdown","source":["Também não se pode dividir arrays com dimensões diferentes"],"metadata":{"id":"rGz0LDGj_WNG"}},{"cell_type":"code","source":["resultado = array1 / array3"],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":175},"id":"ZI4oiTlY_YgJ","executionInfo":{"status":"error","timestamp":1692300844841,"user_tz":180,"elapsed":245,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"a93d8d48-d59b-4c5f-a930-0930467230b4"},"execution_count":null,"outputs":[{"output_type":"error","ename":"ValueError","evalue":"ignored","traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)","\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mresultado\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0marray1\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0marray3\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m","\u001b[0;31mValueError\u001b[0m: operands could not be broadcast together with shapes (3,) (2,) "]}]},{"cell_type":"markdown","source":["* 5 - Potenciação:\n","\n","Eleva cada elemento do array à potência indicada."],"metadata":{"id":"_XB5Kezi_dKS"}},{"cell_type":"code","source":["resultado_potencia = array1 ** 2\n","\n","print(resultado_potencia)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"vD8Ak7AR_eyF","executionInfo":{"status":"ok","timestamp":1692300884633,"user_tz":180,"elapsed":240,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"155e8afc-085e-4308-fc04-6185aa038f7c"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[1 4 9]\n"]}]},{"cell_type":"markdown","source":["* 6 - Operações Matriciais"],"metadata":{"id":"nbwQkxCuBWl4"}},{"cell_type":"markdown","source":["NumPy também suporta operações matriciais, como multiplicação de matrizes e produtos internos, usando funções como np.dot() e o operador @."],"metadata":{"id":"Ajwv4nZTBZMv"}},{"cell_type":"code","source":["matriz1 = np.array([[1, 2], [3, 4]])\n","matriz2 = np.array([[5, 6], [7, 8]])\n","produto_matricial = np.dot(matriz1, matriz2)\n","\n","print(produto_matricial)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"4cvmFPGTBY16","executionInfo":{"status":"ok","timestamp":1692301389893,"user_tz":180,"elapsed":240,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"15a9f392-3b2c-4eee-cb34-83422a40986a"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[[19 22]\n"," [43 50]]\n"]}]},{"cell_type":"markdown","source":["#### Testes lógicos e operações booleanas\n"],"metadata":{"id":"FTgwwOFVBxlX"}},{"cell_type":"markdown","source":["O NumPy oferece várias funcionalidades para realizar testes lógicos e operações booleanas em arrays, permitindo filtrar dados com base em condições e realizar operações que dependem de valores booleanos. Isso é especialmente útil para análise de dados e tomada de decisões com base em critérios específicos. Aqui estão algumas das principais funcionalidades relacionadas a testes lógicos e booleanos em NumPy:"],"metadata":{"id":"0horCQjXCDEs"}},{"cell_type":"markdown","source":["* 1 - Operações lógicas elementares\n","\n","NumPy fornece operadores lógicos elementares, como >, <, >=, <=, ==, !=, para realizar comparações elemento a elemento entre arrays."],"metadata":{"id":"RBRw7_nNCFXg"}},{"cell_type":"code","source":["array = np.array([1, 2, 3, 4, 5])\n","maior_que_2 = array > 2\n","\n","print(maior_que_2)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"h5lDBfeUD__q","executionInfo":{"status":"ok","timestamp":1692302162992,"user_tz":180,"elapsed":339,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"1aaa4028-01ae-4832-93de-4cd563de5e84"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[False False True True True]\n"]}]},{"cell_type":"code","source":["igual_a_3 = array == 3\n","\n","print(igual_a_3)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"QurWiwbHEcg6","executionInfo":{"status":"ok","timestamp":1692302176743,"user_tz":180,"elapsed":256,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"9b7629d0-a050-42e9-f68b-fd1d33da5481"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[False False True False False]\n"]}]},{"cell_type":"markdown","source":["* 2 - Combinação de Condições"],"metadata":{"id":"MWF8MaL2EuYz"}},{"cell_type":"markdown","source":["Você pode usar operadores lógicos & (AND) e | (OR) para combinar condições booleanas em arrays."],"metadata":{"id":"M5FD11D3ExbC"}},{"cell_type":"code","source":["condicao1 = array > 2\n","condicao2 = array < 5\n","combinacao = condicao1 & condicao2\n","\n","print(combinacao)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"2k-sGfPFEwEz","executionInfo":{"status":"ok","timestamp":1692302268309,"user_tz":180,"elapsed":3,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"56a957b5-7257-4e1e-8c3b-ac8ae79d45bd"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[False False True True False]\n"]}]},{"cell_type":"markdown","source":["* 3 - Filtragem de Dados"],"metadata":{"id":"4FJ63dIYE_tN"}},{"cell_type":"markdown","source":["Usando arrays booleanos, você pode filtrar os elementos que atendem a determinadas condições."],"metadata":{"id":"VdfRTznyFBPz"}},{"cell_type":"code","source":["elementos_filtrados = array[combinacao]\n","\n","print(elementos_filtrados)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"QRIw_DpiFA2v","executionInfo":{"status":"ok","timestamp":1692302330967,"user_tz":180,"elapsed":343,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"3c3e498b-c57e-4ba7-9667-d56b4ee2aa05"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[3 4]\n"]}]},{"cell_type":"markdown","source":["* 4 - Funções de Agregação Booleanas"],"metadata":{"id":"Ciz61qZeFG0r"}},{"cell_type":"markdown","source":["NumPy oferece funções como np.all() e np.any() para verificar se todos os elementos de um array são True ou se pelo menos um elemento é True."],"metadata":{"id":"3fXoR7ECFJuN"}},{"cell_type":"code","source":["todos_maior_que_2 = np.all(array > 2)\n","algum_igual_a_3 = np.any(array == 3)\n","\n","print(todos_maior_que_2)\n","print(algum_igual_a_3)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"2gu6_XxBFIih","executionInfo":{"status":"ok","timestamp":1692302375197,"user_tz":180,"elapsed":246,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"3bd0145a-2279-4141-dabb-e89d324bc492"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["False\n","True\n"]}]},{"cell_type":"markdown","source":["#### Indexação e Fatiamento de arrays"],"metadata":{"id":"ths-iCCIHpF5"}},{"cell_type":"markdown","source":["A indexação e o fatiamento (slicing) de arrays são operações fundamentais em NumPy que permitem acessar elementos individuais ou subconjuntos de elementos em um array multidimensional. Isso é útil para recuperar informações específicas ou para manipular dados de maneira eficiente. Aqui está uma visão geral dessas operações:\n","\n","A indexação em NumPy é baseada em zero, o que significa que o primeiro elemento de um array tem índice 0, o segundo índice 1 e assim por diante. A indexação pode ser feita de forma direta para arrays unidimensionais ou usando tuplas para arrays multidimensionais."],"metadata":{"id":"ZJX7X5m8Hrig"}},{"cell_type":"code","source":["array = np.array([10, 20, 30, 40, 50])\n","\n","elemento = array[0] # Acessa o primeiro elemento (índice 0)\n","ultimo_elemento = array[-1] # Acessa o último elemento usando índice negativo\n","\n","print(elemento)\n","print(ultimo_elemento)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"t_EL4IiOHyBG","executionInfo":{"status":"ok","timestamp":1692303053310,"user_tz":180,"elapsed":254,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"2d57c92c-d475-44dc-d08f-ee8d430a418b"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["10\n","50\n"]}]},{"cell_type":"markdown","source":["O fatiamento permite selecionar subconjuntos de elementos de um array. Ele é realizado usando a notação [start:stop:step], onde start é o índice de início (incluído), stop é o índice de parada (excluído) e step é o intervalo entre elementos."],"metadata":{"id":"sstCb1HSH53N"}},{"cell_type":"code","source":["sub_array = array[1:4] # Seleciona elementos do índice 1 ao 3 (índice 4 é excluído)\n","passo2 = array[::2] # Seleciona elementos em intervalos de 2\n","\n","print(sub_array)\n","print(passo2)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"CgXJAb25H8bL","executionInfo":{"status":"ok","timestamp":1692303105626,"user_tz":180,"elapsed":259,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"c0c307f8-71f5-4b3a-c454-2be23128c24d"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[20 30 40]\n","[10 30 50]\n"]}]},{"cell_type":"markdown","source":["Para arrays multidimensionais, você pode usar indexação e fatiamento em cada dimensão separadamente, separados por vírgulas."],"metadata":{"id":"GLy7srK4ID_3"}},{"cell_type":"code","source":["matriz = np.array([[1, 2, 3],\n"," [4, 5, 6],\n"," [7, 8, 9]])\n","\n","primeira_linha = matriz[0] # Acessa a primeira linha\n","\n","segunda_coluna = matriz[:, 1] # Acessa a segunda coluna\n","submatriz = matriz[1:3, 0:2] # Seleciona uma submatriz\n","\n","print(primeira_linha)\n","print('==============')\n","print(segunda_coluna)\n","print('==============')\n","print(submatriz)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"XTlgk1fvIFFC","executionInfo":{"status":"ok","timestamp":1692303199138,"user_tz":180,"elapsed":239,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"d83a9b1e-a5f6-4706-db4a-d18b93d01a29"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[1 2 3]\n","==============\n","[2 5 8]\n","==============\n","[[4 5]\n"," [7 8]]\n"]}]},{"cell_type":"markdown","source":["A figura 4-1 de Mckinney (2022) permite entender melhor a indexação de arrays."],"metadata":{"id":"YVvtwYmKIpRb"}},{"cell_type":"markdown","source":["![image.png](data:image/png;base64,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)"],"metadata":{"id":"WFGlf-obIdby"}},{"cell_type":"markdown","source":["### Exercícios"],"metadata":{"id":"pB76DHQgnI5g"}},{"cell_type":"markdown","source":["Antes de ir aos exercícios, explore a documentação própria do Numpy ([Link](https://numpy.org/doc/stable/reference/routines.html))"],"metadata":{"id":"np3urlXCTVgw"}},{"cell_type":"markdown","source":["1 - Crie um array NumPy que contenha os primeiros 10 números pares. Imprima o array"],"metadata":{"id":"leaLDwwHp1lA"}},{"cell_type":"code","source":["numeros_pares = np.arange(0, 20, 2)\n","print(numeros_pares)"],"metadata":{"id":"zRAbyoOmp1T8"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["2 - Crie uma matriz identidade 4x4 usando NumPy. Imprima o array"],"metadata":{"id":"n8RrP0ZVp16G"}},{"cell_type":"code","source":["matriz_identidade = np.eye(4)\n","print(matriz_identidade)"],"metadata":{"id":"Z8IT-c9jp2T3"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["3 - Utilizando um for loop, multiplique os valores da primeira lista pela segunda lista. Imprima o resultado final. Dica: Você pode precisar da função range() e len() vistas na aula anterior."],"metadata":{"id":"E7ZLVfdZrKyj"}},{"cell_type":"code","source":["lista1 = [7,6,1,2,54,25]\n","lista2 = [1,2,3,4,5,6]\n","\n","resultado = []\n","\n","for x in range(0, len(lista1)):\n"," valor = lista1[x] * lista2[x]\n"," resultado.append(valor)\n","\n","\n","print(resultado)\n","\n"],"metadata":{"id":"FJegLxCbp2qc","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1692303965630,"user_tz":180,"elapsed":252,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"b175e10a-a45c-4f90-dc2f-7ee44ed33274"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[7, 12, 3, 8, 270, 150]\n"]}]},{"cell_type":"markdown","source":["4 - Transforme as listas 1 e 2 em arrays e multiplique seus valores"],"metadata":{"id":"fIqHOXYMtEP9"}},{"cell_type":"code","source":["print(np.array(lista1) * np.array(lista2))\n","\n"],"metadata":{"id":"F_SABdJEp2hC","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1692304048282,"user_tz":180,"elapsed":257,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"932d5fec-05e1-411a-c8a2-b902d0e67eb6"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[ 7 12 3 8 270 150]\n"]}]},{"cell_type":"markdown","source":["5 - Pegue apenas os valores pares da seguinte lista utilizando um for loop"],"metadata":{"id":"ptnGI1LCtKTM"}},{"cell_type":"code","source":["\n","lista = list(range(0,100))\n","\n","pares = []\n","\n","for i in lista:\n"," if i % 2 == 0:\n"," pares.append(i)\n"," else:\n"," pass\n","\n","print(pares)\n","\n"],"metadata":{"id":"4lwY3XEtp3DI","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1692646604755,"user_tz":180,"elapsed":315,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"5777ff04-5667-4c9f-b99c-666f7edf9274"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]\n"]}]},{"cell_type":"markdown","source":["6 - Transforme a lista do exercício 5 em um array e também só pegue os números pares."],"metadata":{"id":"PlCYl4Y3MkJf"}},{"cell_type":"code","source":["array = np.array(lista)\n","\n","pares = array[array % 2 == 0]\n","\n","print(pares)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"u1EjEbjwMqdb","executionInfo":{"status":"ok","timestamp":1692304364442,"user_tz":180,"elapsed":2,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"5bbac795-8524-44a5-9960-d0e3537e7723"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[ 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46\n"," 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94\n"," 96 98]\n"]}]},{"cell_type":"markdown","source":["7 - Abaixo estão duas listas: uma com o nome de candidatos (inventados) e outra com valores *dummy* (ou binários) que informam se o candidato possui ou não twitter. Usando numpy arrays, filtre os candidatos que *possuem* twitter."],"metadata":{"id":"xlHdQzLnM7tL"}},{"cell_type":"code","source":["import random\n","\n","nomes = [\"Alice\", \"Bob\", \"Carlos\", \"David\", \"Emily\", \"Fernanda\", \"Gabriel\", \"Hannah\", \"Isaac\", \"Julia\",\n"," \"Kevin\", \"Larissa\", \"Mateus\", \"Natalia\", \"Oliver\", \"Paula\", \"Quincy\", \"Renata\", \"Samuel\", \"Tatiana\"]\n","\n","twitter = [random.choice([0, 1]) for _ in range(20)]\n","\n","\n","nomes_array = np.array(nomes)\n","twitter_array = np.array(twitter)\n","\n","\n","candidatos_twitter = nomes_array[twitter_array == 1]\n","\n","print(candidatos_twitter)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"xRinnIJENSzr","executionInfo":{"status":"ok","timestamp":1692304871416,"user_tz":180,"elapsed":268,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"5dd7e5fd-4ff7-48f2-e841-81d5df553445"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["['Bob' 'Emily' 'Fernanda' 'Gabriel' 'Kevin' 'Larissa' 'Natalia' 'Paula'\n"," 'Samuel' 'Tatiana']\n"]}]},{"cell_type":"markdown","source":["8 - Escreva um programa NumPy para criar uma matriz 5x5 com valores aleatórios e calcule o exponencial de cada elemento. [Dica](https://numpy.org/doc/stable/reference/routines.math.html#mathematical-functions)"],"metadata":{"id":"E9pYhIcHQhOJ"}},{"cell_type":"code","source":["nums = np.random.rand(5, 5)\n","print(\"Array original:\")\n","print(nums)\n","exp_arr = np.exp(nums)\n","print(\"Exponencial do Array:\")\n","print(exp_arr)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"vMFWbiqnQicD","executionInfo":{"status":"ok","timestamp":1692305640530,"user_tz":180,"elapsed":922,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"68494ee1-5e8b-4601-a89d-02f014f13a3b"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Array original:\n","[[0.43599782 0.69890041 0.83101454 0.9320552 0.24958755]\n"," [0.00395804 0.43723751 0.84946878 0.40464531 0.24594518]\n"," [0.46150315 0.04044142 0.27562886 0.10907478 0.39639848]\n"," [0.63925224 0.6660276 0.72738481 0.45879473 0.3891829 ]\n"," [0.0180678 0.71424388 0.05872258 0.14679153 0.75860369]]\n","Exponencial do Array:\n","[[1.54650543 2.01153962 2.29564658 2.53972345 1.28349592]\n"," [1.00396588 1.54842379 2.33840432 1.49877081 1.27882947]\n"," [1.58645688 1.04127031 1.31735885 1.11524574 1.48646152]\n"," [1.8950633 1.9464897 2.06966097 1.58216589 1.47577444]\n"," [1.01823201 2.04264161 1.060481 1.15811251 2.13529261]]\n"]}]},{"cell_type":"markdown","source":["9 - Crie uma matriz (array) 3x2 e outra 2x3, sem utilizar o random, e multiplique-as. Dica: Não dá para usar o operador \"*\""],"metadata":{"id":"oM4jlef0Rt4q"}},{"cell_type":"code","source":["matriz1 = np.array([[1, 2],\n"," [3, 4],\n"," [5, 6]])\n","\n","matriz2 = np.array([[1,2,3],\n"," [3,2,1]])\n","\n","print(np.matmul(matriz1,matriz2))"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"9S5Qoz3kR6gK","executionInfo":{"status":"ok","timestamp":1692305938812,"user_tz":180,"elapsed":263,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"669f857f-f1ec-497a-d3d8-8a963034d1d3"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[[ 7 6 5]\n"," [15 14 13]\n"," [23 22 21]]\n"]}]},{"cell_type":"markdown","source":["10 - Transponha a matriz2 e refaça a operação"],"metadata":{"id":"McY-qLTdTJ-V"}},{"cell_type":"code","source":["matriz2_T = np.transpose(matriz2)\n","\n","print(matriz2_T)\n","\n","print(\"Resultado: \")\n","print(matriz1 * matriz2_T)\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"GvDigZ_tTNR9","executionInfo":{"status":"ok","timestamp":1692306215282,"user_tz":180,"elapsed":2,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"d345ad2d-d4f7-4344-8e7a-e9e1444edf45"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[[1 3]\n"," [2 2]\n"," [3 1]]\n","Resultado: \n","[[ 1 6]\n"," [ 6 8]\n"," [15 6]]\n"]}]},{"cell_type":"markdown","source":["11 - Imprima o número 50 do seguinte array"],"metadata":{"id":"KY4glxO8Ua8P"}},{"cell_type":"code","source":["arr = np.array([[10, 20, 30, 40], [50, 60, 70, 80]])\n","\n","print(arr[1, 0])"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"mjMI7vx0Uc3I","executionInfo":{"status":"ok","timestamp":1692306375464,"user_tz":180,"elapsed":230,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"e456e19a-f9de-4857-a330-4c00f6661c5e"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["50\n"]}]},{"cell_type":"markdown","source":["12 - Crie uma matriz 3x3 de números e acesse o elemento da segunda linha e terceira coluna."],"metadata":{"id":"K2p5687bU32n"}},{"cell_type":"code","source":["matriz = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n","elemento = matriz[1, 2]\n","print(elemento)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"b6C07nkoU5K0","executionInfo":{"status":"ok","timestamp":1692306479725,"user_tz":180,"elapsed":256,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"777f0628-f759-41df-d225-d6095475bfb5"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["6\n"]}]},{"cell_type":"markdown","source":["13 - Crie uma matriz 4x4 de números e use fatiamento para obter uma submatriz 2x2 da parte superior esquerda."],"metadata":{"id":"XgIcm4deVecc"}},{"cell_type":"code","source":["matriz = np.array([[1, 2, 3, 4],\n"," [5, 6, 7, 8],\n"," [9, 10, 11, 12],\n"," [13, 14, 15, 16]])\n","\n","submatriz = matriz[:2, :2]\n","print(submatriz)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"m4sHEx-FVhU1","executionInfo":{"status":"ok","timestamp":1692309801879,"user_tz":180,"elapsed":259,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"0c6dd83a-3cb7-48d8-cb1d-6ea249f5714d"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["[[1 2]\n"," [5 6]]\n"]}]},{"cell_type":"markdown","source":["14 - Crie uma função que recebe um array de strings que contém os usuários de twitter de deputados, remova o prefixo \"@\" e deixe tudo minúsculo. Depois, a aplique na lista_twitters. [Dica](https://numpy.org/doc/stable/reference/routines.char.html)"],"metadata":{"id":"oOD-V93QjVTE"}},{"cell_type":"code","source":["\n","\n","# Lista de nomes de usuário no twitter\n","lista_twitters = nomes_com_arroba = [\"@Ana\", \"@Pedro\", \"@Isabel\", \"@João\",\n"," \"@Mariana\", \"@Rafael\", \"@Beatriz\", \"@Lucas\",\n"," \"@Carolina\", \"@Gustavo\", \"@Lívia\", \"@André\",\n"," \"@Júlia\", \"@Matheus\", \"@Laura\", \"@Gabriel\",\n"," \"@Amanda\", \"@Daniel\", \"@Clara\", \"@Felipe\"]\n","\n","array_twitters = lista_twitters\n","\n","def limpa_twitters(array):\n","\n"," array = np.char.replace(array, '@', '')\n"," array = np.char.lower(array)\n"," return array\n","\n","\n","\n","resultado = limpa_twitters(array_twitters)\n","\n","print(resultado)\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"WxXw3wI6jZXs","executionInfo":{"status":"ok","timestamp":1692310713206,"user_tz":180,"elapsed":3,"user":{"displayName":"Pedro Henrique de Santana Schmalz","userId":"15443225301388878262"}},"outputId":"34b78253-21ac-42db-9139-1749b9b3ec45"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["['ana' 'pedro' 'isabel' 'joão' 'mariana' 'rafael' 'beatriz' 'lucas'\n"," 'carolina' 'gustavo' 'lívia' 'andré' 'júlia' 'matheus' 'laura' 'gabriel'\n"," 'amanda' 'daniel' 'clara' 'felipe']\n"]}]},{"cell_type":"markdown","source":["## Desafio - Aprimore suas Técnicas de Seleção"],"metadata":{"id":"_r3WbMPaRuXt"}},{"cell_type":"markdown","source":["

Agora que você já colocou em prática sua criatividade e está familiarizado com as etapas de seleção do corpus utilizado na pesquisa que orienta a nossa disciplina, vamos aprimorar o código desenvolvido no desafio do Tutorial 02 e avançar na discussão acerca das dificuldades inerentes a construção de um corpus de uma pesquisa em PLN."],"metadata":{"id":"poYWOkuF7s9I"}},{"cell_type":"markdown","source":["#### Recapitulando"],"metadata":{"id":"Eg9BxC2d7uJC"}},{"cell_type":"markdown","source":["

No desafio anterior, solicitamos que você construísse uma estrutura de classificação destinada a determinar quais tweets seriam incluídos ou excluídos do corpus da pesquisa. Isso deveria ser feito com base nas informações fornecidas pelo Vaccine Codebook of Political Elites 2023. O objetivo principal era que você identificasse com precisão as várias etapas do processo de seleção dos tweets destinados a compor o corpus, começando pela análise da lista de candidatos à prefeito nas capitais brasileiras e seguindo até a escolha dos tweets que, conforme os critérios definidos no documento, seriam submetidos à codificação humana.\n","\n","

Tratava-se de um exercício fundamentalmente criativo, o que lhe conferia uma dose de liberdade para agir. Desde que o seu código conseguisse diferenciar de forma nítida quais candidatos ou tweets seriam descartados ou aceitos a cada etapa do processo, não havia margem para erro. Era viável presumir a existência de uma base de dados consolidada contendo essas informações. Você também tinha a liberdade para criar uma base de dados fictícia para trabalhar e até mesmo supor a existência de variáveis que, pelo menos na atual conjuntura, não são levadas em consideração pelos órgãos que divulgam essas informações, como o TSE e até mesmo o próprio Twitter.\n","\n","\n","

Poréeeem, como tudo o que é bom tem seu fim, chegou a hora de trazer um pouco de realidade para a equação."],"metadata":{"id":"YXPky1dy762z"}},{"cell_type":"markdown","source":["#### Uma Dose de Realidade"],"metadata":{"id":"9gip9Y7n8Afo"}},{"cell_type":"markdown","source":["

Não pretendo te desanimar, contudo, acredito que seja essencial trazer à discussão um ponto relevante. Essa base de dados excepcional, contendo todas as informações necessárias, simplesmente NÃO existe e é improvável que venha a existir. Sempre haverá a necessidade de realizar ajustes, organizar ou fazer modificações mínimas. Mesmo quando parece estar em condições ideais (o que RARAMENTE ocorre), ainda assim, será necessário investir tempo para adaptar os dados às exigências tanto suas quanto da pesquisa em si.\n","\n","

No contexto de nossa pesquisa, precisamos recorrer a três fontes de informação distintas: o TSE, o Google e o Twitter. Permita-me explicar.\n","\n","

Recorremos ao TSE, por razões óbvias, para cruzar as informações demográficas dos candidatos à prefeito com os votos que obtiveram em seus respectivos distritos eleitorais. Uma vez concluído esse processo, selecionamos apenas aqueles cujas candidaturas foram aprovadas pelo TSE e que competiram em uma das capitais. Somente então prosseguimos para identificar aqueles que possuíam uma conta no Twitter. Sim, essa informação não está disponível nas bases de dados do TSE. Pelo menos não de forma consistente. Observem que somente recentemente essa informação passou a ser coletada e divulgada pelos diretórios partidários. Além disso, não é obrigatório que os candidatos tenham e façam uso das redes sociais nas campanhas eleitorais, o que torna esse dado pouco confiável e de difícil utilização, pelo menos no momento atual.\n","\n","

Em razão disso, tornou-se necessário investigar individualmente os 300 candidatos cujas candidaturas foram aprovadas, utilizando o Google para verificar se possuíam contas no Twitter ou não. Após a conclusão desse processo e com os perfis de usuário dos candidatos em nossa posse, avançamos para a coleta de todos os tweets publicados em 2020 pelos candidatos à prefeito que possuíam contas ativas na plataforma Twitter.\n","\n","

Uma vez concluída essa etapa, procedemos então à filtragem dos 231.770 tweets coletados, selecionando exclusivamente aqueles que faziam menção a um ou mais dos termos e palavras-chave previamente estabelecidos por nossa equipe.\n","\n","

Ufa, acabou! Finalmente temos um corpus pronto para ser utilizado."],"metadata":{"id":"AuQdlq1S8E5U"}},{"cell_type":"markdown","source":["#### A Tarefa"],"metadata":{"id":"RGctPXNq8XeK"}},{"cell_type":"markdown","source":["

Com base no conteúdo abordado nas seções anteriores, especialmente na consideração dos desafios envolvidos na construção de um corpus robusto e coerente, e aproveitando os conhecimentos em Python que você acumulou até agora, chegou o momento de elevar a qualidade e aplicabilidade do seu classificador.\n","\n","

Dessa vez, iremos avaliar a eficácia do seu código em dados reais. Para isso, selecione 10 candidatos da amostra fornecida no Vaccine Codebook of Political Elites 2023. Assegure-se de escolher candidatos provenientes de diferentes capitais, e garanta que nem todos possuam uma conta no Twitter. Após essa seleção, crie mais 10 candidatos entre prefeitos e vereadores, de cidades que não foram abordadas na pesquisa. Podem ser candidatos reais ou fictícios, você escolhe.\n","\n","

Por último, examine a relação de termos e palavras-chave estabelecida pela equipe e associe \"tweets\" aos candidatos que possuem perfil no Twitter, levando em consideração a presença ou ausência desses termos. Dado que ainda não abordamos o uso de data frames, vamos proceder como se estivéssemos analisando apenas os tweets do dia 27/09/2020, data a partir da qual foi permitida a propaganda eleitoral nas eleições daquele ano.\n","\n","

Com base nessas diretrizes, você deverá criar nove listas, seguindo a estrutura abaixo, e então consolidá-las em um dicionário utilizando a função que você desenvolveu no exercício 05.\n","\n","nome_candidato = ['Joana', 'José']
\n","sigla_partido =['PT', 'PSDB']\n","sigla_uf = ['AC', 'SP']
\n","nome_municipio = ['Rio Branco', 'São Paulo']
\n","cargo = ['Prefeito', 'Vereador']
\n","situacao_candidatura = ['Deferido', 'Indeferido']
\n","conta_twitter = [1, 1]
\n","publicou_2020 = [1, 1]
\n","tweet_27092020 = ['blablavacinablabla', 'blablablabla']
\n","\n","

Com o dicionário pronto, elabore uma função para o classificador concebido no Tutorial 02 e empregue o dicionário a fim de verificar sua eficácia. Essa função deve incorporar ao dicionário criado uma lista de dummies denominada 'termo_vacina', indicando se o tweet incluía ou não um dos termos designados pela equipe. Ao final, a função deve imprimir apenas as informações dos candidatos escolhidos para integrar o corpus. Não se esqueça de ordenar a lista de candidatos.\n","\n","[**Link do Codebook**](https://github.com/PedroSchmalz/covid19-tweets-brazilian-mayoral-candidates/blob/main/Codebook.pdf)"],"metadata":{"id":"WDo6E7B88ZUk"}},{"cell_type":"code","source":["### INFORMAÇÕES DOS CANDIDATOS\n","\n","## Nome dos candidatos\n","\n","nome_candidato = ['Joana', 'José']\n","\n","## Sigla do partido\n","\n","sigla_partido =['PT', 'PSDB']\n","\n","## UF\n","\n","sigla_uf = ['AC', 'SP']\n","\n","## Distrito eleitoral\n","\n","nome_municipio = ['Rio Branco', 'São Paulo']\n","\n","## Cargo\n","\n","cargo = ['Prefeito', 'Vereador']\n","\n","## Situação da candidatura\n","\n","situacao_candidatura = ['Deferido', 'Indeferido']\n","\n","## Dummy que indica se o candidato possui conta no Twitter\n","\n","conta_twitter = [1, 1]\n","\n","## Dummy que indica se o candidato publicou no Twitter em 2020\n","\n","publicou_2020 = [1, 1]\n","\n","## Tweets publicados no dia 27/09/2020\n","\n","tweet_27092020 = list(map(lambda x: x.lower(), ['blablaVacinablabla', 'blablablablaOI']))\n","\n","## Lista vazia onde a informação se o tweet integrará o corpus será salva\n","\n","termo_vacina = [\"NA\", \"NA\"]\n","\n","## Total de candidatos\n","\n","tot_candidatos = len(nome_candidato)\n","\n","candidatos = nome_candidato\n","\n","### DICIONÁRIO\n","\n","## Cria uma lista vazia onde o dicionário será armazenado\n","\n","dicionario = {}\n","\n","## Adicionando as informações criadas em um dicionário\n","\n","for nome_candidato, sigla_partido, sigla_uf, nome_municipio, cargo, situacao_candidatura, conta_twitter, publicou_2020, tweet_27092020, termo_vacina in zip(nome_candidato, sigla_partido, sigla_uf, nome_municipio, cargo, situacao_candidatura, conta_twitter, publicou_2020, tweet_27092020, termo_vacina):\n"," dicionario[nome_candidato] = {\"sigla_partido\": sigla_partido, \"sigla_uf\": sigla_uf, \"nome_municipio\": nome_municipio, \"cargo\": cargo, \"situacao_candidatura\": situacao_candidatura, \"conta_twitter\": conta_twitter, \"publicou_2020\": publicou_2020, \"tweet_27092020\": tweet_27092020, \"termo_vacina\": termo_vacina}\n","\n","## Imprimindo o dicionário atual\n","\n","for nome_candidato, info in dicionario.items():\n"," print(f\"Nome do candidato: {nome_candidato}, Sigla do partido: {info['sigla_partido']}, UF: {info['sigla_uf']}, Município: {info['nome_municipio']}, Cargo: {info['cargo']}, Situação da candidatura: {info['situacao_candidatura']}, Twitter: {info['conta_twitter']}, Publicou em 2020: {info['publicou_2020']}, Tweet: {info['tweet_27092020']}, Corpus: {info['termo_vacina']}\")\n","\n"],"metadata":{"id":"4ZMOX3vm8dYr","executionInfo":{"status":"ok","timestamp":1693342136275,"user_tz":180,"elapsed":356,"user":{"displayName":"Rebeca Carvalho","userId":"01975075342439777451"}}},"execution_count":82,"outputs":[]},{"cell_type":"code","source":["## Lista das capitais brasileiras\n","\n","capitais_brasileiras = [\n"," \"Rio Branco\", \"Maceió\", \"Macapá\", \"Manaus\", \"Salvador\",\n"," \"Fortaleza\", \"Brasília\", \"Vitória\", \"Goiânia\", \"São Luís\",\n"," \"Cuiabá\", \"Campo Grande\", \"Belo Horizonte\", \"Belém\",\n"," \"João Pessoa\", \"Curitiba\", \"Recife\", \"Teresina\", \"Rio de Janeiro\",\n"," \"Natal\", \"Porto Alegre\", \"Porto Velho\", \"Boa Vista\", \"Florianópolis\",\n"," \"São Paulo\", \"Aracaju\", \"Palmas\"]\n","\n","## Lista dos termos de interesse\n","\n","termos = list(map(lambda x: x.lower(), [\"vacina\", \"Vacinacao\", \"Butantan\"]))\n","\n","## Estrutura de classificação que avalia quais\n","## candidatos e tweets participarão do corpus\n","\n","for candidato in range(0, tot_candidatos):\n","\n"," print(\"\\n\\nLendo\", candidatos[candidato], \"(\", dicionario[candidatos[candidato]][\"sigla_partido\"],\n"," \"-\", dicionario[candidatos[candidato]][\"nome_municipio\"], \")\", \"\\n\")\n","\n"," ## Verifica se o candidato concorreu à prefeito em uma das capitais brasileiras\n","\n"," if dicionario[candidatos[candidato]][\"cargo\"] == \"Prefeito\" and dicionario[candidatos[candidato]][\"nome_municipio\"] in capitais_brasileiras:\n","\n"," print(\"\\nO candidato\", candidatos[candidato], \"concorreu à prefeitura do município de\", dicionario[candidatos[candidato]][\"nome_municipio\"],\n"," \"-\", dicionario[candidatos[candidato]][\"sigla_uf\"], end =\".\")\n","\n"," ## Avalia se a candidatura foi deferida pelo TSE\n","\n"," if dicionario[candidatos[candidato]][\"situacao_candidatura\"] == \"Deferido\":\n","\n"," print('\\n\\nO candidato', candidatos[candidato], '(', dicionario[candidatos[candidato]][\"sigla_partido\"], '-',\n"," dicionario[candidatos[candidato]][\"nome_municipio\"], ') foi deferido pelo TSE.')\n","\n"," ## Avalia se o candidato possui conta no Twitter\n","\n"," if dicionario[candidatos[candidato]][\"conta_twitter\"] == 1:\n","\n"," print(\"\\nO candidato\", candidatos[candidato], '(', dicionario[candidatos[candidato]][\"sigla_partido\"], '-',\n"," dicionario[candidatos[candidato]][\"nome_municipio\"], \") possui conta no Twitter.\")\n","\n"," ## Avalia se o candidato publicou no Twitter entre 01/01/2020 e 31/12/2020\n","\n"," if dicionario[candidatos[candidato]][\"publicou_2020\"] == 1:\n","\n"," print(\"\\nO candidato\", candidatos[candidato], '(', dicionario[candidatos[candidato]][\"sigla_partido\"], '-',\n"," dicionario[candidatos[candidato]][\"nome_municipio\"], \") publicou no Twitter em 2020.\")\n","\n"," ## Cria uma string com NA que é atualizada assim que um termo relacionado à vacina é encontrado no tweet\n","\n"," relacionado_vacina = \"NA\"\n","\n"," ## Cria um contador\n","\n"," contador = 0\n","\n"," ## Verifica se o tweet possui um dos termos especificados\n","\n"," while contador < len(termos) or relacionado_vacina == \"NA\":\n","\n"," if termos[contador] in dicionario[candidatos[candidato]][\"tweet_27092020\"]:\n","\n"," relacionado_vacina = 1\n","\n"," contador = contador + 1\n","\n"," if relacionado_vacina == 1:\n","\n"," ## Alterando os valores da variável 'termo_vacina'\n","\n"," dicionario[candidatos[candidato]][\"termo_vacina\"] = 1\n","\n"," print(\"\\nO tweet do candidato\", candidatos[candidato], '(', dicionario[candidatos[candidato]][\"sigla_partido\"], '-',\n"," dicionario[candidatos[candidato]][\"nome_municipio\"], \") será incluído no corpus de análise.\")\n","\n"," else:\n","\n"," ## Alterando os valores da variável 'termo_vacina'\n","\n"," dicionario[candidatos[candidato]][\"termo_vacina\"] = 0\n","\n"," print(\"\\nO tweet do candidato\", candidatos[candidato], '(', dicionario[candidatos[candidato]][\"sigla_partido\"], '-',\n"," dicionario[candidatos[candidato]][\"nome_municipio\"], \") não será incluído no corpus de análise.\")\n","\n"," else:\n","\n"," print(\"\\nO candidato\", candidatos[candidato], '(', dicionario[candidatos[candidato]][\"sigla_partido\"], '-',\n"," dicionario[candidatos[candidato]][\"nome_municipio\"], \") não publicou no Twitter em 2020.\")\n","\n"," else:\n","\n"," print(\"\\nO candidato\", candidatos[candidato], '(', dicionario[candidatos[candidato]][\"sigla_partido\"], '-',\n"," dicionario[candidatos[candidato]][\"nome_municipio\"], \") não possui conta no Twitter.\")\n","\n"," else:\n","\n"," print('\\nO candidato', candidatos[candidato], '(', dicionario[candidatos[candidato]][\"sigla_partido\"],\n"," '-', dicionario[candidatos[candidato]][\"nome_municipio\"], ') não foi deferido pelo TSE')\n","\n"," else:\n","\n"," print(\"\\nO candidato\", candidatos[candidato], \"não foi candidato à prefeito ou não concorreu em uma das capitais brasileiras.\\n\\n\")\n"],"metadata":{"id":"DgWWUdm-oq8t"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["## Imprimindo as informações dos candidatos que integrarão o corpus\n","\n","for candidato in range(0, tot_candidatos):\n","\n"," if dicionario[candidatos[candidato]][\"termo_vacina\"] == 1:\n","\n"," print(\"Nome do candidato:\", candidatos[candidato], \"\\nSigla do partido:\", dicionario[candidatos[candidato]][\"sigla_partido\"],\n"," \"\\nUF:\", dicionario[candidatos[candidato]][\"sigla_uf\"], \"\\nMunicípio:\", dicionario[candidatos[candidato]][\"nome_municipio\"],\n"," \"\\nCargo:\", dicionario[candidatos[candidato]][\"cargo\"], \"\\nSituação da candidatura:\", dicionario[candidatos[candidato]]['situacao_candidatura'],\n"," \"\\nTwitter:\", dicionario[candidatos[candidato]]['conta_twitter'], \"\\nPublicou em 2020:\", dicionario[candidatos[candidato]]['publicou_2020'],\n"," \"\\nTweet:\", dicionario[candidatos[candidato]][\"tweet_27092020\"], \"\\nCorpus:\", dicionario[candidatos[candidato]]['termo_vacina'])\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"ffl32LDKE7FV","executionInfo":{"status":"ok","timestamp":1693343966022,"user_tz":180,"elapsed":342,"user":{"displayName":"Rebeca Carvalho","userId":"01975075342439777451"}},"outputId":"e2a7383a-e70b-4a38-a5c2-c18ae2be3590"},"execution_count":107,"outputs":[{"output_type":"stream","name":"stdout","text":["Nome do candidato: Joana \n","Sigla do partido: PT \n","UF: AC \n","Município: Rio Branco \n","Cargo: Prefeito \n","Situação da candidatura: Deferido \n","Twitter: 1 \n","Publicou em 2020: 1 \n","Tweet: blablavacinablabla \n","Corpus: 1\n"]}]}]}