├── lista3 ├── test_len.py ├── test_sorted.py └── lista3.md ├── lista2 ├── respostas.py ├── modulo.py └── lista2.md ├── lista1 └── lista1.md ├── atividade_relacoes_gabarito ├── funcionarios.py ├── instrumentos.py └── lojas.py ├── atividade_relacoes.md └── aula_series.ipynb /lista3/test_len.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lista3/test_sorted.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lista2/respostas.py: -------------------------------------------------------------------------------- 1 | def exercicio1(vetor: tuple) -> int: 2 | pass #Sua resposta aqui 3 | 4 | 5 | def exercicio2(ponto_1: tuple, ponto_2: tuple) -> tuple: 6 | pass #Sua resposta aqui 7 | -------------------------------------------------------------------------------- /lista2/modulo.py: -------------------------------------------------------------------------------- 1 | """Módulo desenvolvido para cuidar da leitura de arquivos JSON.""" 2 | 3 | import json 4 | 5 | def carrega_conteudos_json(arquivo: str) -> dict: 6 | """ 7 | Carrega o conteúdo de um arquivo `json` e retorna na forma de um dicionário 8 | Python. 9 | 10 | Parameters 11 | ---------- 12 | arquivo: 13 | Uma string contendo o nome do arquivo. 14 | 15 | Returns 16 | ------- 17 | dict: 18 | Um dicionário representando os conteúdos do arquivo `json`. 19 | 20 | Raises 21 | ------ 22 | TypeError: 23 | O parâmetro `arquivo` não era uma string. 24 | FileNotFoundError: 25 | O arquivo não pode ser encontrado. 26 | IsADirectoryError: 27 | A string passada representa um diretório. 28 | PermissionError: 29 | Não há autorização para acessar o arquivo. 30 | OSError: 31 | Houve um problema do Sistema Operacional durante a leitura do arquivo. 32 | json.JSONDecodeError: 33 | Os conteúdos dentro do arquivo não estavam no formato de um `json`. 34 | """ 35 | if not isinstance(arquivo, str): 36 | raise TypeError 37 | with open(arquivo, "r") as arquivo_json: 38 | dicionario = json.load(arquivo_json) 39 | return dicionario 40 | -------------------------------------------------------------------------------- /lista3/lista3.md: -------------------------------------------------------------------------------- 1 | # Lista de Exercícios 3 - Tratamento de Erros 2 | 3 | Objetivo: Revisar testes unitários e assertivas. 4 | 5 | Data para entrega: 25/09 23h59. 6 | 7 | ## Exercício 1 (primeiro e último) 8 | Escrever testes para as funções `len()` e `sorted()` (funções padrão do Python). Os testes devem cobrir cenários com entradas válidas e inválidas. 9 | 10 | ### 1. Função [`len()`](https://docs.python.org/3/library/functions.html#len) (padrão do Python) 11 | 12 | - Escreva testes que verifiquem o comportamento da função `len()` com diferentes tipos de entradas, como listas, strings e dicionários. 13 | - Crie testes para entradas inválidas, como passar um número ou outro tipo que não seja iterável. 14 | 15 | ### 2. Função [`sorted()`](https://docs.python.org/3/library/functions.html#sorted) (padrão do Python) 16 | 17 | - Escreva testes que verifiquem o comportamento da função sorted() com diferentes tipos de listas e strings. 18 | - Teste também se o parâmetro `reverse=True` funciona corretamente. 19 | - Crie testes para entradas inválidas, como passar `None` ou objetos não iteráveis. 20 | 21 | ## Instruções de entrega: 22 | 23 | 1. Use um arquivo de teste para cada função: 24 | - Para a função `len()`, use o arquivo `test_len.py`. 25 | - Para a função `sorted()`, use o arquivo `test_sorted.py`. 26 | 27 | 2. Cada arquivo deve conter: 28 | - *Testes válidos*: Casos em que a função retorna o valor esperado (pelo menos 3). 29 | - *Testes inválidos*: Casos em que a função lança uma exceção apropriada (pelo menos 2 excessões diferentes). 30 | - *Teste de exceção*: Valide se a exceção está sendo lançada com a mensagem correta (quando aplicável). 31 | 32 | 3. Nomeie os testes de forma clara, como `test_len_with_list` ou `test_sorted_with_strings`. 33 | - Importante: a biblioteca pytest, por padrão, busca apenas por funções com nomes iniciados em `test_`. Por isso, suas funções devem sempre iniciar com esse prefixo. 34 | 35 | 4. Utilize assert para verificar as saídas dos testes. 36 | 37 | --- 38 | 39 | ## Exemplos de Testes: 40 | 41 | ### Testando a função len(): 42 | 43 | ```python 44 | # test_len.py 45 | 46 | def test_len_with_list(): 47 | assert len([1, 2, 3]) == 3 48 | 49 | def test_len_with_string(): 50 | assert len("hello") == 5 51 | 52 | def test_len_with_invalid_input(): 53 | try: 54 | len(42) 55 | except TypeError: 56 | assert True 57 | else: 58 | assert False 59 | -------------------------------------------------------------------------------- /lista1/lista1.md: -------------------------------------------------------------------------------- 1 | # Lista 1 - Linguagens de programação 2 | 3 | Objetivos: revisar laços de repetição, condicionais e funções. 4 | 5 | ## Exercício 1 6 | 7 | Seja $p$ o perimetro de um triângulo retângulo com lados $\\{a, b, c\\}$ 8 | ($a, b, c$ são números naturais). Se definimos $p = 120$, teremos três possíveis 9 | triângulos retângulos com perímetro $p$: $\\{20, 48, 52\\}, \\{24, 45, 51\\}, \\{30, 40, 50\\}$. 10 | 11 | Escreva uma função que receba um inteiro $n$ e retorne um inteiro representando 12 | qual valor de $p \leq n$ temos o maior número de triângulos possível. Se mais de 13 | um valor de $p$ for adequado, a função deve retornar o menor deles. 14 | 15 | Se a entrada da função não for um número inteiro, ela deverá imprimir uma mensagem 16 | avisando que só recebe inteiros e retornar `None`. 17 | 18 | ## Exercício 2 19 | 20 | Escreva uma função que receba dois números naturais não nulos $m, n$, que seguem 21 | duas restrições: $m < n$ e $m$ e $n$ devem ser primos entre si. A função deve 22 | retornar uma matriz $n \times n$ preenchida com os números naturais de 1 a $n^2$. 23 | 24 | O preenchimento deve ser realizado no sentido horizontal, mas seguindo uma regra 25 | especial: a inserção dos números deve ser feita em passos de $m$ em $m$ casas. 26 | Caso $m$ e $n$ não atendam os requisitos, a função deve imprimir uma mensagem avisando 27 | do problema e retornar `None`. 28 | 29 | Exemplo de retorno para $m = 2$ e $n = 3$: 30 | ```python 31 | [[1 6 2], 32 | [7 3 8], 33 | [4 9 5]] 34 | ``` 35 | 36 | Exemplo de retorno para $m = 3$ e $n = 5$: 37 | ```python 38 | [[1 18 10 2 19], 39 | [11 3 20 12 4 ], 40 | [21 13 5 22 14], 41 | [6 23 15 7 24], 42 | [16 8 25 17 9 ]] 43 | ``` 44 | 45 | ## Exercício 3 46 | 47 | Construa uma função que receba dois retângulos e retorne um booleano indicando 48 | se eles colidem. Um retângulo é representado como uma tupla de 4 elementos, cada 49 | um sendo um dos vértices do retângulo, iniciando do superior esquerdo e 50 | avançando em sentido horário. Cada vértice é representado como uma tupla, contendo 51 | coordenadas x e y do plano cartesiano. 52 | 53 | Considere que os retângulos não são rotacionados (isto é, as arestas são 54 | paralelas aos eixos) e que dois retângulos colidem se um dos vértices de um 55 | deles está contido no conjunto **fechado** delimitado pelo outro retângulo. 56 | 57 | Se um dos retẫngulos estiver representado incorretamente, a função deverá retornar 58 | `None` e mostrar uma mensagem indicando o problema com o input. 59 | 60 | ## Exercício 4 61 | 62 | Agora generalize o problema, com uma função que receba um número qualquer de 63 | retângulos, por meio de argumentos nomeados `(**kwargs)`, e retorne uma lista com 64 | tuplas. Cada tupla deve ter dois elementos, que equivalem a um par de retângulos que 65 | colidem (os nomes dos argumentos devem ser usados para representar um retângulo). 66 | A ordenação dos retângulos de uma tupla deve seguir a ordenação passada na função. 67 | 68 | Se nenhum retângulo colidir, ou se nenhum ou apenas um retângulo for passado 69 | para a função, ela devera retornar uma lista vazia. 70 | -------------------------------------------------------------------------------- /atividade_relacoes_gabarito/funcionarios.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | class CargoFuncionario(Enum): 4 | ESTAGIARIO = 1 5 | VENDEDOR = 2 6 | GERENTE = 3 7 | ZELADOR = 4 8 | 9 | class Funcionario(): 10 | def __init__(self, nome, cpf, data_nascimento, salario, cargo = CargoFuncionario.ESTAGIARIO): 11 | self._nome = nome 12 | self._documento = cpf 13 | self._data_nascimento = data_nascimento 14 | self._salario = float(salario) 15 | self._cargo = cargo 16 | self._loja = None 17 | 18 | @property 19 | def nome(self): 20 | return self._nome 21 | 22 | @property 23 | def cpf(self): 24 | return self._documento 25 | 26 | @property 27 | def data_nascimento(self): 28 | return self._data_nascimento 29 | 30 | @property 31 | def salario(self): 32 | return self._salario 33 | 34 | @salario.setter 35 | def salario(self, novo_salario): 36 | if novo_salario < 1412 or not isinstance(novo_salario, int): 37 | raise ValueError("Sálario abaixo do permitido por lei.") 38 | self._salario = novo_salario 39 | 40 | @property 41 | def cargo(self): 42 | return self._cargo 43 | 44 | @property 45 | def loja(self): 46 | return self._loja 47 | 48 | def alocar(self, loja): 49 | if loja == None: 50 | if self._loja == None: 51 | print(f"{self._nome} já não estava alocado em nenhuma loja") 52 | else: 53 | print(f"{self._nome} foi tirado da loja {self._loja.cep} e agora não está em nenhuma") 54 | self._loja = None 55 | else: 56 | if self._loja == None: 57 | self._loja = loja 58 | print(f"{self._nome} foi alocado para a loja {loja.cep}") 59 | else: 60 | loja_antiga = self._loja 61 | self._loja = loja 62 | print(f"{self._nome} saiu da loja {loja_antiga.cep} para a loja {loja.cep}") 63 | 64 | 65 | def promover(self): 66 | if self._cargo == CargoFuncionario.ESTAGIARIO: 67 | self._cargo = CargoFuncionario.ZELADOR 68 | print(f"{self._nome} foi promovido para zelador") 69 | elif self._cargo == CargoFuncionario.ZELADOR: 70 | self._cargo = CargoFuncionario.VENDEDOR 71 | print(f"{self._nome} foi promovido para vendedor") 72 | if self._cargo == CargoFuncionario.VENDEDOR: 73 | self._cargo = CargoFuncionario.GERENTE 74 | print(f"{self._nome} foi promovido para gerente") 75 | if self._cargo == CargoFuncionario.GERENTE: 76 | print(f"{self._nome} alcançou o topo da hierarquia") 77 | 78 | def pagar(self): 79 | print(f"{self._nome} recebeu R${self._salario} no banco e gastou tudo para pagar contas") 80 | 81 | def __repr__(self): 82 | loja = self._loja.cep if self._loja is not None else "(nenhuma)" 83 | return f"Funcionário {self._nome} atualmente no cargo de {self._cargo.name} na loja {loja} recebendo R${self._salario}" 84 | 85 | def __del__(self): 86 | print(f"{self._nome} morreu.") 87 | 88 | if __name__ == "__main__": 89 | gerson = Funcionario("Gerson", 99999999900, "28/07/2004", 1412.0) 90 | adilson = Funcionario("Adilson", 88888888811, "25/10/1987", 5000, cargo = CargoFuncionario.GERENTE) 91 | 92 | print(gerson) 93 | print(gerson.cpf) 94 | print(adilson) 95 | print(adilson.data_nascimento) 96 | 97 | print("") 98 | 99 | gerson.pagar() 100 | adilson.pagar() 101 | 102 | print("") 103 | 104 | gerson.promover() 105 | print(gerson) 106 | 107 | print("") 108 | 109 | -------------------------------------------------------------------------------- /atividade_relacoes.md: -------------------------------------------------------------------------------- 1 | # Atividade - 09/11 2 | 3 | Objetivo: implementar classes que modelem um dado problema. Implementar herança entre 4 | classes. Implementar três tipos de relacionamentos entre classes: Associação, 5 | Composição e Agregação. Se não se lembrar o que são essas relações, 6 | [consulte essa explicação.](https://github.com/matwerner/fgv-lp/blob/master/aulas/Semana%2011%20-%20Classes/35_classes_associacao_agregacao_composicao.md). 7 | 8 | Entrega: deverá ser criado um repositório no GitHub contendo os arquivos resultantes 9 | da atividade, na conta do aluno. Enviar o link do repositório, nome e matrícula 10 | para pedrotokar2004@gmail.com com o assunto "Atividade LP 0911". **Prazo: 10/11 23h59** 11 | 12 | OBS: não é necessário fazer documentação, mas é importante comentar o motivo das 13 | suas escolhas para implementação. É necessário ter pelo menos um driver code que 14 | teste as funcionalidades implementadas. 15 | 16 | ## Enunciado 17 | 18 | Você deve modelar um sistema para uma franquia de loja de instrumentos que vende 19 | três tipos de instrumentos: baixos, guitarras e violões. Esse sistema será feito 20 | em Python e usará classes para representar as principais entidades relacionadas 21 | à empresa. 22 | 23 | A primeira entidade são as lojas. Como se espera de uma franquia, existem várias 24 | filiais diferentes espalhadas pelo mundo. O sistema deve ser capaz de manter 25 | registro de todas as filiais existentes, e das seguintes infomações sobre elas: 26 | 27 | - Localização; 28 | - Quadro de funcionários (quais funcionários tem na loja); 29 | - Estoque (quantos e quais instrumentos estão no estoque da loja). 30 | 31 | Além de registrar essas informações, é preciso que um usuário do sistema possa: 32 | 33 | - Mudar o quadro de funcionarios (colocar ou tirar um funcionario); 34 | - Mudar o estoque (colocar ou retirar um instrumento); 35 | - Consultar quantos instrumentos de cada tipo tem disponíveis na loja; 36 | - Consultar quantos funcionários de cada cargo estão alocados na loja. 37 | 38 | (Para o quadro de funcionários e estoque, não necessariamente precisa ser capaz 39 | de remover um objeto especifico. Pode remover qualquer um arbitrariamente, para 40 | simplificar) 41 | Por último, as lojas podem armazenar qual a outra loja que é mais perto delas. 42 | 43 | A segunda entidade são os funcionários. O sistema precisa manter registro das 44 | seguintes informações deles: 45 | 46 | - Nome completo; 47 | - Documento (CPF); 48 | - Salário; 49 | - Cargo; 50 | - Loja atual. 51 | 52 | É importante ter em mente que os funcionários podem ser remanejados entre as lojas, 53 | ou seja, continuam existindo independente da loja. Além disso, é importante notar 54 | que existe uma hierarquia fixa de cargos na franquia, ou seja, existe um conjunto 55 | fixo de cargos que um funcionário pode ter (e cada funcionário tem apenas um cargo) 56 | 57 | A última entidade são os instrumentos. Como dito acima, as lojas vendem três tipos de 58 | instrumentos: guitarras, baixos e violões. O sistema precisa manter as seguintes 59 | informações para todos os instrumentos: 60 | 61 | - Marca; 62 | - Modelo; 63 | - Preço; 64 | - Número de cordas. 65 | 66 | Além disso, instrumentos diferentes podem ter peculiaridades e informações a 67 | serem armazenadas diferentes (use sua criatividade e conhecimento de música). 68 | 69 | É importante ter em mente que os instrumentos nunca são remanejados: um instrumento 70 | existe exclusivamente em uma loja, e não é transferido para outra. Devido a essa 71 | natureza, não existem instrumentos que não são associados a nenhuma loja. Logo, 72 | se uma loja deixa de existir, os instrumentos também deixam (são doados para caridade). 73 | 74 | Agora, você tem informações o suficiente para implementar o sistema da loja. Antes 75 | de começar, pense bem nos tipos de relação que existem entre cada classe. 76 | -------------------------------------------------------------------------------- /lista2/lista2.md: -------------------------------------------------------------------------------- 1 | # Lista 2 - Linguagens de programação 2 | 3 | Objetivos: revisar tratamento de erros. 4 | 5 | Entrega: crie um arquivo `respostas.py` na pasta raiz do repositório, contendo as 6 | funções relativas aos dois primeiros exercícios. A função relativa ao exercício 7 | um deverá se chamar `exercicio1` e a relativa ao exercício dois deverá se chamar 8 | `exercicio2`. O arquivo criado para o exercício 3 deverá estar na raiz do 9 | respositório. O prazo de entrega é dia 12/09, 11h59. 10 | 11 | ## Exercício 1: Validação de Entrada e Cálculo de Norma Vetorial 12 | 13 | Implemente uma função em Python que receba como entrada um vetor (tupla de 14 | números) e calcule a norma Euclidiana desse vetor. A função deve realizar 15 | validações básicas de entrada para garantir que o vetor contém apenas números. 16 | Se a entrada for inválida, a função deve levantar uma exceção apropriada. 17 | 18 | ### *Passos:* 19 | 1. *Função para cálculo da norma:* 20 | - Implemente uma função chamada exercicio1(vetor) que calcule e retorne 21 | a norma Euclidiana do vetor, definida como 22 | $\|\mathbf{v}\| = \sqrt{\sum_{i=1}^n v_i^2}$. 23 | 24 | 2. *Validação da entrada:* 25 | - A função deve verificar se a entrada é uma tupla de números (int ou float). 26 | - Se a entrada não for uma tupla, ou se algum elemento da tupla não for 27 | numérico, a função deve levantar uma exceção do tipo `TypeError` ou 28 | `ValueError` com uma mensagem apropriada. 29 | 30 | ### *Exemplos:* 31 | 32 | ```python 33 | >>> exercicio1((3, 4)) 34 | 5 35 | 36 | >>> exercicio1((1, 1, -1, -1)) 37 | 2 38 | 39 | >>> exercicio1(9) 40 | Traceback (most recent call last): 41 | ... 42 | TypeError: ... 43 | 44 | >>> exercicio1((2, "6")) 45 | Traceback (most recent call last): 46 | ... 47 | ValueError: ... 48 | ``` 49 | 50 | ## Exercício 2: Determinação da Equação da Reta 51 | 52 | Dado dois pontos $P_1 = (x_1, y_1)$ e $P_2 = (x_2, y_2)$ no plano 53 | cartesiano, implemente uma função em Python que calcule e retorne a equação da 54 | reta que passa por esses dois pontos na forma geral $y = ax + b$. 55 | 56 | ### *Passos:* 57 | 1. *Entrada dos Pontos:* 58 | - A função exercicio2(ponto1, ponto2) deve receber dois parâmetros, ponto1 e 59 | ponto2, que são tuplas representando as coordenadas dos pontos $P_1$ e 60 | $P_2$, respectivamente. 61 | 62 | 2. *Validação da entrada:* 63 | - A função deve verificar se os pontos de entrada são tuplas de tamanho 2, 64 | contendo números (int ou float). 65 | - Se a entrada não for válida, a função deve levantar uma exceção do tipo 66 | TypeError ou ValueError com uma mensagem apropriada. 67 | - Existem outros erros a serem tratados? Se sim, trate-os! 68 | 69 | 3. *Saída da função:* 70 | - A função deve retornar uma tupla (a, b) contendo os coeficientes da equação 71 | da reta. 72 | 73 | ### *Exemplos:* 74 | 75 | ```python 76 | >>> exercicio2((0, 0), (3, 6)) 77 | (2, 0) 78 | 79 | >>> exercicio2((2, 3), (5.5, 6.5)) 80 | (1, 1) 81 | 82 | >>> exercicio2((5, 6), 12) 83 | Traceback (most recent call last): 84 | ... 85 | TypeError: ... 86 | 87 | >>> exercicio2((9, 4), ("12", 9)) 88 | Traceback (most recent call last): 89 | ... 90 | ValueError: ... 91 | ``` 92 | 93 | ## Exercício 3: Tratamento de erros em função externa 94 | 95 | Você está desenvolvendo uma interface em terminal para ler arquivos JSON, com a 96 | ajuda de um módulo externo que implementa uma função para ler um arquivo JSON 97 | (que vida fácil!). Na sua interface, um usuário deverá inserir de input o nome 98 | de um arquivo, e eses input é usado pela função para retornar um dicionário 99 | com os conteúdos do arquivo. 100 | 101 | Como é de conhecimento geral, usuários costumam usar os programas da pior forma 102 | possível, e você sabe que a função pode dar alguns erros. Então, você deve tratar 103 | esses erros, usando `try`, `except` e `else`, e exibindo mensagens pertinentes 104 | para os possíveis erros que um usuário pode cometer. 105 | 106 | ### *Passos:* 107 | 1. *Elaboração inicial do script:* 108 | - Crie um arquivo `leitor_json.py`, que deve importar o arquivo `modulo.py`, 109 | coletar um input do usuário e usá-lo na função `carrega_conteudos_json`, que 110 | retorna um dicionário. 111 | - Esse dicionário deverá ser exibido ao usuário (opcionalmente com o módulo 112 | `pprint`). 113 | 114 | 2. *Tratamento de exceções:* 115 | - Com a ajuda de um bloco `try` `except`, o seu código deverá ser capaz de 116 | mostrar mensagens informativas ao usuário para caso a entrada dele faça a 117 | função levantar uma exceção. A documentação da função lista quais exceções 118 | ela pode levantar. 119 | - O script deverá pedir outro input depois de mostrar a mensagem de erro, 120 | até ter sucesso ou ser interrompido (por um ctrl+C) 121 | -------------------------------------------------------------------------------- /atividade_relacoes_gabarito/instrumentos.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | class TipoCaptacao(Enum): 4 | PASSIVA = 1 5 | ATIVA = 2 6 | 7 | class TipoPonte(Enum): 8 | FIXA = 1 9 | MOVEL = 2 10 | 11 | class TipoCorda(Enum): 12 | NYLON = 1 13 | ACO = 2 14 | 15 | class Instrumento(): 16 | def __init__(self, marca, modelo, preco, numero_cordas): 17 | self._marca = marca 18 | self._modelo = modelo 19 | self._preco = float(preco) 20 | self._len_cordas = numero_cordas 21 | 22 | @property 23 | def marca(self): 24 | return self._marca 25 | 26 | @marca.setter 27 | def marca(self, marca): 28 | self._marca = marca 29 | 30 | @property 31 | def modelo(self): 32 | return self._modelo 33 | 34 | @modelo.setter 35 | def modelo(self, modelo): 36 | self._modelo = modelo 37 | 38 | @property 39 | def numero_cordas(self): 40 | return self._len_cordas 41 | 42 | @numero_cordas.setter 43 | def numero_cordas(self, numero_cordas): 44 | if numero_cordas < 1 or numero_cordas > 20 or not isinstance(numero_cordas, int): 45 | raise ValueError("Infelizmente não existem instrumentos com esse número de cordas") 46 | self._len_cordas = numero_cordas 47 | 48 | @property 49 | def preco(self): 50 | return self._preco 51 | 52 | @preco.setter 53 | def preco(self, preco): 54 | if preco <= 0 or not isinstance(preco, float): 55 | raise ValueError("Preço invalido para o instrumento") 56 | self._preco = preco 57 | 58 | def tocar(self, nota): 59 | raise NotImplementedError("Subclasse não implementou essse método.") 60 | 61 | def __repr__(self): 62 | return f"{self._marca} {self._modelo} com {self._len_cordas} cordas. Custando R${self._preco}." 63 | 64 | def __del__(self): 65 | print(f"deletando instrumento {self._marca} {self._modelo}") 66 | 67 | class Baixo(Instrumento): 68 | def __init__(self, marca, modelo, preco, numero_cordas = 4, captacao = TipoCaptacao.PASSIVA): 69 | super().__init__(marca, modelo, preco, numero_cordas) 70 | self._tipo_captacao = captacao 71 | 72 | @property 73 | def captacao(self): 74 | return self._tipo_captacao 75 | 76 | def tocar(self, nota): 77 | print(f"Tocaram um {nota} muito grave no baixo. MUITO grave.") 78 | 79 | def __repr__(self): 80 | return super().__repr__() + f" Captação {self._tipo_captacao.name}" 81 | 82 | class Guitarra(Instrumento): 83 | def __init__(self, marca, modelo, preco, numero_cordas = 6, captacao = TipoCaptacao.PASSIVA, ponte = TipoPonte.FIXA): 84 | super().__init__(marca, modelo, preco, numero_cordas) 85 | self._tipo_captacao = captacao 86 | self._tipo_ponte = ponte 87 | 88 | @property 89 | def captacao(self): 90 | return self._tipo_captacao 91 | 92 | @property 93 | def ponte(self): 94 | return self._tipo_ponte 95 | 96 | def tocar(self, nota): 97 | print(f"Tocaram um solo em {nota} cheio de tappings") 98 | if self._tipo_ponte == TipoPonte.MOVEL: 99 | print("E usaram a alavanca pra deixar mais do rock ainda") 100 | 101 | def __repr__(self): 102 | return super().__repr__() + f" Captação {self._tipo_captacao.name} e ponte {self._tipo_ponte.name}" 103 | 104 | class Violao(Instrumento): 105 | def __init__(self, marca, modelo, preco, numero_cordas = 6, cordas = TipoCorda.NYLON): 106 | super().__init__(marca, modelo, preco, numero_cordas) 107 | self._tipo_cordas = cordas 108 | 109 | @property 110 | def cordas(self): 111 | return self._tipo_cordas 112 | 113 | def tocar(self, nota): 114 | print("Tocaram um sertanejo.") 115 | 116 | def __repr__(self): 117 | return super().__repr__() + f" Cordas de {self._tipo_cordas.name}" 118 | 119 | if __name__ == "__main__": 120 | #Testando representações e deleções, além da troca de atributos 121 | guitarra_1 = Guitarra("Giannini", "G-100", 665, captacao = TipoCaptacao.ATIVA) 122 | guitarra_2 = Guitarra("Tagima", "TG-510", 1092, numero_cordas = 8, ponte = TipoPonte.MOVEL) 123 | guitarra_1.preco = 999.0 124 | try: 125 | guitarra_2.numero_cordas = 9 126 | except Exception as e: 127 | print(f"ERRO: {e}") #Mesmo atribuindo um valor, ele por de baixo dos panos roda as verificações 128 | 129 | print(guitarra_1) 130 | print(guitarra_2) 131 | guitarra_1.tocar("lá") 132 | guitarra_2.tocar("ré") 133 | 134 | print("") 135 | 136 | baixo = Baixo("Aria Pro II", "Magna Series", 500) 137 | print(baixo) 138 | try: 139 | baixo.captacao = TipoCaptacao.ATIVA 140 | except Exception as e: 141 | print(f"ERRO: {e}") #Não é possível modificar propriedade que não tem setter 142 | baixo.tocar("si") 143 | 144 | print("") 145 | 146 | violao_1 = Violao("Giannini", "GDR", 898, cordas = TipoCorda.ACO) 147 | violao_2 = Violao("Folk Michael", "VM925DT", 1259, numero_cordas = 5) 148 | print(violao_1) 149 | print(violao_2) 150 | violao_1.tocar("mi") 151 | violao_2.tocar("sol") 152 | 153 | print("") 154 | -------------------------------------------------------------------------------- /atividade_relacoes_gabarito/lojas.py: -------------------------------------------------------------------------------- 1 | from instrumentos import Guitarra, Baixo, Violao, TipoPonte, TipoCaptacao, TipoCorda 2 | from funcionarios import Funcionario, CargoFuncionario 3 | 4 | class Loja(): 5 | def __init__(self, cep): 6 | self._localizacao = cep 7 | self._funcionarios = [] 8 | self._estoque = [] 9 | self._lojas_mais_proxima = None 10 | 11 | @property 12 | def cep(self): 13 | return self._localizacao 14 | 15 | #COMPOSIÇÃO: Os instrumentos são inicializados totalmente dentro da classe loja, e não existem fora dela. 16 | #Por isso, o método recebe os parâmetros que são usados para incicialiar um instrumento 17 | def adicionar_guitarra(self, marca, modelo, preco, numero_cordas = 6, captacao = TipoCaptacao.PASSIVA, ponte = TipoPonte.FIXA): 18 | self._estoque.append(Guitarra(marca, modelo, preco, numero_cordas, captacao, ponte)) 19 | 20 | def adicionar_baixo(self, marca, modelo, preco, numero_cordas = 4, captacao = TipoCaptacao.PASSIVA): 21 | self._estoque.append(Baixo(marca, modelo, preco, numero_cordas, captacao)) 22 | 23 | def adicionar_violao(self, marca, modelo, preco, numero_cordas = 6, cordas = TipoCorda.NYLON): 24 | self._estoque.append(Violao(marca, modelo, preco, numero_cordas, cordas)) 25 | 26 | def vender_instrumento(self): 27 | if len(self._estoque) == 0: 28 | print("Não foi possível vender nada, acabaram os instrumentos") 29 | else: 30 | print(f"Foi vendido um \"{self._estoque[0]}\"") 31 | del self._estoque[0] #COMPOSIÇÃO: O instrumento deixa de existir totalmente 32 | 33 | @property 34 | def estoque(self): 35 | contagens = [0, 0, 0] 36 | for instrumento in self._estoque: 37 | if isinstance(instrumento, Guitarra): 38 | contagens[0] += 1 39 | elif isinstance(instrumento, Baixo): 40 | contagens[1] += 1 41 | elif isinstance(instrumento, Violao): 42 | contagens[2] += 1 43 | return contagens 44 | 45 | #AGREGAÇÃO: O funcionário pode existir mesmo se essa loja não existir. Por isso. 46 | #o método recebe o objeto representando o funcionário no lugar de criar um internamente 47 | def alocar_funcionario(self, funcionario: Funcionario): 48 | self._funcionarios.append(funcionario) 49 | funcionario.alocar(self) 50 | print(f"Funcionário {funcionario.nome} foi alocado para a loja {self._localizacao}") 51 | 52 | def remover_funcionario(self): 53 | if len(self._funcionarios) == 0: 54 | print("Não há funcionarios para desalocar da loja") 55 | else: 56 | print(f"{self._funcionarios[0].nome} foi removido da loja {self._localizacao}") 57 | self._funcionarios[0].alocar(None) 58 | self._funcionarios.pop(0) #AGREGAÇÃO: o funcionário segue existindo e não foi deletado 59 | 60 | @property 61 | def funcionarios(self): 62 | contagens = [0, 0, 0, 0] 63 | for funcionario in self._funcionarios: 64 | if funcionario.cargo == CargoFuncionario.ESTAGIARIO: 65 | contagens[0] += 1 66 | elif funcionario.cargo == CargoFuncionario.VENDEDOR: 67 | contagens[1] += 1 68 | elif funcionario.cargo == CargoFuncionario.GERENTE: 69 | contagens[2] += 1 70 | elif funcionario.cargo == CargoFuncionario.ESTAGIARIO: 71 | contagens[3] += 1 72 | return contagens 73 | 74 | @property 75 | def loja_proxima(self): 76 | return self._lojas_mais_proxima 77 | 78 | @loja_proxima.setter #ASSOCIAÇÃO: Uma loja pode referenciar a outra mas isso não impacta na vida de nenhuma das duas. Uma loja segue existindo mesmo se a outra não existir 79 | def loja_proxima(self, loja_perto): 80 | self._lojas_mais_proxima = loja_perto 81 | 82 | def __repr__(self): 83 | return f"Loja {self._localizacao}. Estoque: {self.estoque}. Funcionarios: {self.funcionarios}" 84 | 85 | def __del__(self): 86 | del self._estoque 87 | for funcionario in self._funcionarios: 88 | funcionario.alocar(None) 89 | 90 | 91 | if __name__ == "__main__": 92 | loja_1 = Loja("22230-010") 93 | loja_2 = Loja("22250-145") 94 | 95 | print(loja_1) 96 | print(loja_2) 97 | 98 | loja_1.loja_proxima = loja_2 #ASSOCIAÇÃO: Mesmo se uma das duas for deletada vai tudo ficar ok 99 | 100 | loja_1.adicionar_baixo("Aria Pro II", "Magna Series", 500) 101 | loja_1.adicionar_guitarra("Giannini", "G-100", 665, captacao = TipoCaptacao.ATIVA) 102 | loja_1.adicionar_guitarra("Tagima", "TG-510", 1092, numero_cordas = 8, ponte = TipoPonte.MOVEL) 103 | loja_1.adicionar_violao("Giannini", "GDR", 898, cordas = TipoCorda.ACO) 104 | loja_1.adicionar_violao("Folk Michael", "VM925DT", 1259, numero_cordas = 5) 105 | 106 | loja_1.vender_instrumento() 107 | loja_1.vender_instrumento() #COMPOSIÇÃO: Aqui vemos que o método __del__ dos instrumentos foi chamado 108 | 109 | print("") 110 | 111 | gerson = Funcionario("Gerson", 99999999900, "28/07/2004", 1412.0) 112 | adilson = Funcionario("Adilson", 88888888811, "25/10/1987", 5000, cargo = CargoFuncionario.GERENTE) 113 | roberto = Funcionario("Rodrigo", 77777777722, "29/02/2000", 8999, cargo = CargoFuncionario.ZELADOR) 114 | 115 | loja_1.alocar_funcionario(gerson) 116 | loja_1.alocar_funcionario(adilson) 117 | loja_1.alocar_funcionario(roberto) 118 | print('-') 119 | print(gerson) 120 | print(adilson) 121 | print(loja_1) 122 | 123 | print("") 124 | 125 | loja_1.remover_funcionario() 126 | print(loja_1) 127 | print(gerson) #AGREGAÇÃO: Podemos observar aqui que gerson continua existindo 128 | print("-") 129 | loja_2.alocar_funcionario(adilson) 130 | print(gerson) 131 | print(loja_2) #AGREGAÇÃO: Trocamos o adilson de loja 132 | #Mesmo após essas mudanças nenhum funcionario deixou de existir 133 | 134 | print("") 135 | -------------------------------------------------------------------------------- /aula_series.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "2267a5ff-aaaa-40d4-b9e5-d4c8bcf51151", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import numpy as np\n", 11 | "import pandas as pd" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 2, 17 | "id": "dc5bef8a-c532-4336-96a5-ee83137dd8eb", 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "lista_1 = [1,2,3,4,6]\n", 22 | "lista_2 = [\"I\",\"II\",\"III\",\"IV\",\"V\"]\n", 23 | "\n", 24 | "dic_1 = {\"I\":1,\"II\":2,\"III\":3,\"IV\":4,\"V\":5}\n", 25 | "\n", 26 | "ndarray_1 = np.array(lista_1)" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "id": "832e0206-1aa7-4ca2-a2d4-8a9bd40260e5", 32 | "metadata": {}, 33 | "source": [ 34 | "## Criando séries" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 3, 40 | "id": "ef6bd089-030b-4a58-b518-730fc685231f", 41 | "metadata": {}, 42 | "outputs": [ 43 | { 44 | "data": { 45 | "text/plain": [ 46 | "I 1\n", 47 | "II 2\n", 48 | "III 3\n", 49 | "IV 4\n", 50 | "V 6\n", 51 | "dtype: int64" 52 | ] 53 | }, 54 | "execution_count": 3, 55 | "metadata": {}, 56 | "output_type": "execute_result" 57 | } 58 | ], 59 | "source": [ 60 | "s1 = pd.Series(lista_1, lista_2) #O primeiro parâmetro é a lista/array e o segundo é o índice\n", 61 | "s1" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 4, 67 | "id": "9e004c2f-9974-4105-8b63-7d2696e8f3aa", 68 | "metadata": {}, 69 | "outputs": [ 70 | { 71 | "data": { 72 | "text/plain": [ 73 | "1 I\n", 74 | "2 II\n", 75 | "3 III\n", 76 | "4 IV\n", 77 | "6 V\n", 78 | "dtype: object" 79 | ] 80 | }, 81 | "execution_count": 4, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "s2 = pd.Series(lista_2, lista_1) #Podemos ter índices númericos ou de strings ou mistos\n", 88 | "s2" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 5, 94 | "id": "da0ed56f-341b-4cf3-97dd-9ca696d0499d", 95 | "metadata": {}, 96 | "outputs": [ 97 | { 98 | "data": { 99 | "text/plain": [ 100 | "I 1\n", 101 | "II 2\n", 102 | "III 3\n", 103 | "IV 4\n", 104 | "V 5\n", 105 | "dtype: int64" 106 | ] 107 | }, 108 | "execution_count": 5, 109 | "metadata": {}, 110 | "output_type": "execute_result" 111 | } 112 | ], 113 | "source": [ 114 | "s3 = pd.Series(dic_1) #Podemos criar de dicionários também\n", 115 | "s3" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 6, 121 | "id": "5668246c-dda2-444b-86fc-a7219809c006", 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "data": { 126 | "text/plain": [ 127 | "0 1\n", 128 | "1 2\n", 129 | "2 3\n", 130 | "3 4\n", 131 | "4 6\n", 132 | "Name: Série, dtype: int64" 133 | ] 134 | }, 135 | "execution_count": 6, 136 | "metadata": {}, 137 | "output_type": "execute_result" 138 | } 139 | ], 140 | "source": [ 141 | "s4 = pd.Series(ndarray_1, name = \"Série\") #Colocar nomes é útil quando se está trabalhando com várias séries (DataFrame)\n", 142 | "s4" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": 7, 148 | "id": "9409b64d-39cd-49f7-a1c3-1c70dec86662", 149 | "metadata": {}, 150 | "outputs": [ 151 | { 152 | "data": { 153 | "text/plain": [ 154 | "I 1\n", 155 | "II 2\n", 156 | "III 3\n", 157 | "IV 4\n", 158 | "V 6\n", 159 | "dtype: int64" 160 | ] 161 | }, 162 | "execution_count": 7, 163 | "metadata": {}, 164 | "output_type": "execute_result" 165 | } 166 | ], 167 | "source": [ 168 | "s4 = pd.Series(ndarray_1, lista_2)\n", 169 | "s4" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 8, 175 | "id": "85608a4b-5254-47d8-82c0-02f46972269e", 176 | "metadata": {}, 177 | "outputs": [ 178 | { 179 | "data": { 180 | "text/plain": [ 181 | "1 1\n", 182 | "2 2\n", 183 | "3 3\n", 184 | "4 4\n", 185 | "6 6\n", 186 | "dtype: int64" 187 | ] 188 | }, 189 | "execution_count": 8, 190 | "metadata": {}, 191 | "output_type": "execute_result" 192 | } 193 | ], 194 | "source": [ 195 | "s5 = pd.Series(ndarray_1, lista_1)\n", 196 | "s5" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 9, 202 | "id": "86b83063-7089-432c-bfdb-5f1a6c16d498", 203 | "metadata": {}, 204 | "outputs": [ 205 | { 206 | "data": { 207 | "text/plain": [ 208 | "array([1, 2, 3, 4, 6])" 209 | ] 210 | }, 211 | "execution_count": 9, 212 | "metadata": {}, 213 | "output_type": "execute_result" 214 | } 215 | ], 216 | "source": [ 217 | "s1.to_numpy()" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": 10, 223 | "id": "586f7660-8837-41cb-ae87-bbd1af33777d", 224 | "metadata": {}, 225 | "outputs": [ 226 | { 227 | "data": { 228 | "text/plain": [ 229 | "[1, 2, 3, 4, 6]" 230 | ] 231 | }, 232 | "execution_count": 10, 233 | "metadata": {}, 234 | "output_type": "execute_result" 235 | } 236 | ], 237 | "source": [ 238 | "s1.to_list()" 239 | ] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "id": "2eafeb8b-b340-43d6-9ef6-9777f9ce7378", 244 | "metadata": {}, 245 | "source": [ 246 | "## Indexando series" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": 11, 252 | "id": "a1200c0c-c635-4946-ba9f-fc6558db8d71", 253 | "metadata": {}, 254 | "outputs": [ 255 | { 256 | "name": "stderr", 257 | "output_type": "stream", 258 | "text": [ 259 | "/tmp/ipykernel_9873/625738788.py:1: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`\n", 260 | " s1[2]\n" 261 | ] 262 | }, 263 | { 264 | "data": { 265 | "text/plain": [ 266 | "np.int64(3)" 267 | ] 268 | }, 269 | "execution_count": 11, 270 | "metadata": {}, 271 | "output_type": "execute_result" 272 | } 273 | ], 274 | "source": [ 275 | "s1[2]" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "execution_count": 12, 281 | "id": "ef59c722-ae2e-4c5b-b8cc-f4ae152cc3f7", 282 | "metadata": {}, 283 | "outputs": [ 284 | { 285 | "data": { 286 | "text/plain": [ 287 | "np.int64(3)" 288 | ] 289 | }, 290 | "execution_count": 12, 291 | "metadata": {}, 292 | "output_type": "execute_result" 293 | } 294 | ], 295 | "source": [ 296 | "s1.iloc[2] #sempre melhor usar iloc para indexar por posição/índice númerico personalizado" 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": 13, 302 | "id": "9de5e1ef-5c58-459a-9630-0924fb4d7f06", 303 | "metadata": {}, 304 | "outputs": [ 305 | { 306 | "data": { 307 | "text/plain": [ 308 | "I 1\n", 309 | "II 2\n", 310 | "III 3\n", 311 | "dtype: int64" 312 | ] 313 | }, 314 | "execution_count": 13, 315 | "metadata": {}, 316 | "output_type": "execute_result" 317 | } 318 | ], 319 | "source": [ 320 | "s1[:3] #Se o índice da série é por string, então ainda podemos usar um índice convencional (0-indexaddo)" 321 | ] 322 | }, 323 | { 324 | "cell_type": "code", 325 | "execution_count": 14, 326 | "id": "b97acd56-8902-460d-89df-99b1806cf294", 327 | "metadata": {}, 328 | "outputs": [ 329 | { 330 | "data": { 331 | "text/plain": [ 332 | "I 1\n", 333 | "II 2\n", 334 | "dtype: int64" 335 | ] 336 | }, 337 | "execution_count": 14, 338 | "metadata": {}, 339 | "output_type": "execute_result" 340 | } 341 | ], 342 | "source": [ 343 | "s1.head(2)" 344 | ] 345 | }, 346 | { 347 | "cell_type": "code", 348 | "execution_count": 15, 349 | "id": "774fdffd-c48c-4944-b810-eb2ddc7a9b7d", 350 | "metadata": {}, 351 | "outputs": [ 352 | { 353 | "data": { 354 | "text/plain": [ 355 | "IV 4\n", 356 | "V 6\n", 357 | "dtype: int64" 358 | ] 359 | }, 360 | "execution_count": 15, 361 | "metadata": {}, 362 | "output_type": "execute_result" 363 | } 364 | ], 365 | "source": [ 366 | "s1.tail(2)" 367 | ] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "execution_count": 16, 372 | "id": "6ebe3257-fc2e-45b0-b715-f7901376badb", 373 | "metadata": {}, 374 | "outputs": [ 375 | { 376 | "data": { 377 | "text/plain": [ 378 | "III 3\n", 379 | "IV 4\n", 380 | "V 6\n", 381 | "dtype: int64" 382 | ] 383 | }, 384 | "execution_count": 16, 385 | "metadata": {}, 386 | "output_type": "execute_result" 387 | } 388 | ], 389 | "source": [ 390 | "s1.iloc[-3:]" 391 | ] 392 | }, 393 | { 394 | "cell_type": "code", 395 | "execution_count": 17, 396 | "id": "82b65645-4825-4341-b404-dcff314d3e98", 397 | "metadata": {}, 398 | "outputs": [ 399 | { 400 | "data": { 401 | "text/plain": [ 402 | "np.int64(1)" 403 | ] 404 | }, 405 | "execution_count": 17, 406 | "metadata": {}, 407 | "output_type": "execute_result" 408 | } 409 | ], 410 | "source": [ 411 | "s1 = pd.Series(dic_1)\n", 412 | "s1[\"I\"] #acessando pelo índice" 413 | ] 414 | }, 415 | { 416 | "cell_type": "code", 417 | "execution_count": 18, 418 | "id": "2e6e7ca6-12fd-47ab-b293-80250754262d", 419 | "metadata": {}, 420 | "outputs": [ 421 | { 422 | "data": { 423 | "text/plain": [ 424 | "np.int64(1)" 425 | ] 426 | }, 427 | "execution_count": 18, 428 | "metadata": {}, 429 | "output_type": "execute_result" 430 | } 431 | ], 432 | "source": [ 433 | "s1.loc[\"I\"] #é melhor usar o `.loc` quando for indexar" 434 | ] 435 | }, 436 | { 437 | "cell_type": "code", 438 | "execution_count": 19, 439 | "id": "62df83a0-5d16-4cd1-8d74-536e3f095972", 440 | "metadata": {}, 441 | "outputs": [ 442 | { 443 | "data": { 444 | "text/plain": [ 445 | "'V'" 446 | ] 447 | }, 448 | "execution_count": 19, 449 | "metadata": {}, 450 | "output_type": "execute_result" 451 | } 452 | ], 453 | "source": [ 454 | "s1.idxmax() #índice máximo" 455 | ] 456 | }, 457 | { 458 | "cell_type": "code", 459 | "execution_count": 20, 460 | "id": "880cf59a-43cc-4f79-9e3f-17f86fa49753", 461 | "metadata": {}, 462 | "outputs": [ 463 | { 464 | "data": { 465 | "text/plain": [ 466 | "'I'" 467 | ] 468 | }, 469 | "execution_count": 20, 470 | "metadata": {}, 471 | "output_type": "execute_result" 472 | } 473 | ], 474 | "source": [ 475 | "s1.idxmin() #índice mínimo" 476 | ] 477 | }, 478 | { 479 | "cell_type": "code", 480 | "execution_count": 21, 481 | "id": "4fd11522-7dc7-44d3-b392-8ee7c47a0612", 482 | "metadata": {}, 483 | "outputs": [ 484 | { 485 | "data": { 486 | "text/plain": [ 487 | "I 1\n", 488 | "II 2\n", 489 | "III 3\n", 490 | "IV 4\n", 491 | "dtype: int64" 492 | ] 493 | }, 494 | "execution_count": 21, 495 | "metadata": {}, 496 | "output_type": "execute_result" 497 | } 498 | ], 499 | "source": [ 500 | "s1.loc[\"I\":\"IV\"] #Podemos fazer slice por índice" 501 | ] 502 | }, 503 | { 504 | "cell_type": "code", 505 | "execution_count": 22, 506 | "id": "cd15e715-d7be-480c-9b15-dac122b327a8", 507 | "metadata": {}, 508 | "outputs": [ 509 | { 510 | "data": { 511 | "text/plain": [ 512 | "1 I\n", 513 | "2 II\n", 514 | "3 III\n", 515 | "4 IV\n", 516 | "dtype: object" 517 | ] 518 | }, 519 | "execution_count": 22, 520 | "metadata": {}, 521 | "output_type": "execute_result" 522 | } 523 | ], 524 | "source": [ 525 | "s2.loc[1:5] #Usando loc ele conta o slice pelos índices e não pela posição" 526 | ] 527 | }, 528 | { 529 | "cell_type": "code", 530 | "execution_count": 23, 531 | "id": "93fdb935-33b7-43f5-8a80-4dd96fa73241", 532 | "metadata": {}, 533 | "outputs": [ 534 | { 535 | "data": { 536 | "text/plain": [ 537 | "I 10\n", 538 | "II 42\n", 539 | "III 7\n", 540 | "V 1000000\n", 541 | "dtype: int64" 542 | ] 543 | }, 544 | "execution_count": 23, 545 | "metadata": {}, 546 | "output_type": "execute_result" 547 | } 548 | ], 549 | "source": [ 550 | "dic_2 = {\"I\":10,\"II\":42,\"III\":7,\"V\":1_000_000}\n", 551 | "dic_3 = {\"I\":1,\"II\":12,\"III\":13,\"IV\":-1}\n", 552 | "\n", 553 | "s6 = pd.Series(dic_2)\n", 554 | "s7 = pd.Series(dic_3)\n", 555 | "\n", 556 | "s6" 557 | ] 558 | }, 559 | { 560 | "cell_type": "code", 561 | "execution_count": 24, 562 | "id": "076d1ada-4255-40f5-8a8e-625f92261daf", 563 | "metadata": {}, 564 | "outputs": [ 565 | { 566 | "data": { 567 | "text/plain": [ 568 | "I 1\n", 569 | "II 12\n", 570 | "III 13\n", 571 | "IV -1\n", 572 | "dtype: int64" 573 | ] 574 | }, 575 | "execution_count": 24, 576 | "metadata": {}, 577 | "output_type": "execute_result" 578 | } 579 | ], 580 | "source": [ 581 | "s7" 582 | ] 583 | }, 584 | { 585 | "cell_type": "markdown", 586 | "id": "fb5afea3-c20f-49d7-a6bc-d3219f2cafd3", 587 | "metadata": {}, 588 | "source": [ 589 | "## Operações com mais de uma série" 590 | ] 591 | }, 592 | { 593 | "cell_type": "code", 594 | "execution_count": 25, 595 | "id": "f5c1fcfe-2df1-4fd1-9247-9f1aa8c7f2be", 596 | "metadata": {}, 597 | "outputs": [ 598 | { 599 | "data": { 600 | "text/plain": [ 601 | "I 11.0\n", 602 | "II 54.0\n", 603 | "III 20.0\n", 604 | "IV NaN\n", 605 | "V NaN\n", 606 | "dtype: float64" 607 | ] 608 | }, 609 | "execution_count": 25, 610 | "metadata": {}, 611 | "output_type": "execute_result" 612 | } 613 | ], 614 | "source": [ 615 | "resultado = s6.add(s7) #Soma de acordo com os índices, dá NaN se não tem o índice nas duas séries\n", 616 | "resultado\n", 617 | "#Equivalente a fazer s6 + s7, mas sem poder passar parâmetros" 618 | ] 619 | }, 620 | { 621 | "cell_type": "code", 622 | "execution_count": 26, 623 | "id": "d7b3a68e-a869-470d-a3b7-60ba2907a1f6", 624 | "metadata": {}, 625 | "outputs": [ 626 | { 627 | "data": { 628 | "text/plain": [ 629 | "I 9.0\n", 630 | "II 30.0\n", 631 | "III -6.0\n", 632 | "IV NaN\n", 633 | "V NaN\n", 634 | "dtype: float64" 635 | ] 636 | }, 637 | "execution_count": 26, 638 | "metadata": {}, 639 | "output_type": "execute_result" 640 | } 641 | ], 642 | "source": [ 643 | "resultado = s6.sub(s7)\n", 644 | "resultado" 645 | ] 646 | }, 647 | { 648 | "cell_type": "code", 649 | "execution_count": 27, 650 | "id": "42ec2d5e-f8bf-4640-908b-d1eb6069a482", 651 | "metadata": {}, 652 | "outputs": [ 653 | { 654 | "data": { 655 | "text/plain": [ 656 | "np.int64(3)" 657 | ] 658 | }, 659 | "execution_count": 27, 660 | "metadata": {}, 661 | "output_type": "execute_result" 662 | } 663 | ], 664 | "source": [ 665 | "resultado.count() #Usado para contar quantos elementos não nulos tem" 666 | ] 667 | }, 668 | { 669 | "cell_type": "code", 670 | "execution_count": 28, 671 | "id": "9c47e773-3e7e-4ac0-87d1-9eed52f9b537", 672 | "metadata": {}, 673 | "outputs": [ 674 | { 675 | "data": { 676 | "text/plain": [ 677 | "5" 678 | ] 679 | }, 680 | "execution_count": 28, 681 | "metadata": {}, 682 | "output_type": "execute_result" 683 | } 684 | ], 685 | "source": [ 686 | "resultado.size #Usado para saber o tamanho total da sére" 687 | ] 688 | }, 689 | { 690 | "cell_type": "code", 691 | "execution_count": 29, 692 | "id": "c0b2513e-bed5-4e7a-ab55-e307d84c74ca", 693 | "metadata": {}, 694 | "outputs": [ 695 | { 696 | "data": { 697 | "text/plain": [ 698 | "I 1\n", 699 | "II 12\n", 700 | "III 13\n", 701 | "IV -1\n", 702 | "V 42\n", 703 | "dtype: int64" 704 | ] 705 | }, 706 | "execution_count": 29, 707 | "metadata": {}, 708 | "output_type": "execute_result" 709 | } 710 | ], 711 | "source": [ 712 | "dic_4 = {\"V\":42}\n", 713 | "s8 = pd.Series(dic_4)\n", 714 | "\n", 715 | "pd.concat([s7,s8]) #Usado para \"empilhar\" séries" 716 | ] 717 | }, 718 | { 719 | "cell_type": "code", 720 | "execution_count": 30, 721 | "id": "9185fed2-0f3b-4217-bd28-759940b69511", 722 | "metadata": {}, 723 | "outputs": [ 724 | { 725 | "data": { 726 | "text/plain": [ 727 | "I 10\n", 728 | "II 42\n", 729 | "III 7\n", 730 | "V 1000000\n", 731 | "I 1\n", 732 | "II 12\n", 733 | "III 13\n", 734 | "IV -1\n", 735 | "dtype: int64" 736 | ] 737 | }, 738 | "execution_count": 30, 739 | "metadata": {}, 740 | "output_type": "execute_result" 741 | } 742 | ], 743 | "source": [ 744 | "s9 = pd.concat([s6,s7])\n", 745 | "s9" 746 | ] 747 | }, 748 | { 749 | "cell_type": "code", 750 | "execution_count": 31, 751 | "id": "d1851366-74b2-4d54-9931-ead8db901a17", 752 | "metadata": {}, 753 | "outputs": [ 754 | { 755 | "data": { 756 | "text/plain": [ 757 | "I 10\n", 758 | "I 1\n", 759 | "dtype: int64" 760 | ] 761 | }, 762 | "execution_count": 31, 763 | "metadata": {}, 764 | "output_type": "execute_result" 765 | } 766 | ], 767 | "source": [ 768 | "s9.loc[\"I\"] #Se tem mais de um elemento com o mesmo índice, ele retorna todos" 769 | ] 770 | }, 771 | { 772 | "cell_type": "code", 773 | "execution_count": 32, 774 | "id": "43c496ed-c664-4b97-8d7f-893c0304a37f", 775 | "metadata": {}, 776 | "outputs": [ 777 | { 778 | "data": { 779 | "text/plain": [ 780 | "np.int64(8)" 781 | ] 782 | }, 783 | "execution_count": 32, 784 | "metadata": {}, 785 | "output_type": "execute_result" 786 | } 787 | ], 788 | "source": [ 789 | "s9.count()" 790 | ] 791 | }, 792 | { 793 | "cell_type": "code", 794 | "execution_count": 33, 795 | "id": "b57b4e12-5d93-4c25-aad9-6b4ae59e423c", 796 | "metadata": {}, 797 | "outputs": [ 798 | { 799 | "data": { 800 | "text/plain": [ 801 | "8" 802 | ] 803 | }, 804 | "execution_count": 33, 805 | "metadata": {}, 806 | "output_type": "execute_result" 807 | } 808 | ], 809 | "source": [ 810 | "s9.size" 811 | ] 812 | }, 813 | { 814 | "cell_type": "markdown", 815 | "id": "7544038c-f482-40fb-83fc-de7c53c84e90", 816 | "metadata": {}, 817 | "source": [ 818 | "## Tratando NAs" 819 | ] 820 | }, 821 | { 822 | "cell_type": "code", 823 | "execution_count": 34, 824 | "id": "ac8a0178-6bbc-456b-9a38-0db62c42dc0a", 825 | "metadata": {}, 826 | "outputs": [ 827 | { 828 | "data": { 829 | "text/plain": [ 830 | "I 11.0\n", 831 | "II 54.0\n", 832 | "III 20.0\n", 833 | "IV 8.0\n", 834 | "V 1000009.0\n", 835 | "dtype: float64" 836 | ] 837 | }, 838 | "execution_count": 34, 839 | "metadata": {}, 840 | "output_type": "execute_result" 841 | } 842 | ], 843 | "source": [ 844 | "resultado = s6.add(s7, fill_value = 9) #Em operações, podemos usar o parâmetro `fill_value` para definir um valor padrão para as contas\n", 845 | "resultado" 846 | ] 847 | }, 848 | { 849 | "cell_type": "code", 850 | "execution_count": 35, 851 | "id": "3f7364aa-6517-4823-8971-02de13702fa1", 852 | "metadata": {}, 853 | "outputs": [ 854 | { 855 | "data": { 856 | "text/plain": [ 857 | "np.int64(5)" 858 | ] 859 | }, 860 | "execution_count": 35, 861 | "metadata": {}, 862 | "output_type": "execute_result" 863 | } 864 | ], 865 | "source": [ 866 | "resultado.count()" 867 | ] 868 | }, 869 | { 870 | "cell_type": "code", 871 | "execution_count": 36, 872 | "id": "9ae97647-0049-4b91-ad04-deef15dcf02a", 873 | "metadata": {}, 874 | "outputs": [ 875 | { 876 | "data": { 877 | "text/plain": [ 878 | "5" 879 | ] 880 | }, 881 | "execution_count": 36, 882 | "metadata": {}, 883 | "output_type": "execute_result" 884 | } 885 | ], 886 | "source": [ 887 | "resultado.size" 888 | ] 889 | }, 890 | { 891 | "cell_type": "code", 892 | "execution_count": 37, 893 | "id": "3e7989e9-a732-4afc-8d50-bed9f0147cc2", 894 | "metadata": {}, 895 | "outputs": [ 896 | { 897 | "data": { 898 | "text/plain": [ 899 | "I 9.0\n", 900 | "II 30.0\n", 901 | "III -6.0\n", 902 | "dtype: float64" 903 | ] 904 | }, 905 | "execution_count": 37, 906 | "metadata": {}, 907 | "output_type": "execute_result" 908 | } 909 | ], 910 | "source": [ 911 | "resultado = s6.sub(s7) \n", 912 | "resultado.dropna(inplace = True) #O drop Na vai excluir os Nas da array, deixando ela menor\n", 913 | "resultado" 914 | ] 915 | }, 916 | { 917 | "cell_type": "code", 918 | "execution_count": 38, 919 | "id": "22f86b41-8924-426d-aafe-d3e9392e02f2", 920 | "metadata": {}, 921 | "outputs": [ 922 | { 923 | "data": { 924 | "text/plain": [ 925 | "3" 926 | ] 927 | }, 928 | "execution_count": 38, 929 | "metadata": {}, 930 | "output_type": "execute_result" 931 | } 932 | ], 933 | "source": [ 934 | "resultado.size" 935 | ] 936 | }, 937 | { 938 | "cell_type": "code", 939 | "execution_count": 39, 940 | "id": "f52f6d36-a03e-49d7-b521-99e9b1a431ec", 941 | "metadata": {}, 942 | "outputs": [ 943 | { 944 | "data": { 945 | "text/plain": [ 946 | "I 9.0\n", 947 | "II 30.0\n", 948 | "III -6.0\n", 949 | "IV 7.0\n", 950 | "V 7.0\n", 951 | "dtype: float64" 952 | ] 953 | }, 954 | "execution_count": 39, 955 | "metadata": {}, 956 | "output_type": "execute_result" 957 | } 958 | ], 959 | "source": [ 960 | "resultado = s6.sub(s7) \n", 961 | "resultado.fillna(7, inplace = True) #Já o fill Na vai trocar os Nas por algum valor especificado\n", 962 | "resultado" 963 | ] 964 | }, 965 | { 966 | "cell_type": "code", 967 | "execution_count": 40, 968 | "id": "061086ff-32d4-47b7-8718-4b3f29bf001c", 969 | "metadata": {}, 970 | "outputs": [ 971 | { 972 | "data": { 973 | "text/plain": [ 974 | "5" 975 | ] 976 | }, 977 | "execution_count": 40, 978 | "metadata": {}, 979 | "output_type": "execute_result" 980 | } 981 | ], 982 | "source": [ 983 | "resultado.size" 984 | ] 985 | }, 986 | { 987 | "cell_type": "markdown", 988 | "id": "7e82504f-001c-42d2-9751-b1075b10815f", 989 | "metadata": {}, 990 | "source": [ 991 | "## Ordenando séries" 992 | ] 993 | }, 994 | { 995 | "cell_type": "code", 996 | "execution_count": 41, 997 | "id": "f95b9296-1833-4327-ba0e-c5b503392cb1", 998 | "metadata": { 999 | "scrolled": true 1000 | }, 1001 | "outputs": [ 1002 | { 1003 | "data": { 1004 | "text/plain": [ 1005 | "I 10\n", 1006 | "II 42\n", 1007 | "III 7\n", 1008 | "V 1000000\n", 1009 | "I 1\n", 1010 | "II 12\n", 1011 | "III 13\n", 1012 | "IV -1\n", 1013 | "dtype: int64" 1014 | ] 1015 | }, 1016 | "execution_count": 41, 1017 | "metadata": {}, 1018 | "output_type": "execute_result" 1019 | } 1020 | ], 1021 | "source": [ 1022 | "s9" 1023 | ] 1024 | }, 1025 | { 1026 | "cell_type": "code", 1027 | "execution_count": 42, 1028 | "id": "f336fd71-8be1-4369-9714-16ce1402e6d1", 1029 | "metadata": {}, 1030 | "outputs": [ 1031 | { 1032 | "data": { 1033 | "text/plain": [ 1034 | "IV -1\n", 1035 | "I 1\n", 1036 | "III 7\n", 1037 | "I 10\n", 1038 | "II 12\n", 1039 | "III 13\n", 1040 | "II 42\n", 1041 | "V 1000000\n", 1042 | "dtype: int64" 1043 | ] 1044 | }, 1045 | "execution_count": 42, 1046 | "metadata": {}, 1047 | "output_type": "execute_result" 1048 | } 1049 | ], 1050 | "source": [ 1051 | "s9.sort_values() #Ordena usando valores" 1052 | ] 1053 | }, 1054 | { 1055 | "cell_type": "code", 1056 | "execution_count": 43, 1057 | "id": "da55b5bc-9015-4efd-bc18-435341ca34e4", 1058 | "metadata": {}, 1059 | "outputs": [ 1060 | { 1061 | "data": { 1062 | "text/plain": [ 1063 | "I 10\n", 1064 | "I 1\n", 1065 | "II 42\n", 1066 | "II 12\n", 1067 | "III 7\n", 1068 | "III 13\n", 1069 | "IV -1\n", 1070 | "V 1000000\n", 1071 | "dtype: int64" 1072 | ] 1073 | }, 1074 | "execution_count": 43, 1075 | "metadata": {}, 1076 | "output_type": "execute_result" 1077 | } 1078 | ], 1079 | "source": [ 1080 | "s9.sort_index() #Ordena usando índices" 1081 | ] 1082 | }, 1083 | { 1084 | "cell_type": "code", 1085 | "execution_count": 44, 1086 | "id": "daf6793c-e856-4aa0-8f12-ef4553adcf12", 1087 | "metadata": {}, 1088 | "outputs": [ 1089 | { 1090 | "name": "stdout", 1091 | "output_type": "stream", 1092 | "text": [ 1093 | "'<' not supported between instances of 'str' and 'int'\n" 1094 | ] 1095 | } 1096 | ], 1097 | "source": [ 1098 | "try:\n", 1099 | " pd.Series({1: 2, \"2\": 3}).sort_index() #Não é possível ordenar por índices mistos\n", 1100 | "except Exception as e:\n", 1101 | " print(e)" 1102 | ] 1103 | }, 1104 | { 1105 | "cell_type": "markdown", 1106 | "id": "34629bca-73d6-47bd-806c-e3ced61934d0", 1107 | "metadata": {}, 1108 | "source": [ 1109 | "## Universal Functions (ufuncs)" 1110 | ] 1111 | }, 1112 | { 1113 | "cell_type": "code", 1114 | "execution_count": 45, 1115 | "id": "1962c7ba-1daa-4611-99d6-8f58b2de418a", 1116 | "metadata": {}, 1117 | "outputs": [ 1118 | { 1119 | "data": { 1120 | "text/plain": [ 1121 | "I 10\n", 1122 | "II 42\n", 1123 | "III 7\n", 1124 | "V 1000000\n", 1125 | "I 1\n", 1126 | "II 12\n", 1127 | "III 13\n", 1128 | "IV -1\n", 1129 | "dtype: int64" 1130 | ] 1131 | }, 1132 | "execution_count": 45, 1133 | "metadata": {}, 1134 | "output_type": "execute_result" 1135 | } 1136 | ], 1137 | "source": [ 1138 | "s9" 1139 | ] 1140 | }, 1141 | { 1142 | "cell_type": "code", 1143 | "execution_count": 46, 1144 | "id": "23b6959e-6e0e-4a21-8ce1-cc02d0bee2ea", 1145 | "metadata": {}, 1146 | "outputs": [ 1147 | { 1148 | "data": { 1149 | "text/plain": [ 1150 | "np.int64(-1)" 1151 | ] 1152 | }, 1153 | "execution_count": 46, 1154 | "metadata": {}, 1155 | "output_type": "execute_result" 1156 | } 1157 | ], 1158 | "source": [ 1159 | "np.amin(s9) #Funções numpy pensadas para arrays podem ser usadas em séries" 1160 | ] 1161 | }, 1162 | { 1163 | "cell_type": "code", 1164 | "execution_count": 47, 1165 | "id": "414b214a-93c0-4fd5-a6db-57655f6fa587", 1166 | "metadata": {}, 1167 | "outputs": [ 1168 | { 1169 | "data": { 1170 | "text/plain": [ 1171 | "np.int64(1000001)" 1172 | ] 1173 | }, 1174 | "execution_count": 47, 1175 | "metadata": {}, 1176 | "output_type": "execute_result" 1177 | } 1178 | ], 1179 | "source": [ 1180 | "np.ptp(s9)" 1181 | ] 1182 | }, 1183 | { 1184 | "cell_type": "code", 1185 | "execution_count": 48, 1186 | "id": "9e3d19a5-f24f-4869-bc21-7cbc35eaee3f", 1187 | "metadata": {}, 1188 | "outputs": [ 1189 | { 1190 | "data": { 1191 | "text/plain": [ 1192 | "np.float64(5.5)" 1193 | ] 1194 | }, 1195 | "execution_count": 48, 1196 | "metadata": {}, 1197 | "output_type": "execute_result" 1198 | } 1199 | ], 1200 | "source": [ 1201 | "np.percentile(s9, 25)" 1202 | ] 1203 | }, 1204 | { 1205 | "cell_type": "code", 1206 | "execution_count": 49, 1207 | "id": "41065a7d-6881-4130-ab15-dabc7e4a1a20", 1208 | "metadata": {}, 1209 | "outputs": [ 1210 | { 1211 | "data": { 1212 | "text/plain": [ 1213 | "np.float64(125010.5)" 1214 | ] 1215 | }, 1216 | "execution_count": 49, 1217 | "metadata": {}, 1218 | "output_type": "execute_result" 1219 | } 1220 | ], 1221 | "source": [ 1222 | "np.mean(s9)" 1223 | ] 1224 | }, 1225 | { 1226 | "cell_type": "code", 1227 | "execution_count": 50, 1228 | "id": "6f8130e3-4a0f-48b2-ba3a-921342381fc0", 1229 | "metadata": {}, 1230 | "outputs": [ 1231 | { 1232 | "data": { 1233 | "text/plain": [ 1234 | "np.float64(11.0)" 1235 | ] 1236 | }, 1237 | "execution_count": 50, 1238 | "metadata": {}, 1239 | "output_type": "execute_result" 1240 | } 1241 | ], 1242 | "source": [ 1243 | "np.median(s9)" 1244 | ] 1245 | }, 1246 | { 1247 | "cell_type": "code", 1248 | "execution_count": 51, 1249 | "id": "99857f57-a335-4ba3-83e6-d7ba12cb58c3", 1250 | "metadata": {}, 1251 | "outputs": [ 1252 | { 1253 | "data": { 1254 | "text/plain": [ 1255 | "np.float64(330714.9454866683)" 1256 | ] 1257 | }, 1258 | "execution_count": 51, 1259 | "metadata": {}, 1260 | "output_type": "execute_result" 1261 | } 1262 | ], 1263 | "source": [ 1264 | "np.std(s9)" 1265 | ] 1266 | }, 1267 | { 1268 | "cell_type": "code", 1269 | "execution_count": 52, 1270 | "id": "dbe618dd-00db-4dac-90ea-3229ac4c3608", 1271 | "metadata": {}, 1272 | "outputs": [ 1273 | { 1274 | "data": { 1275 | "text/plain": [ 1276 | "np.float64(109372375168.25)" 1277 | ] 1278 | }, 1279 | "execution_count": 52, 1280 | "metadata": {}, 1281 | "output_type": "execute_result" 1282 | } 1283 | ], 1284 | "source": [ 1285 | "np.var(s9)" 1286 | ] 1287 | }, 1288 | { 1289 | "cell_type": "code", 1290 | "execution_count": 53, 1291 | "id": "8b87d886-db7a-4ec4-a755-51fcfdab5795", 1292 | "metadata": {}, 1293 | "outputs": [ 1294 | { 1295 | "data": { 1296 | "text/plain": [ 1297 | "np.float64(125010.5)" 1298 | ] 1299 | }, 1300 | "execution_count": 53, 1301 | "metadata": {}, 1302 | "output_type": "execute_result" 1303 | } 1304 | ], 1305 | "source": [ 1306 | "np.average(s9)" 1307 | ] 1308 | }, 1309 | { 1310 | "cell_type": "code", 1311 | "execution_count": 54, 1312 | "id": "607844ad-3c0d-497a-bd13-8468f1fedee7", 1313 | "metadata": {}, 1314 | "outputs": [ 1315 | { 1316 | "name": "stdout", 1317 | "output_type": "stream", 1318 | "text": [ 1319 | "Return the minimum of an array or minimum along an axis.\n", 1320 | "\n", 1321 | "`amin` is an alias of `~numpy.min`.\n", 1322 | "\n", 1323 | "See Also\n", 1324 | "--------\n", 1325 | "min : alias of this function\n", 1326 | "ndarray.min : equivalent method\n" 1327 | ] 1328 | } 1329 | ], 1330 | "source": [ 1331 | "np.info(np.amin)" 1332 | ] 1333 | }, 1334 | { 1335 | "cell_type": "code", 1336 | "execution_count": 55, 1337 | "id": "6b2cb8ca-8e8a-4aec-941f-b2bdab4af0a5", 1338 | "metadata": {}, 1339 | "outputs": [ 1340 | { 1341 | "data": { 1342 | "text/plain": [ 1343 | "count 8.000000\n", 1344 | "mean 125010.500000\n", 1345 | "std 353549.148199\n", 1346 | "min -1.000000\n", 1347 | "25% 5.500000\n", 1348 | "50% 11.000000\n", 1349 | "75% 20.250000\n", 1350 | "max 1000000.000000\n", 1351 | "dtype: float64" 1352 | ] 1353 | }, 1354 | "execution_count": 55, 1355 | "metadata": {}, 1356 | "output_type": "execute_result" 1357 | } 1358 | ], 1359 | "source": [ 1360 | "s9.describe() #As séries oferecem o método describe, já que é comum analisar datasets usando `pandas`" 1361 | ] 1362 | } 1363 | ], 1364 | "metadata": { 1365 | "kernelspec": { 1366 | "display_name": "faculdade", 1367 | "language": "python", 1368 | "name": "faculdade" 1369 | }, 1370 | "language_info": { 1371 | "codemirror_mode": { 1372 | "name": "ipython", 1373 | "version": 3 1374 | }, 1375 | "file_extension": ".py", 1376 | "mimetype": "text/x-python", 1377 | "name": "python", 1378 | "nbconvert_exporter": "python", 1379 | "pygments_lexer": "ipython3", 1380 | "version": "3.12.5" 1381 | } 1382 | }, 1383 | "nbformat": 4, 1384 | "nbformat_minor": 5 1385 | } 1386 | --------------------------------------------------------------------------------