├── Arquivos ├── gato.json ├── livros.xml ├── new_livros.xml ├── novo_livros.xml ├── personagem.json └── teste.txt ├── Capitulos ├── 01.Introdução.md ├── 02.Ambiente de Programação.md ├── 03.Sintaxe.md ├── 04.Tipos de Variáveis.md ├── 05.Números.md ├── 06.Strings.md ├── 07.Operadores.md ├── 08.Listas.md ├── 09.Tuplas.md ├── 10.Dicionários.md ├── 11.Sets.md ├── 12.Input.md ├── 13.If...Else.md ├── 14.ForLoops.md ├── 15.WhileLoops.md ├── 16.Funções.md ├── 17.Lambda.md ├── 18.Módulos.md ├── 19.InputOutputArquivos.md ├── 20.ErrosExceções.md ├── 21.DataTempo.md ├── 22.ClassesObjetos.md ├── 23.ExpressõesRegulares.md ├── 24.PythonJSON.md ├── 25.PythonXML.md ├── 26.Iteradores.md ├── 27.Geradores.md ├── 28.Decoradores.md ├── 29.PIP.md ├── 30.PythonMySQL.md ├── 31.PythonMongoDB.md ├── 32.Grandes Bibliotecas e Ferramentas.md └── 33.Referências Online.md ├── Imagens ├── ASCIITable.png ├── Algorithm.png ├── Avatar.png ├── BinaryNumbers.gif ├── Classes.png ├── ComputerArchitecture.png ├── Conditionals.png ├── Dictionary.png ├── Diferença.png ├── DiferençaSimétrica.png ├── DistanceFormula.png ├── File.png ├── ForLoop.png ├── Function.png ├── HinduAvatar.png ├── Intersecção.png ├── Introduction.png ├── JanKenPon.png ├── Lambda.png ├── Lists.png ├── Modules.png ├── Numbers.png ├── Object.png ├── Package.png ├── Permutations.png ├── Polymorphism.png ├── PythonFunction.png ├── Set.png ├── Sierpinski.png ├── String.png ├── União.png ├── Variables.png ├── WhileLoop.png ├── XkcdPython.png ├── abs.png ├── x-y.png ├── x.png ├── x_y.png └── xy.png ├── LICENSE └── README.md /Arquivos/gato.json: -------------------------------------------------------------------------------- 1 | {"py/object": "__main__.Gato", "nome": "Osíris", "raca": "Sphynx"} -------------------------------------------------------------------------------- /Arquivos/livros.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Orwell, George 5 | Nineteen Eighty-Four: A Novel 6 | Dystopian 7 | 1949-06-08 8 | Thematically, Nineteen Eighty-Four centres on the consequences of totalitarianism, mass surveillance, and repressive regimentation of persons and behaviours within society. 9 | 10 | 11 | Huxley, Aldous 12 | Brave New World 13 | Dystopian 14 | 1932-12-16 15 | Largely set in a futuristic World State, whose citizens are environmentally engineered into an intelligence-based social hierarchy, the novel anticipates huge scientific advancements in reproductive technology, sleep-learning, psychological manipulation and classical conditioning that are combined to make a dystopian society which is challenged by only a single individual: the story's protagonist. 16 | 17 | 18 | Huxley, Aldous 19 | The Doors of Perception 20 | Psychology 21 | 1954-11-17 22 | The Doors of Perception provoked strong reactions for its evaluation of psychedelic drugs as facilitators of mystical insight with great potential benefits for science, art, and religion. 23 | 24 | 25 | Gibson, William 26 | Neuromancer 27 | Cyberpunk 28 | 1984-07-01 29 | Set in the future, the novel follows Henry Case, a washed-up computer hacker who is hired for one last job, which brings him up against a powerful artificial intelligence. 30 | 31 | 32 | Erickson, Jon 33 | Hacking: The Art of Exploitation 34 | Computer Security 35 | 2003-09-10 36 | Hacking: The Art of Exploitation is a book by Jon "Smibbs" Erickson about computer security and network security. 37 | 38 | 39 | Chollet, François 40 | Deep Learning with Python 41 | Machine Learning 42 | 2017-11-02 43 | Deep Learning with Python introduces the field of deep learning using the Python language and the powerful Keras library. Written by Keras creator and Google AI researcher François Chollet, this book builds your understanding through intuitive explanations and practical examples. 44 | 45 | 46 | Kant, Immanuel 47 | Critique of Pure Reason 48 | Philosophy 49 | 1787-11-02 50 | The Critique of Pure Reason is a book by the German philosopher Immanuel Kant, in which the author seeks to determine the limits and scope of metaphysics. 51 | 52 | 53 | Schopenhauer, Arthur 54 | The World as Will and Representation 55 | Philosophy 56 | 1818-12-06 57 | Taking the transcendental idealism of Immanuel Kant as his starting point, Schopenhauer argues that the world we experience around us—the world of objects in space and time and related in causal ways—exists solely as 'representation' (Vorstellung) dependent on a cognizing subject, not as a world that can be considered to exist in itself (independently of how it appears to the subject’s mind). 58 | 59 | -------------------------------------------------------------------------------- /Arquivos/new_livros.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Orwell, George 4 | Nineteen Eighty-Four: A Novel 5 | Dystopian 6 | Thematically, Nineteen Eighty-Four centres on the consequences of totalitarianism, mass surveillance, and repressive regimentation of persons and behaviours within society. 7 | 8 | 9 | Huxley, Aldous 10 | Brave New World 11 | Dystopian 12 | Largely set in a futuristic World State, whose citizens are environmentally engineered into an intelligence-based social hierarchy, the novel anticipates huge scientific advancements in reproductive technology, sleep-learning, psychological manipulation and classical conditioning that are combined to make a dystopian society which is challenged by only a single individual: the story's protagonist. 13 | 14 | 15 | Huxley, Aldous 16 | The Doors of Perception 17 | Psychology 18 | The Doors of Perception provoked strong reactions for its evaluation of psychedelic drugs as facilitators of mystical insight with great potential benefits for science, art, and religion. 19 | 20 | 21 | Gibson, William 22 | Neuromancer 23 | Cyberpunk 24 | Set in the future, the novel follows Henry Case, a washed-up computer hacker who is hired for one last job, which brings him up against a powerful artificial intelligence. 25 | 26 | 27 | Erickson, Jon 28 | Hacking: The Art of Exploitation 29 | Computer Security 30 | Hacking: The Art of Exploitation is a book by Jon "Smibbs" Erickson about computer security and network security. 31 | 32 | 33 | Chollet, François 34 | Deep Learning with Python 35 | Machine Learning 36 | Deep Learning with Python introduces the field of deep learning using the Python language and the powerful Keras library. Written by Keras creator and Google AI researcher François Chollet, this book builds your understanding through intuitive explanations and practical examples. 37 | 38 | 39 | Kant, Immanuel 40 | Critique of Pure Reason 41 | Philosophy 42 | The Critique of Pure Reason is a book by the German philosopher Immanuel Kant, in which the author seeks to determine the limits and scope of metaphysics. 43 | 44 | 45 | Schopenhauer, Arthur 46 | The World as Will and Representation 47 | Philosophy 48 | Taking the transcendental idealism of Immanuel Kant as his starting point, Schopenhauer argues that the world we experience around us—the world of objects in space and time and related in causal ways—exists solely as 'representation' (Vorstellung) dependent on a cognizing subject, not as a world that can be considered to exist in itself (independently of how it appears to the subject’s mind). 49 | 50 | -------------------------------------------------------------------------------- /Arquivos/novo_livros.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Orwell, George 4 | Nineteen Eighty-Four: A Novel 5 | Dystopian 6 | 1949-06-08 7 | Thematically, Nineteen Eighty-Four centres on the consequences of totalitarianism, mass surveillance, and repressive regimentation of persons and behaviours within society. 8 | 9 | 10 | Huxley, Aldous 11 | Brave New World 12 | Dystopian 13 | 1932-12-16 14 | Largely set in a futuristic World State, whose citizens are environmentally engineered into an intelligence-based social hierarchy, the novel anticipates huge scientific advancements in reproductive technology, sleep-learning, psychological manipulation and classical conditioning that are combined to make a dystopian society which is challenged by only a single individual: the story's protagonist. 15 | 16 | 17 | Huxley, Aldous 18 | The Doors of Perception 19 | Psychology 20 | 1954-11-17 21 | The Doors of Perception provoked strong reactions for its evaluation of psychedelic drugs as facilitators of mystical insight with great potential benefits for science, art, and religion. 22 | 23 | 24 | Gibson, William 25 | Neuromancer 26 | Science Fiction 27 | 1984-07-01 28 | Set in the future, the novel follows Henry Case, a washed-up computer hacker who is hired for one last job, which brings him up against a powerful artificial intelligence. 29 | 30 | 31 | Erickson, Jon 32 | Hacking: The Art of Exploitation 33 | Computer Security 34 | 2003-09-10 35 | Hacking: The Art of Exploitation is a book by Jon "Smibbs" Erickson about computer security and network security. 36 | 37 | 38 | Chollet, François 39 | Deep Learning with Python 40 | Machine Learning 41 | 2017-11-02 42 | Deep Learning with Python introduces the field of deep learning using the Python language and the powerful Keras library. Written by Keras creator and Google AI researcher François Chollet, this book builds your understanding through intuitive explanations and practical examples. 43 | 44 | 45 | Kant, Immanuel 46 | Critique of Pure Reason 47 | Philosophy 48 | 1787-11-02 49 | The Critique of Pure Reason is a book by the German philosopher Immanuel Kant, in which the author seeks to determine the limits and scope of metaphysics. 50 | 51 | 52 | Schopenhauer, Arthur 53 | The World as Will and Representation 54 | Philosophy 55 | 1818-12-06 56 | Taking the transcendental idealism of Immanuel Kant as his starting point, Schopenhauer argues that the world we experience around us—the world of objects in space and time and related in causal ways—exists solely as 'representation' (Vorstellung) dependent on a cognizing subject, not as a world that can be considered to exist in itself (independently of how it appears to the subject’s mind). 57 | 58 | -------------------------------------------------------------------------------- /Arquivos/personagem.json: -------------------------------------------------------------------------------- 1 | { 2 | "nome": "Talantyr", 3 | "epiteto": "O Glorioso", 4 | "nível": 45, 5 | "vivo": true, 6 | "atributos": { 7 | "força": 45, 8 | "destreza": 60, 9 | "inteligência": 70 10 | }, 11 | "mascotes": [ 12 | "Lobo", 13 | "Coruja" 14 | ], 15 | "magias": null, 16 | "itens": [ 17 | { 18 | "nome": "poção de mana", 19 | "quantidade": 5 20 | }, 21 | { 22 | "nome": "poção de vida", 23 | "quantidade": 7 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /Arquivos/teste.txt: -------------------------------------------------------------------------------- 1 | Estamos escrevendo no arquivo 2 | Outra linha escrita no arquivo 3 | Anexando ao arquivo -------------------------------------------------------------------------------- /Capitulos/01.Introdução.md: -------------------------------------------------------------------------------- 1 | # Introdução 2 | 3 | ![img](/Imagens/Introduction.png) 4 | 5 | Python é uma linguagem de programação **[interpretada](https://pt.wikipedia.org/wiki/Linguagem_interpretada)**, **[de alto nível](https://pt.wikipedia.org/wiki/Linguagem_de_programação_de_alto_nível)**, que pode ser aplicada em diversas soluções. Famosa por sua sintaxe amigável, ela vem ganhando uma expressiva popularidade nos últimos anos. Foi criada por Guido Van Rossum no 6 | período de 1985-1990, seu código fonte está disponível sob o **GNU General Public License (GPL)**. Python conta com uma **[tipagem dinâmica](https://pt.wikipedia.org/wiki/Sistema_de_tipos)** e um sistema de gerenciamento de memória automático, sendo capaz de suportar múltiplos **[paradigmas de programação](https://pt.wikipedia.org/wiki/Paradigma_de_programação)**. 7 | 8 | Python é uma linguagem poderosa e de fácil aprendizado. Possui **[estruturas de dados](https://pt.wikipedia.org/wiki/Estrutura_de_dados)** eficientes e de alto nível e uma simples e efetiva abordagem em relação à **[programação orientada a objetos](https://pt.wikipedia.org/wiki/Programação_orientada_a_objetos)**. A sintaxe elegante de Python e sua **tipagem dinâmica**, juntamente com sua natureza interpretada, faz do Python uma linguagem ideal para *scripting* e desenvolvimento rápido de aplicações em muitas áreas e para diversas plataformas. 9 | 10 | O **interpretador** Python e a extensiva **[standard library](https://docs.python.org/3/library/)** estão disponíveis gratuitamente na forma *source* ou *binary* para todas as maiores plataformas através do **[site oficial Python](https://www.python.org/)**. 11 | 12 | ## As principais aplicações de Python são: 13 | 14 | - Desenvolvimento web **[(lado do servidor)](https://pt.wikipedia.org/wiki/Server-side)** 15 | - Desenvolvimento de softwares em geral 16 | - Matemática e Computação Científica 17 | - Inteligência Artificial, **[Machine Learning](https://en.wikipedia.org/wiki/Machine_learning)**, **[Deep Learning](https://en.wikipedia.org/wiki/Deep_learning)** 18 | - **[Scripting](https://pt.wikipedia.org/wiki/Linguagem_de_script)** e automação de tarefas repetitivas 19 | - Testes de software 20 | 21 | ## Por que aprender Python? 22 | 23 | - Python é capaz de rodar em múltiplas plataformas (**Windows**, **Linux**, **MacOS**, **Raspberry Pi**, etc) 24 | - Python suporta **programação interativa** (Interação direta com o interpretador) 25 | - Sua sintaxe é simples de compreender 26 | - Suporta múltiplos **[paradigmas de programação](https://pt.wikipedia.org/wiki/Paradigma_de_programação)** 27 | - Python pode ser usada para prototipação rápida 28 | - Python está apta a se conectar com sistemas de **[banco de dados](https://pt.wikipedia.org/wiki/Banco_de_dados)**, pode também ler e modificar arquivos 29 | - Pode ser utilizada para lidar com grandes quantidades de dados e executar cálculos matemáticos complexos 30 | - Python conta com uma comunidade gigantesca e muito material de aprendizado! 31 | 32 | ## Importante 33 | 34 | - A versão mais recente de Python é o Python 3, no qual iremos utilizar nesse guia, porém a versão Python 2 ainda é muito popular, embora não esteja mais recebendo suporte da **Python Software Foundation** 35 | - Python pode ser integrada com **C**, **C++**, **CORBA**, **Java**. Caso haja a necessidade de trabalhar com códigos de alta perfomance 36 | - Atualmente muitas das grandes corporações utilizam Python, podemos citar elas: **Google**, **Facebook**, **Microsoft**, **NASA**, **CERN**. 37 | 38 | # Computação 39 | 40 | ![img](/Imagens/BinaryNumbers.gif) 41 | 42 | Antes de iniciarmos nossos estudos sobre a linguagem Python, é importante que tenhamos uma breve Introdução à Computação. 43 | 44 | A Computação é qualquer tipo de cálculo que inclui etapas aritméticas e não-aritméticas e que segue um modelo bem definido (por exemplo, um [algoritmo](https://en.wikipedia.org/wiki/Algorithm)). 45 | 46 | Dispositivos mecânicos ou eletrônicos (ou, historicamente, pessoas) que realizam cálculos são conhecidos como computadores. Uma disciplina especialmente conhecida do estudo da computação é a [ciência da computação](https://en.wikipedia.org/wiki/Computer_science). 47 | 48 | A Computação pode ser vista como um fenômeno puramente físico que ocorre dentro de um [sistema físico](https://en.wikipedia.org/wiki/Physical_system) fechado chamado computador. Exemplos de tais sistemas físicos incluem computadores digitais, computadores mecânicos, computadores quânticos, computadores de DNA, computadores moleculares ou até mesmo computadores analógicos. Esse ponto de vista foi adotado pela [física da computação](https://en.wikipedia.org/wiki/Physics_of_computation), um ramo da física teórica, bem como pelo campo da [computação natural](https://en.wikipedia.org/wiki/Natural_computing). 49 | 50 | Um ponto de vista ainda mais radical, o [pancomputacionalismo](https://en.wikipedia.org/wiki/Pancomputationalism), é o postulado da [física digital](https://en.wikipedia.org/wiki/Digital_physics) que argumenta que a evolução do universo é em si uma computação. 51 | 52 | ## Computação na Prática 53 | 54 | Programação de computador é o processo de escrever instruções que são executadas por computadores. As instruções, também conhecidas como código, são escritas em uma linguagem de programação que o computador pode entender e usar para realizar uma tarefa ou resolver um problema. 55 | 56 | Para que possamos escrever programas de qualidade e eficientes, é importante que conheçamos conceitos como: 57 | 58 | - Representação de conhecimento através de **Estruturas de Dados** 59 | - **Iteração** e **Recursão** como metáforas computacionais 60 | - **Abstração** de procedimentos e tipos de dados 61 | - **Organizar** e **Modularizar** sistemas utilizando objetos [classes](https://docs.python.org/3/tutorial/classes.html) e métodos 62 | - Diferentes classes de **algoritmos** ([searching](https://en.wikipedia.org/wiki/Search_algorithm), [sorting](https://en.wikipedia.org/wiki/Sorting_algorithm)) 63 | - **Complexidade** de algoritmos 64 | 65 | ## O que um Computador faz? 66 | 67 | Fundamentalmente ele é capaz de realizar cálculos (bilhões de cálculos por segundo) e também é capaz de lembrar resultados (centenas de gigabytes de storage). 68 | 69 | Quais tipos de cálculos ele pode executar? Um computador pode executar cálculos que são **pré-construídos** na linguagem e também aqueles que você define como programador. É importante lembrarmos que **Computadores** apenas sabem o que dizemos a eles, então é importante que forneçamos as instruções corretas para que possamos obter os resultados desejados. 70 | 71 | ## Tipos de Conhecimento 72 | 73 | Em [epistemologia](https://en.wikipedia.org/wiki/Epistemology), conhecimento descritivo, também conhecido como **Conhecimento Declarativo** é uma afirmação de um fato, em outras palavras, é o conhecimento que pode ser expresso em uma frase declarativa ou uma proposição indicativa (por exemplo: "Está chovendo lá fora"). 74 | 75 | Conhecimento processual, também conhecido como **Conhecimento Imperativo** é uma **receita** ou "tutorial", é o conhecimento exercido no desempenho de alguma tarefa. 76 | 77 | Podemos considerar um algoritmo, por exemplo: 78 | 79 | - Ler um número 80 | - Verificar se ele é maior que **0** 81 | - Se o número for maior que **0**, retornar que ele é **positivo** 82 | - Verificar se ele é menor que **0** 83 | - Se o número for menor que **0**, retornar que ele é **negativo** 84 | - Se nenhum dos casos acima for atendido, então ele é **0**. 85 | - Fim do algoritmo 86 | 87 | O fluxograma a seguir nos apresenta esta ideia visualmente: 88 | 89 | ![img](/Imagens/Algorithm.png) 90 | 91 | ## Calculando a Raiz Quadrada 92 | 93 | Na matemática, a raiz quadrada de um número **x** é um número **y** tal que `y² = x`. Em outras palavras, um número **y** cujo quadrado (o resultado da multiplicação do número por ele mesmo, ou `y*y`) é x. 94 | 95 | Vamos então definir que: 96 | 97 | - A raiz quadrada de um número **x** é **y** de forma que `y*y = x` 98 | 99 | - A receita para deduzir a raiz quadrada de um número **x** é: 100 | 101 | 1. Começar com uma suposição **g** 102 | 2. Se `g*g` é próximo o suficiente de **x**, pare e diga que **g** é a resposta 103 | 3. Caso contrário faça uma nova suposição calculando a média de **g** e **x/g** 104 | 4. Utilizando a nova suposição, repita o processo até se aproximar 105 | 106 | Neste exemplo, queremos obter a raiz quadrada do número **16**, que é **4**, veja que através do nosso algoritmo somos capazes de alcançar um número muito próximo de **4**. 107 | 108 | | `g` | `g*g` | `x/g` |`(g+x/g)/2`| 109 | |--------|---------|-------|-----------| 110 | | 3 | 9 | 16/3 | 4.17 | 111 | | 4.17 | 17.36 | 3.837 | 4.0035 | 112 | | **4.0035** | 16.0277 | 3.997 | 4.000002 | 113 | 114 | ## O que é uma Receita? 115 | 116 | Uma receita é um conjunto de instruções que descreve como preparar ou fazer algo, em outras palavras: 117 | 118 | - Uma sequência de simples passos 119 | - Processo de **Controle de Fluxo** que específica quando cada passo é executado 120 | - Um meio de determinar quando parar 121 | 122 | 1+5+7 = UM **ALGORITMO**! 123 | 124 | ## Computadores são Máquinas 125 | 126 | Um computador é uma máquina que pode ser instruída a realizar sequências de operações aritméticas ou lógicas automaticamente por meio de programação de computador. Os computadores modernos têm a capacidade de seguir conjuntos generalizados de operações, chamados programas. 127 | 128 | Existem diversos tipos de computadores, por exemplo: 129 | 130 | - Computador de **Programa Fixo**: Calculadora 131 | - Computador de **Programa Armazenado**: A máquina armazena e executa instruções 132 | 133 | ## Arquitetura Básica do Computador 134 | 135 | ![img](/Imagens/ComputerArchitecture.png) 136 | 137 | ## Computador de Programa Armazenado 138 | 139 | Um computador de programa armazenado é aquele que armazena instruções do programa em uma memória acessível eletronicamente ou opticamente. Isso contrasta com os sistemas que armazenavam as instruções do programa com plugboards ou mecanismos semelhantes. 140 | 141 | A Sequência de Instruções são então armazenadas dentro do computador. Construídos através de um conjunto pré-definido de instruções primitivas: 142 | 143 | 1. Aritmética e Lógica 144 | 2. Testes simples 145 | 3. Movendo dados 146 | 147 | Um Programa Especial (Interpretador) **executa cada instrução em ordem** e pode ser usado em testes para alterar o fluxo de controle. 148 | 149 | ## Primitivos Básicos 150 | 151 | Na computação, primitivos de linguagem são os elementos mais simples disponíveis em uma linguagem de programação. Um primitivo é a menor 'unidade de processamento' disponível para um programador de uma determinada máquina, ou pode ser um elemento atômico de uma expressão em uma linguagem. 152 | 153 | Um primitivo é um tipo de dados fundamental que não pode ser dividido em um tipo de dados mais simples. Por exemplo, um **inteiro** é um tipo de dados primitivo, enquanto que um **array**, que pode armazenar vários tipos de dados, não é. 154 | 155 | - Turing mostrou que podemos **computar tudo** utilizando apenas 6 primitivos 156 | - Linguagens de programação modernas possuem conjuntos de primitivos mais convenientes 157 | - É possível abstrair métodos para criar **novos primitivos** 158 | - Qualquer cálculo computável em uma linguagem é computável em qualquer outra linguagem de programação 159 | 160 | ## Criando Receitas 161 | 162 | Uma linguagem de programação fornece um conjunto de **operações** primitivas. **Expressões** são complexas combinações legais de primitivos em uma linguagem de programação. Expressões e Computações possuem **valores** e **sentido** em uma linguagem de programação 163 | 164 | ## Aspectos das Linguagens 165 | 166 | As linguagens possuem **Constructos Primitivos**, em português, por exemplo, temos as **palavras**, nas linguagens de programação temos os **números**, **strings** e **operadores simples**. 167 | 168 | Elas também possuem uma **Sintaxe**, por exemplo, em português podemos construir a seguinte frase "gato caxorro garoto", que é inválida sintaticamente, também podemos construir "mãe abraça o garoto", que é válida sintaticamente. Nas linguagens de programação existem as mesmas situações, por exemplo `"oi"5` é uma definição inválida em termos de sintaxe, porém `3*5` é válido, pois define a multiplicação de dois números de maneira correta, veja que aqui estamos usando um exemplo geral e não estamos falando de uma linguagem específica. 169 | 170 | Além disso, as linguagens também possuem a **Semântica Estática**, no qual strings sintaticamente válidas possuem sentido, no português, por exemplo, podemos definir "Eu árvore fome", embora seja uma expressão valida sintaticamente, ela tem erro de semântica, pois não há sentido no que se quer dizer. Nas linguagens de programação temos o mesmo problema, se definirmos por exemplo `3+"oi"` teremos um erro semântico, pois esta soma não faz sentido. 171 | 172 | A **Semântica** é então o sentido associado com uma string de símbolos sintaticamente correta com nenhum erro de semântica. 173 | 174 | ## Quando Ocorrem Erros 175 | 176 | Erros são os problemas ou falhas no programa que fazem com que nosso programa se comporte de forma inesperada, existem diversos tipos de erros, podemos citar por exemplo: 177 | 178 | - Erros de Sintáxe: Comuns e fáceis de perceber 179 | - Erros de Semântica Estática: Algumas linguagens checam por eles antes de rodar o programa, eles podem causar comportamento imprevisível 180 | - Nenhum erro de Semântica, porém um sentido diferente do que o programador desejava expressar ocorre: Programa crasha, para de rodar, programa roda para sempre, programa dá uma resposta, porém diferente do esperado 181 | 182 | ## Programas em Python 183 | 184 | Um programa é uma sequência de definições e comandos, estas definições devem ser bem avaliadas. Também podemos considerar ele como comandos executados pelo Interpretador Python em uma shell, comandos (afirmações) instruem o interpretador a fazerem algo e podem ser digitados diretamente em uma shell ou guardados em um arquivo que é então lido na shell e avaliado. 185 | 186 | ## Objetos 187 | 188 | Python é uma linguagem de programação orientada a objetos. Quase tudo em Python é um objeto, com suas propriedades e métodos. 189 | 190 | ![img](/Imagens/Object.png) 191 | 192 | Devemos estar cientes da importância dos Objetos, pois programas manipulam **objetos de dados**. Objetos possuem um **tipo** que define os tipos de ações que os programas podem fazer com eles, por exemplo: 193 | 194 | - Gabriel é um humano, sendo assim ele pode caminhar, falar, etc. 195 | - Zeus é um cachorro, sendo assim ele pode latir, rosnar, etc. 196 | 197 | Objetos são normalmente divididos em duas categorias: 198 | 199 | - Escalares (não podem ser subdivididos) 200 | - Não-Escalares (possui uma estrutura interna que pode ser acessada) 201 | 202 | Agora que temos informações fundamentais básicas sobre princípios da computação e da linguagem **Python**, podemos iniciar a configuração de nosso Ambiente de Programação. 203 | -------------------------------------------------------------------------------- /Capitulos/02.Ambiente de Programação.md: -------------------------------------------------------------------------------- 1 | # Ambiente de Programação 2 | 3 | Obter **Python** é muito fácil, para isso precisamos acessar o site oficial e fazer o download: **[python.org](https://www.python.org/downloads/)**. Recomendamos que você faça o download da versão mais recente e siga as *instruções de instalação*. Vale lembrar que se você usa o sistema operacional **MacOS** ou **Linux**, existem grandes chances do **Python** já estar instalado. 4 | 5 | Caso queira confirmar se **Python** está instalado no seu sistema, abra sua **[interface de linha de comando](https://pt.wikipedia.org/wiki/Interface_de_linha_de_comandos)** e digite: 6 | 7 | ``` 8 | python --version 9 | ``` 10 | 11 | Como você pôde observar, será retornada a versão atual do Python em sua máquina. 12 | 13 | ## Iniciando 14 | 15 | Antes de começarmos a programar, é de extrema importância que tenhamos um editor de texto eficiente e leve, para isso existem muitas opções excelentes: 16 | 17 | - [Sublime Text](https://www.sublimetext.com/) 18 | - [Brackets](http://brackets.io/) 19 | - [Notepad++](https://notepad-plus-plus.org/) 20 | - [Gedit](https://wiki.gnome.org/Apps/Gedit) 21 | - [Visual Studio Code](https://code.visualstudio.com/) 22 | - [Vim](https://www.vim.org/) 23 | - [Light Table](http://lighttable.com/) 24 | - [GNU Emacs](https://www.gnu.org/software/emacs/) 25 | 26 | Caso você tenha preferências por [Ambientes de Desenvolvimento Integrado](https://pt.wikipedia.org/wiki/Ambiente_de_desenvolvimento_integrado) mais robustos e completos, você pode optar por: 27 | 28 | - [Thonny](https://thonny.org/) 29 | - [PyCharm](https://www.jetbrains.com/pycharm/download/) 30 | - [IPython](https://ipython.org/) 31 | - [PyDev](http://www.pydev.org/) 32 | - [Spyder](https://www.spyder-ide.org/) 33 | 34 | Se eventualmente você desejar executar seus scripts Python em um ambiente online usando o seu Web Browser, você pode usar uma das seguintes opções: 35 | 36 | - [Python Shell](https://www.python.org/shell/) 37 | - [Repl.it](https://repl.it/languages/python3) 38 | - [Python Online Compiler](https://www.programiz.com/python-programming/online-compiler/) 39 | - [Python Tryit Editor](https://www.w3schools.com/python/trypython.asp?filename=demo_compiler) 40 | - [Online Python Interpreter](https://www.onlinegdb.com/online_python_interpreter) 41 | 42 | Nesse guia iremos utilizar o **Sublime Text**, porém sinta-se livre para escolher o editor que mais lhe agrada. Faça o download, siga os passos da instalação e vamos começar a nossa aventura! 43 | 44 | Assumindo que você está com o **Python** instalado em sua máquina e já tem um editor de texto em mãos, inicie o editor de Texto (a partir daqui assumiremos o Sublime Text como exemplo) e vá até `File -> New File`. Nesse arquivo vamos digitar nosso primeiro programa, o tradicional *Hello World*: 45 | 46 | ```python 47 | print("Hello World") # Hello World 48 | ``` 49 | 50 | Salve o arquivo, `File -> Save` ou através do atalho `CTRL + S`, importante você lembrar que a **[extensão dos arquivos](https://pt.wikipedia.org/wiki/Extensão_de_nome_de_ficheiro)** Python termina com `.py`, nesse caso nosso arquivo será chamado de **`hello.py`**, em seguida vá até `Tools -> Build System -> Python`. Agora que o Sublime Text está configurado para interpretar todos os nossos *scripts*, para executarmos ele devemos ir até `Tools -> Build` ou simplesmente através do atalho `CTRL + B`. 51 | 52 | Feito! Você acabou de escrever o seu primeiro programa em Python, se tudo ocorreu como esperado, aparecerá no console do **Sublime Text** a mensagem **Hello World**! 53 | 54 | ## Python Interativo 55 | 56 | Vale ressaltar também, como antes já citado, que o Python é capaz de rodar na **[interface de linha de comando](https://pt.wikipedia.org/wiki/Interface_de_linha_de_comandos)**, abra a sua e faça o teste digitando: 57 | 58 | ```python 59 | python3 60 | ``` 61 | 62 | Aparecerão algumas informações, como a versão do Python, sua data e você verá **`>>>`**, esse é o **interpretador** do Python, agora é só digitarmos: 63 | 64 | ```python 65 | >>> print("Hello World") # Hello World 66 | ``` 67 | 68 | Para obter ajuda no **interpretador** nós podemos utilizar a função **help()**, que recebe como parâmetro um **objeto** que desejamos entender melhor, por exemplo: 69 | 70 | ```python 71 | >>> help(float) # Nos trará informações sobre a classe float 72 | >>> help(print) # Nos trará informações sobre a função print 73 | ``` 74 | 75 | ## Filosofia Python 76 | 77 | Para conhecer a Essência & Filosofia da Linguagem Python você pode digitar o seguinte comando: 78 | 79 | ```python 80 | >>> import this 81 | ``` 82 | 83 | Nos será retornado: 84 | 85 | ``` 86 | The Zen of Python, by Tim Peters 87 | 88 | Beautiful is better than ugly. 89 | Explicit is better than implicit. 90 | Simple is better than complex. 91 | Complex is better than complicated. 92 | Flat is better than nested. 93 | Sparse is better than dense. 94 | Readability counts. 95 | Special cases aren't special enough to break the rules. 96 | Although practicality beats purity. 97 | Errors should never pass silently. 98 | Unless explicitly silenced. 99 | In the face of ambiguity, refuse the temptation to guess. 100 | There should be one-- and preferably only one --obvious way to do it. 101 | Although that way may not be obvious at first unless you're Dutch. 102 | Now is better than never. 103 | Although never is often better than *right* now. 104 | If the implementation is hard to explain, it's a bad idea. 105 | If the implementation is easy to explain, it may be a good idea. 106 | Namespaces are one honking great idea -- let's do more of those! 107 | ``` 108 | 109 | O **[Zen of Python](https://en.wikipedia.org/wiki/Zen_of_Python)**, escrito por Tim Peters descreve a filosofia e os princípios que guiam boas práticas da linguagem Python. 110 | 111 | Existe um *easter egg* muito divertido no Python, conhecido como *antigravity*, que nos redireciona para um quadrinho que ilustra o potencial da linguagem. Para vermos ele, devemos simplesmente importar o seguinte comando: 112 | 113 | ```python 114 | import antigravity 115 | ``` 116 | 117 | Nos será apresentado: 118 | 119 | ![img](/Imagens/XkcdPython.png) 120 | 121 | Para sair do **interpretador** basta digitar o comando `exit()`, `quit()` ou `CTRL + D`. Agora que temos nosso ambiente de programação estabelecido, já estamos prontos para mergulhar em mares mais profundos e explorar as diversas capacidades que **Python** tem a nos oferecer, bem como todos os seus detalhes! 122 | -------------------------------------------------------------------------------- /Capitulos/03.Sintaxe.md: -------------------------------------------------------------------------------- 1 | # Sintaxe 2 | 3 | Python foi originalmente desenvolvido como uma linguagem de ensino, mas sua facilidade de uso e sintaxe limpa levaram-no a ser adotado por iniciantes e especialistas. 4 | 5 | A **sintaxe** da linguagem de programação Python é o conjunto de regras que define como um programa Python será escrito e interpretado (tanto pelo sistema de execução quanto por leitores humanos). 6 | 7 | ## Palavras-chave em **Python** 8 | 9 | As palavras-chave são as palavras reservadas pela linguagem **Python**, nós não podemos utilizar essas palavras para nomear nossas **[variáveis](https://pt.wikipedia.org/wiki/Variável_(programação))**, **[funções](http://www.inf.ufpr.br/cursos/ci067/Docs/NotasAula/notas-11_Fun_c_coes.html)** ou qualquer outro identificador, elas são usadas para definir a sintaxe e a estrutura da linguagem **Python**, vale lembrar que as palavras-chave são **case sensitive** e devem ser escritas dessa maneira. 10 | 11 | A seguir mostramos a lista de todas as palavras-chave: 12 | 13 | | **Nome** | **Descrição** | 14 | |----------|:-------------------------------------------------------------------------------------------------:| 15 | | and | operador lógico "e" | 16 | | as | capaz de criar um **[alias](https://pt.wikipedia.org/wiki/Alias_(comando))** | 17 | | assert | usado para **[debugging](https://www.inf.pucrs.br/flash/progbio/aulas/seq/build/progbio/WhatisDebugging.html)** | 18 | | async | usado para escrever aplicações **[asyncio](https://docs.python.org/3/library/asyncio-task.html)** | 19 | | await | usado para escrever aplicações **[asyncio](https://docs.python.org/3/library/asyncio-task.html)** | 20 | | break | para sair de um **[loop](https://pt.wikipedia.org/wiki/Loop_(programação))** | 21 | | class | define uma **[classe](https://pt.wikipedia.org/wiki/Classe_(programação))** | 22 | | continue | continua para a nova iteração do **[loop](https://pt.wikipedia.org/wiki/Loop_(programação))** | 23 | | def | define uma **[função](http://www.inf.ufpr.br/cursos/ci067/Docs/NotasAula/notas-11_Fun_c_coes.html)** | 24 | | del | deleta um **[objeto](https://pt.wikipedia.org/wiki/Objeto_(ciência_da_computação))** | 25 | | elif | usado em **[comandos condicionais](https://pt.wikipedia.org/wiki/Estrutura_de_seleção)**, como else e if | 26 | | else | usado em **[comandos condicionais](https://pt.wikipedia.org/wiki/Estrutura_de_seleção)** | 27 | | except | usado com **[exceções](https://pt.wikipedia.org/wiki/Tratamento_de_exceção)**, para tratar possíveis erros | 28 | | False | Valor **[booleano](https://pt.wikipedia.org/wiki/Booleano)**, resulta de operações de comparação | 29 | | finally | utilizado com **[exceções](https://pt.wikipedia.org/wiki/Tratamento_de_exceção)**, um bloco de código que executará independente de ter uma exceção ou não | 30 | | for | usado para criar um **[loop](https://pt.wikipedia.org/wiki/Loop_(programação))** | 31 | | from | para importar partes específicas de um **[módulo](https://pt.wikipedia.org/wiki/Módulo_de_um_programa)** | 32 | | global | declara uma **[variável global](https://pt.wikipedia.org/wiki/Variável_global)** | 33 | | if | usado para **[comandos condicionais](https://pt.wikipedia.org/wiki/Estrutura_de_seleção)** | 34 | | import | usado para importar **[módulos](https://pt.wikipedia.org/wiki/Módulo_de_um_programa)** | 35 | | in | capaz de checar se um valor está presente em uma lista, tupla, etc | 36 | | is | testa se duas **[variáveis](https://pt.wikipedia.org/wiki/Variável_(programação))** são iguais | 37 | | lambda | cria uma **[função anônima](https://github.com/the-akira/Python-Iluminado/blob/master/17.Lambda.md)** | 38 | | None | representa um valor **[null](https://pt.wikipedia.org/wiki/Null_(programação))** | 39 | | nonlocal | declara uma **[variável](https://pt.wikipedia.org/wiki/Variável_(programação))** não-local | 40 | | not | **[operador lógico](https://pt.wikipedia.org/wiki/Operador_lógico)** de negação | 41 | | or | **[operador lógico](https://pt.wikipedia.org/wiki/Operador_lógico)** "ou" | 42 | | pass | comando null, um comando que não faz nada | 43 | | raise | dispara um **[exceção](https://pt.wikipedia.org/wiki/Tratamento_de_exceção)** | 44 | | return | para sair de uma **[função](http://www.inf.ufpr.br/cursos/ci067/Docs/NotasAula/notas-11_Fun_c_coes.html)** e retornar um valor | 45 | | True | Valor **[booleano](https://pt.wikipedia.org/wiki/Booleano)**, resulta de operações de comparação | 46 | | try | Comando de try, usado em conjunto com except | 47 | | while | Cria um **[loop](https://pt.wikipedia.org/wiki/Loop_(programação))** while | 48 | | with | usado para simplificar a lida com **[exceções](https://pt.wikipedia.org/wiki/Tratamento_de_exceção)** | 49 | | yield | finaliza uma **[função](http://www.inf.ufpr.br/cursos/ci067/Docs/NotasAula/notas-11_Fun_c_coes.html)**, retorna um **[gerador](https://pt.wikipedia.org/wiki/Gerador_(ciência_da_computação))** | 50 | 51 | Obtendo as palavras-chave através do **interpretador** Python: 52 | 53 | ```python 54 | >>> import keyword 55 | >>> print(keyword.kwlist) 56 | ``` 57 | 58 | Veja que nos é retornado uma **lista** (Estrutura de Dados que veremos com mais detalhes em breve) com todas as palavras-chave da linguagem Python. 59 | 60 | ``` 61 | ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield'] 62 | ``` 63 | 64 | *Bastante informação, não?* Talvez muito do que foi mostrado não faça sentido para você, porém fique tranquilo que veremos todas as palavras-chave com detalhe, até que você fique acostumado com elas! 65 | 66 | ## Identificadores 67 | 68 | Os identificadores são nomes dados às entidades como **[variáveis](https://pt.wikipedia.org/wiki/Variável_(programação))**, **[funções](http://www.inf.ufpr.br/cursos/ci067/Docs/NotasAula/notas-11_Fun_c_coes.html)**, **[classes](https://pt.wikipedia.org/wiki/Classe_(programação))**, etc, eles nos ajudam a diferenciar uma entidade da outra. 69 | 70 | ## Regras 71 | 72 | Identificadores podem ser escritos com uma combinação de **letras em lowercase (a até z)** ou **uppercase (A até Z)** ou **dígitos (0 até 9)** ou um **underline (_)**. Nomes como **minhaClasse**, **variavel_1** e **minha_variavel** são exemplos válidos de identificadores. 73 | 74 | Variáveis são **case sensitive** (idade, Idade e IDADE são três variáveis diferentes) 75 | Identificadores **não podem começar com dígitos:** 13variavel é inválido, porém variavel13 é aceito! 76 | 77 | Palavras-chave jamais podem ser usadas como identificadores! 78 | 79 | ## Indentação 80 | 81 | Enquanto em outras linguagens de programação a **[indentação](https://pt.wikipedia.org/wiki/Indentação)** é usada apenas para tornar o código mais legível, em **Python** ela é importantíssima, **Python** usa a indentação para indicar blocos de código, por exemplo: 82 | 83 | ```python 84 | vida = 100 85 | 86 | if vida > 0: 87 | print("Você está vivo") 88 | ``` 89 | 90 | Caso você não utilize a indentação correta, Python irá disparar um erro. 91 | 92 | Algumas regras de indentação: 93 | 94 | - Use dois pontos `:` para iniciar um bloco e pressione `[Enter]`. 95 | - Todas as linhas em um bloco devem usar a mesma indentação, seja com espaços ou `[tab]`. 96 | - Python recomenda quatro espaços como indentação para tornar o código mais legível. Não misture espaço e `[tab]` no mesmo bloco. 97 | 98 | Você pode configurar seu editor de texto para a tecla `[tab]` indentar uma quantidade **x** de espaço. 99 | 100 | ## Comentários 101 | 102 | **Python** tem a capacidade de comentários para que seja mais fácil de lermos os códigos de outros programadores, melhora muito a comunicação! 103 | 104 | Comentários começam com `#`, por exemplo: 105 | 106 | ```python 107 | # Este é um comentário 108 | print("Códigos comentados são muito mais fáceis de serem compreendidos") 109 | ``` 110 | 111 | **Python** também suporta [docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html), que são comentários que podem extender até mais linhas, veja: 112 | 113 | ```python 114 | """ 115 | Este é um comentário 116 | que abrange várias 117 | linhas do programa 118 | """ 119 | print("Procure sempre comentar o seu código") 120 | ``` 121 | 122 | ## Statements 123 | 124 | As instruções em Python geralmente terminam com uma nova linha. Python, entretanto, permite o uso do caractere de continuação de linha (`\`) para indicar que a linha deve continuar. Por exemplo: 125 | 126 | ```python 127 | total = 3 + \ 128 | 5 + \ 129 | 7 130 | print(total) # 15 131 | ``` 132 | 133 | O ponto e vírgula (`;`) permite várias instruções em uma única linha, visto que nenhuma instrução inicia um novo bloco de código. Aqui está uma amostra que ilustra esta ideia: 134 | 135 | ```python 136 | x, y = 9, 3; z = x * y; print(f'{x} x {y} = {z}') 137 | # 9 x 3 = 27 138 | ``` 139 | 140 | Para saber mais detalhes específicos e técnicos sobre boas práticas de estilo de programação em Python, recomendamos que você visite e leia [PEP 8 -- Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) -------------------------------------------------------------------------------- /Capitulos/04.Tipos de Variáveis.md: -------------------------------------------------------------------------------- 1 | # Tipos de Variáveis 2 | 3 | **Variáveis** são um conceito de extrema importância nas linguagens de programação. 4 | 5 | Variáveis são usadas para armazenar informações a serem referenciadas e manipuladas em um programa de computador. Elas também fornecem uma maneira de rotular dados com um nome descritivo, para que nossos programas possam ser entendidos mais claramente pelo leitor e por nós mesmos. É útil pensar nas variáveis como contêineres que contêm informações. Seu único objetivo é rotular e armazenar dados na memória. Esses dados podem ser usados em todo o seu programa. 6 | 7 | ## Atribuindo Valores às Variáveis 8 | 9 | As variáveis em **Python** não precisam declaração explícita para reservar espaço em memória, a declaração ocorre automaticamente quando você atribui um valor à variável. O sinal de **(=)** é usado para fazer a atribuição de valores. 10 | 11 | ![img](/Imagens/Variables.png) 12 | 13 | Por exemplo: 14 | 15 | ```python 16 | nome = 'Gabriel' # Uma string 17 | idade = 33 # Um valor inteiro 18 | altura = 1.75 # Um valor em ponto flutuante 19 | 20 | print(nome) # Gabriel 21 | print(idade) # 33 22 | print(altura) # 1.71 23 | ``` 24 | 25 | Também é possível atribuir múltiplos valores para múltiplas variáveis: 26 | 27 | ```python 28 | a, b, c = 5, 3.1, "Hello" 29 | 30 | print(a) # 5 31 | print(b) # 3.1 32 | print(c) # Hello 33 | ``` 34 | 35 | Um detalhe importante que não podemos esquecer é que devemos dar nomes que façam sentido as nossas variáveis, existem também notações que são usadas por programadores, por exemplo **camelCase**, onde a variável começa com uma letra em lowercase, por exemplo: 36 | 37 | ```python 38 | meuNome = "Gabriel" 39 | minhaIdade = 33 40 | meuEndereco = "Avenida Castelo" 41 | ``` 42 | 43 | Letras capitalizadas podem ser usadas para declarar **constantes**, valores que não variam, exemplo: 44 | 45 | ```python 46 | PI = 3.14 47 | GRAVIDADE = 9.8 48 | ``` 49 | 50 | ## Tipos de Variáveis em Python 51 | 52 | Em muitas linguagens de programação, as variáveis são [statically typed](https://en.wikipedia.org/wiki/Type_system#Static_type_checking). Isso significa que uma variável é inicialmente declarada como tendo um tipo de dados específico e qualquer valor atribuído a ela durante sua vida útil deve sempre ter esse tipo. 53 | 54 | Variáveis em Python não estão sujeitas a esta restrição. No Python, uma variável pode ser atribuída a um valor de um tipo e, posteriormente, re-atribuída a um valor de um tipo diferente: 55 | 56 | ```python 57 | v = 100 58 | print(v) # 100 59 | 60 | v = 'agora sou uma string' 61 | print(v) # agora sou uma string 62 | ``` 63 | 64 | ## Referências a Objetos 65 | 66 | Python é uma linguagem [orientada a objetos](https://en.wikipedia.org/wiki/Object-oriented_programming). De fato, praticamente todos os itens de dados em um programa Python são objetos de um tipo ou classe específica. 67 | 68 | Consideramos agora o seguinte código 69 | 70 | ```python 71 | print(33) 72 | ``` 73 | 74 | Ao apresentarmos o interpretador o seguinte [statement](https://en.wikipedia.org/wiki/Statement_(computer_science)) `print(33)`, ele executará as seguintes ações: 75 | 76 | - Criará um objeto inteiro 77 | - Dará a ele o valor 33 78 | - Apresentará ele no console 79 | 80 | Podemos usar a função construída **type()** para confirmarmos 81 | 82 | ```python 83 | type(33) # 84 | ``` 85 | 86 | Uma variável Python é um nome simbólico que é uma referência ou ponteiro para um objeto. Uma vez que um objeto é atribuído a uma variável, você pode se referir ao objeto com esse nome. Mas os dados em si ainda estão contidos no objeto. 87 | 88 | Consideramos o seguinte exemplo: 89 | 90 | ```python 91 | x = 33 92 | ``` 93 | 94 | Esta atribuição cria um **objeto integer** com o valor `33` e atribui a variável `x` para apontar para este objeto 95 | 96 | ![img](/Imagens/x.png) 97 | 98 | Agora vamos considerar o seguinte statement 99 | 100 | ```python 101 | y = x 102 | ``` 103 | 104 | Ao executarmos ele, Python não criará outro objeto, ele simplesmente criará um nome simbólico ou referência `y`, no qual aponta para o mesmo objeto que aponta para `x`. 105 | 106 | ![img](/Imagens/xy.png) 107 | 108 | Imagine agora que façamos essa alteração 109 | 110 | ```python 111 | y = 13 112 | ``` 113 | 114 | Dessa vez, Python criará um novo **objeto integer** com o valor `13`, e `y` se tornará uma referência para ele. 115 | 116 | ![img](/Imagens/x-y.png) 117 | 118 | Agora imagine que venhamos a executar o seguinte statement 119 | 120 | ```python 121 | x = 'e' 122 | ``` 123 | 124 | Python criará um **objeto string** com o valor `'e'` e fará de `x` uma referência a ele. 125 | 126 | ![img](/Imagens/x_y.png) 127 | 128 | Como podemos observar, não há mais referência ao objeto integer `33`. Quando o número de referências a um objeto cai para zero, ele não está mais acessível. Nesse ponto, sua vida acabou. O Python eventualmente perceberá que é inacessível e recuperará a memória alocada para que possa ser usada para outra coisa. Esse processo é chamado de [garbage collection](https://stackify.com/python-garbage-collection/). 129 | 130 | ## Identidade dos Objetos 131 | 132 | No Python, todo objeto criado recebe um número que o identifica exclusivamente. É garantido que dois objetos não terão o mesmo identificador durante qualquer período em que sua vida útil se sobreponha. 133 | 134 | A função construída **id()** retorna o identificador inteiro de um objeto. Utilizando a função **id()** podemos verificar se duas variáveis realmente apontam para o mesmo objeto: 135 | 136 | ```python 137 | k = 100 138 | t = k 139 | id(k) # 94320283578208 140 | id(t) # 94320283578208 141 | ``` 142 | 143 | Perceba que ambas possuem o mesmo número identificador, uma vez que elas apontam para o mesmo objeto. Caso façamos uma alteração em `t`, ele passará a apontar para outro objeto, ganhando assim um **id** diferente. 144 | 145 | ```python 146 | t = 50 147 | id(t) # 94320283576608 148 | ``` 149 | 150 | ## Deletando uma Variável 151 | 152 | O comando **del** nos permite deletar variáveis. 153 | 154 | No exemplo abaixo, declaramos uma variável chamada de **numero** e atribuímos um valor ponto flutuante a ela, em seguida, utilizamos o comando **del** para deletá-la. 155 | 156 | ```python 157 | numero = 12.5 158 | del numero 159 | ``` 160 | 161 | Se eventualmente tentarmos imprimí-la no console com o comando `print()` nos será retornado um erro: `NameError: name 'numero' is not defined`, nos indicando que ela não está mais definida. 162 | 163 | ## Nomes de Variáveis 164 | 165 | Uma variável pode ter um nome curto (como por exemplo **x** ou **y**) e ou nome mais descritivo (**nome**, **idade**, **resultado**). 166 | 167 | Veja as regras para as variáveis 168 | 169 | - Uma variável deve iniciar com uma letra ou um caracter *underscore* (**_**) 170 | - Uma variável não pode começar com um número 171 | - O nome de uma variável pode conter apenas caracteres alpha-numéricos e *underscores* (A-z, 0-9, e _) 172 | - Nomes de variáveis são *case sensitive* (idade, Idade e IDADE são três variáveis diferentes) 173 | 174 | ## Variáveis Globais 175 | 176 | Em Python, uma variável declarada fora da função ou no escopo global é conhecida como variável global. Isso significa que uma variável global pode ser acessada dentro ou fora da função. 177 | 178 | Vejamos um exemplo de como uma variável global é criada em Python: 179 | 180 | ```python 181 | x = 'global' 182 | 183 | def imprimir(): 184 | print(f'{x} na função imprimir()') 185 | 186 | imprimir() 187 | print(f'{x} fora da função') 188 | ``` 189 | 190 | No código acima, criamos **x** como uma variável global e definimos `imprimir()` para imprimir a variável global x. Finalmente, chamamos o `imprimir()` que imprimirá o valor de x, além disso, usamos o comando `print()` que também irá imprimir x. 191 | 192 | E se desejarmos alterar o valor de x dentro de uma função? 193 | 194 | ```python 195 | x = 3 196 | 197 | def add(): 198 | x = x + 5 199 | print(x) 200 | 201 | add() 202 | ``` 203 | 204 | Nos será retornado o seguinte erro: 205 | 206 | ``` 207 | UnboundLocalError: local variable 'x' referenced before assignment 208 | ``` 209 | 210 | O *output* apresenta um erro porque o Python trata **x** como uma variável local e **x** também não está definido dentro da função `add()`. 211 | 212 | Para solucionar este problema, podemos criar uma variável global dentro de uma função, para isso usamos a palavra-chave **global**: 213 | 214 | ```python 215 | x = 3 216 | 217 | def add(): 218 | global x 219 | x = x + 5 220 | print(x) 221 | 222 | add() # 8 223 | ``` 224 | 225 | Observe que dessa vez a função tem acesso à variável x, tornando assim possível adicionarmos o número 5. 226 | 227 | Agora que você já consegue armazenar valores em variáveis, vamos ver os tipos de dados que existem em **Python** e suas aplicações! -------------------------------------------------------------------------------- /Capitulos/05.Números.md: -------------------------------------------------------------------------------- 1 | # Números 2 | 3 | ![img](/Imagens/Numbers.png) 4 | 5 | Em **Python** existem **três** tipos numéricos, são eles: 6 | 7 | - *int* 8 | - *float* 9 | - *complex* 10 | 11 | É importante lembrarmos que tudo em **Python** é um **objeto**, sendo assim, tipos de dados são **classes** e variáveis são instâncias (objetos) dessas classes, não se preocupe que veremos esses aspectos com mais detalhe ao longo do guia. 12 | 13 | Variáveis do tipo numérico são criadas quando atribuimos valores a elas: 14 | 15 | ```python 16 | a = 27 # int 17 | b = 22.2 # float 18 | c = 3j # complex 19 | ``` 20 | 21 | Para verificarmos qual classe a variável pertence, podemos utilizar a função **type()**: 22 | 23 | ```python 24 | print(type(a)) # 25 | print(type(b)) # 26 | print(type(c)) # 27 | ``` 28 | 29 | ## Int 30 | 31 | Inteiros são números **positivos**, **negativos**, que não apresentam casas decimais, seu tamanho é limitado apenas pela capacidade de memória disponível: 32 | 33 | ```python 34 | a = 3 35 | b = 342907249723902 36 | c = -100 37 | 38 | print(type(a)) # 39 | print(type(b)) # 40 | print(type(c)) # 41 | ``` 42 | 43 | ## Float 44 | 45 | Floats ou **"números de ponto flutuante"** são números positivos ou negativos que podem conter uma ou mais casas decimais: 46 | 47 | ```python 48 | a = 23.3 49 | b = 2.0 50 | c = -17.78 51 | 52 | print(type(a)) # 53 | print(type(b)) # 54 | print(type(c)) # 55 | ``` 56 | 57 | Podemos acrescentar o caracter **e** ou **E** seguido por um número inteiro positivo ou negativo para especificar a [notação científica](https://en.wikipedia.org/wiki/Scientific_notation). 58 | 59 | ```python 60 | e = 35e4 61 | print(type(e)) # 62 | print(e) # 350000.0 63 | 64 | E = 3.8e-2 65 | print(type(E)) # 66 | print(E) # 0.038 67 | ``` 68 | 69 | O valor máximo que um **float** pode ter é aproximadamente `1.8×10^308`. Qualquer número maior que este é indicado pelo valor **inf** (infinity). 70 | 71 | ```python 72 | print(1.79e308) # 1.79e+308 73 | print(1.8e308) # inf 74 | ``` 75 | 76 | Entretanto, o valor mínimo que um **float** pode ter é aproximadamente `5.0×10^-324`. Qualquer número menor que este é considerado **0** (zero). 77 | 78 | ```python 79 | print(5e-324) # 5e-324 80 | print(5e-325) # 0.0 81 | ``` 82 | 83 | ## Complex 84 | 85 | Números complexos são escritos com `j` representando a parte imaginária. Eles podem ser escritos `complex(3,4)` ou `3 + 4j`. Um número complexo Python `c` é armazenado internamente usando coordenadas Cartesianas ou Retangulares. 86 | 87 | Vejamos alguns exemplos: 88 | 89 | ```python 90 | a = 2+4j 91 | b = -3j 92 | c = complex(3,4) 93 | 94 | print(type(a)) # 95 | print(type(b)) # 96 | print(type(c)) # 97 | ``` 98 | 99 | Obtendo as partes **Real** e **Imaginária** de um número complexo: 100 | 101 | ```python 102 | print(c.real) # 3.0 103 | print(c.imag) # 4.0 104 | ``` 105 | 106 | ### Operações 107 | 108 | Realizando a operação de **adição** com números complexos: 109 | 110 | ```python 111 | x = complex(4,3) 112 | y = complex(-1,4) 113 | z = complex(2,1) 114 | 115 | print(x + y) # (3+7j) 116 | ``` 117 | 118 | Acrescentando um escalar adicionará à **parte real**: 119 | 120 | ```python 121 | print(x + 1) # (5+3j) 122 | ``` 123 | 124 | Também podemos realizar a operação de **multiplicação** com números complexos: 125 | 126 | ```python 127 | print(x * y) # (-16+13j) 128 | ``` 129 | 130 | Multiplicação por um Escalar: 131 | 132 | ```python 133 | print(x * 2) # (8+6j) 134 | ``` 135 | 136 | ### Extensão 137 | 138 | A função `abs(z)` retorna a extensão do número complexo `z`, em outras palavras, representa o cálculo da seguinte fórmula: 139 | 140 | ![img](/Imagens/abs.png) 141 | 142 | ```python 143 | print(abs(z)) # 2.23606797749979 144 | ``` 145 | 146 | Também podemos realizar este cálculo com o auxílio da função **sqrt()** da biblioteca math. 147 | 148 | ```python 149 | from math import sqrt 150 | 151 | sqrt(z.real**2 + z.imag**2) # 2.23606797749979 152 | ``` 153 | 154 | ### Ângulo 155 | 156 | A função `phase()` retorna o ângulo `x` em radianos, porém, para usá-la teremos que importar a biblioteca **[cmath](https://docs.python.org/3/library/cmath.html)** em nosso código. 157 | 158 | Esta biblioteca nos traz funções matemáticas específicas para números complexos. 159 | 160 | ```python 161 | import cmath 162 | 163 | print(cmath.phase(x)) # 0.6435011087932844 164 | print(phase(complex(-1.0, 0.0))) # 3.1415926535897931 165 | print(phase(complex(-1.0, -0.0))) # -3.1415926535897931 166 | ``` 167 | 168 | O resultado estará entre [-π, π] 169 | 170 | ### Constante π and e 171 | 172 | A biblioteca cmath também nos traz constantes matemáticas como **e** e **pi**: 173 | 174 | ```python 175 | print(cmath.pi) # 3.141592653589793 176 | print(cmath.e) # 2.718281828459045 177 | ``` 178 | 179 | ## Números Aleatórios 180 | 181 | Embora Python não tenha uma função **random()** para nos gerar um número aleatório, existe um módulo construído em Python chamado `random` que nos permite criar números aleatórios: 182 | 183 | ```python 184 | import random 185 | 186 | print(random.randrange(1,10)) 187 | ``` 188 | 189 | A função acima gera números entre 1 e 9. 190 | 191 | Caso queira saber mais detalhes sobre o módulo `random` você pode visitar sua **[Referência](https://www.w3schools.com/python/module_random.asp)**. 192 | 193 | ## Conversão de Números 194 | 195 | A linguagem Python nos permite converter entre tipos numéricos. 196 | 197 | ```python 198 | k = 3 199 | i = 7.7 200 | z = 4j 201 | 202 | print(type(k)) # 203 | print(type(i)) # 204 | print(type(z)) # 205 | ``` 206 | 207 | Convertendo de **int** para **float**: 208 | 209 | ```python 210 | print(float(k)) # 3.0 211 | ``` 212 | 213 | Convertendo de **float** para **int**: 214 | 215 | ```python 216 | print(int(i)) # 7 217 | ``` 218 | 219 | Convertendo de **int** para **complex**: 220 | 221 | ```python 222 | print(complex(k)) # (3+0j) 223 | ``` 224 | 225 | Importante lembrar que não podemos converter um número complexo para outro tipo numérico. 226 | 227 | ## Bases 228 | 229 | Normalmente escrevemos inteiros na base 10. No entanto, Python nos permite escrever inteiros nos formatos **Hexadecimal** (base 16), **Octal** (base 8) e **Binário** (base 2). 230 | 231 | Podemos fazer isso adicionando um dos seguintes prefixos ao número inteiro: 232 | 233 | | Prefixo | Interpretação | Base | 234 | |---|---|--- | 235 | | `0b` ou `0B` | Binário | 2 | 236 | | `0o` ou `0O` | Octal | 8 | 237 | | `0x` or `0X` | Hexadecimal | 16 | 238 | 239 | Para esclarecer o funcionamento, vejamos alguns exemplos: 240 | 241 | ```python 242 | print(0b01111111) # 127 243 | print(0o10) # 8 244 | print(0XFF) # 255 245 | ``` 246 | 247 | O método **bin()** converte e retorna a string binária equivalente de um determinado inteiro. 248 | 249 | ```python 250 | bin(255) # '0b11111111' 251 | ``` 252 | 253 | Se quisermos convertê-lo de volta para o valor inteiro, podemos usar a função **int()**, passando a base 2 como argumento: 254 | 255 | ```python 256 | int('0b11111111',2) # 255 257 | ``` 258 | 259 | O método **oct()** converte e retorna a string octal equivalente de um determinado inteiro. 260 | 261 | ```python 262 | oct(8) # '0o10' 263 | ``` 264 | 265 | Se quisermos convertê-lo de volta para o valor inteiro, podemos usar a função **int()**, passando a base 8 como argumento: 266 | 267 | ```python 268 | int('0o10',8) # 8 269 | ``` 270 | 271 | O método **hex()** converte e retorna a string hexadecimal equivalente de um determinado inteiro. 272 | 273 | ```python 274 | hex(255) # '0xff' 275 | ``` 276 | 277 | Se quisermos convertê-lo de volta para o valor inteiro, podemos usar a função **int()**, passando a base 16 como argumento: 278 | 279 | ```python 280 | int('0xff',16) # 255 281 | ``` 282 | 283 | Lembre sempre que números são elementos essenciais e fundamentais na programação e que vamos utilizar muito eles! -------------------------------------------------------------------------------- /Capitulos/07.Operadores.md: -------------------------------------------------------------------------------- 1 | # Operadores 2 | 3 | **Operadores** são **símbolos especiais** capazes de executar computação **aritmética** ou **lógica**. 4 | 5 | Os operadores são usados para realizar operações em variáveis e valores. 6 | 7 | Existem diversos tipos de operadores em **Python**: 8 | 9 | - Operadores Aritméticos 10 | - Operadores de Atribuição 11 | - Operadores de Comparação 12 | - Operadores Lógicos 13 | - Operadores de Identidade 14 | - Operadores de Membros 15 | - Operadores Bitwise 16 | 17 | Vejamos então como eles funcionam em mais detalhes. 18 | 19 | ## Operadores Aritméticos 20 | 21 | Operadores aritméticos são usados com valores numéricos para realizar operações matemáticas comuns: 22 | 23 | | Operador | Descrição | Exemplo | 24 | |----------|----------------------------------------------------------------------------|---------| 25 | | + | Adiciona dois operandos | 2+5 | 26 | | - | Subtrai o operando da direita pelo da esquerda | 7-2 | 27 | | * | Multiplica dois operandos | 3*3 | 28 | | / | Divide o operando da esquerda pelo da direita | 3/2 | 29 | | % | Módulo, resto da divisão do operando da esquerda pelo da direita | 10%3 | 30 | | // | Divisão arredondada, esta divisão retorna um número inteiro | 3//2 | 31 | | ** | Expoente, operando a esquerda elevado à potência do operando a direita | 2**32 | 32 | 33 | Por exemplo: 34 | 35 | ```python 36 | x = 10 37 | y = 6 38 | z = 6.0 39 | 40 | print("x + y = ", x+y) # Nos resulta 16 41 | print("x - y = ", x-y) # Nos resulta 4 42 | print("x * y = ", x*y) # Nos resulta 60 43 | print("x / y = ", x/y) # Nos resulta 1.6666666666666667 44 | print("x / z = ", x/z) # Nos resulta 1.6666666666666667 45 | print("x // y = ", x//y) # Nos resulta 1 46 | print("x ** y = ", x**y) # Nos resulta 1000000 47 | ``` 48 | 49 | Observe que definimos a variável **z** com o valor **6.0**, um número ponto flutuante, de forma que Python possa nos trazer um resultado ponto flutuante no momento de fazermos a divisão do valor de **x** por **z**. 50 | 51 | ## Operadores de Atribuição 52 | 53 | Operadores de atribuição são usados para atribuir valores a variáveis: 54 | 55 | | Operador | Exemplo 1 | Exemplo 2 | 56 | |----------|-----------|------------| 57 | | = | x = 3 | x = 3 | 58 | | += | x += 3 | x = x + 3 | 59 | | -= | x -= 3 | x = x - 3 | 60 | | *= | x *= 3 | x = x * 3 | 61 | | /= | x /= 3 | x = x / 3 | 62 | | %= | x %= 3 | x = x % 3 | 63 | | //= | x //= 3 | x = x // 3 | 64 | | **= | x **= 3 | x = x ** 3 | 65 | | &= | x &= 3 | x = x & 3 | 66 | | \|= | x \|= 3 | x = x \| 3 | 67 | | ^= | x ^= 3 | x = x ^ 3 | 68 | | >>= | x >>= 3 | x = x >> 3 | 69 | | <<= | x <<= 3 | x = x << 3 | 70 | 71 | Vejamos um simples exemplo: 72 | 73 | ```python 74 | a = 1 75 | a += 3 76 | 77 | print(a) # 4 78 | ``` 79 | 80 | ## Operadores de Comparação 81 | 82 | Operadores de comparação são usados para comparar valores. Retornarão **True** ou **False** de acordo com a condição. 83 | 84 | | Operador | Descrição | Exemplo | 85 | |----------|--------------------------------------------------------------------------------------|---------| 86 | | > | Maior que - True se o operando a esquerda for maior que o da direita | x > y | 87 | | < | Menor que - True se o operando a esquerda for menor que o da direita | x < y | 88 | | == | Igual - True se ambos os operandos forem iguais | x == y | 89 | | != | Não Igual - True se os operandos forem diferentes | x != y | 90 | | >= | Maior que ou Igual - True se o operando da esquerda for maior ou igual ao da direita | x >= y | 91 | | <= | Menor que ou Igual - True se o operando da esquerda for menor ou igual ao da direita | x <= y | 92 | 93 | Vejamos alguns exemplos de comparações: 94 | 95 | ```python 96 | x = 12 97 | y = 3 98 | 99 | print(x>y) # True 100 | print(x=y) # True 104 | print(x<=y) # False 105 | ``` 106 | 107 | ## Operadores Lógicos 108 | 109 | Operadores Lógicos são usados para combinar **comandos condicionais**. 110 | 111 | | Operador | Descrição | Exemplo | 112 | |----------|-------------------------------------------------------------------------|------------------| 113 | | and | Retorna True se ambos os comandos são verdadeiros | x < y and x < 10 | 114 | | or | Retorna True se um dos comandos é verdadeiro | x < y or x > 3 | 115 | | not | Reverte o resultado, retorna False se o resultado for True e vice-versa | not(x > 10) | 116 | 117 | Vamos considerar então alguns exemplos com operadores lógicos: 118 | 119 | ```python 120 | n1, n2, n3 = 3, 6, 7 121 | 122 | print(n1 < n2 and n1 < n3) # True 123 | print(n1 == n2 or n3 == n2) # False 124 | print(not True) # False 125 | ``` 126 | 127 | ## Operadores de Identidade 128 | 129 | Operadores de identidade são usados para comparar os objetos, não se são iguais, mas se eles forem realmente o mesmo objeto, com o mesmo local de memória. 130 | 131 | **is** e **is not** são operadores de identidade em **Python**, eles são usados para checar se dois valores (ou variáveis) estão localizados na mesma área de memória, *duas variáveis iguais não significam que são idênticas!* 132 | 133 | | Operador | Descrição | 134 | |----------|----------------------------------------------------------------------| 135 | | is | True se os operandos são idênticos (referem ao mesmo objeto) | 136 | | is not | True se os operandos não são idênticos (não referem ao mesmo objeto) | 137 | 138 | Exemplo com números: 139 | 140 | ```python 141 | x = 1 142 | y = 1 143 | 144 | print(x is y) # True 145 | print(x is not y) # False 146 | ``` 147 | 148 | Exemplo com strings: 149 | 150 | ```python 151 | a = "cachorro" 152 | b = "cachorro" 153 | 154 | print(a is b) # True 155 | print(a is not b) # False 156 | ``` 157 | 158 | Exemplo com listas: 159 | 160 | ```python 161 | z = [1,2,3] 162 | k = [1,2,3] 163 | 164 | print(z is k) # False 165 | print(z is not k) # True 166 | ``` 167 | 168 | Perceba aqui que **x** e **y** são inteiros do mesmo valor, então eles são iguais e idênticos, o mesmo vale 169 | para **a** e **b** (strings). Porém o mesmo não ocorre com **z** e **k**, que são iguais, porem não idênticos, isso porque o interpretador localiza eles separadamente em memória, mesmo eles sendo iguais. 170 | 171 | ## Operadores de Membros 172 | 173 | Operadores de membros são usados para testar se uma sequência é apresentada em um objeto. 174 | 175 | | Operador | Descrição | Exemplo | 176 | |----------|-----------------------------------------------------------------|-------------------| 177 | | in | Retorna True se o valor/variável é encontrado na sequência | "c" in "cachorro" | 178 | | not in | Retorna True se o valor/variável não está presenta na sequência | 1 not in [1,2,3] | 179 | 180 | Exemplo básico: 181 | 182 | ```python 183 | a = [1,2,3] 184 | b = "Guilherme" 185 | 186 | print(1 in a) # Retorna True, pois 1 se encontra na lista a 187 | print("o" in b) # Retorna False, pois o não se encontra na string b 188 | ``` 189 | 190 | ## Operadores Bitwise 191 | 192 | Os operadores Bitwise atuam nos operandos como se eles fossem strings ou dígitos binários, eles executam operações **bit** por **bit**, por isso levam o nome **Bitwise**. 193 | 194 | Considere o valor 2 que é representado por **10** em binário e 7 que é representado por **111**. 195 | 196 | Vamos utilizar a função **bin()** que nos retorna uma string binária: 197 | 198 | ```python 199 | x = 10 200 | y = 4 201 | 202 | print(bin(x)) # 0b1010 203 | print(bin(y)) # 0b100 204 | ``` 205 | 206 | Adaptando-os, temos **(x = 0000 1010)** em binário e **(y = 0000 0100)** em binário, vamos aos operadores: 207 | 208 | | Operador | Descrição | Exemplo | 209 | |----------|---------------------|-------------------------| 210 | | & | Bitwise AND | x & y = 0 (0000 0000) | 211 | | \| | Bitwise OR | x \| y = 14 (0000 1110) | 212 | | ~ | Bitwise NOT | ~x = -11 (1111 0101) | 213 | | ^ | Bitwise XOR | x ^ y = 14 (0000 1110) | 214 | | >> | Bitwise right shift | x >> 2 = 2 (0000 0010) | 215 | | << | Bitwise left shift | x << 2 = 40 (0010 1000) | 216 | 217 | ## Precedência de Operadores 218 | 219 | Vamos agora considerar a seguinte expressão: 220 | 221 | ```python 222 | print(3 + 4 * 5) # 23 223 | ``` 224 | 225 | Há ambigüidade nesta expressão. O Python deve realizar a adição `3 + 4` primeiro e depois multiplicar a soma por `5`? Ou a multiplicação de `4 * 5` deve ser realizada primeiro? 226 | 227 | Uma vez que nosso resultado é **23**, significa que Python optou por multiplicar primeiro e depois realizar a adição, este é o procedimento padrão algébrico, encontrado universalmente em todas as linguagens de programação. 228 | 229 | Todos os operadores suportados por Python têm precedência. Em uma expressão, todos os operadores de maior precedência são executados primeiro. Depois que esses resultados são obtidos, os operadores da próxima precedência mais alta são executados. Então continua-se, até que a expressão seja totalmente avaliada. Quaisquer operadores de igual precedência são executados da **esquerda** para a **direita**. 230 | 231 | A tabela a seguir apresenta a ordem de precedência dos operadores Python do menor ao maior: 232 | 233 | | | Operador | Descrição | 234 | |---|---|---| 235 | | menor precedência | or | Boolean OR | 236 | | | and | Boolean AND | 237 | | | not | Boolean NOT | 238 | | | ==, !=, <, <=, >, >=, is, is not | Comparações, Identidade | 239 | | | \| | Bitwise OR | 240 | | | ^ | Bitwise XOR | 241 | | | & | Bitwise AND | 242 | | | <<, >> | Bit Shifts | 243 | | | +, - | Adição, Subtração | 244 | | | *, /, //, % | Multiplicação, Divisão, Floor Division, Modulus | 245 | | | +x, -x, ~x | Unário Positivo, Unário Negativo, Bitwise Negation | 246 | | maior precedência | ** | Exponenciação | 247 | 248 | Os operadores na parte superior da tabela têm a precedência mais baixa e aqueles na parte inferior da tabela têm a mais alta. Quaisquer operadores na mesma linha da tabela têm precedência igual. 249 | 250 | A precedência do operador pode ser substituída usando parênteses. As expressões entre parênteses são sempre executadas primeiro, antes das expressões que não estão entre parênteses. Por exemplo: 251 | 252 | ```python 253 | print(3 + 3 * 5) # 18 254 | print((3 + 3) * 5) # 30 255 | ``` 256 | 257 | Lembre sempre que os operadores tem um papel fundamental na programação e que devemos entender o seu funcionamento de maneira plena, *faça experimentos e divirta-se com os cálculos*! -------------------------------------------------------------------------------- /Capitulos/09.Tuplas.md: -------------------------------------------------------------------------------- 1 | # Tuplas 2 | 3 | Tuplas são uma sequência de **objetos imutáveis**, em outras palavras, uma vez criadas, tuplas não podem ser modificadas, normalmente são usadas para guardar **dados protegidos**. 4 | 5 | As tuplas são escritas entre parênteses **()**. 6 | 7 | Uma tupla em Python é semelhante a uma lista. A diferença entre os dois é que não podemos alterar os elementos de uma tupla depois de atribuída, enquanto podemos alterar os elementos de uma lista. 8 | 9 | ### Criando uma Tupla 10 | 11 | Podemos definir uma tupla da seguinte maneira: 12 | 13 | ```python 14 | linguagens = ("Python","Ruby","Javascript","Perl","Haskell") 15 | print(linguagens) # ('Python', 'Ruby', 'Javascript', 'Perl', 'Haskell') 16 | ``` 17 | 18 | Com o método **type()** podemos confirmar que se trata de uma **'tuple'**: 19 | 20 | ```python 21 | type(linguagens) # 22 | ``` 23 | 24 | ### Acessando Itens de uma Tupla 25 | 26 | O acesso aos itens de uma tupla é idêntico ao de uma lista: 27 | 28 | ```python 29 | print(linguagens[0:2]) # ('Python', 'Ruby') 30 | print(linguagens[-1]) # Haskell 31 | print(linguagens[:-2]) # ('Python', 'Ruby', 'Javascript') 32 | print(linguagens[:]) # ('Python', 'Ruby', 'Javascript', 'Perl', 'Haskell') 33 | ``` 34 | 35 | ### Atualizando Tuplas 36 | 37 | Lembrando que as tuplas são imutáveis, portanto se tentarmos modificá-la, nos será retornado um erro do tipo **TypeError**: 38 | 39 | ```python 40 | linguagens[0] = "C++" 41 | # TypeError: 'tuple' object does not support item assignment 42 | ``` 43 | 44 | Como já mencionado, Tuplas são imutáveis, ou seja, não podemos alterar os seus elementos, porém podemos capturar porções de uma tupla e criar novas tuplas, por exemplo: 45 | 46 | ```python 47 | x = (1,2) 48 | y = (3,4) 49 | 50 | z = x + y 51 | print(z) # (1, 2, 3, 4) 52 | ``` 53 | 54 | ### Imprimindo Elementos de uma Tupla 55 | 56 | As tuplas são úteis para representar o que outras linguagens costumam chamar de registros, algumas informações relacionadas que pertencem entre si, como o registro de um **estudante**. Não há descrição do que significa cada um desses campos, mas podemos intuir. Uma tupla nos permite “agrupar” informações relacionadas e usá-las em uma única estrutura. 57 | 58 | ```python 59 | estudante = ('Miguel', 29, 1990, 'Brasil') 60 | ``` 61 | 62 | Agora podemos utilizar um **for loop** para imprimir todos os elementos da tupla **estudante**: 63 | 64 | ```python 65 | for e in estudante: # Percorre os valores da tupla estudante 66 | print(e) # Imprime os valores 67 | ``` 68 | 69 | Também podemos facilmente converter esta tupla em uma lista usando a técnica list comprehension: 70 | 71 | ```python 72 | print([e for e in estudante]) # ['Miguel', 29, 1990, 'Brasil'] 73 | ``` 74 | 75 | ### Checando por Valores em uma Tupla 76 | 77 | Assim como nas listas, também podemos checar se determinado item está presente em uma tupla: 78 | 79 | ```python 80 | print('Gabriel' in estudante) # False 81 | ``` 82 | 83 | ```python 84 | print(1990 in estudante) # True 85 | ``` 86 | 87 | Além disso, podemos checar também a absência de determinado elemento: 88 | 89 | ```python 90 | print('Japão' not in estudante) # True 91 | ``` 92 | 93 | ```python 94 | print('Brasil' not in estudante) # False 95 | ``` 96 | 97 | ### Verificando o Tamanho de uma Tupla 98 | 99 | Para obtermos o número de itens em uma tupla, podemos usar o método **len()**: 100 | 101 | ```python 102 | print(len(estudante)) # 4 103 | ``` 104 | 105 | ### Deletando a Tupla 106 | 107 | Embora seja impossível remover itens da tupla, é possível deletá-la por completo com o uso da palavra-chave **del**. Observe que se tentarmos imprimir ela, ocorrerá um erro do tipo **NameError**, uma vez que a tupla não existe mais. 108 | 109 | ```python 110 | del estudante 111 | print(estudante) 112 | # NameError: name 'estudante' is not defined 113 | ``` 114 | 115 | ### Construtor tuple() 116 | 117 | Somos capazes também de construir uma tupla com o uso do construtor **tuple()**: 118 | 119 | ```python 120 | numeros = tuple(x for x in range(1,20,3)) 121 | print(numeros) # (1, 4, 7, 10, 13, 16, 19) 122 | ``` 123 | 124 | ### Método count() 125 | 126 | O método **count()** nos retorna a quantidade de vezes que determinado valor ocorre em uma tupla 127 | 128 | ```python 129 | print(numeros.count(7)) # 1 130 | ``` 131 | 132 | ### Método index() 133 | 134 | O método **index()** nos permite buscar por um determinado elemento e nos retorna o índice dele: 135 | 136 | ```python 137 | numeros.index(4) # 1 138 | ``` 139 | 140 | ### Criando uma Função que Retorna uma Tupla 141 | 142 | Funções normalmente retornam apenas um **único valor**, porém ao tornarmos esse valor uma **Tupla**, nós podemos efetivamente agrupar a quantidade de valores que desejarmos e retorná-los juntos. Esta funcionalidade pode nos ser muito útil em casos que queiramos por exemplo encontrar a **média** e o **desvio padrão** ou talvez obter o ano, mês e dia. 143 | 144 | Vejamos um exemplo para ilustrar esta ideia, em que vamos definir uma função de nome **f** que irá calcular a **circunferência** e a **área** de um círculo de raio **r** (o raio será informado via argumento por nós): 145 | 146 | ```python 147 | import math 148 | 149 | def f(r): 150 | """ Retorna (circunferência, área) de um círculo de raio r """ 151 | c = 2 * math.pi * r 152 | a = math.pi * r * r 153 | return (c, a) 154 | 155 | print(f(5)) # (31.41592653589793, 78.53981633974483) 156 | print(f(8)) # (50.26548245743669, 201.06192982974676) 157 | ``` 158 | 159 | ### Named Tuples 160 | 161 | **Named Tuples** são objetos de fácil criação e leves. Instâncias de Named Tuples podem ser referenciadas utilizando variáveis. Elas podem serem utilizadas como uma espécie de estrutura para agruparmos dados. 162 | 163 | É muito comum representarmos um ponto como uma tupla (x, y). 164 | 165 | A fórmula da distância é uma expressão algébrica usada para determinar a distância entre dois pontos com as coordenadas (x1, y1) e (x2, y2). 166 | 167 | ![img](/Imagens/DistanceFormula.png) 168 | 169 | ```python 170 | from math import sqrt 171 | 172 | p1 = (2.0, 7.0) 173 | p2 = (2.5, 3.5) 174 | 175 | comprimento_linha = sqrt((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2) 176 | print(comprimento_linha) # 3.5355339059327378 177 | ``` 178 | 179 | Ao utilizarmos uma Named Tuple, nosso código se torna mais legível, porém para usá-la devemos importá-la da biblioteca [collections](https://docs.python.org/3/library/collections.html): 180 | 181 | ```python 182 | from collections import namedtuple 183 | 184 | Ponto = namedtuple('Point', 'x y') 185 | p1 = Ponto(1.5, 5.0) 186 | p2 = Ponto(4.5, 1.5) 187 | 188 | comprimento_linha = sqrt((p1.x-p2.x)**2 + (p1.y-p2.y)**2) 189 | print(comprimento_linha) # 4.6097722286464435 190 | ``` 191 | 192 | Podemos usar as Named Tuples para armazenar cores **RGB**: 193 | 194 | ```python 195 | Cor = namedtuple('Cor', ['red', 'green', 'blue']) 196 | 197 | cor = Cor(55,155,255) 198 | 199 | print(cor) # Cor(red=55, green=155, blue=255) 200 | print(cor.red) # 55 201 | ``` 202 | 203 | ### Tuplas vs Listas 204 | 205 | Por que devemos usar uma Tupla ao invés de uma Lista? 206 | 207 | - A execução do programa é mais rápida quando manipulamos uma tupla do que uma equivalente lista. 208 | - As vezes desejamos que os dados não sejam modificados, se determinados que valores em uma coleção devem ser constantes no programa, utilizar uma Tupla nos protege contra acidentes de modificação. 209 | 210 | #### Exemplos 211 | 212 | Exemplo de Lista: 213 | 214 | ```python 215 | numeros_primos = [2, 3, 5, 7, 11, 13, 17] 216 | ``` 217 | 218 | Mostrando o tamanho: 219 | 220 | ```python 221 | print(f'# Primos: {len(numeros_primos)}') 222 | ``` 223 | 224 | Iterando sob a sequência: 225 | 226 | ```python 227 | for p in numeros_primos: 228 | print(f'Primos: {p}') 229 | ``` 230 | 231 | Exemplo de Tupla: 232 | 233 | ```python 234 | quadrados_perfeitos = (1, 4, 9, 16, 25, 36) 235 | ``` 236 | 237 | Mostrando o tamanho: 238 | 239 | ```python 240 | print(f'# Quadrados Perfeitos: {len(quadrados_perfeitos)}') 241 | ``` 242 | 243 | Iterando sob a sequência: 244 | 245 | ```python 246 | for n in quadrados_perfeitos: 247 | print(f'Primos: {n}') 248 | ``` 249 | 250 | #### Métodos das Listas e Tuplas 251 | 252 | Podemos usar o método **dir()** para visualizarmos todos os atributos e métodos disponíveis nas listas e tuplas: 253 | 254 | ```python 255 | print('Métodos Lista') 256 | print(dir(numeros_primos)) 257 | print('Métodos Tupla') 258 | print(dir(quadrados_perfeitos)) 259 | ``` 260 | 261 | #### Obtendo o Tamanho em Bytes 262 | 263 | O método **getsizeof()** da biblioteca [sys](https://docs.python.org/3/library/sys.html) nos permite obter o tamanho que um objeto ocupa em bytes. Por exemplo: 264 | 265 | ```python 266 | import sys 267 | 268 | lista_ex = [1, 2, 3, 'x', 'y', 'z', True, 3.14159] 269 | tupla_ex = (1, 2, 3, 'x', 'y', 'z', True, 3.14159) 270 | 271 | print(f'Tamanho da lista = {sys.getsizeof(lista_ex)}') # Tamanho da lista = 136 272 | print(f'Tamanho da tupla = {sys.getsizeof(tupla_ex)}') # Tamanho da tupla = 120 273 | ``` 274 | 275 | Como podemos observar, a tupla ocupa menos espaço em memória que uma lista. 276 | 277 | #### Comparando o Tempo 278 | 279 | A biblioteca [timeit](https://docs.python.org/3/library/timeit.html) nos fornece uma maneira simples de cronometrar pequenos trechos de código Python, podemos usá-la para medir a eficiência de estruturas de dados como listas e tuplas: 280 | 281 | ```python 282 | import timeit 283 | 284 | lista_teste = timeit.timeit(stmt='[1,2,3,4,5]', number=1_000_000) 285 | tupla_teste = timeit.timeit(stmt='(1,2,3,4,5)', number=1_000_000) 286 | 287 | print(f'Tempo da lista: {lista_teste}') # Tempo da lista: 0.11356729100225493 288 | print(f'Tempo da tupla: {tupla_teste}') # Tempo da tupla: 0.058329956023953855 289 | ``` 290 | 291 | Como podemos ver, as **tuplas** são uma estrutura de dados **imutável** e muito **rápida** que pode nos auxiliar bastante em nossos cálculos. -------------------------------------------------------------------------------- /Capitulos/10.Dicionários.md: -------------------------------------------------------------------------------- 1 | # Dicionários 2 | 3 | ![img](/Imagens/Dictionary.png) 4 | 5 | Os **dicionários** são encontrados em outros linguagens de programação como "memórias associativas" ou "matrizes associativas". Ao contrário das seqüências, que são indexadas por um intervalo de números, os dicionários são indexados por **chaves**, que podem ser de qualquer tipo imutável. 6 | 7 | Eles são uma coleção **não-ordenada** de pares de **chave** & **valor**, são normalmente usados quando temos uma grande quantidade de dados. 8 | 9 | Dicionários são otimizados para buscarmos dados e para isso, precisamos saber sua **chave**. 10 | 11 | Dicionários são definidos entre chaves `{}` onde cada item é um par na forma de **chave:valor**, separados por `,`, sendo a chave e o valor podendo ser de qualquer tipo. 12 | 13 | **Chaves**: 14 | 15 | - Devem ser **únicas** 16 | - Tipo **imutável** (int, float, string, tuple, bool) 17 | - Na verdade precisa de um objeto que seja *hashable*, mas imagine como imutável uma vez que todos os tipos imutáveis são *hashable* 18 | - Tenha cuidado com o tipo *float* como chave 19 | - Nenhuma ordem para chaves ou valores 20 | 21 | **Valores**: 22 | 23 | - Qualquer tipo (**imutável** e **mutável**) 24 | - Pode ser **duplicado** 25 | - Valores de dicionários podem ser listas, até mesmo outros dicionários 26 | 27 | Para compreendermos melhor o funcionamento dos dicionários, vamos definir alguns exemplos: 28 | 29 | ```python 30 | album = {'nome':'A Night at the Opera','artista':'Blind Guardian','lançamento':2002} 31 | print(type(album)) # 32 | print(album) # {'nome': 'A Night at the Opera', 'artista': 'Blind Guardian', 'lançamento': 2002} 33 | print(album['nome']) # A Night at the Opera 34 | print(album['artista']) # Blind Guardian 35 | print(album['lançamento']) # 2002 36 | ``` 37 | 38 | Também podemos definir um dicionário dessa forma, o que torna ele mais legível: 39 | 40 | ```python 41 | elemento = { 42 | "nome":"Ouro", 43 | "símbolo":"Au", 44 | "número atômico":79 45 | } 46 | ``` 47 | 48 | ### Acessando e Manipulando Dados 49 | 50 | Para acessarmos os itens do dicionário, precisamos nos referir a sua chave, por exemplo: 51 | 52 | ```python 53 | print(elemento["nome"]) # Ouro 54 | ``` 55 | 56 | Podemos também utilizar o método **get()** para acessarmos: 57 | 58 | ```python 59 | print(elemento.get("nome")) # Ouro 60 | ``` 61 | 62 | É possível alterar os valores de um dicionário, podemos fazê-lo da seguinte maneira: 63 | 64 | ```python 65 | elemento["nome"] = "Prata" 66 | elemento["símbolo"] = "Ag" 67 | elemento["número atômico"] = 47 68 | print(elemento) # {'nome': 'Prata', 'símbolo': 'Ag', 'número atômico': 47} 69 | ``` 70 | 71 | ### Imprimindo os Valores de um Dicionário 72 | 73 | Podemos usar o **for loop** para imprimir os elementos de um dicionário. 74 | 75 | ```python 76 | personagem = { 77 | "nome" : "Gandalf", 78 | "classe" : "Wizard", 79 | "ordem" : "Istari" 80 | } 81 | 82 | for key in personagem: # Percorre os valores do dicionário 83 | print(personagem[key]) # Imprime os valores do dicionário 84 | ``` 85 | 86 | Também podemos usar o método **values()** da seguinte forma: 87 | 88 | ```python 89 | for p in personagem.values(): # Percorre os valores do dicionário 90 | print(p) # Imprime os valores do dicionário 91 | ``` 92 | 93 | Além disso é possível percorrer tanto as **chaves** como os **valores**, usando a função **items()**: 94 | 95 | ```python 96 | for chave,valor in personagem.items(): # Percorre as chaves e os valores 97 | print(f'{chave} : {valor}') # Imprime as chaves e os valores 98 | ``` 99 | 100 | Caso seja necessário verificar a presença de uma **chave** no dicionário, podemos fazer o teste com a palavra-chave **in**: 101 | 102 | ```python 103 | print('nome' in personagem) # True 104 | ``` 105 | 106 | Também podemos testar pela presença de um determinado **valor** no dicionário: 107 | 108 | ```python 109 | print("Gandalf" in personagem.values()) # True 110 | ``` 111 | 112 | Assim como nas listas e tuplas, também podemos aplicar o método **len()** nos dicionários: 113 | 114 | ```python 115 | print(len(personagem)) # 3 116 | ``` 117 | 118 | ### Adicionando Itens ao Dicionário 119 | 120 | Para adicionarmos um novo item em nosso dicionário usamos uma nova chave e atribuimos um valor a ela 121 | 122 | ```python 123 | personagem['altura'] = 1.85 124 | print(personagem) # {'nome': 'Gandalf', 'classe': 'Wizard', 'Ordem': 'Istari', 'altura': 1.85} 125 | ``` 126 | 127 | ### Removendo Itens do Dicionário 128 | 129 | É possível também, de várias formas, remover os itens de um dicionário. 130 | 131 | Usando o método **pop()**, nos será retornado o item removido: 132 | 133 | ```python 134 | personagem.pop('altura') # 1.85 135 | print(personagem) # {'nome': 'Gandalf', 'classe': 'Wizard', 'Ordem': 'Istari'} 136 | ``` 137 | 138 | Usando o método **popitem()**, remove o último par de **chave**-**valores** adicionado de **personagem** e o retorna como uma tupla: 139 | 140 | ```python 141 | personagem.popitem() # ('Ordem', 'Istari') 142 | print(personagem) # {'nome': 'Gandalf', 'classe': 'Wizard'} 143 | ``` 144 | 145 | A palavra-chave **del** remove um item com a chave especificada: 146 | 147 | ```python 148 | del personagem['classe'] 149 | print(personagem) # {'nome': 'Gandalf'} 150 | ``` 151 | 152 | Além disso é possível deletar o dicionário por completo com **del**, tenha muita atenção, pois todos os dados serão perdidos. 153 | 154 | ```python 155 | del personagem 156 | print(personagem) # NameError: name 'personagem' is not defined 157 | ``` 158 | 159 | ### Construtor dict() 160 | 161 | Através do construtor **dict()** também é possível criarmos dicionários: 162 | 163 | ```python 164 | pessoa = dict(nome="Jesus", idade=33) 165 | print(pessoa) # {'nome': 'Jesus', 'idade': 33} 166 | ``` 167 | 168 | Uma outra maneira de atualizarmos os dados de um dicionário é com o uso do método **update()**: 169 | 170 | ```python 171 | pessoa.update({'nome':'Immanuel'}) 172 | print(pessoa) # {'nome': 'Immanuel', 'idade': 33} 173 | ``` 174 | 175 | ### Método clear() 176 | 177 | O método **clear()** nos permite esvaziar o dicionário por completo: 178 | 179 | ```python 180 | pessoa.clear() 181 | print(pessoa) # {} 182 | ``` 183 | 184 | ### Ordenando um Dicionário 185 | 186 | Vamos agora criar um dicionário chamado de **pokedex**, este será um pequeno registro de alguns pokémons, que iremos **ordernar** através de **[expressões lambda](https://python-reference.readthedocs.io/en/latest/docs/operators/lambda.html)**. 187 | 188 | Criando o Dicionário: 189 | 190 | ```python 191 | pokedex = [ 192 | {'nome':'pikachu','tipo':'elétrico'}, 193 | {'nome':'charizard','tipo':'fogo'}, 194 | {'nome':'bulbasaur','tipo':'planta'}, 195 | {'nome':'squirtle','tipo':'aquatico'} 196 | ] 197 | ``` 198 | 199 | Ordenando os pokémons por **tipo** através de uma expressão lambda: 200 | 201 | ```python 202 | ordenados = sorted(pokedex, key=lambda x: x['tipo']) 203 | print(ordenados) 204 | # [{'nome': 'squirtle', 'tipo': 'aquatico'}, {'nome': 'pikachu', 'tipo': 'elétrico'}, {'nome': 'charizard', 'tipo': 'fogo'}, {'nome': 'bulbasaur', 'tipo': 'planta'}] 205 | ``` 206 | 207 | ### Dicionários Comprehensions 208 | 209 | Supondo que tenhamos por exemplo duas listas e desejamos montar um dicionário através delas, podemos usar a técnica de **[comprehensions](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions)** para executar tal tarefa. 210 | 211 | Para este exemplo, vamos primeiro iniciar duas listas e com elas, construíremos um dicionário: 212 | 213 | ```python 214 | autores = ['Aldous Huxley','George Orwell','Ray Bradbury','William Gibson'] 215 | livros = ['Brave New World','1984','Fahrenheit 451','Neuromancer'] 216 | 217 | autores_livros = {autor: livro for autor, livro in zip(autores, livros)} 218 | print(autores_livros) 219 | # {'Aldous Huxley': 'Brave New World', 'George Orwell': '1984', 'Ray Bradbury': 'Fahrenheit 451', 'William Gibson': 'Neuromancer'} 220 | ``` 221 | 222 | Um *dictionary comprehension* também pode conter o statement **if**, que pode ser usado para filtrarmos itens. 223 | 224 | Vejamos como podemos formar um dicionário apenas com números pares e seus respectivos quadrados: 225 | 226 | ```python 227 | quadrados_pares = {x: x*x for x in range(11) if x % 2 == 0} 228 | print(quadrados_pares) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64, 10: 100} 229 | ``` 230 | 231 | ### Dicionários Aninhados 232 | 233 | Os dicionários são uma estrutura de dados muito flexível e nos permitem até mesmo guardar **dicionários dentro de um dicionário**, de forma que possamos acessá-los através de uma **chave**. Vejamos um exemplo para ilustrar: 234 | 235 | ```python 236 | jogos = { 237 | '1':{'nome':'castlevania','genero':'aventura'}, 238 | '2':{'nome':'super mario','genero':'aventura'}, 239 | '3':{'nome':'world of warcraft','genero':'MMORPG'} 240 | } 241 | 242 | print(jogos['2']) # {'nome': 'super mario', 'genero': 'aventura'} 243 | print(jogos.get('1')) # {'nome': 'castlevania', 'genero': 'aventura'} 244 | print(jogos['3']['nome']) # world of warcraft 245 | ``` 246 | 247 | ### Copiando um Dicionário 248 | 249 | Você não pode copiar um dicionário simplesmente digitando `copia_filme = filme`, porque: **copia_filme** será apenas uma referência para **filme**, e as alterações feitas em **filme** também serão feitas automaticamente em **copia_filme**. 250 | 251 | Uma maneira de copiarmos um dicionário é usando o método interno **copy()**: 252 | 253 | ```python 254 | filme = {'titulo':'Lord of the Rings','Gênero':'Aventura'} 255 | print(filme) # {'titulo': 'Lord of the Rings', 'Gênero': 'Aventura'} 256 | copia_filme = filme.copy() 257 | print(copia_filme) # {'titulo': 'Lord of the Rings', 'Gênero': 'Aventura'} 258 | ``` 259 | 260 | Se eventualmente alterarmos o dicionário **filme**, a cópia não será afetada: 261 | 262 | ```python 263 | filme['Gênero'] = 'Fantasia' 264 | print(filme) # {'titulo': 'Lord of the Rings', 'Gênero': 'Fantasia'} 265 | print(copia_filme) # {'titulo': 'Lord of the Rings', 'Gênero': 'Aventura'} 266 | ``` 267 | 268 | Uma outra opção para copiarmos um dicionário é com o uso do método **dict()**, ao qual já vimos anteriormente. 269 | 270 | ```python 271 | copia_filme = dict(filme) 272 | print(copia_filme) # {'titulo': 'Lord of the Rings', 'Gênero': 'Fantasia'} 273 | filme['titulo'] = 'The Hobbit: An Unexpected Journey' 274 | print(filme) # {'titulo': 'The Hobbit: An Unexpected Journey', 'Gênero': 'Fantasia'} 275 | print(copia_filme) # {'titulo': 'Lord of the Rings', 'Gênero': 'Fantasia'} 276 | ``` 277 | 278 | ### Fibonacci com Dicionários 279 | 280 | Podemos utilizar o poder dos dicionários para otimizar uma função Fibonnaci e tornar seus resultados mais rápidos ao guardarmos os valores já computados em um **dicionário**. Esta técnica é conhecida como [Memoization](https://en.wikipedia.org/wiki/Memoization). 281 | 282 | ```python 283 | def fib_eficiente(n, d): 284 | if n in d: 285 | return d[n] 286 | else: 287 | resposta = fib_eficiente(n-1, d) + fib_eficiente(n-2, d) 288 | d[n] = resposta 289 | return resposta 290 | 291 | d = {1:1, 2:2} 292 | print(fib_eficiente(8, d)) # 34 293 | ``` 294 | 295 | Podemos concluir que os dicionários são uma estrutura de dados que nos oferece uma maneira eficaz de **guardar** e **buscar** os dados, considere a importância deles para usos no futuro. -------------------------------------------------------------------------------- /Capitulos/11.Sets.md: -------------------------------------------------------------------------------- 1 | # Sets 2 | 3 | Sets são **coleções não-ordenadas** de itens **ÚNICOS**, embora um Set possa ser modificado, os elementos contidos dentro do Set devem ser imutáveis. Sets são definidos por valores separados por vírgula dentro de chaves `{}`. 4 | 5 | **Importante:** Cuidado para não confundir os Sets com os dicionários! 6 | 7 | A principal vantagem de usar um **Set**, ao contrário de uma lista, é que ele possui um mecanismo altamente otimizado para verificar se um elemento específico está contido nele. 8 | 9 | Talvez você lembre dos Sets através da **[famosa teoria matemática dos conjuntos](https://pt.wikipedia.org/wiki/Teoria_dos_conjuntos)**. 10 | 11 | ![img](/Imagens/Set.png) 12 | 13 | Os Sets podem ser usados para executarmos operações matemáticas de conjuntos como **união**, **intersecção**, **diferença simétrica**, etc. 14 | 15 | ### Definindo um Set 16 | 17 | Para definirmos um **Set** é muito simples: 18 | 19 | ```python 20 | s = {1,1,2,3,3,4} 21 | print(type(s)) # 22 | print(s) # {1, 2, 3, 4} 23 | ``` 24 | 25 | Observe que os valores repetidos foram eliminados de nosso set. 26 | 27 | Também podemos criar um set através do método **set()**: 28 | 29 | ```python 30 | k = set([1,2,3,4,5]) 31 | print(type(k)) # 32 | print(k) # {1, 2, 3, 4, 5} 33 | ``` 34 | 35 | Lembrando que podemos iterar sob um set com um **for loop**: 36 | 37 | ```python 38 | for itens in k: 39 | print(itens) 40 | ``` 41 | 42 | ### Operações com Sets 43 | 44 | O método **add()** nos possibilita adicionar um item ao set: 45 | 46 | ```python 47 | k.add(8) 48 | print(k) # {1, 2, 3, 4, 5, 8} 49 | ``` 50 | 51 | O método **discard()** nos permite remover itens de um set: 52 | 53 | ```python 54 | k.discard(1) 55 | print(k) # {2, 3, 4, 5, 8} 56 | ``` 57 | 58 | Para remover todos os elementos do set podemos usar o método **clear()**: 59 | 60 | ```python 61 | k.clear() 62 | print(k) # set() 63 | ``` 64 | 65 | Também podemos usar os sets para eliminar letras repetidas de uma palavra: 66 | 67 | ```python 68 | print(set('cachorro')) # {'o', 'a', 'c', 'r', 'h'} 69 | ``` 70 | 71 | Para sabermos o número de elementos em um set usamos o método **len()**: 72 | 73 | ```python 74 | len(set('cachorro')) # 5 75 | ``` 76 | 77 | Vamos agora definir dois novos sets `x` e `y` para testarmos **novas operações**. 78 | 79 | ```python 80 | x = {1,2,3} 81 | y = {2,3,4} 82 | ``` 83 | 84 | ### Intersecção 85 | 86 | Para intersecção podemos usar `&` ou o método **intersection()**. 87 | 88 | ![img](/Imagens/Intersec%C3%A7%C3%A3o.png) 89 | 90 | ```python 91 | print(x & y) # {2, 3} 92 | print(x.intersection(y)) # {2, 3} 93 | ``` 94 | 95 | ### Diferença 96 | 97 | Para diferença podemos usar `-` ou o método **difference()**. 98 | 99 | ![img](/Imagens/Diferen%C3%A7a.png) 100 | 101 | ```python 102 | # Relativo a x 103 | print(x - y) # {1} 104 | x.difference(y) # {1} 105 | 106 | # Relativo a y 107 | print(y - x) # {4} 108 | y.difference(x) # {4} 109 | ``` 110 | 111 | ### Diferença Simétrica 112 | 113 | Para diferença simétrica podemos usar `^` ou o método **symmetric_difference()**. 114 | 115 | ![img](/Imagens/Diferen%C3%A7aSim%C3%A9trica.png) 116 | 117 | ```python 118 | print(x.symmetric_difference(y)) # {1, 4} 119 | print(y.symmetric_difference(x)) # {1, 4} 120 | print(x ^ y) # {1, 4} 121 | print(y ^ x) # {1, 4} 122 | ``` 123 | 124 | Todos imprimem o mesmo resultado, uma vez que a diferença é simétrica. 125 | 126 | ### União 127 | 128 | Para união podemos usar `|` ou o método **union()**. 129 | 130 | ![img](/Imagens/Uni%C3%A3o.png) 131 | 132 | ```python 133 | print(x | y) # {1, 2, 3, 4} 134 | print(x.union(y)) # {1, 2, 3, 4} 135 | ``` 136 | 137 | ### Verificando a presença de um Elemento 138 | 139 | Assim como nas outras estruturas de dados compostas, nos sets também é possível verificarmos a **presença** ou **absência** de um determinado elemento com o uso da palavra-chave **in**, por sinal, os sets são muito eficientes para essas operações. 140 | 141 | ```python 142 | print(1 in x) # True 143 | print(5 in x) # False 144 | print(10 not in x) # True 145 | print(1 not in x) # False 146 | ``` 147 | 148 | ### Referência dos Sets 149 | 150 | Os Sets nos trazem diversas funcionalidades e nos permitem resolver diversos problemas, para conhecer mais detalhes sobre eles visite a **[documentação oficial](https://docs.python.org/3/tutorial/datastructures.html#sets)**. 151 | 152 | A tabela a seguir apresenta os métodos mais importantes dos sets e suas descrições: 153 | 154 | | Método | Descrição | 155 | |-------------------------------|:--------------------------------------------------------------------------------:| 156 | | add() | Adiciona um elemento ao set | 157 | | clear() | Remove todos os elementos do set | 158 | | copy() | Retorna uma cópia do set | 159 | | difference() | Retorna um set contendo a diferença entre dois ou mais sets | 160 | | difference_update() | Remove os itens desse set que também estão incluídos em outro set especificado | 161 | | discard() | Remove um item específico | 162 | | intersection() | Retorna um set que é intersecção entre dois sets | 163 | | intersection_update() | Remove os itens desse set que não estão presente em outro set especificado | 164 | | isdisjoint() | Retorna se dois sets possuem intersecção ou não | 165 | | issubset() | Retorna se outro set contém esse set ou não | 166 | | issuperset() | Retorna se esse set contém outro set ou não | 167 | | pop() | Remove o item especificado | 168 | | remove() | Remove o item especificado | 169 | | symmetric_difference() | Retorna um set com a diferença simétrica de dois sets | 170 | | symmetric_difference_update() | Insere a diferença simétrica desse set no outro | 171 | | union() | Retorna um set contendo a união de sets | 172 | | update() | Atualiza o set com a união desse set e outros | -------------------------------------------------------------------------------- /Capitulos/12.Input.md: -------------------------------------------------------------------------------- 1 | # Input 2 | 3 | Desenvolvedores geralmente precisam interagir com os usuários, seja para obter dados ou fornecer algum tipo de resultado. A maioria dos programas hoje em dia usam uma caixa de diálogo como uma forma de solicitar ao usuário algum tipo de *input* (entrada) do usuário. 4 | 5 | Na maioria dos casos, o *input* vem do teclado. Para este propósito, Python fornece a função `input()`, que possui um parâmetro opcional, que é a string que será enviada para o usuário. 6 | 7 | Até então todos os nossos programas foram **estáticos**, os valores das variáveis foram definidos por nós no código fonte. De forma a aumentar nossas opções de criações, vamos então aprender como podemos coletar dados dos usuários. 8 | 9 | ### Exemplos Input 10 | 11 | Começaremos chamando a função `input()`, passando como argumento uma string que será retornada como feedback ao usuário e armazenaremos o valor digitado pelo usuário na variável `n` que será impressa na sequência. 12 | 13 | ```python 14 | n = input("Insira um número: ") 15 | print(n) 16 | ``` 17 | 18 | Ao executarmos o código acima, o prompt de comandos aguardará pela entrada de dados por parte de usuário, uma vez informado o valor e enviado, ele será impresso. Vamos agora ver qual o tipo de dados que temos em **n**: 19 | 20 | ```python 21 | print(type(n)) # 22 | ``` 23 | 24 | Como podemos ver, embora tenhamos digitado um **número**, ele nos retorno uma **string**, para obtermos um número podemos utilizar as funções **int()** ou **float()** para fazer a conversão. 25 | 26 | ```python 27 | n = int(input("Insira um número: ")) 28 | print(type(n)) # 29 | ``` 30 | 31 | O método **eval()** também é capaz de solucionar o nosso problema e até mesmo resolver expressões, muito útil, mas tenha cuidado com ele! 32 | 33 | ```python 34 | eval('2+3') # 5 35 | numero = eval(input("Digite um valor: ")) 36 | print(numero) # 2.3 37 | print(type(numero)) # 38 | ``` 39 | 40 | ### Pedra, Papel e Tesoura 41 | 42 | Uma vez que sabemos como coletar dados de usuários, podemos agora criar jogos. Neste exemplo vamos construir o clássico Pedra, Papel e Tesoura, também conhecido como Jankenpon. 43 | 44 | ![img](/Imagens/JanKenPon.png) 45 | 46 | Para nos auxiliar neste pequeno projeto, vamos contar com a ajuda da função **choice()** da biblioteca [random](https://docs.python.org/3/library/random.html), ela será responsável por emular uma escolha pseudo-aleatória da máquina, entre as três opções disponíveis (Pedra, Papel e Tesoura). 47 | 48 | Também iremos utilizar um **While Loop** para manter o jogo executando até que o usuário deseje sair. 49 | 50 | Coletaremos o input do usuário através da função `input()` e testaremos uma série de `if`, `elif` e `else` para sabermos quem é o vitorioso. 51 | 52 | ```python 53 | from random import choice 54 | 55 | opcoes = ['pedra', 'papel', 'tesoura'] 56 | maquina = choice(opcoes) 57 | jogando = True 58 | 59 | while jogando: 60 | print("# pedra\n# papel\n# tesoura\n# sair") 61 | player = input('Escolha entre uma das opções: ') 62 | if maquina == player.lower(): 63 | print(f'Ocorreu um empate!') 64 | elif player.lower() == 'pedra': 65 | if maquina == 'papel': 66 | print(f'Você perdeu! {maquina} cobre {player.lower()}!') 67 | else: 68 | print(f'Parabéns! Você venceu! {player.lower()} quebra {maquina}!') 69 | elif player.lower() == 'papel': 70 | if maquina == 'tesoura': 71 | print(f'Você perdeu! {maquina} corta {player.lower()}!') 72 | else: 73 | print(f'Parabéns! Você venceu! {player.lower()} cobre {maquina}!') 74 | elif player.lower() == 'tesoura': 75 | if maquina == 'pedra': 76 | print(f'Você perdeu! {maquina} esmaga {player.lower()}!') 77 | else: 78 | print(f'Parabéns! Você venceu! {player.lower()} corta {maquina}!') 79 | elif player.lower() == 'sair': 80 | jogando = False 81 | else: 82 | print('Jogada inválida, verifique se digitou a opção corretamente!') 83 | print('-'*45) 84 | maquina = choice(opcoes) 85 | ``` 86 | 87 | Como podemos ver, a função **input()** pode nos auxiliar na questão de receber dados de usuários e através dos diversos métodos vistos, podemos converter os dados recebidos para trabalharmos com eles de forma adequada. -------------------------------------------------------------------------------- /Capitulos/13.If...Else.md: -------------------------------------------------------------------------------- 1 | # If...Else 2 | 3 | A tomada de decisão é necessária quando queremos executar um código apenas se uma determinada **condição** for satisfeita. 4 | 5 | As instruções `if`, `elif` e `else` são usadas em Python para nos auxiliar na tomada de decisões. 6 | 7 | ![img](/Imagens/Conditionals.png) 8 | 9 | A tomada de decisão é um conceito muito importante da programação e representa a capacidade de executarmos determinados comandos apenas se condições especificadas forem satisfeitas. 10 | 11 | Lembrando que Python é capaz de suportar as condições lógicas tradicionais da matemática: 12 | 13 | - Igualdade: `x == y` 14 | - Diferente de: `x != y` 15 | - Menor que: `x < y` 16 | - Menor que ou igual a: `x <= y` 17 | - Maior que: `x > y` 18 | - Maior que ou igual a: `x >= y` 19 | 20 | Essas condições podem ser usadas de várias maneiras, e são comumente utilizadas em instruções **if** e **loops**. 21 | 22 | A sintaxe para construirmos uma estrutura de tomada de decisão funciona então da seguinte forma: 23 | 24 | ```pyhton 25 | if : 26 | 27 | elif : 28 | 29 | else: 30 | 31 | ``` 32 | 33 | Neste exemplo, o programa executa a primeira linha `if `, se a `` for avaliada como `True`, os `` dentro do bloco **if** serão executados. 34 | 35 | Caso a `` da primeira linha `if ` seja avaliada como `False`, nosso programa irá pular para a linha `elif ` e irá testar a nova ``: 36 | 37 | - Se ela for avaliada como `True` os comandos do bloco **elif** serão executados. 38 | - Se ela for avaliada como `False` os comandos do bloco **else** serão executados. 39 | 40 | ### Exemplos 41 | 42 | Vamos agora construir exemplos práticos para compreender melhor a ideia de tomada de decisão em nossos códigos. 43 | 44 | ```python 45 | num = 5 46 | 47 | if num > 0: 48 | print("O número é positivo") 49 | print("Esse valor é sempre impresso, pois está fora do bloco if") 50 | ``` 51 | 52 | Nesse caso podemos perceber que a expressão dentro do bloco **if** será executa, uma vez que o valor de **num** é maior que **0**, sendo assim, **positivo**. 53 | 54 | Também podemos usar a palavra-chave **elif** para testarmos outras possibilidades, uma vez que nem sempre a primeira pode ser atendida. 55 | 56 | ```python 57 | x = 12 58 | y = 12 59 | 60 | if x > y: 61 | print("x é maior do que y") 62 | elif x == y: 63 | print("x e y são iguais") 64 | ``` 65 | 66 | Nesse exemplo a primeira condição não é satisfeita, então pulamos para o **elif** e fazemos o teste, como os valores de **x** e **y** são iguais, temos nossa expressão **"x e y são iguais"** executada. 67 | 68 | Além do **if** e **elif**, temos o **else** que preencherá qualquer situação que o **if** e **elif** não sejam capazes de executar. 69 | 70 | ```python 71 | a = 100 72 | b = 20 73 | 74 | if b > a: 75 | print("b é maior do que a") 76 | elif b == a: 77 | print("b e a são iguais") 78 | else: 79 | print("a é maior do que b") 80 | ``` 81 | 82 | Veja que nesse caso o primeiro **if** será avaliado como **False**, pulamos então para o **elif** que também será avaliado como **False**, nos deixando apenas com a execução do **else**. 83 | 84 | Lembrando que é possível utilizarmos o **else** sem o **elif**. 85 | 86 | ```python 87 | k = 30 88 | z = 22 89 | 90 | if z > k: 91 | print("z é maior do que k") 92 | else: 93 | print("k é maior do que z") 94 | ``` 95 | 96 | Podemos também encadear multiplos **if**, **elif** e **else**. 97 | 98 | Nesse programa vamos pedir para o usuário entrar com um número, avaliaremos se ele é positivo, negativo ou zero e mostraremos ao usuário a mensagem apropriada. 99 | 100 | ```python 101 | num = int(input("Digite um número: ")) 102 | 103 | if num >= 0: 104 | if num == 0: 105 | print("Zero") 106 | else: 107 | print("Número positivo") 108 | else: 109 | print("Número negativo") 110 | ``` 111 | 112 | Imagine agora que temos uma string chamada de **senha** e queremos avaliar se ela foi digitada ou não, podemos neste caso usar a palavra-chave **not** que indica a negação de uma expressão, alterando assim seu estado. Por exemplo: 113 | 114 | ```python 115 | senha = '' 116 | 117 | if not senha: 118 | print('Senha inexistente!') 119 | else: 120 | print('Senha existe!') 121 | # Senha inexistente! 122 | ``` 123 | 124 | Neste caso específico, o comando `print('Senha inexistente!')` será executado, uma vez que qualquer string vazia é avaliada como `False`, e nesse caso, usamos o **not** para trocar o **False** para **True**. 125 | 126 | Podemos confirmar essa ideia com o seguinte experimento: 127 | 128 | ```python 129 | print(bool('')) # False 130 | print(bool('75966231325')) # True 131 | ``` 132 | 133 | Isso quer dizer que se adicionarmos uma senha, o bloco **else** será executado, pois dessa vez temos uma string preenchida, que será avalida como **True** e a palavra-chave **not** irá transformar o **True** em **False**. 134 | 135 | ```python 136 | senha = '75966231325' 137 | 138 | if not senha: 139 | print('Senha inexistente!') 140 | else: 141 | print('Senha existe!') 142 | # Senha existe! 143 | ``` 144 | 145 | No caso de números, o que ocorre é que o número **0** é avaliado como `False` e quaisquer outros números são considerados `True`: 146 | 147 | ```python 148 | bool(0) # False 149 | bool(1) # True 150 | bool(-1) # True 151 | bool(3.3) # True 152 | bool(3+1j) # True 153 | ``` 154 | 155 | ### Operadores Lógicos 156 | 157 | Anteriormente vimos os **operadores lógicos**, eles também podem ser utilizados em conjunto com **if** para construirmos testes mais elaborados. 158 | 159 | A palavra-chave **and** é um operador lógico e é usado para combinar declarações condicionais: 160 | 161 | ```python 162 | n1 = 15 163 | n2 = 30 164 | n3 = 15 165 | 166 | if n1 < n2 and n3 == n1: 167 | print("Ambas as condições são verdadeiras") 168 | ``` 169 | 170 | Neste exemplo o comando **print()** será executado, pois ambas as condições se concretizam como `True` (n1 é **menor** que n2 e n3 é **igual** a n1). 171 | 172 | A palavra-chave **or** é um operador lógico e é usada para combinar declarações condicionais: 173 | 174 | ```python 175 | 176 | 177 | if n1 > n2 or n1 == n3: 178 | print("Pelo menos uma condição é verdadeira") 179 | ``` 180 | 181 | Neste exemplo o comando **print()** será executado, mesmo a primeira expressão não sendo avaliada como `True`, a segunda é avaliada, o que é o suficiente para termos nosso comando **print()** executado. 182 | 183 | ### O Desafio FizzBuzz 184 | 185 | Imagine que temos um número **n**. Temos que exibir uma representação em string de todos os números de **1** até **n**, mas existem algumas restrições: 186 | 187 | - Se o número n for divisível por 3, imprimir "Fizz" ao invés do número. 188 | - Se o número n for divisível por 5, imprimir "Buzz" ao invés do número. 189 | - Se o número n for divisível por 3 e 5, imprimir "FizzBuzz" ao invés do número 190 | 191 | Em outras palavras, para múltiplos de três vamos imprimir "Fizz" em vez do número e para múltiplos de cinco vamos imprimir "Buzz". Para números que são múltiplos de três e cinco, imprimir "FizzBuzz". 192 | 193 | Para resolvermos este problema, precisaremos de um **for loop** e uma série de testes com **if**, **elif** e **else**. Vejamos como podemos fazer: 194 | 195 | ```python 196 | n = 35 197 | 198 | for n in range(1,n): 199 | if n % 3 is 0 and n % 5 is 0: 200 | print("FizzBuzz") 201 | elif n % 3 is 0: 202 | print("Fizz") 203 | elif n % 5 is 0: 204 | print("Buzz") 205 | else: 206 | print(n) 207 | ``` 208 | 209 | Observe que estamos usando o operador de resto de divisão (`%`) e também a palavra-chave **is**, para verificarmos se o resto de divisão é igual a 0. 210 | 211 | - No primeiro bloco **if** testamos se o número é divisível por 3 e 5. 212 | - No segundo bloco **elif** testamos se o número é divisível por 3. 213 | - No terceiro bloco **elif** testamos se o número é divisível por 5. 214 | - Finalmente, se todas os testes anteriores forem `False`, iremos imprimir o próprio número **n**. 215 | 216 | É importante fixarmos bastante a parte de **tomada de decisão**, pois ela nos dará uma base sólida para construirmos nossos programas, lembre sempre de fazer experimentos. -------------------------------------------------------------------------------- /Capitulos/14.ForLoops.md: -------------------------------------------------------------------------------- 1 | # For Loops 2 | 3 | ![img](/Imagens/ForLoop.png) 4 | 5 | O **For Loop** em Python é usado para iterar sob uma sequência (lista, tupla, string) ou outros objetos iteráveis. A iteração sob uma sequência também é conhecida como travessia. 6 | 7 | O **For Loop** já é um conhecido nosso, pois utilizamos ele para percorrer nossas listas no passado, porém agora veremos ele com uma maior riqueza de detalhes e veremos que ele é muito importante, uma vez que nos permite percorrer diversas sequências (**listas**, **tuplas**, **dicionários**, **sets** e até mesmo **strings**). 8 | 9 | Para escrevermos o **for** Loop devemos obedecer a seguinte sintaxe: 10 | 11 | ``` 12 | for seq in sequencia: 13 | print(seq) 14 | ``` 15 | 16 | Onde `seq` é a variável que recebe o valor do item dentro da sequência em cada iteração, o loop continua até alcançarmos o último item da sequência. 17 | 18 | É válido lembrar que o **for** em **Python** difere um pouco de outras linguagens como por exemplo **C**, onde nós podemos definir os passos de **iteração** e o momento de parada, em **Python** o **for** faz a iteração em cima dos itens de uma sequência, na ordem que eles aparecem naquela sequência, por exemplo: 19 | 20 | ```python 21 | animais = ["cachorro", "gato", "elefante"] 22 | 23 | for animal in animais: 24 | print(animal) 25 | ``` 26 | 27 | Simples, não? Também podemos percorrer **strings**: 28 | 29 | ```python 30 | for string in "Programação com Python": 31 | print(string) 32 | ``` 33 | 34 | Se quisermos evitar a quebra de linha `\n`, podemos alterar o valor do argumento **end**: 35 | 36 | ```python 37 | for string in "Programação com Python": 38 | print(string,end='') 39 | ``` 40 | 41 | ### A Função **range()** 42 | 43 | Nós podemos gerar sequências de números através da função **range()**. Por exemplo, **range(10)** irá gerar números de 0 até 9 (10 números). A função **range()** também nos permite definir o começo da nossa sequência, o fim e os passos que serão dados como por exemplo range(começo,fim,passos), caso não venhamos a definir os passos, o padrão é que seja de 1 em 1. 44 | 45 | Importante lembrar que a função não guarda todos os valores em memória por questões de eficiência, para forçarmos que a função imprima os itens, nós podemos utilizar a função **list()**, veja: 46 | 47 | ```python 48 | x = range(0,10) 49 | print(type(x)) # veja que o tipo retornado é 'range' 50 | print(list(x)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 51 | 52 | y = range(4,30,2) 53 | print(list(y)) # [4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28] 54 | ``` 55 | 56 | Podemos aplicar a função **range()** em conjunto com o **for**: 57 | 58 | ```python 59 | for i in range(10): 60 | print(i) 61 | 62 | for data in range(1995,2018): 63 | print(data) 64 | ``` 65 | 66 | ### Condicionais 67 | 68 | A palavra-chave **break** nos permite parar o loop antes que ele passe por todos os itens 69 | 70 | ```python 71 | paises = ['China', 'Índia', 'Tailândia'] 72 | 73 | for pais in paises: 74 | print(pais) 75 | if pais == "Índia": 76 | break 77 | ``` 78 | 79 | Como podemos ver só serão impressos os países **China** e **Índia**, quando **pais** tiver o valor de **Índia** o loop irá parar e não será capaz de imprimir **Tailândia**. 80 | 81 | A palavra-chave **continue** nos permite parar a iteração atual do loop e continuar para a próxima: 82 | 83 | ```python 84 | linguagens = ['C','Javascript','Python','Lua'] 85 | 86 | for linguagem in linguagens: 87 | if linguagem == "Javascript": 88 | continue 89 | print(linguagem) 90 | ``` 91 | 92 | Como podem ver, ao chegamos em **Javascript** o loop pára e vai para a próxima impressão, nos retornando apenas 'C', 'Python' e 'Lua'. 93 | 94 | Dessa forma é muito fácil criarmos um **for loop** para imprimir apenas números pares: 95 | 96 | ```python 97 | for x in range(10): 98 | if x % 2 == 1: 99 | continue 100 | print(x) 101 | ``` 102 | 103 | Nos serão trazidos todos os números pares de 0 até 9. 104 | 105 | **Python** nos permite também usarmos a palavra-chave **else** em conjunto com o **for**, por exemplo: 106 | 107 | ```python 108 | for x in range(10): 109 | print(x) 110 | else: 111 | print("Loop finalizado com sucesso!") 112 | ``` 113 | 114 | ### Loops Encadeados 115 | 116 | Loops encadeados são loops dentro de loops, o "loop de dentro" será executado uma vez para cada iteração do "loop de fora". 117 | 118 | ```python 119 | cores = ['azul','verde','amarelo'] 120 | numeros = [1,2,3] 121 | 122 | for cor in cores: 123 | for numero in numeros: 124 | print(f'{cor.capitalize()} - {numero}') 125 | ``` 126 | 127 | ### Enumerando Valores 128 | 129 | O método **enumerate()** adiciona um contador a um iterável e o retorna o objeto enumerate. 130 | 131 | O método **enumerate()** recebe dois parâmetros: 132 | 133 | - **iterable**: Uma sequência, um iterator, ou objetos que suportam iteração 134 | - **start** (opcional): É o número que o método **enumerate()** iniciará contando, se **start** for omitido, 0 será o valor padrão. 135 | 136 | Vejamos um exemplo de como podemos usá-lo: 137 | 138 | ```python 139 | alimentos = ['arroz','feijão','batata'] 140 | 141 | for indice,alimento in enumerate(alimentos): 142 | print(f'{indice} -> {alimento}') 143 | ``` 144 | 145 | Informando o parâmetro start: 146 | 147 | ```python 148 | for indice,alimento in enumerate(alimentos,10): 149 | print(f'{indice} -> {alimento}') 150 | ``` 151 | 152 | Dessa vez ele começará a contar a partir do número **10**. 153 | 154 | Vimos nestes exemplos que as utilidades do **for** são imensas e podem nos ajudar bastante no sentido de percorrer sequências e até mesmo gerá-las com **range()**. -------------------------------------------------------------------------------- /Capitulos/15.WhileLoops.md: -------------------------------------------------------------------------------- 1 | # While Loop 2 | 3 | O **while loop** em **Python** é utilizado para iterar em cima de um bloco de código enquanto determinada **Expressão de Teste** (condição) for avaliada como **True**. 4 | 5 | **While** é normalmente usado quando não sabemos de ante-mão o número de vezes no qual vamos iterar. 6 | 7 | Python primeiro verifica a condição: 8 | 9 | - Se for **False**, o loop será encerrado e o controle será passado para a próxima instrução após o corpo do While Loop. 10 | - Se a condição for **True**, o corpo do While Loop será executado e a condição será verificada novamente. 11 | 12 | Este procedimento continua enquanto a condição for **True**. Quando a condição se torna **False**, o loop termina e o controle é passado para a próxima instrução após o loop. 13 | 14 | ### Estrutura Básica do While 15 | 16 | ![img](/Imagens/WhileLoop.png) 17 | 18 | ``` 19 | while : 20 | 21 | 22 | ... 23 | ``` 24 | 25 | - `` é avaliado para um **booleano** 26 | - Se a `` for **True**, executa-se todas as `` dentro do bloco de código while 27 | - Checa a `` novamente 28 | - Repete até que a `` seja **False** 29 | 30 | Vejamos um exemplo prático: 31 | 32 | ```python 33 | i = 1 34 | while i < 10: 35 | print(i) 36 | i += 1 37 | ``` 38 | 39 | Observe que `i += 1` é o mesmo que `i = i + 1`, precisamos dessa expressão, caso contrário teremos um loop infinito. 40 | 41 | Também podemos definir o while loop em um único statement, da seguinte forma: 42 | 43 | ```python 44 | count = 0 45 | while (count < 5): count += 1; print("Hello World") 46 | ``` 47 | 48 | A palavra-chave **break** também pode ser utilizada em conjunto com o **while**: 49 | 50 | ```python 51 | a = 1 52 | while a < 10: 53 | print(a) 54 | if a == 5: 55 | break 56 | a += 1 57 | ``` 58 | 59 | Neste caso só serão impressos os números de 1 até 5, pois quando `a == 5` o loop irá encerrar. 60 | 61 | Podemos também usar a palavra-chave **continue**: 62 | 63 | ```python 64 | x = 0 65 | while x < 10: 66 | x += 1 67 | if x == 5: 68 | continue 69 | print(x) 70 | ``` 71 | 72 | Neste caso o número 5 não será impresso, pois quando `x == 5` o comando **print()** não será executado. 73 | 74 | O while loop também pode ser usado para computarmos a [Sequência de Fibonacci](https://en.wikipedia.org/wiki/Fibonacci): 75 | 76 | ```python 77 | n = int(input("Informe o número de termos: ")) 78 | 79 | a, b = 0, 1 80 | count = 0 81 | 82 | while count < n: 83 | print(a) 84 | c = a + b 85 | a, b = b, c 86 | count += 1 87 | ``` 88 | 89 | Com ele podemos facilmente definir o algoritmo de [Euclides](https://en.wikipedia.org/wiki/Euclid) para buscar o máximo divisor comum entre dois números: 90 | 91 | ```python 92 | def gcd(x, y): 93 | while y != 0: 94 | (x, y) = (y, x % y) 95 | return x 96 | 97 | print(gcd(155,70)) # 5 98 | print(gcd(77,33)) # 11 99 | print(gcd(400,140)) # 20 100 | print(gcd(97,13)) # 1 101 | ``` 102 | 103 | ### For vs While 104 | 105 | #### for 106 | 107 | - Número de iterações é **conhecido** 108 | - Pode finalizar antecipadamente através do **break** 109 | - Utiliza um **contador** 110 | 111 | #### while 112 | 113 | - Número de iterações **ilimitados** 114 | - Pode finalizar antecipadamente através do **break** 115 | - Pode utilizar um **contador**, porém é necessário inicializar ele antes do loop e incrementá-lo dentro do loop 116 | 117 | Como vimos, **while loops** não são muito misteriosos, porém a utilidade deles pode ser muito grande em nossos programas! -------------------------------------------------------------------------------- /Capitulos/17.Lambda.md: -------------------------------------------------------------------------------- 1 | # Expressões Lambda 2 | 3 | **Expressões lambda** também são conhecidas como **funções anônimas**, elas diferem das funções comuns por serem declaradas de maneira diferente, sem definirmos nome para criarmos elas, utilizamos a palavra-chave **lambda** para definí-las. 4 | 5 | Python e outras linguagens como Java, C# e até mesmo C++ tiveram as funções lambda adicionadas a sua sintaxe, já linguagens como LISP, ou linguagens da família **[ML](https://en.wikipedia.org/wiki/ML_(programming_language))**: Haskell, OCaml e F# usam lambdas como um conceito central. 6 | 7 | Expressões Lambda em Python e em outras linguagens de programação possuem suas raízes no **[cálculo lambda](https://en.wikipedia.org/wiki/Lambda_calculus)**, um modelo de computação inventando por **[Alonzo Church](https://en.wikipedia.org/wiki/Alonzo_Church)**. 8 | 9 | O cálculo lambda pode codificar qualquer cálculo, é [Turing completo](https://simple.wikipedia.org/wiki/Turing_complete), mas ao contrário do conceito de [máquina de Turing](https://en.wikipedia.org/wiki/Turing_machine), é puro e não guarda nenhum [estado](https://en.wikipedia.org/wiki/Turing_machine#The_%22state%22). 10 | 11 | As linguagens funcionais têm sua origem na lógica matemática e no cálculo lambda, enquanto as linguagens de programação imperativas adotam o modelo de computação baseado em estado inventado por Alan Turing. Os dois modelos de computação, cálculo lambda e máquinas de Turing, podem ser traduzidos um no outro. Essa equivalência é conhecida como [hipótese de Church-Turing](https://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis). 12 | 13 | As linguagens funcionais herdam diretamente a filosofia do cálculo lambda, adotando uma abordagem declarativa de programação que enfatiza a abstração, a transformação de dados, a composição e a pureza (sem estado e sem efeitos colaterais). Exemplos de linguagens funcionais incluem Haskell e Lisp. 14 | 15 | - Expressões lambdas podem receber qualquer número de argumentos, porém retornam apenas um valor na forma de expressão, elas não podem ter comandos ou multiplas expressões 16 | - Uma função anônima não pode ser chamada diretamente pela função **print()**, pois ela requer uma expressão 17 | 18 | ### Funções Anônimas 19 | 20 | Os seguintes termos são usados de forma de forma intercambiável dependendo da linguagem de programação ou local que você vive: 21 | 22 | - Funções Anônimas 23 | - Funções Lambda 24 | - Expressões Lambda 25 | - Abstrações Lambda 26 | - Forma Lambda 27 | - Literais de Função 28 | 29 | ### Fundamentos Básicos 30 | 31 | ![img](/Imagens/Lambda.png) 32 | 33 | A estrutura para utilizarmos as funções lambdas é muito simples 34 | 35 | ``` 36 | lambda argumento1, argumento2, argumento3: expressão 37 | ``` 38 | 39 | Por exemplo, se quisermos multiplicar o argumento por **3**: 40 | 41 | ```python 42 | triplo = lambda x: x * 3 43 | print(type(triplo)) # 44 | print(triplo(3)) # 9 45 | ``` 46 | 47 | Se quisermos elevar o número ao quadrado: 48 | 49 | ```python 50 | quadrado = lambda x: x * x 51 | print(quadrado(5)) # 25 52 | ``` 53 | 54 | As expressões lambdas também nos permitem trabalharmos com strings, por exemplo: 55 | 56 | ```python 57 | nome_completo = lambda nome,sobrenome: f'Nome: {nome.title()}\nSobrenome: {sobrenome.title()}' 58 | print(nome_completo('isaac','newton')) 59 | # Nome: Isaac 60 | # Sobrenome: Newton 61 | ``` 62 | 63 | Podemos também usar **condicionais** com funções Lambda 64 | 65 | ```python 66 | comeca_com_G = lambda x: True if x.startswith('G') else False 67 | print(comeca_com_G('Gabriel')) # True 68 | print(comeca_com_G('Rafael')) # False 69 | ``` 70 | 71 | Se quisermos verificar se um determinado número é ímpar: 72 | 73 | ```python 74 | impar = lambda x: True if x % 2 == 1 else False 75 | print(impar(1)) # True 76 | print(impar(8)) # False 77 | ``` 78 | 79 | Até mesmo compor funções mais complexas, neste caso, imprimir a palavra que vem antes da palavra passada via argumento. 80 | 81 | ```python 82 | palavra_antes = lambda s, w: s.split()[s.split().index(w)-1] if w in s else None 83 | sentenca = 'Rato Roeu Roupa Rei Roma' 84 | print(palavra_antes(sentenca,'Roma')) # Rei 85 | ``` 86 | 87 | ### Lambda em Python 88 | 89 | Nós normalmente usamos as funções Lambda quando precisamos de uma função por um período curto de tempo, podemos também usá-las como argumentos para funções de **high-order** (funções que recebem outras funções como argumento). 90 | 91 | **Funções lambda** também podem ser usadas com outras funções pré-construídas, como **filter()**, **map()**, etc. 92 | 93 | #### Filtrando 94 | 95 | Por exemplo, com **filter()**, que recebe uma função e uma lista como argumento. 96 | 97 | ```python 98 | lista = [1,2,3,4,5] 99 | 100 | nova_lista = list(filter(lambda x: (x % 2 == 0), lista)) 101 | 102 | print(nova_lista) # [2, 4] 103 | ``` 104 | 105 | Veja que a expressão lambda calculará o resto de divisão de cada valor da lista, caso o valor seja 0 o número será filtrado para nossa nova lista, formando assim uma lista de números pares. 106 | 107 | #### Mapeando 108 | 109 | Por exemplo, com **map()**, que também recebe uma função e uma lista como argumento. 110 | 111 | ```python 112 | lst = [3,5,6,7,9] 113 | 114 | nova_lst = list(map(lambda y: y * 10, lst)) 115 | 116 | print(nova_lst) # [30, 50, 60, 70, 90] 117 | ``` 118 | 119 | Dessa vez a expressão lambda multiplicará cada item da lista por 10 e estes serão mapeados em uma nova lista. 120 | 121 | Podemos usar esta ideia para converter de uma lista de temperaturas em grau Celsius para grau Fahrenheit. 122 | 123 | ```python 124 | celsius = [31.5, 22.1, 17.5, 42.8] 125 | 126 | fahrenheit = map(lambda x: (float(9)/5)*x + 32, celsius) 127 | 128 | print(list(fahrenheit)) # [88.7, 71.78, 63.5, 109.03999999999999] 129 | ``` 130 | 131 | #### Ordenando 132 | 133 | Através do método **sort()** podemos por exemplo organizar uma **lista** com uma expressão lambda. Vejamos um exemplo para ilustrar esta ideia: 134 | 135 | ```python 136 | alimentos = [('ovos', 10),('pães', 5),('tomate', 6),('cenoura', 4),('maçã', 3)] 137 | ``` 138 | 139 | Ordenando os alimentos por ordem alfabética: 140 | 141 | ```python 142 | alimentos.sort(key = lambda x: x[0]) 143 | print(alimentos) 144 | # [('cenoura', 4), ('maçã', 3), ('ovos', 10), ('pães', 5), ('tomate', 6)] 145 | ``` 146 | 147 | Ordenando os alimentos por quantidade crescente: 148 | 149 | ```python 150 | alimentos.sort(key = lambda x: x[1]) 151 | print(alimentos) 152 | # [('maçã', 3), ('cenoura', 4), ('pães', 5), ('tomate', 6), ('ovos', 10)] 153 | ``` 154 | 155 | Obtendo o alimento com a maior quantidade: 156 | 157 | ```python 158 | print(max(alimentos, key = lambda x: x[1])) # ('ovos', 10) 159 | ``` 160 | 161 | Obtendo o alimento com a menor quantidade: 162 | 163 | ```python 164 | print(min(alimentos, key = lambda x: x[1])) # ('maçã', 3) 165 | ``` 166 | 167 | #### Função que cria Funções 168 | 169 | É possível criarmos uma função que nos **retorna** uma expressão lambda para assim realizarmos cálculos: 170 | 171 | ```python 172 | # Função que cria funções 173 | def construcao_quadraticas(a, b, c): 174 | """Retorna a função f(x) = ax^2 + bx + c""" 175 | return lambda x: a*x**2 + b*x + c 176 | 177 | # Constrói uma nova função com os parâmetros (4,7,-6) 178 | f = construcao_quadraticas(4,7,-6) 179 | 180 | print(f(0)) # -6 181 | print(f(3)) # 51 182 | ``` 183 | 184 | Muito legal e útil, não? **Expressões lambdas** podem agilizar bastante nossa vida. -------------------------------------------------------------------------------- /Capitulos/23.ExpressõesRegulares.md: -------------------------------------------------------------------------------- 1 | # Expressões Regulares 2 | 3 | **Expressões regulares** são um mecanismo muito poderoso para manipulação de **strings**, também conhecido como **regex** ou **regexp**, é um campo de estudo muito abrangente na **ciência da computação teórica** e **linguagens formais**. 4 | 5 | Pode-se dizer que é uma sequência de caracteres que define um padrão de busca, normalmente este padrão é usado por algoritmos de busca de strings, onde é feito uma busca por determinado padrão, seja para encontrá-lo ou até mesmo encontrá-lo e alterá-lo, também é muito usado para *validação de input de dados*. 6 | 7 | O conceito surgiu na década de 1950, quando o matemático americano [Stephen Cole Kleene](https://en.wikipedia.org/wiki/Stephen_Cole_Kleene) formalizou a descrição de uma [linguagem regular](https://en.wikipedia.org/wiki/Regular_language). O conceito entrou em uso comum com utilitários de processamento de texto do Unix. Diferentes sintaxes para escrever expressões regulares existem desde a década de 1980, sendo uma o padrão [POSIX](https://en.wikipedia.org/wiki/POSIX) e outra, amplamente utilizada, a sintaxe [Perl](https://en.wikipedia.org/wiki/Perl). 8 | 9 | Expressões regulares são usadas em [search engines](https://en.wikipedia.org/wiki/Search_engine), *search and replace dialogs* de processadores de texto e editores de texto, em utilitários de processamento de texto como [sed](https://en.wikipedia.org/wiki/Sed) e [AWK](https://en.wikipedia.org/wiki/AWK) e em análise lexical. Muitas linguagens de programação fornecem recursos de regex integrados ou por meio de bibliotecas, como é o caso da linguagem Python que nos oferece a biblioteca [re](https://docs.python.org/3/library/re.html). 10 | 11 | ## Introdução 12 | 13 | Uma expressão regular, geralmente chamada de padrão, especifica um conjunto de strings necessárias para um propósito específico. Uma maneira simples de especificar um conjunto finito de strings é listar seus elementos ou membros. No entanto, muitas vezes existem maneiras mais concisas, por exemplo, o conjunto contendo as três cadeias de caracteres "Handel", "Händel" e "Haendel" pode ser especificado pelo padrão `H(ä|ae?)Ndel`, dizemos que esse padrão corresponde a cada uma das três strings. Na maioria dos formalismos, se existe pelo menos uma expressão regular que corresponde a um determinado conjunto, então existe um número infinito de outras expressões regulares que também correspondem a ela - a especificação não é única. 14 | 15 | **Âncoras**: `^` e `$` 16 | 17 | | Exemplo | Descrição | URL | 18 | |----------|------------------------------------------------|------------------------------------| 19 | | ^Py | Encontra qualquer string que comece com Py | **https://regex101.com/r/cO8lqs/4303** | 20 | | on$ | Encontra uma string que termina com on | **https://regex101.com/r/cO8lqs/4304** | 21 | | ^Python$ | Encontra a string Python | **https://regex101.com/r/cO8lqs/4305** | 22 | | Python | Encontra qualquer string que tenha Python em si | **https://regex101.com/r/cO8lqs/23892** | 23 | 24 | **Quantificadores**: `*`, `+`, `?` e `{}` 25 | 26 | | Exemplo | Descrição | 27 | |------------|-------------------------------------------------------------------------------------| 28 | | abc* | Encontra uma string que tenha ab seguido por zero ou mais c | 29 | | abc+ | Encontra uma string que tenha ab seguido por um ou mais c | 30 | | abc? | Encontra uma string que tenha ab seguido por zero, ou um c | 31 | | abc{2} | Encontra uma string que tenha ab seguido por dois c | 32 | | abc{2,} | Encontra uma string que tenha ab seguido por dois ou mais c | 33 | | abc{2,5} | Encontra uma string que tenha ab seguido por 2 até no máximo 5 c | 34 | | a(bc)* | Encontra uma string que tenha a seguido por zero ou mais cópias da sequência bc | 35 | | a(bc){2,5} | Encontra uma string que tenha a seguido por 2 até no máximo 5 cópias da sequência bc | 36 | 37 | **Operador OU**: `|` e `[]` 38 | 39 | | Exemplo | Descrição | 40 | |---------|-----------------------------------------------------------------------------------| 41 | | a(b\|c) | Encontra uma string que tenha a seguido por b ou c | 42 | | a[bc] | Igual o anterior, ambas as notações podem ser usadas e produzem o mesmo resultado | 43 | 44 | **Classes de caracteres**: `\d`, `\w`, `\s` e `.` 45 | 46 | | Exemplo | Descrição | 47 | |---------|-------------------------------------------------------------------------| 48 | | \d | Encontra um único caracter que seja um dígito | 49 | | \w | Encontra um caracter de palavra (caracter alfanumérico e underline) | 50 | | \s | Encontra caracteres de espaço em branco (incluindo tabs e quebra de linha) | 51 | | . | Encontra qualquer caracter | 52 | 53 | **Negação de classe de caracteres**: `\D`, `\W`, `\S` 54 | 55 | | Exemplo | Descrição | 56 | |---------|-----------------------------------------------------------| 57 | | \D | Faz a operação inversa de \d e traz todos os não-dígitos | 58 | | \W | Faz a operação inversa de \w e traz todas as não-palavras | 59 | | \S | Faz a operação inversa de \s e traz todos os não-espaços | 60 | 61 | Outro ponto importante, é caso queiramos dar **escape**, por exemplo validar um `.`, para isso usamos o `\.` 62 | 63 | O mesmo vale caso seja necessário validarmos `$`, utilizamos `\$` 64 | 65 | Experimente mais opções de expressões em **[Regex101](https://regex101.com/r/cO8lqs/1)** 66 | 67 | ## Expressões Regulares em Python 68 | 69 | Python já possui incluído o módulo **re** que utilizaremos para nossas **expressões regulares**, este módulo fornece operações de correspondência de expressões regulares semelhantes às encontradas em Perl. 70 | 71 | Para usá-lo precisamos importá-lo, sem a necessidade de instalação, vamos também inspecionar o módulo para termos uma visão do que ele nos disponibiliza em termos de atributos e métodos. 72 | 73 | ```python 74 | import re 75 | 76 | print(dir(re)) 77 | # ['A', 'ASCII', 'DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE', 'M', 'MULTILINE', 'S', 'Scanner', 'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', '_alphanum_bytes', '_alphanum_str', '_cache', '_cache_repl', '_compile', '_compile_repl', '_expand', '_locale', '_pattern_type', '_pickle', '_subx', 'compile', 'copyreg', 'error', 'escape', 'findall', 'finditer', 'fullmatch', 'match', 'purge', 'search', 'split', 'sre_compile', 'sre_parse', 'sub', 'subn', 'sys', 'template'] 78 | ``` 79 | 80 | Veja que temos bastantes opções para trabalharmos, inicialmente vamos ver os métodos mais relevantes através de diversos exemplos, mas primeiramente é importante entendermos o conceito de *raw string*, pois são elas que vamos utilizar em nossas expressões regulares. 81 | 82 | Uma *raw string* do Python é uma string normal, prefixada com **r** ou **R**. Isso trata caracteres como barra invertida (`\`) como um caractere literal. Isso também significa que esse caractere não será tratado como um caractere de escape, por exemplo: 83 | 84 | ```python 85 | print('Hello\nWorld') 86 | # Hello 87 | # World 88 | ``` 89 | 90 | Veja que o *output* é tratado como esperado, o escape caracter `\n` é interpretado como uma quebra de linha, já no caso de uma *raw string*, ele será tratado como um caractere literal: 91 | 92 | ```python 93 | print(r'Hello\nWorld') # Hello\nWorld 94 | ``` 95 | 96 | Agora que sabemos como as *raw strings* funcionam, vamos ver os métodos de expressões regulares. 97 | 98 | ### findall() 99 | 100 | O método **findall()** retorna todas as porções correspondidas como uma lista de strings. Ele conta com os seguintes argumentos: 101 | 102 | - padrão 103 | - string 104 | - flags 105 | 106 | O primeiro argumento é o padrão que desejamos testar e extrair em relação à string de *input*, que é o segundo argumento. O último argumento flags é opcional. Vamos então aos exemplos para uma melhor compreensão: 107 | 108 | ```python 109 | resultados = re.findall(r'ab*c', 'abc ac adc abbbc abbb') 110 | print(resultados) # ['abc', 'ac', 'abbbc'] 111 | ``` 112 | 113 | No exemplo acima usamos o quantificador `*`, que indica 0 ou mais **b**'s. 114 | 115 | ```python 116 | resultados = re.findall(r'ab+c', 'abc ac adc abbbc abbb') 117 | print(resultados) # ['abc', 'abbbc'] 118 | ``` 119 | 120 | No exemplo acima usamos o quantificador `+`, que indica 1 ou mais **b**'s. 121 | 122 | Vejamos como podemos definir uma expressão regular para encontrar caracteres de palavras: 123 | 124 | ```python 125 | import re 126 | 127 | x = "Expressões regulares são legais" 128 | r = re.findall(r"\w+", x) 129 | print(r) # ['Expressões', 'regulares', 'são', 'legais'] 130 | ``` 131 | 132 | Como podemos ver, todos os caracteres da sentença foram correspondidos e recebemos uma lista deles. 133 | 134 | ### split() 135 | 136 | O método **split()** divida a string pelas ocorrências do padrão. 137 | 138 | ```python 139 | import re 140 | 141 | e = "Eu sou uma expressao com diversas palavras" 142 | r = re.split(r'\s', e) 143 | print(r) # ['Eu', 'sou', 'uma', 'expressao', 'com', 'diversas', 'palavras'] 144 | ``` 145 | 146 | Como podemos ver, a função **split()** separou a expressão em uma lista de palavras, usando o separador `\s` que representa o espaço em branco. 147 | 148 | Vamos agora usar um dígito como separador: 149 | 150 | ```python 151 | string = 'um:1 dois:2 quinze:15 trinta:30' 152 | padrao = r'\d+' 153 | resultado = re.split(padrao, string) 154 | print(resultado) # ['um:', ' dois:', ' quinze:', ' trinta:', ''] 155 | ``` 156 | 157 | ### search() 158 | 159 | Normalmente, usamos o operador **in** para testar se uma string faz parte de outra string ou não. Para expressões regulares, usamos a função **search()** cuja lista de argumentos é mostrada abaixo: 160 | 161 | - padrão 162 | - string 163 | - flags 164 | 165 | O primeiro argumento é o padrão de expressão regular que você deseja testar contra a string de *input*, que é o segundo argumento, flags é opcional, ajuda a alterar o comportamento padrão dos padrões de expressões regulares. 166 | 167 | Como uma boa prática, é interessante usar *raw strings* para construir o padrão de expressão regular. Vejamos então alguns exemplos: 168 | 169 | ```python 170 | import re 171 | 172 | sentenca = "esta é uma string" 173 | 174 | print('esta' in sentenca) # True 175 | print('este' in sentenca) # False 176 | 177 | print(bool(re.search(r'esta',sentenca))) # True 178 | print(bool(re.search(r'este',sentenca))) # False 179 | print(type(re.search(r'esta',sentenca))) # 180 | print(type(re.search(r'este',sentenca))) # 181 | ``` 182 | 183 | O valor de retorno da função **search()** é um objeto `re.Match` quando há uma correspondência, caso contrário o resultado é `NoneType`. 184 | 185 | Vejamos agora um exemplo usando o argumento flags: 186 | 187 | ```python 188 | print(bool(re.search(r'Esta',sentenca))) # False 189 | print(bool(re.search(r'Esta',sentenca, flags=re.I))) # True 190 | ``` 191 | 192 | A flag `re.I` significa **IGNORECASE** é uma flag para permitir correspondência sem distinção entre maiúsculas e minúsculas. 193 | 194 | Vejamos agora um exemplo com expressões geradoras: 195 | 196 | ```python 197 | palavras = ['cachorro','macarrão','macaco'] 198 | 199 | [p for p in palavras if re.search(r'rr',p)] # ['cachorro', 'macarrão'] 200 | all(re.search(r'ca',p) for p in palavras) # True 201 | any(re.search(r'xa',p) for p in palavras) # False 202 | ``` 203 | 204 | Vejamos agora como podemos utilizar um quantificador em nossa padrão: 205 | 206 | ```python 207 | import re 208 | 209 | padrao = "a*b" 210 | r = re.search(padrao, "aaaaaaabcedefg") 211 | print(r) # <_sre.SRE_Match object; span=(0, 8), match='aaaaaaab'> 212 | print(r.group()) # aaaaaaab 213 | ``` 214 | 215 | Como podemos ver, primeiro nos foi retornado um **objeto match**, posteriormente acessamos a string encontrada através do método **group()** que nos traz o resultado, também podemos aplicar métodos como **start()**, **end()** e **span()**. 216 | 217 | ### sub() 218 | 219 | Para busca e substituição normais, podemos usar o método **str.replace()**. Para expressões regulares, usamos a função **sub()**, cuja lista de argumentos é mostrada abaixo: 220 | 221 | - padrão 222 | - substituição 223 | - string 224 | - count 225 | - flags 226 | 227 | O primeiro argumento é o padrão de expressão regular a ser correspondido em relação à string de *input*, que é o terceiro argumento. O segundo argumento específica a string que irá substituir as porções correspondidas pelo padrão da expressão regular. Os últimos dois argumentos são opcionais. Para entendermos melhor este conceito, vamos ao exemplo: 228 | 229 | ```python 230 | frase = 'eu gosto de pizza' 231 | 232 | print(re.sub(r'z','Z',frase)) # eu gosto de piZZa 233 | print(re.sub(r'z','Z',frase,count=1)) # eu gosto de piZza 234 | ``` 235 | 236 | Observe que o argumento **count** limita o número de substituições. 237 | 238 | ### Compilando Expressões Regulares 239 | 240 | Expressões Regulares podem ser compiladas usando a função **compile()**, que nos retorna um objeto `re.Pattern`. 241 | 242 | As funções do módulo **re** de nível superior estão todas disponíveis como métodos para tais objetos. Compilando uma expressão regular é útil se ela tiver que ser usada em vários lugares ou chamada em vários vezes dentro de um loop (benefício de velocidade). 243 | 244 | Vamos começar compilando uma expressão regular: 245 | 246 | ```python 247 | animal = re.compile(r'gato') 248 | print(type(animal)) # 249 | ``` 250 | 251 | Usaremos agora o o método **search()** no padrão definido por nós para buscar pelo padrão em uma determinada string: 252 | 253 | ```python 254 | bool(animal.search('o gato é bonito')) # True 255 | bool(animal.search('o rato é roedor')) # False 256 | ``` 257 | 258 | Também podemos usar o método **sub** neste padrão, de forma a executar substituções: 259 | 260 | ```python 261 | animal.sub('rato','o gato fugiu do cachorro') 262 | # 'o rato fugiu do cachorro' 263 | ``` 264 | 265 | ### match() 266 | 267 | O método **match()** funciona da seguinte forma: Se zero ou mais caracteres no início da string corresponderem a expressão regular informada, retorna um objeto de `re.Match` correspondente. Retorna `None` se a string não corresponder ao padrão. 268 | 269 | Neste exemplo vamos usar um padrão simples para darmos **match** em um email: 270 | 271 | ```python 272 | import re 273 | 274 | padrao = r"\w+@(\w+\.)+(com|org|net)" 275 | r = re.match(padrao,"teste@teste.org") 276 | print(r) # 277 | print(r.group()) # teste@teste.org 278 | ``` 279 | 280 | Vimos que nesse caso, foi possível dar match no e-mail `teste@teste.org`, nos mostrando assim a relevância e importância das expressões regulares dentro da computação, um assunto relevante e de compreensão necessária, pois está presente em praticamente todas as linguagens de programação e sua aplicabilidade é muito vasta. -------------------------------------------------------------------------------- /Capitulos/24.PythonJSON.md: -------------------------------------------------------------------------------- 1 | # JSON 2 | 3 | Na computação, **[JSON](https://www.json.org/)** ou **Javascript Object Notation** é um padrão aberto de formato de arquivo que utiliza textos legíveis para humanos para transmistir objetos de dados que consistem de *pares de atributos-valores* e tipos de dados **array** (ou qualquer outro valor serializável), é um formato de dados de uso muito comum para comunicação *asíncrona de cliente-servidor*. 4 | 5 | É importante destacar, que embora JSON carregue Javascript no seu nome, ele é independente e vale para qualquer linguagem de programação. 6 | 7 | Os tipos básicos de dados do JSON são: 8 | 9 | - **Number**: Um número decimal com sinal que pode conter uma parte fracionária e pode usar a notação exponencial **E**, mas não pode incluir não-números como **NaN**. O formato não faz distinção entre integer e floating-point. 10 | - **String**: Uma sequência de zero ou mais caracteres Unicode. Strings são delimitadas com aspas duplas e oferecem suporte a uma sintaxe de escape de barra invertida. 11 | - **Boolean**: Um valor `true` ou `false` 12 | - **Array**: Uma lista ordenada de zero ou mais valores, cada um dos quais pode ser de qualquer tipo. Arrays usam notação de colchetes com elementos separados por vírgula. 13 | - **Object**: Uma coleção de pares **nome-valor** onde os nomes (também chamados de chaves) são strings. Os objetos têm o objetivo de representar arrays associativos, onde cada chave é única dentro de um objeto. Os objetos são delimitados por chaves e usam vírgulas `,` para separar cada par, enquanto dentro de cada par o caractere `:` separa a **chave** ou **nome** de seu **valor**. 14 | - **null**: Um valor vazio, utilizando a palavra `null` 15 | 16 | Para entendermos melhor o **JSON**, vamos definir um arquivo `pessoa.json` que descreverá uma pessoa: 17 | 18 | ```javascript 19 | { 20 | "primeiroName": "Miguel", 21 | "segundoName": "Arcanjo", 22 | "estaVivo": true, 23 | "idade": 27, 24 | "endereço": { 25 | "rua": "Rua Alfa 33", 26 | "cidade": "São Paulo", 27 | "estado": "SP", 28 | "codigoPostal": "1321-32423" 29 | }, 30 | "numerosTelefones": [ 31 | { 32 | "tipo": "casa", 33 | "numero": "212 555-1234" 34 | }, 35 | { 36 | "tipo": "escritorio", 37 | "numero": "646 555-4567" 38 | }, 39 | { 40 | "tipo": "celular", 41 | "numero": "123 456-7890" 42 | } 43 | ], 44 | "criancas": [], 45 | "cônjuge": null 46 | } 47 | ``` 48 | 49 | Como podermos ver, **JSON** é bastante legível e acessível, fazendo com que seja excelente para estruturarmos dados, nesse caso, veja que temos um objeto **pessoa**. 50 | 51 | Dentro do objeto pessoas temos diversos atributos: 52 | 53 | - **primeiroName**: String representando o primeiro nome da pessoa 54 | - **segundoName**: String representando o sobrenome da pessoa 55 | - **estaVivo**: Boolean representando se a pessoa está viva ou não 56 | - **idade**: Number integer representando a idade da pessoa 57 | - **endereço**: Um objeto com quatro atributos (rua, cidade, estado, codigoPostal) representando o endereço da pessoa 58 | - **numerosTelefones**: Um array contendo três objetos, representando os telefones da pessoa 59 | - **criancas**: Um array representando as crianças da pessoa, neste exemplo ele está vazio 60 | - **cônjuge**: Campo representando se a pessoa é casada, neste exemplo está `null` 61 | 62 | Para utilizarmos **JSON** em **Python**, contamos com o módulo **json**, que podemos importá-lo facilmente, sem a necessida de instalação: 63 | 64 | ```python 65 | import json 66 | ``` 67 | 68 | ## Parse de JSON, Convertendo JSON para Python 69 | 70 | Em Python, caso tenhamos uma string JSON, nós usamos o método **json.loads()** para fazer o **parse** e convertermos em um dicionário para que seja mais fácil de trabalharmos com os dados. 71 | 72 | Veja que além do arquivo `.json`, também podemos ter JSON armazenado como uma string: 73 | 74 | ```python 75 | import json 76 | 77 | pessoa = '{ "nome":"Rafael", "idade":29, "cidade":"São Paulo"}' 78 | 79 | pessoa_dict = json.loads(pessoa) 80 | print(type(pessoa_dict)) # 81 | print(pessoa_dict) # {'nome': 'Rafael', 'idade': 29, 'cidade': 'São Paulo'} 82 | print(pessoa_dict['idade']) # 29 83 | ``` 84 | 85 | ## Convertendo Python para JSON 86 | 87 | Se quisermos, também podemos converter um objeto de Python em uma string JSON, para esta tarefa vamos usar o método **json.dumps()**. 88 | 89 | Vamos definir um dicionário Python e fazer sua conversão: 90 | 91 | ```python 92 | import json 93 | 94 | pessoa = { 95 | "nome": "Gabriel", 96 | "idade": 27, 97 | "país": "Brasil" 98 | } 99 | 100 | pessoa_json = json.dumps(pessoa) # 101 | print(pessoa_json) # {"nome": "Gabriel", "idade": 27, "pa\u00eds": "Brasil"} 102 | ``` 103 | 104 | Perceba que ele não nos retornou os dados na codificação correta, para obtermos os dados em UTF-8, devemos setar o atributo **ensure_ascii** como `False`: 105 | 106 | ```python 107 | pessoa_json = json.dumps(pessoa, ensure_ascii=False) 108 | print(pessoa_json) # '{"nome": "Gabriel", "idade": 27, "país": "Brasil"}' 109 | ``` 110 | 111 | É possível converter os seguintes objetos em **Python** para **JSON**, e eles receberão um valor de equivalência em JSON como mostra a seguinte tabela: 112 | 113 | | Python | JSON | 114 | |--------|--------| 115 | | dict | Object | 116 | | list | Array | 117 | | tuple | Array | 118 | | str | String | 119 | | int | Number | 120 | | float | Number | 121 | | True | true | 122 | | False | false | 123 | | None | null | 124 | 125 | ## Exemplo com todos os Tipos de Dados 126 | 127 | Para compreendermos melhor o funcionamento da biblioteca json, vamos agora trabalhar em um exemplo contendo todos os tipos possíveis de dados. 128 | 129 | ```python 130 | import json 131 | 132 | personagem = { 133 | "nome": "Talantyr", 134 | "epiteto": "O Glorioso", 135 | "nível": 45, 136 | "vivo": True, 137 | "atributos": {"força": 45, "destreza": 60, "inteligência": 70}, 138 | "mascotes": ("Lobo","Coruja"), 139 | "magias": None, 140 | "itens": [ 141 | {"nome": "poção de mana", "quantidade": 5}, 142 | {"nome": "poção de vida", "quantidade": 7} 143 | ] 144 | } 145 | 146 | print(json.dumps(personagem, ensure_ascii=False)) 147 | # {"nome": "Talantyr", "epiteto": "O Glorioso", "nível": 45, "vivo": true, "atributos": {"força": 45, "destreza": 60, "inteligência": 70}, "mascotes": ["Lobo", "Coruja"], "magias": null, "itens": [{"nome": "poção de mana", "quantidade": 5}, {"nome": "poção de vida", "quantidade": 7}]} 148 | ``` 149 | 150 | Para obtermos um output mais limpo, podemos setar o atributo **indent** com um determinado número, neste caso específico, **4**: 151 | 152 | ```python 153 | print(json.dumps(personagem, ensure_ascii=False, indent=4)) 154 | ``` 155 | 156 | Dessa vez, temos o resultado que esperamos: 157 | 158 | ```javascript 159 | { 160 | "nome": "Talantyr", 161 | "epiteto": "O Glorioso", 162 | "nível": 45, 163 | "vivo": true, 164 | "atributos": { 165 | "força": 45, 166 | "destreza": 60, 167 | "inteligência": 70 168 | }, 169 | "mascotes": [ 170 | "Lobo", 171 | "Coruja" 172 | ], 173 | "magias": null, 174 | "itens": [ 175 | { 176 | "nome": "poção de mana", 177 | "quantidade": 5 178 | }, 179 | { 180 | "nome": "poção de vida", 181 | "quantidade": 7 182 | } 183 | ] 184 | } 185 | ``` 186 | 187 | Caso queiramos os atributos do resultado ordenados, podemos usar o parâmetro **sort_keys** como `True`: 188 | 189 | ```python 190 | print(json.dumps(p, indent=4, sort_keys=True)) 191 | ``` 192 | 193 | Dessa vez, temos o seguinte resultado: 194 | 195 | ```javascript 196 | { 197 | "atributos": { 198 | "destreza": 60, 199 | "força": 45, 200 | "inteligência": 70 201 | }, 202 | "epiteto": "O Glorioso", 203 | "itens": [ 204 | { 205 | "nome": "poção de mana", 206 | "quantidade": 5 207 | }, 208 | { 209 | "nome": "poção de vida", 210 | "quantidade": 7 211 | } 212 | ], 213 | "magias": null, 214 | "mascotes": [ 215 | "Lobo", 216 | "Coruja" 217 | ], 218 | "nome": "Talantyr", 219 | "nível": 45, 220 | "vivo": true 221 | } 222 | ``` 223 | 224 | Se quisermos, podemos facilmente converter o dicionário personagem em JSON (como já vimos anteriormente) e em seguida, salvar os dados em um arquivo de nome `personagem.json`: 225 | 226 | ```python 227 | dados_json = json.dumps(personagem, ensure_ascii=False, indent=4) 228 | 229 | with open('personagem.json','w') as json_file: 230 | json_file.write(dados_json) 231 | ``` 232 | 233 | Como podemos observar, os dados agora persistem no arquivo [personagem.json](https://github.com/the-akira/Python-Iluminado/blob/master/Arquivos/personagem.json) 234 | 235 | ## Utilizando uma API 236 | 237 | Vamos consumir uma simples [API](https://en.wikipedia.org/wiki/Representational_state_transfer) de testes para entendermos melhor a interação com outras aplicações que expõem seus serviços online. 238 | 239 | ```python 240 | import json 241 | import requests 242 | 243 | r = requests.get('https://jsonplaceholder.typicode.com/posts') 244 | posts = r.json() 245 | 246 | for post in posts: 247 | print(post) # Imprime todos os posts 248 | print(post['id']) # Imprime todos os ids 249 | print(post['title']) # Imprime todos os títulos 250 | print(post['body']) # Imprime todos os textos 251 | ``` 252 | 253 | Como podemos observar, conseguimos obter os dados com sucesso e agora podemos trabalhar com eles da forma que desejarmos. 254 | 255 | Experimente esta ideia trabalhando com outras API's, por exemplo a do [GitHub](https://api.github.com/). 256 | 257 | ## JSONPickle 258 | 259 | A biblioteca **[jsonpickle](https://jsonpickle.github.io/)** nos permite **serializar** e **deserializar** objetos complexos em Python para JSON e também de JSON. 260 | 261 | Para podermos usar suas funcionalidades, precisamos instalar ela com um simples comando: 262 | 263 | ``` 264 | pip install jsonpickle 265 | ``` 266 | 267 | Vejamos exemplos dela para ilustrar o seu uso. 268 | 269 | Vamos começar criando um objeto `Gato`: 270 | 271 | ```python 272 | class Gato: 273 | def __init__(self, nome, raca): 274 | self.nome = nome 275 | self.raca = raca 276 | ``` 277 | 278 | Agora vamos criar um novo `Gato` 279 | 280 | ```python 281 | gato = Gato('Osíris','Sphynx') 282 | ``` 283 | 284 | Transformando o objeto `Gato` em uma string JSON e salvando em um arquivo: 285 | 286 | ```python 287 | import jsonpickle 288 | 289 | jsonpickle.set_preferred_backend('json') 290 | jsonpickle.set_encoder_options('json', ensure_ascii=False) 291 | 292 | with open('gato.json', 'w') as file: 293 | frozen = jsonpickle.encode(gato) 294 | file.write(frozen) 295 | ``` 296 | 297 | Nosso objeto agora persiste no arquivo [gato.json](https://github.com/the-akira/Python-Iluminado/blob/master/Arquivos/gato.json) 298 | 299 | Lendo o arquivo JSON e decodificando para recriar o objeto `Gato`: 300 | 301 | ```python 302 | with open('gato.json', 'r') as file: 303 | contents = file.read() 304 | unfrozen = jsonpickle.decode(contents) 305 | print(unfrozen) # <__main__.Gato object at 0x7efdfeeca5c0> 306 | print(unfrozen.raca) # Sphynx 307 | print(unfrozen.nome) # Osíris 308 | ``` 309 | 310 | Essa breve introdução nos mostrou a importância do **JSON** atualmente e a capacidade que o Python tem de manipulá-lo com uma certa facilidade, inclusive. 311 | 312 | Se você deseja obter mais detalhes sobre a biblioteca padrão json em Python, visite **[docs.python](https://docs.python.org/3/library/json.html)**. Bons estudos! -------------------------------------------------------------------------------- /Capitulos/25.PythonXML.md: -------------------------------------------------------------------------------- 1 | # XML 2 | 3 | **[XML](https://en.wikipedia.org/wiki/XML)** se refere a *"Extensible Markup Language"*, é uma **[markup language](https://en.wikipedia.org/wiki/Markup_language)** que define um conjunto de regras para a codificação de documentos em um formato tanto legível por humanos quanto por máquina. 4 | 5 | Com similaridades ao famoso **HTML**, sua proposta principal é guardar e transportar dados, sendo uma linguagem auto-descritiva. **XML** funciona como uma estrutura de árvore que é fácil de interpretar e suporta hierarquia. 6 | 7 | Os objetivos de design do XML enfatizam a simplicidade, generalidade e usabilidade na Internet. É um formato de dados textual com forte suporte via [Unicode](https://en.wikipedia.org/wiki/Unicode) para diferentes idiomas humanos. Embora o design de XML se concentre em documentos, a linguagem é amplamente utilizada para a representação de estruturas de dados arbitrárias, como aquelas usadas em [serviços web](https://en.wikipedia.org/wiki/Web_service). 8 | 9 | **Documentos XML** possuem seções chamadas de **elementos**, sendo definidos por uma *tag de abertura e fechamento*. Tag é um constructo de markup que começa com `<` e termina com `>`. Os caracteres entre a tag de abertura e fechamento, caso tenha algum, é o conteúdo do elemento. 10 | 11 | Elementos podem conter markup, incluindo outros elementos, que nesse caso, são chamados de filhos. O elemento de maior nível é chamado de **root**, do inglês, raiz em português, esse seria o elemento que **engloba** todos os outros. *Atributos são pares de nome-valor* que existem dentro de uma tag de abertura ou uma tag de elemento vazio. Um atributo **XML** só pode ter um único valor e cada atributo pode aparecer no máximo uma vez em cada elemento. 12 | 13 | Para entendermos melhor o **XML**, vamos utilizar o arquivo [livros.xml](https://github.com/the-akira/Python-Iluminado/blob/master/Arquivos/livros.xml) como exemplo: 14 | 15 | ```xml 16 | 17 | 18 | 19 | Orwell, George 20 | Nineteen Eighty-Four: A Novel 21 | Dystopian 22 | 1949-06-08 23 | Thematically, Nineteen Eighty-Four centres on the consequences of totalitarianism, mass surveillance, and repressive regimentation of persons and behaviours within society. 24 | 25 | 26 | Huxley, Aldous 27 | Brave New World 28 | Dystopian 29 | 1932-12-16 30 | Largely set in a futuristic World State, whose citizens are environmentally engineered into an intelligence-based social hierarchy, the novel anticipates huge scientific advancements in reproductive technology, sleep-learning, psychological manipulation and classical conditioning that are combined to make a dystopian society which is challenged by only a single individual: the story's protagonist. 31 | 32 | 33 | Huxley, Aldous 34 | The Doors of Perception 35 | Psychology 36 | 1954-11-17 37 | The Doors of Perception provoked strong reactions for its evaluation of psychedelic drugs as facilitators of mystical insight with great potential benefits for science, art, and religion. 38 | 39 | 40 | Gibson, William 41 | Neuromancer 42 | Cyberpunk 43 | 1984-07-01 44 | Set in the future, the novel follows Henry Case, a washed-up computer hacker who is hired for one last job, which brings him up against a powerful artificial intelligence. 45 | 46 | 47 | Erickson, Jon 48 | Hacking: The Art of Exploitation 49 | Computer Security 50 | 2003-09-10 51 | Hacking: The Art of Exploitation is a book by Jon "Smibbs" Erickson about computer security and network security. 52 | 53 | 54 | Chollet, François 55 | Deep Learning with Python 56 | Machine Learning 57 | 2017-11-02 58 | Deep Learning with Python introduces the field of deep learning using the Python language and the powerful Keras library. Written by Keras creator and Google AI researcher François Chollet, this book builds your understanding through intuitive explanations and practical examples. 59 | 60 | 61 | Kant, Immanuel 62 | Critique of Pure Reason 63 | Philosophy 64 | 1787-11-02 65 | The Critique of Pure Reason is a book by the German philosopher Immanuel Kant, in which the author seeks to determine the limits and scope of metaphysics. 66 | 67 | 68 | Schopenhauer, Arthur 69 | The World as Will and Representation 70 | Philosophy 71 | 1818-12-06 72 | Taking the transcendental idealism of Immanuel Kant as his starting point, Schopenhauer argues that the world we experience around us—the world of objects in space and time and related in causal ways—exists solely as 'representation' (Vorstellung) dependent on a cognizing subject, not as a world that can be considered to exist in itself (independently of how it appears to the subject’s mind). 73 | 74 | 75 | ``` 76 | 77 | Como podemos ver, ele é fácil de compreender e legível, assim como os arquivos JSON, agora vamos começar a trabalhar com ele em **Python**, para isso vamos usar o módulo **[xml.etree.ElementTree](https://docs.python.org/3/library/xml.etree.elementtree.html)**, porém esteja atento que esse módulo *não é seguro contra dados maliciosos*, então esteja atento na segurança dos dados que você vai processar. 78 | 79 | O módulo **xml.etree.ElementTree** implementa uma API simples e eficiente para analisar e criar dados XML. 80 | 81 | Para trabalharmos com este módulo, é necessário apenas importá-lo, sem a necessidade de instalação. Vamos nos referir a ele apenas como **et** para ficar mais simples para trabalharmos: 82 | 83 | ```python 84 | import xml.etree.ElementTree as et 85 | ``` 86 | 87 | Para carregar o nosso arquivo, vamos utilizar o método **parse()**: 88 | 89 | ```python 90 | arquivo = et.parse('livros.xml') 91 | print(arquivo) 92 | # 93 | ``` 94 | 95 | Observe que nos é retornado um objeto **ElementTree**, que representa respectivamente uma árvore de elementos XML. Para obtermos a raiz (root) desta árvore, podemos usar o método **getroot()**: 96 | 97 | ```python 98 | raiz = arquivo.getroot() 99 | print(raiz) # 100 | print(raiz.tag) # 'catalog' 101 | ``` 102 | 103 | Como podemos ver, temos um objeto **Element** com o nome 'catalog', que representa o nosso catálogo de livros, a raiz de nossa árvore, com o atributo **tag** podemos acessar este valor. 104 | 105 | Uma vez que temos a raiz, podemos por exemplo iterar sob os children nodes, que são as tags filhas respectivamente: 106 | 107 | ```python 108 | for filhas in raiz: 109 | print(filhas.tag, filhas.attrib) 110 | 111 | # book {'id': 'bk101'} 112 | # book {'id': 'bk102'} 113 | # book {'id': 'bk103'} 114 | # book {'id': 'bk104'} 115 | # book {'id': 'bk105'} 116 | # book {'id': 'bk106'} 117 | # book {'id': 'bk107'} 118 | # book {'id': 'bk108'} 119 | ``` 120 | 121 | Neste exemplo específico, estamos obtendo o nome das tags filhas e seus respectivos atributos. 122 | 123 | As tags filhas são **encadeadas**, e para acessarmos seus valores específicos por índice, usamos esta notação: 124 | 125 | ```python 126 | print(raiz[0][0].text) # Orwell, George 127 | print(raiz[1][1].text) # Brave New World 128 | ``` 129 | 130 | Agora vamos utilizar o método **findall()** que nos permite procurar por **tags** que são filhas diretas do elemento atual que estamos usando. Além disso, temos também o método **find()** que procura o primeiro filho com uma tag particular e **Element.text** que acesso o conteúdo de texto do elemento. 131 | 132 | ```python 133 | for filhas in raiz.findall('book'): 134 | autor = filhas.find('author').text 135 | titulo = filhas.find('title').text 136 | print(f'Autor: {autor} | Título: {titulo}') 137 | 138 | # Autor: Orwell, George | Título: Nineteen Eighty-Four: A Novel 139 | # Autor: Huxley, Aldous | Título: Brave New World 140 | # Autor: Huxley, Aldous | Título: The Doors of Perception 141 | # Autor: Gibson, William | Título: Neuromancer 142 | # Autor: Erickson, Jon | Título: Hacking: The Art of Exploitation 143 | # Autor: Chollet, François | Título: Deep Learning with Python 144 | # Autor: Kant, Immanuel | Título: Critique of Pure Reason 145 | # Autor: Schopenhauer, Arthur | Título: The World as Will and Representation 146 | ``` 147 | 148 | Também podemos usar o método **iter()** que nos ajuda a iterar sob a árvore XML. Por exemplo: 149 | 150 | ```python 151 | descricoes = [d.text for d in raiz.iter('description')] 152 | print(descricoes[0]) 153 | # Thematically, Nineteen Eighty-Four centres on the consequences of totalitarianism, mass surveillance, and repressive regimentation of persons and behaviours within society. 154 | ``` 155 | 156 | ElementTree fornece uma maneira simples de construir documentos XML e gravá-los em arquivos. O método **write()** serve a esse propósito. 157 | 158 | Uma vez criado, um objeto Element pode ser manipulado alterando diretamente seus campos (como Element.text), adicionando e modificando atributos (método **set()**), bem como adicionando novos filhos (por exemplo, com **append()**). 159 | 160 | Imagine que queremos atualizar o gênero do livro **Neuromancer** para **Science Fiction**, podemos fazê-lo com o auxílio dos métodos **find()** e **findall()** e com um simples `if` testamos pela existência do gênero atual e o substituímos pelo novo, e através do método **set()** nós adicionamos um atributo `atualizado` para esta tag ``. 161 | 162 | ```python 163 | for genre in raiz.findall('book'): 164 | genero = genre.find('genre') 165 | if genero.text == 'Cyberpunk': 166 | genero.text = 'Science Fiction' 167 | genero.set('atualizado','sim') 168 | print(genero.text) 169 | 170 | arquivo.write('novo_livros.xml') 171 | ``` 172 | 173 | Finalmente, com o método **write()** salvamos os novos dados em um novo arquivo. 174 | 175 | Também podemos remover elementos usando o método **remove()**. Se quisermos por exemplo remover o elemento ``, podemos usar o método **findall()** para iterar sob todos os elementos livros e buscar especificamente o elemento **publish_date** e removê-lo com o método **remove()**. Novamente podemos salvar as alterações em um novo arquivo com **write()**. 176 | 177 | ```python 178 | for book in raiz.findall('book'): 179 | publish_date = book.find('publish_date') 180 | book.remove(publish_date) 181 | 182 | arquivo.write('new_livros.xml') 183 | ``` 184 | 185 | Essa foi uma introdução básica ao XML com Python, embora já não esteja tão popular como no passado por conta do poderoso JSON, é necessário que entendamos como funciona a estrutura do arquivo XML e se necessário como manipulá-lo. -------------------------------------------------------------------------------- /Capitulos/26.Iteradores.md: -------------------------------------------------------------------------------- 1 | # Iteradores 2 | 3 | Iteradores são objetos que podem ser iterados. Nesse guia vamos estudá-los e aprender como eles funcionam construindo um iterador usando os métodos `__iter__` e `__next__`. 4 | 5 | - Um objeto iterável é um objeto que implementa `__iter__`, que deve retornar um objeto iterador. 6 | - Um iterador é um objeto que implementa **next**, que deve retornar o próximo elemento do objeto iterável que o retornou e gerar uma exceção **StopIteration** quando não houver mais elementos disponíveis. 7 | 8 | ## Introdução 9 | 10 | **Iteradores** sempre estiveram conosco em Python, eles estão implementados nos **for loops**, **geradores**, etc, porém estão "escondidos". Um iterador é simplesmente um objeto que podemos iterar nele, ou seja, um objeto que retornará dados, um elemento de cada vez. 11 | 12 | O objeto iterador implementa dois métodos especiais `__iter__()` e `__next__()`, que são conhecidos como o protocolo do iterador. Um objeto é chamado de iterável se formos capazes de obter um iterador dele, estruturas como **lista**, **tupla** e **string** são iteráveis. A função **iter()** (que chama o método `__iter__`) retorna um iterador delas. 13 | 14 | Vamos então aos experimentos para entendermos melhor os iteradores, usaremos a função **next()** para iterar manualmente através de todos os itens de um iterador. Quando chegarmos ao fim e não houver mais dados para retorno, ocorrerá um erro **StopIteration**. 15 | 16 | ```python 17 | lista = [1,2,3,4] 18 | 19 | iterador = iter(lista) 20 | 21 | print(next(iterador)) # 1 22 | print(next(iterador)) # 2 23 | print(iterador.__next__()) # 3 24 | print(iterador.__next__()) # 4 25 | 26 | next(iterador) # Sem mais itens para iterar, erro StopIteration ocorre 27 | ``` 28 | 29 | Uma forma melhor e mais simples de iterar automaticamente seria usando um for loop. Usando ele, nós podemos iterar sob qualquer objeto que retorne um iterador, por exemplo uma lista, string, arquivo, etc. 30 | 31 | ```python 32 | for elemento in lista: 33 | print(lista) 34 | # 1 35 | # 2 36 | # 3 37 | # 4 38 | ``` 39 | 40 | Vimos que o **for** foi capaz de iterar automaticamente através da **lista**, agora vamos analisar como ele faz essa mágica internamente no Python: 41 | 42 | ```python 43 | for elemento in iteravel: 44 | # faça algo com o elemento 45 | ``` 46 | 47 | É na verdade: 48 | 49 | ```python 50 | # cria um objeto iterador do iteravel 51 | objeto_iteravel = iter(iteravel) 52 | 53 | # Loop infinito 54 | while True: 55 | try: 56 | # obtém o novo item 57 | elemento = next(objeto_iteravel) 58 | # faz algo com o elemento 59 | except StopIteration: 60 | # Se o StopIteration ocorrer, break no loop 61 | break 62 | ``` 63 | 64 | Veja que internamente o **for loop** cria um objeto iterador **objeto_iteravel** chamando o método **iter()** nele, e que na verdade ele é um **while loop**. Dentro desse while loop ele chama **next()** para pegar o próximo elemento e executar o for loop com esse valor, assim que todos os itens forem percorridos, StopIteration é acionado que é capturado internamente e o loop acaba, perceba que qualquer outra exceção irá passar. 65 | 66 | ## Criando um Iterador 67 | 68 | Para criar um **objeto**/**classe** como um iterador nós precisamos implementar os métodos `__iter__()` e `__next__()` no nosso objeto. Como aprendemos no nosso capítulo de Classes e Objetos, todas as classes possuem uma função chamada `__init__()`, que possibilita a inicialização quando o objeto é criado. O método `__iter__()` age similar, pode executar operações (inicializações, etc), mas sempre deve retornar o objeto iterador. O método `__next__()` também possibilita operações e deve retornar o próximo item na sequência. 69 | 70 | ```python 71 | class Numeros: 72 | def __iter__(self): 73 | self.x = 1 74 | return self 75 | 76 | def __next__(self): 77 | y = self.x 78 | self.x += 1 79 | return y 80 | 81 | n = Numeros() 82 | iterador = iter(n) 83 | 84 | print(next(iterador)) 85 | print(next(iterador)) 86 | print(next(iterador)) 87 | print(next(iterador)) 88 | print(next(iterador)) 89 | # 1 90 | # 2 91 | # 3 92 | # 4 93 | # 5 94 | ``` 95 | 96 | ## StopIteration 97 | 98 | O exemplo acima pode ser executado infinitamente, especialmente se aplicarmos um **for loop**. Para previnirmos que a iteração ocorra eternamente, podemos usar o comando **StopIteration** no método `__next__()`, nós podemos adicionar a condição de término para que o erro seja disparado caso a iteração ultrapasse a condição. 99 | 100 | ```python 101 | class Numeros: 102 | def __iter__(self): 103 | self.x = 1 104 | return self 105 | 106 | def __next__(self): 107 | if self.x <= 6: 108 | y = self.x 109 | self.x +=1 110 | return y 111 | else: 112 | raise StopIteration 113 | 114 | n = Numeros() 115 | iterador = iter(n) 116 | 117 | for elemento in iterador: 118 | print(elemento) 119 | # 1 120 | # 2 121 | # 3 122 | # 4 123 | # 5 124 | # 6 125 | ``` 126 | 127 | ## Iterador Aleatório 128 | 129 | Vejamos um iterador que nos retorna sequências de comprimento aleatórios de **1**'s. 130 | 131 | ```python 132 | import random 133 | 134 | class RandomIterable: 135 | def __iter__(self): 136 | return self 137 | def __next__(self): 138 | if random.choice(["go", "go", "stop"]) == "stop": 139 | raise StopIteration # finaliza o iterador 140 | return 1 141 | 142 | for x in RandomIterable(): 143 | print(x) 144 | # 1 145 | # 1 146 | # 1 147 | ``` 148 | 149 | Esses foram os iteradores, conceito importante e muito presente em nossos estudos, central na linguagem Python, vamos então continuar **iterando** nosso conhecimento. -------------------------------------------------------------------------------- /Capitulos/27.Geradores.md: -------------------------------------------------------------------------------- 1 | # Geradores 2 | 3 | Introduzidos no [PEP 255](https://www.python.org/dev/peps/pep-0255), as funções geradoras são um tipo especial de função que retorna um [lazy iterator](https://en.wikipedia.org/wiki/Lazy_evaluation). Esses são objetos que você pode percorrer como uma lista. No entanto, ao contrário das listas, os lazy iterators não armazenam seu conteúdo na memória. 4 | 5 | Em outras palavras, **Geradores** são **iteradores**, porém só podemos iterar sob eles uma vez, pelo fato deles não guardarem todos os valores em memória, eles vão gerando os valores conforme instruímos. Nós usamos os geradores iterando sob eles, seja com um **for loop** ou passando eles para uma função ou constructo que seja capaz de iterar. 6 | 7 | Na maioria das vezes os geradores são implementados como **funções**, entretanto, eles não retornam um valor com **return**, eles usam a palavra chave **yield**, que seria uma forma de ir guardando os valores. 8 | 9 | Veja agora um exemplo de uma função geradora. 10 | 11 | ```python 12 | def gerador(): 13 | for e in range(5): 14 | yield e 15 | 16 | for item in gerador(): 17 | print(item) 18 | # 0 19 | # 1 20 | # 2 21 | # 3 22 | # 4 23 | ``` 24 | 25 | Veja que nesse caso não há muita utilidade, geradores são melhores para calcular **grandes quantidades** de resultados (particularmente cálculos que envolvem loops) onde não queremos alocar memória para todos os resultados ao mesmo tempo, trata-se de **eficiência**. 26 | 27 | Agora veja um gerador que é capaz de calcular números **fibonacci**: 28 | 29 | ```python 30 | def fib_gen(n): 31 | a = b = 1 32 | for e in range(n): 33 | a, b = b, a + b 34 | yield a 35 | 36 | for x in fib_gen(7): 37 | print(x) 38 | # 1 39 | # 1 40 | # 2 41 | # 3 42 | # 5 43 | # 8 44 | # 13 45 | ``` 46 | 47 | Também podemos definir um gerador que irá gerar uma **sequência infinita**: 48 | 49 | ```python 50 | def sequencia_infinita(): 51 | num = 0 52 | while True: 53 | yield num 54 | num +=1 55 | 56 | for i in sequencia_infinita(): 57 | print(i,end=' ') 58 | ``` 59 | 60 | Este programa irá executar infinitamente até que o paremos, podemos usar o comando `CTRL + C` para isso. Outra opção que temos é usar o método **next()**, dessa vez vamos controlar o número de iterações: 61 | 62 | ```python 63 | gen = sequencia_infinita() 64 | for _ in range(501): 65 | print(next(gen),end=',') 66 | ``` 67 | 68 | Dessa vez serão gerados números de 0 até 500. 69 | 70 | ## Expressões Geradoras 71 | 72 | **Python** nos permite criar simples geradores usando **expressões geradoras**, fazendo com que o processo de criação de geradores seja muito mais simples. Assim como as funções lambda criam funções anônimas, expressões geradoras criam funções geradoras anônimas. 73 | 74 | A sintaxe da expressão geradora nos lembra as **list comprehensions**, porém os colchetes são alterados para parênteses. A grande diferença entre os dois é que a compreensão de lista produz a lista inteira de uma só vez, enquanto que a expressão geradora produz um item de cada vez, fazendo dela muito mais eficiente em questões de desempenho e memória. 75 | 76 | Para o exemplo, vamos começar inicializando uma lista: 77 | 78 | ```python 79 | lista = [1, 3, 6, 10, 14] 80 | ``` 81 | 82 | Elevamos ao cubo cada elemento da lista, usando uma list comprehension: 83 | 84 | ```python 85 | [x**3 for x in lista] # [1, 27, 216, 1000, 2744] 86 | ``` 87 | 88 | Veja que de imediato obtemos uma nova lista com todos os elementos elevados ao cubo. Se quisermos alterar para uma expressão geradora, apenas precisamos trocar os colchetes por parênteses: 89 | 90 | ```python 91 | gerador = (x**3 for x in lista) 92 | print(gerador) # at 0x7fd0067de9d0> 93 | ``` 94 | 95 | Dessa vez nos é retornado um objeto generator, que podemos iterar sob ele: 96 | 97 | ```python 98 | for gen in gerador: 99 | print(gen) 100 | # 1 101 | # 27 102 | # 216 103 | # 1000 104 | # 2744 105 | ``` 106 | 107 | Observe que a **expressão geradora** não produziu o resultado que esperávamos de forma imediata, na verdade retornou um **objeto gerador**, que é capaz de produzir items sob demanda. 108 | 109 | Inicializamos agora uma outra lista para vermos como um gerador funciona ao usarmos o método **next()**: 110 | 111 | ```python 112 | l = [2,3,6,9] # 113 | 114 | a = (x**4 for x in l) 115 | 116 | print(next(a)) # 16 117 | print(next(a)) # 81 118 | print(next(a)) # 1296 119 | print(next(a)) # 6561 120 | print(next(a)) 121 | # Traceback (most recent call last): 122 | # File "", line 1, in 123 | # StopIteration 124 | ``` 125 | 126 | Veja que ao atingirmos o limite da lista, o erro **StopIteration** ocorre. 127 | 128 | As **expressões geradoras** também podem ser usadas dentro de funções, por exemplo: 129 | 130 | ```python 131 | numeros = [4,5,6,7] 132 | 133 | print(sum(x**4 for x in numeros)) # 4578 134 | print(max(x**4 for x in numeros)) # 2401 135 | ``` 136 | 137 | ## Importância dos Geradores 138 | 139 | Agora uma questão importante. Por que geradores são usados em Python? 140 | 141 | 1. Fácil de implementar, geradores podem ser implementados de maneira clara e concisa, de forma muito mais simples que os iteradores 142 | 2. Eficiência de memória, por produzirem um item por vez e não gerarem toda a sequência de uma só vez, os geradores nos trazem bastante perfomance. 143 | 3. Nos permitem produzir um fluxo infinito de dados, uma vez que esses fluxos não podem ser guardados em memória por serem infinitos, os geradores nos permitem trabalhar com eles, uma vez que itens serão gerados um por vez. 144 | 145 | Para entendermos a eficiência de memória de um gerador, vamos compará-lo com uma list comprehension para observarmos a diferença de tamanho entre eles. Vamos começar definindo uma função geradora: 146 | 147 | ```python 148 | def gen(n): 149 | for i in range(n): 150 | yield i**2 151 | ``` 152 | 153 | Agora vamos construir uma list comprehension com 100.000 elementos e um gerador com o mesmo número e usaremos a função **getsizeof** do módulo **sys** para obtermos a quantidade ocupada de memória do objeto em bytes: 154 | 155 | ```python 156 | import sys 157 | 158 | x = [i**2 for i in range(100_000)] 159 | g = gen(100_000) 160 | 161 | print(sys.getsizeof(x)) # 824472 162 | print(sys.getsizeof(g)) # 128 163 | ``` 164 | 165 | Veja que temos uma diferença substancial, com este exemplo, concluímos que os geradores são extremamente eficientes! -------------------------------------------------------------------------------- /Capitulos/28.Decoradores.md: -------------------------------------------------------------------------------- 1 | # Decoradores 2 | 3 | **Decoradores** são um elemento significante do Python, também são conhecidos como **[meta-programação](https://en.wikipedia.org/wiki/Metaprogramming)**, para simplificarmos sua ideia, podemos dizer que eles são funções que modificam a funcionalidade de uma outra função, eles nos ajudam a deixar o código menor e mais **Pythônico** (legível ao modo Python). O conceito de decoradores pode ser inicialmente um pouco difícil de capturarmos, mas vamos por partes. 4 | 5 | Antes de compreendermos os decoradores, é interessante que entendamos como as funções funcionam. Lembre que uma função retorna um valor baseado nos argumentos fornecidos a ela. Vejamos um simples exemplo: 6 | 7 | ```python 8 | def saudar(nome='Gabriel'): 9 | return f'Saudações, {nome}!' 10 | ``` 11 | 12 | Podemos agora chamar essa função sem um argumento (pois já existe um argumento padrão nela), ou com um argumento: 13 | 14 | ```python 15 | saudar() # 'Saudações, Gabriel!' 16 | saudar('Rafael') # 'Saudações, Rafael!' 17 | ``` 18 | 19 | Em geral, as funções em Python também podem ter efeitos colaterais, em vez de apenas transformar um *input* em um *output*. A função **print()** é um exemplo básico disso: ela retorna `None` enquanto tem o efeito colateral de enviar algo para o console. Porém, para entender os decoradores, basta pensar nas funções como algo que transforma determinados argumentos em um valor. 20 | 21 | Também podemos atribuir uma função a uma variável, para isso, não usamos parenteses, dessa maneira estamos guardando apenas a referência ao objeto função. 22 | 23 | ```python 24 | saudacao = saudar 25 | print(saudacao) # 26 | saudacao('Miguel') # 'Saudações, Miguel!' 27 | ``` 28 | 29 | Podemos por exemplo deletar a referência em memória da antiga função: 30 | 31 | ```python 32 | del saudar 33 | saudar() # NameError: name 'saudar' is not defined 34 | ``` 35 | 36 | Veja que se tentarmos invocá-la írá ocorrer um `NameError`, mas veja que ainda podemos chamar a outra referência que temos: 37 | 38 | ```python 39 | saudacao() # 'Saudações, Gabriel!' 40 | ``` 41 | 42 | Veja que mesmo deletando a função antiga, ainda conseguimos executar a função **saudacao()**! 43 | 44 | ## Funções dentro de Funções 45 | 46 | Em Python, funções são [first-class objects](https://stackoverflow.com/questions/245192/what-are-first-class-objects#:~:text=A%20first%20class%20object%20is,being%20storable%20in%20variables). Isso significa que as funções podem ser transmitidas e usadas como argumentos, assim como qualquer outro objeto (string, int, float, listas e assim por diante). 47 | 48 | Vamos começar definindo uma simples função: 49 | 50 | ```python 51 | def func(string): 52 | def wrapper(): 53 | print("Iniciada") 54 | print(string) 55 | print("Finalizada") 56 | return wrapper() 57 | ``` 58 | 59 | Observe que temos uma função de nome **func()** que recebe uma string como argumento e dentro dela temos uma função de nome **wrapper()** que não recebe nenhum argumento e imprime `"Iniciada"`, a **string** passada para a função **func()** e `"Finalizada"` e finalmente retorna a função **wrapper()** (ela mesma) invocando-a. Podemos usá-la da seguinte forma: 60 | 61 | ```python 62 | f = func("Hello World") 63 | # Iniciada 64 | # Hello World 65 | # Finalizada 66 | ``` 67 | 68 | Vamos agora modificá-la para que a função **wrapper()** não retorne a ela mesmo invocando-a, mas dessa vez apenas o objeto função. 69 | 70 | ```python 71 | def func(string): 72 | def wrapper(): 73 | print("Iniciada") 74 | print(string) 75 | print("Finalizada") 76 | return wrapper 77 | ``` 78 | 79 | Dessa vez para usá-la temos de usar o seguinte procedimento: 80 | 81 | ```python 82 | f = func("Hello World") 83 | print(f) # .wrapper at 0x7f7ab6fca0e0> 84 | f() 85 | # Iniciada 86 | # Hello World 87 | # Finalizada 88 | ``` 89 | 90 | Também existe a opção de chamá-la da seguinte forma: 91 | 92 | ```python 93 | func("Hello World")() 94 | # Iniciada 95 | # Hello World 96 | # Finalizada 97 | ``` 98 | 99 | Até então tudo bem, nada que venha a nos surpreender. Mas e se desejarmos passar uma outra função como argumento para **func()**? Vamos definir duas novas funções para testarmos: 100 | 101 | ```python 102 | def func(f): 103 | def wrapper(): 104 | print("Iniciada") 105 | f() 106 | print("Finalizada") 107 | return wrapper 108 | 109 | def f1(): 110 | print("Função f1() chamada!") 111 | 112 | def f2(): 113 | print("Função f2() chamada") 114 | ``` 115 | 116 | Observe que modificamos a função **wrapper()** e agora ela está invocando a função **f()** (esta que passaremos como argumento). Vamos agora chamar a função **func()** passando as funções **f1()** e **f2()** como argumento: 117 | 118 | ```python 119 | f1 = func(f1) 120 | f2 = func(f2) 121 | print(f1) # .wrapper at 0x7f7ab702ab90> 122 | print(f2) # .wrapper at 0x7f7ab702a950> 123 | f1() 124 | # Iniciada 125 | # Função f1() chamada! 126 | # Finalizada 127 | f2() 128 | # Iniciada 129 | # Função f2() chamada 130 | # Finalizada 131 | ``` 132 | 133 | Basicamente este é o conceito de decoradores, estamos usando a função **func()** para alterar o comportamento das funções **f1()** e **f2()**, porém existe uma maneira mais interessante de definí-los, em outras palavras, mais Pythônica. 134 | 135 | ## Decorando Funções 136 | 137 | Vamos decorar as funções **f1()** e **f2()** usando a sintaxe `@`: 138 | 139 | ```python 140 | @func 141 | def f1(): 142 | print("Função f1() chamada!") 143 | 144 | @func 145 | def f2(): 146 | print("Função f2() chamada") 147 | ``` 148 | 149 | Dessa vez podemos chamá-las diretamente e teremos o mesmo efeito anterior: 150 | 151 | ```python 152 | f1() 153 | # Iniciada 154 | # Função f1() chamada! 155 | # Finalizada 156 | f2() 157 | # Iniciada 158 | # Função f2() chamada 159 | # Finalizada 160 | ``` 161 | 162 | Faremos agora outra modificação, dessa vez as funções **wrapper()** e **f1()** passam a receber um argumento e a função passada como argumento para **func()** passa a ser invocada com esse argumento: 163 | 164 | ```python 165 | def func(f): 166 | def wrapper(x): 167 | print("Iniciada") 168 | f(x) 169 | print("Finalizada") 170 | return wrapper 171 | 172 | @func 173 | def f1(x): 174 | print(f"O valor de x é = {x}") 175 | 176 | @func 177 | def f2(): 178 | print("Função f2() chamada") 179 | ``` 180 | 181 | Vejamos agora o que ocorre se invocarmos as funções **f1()** e **f2()**: 182 | 183 | ```python 184 | f1(7) 185 | # Iniciada 186 | # O valor de x é = 7 187 | # Finalizada 188 | f2() # TypeError: wrapper() missing 1 required positional argument: 'x' 189 | ``` 190 | 191 | **f1()** é chamada e nos imprime o valor como esperado, porém **f2()** "quebra", não somo capazes de chamá-la, pois a função **wrapper()** espera um argumento. Para solucionar este problema podemos usar o conceito de `*args` e `**kwargs`, vamos então masi uma vez modificar nossas funções: 192 | 193 | ```python 194 | def func(f): 195 | def wrapper(*args, **kwargs): 196 | print("Iniciada") 197 | f(*args, **kwargs) 198 | print("Finalizada") 199 | return wrapper 200 | 201 | @func 202 | def f1(x): 203 | print(f"O valor de x é = {x}") 204 | 205 | @func 206 | def f2(): 207 | print("Função f2() chamada") 208 | 209 | f1(7) 210 | # Iniciada 211 | # O valor de x é = 7 212 | # Finalizada 213 | f2() 214 | # Iniciada 215 | # Função f2() chamada 216 | # Finalizada 217 | ``` 218 | 219 | Para finalizarmos, vamos modificar nossas funções **wrapper()** e **f1()** para retornar um valor: 220 | 221 | ```python 222 | def func(f): 223 | def wrapper(*args, **kwargs): 224 | print("Iniciada") 225 | valor_retorno = f(*args, **kwargs) 226 | print("Finalizada") 227 | return valor_retorno 228 | return wrapper 229 | 230 | @func 231 | def f1(x, y): 232 | print(f"O valor de x é = {x}") 233 | print(f"O valor de y é = {y}") 234 | return y + x 235 | 236 | f1 = f1(5,33) 237 | # Iniciada 238 | # O valor de x é = 5 239 | # O valor de y é = 33 240 | # Finalizada 241 | print(f1) # 38 242 | ``` 243 | 244 | ## Outros Exemplos 245 | 246 | Funções e métodos são chamados **callable** se for possível chamá-los. De fato, qualquer objeto que implemente o método especial `__call__()` é um **callable**, então um decorador seria um callable que retorna um callable. 247 | 248 | Então como já tinhamos dito na nossa introdução, um decorador recebe um função, adiciona alguma funcionalidade a ela e a retorna: 249 | 250 | ```python 251 | def embelezar(func): 252 | def interno(): 253 | print("Fui decorado") 254 | func() 255 | return interno 256 | 257 | def normal(): 258 | print("Eu sou normal") 259 | 260 | normal() # Eu sou normal 261 | bonito = embelezar(normal) 262 | bonito() 263 | # Fui decorado 264 | # Eu sou normal 265 | ``` 266 | 267 | Veja que a função **normal()** foi decorada e demos o nome à função retornada, que se chamou bonito. Uma forma mais eficaz de usarmos os decoradores é usando o símbolo `@` junto do nome da função decoradora e colocar ele em cima da definição da função a ser decorada. Por exemplo: 268 | 269 | ```python 270 | @embelezar 271 | def normal(): 272 | print("Eu sou normal também") 273 | 274 | normal() 275 | # Fui decorado 276 | # Eu sou normal também 277 | ``` 278 | 279 | ### Decorando Funções com Parâmetros 280 | 281 | O último **decorador** que escrevemos foi bastante simples, só funcionava com funções sem parâmatros, apenas para ilustrarmos o conceito, mas e se tivermos funções que operam com parâmetros? 282 | 283 | ```python 284 | def divisao(x, y): 285 | return x / y 286 | ``` 287 | 288 | A função recebe dois parâmetros **x** e **y**, sabemos que se passarmos **0** para **y** ocorrerá um erro. 289 | 290 | ```python 291 | print(divisao(10,2)) # 5.0 292 | print(divisao(3,0)) # ZeroDivisionError: division by zero 293 | ``` 294 | 295 | Agora vamos fazer um decorador para resolvermos esse problema. 296 | 297 | ```python 298 | def divisao_inteligente(func): 299 | def interior(x,y): 300 | print("Será feita uma divisão de {0} por {1}".format(x,y)) 301 | if y == 0: 302 | print("Impossível dividir") 303 | return 304 | return func(x,y) 305 | return interior 306 | 307 | @divisao_inteligente 308 | def divisao(x,y): 309 | return x / y 310 | 311 | divisao(3,3) 312 | # Será feita uma divisão de 3 por 3 313 | # 1.0 314 | divisao(3,0) 315 | # Será feita uma divisão de 3 por 0 316 | # Impossível dividir 317 | ``` 318 | 319 | ### Medindo Desempenho 320 | 321 | Podemos criar um decorar que é capaz de medir quanto tempo uma função leva para rodar: 322 | 323 | ```python 324 | import time 325 | 326 | def timer(func): 327 | def wrapper(*args, **kwargs): 328 | inicio = time.time() 329 | valor_retorno = func() 330 | total = time.time() - inicio 331 | print(f"Tempo: {total}") 332 | return valor_retorno 333 | return wrapper 334 | ``` 335 | 336 | Vamos definir duas funções para medí-las: 337 | 338 | ```python 339 | @timer 340 | def t1(): 341 | for _ in range(10_000_000): 342 | pass 343 | 344 | @timer 345 | def t2(): 346 | time.sleep(2.3) 347 | ``` 348 | 349 | Finalmente, vamos obter o tempo de cada uma: 350 | 351 | ```python 352 | t1() # Tempo: 0.36320018768310547 353 | t2() # Tempo: 2.302194118499756 354 | ``` 355 | 356 | Com esse estudo podemos considerar que decoradores são de certa forma um pouco complexos, mas que nos trazem novas possibilidades de trabalharmos em cima das funções, modificando seu comportamento. Eles são muito comuns também em **frameworks web**, como **[Flask](https://flask.palletsprojects.com/)** e **[Bottle](https://bottlepy.org/docs/dev/)** por exemplo. -------------------------------------------------------------------------------- /Capitulos/29.PIP.md: -------------------------------------------------------------------------------- 1 | # PIP 2 | 3 | **PIP** é o gerenciador de pacotes do Python, também conhecidos como **bibliotecas**. 4 | 5 | É importante notar que o termo "pacote" neste contexto está sendo usado como sinônimo de distribuição (ou seja, um pacote de software a ser instalado), não para se referir ao tipo de pacote que você importa em seu código-fonte Python (ou seja, um contêiner de módulos). É comum na comunidade Python referir-se a uma distribuição usando o termo "pacote". O uso do termo "distribuição" geralmente não é preferido, porque pode ser facilmente confundido com uma distribuição Linux ou outra distribuição de software maior como o próprio Python. 6 | 7 | A partir da versão 3.4 do Python o PIP já vem incluído por padrão com a instalação do Python, então existem grandes chances de você já tê-lo em sua máquina. 8 | 9 | Para confirmar se ele está instalado, vamos digitar o seguinte comando na nossa **interface de linha de comando**: 10 | 11 | ``` 12 | pip --version 13 | ``` 14 | 15 | Caso ele não esteja presente em sua máquina, você pode encontrá-lo em: **https://pypi.org/project/pip/** ou **[get-pip.py](https://bootstrap.pypa.io/get-pip.py)**: 16 | 17 | - Faça o download do arquivo `get-pip.py` 18 | - Execute o comando `python get-pip.py`. Isso irá instalar ou atualizar o pip. 19 | 20 | Outra opção de instalação é executar o comando: 21 | 22 | ``` 23 | python -m ensurepip --default-pip 24 | ``` 25 | 26 | Para confirmar se o pip está atualizado, você pode executar o seguinte comando: 27 | 28 | ``` 29 | python -m pip install --upgrade pip 30 | ``` 31 | 32 | Para navegar através da lista de mais de `190,943` projetos, `2,069,359` arquivos e `354,989` usuários, visite: **https://pypi.org** 33 | 34 | ## Pacotes 35 | 36 | Um pacote seria um conjunto de arquivos para um módulo, como já vimos antes, módulos são como bibliotecas de código que podemos incluir em nossos projetos para usarmos suas funcionalidades e facilitar nossa vida como programadores. 37 | 38 | Normalmente, não armazenamos todos os nossos arquivos em nosso computador no mesmo local. Usamos uma hierarquia de diretórios bem organizada para facilitar o acesso e gerência. 39 | 40 | Conforme nosso programa cresce em tamanho com muitos módulos, colocamos módulos semelhantes em um pacote e módulos diferentes em pacotes diferentes. Isso torna um projeto (programa) fácil de gerenciar. 41 | 42 | Da mesma forma, como um diretório pode conter sub-diretórios e arquivos, um pacote Python pode ter sub-pacotes e módulos. 43 | 44 | Um diretório deve conter um arquivo denominado `__init__.py` para que o Python o considere como um pacote. Este arquivo pode ser deixado vazio, mas geralmente colocamos o código de inicialização para esse pacote neste arquivo. 45 | 46 | A seguinte ilustração nos apresenta a ideia de como funciona a estrutura de um projeto, usamos como exemplo um pacote de nome **Game** que possui diversos módulos. 47 | 48 | ![img](/Imagens/Package.png) 49 | 50 | ### Instalando Pacotes 51 | 52 | Novamente, vamos abrir nossa **interface de linha de comando** e vamos até o diretório que está nosso script. Digitaremos o seguinte comando para instalar a biblioteca [requests](https://requests.readthedocs.io/en/master/): 53 | 54 | ```python 55 | pip install requests 56 | ``` 57 | 58 | Será iniciado um processo de *download e instalação*, aguarde um pouco e estará pronto, agora poderemos usar a nova biblioteca. 59 | 60 | ### Utilizando o Pacote 61 | 62 | Uma vez que já temos requests instalada, para usarmos é só importá-la, assim como fazemos com os módulos padrão do Python: 63 | 64 | ```python 65 | import requests 66 | 67 | print(dir(requests)) 68 | # ['ConnectionError', 'FileModeWarning', 'HTTPError', 'NullHandler', 'PreparedRequest', 'Request', 'RequestException', 'Response', 'Session', 'Timeout', 'TooManyRedirects', 'URLRequired', '__author__', '__build__', '__builtins__', '__cached__', '__copyright__', '__doc__', '__file__', '__license__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__title__', '__version__', 'adapters', 'api', 'auth', 'certs', 'codes', 'compat', 'cookies', 'delete', 'exceptions', 'get', 'head', 'hooks', 'logging', 'models', 'options', 'packages', 'patch', 'post', 'put', 'request', 'session', 'sessions', 'status_codes', 'structures', 'utils', 'warnings'] 69 | 70 | r = requests.get("http://google.com") 71 | print(r.status_code) # 200, significa que a requisição ocorreu com sucesso 72 | print(r.text) # Retorna o conteúdo HTML da página 73 | print(r.encoding) # ISO-8859-1, codificação usada na página 74 | ``` 75 | 76 | Como podem ver, com um rápido download e instalação, temos acesso a uma poderosa biblioteca chamada **requests**, que nos permite fazer requisições **[HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview)** e uma série de outras funcionalidades web. 77 | 78 | ### Removendo um Pacote 79 | 80 | Para desinstalarmos um pacote de nossa máquina podemos usar o comando `uninstall` 81 | 82 | ``` 83 | pip uninstall requests 84 | ``` 85 | 86 | É necessário confirmarmos a desinstalação com a tecla `y`. 87 | 88 | ### Listando os Pacotes 89 | 90 | Podemos usar o comando `list` para listarmos os pacotes que temos instalado em nossa máquina: 91 | 92 | ``` 93 | pip list 94 | ``` 95 | 96 | ### Atualizando um Pacote Existente 97 | 98 | O comando `install --upgrade` nos permite atualizar um pacote para sua versão mais recente: 99 | 100 | ``` 101 | pip install --upgrade requests 102 | ``` 103 | 104 | ### Obtendo Informações 105 | 106 | Através do comando `show` podemos obter informações sobre um determinado pacote: 107 | 108 | ``` 109 | pip show requests 110 | ``` 111 | 112 | Podemos também fazer pesquisas por **palavras-chave**: 113 | 114 | ``` 115 | pip search http 116 | ``` 117 | 118 | # Ambientes Virtuais 119 | 120 | O principal propósito dos **Ambientes Virtuais** é criar um ambiente isolado para projetos Python. Isso significa que cada projeto pode ter suas próprias dependências, independente da dependência de outros projetos. Eles são essenciais para evitarmos conflitos de versões de bibliotecas entre os nossos projetos. 121 | 122 | Python, como a maioria das outras linguagens de programação modernas, tem sua própria maneira única de baixar, armazenar e resolver pacotes. Embora isso tenha suas vantagens, algumas decisões interessantes foram tomadas sobre o armazenamento e a resolução de pacotes, o que levou a alguns problemas - especialmente em relação à como e onde os pacotes são armazenados. 123 | 124 | Existem alguns locais diferentes onde esses pacotes podem ser instalados em seu sistema. Por exemplo, a maioria dos pacotes de sistema são armazenados em um diretório filho, no qual o caminho fica armazenado em [sys.prefix](https://docs.python.org/3/library/sys.html#sys.prefix). 125 | 126 | Sendo assim, podemos usar a biblioteca **sys** para sabermos onde `sys.prefix` está apontando: 127 | 128 | ```python 129 | import sys 130 | print(sys.prefix) # /home/akira/anaconda3 131 | ``` 132 | 133 | Veja que no meu caso, estou usando anaconda e posso usar este caminho para saber quais pacotes eu tenho instalado com o seguinte comando Linux: 134 | 135 | ``` 136 | ls -la /home/akira/anaconda3/lib/python3.7/ 137 | ``` 138 | 139 | Mas afinal, por que essas informações são relevantes? 140 | 141 | É importante saber isso porque, por padrão, todos os projetos em seu sistema usarão esses mesmos diretórios para armazenar e recuperar pacotes de sites (bibliotecas de terceiros). Inicialmente, isso pode não parecer problemático, e não é realmente, para pacotes de sistema (pacotes que fazem parte da biblioteca Python padrão), mas importa para pacotes de terceiros. 142 | 143 | Considere o seguinte cenário em que você tem dois projetos: **ProjetoA** e **ProjetoB**, ambos os quais dependem da mesma biblioteca, **TimeLib**. O problema se torna aparente quando começamos a exigir versões diferentes do TimeLib. Talvez o ProjectA precise da v1.0.0, enquanto o ProjectB requer a v2.0.0 mais recente, por exemplo. 144 | 145 | Isso irá gerar conflitos e por este motivo os ambientes virtuais são tão importantes! 146 | 147 | Para saber mais detalhes sobre os **Ambientes Virtuais** você pode visitar: **[venv](https://docs.python.org/3/library/venv.html)** 148 | 149 | ## Usando Ambientes Virtuais 150 | 151 | Antes de tudo, devemos instalar a ferramenta `virtualenv` que nos permite trabalhar com ambientes virtuais. 152 | 153 | ``` 154 | pip install virtualenv 155 | ``` 156 | 157 | Lembrando que se você instalou a versão 3 do Python, é provável que você já o módulo `venv` da biblioteca padrão em seu computador. Agora que você já tem a ferramenta para criar **ambientes virtuais**, vamos criar um novo **diretório** em nossa máquina e navegar até ele através de nossa **interface de linha de comando** e digitar o seguinte comando 158 | 159 | ``` 160 | # Para Python 2 161 | virtualenv env 162 | 163 | # Para Python 3 164 | python3 -m venv env 165 | ``` 166 | 167 | O comando acima irá criar um diretório chamado `env` (nome arbitrário escolhido por nós) que contém uma estrutura similar a essa: 168 | 169 | ``` 170 | ├── bin 171 | │ ├── activate 172 | │ ├── activate.csh 173 | │ ├── activate.fish 174 | │ ├── easy_install 175 | │ ├── easy_install-3.5 176 | │ ├── pip 177 | │ ├── pip3 178 | │ ├── pip3.5 179 | │ ├── python -> python3.5 180 | │ ├── python3 -> python3.5 181 | │ └── python3.5 -> /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 182 | ├── include 183 | ├── lib 184 | │ └── python3.5 185 | │ └── site-packages 186 | └── pyvenv.cfg 187 | ``` 188 | 189 | Cada *folder* no diretório `env` contém: 190 | 191 | - **bin**: arquivos que interagem com o ambiente virtual 192 | - **include**: Cabeçalhos **C** que compilam os pacotes Python 193 | - **lib**: Uma cópia da versão Python juntamente com o *folder* `site-packages` onde cada dependência está localizada 194 | 195 | ## Ativando um Ambiente Virtual 196 | 197 | Dentro do *folder* **bin** que vimos anteriormente existem **scripts de ativação**, esses scripts são usados para setar nossa **[Shell](https://en.wikipedia.org/wiki/Shell_(computing))** para usar o executável Python do ambiente e os `site-packages`. 198 | 199 | De forma a usarmos os pacotes e recursos de um **ambiente virtual** é necessário que ativemos ele: 200 | 201 | ``` 202 | source env/bin/activate 203 | ``` 204 | 205 | Ou até mesmo utilizando somente `.` 206 | 207 | ``` 208 | . env/bin/activate 209 | ``` 210 | 211 | Perceba que ao ativarmos o ambiente virtual, nosso **prompt** de comandos irá se alterar para nos indicar que o ambiente está ligado. Caso você queira desativar o **ambiente virtual** basta digitar: 212 | 213 | ```python 214 | deactivate 215 | ``` 216 | 217 | Agora que vimos como **ativar** e **desativar** nosso ambiente virtual, vamos reativá-lo e testá-lo instalando a biblioteca [bcrypt](https://pypi.org/project/bcrypt): 218 | 219 | ```python 220 | pip install bcrypt 221 | ``` 222 | 223 | Abra agora o **Python Interactivo** ou um **Script** e vamos testar se a biblioteca está instalada corretamenta: 224 | 225 | ```python 226 | import bcrypt 227 | 228 | bcrypt.hashpw('senha'.encode('utf-8'), bcrypt.gensalt(12)) 229 | # b'$2b$12$ZT52zrACwPVFy1ST8UbsKuRQ/LZmhMvmMB7EqchU1VUQTLTi4X7Mu' 230 | ``` 231 | 232 | ## Gerando o Arquivo requirements.txt 233 | 234 | O comando `pip freeze` nos permite listar os pacotes que estão instalados em nossa **máquina** ou, caso estejamos em um **ambiente virtual**, os pacotes que nele estão presentes. 235 | 236 | É muito comum existir em projetos o arquivo `requirements.txt` que mostra os pacotes e suas versões necessárias para que o projeto possa funcionar corretamente, também é possível instalar pacotes através do arquivo `requirements.txt` 237 | 238 | Assumindo que estamos em nosso **ambiente virtual** e temos a biblioteca **bcrypt** instalada, vamos executar: 239 | 240 | ```python 241 | pip freeze > requirements.txt 242 | ``` 243 | 244 | Ao verificar o contéudo do arquivo **requirements.txt**, encontramos o seguinte: 245 | 246 | ``` 247 | bcrypt==3.1.7 248 | cffi==1.12.3 249 | pycparser==2.19 250 | six==1.12.0 251 | ``` 252 | 253 | Caso queiramos instalar todos os pacotes contidos nele podemos usar o comando: 254 | 255 | ```python 256 | pip install -r requirements.txt 257 | ``` 258 | 259 | ## Outras Alternativas 260 | 261 | Pip é uma ferramenta essencial para todos os Pythonistas e é usada por muitos aplicativos e projetos para gerenciamento de pacotes, ainda sim, existem outras alternativas muito boas que podemos usar em nossos projetos. 262 | 263 | ### Conda 264 | 265 | Conda é um gerenciador de pacotes, dependências e ambientes para muitas linguagens, incluindo Python. Na verdade, sua origem vem do [Anaconda](https://www.anaconda.com/), que começou como um pacote de ciência de dados para Python. 266 | 267 | O Conda é amplamente utilizado para aplicativos de ciência de dados e *Machine Learning*, e usa seu próprio índice para hospedar pacotes compatíveis. 268 | 269 | Conda não apenas permite que você gerencie dependências de pacote, mas também gerencia ambientes virtuais para seus aplicativos, instala distribuições Python compatíveis e empacota seu aplicativo para implantação na produção. 270 | 271 | Além do **pip** e do **ambiente virtual** tradicional que utilizamos anteriormente, também existem outras opções de gerenciadores de pacotes para Python. 272 | 273 | Você pode obter mais detalhes sobre Conda em: https://docs.conda.io/en/latest/ 274 | 275 | ### Pipenv 276 | 277 | Pipenv é uma ferramenta que visa trazer o melhor de todos os mundos de pacotes (bundler, composer, npm, cargo, yarn, etc.) para o mundo Python. O Windows é um cidadão de primeira classe no Pipenv. 278 | 279 | Ele cria e gerencia automaticamente um virtualenv para seus projetos, bem como adiciona / remove pacotes de seu Pipfile conforme você instala / desinstala pacotes. Ele também gera o sempre importante `Pipfile.lock`, que é usado para produzir compilações determinísticas. 280 | 281 | Você pode obter mais detalhes sobre ele em: https://pipenv.pypa.io/en/latest/ -------------------------------------------------------------------------------- /Imagens/ASCIITable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/ASCIITable.png -------------------------------------------------------------------------------- /Imagens/Algorithm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Algorithm.png -------------------------------------------------------------------------------- /Imagens/Avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Avatar.png -------------------------------------------------------------------------------- /Imagens/BinaryNumbers.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/BinaryNumbers.gif -------------------------------------------------------------------------------- /Imagens/Classes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Classes.png -------------------------------------------------------------------------------- /Imagens/ComputerArchitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/ComputerArchitecture.png -------------------------------------------------------------------------------- /Imagens/Conditionals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Conditionals.png -------------------------------------------------------------------------------- /Imagens/Dictionary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Dictionary.png -------------------------------------------------------------------------------- /Imagens/Diferença.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Diferença.png -------------------------------------------------------------------------------- /Imagens/DiferençaSimétrica.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/DiferençaSimétrica.png -------------------------------------------------------------------------------- /Imagens/DistanceFormula.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/DistanceFormula.png -------------------------------------------------------------------------------- /Imagens/File.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/File.png -------------------------------------------------------------------------------- /Imagens/ForLoop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/ForLoop.png -------------------------------------------------------------------------------- /Imagens/Function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Function.png -------------------------------------------------------------------------------- /Imagens/HinduAvatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/HinduAvatar.png -------------------------------------------------------------------------------- /Imagens/Intersecção.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Intersecção.png -------------------------------------------------------------------------------- /Imagens/Introduction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Introduction.png -------------------------------------------------------------------------------- /Imagens/JanKenPon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/JanKenPon.png -------------------------------------------------------------------------------- /Imagens/Lambda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Lambda.png -------------------------------------------------------------------------------- /Imagens/Lists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Lists.png -------------------------------------------------------------------------------- /Imagens/Modules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Modules.png -------------------------------------------------------------------------------- /Imagens/Numbers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Numbers.png -------------------------------------------------------------------------------- /Imagens/Object.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Object.png -------------------------------------------------------------------------------- /Imagens/Package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Package.png -------------------------------------------------------------------------------- /Imagens/Permutations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Permutations.png -------------------------------------------------------------------------------- /Imagens/Polymorphism.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Polymorphism.png -------------------------------------------------------------------------------- /Imagens/PythonFunction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/PythonFunction.png -------------------------------------------------------------------------------- /Imagens/Set.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Set.png -------------------------------------------------------------------------------- /Imagens/Sierpinski.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Sierpinski.png -------------------------------------------------------------------------------- /Imagens/String.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/String.png -------------------------------------------------------------------------------- /Imagens/União.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/União.png -------------------------------------------------------------------------------- /Imagens/Variables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/Variables.png -------------------------------------------------------------------------------- /Imagens/WhileLoop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/WhileLoop.png -------------------------------------------------------------------------------- /Imagens/XkcdPython.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/XkcdPython.png -------------------------------------------------------------------------------- /Imagens/abs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/abs.png -------------------------------------------------------------------------------- /Imagens/x-y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/x-y.png -------------------------------------------------------------------------------- /Imagens/x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/x.png -------------------------------------------------------------------------------- /Imagens/x_y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/x_y.png -------------------------------------------------------------------------------- /Imagens/xy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the-akira/Python-Iluminado/47849ac97bde6678e69666b40f601f075df4faf6/Imagens/xy.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Gabriel Felippe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Python Iluminado

2 | 3 |

4 | Python
5 |

6 | 7 |

8 | Python Iluminado é um Guia construído especialmente para Iniciantes com a Linguagem Python. O objetivo é explorar conceitos fundamentais de programação e compreender o funcionamento da linguagem e suas capacidades e potencial, bem como apresentar uma vasta lista de materiais de estudos qualificados para você ampliar e aperfeiçoar o seu conhecimento. 9 |

10 | 11 | ## Conteúdo 12 | 13 | 01. [Introdução](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/01.Introdu%C3%A7%C3%A3o.md) 14 | 02. [Ambiente de Programação](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/02.Ambiente%20de%20Programa%C3%A7%C3%A3o.md) 15 | 03. [Sintaxe](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/03.Sintaxe.md) 16 | 04. [Tipos de Variáveis](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/04.Tipos%20de%20Vari%C3%A1veis.md) 17 | 05. [Números](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/05.N%C3%BAmeros.md) 18 | 06. [Strings](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/06.Strings.md) 19 | 07. [Operadores](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/07.Operadores.md) 20 | 08. [Listas](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/08.Listas.md) 21 | 09. [Tuplas](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/09.Tuplas.md) 22 | 10. [Dicionários](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/10.Dicion%C3%A1rios.md) 23 | 11. [Sets](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/11.Sets.md) 24 | 12. [Input](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/12.Input.md) 25 | 13. [If... Else](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/13.If...Else.md) 26 | 14. [For Loops](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/14.ForLoops.md) 27 | 15. [While Loops](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/15.WhileLoops.md) 28 | 16. [Funções](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/16.Fun%C3%A7%C3%B5es.md) 29 | 17. [Expressões Lambda](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/17.Lambda.md) 30 | 18. [Módulos](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/18.M%C3%B3dulos.md) 31 | 19. [Input & Output de Arquivos](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/19.InputOutputArquivos.md) 32 | 20. [Erros, Exceções e Testes](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/20.ErrosExce%C3%A7%C3%B5es.md) 33 | 21. [Data e Tempo](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/21.DataTempo.md) 34 | 22. [Classes e Objetos](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/22.ClassesObjetos.md) 35 | 23. [Expressões Regulares](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/23.Express%C3%B5esRegulares.md) 36 | 24. [JSON](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/24.PythonJSON.md) 37 | 25. [XML](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/25.PythonXML.md) 38 | 26. [Iteradores ](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/26.Iteradores.md) 39 | 27. [Geradores](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/27.Geradores.md) 40 | 28. [Decoradores](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/28.Decoradores.md) 41 | 29. [Gerenciadores de Pacotes e Ambientes Virtuais](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/29.PIP.md) 42 | 29. [MySQL](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/30.PythonMySQL.md) 43 | 31. [MongoDB](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/31.PythonMongoDB.md) 44 | 32. [Grandes Bibliotecas e Ferramentas](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/32.Grandes%20Bibliotecas%20e%20Ferramentas.md) 45 | 33. [Referências Online](https://github.com/the-akira/Python-Iluminado/blob/master/Capitulos/33.Refer%C3%AAncias%20Online.md) 46 | --------------------------------------------------------------------------------