Paradigmas de Programação
Ronaldo F. Ramos
Instituto Federal do Ceará
28 de outubro de 2023
PARTE 3 - PARADIGMA FUNCIONAL
PROGRAMAÇÃO FUNCIONAL EM PYTHON
AULA 1/1
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Roteiro
• Programação Funcional em Python
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Definição
Em ciência da computação, programação funcional é um paradigma de programação
que trata a computação como uma avaliação de funções matemáticas e que evita
estados ou dados mutáveis. Ela enfatiza a aplicação de funções, em contraste da
programação imperativa, que enfatiza mudanças no estado do programa 1 2
1
Fonte: Wikipedia
2
Paul Hudak (setembro de 1989). "Conception, evolution, and application of functional
programming languages"(pdf) . ACM Computing Surveys.
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Foco da Programação Funcional
• Manutenibilidade
• Testabilidade
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Um Programa Simples Não Funcional em Python
1 from datetime import datetime
2 class SaudacaoEntrada :
3 def __init__(self):
4 hora_atual = datetime.now()
5 if hora_atual.hour < 12:
6 self. SaudacaoEntrada = "Bom Dia"
7 elif 12 <= hora_atual.hour < 18:
8 self. SaudacaoEntrada = "Boa Tarde"
9 else:
10 self. SaudacaoEntrada = "Boa Noite"
11 def sauda(self, nome):
12 print(f"{self. SaudacaoEntrada }, {nome}.")
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Continuação do Programa
1 def main ():
2 name = input("Digite o seu nome ")
3 Saudacao = SaudacaoEntrada ()
4 Saudacao.sauda(name)
5
6 if __name__ == "__main__":
7 main ()
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Efeitos Colaterais - Side Effects
Problemas do ponto de vista da programação funcional(efeitos colaterais)
• A função construtora modifica variáveis fora do seu escopo
• As funções internas (não main) executam operações de entrada e saída
A existência de efeitos colaterais nos programas dificulta a compreensibilidade do
programa e sua manutenibilidade. Além disso o fato das variáveis serem mutáveis
também contribui para dificultar a rastreabilidade do mesmo.
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Testabilidade
Procedimentos com efeitos colaterais, por não serem isolados, dificultam o processo de
testes.
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Exemplos de Efeitos Colaterais
• Imprimir alguma coisa
• Ler um arquivo
• Escrever em um arquivo
• Interagir com uma base de dados
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Reduzindo os efeitos colaterais
1 from datetime import datetime
2 class Saudacoes:
3 # a classe será autocontida e não realiza operações de E/S
4 def __init__(self, saudacao):
5 self. saudacaoIntrodutoria = saudacao
6
7 # a função retorna a string ao invés de imprimí-la
8 def sauda(self, nome):
9 return f"{self. saudacaoIntrodutoria }, {nome}."
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
As opereções de E/S são transferidas para a main()
1 def main ():
2 # criacao do objeto fora do escopo da classe Saudacoes
3 hora_atual = datetime.now()
4 if hora_atual.hour < 12:
5 saudacao_inicial = "Bom dia"
6 elif 12 <= hora_atual.hour < 18:
7 saudacao_inicial = "Boa Tarde"
8 else:
9 saudacao_inicial = "Boa Noite"
10
11 nome = input("Entre com o seu nome:")
12 saudacao = Saudacoes( saudacao_inicial )
13 print(saudacao.sauda(nome))
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Sem Classes e Objetos
Programas não necessariamente precisam de classes e objetos. Classes e Objetos
podem tornar programas mais complexos e até mais lentos.
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Somente com funções
Ao separar as responsabilidades em funções teremos:
1 from datetime import datetime
2
3 def sauda(nome, saudacao_inicial ):
4 return f"{ saudacao_inicial }"
5
6 def definir_saudacao ():
7 hora_atual = datetime.now()
8 if hora_atual.hour < 12:
9 return "Bom dia"
10 elif 12 <= hora_atual.hour < 18:
11 return "Boa tarde"
12 else:
13 return "Boa noite"
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Função main
Temos um programa completamente funcional sem uso de maiores recursos.
1 def ler_nome ():
2 return input("Digite o seu nome: ")
3
4 def main ():
5 print(sauda(ler_nome (), definir_saudacao ()))
6
7 if __name__ == "__main__":
8 main ()
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Funções Puras ou Impuras
Definição
Uma função é considerada pura se é livre de efeitos colaterais, caso contrário é
chamada de impura.
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Cidadãos de Primeira Classe
Em ambientes funcionais as funções podem (devem) ser passadas como argumentos
em outras funções
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Funções como Argumentos
1 from datetime import datetime
2 # a variavel leitor_saudacoes receberá uma função
3 def sauda(nome, leitor_saudacoes ): # :LeitorSaudacao
4 if nome == "ronaldo":
5 return "Grande Ron"
6 # a função recebida é chamada aqui
7 return f"{ leitor_saudacoes ()}, {nome}."
8 def ler_saudacao ():
9 hora_atual = datetime.now()
10 if hora_atual.hour < 12:
11 return "Bom dia"
12 elif 12 <= hora_atual.hour < 18:
13 return "Boa Tarde"
14 else:
15 return "Boa Noite"
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Funções como Argumentos - Continua
Observe que para que uma função seja passada como argumento em Python basta
remover os ()
1 def ler_nome ():
2 return input("Entre com o seu nome: ")
3
4 def main () -> None:
5 # chamada de função passando função como argumento
6 print(sauda(ler_nome (), ler_saudacao))
7
8 if __name__ == "__main__":
9 main ()
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Partials
Com partials podemos fixar um certo número de argumentos com valores prefixados
1 from datetime import datetime
2 from functools import partial
3 def sauda(nome, leitor_saudacao ):
4 if nome == "ronaldo":
5 return "Grande Ron"
6 return f"{ leitor_saudacao ()}, {nome}."
7 def ler_saudacoes ():
8 hora_atual = datetime.now()
9 if hora_atual.hour < 12:
10 return "Bom dia"
11 elif 12 <= hora_atual.hour < 18:
12 return "Boa Tarde"
13 else:
14 return "Boa Noite"
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Partials - main
1 def ler_nome ():
2 return input("Entre com seu nome: ")
3
4 def main ():
5 # seta o valor de leitor_saudacao da função original
6 funcao_sauda = partial(sauda, leitor_saudacao =ler_saudacoes)
7 print(funcao_sauda(ler_nome ()))
8
9 if __name__ == "__main__":
10 main ()
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Imutabilidade
Em ambientes funcionais as variáveis são associadas a expressões e seus valores se
tornam imutáveis. Linguagens como python usam as duas possibilidades. Vejamos
alguns exemplos.
1 import random
2 def main () -> None:
3 lista_para_testar = [120, 68, -20, 0, 5, 67, 14, 99]
4 # Usando ordenamento com imutabilidade mantém a listas original
intacta
5 lista_ordenada = sorted( lista_para_testar )
6 print(f"Lista original: { lista_para_testar }")
7 print(f"Lista ordenada: { lista_ordenada}")
8 # ordenamento com modificação da lista original
9 lista_para_testar .sort ()
10 print(f"Lista original: { lista_para_testar }")
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Imutabilidade - Continuação
1 # outros exemplos de operações mutáveis e imutáveis
2 cartas = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q",
"K", "A"]
3
4 cartas_embaralhadas = random.sample(cartas, k=len(cartas))
5 print(f"Cartas embaralhadas: { cartas_embaralhadas }")
6 print(f"Cartas originais: {cartas}")
7
8 random.shuffle(cartas) # embaralha cartas (mutável)
9 print(f"cartas: {cartas}")
10
11 if __name__ == "__main__":
12 main ()
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Mutabilidade x Imutabilidade
Um objeto pode ser também mutável ou imutável se o seu estado pode ser modificado
após a criação. As linguagens híbridas como python podem ter elementos pertencentes
a uma ou outra categorias.
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Objetcos x Variáveis em Python
Definições:
• Variáveis são referências para objetos.
• Objetos são elementos delimitados em um espaço de memória concreto.
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Objetos em Python
Em Python tudo são objetos: números, strings, funções, classes, etc.
Os objetos possuem as seguintes caractarísticas:
• Valor
• Identidade
• Tipo
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Verificando o valor do objeto
Os valores dos objetos são instâncias de tipos primitivos como int, float, etc ou ainda
definidos pelo programador. Podemos verificar estes valores e seus tipos através do
isinstance.
1 >>> isinstance (28,int)
2 True
3
4 >>> isinstance (3.14,float)
5 True
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Verificando o ID do objeto
1 >>> id (12)
2 2182424887888
3 >>> x = 10
4 >>> id(x)
5 2182424887824
6 >>> id (10)
7 2182424887824
8 >>> y = 10
9 >>> id(y)
10 2182424887824
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Testando a Imutabilidade dos Tipos Primitivos
1 >>> x = y = 13
2 >>> id(x)
3 2182424887920
4 >>> id(y)
5 2182424887920
6 >>> y += 1
7 >>> y
8 14
9 >>> id(y)
10 2182424887952
11 >>> id(x)
12 2182424887920
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Tipos dos Objetos type e .__class__
1 >>> type (42)
2 <class ’int’>
3 >>> type(’Escambau do judas ’)
4 <class ’str’>
5 >>> type ([1,2,3,4])
6 <class ’list ’>
7 >>>
8 >>> (42).__class__
9 <class ’int’>
10 >>> ’Queima leao do pici ’.__class__
11 <class ’str’>
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Tipos Primitivos Imutáveis
O tipos primitivos boolean, int float e complex são imutáveis.
Os tipos str, bytes e tuple também o são.
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Tipos Mutáveis em Python - List
A lista em si é mutável, mas os elementos internos podem ou não ser dependendo do
tipo.
Ex.
1 >>> numeros = [1,5,8] # criando uma lista de números
2 >>> id(numeros)
3 2490398152384
4 >>> id(numeros [1]) # verificando o id do segundo elemento
5 2490392248688
6 >>> numeros [1] = 10 # mudando o segundo elemento
7 >>> id(numeros [1]) # verificando se o elemento mudou
8 2490392248848
9 >>>
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Tipos Mutáveis em Python - Dicionários
Com dicionários você pode mudar o valor associado a uma chave e adicionar ou
remover novos pares de ’valor-chave’.
Ex.
1 >>> lista_compras = {’feijao ’:10, ’arroz ’:20, ’ovos ’:12,
’farinha ’:30, ’rapadura ’:15}
2 >>> lista_compras[’banana ’]=20 # adicionando dados
3 >>> del lista_compras[’arroz ’] # apagando dados
4 >>> lista_compras
5 {’feijao ’: 10, ’ovos ’: 12, ’farinha ’: 30, ’rapadura ’: 15,
’banana ’: 20}
6 >>> lista_compras[’rapadura ’]=30
7 >>> lista_compras
8 {’feijao ’: 10, ’ovos ’: 12, ’farinha ’: 30, ’rapadura ’: 30,
’banana ’: 20}
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Tipos Mutáveis em Python - Sets (Conjuntos)
Com os conjuntos podemos inserir ou remover itens.
Ex.
1 >>> compras = {’feijao ’,’farinha ’,’rapadura ’}
2 >>> compras.add(’arroz ’)
3 >>> compras
4 {’arroz ’, ’rapadura ’, ’feijao ’, ’farinha ’}
5 >>> compras.discard(’arroz ’)
6 >>> compras
7 {’rapadura ’, ’feijao ’, ’farinha ’}
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Resumo dos Dados de Mutabilidade no Python
Tipo Classe Mutável
Números int, float, complex Não
Strings str Não
Tuplas tuple Não
Bytes bytes Não
Booleano bool Não
conjuntos Fixos(Frozen Sets) frozenset Não
Listas list Sim
Dicionários dict Sim
Conjuntos (Sets) set Sim
Listas de Bytes(Byte Arrays) bytearray Sim
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Atenção: Aliases com Mutabilidade
Uma mudança em um alias de um tipo imutável não afeta o original.
Ex.
1 >>> x = 2
2 >>> y = x
3 >>> x
4 2
5 >>> y
6 2
7 >>> y += 1
8 >>> x
9 2
10 >>> y
11 3
12 >>>
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Atenção: Aliases com Mutabilidade
Uma mudança em um alias de um tipo mutável afeta o original.
Ex.
1 >>> compras = [’pera ’,’maca ’,’banana ’]
2 >>> lista = compras
3 >>> lista.append(’laranjas ’)
4 >>> compras
5 [’pera ’, ’maca ’, ’banana ’, ’laranjas ’]
6 >>> lista
7 [’pera ’, ’maca ’, ’banana ’, ’laranjas ’]
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Argumentos Mutáveis
Ao serem passados argumentos mutáveis para uma função a variável externa pode
sofrer as consequencias de mudanças realizadas dentro das funções.
Ex.
1 >>> def dobro(lista):
2 ... for i in range(len(lista)):
3 ... lista[i] = lista[i]**2
4 ... return lista
5 >>> x = [1,2,3,4]
6 >>> dobro(x)
7 [1, 4, 9, 16]
8 >>> x
9 [1, 4, 9, 16]
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Argumentos Imutáveis
Isto não acontece se o argumento representar um dado imutável.
Ex.
1 >>> def dobro(y):
2 ... y *= 2
3 ... print(id(y))
4 ... return y
5 ...
6 >>> x = 10
7 >>> id(x)
8 2490392248848
9 >>> dobro(x)
10 2490392249168
11 20
12 >>> id(x)
13 2490392248848
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Argumentos Default Não Sobrescrevem a Lista(Mutável)
Lista é preservada entre chamadas não ocorrendo o esperado.
Ex.
1 >>> def adicionar_item (item, lista = []):
2 ... lista.append(item)
3 ... return lista
4 ...
5 >>> adicionar_item (1)
6 [1]
7 >>> adicionar_item (2)
8 [1, 2]
9 >>> adicionar_item (3)
10 [1, 2, 3]
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Solução
1 >>> def adiciona(item, lista=None):
2 ... if lista == None:
3 ... lista =[]
4 ... lista.append(item)
5 ... return lista
6 ...
7 >>> adiciona (1)
8 [1]
9 >>> adiciona (2)
10 [2]
11 >>> adiciona (3)
12 [3]
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Atenção
Muitos aconselham a não usar argumentos default. De
qualquer forma, melhor sempre tomar cuidado.
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Uma aplicação para esse caso
Essa propriedade das listas pode ser usada para calcular alguma coisa como a média
móvel.
Ex.
1 >>> def media_movel(x, amostra =[]):
2 ... amostra.append(x)
3 ... return sum(amostra)/len(amostra)
4 >>> media_movel (1)
5 1.0
6 >>> media_movel (3)
7 2.0
8 >>> media_movel (7)
9 3. 6666666666666665
10 >>> media_movel (5)
11 4.0
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Cópias Rasas - Shallow Copy
Cópia de uma lista obtida com slice [:], o método .copy ou o copy.copy(). Neste casos
cria-se uma nova lista porém os elementos da nova lista são aliases para os elementos
internos da lista anterior.
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Cópia Profunda
Quando usada a função copy.deepcopy() a lista é copiada integralmente para uma
nova lista.
Experimente.....
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Métodos Não Mutáveis
Strings são imutáveis o que significa que os métodos que as modificam criam cópias
das strings sem modificar as originais.
1 >>> original = "esta e uma string"
2 >>> original.upper () # isto apenas cria uma cópia
3 "ESTA E UMA STRING"
4 >>> original
5 "esta é uma string"
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Aplicação desta característica
Esta propriedade pode permitir o encadeamento de métodos.
Ex.
1 >>> texto = "<html lan=’eng ’>"
2 >>> texto.removeprefix("<").removesuffix(">").upper ().center (20)
3 " HTML LAN=’ENG’ "
4 >>> texto
5 "<html lan=’eng ’>"
6 >>>
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Tuplas contendo dados mutáveis
Tuplas são imutáveis, mas podem conter objetos mutáveis.
Ex.
1 >>> vermelho = ("RED",[255,0,0])
2 >>> vermelho [0] = "red"
3 Traceback (most recent call last):
4 File "<stdin >", line 1, in <module >
5 TypeError: ’tuple ’ object does not support item assignment
6 >>> vermelho [1] = [0,0,255]
7 Traceback (most recent call last):
8 File "<stdin >", line 1, in <module >
9 TypeError: ’tuple ’ object does not support item assignment
10 >>> vermelho [1][0] = 0
11 >>> vermelho
12 (’RED’, [0, 0, 0])
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Componentes Automáticos de Classes
Python já cria automaticamente alguns métodos em classes.
Ex.
1 >>> class Pessoa:
2 ... pass
3 ...
4 >>> dir(Pessoa)
5 [’__class__ ’, ’__delattr__ ’, ’__dict__ ’, ’__dir__ ’, ’__doc__ ’,
’__eq__ ’, ’__format__ ’, ’__ge__ ’, ’__getattribute__ ’,
’__gt__ ’, ’__hash__ ’, ’__init__ ’, ’__init_subclass__ ’,
’__le__ ’, ’__lt__ ’, ’__module__ ’, ’__ne__ ’, ’__new__ ’,
’__reduce__ ’, ’__reduce_ex__ ’, ’__repr__ ’, ’__setattr__ ’,
’__sizeof__ ’, ’__str__ ’, ’__subclasshook__ ’, ’__weakref__ ’]
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Injeção de Atributos e Métodos
1 >>> Pessoa.emprego=’Programador ’
2 >>> def __init__(self, nome, emprego):
3 ... self.nome = nome
4 ... self.emprego = emprego
5 >>> Pessoa.__init__=__init__
6 >>> dir(Pessoa)
7 [’__class__ ’, ’__delattr__ ’, ’__dict__ ’, ’__dir__ ’,
’__doc__ ’, ’__eq__ ’, ’__format__ ’, ’__ge__ ’,
’__getattribute__ ’, ’__gt__ ’, ’__hash__ ’,
’__init__ ’, ’__init_subclass__ ’, ’__le__ ’,
’__lt__ ’, ... , ’__subclasshook__ ’, ’__weakref__ ’,
’emprego ’]
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Dica sobre Injeção de Atributos e Métodos
A injeção de elementos em uma classe pode ser útil para a programação funcional em
Python
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Impedindo a Adição de Atributos a Objetos
Podemos limitar a adição de atributos a objetos usando __slots__,...
Ex.
1 class Pessoa:
2 ... __slots__ = (’nome ’,’emprego ’)
3 ... def __init__(self,nome):
4 ... self.nome = nome
5 ...
6 >>> joao = Pessoa(’Joao ’)
7 >>> joao.emprego = ’Engenheiro ’
8 >>> joao.endereco = ’Rua X Numero Z’
9 Traceback (most recent call last):
10 File "<stdin >", line 1, in <module >
11 AttributeError : ’Pessoa ’ object has no attribute ’endereco ’
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Impedindo a Adição de Atributos a Objetos
... mas não a classes .
Ex.
1 >>>
2 >>> Pessoa.endereco = "Rua X número Z"
3 >>>
4 >>> dir(joao)
5 [’__class__ ’, ’__delattr__ ’, ’__dir__ ’, ’__doc__ ’, ’__eq__ ’,
’__format__ ’, ’__ge__ ’, ’__getattribute__ ’, ... ,
’__subclasshook__ ’, ’emprego ’, ’endereco ’, ’nome ’]
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Funções __setattr__() and .__delattr__()
Estas funções controlam o acesso a atributos de forma a torná-los imutáveis se for o
caso.
EX.
1 >>> class Imutavel:
2 ... def __init__(self, valor):
3 ... super ().__setattr__("valor", valor)
4 ... def __setattr__(self, nome, attr_valor):
5 ... raise AttributeError(f"Não posso mudar o valor do
atributo ’{nome}’")
6 ... def __delattr__(self, nome):
7 ... raise AttributeError(f"Não posso apagar o atributo
’{nome}’")
8 ...
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Funções __setattr__() and .__delattr__()
Cont..
1 >>> gravidade = Imutavel (9.78)
2 >>> gravidade.valor
3 9.78
4 >>> gravidade.valor = 9.8
5 Traceback (most recent call last):
6 File "<stdin >", line 1, in <module >
7 File "<stdin >", line 5, in __setattr__
8 AttributeError : Não posso mudar o valor do atributo ’valor ’
9 >>> del gravidade.valor
10 Traceback (most recent call last):
11 File "<stdin >", line 1, in <module >
12 File "<stdin >", line 7, in __delattr__
13 AttributeError : Não posso apagar o atributo ’valor ’
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Properties
O uso de getters sem setters pode ocultar (fazer de conta que oculta) atributos que
queremos que sejam ’imutáveis’. EX.
1 >>> class Pontos:
2 ... def __init__(self, x):
3 ... self._x = x
4 ... @property
5 ... def x(self):
6 ... return self._x
7 >>> p = Pontos (2,3)
8 >>> p.x
9 2
10 >>> p.x = 3
11 Traceback (most recent call last):
12 File "<stdin >", line 1, in <module >
13 AttributeError : can’t set attribute ’x’
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Tuplas Nomeadas
Tuplas nomeadas podem ser uma boa opção para se trabalhar com dados imutáveis.
Ex.
1 >>> from collections import namedtuple
2 >>> Pontos = namedtuple(’Ponto ’,"x y")
3 >>> ponto = Pontos (21,43)
4 >>> ponto
5 Ponto(x=21, y=43)
6 >>> ponto.x
7 21
8 >>> ponto.x = 12
9 Traceback (most recent call last):
10 File "<stdin >", line 1, in <module >
11 AttributeError : can’t set attribute
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Classes de Dados
dataclass pode ser uma boa opção para trabalhar com classes que apenas representam
dados.
Ex.
1 >>> from dataclasses import dataclass
2 >>> @dataclass
3 ... class Color:
4 ... red: int
5 ... green: int
6 ... blue: int
7 >>> color = Color (255, 0, 0)
8 >>> color.green = 128
9 >>> color
10 Color(red =255, green =128, blue =0)
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Criando Classes de Dados Imutáveis
1 >>> @dataclass(frozen=True)
2 ... class Cor:
3 ... vermelho :int
4 ... verde : int
5 ... azul: int
6 ...
7 >>> cor = Cor (255,0,0)
8 >>> cor.verde = 255
9 Traceback (most recent call last):
10 File "<stdin >", line 1, in <module >
11 File "<string >", line 4, in __setattr__
12 dataclasses. FrozenInstanceError : cannot assign to field ’verde ’
13 >>> cor
14 Cor(vermelho =255, verde =0, azul =0)
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Elementos de Programação Funcional em Python
• Compreensão de Listas, Iteradores e Geradores(list comprehensions, iterators e
generators)
• Funções Anônimas (Lambda)
• Mapas e Reduções (Map Reduce)
• Filtros (Filter)
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
List Comprehensions
List compreension é uma abordagem declarativa para criação de listas3. Ex.
1 >>> lista = [x for x in range (10) if x < 5]
2 >>> lista
3 [0, 1, 2, 3, 4]
4 >>>
3
Ver também iterators e generators
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Funções Lambda
1 >>> x = lambda a, b, c : a + b + c # lambda simples
2 >>> x(5,6,7)
3 18
4 >>> def myfunc(n):
5 ... return lambda a : a * n # retorna uma lamba com n fixo
6 ...
7 >>> m = myfunc (3)
8 >>> m(4)
9 12
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Maps
O Map é uma forma de aplicar funções a iteráveis (listas, tuplas, dicionários, etc) Ex.
1 >>> def square(number):
2 ... return number ** 2
3 ...
4 >>> numbers = [1, 2, 3, 4, 5]
5 >>> squared = map(square, numbers)
6 >>> list(squared)
7 [1, 4, 9, 16, 25]
8 >>>
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Reduce
A função reduce encadeia uma chamada sequencialmente a um conjunto de dados.
Vejamos como calcular uma soma acumulada.
1 >>> def my_add(a, b):
2 ... return a + b
3 ...
4 >>> ns = [1,2,3,4,5,6,7,8,9,10]
5 >>> from functools import reduce
6 >>> reduce(my_add,ns)
7 55
Resultado: ((((((((((0 + 1) + 2) + 3) + 4) + 5) + 6) + 7) + 8) + 9) + 10)
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Filter
Filtra elementos em iteráveis. Ex.
1 >>> import math
2 >>> def eh_par(x):
3 ... return x%2==0
4 >>> numeros = [1,2,4,5,3,6,7,8,9]
5 >>> pares = list(filter(eh_par,numeros))
6 >>> pares
7 [2, 4, 6, 8]
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
Seguindo
Agora que vimos os conceitos básicos associados a programação funcional podemos
estudar linguagens puramente funcional.
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação
E N J O Y
Ronaldo F. Ramos Instituto Federal do Ceará
Paradigmas de Programação

python_funcional.pdf

  • 1.
    Paradigmas de Programação RonaldoF. Ramos Instituto Federal do Ceará 28 de outubro de 2023
  • 2.
    PARTE 3 -PARADIGMA FUNCIONAL PROGRAMAÇÃO FUNCIONAL EM PYTHON AULA 1/1 Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 3.
    Roteiro • Programação Funcionalem Python Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 4.
    Definição Em ciência dacomputação, programação funcional é um paradigma de programação que trata a computação como uma avaliação de funções matemáticas e que evita estados ou dados mutáveis. Ela enfatiza a aplicação de funções, em contraste da programação imperativa, que enfatiza mudanças no estado do programa 1 2 1 Fonte: Wikipedia 2 Paul Hudak (setembro de 1989). "Conception, evolution, and application of functional programming languages"(pdf) . ACM Computing Surveys. Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 5.
    Foco da ProgramaçãoFuncional • Manutenibilidade • Testabilidade Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 6.
    Um Programa SimplesNão Funcional em Python 1 from datetime import datetime 2 class SaudacaoEntrada : 3 def __init__(self): 4 hora_atual = datetime.now() 5 if hora_atual.hour < 12: 6 self. SaudacaoEntrada = "Bom Dia" 7 elif 12 <= hora_atual.hour < 18: 8 self. SaudacaoEntrada = "Boa Tarde" 9 else: 10 self. SaudacaoEntrada = "Boa Noite" 11 def sauda(self, nome): 12 print(f"{self. SaudacaoEntrada }, {nome}.") Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 7.
    Continuação do Programa 1def main (): 2 name = input("Digite o seu nome ") 3 Saudacao = SaudacaoEntrada () 4 Saudacao.sauda(name) 5 6 if __name__ == "__main__": 7 main () Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 8.
    Efeitos Colaterais -Side Effects Problemas do ponto de vista da programação funcional(efeitos colaterais) • A função construtora modifica variáveis fora do seu escopo • As funções internas (não main) executam operações de entrada e saída A existência de efeitos colaterais nos programas dificulta a compreensibilidade do programa e sua manutenibilidade. Além disso o fato das variáveis serem mutáveis também contribui para dificultar a rastreabilidade do mesmo. Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 9.
    Testabilidade Procedimentos com efeitoscolaterais, por não serem isolados, dificultam o processo de testes. Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 10.
    Exemplos de EfeitosColaterais • Imprimir alguma coisa • Ler um arquivo • Escrever em um arquivo • Interagir com uma base de dados Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 11.
    Reduzindo os efeitoscolaterais 1 from datetime import datetime 2 class Saudacoes: 3 # a classe será autocontida e não realiza operações de E/S 4 def __init__(self, saudacao): 5 self. saudacaoIntrodutoria = saudacao 6 7 # a função retorna a string ao invés de imprimí-la 8 def sauda(self, nome): 9 return f"{self. saudacaoIntrodutoria }, {nome}." Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 12.
    As opereções deE/S são transferidas para a main() 1 def main (): 2 # criacao do objeto fora do escopo da classe Saudacoes 3 hora_atual = datetime.now() 4 if hora_atual.hour < 12: 5 saudacao_inicial = "Bom dia" 6 elif 12 <= hora_atual.hour < 18: 7 saudacao_inicial = "Boa Tarde" 8 else: 9 saudacao_inicial = "Boa Noite" 10 11 nome = input("Entre com o seu nome:") 12 saudacao = Saudacoes( saudacao_inicial ) 13 print(saudacao.sauda(nome)) Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 13.
    Sem Classes eObjetos Programas não necessariamente precisam de classes e objetos. Classes e Objetos podem tornar programas mais complexos e até mais lentos. Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 14.
    Somente com funções Aoseparar as responsabilidades em funções teremos: 1 from datetime import datetime 2 3 def sauda(nome, saudacao_inicial ): 4 return f"{ saudacao_inicial }" 5 6 def definir_saudacao (): 7 hora_atual = datetime.now() 8 if hora_atual.hour < 12: 9 return "Bom dia" 10 elif 12 <= hora_atual.hour < 18: 11 return "Boa tarde" 12 else: 13 return "Boa noite" Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 15.
    Função main Temos umprograma completamente funcional sem uso de maiores recursos. 1 def ler_nome (): 2 return input("Digite o seu nome: ") 3 4 def main (): 5 print(sauda(ler_nome (), definir_saudacao ())) 6 7 if __name__ == "__main__": 8 main () Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 16.
    Funções Puras ouImpuras Definição Uma função é considerada pura se é livre de efeitos colaterais, caso contrário é chamada de impura. Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 17.
    Cidadãos de PrimeiraClasse Em ambientes funcionais as funções podem (devem) ser passadas como argumentos em outras funções Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 18.
    Funções como Argumentos 1from datetime import datetime 2 # a variavel leitor_saudacoes receberá uma função 3 def sauda(nome, leitor_saudacoes ): # :LeitorSaudacao 4 if nome == "ronaldo": 5 return "Grande Ron" 6 # a função recebida é chamada aqui 7 return f"{ leitor_saudacoes ()}, {nome}." 8 def ler_saudacao (): 9 hora_atual = datetime.now() 10 if hora_atual.hour < 12: 11 return "Bom dia" 12 elif 12 <= hora_atual.hour < 18: 13 return "Boa Tarde" 14 else: 15 return "Boa Noite" Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 19.
    Funções como Argumentos- Continua Observe que para que uma função seja passada como argumento em Python basta remover os () 1 def ler_nome (): 2 return input("Entre com o seu nome: ") 3 4 def main () -> None: 5 # chamada de função passando função como argumento 6 print(sauda(ler_nome (), ler_saudacao)) 7 8 if __name__ == "__main__": 9 main () Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 20.
    Partials Com partials podemosfixar um certo número de argumentos com valores prefixados 1 from datetime import datetime 2 from functools import partial 3 def sauda(nome, leitor_saudacao ): 4 if nome == "ronaldo": 5 return "Grande Ron" 6 return f"{ leitor_saudacao ()}, {nome}." 7 def ler_saudacoes (): 8 hora_atual = datetime.now() 9 if hora_atual.hour < 12: 10 return "Bom dia" 11 elif 12 <= hora_atual.hour < 18: 12 return "Boa Tarde" 13 else: 14 return "Boa Noite" Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 21.
    Partials - main 1def ler_nome (): 2 return input("Entre com seu nome: ") 3 4 def main (): 5 # seta o valor de leitor_saudacao da função original 6 funcao_sauda = partial(sauda, leitor_saudacao =ler_saudacoes) 7 print(funcao_sauda(ler_nome ())) 8 9 if __name__ == "__main__": 10 main () Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 22.
    Imutabilidade Em ambientes funcionaisas variáveis são associadas a expressões e seus valores se tornam imutáveis. Linguagens como python usam as duas possibilidades. Vejamos alguns exemplos. 1 import random 2 def main () -> None: 3 lista_para_testar = [120, 68, -20, 0, 5, 67, 14, 99] 4 # Usando ordenamento com imutabilidade mantém a listas original intacta 5 lista_ordenada = sorted( lista_para_testar ) 6 print(f"Lista original: { lista_para_testar }") 7 print(f"Lista ordenada: { lista_ordenada}") 8 # ordenamento com modificação da lista original 9 lista_para_testar .sort () 10 print(f"Lista original: { lista_para_testar }") Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 23.
    Imutabilidade - Continuação 1# outros exemplos de operações mutáveis e imutáveis 2 cartas = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"] 3 4 cartas_embaralhadas = random.sample(cartas, k=len(cartas)) 5 print(f"Cartas embaralhadas: { cartas_embaralhadas }") 6 print(f"Cartas originais: {cartas}") 7 8 random.shuffle(cartas) # embaralha cartas (mutável) 9 print(f"cartas: {cartas}") 10 11 if __name__ == "__main__": 12 main () Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 24.
    Mutabilidade x Imutabilidade Umobjeto pode ser também mutável ou imutável se o seu estado pode ser modificado após a criação. As linguagens híbridas como python podem ter elementos pertencentes a uma ou outra categorias. Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 25.
    Objetcos x Variáveisem Python Definições: • Variáveis são referências para objetos. • Objetos são elementos delimitados em um espaço de memória concreto. Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 26.
    Objetos em Python EmPython tudo são objetos: números, strings, funções, classes, etc. Os objetos possuem as seguintes caractarísticas: • Valor • Identidade • Tipo Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 27.
    Verificando o valordo objeto Os valores dos objetos são instâncias de tipos primitivos como int, float, etc ou ainda definidos pelo programador. Podemos verificar estes valores e seus tipos através do isinstance. 1 >>> isinstance (28,int) 2 True 3 4 >>> isinstance (3.14,float) 5 True Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 28.
    Verificando o IDdo objeto 1 >>> id (12) 2 2182424887888 3 >>> x = 10 4 >>> id(x) 5 2182424887824 6 >>> id (10) 7 2182424887824 8 >>> y = 10 9 >>> id(y) 10 2182424887824 Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 29.
    Testando a Imutabilidadedos Tipos Primitivos 1 >>> x = y = 13 2 >>> id(x) 3 2182424887920 4 >>> id(y) 5 2182424887920 6 >>> y += 1 7 >>> y 8 14 9 >>> id(y) 10 2182424887952 11 >>> id(x) 12 2182424887920 Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 30.
    Tipos dos Objetostype e .__class__ 1 >>> type (42) 2 <class ’int’> 3 >>> type(’Escambau do judas ’) 4 <class ’str’> 5 >>> type ([1,2,3,4]) 6 <class ’list ’> 7 >>> 8 >>> (42).__class__ 9 <class ’int’> 10 >>> ’Queima leao do pici ’.__class__ 11 <class ’str’> Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 31.
    Tipos Primitivos Imutáveis Otipos primitivos boolean, int float e complex são imutáveis. Os tipos str, bytes e tuple também o são. Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 32.
    Tipos Mutáveis emPython - List A lista em si é mutável, mas os elementos internos podem ou não ser dependendo do tipo. Ex. 1 >>> numeros = [1,5,8] # criando uma lista de números 2 >>> id(numeros) 3 2490398152384 4 >>> id(numeros [1]) # verificando o id do segundo elemento 5 2490392248688 6 >>> numeros [1] = 10 # mudando o segundo elemento 7 >>> id(numeros [1]) # verificando se o elemento mudou 8 2490392248848 9 >>> Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 33.
    Tipos Mutáveis emPython - Dicionários Com dicionários você pode mudar o valor associado a uma chave e adicionar ou remover novos pares de ’valor-chave’. Ex. 1 >>> lista_compras = {’feijao ’:10, ’arroz ’:20, ’ovos ’:12, ’farinha ’:30, ’rapadura ’:15} 2 >>> lista_compras[’banana ’]=20 # adicionando dados 3 >>> del lista_compras[’arroz ’] # apagando dados 4 >>> lista_compras 5 {’feijao ’: 10, ’ovos ’: 12, ’farinha ’: 30, ’rapadura ’: 15, ’banana ’: 20} 6 >>> lista_compras[’rapadura ’]=30 7 >>> lista_compras 8 {’feijao ’: 10, ’ovos ’: 12, ’farinha ’: 30, ’rapadura ’: 30, ’banana ’: 20} Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 34.
    Tipos Mutáveis emPython - Sets (Conjuntos) Com os conjuntos podemos inserir ou remover itens. Ex. 1 >>> compras = {’feijao ’,’farinha ’,’rapadura ’} 2 >>> compras.add(’arroz ’) 3 >>> compras 4 {’arroz ’, ’rapadura ’, ’feijao ’, ’farinha ’} 5 >>> compras.discard(’arroz ’) 6 >>> compras 7 {’rapadura ’, ’feijao ’, ’farinha ’} Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 35.
    Resumo dos Dadosde Mutabilidade no Python Tipo Classe Mutável Números int, float, complex Não Strings str Não Tuplas tuple Não Bytes bytes Não Booleano bool Não conjuntos Fixos(Frozen Sets) frozenset Não Listas list Sim Dicionários dict Sim Conjuntos (Sets) set Sim Listas de Bytes(Byte Arrays) bytearray Sim Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 36.
    Atenção: Aliases comMutabilidade Uma mudança em um alias de um tipo imutável não afeta o original. Ex. 1 >>> x = 2 2 >>> y = x 3 >>> x 4 2 5 >>> y 6 2 7 >>> y += 1 8 >>> x 9 2 10 >>> y 11 3 12 >>> Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 37.
    Atenção: Aliases comMutabilidade Uma mudança em um alias de um tipo mutável afeta o original. Ex. 1 >>> compras = [’pera ’,’maca ’,’banana ’] 2 >>> lista = compras 3 >>> lista.append(’laranjas ’) 4 >>> compras 5 [’pera ’, ’maca ’, ’banana ’, ’laranjas ’] 6 >>> lista 7 [’pera ’, ’maca ’, ’banana ’, ’laranjas ’] Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 38.
    Argumentos Mutáveis Ao serempassados argumentos mutáveis para uma função a variável externa pode sofrer as consequencias de mudanças realizadas dentro das funções. Ex. 1 >>> def dobro(lista): 2 ... for i in range(len(lista)): 3 ... lista[i] = lista[i]**2 4 ... return lista 5 >>> x = [1,2,3,4] 6 >>> dobro(x) 7 [1, 4, 9, 16] 8 >>> x 9 [1, 4, 9, 16] Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 39.
    Argumentos Imutáveis Isto nãoacontece se o argumento representar um dado imutável. Ex. 1 >>> def dobro(y): 2 ... y *= 2 3 ... print(id(y)) 4 ... return y 5 ... 6 >>> x = 10 7 >>> id(x) 8 2490392248848 9 >>> dobro(x) 10 2490392249168 11 20 12 >>> id(x) 13 2490392248848 Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 40.
    Argumentos Default NãoSobrescrevem a Lista(Mutável) Lista é preservada entre chamadas não ocorrendo o esperado. Ex. 1 >>> def adicionar_item (item, lista = []): 2 ... lista.append(item) 3 ... return lista 4 ... 5 >>> adicionar_item (1) 6 [1] 7 >>> adicionar_item (2) 8 [1, 2] 9 >>> adicionar_item (3) 10 [1, 2, 3] Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 41.
    Solução 1 >>> defadiciona(item, lista=None): 2 ... if lista == None: 3 ... lista =[] 4 ... lista.append(item) 5 ... return lista 6 ... 7 >>> adiciona (1) 8 [1] 9 >>> adiciona (2) 10 [2] 11 >>> adiciona (3) 12 [3] Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 42.
    Atenção Muitos aconselham anão usar argumentos default. De qualquer forma, melhor sempre tomar cuidado. Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 43.
    Uma aplicação paraesse caso Essa propriedade das listas pode ser usada para calcular alguma coisa como a média móvel. Ex. 1 >>> def media_movel(x, amostra =[]): 2 ... amostra.append(x) 3 ... return sum(amostra)/len(amostra) 4 >>> media_movel (1) 5 1.0 6 >>> media_movel (3) 7 2.0 8 >>> media_movel (7) 9 3. 6666666666666665 10 >>> media_movel (5) 11 4.0 Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 44.
    Cópias Rasas -Shallow Copy Cópia de uma lista obtida com slice [:], o método .copy ou o copy.copy(). Neste casos cria-se uma nova lista porém os elementos da nova lista são aliases para os elementos internos da lista anterior. Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 45.
    Cópia Profunda Quando usadaa função copy.deepcopy() a lista é copiada integralmente para uma nova lista. Experimente..... Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 46.
    Métodos Não Mutáveis Stringssão imutáveis o que significa que os métodos que as modificam criam cópias das strings sem modificar as originais. 1 >>> original = "esta e uma string" 2 >>> original.upper () # isto apenas cria uma cópia 3 "ESTA E UMA STRING" 4 >>> original 5 "esta é uma string" Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 47.
    Aplicação desta característica Estapropriedade pode permitir o encadeamento de métodos. Ex. 1 >>> texto = "<html lan=’eng ’>" 2 >>> texto.removeprefix("<").removesuffix(">").upper ().center (20) 3 " HTML LAN=’ENG’ " 4 >>> texto 5 "<html lan=’eng ’>" 6 >>> Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 48.
    Tuplas contendo dadosmutáveis Tuplas são imutáveis, mas podem conter objetos mutáveis. Ex. 1 >>> vermelho = ("RED",[255,0,0]) 2 >>> vermelho [0] = "red" 3 Traceback (most recent call last): 4 File "<stdin >", line 1, in <module > 5 TypeError: ’tuple ’ object does not support item assignment 6 >>> vermelho [1] = [0,0,255] 7 Traceback (most recent call last): 8 File "<stdin >", line 1, in <module > 9 TypeError: ’tuple ’ object does not support item assignment 10 >>> vermelho [1][0] = 0 11 >>> vermelho 12 (’RED’, [0, 0, 0]) Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 49.
    Componentes Automáticos deClasses Python já cria automaticamente alguns métodos em classes. Ex. 1 >>> class Pessoa: 2 ... pass 3 ... 4 >>> dir(Pessoa) 5 [’__class__ ’, ’__delattr__ ’, ’__dict__ ’, ’__dir__ ’, ’__doc__ ’, ’__eq__ ’, ’__format__ ’, ’__ge__ ’, ’__getattribute__ ’, ’__gt__ ’, ’__hash__ ’, ’__init__ ’, ’__init_subclass__ ’, ’__le__ ’, ’__lt__ ’, ’__module__ ’, ’__ne__ ’, ’__new__ ’, ’__reduce__ ’, ’__reduce_ex__ ’, ’__repr__ ’, ’__setattr__ ’, ’__sizeof__ ’, ’__str__ ’, ’__subclasshook__ ’, ’__weakref__ ’] Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 50.
    Injeção de Atributose Métodos 1 >>> Pessoa.emprego=’Programador ’ 2 >>> def __init__(self, nome, emprego): 3 ... self.nome = nome 4 ... self.emprego = emprego 5 >>> Pessoa.__init__=__init__ 6 >>> dir(Pessoa) 7 [’__class__ ’, ’__delattr__ ’, ’__dict__ ’, ’__dir__ ’, ’__doc__ ’, ’__eq__ ’, ’__format__ ’, ’__ge__ ’, ’__getattribute__ ’, ’__gt__ ’, ’__hash__ ’, ’__init__ ’, ’__init_subclass__ ’, ’__le__ ’, ’__lt__ ’, ... , ’__subclasshook__ ’, ’__weakref__ ’, ’emprego ’] Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 51.
    Dica sobre Injeçãode Atributos e Métodos A injeção de elementos em uma classe pode ser útil para a programação funcional em Python Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 52.
    Impedindo a Adiçãode Atributos a Objetos Podemos limitar a adição de atributos a objetos usando __slots__,... Ex. 1 class Pessoa: 2 ... __slots__ = (’nome ’,’emprego ’) 3 ... def __init__(self,nome): 4 ... self.nome = nome 5 ... 6 >>> joao = Pessoa(’Joao ’) 7 >>> joao.emprego = ’Engenheiro ’ 8 >>> joao.endereco = ’Rua X Numero Z’ 9 Traceback (most recent call last): 10 File "<stdin >", line 1, in <module > 11 AttributeError : ’Pessoa ’ object has no attribute ’endereco ’ Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 53.
    Impedindo a Adiçãode Atributos a Objetos ... mas não a classes . Ex. 1 >>> 2 >>> Pessoa.endereco = "Rua X número Z" 3 >>> 4 >>> dir(joao) 5 [’__class__ ’, ’__delattr__ ’, ’__dir__ ’, ’__doc__ ’, ’__eq__ ’, ’__format__ ’, ’__ge__ ’, ’__getattribute__ ’, ... , ’__subclasshook__ ’, ’emprego ’, ’endereco ’, ’nome ’] Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 54.
    Funções __setattr__() and.__delattr__() Estas funções controlam o acesso a atributos de forma a torná-los imutáveis se for o caso. EX. 1 >>> class Imutavel: 2 ... def __init__(self, valor): 3 ... super ().__setattr__("valor", valor) 4 ... def __setattr__(self, nome, attr_valor): 5 ... raise AttributeError(f"Não posso mudar o valor do atributo ’{nome}’") 6 ... def __delattr__(self, nome): 7 ... raise AttributeError(f"Não posso apagar o atributo ’{nome}’") 8 ... Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 55.
    Funções __setattr__() and.__delattr__() Cont.. 1 >>> gravidade = Imutavel (9.78) 2 >>> gravidade.valor 3 9.78 4 >>> gravidade.valor = 9.8 5 Traceback (most recent call last): 6 File "<stdin >", line 1, in <module > 7 File "<stdin >", line 5, in __setattr__ 8 AttributeError : Não posso mudar o valor do atributo ’valor ’ 9 >>> del gravidade.valor 10 Traceback (most recent call last): 11 File "<stdin >", line 1, in <module > 12 File "<stdin >", line 7, in __delattr__ 13 AttributeError : Não posso apagar o atributo ’valor ’ Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 56.
    Properties O uso degetters sem setters pode ocultar (fazer de conta que oculta) atributos que queremos que sejam ’imutáveis’. EX. 1 >>> class Pontos: 2 ... def __init__(self, x): 3 ... self._x = x 4 ... @property 5 ... def x(self): 6 ... return self._x 7 >>> p = Pontos (2,3) 8 >>> p.x 9 2 10 >>> p.x = 3 11 Traceback (most recent call last): 12 File "<stdin >", line 1, in <module > 13 AttributeError : can’t set attribute ’x’ Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 57.
    Tuplas Nomeadas Tuplas nomeadaspodem ser uma boa opção para se trabalhar com dados imutáveis. Ex. 1 >>> from collections import namedtuple 2 >>> Pontos = namedtuple(’Ponto ’,"x y") 3 >>> ponto = Pontos (21,43) 4 >>> ponto 5 Ponto(x=21, y=43) 6 >>> ponto.x 7 21 8 >>> ponto.x = 12 9 Traceback (most recent call last): 10 File "<stdin >", line 1, in <module > 11 AttributeError : can’t set attribute Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 58.
    Classes de Dados dataclasspode ser uma boa opção para trabalhar com classes que apenas representam dados. Ex. 1 >>> from dataclasses import dataclass 2 >>> @dataclass 3 ... class Color: 4 ... red: int 5 ... green: int 6 ... blue: int 7 >>> color = Color (255, 0, 0) 8 >>> color.green = 128 9 >>> color 10 Color(red =255, green =128, blue =0) Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 59.
    Criando Classes deDados Imutáveis 1 >>> @dataclass(frozen=True) 2 ... class Cor: 3 ... vermelho :int 4 ... verde : int 5 ... azul: int 6 ... 7 >>> cor = Cor (255,0,0) 8 >>> cor.verde = 255 9 Traceback (most recent call last): 10 File "<stdin >", line 1, in <module > 11 File "<string >", line 4, in __setattr__ 12 dataclasses. FrozenInstanceError : cannot assign to field ’verde ’ 13 >>> cor 14 Cor(vermelho =255, verde =0, azul =0) Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 60.
    Elementos de ProgramaçãoFuncional em Python • Compreensão de Listas, Iteradores e Geradores(list comprehensions, iterators e generators) • Funções Anônimas (Lambda) • Mapas e Reduções (Map Reduce) • Filtros (Filter) Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 61.
    List Comprehensions List compreensioné uma abordagem declarativa para criação de listas3. Ex. 1 >>> lista = [x for x in range (10) if x < 5] 2 >>> lista 3 [0, 1, 2, 3, 4] 4 >>> 3 Ver também iterators e generators Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 62.
    Funções Lambda 1 >>>x = lambda a, b, c : a + b + c # lambda simples 2 >>> x(5,6,7) 3 18 4 >>> def myfunc(n): 5 ... return lambda a : a * n # retorna uma lamba com n fixo 6 ... 7 >>> m = myfunc (3) 8 >>> m(4) 9 12 Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 63.
    Maps O Map éuma forma de aplicar funções a iteráveis (listas, tuplas, dicionários, etc) Ex. 1 >>> def square(number): 2 ... return number ** 2 3 ... 4 >>> numbers = [1, 2, 3, 4, 5] 5 >>> squared = map(square, numbers) 6 >>> list(squared) 7 [1, 4, 9, 16, 25] 8 >>> Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 64.
    Reduce A função reduceencadeia uma chamada sequencialmente a um conjunto de dados. Vejamos como calcular uma soma acumulada. 1 >>> def my_add(a, b): 2 ... return a + b 3 ... 4 >>> ns = [1,2,3,4,5,6,7,8,9,10] 5 >>> from functools import reduce 6 >>> reduce(my_add,ns) 7 55 Resultado: ((((((((((0 + 1) + 2) + 3) + 4) + 5) + 6) + 7) + 8) + 9) + 10) Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 65.
    Filter Filtra elementos emiteráveis. Ex. 1 >>> import math 2 >>> def eh_par(x): 3 ... return x%2==0 4 >>> numeros = [1,2,4,5,3,6,7,8,9] 5 >>> pares = list(filter(eh_par,numeros)) 6 >>> pares 7 [2, 4, 6, 8] Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 66.
    Seguindo Agora que vimosos conceitos básicos associados a programação funcional podemos estudar linguagens puramente funcional. Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação
  • 67.
    E N JO Y Ronaldo F. Ramos Instituto Federal do Ceará Paradigmas de Programação