├── README.md ├── aulas ├── Semana 1 - Revisao Python │ ├── 1_apresentacao.md │ ├── 2_diferencas_c_python.md │ ├── 2_programming-taxonomy.webp │ ├── 3_dados_condicionais_loops.md │ ├── 4_funcoes_modulos.md │ ├── 4_function_syntax.webp │ ├── sum.c │ └── sum.py ├── Semana 10 - Classes │ ├── 31_classes_heranca.md │ ├── 31_codigo_aula.py │ └── 32_codigo_aula.py ├── Semana 11 - Classes │ ├── 33_classes_exercicios.md │ ├── 33_codigo_aula.py │ ├── 34_classes_polimorfismo.md │ ├── 34_codigo_aula.py │ ├── 35_classes_associacao_agregacao_composicao.md │ └── 35_codigo_aula.py ├── Semana 12 - Pygame │ ├── 36_codigo_aula.py │ ├── 36_pygame_introducao.md │ ├── 37_pygame_movimento_colisao.md │ └── 38_codigo_aula.py ├── Semana 13 - Pygame │ ├── 38_codigo_aula.py │ ├── 39_pygame_sprite_animacao.md │ ├── 40_codigo_aula.py │ ├── 40_pygame_interfaces.md │ └── sprites │ │ ├── background.png │ │ ├── link.png │ │ ├── link │ │ ├── down │ │ │ ├── link_down_0.png │ │ │ ├── link_down_1.png │ │ │ ├── link_down_2.png │ │ │ ├── link_down_3.png │ │ │ ├── link_down_4.png │ │ │ ├── link_down_5.png │ │ │ ├── link_down_6.png │ │ │ ├── link_down_7.png │ │ │ ├── link_down_8.png │ │ │ └── link_down_9.png │ │ ├── down_idle │ │ │ ├── link_down_idle_0.png │ │ │ ├── link_down_idle_1.png │ │ │ └── link_down_idle_2.png │ │ ├── left │ │ │ ├── link_left_0.png │ │ │ ├── link_left_1.png │ │ │ ├── link_left_2.png │ │ │ ├── link_left_3.png │ │ │ ├── link_left_4.png │ │ │ ├── link_left_5.png │ │ │ ├── link_left_6.png │ │ │ ├── link_left_7.png │ │ │ ├── link_left_8.png │ │ │ └── link_left_9.png │ │ ├── left_idle │ │ │ ├── link_left_idle_0.png │ │ │ ├── link_left_idle_1.png │ │ │ └── link_left_idle_2.png │ │ ├── link_animation.png │ │ ├── right │ │ │ ├── link_right_0.png │ │ │ ├── link_right_1.png │ │ │ ├── link_right_2.png │ │ │ ├── link_right_3.png │ │ │ ├── link_right_4.png │ │ │ ├── link_right_5.png │ │ │ ├── link_right_6.png │ │ │ ├── link_right_7.png │ │ │ ├── link_right_8.png │ │ │ └── link_right_9.png │ │ ├── right_idle │ │ │ ├── link_right_idle_0.png │ │ │ ├── link_right_idle_1.png │ │ │ └── link_right_idle_2.png │ │ ├── up │ │ │ ├── link_up_0.png │ │ │ ├── link_up_1.png │ │ │ ├── link_up_2.png │ │ │ ├── link_up_3.png │ │ │ ├── link_up_4.png │ │ │ ├── link_up_5.png │ │ │ ├── link_up_6.png │ │ │ ├── link_up_7.png │ │ │ ├── link_up_8.png │ │ │ └── link_up_9.png │ │ └── up_idle │ │ │ └── link_up_idle_0.png │ │ └── powerup.png ├── Semana 14 - Pygame │ └── 41_pygame_breakout │ │ ├── assets │ │ ├── README.md │ │ └── sprite │ │ │ ├── ball │ │ │ └── 58-Breakout-Tiles.png │ │ │ ├── block │ │ │ ├── 21-Breakout-Tiles.png │ │ │ ├── 22-Breakout-Tiles.png │ │ │ ├── 23-Breakout-Tiles.png │ │ │ ├── 24-Breakout-Tiles.png │ │ │ ├── 25-Breakout-Tiles.png │ │ │ ├── 26-Breakout-Tiles.png │ │ │ ├── 27-Breakout-Tiles.png │ │ │ ├── 28-Breakout-Tiles.png │ │ │ ├── 29-Breakout-Tiles.png │ │ │ └── 30-Breakout-Tiles.png │ │ │ ├── brick │ │ │ ├── 01-Breakout-Tiles.png │ │ │ ├── 02-Breakout-Tiles.png │ │ │ ├── 03-Breakout-Tiles.png │ │ │ ├── 04-Breakout-Tiles.png │ │ │ ├── 05-Breakout-Tiles.png │ │ │ ├── 06-Breakout-Tiles.png │ │ │ ├── 07-Breakout-Tiles.png │ │ │ ├── 08-Breakout-Tiles.png │ │ │ ├── 09-Breakout-Tiles.png │ │ │ ├── 10-Breakout-Tiles.png │ │ │ ├── 11-Breakout-Tiles.png │ │ │ ├── 12-Breakout-Tiles.png │ │ │ ├── 13-Breakout-Tiles.png │ │ │ ├── 14-Breakout-Tiles.png │ │ │ ├── 15-Breakout-Tiles.png │ │ │ ├── 16-Breakout-Tiles.png │ │ │ ├── 17-Breakout-Tiles.png │ │ │ ├── 18-Breakout-Tiles.png │ │ │ ├── 19-Breakout-Tiles.png │ │ │ └── 20-Breakout-Tiles.png │ │ │ ├── paddle │ │ │ ├── 50-Breakout-Tiles.png │ │ │ ├── 51-Breakout-Tiles.png │ │ │ ├── 52-Breakout-Tiles.png │ │ │ ├── 53-Breakout-Tiles.png │ │ │ ├── 54-Breakout-Tiles.png │ │ │ ├── 55-Breakout-Tiles.png │ │ │ ├── 56-Breakout-Tiles.png │ │ │ ├── 57-Breakout-Tiles.png │ │ │ └── 61-Breakout-Tiles.png │ │ │ └── powerups │ │ │ ├── 31-Breakout-Tiles.png │ │ │ ├── 32-Breakout-Tiles.png │ │ │ ├── 33-Breakout-Tiles.png │ │ │ ├── 34-Breakout-Tiles.png │ │ │ ├── 35-Breakout-Tiles.png │ │ │ ├── 36-Breakout-Tiles.png │ │ │ ├── 37-Breakout-Tiles.png │ │ │ ├── 38-Breakout-Tiles.png │ │ │ ├── 39-Breakout-Tiles.png │ │ │ ├── 40-Breakout-Tiles.png │ │ │ ├── 41-Breakout-Tiles.png │ │ │ ├── 42-Breakout-Tiles.png │ │ │ ├── 43-Breakout-Tiles.png │ │ │ ├── 44-Breakout-Tiles.png │ │ │ ├── 45-Breakout-Tiles.png │ │ │ ├── 46-Breakout-Tiles.png │ │ │ ├── 47-Breakout-Tiles.png │ │ │ ├── 48-Breakout-Tiles.png │ │ │ ├── 49-Breakout-Tiles.png │ │ │ ├── 59-Breakout-Tiles.png │ │ │ └── 60-Breakout-Tiles.png │ │ ├── config │ │ └── config.json │ │ └── src │ │ ├── breakout.py │ │ ├── game_objects.py │ │ └── utils.py ├── Semana 2 - Revisao Python │ ├── 5_car_class.jpg │ ├── 5_objetos_classes.md │ ├── 6_data_structures.jpg │ ├── 6_estruturas_de_dados.md │ ├── 7_mutabable_objects.md │ ├── 8_input_output.md │ ├── 9_lista_1.md │ ├── 9_lista_1_gabarito.py │ ├── nintendo.txt │ ├── vgsales.csv │ └── vgsales.json ├── Semana 3 - Documentacao & Type Hint │ ├── 10_documentacao.md │ ├── 11_type_hint.md │ ├── 12_similaridade_documentos.md │ └── wikipedia_good_articles_video_games.zip ├── Semana 4 - Excecoes & Teste Unitarios │ ├── 13_erros.md │ ├── 14_excecoes.md │ ├── 15_depuracao.md │ └── 16_testes_automatizados.md ├── Semana 5 - Sphinx & Programação Funcional │ ├── 17_organizacao_codigo_projeto.md │ ├── 18_documentacao_projeto.md │ └── 19_programacao_funcional.md ├── Semana 6 - Numpy │ ├── 20_numpy_introducao.md │ ├── 21_numpy_operacoes.md │ ├── 22_numpy_estatisticas_algebra.md │ ├── 23_lista_2.md │ ├── check_sudoku.py │ └── vgsales_subset.txt ├── Semana 7 - Pandas │ ├── 24_pandas_series.md │ ├── 25_pandas_dataframe.md │ ├── 26_pandas_preparando_dados.md │ ├── analise_steam.py │ ├── analise_vgsales.py │ ├── dados.zip │ └── dados_fonte.txt ├── Semana 8 - Pandas │ ├── 27_pandas_agregacao.png │ ├── 27_pandas_agrupamento.md │ └── 28_pandas_visualizacao.md └── Semana 9 - Classes │ ├── 29_classes_basico.md │ ├── 29_codigo_aula.py │ ├── 30_classes_encapsulamento.md │ └── 30_codigo_aula.py ├── projeto_similaridade_de_documentos ├── .gitignore ├── data │ └── wikipedia_good_articles_video_games.zip ├── docs │ └── .placeholder ├── readme.md ├── requirements.txt ├── src │ ├── __init__.py │ ├── data_loader.py │ ├── main.py │ ├── metrics.py │ ├── search.py │ └── text.py ├── tests │ ├── __init__.py │ ├── test_data_loader.py │ ├── test_metrics.py │ ├── test_search.py │ └── test_text.py └── versao_antiga │ └── main.py └── pygame └── 38_codigo_aula.py /README.md: -------------------------------------------------------------------------------- 1 | # Linguagens de Programação 2 | 3 | Material de apoio ao curso de Linguagens de Programação da EMAp-FGV 4 | -------------------------------------------------------------------------------- /aulas/Semana 1 - Revisao Python/1_apresentacao.md: -------------------------------------------------------------------------------- 1 | # Apresentação do Curso 2 | 3 | ## Objetivo 4 | 5 | Este curso visa aprofundar os conhecimentos em Python, dando continuidade ao conteúdo introduzido na disciplina de Introdução à Computação. 6 | O objetivo principal é solidificar os conceitos já aprendidos e capacitar os alunos a lidar com algumas das principais bibliotecas da linguagem Python. 7 | 8 | Os alunos de Matemática Aplicada enfrentarão um desafio adicional, pois precisam se adaptar à linguagem Python após terem aprendido C. 9 | Qualquer dúvida em relação às diferenças de comportamento e sintaxe entre essas linguagens pode ser esclarecida durante o curso. 10 | 11 | ## Estrutura do curso 12 | 13 | ### Tópicos 14 | 15 | Neste curso, abordaremos os seguintes tópicos (não necessariamente nesta ordem): 16 | 1. Revisão de python básica 17 | 2. Numpy 18 | 3. Pandas 19 | 4. Visualização de Dados 20 | 5. Qualidade de Software 21 | 6. \[Ainda a definir\] Programação Modular 22 | 7. \[Ainda a definir\] Orientação a Objetos 23 | 24 | A1 = Tópicos 1 a 5\ 25 | A2 = Restante 26 | 27 | ### Avaliação 28 | 29 | A média da disciplina é calculada da seguinte forma: 30 | 31 | $$ 32 | \text{Média} = 33 | \begin{cases} 34 | \frac{A1 + A2}{2}, & \text{se } \frac{A1 + A2}{2} \geq 6.0 \\ 35 | \frac{\max(A1, A2) + AS}{2}, & \text{caso contrário} 36 | \end{cases} 37 | $$ 38 | 39 | Onde: 40 | - \( A1 \) é a nota da primeira avaliação. 41 | - \( A2 \) é a nota da segunda avaliação. 42 | - \( AS \) é a nota da avaliação substitutiva. 43 | 44 | ## Material de Apoio 45 | 46 | Abaixo se encontram alguns materiais que podem ser úteis ao longo da disciplina. 47 | 48 | **Livros**: 49 | * McKinney, Wes. "Python para análise de dados: Tratamento de dados com Pandas, NumPy e IPython". Novatec Editora, 2019. 50 | * Martin, Robert C. "Código limpo: habilidades práticas do Agile software". Alta Books Grupo Editorial, 2019. 51 | 52 | **Videos**: 53 | * [Harvard CS50’s Introduction to Programming with Python – Full University Course](https://www.youtube.com/watch?v=nLRL_NcnK-4) 54 | * [Data Analysis with Python - Full Course for Beginners (Numpy, Pandas, Matplotlib, Seaborn)](https://www.youtube.com/watch?v=r-uOLxNrNk8) 55 | * [Pandas & Python for Data Analysis by Example – Full Course for Beginners](https://www.youtube.com/watch?v=gtjxAH8uaP0) 56 | 57 | **Sites**: 58 | * https://www.reddit.com/r/learnpython/wiki/index/#wiki_new_to_programming.3F 59 | * https://www.geeksforgeeks.org/ 60 | * https://stackoverflow.com/ 61 | * https://youtube.com/ 62 | * https://google.com/ 63 | * ... 64 | -------------------------------------------------------------------------------- /aulas/Semana 1 - Revisao Python/2_diferencas_c_python.md: -------------------------------------------------------------------------------- 1 | # C vs Python 2 | 3 | ## Classificação de Linguagens 4 | 5 | Linguagens de programação podem ser divididas em relação a diversos aspectos da linguagem. 6 | 7 | ### Imperativa vs Declarativa 8 | 9 | * **Imperativas**: 10 | Focam em "como" o programa deve ser executado, especificando passo a passo as instruções que o computador deve seguir. 11 | Exemplo: C, Python 12 | 13 | * **Declarativas**: 14 | Focam em "o que" deve ser realizado, descrevendo o resultado desejado sem especificar os passos para alcançar esse resultado. 15 | Exemplo: SQL, HTML 16 | 17 | ### Procedural vs Orientada a Objetos 18 | 19 | * **Procedural**: 20 | Baseadas em procedimentos ou funções, onde o código é organizado em sub-rotinas. 21 | Exemplo: C 22 | 23 | * **Orientada a Objetos**: 24 | Baseadas em objetos, que são instâncias de classes, encapsulando dados e comportamentos. 25 | Exemplo: Python, Java 26 | 27 |

28 | 29 |

30 | 31 | ## Linguagem compilada vs interpretada 32 | 33 | No caso de Python e C, uma das principais diferenças entre eles é o fato de da primeira ser interpretada, 34 | enquanto a segunda ser compilada. 35 | 36 | ### Compilada 37 | 38 | Em linguagens compiladas, o código-fonte escrito pelo desenvolvedor é traduzido para código de máquina por meio de um compilador. 39 | Este processo gera um arquivo executável que pode ser diretamente executado pelo sistema operacional da máquina alvo. 40 | 41 | Processo de Compilação: 42 | 1. Escrita do Código-Fonte: O desenvolvedor escreve o programa em uma linguagem de alto nível (ex.: C). 43 | 2. Compilação: Um compilador traduz o código-fonte para código de máquina (binário) específico para a arquitetura do computador. 44 | 3. Execução: O arquivo executável gerado é executado diretamente pela CPU. 45 | 46 | Exemplo de Linguagem Compilada: C, C++, Rust, Go 47 | 48 | ### Interpretada 49 | 50 | Em linguagens interpretadas, o código-fonte é executado linha por linha por um interpretador, sem a necessidade de tradução prévia para código de máquina. O interpretador lê o código-fonte e o executa diretamente, convertendo-o para código de máquina durante a execução. 51 | 52 | Processo de Interpretação: 53 | 1. Escrita do Código-Fonte: O desenvolvedor escreve o programa em uma linguagem de alto nível (ex.: Python). 54 | 2. Interpretação: Um interpretador lê e executa o código-fonte linha por linha. 55 | 3. Execução Imediata: O interpretador converte o código-fonte para código de máquina e executa cada instrução em tempo real. 56 | 57 | Exemplo de Linguagem Interpretada: Python, JavaScript, Ruby, PHP 58 | 59 | ## Exemplo 60 | 61 | Vamos criar um programa simples em ambas as linguagens que lê um número $n$ do usuário, soma todos os números de $1$ até $n$, e imprime o resultado. 62 | 63 | ### C (Compilada) 64 | 65 | ```c 66 | #include 67 | 68 | int main(int argc, char *argv[]) { 69 | int n = atoi(argv[1]); 70 | 71 | int sum = 0; 72 | for (int i = 0; i < n; i++) { 73 | sum += i; 74 | } 75 | 76 | printf("The sum is: %d\n", sum); 77 | 78 | return 0; 79 | } 80 | ``` 81 | 82 | Passo-a-passo: 83 | 1. Escrever o código em um editor de texto. 84 | 2. Compilar o código usando um compilador C (ex.: gcc program.c -o program). 85 | 3. Executar o arquivo gerado (./program). 86 | 87 | ### Python (Interpretada) 88 | 89 | ```python 90 | import sys 91 | n = int(sys.argv[1]) 92 | 93 | total_sum = 0 94 | for i in range(n): 95 | total_sum += i 96 | 97 | print("The sum is:", total_sum) 98 | ``` 99 | 100 | Passo-a-passo: 101 | 1. Escrever o código em um editor de texto. 102 | 2. Executar diretamente o código-fonte usando o interpretador Python (python program.py). 103 | 104 | ## Vantagens e Desvantagens 105 | 106 | ### C 107 | 108 | Vantagens: 109 | 1. Alta performance e eficiência. 110 | 2. Controle preciso sobre recursos do sistema. 111 | 3. Ampla utilização em desenvolvimento de sistemas operacionais e aplicações que exigem alta performance. 112 | 113 | Desvantagens: 114 | 1. Sintaxe complexa e propensa a erros. 115 | 2. Gerenciamento manual de memória. 116 | 3. Curva de aprendizado mais íngreme. 117 | 118 | ### Python 119 | 120 | Vantagens: 121 | 1. Sintaxe simples e fácil de aprender. 122 | 2. Alta produtividade e rapidez no desenvolvimento. 123 | 3. Grande quantidade de bibliotecas e uma comunidade ativa. 124 | 125 | Desvantagens: 126 | 1. Performance menor em comparação com linguagens compiladas. 127 | 2. Menos controle sobre recursos do sistema. 128 | 3. Pode não ser a melhor escolha para aplicações que exigem máxima performance. -------------------------------------------------------------------------------- /aulas/Semana 1 - Revisao Python/2_programming-taxonomy.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 1 - Revisao Python/2_programming-taxonomy.webp -------------------------------------------------------------------------------- /aulas/Semana 1 - Revisao Python/4_function_syntax.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 1 - Revisao Python/4_function_syntax.webp -------------------------------------------------------------------------------- /aulas/Semana 1 - Revisao Python/sum.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | int n; 5 | printf("Digite um número: "); 6 | scanf("%d", &n); 7 | 8 | int total = 0; 9 | for(int i = 0; i < n; i++) { 10 | total += i; 11 | } 12 | 13 | printf("A soma é %d\n", total); 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /aulas/Semana 1 - Revisao Python/sum.py: -------------------------------------------------------------------------------- 1 | n = input("Digite um número: ") 2 | n = int(n) 3 | 4 | total_sum = 0 5 | for i in range(n): 6 | total_sum += i 7 | 8 | print("A soma é ", total_sum) 9 | 10 | 11 | -------------------------------------------------------------------------------- /aulas/Semana 10 - Classes/31_codigo_aula.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | class Personagem: 4 | 5 | def __init__(self, vida, ataque_min, ataque_max, defesa): 6 | self.vida = vida 7 | self.ataque_min = ataque_min 8 | self.ataque_max = ataque_max 9 | self.defesa = defesa 10 | 11 | def ataque(self, outro): 12 | ataque = random.randint(self.ataque_min, self.ataque_max) 13 | delta = ataque - outro.defesa 14 | outro.vida -= max(0, delta) 15 | 16 | class SimuladorBatalha: 17 | 18 | def __init__(self, p1: Personagem, p2: Personagem) -> None: 19 | self.p1: Personagem = p1 20 | self.p2: Personagem = p2 21 | 22 | def batalhar(self): 23 | round = 1 24 | while self.p1.vida > 0 and self.p2.vida > 0: 25 | print(f"Round #{round}") 26 | n = random.randint(0, 100) 27 | if n > 50: 28 | print("P1 atacou!") 29 | self.p1.ataque(self.p2) 30 | else: 31 | print("P2 atacou!") 32 | self.p2.ataque(self.p1) 33 | print(f"p1: {p1.vida}") 34 | print(f"p2: {p2.vida}") 35 | print() 36 | round += 1 37 | if self.p1.vida <= 0: 38 | print("P2 venceu!") 39 | else: 40 | print("P1 venceu!") 41 | 42 | p1 = Personagem(100, 10, 20, 10) 43 | p2 = Personagem(100, 20, 40, 0) 44 | similador = SimuladorBatalha(p1, p2) 45 | similador.batalhar() -------------------------------------------------------------------------------- /aulas/Semana 10 - Classes/32_codigo_aula.py: -------------------------------------------------------------------------------- 1 | class Pagamento: 2 | 3 | def __init__(self, valor, data, status): 4 | self.valor = valor # Atributo de instância 5 | self.data = data # Atributo de instância 6 | self.status = status # Atributo de instância 7 | 8 | def info(self): 9 | """Retorna informações básicas sobre o pagamento.""" 10 | return f"Pagamento de R${self.valor:.2f} a ser pago até {self.data}. Status: {self.status}." 11 | 12 | def executar_operacao(self): 13 | raise NotImplemented('Implemente agora!') 14 | 15 | pag = Pagamento(100, '2024-10-18', 'pendente') 16 | print(pag.info()) 17 | 18 | class PagamentoCartaoCredito(Pagamento): 19 | 20 | def __init__(self, valor: float, data: str, status: str, n_cartao: str): 21 | super().__init__(valor, data, status) 22 | if not self.__validar(n_cartao): 23 | raise ValueError('Numero invalido') 24 | self.n_cartao = n_cartao 25 | 26 | def __validar(self, n_cartao: str) -> bool: 27 | return True 28 | 29 | def info(self): 30 | msg_base = super().info() 31 | msg = msg_base + f'\nNumero do cartao: {self.n_cartao}' 32 | return msg 33 | 34 | def executar_operacao(self): 35 | print("Executou tambem!") 36 | 37 | class PagamentoPix(Pagamento): 38 | 39 | def __init__(self, valor: float, data: str, status: str, chave_devedor, chave_credor): 40 | super().__init__(valor, data, status) 41 | if not self.__validar_chave(chave_devedor): 42 | raise ValueError('Chave do devedor invalida') 43 | if not self.__validar_chave(chave_credor): 44 | raise ValueError('Chave do credor') 45 | self.chave_devedor = chave_devedor 46 | self.chave_credor = chave_credor 47 | 48 | def __validar_chave(self, chave): 49 | return True 50 | 51 | def info(self): 52 | msg_base = super().info() 53 | msg = msg_base + f'\nChave credor: {self.chave_credor}' 54 | msg = msg + f'\nChave devedor: {self.chave_devedor}' 55 | return msg 56 | 57 | def executar_operacao(self): 58 | print("Executou!") 59 | 60 | 61 | pix = PagamentoPix(1_000, '2020-01-01', 'Pago', '111.111.111.90', '24232u5rhljtilwhnuvp8g') 62 | cred = PagamentoCartaoCredito(10_000, '2024-01-01', 'Processando', '5561 0689 1331 4792') 63 | 64 | print(pix.chave_credor) 65 | print(cred.n_cartao) 66 | 67 | print(pix.data) 68 | print(cred.data) 69 | 70 | print() 71 | print(pix.info()) 72 | print() 73 | print(cred.info()) 74 | 75 | 76 | print(pix.executar_operacao()) 77 | print(cred.executar_operacao()) -------------------------------------------------------------------------------- /aulas/Semana 11 - Classes/33_classes_exercicios.md: -------------------------------------------------------------------------------- 1 | # Orientação a Objetos: Exercícios 2 | 3 | ## 1. Sistema de Gestão de Biblioteca 4 | - **Classe `Book`**: 5 | - Atributos: 6 | - `title`: (string) nome do livro. 7 | - `author`: (string) autor do livro. 8 | - `isbn`: (string) código ISBN do livro. 9 | - **Classe `Library`**: 10 | - Atributos: 11 | - `books`: (lista) uma lista que armazena objetos `Book`. 12 | - Métodos: 13 | - `add_book(book)`: adiciona um objeto `Book` à lista de livros. 14 | - `remove_book(isbn)`: remove um livro da lista com base no ISBN. Se o livro não existir, deve exibir uma mensagem informando. 15 | - `search_by_title(title)`: procura um livro pelo título e retorna suas informações. Se não encontrado, deve exibir uma mensagem informando. 16 | - `search_by_author(author)`: procura livros pelo autor e retorna uma lista de livros correspondentes. 17 | 18 | - **Testar** 19 | 20 | ```python 21 | class LibraryApp: 22 | def __init__(self): 23 | self.library = Library() 24 | 25 | def run(self): 26 | while True: 27 | print("\n--- Library Menu ---") 28 | print("1. Add Book") 29 | print("2. Remove Book") 30 | print("3. Search by Title") 31 | print("4. Search by Author") 32 | print("5. List All Books") 33 | print("6. Exit") 34 | 35 | choice = input("Choose an option: ") 36 | 37 | if choice == '1': 38 | title = input("Enter book title: ") 39 | author = input("Enter book author: ") 40 | isbn = input("Enter book ISBN: ") 41 | self.library.add_book(Book(title, author, isbn)) 42 | 43 | elif choice == '2': 44 | isbn = input("Enter book ISBN to remove: ") 45 | self.library.remove_book(isbn) 46 | 47 | elif choice == '3': 48 | title = input("Enter book title to search: ") 49 | books = self.library.search_by_title(title) 50 | if books: 51 | for book in books: 52 | print(book) 53 | else: 54 | print('No books found with that title.') 55 | 56 | elif choice == '4': 57 | author = input("Enter author name to search: ") 58 | books = self.library.search_by_author(author) 59 | if books: 60 | for book in books: 61 | print(book) 62 | else: 63 | print('No books found by that author.') 64 | 65 | elif choice == '5': 66 | self.library.list_books() 67 | 68 | elif choice == '6': 69 | print('Exiting...') 70 | break 71 | 72 | else: 73 | print('Invalid choice, please try again.') 74 | 75 | 76 | if __name__ == "__main__": 77 | app = LibraryApp() 78 | app.run() 79 | ``` 80 | 81 | ## 2. Sistema de Gerenciamento de Estoque 82 | - **Classe `Product`**: 83 | - Atributos: 84 | - `name`: (string) nome do produto. 85 | - `quantity`: (int) quantidade disponível em estoque. 86 | - `price`: (float) preço do produto. 87 | - Métodos: 88 | - `__init__(self, name, quantity, price)`: inicializa um novo produto. 89 | - `update_quantity(self, amount)`: atualiza a quantidade do produto. O parâmetro `amount` pode ser positivo (para adicionar) ou negativo (para remover). 90 | - `get_info(self)`: retorna uma string com as informações do produto, incluindo nome, quantidade e preço. 91 | - **Classe `Inventory`**: 92 | - Atributos: 93 | - `products`: (lista) uma lista que armazena objetos `Product`. 94 | - Métodos: 95 | - `__init__(self)`: inicializa um novo inventário vazio. 96 | - `add_product(self, product)`: adiciona um objeto `Product` à lista de produtos. 97 | - `remove_product(self, product_name)`: remove um produto da lista com base no nome. Se o produto não existir, deve exibir uma mensagem informando. 98 | - `list_products(self)`: exibe todos os produtos no inventário com suas informações. 99 | - `find_product(self, product_name)`: procura um produto pelo nome e retorna suas informações. Se não encontrado, deve exibir uma mensagem informando. 100 | 101 | - **Testar** 102 | 103 | ```python 104 | class InventoryApp: 105 | def __init__(self): 106 | self.inventory = Inventory() 107 | 108 | def run(self): 109 | while True: 110 | print("\n--- Inventory Menu ---") 111 | print("1. Add Product") 112 | print("2. Remove Product") 113 | print("3. List Products") 114 | print("4. Find Product") 115 | print("5. Exit") 116 | 117 | choice = input("Choose an option: ") 118 | 119 | if choice == '1': 120 | name = input("Enter product name: ") 121 | quantity = int(input("Enter quantity: ")) 122 | price = float(input("Enter price: ")) 123 | self.inventory.add_product(Product(name, quantity, price)) 124 | 125 | elif choice == '2': 126 | name = input("Enter product name to remove: ") 127 | self.inventory.remove_product(name) 128 | 129 | elif choice == '3': 130 | self.inventory.list_products() 131 | 132 | elif choice == '4': 133 | name = input("Enter product name to find: ") 134 | info = self.inventory.find_product(name) 135 | print(info) 136 | 137 | elif choice == '5': 138 | print('Exiting...') 139 | break 140 | 141 | else: 142 | print('Invalid choice, please try again.') 143 | 144 | 145 | if __name__ == "__main__": 146 | app = InventoryApp() 147 | app.run() 148 | ``` 149 | 150 | ## 3. Estrutura Básica de Classes: Jogo da Cobra 151 | - **Classe `Snake`**: 152 | - Atributos: 153 | - `length`: (int) comprimento da cobra. 154 | - `direction`: (string) direção atual da cobra (ex: "cima", "baixo", "esquerda", "direita"). 155 | - `position`: (tuple) posição atual da cabeça da cobra (x, y). 156 | - Métodos: 157 | - `move()`: atualiza a posição da cobra com base na direção atual. 158 | - `grow()`: aumenta o comprimento da cobra em 1 unidade. 159 | - `change_direction(new_direction)`: atualiza a direção da cobra. 160 | - `check_collision()`: verifica se a cobra colide consigo mesma ou com as bordas do jogo. Retorna um booleano. 161 | 162 | ## 4. Herança: Power-ups no Jogo da Cobra 163 | - **Classe base `PowerUp`**: 164 | - Atributos: 165 | - `position`: (tuple) posição do power-up (x, y). 166 | - `duration`: (int) duração do efeito do power-up em segundos. 167 | - **Subclasses**: 168 | - `SpeedBoost`: aumenta a velocidade da cobra temporariamente. 169 | - `SlowDown`: diminui a velocidade da cobra temporariamente. 170 | - `Grow`: aumenta o comprimento da cobra temporariamente. 171 | - Métodos: 172 | - `apply(snake)`: aplica o efeito do power-up à cobra. 173 | - `expire(snake)`: remove o efeito do power-up da cobra após a duração expirar. 174 | 175 | ## 5. Estrutura Básica de Classes: Jogo Tetris (Rotação de Peças) 176 | - **Classe `TetrisPiece`**: 177 | - Atributos: 178 | - `shape`: (lista de listas) representa a forma da peça. 179 | - `position`: (tuple) posição atual da peça na grade (x, y). 180 | - `orientation`: (int) orientação atual da peça em graus (0, 90, 180, 270). 181 | - Métodos: 182 | - `rotate()`: altera a orientação da peça 90 graus no sentido horário. 183 | - `move_left()`, `move_right()`, `move_down()`: desloca a peça na grade na direção especificada. 184 | - `check_collision()`: verifica se a peça colide com as paredes ou outras peças. Retorna um booleano. 185 | 186 | ## 6. Herança: Peças de Tetris 187 | - **Classe base `TetrisPiece`**: 188 | - Atributos: 189 | - `shape`: (lista de listas) forma da peça. 190 | - `color`: (string) cor da peça. 191 | - **Subclasses**: 192 | - `LinePiece`, `SquarePiece`, `TPiece`, etc., cada uma com formas iniciais únicas. 193 | - Métodos: 194 | - `rotate()`: sobrescreve o método de rotação, se necessário, para peças que se comportam de maneira diferente. 195 | - `move_left()`, `move_right()`, `move_down()`: cada peça pode ter implementações específicas de movimentação. 196 | -------------------------------------------------------------------------------- /aulas/Semana 11 - Classes/33_codigo_aula.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Book: 4 | 5 | def __init__(self, title: str, author: str, isbn: str) -> None: 6 | self.title : str = title 7 | self.author : str = author 8 | self.isbn : str = isbn 9 | 10 | def __str__(self) -> str: 11 | return f"Titulo: {self.title}\nAutor: {self.author}\nISBN: {self.isbn}" 12 | 13 | class Library: 14 | 15 | def __init__(self) -> None: 16 | self.books : List[Book] = [] 17 | 18 | def add_book(self, book: Book) -> None: 19 | if book is None: 20 | raise ValueError("Nao foi passado nenhum livro") 21 | if self.search_by_isbn(book.isbn) is not None: 22 | return 23 | self.books.append(book) 24 | 25 | def remove_book(self, isbn: str) -> None: 26 | book = self.search_by_isbn(isbn) 27 | if book is not None: 28 | self.books.remove(book) 29 | 30 | def search_by_isbn(self, isbn: str) -> Book: 31 | for book in self.books: 32 | if book.isbn == isbn: 33 | return book 34 | return None 35 | 36 | def search_by_title(self, search_text: str) -> List[Book]: 37 | selected_book = [] 38 | for book in self.books: 39 | if search_text in book.title: 40 | selected_book.append(book) 41 | return selected_book 42 | 43 | def search_by_author(self, search_text: str) -> List[Book]: 44 | selected_book = [] 45 | for book in self.books: 46 | if search_text in book.author: 47 | selected_book.append(book) 48 | return selected_book 49 | 50 | class LibraryApp: 51 | def __init__(self): 52 | self.library = Library() 53 | 54 | def run(self): 55 | while True: 56 | print("\n--- Library Menu ---") 57 | print("1. Add Book") 58 | print("2. Remove Book") 59 | print("3. Search by Title") 60 | print("4. Search by Author") 61 | print("5. List All Books") 62 | print("6. Exit") 63 | 64 | choice = input("Choose an option: ") 65 | 66 | if choice == '1': 67 | title = input("Enter book title: ") 68 | author = input("Enter book author: ") 69 | isbn = input("Enter book ISBN: ") 70 | self.library.add_book(Book(title, author, isbn)) 71 | 72 | elif choice == '2': 73 | isbn = input("Enter book ISBN to remove: ") 74 | self.library.remove_book(isbn) 75 | 76 | elif choice == '3': 77 | title = input("Enter book title to search: ") 78 | books = self.library.search_by_title(title) 79 | if books: 80 | for book in books: 81 | print(book) 82 | else: 83 | print('No books found with that title.') 84 | 85 | elif choice == '4': 86 | author = input("Enter author name to search: ") 87 | books = self.library.search_by_author(author) 88 | if books: 89 | for book in books: 90 | print(book) 91 | else: 92 | print('No books found by that author.') 93 | 94 | elif choice == '5': 95 | for book in self.library.books: 96 | print(book) 97 | 98 | elif choice == '6': 99 | print('Exiting...') 100 | break 101 | 102 | else: 103 | print('Invalid choice, please try again.') 104 | 105 | if __name__ == "__main__": 106 | app = LibraryApp() 107 | app.run() 108 | 109 | # class SnakePart: 110 | 111 | # def __init__(self, x, y): 112 | # self.x = x 113 | # self.y = y 114 | 115 | # class Snake: 116 | 117 | # def __init__(self, x: int, y: int, direction: tuple = (1, 0)): 118 | # self.body: list[SnakePart] = [SnakePart(x, y)] 119 | # self.direction = direction 120 | 121 | # def move(self): 122 | -------------------------------------------------------------------------------- /aulas/Semana 11 - Classes/34_codigo_aula.py: -------------------------------------------------------------------------------- 1 | class Personagem: 2 | 3 | def __init__(self, vida, ataque, defesa): 4 | self.vida = vida 5 | self.ataque = ataque 6 | self.defesa = defesa 7 | 8 | def atacar(self, outro_personagem): 9 | print("Personagem deu um soco!") 10 | 11 | class Guerreiro(Personagem): 12 | 13 | def __init__(self, vida, ataque, defesa): 14 | super().__init__(vida, ataque, defesa) 15 | 16 | def atacar(self, outro_personagem): 17 | print("Guerreiro desferiu um golpe de espada!") 18 | 19 | class Mago(Personagem): 20 | 21 | def __init__(self, vida, ataque, defesa): 22 | super().__init__(vida, ataque, defesa) 23 | 24 | def atacar(self, outro_personagem): 25 | print("Mago utilizou uma bola de fogo!") 26 | 27 | from typing import List 28 | 29 | def executar_ataque_em_conjunto(personagens: List[Personagem], alvo: Personagem): 30 | for p in personagens: 31 | p.atacar(alvo) 32 | 33 | class Reptil: 34 | 35 | def __init__(self): 36 | pass 37 | 38 | def caminhe(self): 39 | print("Estou caminhando") 40 | 41 | class Voador: 42 | 43 | def __init__(self): 44 | pass 45 | 46 | def voa(self): 47 | print("Estou voando") 48 | 49 | class Dragao(Voador, Reptil): 50 | 51 | def __init__(self): 52 | self.asa = Dragao.Asa() 53 | 54 | class Asa: 55 | 56 | def __init__(self): 57 | pass 58 | 59 | from abc import ABC, abstractmethod 60 | 61 | class Forma(ABC): 62 | 63 | @abstractmethod 64 | def area(self): 65 | pass 66 | 67 | @abstractmethod 68 | def perimetro(self): 69 | pass 70 | 71 | class Retangulo(Forma): 72 | def __init__(self, largura, altura): 73 | self.largura = largura 74 | self.altura = altura 75 | 76 | # def area(self): 77 | # return self.largura * self.altura 78 | 79 | def perimetro(self): 80 | return 2 * (self.largura + self.altura) 81 | 82 | if __name__ == "__main__": 83 | npc1 = Personagem(20, 20, 20) 84 | mago1 = Mago(50, 200, 20) 85 | guerreiro1 = Guerreiro(200, 50, 100) 86 | 87 | grupo = [npc1, mago1] 88 | executar_ataque_em_conjunto(grupo, guerreiro1) 89 | 90 | d = Dragao() 91 | d.caminhe() 92 | d.voa() 93 | 94 | a = Dragao.Asa() 95 | 96 | # Exemplo de uso 97 | forma = Forma() 98 | # retangulo = Retangulo(5, 3) 99 | # print(retangulo.perimetro()) -------------------------------------------------------------------------------- /aulas/Semana 11 - Classes/35_codigo_aula.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | class ClasseBase(ABC): 4 | 5 | @abstractmethod 6 | def ataque(self): 7 | pass 8 | 9 | class ClasseFilha1(ClasseBase): 10 | 11 | def __init__(self) -> None: 12 | super().__init__() 13 | 14 | # Se descomentar a linha de baixo, ocorrera uma exceção 15 | # f = ClasseFilha1() 16 | 17 | from typing import Protocol, runtime_checkable 18 | 19 | @runtime_checkable 20 | class Agressivo(Protocol): 21 | pontos_de_ataque: int 22 | pontos_de_defesa: int 23 | 24 | def ataque(self) -> None: 25 | ... 26 | 27 | class Personagem: 28 | 29 | def __init__(self) -> None: 30 | self.pontos_de_ataque: int = 10 31 | self.pontos_de_defesa: int = 10 32 | 33 | def ataque(self) -> None: 34 | print("Personagem atacou") 35 | 36 | class Funcionario: 37 | 38 | def ataque(self) -> None: 39 | print("Funcionario atacou") 40 | 41 | class Bola: 42 | 43 | def __init__(self) -> None: 44 | pass 45 | 46 | def atacar_forma(forma: Agressivo): 47 | if not isinstance(forma, Agressivo): 48 | raise Exception("Opa....") 49 | forma.ataque() 50 | 51 | personagem = Personagem() 52 | func = Funcionario() 53 | ball = Bola() 54 | atacar_forma(personagem) 55 | # atacar_forma(func) 56 | # atacar_forma(ball) 57 | 58 | from typing import List 59 | 60 | class Personagem: 61 | 62 | def __init__(self, pontos_de_vida: int): 63 | self.pontos_de_vida: int = pontos_de_vida 64 | # Agregação 65 | self.pocoes: List[Pocao] = [] 66 | 67 | def receber(self, pocao): 68 | self.pocoes.append(pocao) 69 | 70 | def auto_cura(self): 71 | if len(self.pocoes) < 1: 72 | return 73 | p = self.pocoes[0] 74 | self.pontos_de_vida += p.pontos_de_cura 75 | self.pocoes.pop() 76 | 77 | class Pocao: 78 | 79 | def __init__(self, pontos_de_cura: int): 80 | self.pontos_de_cura: int = pontos_de_cura 81 | 82 | # # Associacao 83 | # # Caso nõs não tivessemos implementado a agragacao + auto_cura acima 84 | # def cura(self, p: Personagem): 85 | # p.pontos_de_vida += self.pontos_de_cura 86 | 87 | class Jogo: 88 | 89 | def __init__(self) -> None: 90 | # Composicao 91 | self.personagem: Personagem = Personagem(100) 92 | self.pocao: Pocao = Pocao(50) 93 | 94 | def executar(self): 95 | pass 96 | 97 | j = Jogo() 98 | j.executar() 99 | del j 100 | -------------------------------------------------------------------------------- /aulas/Semana 12 - Pygame/36_codigo_aula.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | 3 | pygame.init() 4 | 5 | WIDTH, HEIGHT = 800, 600 6 | screen_size = (WIDTH, HEIGHT) 7 | screen = pygame.display.set_mode(screen_size) 8 | screen.fill((0, 0, 0)) 9 | 10 | class Player: 11 | 12 | def __init__(self, x, y, width, height): 13 | self.rect = pygame.Rect(x, y, width, height) 14 | self.color = (255, 0, 0) 15 | self.gravity_y = 2 # pixels^2 / frame 16 | self.speed_y = 0 17 | self.jump_count = 0 18 | self.jump_count_max = 2 19 | 20 | def draw(self, screen): 21 | pygame.draw.rect(screen, self.color, self.rect) 22 | 23 | def update(self): 24 | self.speed_y += self.gravity_y 25 | self.rect.y += self.speed_y 26 | 27 | # TODO: Usar colisao entre objetos 28 | if self.rect.y > HEIGHT - self.rect.height: 29 | self.rect.y = HEIGHT - self.rect.height 30 | self.speed_y = 0 31 | self.jump_count = 0 32 | 33 | def on_event(self, event: pygame.event.Event): 34 | if event.type == pygame.KEYDOWN: 35 | if event.key == pygame.K_SPACE: 36 | self.jump() 37 | 38 | def jump(self): 39 | if self.jump_count >= self.jump_count_max: 40 | return 41 | self.speed_y = -40 42 | self.jump_count += 1 43 | 44 | def on_key_pressed(self, key_map): 45 | if key_map[pygame.K_RIGHT] or key_map[pygame.K_w]: 46 | self.rect.x += 10 47 | if key_map[pygame.K_LEFT]: 48 | self.rect.x -= 10 49 | 50 | class Ground: 51 | 52 | def __init__(self, x, y, width, height): 53 | self.rect = pygame.Rect(x, y, width, height) 54 | self.color = (0, 255, 0) 55 | 56 | def draw(self, screen): 57 | pygame.draw.rect(screen, self.color, self.rect) 58 | 59 | def update(self): 60 | pass 61 | 62 | player = Player(WIDTH // 2, HEIGHT // 2, 50, 50) 63 | ground = Ground(0, HEIGHT - 30, WIDTH, 60) 64 | 65 | clock = pygame.time.Clock() 66 | 67 | is_running = True 68 | while is_running: 69 | # Eventos 70 | events = pygame.event.get() 71 | for event in events: 72 | if event.type == pygame.QUIT: 73 | is_running = False 74 | 75 | player.on_event(event) 76 | 77 | key_map = pygame.key.get_pressed() 78 | player.on_key_pressed(key_map) 79 | 80 | # Logica 81 | player.update() 82 | ground.update() 83 | 84 | has_collided = player.rect.colliderect(ground.rect) 85 | print(has_collided) 86 | 87 | # Renderizaçao 88 | screen.fill((0, 0, 0)) 89 | player.draw(screen) 90 | ground.draw(screen) 91 | pygame.display.flip() 92 | 93 | clock.tick(30) 94 | 95 | pygame.quit() 96 | -------------------------------------------------------------------------------- /aulas/Semana 12 - Pygame/38_codigo_aula.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | 3 | class Player: 4 | 5 | def __init__(self, x, y, width, height): 6 | self.rect = pygame.Rect(x, y, width, height) 7 | self.color = (255, 0, 0) 8 | self.gravity_y = 2 # pixels^2 / frame 9 | self.speed_y = 0 10 | self.jump_count = 0 11 | self.jump_count_max = 2 12 | 13 | def draw(self, screen): 14 | pygame.draw.rect(screen, self.color, self.rect) 15 | 16 | def update(self): 17 | self.speed_y += self.gravity_y 18 | self.rect.y += self.speed_y 19 | 20 | def on_event(self, event: pygame.event.Event): 21 | if event.type == pygame.KEYDOWN: 22 | if event.key == pygame.K_SPACE: 23 | self._jump() 24 | 25 | def _jump(self): 26 | if self.jump_count >= self.jump_count_max: 27 | return 28 | self.speed_y = -40 29 | self.jump_count += 1 30 | 31 | def on_key_pressed(self, key_map): 32 | if key_map[pygame.K_RIGHT] or key_map[pygame.K_w]: 33 | self.rect.x += 10 34 | elif key_map[pygame.K_LEFT]: 35 | self.rect.x -= 10 36 | 37 | def on_collision(self, other): 38 | # TODO: Comportamento precisa ser diferente dependendo lado da colisão 39 | if isinstance(other, Ground): 40 | ground_y = other.rect.top 41 | self.rect.bottom = ground_y 42 | self.speed_y = 0 43 | self.jump_count = 0 44 | 45 | class Ground: 46 | 47 | def __init__(self, x, y, width, height): 48 | self.rect = pygame.Rect(x, y, width, height) 49 | self.color = (0, 255, 0) 50 | 51 | def draw(self, screen): 52 | pygame.draw.rect(screen, self.color, self.rect) 53 | 54 | def update(self): 55 | pass 56 | 57 | def on_collision(self, other): 58 | pass 59 | 60 | class GameManager: 61 | 62 | def __init__(self) -> None: 63 | pygame.init() 64 | 65 | # A tela 66 | self.width = 800 67 | self.height = 600 68 | screen_size = (self.width, self.height) 69 | self.screen = pygame.display.set_mode(screen_size) 70 | self.screen.fill((0, 0, 0)) 71 | 72 | # Objetos 73 | self.player = Player(self.width // 2, self.height // 2, 50, 50) 74 | self.grounds = [ 75 | Ground(0, self.height - 30, self.width, 60), 76 | Ground(self.width // 2, self.height - 200, 100, 20), 77 | Ground(300, self.height - 90, 50, 50) 78 | ] 79 | 80 | self.clock = None 81 | self.is_running = False 82 | 83 | def run(self): 84 | # Inicializa o jogo 85 | self.clock = pygame.time.Clock() 86 | self.is_running = True 87 | while self.is_running: 88 | self.event() 89 | self.update() 90 | self.draw() 91 | self.clock.tick(30) 92 | pygame.quit() 93 | 94 | def event(self): 95 | # Eventos 96 | events = pygame.event.get() 97 | for event in events: 98 | if event.type == pygame.QUIT: 99 | self.is_running = False 100 | self.player.on_event(event) 101 | 102 | # Chaves pressionadas no momento 103 | key_map = pygame.key.get_pressed() 104 | self.player.on_key_pressed(key_map) 105 | 106 | def update(self): 107 | self.player.update() 108 | for ground in self.grounds: 109 | ground.update() 110 | self.collision_detection() 111 | 112 | def collision_detection(self): 113 | # Verificar colisao 114 | for ground in self.grounds: 115 | has_collided = self.player.rect.colliderect(ground.rect) 116 | if has_collided: 117 | self.player.on_collision(ground) 118 | ground.on_collision(self.player) 119 | 120 | def draw(self): 121 | # Renderizaçao 122 | self.screen.fill((0, 0, 0)) 123 | self.player.draw(self.screen) 124 | for ground in self.grounds: 125 | ground.draw(self.screen) 126 | pygame.display.flip() 127 | 128 | if __name__ == '__main__': 129 | game = GameManager() 130 | game.run() 131 | -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/38_codigo_aula.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | 3 | 4 | class Player(pygame.sprite.Sprite): 5 | 6 | def __init__(self, x, y, width, height, image_paths): 7 | # image_animation_right: List[str] 8 | # image_animation_left: List[str] 9 | # image_animation_up: List[str] 10 | # image_animation_down: List[str] 11 | # image_animation_idle: List[str] 12 | super().__init__() 13 | 14 | # 15 | self.idle_animation = [] 16 | for image_path in image_paths: 17 | sprite = pygame.image.load(image_path) 18 | # sprite = pygame.transform.scale(sprite, (width, height)) 19 | self.idle_animation.append(sprite) 20 | self.current_frame_index = 0 21 | self.image = self.idle_animation[self.current_frame_index] 22 | 23 | self.frames_per_sprite = 5 24 | self.frame_index = 0 25 | 26 | self.rect = self.image.get_rect() 27 | self.rect.x = x 28 | self.rect.y = y 29 | 30 | self.color = (255, 0, 0) 31 | self.gravity_y = 2 # pixels^2 / frame 32 | self.speed_y = 0 33 | self.jump_count = 0 34 | self.jump_count_max = 2 35 | 36 | def draw(self, screen): 37 | self.frame_index += 1 38 | if self.frame_index >= self.frames_per_sprite: 39 | self.frame_index = 0 40 | self.current_frame_index += 1 41 | if self.current_frame_index >= len(self.idle_animation): 42 | self.current_frame_index = 0 43 | self.image = self.idle_animation[self.current_frame_index] 44 | screen.blit(self.image, self.rect) 45 | 46 | def update(self): 47 | self.speed_y += self.gravity_y 48 | self.rect.y += self.speed_y 49 | 50 | def on_event(self, event: pygame.event.Event): 51 | if event.type == pygame.KEYDOWN: 52 | if event.key == pygame.K_SPACE: 53 | self._jump() 54 | 55 | def _jump(self): 56 | if self.jump_count >= self.jump_count_max: 57 | return 58 | self.speed_y = -40 59 | self.jump_count += 1 60 | 61 | def on_key_pressed(self, key_map): 62 | if key_map[pygame.K_RIGHT] or key_map[pygame.K_w]: 63 | self.rect.x += 10 64 | elif key_map[pygame.K_LEFT]: 65 | self.rect.x -= 10 66 | 67 | def on_collision(self, other): 68 | # TODO: Comportamento precisa ser diferente dependendo lado da colisão 69 | if isinstance(other, Ground): 70 | ground_y = other.rect.top 71 | self.rect.bottom = ground_y 72 | self.speed_y = 0 73 | self.jump_count = 0 74 | 75 | class Ground(pygame.sprite.Sprite): 76 | 77 | def __init__(self, x, y, width, height, image_path): 78 | super().__init__() 79 | self.image = pygame.image.load(image_path) 80 | self.image = pygame.transform.scale(self.image, (width, height)) 81 | self.rect = self.image.get_rect() 82 | self.rect.x = x 83 | self.rect.y = y 84 | self.color = (0, 255, 0) 85 | 86 | # def draw(self, screen): 87 | # pygame.draw.rect(screen, self.color, self.rect) 88 | 89 | def update(self): 90 | pass 91 | 92 | def on_collision(self, other): 93 | pass 94 | 95 | class GameManager: 96 | 97 | def __init__(self) -> None: 98 | pygame.init() 99 | 100 | # A tela 101 | self.width = 800 102 | self.height = 600 103 | screen_size = (self.width, self.height) 104 | self.screen = pygame.display.set_mode(screen_size) 105 | self.screen.fill((0, 0, 0)) 106 | 107 | # Objetos 108 | sprite_paths = [ 109 | "./sprites/link/down_idle/link_down_idle_0.png", 110 | "./sprites/link/down_idle/link_down_idle_1.png", 111 | "./sprites/link/down_idle/link_down_idle_2.png" 112 | ] 113 | 114 | self.player = Player(self.width // 2, self.height // 2, 50, 75, sprite_paths) 115 | 116 | sprite_path = "./sprites/powerup.png" 117 | self.ground_group = pygame.sprite.Group() 118 | self.ground_group.add(Ground(0, self.height - 30, self.width, 60, sprite_path)) 119 | self.ground_group.add(Ground(self.width // 2, self.height - 200, 100, 20, sprite_path)) 120 | self.ground_group.add(Ground(300, self.height - 90, 50, 50, sprite_path)) 121 | 122 | self.clock = pygame.time.Clock() 123 | self.is_running = True 124 | 125 | def run(self): 126 | while self.is_running: 127 | self.event() 128 | self.update() 129 | self.draw() 130 | self.clock.tick(30) 131 | pygame.quit() 132 | 133 | def event(self): 134 | # Eventos 135 | events = pygame.event.get() 136 | for event in events: 137 | if event.type == pygame.QUIT: 138 | self.is_running = False 139 | self.player.on_event(event) 140 | 141 | # Chaves pressionadas no momento 142 | key_map = pygame.key.get_pressed() 143 | self.player.on_key_pressed(key_map) 144 | 145 | def update(self): 146 | self.player.update() 147 | self.ground_group.update() 148 | self.collision_detection() 149 | 150 | def collision_detection(self): 151 | # Verificar colisao 152 | for ground in self.ground_group: 153 | has_collided = self.player.rect.colliderect(ground.rect) 154 | if has_collided: 155 | self.player.on_collision(ground) 156 | ground.on_collision(self.player) 157 | 158 | def draw(self): 159 | # Renderizaçao 160 | self.screen.fill((0, 0, 0)) 161 | self.player.draw(self.screen) 162 | self.ground_group.update() 163 | self.ground_group.draw(self.screen) 164 | pygame.display.flip() 165 | 166 | if __name__ == '__main__': 167 | game = GameManager() 168 | game.run() -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/40_codigo_aula.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | pygame.init() 3 | 4 | SCREEN_WIDTH = 800 5 | SCREEN_HEIGHT = 600 6 | 7 | class ScoreManager: 8 | 9 | def __init__(self, x, y, initil_score=0): 10 | self.x = x 11 | self.y = y 12 | self.score = initil_score 13 | 14 | self.font = pygame.font.Font(None, 36) 15 | self.score_msg = "Pontuação: {:,}" 16 | 17 | def draw(self, screen): 18 | msg = self.score_msg.format(self.score) 19 | text_box = self.font.render(msg, True, "grey") 20 | screen.blit(text_box, (self.x, self.y)) 21 | 22 | def increment(self, points=1): 23 | self.score += points 24 | 25 | class Button: 26 | 27 | def __init__(self, x, y, width, height, text, callback, fontsize=36): 28 | self.rect = pygame.Rect(x, y, width, height) 29 | self.text = text 30 | self.font = pygame.font.Font(None, fontsize) 31 | self.callback = callback 32 | 33 | self.color_default = "white" 34 | self.color_hover = "red" 35 | self.color_current = self.color_default 36 | 37 | def draw(self, screen): 38 | pygame.draw.rect(screen, self.color_current, self.rect) 39 | text_box = self.font.render(self.text, True, "black") 40 | text_box_rect = text_box.get_rect(center=self.rect.center) 41 | screen.blit(text_box, text_box_rect) 42 | 43 | def on_event(self, event): 44 | if event.type == pygame.MOUSEBUTTONDOWN: 45 | has_collided = self.rect.collidepoint(event.pos) 46 | if has_collided and event.button == 1: 47 | self.callback() 48 | 49 | if event.type == pygame.MOUSEMOTION: 50 | has_collided = self.rect.collidepoint(event.pos) 51 | if has_collided: 52 | self.color_current = self.color_hover 53 | else: 54 | self.color_current = self.color_default 55 | 56 | class MainMenu: 57 | 58 | def __init__(self, manager): 59 | self.manager = manager 60 | self.start_button = Button(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2, 200, 50, "Start", self.start_callback) 61 | self.exit_button = Button(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 100, 200, 50, "exit", self.exit_callback) 62 | 63 | def draw(self, screen): 64 | screen.fill((0, 0, 0)) 65 | self.start_button.draw(screen) 66 | self.exit_button.draw(screen) 67 | pygame.display.flip() 68 | 69 | def on_event(self, event): 70 | self.start_button.on_event(event) 71 | self.exit_button.on_event(event) 72 | 73 | def start_callback(self): 74 | self.manager.change_state("game_level") 75 | 76 | def exit_callback(self): 77 | self.manager.is_running = False 78 | 79 | class GameLevel: 80 | 81 | def __init__(self, manager): 82 | pass 83 | 84 | def draw(self, screen): 85 | screen.fill((255, 0, 0)) 86 | pygame.display.update() 87 | 88 | def on_event(self, event): 89 | pass 90 | 91 | class GameManager: 92 | 93 | def __init__(self): 94 | self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) 95 | self.states = { 96 | "main_menu": MainMenu(self), 97 | "game_level": GameLevel(self) 98 | } 99 | self.current_state = self.states["main_menu"] 100 | self.is_running = False 101 | 102 | def change_state(self, state_name): 103 | self.current_state = self.states[state_name] 104 | 105 | def run(self): 106 | self.is_running = True 107 | while self.is_running: 108 | events = pygame.event.get() 109 | for event in events: 110 | if event.type == pygame.QUIT: 111 | self.is_running = False 112 | self.current_state.on_event(event) 113 | 114 | self.current_state.draw(self.screen) 115 | pygame.display.flip() 116 | 117 | pygame.quit() 118 | 119 | if __name__ == "__main__": 120 | game = GameManager() 121 | game.run() 122 | -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/background.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down/link_down_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down/link_down_0.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down/link_down_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down/link_down_1.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down/link_down_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down/link_down_2.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down/link_down_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down/link_down_3.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down/link_down_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down/link_down_4.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down/link_down_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down/link_down_5.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down/link_down_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down/link_down_6.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down/link_down_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down/link_down_7.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down/link_down_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down/link_down_8.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down/link_down_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down/link_down_9.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down_idle/link_down_idle_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down_idle/link_down_idle_0.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down_idle/link_down_idle_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down_idle/link_down_idle_1.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/down_idle/link_down_idle_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/down_idle/link_down_idle_2.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left/link_left_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left/link_left_0.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left/link_left_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left/link_left_1.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left/link_left_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left/link_left_2.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left/link_left_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left/link_left_3.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left/link_left_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left/link_left_4.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left/link_left_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left/link_left_5.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left/link_left_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left/link_left_6.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left/link_left_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left/link_left_7.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left/link_left_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left/link_left_8.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left/link_left_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left/link_left_9.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left_idle/link_left_idle_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left_idle/link_left_idle_0.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left_idle/link_left_idle_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left_idle/link_left_idle_1.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/left_idle/link_left_idle_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/left_idle/link_left_idle_2.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/link_animation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/link_animation.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right/link_right_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right/link_right_0.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right/link_right_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right/link_right_1.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right/link_right_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right/link_right_2.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right/link_right_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right/link_right_3.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right/link_right_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right/link_right_4.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right/link_right_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right/link_right_5.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right/link_right_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right/link_right_6.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right/link_right_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right/link_right_7.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right/link_right_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right/link_right_8.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right/link_right_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right/link_right_9.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right_idle/link_right_idle_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right_idle/link_right_idle_0.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right_idle/link_right_idle_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right_idle/link_right_idle_1.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/right_idle/link_right_idle_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/right_idle/link_right_idle_2.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/up/link_up_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/up/link_up_0.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/up/link_up_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/up/link_up_1.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/up/link_up_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/up/link_up_2.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/up/link_up_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/up/link_up_3.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/up/link_up_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/up/link_up_4.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/up/link_up_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/up/link_up_5.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/up/link_up_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/up/link_up_6.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/up/link_up_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/up/link_up_7.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/up/link_up_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/up/link_up_8.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/up/link_up_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/up/link_up_9.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/link/up_idle/link_up_idle_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/link/up_idle/link_up_idle_0.png -------------------------------------------------------------------------------- /aulas/Semana 13 - Pygame/sprites/powerup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 13 - Pygame/sprites/powerup.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/README.md: -------------------------------------------------------------------------------- 1 | ## Acknowledgments 2 | 3 | 1. Image assets created by [imaginelabs](https://opengameart.org/content/breakout-brick-breaker-tile-set-free), licensed under [CC BY 1.0](https://creativecommons.org/publicdomain/zero/1.0/). 4 | -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/ball/58-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/ball/58-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/21-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/21-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/22-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/22-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/23-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/23-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/24-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/24-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/25-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/25-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/26-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/26-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/27-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/27-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/28-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/28-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/29-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/29-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/30-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/block/30-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/01-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/01-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/02-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/02-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/03-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/03-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/04-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/04-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/05-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/05-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/06-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/06-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/07-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/07-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/08-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/08-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/09-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/09-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/10-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/10-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/11-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/11-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/12-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/12-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/13-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/13-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/14-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/14-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/15-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/15-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/16-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/16-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/17-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/17-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/18-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/18-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/19-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/19-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/20-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/brick/20-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/50-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/50-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/51-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/51-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/52-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/52-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/53-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/53-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/54-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/54-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/55-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/55-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/56-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/56-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/57-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/57-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/61-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/paddle/61-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/31-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/31-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/32-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/32-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/33-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/33-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/34-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/34-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/35-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/35-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/36-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/36-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/37-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/37-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/38-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/38-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/39-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/39-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/40-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/40-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/41-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/41-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/42-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/42-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/43-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/43-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/44-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/44-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/45-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/45-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/46-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/46-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/47-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/47-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/48-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/48-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/49-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/49-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/59-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/59-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/60-Breakout-Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 14 - Pygame/41_pygame_breakout/assets/sprite/powerups/60-Breakout-Tiles.png -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "screen": { 3 | "width": 800, 4 | "height": 600, 5 | "fps": 60 6 | }, 7 | "difficulty": { 8 | "easy": { 9 | "lives": 5, 10 | "paddle_vel_x": 4, 11 | "ball_vel_x": 2, 12 | "ball_vel_y": 2 13 | }, 14 | "medium": { 15 | "lives": 3, 16 | "paddle_vel_x": 5, 17 | "ball_vel_x": 3, 18 | "ball_vel_y": 3 19 | }, 20 | "hard": { 21 | "lives": 2, 22 | "paddle_vel_x": 6, 23 | "ball_vel_x": 4, 24 | "ball_vel_y": 4 25 | } 26 | }, 27 | "levels": [ 28 | { 29 | "layout": [ 30 | {"type": "brick_blue", "x": 50, "y": 50}, 31 | {"type": "brick_blue", "x": 150, "y": 50}, 32 | {"type": "brick_blue", "x": 250, "y": 50}, 33 | {"type": "brick_blue", "x": 350, "y": 50}, 34 | {"type": "brick_blue", "x": 450, "y": 50}, 35 | {"type": "brick_blue", "x": 550, "y": 50}, 36 | {"type": "brick_blue", "x": 650, "y": 50}, 37 | {"type": "brick_green", "x": 50, "y": 100}, 38 | {"type": "brick_green", "x": 150, "y": 100}, 39 | {"type": "brick_green", "x": 250, "y": 100}, 40 | {"type": "brick_green", "x": 350, "y": 100}, 41 | {"type": "brick_green", "x": 450, "y": 100}, 42 | {"type": "brick_green", "x": 550, "y": 100}, 43 | {"type": "brick_green", "x": 650, "y": 100}, 44 | {"type": "brick_purple", "x": 50, "y": 150}, 45 | {"type": "brick_purple", "x": 150, "y": 150}, 46 | {"type": "brick_purple", "x": 250, "y": 150}, 47 | {"type": "brick_purple", "x": 350, "y": 150}, 48 | {"type": "brick_purple", "x": 450, "y": 150}, 49 | {"type": "brick_purple", "x": 550, "y": 150}, 50 | {"type": "brick_purple", "x": 650, "y": 150} 51 | ] 52 | } 53 | ], 54 | "objects": { 55 | "paddle": { 56 | "width": 100, 57 | "height": 20, 58 | "images": [ 59 | "../assets/sprite/paddle/50-Breakout-Tiles.png", 60 | "../assets/sprite/paddle/51-Breakout-Tiles.png", 61 | "../assets/sprite/paddle/52-Breakout-Tiles.png" 62 | ], 63 | "frames_per_image": 10 64 | }, 65 | "ball": { 66 | "radius": 10, 67 | "image": "../assets/sprite/ball/58-Breakout-Tiles.png" 68 | }, 69 | "brick_blue": { 70 | "width": 50, 71 | "height": 20, 72 | "image_map": { 73 | "normal": "../assets/sprite/brick/01-Breakout-Tiles.png", 74 | "cracked": "../assets/sprite/brick/02-Breakout-Tiles.png" 75 | } 76 | }, 77 | "brick_green": { 78 | "width": 50, 79 | "height": 20, 80 | "image_map": { 81 | "normal": "../assets/sprite/brick/03-Breakout-Tiles.png", 82 | "cracked": "../assets/sprite/brick/04-Breakout-Tiles.png" 83 | } 84 | }, 85 | "brick_purple": { 86 | "width": 50, 87 | "height": 20, 88 | "image_map": { 89 | "normal": "../assets/sprite/brick/05-Breakout-Tiles.png", 90 | "cracked": "../assets/sprite/brick/06-Breakout-Tiles.png" 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/src/breakout.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | pygame.init() 3 | import json 4 | 5 | from game_objects import Ball, Paddle, Brick, Wall 6 | 7 | from typing import List, Dict, Tuple 8 | 9 | class GameManager: 10 | 11 | def __init__(self, config): 12 | self.config = config 13 | 14 | # UI 15 | screen_config = config["screen"] 16 | self.load_screen(screen_config) 17 | 18 | # GAME OBJECTS 19 | difficulty_config = config["difficulty"]["hard"] 20 | game_objects_config = config["objects"] 21 | 22 | paddle_config = game_objects_config["paddle"] 23 | self.load_paddle(paddle_config, difficulty_config) 24 | 25 | ball_config = game_objects_config["ball"] 26 | self.load_ball(ball_config, difficulty_config) 27 | 28 | brick_types = { 29 | "brick_blue": self.load_brick(game_objects_config["brick_blue"]), 30 | "brick_green": self.load_brick(game_objects_config["brick_green"]), 31 | "brick_purple": self.load_brick(game_objects_config["brick_purple"]) 32 | } 33 | level_configs = config["levels"] 34 | self.load_level(level_configs[0], brick_types) 35 | self.load_walls() 36 | 37 | self.running = False 38 | self.clock = None 39 | 40 | def load_screen(self, config: dict): 41 | self.screen_width = config["width"] 42 | self.screen_height = config["height"] 43 | self.fps = config["fps"] 44 | self.screen = pygame.display.set_mode((self.screen_width, self.screen_height)) 45 | pygame.display.set_caption("Breakout") 46 | 47 | def load_paddle(self, sprite_config: dict, difficulty_config: dict): 48 | width = sprite_config["width"] 49 | height = sprite_config["height"] 50 | x = self.screen_width // 2 - width // 2 51 | y = self.screen_height - 50 52 | sprite_paths = sprite_config["images"] 53 | frames_per_image = sprite_config["frames_per_image"] 54 | vel_x = difficulty_config["paddle_vel_x"] 55 | self.paddle = Paddle(x, y, width, height, sprite_paths, frames_per_image, vel_x) 56 | 57 | def load_ball(self, sprite_config: dict, difficulty_config: dict): 58 | radius = sprite_config["radius"] 59 | sprite_path = sprite_config["image"] 60 | x = self.screen_width // 2 61 | y = self.screen_height // 2 62 | vel_x = difficulty_config["ball_vel_x"] 63 | vel_y = difficulty_config["ball_vel_y"] 64 | self.ball = Ball(x, y, radius, sprite_path, vel_x, vel_y) 65 | 66 | def load_brick(self, config: dict): 67 | width = config["width"] 68 | height = config["height"] 69 | normal_sprite_path = config["image_map"]["normal"] 70 | cracked_sprite_path = config["image_map"]["cracked"] 71 | return Brick(0, 0, width, height, normal_sprite_path, cracked_sprite_path) 72 | 73 | def load_level(self, config: dict, brick_types: Dict[str, Brick]): 74 | self.bricks = pygame.sprite.Group() 75 | for brick_config in config["layout"]: 76 | brick_type = brick_config["type"] 77 | x = brick_config["x"] 78 | y = brick_config["y"] 79 | 80 | brick = brick_types[brick_type].copy() 81 | brick.rect.x = x 82 | brick.rect.y = y 83 | self.bricks.add(brick) 84 | 85 | def load_walls(self): 86 | self.walls = pygame.sprite.Group() 87 | self.walls.add(Wall(-10, 0, 10, self.screen_height)) # wall_left 88 | self.walls.add(Wall(self.screen_width, 0, 10, self.screen_height)) # wall_right 89 | self.walls.add(Wall(0, -10, self.screen_width, 10)) # wall_top 90 | 91 | # This wall has a different behavior then the others 92 | # It will reset the ball when it collides with it 93 | self.wall_bottom = Wall(0, self.screen_height, self.screen_width, 10) # wall_bottom 94 | 95 | def run(self): 96 | self.running = True 97 | self.clock = pygame.time.Clock() 98 | while self.running: 99 | self.events() 100 | self.update() 101 | self.draw() 102 | self.clock.tick(self.fps) 103 | pygame.quit() 104 | 105 | def events(self): 106 | events = pygame.event.get() 107 | for event in events: 108 | if event.type == pygame.QUIT: 109 | self.running = False 110 | 111 | key_map = pygame.key.get_pressed() 112 | self.paddle.on_key_pressed(key_map) 113 | 114 | def draw(self): 115 | self.screen.fill((0, 0, 0)) 116 | self.paddle.draw(self.screen) 117 | self.ball.draw(self.screen) 118 | self.bricks.draw(self.screen) 119 | pygame.display.flip() 120 | 121 | def update(self): 122 | self.ball.update() 123 | self.paddle.update() 124 | self.check_collisions() 125 | 126 | def check_collisions(self): 127 | # BALL - BRICK 128 | # BALL - WALL 129 | # BALL - BOTTOM WALL 130 | # PADDLE - WALL 131 | # PADDLE - BALL 132 | pass 133 | 134 | if __name__ == "__main__": 135 | config_path = "../config/config.json" 136 | config = json.load(open(config_path, "r")) 137 | gm = GameManager(config) 138 | gm.run() 139 | -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/src/game_objects.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import utils 3 | 4 | class Ball(pygame.sprite.Sprite): 5 | 6 | def __init__(self, x, y, radius, image_path, vel_x, vel_y): 7 | super().__init__() 8 | self.rect = pygame.Rect(x, y, radius, radius) 9 | self.image = utils.load_image(image_path, (radius, radius)) 10 | self.vel_x = vel_x 11 | self.vel_y = vel_y 12 | 13 | def draw(self, screen): 14 | screen.blit(self.image, self.rect) 15 | 16 | def update(self): 17 | self.rect.x += self.vel_x 18 | self.rect.y += self.vel_y 19 | 20 | def on_collision(self, other): 21 | pass 22 | 23 | class Wall(pygame.sprite.Sprite): 24 | 25 | def __init__(self, x, y, width, height): 26 | super().__init__() 27 | self.rect = pygame.Rect(x, y, width, height) 28 | self.image = pygame.Surface((width, height)) 29 | 30 | def on_collision(self, other): 31 | pass 32 | 33 | class Brick(pygame.sprite.Sprite): 34 | 35 | def __init__(self, x, y, width, height, normal_image_path, cracked_image_path): 36 | super().__init__() 37 | self.rect = pygame.Rect(x, y, width, height) 38 | self.normal_image = utils.load_image(normal_image_path, (width, height)) 39 | self.cracked_image = utils.load_image(cracked_image_path, (width, height)) 40 | self.image = self.normal_image 41 | 42 | self.points = 10 43 | self.is_cracked = False 44 | self.__normal_image_path = normal_image_path 45 | self.__cracked_image_path = cracked_image_path 46 | 47 | def copy(self): 48 | return Brick(self.rect.x, 49 | self.rect.y, 50 | self.rect.width, 51 | self.rect.height, 52 | self.__normal_image_path, 53 | self.__cracked_image_path) 54 | 55 | def draw(self, screen): 56 | screen.blit(self.image, self.rect) 57 | 58 | def on_collision(self, other): 59 | pass 60 | 61 | class Paddle(pygame.sprite.Sprite): 62 | 63 | def __init__(self, x, y, width, height, image_paths, frames_per_image, vel_x): 64 | self.rect = pygame.Rect(x, y, width, height) 65 | self.animation = [utils.load_image(image_path, (width, height)) 66 | for image_path in image_paths] 67 | self.image = self.animation[0] 68 | self.frame = 0 69 | self.frames_per_image = frames_per_image 70 | self.vel_x = vel_x 71 | 72 | def draw(self, screen): 73 | screen.blit(self.image, self.rect) 74 | 75 | def update(self): 76 | self.frame = (self.frame + 1) % (len(self.animation) * self.frames_per_image) 77 | self.image = self.animation[self.frame // self.frames_per_image] 78 | 79 | def on_event(self, event): 80 | pass 81 | 82 | def on_key_pressed(self, key_map): 83 | if key_map[pygame.K_LEFT]: 84 | self.rect.x -= self.vel_x 85 | elif key_map[pygame.K_RIGHT]: 86 | self.rect.x += self.vel_x 87 | 88 | def on_collision(self, other): 89 | pass 90 | -------------------------------------------------------------------------------- /aulas/Semana 14 - Pygame/41_pygame_breakout/src/utils.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | 3 | def load_image(image_path, screen_size): 4 | image = pygame.image.load(image_path).convert_alpha() 5 | image = pygame.transform.scale(image, screen_size) 6 | return image -------------------------------------------------------------------------------- /aulas/Semana 2 - Revisao Python/5_car_class.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 2 - Revisao Python/5_car_class.jpg -------------------------------------------------------------------------------- /aulas/Semana 2 - Revisao Python/5_objetos_classes.md: -------------------------------------------------------------------------------- 1 | # Objetos e Classes 2 | 3 | Em Python, tudo é um objeto. 4 | Isso significa que não apenas as variáveis e os tipos de dados básicos (como números e strings), 5 | mas também funções e outros componentes da linguagem são objetos. 6 | Um objeto é como uma variável especial que pode armazenar multiplus valores 7 | e simultaneamente possuir funções associadas a ele. 8 | Pense em um objeto como uma caixa que pode conter coisas e também fazer coisas. 9 | 10 | Nesse contexto, uma classe é como uma receita para criar esses objetos especiais. 11 | É como um modelo que define quais coisas (propriedades) e ações (funções) um objeto pode ter. 12 | 13 | Seguindo essa linha de racíocinio, nos podemos considerar o conceito de ```carro``` como sendo uma receita (classe). 14 | Nela, um carro possue diversos valores (Números de Portas, Velocidade Máxima, etc) e ações (acelerar, direcionar, etc). 15 | E você pode pensar em diversos outros exemplos similares como Televisões, Celulares, Roupas, etc 16 | 17 |

18 | 19 |

20 | 21 | Imagine que uma classe seja como uma receita para fazer algo, como um carro. 22 | Essa receita detalha todos os aspectos do carro, como o número de portas, 23 | a velocidade máxima, a cor e assim por diante. Além disso, ela também inclui 24 | todas as ações que um carro pode realizar, como acelerar, virar à esquerda, parar e assim por diante. 25 | 26 | Agora, você pode aplicar essa mesma ideia para diferentes coisas, como televisões, celulares, roupas e muito mais. 27 | Cada uma teria sua própria "receita" (classe) que define suas características e ações únicas. 28 | 29 | Dessa forma, as classes servem como modelos ou receitas que nos permitem criar diferentes objetos 30 | com características e comportamentos específicos. 31 | 32 | ## Comparando com C e Structs 33 | 34 | Em C, uma struct é uma coleção de variáveis de diferentes tipos agrupadas sob um mesmo nome. 35 | Structs permitem que você defina um tipo de dado personalizado que pode conter diferentes tipos de informações. 36 | Aqui está um exemplo simples de uma struct em C: 37 | 38 | ```c 39 | struct Pessoa { 40 | char nome[50]; 41 | int idade; 42 | }; 43 | ``` 44 | 45 | Em Python, os objetos também podem ser vistos como uma forma de estruturar dados, 46 | mas de uma maneira mais flexível e poderosa. 47 | Cada objeto tem um tipo e pertence a uma classe, 48 | e essa classe define as propriedades e comportamentos do objeto. 49 | Vamos fazer uma analogia para ajudar: 50 | 51 | * Structs em C: Servem para agrupar dados relacionados. Por exemplo, a struct Pessoa agrupa um nome e uma idade. 52 | * Objetos em Python: Servem para encapsular dados e comportamentos. Uma classe em Python pode ser comparada a uma struct, mas com a capacidade adicional de definir métodos que operam sobre os dados. 53 | 54 | ## Em python 55 | 56 | Uma lista é um tipo de objeto em Python. 57 | Podemos criar uma lista e adicionar elementos a ela usando funções 58 | associadas a esse objeto. 59 | 60 | ```python 61 | # Criando uma lista 62 | minha_lista = [1, 2, 3, 4] 63 | 64 | # Adicionando um elemento à lista 65 | minha_lista.append(5) 66 | ``` 67 | 68 | Neste exemplo, ```minha_lista``` é o objeto (variável) que possui uma função 69 | chamada ```append()``` associada a ele, que adiciona um elemento à lista. 70 | 71 | Então, você pode pensar em usar funções associadas a objetos como ```list_append(minha_lista, 5)```, 72 | mas em Python, podemos chamar essas funções de uma forma mais simples usando a notação de ponto ('.'), 73 | como minha_lista.append(5). 74 | 75 | Outro tipo de objeto é a string, que é uma sequência de caracteres em Python. 76 | Podemos criar uma string para representar texto e usar várias funções associadas a ela. 77 | Por exemplo, podemos usar a função ```find()``` para encontrar a posição de uma determinada palavra dentro do texto. 78 | 79 | ```python 80 | # Criando uma string 81 | meu_texto = "Hello World!" 82 | 83 | # Encontrando a palavra "World" no texto 84 | posicao = meu_texto.find("World") 85 | print(posicao) # Saída: 6 86 | ``` 87 | 88 | E, como visto no exemplo anterior, pode-se pensar nesta função como sendo 89 | ```string_find(meu_texto, "World")```. 90 | 91 | -------------------------------------------------------------------------------- /aulas/Semana 2 - Revisao Python/6_data_structures.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 2 - Revisao Python/6_data_structures.jpg -------------------------------------------------------------------------------- /aulas/Semana 2 - Revisao Python/6_estruturas_de_dados.md: -------------------------------------------------------------------------------- 1 | # Estruturas de Dados básicas 2 | 3 | Nesta aula, vamos aprender sobre estruturas de dados básicas em Python: 4 | * Listas; 5 | * Conjuntos; 6 | * Tupla; 7 | * dicionários; 8 | * Strings. 9 | 10 |

11 | 12 |

13 | 14 | ## A. LISTAS (Lists) 15 | 16 | Uma lista em Python é uma coleção ordenada de elementos, onde cada elemento é identificado por um índice. 17 | 18 | ### Criando uma Lista 19 | 20 | ```python 21 | minha_lista = [1, 2, 3, 4, 5] 22 | ``` 23 | 24 | ### Acessando Elementos 25 | 26 | ```python 27 | print(minha_lista[0]) # Saída: 1 28 | ``` 29 | 30 | ### Operações Básicas em Listas 31 | 32 | * Adição de elementos: ```append()```, ```extend()```, ```insert()``` 33 | * Remoção de elementos: ```remove()```, ```pop()```, ```clear()``` 34 | * Atualização de elementos 35 | * Concatenação: ```+```, ```*``` 36 | * Fatiamento: ```my_list[begin:end:step]``` 37 | * Pesquisa: ```in``` 38 | * Built-in functions: ```len()```, ```sum()```, ```min()```, ```max()```, ```sorted()``` 39 | 40 | ### Exercícios 41 | 42 | 1. Crie uma lista com os nomes de cinco pessoas. 43 | 2. Adicione o seu próprio nome à lista. 44 | 3. Remova o nome da segundo pessoa da lista. 45 | 4. Imprima a lista de amigos em ordem alfabética. 46 | 47 | 48 | 49 | ## B. TUPLAS (Tuples) 50 | 51 | Uma tupla em Python é uma coleção ordenada e imutável (não pode ser modificada) de elementos. 52 | 53 | ### Criando uma Tupla 54 | 55 | ```python 56 | minha_tupla = (1, 2, 3, 4, 5) 57 | ``` 58 | 59 | ### Acessando Elementos 60 | 61 | ```python 62 | print(minha_tupla[0]) # Saída: 1 63 | ``` 64 | 65 | ### Operações Básicas em Tuplas 66 | 67 | * Concatenação: ```+```, ```*``` 68 | * Fatiamento: ```my_list[begin:end:step]``` 69 | * Pesquisa: ```in``` 70 | 71 | ### Exemplo 72 | 73 | Representar coordenadas geográficas, como latitude e longitude de diferentes locais. 74 | 75 | ```python 76 | latlong = (40.7128, -74.0060) 77 | ``` 78 | 79 | ### Exercícios 80 | 81 | 1. Crie uma tupla com os dias da semana. 82 | 2. Acesse o terceiro elemento da tupla. 83 | 3. Imprima a tupla completa na ordem reversa. 84 | 85 | 86 | 87 | ## C. CONJUNTOS (Sets) 88 | 89 | Um conjunto em Python é uma coleção não ordenada e sem elementos duplicados. 90 | 91 | ### Criando um Conjunto 92 | 93 | ```python 94 | meu_conjunto = {1, 2, 3, 4, 5} 95 | ``` 96 | 97 | Operações Básicas em Conjuntos 98 | 99 | * Adição de elementos: ```add()``` 100 | * Remoção de elementos: ```remove()```, ```discard()``` 101 | * União, interseção, diferença: ```union()```, ```intersection()```, ```difference()``` 102 | * Verificação de pertencimento: ```in``` 103 | 104 | ### Exemplo 105 | 106 | Verificar se uma palavra faz parte de uma lista de palavras proibidas. 107 | 108 | ```python 109 | word = "pix" 110 | spam_words = {"dinheiro", "urgente", "pix", "ganhador"} 111 | 112 | print(word in spam_words) 113 | ``` 114 | 115 | ### Exercícios 116 | 117 | 1. Crie dois conjuntos com cores diferentes. 118 | 2. Verifique se há alguma cor em comum entre os dois conjuntos. 119 | 3. Adicione uma cor ao primeiro conjunto. 120 | 4. Imprima a união dos dois conjuntos. 121 | 122 | 123 | 124 | ## D. DICÍONARIOS (Dictionaries) 125 | 126 | Um dicionário em Python é uma coleção de elementos que são armazenados como pares chave-valor. 127 | Criando um Dicionário 128 | 129 | ```python 130 | meu_dicionario = {'a': 1, 'b': 2, 'c': 3} 131 | ``` 132 | 133 | ### Acessando Elementos 134 | 135 | ```python 136 | print(meu_dicionario['a']) # Saída: 1 137 | ``` 138 | 139 | ### Operações Básicas em Dicionários 140 | 141 | * Adição de elementos 142 | * Remoção de elementos: ```pop()```, ```popitem()```, ```clear()``` 143 | * Atualização de elementos ```update()``` 144 | * Iteração: ```keys()```, ```values()```, ```items()``` 145 | 146 | ### Exemplo 147 | 148 | Armazenar informações detalhadas sobre um produto, como nome, preço e quantidade em estoque. Por exemplo: 149 | 150 | ```python 151 | produto = { 152 | "nome": "Camiseta", 153 | "preco": 29.99, 154 | "estoque": 100 155 | } 156 | produto["estoque"] -= 1 # Atualiza o estoque após uma venda 157 | print("Estoque restante:", produto["estoque"]) # Saída: 99 158 | ``` 159 | 160 | ### Exercícios 161 | 162 | 1. Crie um dicionário com informações sobre um livro (título, autor, ano de publicação). 163 | 2. Imprima o título do livro. 164 | 3. Atualize o ano de publicação do livro. 165 | 4. Remova o autor do dicionário. 166 | 167 | ## E. STRINGS 168 | 169 | Uma string em Python é uma sequência de caracteres. 170 | 171 | ### Criando uma String 172 | 173 | ```python 174 | minha_string = "Olá, mundo!" 175 | ``` 176 | 177 | ### Manipulação de Strings 178 | 179 | * Concatenação: ```join()``` 180 | * Fatiamento 181 | * Métodos embutidos: ```split()```, ```join()```, ```find()```, ```replace()``` 182 | 183 | ### Exemplo 184 | 185 | Acho que sabemos aplicações para strings... 186 | 187 | ### Exercícios 188 | 189 | 1. Crie uma string com uma frase de sua escolha. 190 | 2. Imprima o comprimento da string. 191 | 3. Imprima a string em letras maiúsculas. 192 | 4. Imprima a string em letras minúsculas. 193 | 5. Conte o número de vezes que a letra 'a' aparece na string. 194 | 6. Crie duas strings com seu primeiro e último nome. 195 | 7. Concatene as duas strings para formar seu nome completo. 196 | 8. Separe seu nome completo em duas strings contendo apenas seu primeiro e último nome, respectivamente. 197 | 9. Junte as duas strings separadas com um espaço entre elas para formar seu nome completo novamente. 198 | 10. Crie uma string com uma frase que contenha a palavra 'Python'. 199 | 11. Substitua 'Python' por 'Java' na string. 200 | 12. Crie uma variável com seu nome e idade. 201 | 13. Use formatação de string para criar uma frase que inclua seu nome e idade. -------------------------------------------------------------------------------- /aulas/Semana 2 - Revisao Python/7_mutabable_objects.md: -------------------------------------------------------------------------------- 1 | # Objetos Mutáveis vs. Imutáveis 2 | 3 | Qual comportamento você espera que aconteça no script abaixo? 4 | 5 | ```python 6 | a = 2 7 | b = a 8 | a = 1 9 | print(b) 10 | ``` 11 | 12 | E agora? 13 | 14 | ```python 15 | a = [1, 2, 3] 16 | b = a 17 | a.append(4) 18 | print(b) 19 | ``` 20 | 21 | Por que isso ocorre? 22 | 23 | ## Introdução 24 | 25 | Em Python, os objetos podem ser classificados como mutáveis ou imutáveis com 26 | base na sua capacidade de alterarmos seu conteúdo após a criação. 27 | Essa distinção é fundamental para entendermos como Python trata diferentes tipos de dados. 28 | 29 | ## Objetos imutáveis 30 | 31 | Os objetos imutáveis são aqueles cujo conteúdo não pode ser alterado após a criação. 32 | Quando tentamos modificar um objeto desse tipo, na verdade estamos criando um novo objeto. 33 | 34 | Exemplos de objetos imutáveis incluem: 35 | * Inteiros (int) 36 | * Floats (float) 37 | * Strings (str) 38 | * Tuplas (tuple) 39 | 40 | Como 41 | 42 | ```python 43 | x = 5 44 | x += 1 45 | print(x) 46 | ``` 47 | 48 | Neste caso, o resultado da soma $5 + 1$ é atribuido ao ```x```, 49 | sobrescrevendo o valor anterior armazenado. 50 | 51 | ## Objetos Mutáveis 52 | 53 | Por outro lado, os objetos mutáveis são aqueles cujo conteúdo podemos alterar após a criação sem precisar de um novo objeto. 54 | 55 | Exemplos comuns de objetos mutáveis incluem: 56 | * Listas (list) 57 | * Dicionários (dict) 58 | * Conjuntos (set) 59 | 60 | Como 61 | 62 | ```python 63 | lista = [1, 2, 3] 64 | lista.append(4) 65 | print(lista) 66 | ``` 67 | 68 | ## Importância na Prática 69 | 70 | Na prática, compreender a diferença entre esses tipos de objetos é crucial para evitar efeitos colaterais inesperados em seu código. 71 | 72 | Por exemplo, como vimos no começo, ao atribuir a mesma lista a mais de uma váriavel. 73 | Mais comumente, porém, ao passar objetos mutáveis como argumentos para funções, 74 | é possível que esses objetos sejam alterados dentro da função, afetando o estado do objeto fora da função. -------------------------------------------------------------------------------- /aulas/Semana 2 - Revisao Python/9_lista_1.md: -------------------------------------------------------------------------------- 1 | ## 1. Implementação de Operações Básicas de Álgebra Linear 2 | 3 | Implemente três funções em Python que realizam operações básicas de álgebra linear: 4 | 5 | ### A. Produto Interno: 6 | Implemente uma função chamada produto_interno(vetor1, vetor2) que recebe dois vetores (listas de números) como entrada e retorna o produto interno (dot product) desses vetores. 7 | * Entrada: Dois vetores representados como listas de números [a1, a2, ..., an] e [b1, b2, ..., bn]. 8 | * Saída: O valor do produto interno entre os vetores. 9 | 10 | Exemplo: 11 | 12 | ```python 13 | vetor1 = [1, 2, 3] 14 | vetor2 = [4, 5, 6] 15 | resultado = produto_interno(vetor1, vetor2) 16 | # resultado deve ser 32 17 | ``` 18 | 19 | ### B. Multiplicação de Matriz por Vetor: 20 | Implemente uma função chamada matriz_por_vetor(matriz, vetor) que recebe uma matriz (lista de listas de números) e um vetor como entrada, e retorna o produto da matriz pelo vetor. 21 | 22 | * Entrada: Uma matriz representada como uma lista de listas de números, onde cada sublista é uma linha da matriz, e um vetor representado como uma lista de números. 23 | * Saída: O resultado da multiplicação da matriz pelo vetor, representado como uma lista de números. 24 | 25 | Exemplo: 26 | 27 | ```python 28 | 29 | matriz = [ 30 | [1, 2], 31 | [3, 4], 32 | [5, 6] 33 | ] 34 | vetor = [7, 8] 35 | resultado = matriz_por_vetor(matriz, vetor) 36 | # resultado deve ser [23, 53, 83] 37 | ``` 38 | 39 | ### C. Multiplicação de Matriz por Matriz 40 | Implemente uma função chamada matriz_por_matriz(matriz1, matriz2) que recebe duas matrizes como entrada e retorna o produto dessas duas matrizes. 41 | 42 | * Entrada: Duas matrizes representadas como listas de listas de números. 43 | * Saída: O resultado da multiplicação das duas matrizes, representado como uma nova matriz (lista de listas). 44 | 45 | Exemplo: 46 | 47 | ```python 48 | matriz1 = [ 49 | [1, 2], 50 | [3, 4] 51 | ] 52 | matriz2 = [ 53 | [5, 6], 54 | [7, 8] 55 | ] 56 | resultado = matriz_por_matriz(matriz1, matriz2) 57 | # resultado deve ser [[19, 22], [43, 50]] 58 | ``` 59 | 60 | Restrições e Considerações: 61 | * Os vetores e as matrizes fornecidos como entrada estarão sempre corretamente dimensionados para as operações (ou seja, terão tamanhos compatíveis). 62 | * Não é permitido utilizar bibliotecas externas como NumPy para realizar as operações. Implemente as operações manualmente. 63 | 64 | Dica: Para a multiplicação de matriz por matriz, lembre-se de que o elemento na posição (i, j) da matriz resultante é o produto interno da linha i da primeira matriz com a coluna j da segunda matriz. 65 | 66 | ## 2. Similaridade de Jaccard entre Textos 67 | 68 | A similaridade de Jaccard é uma medida de similaridade entre dois conjuntos, muito utilizada para comparar textos, 69 | definida como: 70 | 71 | $$ S_{Jaccard}(A, B) = \frac{|A \cap B|}{|A \cup B|} $$ 72 | 73 | onde: 74 | - $|A \cap B|$ é o número de elementos na interseção dos conjuntos $A$ e $B$, 75 | - $|A \cup B|$ é o número de elementos na união dos conjuntos $A$ e $B$. 76 | 77 | Considere os seguintes textos: 78 | 79 | **Texto 1:** "O gato está no telhado." 80 | 81 | **Texto 2:** "O gato dorme no telhado." 82 | 83 | ### Perguntas: 84 | 85 | A. Quais são os conjuntos de palavras únicos para cada texto após a padronização (remover pontuações e transformar todas as palavras para letras minúsculas)? 86 | 87 | B. Quantos elementos estão na interseção dos dois conjuntos? 88 | 89 | C. Quantos elementos estão na união dos dois conjuntos? 90 | 91 | D. Qual é a similaridade de Jaccard entre os dois textos? 92 | 93 | ## 3. Encontrar termos no texto 94 | 95 | Dado o texto abaixo, escreva um programa em Python que receba uma lista de termos e reporte em quais linhas cada termo apareceu. 96 | 97 | Texto: 98 | 99 | ``` 100 | Este é o primeiro exemplo de linha. 101 | Esta linha é a segunda linha do exemplo. 102 | O terceiro exemplo está aqui. 103 | Aqui temos a quarta linha de exemplo. 104 | E finalmente, esta é a quinta linha de exemplo. 105 | ``` 106 | 107 | Lista de Termos: 108 | 109 | ``` 110 | linha 111 | exemplo 112 | segunda 113 | quinta 114 | 115 | ``` 116 | 117 | Requisitos do Programa: 118 | * O programa deve ler o texto e a lista de termos. 119 | * Para cada termo da lista, o programa deve identificar e imprimir em quais linhas (números das linhas) o termo aparece. 120 | * A numeração das linhas deve começar de 1. 121 | 122 | ### Saída esperada 123 | ``` 124 | Termo 'linha' aparece nas linhas: 1, 2, 4, 5 125 | Termo 'exemplo' aparece nas linhas: 1, 2, 3, 4, 5 126 | Termo 'segunda' aparece na linha: 2 127 | Termo 'quinta' aparece na linha: 5 128 | ``` 129 | 130 | ## 4. Contar palavras em arquivo 131 | 132 | Você deve desenvolver um programa em Python que leia o arquivo de texto `nintendo.txt` e realize as seguintes tarefas: 133 | 134 | * Contar o número total de palavras contidas no arquivo. 135 | * Listar as 5 palavras mais frequentes no arquivo. 136 | * Listar as 5 sequências de duas palavras mais frequentes no arquivo. 137 | 138 | Para a contagem das palavras e sequências: 139 | * Desconsidere diferenças entre maiúsculas e minúsculas (ou seja, trate todas as palavras como se fossem minúsculas) -> `str.lower()`. 140 | * Descartar todos os caracteres que não sejam letras e números para garantir a precisão das contagens -> `str.isalnum()`. 141 | 142 | ### Exemplo 143 | 144 | ```python 145 | texto = "A programação em Python é divertida. A programação é poderosa e simples. Python é uma linguagem versátil." 146 | obter_estatisticas(texto) 147 | # Número total de palavras: 15 148 | 149 | # Top 5 palavras mais frequentes: 150 | # 1. é: 3 151 | # 2. a: 2 152 | # 3. programação: 2 153 | # 4. python: 2 154 | # 5. em: 1 155 | 156 | # Top 5 sequências de duas palavras mais frequentes: 157 | # 1. a programação: 2 158 | # 2. python é: 2 159 | # 3. programação em: 1 160 | # 4. em python: 1 161 | # 5. é divertida: 1 162 | ``` 163 | 164 | 165 | ## 5. Validar CPF 166 | 167 | Um CPF (Cadastro de Pessoas Físicas) é composto por 11 dígitos numéricos, 168 | geralmente apresentados no formato "XXX.XXX.XXX-YY". 169 | Para ser considerado válido, um CPF deve atender aos seguintes critérios: 170 | 171 | 1. Deve conter 11 dígitos numéricos. 172 | 2. Não deve consistir de todos os dígitos iguais (por exemplo, "111.111.111-11" não é um CPF válido). 173 | 3. Deve obedecer ao algoritmo de validação do CPF, descrito a seguir: 174 | * Os primeiros 9 dígitos são os números base. 175 | * O 10º dígito (primeiro dígito verificador) é calculado da seguinte forma: 176 | * Multiplique os 9 primeiros dígitos pela sequência decrescente de 10 a 2. 177 | * Some os resultados dessas multiplicações. 178 | * Calcule o resto da divisão dessa soma por 11. 179 | * Se o resto for menor que 2, o dígito verificador é 0. Se for maior ou igual a 2, o dígito verificador é 11 menos o resto. 180 | * O 11º dígito (segundo dígito verificador) é calculado da mesma forma, mas agora com a sequência decrescente de 11 a 2 (considerando os 9 dígitos base mais o primeiro dígito verificador). 181 | 182 | Implemente a função `valida_cpf(cpf)` que recebe uma string representando o CPF no formato "XXX.XXX.XXX-YY" 183 | e retorna um valor booleano indicando se o CPF é válido ou não. 184 | 185 | ### Exemplos 186 | 187 | ```python 188 | print(valida_cpf("123.456.789-14")) # Deve retornar False 189 | print(valida_cpf("111.444.777-35")) # Deve retornar True 190 | ``` 191 | -------------------------------------------------------------------------------- /aulas/Semana 2 - Revisao Python/9_lista_1_gabarito.py: -------------------------------------------------------------------------------- 1 | ########## Questão 1.A ########## 2 | print('########## Questão 1.A ##########') 3 | 4 | def inner_product(v1, v2): 5 | size_v1 = len(v1) 6 | size_v2 = len(v2) 7 | if size_v1 != size_v2: 8 | print('Os vetores devem ter o mesmo tamanho') 9 | return None 10 | 11 | result = 0 12 | for i in range(size_v1): 13 | result += v1[i] * v2[i] 14 | return result 15 | 16 | v1 = [1, 2, 3] 17 | v2 = [4, 5, 6] 18 | print(inner_product(v1, v2)) 19 | 20 | 21 | 22 | ########## Questão 1.B ########## 23 | print('\n\n\n') 24 | print('########## Questão 1.B ##########') 25 | 26 | def mult_matrix_vector(m, v): 27 | rows_m = len(m) 28 | cols_m = len(m[0]) 29 | 30 | size_v = len(v) 31 | 32 | if cols_m != size_v: 33 | print('O número de colunas da matriz deve ser igual ao tamanho do vetor') 34 | return None 35 | 36 | result = [] 37 | for i in range(rows_m): 38 | result.append(inner_product(m[i], v)) 39 | return result 40 | 41 | m = [ 42 | [1, 2], 43 | [3, 4], 44 | [5, 6] 45 | ] 46 | v = [7, 8] 47 | print(mult_matrix_vector(m, v)) 48 | 49 | 50 | 51 | ########## Questão 1.C ########## 52 | print('\n\n\n') 53 | print('########## Questão 1.C ##########') 54 | 55 | def mult_matrix_matrix(m1, m2): 56 | rows_m1 = len(m1) 57 | cols_m1 = len(m1[0]) 58 | 59 | rows_m2 = len(m2) 60 | cols_m2 = len(m2[0]) 61 | 62 | if cols_m1 != rows_m2: 63 | print('O número de colunas da primeira matriz deve ser igual ao número de linhas da segunda matriz') 64 | return None 65 | 66 | cols = [] 67 | for j in range(cols_m2): 68 | v_col = [] 69 | for i in range(rows_m2): 70 | v_col.append(m2[i][j]) 71 | col = mult_matrix_vector(m1, v_col) 72 | cols.append(col) 73 | 74 | # Aplicar a transposta 75 | # A represetação de uma matriz é uma lista das linhas, não das colunas 76 | result = [] 77 | for i in range(rows_m1): 78 | row = [] 79 | for j in range(cols_m2): 80 | row.append(cols[j][i]) 81 | result.append(row) 82 | return result 83 | 84 | matriz1 = [ 85 | [1, 2], 86 | [3, 4] 87 | ] 88 | matriz2 = [ 89 | [5, 6], 90 | [7, 8] 91 | ] 92 | print(mult_matrix_matrix(matriz1, matriz2)) 93 | 94 | 95 | 96 | ########## Questão 2 ########## 97 | print('\n\n\n') 98 | print('########## Questão 2 ##########') 99 | 100 | def computar_jaccard(a, b): 101 | num = a.intersection(b) 102 | den = a.union(b) 103 | return len(num) / len(den) 104 | 105 | def process_text(t): 106 | t = t.lower() 107 | # Remover pontuação 108 | # Opção 1 - Só funciona para o exemplo dado 109 | # t = t.replace('.', '') 110 | # Opção 2 - Funciona para qualquer texto 111 | c_valid = [] 112 | for c in t: 113 | if c.isalnum() or c.isspace(): 114 | c_valid.append(c) 115 | t = ''.join(c_valid) 116 | return t 117 | 118 | t1 = "O gato está no telhado." 119 | t2 = "O gato dorme no telhado." 120 | 121 | # Aplica o processamento de texto 122 | t1 = process_text(t1) 123 | t2 = process_text(t2) 124 | 125 | # Convertendo para conjuntos 126 | t1 = set(t1.split()) 127 | t2 = set(t2.split()) 128 | 129 | # Calcula a similaridade de Jaccard 130 | print(computar_jaccard(t1, t2)) 131 | 132 | 133 | 134 | ########## Questão 3 ########## 135 | print('\n\n\n') 136 | print('########## Questão 3 ##########') 137 | 138 | text = """ 139 | Este é o primeiro exemplo de linha. 140 | Esta linha é a segunda linha do exemplo. 141 | O terceiro exemplo está aqui. 142 | Aqui temos a quarta linha de exemplo. 143 | E finalmente, esta é a quinta linha de exemplo. 144 | """ 145 | 146 | terms = """ 147 | linha 148 | exemplo 149 | segunda 150 | quinta 151 | """ 152 | 153 | text = text.strip().split('\n') 154 | terms = terms.strip().split('\n') 155 | 156 | def find_lines(text, term): 157 | num_line = 1 158 | result = [] 159 | for line in text: 160 | if term in line: 161 | result.append(num_line) 162 | num_line += 1 163 | return result 164 | 165 | for term in terms: 166 | line_indices = find_lines(text, term) 167 | print(f"Termo '{term}' aparece nas linhas: {line_indices}") 168 | 169 | 170 | 171 | ########## Questão 4 ########## 172 | print('\n\n\n') 173 | print('########## Questão 4 ##########') 174 | 175 | def count_words(words): 176 | count_map = {} 177 | for word in words: 178 | if word not in count_map: 179 | count_map[word] = 0 180 | count_map[word] += 1 181 | return count_map 182 | 183 | def most_frequent_word(count_map): 184 | max_count = 0 185 | max_word = None 186 | for word, count in count_map.items(): 187 | if count > max_count: 188 | max_count = count 189 | max_word = word 190 | return max_word 191 | 192 | def most_frequent_words(count_map, top_n): 193 | # Copiar o dicionário para não alterar o original 194 | count_map = count_map.copy() 195 | 196 | words = [] 197 | for i in range(top_n): 198 | word = most_frequent_word(count_map) 199 | del count_map[word] 200 | words.append(word) 201 | return words 202 | 203 | def get_2_words(words): 204 | two_words_list = [] 205 | for i in range(len(words) - 1): 206 | two_words_list.append((words[i], words[i+1])) 207 | return two_words_list 208 | 209 | def get_stats(words): 210 | count_map = count_words(words) 211 | 212 | top_n = 5 213 | top_words = most_frequent_words(count_map, top_n) 214 | print(f"Total de palavras: {len(words)}") 215 | print(f"Top {top_n} palavras:") 216 | for word in top_words: 217 | print(f"{word}: {count_map[word]}") 218 | 219 | two_words_list = get_2_words(words) 220 | count_map = count_words(two_words_list) 221 | top_n = 5 222 | top_words = most_frequent_words(count_map, top_n) 223 | print(f"Top {top_n} pares de palavras:") 224 | for word in top_words: 225 | print(f"{word}: {count_map[word]}") 226 | return top_words 227 | 228 | filepath = "nintendo.txt" 229 | with open(filepath, 'r') as f: 230 | text = f.read() 231 | # Roubando a função process_text do exercício 2 232 | text = process_text(text) 233 | 234 | words = text.split() 235 | get_stats(words) 236 | get_stats(text) 237 | 238 | 239 | 240 | ########## Questão 5 ########## 241 | print('\n\n\n') 242 | print('########## Questão 5 ##########') 243 | print('Error 404: Resposta não encontrada') -------------------------------------------------------------------------------- /aulas/Semana 3 - Documentacao & Type Hint/12_similaridade_documentos.md: -------------------------------------------------------------------------------- 1 | # Similaridade entre Documentos 2 | 3 | Até agora, ao falar sobre qualidade de software, discutimos tópicos como documentação e uso de *type hints*. 4 | Para consolidar esses conceitos, vamos criar uma aplicação simples para encontrar documentos similares. 5 | Esta aplicação também servirá como base para as próximas aulas, nas quais abordaremos conceitos de testes unitários e tratamento de exceções. 6 | 7 | Nesta aula, vamos introduzir alguns conceitos básicos de Processamento de Linguagem Natural (NLP, em inglês). 8 | Vamos focar em três conceitos principais: 9 | 1. Representação de Documentos 10 | 2. Vocabulário 11 | 3. Similaridade entre Documentos 12 | 13 | É importante notar que a ideia aqui é apenas apresentar esses tópicos de forma superficial, para que a aplicação faça mais sentido. 14 | Para um estudo mais aprofundado, recomendo a disciplina de Processamento de Linguagem Natural oferecida pela FGV. 15 | 16 | ## 1. Representação Computacional de Texto 17 | 18 | ### Por que Representar Textos Computacionalmente? 19 | 20 | Em aplicações envolvendo processamento de texto, é essencial que o computador seja capaz de compreender e manipular texto de maneira significativa. 21 | Para isso, precisamos transformar o texto, que originalmente é uma sequência de caracteres, em uma representação numérica que o computador possa processar e analisar. 22 | 23 | ### Diferentes Formas de Representar Texto 24 | 25 | Não existe uma única maneira correta de representar texto; 26 | a escolha da representação depende da aplicação específica. 27 | Aqui estão algumas formas comuns de representação: 28 | 29 | 1. **Representação como Cadeia de Caracteres**: 30 | - A forma mais básica, onde cada documento é simplesmente uma sequência de caracteres. 31 | - **Caso de uso**: Exibição para o usuário. 32 | - **Limitação**: Não permite operações matemáticas ou comparações eficientes entre diferentes textos. 33 | 34 | 2. **Representação como Lista de Palavras**: 35 | - Nesta abordagem, introduzimos o conceito de "palavra". 36 | - Para computação, uma palavra é normalmente qualquer sequência de caracteres delimitada por espaços em branco. 37 | - Chamamos o processo de converter uma sequência de caracteres em uma sequência de palavras de **tokenização**. 38 | - **Exemplo**: A frase "o gato preto" é dividida em ["o", "gato", "preto"]. 39 | - **Caso de uso**: Permite operações como contagem de palavras e construção de vocabulário. 40 | - **Limitação**: Não permite a aplicação de operações matemáticas de forma eficiente. 41 | 42 | 3. **Vocabulário**: 43 | - Consiste em um conjunto de todas as palavras únicas (tokens) validas presentes em um ou mais documentos. 44 | - **Exemplo**: Dado os documentos ["o gato", "o cachorro"], o vocabulário seria {"o", "gato", "cachorro"}. 45 | - Ter um vocabulário é essencial para converter texto em uma representação numérica. 46 | 47 | ### Exemplo Prático de Tokenização e Criação de Vocabulário 48 | 49 | ```python 50 | docs = [ 51 | "o gato preto", 52 | "o cachorro marrom", 53 | "o gato e o cachorro" 54 | ] 55 | 56 | # Criação de vocabulário 57 | vocab = set() 58 | for doc in docs: 59 | words = doc.split() 60 | vocab.update(words) 61 | 62 | print(vocab) 63 | # Saída: {'o', 'gato', 'preto', 'cachorro', 'marrom', 'e'} 64 | ``` 65 | 66 | ## 2. Modelo Bag-of-Words (BoW) 67 | 68 | ### O que é o Modelo Bag-of-Words? 69 | 70 | Bag-of-Words é uma técnica simples e amplamente utilizada para representar texto em forma de vetor. 71 | Nessa abordagem: 72 | 73 | * Cada documento é representado por um vetor. 74 | * O vetor contém a contagem de cada palavra do vocabulário no documento. 75 | * Ignora a ordem das palavras, a estrutura gramatical e a semântica das palavras. 76 | 77 | Por que Usar Bag-of-Words? 78 | * É uma forma direta e eficiente de transformar texto em dados numéricos que podem ser usados por algoritmos de aprendizado de máquina. 79 | * É fácil de implementar e funciona bem para tarefas básicas de classificação de texto. 80 | 81 | ### Implementação de Bag-of-Words 82 | 83 | ```python 84 | def bag_of_words(doc, vocab): 85 | words = doc.split() 86 | 87 | bow = [0] * len(vocab) 88 | for i in range(len(vocab)): 89 | word = vocab[i] 90 | bow[i] = words.count(word) 91 | return bow 92 | 93 | # Ordenar o vocabulário para consistência 94 | # Ou seja, saberemos que: 95 | # vocab[0] = "cachorro" 96 | # vocab[1] = "e" 97 | # ... 98 | vocab = sorted(list(vocab)) 99 | bows = [] 100 | for doc in docs: 101 | bow = bag_of_words(doc, vocab) 102 | bows.append(bow) 103 | 104 | # Exibindo as representações 105 | for i in range(len(docs)): 106 | doc = docs[i] 107 | bow = bows[i] 108 | print(f"Documento: {doc}\nRepresentação: {bow}") 109 | ``` 110 | 111 | ### Vantagens e Limitações do Bag-of-Words 112 | 113 | Vantagens: 114 | * Simplicidade: Fácil de entender e implementar. 115 | * Escalabilidade: Funciona bem para grandes coleções de documentos. 116 | 117 | Limitações: 118 | * Ignora a ordem das palavras: Perde o contexto que a ordem das palavras pode fornecer. 119 | * Dimensionalidade: O vetor pode se tornar muito grande se o vocabulário for extenso, o que pode levar a problemas de armazenamento e processamento. 120 | 121 | ## 3. Cálculo de Distância entre Documentos 122 | 123 | Uma vez que temos nossos documentos representados como vetores, podemos comparar sua similaridade usando medidas de distância. 124 | 125 | ### Distância de Jaccard 126 | 127 | A distância de Jaccard mede a similaridade entre dois conjuntos, calculando a razão entre a interseção e a união dos conjuntos de palavras. 128 | 129 | ```python 130 | def jaccard_distance(s1, s2): 131 | num = len(s1.intersection(s2)) 132 | den = len(s1.union(s2)) 133 | return 1 - num / den 134 | 135 | # Exemplo de uso 136 | doc1 = set(docs[0].split()) 137 | doc2 = set(docs[1].split()) 138 | print(f"Distância de Jaccard: {jaccard_distance(doc1, doc2)}") 139 | ``` 140 | 141 | Útil quando queremos comparar documentos com base no conjunto de palavras únicas, desconsiderando a frequência. 142 | 143 | ### Distância Euclidiana 144 | 145 | ```python 146 | import math 147 | 148 | def euclidean_distance(v1, v2): 149 | dist = 0 150 | for i in range(len(v1)): 151 | dist += (v1[i] - v2[i]) ** 2 152 | return math.sqrt(dist) 153 | 154 | # Exemplo de uso 155 | print(f"Distância Euclidiana: {euclidean_distance(bows[0], bows[1])}") 156 | ``` 157 | 158 | Considera a frequência das palavras, sendo mais sensível a mudanças nas contagens de palavras entre os documentos. 159 | 160 | ## Exercicio 161 | 162 | Adaptar os códigos de exemplo acima para podermos lidar com as páginas da wikipedia vistos na ultima aula. 163 | Para comparar as paginas, utilizar a distancia euclidiana. 164 | 165 | ## Exercício 166 | 167 | Adapte os códigos de exemplo para lidar com as páginas da Wikipedia discutidas na última aula. Para comparar a similaridade entre as páginas, utilize a distância euclidiana. Siga os passos abaixo: 168 | 169 | ### 0. **Modularização do Código para Melhor Legibilidade** 170 | - Separe o código em funções distintas para melhorar a organização e legibilidade. 171 | - Crie funções dedicadas para leitura de arquivos e criação de vocabulário. 172 | - Documentar e adicionar Type Hint para todas as funções. 173 | - Coloque todas as funções no início do código e concentre a lógica principal de execução dentro de uma função `main`. 174 | 175 | ### 1. **Adaptar o Código para Lidar com Páginas da Wikipedia** 176 | - Modifique o código de exemplo para carregar textos das páginas da Wikipedia. 177 | - Certifique-se de que o vocabulário inclui todas as palavras únicas presentes nos documentos extraídos. 178 | 179 | ### 2. **Testar a Execução do Código Adaptado** 180 | - Execute o código adaptado. 181 | - Observe e documente o comportamento do programa. 182 | - Identifique possíveis problemas de desempenho, como lentidão na execução. Reflita sobre por que o código pode estar lento. 183 | 184 | ### 3. **Otimização de Desempenho** 185 | - Melhore a eficiência das funções críticas, por exemplo, a função de contagem de palavras no modelo Bag-of-Words. 186 | - Considere reduzir o tamanho do vocabulário para minimizar o número de cálculos de distância, mantendo apenas as palavras mais frequentes ou relevantes. 187 | - Adicione uma função de normalização de texto que converta tudo para caixa baixa e remova caracteres não alfanuméricos, para garantir consistência na tokenização. 188 | 189 | ### 4. **Implementação de Busca por Páginas Similares** 190 | - Escolha uma página da Wikipedia e implemente um algoritmo para encontrar as páginas mais similares a ela com base no conteúdo textual. 191 | - Carregue também os títulos das páginas, além do conteúdo textual. 192 | - Desenvolva uma função que permita ao usuário selecionar uma página específica usando os títulos das páginas. 193 | - Compare o conteúdo textual das páginas e exiba os títulos das páginas que são mais similares ao título selecionado pelo usuário, utilizando a distância euclidiana para medir similaridade. 194 | -------------------------------------------------------------------------------- /aulas/Semana 3 - Documentacao & Type Hint/wikipedia_good_articles_video_games.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 3 - Documentacao & Type Hint/wikipedia_good_articles_video_games.zip -------------------------------------------------------------------------------- /aulas/Semana 4 - Excecoes & Teste Unitarios /13_erros.md: -------------------------------------------------------------------------------- 1 | # Erros 2 | 3 | Por mais que desejemos que nossas aplicações funcionem perfeitamente na primeira tentativa, é comum que desenvolvedores encontrem erros ao tentar executar um programa. 4 | 5 | ## Tipos de erro 6 | 7 | Esses erros são uma parte natural do processo de desenvolvimento e, na maioria das vezes, podem ser classificados em três categorias principais: 8 | 9 | 1. Erro de Sintaxe 10 | 2. Erro Lógico 11 | 3. Erro em Tempo de Execução 12 | 13 | ### Erro de Sintaxe 14 | 15 | Erros de sintaxe ocorrem quando o código viola as regras gramaticais da linguagem de programação. 16 | Esses erros são detectados pelo interpretador ou compilador antes mesmo do código ser executado, e resultam em mensagens de erro que indicam onde a violação ocorreu. 17 | Exemplos comuns incluem a falta de ponto e vírgula, colchetes, ou a indentação incorreta do código. 18 | 19 | ```python 20 | arr = [1, 2, 3, 4] 21 | for v in arr 22 | print(v) 23 | ``` 24 | 25 | Neste exemplo, podemos ver claramente que falta um dois-pontos (`:`) no final da linha do `for`. 26 | Esse pequeno erro de sintaxe impede que o código seja executado. 27 | 28 | ### Erro Lógico 29 | 30 | Erros lógicos ocorrem quando a lógica implementada no código não corresponde ao comportamento desejado. 31 | Mesmo que o código esteja sintaticamente correto e execute sem problemas, ele pode produzir resultados inesperados devido a uma falha na lógica. 32 | 33 | ```python 34 | def find_min_value(arr): 35 | min_value = 0 36 | for v in arr: 37 | if v < min_value: 38 | min_value = v 39 | return min_value 40 | 41 | arr = [1, 2, 3, 4] 42 | print(find_min_value(arr)) 43 | ``` 44 | 45 | Esperamos que o menor valor retornado ao executar esse código seja `1`. 46 | No entanto, o resultado será `0`. 47 | Isso acontece porque o valor inicial `min_value` foi definido como `0`. 48 | Como a lista contém apenas valores positivos, nenhum deles será menor que `0`, levando a um resultado incorreto. 49 | 50 | ### Erro em Tempo de Execução 51 | 52 | Erros em tempo de execução são causados por condições inesperadas que ocorrem enquanto o código está sendo executado. 53 | Esses erros não são detectados pelo interpretador até que o código seja efetivamente executado e podem interromper o funcionamento do programa. 54 | Exemplos incluem tentativas de acessar uma posição inexistente em uma lista, divisões por zero, ou manipulação inadequada de variáveis nulas. 55 | 56 | Continuando com o exemplo anterior, podemos ajustar o valor inicial de `min_value` para `arr[0]`, esperando que o código funcione corretamente: 57 | 58 | ```python 59 | def find_min_value(arr): 60 | min_value = arr[0] 61 | for v in arr: 62 | if v < min_value: 63 | min_value = v 64 | return min_value 65 | 66 | arr = [1, 2, 3, 4] 67 | print(find_min_value(arr)) 68 | ``` 69 | 70 | Embora essa função funcione corretamente para listas não vazias, ela falhará se a lista for vazia, resultando em um erro em tempo de execução. 71 | Nesse caso, o Python retornará um erro indicando que não é possível acessar a posição `0` de uma lista vazia. 72 | 73 | Esse tipo de erro é comum ao lidar com entrada e saída de dados, onde é possível que o usuário forneça dados em um formato inesperado ou inválido, para o qual o código não foi preparado. 74 | 75 | ## Como Solucionar Erros? 76 | 77 | Tudo bem, então, como podemos minimizar a ocorrência desses erros? 78 | 79 | Para **erros de sintaxe**, não há muito com o que se preocupar. Quando tentamos executar (ou compilar) um código, o interpretador (ou compilador) identifica imediatamente esses erros, indicando sua existência e localização exata. 80 | 81 | A verdadeira dificuldade surge ao tentarmos evitar erros lógicos e erros em tempo de execução. 82 | 83 | ### Evitando Erros Lógicos 84 | 85 | Como podemos garantir que nossa implementação está, de fato, funcionando corretamente? 86 | A resposta está nos testes. Ao testarmos diferentes exemplos, podemos verificar se o comportamento do código corresponde ao esperado. 87 | Essa prática foi formalizada na área de engenharia de software como `testes unitários`. 88 | Testes unitários são fundamentais para validar a lógica do código, ajudando a identificar e corrigir erros antes que o programa seja executado em um ambiente de produção. 89 | 90 | ### Lidando com Erros em Tempo de Execução 91 | 92 | Para erros em tempo de execução, os testes unitários também podem ser úteis até certo ponto. 93 | Podemos incluir exemplos de entradas inválidas para observar como nossa aplicação se comporta. 94 | No entanto, não é viável nem desejável prever e tratar todos os possíveis erros em tempo de execução que podem ocorrer em cada função ou prever todo comportamento inesperado que um usuário pode desencadear. 95 | 96 | Se tentássemos cobrir todos esses casos, acabaríamos com funções extremamente complexas, cheias de verificações redundantes. 97 | Em vez disso, o que fazemos é tratar os casos mais comuns e críticos, conscientes de que outros erros podem ocorrer. 98 | Para esses cenários, lançamos `exceções`. 99 | 100 | #### Tratamento de Exceções 101 | 102 | A maioria das linguagens modernas, incluindo Python, inclui mecanismos de `tratamento de exceções` como parte da linguagem. 103 | Esses mecanismos permitem capturar erros em tempo de execução e reagir de maneira controlada, evitando que o programa simplesmente falhe. 104 | 105 | ## Próximos Passos 106 | 107 | Nas próximas aulas, exploraremos em maior profundidade como utilizar `testes unitários` para garantir a robustez do código e como implementar `tratamentos de exceção` em Python para lidar com situações inesperadas, mantendo o controle sobre o fluxo de execução do programa. -------------------------------------------------------------------------------- /aulas/Semana 4 - Excecoes & Teste Unitarios /15_depuracao.md: -------------------------------------------------------------------------------- 1 | # Níveis de Depuração de Código 2 | 3 | Depuração é o processo de encontrar e corrigir erros em um programa de computador. 4 | Independentemente da experiência do programador, erros são comuns e inevitáveis. 5 | Portanto, saber como depurar código eficientemente é uma habilidade essencial para qualquer desenvolvedor. 6 | Nesta aula, vamos explorar diferentes níveis de depuração, desde técnicas básicas até estratégias avançadas. 7 | 8 | ## 1. Nível Básico: Depuração Manual 9 | 10 | ### 1.1 Uso de Mensagens de Impressão 11 | 12 | Uma das formas mais simples de depurar código é usar a função `print()` para exibir valores de variáveis e mensagens no console. Isso ajuda a entender o que está acontecendo em diferentes partes do código. 13 | 14 | ```python 15 | def calcular_soma(a, b): 16 | print(f"Calculando a soma de {a} e {b}") # Mensagem de depuração 17 | return a + b 18 | 19 | resultado = calcular_soma(5, 3) 20 | print(f"Resultado: {resultado}") 21 | ``` 22 | 23 | Vantagens: 24 | * Simples de implementar. 25 | * Útil para rastrear o fluxo de execução e valores de variáveis. 26 | 27 | Desvantagens: 28 | * Pode gerar muito output, tornando difícil encontrar informações relevantes. 29 | * Não é eficiente para programas complexos ou de larga escala. 30 | 31 | Quando Usar: 32 | * **Ideal para problemas simples**: 33 | Use `print()` quando estiver lidando com erros de lógica ou comportamento inesperado em partes específicas do código. 34 | * **Rápida verificação**: 35 | Quando você precisa de uma resposta rápida sobre o estado de uma variável ou para verificar se uma parte do código está sendo executada. 36 | * **Projetos pequenos ou scripts**: 37 | Adequado para projetos de pequena escala ou scripts curtos, onde a complexidade é mínima. 38 | 39 | ### 1.2 Verificação Visual 40 | 41 | Ler e revisar o código com atenção para identificar erros de sintaxe ou lógicos. Algumas dicas incluem: 42 | * Verificar indentação correta (especialmente em linguagens como Python). 43 | * Conferir o uso correto de parênteses e chaves. 44 | * Procurar por erros comuns, como variáveis não inicializadas ou uso incorreto de operadores. 45 | 46 | Vantagens: 47 | * Ajuda a desenvolver habilidades de leitura de código. 48 | * Pode encontrar erros óbvios que passam despercebidos por testes automatizados. 49 | 50 | Desvantagens: 51 | * Pode ser demorado para códigos grandes. 52 | * Erros sutis ou complexos podem não ser detectados apenas com a leitura. 53 | 54 | Quando Usar: 55 | * **Erros de sintaxe e formatação**: 56 | Use a verificação visual para identificar problemas evidentes de sintaxe, formatação ou lógica básica. 57 | * **Revisão de código**: 58 | Ideal para revisões de código em equipe, onde múltiplos olhos podem detectar erros que passam despercebidos por uma única pessoa. 59 | 60 | ### 1.3 Testes Manuais 61 | 62 | Executar o programa com diferentes entradas e observar se os resultados são os esperados. 63 | Isso ajuda a identificar falhas em cenários específicos. 64 | 65 | ```python 66 | # Testando manualmente a função de soma 67 | print(calcular_soma(10, 5)) # Deve imprimir 15 68 | print(calcular_soma(-3, 3)) # Deve imprimir 0 69 | ``` 70 | 71 | Vantagens: 72 | * Facilita a identificação de cenários de falha específicos. 73 | * Útil para testes iniciais e desenvolvimento rápido. 74 | 75 | Desvantagens: 76 | * Propenso a erros humanos. 77 | * Não é escalável para testar todos os cenários possíveis em programas complexos. 78 | 79 | Quando Usar: 80 | * **Validação inicial**: 81 | Use testes manuais para validar rapidamente novas funcionalidades ou correções. 82 | * **Experimentação e prototipagem**: 83 | Adequado para projetos em fase inicial, onde a velocidade de desenvolvimento é crucial. 84 | 85 | ## 2. Nível Intermediário: Uso de Ferramentas de Depuração 86 | 87 | ### 2.1 Depuradores Integrados 88 | 89 | Ambientes de Desenvolvimento Integrados (IDEs) como 90 | [Visual Studio Code](https://code.visualstudio.com/docs/editor/debugging) 91 | e [PyCharm](https://www.jetbrains.com/help/pycharm/debugging-your-first-python-application.html) 92 | oferecem depuradores que permitem: 93 | * **Definir Breakpoints**: 94 | Pontos no código onde a execução será pausada para análise. 95 | * **Executar Passo a Passo**: 96 | Permite executar o código linha por linha, observando como o estado do programa muda. 97 | * **Inspecionar Variáveis**: 98 | Visualizar o valor atual das variáveis em qualquer ponto durante a execução. 99 | 100 | Vantagens: 101 | * Fornece uma visão detalhada do comportamento do programa. 102 | * Permite pausar e retomar a execução em pontos específicos. 103 | * Facilita a identificação de problemas em loops e funções complexas. 104 | 105 | Desvantagens: 106 | * Pode ser complexo para iniciantes. 107 | * Requer um ambiente de desenvolvimento configurado corretamente. 108 | 109 | Quando Usar: 110 | * **Depuração de problemas complexos**: 111 | Use depuradores integrados para investigar bugs complexos ou para entender o fluxo de execução de código em projetos grandes. 112 | * **Análise de loops e funções recursivas**: 113 | Ideal para depurar código que envolve lógica complexa e múltiplas chamadas de funções. 114 | 115 | ### 2.2 Exploração de Pilhas de Chamada 116 | 117 | A pilha de chamadas mostra a sequência de funções que foram chamadas até o ponto atual de execução. 118 | Isso é útil para entender o contexto de um erro, especialmente em casos de chamadas recursivas ou funções aninhadas. 119 | 120 | ```python 121 | def funcao_a(): 122 | funcao_b() 123 | 124 | def funcao_b(): 125 | funcao_c() 126 | 127 | def funcao_c(): 128 | print("Dentro de funcao_c") 129 | 130 | funcao_a() 131 | ``` 132 | 133 | ### 2.3 Mensagens de Erro Detalhadas 134 | 135 | Aprender a interpretar mensagens de erro pode fornecer pistas importantes sobre o que deu errado: 136 | * **IndexError**: 137 | Tentativa de acessar um índice que não existe em uma lista. 138 | * **TypeError**: 139 | Operação inválida para um tipo de dado (por exemplo, somar uma string com um número). 140 | * **SyntaxError**: 141 | Erro de sintaxe, como esquecer um parêntese ou dois pontos. 142 | 143 | ## 3. Nível Avançado: Testes Automatizados 144 | 145 | Implementar testes unitários para verificar se cada parte do código funciona como esperado. 146 | Isso é feito usando frameworks de teste, como unittest em Python ou JUnit em Java. 147 | 148 | ```python 149 | 150 | import unittest 151 | 152 | def soma(a, b): 153 | return a + b 154 | 155 | class TestSoma(unittest.TestCase): 156 | 157 | def test_soma_positiva(self): 158 | self.assertEqual(soma(2, 3), 5) 159 | 160 | def test_soma_negativa(self): 161 | self.assertEqual(soma(-2, -3), -5) 162 | 163 | if __name__ == '__main__': 164 | unittest.main() 165 | ``` 166 | 167 | Vantagens: 168 | * Automatiza o processo de verificação de erros. 169 | * Facilita a manutenção e evolução do código ao longo do tempo. 170 | * Aumenta a confiança de que as alterações no código não introduziram novos bugs. 171 | 172 | Desvantagens: 173 | * Requer tempo e esforço inicial para configurar e escrever testes. 174 | * Pode não cobrir todos os cenários possíveis. 175 | 176 | Quando Usar: 177 | * **Projetos de longa duração**: 178 | Use testes automatizados em projetos que precisam de manutenção contínua e onde mudanças frequentes no código são esperadas. 179 | * **Cobertura de código**: 180 | Ideal para garantir que partes críticas do código sejam testadas consistentemente. -------------------------------------------------------------------------------- /aulas/Semana 6 - Numpy/21_numpy_operacoes.md: -------------------------------------------------------------------------------- 1 | # Operações com ndarrays 2 | 3 | Nesta aula, vamos continuar explorando o poder do NumPy, focando em funções universais (ufuncs), geração de números aleatórios, operações com arrays booleanos e de conjuntos, além de ordenação de arrays. 4 | O objetivo é entender como essas funcionalidades podem tornar o trabalho com grandes volumes de dados eficiente, substituindo o uso de loops e outras operações que, em Python puro, seriam mais lentas. 5 | 6 | ## 1. Funções Universais (ufuncs) 7 | 8 | As `funções universais` são uma das principais funcionalidades do NumPy. 9 | Elas permitem aplicar operações matemáticas diretamente aos arrays, operando elemento por elemento de maneira muito eficiente. 10 | Em vez de escrever loops para processar cada item do array, as ufuncs permitem realizar operações em massa. 11 | 12 | Exemplos de ufuncs incluem operações matemáticas como: 13 | * `np.abs`: Calcula o valor absoluto de cada elemento. 14 | * `np.sqrt`: Calcula a raiz quadrada de cada elemento. 15 | * `np.square`: Eleva ao quadrado. 16 | * `np.log`: Logaritmo natural. 17 | * `np.floor, np.ceil`: Arredondamento para baixo ou para cima. 18 | * `np.cos, np.sin, np.tan`: Funções trigonométricas. 19 | * `np.maximum, np.minimum`: Retorna o valor máximo ou mínimo entre dois arrays. 20 | * `np.exp`: Exponencial de cada elemento. 21 | 22 | Essas funções são vetorizadas, o que significa que são aplicadas a todos os elementos de um array de uma só vez, sem a necessidade de laços explícitos. 23 | 24 | ```python 25 | import numpy as np 26 | 27 | a = np.array([1, 2, 3]) 28 | b = np.array([4, 5, 6]) 29 | 30 | # Soma dos arrays 31 | c = np.maximum(a, b) 32 | print("Máximo: ", c) 33 | 34 | # Exponencial de cada elemento 35 | exp = np.exp(a) 36 | print("Exponencial: ", exp) 37 | ``` 38 | 39 | Neste exemplo, `np.maximum` compara os elementos correspondentes de `a` e `b` e retorna o maior valor. 40 | Já `np.exp` calcula o valor de $e^x$ para cada elemento de `a`. 41 | 42 | ## 2. Gerador de Números Aleatórios 43 | 44 | O NumPy oferece o módulo `random`, que facilita a geração de números aleatórios de diferentes distribuições estatísticas. 45 | Isso é extremamente útil em simulações, experimentos estatísticos e testes. 46 | O gerador de números aleatórios do NumPy é muito mais eficiente e poderoso do que a função random padrão do Python. 47 | 48 | Principais funções: 49 | * `np.random.rand()`: 50 | Gera números aleatórios de uma distribuição uniforme no intervalo `[0, 1)`. 51 | * `np.random.randn()`: 52 | Gera números aleatórios de uma distribuição normal (média 0 e desvio padrão 1). 53 | * `np.random.randint(low, high)`: 54 | Gera números inteiros aleatórios em um intervalo específico. 55 | 56 | ```python 57 | # Gera uma matriz 3x3 de números aleatórios uniformes 58 | random_array = np.random.rand(3, 3) 59 | print("Matriz de números aleatórios:\n", random_array) 60 | 61 | # Gera números inteiros aleatórios de 1 a 10 62 | integers = np.random.randint(1, 10, size=(3, 3)) 63 | print("Números inteiros aleatórios:\n", integers) 64 | ``` 65 | 66 | Neste exemplo, utilizamos o `np.random.rand()` para gerar uma matriz de números aleatórios entre `0` e `1`, 67 | e `np.random.randint()` para gerar uma matriz de inteiros dentro do intervalo de `1` a `10`. 68 | 69 | ## 3. Operações sobre Arrays 70 | 71 | ### 3.1 Operações Booleanas 72 | 73 | Arrays booleanos são extremamente úteis em análises condicionais. 74 | O NumPy permite aplicar operações como `np.where`, `np.all`, e `np.any`, que facilitam a seleção, filtragem e análise de dados. 75 | 76 | * `np.where(condition, x, y)`: 77 | Retorna elementos de x onde a condição é verdadeira e de y onde é falsa. 78 | * `np.all(a)`: 79 | Verifica se todos os elementos do array são verdadeiros. 80 | * `np.any(a)`: 81 | Verifica se pelo menos um elemento é verdadeiro. 82 | 83 | Essas operações são rápidas e podem ser aplicadas a arrays inteiros de forma vetorizada, o que melhora o desempenho quando comparado a loops comuns. 84 | 85 | ```python 86 | arr = np.array([1, 2, 3, 4, 5]) 87 | 88 | # Condição: valores maiores que 2 89 | condition = arr > 2 90 | result = np.where(condition, arr, -1) # Substitui por -1 onde a condição é falsa 91 | print("Resultado com where:", result) 92 | 93 | # Verifica se todos os elementos são maiores que 0 94 | all_positive = np.all(arr > 0) 95 | print("Todos maiores que 0:", all_positive) 96 | ``` 97 | 98 | Aqui usamos `np.where` para substituir valores menores ou iguais a `2` por `-1`, e `np.all` para verificar se todos os elementos do array são maiores que zero. 99 | 100 | ### 3.2 Operações com Conjuntos 101 | 102 | O NumPy fornece funções para realizar operações de conjunto, como `np.unique`, `np.intersect1d`, `np.union1d` e `np.in1d`. 103 | Estas funções são úteis para comparar e manipular arrays, tratando-os como conjuntos matemáticos. 104 | * `np.unique(a)`: Retorna os valores únicos do array. 105 | * `np.intersect1d(a, b)`: Interseção entre dois arrays. 106 | * `np.union1d(a, b)`: União de dois arrays. 107 | * `np.in1d(a, b)`: Verifica se os elementos de a estão presentes em b. 108 | 109 | ```python 110 | a = np.array([1, 2, 3, 4, 5]) 111 | b = np.array([3, 4, 5, 6, 7]) 112 | 113 | # Elementos únicos 114 | unique_values = np.unique(a) 115 | print("Valores únicos:", unique_values) 116 | 117 | # Interseção de a e b 118 | intersection = np.intersect1d(a, b) 119 | print("Interseção:", intersection) 120 | 121 | # União de a e b 122 | union = np.union1d(a, b) 123 | print("União:", union) 124 | ``` 125 | 126 | Essas operações facilitam a comparação de arrays como se fossem conjuntos. 127 | A função `np.unique` elimina elementos duplicados, enquanto `np.intersect1d` e `np.union1d` permitem encontrar interseções e uniões entre arrays. 128 | 129 | ### 3.3 Ordenação de Arrays 130 | 131 | Ordenar arrays no NumPy pode ser feito com as funções `np.sort()` ou `arr.sort()`. 132 | A principal diferença entre elas é que `np.sort` retorna uma cópia ordenada do array, enquanto `arr.sort` modifica o array original. 133 | 134 | ```python 135 | arr = np.array([5, 1, 9, 3, 7]) 136 | 137 | # Ordena o array 138 | sorted_array = np.sort(arr) 139 | print("Array ordenado:", sorted_array) 140 | 141 | # Ordena in-place 142 | arr.sort() 143 | print("Array ordenado in-place:", arr) 144 | ``` 145 | 146 | Aqui, `np.sort` cria um novo array com os elementos ordenados, enquanto `arr.sort` altera o array original. 147 | 148 | ## 4. Exercícios 149 | 150 | * A. Implemente as seguintes métricas utilizando NumPy: 151 | - a) Distância Euclideana: 152 | $$ 153 | \text{distância} = \sqrt{\sum_{i} (a_i - b_i)^2} 154 | $$ 155 | 156 | - b) Similaridade de cossenos: 157 | $$ 158 | \text{similaridade} = \frac{\mathbf{a} \cdot \mathbf{b}}{\|\mathbf{a}\| \|\mathbf{b}\|} 159 | $$ 160 | 161 | * B. Implemente uma função para verificar se uma solução de Sudoku é válida. 162 | * Uma solução é válida se: 163 | * Cada linha contém todos os números de `1` a `9`, sem repetição. 164 | * Cada coluna contém todos os números de `1` a `9`, sem repetição. 165 | * Cada subgrade 3x3 contém todos os números de `1` a `9`, sem repetição. 166 | * Para facilitar, buscar na documentação do numpy as funções: `np.all`, `np.flatten` e `np.unique` 167 | * Para testar: 168 | ```python 169 | valid_sudoku = np.array([ 170 | [5, 3, 4, 6, 7, 8, 9, 1, 2], 171 | [6, 7, 2, 1, 9, 5, 3, 4, 8], 172 | [1, 9, 8, 3, 4, 2, 5, 6, 7], 173 | [8, 5, 9, 7, 6, 1, 4, 2, 3], 174 | [4, 2, 6, 8, 5, 3, 7, 9, 1], 175 | [7, 1, 3, 9, 2, 4, 8, 5, 6], 176 | [9, 6, 1, 5, 3, 7, 2, 8, 4], 177 | [2, 8, 7, 4, 1, 9, 6, 3, 5], 178 | [3, 4, 5, 2, 8, 6, 1, 7, 9] 179 | ]) 180 | 181 | invalid_sudoku = np.array([ 182 | [5, 3, 4, 6, 7, 8, 9, 1, 2], 183 | [6, 7, 2, 1, 9, 5, 3, 4, 8], 184 | [1, 9, 8, 3, 4, 2, 5, 6, 7], 185 | [8, 5, 9, 7, 6, 1, 4, 2, 3], 186 | [4, 2, 6, 8, 5, 3, 7, 9, 1], 187 | [7, 1, 3, 9, 2, 4, 8, 5, 6], 188 | [9, 6, 1, 5, 3, 7, 2, 8, 4], 189 | [2, 8, 7, 4, 1, 9, 6, 3, 5], 190 | [3, 4, 5, 2, 8, 6, 1, 1, 9] # Repetição de 1 na última linha 191 | ]) 192 | ``` 193 | -------------------------------------------------------------------------------- /aulas/Semana 6 - Numpy/22_numpy_estatisticas_algebra.md: -------------------------------------------------------------------------------- 1 | # Manipulação de Arrays, Estatística Básica e Álgebra Linear 2 | 3 | ## 1. Leitura e Escrita de Arrays 4 | 5 | O NumPy permite salvar e carregar dados no disco em formatos de texto e binários. 6 | Embora seja possível usar o NumPy para essas operações, na prática, muitos usuários optam por utilizar o pandas e outras ferramentas especializadas para lidar com dados em formatos de texto ou tabulares. 7 | A principal vantagem de usar as funções do NumPy sobre as demais ferramentas é se necessitar salvar e carregar arrays diretamente em formato binário, o que é mais eficiente e adequado do que manipular textos. 8 | 9 | ### 1.1 Arrays como Texto 10 | O `NumPy` permite salvar arrays em formato de texto usando `np.savetxt()` e carregá-los utilizando `np.loadtxt()`. 11 | Por exemplo: 12 | 13 | ```python 14 | import numpy as np 15 | 16 | # Criando um array 17 | arr = np.array([[1, 2, 3], [4, 5, 6]]) 18 | 19 | # Salvando como arquivo de texto 20 | np.savetxt('array.txt', arr, delimiter=',') 21 | 22 | # Carregando o array do arquivo salvo 23 | loaded_arr = np.loadtxt('array.txt', delimiter=',') 24 | print(loaded_arr) 25 | ``` 26 | 27 | ### 1.2 Arquivos Binários 28 | 29 | Para uma leitura e escrita mais eficiente, usamos arquivos binários `.npy`: 30 | ```python 31 | # Salvando como arquivo binário 32 | np.save('array.npy', arr) 33 | 34 | # Carregando do arquivo binário 35 | binary_arr = np.load('array.npy') 36 | print(binary_arr) 37 | ``` 38 | 39 | ### 1.3 Múltiplos Arrays 40 | 41 | Podemos salvar múltiplos arrays em um único arquivo `.npz` usando `np.savez()`: 42 | 43 | ```python 44 | # Salvando múltiplos arrays 45 | np.savez('arrays.npz', arr1=arr, arr2=np.array([7, 8, 9])) 46 | 47 | # Carregando múltiplos arrays 48 | data = np.load('arrays.npz') 49 | print(data['arr1']) 50 | print(data['arr2']) 51 | ``` 52 | 53 | ## 2. Estatística Básica 54 | 55 | Um conjunto de funções matemáticas que calculam estatísticas sobre um array inteiro ou sobre os dados ao longo de um eixo está acessível como métodos da classe de array. 56 | Você pode usar agregações (às vezes chamadas de reduções), como `soma`, `média` e `desvio padrão (std)`. 57 | 58 | ### 2.1 Soma 59 | 60 | A função `np.sum()` calcula a soma dos elementos de um array. 61 | Você pode usar o parâmetro `axis` para somar ao longo de um eixo específico. 62 | Este parâmetro é aplicável também às demais funções de agregação que veremos mais a frente. 63 | 64 | ```python 65 | arr_2d = np.array([[1, 2, 3], [4, 5, 6]]) 66 | 67 | # Soma de todos os elementos 68 | print(np.sum(arr_2d)) 69 | 70 | # Soma ao longo do eixo 0 (colunas) 71 | print(np.sum(arr_2d, axis=0)) 72 | 73 | # Soma ao longo do eixo 1 (linhas) 74 | print(np.sum(arr_2d, axis=1)) 75 | ``` 76 | 77 | * `axis=0`: Soma ao longo das colunas, retornando um array com a soma de cada coluna. 78 | * `axis=1`: Soma ao longo das linhas, retornando um array com a soma de cada linha. 79 | 80 | ### 2.2 Cálculo de Máximo e Mínimo 81 | 82 | #### Valor Máximo e Mínimo 83 | 84 | Usamos `np.max()` e `np.min()` para encontrar os valores máximos e mínimos de um array: 85 | 86 | ```python 87 | arr = np.array([1, 3, 5, 7, 9]) 88 | 89 | # Valor máximo 90 | print(np.max(arr)) 91 | print(arr.max()) 92 | 93 | # Valor mínimo 94 | print(np.min(arr)) 95 | print(arr.min()) 96 | ``` 97 | 98 | #### Índice do Valor Máximo e Mínimo 99 | 100 | Para encontrar o índice do maior e menor valor, utilizamos `np.argmax()` e `np.argmin()`: 101 | 102 | ```python 103 | # Índice do valor máximo 104 | print(np.argmax(arr)) 105 | print(arr.argmax()) 106 | 107 | # Índice do valor mínimo 108 | print(np.argmin(arr)) 109 | print(arr.argmin()) 110 | ``` 111 | 112 | ### 2.3 Percentis 113 | 114 | Podemos calcular percentis de um array com `np.percentile()`: 115 | 116 | ```python 117 | 118 | # Cálculo do percentil 50 (mediana) 119 | print(np.percentile(arr, 50)) 120 | 121 | # Percentil 90 122 | print(np.percentile(arr, 90)) 123 | ``` 124 | 125 | ### 2.4 Média, Mediana, Desvio Padrão e Variância 126 | 127 | ```python 128 | 129 | # Média 130 | print(np.mean(arr)) 131 | print(arr.mean()) 132 | 133 | # Mediana 134 | print(np.median(arr)) 135 | print(arr.median()) 136 | 137 | # Desvio Padrão 138 | print(np.std(arr)) 139 | print(arr.std()) 140 | 141 | # Variância 142 | print(np.var(arr)) 143 | print(arr.var()) 144 | ``` 145 | 146 | ## 3. Álgebra Linear 147 | 148 | Operações de álgebra linear, como multiplicação de matrizes, decomposições, determinantes e outras operações com matrizes quadradas, são uma parte importante de muitas bibliotecas de arrays. 149 | 150 | ### 3.1 Operações com Matrizes 151 | 152 | #### Multiplicação de Matrizes 153 | 154 | Podemos multiplicar duas matrizes usando `np.dot()` ou o operador `@`: 155 | 156 | ```python 157 | A = np.array([[1, 2], [3, 4]]) 158 | B = np.array([[5, 6], [7, 8]]) 159 | 160 | # Multiplicação de matrizes 161 | print(np.dot(A, B)) 162 | # Ou usando o operador @ 163 | print(A @ B) 164 | ``` 165 | 166 | #### Transposição de Matrizes 167 | 168 | Para transpor uma matriz, usamos `np.transpose()`: 169 | 170 | ```python 171 | # Transpor a matriz A 172 | print(np.transpose(A)) 173 | ``` 174 | 175 | #### Traço de uma Matriz 176 | 177 | O traço de uma matriz (soma dos elementos na diagonal principal) pode ser obtido com np.trace(): 178 | 179 | ```python 180 | # Traço da matriz A 181 | print(np.trace(A)) 182 | ``` 183 | 184 | #### Determinante de uma Matriz 185 | 186 | Usamos `np.linalg.det()` para calcular o determinante de uma matriz: 187 | 188 | ```python 189 | # Determinante de A 190 | print(np.linalg.det(A)) 191 | ``` 192 | 193 | #### Inversão de Matrizes 194 | 195 | Para calcular a inversa de uma matriz, utilizamos `np.linalg.inv()`: 196 | 197 | ```python 198 | # Inversa da matriz A 199 | print(np.linalg.inv(A)) 200 | ``` 201 | 202 | ### 3.2 Solução de Sistemas Lineares 203 | 204 | Para resolver sistemas de equações lineares da forma `Ax = b`, usamos `np.linalg.solve()`. 205 | Consideremos o seguinte sistema linear: 206 | 207 | $$ 208 | \begin{aligned} 209 | 3x + y &= 9 \\ 210 | x + 2y &= 8 211 | \end{aligned} 212 | $$ 213 | 214 | e sua forma matricial: 215 | 216 | $$ 217 | A = \begin{bmatrix} 218 | 3 & 1 \\ 219 | 1 & 2 220 | \end{bmatrix}, \quad 221 | x = \begin{bmatrix} 222 | x \\ 223 | y 224 | \end{bmatrix}, \quad 225 | b = \begin{bmatrix} 226 | 9 \\ 227 | 8 228 | \end{bmatrix} 229 | $$ 230 | 231 | ```python 232 | # Sistema: Ax = b 233 | A = np.array([[3, 1], [1, 2]]) 234 | b = np.array([9, 8]) 235 | 236 | # Resolver para x 237 | x = np.linalg.solve(A, b) 238 | print(x) 239 | ``` -------------------------------------------------------------------------------- /aulas/Semana 6 - Numpy/23_lista_2.md: -------------------------------------------------------------------------------- 1 | ## 1. Separador de Pares e Ímpares 2 | 3 | Gere um array de 20 números inteiros aleatórios entre 1 e 100. Escreva uma função para separar os números pares dos números ímpares, retornando dois novos arrays. 4 | 5 | ```python 6 | # Entrada 7 | numeros = np.array([15, 26, 33, 42, 55, 68, 71, 88, 90, 91]) 8 | # Saida 9 | pares = [26, 42, 68, 88, 90] 10 | ímpares = [15, 33, 55, 71, 91] 11 | ``` 12 | 13 | ## 2. Normalização de Dados 14 | 15 | Normalize um array 1D de notas de exames (números inteiros aleatórios entre 0 e 100) para uma escala de 0 a 1 usando a fórmula: 16 | 17 | $$ \text{normalized} = \frac{x - \text{min}(x)}{\text{max}(x) - \text{min}(x)} $$ 18 | 19 | ```python 20 | # Entrada 21 | notas = np.array([75, 40, 50, 60, 80]) 22 | # Saida 23 | notas_normalizadas = [0.875, 0., 0.25, 0.5, 1.] 24 | ``` 25 | 26 | ## 3. Distância de Manhattan 27 | 28 | Você tem as coordenadas de cinco cidades em um plano 2D, representadas por seus valores de latitude e longitude. Escreva uma função que calcule a distância de Manhattan entre cada par de cidades. 29 | 30 | $$ d_{\text{Manhattan}} = |x_2 - x_1| + |y_2 - y_1| $$ 31 | 32 | ```python 33 | # Entrada 34 | cidades = np.array([[50, -120], 35 | [40, -70]]) 36 | # Saida 37 | distância_manhattan = 60 38 | ``` 39 | 40 | ## 4. Cálculo de Média Móvel 41 | 42 | Escreva uma função para calcular a média móvel dos preços de ações em uma janela de 5 dias. Gere um array NumPy de 30 preços de ações aleatórios (números de ponto flutuante) e retorne o array das médias móveis. 43 | 44 | ```python 45 | # Entrada 46 | precos = np.array([10.0, 12.5, 13.0, 14.5, 15.0, 14.0, 13.5]) 47 | # Saida 48 | medias_moveis = [13.16, 13.75, 14.0] 49 | ``` 50 | 51 | ## 5. Sumário estatístico 52 | 53 | Crie uma função que realiza um sumário estatístico básico de um array NumPy. 54 | Ela deve calcular e exibir o valor mínimo, o valor máximo e os quartis (25%, 50%, e 75%) de um array fornecido. 55 | 56 | ```python 57 | # Entrada 58 | array = np.array([10, 20, 35, 50, 70, 80, 95, 100]) 59 | # Saída: 60 | # Sumário Estatístico do Array: 61 | # Valor Mínimo: 10 62 | # Valor Máximo: 100 63 | # Quartis: 64 | # 25%: 31.25 65 | # 50% (Mediana): 60.0 66 | # 75%: 83.75 67 | ``` 68 | 69 | ## 6. Agrupamento por categoria 70 | 71 | Você tem duas listas: uma com categorias e outra com os valores das transações. 72 | Crie uma função que calcule a soma total do faturamento para cada categoria usando NumPy e retorne um dicionário onde as chaves são as categorias e os valores são as somas dos faturamentos para essas categorias. 73 | 74 | ```python 75 | # entrada 76 | categorias = ['Alimentação', 'Saúde', 'Alimentação', 'Educação', 'Saúde', 'Educação'] 77 | valores = [100, 200, 50, 300, 150, 100] 78 | # Saída 79 | resultado = { 80 | 'Alimentação': 150, 81 | 'Saúde': 350, 82 | 'Educação': 400 83 | } 84 | ``` 85 | 86 | ## 7. Verificador de Vencedor do Jogo da Velha 87 | 88 | Crie uma função que verifique o vencedor de um tabuleiro de Jogo da Velha dado (array 3x3 do NumPy). 89 | O tabuleiro contém 1s, -1s e 0s (representando o Jogador 1, o Jogador 2 e espaços vazios, respectivamente). 90 | A função deve detectar se algum jogador venceu ou se o jogo terminou empatado. 91 | 92 | ```python 93 | # Entrada 94 | tabuleiro = np.array([[ 1, -1, 1], 95 | [ 0, 1, -1], 96 | [-1, 1, 1]]) 97 | # Saida 98 | vencedor = 1 99 | ``` 100 | -------------------------------------------------------------------------------- /aulas/Semana 6 - Numpy/check_sudoku.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def check_range(solution): 4 | return np.all((solution > 0) & (solution < 10)) 5 | 6 | def check_sudoku(solution: np.array) -> bool: 7 | if not check_range(solution): 8 | raise RuntimeError("Não é uma solução de Sudoku") 9 | 10 | # Como garantimos que todos os números estão entre 1 e 9 11 | # Ao verificar uma linha / coluna, devem haver 9 elementos distintos 12 | def check_row(data): 13 | return np.unique(data).size == 9 14 | 15 | # Verificar linhas 16 | n_rows = solution.shape[0] 17 | for i in range(n_rows): 18 | row = solution[i] 19 | if not check_row(row): 20 | print(f"Linha {i} esta errada") 21 | return False 22 | 23 | # Verificar colunas 24 | n_cols = solution.shape[1] 25 | for j in range(n_cols): 26 | # Transforma a coluna em array 1D 27 | column = solution[:, j] 28 | if not check_row(column): 29 | print(f"Coluna {j} esta errada") 30 | return False 31 | 32 | # Verificar blocos 33 | for i in range(3): 34 | x_start = 3 * i 35 | x_end = 3 * (i + 1) 36 | for j in range(3): 37 | y_start = 3 * j 38 | y_end = 3 * (j + 1) 39 | 40 | block = solution[x_start: x_end, y_start:y_end] 41 | # print(block) # Veriicar visualmente se pegamos o quadrante certo 42 | 43 | # Transforma a matrix 3d em um array 1d 44 | block_data = block.flatten() 45 | if not check_row(block_data): 46 | print(f"Bloco ({i}, {j}) esta errada") 47 | return False 48 | 49 | return True 50 | 51 | valid_solution = np.array([ 52 | [5, 3, 4, 6, 7, 8, 9, 1, 2], 53 | [6, 7, 2, 1, 9, 5, 3, 4, 8], 54 | [1, 9, 8, 3, 4, 2, 5, 6, 7], 55 | [8, 5, 9, 7, 6, 1, 4, 2, 3], 56 | [4, 2, 6, 8, 5, 3, 7, 9, 1], 57 | [7, 1, 3, 9, 2, 4, 8, 5, 6], 58 | [9, 6, 1, 5, 3, 7, 2, 8, 4], 59 | [2, 8, 7, 4, 1, 9, 6, 3, 5], 60 | [3, 4, 5, 2, 8, 6, 1, 7, 9] 61 | ]) 62 | print(check_sudoku(valid_solution)) 63 | 64 | invalid_solution = np.array([ 65 | [5, 3, 4, 6, 7, 8, 9, 1, 2], 66 | [6, 7, 2, 1, 9, 5, 3, 4, 8], 67 | [1, 9, 8, 3, 4, 2, 5, 6, 7], 68 | [8, 5, 9, 7, 6, 1, 4, 2, 3], 69 | [4, 2, 6, 8, 5, 3, 7, 9, 1], 70 | [7, 1, 3, 9, 2, 4, 8, 5, 6], 71 | [9, 6, 1, 5, 3, 7, 2, 8, 4], 72 | [2, 8, 7, 4, 1, 9, 6, 3, 5], 73 | [3, 4, 5, 2, 8, 6, 1, 1, 9] # Repetição de 1 na última linha 74 | ]) 75 | print(check_sudoku(invalid_solution)) -------------------------------------------------------------------------------- /aulas/Semana 7 - Pandas/24_pandas_series.md: -------------------------------------------------------------------------------- 1 | # Introdução ao Pandas 2 | 3 | Pandas é uma das bibliotecas mais populares para análise de dados em Python. 4 | Ele oferece estruturas de dados de alto desempenho e ferramentas para manipulação de dados tabulares e rotulados. 5 | Essas ferramentas facilitam o processo de limpeza, transformação, e análise de grandes conjuntos de dados, tarefas comuns na ciência de dados e em outros campos. 6 | 7 | ## 1. Por que usar Pandas? 8 | 9 | * Operações como selecionar, filtrar, agrupar e agregar dados são feitas de forma intuitiva. 10 | * Oferece suporte a dados rotulados (com índices) e dados tabulares, facilitando a manipulação de dados semelhantes aos encontrados em planilhas ou bancos de dados. 11 | * Ferramentas poderosas para leitura e escrita de diversos formatos de arquivos (CSV, Excel, SQL, etc.). 12 | * Integração com outras bibliotecas populares como NumPy, Matplotlib e Scikit-learn. 13 | 14 | ### Exemplo de contexto real 15 | 16 | * Imagine que você tem um CSV com dados de vendas de uma loja, onde cada coluna representa um aspecto (data, valor, produto). 17 | O Pandas permite ler, manipular e analisar esse tipo de arquivo com facilidade. 18 | 19 | ## 2. Estrutura Unidimensional: Series 20 | 21 | ### A. O que é uma `Series`? 22 | * Uma Series no Pandas é uma estrutura de dados unidimensional, semelhante a uma coluna de uma tabela ou a um array do NumPy, mas com a adição de índices personalizados. 23 | * Esses índices permitem que você acesse os dados de maneira mais intuitiva, como se estivesse trabalhando com um dicionário Python. 24 | 25 | ### B. Exemplo básico 26 | 27 | ```python 28 | import pandas as pd 29 | 30 | dados = [10, 20, 30, 40] 31 | serie = pd.Series(dados, index=['a', 'b', 'c', 'd']) 32 | print(serie) 33 | # a 10 34 | # b 20 35 | # c 30 36 | # d 40 37 | # dtype: int64 38 | ``` 39 | Aqui, a Series contém valores `[10, 20, 30, 40]` e tem índices personalizados `['a', 'b', 'c', 'd']`. 40 | 41 | ### C. Conceitos-chave: 42 | 43 | * **Index**: 44 | Cada elemento na Series possui um rótulo (ou índice), que pode ser numérico ou alfabético. 45 | * **Header (Cabeçalho)**: 46 | Em uma Series, o cabeçalho é o nome da própria coluna, que pode ser atribuído para facilitar a interpretação. 47 | 48 | 49 | ## 3. Diferenças de Series em Relação ao ndarray 50 | 51 | ### A. Índices (Index) Personalizados 52 | * Ao contrário dos arrays do NumPy, as Series podem ter índices personalizados (não apenas numéricos). 53 | * Isso facilita a manipulação de dados rotulados e permite o uso de nomes amigáveis ao invés de apenas números. 54 | 55 | ```python 56 | # Criando uma Series com índices personalizados 57 | cidades = ['São Paulo', 'Rio de Janeiro', 'Belo Horizonte', 'Porto Alegre', 'Curitiba'] 58 | temperaturas = [30, 35, 28, 25, 27] 59 | series_temp = pd.Series(temperaturas, index=cidades) 60 | # Saída 61 | print(series_temp) 62 | # São Paulo 30 63 | # Rio de Janeiro 35 64 | # Belo Horizonte 28 65 | # Porto Alegre 25 66 | # Curitiba 27 67 | # dtype: int64 68 | ``` 69 | 70 | ### B. Cabeçalhos (Header) 71 | * O header nas Series é o nome associado à coluna. 72 | * Embora uma Series tenha apenas uma coluna, a presença de cabeçalhos se torna mais útil ao trabalhar com `DataFrames`. 73 | 74 | ```python 75 | # Atribuindo um nome à Series 76 | series_temp.name = 'Temperatura (°C)' 77 | # Saída 78 | print(series_temp) 79 | # São Paulo 30 80 | # Rio de Janeiro 35 81 | # Belo Horizonte 28 82 | # Porto Alegre 25 83 | # Curitiba 27 84 | # Name: Temperatura (°C), dtype: int64 85 | ``` 86 | 87 | ### C. Vantagens e desvantagens das Series 88 | 89 | * Vantagens: 90 | * Acesso Intuitivo: 91 | Acesso aos dados por rótulos em vez de apenas por posições. 92 | * Flexibilidade: 93 | Permite operações de filtragem, agregação e transformação de maneira mais fácil. 94 | * Interoperabilidade: 95 | Fácil integração com outras estruturas de dados e bibliotecas. 96 | 97 | * Desvantagens: 98 | * Operações Matemáticas mais Lentas: 99 | O NumPy é otimizado para operações numéricas em larga escala devido ao seu uso de arrays densos e homogêneos, enquanto o Pandas foi projetado para a manipulação de dados heterogêneos e rotulados. 100 | * Foco em Dados Tabulares: 101 | O Pandas foi projetado para manipulação de planilhas e dados rotulados, não sendo a melhor escolha para operações matemáticas puras, onde o NumPy é mais eficiente. 102 | 103 | ### D. Quando usar Pandas vs NumPy? 104 | 105 | * `Pandas`: ideal para manipulação e análise de dados tabulares e rotulados. Use Pandas quando você precisa trabalhar com grandes datasets em formato de planilhas. 106 | * `NumPy`: mais adequado para cálculos numéricos massivos e computação de alta performance. Ele é perfeito para operações como álgebra linear, transformações de matrizes, etc. 107 | 108 | ## 4. Operações básicas 109 | 110 | ### Parâmetros index e name 111 | 112 | * `index`: Define os rótulos dos elementos na Series. Pode ser numérico ou alfabético. 113 | * `name`: Nomeia a Series. Útil quando se trabalha com múltiplas Series ou DataFrames para identificar e distinguir entre diferentes conjuntos de dados. 114 | 115 | ```python 116 | serie = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'], name='Valores') 117 | print(serie) 118 | print(serie.name) # Saída: Valores 119 | ``` 120 | 121 | ### Acessando Dados 122 | 123 | Os métodos abaixo são essenciais para acessar valores de uma Series de maneira eficiente e controlada: 124 | * `at`: Acessa um único valor pela etiqueta do índice (rótulo). 125 | * `iat`: Acessa um único valor pela posição numérica (como em um array). 126 | * `loc`: Acessa um ou mais valores pela etiqueta. 127 | * `iloc`: Acessa um ou mais valores pela posição numérica. 128 | 129 | ```python 130 | serie = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd']) 131 | 132 | # Usando at e iat para acessar elementos individuais 133 | print(serie.at['b']) # Saída: 20 134 | print(serie.iat[1]) # Saída: 20 135 | 136 | # Usando loc e iloc para acessar múltiplos elementos 137 | print(serie.loc['b':'d']) # Saída: b 20, c 30, d 40 138 | print(serie.iloc[1:3]) # Saída: b 20, c 30 139 | ``` 140 | 141 | ### Estatísticas 142 | 143 | * Diferente do numpy, pandas já vem com uma função especifica para exibir estátisticas de uma distribuição de valores 144 | * O método `describe()` do Pandas é uma maneira rápida e eficiente de obter estatísticas descritivas de uma Series, como `média`, `desvio padrão`, `valor mínimo`, `máximo`, `etc`. 145 | 146 | ```python 147 | serie = pd.Series([10, 20, 30, 40, 50, 60]) 148 | estatisticas = serie.describe() 149 | print(estatisticas) 150 | # Saída: 151 | # count 6.000000 152 | # mean 35.000000 153 | # std 18.708287 154 | # min 10.000000 155 | # 25% 22.500000 156 | # 50% 35.000000 157 | # 75% 47.500000 158 | # max 60.000000 159 | ``` 160 | 161 | ## 5. Lendo uma Series de um Arquivo de Texto 162 | 163 | * Criar um arquivo `dados_com_indice.txt` com o seguinte conteúdo: 164 | ```python 165 | Indice,Valor 166 | a,10 167 | b,20 168 | c,30 169 | d,40 170 | ``` 171 | * Ler o arquivo e criar uma Series com índices personalizados: 172 | ```python 173 | import pandas as pd 174 | 175 | # Lendo o arquivo txt com cabeçalhos e índices 176 | serie = pd.read_csv('dados_com_indice.txt', index_col='Indice', squeeze=True) 177 | print(serie) 178 | ``` 179 | * Explicação: 180 | * `index_col='Indice'` define a coluna que será usada como índice para a Series. 181 | * `squeeze=True` é usado para garantir que o DataFrame seja convertido em uma Series, se houver uma única coluna. 182 | 183 | ## 6. Exercícios 184 | 185 | 1. Criar uma Series a partir de uma lista de dados e índices personalizados. 186 | ```python 187 | produtos = ['Caneta', 'Lápis', 'Caderno', 'Borracha', 'Estojo'] 188 | quantidades = [150, 200, 120, 80, 60] 189 | ``` 190 | 2. Realizar operações matemáticas com a Series e comparar com um ndarray. 191 | 3. Utilizar `at`, `iat`, `loc` e `iloc` para acessar elementos específicos da Series. 192 | 4. Aplicar o método `describe()` em uma Series criada e interpretar os resultados. 193 | -------------------------------------------------------------------------------- /aulas/Semana 7 - Pandas/analise_steam.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | 3 | # Apontar para o caminho correto 4 | filepath = "steam.csv" 5 | df = pd.read_csv(filepath) 6 | print(df.head()) 7 | print(df.columns) 8 | print(df.iloc[0]) 9 | 10 | # Verificando distribuição de dados 11 | print(df['All Reviews Summary'].head(20)) 12 | print(df['All Reviews Summary'].unique()) 13 | print(df['All Reviews Summary'].value_counts()) 14 | print(pd.isna(df['All Reviews Summary']).sum()) 15 | print(pd.isna(df['Recent Reviews Summary']).sum()) 16 | 17 | # Filtrar por jogos com nota "Overwhelmingly Negative" 18 | result = df['All Reviews Summary'] == "Overwhelmingly Negative" 19 | print(df[result]) 20 | 21 | # Remover linhas com valores faltantes 22 | subset_df = df[['Release Date','All Reviews Summary']] 23 | print(subset_df.head()) 24 | result = subset_df['All Reviews Summary'].isna() 25 | subset_df = subset_df[~result] 26 | result = subset_df['Release Date'].isna() 27 | subset_df = subset_df[~result] 28 | print(subset_df.head(20)) 29 | 30 | # Extrair o ano da data 31 | print(subset_df['Release Date'].value_counts()) 32 | def parse_year(date_str: str) -> int: 33 | try: 34 | print(date_str) 35 | values = date_str.split(",") 36 | return int(values[1]) 37 | # date = date_str[-4:] 38 | # return int(date) 39 | except: 40 | return pd.NA # null 41 | 42 | year = parse_year("17 Jul, 2023") 43 | print(year + 1) 44 | 45 | # Obter os anos de todas as datas 46 | subset_df["year"] = subset_df['Release Date'].map(parse_year) 47 | 48 | # Veriicar a distribuição das notas pelos anos 49 | def concat(x: pd.Series) -> str: 50 | return str(x["year"]) + " " + x["All Reviews Summary"] 51 | subset_df["concat"] = subset_df.apply(concat, axis=1) 52 | print(subset_df["concat"].value_counts()) 53 | 54 | -------------------------------------------------------------------------------- /aulas/Semana 7 - Pandas/analise_vgsales.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | 3 | # Apontar para o caminho correto 4 | filepath = "vgsales.csv" 5 | df = pd.read_csv(filepath, sep=",") 6 | print(df.index) 7 | print(df.columns) 8 | print(df.shape) 9 | print(df.dtypes) 10 | 11 | print(df.head()) 12 | print(df.columns) 13 | 14 | # Filtrar as colunas 15 | # -> Concentrar nos dados a serem analisados 16 | # -> Diminui tamanho do arquivo 17 | columns = ['Name', 'Platform', 'Year', 'Genre', 'Publisher', 'Global_Sales'] 18 | subset_df = df[columns] 19 | subset_df.to_csv('subset.csv', index=False) 20 | 21 | print(subset_df.head()) 22 | 23 | # Indexar pelo campo Name em vez de 0 a n-1 24 | columns = ["Name", "Genre", "Platform"] 25 | sub_df = df[columns] 26 | sub_df2 = sub_df.set_index("Name") 27 | print(sub_df2) 28 | 29 | # Pegar parte das linhas 30 | print(sub_df2.iloc[10:20]) 31 | print(sub_df2.loc["Pokemon Red/Pokemon Blue"]) 32 | print(df[df["Global_Sales"] >= 1.0]) 33 | 34 | # Criando nova coluna valores 35 | head_df = df.head().copy() 36 | head_df["type"] = ["Retro", "Retro", "Modern", "Modern", "Modern"] 37 | print(head_df) 38 | # Removendo coluna 39 | head_df.drop("type", axis=1, inplace=True) 40 | print(head_df) 41 | 42 | # Inserindo nova linha 43 | sub_df = sub_df.copy() 44 | new_row = { 45 | "Name": "Mario Demo", 46 | "Genre": "Plataform", 47 | "Platform": "Switch 2", 48 | } 49 | new_df = pd.DataFrame([new_row]) 50 | print(new_df) 51 | print(pd.concat([df, new_df], ignore_index=True)) 52 | 53 | # Quantidade de jogos por genero 54 | genre_counter = df["Genre"].value_counts() 55 | print(100 * genre_counter / df.shape[0]) 56 | 57 | # Tratamento de dados 58 | sale_columns = ['NA_Sales', 'EU_Sales', 'JP_Sales', 'Other_Sales'] 59 | 60 | def compute_mean(x: pd.Series): 61 | return x.mean() 62 | 63 | print(df[sale_columns].apply(compute_mean, axis=0)) 64 | for column in sale_columns: 65 | print(compute_mean(df[column])) 66 | 67 | print(df[sale_columns].apply(compute_mean, axis=1)) 68 | for idx, row in df.iterrows(): 69 | print(row[sale_columns].mean()) 70 | # Sõ para verificar a primeira linha 71 | break 72 | -------------------------------------------------------------------------------- /aulas/Semana 7 - Pandas/dados.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 7 - Pandas/dados.zip -------------------------------------------------------------------------------- /aulas/Semana 7 - Pandas/dados_fonte.txt: -------------------------------------------------------------------------------- 1 | https://www.kaggle.com/datasets/nikatomashvili/steam-games-dataset/data 2 | -------------------------------------------------------------------------------- /aulas/Semana 8 - Pandas/27_pandas_agregacao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/aulas/Semana 8 - Pandas/27_pandas_agregacao.png -------------------------------------------------------------------------------- /aulas/Semana 9 - Classes/29_codigo_aula.py: -------------------------------------------------------------------------------- 1 | livro1 = { 2 | 'nome': '1984', 3 | 'autor': 'George Orwell', 4 | 'ano': 1949 5 | } 6 | 7 | livro2 = { 8 | 'nome': 'Revolucao dos Animais', 9 | 'autor': 'George Orwell', 10 | 'ano': 1945 11 | } 12 | 13 | livros = [livro1, livro2] 14 | 15 | def filtro(livros, depois_ano): 16 | livros_validos = [] 17 | for livro in livros: 18 | if livro['ano'] >= depois_ano: 19 | livros_validos.append(livro) 20 | return livros_validos 21 | 22 | print(filtro(livros, 1960)) 23 | 24 | # Struct 25 | class Book: 26 | 27 | # Construtor 28 | def __init__(self, a, b, c) -> None: 29 | self.nome = a 30 | self.autor = b 31 | self.ano = c 32 | 33 | book1 = Book("1984", "George Orwell", 1949) 34 | print(book1.nome) 35 | # print(book1["nome"]) 36 | book2 = Book("Revolucao dos Animais", "George Orwell", 1945) 37 | print(book2.nome) 38 | 39 | class ProdutoDataFrame: 40 | 41 | def __init__(self, dict): 42 | self.df = dict 43 | self.validar() 44 | 45 | def validar(self): 46 | columns = ['nome', 'ano'] 47 | for column in columns: 48 | if column not in self.df.keys(): 49 | raise Exception(f"Coluna {column} nao existe!") 50 | 51 | d = {"nome": "Matheus", "ano": 1800} 52 | obj = ProdutoDataFrame(d) 53 | print(obj.df) 54 | 55 | class Produto: 56 | 57 | def __init__(self, nome, preco, categoria): 58 | self.nome = nome 59 | self.preco = preco 60 | self.categoria = categoria 61 | 62 | def aplicar_desconto(self, perc): 63 | desconto = 1 - perc / 100 64 | self.preco = desconto * self.preco 65 | print(f"O novo valor do produto é R${self.preco}") 66 | 67 | p1 = Produto("Iphone", 10000, "celular") 68 | p2 = Produto("1984", 40, "livro") 69 | 70 | print(p1.preco) 71 | print(p2.preco) 72 | p1.aplicar_desconto(10) 73 | print(p1.preco) 74 | print(p2.preco) 75 | 76 | class Carrinho: 77 | 78 | def __init__(self): 79 | self.produtos = [] 80 | 81 | def adicionar(self, produto: Produto): 82 | self.produtos.append(produto) 83 | 84 | def calcular_total(self): 85 | total = 0 86 | for p in self.produtos: 87 | total += p.preco 88 | print(f"O total do seu carrinho é R${total}") 89 | 90 | carrinho_matheus = Carrinho() 91 | carrinho_matheus.calcular_total() 92 | carrinho_matheus.adicionar(p1) 93 | carrinho_matheus.adicionar(p1) 94 | carrinho_matheus.calcular_total() 95 | carrinho_matheus.adicionar(p2) 96 | carrinho_matheus.calcular_total() 97 | 98 | -------------------------------------------------------------------------------- /aulas/Semana 9 - Classes/30_codigo_aula.py: -------------------------------------------------------------------------------- 1 | # PROGRAMACAO PROCEDURAL 2 | 3 | p1 = { 4 | "nome": "Iphone 15X", 5 | "preco": 10000 6 | } 7 | 8 | p2 = { 9 | "nome": "Samsung Galaxy S24", 10 | "preco": 4000 11 | } 12 | 13 | carrinho = { 14 | "usuario": "Matheus", 15 | "produtos": [p1, p2] 16 | } 17 | 18 | def total_carrinho(carrinho: dict) -> float: 19 | total = 0 20 | for p in carrinho["produtos"]: 21 | total += p["preco"] 22 | return total 23 | 24 | print(total_carrinho(carrinho)) 25 | 26 | # ORIENTACAO A OBJETOS 27 | 28 | class Produto: 29 | 30 | def __init__(self, nome: str, preco: float=-1): 31 | self.nome = nome 32 | self.preco = preco 33 | 34 | def copy(self): 35 | return Produto(self.nome, self.preco) 36 | 37 | p1 = Produto("Iphone", 10000) 38 | p2 = Produto("Galaxy", 4000) 39 | 40 | from typing import List 41 | class Carrinho: 42 | 43 | def __init__(self, produtos: List[Produto]): 44 | self.produtos = produtos 45 | self.nome_usuario = "Matheus" 46 | 47 | def calcular_total(self) -> float: 48 | total = 0 49 | for p in self.produtos: 50 | total += p.preco 51 | return total 52 | 53 | carrinho = Carrinho([p1, p2]) 54 | print(carrinho.calcular_total()) 55 | 56 | conta = { 57 | "saldo": 1000 58 | } 59 | 60 | conta["saldo"] = -10000000 61 | 62 | def exibir_saldo(conta): 63 | print(conta["saldo"]) 64 | 65 | class Conta: 66 | 67 | def __init__(self, saldo) -> None: 68 | self.__saldo = saldo # Publico 69 | self.__usuario = "Matheus" # Protegido 70 | self.__cpf = "111.111.111-00" # Privado 71 | 72 | def get_usuario(self): 73 | return self.__usuario 74 | 75 | def set_usuario(self, novo_usuario): 76 | self.__usuario = novo_usuario 77 | 78 | def get_cpf(self): 79 | return self.__cpf[:3] + ".XXX.XXX-XX" 80 | 81 | def set_saldo(self, novo_saldo): 82 | print("Saldo foi modificado no dia XXXX para valor tal") 83 | self.__saldo = novo_saldo 84 | 85 | def __str__(self): 86 | return f"Nome: {self.__usuario}\nCPF: {self.__cpf}" 87 | 88 | conta = Conta(1000) 89 | print() 90 | print(conta) -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignorar diretórios com esse nome 2 | __pycache__/ -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/data/wikipedia_good_articles_video_games.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/projeto_similaridade_de_documentos/data/wikipedia_good_articles_video_games.zip -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/docs/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/projeto_similaridade_de_documentos/docs/.placeholder -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/readme.md: -------------------------------------------------------------------------------- 1 | # Projeto Similaridade de Documentos 2 | 3 | Este projeto tem como objetivo demonstrar o desenvolvimento de um projeto em Python, focando na organização do código, criação de testes automatizados e documentação. Para isso, foi criado um sistema de busca de documentos baseado em palavras-chave e similaridade de texto. 4 | 5 | **Aviso**: 6 | Este projeto é apenas um exemplo e, portanto, não inclui documentação completa, tratamento de exceções ou testes unitários abrangentes. 7 | 8 | ## Estrutura do projeto 9 | 10 | O projeto está organizado da seguinte forma: 11 | 12 | ```markdown 13 | projeto_similaridade_de_documentos/ 14 | 15 | ├── data/ 16 | │ └── wikipedia_good_articles_video_games.txt 17 | ├── src/ 18 | │ ├── main.py 19 | │ ├── data_loader.py 20 | │ ├── search.py 21 | | ├── text.py 22 | | └── metrics.py 23 | ├── tests/ 24 | │ ├── test_data_loader.py 25 | │ ├── test_search.py 26 | | ├── test_text.py 27 | | └── test_metrics.py 28 | ├── README.md 29 | ├── requirements.txt 30 | ``` 31 | 32 | ## Como executar o projeto 33 | 34 | 1. Instale as dependências do projeto: 35 | ```bash 36 | pip install -r requirements.txt 37 | ``` 38 | 39 | 2. Decompacte o arquivo `wikipedia_good_articles_video_games.zip` na pasta `data`: 40 | 41 | 3. Execute o script `main.py`: 42 | ```bash 43 | cd src/ 44 | python3 main.py 45 | ``` 46 | 47 | ## Como testar o projeto 48 | 49 | 1. Execute o script de testes do diretório raiz: 50 | ```bash 51 | python3 -m unittest 52 | ``` -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/projeto_similaridade_de_documentos/requirements.txt -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matwerner/fgv-lp/ad05f9ae958f09fc9ebf871fc9c4d621f41c2394/projeto_similaridade_de_documentos/src/__init__.py -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/src/data_loader.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This module is responsible for loading the wikipedia documents from a file. 3 | ''' 4 | 5 | import json 6 | import os 7 | 8 | from typing import List, Dict, Any, Optional 9 | 10 | def read_documents(file_path: str) -> List[Dict[str, Any]]: 11 | """ 12 | Read the wikipedia documents from a file. 13 | The file should contain one document per line in json format. 14 | 15 | Parameters 16 | ---------- 17 | file_path : str 18 | The path to the file containing the documents 19 | 20 | Returns 21 | ------- 22 | List[Dict[str, Any]] 23 | The list of documents read. 24 | Each document is a dictionary with the keys: 25 | - id : int 26 | Wikipage identifier 27 | - url : str 28 | Wikipage url 29 | - title : str 30 | Wikipage title 31 | - text : str 32 | Wikipage content 33 | 34 | Raises 35 | ------ 36 | FileNotFoundError 37 | If the file does not exist 38 | 39 | Examples 40 | -------- 41 | >>> documents = read_documents('data/wikipedia_documents.json') 42 | >>> print(documents[0]) 43 | { 44 | 'id': 12, 45 | 'url': 'https://en.wikipedia.org/wiki/Document', 46 | 'title': 'Document', 47 | 'text': 'A document is a written, drawn, presented, ...' 48 | } 49 | """ 50 | if not os.path.exists(file_path): 51 | raise FileNotFoundError(f'File not found: {file_path}') 52 | index = 0 53 | documents = [] 54 | with open(file_path, 'r') as file: 55 | for line in file: 56 | index += 1 57 | try: 58 | document = parse_line(line, index) 59 | except (json.JSONDecodeError, ValueError) as e: 60 | print(e) 61 | continue 62 | # Only add valid documents 63 | documents.append(document) 64 | return documents 65 | 66 | def parse_line(line: str, line_idx: int = 0) -> Dict[str, Any]: 67 | """ 68 | Parse a line containing a wikipedia document in json format. 69 | 70 | Parameters 71 | ---------- 72 | line : str 73 | The line to parse 74 | line_idx : int 75 | The line index (default is 0) 76 | 77 | Returns 78 | ------- 79 | Dict[str, Any] 80 | The parsed document. 81 | The document is a dictionary with the keys: 82 | - id : int 83 | Wikipage identifier 84 | - url : str 85 | Wikipage url 86 | - title : str 87 | Wikipage title 88 | - text : str 89 | Wikipage content 90 | 91 | Raises 92 | ------ 93 | json.JSONDecodeError 94 | If the line is not a valid json 95 | ValueError 96 | If the document is not a valid wikipedia page 97 | 98 | Examples 99 | -------- 100 | >>> line = '{"id": 12, "url": "https://en.wikipedia.org/wiki/Document", "title": "Document", "text": "A document is a written, drawn, presented, ..."}' 101 | >>> print(parse_line(line)) 102 | { 103 | 'id': 12, 104 | 'url': 'https://en.wikipedia.org/wiki/Document', 105 | 'title': 'Document', 106 | 'text': 'A document is a written, drawn, presented, ...' 107 | } 108 | """ 109 | try: 110 | data = json.loads(line) 111 | except json.JSONDecodeError: 112 | raise json.JSONDecodeError(f'Invalid json at line {line_idx}', line, line_idx) 113 | if not is_valid_wikipage(data): 114 | raise ValueError('Invalid wikipedia document') 115 | return data 116 | 117 | def is_valid_wikipage(doc: dict): 118 | """ 119 | Check if a document is a valid wikipedia page. 120 | A valid wikipedia page should contain the keys: 121 | - id : int 122 | Wikipage identifier 123 | - url : str 124 | Wikipage url 125 | - title : str 126 | Wikipage title 127 | - text : str 128 | Wikipage content 129 | 130 | Parameters 131 | ---------- 132 | doc : dict 133 | The document to check 134 | 135 | Returns 136 | ------- 137 | bool 138 | True if the document is a valid wikipedia page, False otherwise 139 | 140 | Examples 141 | -------- 142 | >>> doc = { 143 | ... 'id': 12, 144 | ... 'url': 'https://en.wikipedia.org/wiki/Document', 145 | ... 'title': 'Document', 146 | ... 'text': 'A document is a written, drawn, presented, ...' 147 | ... } 148 | >>> is_valid_wikipage(doc) 149 | True 150 | >>> doc = { 151 | ... 'id': 12, 152 | ... 'title': 'Document', 153 | ... 'text': 'A document is a written, drawn, presented, ...' 154 | ... } 155 | >>> is_valid_wikipage(doc) 156 | False 157 | """ 158 | required_keys = ['id', 'url', 'title', 'text'] 159 | for key in required_keys: 160 | if key not in doc: 161 | return False 162 | return True -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/src/main.py: -------------------------------------------------------------------------------- 1 | from data_loader import read_documents 2 | from search import search_by_keyword, search_by_similarity 3 | 4 | def main(): 5 | filepath = '../data/wikipedia_good_articles_video_games.txt' 6 | docs = read_documents(filepath) 7 | 8 | # Select title to search 9 | keywords = input('Enter the keywords to search (separated by space): ') 10 | 11 | index = 0 12 | titles = [] 13 | for doc in docs: 14 | titles.append(doc['title']) 15 | title_scores = search_by_keyword(titles, keywords, top_n=-1) 16 | print('Titles found:') 17 | for title_index, score in title_scores: 18 | # Must have at least 1 keyword in the title 19 | if score < 1: 20 | break 21 | print(f'{index}:\t{titles[title_index]}') 22 | index += 1 23 | 24 | title_index = int(input('Enter the index of the title to search: ')) 25 | query_doc = docs[title_scores[title_index][0]] 26 | query_title = query_doc['title'] 27 | query_text = query_doc['text'] 28 | 29 | texts = [] 30 | for doc in docs: 31 | texts.append(doc['text']) 32 | similarities = search_by_similarity(texts, query_text, top_n=5) 33 | 34 | print(f'Search results for "{query_title}":') 35 | for text_index, similarity in similarities: 36 | print(f'{titles[text_index]}: {similarity:.2f}') 37 | 38 | if __name__ == '__main__': 39 | main() -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/src/metrics.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This module contains the implementation of metrics to compare documents. 3 | ''' 4 | 5 | from typing import Dict 6 | 7 | def jaccard_similarity(bow1: Dict[str, int], bow2: Dict[str, int]) -> float: 8 | """ 9 | Compute the Jaccard similarity between two bag of words representations. 10 | 11 | Parameters 12 | ---------- 13 | bow1 : Dict[str, int] 14 | The first bag of words representation 15 | bow2 : Dict[str, int] 16 | The second bag of words representation 17 | 18 | Returns 19 | ------- 20 | float 21 | The Jaccard similarity between the two bag of words representations 22 | 23 | Examples 24 | -------- 25 | >>> bow1 = {'a': 2, 'document': 1, 'is': 1, 'written': 1, 'drawn': 1, 'presented': 1, 'another': 0} 26 | >>> bow2 = {'a': 1, 'document': 1, 'is': 1, 'written': 1, 'drawn': 1, 'presented': 1, 'another': 0} 27 | >>> print(compute_jaccard_similarity(bow1, bow2)) 28 | 1.0 29 | """ 30 | intersection = 0 31 | union = 0 32 | for k in bow1: 33 | if bow1[k] > 0 or bow2[k] > 0: 34 | union += 1 35 | if bow1[k] > 0 and bow2[k] > 0: 36 | intersection += 1 37 | return intersection / union -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/src/search.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This module is responsible for searching documents by title and by text. 3 | ''' 4 | 5 | from typing import List, Dict, Tuple, Any 6 | 7 | from text import preprocess_text, compute_vocab, compute_bow 8 | from metrics import jaccard_similarity 9 | 10 | def search_by_keyword( 11 | texts: List[str], 12 | keywords: str, 13 | top_n: int=5, 14 | already_preprocessed: bool=False 15 | ) -> List[Tuple[int, int]]: 16 | """ 17 | Search texts using the given keywords. 18 | 19 | Parameters 20 | ---------- 21 | texts : List[str] 22 | The list of texts to search 23 | keywords : str 24 | The keywords to search in the texts 25 | top_n : int, optional 26 | The number of texts to return, by default 5 27 | already_preprocessed : bool, optional 28 | If the texts are already preprocessed, by default False 29 | 30 | Returns 31 | ------- 32 | List[Tuple[int, int]] 33 | The list of texts with the number of keywords found 34 | The texts are sorted by the number of keywords found 35 | 36 | Examples 37 | -------- 38 | >>> texts = [ 39 | ... 'A document is a written, drawn, presented, ...', 40 | ... 'A documentary is a non-fictional motion picture ...', 41 | ... 'Documentation is a set of documents provided ...' 42 | ... ] 43 | >>> keywords = 'document' 44 | >>> print(search_by_keyword(texts, keywords)) 45 | [(0, 1), (1, 0), (2, 0)] 46 | """ 47 | if not already_preprocessed: 48 | for i in range(len(texts)): 49 | texts[i] = preprocess_text(texts[i]) 50 | keywords = preprocess_text(keywords) 51 | keywords = keywords.split() 52 | 53 | index = 0 54 | scores = [] 55 | for text in texts: 56 | words = set(text.split()) 57 | keyword_score = 0 58 | for keyword in keywords: 59 | if keyword in words: 60 | keyword_score += 1 61 | scores.append((index, keyword_score)) 62 | index += 1 63 | scores = sorted(scores, key=lambda x: x[1], reverse=True) 64 | return scores[:top_n] 65 | 66 | def search_by_similarity( 67 | texts: List[str], 68 | query: str, 69 | top_n: int=5, 70 | already_preprocessed: bool=False 71 | ) -> List[Tuple[int, float]]: 72 | """ 73 | Search texts using the given query. 74 | 75 | Parameters 76 | ---------- 77 | texts : List[str] 78 | The list of texts to search 79 | query : str 80 | The query to search in the texts 81 | top_n : int, optional 82 | The number of texts to return, by default 5 83 | already_preprocessed : bool, optional 84 | If the texts are already preprocessed, by default False 85 | 86 | Returns 87 | ------- 88 | List[Tuple[int, float]] 89 | The list of texts with the similarity to the query 90 | The texts are sorted by the similarity to the query 91 | 92 | Examples 93 | -------- 94 | >>> texts = [ 95 | ... 'A document is a written, drawn, presented, ...', 96 | ... 'A documentary is a non-fictional motion picture ...', 97 | ... 'Documentation is a set of documents provided ...' 98 | ... ] 99 | >>> query = 'document' 100 | >>> print(search_by_similarity(texts, query)) 101 | [(0, 1), (1, 2/11), (2, 2/11)] 102 | """ 103 | if not already_preprocessed: 104 | for i in range(len(texts)): 105 | texts[i] = preprocess_text(texts[i]) 106 | query = preprocess_text(query) 107 | 108 | vocab = compute_vocab(texts, top_n=10000) 109 | 110 | query_bow = compute_bow(query, vocab) 111 | index = 0 112 | similarities = [] 113 | for text in texts: 114 | doc_bow = compute_bow(text, vocab) 115 | similarity = jaccard_similarity(query_bow, doc_bow) 116 | similarities.append((index, similarity)) 117 | index += 1 118 | similarities = sorted(similarities, key=lambda x: x[1], reverse=True) 119 | return similarities[:top_n] 120 | -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/src/text.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This module contains functions to preprocess text and compute the bag of words representation of a text. 3 | ''' 4 | 5 | from typing import List, Set, Dict 6 | 7 | def preprocess_text(text: str) -> str: 8 | """ 9 | Preprocess the text by converting it to lowercase and removing punctuation. 10 | 11 | Parameters 12 | ---------- 13 | text : str 14 | The text to be preprocessed 15 | 16 | Returns 17 | ------- 18 | str 19 | The preprocessed text 20 | 21 | Examples 22 | -------- 23 | >>> text = 'A document is a written, drawn, presented, ...' 24 | >>> print(preprocess_text(text)) 25 | 'a document is a written drawn presented' 26 | """ 27 | text = text.lower().strip() 28 | chars = [] 29 | for c in text: 30 | if c.isalnum() or c.isspace(): 31 | chars.append(c) 32 | else: 33 | chars.append(' ') 34 | text = ''.join(chars) 35 | text = ' '.join(text.split()) 36 | return text 37 | 38 | def compute_vocab(texts: List[str], top_n: int = 10000) -> Set[str]: 39 | """ 40 | Compute the vocabulary of the documents by selecting the top_n most frequent words. 41 | 42 | Parameters 43 | ---------- 44 | texts : List[str] 45 | The list of documents to compute the vocabulary 46 | top_n : int, optional 47 | The number of most frequent words to select, by default 10000 48 | 49 | Returns 50 | ------- 51 | Set[str] 52 | The set of most frequent words in the documents 53 | 54 | Examples 55 | -------- 56 | >>> texts = ['a document is a written drawn presented', 'another document is a written drawn presented'] 57 | >>> print(compute_vocab(texts)) 58 | {'a', 'document', 'is', 'written', 'drawn', 'presented', 'another'} 59 | """ 60 | vocab = {} 61 | for text in texts: 62 | for word in text.split(): 63 | vocab[word] = vocab.get(word, 0) + 1 64 | vocab = [(k, v) for k, v in vocab.items()] 65 | vocab = sorted(vocab, key=lambda x: x[1], reverse=True) 66 | vocab = vocab[:top_n] 67 | vocab = {k for k, _ in vocab} 68 | return vocab 69 | 70 | def compute_bow(text: str, vocab: Set[str]) -> Dict[str, int]: 71 | """ 72 | Compute the bag of words representation of a text using a given vocabulary. 73 | 74 | Parameters 75 | ---------- 76 | text : str 77 | The text to compute the bag of words 78 | vocab : Set[str] 79 | The vocabulary to use for the bag of words 80 | 81 | Returns 82 | ------- 83 | Dict[str, int] 84 | The bag of words representation of the text 85 | 86 | Examples 87 | -------- 88 | >>> vocab = {'a', 'document', 'is', 'written', 'drawn', 'presented', 'another'} 89 | >>> text = 'a document is a written drawn presented' 90 | >>> print(compute_bow(text, vocab)) 91 | {'a': 2, 'document': 1, 'is': 1, 'written': 1, 'drawn': 1, 'presented': 1, 'another': 0} 92 | """ 93 | bow = {k: 0 for k in vocab} 94 | for word in text.split(): 95 | if word in vocab: 96 | bow[word] += 1 97 | return bow 98 | 99 | -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/tests/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | module_dirpath = os.path.dirname(os.path.abspath(__file__)) 5 | source_dirpath = os.path.join(module_dirpath, '..', 'src') 6 | print(source_dirpath) 7 | sys.path.insert(0, source_dirpath) 8 | -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/tests/test_data_loader.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from data_loader import is_valid_wikipage, parse_line 4 | 5 | class TestDataLoader(unittest.TestCase): 6 | 7 | def test_is_valid_wikipage_valid(self): 8 | doc = { 9 | 'id': 12, 10 | 'url': 'https://en.wikipedia.org/wiki/Document', 11 | 'title': 'Document', 12 | 'text': 'A document is a written, drawn, presented, ...' 13 | } 14 | self.assertTrue(is_valid_wikipage(doc)) 15 | 16 | def test_is_valid_wikipage_invalid(self): 17 | doc = { 18 | 'id': 12, 19 | 'url': 'https://en.wikipedia.org/wiki/Document', 20 | 'title': 'Document' 21 | } 22 | self.assertFalse(is_valid_wikipage(doc)) 23 | 24 | def test_parse_line_valid(self): 25 | line = '{"id": 12, "url": "https://en.wikipedia.org/wiki/Document", "title": "Document", "text": "A document is a written, drawn, presented, ..."}' 26 | doc = { 27 | 'id': 12, 28 | 'url': 'https://en.wikipedia.org/wiki/Document', 29 | 'title': 'Document', 30 | 'text': 'A document is a written, drawn, presented, ...' 31 | } 32 | self.assertEqual(parse_line(line), doc) 33 | 34 | def test_parse_line_invalid(self): 35 | line = '{"id": 12, "url": "https://en.wikipedia.org/wiki/Document", "title": "Document"}' 36 | with self.assertRaises(ValueError): 37 | parse_line(line) 38 | -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/tests/test_metrics.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from metrics import jaccard_similarity 4 | 5 | class TestMetrics(unittest.TestCase): 6 | 7 | def test_jaccard_similarity_perfect(self): 8 | bow1 = {'a': 2, 'document': 1, 'is': 1, 'written': 1, 'drawn': 1, 'presented': 1, 'another': 0} 9 | bow2 = {'a': 1, 'document': 1, 'is': 1, 'written': 1, 'drawn': 1, 'presented': 1, 'another': 0} 10 | self.assertEqual(jaccard_similarity(bow1, bow2), 1.0) 11 | 12 | def test_jaccard_similarity_almost(self): 13 | bow1 = {'a': 2, 'document': 1, 'is': 1, 'written': 1, 'drawn': 1, 'presented': 1, 'another': 0} 14 | bow2 = {'a': 1, 'document': 1, 'is': 1, 'written': 1, 'drawn': 1, 'presented': 1, 'another': 1} 15 | self.assertAlmostEqual(jaccard_similarity(bow1, bow2), 0.857, places=3) 16 | 17 | if __name__ == '__main__': 18 | unittest.main() 19 | -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/tests/test_search.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from search import search_by_keyword, search_by_similarity 4 | 5 | class TestSearch(unittest.TestCase): 6 | 7 | def test_search_by_keyword(self): 8 | texts = [ 9 | 'A document is a written, drawn, presented, ...', 10 | 'A documentary is a non-fictional motion picture ...', 11 | 'Documentation is a set of documents provided ...' 12 | ] 13 | keywords = 'document' 14 | expected = [(0, 1), (1, 0), (2, 0)] 15 | result = search_by_keyword(texts, keywords) 16 | self.assertListEqual(result, expected) 17 | 18 | def test_search_by_similarity(self): 19 | texts = [ 20 | 'A document is a written, drawn, presented, ...', 21 | 'A documentary is a non-fictional motion picture ...', 22 | 'Documentation is a set of documents provided ...' 23 | ] 24 | query = texts[0] 25 | result = search_by_similarity(texts, query) 26 | expected = [(0, 1), (1, 2/11), (2, 2/11)] 27 | self.assertListEqual(result, expected) -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/tests/test_text.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from text import preprocess_text, compute_vocab, compute_bow 4 | 5 | class TestText(unittest.TestCase): 6 | 7 | def test_preprocess_text(self): 8 | text = 'A document is a written, drawn, presented, ...' 9 | result = preprocess_text(text) 10 | expected = 'a document is a written drawn presented' 11 | self.assertEqual(result, expected) 12 | 13 | def test_compute_vocab(self): 14 | texts = ['a document is a written drawn presented', 'another document is a written drawn presented'] 15 | result = compute_vocab(texts) 16 | expected = {'a', 'document', 'is', 'written', 'drawn', 'presented', 'another'} 17 | self.assertSetEqual(result, expected) 18 | 19 | def test_compute_bow(self): 20 | text = 'a document is a written drawn presented' 21 | vocab = {'a', 'document', 'is', 'written', 'drawn', 'presented', 'another'} 22 | result = compute_bow(text, vocab) 23 | expected = {'a': 2, 'document': 1, 'is': 1, 'written': 1, 'drawn': 1, 'presented': 1, 'another': 0} 24 | self.assertDictEqual(result, expected) 25 | -------------------------------------------------------------------------------- /projeto_similaridade_de_documentos/versao_antiga/main.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | import math 3 | import json 4 | 5 | def preprocessamento_texto(texto: str) -> str: 6 | """ 7 | Realiza o preprocessamento de um texto. 8 | 9 | Parameters 10 | ---------- 11 | texto: str 12 | Texto a ser preprocessado 13 | 14 | Returns 15 | ------- 16 | str 17 | Texto preprocessado 18 | 19 | Examples 20 | -------- 21 | >>> preprocessamento_texto("Hello, World!") 22 | 'hello world' 23 | >>> preprocessamento_texto("Hello, World! 123") 24 | 'hello world 123' 25 | >>> preprocessamento_texto("Hello, World! 123 @#") 26 | 'hello world 123' 27 | >>> preprocessamento_texto(123) 28 | Traceback (most recent call last): 29 | File "main.py", line 34, in preprocessamento_texto 30 | texto = texto.lower() 31 | AttributeError: 'int' object has no attribute 'lower' 32 | """ 33 | # Colocar texto em caixa-baixa. 34 | # Exemplo: "Hello, World!" -> "hello, world!" 35 | texto = texto.lower() 36 | 37 | # Troca todos os caracteres não alfanuméricos por espaços 38 | # Exemplo: "hello, world!" -> "hello world" 39 | char_validos = [] 40 | for c in texto: 41 | if c.isalnum() or c.isspace(): 42 | char_validos.append(c) 43 | else: 44 | char_validos.append(' ') 45 | texto = ''.join(char_validos) 46 | 47 | # Troca todos as sequencias de espaços em brancos por um único espaço 48 | # Exemplo: "hello world" -> "hello world" 49 | texto = ' '.join(texto.split()) 50 | return texto 51 | 52 | def carregar_dados(caminho: str) -> list[str]: 53 | """ 54 | Carrega os textos da aplicação 55 | 56 | Returns 57 | ------- 58 | List[Dict[str, Any]] 59 | Lista de dicionarios representando paginas da wikipedia. 60 | Cada dicionario ira conter as seguintes chaves: 61 | - id: int 62 | Identificador da pagina 63 | - title: str 64 | Titulo da pagina 65 | - text: str 66 | O conteudo da pagina 67 | """ 68 | wiki_pages = [] 69 | with open(caminho, mode='r', encoding='utf-8') as fp: 70 | for line in fp: 71 | wiki_page = json.loads(line) 72 | wiki_pages.append(wiki_page) 73 | return wiki_pages 74 | 75 | def criar_vocabulario(textos: list[str], vocab_size: int=10000) -> dict[str, int]: 76 | """ 77 | Cria um vocabulário baseado numa lista de documentos 78 | 79 | Parameters 80 | ---------- 81 | textos: List[str] 82 | Documentos utilizados para gerar o vocabulario 83 | vocab_size: int 84 | Tamanho maximo do vocabulario 85 | """ 86 | contador = Counter() 87 | for texto in textos: 88 | palavras = texto.split() 89 | contador.update(palavras) 90 | 91 | vocab = dict() 92 | index = 0 93 | for palavra, freq in contador.most_common(vocab_size): 94 | vocab[palavra] = index 95 | index += 1 96 | 97 | return vocab 98 | 99 | def bag_of_words(texto: str, vocab: dict[str, int]): 100 | """Converte um texto na sua representação Bag-of-Words""" 101 | # Divido em palavras 102 | palavras = texto.split() 103 | 104 | # Vetor ocorrencias das palvras 105 | vetor = [0] * len(vocab) 106 | 107 | # Mapear palvras no vetor 108 | for palavra in palavras: 109 | index = vocab.get(palavra, -1) 110 | if index < 0: 111 | continue 112 | vetor[index] += 1 113 | 114 | return vetor 115 | 116 | def distancia_euclideana(v1: list[float], v2: list[float]) -> float: 117 | """Calcula a distância euclidiana entre dois vetores""" 118 | if len(v1) != len(v2): 119 | print("Tamanhos diferentes!") 120 | exit() 121 | 122 | tam1 = len(v1) 123 | dist = 0 124 | for i in range(tam1): 125 | dist += (v1[i] - v2[i]) ** 2 126 | return math.sqrt(dist) 127 | 128 | def ranquear_documentos(bows: list[list[float]], bow_busca: list[float]) -> list[tuple[int, float]]: 129 | """Ranquear os documentos mais similares a um documento especifico""" 130 | dists = [] 131 | for i in range(len(bows)): 132 | dist = distancia_euclideana(bows[i], bow_busca) 133 | dists.append((i, dist)) 134 | dists = sorted(dists, key=lambda x: x[1]) 135 | return dists 136 | 137 | def selecionar_titulo(titulos: list[str]) -> int: 138 | """ 139 | Pede para o usuário selecionar um titulo da lista disponivel 140 | 141 | parameters 142 | ---------- 143 | titulos: list[str] 144 | Lista de titulos disponiveis 145 | 146 | returns 147 | ------- 148 | Indice do titulo escolhido 149 | """ 150 | for i in range(len(titulos)): 151 | print(f'#{i}: {titulos[i]}') 152 | 153 | idx = input('Selecione um dos titulos acima: ') 154 | return int(idx) 155 | 156 | def main(): 157 | # Descompactar o zip presente em: 158 | # ./aulas/Semana 3 - Documentacao & Type Hint/wikipedia_good_articles_video_games.zip 159 | # e jogar no diretório do presente script (ou atualizar o caminho abaixo para o local adequado) 160 | # caminho = 'wikipedia_good_articles_video_games.txt' 161 | caminho = './aulas/Semana 3 - Documentacao & Type Hint/wikipedia_good_articles_video_games.txt' 162 | wiki_pages = carregar_dados(caminho) 163 | 164 | docs = [] 165 | titulos = [] 166 | for wiki_page in wiki_pages: 167 | texto = wiki_page["text"] 168 | texto = preprocessamento_texto(texto) 169 | docs.append(texto) 170 | 171 | titulo = wiki_page["title"] 172 | titulos.append(titulo) 173 | 174 | vocab = criar_vocabulario(docs) 175 | print(f'Tamanho do vocabulario: {len(vocab)}') 176 | 177 | bows = [] 178 | for doc in docs: 179 | bow = bag_of_words(doc, vocab) 180 | bows.append(bow) 181 | 182 | # Ranking 183 | bow_busca_idx = selecionar_titulo(titulos) 184 | bow_busca = bows[bow_busca_idx] 185 | ranking = ranquear_documentos(bows, bow_busca) 186 | 187 | rank_index = 0 188 | print(f'Documento selecionado: {titulos[bow_busca_idx]}') 189 | for idx, dist in ranking[:5]: 190 | print(f'#{rank_index}: {titulos[idx]}') 191 | rank_index+=1 192 | 193 | if __name__ == "__main__": 194 | # main() 195 | import doctest 196 | doctest.testmod() -------------------------------------------------------------------------------- /pygame/38_codigo_aula.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | 3 | 4 | class Player(pygame.sprite.Sprite): 5 | 6 | def __init__(self, x, y, width, height, image_paths): 7 | # image_animation_right: List[str] 8 | # image_animation_left: List[str] 9 | # image_animation_up: List[str] 10 | # image_animation_down: List[str] 11 | # image_animation_idle: List[str] 12 | super().__init__() 13 | 14 | # 15 | self.idle_animation = [] 16 | for image_path in image_paths: 17 | sprite = pygame.image.load(image_path) 18 | # sprite = pygame.transform.scale(sprite, (width, height)) 19 | self.idle_animation.append(sprite) 20 | self.current_frame_index = 0 21 | self.image = self.idle_animation[self.current_frame_index] 22 | 23 | self.frames_per_sprite = 5 24 | self.frame_index = 0 25 | 26 | self.rect = self.image.get_rect() 27 | self.rect.x = x 28 | self.rect.y = y 29 | 30 | self.color = (255, 0, 0) 31 | self.gravity_y = 2 # pixels^2 / frame 32 | self.speed_y = 0 33 | self.jump_count = 0 34 | self.jump_count_max = 2 35 | 36 | def draw(self, screen): 37 | self.frame_index += 1 38 | if self.frame_index >= self.frames_per_sprite: 39 | self.frame_index = 0 40 | self.current_frame_index += 1 41 | if self.current_frame_index >= len(self.idle_animation): 42 | self.current_frame_index = 0 43 | self.image = self.idle_animation[self.current_frame_index] 44 | screen.blit(self.image, self.rect) 45 | 46 | def update(self): 47 | self.speed_y += self.gravity_y 48 | self.rect.y += self.speed_y 49 | 50 | def on_event(self, event: pygame.event.Event): 51 | if event.type == pygame.KEYDOWN: 52 | if event.key == pygame.K_SPACE: 53 | self._jump() 54 | 55 | def _jump(self): 56 | if self.jump_count >= self.jump_count_max: 57 | return 58 | self.speed_y = -40 59 | self.jump_count += 1 60 | 61 | def on_key_pressed(self, key_map): 62 | if key_map[pygame.K_RIGHT] or key_map[pygame.K_w]: 63 | self.rect.x += 10 64 | elif key_map[pygame.K_LEFT]: 65 | self.rect.x -= 10 66 | 67 | def on_collision(self, other): 68 | # TODO: Comportamento precisa ser diferente dependendo lado da colisão 69 | if isinstance(other, Ground): 70 | ground_y = other.rect.top 71 | self.rect.bottom = ground_y 72 | self.speed_y = 0 73 | self.jump_count = 0 74 | 75 | class Ground(pygame.sprite.Sprite): 76 | 77 | def __init__(self, x, y, width, height, image_path): 78 | super().__init__() 79 | self.image = pygame.image.load(image_path) 80 | self.image = pygame.transform.scale(self.image, (width, height)) 81 | self.rect = self.image.get_rect() 82 | self.rect.x = x 83 | self.rect.y = y 84 | self.color = (0, 255, 0) 85 | 86 | # def draw(self, screen): 87 | # pygame.draw.rect(screen, self.color, self.rect) 88 | 89 | def update(self): 90 | pass 91 | 92 | def on_collision(self, other): 93 | pass 94 | 95 | class GameManager: 96 | 97 | def __init__(self) -> None: 98 | pygame.init() 99 | 100 | # A tela 101 | self.width = 800 102 | self.height = 600 103 | screen_size = (self.width, self.height) 104 | self.screen = pygame.display.set_mode(screen_size) 105 | self.screen.fill((0, 0, 0)) 106 | 107 | # Objetos 108 | sprite_paths = [ 109 | "./sprites/link/down_idle/link_down_idle_0.png", 110 | "./sprites/link/down_idle/link_down_idle_1.png", 111 | "./sprites/link/down_idle/link_down_idle_2.png" 112 | ] 113 | 114 | self.player = Player(self.width // 2, self.height // 2, 50, 75, sprite_paths) 115 | 116 | sprite_path = "./sprites/powerup.png" 117 | self.ground_group = pygame.sprite.Group() 118 | self.ground_group.add(Ground(0, self.height - 30, self.width, 60, sprite_path)) 119 | self.ground_group.add(Ground(self.width // 2, self.height - 200, 100, 20, sprite_path)) 120 | self.ground_group.add(Ground(300, self.height - 90, 50, 50, sprite_path)) 121 | 122 | self.clock = pygame.time.Clock() 123 | self.is_running = True 124 | 125 | def run(self): 126 | while self.is_running: 127 | self.event() 128 | self.update() 129 | self.draw() 130 | self.clock.tick(30) 131 | pygame.quit() 132 | 133 | def event(self): 134 | # Eventos 135 | events = pygame.event.get() 136 | for event in events: 137 | if event.type == pygame.QUIT: 138 | self.is_running = False 139 | self.player.on_event(event) 140 | 141 | # Chaves pressionadas no momento 142 | key_map = pygame.key.get_pressed() 143 | self.player.on_key_pressed(key_map) 144 | 145 | def update(self): 146 | self.player.update() 147 | self.ground_group.update() 148 | self.collision_detection() 149 | 150 | def collision_detection(self): 151 | # Verificar colisao 152 | for ground in self.ground_group: 153 | has_collided = self.player.rect.colliderect(ground.rect) 154 | if has_collided: 155 | self.player.on_collision(ground) 156 | ground.on_collision(self.player) 157 | 158 | def draw(self): 159 | # Renderizaçao 160 | self.screen.fill((0, 0, 0)) 161 | self.player.draw(self.screen) 162 | self.ground_group.update() 163 | self.ground_group.draw(self.screen) 164 | pygame.display.flip() 165 | 166 | if __name__ == '__main__': 167 | game = GameManager() 168 | game.run() --------------------------------------------------------------------------------