DEFINIÇÃO
DEFINIÇÃO
DEFINIÇÃO
PROPÓSITO
Compreender as características e classificações das linguagens de
programação, bem como identificar os paradigmas de aplicação de cada
linguagem para escolher adequadamente a linguagem de programação
conforme o tipo de problema e solução demandada.
OBJETIVOS
MÓDULO 1
Classificar as linguagens de programação
MÓDULO 2
Descrever critérios de avaliação de linguagens de programação
MÓDULO 3
Distinguir os paradigmas e suas características
MÓDULO 4
Identificar métodos de implementação das linguagens
INTRODUÇÃO
Desde o surgimento dos computadores, centenas de linguagens de
programação vêm sendo criadas com o objetivo de permitir ao programador
mais eficiência e conforto ao escrever seus códigos.
Muitos são os problemas que hoje em dia são solucionados com a ajuda de
softwares, escritos sempre em uma linguagem de programação (que por sua
vez também é um software) e muitas vezes esses problemas demandam
diferentes pensamentos computacionais em sua solução.
PARADIGMAS
Paradigmas é uma forma de agrupar e classificar as linguagens de
programação baseados em suas funcionalidades.
Facilidade de aprendizado;
Produtividade e confiabilidade.
MÓDULO 1
Fonte: Shutterstock
SOFTWARE APLICATIVO
Ou, simplesmente, aplicativo ou app (mundo mobile), que visa oferecer ao
usuário facilidades para realizar uma tarefa laboral ou de lazer.
Fonte: Shutterstock
SOFTWARE BÁSICO
Compreende programas essenciais ao funcionamento do computador. O
sistema operacional é o principal exemplo.
ATENÇÃO
As linguagens de programação surgiram da necessidade de livrar o
programador dos detalhes mais íntimos das máquinas em que a programação
é feita, permitindo a programação em termos mais próximos ao problema, ou
em nível mais alto.
Fonte: Shutterstock
VOCÊ SABIA
O programador podia empregar termos relativamente autoexplicativos (nomes
simbólicos) para nomear códigos de operação (ADD = soma, SUB = subtração,
M = multiplicação e DIV = divisão) e posições de memória. A linguagem de
montagem (Assembly) melhorou a vida do programador, porém obrigava-o a
escrever 1 linha de código para cada instrução que a máquina deve executar,
forçando-o a pensar como se fosse uma máquina.
self.v[k+1]; Lw $15,0($2)
Lw $16,4($2)
Sw $16,0($2)
self.v[k+1]= temp;
Sw $15,4($2)
Jr $31
LINGUAGEM PYTHON
O programa na linguagem Python tem, na verdade, 3 comandos, que estão nas
linhas 2, 3 e 4. → Linha 1 é a declaração da função Swap.
ASSEMBLY
O programa em linguagem Assembly tem 7 comandos (na linha 1, SWAP não é
um comando, mas um rótulo, nome dado a um trecho de código).
LINGUAGEM DE MÁQUINA
O programa em linguagem de máquina tem 7 comandos, a mesma quantidade
de comandos do mesmo programa em Assembly → paridade de 1 para 1 →
comandos em Assembly → comandos em linguagem de máquina.
NÍVEL 1
É representado pelo hardware, conjunto de circuitos eletrônicos.
NÍVEL 2
É representado pela linguagem de máquina (1 e 0), única que o hardware
entende.
NÍVEL 3
É representado pela linguagem Assembly (mneumônicos).
NÍVEL 4
É representado pelas linguagens de alto nível, próximas à língua do usuário e
distantes da linguagem computacional. Python e Java são linguagens de
programação representativas da classe LP de alto nível (LP = Linguagem de
Programação).
0001001010001111
1010010001000010
0010101110110111
0101010000000111
EXEMPLO
As três linhas de código na linguagem Assembly, abaixo, que move o numeral
2 para o registrador AX (linha 1), move o numeral 1 para o registrador BX (linha
2) e soma o conteúdo dos 2 registradores (linha 3).
MOV AX, 0002
MOV BX, 0001
ADD AX, BX
Não chega a ser o ideal em termos de uma linguagem, que é ainda próxima da
máquina, mas já foi um grande avanço em relação à memorização da
sequência de 0 e 1 de uma instrução de máquina.
VOCÊ SABIA
Quem programa em uma linguagem de alto nível não precisa conhecer
características dos componentes do hardware (processador, instruções e
registradores). Isso é abstraído no pensamento computacional.
As instruções das linguagens de alto nível são bastante abstratas e não estão
relacionadas à arquitetura do computador diretamente. As principais
linguagens são:
ASP, C, C++, C#, Pascal, Delphi, Java, Javascript, Lua, MATLAB, PHP e
Ruby, dentre outras.
EXEMPLO
Abaixo, o mesmo código expresso acima, escrito em Assembly, porém usando
variáveis, como abstração do armazenamento e codificado na linguagem
Python.
def main():
num1 = 2
num2 = 1
int main()
num1=2;
num1=1;
soma=num1+num2;
SAIBA MAIS
Há uma curiosidade: C e C++ são classificados por alguns autores como
linguagem de médio nível, na medida que estão próximas da linguagem
humana (linguagem de alto nível), mas também estão próximas da máquina
(linguagem de baixo nível), pois possuem instruções que acessam diretamente
memória e registradores. Inicialmente, a linguagem C foi criada para
desenvolver o sistema operacional UNIX, que até então era escrito em
Assembly.
Outro dado que merece ser comentado é que algumas pessoas consideram a
existência de linguagens de altíssimo nível, como Python, Ruby e Elixir, por
serem linguagens com uma enorme biblioteca de funções e que permitem a
programação para iniciantes sem muito esforço de aprendizado.
CLASSIFICAÇÃO POR GERAÇÕES
Outra forma de classificar as linguagens, amplamente difundida, é por
gerações. Não há um consenso sobre as gerações, alguns consideram 5,
outros 6. A cada geração, novos recursos facilitadores são embutidos nas
respectivas linguagens.
Fonte: Autor
Código em Assembly
Código em Assembly
São as, também, linguagens de alto nível, de aplicação geral, em que uma
única instrução em uma linguagem próxima a do homem pode corresponder a
mais de uma instrução em linguagem de máquina.
VERIFICANDO O APRENDIZADO
1. AVALIE AS ASSERTIVAS SOBRE AS LINGUAGENS DE
PROGRAMAÇÃO:
I. LINGUAGEM ASSEMBLY É A NATIVA DOS
COMPUTADORES.
II. UMA LINGUAGEM DEVE SER COMPATÍVEL ÚNICA E
EXCLUSIVAMENTE COM O HARDWARE A QUE SE PROPÔS
A ATENDER.
II. A ABSTRAÇÃO TRAZ FACILIDADES AO PROGRAMADOR
QUE CADA VEZ MENOS PRECISA CONHECER O AMBIENTE
ONDE A LINGUAGEM OPERA (COMPOSTO POR SISTEMA
OPERACIONAL E HARDWARE).
IV. UM COMANDO EM UMA LINGUAGEM DE ALTO NÍVEL
FAZ MAIS QUE UMA OPERAÇÃO PRIMÁRIA DO HARDWARE.
COM BASE EM SUA ANÁLISE, MARQUE A OPÇÃO QUE
APRESENTA APENAS AS ASSERTIVAS CORRETAS.
I, II, III e IV
III e IV apenas
III apenas
II e IV apenas
A – GERAÇÕES
MÓDULO 2
Aplicações científicas
Aplicações comerciais
Programação de sistemas
Programação mobile
DOMÍNIOS DA PROGRAMAÇÃO
Fonte: Autor
O computador tem sido usado para diversos fins, na ciência, nas forças
armadas, nas empresas públicas e privadas, pelos profissionais liberais, pelas
pessoas em seus lazeres e onde mais possa ser aplicado. Seu uso vai desde
controlar robôs que fazem a montagem de automóveis em suas linhas de
montagem até jogos digitais. Em função desse uso adverso, surgiram
linguagens de programação com diferentes objetivos. A seguir, discutiremos as
principais áreas e as respectivas linguagens de programação em destaque.
APLICAÇÕES COMERCIAIS
PROGRAMAÇÃO DE SISTEMAS
PROGRAMAÇÃO MOBILE
A Google, por sua vez, tem por base o Android SDK, orienta a usar as
linguagens Kotlin, Java e C++, mas as linguagens Python, Shell script,
Basic4Android, LiveCode (para iOS e Windows também), App Inventor (não
necessita conhecer programação) e Unity (motor para games) e GO, também
são usadas para desenvolver app para Android.
AVALIAÇÃO DE LINGUAGENS DE
PROGRAMAÇÃO
Segundo Sebesta (2018) são quatro grandes critérios para avaliação das
linguagens de programação, dentro de um mesmo domínio de programação.
Cada critério é influenciado por algumas características da linguagem.
Fonte: Shutterstock
LEGIBILIDADE
Um dos critérios mais relevantes é a “facilidade com que os programas podem
ser lidos e entendidos” pelas pessoas que não necessariamente participaram
do desenvolvimento.
Fonte: Shutterstock
FACILIDADE DE ESCRITA
O quão facilmente uma linguagem pode ser usada para desenvolver programas
para o domínio do problema escolhido.
Fonte: Shutterstock
CONFIABILIDADE
Um programa é dito confiável se ele se comporta conforme a sua
especificação, repetidas vezes.
Fonte: Shutterstock
CUSTO
O custo final de uma linguagem de programação é em função de muitas de
suas propriedades e características.
Características Legibilidade
Simplicidade
Ortogonalidade
Estruturas de controle
Tipos de dados
Projeto de sintaxe
Expressividade
Verificação de tipos
Tratamento de exceções
Aliasing
SIMPLICIDADE
Quanto mais simples for uma linguagem, melhor será a legibilidade do código
por ela produzido. Uma linguagem com número elevado de construções
básicas é mais difícil de ser aprendida do que uma que tenha poucas. Tende a
ser subutilizada.
cont= cont + 1;
cont +=1.
Uma linguagem ortogonal tende a ser mais fácil de aprender e tem menos
exceções.
INSTRUÇÕES DE CONTROLE
SINTAXE
FACILIDADE DE ESCRITA
(REDIGIBILIDADE)
A facilidade de escrita é a medida do quão fácil a linguagem permite criar
programas para um domínio da aplicação.
SIMPLICIDADE E ORTOGONALIDADE
Quanto mais simples e ortogonal for a linguagem, melhor sua facilidade para
escrever programas. O ideal são linguagens com poucas construções
primitivas.
EXPRESSIVIDADE
CONFIABILIDADE
Dizemos que um programa é confiável se ele se comportar conforme sua
especificação, sob todas as condições, todas as vezes em que for executado.
VERIFICAÇÃO DE TIPOS
TRATAMENTO DE EXCEÇÃO
ALIASING (APELIDOS)
CUSTO
O custo de uma linguagem de programação varia em função das seguintes
despesas: de treinamento, de escrita do programa, do compilador, de execução
do programa, de implementação da linguagem e o de manutenção do código.
Custo de
ATENÇÃO
Existem outros critérios, como por exemplo a portabilidade ou a capacidade
que os programas têm de rodarem em ambientes diferentes (sistema
operacional e hardware), o que é altamente desejável. A reusabilidade, ou seja,
o quanto um código pode ser reutilizado em outros programas ou sistemas
aumenta o nível de produtividade da linguagem. Além da facilidade de
aprendizado, que é fortemente afetada pela legibilidade e facilidade de escrita.
VERIFICANDO O APRENDIZADO
1. DOS DOMÍNIOS DE PROGRAMAÇÃO APRESENTADOS NA
AULA, QUAIS DEVEM CONSIDERAR, NECESSARIAMENTE, A
ARQUITETURA CLIENTE-SERVIDOR?
Programação web e Mobile.
Redigibilidade
Confiabilidade
Custo
GABARITO
MÓDULO 3
PARADIGMA ESTRUTURADO
Caracteriza as principais linguagens de programação da década de 1970 e
1980 que seguiram os princípios da programação estruturada:
PRINCÍPIO 01
PRINCÍPIO 02
PRINCÍPIO 03
PRINCÍPIO 04
1
Não usar desvios incondicionais (Goto, característico de linguagens como
BASIC e versões iniciais do COBOL).
2
Desenvolver programas por refinamentos sucessivos (metodologia top down),
motivando o desenvolvimento de rotinas (procedimentos e funções) e a visão
do programa partindo do geral para o particular, ou seja, o programa vai sendo
refinado à medida que se conhece melhor o problema e seus detalhes.
3
Desenvolver programas usando três tipos de estruturas: sequenciais,
condicionais e repetição.
4
Visando eficiência, o paradigma estruturado baseia-se nos princípios da
arquitetura de Von Neumann, onde:
As classes são abstrações que definem uma estrutura que encapsula dados
(chamados de atributos) e um conjunto de operações possíveis de serem
usados, chamados métodos. Os objetos são instâncias das classes.
EXEMPLO
Por exemplo, a classe ALUNO encapsula um conjunto de dados que os
identifiquem: matrícula, nome, endereço (rua, número, complemento, bairro,
estado e CEP) e um conjunto de métodos: Incluir Aluno, Matricular Aluno,
Cancelar Matrícula, dentre outros.
ATENÇÃO
Phyton, Smalltalk, C++, Java, Delphi (oriundo do Object Pascal) são linguagens
que caracterizam o paradigma orientado a objetos. Python é orientado a objeto,
pois tudo em Python é objeto, permitindo a declaração de classes
encapsuladas, além de possibilitar herança e polimorfismo.
PARADIGMA CONCORRENTE
Caracterizado quando processos executam simultaneamente e concorrem aos
recursos de hardware (processadores, discos e outros periféricos),
características cada vez mais usuais em sistemas de informação.
UM PROCESSADOR
Os processos concorrem ao uso do processador e recursos.
VÁRIOS PROCESSADORES
Estamos caracterizando o paralelismo na medida em que podem executar em
diferentes processadores (e de fato, ao mesmo tempo), os quais podem estar
em uma mesma máquina ou distribuídos em mais de um computador.
VOCÊ SABIA
Ao contrário de Go, Python não foi originalmente projetada com foco em
programação concorrente, muito menos paralela. O modo tradicional de
programar concorrência em Python -- threads -- é limitado no interpretador
padrão (CPython) por uma trava global (a GIL), que impede a execução
paralela de threads escritas em Python. Isso significa que threads em Python
são úteis apenas em aplicações I/O bound – em que o gargalo está no I/O
(entrada e saída), como é o caso de aplicações na Internet.
I/O BOUND
Aplicações I/O bound são aquelas em que há predomínio de ações de entrada
e saída de dados.
PARADIGMA DECLARATIVO
Diferentemente do paradigma imperativo, no declarativo o programador diz o
que o programa deve fazer (qual a tarefa), ao invés de descrever como o
programa deve fazer. O programador declara, de forma abstrata, a solução do
problema.
PARADIGMA FUNCIONAL
Abrange linguagens que operam tão somente funções que recebem um
conjunto de valores e retornam um valor. O resultado que a função retorna é a
solução do problema (foca o processo de resolução de problemas).
O programa resume-se em chamadas de funções, que por sua vez podem usar
outras funções. Uma função pode invocar outra, ou o resultado de uma função
pode ser argumento para outra função. Usa-se também chamadas recursivas
de funções.
def conta_numeros(n):
p=0
if num%2 == 0:
p += 1
return p
Abaixo, o mesmo código usando o conceito de função recursiva. Repare que a
função de nome conta_numeros chama ela mesma em seu código (isso é a
recursão).
def conta_numeros(n):
if n == 0: return 1 # 0 é par
ATENÇÃO
Python não é uma linguagem funcional nativa, seria exagerado afirmar isso,
porém sofreu influência desse paradigma ao permitir: recursividade, uso de
funções anônimas, com a função lambda, dentre outros recursos, além, claro,
de ser uma linguagem com enorme biblioteca de funções.
PARADIGMA LÓGICO
Um programa lógico expressa a solução da maneira como o ser humano
raciocina sobre o problema: baseado em fatos, derivam-se conclusões e novos
fatos.
Multiparadigma.
A – PARADIGMAS B – CARA
GABARITO
A – Paradigmas B–
MÓDULO 4
TRADUÇÃO
Nesse processo de conversão, o programa escrito em uma linguagem de alto
nível é traduzido para uma versão equivalente em linguagens de máquina,
antes de ser executado. O processo de tradução pode ser executado em várias
fases, que podem ser combinadas e executadas em simultaneidade. O
processo de tradução é erroneamente chamado de compilação, que na
verdade é uma de suas fases.
Código-fonte
Compilador
COMPILADOR
O compilador (detalhes adiante) analisa o código-fonte e estando tudo OK, o
converte para um código Assembly (da máquina hospedeira).
Código Assembly
Montador
MONTADOR
O montador traduz o código Assembly para o código de máquina intermediário
(Código-objeto), que não é executável pelo computador. O código-objeto pode
ser relocável, ou seja, carregado em qualquer posição de memória ou absoluto,
carregado em um endereço de memória específico. A opção relocável é mais
comum e mais vantajosa.
Código Assembly
Ligador
LIGADOR
O Ligador liga (ou linka) o código-objeto relocável com as rotinas bibliotecas
(outros objetos, rotinas do SO, DLLs etc.), usadas nos códigos-fontes. Essa
ligação gera o código executável.
Código-objeto relocável
Carregador
CARREGADOR
O carregador é que torna o código-objeto em relocável.
Código objeto
Código executável
COMPILADOR
É o elemento central do processo de tradução, responsável pelo custo de
compilação, visto no modulo anterior. Em função dessa relevância, muitas
vezes o processo como um todo é erroneamente chamado de compilação, uma
vez que o ambiente integrado das linguagens atuais já integra todos os
componentes (montador, compilador, carregador e ligador) quando necessário.
ANÁLISE LÉXICA
ANÁLISE SINTÁTICA
ANÁLISE SEMÂNTICA
Verifica se as estruturas sintáticas possuem sentido. Por exemplo, verifica se
um identificador de variável ou constante é usado adequadamente, se
operandos e operadores são compatíveis. Monta a árvore de derivação
conforme ilustrado abaixo para formação das expressões.
Fonte: Autor
O otimizador tem por objetivo eliminar redundâncias do código intermediário
e tornar o objeto mais enxuto e eficiente.TRATADOR DE ERROS
ATENÇÃO
As principais características dos compiladores são:
INTERPRETAÇÃO
A imagem abaixo ilustra o simples processo de Interpretação:
Fonte: Autor
1
Obter a próxima instrução do código-fonte.
2
Interpretar a instrução (conversão para comandos em linguagem de máquina).
3
Executar a instrução.
Decodificar a instrução.
Executar a instrução.
O Código-fonte é portátil.
o Não é gerado um código de máquina.
TRADUÇÃO X INTERPRETAÇÃO
Vantagens
Fonte: http://codemastersufs.blogspot.com/2015/10/compiladores-versus-
interpretadores.html. Adaptado pelo autor.
COMENTÁRIO
Curioso saber que o código Python pode ser traduzido em Bytecode Java
usando a implementação Jython.
VERIFICANDO O APRENDIZADO
1. COMO SE CHAMAM OS DOIS PROCESSOS DE
CONVERSÃO DE LINGUAGENS DE ALTO NÍVEL EM
LINGUAGENS INTELIGÍVEIS PELO COMPUTADOR?
Tradução e interpretação.
Compilação e interpretação.
Compilação e montagem.
GABARITO
CONCLUSÃO
CONSIDERAÇÕES FINAIS
Saber classificar uma linguagem dentro do(s) paradigma(s) a que pertença(m),
assim como conhecer os domínios de programação de uma linguagem, é
fundamental para seu entendimento e correta aplicação na hora de decidir pelo
uso dessa ou aquela linguagem.
REFERÊNCIAS
BORGES, Luiz Eduardo. Python para Desenvolvedores. 2. ed. Rio de
Janeiro: Edição do Autor, 2010.
SEBESTA, R. W. Conceitos de Linguagens de Programação. Tradução de
João Eduardo Nobrega Tortello. 11. ed. Porto Alegre: Bookman, 2018.
Disponível na biblioteca virtual da Estácio.
VAREJÃO, F. M. Linguagem de Programação: conceitos e técnicas. 2ª
reimpressão. Rio de Janeiro: Elsevier, 2004.
DIJKSTRA EW. A Discipline of Programming. Prentice Hall Inc;1976. 217.
EXPLORE+
Para saber mais sobre os assuntos tratados neste tema, pesquise na internet
sobre:
CONTEUDISTA
Marcelo Vasques de Oliveira
CURRÍCULO LATTES
DEFINIÇÃO
Introdução à linguagem Python e suas características, apresentando as
variáveis, os tipos de dados, as expressões, os operadores e as formas de
atribuição, de entrada e saída de dados.
PROPÓSITO
Compreender os aspectos básicos de Python visando ao aprendizado da
programação nessa linguagem.
OBJETIVOS
MÓDULO 1
Descrever a linguagem Python e suas principais características
MÓDULO 2
Reconhecer o uso de variáveis em Python
MÓDULO 3
Identificar os tipos de dados e as expressões em Python
MÓDULO 4
Identificar as formas de atribuição, de entrada e saída de dados em Python
INTRODUÇÃO
Atualmente, o ensino de disciplinas relacionadas à programação vem
crescendo na educação básica e no ensino superior. Nos cursos de graduação
voltados à tecnologia da informação, como Engenharia da Computação e
Ciência da Computação, é frequente que se tenha contato com mais de uma
disciplina focada em programação. Além desses cursos, outras carreiras têm
contato com a programação em disciplinas como Introdução à Computação ou
similares. Nesses diferentes contextos, várias linguagens de programação são
usadas, tanto para o ensino como para o desenvolvimento de projetos.
MÓDULO 1
CONCEITOS
Python é uma linguagem de programação de alto nível, que permite ao
programador utilizar instruções de forma intuitiva, tornando seu aprendizado
mais simples do que o aprendizado de uma linguagem de baixo nível.
CARACTERÍSTICAS DA LINGUAGEM
PYTHON
A linguagem Python tem se tornado cada vez mais popular porque, além de
permitir um rápido aprendizado inicial, tem características importantes, tais
como:
É MULTIPARADIGMA
Apesar de suportar perfeitamente o paradigma de programação estruturada,
Python também suporta programação orientada a objetos, tem características
do paradigma funcional, com o amplo uso de bibliotecas, assim como permite
recursividade e uso de funções anônimas.
É INTERATIVA
Permite que os usuários interajam com o interpretador Python diretamente para
escrever os programas, utilizando o prompt interativo. Esse prompt fornece
mensagens detalhadas para qualquer tipo de erro ou para qualquer comando
específico em execução, suporta testes interativos e depuração de trechos de
código.
É PORTÁVEL
Tem a capacidade de rodar em uma grande variedade de plataformas de
hardware com a mesma interface. Ele roda perfeitamente em quase todos os
sistemas operacionais, como Windows, Linux, UNIX, e Mac OS, sem nenhuma
alteração.
É EXTENSÍVEL
Permite que os programadores adicionem ou criem módulos e pacotes de
baixo nível / alto nível ao interpretador Python. Esses módulos e pacotes de
ferramentas permitem que os desenvolvedores tenham possibilidades amplas
de colaboração, contribuindo para a popularidade da linguagem.
PERMITE DESENVOLVIMENTO DE
APLICAÇÕES WEB
Devido à escalabilidade já citada, Python oferece uma variedade de opções
para o desenvolvimento de aplicativos Web. A biblioteca padrão do Python
incorpora muitos protocolos para o desenvolvimento da web, como HTML,
XML, JSON, processamento de e-mail, além de fornecer base para FTP, IMAP
e outros protocolos da Internet.
INSTALAÇÃO
A linguagem Python tem seu site oficial, onde é possível encontrar as últimas
versões lançadas, notícias e documentação, entre outras informações. A
versão que utilizaremos neste tema é a 3.7.7. Por isso, recomendamos que ela
seja baixada e instalada em seu computador. Também será necessário baixar
e instalar a IDE PyCharm, usando a versão disponível em seu site.
Não se preocupe ainda com o conceito de variável, nem com o seu tipo.
Veremos tudo isso com detalhes nos próximos módulos deste tema.
O utilitário dir apresenta todos os atributos e métodos disponíveis para
determinado tipo de dado. No prompt interativo >>>, digite dir(x) e pressione a
tecla [ENTER] ou [RETURN] do seu teclado.
Fonte: Freepik
BLOCOS
Em Python, os blocos são definidos pela indentação. Diferente de C e Java,
que usam as chaves { e } para delimitar os blocos, em Python todos os blocos
são iniciados com o símbolo : (dois pontos) na linha superior e representados
pelo acréscimo de 4 (quatro) espaços à esquerda. Sem se preocupar por
enquanto com o significado das expressões for, if, else ou range, observe a
figura 4:
INDENTAÇÃO
Trata-se da digitação dos códigos do programa, afastados por espaço da
margem e dispostos hierarquicamente para facilitar a visualização e percepção
do programa.
Fonte: o autor (2020) Figura 4 - Blocos
LINHA 1
Está mais à esquerda, assim como as linhas 2 e 11.
LINHA 2
Todas as linhas de 3 a 10 estão dentro do bloco do for da linha 2.
LINHA 3
Observe que a linha 3 tem um if abrindo um bloco, dentro do qual estão as
linhas 4 e 5.
LINHA 6
Por sua vez, a linha 6 tem um else abrindo outro bloco, composto pelas linhas
de 7 a 10. Os blocos do if (linha 3) e do else (linha 6) estão no mesmo nível.
LINHA 7
Mostra outro if abrindo outro bloco – composto apenas pela linha 8 – que está
no mesmo nível do bloco do else da linha 9 – composto apenas pela linha 10.
LINHA 11
Como a linha 11 está no mesmo nível da linha 2, ela não faz parte do bloco
do for.
COMENTÁRIOS
Em Python, os comentários podem ser de uma linha ou de várias linhas. A
tabela 1 mostra as formas de limitar um comentário, além de comparar essas
formas em Python e C.
Python
Comentários com várias linhas Limitados por “”” (três aspas duplas) no início
ATENÇÃO
É importante lembrar que os comentários não são instruções a serem
executadas. Então, você pode escrever de forma simples e objetiva, sem
obedecer às regras de sintaxe da linguagem.
BOAS PRÁTICAS DE
PROGRAMAÇÃO
Ao começar sua jornada como programador, é importante perceber que
existem algumas práticas que não são obrigatórias, mas podem ajudar muito
no seu aprendizado. Além disso, podem permitir que você corrija mais
rapidamente erros que podem surgir no futuro e tornam seu código mais fácil
de ser compreendido por outro programador, favorecendo o trabalho em
equipe. Vamos conhecer algumas delas:
Fonte: Porcupen/shutterstock
Uma prática muito importante é utilizar comentários no seu programa,
explicando o que aquele trecho resolve.
Fonte: Porcupen/shutterstock
Uma característica marcante da comunidade de desenvolvedores Python é
manter uma lista de propostas de melhorias, chamadas PEP (Python
Enhancement Proposals). Dentre as PEPs, destaca-se a PEP8, que estabelece
um guia de estilo de programação.
Agora que já vimos os principais conceitos deste módulo, é hora de testar seus
conhecimentos.
VERIFICANDO O APRENDIZADO
1. ANALISE AS AFIRMATIVAS A SEGUIR:
SÃO CORRETAS:
Somente II.
Somente III.
Somente II e III.
Somente I e II.
GABARITO
São corretas:
A alternativa "C " está correta.
MÓDULO 2
CONCEITOS
As variáveis são abstrações para endereços de memória que permitem que os
programas fiquem mais fáceis de codificar, entender e depurar. Podemos
entender que ao nomear uma variável com o identificador x, determinado
espaço em memória passará a ter esse apelido. Em outras palavras, será
possível acessar esse espaço de memória sabendo o seu apelido e,
consequentemente, recuperar o valor guardado nele, que no nosso exemplo
é 10.
Uma analogia possível com o mundo real é com aquelas caixas de correio que
ficam em frente às casas.
Fonte: Fabio Balbi/Shutterstock
ATENÇÃO
Observe na figura 5 que o retorno do Python Console foi 10.
ATENÇÃO
Diferentemente de outras linguagens, como C ou Java, não é necessário
declarar uma variável antes de utilizá-la em Python. Basta atribuir um valor
inicial à variável e utilizá-la dali em diante. Embora não seja necessário
declarar uma variável para utilizá-la, não é possível utilizar uma variável que
não tenha recebido alguma atribuição de valor.
Fonte: Freepik
IDENTIFICADORES DE VARIÁVEIS
Os identificadores das variáveis podem ser compostos por letras,
o underline (_) e, com exceção do primeiro caractere, números de 0 a 9. Veja
os exemplos:
minhaVariavel, _variavel, salario1 e salario1_2 são válidos.
Algumas palavras são consideradas reservadas e não podem ser usadas como
identificadores de variáveis em Python. São
elas: and, as, assert, break, class, continue, def, del, elif, else, except, exe
c, finally, for, from, global, if, import, in, is, lambda, not, or, pass, print, rai
se, return, try, while, with e yield.
AMARRAÇÕES
Chamamos de amarração (binding) a associação entre entidades de
programação. Veja alguns exemplos:
TEMPO DE COMPILAÇÃO
TEMPO DE LIGAÇÃO
A ligação de vários módulos compilados previamente, como a chamada a uma
função de um módulo importado. Em C, utilizamos a diretiva #include para
termos permissão de utilizar as funções de determinada biblioteca. Em Python,
utilizamos o import para isto.
TEMPO DE CARGA
TEMPO DE EXECUÇÃO
O momento em que ocorre a ligação pode ser classificado como cedo (early
binding) ou tardio (late binding). Quanto mais cedo ocorre a ligação, maior a
eficiência de execução do programa, porém menor a flexibilidade das
estruturas disponibilizadas.
AMARRAÇÃO DE TIPO
As amarrações de tipo vinculam a variável ao tipo do dado. Elas podem ser:
ESTÁTICAS
Ocorrem antes da execução e permanecem inalteradas. Em C, declaramos int
a.
DINÂMICAS
Ocorrem durante a execução e podem ser alteradas. É o caso do Python.
Veja a figura 8:
Fonte: o autor (2020) Figura 8 - Tipagem dinâmica
ESCOPO DE VISIBILIDADE
O escopo define em quais partes do programa uma variável é visível. Cada
nome de variável em Python tem seu escopo e fora desse escopo o nome não
existe, gerando um erro quando se tenta referenciar esse nome. Quanto ao
escopo, chamamos as variáveis de globais ou locais.
Fonte: BEST-BACKGROUNDS/Shutterstock
VARIÁVEIS GLOBAIS
Todos os nomes atribuídos no prompt interativo ou em um módulo fora de
qualquer função são considerados como de escopo global. Por exemplo, ao
executar a instrução da figura 9, a variável x é uma variável global.
VARIÁVEIS LOCAIS
Para exemplificar o uso de variáveis com escopo local, vamos utilizar uma
função definida pelo desenvolvedor. Não se preocupe com esse tipo de função
por enquanto, você aprenderá mais detalhes posteriormente. Observe a figura
10:
Usamos este exemplo para mostrar que o interpretador Python pode procurar o
mesmo nome de variável em diferentes escopos. A ordem utilizada para a
procura é:
1
A chamada da função delimitadora
2
Variáveis globais
3
O módulo builtins
TIPOS DE ESCOPO
Os tipos de escopo são:
ESTÁTICO
O escopo é baseado na descrição textual do programa e as amarrações são
feitas em tempo de compilação. É o caso de C, C++ e Java, por exemplo.
DINÂMICO
O fato de Python ser de escopo dinâmico traz alguns problemas, como a perda
de eficiência – uma vez que os tipos precisam ser verificados em tempo de
execução – e a redução na legibilidade – porque é difícil determinar a
sequência exata de todas as chamadas de função.
Fonte: BEST-BACKGROUNDS/Shutterstock
TEMPO DE VIDA
Embora escopo e tempo de vida tenham uma relação próxima, eles são
conceitos diferentes. Observe:
CONSTANTES
Em Python, não existe o conceito de constante. Se você precisar de uma
constante ao longo de sua jornada como programador, atribua o valor a uma
variável e tome cuidado para não mudar esse valor.
DICA
Uma dica é iniciar o nome dessa variável com c_ ou utilizar todas as letras
maiúsculas, o que vai diferenciar essa variável das outras. Por exemplo, é
possível utilizar a expressão c_PI = 3.141592 para armazenar o valor de PI e
agilizar o cálculo de área e perímetro de um círculo, ou utilizar a
expressão PRECISION = 0.001 para armazenar a precisão a ser utilizada em
qualquer cálculo matemático no seu programa.
DEF FUNC():
X=1
PRINT(X)
X = 10
FUNC()
PRINT(X)
OS VALORES IMPRESSOS, AO SE EXECUTAR O
PROGRAMA, SÃO, RESPECTIVAMENTE:
1 e 1.
10.
1 e 10.
10 e 10.
int i = 1;
GABARITO
def func():
x=1
print(x)
x = 10
func()
print(x)
MÓDULO 3
Fonte: Freepik
O Python Console permite que você calcule expressões algébricas como uma
calculadora, além de executar instruções básicas em Python.
TIPOS NUMÉRICOS
Existem três tipos numéricos distintos em Python: inteiros, números de ponto
flutuante e números complexos. Além disso, os booleanos são um subtipo dos
inteiros.
O TIPO INT
É o tipo usado para manipular números inteiros. Fazendo uma analogia com a
Matemática, o tipo int é usado para elementos do conjunto dos inteiros (Z).
Python permite que você utilize o underline (_) como separador de milhar. Isso
ajuda a visualizar números com muitos dígitos. Para encerrarmos este primeiro
contato com o tipo int, verifique que o valor do exemplo anterior é inteiro.
Fonte: Freepik
O TIPO FLOAT
É o tipo usado para manipular números com parte inteira e parte decimal,
chamados de números de ponto flutuante. Fazendo uma analogia com a
Matemática, o tipo float é usado para elementos do conjunto dos reais (R).
Fonte: Freepik
ATENÇÃO
Vale ressaltar que devemos usar o ponto para separar a parte inteira da parte
decimal, e não a vírgula.
Fonte: Freepik
Veja que basta que a base seja float para que o resultado também o seja.
ATENÇÃO
Diferentemente de outras linguagens, como C, a divisão de dois números
inteiros não necessariamente tem resultado inteiro.
Fonte: Freepik
Para obter o quociente inteiro e o resto, quando dois inteiros são divididos, é
necessário utilizar os operadores // e %, respectivamente. Ao dividir 21 por 2,
temos quociente 10 e resto 1. Observe a figura 24:
O TIPO COMPLEX
É o tipo utilizado para manipular números complexos, na forma x + yj,
sendo x a parte real e y a parte imaginária do complexo.
O TIPO BOOL
Uma expressão algébrica, como vimos nos exemplos dos tipos int e float, é
avaliada como um número, seja desses tipos ou de outro tipo numérico
admitido em Python. Porém, utilizar expressões não algébricas também é
bastante comum. E uma boa notícia é que Python pode avaliar expressões
desse tipo também. Essa é uma diferença entre Python e outras linguagens,
como C, por exemplo, em que não existe o tipo bool.
Fonte: Freepik
No prompt interativo >>>, digite a expressão 2 < 3 e pressione [ENTER].
Observe o resultado na figura 27:
SAIBA MAIS
As expressões que você viu nos dois exemplos são chamadas de expressões
booleanas. Trata-se de expressões que podem ser avaliadas com um dos dois
valores booleanos: True ou False. Assim, em Python, existe o tipo bool,
utilizado para permitir o tratamento de expressões como essas.
OPERADORES NUMÉRICOS
OPERADORES MATEMÁTICOS
Os operadores matemáticos são muito semelhantes àqueles que vimos ao
longo de nossa jornada como estudantes, aprendendo Álgebra e Aritmética na
escola. Existem algumas pequenas diferenças, como a divisão (que pode ser a
usual ou a divisão inteira). Mas é possível identificar operações que fizemos ao
longo de toda nossa vida. A tabela 2 lista os operadores de expressão
aritmética disponíveis em Python.
Soma +
Subtração -
Multiplicação *
Divisão /
Divisão inteira //
Exponenciação **
Símbolo usado
< Me
<= Me
> Ma
>= Ma
== Igu
!= Nã
ATENÇÃO
Cabe observar que o operador utilizado para comparar se dois valores são
iguais é o ==, ou seja, duplo sinal de igual. Tome cuidado para não confundir
com o operador de atribuição, que é representado pelo sinal de igual apenas
uma vez (=).
OPERADORES BOOLEANOS
As expressões booleanas são aquelas que podem ter como resultado um dos
valores booleanos: True ou False. É comum utilizarmos os operadores de
comparação em expressões booleanas, mas não só eles.
True False
False True
p q
True True
True False
False True
False False
p q
True True
True False
False True
False False
Tabela 6 - Operador or
Fonte: kikujungboy CC/Shutterstock
TIPOS SEQUENCIAIS
Existem três tipos sequenciais básicos em Python: listas, tuplas e objetos
range. Além dos tipos básicos citados, existe um tipo especial criado para
tratamento de dados textuais: o tipo str (string).
Assim como em C ou Java, a indexação dos itens é iniciada com 0 e cada item
tem o seu índice incrementado uma unidade em relação ao item anterior.
Porém, Python também permite a indexação com valores negativos. O valor -1
é o índice do último item, e cada item anterior é decrementado de uma unidade
em relação ao sucessor. Observe a tabela 7:
índice 0 1
s t e
índice negativo -5 -4
STRINGS
Em uma variável do tipo str, é possível armazenar letras, números, espaços,
pontuação e diversos símbolos. Diferentemente da linguagem C, não existe o
tipo char. Cada caractere em Python é uma string. Para delimitar uma string,
podemos utilizar:
ASPAS SIMPLES
‘uma string'
ASPAS DUPLAS
“uma string”
UPPER
Transforma todas as letras em maiúsculas.
LOWER
Transforma todas as letras em minúsculas.
SPLIT
Quebra a string em substrings.
SAIBA MAIS
A lista gerada com o método split() tem três elementos, porque a string original
tinha três palavras.
LISTAS
Listas são sequências mutáveis, normalmente usadas para armazenar
coleções de itens homogêneos. Uma lista pode ser criada de algumas
maneiras, tais como:
[]
Usando um par de colchetes para denotar uma lista vazia.
[A], [A, B, C]
Usando colchetes, separando os itens por vírgulas.
[X FOR X IN ITERABLE]
Usando a compreensão de lista.
LIST() OU LIST(ITERABLE)
Usando o construtor do tipo list.
SAIBA MAIS
iterable pode ser uma sequência, um container que suporte iteração ou um
objeto iterador. Por exemplo, list('abc') retorna ['a', 'b', 'c'] e list( (1, 2,
3) ) retorna [1, 2, 3]. Se nenhum argumento for passado, o construtor cria uma
lista vazia: [ ].
TUPLAS
Tuplas são sequências imutáveis, tipicamente usadas para armazenar
coleções de itens heterogêneos. Elas são aplicadas também quando é
necessário utilizar uma sequência imutável de dados homogêneos. Uma tupla
pode ser criada de algumas maneiras, tais como:
()
Usando um par de parênteses para denotar uma tupla vazia.
A, B, C OU (A, B, C)
Separando os itens por vírgulas.
TUPLE() OU TUPLE(ITERABLE)
Usando o construtor do tipo tuple.
ATENÇÃO
Note que o uso das vírgulas é o que gera a tupla, e não o uso de parênteses.
Os parênteses são opcionais, exceto no caso em que queremos gerar uma
tupla vazia.
RANGE
O tipo range representa uma sequência imutável de números e
frequentemente é usado em loops de um número específico de vezes, como
o for.
Ele pode ser chamado de maneira simples, apenas com um argumento. Nesse
caso, a sequência começará em 0 e será incrementada de uma unidade até o
limite do parâmetro passado (exclusive). Por exemplo, range(3) cria a
sequência (0, 1, 2).
Para que a sequência não comece em 0, podemos informar o início e o fim
como parâmetros, lembrando que o parâmetro fim não entra na lista (exclusive
o fim). O padrão é incrementar cada termo em uma unidade. Ou seja, a
chamada range(2, 7) cria a sequência (2, 3, 4, 5, 6).
SAIBA MAIS
Também é possível criar sequências mais complexas, indicando os parâmetros
de início, fim e passo, nessa ordem. O passo é o valor que será incrementado
de um termo para o próximo. Por exemplo, range(2, 9, 3) cria a sequência (2,
5, 8).
Fonte: BEST-BACKGROUNDS/Shutterstock
EXEMPLO
O operador == verifica se as strings dos dois lados são iguais. Porém, os
operadores < e > comparam as strings usando a ordem do dicionário.
Uso
DICIONÁRIOS
Os dicionários permitem que itens de uma sequência recebam índices
definidos pelo usuário. Um dicionário contém pares de (chave, valor). O
formato geral de um objeto dicionário é:
{<chave 1>:<valor 1>, <chave 2>:<valor 2>, ..., <chave i>:<valor i>}
EXEMPLO
Poderíamos criar um dicionário em que cada pessoa fosse representada pelo
seu CPF, com nome e sobrenome. Para isso, teríamos:
Na figura 32, o dicionário tem 3 entradas. Observe como foi possível recuperar
nome e sobrenome de uma entrada, baseado na chave informada ‘111222333-
44’.
EXEMPLO
Por exemplo, a expressão 3 + 2 * 5 tem como resultado 25 ou 13? Aprendemos
no ensino fundamental que as operações de produto e divisão têm precedência
sobre as operações de soma e subtração. Ou seja, um produto será realizado
antes de uma soma, na mesma expressão. Assim, a expressão acima tem
como resultado 13. Isso ocorre sempre que não forem explicitadas outras
relações de precedência com o uso de parênteses. Caso o programador
quisesse forçar que a soma ocorresse primeiro, ele deveria escrever assim: (3
+ 2) * 5.
Operador
** Exponenciação
+x, -x Sinal de positivo
+, - Soma, subtraçã
in, not in, <, <=, >, >=, <>, !=, == Comparações, i
or Booleano OR (o
ATENÇÃO
É importante ficar atento ao uso correto dos operadores, respeitando a
precedência entre eles, para evitar que algum cálculo seja realizado
corretamente, mas com resultado diferente do esperado por você ao
programar.
CONVERSÕES DE TIPOS
Quando temos tipos diferentes envolvidos na mesma expressão, o Python
converte implicitamente cada operando para o tipo mais abrangente envolvido
na expressão. Estamos usando a palavra abrangente, mas poderíamos falar
que existem tipos que englobam (ou contêm) outros.
EXEMPLO
Um número do tipo int pode ser visto como um float com a parte decimal nula.
Porém, o inverso não é verdade. Ou seja, o conjunto dos inteiros (int) é um
subconjunto do conjunto dos reais (float). Assim, a expressão 5 + 0.68 – que
envolve um int e um float – tem como resultado 5.68. O inteiro 5 é convertido
pelo Python para o número de ponto flutuante 5.0 antes que a soma (de dois
valores float) seja realmente efetuada.
ATENÇÃO
Fique atento, porque não é uma aproximação para o inteiro mais próximo, e
sim o truncamento.
VERIFICANDO O APRENDIZADO
1. CONSIDERE A EXPRESSÃO A SEGUIR: 2 + 3 – 4 ** 2 + 5 / 2
– 5 // 2
-1
1.5
2. (ADAPTADA DE COMPERVE/2019/UFRN/ENGENHARIA DA
COMPUTAÇÃO) PYTHON É UMA LINGUAGEM
INTERPRETADA MUITO UTILIZADA. NÃO REQUER TIPAGEM
DE VARIÁVEIS E SUA SINTAXE INDENTADA FAVORECE A
ORGANIZAÇÃO DO CÓDIGO. UMA DAS SUAS
FUNCIONALIDADES MAIS PODEROSAS SÃO AS LISTAS.
CONSIDERE O CÓDIGO EM PYTHON DO QUADRO ABAIXO:
FONTE: O AUTOR (2020)
A SAÍDA CORRETA CORRESPONDENTE ÀS LINHAS 2 E 4
DO CÓDIGO É:
2 e 4.
4 e 16.
2 e 16.
4 e 4.
GABARITO
MÓDULO 4
CONCEITOS
Já vimos, de maneira básica, como podemos atribuir valor a uma variável, no
módulo 2. Vamos agora conhecer outras formas de atribuição.
Fonte: BEST-BACKGROUNDS/Shutterstock
SENTENÇAS DE ATRIBUIÇÃO
ATRIBUIÇÃO SIMPLES
Chamamos de atribuição simples a forma que já utilizamos neste tema, com
uma expressão parecida com x = 10. Nessa atribuição, a variável x recebe o
valor 10.
ATRIBUIÇÃO MÚLTIPLA
Python também permite a atribuição múltipla, ou seja, mais de uma variável
receber atribuição na mesma linha. Veja o exemplo na figura 36:
Fonte: o autor (2020) Figura 36 - Atribuição múltipla
ATENÇÃO
Observe que as variáveis x e y receberam atribuição na mesma instrução, com
a variável x armazenando o valor 2, e a variável y armazenando o valor 5.
Mais igual += x
Menos igual -= x
Vezes igual *= x
Dividido igual /= x
Módulo igual %= x
Tabela 10 - Operadores compostos
ATENÇÃO
Diferente de C, em Python não é possível incrementar ou decrementar uma
variável com um operador unário, como o ++ ou --.
TROCA DE VARIÁVEIS
Um dos problemas iniciais que envolvem atribuição de valores a variáveis é a
troca entre duas delas. Suponha que as variáveis a e b armazenem,
respectivamente, os valores 1 e 2. Caso quiséssemos inverter os valores em
linguagens como C ou Java, seria necessário usar uma variável auxiliar, com
uma sequência de instruções exibida na figura a seguir:
Em Python, é possível fazer essa troca de uma maneira muito mais fácil. Veja o
uso da atribuição múltipla, nesse caso, na figura a seguir:
Fonte: o autor (2020) Figura 40 - Troca de variáveis 2
O PRIMEIRO PROGRAMA EM
PYTHON
Para escrever um programa em Python, será essencial utilizar as formas
de saída de dados para exibir ao usuário mensagens e resultados de
operações. Caso você deseje que o usuário informe algum dado para que seu
programa processe, será necessário utilizar as formas de entrada de dados.
Fonte: Freepik
Para criar seu primeiro programa, clique com o botão direito do mouse no
nome do projeto, na guia de navegação do lado esquerdo. Em seguida,
escolha a opção New > File.
Fonte: o autor (2020) Figura 41 - Novo arquivo no PyCharm
Ao nomear o arquivo, será aberta uma nova aba, do lado direito, com o espaço
para que você efetivamente digite as instruções.
Fonte: o autor (2020) Figura 43 - Aba de codificação
Para escrever seu Hello World em Python, digite a seguinte linha, exatamente
como está escrita:
print(“Hello World”)
Veja que foi impresso no console exatamente o que colocamos entre aspas, ao
chamar a função print(). Essa é a primeira forma de saída de dados: usar a
função print() com uma string sendo passada como parâmetro (entre os
parênteses). É importante perceber que a função print(), além de imprimir a
string, também salta o cursor para a próxima linha.
A linha 1 fará com que a frase Entre com seu nome: seja exibida no console,
mas a execução do programa fica travada até que o usuário aperte [ENTER] no
teclado. Tudo o que foi digitado até o [ENTER] vai ser armazenado na
variável nome. A linha 2 fará a exibição do conteúdo da variável nome. Veja o
resultado no console, com o usuário tendo digitado Fulano de Tal.
A FUNÇÃO EVAL()
A função eval() recebe uma string, mas trata como um valor numérico. Veja o
exemplo a seguir:
MÃO NA MASSA
COMO EXERCÍCIO PRÁTICO, TENTE
ESCREVER UM PROGRAMA PARA
CALCULAR E INFORMAR O IMC (ÍNDICE
DE MASSA CORPÓREA) DO USUÁRIO,
QUE DEVERÁ FORNECER SEU PESO E
SUA ALTURA. LEMBRE-SE QUE O IMC É
CALCULADO PELA
FÓRMULA: IMC=PESOALTURA2
RESPOSTA
Uma solução simples é a da figura 57:
SAIBA MAIS
Também é válido perceber que o padrão é alinhar os valores à direita do
espaço reservado para a impressão da variável.
IMPRESSÃO DE SEQUÊNCIAS
Python também permite a impressão de sequências com mais possibilidades
que C, incluindo as strings. Para imprimir um vetor em C, por exemplo,
precisamos chamar a printf() item a item. Em Python, basta chamar a
função print() passando como parâmetro a sequência. Veja a figura 64:
Para imprimir uma substring, por exemplo, basta utilizar os colchetes para
indicar o intervalo de índices que deve ser impresso. Vale lembrar que o
primeiro caractere da string é indexado com 0. Veja a figura 65:
Fonte: o autor (2020) Figura 65
ATENÇÃO
Usar [0:4] provoca a impressão dos índices 0, 1, 2 e 3, mas não do índice 4.
Analogamente, usar [2:8] provoca a impressão dos índices de 2 a 7, mas não
do 8.
Também é possível imprimir a string como lida da direita para a esquerda. Para
isso, deve-se utilizar [: : -1]. Esse valor -1 indica que a leitura dos caracteres
será feita no sentido oposto ao tradicional. Observe a figura 66:
Fonte: o autor (2020) Figura 66
ATENÇÃO
Fique atento quando utilizar o intervalo na impressão no sentido inverso,
porque os limites do intervalo devem respeitar esse sentido.
VERIFICANDO O APRENDIZADO
1. (2015/PGE-RO/TÉCNICO DA
PROCURADORIA/TECNOLOGIA DA INFORMAÇÃO) NA
LINGUAGEM PYTHON, UM COMANDO COMO
A=INPUT("XXX")
PROVOCA:
A associação à variável “a" de uma função denominada “XXX" que pertence à
biblioteca “input".
2. (2015/TJ-BA/ANALISTA JUDICIÁRIO/TECNOLOGIA DA
INFORMAÇÃO/REAPLICAÇÃO) ANALISE O TRECHO DE
PROGRAMA PYTHON APRESENTADO A SEGUIR.
L = [1,2,3,4,5,6,7,8]
PRINT L[::-1]
[8]
[]
[8, 7, 6, 5, 4, 3, 2, 1]
GABARITO
a=input("XXX")
provoca:
A alternativa "D " está correta.
L = [1,2,3,4,5,6,7,8]
print L[::-1]
CONCLUSÃO
CONSIDERAÇÕES FINAIS
Neste tema, você conheceu as principais características da linguagem Python
e alguns conceitos relativos ao uso de variáveis, bem como aspectos
concernentes à vinculação, como tempo e ambientes. Além disso, viu o
conceito de escopo de visibilidade, tanto estático como dinâmico.
Nos módulos, foi feita uma referência a tipos de dados,
como int, float ou string. Você estudou ainda as formas de atribuição, além de
ter escrito seu primeiro programa em Python, utilizando o que aprendeu e,
também, as formas de entrada e saída de dados que a linguagem oferece.
AVALIAÇÃO DO TEMA:
REFERÊNCIAS
BELANI, G. Programming Languages You Should Learn in 2020.
Consultado em meio eletrônico em: 26 mai. 2020.
PERKOVIC, L. Introdução à computação usando Python: um foco no
desenvolvimento de aplicações. Rio de Janeiro: LTC, 2016.
PYCHARM. The Python IDE for Professional Developers. Consultado em
meio eletrônico em: 15 jun. 2020.
PYTHON. PEP 0 – Index of Python Enhancement Proposals (PEPs).
Consultado em meio eletrônico em: 2 jun. 2020.
PYTHON. Fractions – Rational Number. Consultado em meio eletrônico em:
16 jun. 2020.
PYTHON. Math – Mathematical Functions. Consultado em meio eletrônico
em: 16 jun. 2020.
EXPLORE+
Se você quiser ter mais exercícios para treinar e desafios mais
complexos, recomendamos a visita ao site da Python Brasil.
Como vimos, dentre as PEPs, destaca-se a PEP8, que estabelece
um guia de estilo de programação. Sugerimos que você pesquise
mais sobre isso.
Para mais funções matemáticas, você pode utilizar os módulos
matemáticos math e fractions.
CONTEUDISTA
Humberto Henriques de Arruda
CURRÍCULO LATTES
DEFINIÇÃO
Identificação de estruturas de controle, de decisão e de repetição na linguagem
Python, bem como de conceitos e da implementação de subprogramas e
bibliotecas e das formas de tratamento de exceções e eventos.
PROPÓSITO
Reconhecer, na linguagem Python, as estruturas de decisão e de repetição, a
utilização de subprogramas e de bibliotecas e as formas de tratamento de
exceção e eventos.
PREPARAÇÃO
Antes de iniciar o conteúdo deste tema, é necessário que tenha o interpretador
Python na versão 3.7.7 e o ambiente de desenvolvimento PyCharm ou outro
ambiente que suporte o desenvolvimento na linguagem Python.
OBJETIVOS
MÓDULO 1
Descrever as estruturas de decisão e repetição em Python
MÓDULO 2
Definir os principais conceitos de subprogramas e a sua utilização em Python
MÓDULO 3
Identificar o uso correto de recursos de bibliotecas em Python
MÓDULO 4
Analisar as formas de tratamento de exceções e eventos em Python
Fonte: BEST-BACKGROUNDS | Shutterstock
INTRODUÇÃO
Programar significa, como em qualquer disciplina, aprender ferramentas que
permitam desenvolver melhor a sua atividade. Ao aprender os conceitos
básicos de programação, o estudante desenvolve habilidades iniciais para
escrever seus primeiros programas. Porém, é difícil imaginar que aplicações
profissionais sejam feitas totalmente baseadas apenas nesses conceitos
básicos.
Ao pensarmos em aplicações mais complexas, é essencial considerar a
necessidade de ganhar tempo, com o computador executando as tarefas
repetitivas, e as demandas de manutenção e tratamento de erros. Para
avançar no aprendizado da programação, você conhecerá novas ferramentas,
entre elas as estruturas de controle, como decisão e repetição, além
dos subprogramas e bibliotecas, bem como as formas de tratar exceções e
eventos.
Vamos começar nossa jornada acessando os códigos-fontes originais
propostos para o aprendizado de Python estruturado. Baixe o arquivo aqui,
descompactando-o em seu dispositivo. Assim, você poderá utilizar os códigos
como material de apoio ao longo do tema!
MÓDULO 1
Descrever as estruturas de decisão e repetição em Python
Python
ATENÇÃO
Observe que o fato de haver o tipo bool em Python permite que as condições
sejam tratadas como verdadeiras ou falsas, o que não é exatamente igual em
C.
Python
if <condição>:
Instrução fora do if
Python
if <condição>:
else:
Instrução fora do if
4 Bloco de código que será executado caso condição 1 seja False e condição 2 seja True
5 else:
6 Bloco de código que será executado caso condição 1 seja False e condição 2 seja False
7 Instrução fora do if
5 elif idade == 5:
8 else:
Perceba que a indentação precisa ser ajustada, uma vez que o último else
é relativo ao elif. Por isso, eles precisam estar alinhados.
NÃO INICIADAS EM 0
Para que a sequência não comece em 0, podemos informar o início e o fim
como parâmetros, lembrando que o parâmetro fim não entra na lista (exclusive
o fim). O padrão é incrementar cada termo em uma unidade. Ou seja, a
chamada range(2, 7) cria a sequência (2, 3, 4, 5, 6).
Python
2 print(item)
A linha 2 indica a instrução que será executada para cada repetição deste
sequên
3 print(letra)
A linha 1 faz com que a palavra inserida pelo usuário seja armazenada na
variável nome;
A linha 3 indica a instrução que será executada para cada repetição desse
2 L
3 a
4 u
5 r
6 a
3 print(nome)
1 Laura
2 Lis
3 Guilherme
4 Enzo
5 Arthur
(2020)
Python
encerrado;
Perceba que ao digitar ‘sair’ logo na primeira solicitação, a linha 3 do nosso
programa não é executada nenhuma vez. Ou seja, o programa nem chega a
entrar no laço while.
Em C, existe outra estrutura muito semelhante ao while, chamada do-while. A
diferença básica entre elas é o momento em que a condição é testada, como
vemos a seguir:
No laço while, a condição é testada antes da iteração.
O laço while testa e executa caso a condição seja verdadeira.
No laço do-while, a condição é testada após a iteração.
O laço do-while executa e testa.
Infelizmente, a estrutura do-while não existe em Python. Isso não chega a
ser um grande problema, porque podemos adaptar nosso programa e controlar
as repetições com o laço while.
O LAÇO WHILE INFINITO
Laços infinitos são úteis quando queremos executar um bloco de instruções
indefinidamente.
EXEMPLO
Suponha que você deseje criar uma aplicação que permaneça por meses ou
anos sendo executada, registrando a temperatura ou a umidade de um
ambiente. Logicamente, estamos supondo que você tenha essa informação
disponível a partir da leitura de algum sensor.
Deve-se tomar cuidado e ter certeza de que seu uso é realmente necessário
para evitar problemas de consumo excessivo de memória.
AS INSTRUÇÕES AUXILIARES
BREAK, CONTINUE E PASS
A INSTRUÇÃO BREAK
A instrução break funciona da mesma maneira em C e em Python. Ela
interrompe as repetições dos laços for e while. Quando a execução do
programa chega a uma instrução break, a repetição é encerrada e o fluxo do
programa segue a partir da primeira instrução seguinte ao laço.
Para exemplificar o uso da instrução break, vamos voltar ao primeiro exemplo
do laço while, utilizando o laço infinito. O laço será encerrado quando o usuário
inserir a palavra ‘sair’. Veja a Figura 10:
1 while True:
4 break
Caso haja vários laços aninhados, o break será relativo ao laço em que estiver
inserido. Veja a Figura 11:
1 while True:
6 else:
7 while True:
14
A INSTRUÇÃO CONTINUE
A instrução continue também funciona da mesma maneira em C e em Python.
Ela atua sobre as repetições dos laços for e while, como a instrução break,
mas não interrompe todas as repetições do laço. A instrução continue
interrompe apenas a iteração corrente, fazendo com que o laço passe
para a próxima iteração.
2 if num == 5:
3 continue
4 else:
5 print(num)
6 print('Laço encerrado')
Laço encerrado
A INSTRUÇÃO PASS
A instrução pass atua sobre a estrutura if, permitindo que ela seja escrita sem
outras instruções a serem executadas caso a condição seja verdadeira. Assim,
podemos concentrar as instruções no caso em que a condição seja falsa.
Suponha que queiramos imprimir somente os números ímpares entre 1 e 10.
Uma implementação possível está na Figura 14:
1 for num in range(1, 11):
2 if num % 2 == 0:
3 pass
4 else:
5 print(num)
6 print('Laço encerrado')
Laço encerrado
Figura 15 - Exemplo de execução com uso do pass em Python - Fonte: O autor (2020)
VERIFICANDO O APRENDIZADO
1. CONSIDERE O SEGUINTE TRECHO DE UM PROGRAMA
ESCRITO EM PYTHON:
1 S = 0
2 FOR I IN RANGE(5):
3 S += 3*I
4 PRINT(S)
ASSINALE A OPÇÃO QUE APRESENTA CORRETAMENTE O
QUE SERÁ IMPRESSO NA TELA.
0 3 9 18 30
0 3 6 9 12
30
45
1 S = 0
2 A = 1
3 WHILE S < 5:
4 S = 3*A
5 A += 1
6 PRINT(S)
ASSINALE A OPÇÃO QUE APRESENTA CORRETAMENTE O
QUE SERÁ IMPRESSO NA TELA.
3 6
3 3
3 6 9 12
GABARITO
2 for i in range(5):
3 s += 3*i
4 print(s)
1 s = 0
2 a = 1
3 while s < 5:
4 s = 3*a
5 a += 1
6 print(s)
MÓDULO 2
DEFINIÇÕES BÁSICAS
As definições básicas, conforme Sebesta (2018), estabelecem que:
1
Um subprograma é definido quando o desenvolvedor descreve a interface e
as ações da abstração desse subprograma.
2
O subprograma foi chamado quando uma instrução traz um pedido explícito
para sua execução.
3
O subprograma está ativo após o início de sua execução, a partir da sua
chamada e enquanto ele não foi concluído.
O cabeçalho do subprograma é a primeira parte da definição, em que podem
ser especificados o nome, os parâmetros e o tipo de retorno do subprograma.
Em C, o cabeçalho dos subprogramas – sendo chamados de funções – traz,
em ordem: o tipo de retorno, o nome e a lista de parâmetros, como a seguir:
FLOAT CALCULAIMC (INT PESO, FLOAT ALTURA)
Em Python, as funções definidas pelo desenvolvedor devem ser precedidas
pela palavra reservada def. Não são especificados o tipo de retorno nem os
tipos dos parâmetros, como no exemplo a seguir:
DEF CALCULAIMC (PESO, ALTURA)
Em Python, as sentenças de função def são executáveis. Isso implica que a
função só pode ser chamada após a execução da sentença def. Veja o
exemplo na Figura 16:
1 escolha = input("Escolha uma opção de função: 1 ou 2")
2 if escolha == 1:
3 def func1(x):
4 return x + 1
5 else:
6 def func2(x):
7 return x + 2
8
9 s = func1(10)
10 print(s)
1. Ou seja, o usuário deverá inserir 1 quando solicitado (na linha 1), para
que a linha 9 possa ser executada sem que seja gerado um erro.
PARÂMETROS
Usualmente, um subprograma executa cálculos e operações a partir de dados
que ele deve processar. Existem duas maneiras de o subprograma obter esses
dados: acessando variáveis não locais, mas visíveis para o subprograma,
ou pela passagem de parâmetros.
Quando o subprograma recebe os parâmetros adequados, ele pode ser
executado com quaisquer valores recebidos. Porém, quando ele manipula
variáveis não locais, uma forma de evitar alterações indevidas nessas variáveis
é fazendo cópias locais delas. De acordo com Sebesta (2018), o acesso
sistemático a variáveis não locais pode diminuir a confiabilidade do programa.
São denominados parâmetros formais aqueles do cabeçalho do
subprograma.
Quando o subprograma é chamado, é necessário escrever o nome do
subprograma e a lista de parâmetros a serem vinculados aos parâmetros
formais dele, que são denominados parâmetros reais ou argumentos.
No exemplo da Figura 16, existe o cabeçalho da função func1 na linha 3, com
o parâmetro formal x. Na linha 9, a função func1 é chamada com o parâmetro
real 10.
Em Python, é possível estabelecer valores padrão para os parâmetros
formais. O valor padrão é usado quando a chamada da função ocorre sem
nenhum parâmetro real. Veja o exemplo de definição e chamada da
função taxímetro na Figura 17:
1 def taximetro(distancia, multiplicador=1):
2 largada = 3
3 km_rodado = 2
5 return valor
8 pagamento = taximetro(3.5)
9 print(pagamento)
real.
PROCEDIMENTOS E FUNÇÕES
Os subprogramas podem ser, distintamente, procedimentos e funções. De
acordo com Sebesta (2018):
Procedimentos
Funções
Na maioria das linguagens que não explicita a diferença entre eles, as funções
podem ser definidas sem retornar qualquer valor, tendo comportamento de
procedimento. Esse é o caso de Python. Veja o exemplo da Figura 18:
1 def func1(x):
2 x = 10
4
5
6 def func2(x):
7 x = 20
9
10
11 x = 0
12 func1(x)
13 func2(x)
AMBIENTES DE
REFERENCIAMENTO LOCAL
VARIÁVEIS LOCAIS
Quando um subprograma define suas próprias variáveis, estabelece ambientes
de referenciamento local. Essas variáveis são chamadas de variáveis locais,
com seu escopo usualmente sendo o corpo do subprograma. As variáveis
locais podem ser:
DINÂMICAS DA PILHA
ESTÁTICAS
DINÂMICAS DA PILHA
São vinculadas ao armazenamento no início da execução do subprograma e
desvinculadas quando essa execução termina. As variáveis locais dinâmicas
da pilha têm diversas vantagens, e a principal delas é a flexibilidade. Suas
principais desvantagens são o custo do tempo – para alocar, inicializar (quando
necessário) e liberar tais variáveis para cada chamada ao subprograma – e o
fato de que os acessos a essas variáveis locais devem ser indiretos, enquanto
os acessos às variáveis estáticas podem ser diretos.
ESTÁTICAS
São vinculadas a células de memória antes do início da execução de um
programa e permanecem vinculadas a essas mesmas células até que a
execução do programa termine. Elas são um pouco mais eficientes que as
variáveis locais dinâmicas da pilha, já que não é necessário tempo para alocar
ou liberar essas variáveis. Sua maior desvantagem é a incapacidade de
suportar recursão, como vai ser explicado adiante.
ATENÇÃO
Nas linguagens C e C++, as variáveis locais são dinâmicas da pilha, a menos
que sejam especificamente declaradas como static. Todas as variáveis locais
em Python são dinâmicas da pilha. As variáveis globais são declaradas em
definições de método, e qualquer variável declarada global em um método
precisa ser definida fora dele. Caso haja uma atribuição à variável local com
mesmo nome de uma variável global, esta é implicitamente declarada como
local.
Voltando ao exemplo da Figura 18, vamos detalhar as
funções func1(x) e func2(x):
As linhas 1, 2 e 3 definem a função func1(x), que recebe o parâmetro x,
mas tem uma variável local de nome x, cujo valor atribuído é 10;
recebe o parâmetro x e tem uma variável de mesmo nome, mas com valor
atribuído 20;
O programa principal tem uma variável global de mesmo nome x, cujo valor
executadas, cada uma dessas funções tem a sua própria variável local, a
Função func1 - x = 10
Função func2 - x = 20
Programa principal - x = 0
Mesmo com a variável global tendo valor nulo, cada variável local das
2 global x
3 x = 10
5
6
7 def func2():
8 global x
9 x = 20
11
12
13 x = 0
14 func1()
15 func2()
autor (2020)
Função func1 - x = 10
Função func2 - x = 20
Programa principal - x = 20
programa principal.
SUBPROGRAMAS ANINHADOS
Em Python, e na maioria das linguagens funcionais, é permitido aninhar
subprogramas. Porém, as linguagens C e C++ não permitem essa prática. Veja
o exemplo da Figura 22:
1 def taximetro(distancia)::
2 def calculaMult():
4 return 1.2
5 else:
6 return 1
7 multiplicador = calculaMult()
8 largada = 3
9 km_rodado = 2
11 return valor
12
13
15 pagamento = taximetro(dist)
MÉTODOS DE PASSAGENS DE
PARÂMETROS
Os métodos de passagem de parâmetros são as maneiras que existem para
transmiti-los ou recebê-los dos subprogramas chamados. Os parâmetros
podem ser passados principalmente por:
VALOR
REFERÊNCIA
VALOR
O parâmetro formal funciona como uma variável local do subprograma, sendo
inicializado com o valor do parâmetro real. Dessa maneira, não ocorre
alteração na variável externa ao subprograma, caso ela seja passada como
parâmetro.
REFERÊNCIA
Em vez de passar o valor do parâmetro real, é transmitido um caminho de
acesso (normalmente um endereço) para o subprograma chamado. Isso
fornece o caminho de acesso para a célula que armazena o parâmetro real.
Assim, o subprograma chamado pode acessar o parâmetro real na unidade de
programa chamadora.
SAIBA MAIS
Na linguagem C, utilizamos ponteiros para fazer a passagem de parâmetros
por referência. As transmissões de parâmetros que não sejam ponteiros
utilizam a passagem por valor.
RECURSIVIDADE
Uma função recursiva é aquela que chama a si mesma. Veja o exemplo da
função regressiva(), como mostrado na Figura 23:
1 def regressiva(x):
2 print(x)
3 regressiva(x - 1)
ATENÇÃO
Conceitualmente, essa execução será repetida indefinidamente até que haja
algum erro por falta de memória. Perceba que não definimos adequadamente
uma condição de parada para a função regressiva(), o que leva a esse
comportamento ruim.
1 def regressiva(x):
2 if x <= 0:
3 print("Acabou")
4 else:
5 print(x)
6 regressiva(x-1)
n! = 1, se n = 0 ou n=1n.(n−1).(n−2)...3.2.1, s
e n≥2n! = 1, se n = 0 ou n=1n.(n-1).(n-
2)...3.2.1, se n≥2
Atenção! Para visualização completa da equação utilize a rolagem horizontal
n! = 1, se n = 0 ou n=1n.[(n−1)!], se n≥2n! =
1, se n = 0 ou n=1n.[(n-1)!], se n≥2
Atenção! Para visualização completa da equação utilize a rolagem horizontal
1 def fatorial(n):
2 if n == 0 or n == 1:
3 return 1
4 else:
5 return n*fatorial(n-1)
Vale ressaltar que a função fatorial também poderia ter sido implementada de
forma não recursiva, como mostrado na Figura 26:
1 def fatorial(n):
2 fat = 1
3 if n == 0 or n == 1:
4 return fat
5 else:
7 fat = fat*x
8 return fat
A SEQUÊNCIA DE FIBONACCI
A sequência de Fibonacci é: 1, 1, 2, 3, 5, 8, 13, 21... Os dois primeiros termos
são 1 e, a partir do 3º termo, cada termo é a soma dos dois anteriores.
1 def fibo(n):
2 if n == 1 or n == 2:
3 return 1
4 else:
anteriores da sequência.
DOCSTRINGS
Em Python, é possível definir uma string que serve como documentação
de funções definidas pelo desenvolvedor. Ao chamar o
utilitário help() passando como parâmetro a função desejada, essa string é
exibida. Veja a Figura 28 e a Figura 29:
1 def fibo(n):
3 if n == 1 or n == 2:
4 return 1
5 else:
8 print(help(fibo))
1 fibo(n)
VERIFICANDO O APRENDIZADO
1. CONSIDERE O SEGUINTE TRECHO DE UM PROGRAMA
ESCRITO EM PYTHON:
1DEF FUNC1(X):
2X = 10
3PRINT(X)
4
5
6X = 0
7PRINT(X)
8FUNC1(X)
9PRINT(X)
O QUE ACONTECERÁ QUANDO O USUÁRIO TENTAR
EXECUTAR ESSE PROGRAMA?
1DEF REC(N):
2IF N < 2:
3RETURN REC(N - 1)
4
5
6PRINT(REC(1))
QUANDO O USUÁRIO TENTOU EXECUTAR ESSE
PROGRAMA, HOUVE UM ERRO. QUAL É A CAUSA?
Na linha 2, o if está escrito de maneira errada.
A função não tem condição de parada.
A função não poderia ter sido definida com uma chamada a ela própria.
GABARITO
1def func1(x):
2x = 10
3print(x)
6x = 0
7print(x)
8func1(x)
9print(x)
A variável x da linha 6 é global. Mas, como existe outra variável com o mesmo
nome dentro da função func1() – na linha 2, apenas dentro da função
func1(), x vale 10 –, chamamos essa variável de local. Assim, o print da linha 7
recebe o valor da variável global (0). A execução da linha 8 chama a
função func1(), que imprime o valor de x válido dentro dela (10). Em seguida, a
execução do programa sai da função func1() e o print da linha 9 volta a
enxergar a variável global x, cujo valor é 0.
2. Considere o seguinte trecho de um programa, com uma implementação
de função recursiva, escrito em Python:
1def rec(n):
2if n < 2:
3return rec(n - 1)
6print(rec(1))
Quando o usuário tentou executar esse programa, houve um erro. Qual é a causa?
MÓDULO 3
Operações matemáticas.
ATENÇÃO
É importante lembrar dos conceitos de classes e objetos, pois eles são os
principais conceitos do paradigma de programação orientada a objeto. As
classes são fábricas, que podem gerar instâncias chamadas objetos. Uma
classe Pessoa, por exemplo, pode ter como atributos nome e CPF. Ao gerar
uma instância de Pessoa, com nome João da Silva e CPF 000.000.000-00,
temos um objeto.
SAIBA MAIS
Para melhor compreensão dos conceitos de classe e objeto, pesquise sobre
paradigma orientado a objeto.
import nome_modulo
nome_modulo.nome_funcao(paramêtros)
Como exemplo, vamos importar o módulo math (dedicado a operações
matemáticas) e calcular a raiz quadrada de 5, por meio da função sqrt().
Observe a Figura 30:
>>> import math
>>> math.sqrt(5)
2.23606797749979
MATH
usado para operações matemáticas.
RANDOM
usado para gerar números pseudoaleatórios.
SMTPLIB
usado para permitir envio de e-mails.
TIME
usado para implementar contadores temporais.
TKINTER
usado para desenvolver interfaces gráficas.
MÓDULO MATH
Esse módulo provê acesso a funções matemáticas de argumentos reais.
As funções não podem ser usadas com números complexos.
O módulo math tem as funções listadas na Tabela 7, entre outras:
Função
cos(x) Cosseno de x
sin(x) Seno de x
log(x, b) Logaritmo de x na base b
pi Valor de Pi (3.141592...)
e Valor de e (2.718281...)
SAIBA MAIS
Para mais informações sobre o módulo math, visite a biblioteca Python.
MÓDULO RANDOM
Esse módulo implementa geradores de números pseudoaleatórios para
várias distribuições.
NÚMEROS INTEIROS
SEQUÊNCIAS
NÚMEROS INTEIROS
Para inteiros, existe:
SEQUÊNCIAS
Para sequências, existem:
Uma seleção uniforme de um elemento aleatório;
Uma função para gerar uma permutação aleatória das posições na lista;
Função
Função
Tabela 9 - Principais funções do módulo random para inteiros - Fonte: O autor (2020)
Função
(2020)
SAIBA MAIS
Para mais informações sobre o módulo random, visite a biblioteca Python.
MÓDULO SMTPLIB
Esse módulo define um objeto de sessão do cliente SMTP que pode ser
usado para enviar e-mail para qualquer máquina da internet com um
serviço de processamento SMTP ou ESMTP. O exemplo a seguir vai permitir
que você envie um e-mail a partir do servidor SMTP do Gmail.
Como a Google não permite, por padrão, realizar o login com a utilização
do smtplib por considerar esse tipo de conexão mais arriscada, será
necessário alterar uma configuração de segurança. Para resolver isso, siga as
instruções a seguir:
Depois Segurança.
Acesso a app menos seguro.
Para fazer seu primeiro envio, crie um programa novo no seu projeto. A Figura
31 mostra as importações necessárias para o envio:
4 import smtplib
5
7 msg = MIMEMultipart()
10 #parâmetros
14 msg['Subject'] = "ASSUNTO"
15
17 msg.attach(MIMEText(texto, 'plain'))
18
objeto msg.
19 #criação do servidor
21 server.starttls()
22
24 server.login(msg['From'], senha)
25
26 #envio da mensagem
28
29 #encerramento do servidor
30 server.quit()
31
33
TLS.
MÓDULO TIME
Esse módulo provê diversas funções relacionadas a tempo. Também
pode ser útil conhecer os módulos datetime e calendar. A Tabela 11
mostra algumas das principais funções disponíveis no módulo time.
Função
Figura 34 - Exemplo de uso das funções time() e ctime() - Fonte: O autor (2020)
TUPLA
Tupla é uma sequência finita de objetos. Uma tupla é similar à estrutura de
dados lista, porém, a principal diferença é que uma tupla, após definida, não
permite a adição ou remoção de elementos.
Índice Atributo
8 tm_isdst 0, 1 ou -1
SAIBA MAIS
Para mais informações sobre o módulo time, visite a biblioteca Python.
MÓDULO TKINTER
O pacote tkinter é a interface Python padrão para o Tk GUI (interface gráfica
com o usuário) toolkit. Na maioria dos casos, basta importar o próprio tkinter,
mas diversos outros módulos estão disponíveis no pacote. A
biblioteca tkinter permite a criação de janelas com elementos gráficos, como
entrada de dados e botões, por exemplo.
O exemplo a seguir vai permitir que você crie a primeira janela com alguns
elementos. Para isso, crie um programa novo no seu projeto. A Figura 35
mostra a criação da sua primeira janela, ainda sem qualquer elemento gráfico.
3 janelaPrincipal = Tk()
4 janelaPrincipal.mainloop()
elemento que representa a janela GUI. Para que essa janela apareça, é
(200,200).
3 janelaPrincipal = Tk()
5 texto.place(x = 50 y = 100)
6 janelaPrincipal.mainloop()
Veja o resultado de sua primeira janela, apenas com o texto, na Figura 37.
Fonte:ShutterstockFigura 37 - Exibição da primeira janela com tkinter - Fonte: O autor
(2020)
Vamos agora incrementar um pouco essa janela. Para isso, vamos acrescentar
uma imagem e um botão. A imagem precisa estar na mesma pasta do seu
arquivo .py.
1 from tkinter import *
3 def funcClicar():
4 print("Botão pressionado")
6 janelaPrincipal = Tk()
7 texto = Label(master = janelaPrincipal, text = "Minha janela exibida")
8 texto.pack()
10 pic = PhotoImage(file="logoEstacio.gif")
12 logo.pack()
13
15 botao.pack()
16
17 janelaPrincipal.mainloop()
18
(2020)
Botão pressionado
SAIBA MAIS
Para mais informações sobre o tkinter, visite a biblioteca Python.
Instalação do pip.
DICA
Para verificar se a sua instalação Python incluiu o pip, procure pela
pasta Scripts dentro do diretório de instalação que você escolheu para o
Python. Dentro dessa pasta, localize o arquivo pip.exe. Caso não o encontre,
pesquise sobre como instalar o pip. O mais recomendado é tentar reinstalar o
Python, lembrando de marcar a opção de incluir o pip durante o processo de
instalação.
Além do pip, é necessário termos o endereço para acessar o pip dentro da
variável de ambiente PATH. O processo de instalação do python também
permite incluir automaticamente o Python no seu PATH, porém, caso não
tenha feito isso, siga os passos abaixo:
1
Clique na tecla do Windows e escreva “Editar as variáveis de ambiente para a
sua conta”.
3
Clique no botão “Novo” e digite o endereço da sua instalação do Python (por
exemplo, D:\Python).
ATENÇÃO
Quando estiver trabalhando com pacotes externos, é extremamente
recomendado o uso de ambientes virtuais (em inglês virtual environments ou
simplesmente virtualenvs). Esses ambientes isolam o projeto em que você está
trabalhando, e uma das vantagens disso é que você consegue saber
exatamente quais pacotes externos estão sendo usados no projeto.
É possível usar pacotes externos sem o uso de ambientes virtuais, porém isso
pode causar uma confusão caso você tenha vários projetos Python no seu
computador.
Pesquise mais sobre ambientes virtuais e configure um em cada projeto. Não é
muito difícil e vai te ajudar a deixar o seu código mais profissional!
Para instalar um pacote externo disponível no PyPI, basta abrir o seu terminal
(clique no botão do Windows e digite “cmd” ou “prompt de comando”), ative
o seu ambiente virtual (se você estiver usando um) e digite o seguinte
comando: d: \Projects\exemplo_pacotes>pip install <nome_do_pacote>
Abaixo você encontra uma lista com alguns dos pacotes externos mais comuns
e utilizados no mercado:
Nome do módulo
DICA
Antes de começar o seu próprio módulo, é sempre recomendado pesquisar se
o que você quer fazer já existe em algum pacote popular. Se existir, procure
pela documentação e instale esse pacote.
2n = 5.9
3print(ceil(n))
1import math
2n = 5.9
3math.ceil(n)
4print(n)
1import math
2n = 5.9
3print(ceil.math(n))
1import math
2n = 5.9
3print(math.ceil(n))
2. SOBRE A LINGUAGEM PYTHON E SUA BIBLIOTECA
PADRÃO, É CORRETO AFIRMAR QUE:
GABARITO
Até agora, consideramos que nossos programas tiveram seu fluxo de execução
normal. Neste módulo, vamos analisar o que acontece quando o fluxo de
execução é interrompido por uma exceção, além de controlar esse fluxo
excepcional.
ERROS E EXCEÇÕES
Dois tipos básicos de erros podem acontecer em um programa em Python.
Os erros de sintaxe são aqueles que ocorrem devido ao formato incorreto de
uma instrução. Esses erros são descobertos pelo componente do interpretador
Python, chamado analisador ou parser. Veja exemplos na Figura 41 e na
Figura 42:
>>> print 'hello'
print 'hello'
lista = [1 ; 2 ; 4]
A divisão por 0.
Exceção
CAPTURA E MANIPULAÇÃO DE
EXCEÇÕES
Para evitar que os programas sejam interrompidos quando uma exceção for
levantada, é possível planejar um comportamento alternativo. Assim, o
programa não será interrompido e a exceção poderá ser tratada. Chamamos
esse processo de captura da exceção.
Vamos considerar um exemplo de programa que solicita ao usuário, com a
função input(), um número inteiro. Embora essa função trate a entrada do
usuário como string, é possível utilizá-la em conjunto com a função eval() para
que os dados inseridos sejam avaliados como números. A Figura 43 mostra
uma implementação simples desse exemplo.
1 num = eval(input("Entre com um número inteiro: "))
2 print(num)
(2020)
Veja que o programa foi encerrado com uma exceção sendo levantada. Uma
forma de fazer a captura e a manipulação de exceções é usar o par de
instruções try / except.
O bloco try é executado primeiro, no qual devem ser inseridas as instruções do
fluxo normal do programa.
O bloco except somente será executado se houver o levantamento de alguma
exceção.
1 try:
3 print(num)
4 except:
2 Bloco 1
3 except:
4 Bloco 2
CAPTURA DE EXCEÇÕES DE
DETERMINADO TIPO
Python permite que o bloco relativo ao except só seja executado caso a
exceção levantada seja de determinado tipo. Para isso, o except precisa trazer
o tipo de exceção que se deseja capturar. A Figura 47 traz uma possível
variação do exemplo anterior, com a captura apenas das exceções do
tipo NameError.
1 try:
3 print(num)
4 except NameError:
(2020)
CAPTURA DE EXCEÇÕES DE
MÚLTIPLOS TIPOS
Python permite que haja diversos tratamentos para diferentes tipos
possíveis de exceção. Isso pode ser feito com mais de uma
cláusula except vinculada à mesma cláusula try. A Figura 48 mostra um
exemplo de implementação da captura de exceções de múltiplos tipos.
1 try:
3 print(num)
4 except ValueError:
5 print("Mensagem 1")
6 except IndexError:
7 print("Mensagem 2")
8 except:
9 print("Mensagem 3")
do tipo IndexError.
try:
2 Bloco 1
3 except Exception1:
5 except Exception2:
7 ...
8 else:
10 finally:
TRATAMENTO DE EVENTOS
O tratamento de eventos é similar ao tratamento de exceções. Assim como
podemos tratar as exceções ocorridas em tempo de execução, podemos tratar
os eventos criados por ações externas, como interações de usuário realizadas
por meio de uma interface gráfica de usuário (GUI).
UM EVENTO É A NOTIFICAÇÃO DE QUE ALGUMA
COISA ACONTECEU, COMO UM CLIQUE DE MOUSE
SOBRE UM ELEMENTO BOTÃO. O TRATADOR DO
EVENTO É O SEGMENTO DE CÓDIGO QUE SERÁ
EXECUTADO EM RESPOSTA À OCORRÊNCIA DO
EVENTO.
No vídeo a seguir, o professor nos apresenta exemplos práticos do tratamento
das exceções. Vamos assistir!
VERIFICANDO O APRENDIZADO
1. CONSIDERE O SEGUINTE TRECHO DE UM PROGRAMA
ESCRITO EM PYTHON:
1 TRY:
2 NUM = EVAL(INPUT("ENTRE COM UM NÚMERO INTEIRO: "))
3 PRINT(NUM)
4 EXCEPT VALUEERROR:
5 PRINT("MENSAGEM 1")
6 EXCEPT INDEXERROR:
7 PRINT("MENSAGEM 2")
8 EXCEPT:
9 PRINT("MENSAGEM 3")
SUPONHA QUE DURANTE A EXECUÇÃO O USUÁRIO ENTRE
COM A PALAVRA NUMERO QUANDO SOLICITADO.
ASSINALE A OPÇÃO QUE MOSTRA O RESULTADO
IMEDIATO DESSA AÇÃO.
GABARITO
1 try:
3 print(num)
4 except ValueError:
5 print("Mensagem 1")
6 except IndexError:
7 print("Mensagem 2")
8 except:
9 print("Mensagem 3")
Como o usuário inseriu uma palavra e não um número, a exceção não será do
tipo ValueError nem do tipo IndexError. Assim, a cláusula except a ser
executada é a da linha 8, imprimindo Mensagem 3.
CONCLUSÃO
CONSIDERAÇÕES FINAIS
Neste tema, você aprendeu a usar as estruturas de controle, sejam de decisão
ou de repetição, foi apresentado aos conceitos de subprogramas em Python,
implementou suas próprias funções, além de conhecer e utilizar as bibliotecas.
Por fim, analisou as formas de tratamento de exceções e eventos. Com esse
conteúdo, você com certeza terá condições de desenvolver aplicações muito
mais complexas e com muito mais recursos.
AVALIAÇÃO DO TEMA:
REFERÊNCIAS
PERKOVIC, L. Introdução à computação usando Python: um foco no
desenvolvimento de aplicações. Rio de Janeiro: LTC, 2016.
SEBESTA, R. W. Conceitos de linguagens de programação. 11. ed. São
Paulo: Bookman, 2018.
EXPLORE+
Para ter desafios mais complexos e exercícios para treinar, recomendamos
uma visita ao website Python Brasil.
CONTEUDISTA
Humberto Henriques de Arruda
CURRÍCULO LATTES
DEFINIÇÃO
Introdução aos conceitos da orientação a objetos; Classes e Encapsulamento;
Herança e Polimorfismo; Construtores; Atributos e Métodos; Implementação de
Herança; Implementação de Polimorfismo; Classes Abstratas; Tratamento de
Exceções; Python e linguagens OO.
PROPÓSITO
Compreender o desenvolvimento de software orientado a objetos, utilizando
uma linguagem de programação como Python com grande aceitação no meio
comercial e acadêmico. Entender os conceitos e pilares da orientação a objetos
e saber contextualizar o Python entre as outras linguagens tradicionais
orientadas a objetos como Java e C++.
PREPARAÇÃO
Para este módulo, é necessário conhecimentos de programação em linguagem
Python, incluindo modularização e utilização de bibliotecas em Python. Antes
de iniciar o conteúdo deste tema é necessário que tenha o interpretador Python
na versão 3.7.7 e o ambiente de desenvolvimento PyCharm ou outro ambiente
que suporte o desenvolvimento na linguagem Python.
OBJETIVOS
MÓDULO 1
Definir os conceitos gerais da orientação a objetos
MÓDULO 2
Descrever os conceitos básicos da programação orientada a objetos na
linguagem Python
MÓDULO 3
Descrever os conceitos da orientação a objetos como Herança e Polimorfismo
MÓDULO 4
Comparar a implementação dos conceitos orientados a objetos aplicados a
Python com outras linguagens orientadas a objetos existentes no mercado
INTRODUÇÃO
O paradigma de programação orientado a objetos é largamente utilizado para o
desenvolvimento de software devido à sua implementação ser próxima dos
conceitos do mundo real. Essa proximidade facilita a manutenção dos
softwares orientados a objetos. A linguagem Python implementa os conceitos
do paradigma orientado a objetos e, devido à sua sintaxe simples e robusta,
torna-se uma ferramenta poderosa para a implementação de sistemas
orientados a objetos.
MÓDULO 1
CONCEITOS DE POO -
PROGRAMAÇÃO ORIENTADA A
OBJETOS
A programação orientada a objetos foi considerada uma revolução na
programação, pois mudou completamente a estruturação dos programas de
computador. Essa mudança se estendeu, inclusive, para os modelos de análise
do mundo real e depois para a implementação dos respectivos modelos nas
linguagens de programação orientadas a objetos.
PILARES DA ORIENTAÇÃO A
OBJETOS
OBJETOS
Um objeto é a representação computacional de um elemento ou processo do
mundo real. Cada objeto possui suas características (informações) e uma série
de operações (comportamento) que alteram as suas características (estado do
objeto). Todo o processamento das linguagens de programação orientadas a
objetos se baseia no armazenamento e na manipulação das informações
(estados). São exemplos de objetos do mundo real e computacional: Aluno,
Professor, Livro, Empréstimo e Locação. (Costa, 2015)
ATRIBUTOS
São propriedades do mundo real que descrevem um objeto. Cada objeto
possui suas respectivas propriedades do mundo real, os quais possuem
valores. A orientação a objetos define as propriedades como atributos. O
conjunto de valores dos atributos de um objeto definem o seu estado naquele
momento (RUMBAUGH, 1994).
Atributos V
Nome Maria
Idade 35
Peso 63kg
Altura 1,70m
Atributos V
Nome Joana
Idade 30
Peso 60kg
Altura 1,65m
OPERAÇÕES
Uma operação é uma função ou transformação que pode ser aplicada a objetos
ou dados pertencentes a um objeto. Importante dizer que todo objeto possui
um conjunto de operações, que podem ser chamadas por outros objetos de
modo a colaborarem entre si. Esse conjunto de operações é conhecido
como interface. A única forma de colaboração entre os objetos é por meio das
suas respectivas interfaces (FARINELLI, 2020).
EXEMPLO
Classe empresa = Contratar_Funcionario, Despedir_Fucionario;
CLASSES
A classe descreve as características e os comportamento de um conjunto de
objetos. De acordo com a estratégia de classificação, cada objeto pertence a
uma única classe e possuirá os atributos e as operações definidos na classe.
Durante a execução de um programa orientado a objetos, são instanciados os
objetos a partir da classe, portanto, um objeto é chamado de instância de
sua classe.
ATENÇÃO
Importante ressaltar que cada nome de atributo é único dentro de uma classe,
no entanto, essa premissa não é verdadeira quando se consideram todas as
classes. Por exemplo, as classes Pessoa e Empresa podem ter um atributo
comum chamado de Endereço.
Com base na Tabela 1, vista anteriormente, deve ser definida uma classe
Pessoa com os atributos Nome, Idade, Peso e Altura. A partir da classe
Pessoa, pode-se instanciar uma quantidade ilimitada de objetos contendo os
mesmos atributos. Os objetos de uma classe sempre compartilham o conjunto
de operações que atuam sobre seus dados, alterando o estado do objeto.
ENCAPSULAMENTO
O conceito de encapsulamento consiste na separação dos aspectos externos
(operações) de um objeto acessíveis a outros objetos, além de seus detalhes
internos de implementação, que ficam ocultos dos demais objetos
(RUMBAUGH, 1994). Algumas vezes, é conhecido como o princípio do
ocultamento de informação, pois permite que uma classe encapsule atributos e
comportamentos, ocultando os detalhes da implementação. Partindo desse
princípio, a interface de comunicação de um objeto deve ser definida de modo
a revelar o menos possível sobre o seu funcionamento interno.
EXEMPLO
Foi desenvolvido um objeto ApresentaçãoMapa, pertencente a um aplicativo de
entrega móvel, que possui a responsabilidade de apresentar um mapa com o
menor caminho entre dois pontos. Porém, o objeto não “sabe” como calcular a
distância entre os dois pontos.
Para resolver esse problema, ele precisa colaborar com um objeto Mapa que
“sabe” calcular e, portanto, possui essa responsabilidade. O objeto Mapa
implementa essa responsabilidade por meio da operação Calcula Melhor
Caminho, cujo resultado é a menor rota entre duas coordenadas geográficas.
RESUMINDO
Os objetos clientes têm conhecimento apenas das operações que podem ser
requisitadas e precisam estar cientes apenas do que as operações realizam, e
não de como elas estão implementadas.
HERANÇA
Na orientação a objetos, a herança é um mecanismo por meio do qual classes
compartilham atributos e comportamentos, formando uma hierarquia. Uma
classe herdeira recebe as características de outra classe para reimplementá-
las ou especializar de uma maneira diferente da classe pai. A herança permite
capturar similaridades entre classes, dispondo-as em hierarquias. As
similaridades incluem atributos e operações sobre as classes (FARINELLI,
2020).
Uma classe pode ser definida genericamente como uma superclasse e, depois,
especializada em classes mais específicas (subclasses). A herança permite a
reutilização de código em larga escala, pois possibilita que se herde todo o
código já implementado na classe pai e se adicione apenas o código específico
para as funcionalidades novas implementadas pela classe filha.
HERANÇA MÚLTIPLA
Para adaptar essa situação no mundo real, deve ser criada uma modelagem de
classes. Uma nova subclasse ProfessorAluno precisa ser adicionada, herdando
atributos e operações das classes Professor e Aluno. Isso configura uma
herança múltipla. Essa nova subclasse deverá ter o atributo
DescontoProfessor, que faz sentido apenas para essa classe.
Fonte: AutorFigura 7 – Exemplo de herança Pessoa -> Professor e Pessoa ->
Aluno e Professor/Aluno ->ProfessorAluno.
POLIMORFISMO
O Polimorfismo é a capacidade de um mesmo comportamento diferente em
classes diferentes. Uma mesma mensagem será executada de maneira
diversa, dependendo do objeto receptor. O polimorfismo acontece quando
reimplementamos um método nas subclasses de uma herança (FARINELLI,
2020).
VERIFICANDO O APRENDIZADO
1. NA PROGRAMAÇÃO ORIENTADA A OBJETOS, TEMOS
CONCEITOS COMO HERANÇA E POLIMORFISMO. SOBRE
ESSES CONCEITOS ANALISE AS ASSERTIVAS E ASSINALE
A ALTERNATIVA QUE APONTA A(S) CORRETA(S).
I. PARA EVITAR CÓDIGO REDUNDANTE, O PARADIGMA DE
ORIENTAÇÃO A OBJETOS OFERECE UMA ESTRUTURA
HIERÁRQUICA E MODULAR PARA REUTILIZAÇÃO DE
CÓDIGO ATRAVÉS DE UMA TÉCNICA CONHECIDA COMO
HERANÇA.
II. HERANÇA PERMITE PROJETAR CLASSES GENÉRICAS
QUE PODEM SER ESPECIALIZADAS EM CLASSES MAIS
PARTICULARES, ONDE AS CLASSES ESPECIALIZADAS
REUTILIZAM O CÓDIGO DAS MAIS GENÉRICAS.
III. LITERALMENTE, “POLIMORFISMO” SIGNIFICA “MUITAS
FORMAS”. NO CONTEXTO E PROJETO ORIENTADO A
OBJETOS, ENTRETANTO, REFERE-SE À HABILIDADE DE
UMA VARIÁVEL DE OBJETO DE ASSUMIR FORMAS
DIFERENTES.
IV. POLIMORFISMO PERMITE QUE OS ATRIBUTOS DE UMA
CLASSE NÃO TENHAM ACESSO DIRETAMENTE.
Apenas I.
Apenas I e III.
Apenas I, II e III.
GABARITO
DEFINIÇÃO DE CLASSE
Como boa prática, cada classe deve fazer parte de um único arquivo.py para
ajudar na estruturação do sistema orientado a objetos em Python. Outra boa
prática consiste no nome da classe semelhante ao do arquivo. Por exemplo,
definir no ambiente de desenvolvimento Python a classe Conta. O nome final
do arquivo deve ser Conta.py.
class Conta:
pass
RECOMENDAÇÃO
É recomendável que você reproduza e execute todos os exemplos que serão
apresentados a seguir.
CONSTRUTORES E SELF
A classe conta foi criada, porém não lhe foram definidos atributos e
instanciados objetos, característica básica dos programas orientados a objetos.
Nas linguagens orientadas a objetos, para se instanciar objetos, devemos criar
os construtores da classe.
self.numero = numero
self.cpf = cpf
self.nomeTitular = nomeTitular
self.saldo = saldo
class A():
def f():
print ‘foo’
MÉTODOS
def __depositar__(self,valor)
self.saldo += valor
class Conta:
self.numero = numero
self.cpf = cpf
self.nomeTitular = nomeTitular
self.saldo = saldo
self.saldo += valor
self.saldo -= valor
self.numero = numero
self.cpf = cpf
self.nomeTitular = nomeTitular
self.saldo = saldo
self.saldo += valor
def sacar(self, valor):
self.saldo -= valor
def gerarextrato(self):
....c1.geratextrato()
200
MÉTODOS COM RETORNO
def sacar(self,valor):
return False
else:
self.saldo -= valor
return True
....c1.sacar(100)
True
Uma classe pode ter mais de uma ou várias instâncias de objetos na memória,
como exemplificado na imagem a seguir:
from Conta import Conta
conta1 = conta2
if (conta1 == conta2):
... print("enderecos iguais de memoria")
Fonte: AutorFigura 16 – Estado da memória conta1 e conta2 no mesmo
endereço.
>>>conta1.cpf
456
>>> conta2.cpf
456
Esse exemplo pode ser estendido para realizar uma transferência de valores
de uma conta para outra. A segunda conta deve ser passada como parâmetro
do método para ser executada a transferência. O método deve ficar da
seguinte maneira:
class Conta:
self.numero = numero
self.cpf = cpf
self.nomeTitular = nomeTitular
self.saldo = saldo
self.saldo += valor
def sacar(self,valor):
else
self.saldo -= valor
return True
def gerarextratp(self):
print(f"numero:{self.numero}\n cpf:{self.cpf}\nsaldo:{selfsaldo}")
def transfereValor(self,contaDestino,valor):
else:
contaDestino.depositar(valor)
self.saldo -= valor
return("Transferencia Realizada")
class Conta:
def__init__(self,cpf,nome,endereco):
self.cpf = cpf
self.nome = nome
self.endereco = endereco
class Conta:
self.clientes = clientes
self.numero = numero
self.saldo = saldo
self.saldo += valor
def sacar(self,valor):
return False
else:
self.saldo -= valor
return True
def transfereValor(self,contaDestino,valor):
else:
contadestino.depositar(valor)
self.saldo -= valor
return("Transferencia Realizada")
def gerarsaldo(self):
conta1.gerarsaldo()
conta1.depositar(1500)
conta1.sacar(500)
conta1.gerarsaldo()
ATENÇÃO
Em (1) foi instanciado um objeto conta1 com dois clientes agregados: cliente1 e
cliente2. Esses dois objetos são passados como parâmetros em (1).
Sugestão: altere o programa do código anterior para criar mais uma conta para
dois clientes diferentes. Como desafio, tente, através do objeto conta, imprimir
o nome e o endereço dos clientes associados às contas.
COMPOSIÇÃO
A classe conta ainda não está completa de acordo com as necessidades do
sistema de conta corrente do banco. Isso ocorre porque o banco precisa gerar
extratos contendo o histórico de todas as operações realizadas para conta
corrente. Para isso, o sistema deve ser atualizado para adicionar uma
composição de cada conta com o histórico de operações realizadas. O
diagrama a seguir representa a composição entre as classes Conta e Extrato.
Esta composição representa que uma conta pode ser composta por vários
extratos. Uma observação: o losango preenchido tem a semântica da
composição.
class Extrato:
def__init_(self):
self.transacoes = []
for p in self.transacoes:
ARRAY DE VALORES
Um array ou vetor é uma estrutura que permite que sejam armazenados um
conjunto de valores do mesmo tipo.
import datetime
class Conta:
def__init__(self,clientes,numero,saldo):
self.clientes = clientes
self.numero = numero
self.saldo = saldo
self.saldo += valor
return False
else:
self.saldo -= valor
return True
else:
contadestino.depositar(valor)
self.saldo -= valor
(4)
def gerarsaldo(self):
Adição das linhas (2), (3) e (4) – adição de linhas ao array de transações do
objeto Extrato através do atributo extrato.
Execução no terminal:
DICA
Experimente adicionar mais uma conta e realize uma transferência de valores
entre ambas. Depois, crie uma classe Banco para armazenar todos os clientes
e todas as contas do banco.
ENCAPSULAMENTO
Conforme apresentado no módulo anterior, o encapsulamento é fundamental
para a manutenção da integridade dos objetos e proibir qualquer alteração
indevida nos valores dos atributos (estado) do objeto (CAELUM, 2020). Este
ponto foi fundamental para a popularização da orientação aos objetos: reunir
dados e funções em uma única entidade e proibir a alteração indevida dos
atributos.
EXEMPLO
No caso da classe conta, imagine que algum programa tente realizar a seguinte
alteração direta no valor do saldo:
conta1.saldo = -200
Esse comando viola a regra de negócio do método sacar(), que indica para não
haver saque maior do que o valor e deixar a conta no negativo (estado inválido
para o sistema).
return False
else:
self.saldo -= valor
return True
... def__init__(self,numero,saldo):
>>> conta._Conta__saldo
1000
Na prática, deve existir uma disciplina para não serem acessados diretamente
os atributos como __ ou _ definido nas classes.
DECORATOR @PROPERTY
Uma estratégia importante disponibilizada pelo Python são as properties.
Utilizando o decorator property nos métodos, mantém-se os atributos como
protegidos, e estes são acessados apenas através dos métodos “decorados”
com property (CAELUM, 2020).
No caso da classe conta, não se pode acessar o atributo saldo (privado) para
leitura. Com o código, ele será acessado pelo método decorator @property:
@property
def saldo(self):
return self._saldo
Notação:
@<nomedometodo>.setter
@saldo.setter
print(“saldo inválido”)
else:
self._saldo = saldo
ATRIBUTOS DE CLASSE
class Circulo():
def__init__(self,pontox,pontoy,raio):
self.pontox = pontox
self.pontoy = pontoy
self.raio = raio
class Circulo():
total_circulos = 0 (1)
self.pontox = pontox
self.pontoy = pontoy
self.raio = raio
_total_circulos = 0
self.pontox = pontox
self.pontoy = pontoy
self.raio = raio
circulo._total_circulos += 1
class Circulo:
_total_circulos = 0
self.pontox = pontox
self.pontoy = pontoy
self.raio = raio
type(self)._total_circulos +=1
@classmethod
self.clientes = clientes
self.numero = numero
self.saldo = saldo
def __gerarsaldo(self):
MÉTODOS ESTÁTICOS
São métodos que podem ser chamados sem ter uma referência para um objeto
da classe, ou seja, não existe obrigatoriedade da instanciação de um objeto da
classe. O método pode ser chamado diretamente:
import math
class Math:
@staticmethod
def sqrt(x):
return math.sqrt(x)
>>> Math.sqrt(20)
4.47213595499958
No caso acima, foi chamado o método sqrt da classe Math sem haver
instanciado um objet da classe Math. Os métodos estáticos não são uma boa
prática na programação orientada a objetos. Devem ser utilizados apenas em
casos especiais, como classes de log em sistemas.
ENTENDA MAIS SOBRE
AGREGAÇÃO, CLASSES E
MÉTODOS ESTÁTICOS
No vídeo a seguir, faremos uma breve contextualização do tema.
VERIFICANDO O APRENDIZADO
1. ANALISE O SEGUINTE CÓDIGO ESCRITO EM PYTHON,
QUE DEFINE A ESTRUTURA DA CLASSE CONTABANCARIA:
CLASS CONTABANCARIA:
NUM_CONTAS = 0
DEF__INIT__(SELF,CLIENTES,NUMERO,SALDO):
SELF.AGENCIA = AGENCIA
SELF.NUMERO = NUMERO
SELF.SALDO = SALDO
CONTABANCARIA.NUM_CONTAS += 1
DEF _DEL_(SELF):
CONTABANCARIA.NUM_CONTAS -= 1
DEF DEPOSITAR(SELF,VALOR):
RETURN SELF.SALDO
GABARITO
class ContaBancaria:
num_contas = 0
def__init__(self,clientes,numero,saldo):
self.agencia = agencia
self.numero = numero
self.saldo = saldo
ContaBancaria.num_contas += 1
def _del_(self):
ContaBancaria.num_contas -= 1
def depositar(self,valor):
def consultarSaldo(Self):
return self.saldo
HERANÇA E POLIMORFISMO
As linguagens orientadas a objeto oferecem recursos que permitem o
desenvolvimento de sistemas de uma forma mais ágil e eficiente. Esses
recursos são a herança, polimorfismo e o tratamento das exceções. A herança
permite uma redução da repetição de código, permitindo que uma classe filho
herde métodos e atributos da classe pai. O polimorfismo permite que, em
determinadas situações, os objetos possam ter comportamentos específicos.
Caso haja algum problema durante a execução do código, o tratamento de
exceções facilita a manipulação do erro.
HERANÇA
É um dos princípios mais importantes da programação orientada a objetos, pois
permite a reutilização de código com a possiblidade de extensão para se
ajustar às regras de negócio dos sistemas.
EXEMPLO
A área de produtos do banco define quais clientes podem ter acesso a um
produto chamado Conta especial, o qual busca atender quem possui conta na
instituição há mais de um ano.
import datetime
class ContaEspecial(Conta):
def__init__(self,clientes,numero,saldo,limite):
Conta.__init__(self,clientes,numero,saldo) (1)
return False
else:
self.saldo -= valor
return True
ATRIBUTO LIMITE
Foi adicionado apenas na subclasse ContaEspecial, onde será utilizado para
implementar a regra de saques além do valor do saldo (2).
MÉTODO SACAR()
O método precisa verificar se o valor a ser sacado, passado como parâmetro, é
menor do que a soma do saldo atual mais o limite da conta especial. Nesse
caso, a classe Conta Especial reescreveu o método sacar da superclasse
Conta. Essa característica é conhecida como sobrescrita (override) dos
métodos (3).
HERANÇA MÚLTIPLA
A herança múltipla é um mecanismo que possibilita uma classe herdar código
de duas ou mais superclasses. Esse mecanismo é implementado por poucas
linguagens orientadas a objetos e insere uma complexidade adicional na
arquitetura das linguagens.
import datetime
class ContaPoupanca:
def__init__(self,taxaremuneracao):
self.taxaremuneracao = taxaremuneracao
self.data_abertura = datetime.datetime.today()
def remuneracaoConta(self)
Conta.__init__(self,clientes,numero,saldo) (2)
Poupanca.__init__(self,taxaremuneracao) (2)
self.taxaremuneracao = taxaremuneracao
def remuneraConta(Self):
self.saldo -= self.taxaremuneracao
Execução no terminal:
POLIMORFISMO
Polimorfismo é o mecanismo que permite que um método com o mesmo nome
seja executado de modo diferente, dependendo do objeto que está chamando
o método. A linguagem define em tempo de execução (late binding) qual
método deve ser chamado. Essa característica é bastante comum em herança
de classes devido à redefinição da implementação dos métodos nas
subclasses.
Vamos assumir que agora teremos uma entidade Banco que controla todas as
contas criadas no sistema de conta corrente. As contas podem ser do tipo
conta, contacomum ou contarenumerada. O cálculo do rendimento da conta
Cliente desconta IOF e IR; a conta Renumerada desconta apenas o IOF; a
conta Cliente não tem desconto nenhum. Todos os descontos são realizados
em cima do valor bruto após o rendimento mensal. Uma vez por vez o Banco
executa o cálculo do rendimento de todos os tipos de contas. O diagrama é
apresentado na Figura 42.
Fonte: AutorFigura 42 - Diagrama Banco.
class ContaCliente:
self.numero = numero
self.IOF = IOF
self.IR = IR
self.valorinvestido = valorinvestido
self.taxarendimento = taxarendimento
def CalculoRendimento(self):
class ContaComum(ContaCliente)
def__init__(self,numero,IOF,IR,valorinvestido,taxarendimento):
super().__init__(numeroIOFIR,valorinvestido,taxarendimento)
class ContaRemunerada(ContaCliente):
def__init__(self,numero,IOF,IR,valorinvestido,taxarendimento):
super().__init__(numeroIOFIR,valorinvestido,taxarendimento)
def CalculoRendimento(Self): (3)
Em (1), foi definido um método Extrato que é igual para as 3 classes, ou seja,
as subclasses herdarão o código completo desse método. Em (2) e (3), as
subclasses possuem regras de negócios diferentes, portanto sobrescreveram o
método CalculoRendimento para atender às suas necessidades.
class Banco():
def__init__(self, codigo,nome):
self.codigo = codigo
self.nome = nome
self.contas = []
def adicionaconta(self,contacliente):
self.contas.append(contacliente)
for c in self.contas:
c.CalculoRendimento()
def imprimesaldocontas(self):
for c in self.contas:
banco1 = Banco(999,"teste")
contacomum1 = ContaComum(2,0.01,0.1,2000,0.05)
contaremunerada1 = ContaRemunerada(3,0.01,0.1,2000,0.05)
banco1.adicionaconta(contacliente1) (4)
banco1.adicionaconta(contacomum1) (5)
banco1.adicionaconta(contaremunerada1) (6)
banco1.calcularendimentomensal(7)
banco1.imprimesaldocontas() (8)
CLASSES ABSTRATAS
Definir uma classe abstrata é uma característica bastante utilizada pela
programação orientada a objetos. Esse é um tipo de classe que não pode ser
instanciado durante a execução do programa orientado a objetos, ou seja, não
podem existir objetos dessa classe sendo executados na memória. O termo
abstrato remete a um conceito do mundo real, considerando que preciso
apenas de objetos concretos no programa.
O Python utiliza um módulo chamado abc para definir uma classe como
abstrata, a qual será herdeira da superclasse ABC (Abstract Base Classes).
Toda classe abstrata é uma subclasse da classe ABC (CAELUM, 2020). Para
tornar a classe Conta Cliente abstrata, muda-se a definição para:
class ContaCliente(ABC):
Para uma classe ser considerada abstrata, tem de ter pelo menos um método
abstrato. Esse método abstrato pode ter implementação, embora não faça
sentido, pois ele deverá, obrigatoriamente, ser implementado pelas subclasses.
Em nosso exemplo, como não teremos o ContaCliente, esta conta não terá
Calculo do rendimento.
class ContaCliente(ABC)
def__init__(self,sumero,IOF,IR,valorinvestido,taxarendimento):
self.numero = numero
self.IOF = IOF
self.IR = IR
self.valorinvestido = valorinvestido
self.taxarendimento = taxarendimento
@abstractmethod
def CalculoRendimento(self):
pass
ATENÇÃO
Um alerta importante é que as classes mencionadas devem, obrigatoriamente,
implementar os métodos. Caso contrário, serão classes abstratas e delegarão
para as suas subclasses a implementação concreta do método abstrato.
EXCEÇÕES
Como diversas linguagens orientadas a objetos, o Python permite criar novos
tipos de exceções para diferenciar os erros gerados pelas bibliotecas da
linguagem dos erros gerados pelas aplicações desenvolvidas. Devemos usar a
característica da herança para herdar novas exceções a partir classe Exception
do Python (MENEZES, 2020).
pass
try: (3)
throws()
No código acima:
GABARITO
MÓDULO 4
LINGUAGEM DE PROGRAMAÇÃO
ORIENTADAS A OBJETOS
As linguagens orientadas a objetos C++ e Java são bastante utilizadas assim
como Python. Inclusive, estão em posições subsequentes no ranking das
linguagens mais utilizadas de todos os paradigmas (TIO-BE, 2020). Portanto, é
interessante fazer um paralelo das principais características de cada linguagem
em relação a orientada a objetos: Python (RAMALHO, 2020), C++ (C++, 2020)
e Java (JAVA, 2020)
Java
CONSTRUTORES DE OBJETOS
As linguagens Java e C++ exigem um método definido como público e com o
mesmo nome da classe. O Python obriga ser um método privado __init__,
conforme apresentado na tabela 4.
Java C++
Utilizado um método público com o mesmo nome Utilizado um método com o mesmo
da classe sem tipo de retorno: Public Conta() sem tipo de retorno: Conta::Conta(v
Java C++
private public
protected private
default
Java C++
Java C++
public void setSoma(int soma) { Existe o conceito de classes locais – inte
return soma; }
}
}
TIPOS PRIMITIVOS
Java C++
Possui vários tipos primitivos:
Possui vários tipos primitivos:
int
bool
byte
char
short
int
long
float
float
double
double
void
boolean
wchar_t
char
INTERFACES
Java
SOBRECARGA DE MÉTODOS
As linguagens Java e C++ implementam sobrecarga de métodos nativamente,
enquanto Python não implementa nativamente.
Java
calculaimposto(salario) calculaimposto(salar
calculaImposto(salario,IR) calculaImposto(salar
TABELA COMPARATIVA
A Tabela 11 apresenta um resumo das características das linguagens Java, C+
+ e Python. A linguagem Python não possui atributos privados, interfaces e
sobrecarga de métodos, que são necessidades fundamentais para a
construção de sistemas orientados a objetos robustos baseado em design
patterns. Portanto, Java e C++ levam uma vantagem considerável para
construção de sistemas puramente orientados a objetos.
Características
Instanciação de objetos
Construtores de objetos
Herança múltipla
Classes informais
Tipos primitivos
Interfaces
Sobrecarga de métodos
COMPARAÇÃO ENTRE AS
LINGUAGENS C++, JAVA E PYTHON
No vídeo a seguir, faremos uma breve contextualização do tema.
VERIFICANDO O APRENDIZADO
1. EM PYTHON, COMO TRABALHAR SEMPRE COM TIPOS
OBJETOS:
x = c + ADD(a + b).
obj(8).__.
5.__add__(3).
sub(5).__add__(3).
II e III, apenas.
I e II, apenas.
III, apenas.
GABARITO
CONCLUSÃO
CONSIDERAÇÕES FINAIS
O paradigma orientado a objetos é largamente utilizado no mercado devido a
facilidade na transformação de conceitos do mundo real para objetos
implementados em uma linguagem de software. A linguagem Python
implementa o paradigma utilizando uma sintaxe simples e robusta. Portanto,
vem ganhando mercado, tanto na área acadêmica, quanto na área comercial,
para o desenvolvimento de sistemas orientado a objetos.
Outro ponto importante é que, devido a sua simplicidade, Python vem sendo
utilizada como a primeira linguagem a ser aprendida nos primeiros períodos
dos cursos de tecnologia e engenharia, inclusive para fixar os conceitos da
orientação a objetos.
AVALIAÇÃO DO TEMA:
REFERÊNCIAS
ANAYA, M. Clean Code in Python: Refactor Your Legacy Code Base. Packt
Publishing Ltd, 29 ago. 2018.
CAELUM. Python e Orientação a Objetos. Consultado em meio eletrônico
em: 14 jun. 2020.
COSTA, M. Análise Orientada a Objetos, março de 2017, 100 f. Notas de
Aula.
FARINELLI, F. Conceitos básicos de programação orientada a objetos.
Consultado em meio eletrônico em: 14 jun. 2020.
GIRIDHAR, C. Learning Python Design Patterns. Packit Publishing, 2018.
JAVA. Java Tutorial. Consultado em meio eletrônico em: 14 jun. 2020.
MENEZES, N. C. Introdução a programação com Python. 3. ed. São Paulo:
Novatec, 2019.
PAJANKAR, A. Python Unit Test Automation: Practical Techniques for
Python Developers and Testers. Apress, 2017.
PYTHON COURSE, Blog Python. Consultado em meio eletrônico em: 14 jun.
2020.
QCONCURSOS, Questões de Concursos. Consultado em meio eletrônico
em: 18 jun. 2020.
RAMALHO, L. Fluent Python. Sebastopol, CA: O´Reilly Media, 2015.
RAMALHO, L. Introdução à Orientação a Objetos em Python (sem sotaque).
Consultado em meio eletrônico em: 14 jun. 2020.
REAL PYTHON, Blog Python, Consultado em meio eletrônico em: 14 jun. 2020.
EXPLORE+
Para saber mais sobre os assuntos tratados neste tema:
CONTEUDISTA
Marcelo Nascimento Costa
CURRÍCULO LATTES
DEFINIÇÃO
Apresentação básica da utilização do Python em outros paradigmas, como
linguagem funcional, computação concorrente, desenvolvimento web e ciência
de dados.
PROPÓSITO
Apresentar a programação por meio do paradigma de linguagem funcional,
bem como a utilização do framework Flask para aplicações web com Python e
a sua utilização para a realização de tarefas relacionadas à mineração de
dados e à extração de conhecimento.
PREPARAÇÃO
Para este tema, é necessário conhecimento prévio em Python.
OBJETIVOS
MÓDULO 1
Identificar a linguagem funcional e sua utilização em Python
MÓDULO 2
Definir os conceitos de computação concorrente e sua utilização em Python
MÓDULO 3
Identificar o Python como ferramenta para desenvolvimento web
MÓDULO 4
Identificar o Python como ferramenta para ciência de dados
INTRODUÇÃO
Neste tema, veremos a utilização da linguagem Python em outros paradigmas,
como linguagem funcional, computação concorrente, desenvolvimento web e
ciência de dados.
Apesar do Python não ser uma linguagem puramente funcional, ela fornece
ferramentas para que possamos programar utilizando esse paradigma. Neste
tema, veremos como isso é possível e quais as vantagens desse estilo de
programação.
MÓDULO 1
INTRODUÇÃO
A programação funcional teve seu início no final dos anos 1950, com a
linguagem LISP.
LISP
LISP é uma família de linguagens de programação desenvolvida, em 1958, por
John McCarthy. Ela foi pensada a princípio para o processamento de dados
simbólicos. Ela é uma linguagem formal matemática.
1
Devem ser puras, ou seja, em qualquer ponto do programa, sempre produzem
o mesmo resultado quando passados os mesmos parâmetros;
Os dados devem ser imutáveis, e uma vez definida uma variável, seu valor não
pode ser alterado;
3
Os loops não devem ser utilizados, mas sim a composição de funções ou
recursividade.
A utilização dessas regras visa garantir, principalmente, que não haja um efeito
indesejável e imprevisto quando executamos um programa ou parte dele.
MUITAS LINGUAGENS DE
PROGRAMAÇÃO (COMO PYTHON, JAVA
E C++) DÃO SUPORTE PARA A
PROGRAMAÇÃO FUNCIONAL, PORÉM
SÃO DE PROPÓSITO GERAL, DANDO
BASE PARA OUTROS PARADIGMAS,
COMO PROGRAMAÇÃO IMPERATIVA E
ORIENTADA A OBJETOS.
Outras linguagens, como Haskell, Clojure e Elixir, são predominantemente de
programação funcional.
FUNÇÕES PURAS
São aquelas que dependem apenas dos parâmetros de entrada para gerar
uma saída. Elas sempre retornam um valor, um objeto ou outra função. Em
qualquer ponto do programa, ao chamar uma função pura, com os mesmos
parâmetros, devemos obter sempre o mesmo resultado.
Codigo 1 - Scripts funcao1.py
valor = 20
def multiplica(fator):
global valor
print("Resultado", valor)
multiplica(3)
multiplica(3)
Codigo 1 - Scripts funcao2.py
valor = 20
def multiplica(valor, fator):
return valor
print("Resultado", multiplica(valor, 3))
print("Resultado", multiplica(valor, 3))
SCRIPT 1
funcao1.py, definimos uma função chamada multiplica, que multiplica a variável
global valor por um fator passado como parâmetro. O valor do resultado é
atribuído à variável valor novamente (linha 5), que é impresso em seguida
(linha 6).
Ao chamarmos a função multiplica(3) pela primeira vez (linha 8), obtemos a
saída “Resultado 60”. Como modificamos a própria variável global valor no
corpo da função, ao chamarmos novamente a função multiplica(3) (linha 9),
obtemos um resultado diferente para a saída: “Resultado 180”.
Além de não depender apenas dos parâmetros, essa função não retorna valor
algum. A função multiplica deste script não é pura.
SCRIPT 2
funcao2.py, utilizamos a variável valor como mais um parâmetro para a
função multiplica. As duas vezes que executamos essa função (linha 7 e 8),
elas retornam o mesmo valor, 60.
A função multiplica deste script é um exemplo de função pura, pois depende
apenas de seus parâmetros para gerar o resultado, e não acessa ou modifica
nenhuma variável externa à função e retorna um valor.
DADOS IMUTÁVEIS
São aqueles que não podem ser alterados após sua criação. Apesar do Python
disponibilizar algumas estruturas de dados imutáveis, como as tuplas, a maioria
é mutável. Na programação funcional, devemos tratar todos os dados como
imutáveis!
Codigo 2 - Scripts funcao3.py
valores = [10, 20, 30]
def altera_lista(lista):
return lista
print("Nova lista", altera_lista(valores))
print("Nova lista", altera_lista(valores))
Codigo 2 - Scripts funcao4.py
valores = [10, 20, 30]
def altera_lista(lista):
nova_lista = list(lista)
return nova_lista
print("Nova lista", altera_lista(valores))
print("Nova lista", altera_lista(valores))
C:\Users\ftoli\PycharmProjects\estac
C:\Users\ftoli\PycharmProjects\estac
EFEITO COLATERAL
O efeito colateral é quando a função faz alguma operação que não seja
computar a saída a partir de uma entrada. Como por exemplo: alterar uma
variável global, escrever no console, alterar um arquivo, inserir um registro no
banco de dados, ou enviar um foguete à lua.
DICA
Ao garantir que uma função utilizará apenas os dados de entrada para gerar
um resultado e que nenhuma variável fora do escopo da função será alterada,
temos a certeza de que não teremos um problema escondido, ou efeito
colateral em nenhuma outra parte do código.
Codigo 5 - Scripts funcao5.py
def multiplicar_por(multiplicador):
def multi(multiplicando):
return multiplicando * multiplicador
return multi
multiplicar_por_10 = multiplicar_por(10)
print(multiplicar_por_10(1))
print(multiplicar_por_10(2))
multiplicar_por_5 = multiplicar_por(5)
print(multiplicar_por_5(1))
print(multiplicar_por_5(2))
RETURN MULTIPLICANDO * 10
Essa função é retornada e armazenada na variável multiplicar_por_10 (linha 6),
que nada mais é que uma referência para a função multi recém-criada.
Dessa forma, podemos chamar a função multiplicar_por_10, passando um
número como argumento, o multiplicando, para ser multiplicado por 10 (linha 7
e 8). Produzindo os resultados 10 e 20.
Da mesma forma, criamos a função multiplicar_por_5, passando o número 5
como argumento para a função multiplicar_por (linha 10), que recebe uma
referência para a função:
DEF MULTI(MULTIPLICANDO):
RETURN MULTIPLICANDO * 5
Com isso, podemos utilizar a função multiplicar_por_5 para multiplicar um
número por 5 (linhas 11 e 12).
C:\Users\fotoli\PycharmProjects\estac
10
20
10
EXEMPLO
Considere a função para multiplicar dois números a seguir:
return a*b
A função lambda equivalente é:
lambda a, b: a*b
Codigo 6 - Script anonima.py
def multiplicar_por(multiplicador):
multiplicar_por_10 = multiplicar_por(10)
print(multiplicar_por_10(1))
print(multiplicar_por_10(2))
multiplicar_por_5 = multiplicar_por(5)
print(multiplicar_por_5(1))
print(multiplicar_por_5(2))
Codigo 6 - Script funcao5.py
def multiplicar_por(multiplicador):
def multi(multiplicando):
return multiplicando * multiplicador
return multi
multiplicar_por_10 = multiplicar_por(10)
print(multiplicar_por_10(1))
print(multiplicar_por_10(2))
multiplicar_por_5 = multiplicar_por(5)
print(multiplicar_por_5(1))
print(multiplicar_por_5(2))
NÃO UTILIZAR LOOPS
Outra regra, ou boa prática, da programação funcional é não utilizar laços
(for e while), mas sim composição de funções ou recursividade.
A função lambda exerce um papel fundamental nisso, como veremos a seguir.
Para facilitar a composição de funções e evitar loops, o Python disponibiliza
diversas funções e operadores.
As funções internas mais comuns são map e filter.
MAP
A função map é utilizada para aplicar uma determinada função em cada
elemento de um iterável (lista, tupla, dicionários etc.), retornando um
novo iterável com os valores modificados.
A FUNÇÃO MAP É PURA E DE ORDEM
SUPERIOR, POIS DEPENDE APENAS DE
SEUS PARÂMETROS E RECEBE UMA
FUNÇÃO COMO PARÂMETRO. A SUA
SINTAXE É A SEGUINTE:
MAP(FUNÇÃO, ITERÁVEL1,
ITERÁVEL2...)
O primeiro parâmetro da map é o nome da função (sem parênteses) que será
executada para cada item do iterável. Os demais parâmetros são os iteráveis
separados por vírgula. A função map SEMPRE retorna um novo iterável.
No exemplo do Codigo 7, a seguir, vamos criar três scripts. Todos executam a
mesma operação. Recebem uma lista e triplicam cada item, gerando
uma nova lista com os valores triplicados.
Codigo 7 - Script funcao_iterable.py
lista = [1, 2, 3, 4, 5]
def triplica_itens(iterable):
lista_aux = []
for item in iterable:
lista_aux.append(item*3)
return lista_aux
nova_lista = triplica_itens(lista)
print(nova_lista)
Codigo 7 - Script funcao_map.py
lista = [1, 2, 3, 4, 5]
def triplica(item):
print(list(nova_lista))
Codigo 7 - Script funcao_map_lambda.py
lista = [1, 2, 3, 4, 5]
print(list(nova_lista))
PRIMEIRO SCRIPT
funcao_iterable.py, definimos uma função chamada triplica_item, que recebe
um iterável como parâmetro (linha 3), cria uma lista auxiliar para garantir
imutabilidade (linha 4), percorre os itens do iterável passado como parâmetro
(linha 5), adiciona os itens triplicados à lista auxiliar (linha 6) e retorna a lista
auxiliar (linha 7).
Essa função é chamada com o argumento lista (linha 9) e o resultado é
impresso (linha 10).
SEGUNDO SCRIPT
funcao_map.py, definimos a função triplica, que triplica e retorna o item
passado como parâmetro (linha 3 e 4). É utilizada, assim como a variável lista,
como argumentos para a função map (linha 6).
A map vai aplicar internamente a função passada como parâmetro em cada
item da lista, retornando um novo iterável (que pode ser convertido em listas,
tuplas etc.). O resultado da função map é armazenado na variável nova_lista,
para então ser impresso (linha 7).
A função map garante a imutabilidade dos iteráveis passados como
argumento. Como a função map retorna um iterável, utilizamos o
construtor list(iterável) para imprimir o resultado (linha 7).
TERCEIRO SCRIPT
funcao_map_lambda.py, substituímos a função triplica pela
função lambda (lambda item: item*3), que foi utilizada como argumento para a
função map (linha 3). Esta vai aplicar a função lambda em cada item da lista,
retornando um novo iterável que foi impresso posteriormente (linha 4).
Observe como o código foi reduzido e mesmo assim preservamos a utilização
de funções puras (lambda), alta ordem (map) e que preservaram a
imutabilidade dos dados. Tudo isso para garantir que não haja efeitos
colaterais e dependência de estados.
TRUE OU FALSE
Verdadeiro ou falso.
ATENÇÃO
Todo elemento que for avaliado como true será incluído em um
novo iterável retornado pela função filter, que é pura e de alta ordem, pois
depende apenas dos parâmetros e recebe uma função como parâmetro. A sua
sintaxe é a seguinte:
filter(função, iterável)
O primeiro parâmetro da função filter é o nome da função (sem parênteses),
que será executada para cada item do iterável. O segundo parâmetro é
o iterável. A função filter SEMPRE retorna um novo iterável, mesmo que
vazio.
No exemplo do Codigo 8 a seguir, vamos criar três scripts. Todos fazem a
mesma filtragem. Recebem uma lista e retornam os elementos ímpares,
gerando uma nova lista, de forma a garantir a imutabilidade.
Codigo 8 - Script funcao_filtro_iterable.py
lista = [1, 2, 3, 4, 5]
def impares(iterable):
lista_aux = []
for item in iterable:
if item % 2 != 0:
lista_aux.append(item)
return lista_aux
nova_lista = impares(lista)
print(nova_lista)
Codigo 8 - Script funcao_filter.py
lista = [1, 2, 3, 4, 5]
def impar(item):
return item % 2 != 0
nova_lista = filter(impar, lista)
print(list(nova_lista))
Codigo 8 - Script funcao_filter_lambda.py
lista = [1, 2, 3, 4, 5]
print(list(nova_lista))
SCRIPT FUNÇÃO_FILTRO_ITERABLE.PY
Definimos uma função chamada ímpares, que recebe um iterável como
parâmetro (linha 3), cria uma lista auxiliar para garantir imutabilidade (linha 4),
percorre os itens do iterável passados como parâmetros (linha 5), adiciona os
itens ímpares à lista auxiliar (linha 6 e 7) e retorna a lista auxiliar (linha 8).
Essa função é chamada com o argumento lista (linha 10) e o resultado é
impresso (linha 11).
SCRIPT FUNCAO_FILTER.PY
Definimos a função ímpar, que retorna true se o item passado como parâmetro
é ímpar ou false caso contrário (linha 3 e 4). Utilizamos essa função, assim
como a variável lista, como argumentos para a função filter (linha 6).
A filter vai aplicar, internamente, a função passada como parâmetro em cada
item da lista, retornando um novo iterável (que pode ser convertido em listas,
tuplas etc.). O resultado da função filter é armazenado na variável nova_lista,
para então ser impresso (linha 7).
A função filter garante a imutabilidade dos iteráveis passados como
argumento. Como a função filter retorna um iterável, utilizamos o
construtor list(iterável) para imprimir o resultado (linha 7).
SCRIPT, FUNÇÃO_FILTER_LAMBDA.PY
Substituímos a função ímpar pela função lambda (lambda item: item%2 != 0)
que foi utilizada como argumento para a função filter (linha 3). Esta vai aplicar a
função lambda em cada item da lista, retornando um novo iterável que foi
impresso posteriormente (linha 4).
VERIFICANDO O APRENDIZADO
1. OBSERVE AS AFIRMATIVAS RELACIONADAS À
PROGRAMAÇÃO FUNCIONAL E RESPONDA.
I e III.
II.
I, III e IV.
2. QUAL É O RESULTADO IMPRESSO PELO PROGRAMA A
SEGUIR?
SCRIPT LAMBDA1.PY
RESULTADO = MINHA_FUNCAO(4)
PRINT(RESULTADO)
4.
8.
16.
32.
GABARITO
resultado = minha_funcao(4)
print(resultado)
MÓDULO 2
INTRODUÇÃO
No início do ano 2000, poucas pessoas tinham acesso a computadores com
mais de um processador. Além disso, os processadores
dos desktops e notebooks daquela época continham apenas um núcleo, ou
seja, só podiam executar uma operação por vez.
Fonte: Nonchanon/Shutterstock
CONCORRENTE
Alerta! Clique no item acima. ×
CONCEITOS
PROGRAMAS E PROCESSOS
Os conceitos iniciais que precisamos definir são programas e processos. Mas
o que seria um programa e um processo na visão do sistema operacional?
CONCORRÊNCIA E PARALELISMO
Em computação, o termo concorrente se refere a uma técnica para tornar os
programas mais usáveis. Ela pode ser alcançada mesmo em processadores de
apenas um núcleo, pois permite compartilhar o processador de forma a rodar
vários processos. Os sistemas operacionais multitarefas suportam
concorrência.
EXEMPLO
Por exemplo, é possível compactar um arquivo e continuar usando o
processador de texto, mesmo em um processador de um núcleo, pois o
processador divide o tempo de uso entre os processos dessas duas
aplicações. Ou seja: essas duas aplicações executam de forma concorrente.
Apesar da concorrência não necessariamente precisar de mais de um núcleo,
ela pode se beneficiar se houver mais deles, pois os processos não precisarão
compartilhar tempo de processador.
VOCÊ SABIA?
A thread pertence a um determinado processo. Múltiplas threads podem ser
executadas dentro de um mesmo processo. As de um mesmo processo
compartilham a área de memória e podem acessar os mesmos dados de forma
transparente.
ATENÇÃO
Normalmente, utilizamos thread para interface gráfica, acesso ao banco de
dados, acesso à rede etc., pois o programa não pode parar, ou a interface
congelar, enquanto esperamos baixar um arquivo, por exemplo.
Criar novos processos pode ser lento e consumir muita memória, enquanto a
criação de threads é mais rápida e consome menos memória.
CRIAÇÃO DE THREADS E PROCESSOS
EXEMPLO
Como criar threads e processos em Python:
Vamos utilizar a classe thread e process, dos
módulos threading e multiprocessing, respectivamente. Para facilitar a
transição entre processos e threads simples, o Python fez os construtores e
métodos das duas classes muito parecidos.
Codigo 9 - Script principal.py
from threading import Thread
from multiprocessing import Process
def funcao_a(nome):
print(nome)
if __name__ == '__main__':
t = Thread(target=funcao_a, args=("Minha Thread",))
t.start()
p = Process(target=funcao_a, args=("Meu Processo",))
p.start()
C:\Users\ftoli\PycharmProjects\estac
Minha Thread
Meu Processo
O OBJETIVO DA CRIAÇÃO
DE THREADS OU PROCESSOS É
JUSTAMENTE A COMPUTAÇÃO
CONCORRENTE OU PARALELA, O
PYTHON NÃO FICA “PARADO”
AGUARDANDO DELA APÓS CHAMAR O
MÉTODO START(), ELE
IMEDIATAMENTE COMEÇA A PRÓXIMA
ITERAÇÃO DO LAÇO FOR.
Codigo 10 - Script threads_var.py
import time
minha_lista = []
def funcao_a(indice):
for i in range(100000):
minha_lista.append(1)
if __name__ == '__main__':
tarefas = []
for indice in range(10):
tarefa = Thread(target=funcao_a, args=(indice,))
tarefas.append(tarefa)
tarefa.start()
for tarefa in tarefas:
tarefa.join()
Codigo 10 - Script processos_var.py
import time
minha_lista = []
def funcao_a(indice):
for i in range(100000):
minha_lista.append(1)
if __name__ == '__main__':
tarefas = []
for indice in range(10):
tarefa = Process(target=funcao_a, args=(indice,))
tarefas.append(tarefa)
tarefa.start()
for tarefa in tarefas:
tarefa.join()
ATENÇÃO
É função do programador armazenar uma referência para as suas threads ou
processos, de maneira que possamos verificar seu estado ou interrompê-las.
Para isso, armazenamos cada thread ou processo criado em uma lista
chamada tarefas (linha 17).
C:\Users\ftoli\PycharmProjects\estacio_ead\venv\Scripts\python.e
Termino thread 5
Termino thread 6
Termino thread 7
970012
C:\Users\ftoli\PycharmProjects\estacio_ead\venv\
Termino thread 0
Termino thread 2
Termino thread 1
Termino thread 4
Termino thread 3
Termino thread 5
Termino thread 7
Termino thread 6
Termino thread 8
Termino thread 9
Apesar da saída do script thread.py ter ficado confusa (já iremos retornar nesse
problema), observe que o número de itens da variável minha_lista muda
durante a execução do programa quando usamos thread e não muda quando
usamos processos.
Isso acontece, pois a área de memória das threads é compartilhada, ou seja,
elas têm acesso às mesmas variáveis globais. Em contrapartida, as áreas de
memória dos processos não são compartilhadas. Cada processo acaba criando
uma versão própria da variável minha_lista.
TRAVAS (LOCK)
No exemplo anterior, a função funcao_a incluía o elemento 1 à lista a cada
iteração, utilizando o método append(). No exemplo a seguir, a funcao_a irá
incrementar a variável global contador. Observe o código do Codigo 12 e
verifique o resultado impresso no console seguinte.
Codigo 12 - Script threads_inc.py
import time
contador = 0
def funcao_a(indice):
global contador
for i in range(1000000):
contador += 1
if __name__ == '__main__':
tarefas = []
for indice in range(10):
tarefa = Thread(target=funcao_a, args=(indice,))
tarefas.append(tarefa)
tarefa.start()
for tarefa in tarefas:
tarefa.join()
C:\Users\ftoli\PycharmProjects\estacio_ead\venv\S
Termino thread 1
5Termino thread 6
2235554
Termino thread 7
O incremento de variável (+=1), que está sendo usando no exemplo atual (linha
10), não é atômico. Ele é, na verdade, composto por duas operações, a leitura
e a atribuição, e não temos como garantir que as duas operações serão
realizadas atomicamente.
Veja a figura 1, em que temos um contador inicialmente com o valor 0 e
três threads incrementando esse contador. Para incrementar, a thread realiza
duas operações: lê o valor do contador e depois atribui o valor lido
incrementado de um ao contador.
Fonte: Autor Figura 1.
Codigo 13 - Script threads_inc_lock.py
from threading import Thread, Lock
import time
contador = 0
lock = Lock()
print_lock = Lock()
def funcao_a(indice):
global contador
for i in range(1000000):
lock.acquire()
contador += 1
lock.release()
print_lock.acquire()
print_lock.release()
if __name__ == '__main__':
tarefas = []
for indice in range(10):
tarefa = Thread(target=funcao_a, args=(indice,))
tarefas.append(tarefa)
tarefa.start()
for tarefa in tarefas:
tarefa.join()
C:\Users\ftoli\PycharmProjects\estacio
Termino thread 1
Termino thread 7
Termino thread 8
Termino thread 9
Termino thread 2
Termino thread 3
Termino thread 0
Termino thread 4
Termino thread 6
Termino thread 5
Codigo 14 - Script processos.py
def funcao_a(indice, cont):
for i in range(100000):
with cont.get_lock():
cont.value += 1
if __name__ == '__main__':
contador = Value('i', 0)
tarefas = []
for indice in range(10):
tarefa = Process(target=funcao_a, args=(indice, contador))
tarefas.append(tarefa)
tarefa.start()
print("Antes de aguardar o termino!", contador.value)
for tarefa in tarefas:
tarefa.join()
C:\Users\ftoli\PycharmProjects\estacio_e
Termino processo 2
Termino processo 1
Termino processo 0
Termino processo 3
Termino processo 4
Termino processo 5
Termino processo 8
Termino processo 9
VOCÊ SABIA?
O Python já disponibiliza essa trava nos objetos do tipo value, não sendo
necessário criar uma variável específica para a trava (lock). Observe como foi
realizada a trava utilizando o método get_lock() (linha 6).
Observe pelo console que agora nossa variável está com o valor certo: um
milhão!
UTILIZANDO PYTHON NA
PROGRAMAÇÃO CONCORRENTE
VERIFICANDO O APRENDIZADO
1. OBSERVE AS AFIRMATIVAS E RESPONDA:
I e IV.
I, II e IV.
I, II.
MINHA_LISTA = []
DEF ADICIONA():
FOR I IN RANGE(100):
MINHA_LISTA.APPEND(1)
IF __NAME__ == '__MAIN__':
TAREFAS = []
FOR INDICE IN RANGE(10):
T = THREAD(TARGET=ADICIONA)
TAREFAS.APPEND(T)
T.START()
FOR INDICE IN RANGE(10):
P = THREAD(TARGET=ADICIONA)
TAREFAS.APPEND(T)
P.START()
FOR TAREFA IN TAREFAS:
TAREFA.JOIN()
PRINT(LEN(MINHA_LISTA))
100.
1000.
2000.
10000.
GABARITO
minha_lista = []
def adiciona():
for i in range(100):
minha_lista.append(1)
if __name__ == '__main__':
tarefas = []
for indice in range(10):
t = Thread(target=adiciona)
tarefas.append(t)
t.start()
for indice in range(10):
p = Thread(target=adiciona)
tarefas.append(t)
p.start()
for tarefa in tarefas:
tarefa.join()
print(len(minha_lista))
MÓDULO 3
INTRODUÇÃO
Atualmente, existem diversas opções de linguagem de programação para
desenvolver aplicações web, sendo as principais: PHP, ASP.NET, Ruby e
Java.
De acordo com o site de pesquisas W3Techs, o PHP é a linguagem mais
utilizada nos servidores, com um total de 79% de todos os servidores utilizando
essa linguagem.
Grande parte da utilização do PHP se deve aos gerenciadores de conteúdo,
como WordPress, Joomla e Drupal, escritos em PHP e que tem muita
representatividade na web hoje.
VOCÊ SABIA?
O Python também pode ser utilizado para desenvolver aplicações web?
Atualmente existem diversos frameworks que facilitam a criação de
aplicações web em Python.
FRAMEWORKS FULL-STACK
Os frameworks full-stack disponibilizam diversos recursos internamente, sem a
necessidade de bibliotecas externas. Dentre os recursos, podemos citar:
Respostas à requisição;
Manipulação de formulários;
Autenticação;
Testes;
O principal framework Python full-stack é o Django.
FRAMEWORKS NÃO FULL-STACK
Estes oferecem os recursos básicos para uma aplicação web, como resposta a
requisição e suporte a modelos. Os principais frameworks dessa categoria são
o Flask e o CherryPy.
Normalmente, para aplicações maiores, são utilizados os frameworks full-stack,
que também são um pouco mais complexos de se utilizar.
CONCEITOS
O FLASK É UM
MICRO FRAMEWORK WEB EM PYTHON.
Pela descrição de seus desenvolvedores, micro não quer dizer que toda a
aplicação precisa ficar em apenas um arquivo ou que falta alguma
funcionalidade, mas que o núcleo de funcionalidades dele é limpo e simples,
porém extensível.
Codigo 15 - Script flask1.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def ola_mundo():
return "Olá, mundo."
if __name__ == '__main__':
app.run()
C:\Users\ftoli\PycharmProjects\estacio_ead\venv\Scripts\phyton.exe C:/Users/ftoli/Py
* Enviroment: production
VOCÊ SABIA?
O Flask utiliza o conceito de rotas para direcionar o acesso às páginas
(ou endpoints). As rotas servem para guiar as requisições feitas ao servidor
para o trecho de código que deve ser executado. Os nomes das rotas são os
nomes utilizados pelo usuário para navegar na sua aplicação.
APRIMORANDO ROTAS
Para ilustrar melhor o uso de rotas, vamos alterar o exemplo anterior de forma
que a rota (URL) para a função ola_mundo seja http://127.0.0.1:5000/ola.
Observe o Codigo 16 e compare com a anterior. Veja que o parâmetro do
decorador @app.route da linha 5 agora é ‘/ola’.
Codigo 16 - Script flask2.py
from flask import Flask
app = Flask(__name__)
@app.route('/ola')
def ola_mundo():
return "Olá, mundo."
if __name__ == '__main__':
app.run()
Vamos acertar nossa aplicação para criar, também, uma rota para a URL raiz
da aplicação (@app.route(‘/’)).
Vamos chamar a função dessa rota de index e criar essa rota conforme linhas
5 a 7. Veja o resultado no Codigo 17 a seguir.
Codigo 17 - Script flask3.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "Página principal."
@app.route('/ola')
def ola_mundo():
return "Olá, mundo."
if __name__ == '__main__':
app.run()
Veja, na imagem a seguir, que agora podemos acessar tanto a rota para
função índice (URL: /) (figura 4 A), onde é retornado “Página principal”, quanto
a rota da função ola_mundo (URL: /ola) ( figura 4 B), que é retornado “Olá,
mundo.”.
RECEBENDO PARÂMETROS
O decorador de rota (route) também permite que sejam passados parâmetros
para as funções. Para isso, devemos colocar o nome do parâmetro da função
entre < e> na URL da rota.
No exemplo do Codigo 18 a seguir, vamos mudar a rota da
função ola_mundo de forma que seja possível capturar e retornar o nome
passado como parâmetro.
Codigo 18 - Script flask4.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "Página principal."
@app.route('/ola/<nome>')
def ola_mundo(nome):
if __name__ == '__main__':
app.run()
Codigo 19 - Script flask5.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "Página principal."
@app.route('/ola/')
@app.route('/ola/<nome>')
def ola_mundo(nome="mundo"):
if __name__ == '__main__':
app.run()
Observe que agora temos duas rotas para a mesma função (linha 9 e 10). Em
qualquer uma das URL, o usuário será direcionado para a função ola_mundo.
ATENÇÃO
OBS: A rota com URL ‘/ola/’ aceita requisições tanto para ‘/ola’ quanto ‘/ola/’.
MÉTODOS HTTP
AS APLICAÇÕES WEB DISPONIBILIZAM
DIVERSOS MÉTODOS PARA ACESSAR
UMA URL: GET, POST, PUT E DELETE.
POR PADRÃO, AS ROTAS DO FLASK
SOMENTE RESPONDEM ÀS
REQUISIÇÕES GET. PARA RESPONDER
A OUTROS MÉTODOS, É NECESSÁRIO
EXPLICITAR, NA ROTA, QUAIS
MÉTODOS SERÃO ACEITOS.
Para isso, precisamos utilizar o parâmetro methods do decorador @app.route(),
que espera uma lista de strings com o nome dos métodos aceitos.
Observe no Codigo 20, a seguir, em que criamos a rota para a função logar e
passamos como argumento uma lista contendo duas strings, ‘GET’ e ‘POST’
(linha 15). Isso indica que essa rota deve responder às requisições do tipo GET
e POST.
Codigo 20 - Script flask6.py
from flask import Flask
app = Flask(__name__)
app.debug = True
@app.route('/')
def index():
return "Página principal."
@app.route('/ola/')
@app.route('/ola/<nome>')
def ola_mundo(nome):
@app.route('/logar', methods=['GET', 'POST'])
def logar():
if request.method == 'POST':
else:
if __name__ == '__main__':
app.run()
Para verificar o método que foi utilizado na requisição, usamos o
atributo method do objeto request, que retorna uma das strings: GET, POST,
PUT ou DELETE.
O objeto request é uma variável global disponibilizada pelo Flask e pode ser
utilizada em todas as funções. Para cada requisição, um novo objeto request é
criado e disponibilizado.
Com o objeto request, temos acesso a muitas outras propriedades da
requisição, como: cookie, parâmetros, dados de formulário, mimetype etc.
Neste exemplo, utilizamos o atributo method do objeto request para verificar o
método passado na requisição e retornar conteúdos diferentes dependendo do
método (linhas 17 a 20).
ATENÇÃO
Caso seja requisitada uma rota que exista, porém o método não seja aceito
pela rota, o erro retornado é o 405 - Method Not Allowed (método não
permitido), e não o 404 – Not Found (não encontrado), como ocorre quando a
rota não existe.
UTILIZANDO MODELOS
As funções no Flask precisam retornar algo. O retorno das funções pode ser
uma string simples e até uma string contendo uma página inteira em HTML.
Porém, criar páginas dessa maneira é muito complicado, principalmente devido
à necessidade de escapar (scape) o HTML, para evitar problemas de
segurança, por exemplo.
Para resolver esse problema, o Flask, por meio da extensão Jinja2, permite
utilizar modelos (templates) que são arquivos texto com alguns recursos a
mais, inclusive escape automático.
No caso de aplicações web, os modelos normalmente são páginas HTML, que
são pré-processadas antes de retornarem ao requisitante, abrindo um novo
leque de possibilidades no desenvolvimento web.
1
Para criar e utilizar os modelos, por convenção, os HTMLs precisam ficar
dentro da pasta templates, no mesmo nível do arquivo que contém a aplicação
Flask.
2
Para ilustrar, no próximo exemplo (Codigo 21), vamos alterar nossa aplicação
de forma que seja retornada uma página HTML ao se acessar a raiz da
aplicação (‘/’).
3
Para isso, vamos criar um arquivo chamado indice.html na pasta templates, no
mesmo nível do script flask7.py, conforme vemos na árvore de diretório abaixo.
Fonte: MAutor
4
Para o modelo ser acessado na URL raiz (‘/’), a função index() deve ser a
responsável por retorná-lo. Para isso, vamos utilizar a
função render_template disponibilizada pelo Flask, que recebe o nome do
arquivo que desejamos retornar.
Codigo 21 - Script flask7.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('indice.html')
@app.route('/ola/')
@app.route('/ola/<nome>')
def ola_mundo(nome="mundo"):
return "Olá, " + nome
if __name__ == '__main__':
app.run()
<!DOCTYPE html>
<html>
<body>
<h1>Página principal!</h1>
<h2>Usando templates</h2>
</body>
</html>
Como dito anteriormente, os modelos são páginas HTML turbinadas, nas quais
podemos utilizar delimitadores especiais para alterar nossa página. Os dois
tipos de delimitadores são:
Expressões: {{ ... }}
Que serve para escrever algo no modelo, como o valor de uma variável.
Declarações: {% ... %}
Utilizado em laços e condicionantes, por exemplo.
Codigo 22 - Script flask8.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('indice.html')
@app.route('/ola/')
@app.route('/ola/<nome>')
def ola_mundo(nome="mundo"):
if __name__ == '__main__':
app.run()
<html>
<body>
</body>
</html>
DESENVOLVENDO APLICAÇÕES
WEB COM PYTHON
VERIFICANDO O APRENDIZADO
1. CONSIDERE O CÓDIGO A SEGUIR, EM QUE TEMOS UM
SERVIDOR FLASK ESCUTANDO NA PORTA 5000, E
RESPONDA:
EXERCICIO1.PY
FROM FLASK IMPORT FLASK
APP = FLASK(__NAME__)
@APP.ROUTE('/OLA')
DEF OLA_MUNDO():
RETURN "OLÁ, MUNDO"
@APP.ROUTE('/OLA')
DEF OLA_MUNDO(NOME="MUNDO"):
IF __NAME__ == '__MAIN__':
APP.RUN()
Olá, mundo.
Olá, EAD.
Olá, EAD.
APP = FLASK(__NAME__)
@APP.ROUTE('/OLA', METHODS=['POST'])
DEF OLA_POST():
RETURN "OLÁ, GET"
@APP.ROUTE('/OLA')
DEF OLA_GET(NOME="MUNDO"):
RETURN "OLÁ, POST"
IF __NAME__ == '__MAIN__':
APP.RUN()
Olá, GET.
Olá, POST.
Olá, POST.
GABARITO
exercicio1.py
from flask import Flask
app = Flask(__name__)
@app.route('/ola')
def ola_mundo():
return "Olá, mundo"
@app.route('/ola')
def ola_mundo(nome="mundo"):
if __name__ == '__main__':
app.run()
exercicio2.py
from flask import Flask
app = Flask(__name__)
@app.route('/ola', methods=['POST'])
def ola_post():
return "Olá, GET"
@app.route('/ola')
def ola_get(nome="mundo"):
return "Olá, POST"
if __name__ == '__main__':
app.run()
MÓDULO 4
INTRODUÇÃO
Desde o século XVII, as ciências experimentais e teóricas são reconhecidas
pelos cientistas como os paradigmas básicos de pesquisa para entender a
natureza. De umas décadas para cá, a simulação computacional de fenômenos
complexos evoluiu, criando o terceiro paradigma, a ciência computacional.
Fonte: metamorworks/Shutterstock
Em 1996, Fayyad (1996) apresentou a definição clássica do processo de
descoberta de conhecimento em bases de dados, conhecido por KDD
(Knowledge Discovery in Databases):
COLETA E INTEGRAÇÃO:
Quando é necessário que dados provenientes de diversas fontes sejam
consolidados em uma única base de dados. Esta atividade é bastante
encontrada na construção de data warehouses;
CODIFICAÇÃO:
CONSTRUÇÃO DE ATRIBUTOS:
Após a coleta e integração dos dados, pode ser necessário criar colunas em
uma tabela, por exemplo, refletindo alguma transformação dos dados
existentes em outras colunas;
LIMPEZA DOS DADOS:
OS ALGORITMOS DE MINERAÇÃO
PODEM SER CLASSIFICADOS
COMO SUPERVISIONADOS E NÃO
SUPERVISIONADOS. NOS PRIMEIROS,
OS ALGORITMOS “APRENDEM”
BASEADOS NOS VALORES QUE CADA
DADO JÁ POSSUI. OS ALGORITMOS
SÃO TREINADOS (AJUSTADOS),
APLICANDO UMA FUNÇÃO E
COMPARANDO O RESULTADO COM OS
VALORES EXISTENTES.
Já nos não supervisionados, os dados não foram classificados previamente e
os algoritmos tentam extrair algum padrão por si só.
Não supervisio
Supervisiona
SUPERVISIONADO – REGRESSÃO
LINEAR
Neste exemplo, vamos utilizar uma série histórica fictícia de casos de
dengue de uma determinada cidade e, com o auxílio do algoritmo
supervisionado de regressão linear, predizer casos futuros.
A série está em uma planilha (arquivo CSV) com duas
colunas, ano e casos (número de casos). Na planilha, temos o número de
casos de 2001 a 2017. Vamos utilizar essa série histórica e aplicar o algoritmo
de regressão linear para estimar os casos de dengue para o ano de 2018.
No Codigo 23, a seguir, temos o código do script regressao.py, o arquivo CSV
(dados_dengue.csv) e a saída do console.
Codigo 23 - Script regressao.py
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
import pandas
# Coleta e Integração
arquivo = pandas.read_csv('dados_dengue.csv')
anos = arquivo[['ano']]
casos = arquivo[['casos']]
regr = LinearRegression()
regr.fit(X=anos, y=casos)
ano_futuro = [[2018]]
casos_2018 = regr.predict(ano_futuro)
plt.scatter(anos, casos, color='black')
plt.scatter(ano_futuro, casos_2018, color='red')
plt.plot(anos, regr.predict(anos), color='blue')
plt.xlabel('Anos')
plt.ylabel('Casos de dengue')
plt.xticks([2018])
plt.yticks([int(casos_2018)])
plt.show()
Codigo 23 - Dados_dengue.csv
ano,casos
2017,450
2016,538
2015,269
2014,56
2013,165
2012,27
2011,156
2010,102
2009,86
2008,42
2007,79
2006,65
2005,58
2004,39
2003,23
2002,15
2001,28
C:\Users\fotoli\PycharmProjects\estac
A CLASSE DA BIBLIOTECA SCIKIT-
LEARN UTILIZADA PARA REALIZAR A
REGRESSÃO LINEAR SE
CHAMA LINEARREGRESSION. PARA
REALIZAR A REGRESSÃO, ELA
PRECISA DOS DADOS DE
TREINAMENTO (PARÂMETRO X) E SEUS
RESPECTIVOS RESULTADOS
(PARÂMETRO Y).
No nosso exemplo, como desejamos estimar o número de casos, vamos utilizar
os anos como dado de treinamento e o número de casos como resultado. Ou
seja, teremos os anos no parâmetro X e os casos no parâmetro y.
Como estamos usando apenas uma variável para o parâmetro X, o ano, temos
uma regressão linear simples e o resultado esperado é uma reta, onde temos
os anos no eixo x e os casos no eixo y.
Após carregar o arquivo, vamos separar os dados das colunas nas respectivas
variáveis. Observe a sintaxe para obter os anos (linha 9) e casos (linha 10). O
Pandas detecta, automaticamente, o nome das colunas e permite extrair os
elementos das colunas utilizando o nome.
ATENÇÃO
O próximo passo é criar o objeto do tipo LinearRegression e atribuí-lo a uma
variável (linha 13). Esse objeto será utilizado para treinar (ajustar) a equação
da reta que será gerada pela regressão. Para realizar o treinamento (fit),
precisamos passar os parâmetros X e y (linha 14).
SUPERVISIONADO ‒ CLASSIFICAÇÃO
Os algoritmos de classificação são do tipo supervisionado, nos quais passamos
um conjunto de características sobre um determinado item de uma classe de
forma que o algoritmo consiga compreender, utilizando apenas as
características, qual a classe de um item não mapeado.
Codigo 24 - Script classificacao.py
from sklearn.datasets import load_iris, fetch_kddcup99
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_text, plot_tree
from sklearn.svm import SVC
# Coleta e Integração
iris = load_iris()
caracteristicas = iris.data
rotulos = iris.target
print("Caracteristicas:\n", caracteristicas[:2])
print("Rótulos:\n", rotulos[:2])
print('########################################################')
carac_treino, carac_teste, rot_treino, rot_teste = train_test_split(caracteristicas, rotulos)
arvore = DecisionTreeClassifier(max_depth=2)
arvore.fit(X=carac_treino, y=rot_treino)
rot_preditos = arvore.predict(carac_teste)
acuracia_arvore = accuracy_score(rot_teste, rot_preditos)
clf = SVC()
clf.fit(X=carac_treino, y=rot_treino)
rot_preditos_svm = clf.predict(carac_teste)
acuracia_svm = accuracy_score(rot_teste, rot_preditos_svm)
print("Acurácia SVM:", round(acuracia_svm, 5))
print('########################################################')
r = export_text(arvore, feature_names=iris['feature_names'])
print("Estrutura da árvore")
print(r)
Caracteristicas:
Rótulos:
[0 0]
###########################################
###########################################
Estrutura da árvore
| |--- class: 0
| | |--- class: 1
| | |--- class: 2
ETAPA 01
Na etapa de pré-processamento, vamos começar pela coleta e integração,
que é a obtenção do dataset de flores utilizando a função load_iris() (linha 9).
Esta função retorna um objeto onde podemos acessar as características das
flores pelo atributo data e os rótulos, ou classes das flores, pelo atributo target.
ETAPA 02
Na linha 11, separamos as características das flores na variável características.
Ela contém uma lista com 150 itens, onde cada item contém outra lista com
quatro elementos. Observe o conteúdo dos dois primeiros itens desta lista no
console.
Cada um dos quatro elementos corresponde ao comprimento da sépala,
largura da sépala, comprimento da pétala e largura da pétala, respectivamente.
ETAPA 03
Na linha 12, separamos os rótulos (ou classes) na variável rótulo. Ela contém
uma lista com 150 itens que variam entre 0, 1 ou 2. Cada número corresponde
a uma classe de flor (0: Iris-Setosa; 1:Iris-Versicolour; 2:Iris-Virginica). Como
dito na introdução deste módulo, esse mapeamento entre categorias e
números se chama codificação categórico-numérica. Essa etapa de pré-
processamento já foi realizada e disponibilizada pela função load_iris().
ETAPA 03
Outra etapa de pré-processamento que precisaremos realizar é a partição dos
dados. Ela nos permitirá verificar a qualidade do algoritmo de classificação.
Para isso, precisamos particionar nossos dados em treino e teste.
Os dados de treino são, como o próprio nome diz, utilizados para treinar
(ajustar) o algoritmo, enquanto os dados de testes são utilizados para verificar
a acurácia dele, comparando o valor calculado para os testes com os valores
reais.
DICA
Para separar as amostras em treino e teste, o Scikit-Learn disponibiliza uma
função chamada train_test_split, que recebe como primeiro parâmetro uma lista
com as características e segundo parâmetro uma lista com os rótulos.
De treino;
De treino;
ANALOGAMENTE, FAREMOS O
TREINAMENTO DE UM ALGORITMO DE
CLASSIFICAÇÃO UTILIZANDO O SVM,
POR MEIO DA CLASSE SVC (SUPPORT
VECTOR CLASSIFICATION) EM QUE
UTILIZAREMOS OS VALORES PADRÃO
DO CONSTRUTOR PARA O
CLASSIFICADOR (LINHA 30 A 34).
No pós-processamento, vamos imprimir a acurácia de cada classificador (linha
37 e 38) e uma representação textual da árvore, utilizando a
função export_text (linha 41).
NÃO SUPERVISIONADO ‒
AGRUPAMENTO
O OBJETIVO DE UM ALGORITMO DE
AGRUPAMENTO É REUNIR OBJETOS DE
UMA COLEÇÃO QUE MANTENHAM
ALGUM GRAU DE AFINIDADE. É
UTILIZADA UMA FUNÇÃO PARA
MAXIMIZAR A SIMILARIDADE DE
OBJETOS DO MESMO GRUPO E
MINIMIZAR ENTRE ELEMENTOS DE
OUTROS GRUPOS.
Exemplos de algoritmo de agrupamento são k-means (k-medias) e mean-shift.
No próximo exemplo (Codigo 25), vamos utilizar o algoritmo k-medias para
gerar grupos a partir do dataset de flor de íris. Porém, como o agrupamento é
um algoritmo não supervisionado não utilizaremos os rótulos para treiná-lo. O
algoritmo vai automaticamente separar as amostras em grupos, que serão
visualizados em um gráfico.
Na etapa de pré-processamento, vamos começar pela coleta e integração que
é a obtenção do dataset de flores utilizando a função load_iris() (linha 8).
Na linha 10, separamos as características das flores na variável características.
Lembrando que as características das flores são: comprimento da sépala
(índice 0), largura da sépala (índice 1), comprimento da pétala (índice 2) e
largura da pétala (índice 3).
Codigo 25 - Script agrupamento.py
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
# Coleta e Integração
iris = load_iris()
caracteristicas = iris.data
grupos = KMeans(n_clusters=3)
grupos.fit(X=caracteristicas)
fig = plt.figure(1)
ax = Axes3D(fig)
ax.set_xlabel('Comprimento Sépala')
ax.set_ylabel('Largura Sépala')
ax.set_zlabel('Comprimento Pétala')
ax.scatter(caracteristicas[:, 0], caracteristicas[:, 1], caracteristicas[:, 2], c=grupos.labels_, edgec
olor='k')
target = iris.target
fig = plt.figure(2)
ax = Axes3D(fig)
ax.set_xlabel('Comprimento Sépala')
ax.set_ylabel('Largura Sépala')
ax.set_zlabel('Comprimento Pétala')
ax.scatter(caracteristicas[:, 0], caracteristicas[:, 1], caracteristicas[:, 2], c=target, edgecolor='k')
plt.show()
I. COLETA E INTEGRAÇÃO.
II. CODIFICAÇÃO.
I, II e III
I, III e IV
II, III e IV
Codificação.
Construção de atributos.
GABARITO
I. Coleta e Integração.
II. Codificação.
CONCLUSÃO
CONSIDERAÇÕES FINAIS
Como visto neste tema, a linguagem funcional pode resolver alguns problemas
relacionados à execução do programa, chamados de efeitos colaterais.
Apesar de não ter sido mostrado, neste tema, o console do Python é muito
utilizado para realizar experimentações nesta área.
AVALIAÇÃO DO TEMA:
REFERÊNCIAS
DICIONÁRIO ONLINE DE PORTUGUÊS. Definições e significados de mais
de 400 mil palavras. Todas as palavras de A a Z. 2009-2020.
FAYYAD, U. M.; PIATETSKY-SHAPIRO, G.; SMYTH, P.; UTHURUSAMY, R.
(Eds.). From data mining to knowledge discovery in databases. AI
Magazine, v. 17, n. 3, p. 37-54, 1996.
FLASK. Web development, one drop at a time. 2010.
HAND, D.; MANNILA, H.; SMYTH, P. Principles of data mining.
Massachusetts: MIT Press, 1991.
HUNT, J. A beginners guide to Python 3 programming. Basileia: Springer,
2019.
MATPLOBIT. Visualization with Python. John Hunter, Darren Dale, Eric
Firing, Michael Droettboom and the Matplotlib development team. 2012-2020.
PANDAS. Sponsored project of NumFOCUS. 2015.
PYTHON. Python Software Foundation. Copyright 2001-2020.
SCIKIT-LEARN. Machine Learning in Python. 2007.
W3TECHS. Web Technology Surveys. 2009-2020.
EXPLORE+
Acesse a documentação oficial do Python sobre as funções e os operadores
que se integram bem ao paradigma de programação funcional, para aprender
mais sobre o assunto.
CONTEUDISTA
Frederico Tosta de Oliveira
CURRÍCULO LATTES