Python em Outros Paradigmas
Python em Outros Paradigmas
paradigmas
Prof. Frederico Tosta de Oliveira
Colaboração
Prof. Kleber de Aguiar
Objetivos
Módulo 1 Módulo 2
Módulo 3 Módulo 4
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.
Relatar problema
Visão geral
Introdução
A programação funcional teve seu início no final dos anos 1950, com a
linguagem LISP.
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.
Relatar problema
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.
Console
play_arrow Executar
Exercício 2
info_outlineTUTORIAL
d content_copyCOPIAR
Python3 Input
Console
play_arrow Executar
funcao1.py
chevron_left 1 de 2
chevron_right
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!
Exercício 3
info_outlined
TUTORIAL
content_copyCOPIAR
Python3 Input
234
Console
play_arrow Executar
Exercício 4
info_outlineTUTORIAL
d content_copyCOPIAR
Python3 Input
234
Console
Executar
play_arrow Executar
Com isso, ao chamar a mesma função duas vezes (linhas 13 e 14), com,
teoricamente, o mesmo parâmetro, obtemos um efeito indesejável, resultando
em saídas diferentes, como pode ser observado no campo Console do
respectivo emulador.
Relatar problema
Efeitos indesejáveis
report_problem
Atenção!
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.
Relatar problema
Exercício 5
info_outlineTUTORIAL
d content_copyCOPIAR
Python3 Input
234
Console
play_arrow Executar
Dentro da função “pai” multiplicar_por, definimos a função multi (linha 3), que
espera um parâmetro chamado multiplicando, que será multiplicado pelo
multiplicador passado como parâmetro para a função “pai”.
PYTHON
content_copy
PYTHON
content_copy
Funções lambda
Atenção!
return a*b
lambda a, b: a*b
Relatar problema
Atividade discursiva
note_alt_black
Que tal tentar implementar essa alteração na função multiplicar_por? No
emulador a seguir, insira o seu código no lugar da palavra reservada pass (linha
3):
Exercício 6
info_outlineTUTORIAL
d content_copyCOPIAR
Python3 Input
Console
play_arrow Executar
Digite sua resposta aqui...
Chave de respostaexpand_more
Relatar problema
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.
Maps
Exercício 7
info_outlineTUTORIAL
d content_copyCOPIAR
Python3 Input
Console
play_arrow Executar
Exercício 8
info_outlineTUTORIAL
d content_copyCOPIAR
Python3 Input
Console
play_arrow Executar
Exercício 9
info_outlineTUTORIAL
d content_copyCOPIAR
Python3 Input
Console
play_arrow Executar
funcao_map.py expand_more
funcao_map_lambda.py expand_more
Filter
report_problem
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)
Exercício 10
info_outlineTUTORIAL
d content_copyCOPIAR
Python3 Input
Console
play_arrow Executar
Exercício 11
info_outlineTUTORIAL
d content_copyCOPIAR
Python3 Input
Console
play_arrow Executar
Exercício 12
info_outlineTUTORIAL
d content_copyCOPIAR
Python3 Input
Console
play_arrow Executar
função_filtro_iterable.py expand_more
função_filter.py expand_more
função_filter_lambda.py expand_more
Relatar problema
emoji_events
Falta pouco
para atingir
seus
objetivos.
Vamos praticar
alguns conceitos?
Questão 1
A II e III
B I e III
C II
D I, III e IV
E II e IV
Responder
Questão 2
Scriptlambda1.Py
content_copy
A 4
B 8
C 16
D 32
E 64
Responder
Visão geral
Introdução
Relatar problema
O mesmo programa executado mais de uma vez gera processos diferentes, que
contêm dados e momento de execução (contexto) também diferentes.
Relatar problema
Conceitos de concorrência e
paralelismo
extension
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.
Já o paralelismo é uma técnica para permitir que programas rodem mais rápido,
executando várias operações ao mesmo tempo. Ela requer várias máquinas ou
um processador com mais de um núcleo. Também é possível realizar o
paralelismo nas placas de vídeo.
Relatar problema
Conceito de Threads
Threads e processos
refresh
Relembrando
O processo é uma instância de um programa em
execução. Ele é composto pelo código que está
sendo executado, os dados utilizados pelo programa
(exemplo: valores de variável) e o estado ou contexto
do processo.
sms_failed
Curiosidade
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.
Antes de falarmos sobre cada abordagem em Python, vamos falar sobre o global
interpreter lock (GIL). No CPython, GIL existe para proteger o acesso aos objetos
da linguagem.
Isso acontece objetivando a prevenção para que múltiplas threads não possam
executar os bytecodes do Python de uma vez. Essa “trava” é necessária, pois
visa garantir a integridade do interpretador, uma vez que o gerenciamento de
memória no CPython não é thread-safe.
Para os processos, por sua vez, o funcionamento é diferente. Para cada um,
temos um GIL separado. Ou seja: podem ser executados paralelamente. Cabe ao
programador garantir o acesso correto aos dados.
report_problem
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.
report_problem
Atenção!
Como criar threads e processos em Python:
Na linha 10, enviamos o comando para a thread iniciar sua execução, chamando
o método start() do objeto t do tipo thread, como pode ser observado a seguir:
Exercício 13
info_outlineTUTORIAL
d content_copyCOPIAR
Python3 Input
Console
play_arrow Executar
Neste exemplo, a função que será paralelizada é a funcao_a (linha 8). Ela contém
um laço que é executado cem mil vezes e para cada iteração adiciona o
elemento 1 à lista minha_lista, definida globalmente na linha 6.
Vamos criar 10 threads (e processos) para executar 10 instâncias dessa função,
na qual, esperamos que o número de elementos na lista ao final da execução do
programa seja de 1 milhão (10 threads X cem mil iterações).
report_problem
Atenção!
Observe que os códigos dos scripts são praticamente
idênticos, com exceção das classes construtoras
thread e process na linha 16 dos dois scripts.
Script Threads_var.Py
content_copy
Script Processos_var.Py
content_copy
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)
O incremento de variável (+=1), que está sendo usado no exemplo atual (linha
11), 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.
Script Threads_inc_lock.Py
content_copy
Script Processos.Py
content_copy
Para evitar esse problema, vamos utilizar uma trava (lock) para realizar a
operação de incremento, assim como fizemos no exemplo anterior.
sms_failed
Curiosidade
Observe pelo console que agora nossa variável está com o valor certo: um
milhão!
Relatar problema
emoji_events
Falta pouco
para atingir
seus
objetivos.
Vamos praticar
alguns conceitos?
Questão 1
A II e III
B I e IV
C I, II e IV
D I, II
E I, II e III
Responder
Questão 2
Script Processos.Py
content_copy
Script processos.py.
A 100
B 1000
C 2000
D 10000
E 20000
Responder
Relatar problema
Introdução
sms_failed
Curiosidade
Os frameworks podem ser divididos em, basicamente, dois tipos: full-stack e não
full-stack. Veja cada um deles a seguir:
Conceito
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.
A configuração padrão inicia um servidor local na porta 5000, que pode ser
acessado por: http://127.0.0.1:5000.
Começaremos com uma aplicação Web básica que retorna “Olá, mundo.” quando
acessamos pelo navegador o nosso servidor em http://127.0.0.1:5000.
Script Flask1.Py
content_copy
Curiosidade
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.
Na linha 5, utilizamos o decorador @app.route(‘/’) para criar uma rota para a URL
raiz da nossa aplicação (‘/’). Esse decorador espera como parâmetro a rota, ou
URL, que será utilizada no navegador, por exemplo.
Relatar problema
Rotas e parâmetros
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.
Script Flask2.Py
content_copy
http://127.0.0.1:5000/ola expand_more
http://127.0.0.1:5000 expand_more
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 script flask3.py a seguir:
Script Flask3.Py
content_copy
Veja, na imagem a seguir, que agora podemos acessar tanto a rota para função
índice (URL: /) (imagem A), onde é retornado “Página principal”, quanto a rota da
função ola_mundo (URL: /ola) (imagem B), que é retornado “Olá, mundo.”:
Recebendo parâmetros
Script Flask4.Py
content_copy
Observe a URL da rota na linha 9, em que utilizamos a variável nome entre < e>,
que é o mesmo nome do parâmetro da função ola_mundo. Isso indica que
qualquer valor que for adicionado à URL após ‘/ola/’ será passado como
argumento para a variável nome da função ola_mundo.
Script Flask5.Py
content_copy
Observe que agora temos duas rotas para a mesma função (linhas 9 e 10). Em
qualquer uma das URL, o usuário será direcionado para a função ola_mundo.
report_problem
Atenção!
A rota com URL ‘/ola/’ aceita requisições tanto para
‘/ola’ quanto ‘/ola/’.
Como nessa nova configuração o parâmetro nome pode ser vazio quando
acessado pela URL ‘/ola’, definimos o valor padrão “mundo” para ele (linha 11).
Relatar problema
Métodos HTTP
Observe no script flask6.py, 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.
Script Flask6.Py
content_copy
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.
report_problem
Atenção!
Observe que ativamos o modo debug do servidor interno do Flask (linha 4). Isso
nos permite visualizar melhor os avisos e erros durante o desenvolvimento.
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.
Árvore de diretório.
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.
Script Flask7.Py
content_copy
Modelo Indice.Html
content_copy
Ao acessar http://127.0.0.1:5000, recebemos o resultado exibido na imagem a
seguir:
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:
Script Flask8.Py
content_copy
Modelo Ola.Html
content_copy
No exemplo, desejamos exibir o nome passado via URL na página. Para passar a
variável nome para o HTML, precisamos chamar a função render_template com
um parâmetro a mais, conforme linha 12 e destacado na imagem a seguir:
Relatar problema
emoji_events
Falta pouco
para atingir
seus
objetivos.
Vamos praticar
alguns conceitos?
Questão 1
Considere o código a seguir, em que temos um servidor Flask escutando na
porta 5000, e responda:
Exercicio1.Py
content_copy
A Olá, mundo.
Olá, mundo.
B
Olá, EAD.
C Olá, EAD.
Olá, EAD.
E
Olá, mundo.
Responder
Questão 2
Exercicio2.Py
content_copy
O que será apresentado no navegador se acessarmos a URL
http://127.0.0.1:5000/ola?
A Olá, GET.
Olá, GET.
B
Olá, POST.
C Olá, POST.
Olá, POST.
E
Olá, GET.
Responder
Relatar problema
Introdução
(FAYYAD, 1996, p. )
Codificação expand_more
Esta etapa, normalmente, é a que atrai maior atenção, por ser ela que revela os
padrões ocultos nos dados.
Não supervisionados:
Supervisionados:
Conceitos
Relatar problema
Algoritmos supervisionados
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.
Utilizaremos essa série histórica e aplicaremos o algoritmo de regressão linear
para estimar os casos de dengue para o ano de 2018.
Script Regressão.Py
content_copy
Dados_dengue.Csv
content_copy
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.
report_problem
Atenção!
Após a execução do método fit, o objeto regr está pronto para ser utilizado para
predizer os casos para os anos futuros, utilizando o método predict (linha 17).
Supervisionado ‒ classificação
Script Classificacao.Py
content_copy
Saída Do Script Classificacao.Py
content_copy
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.
wb_incandescent
Dica
De treino;
De teste das características;
De treino;
De teste dos rótulos.
Observe a linha 19, onde utilizamos essa função para gerar quatro novas
variáveis: características para treino (carac_treino); características para teste
(carac_teste); rótulos para treino (rot_treino); e rótulos para teste (rot_teste).
Relatar problema
Passamos o número 3, pois sabemos que são 3 classes de flor, mas poderíamos
alterar esse valor. O objeto grupos criado será utilizado para treinar (ajustar) o
algoritmo. Para realizar o treinamento (fit), precisamos passar apenas
parâmetros X, que conterão as características das flores (linha 14).
Após o treino, podemos utilizar o atributo labels_ do objeto grupos para retornar
uma lista com o índice do grupo ao qual cada amostra pertence. Como o número
de grupos (n_clusters) é 3, o índice varia entre: 0, 1 e 2. Veja o código a seguir:
Script Agrupamento.Py
content_copy
Relatar problema
emoji_events
Falta pouco
para atingir
seus
objetivos.
Vamos praticar
alguns conceitos?
Questão 1
I. Coleta e Integração.
II. Codificação.
III. Construção de atributos.
IV. Visualização dos dados.
A I e II
B I, II e III
C I, III e IV
D II, III e IV
E I, II e IV
Responder
Questão 2
A Coleta e integração
B Codificação
C Construção de atributos
Responder
Relatar problema
Considerações finais
Como visto neste tema, a linguagem funcional pode resolver alguns problemas
relacionados à execução do programa, chamados de efeitos colaterais.
A utilização do Python como ferramenta para Ciência de Dados evolui a cada dia.
As principais bibliotecas para análise e extração de conhecimento de base de
dados, mineração de dados e aprendizado de máquinas têm uma
implementação em Python.
Apesar de não ter sido mostrado neste tema, o console do Python é muito
utilizado para realizar experimentações nesta área.
headset Podcast
Ouça este podcast sobre os principais assuntos abordados no tema.
00:00 06:31
speed
1x
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.
Referências
CONCORRENTE. Dicionário On-line de Português –2009-2020. Consultado na
Internet em: 25 mar. 2022.
MATPLOTLIB. Visualization with Python. John Hunter, Darren Dale, Eric Firing,
Michael Droettboom and the Matplotlib development team, 2012-2020.
PANDAS. Sponsored project of NumFOCUS. 2015.
Download material
Relatar problema