300x250 AD TOP

Blogger news

AD (728x90)

Tecnologia do Blogger.

Colaboradores

Seguidores

Postagens populares

Mostrando postagens com marcador Funcional. Mostrar todas as postagens
Mostrando postagens com marcador Funcional. Mostrar todas as postagens
Tagged under: , ,

Programação funcional - Python [Exercícios]


Dando continuidade aos posts sobre o paradigma funciona, achei interessante propor e resolver alguns exercícios nesse paradigma:

  • Usando LCs, defina a função vogais(palavra) que retorna o número de vogais em palavra. Ex: vogais('nasemanadaprova') = 7 .

letras_vogais = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
vogal = lambda letra : 1 if letra in letras_vogais  else 0
vogais = lambda l: reduce( lambda x, y: x+ y, [vogal(letras) for letras in l])

print vogais('nasemanadaprova')

  • Defina a função maisQueKVogais(string) que retorna as palavras em string com mais que k vogais.
 Ex: maisQueKVogais('na semana da prova', 1) =  ['semana', 'prova'].
 Dica: string.split() retorna uma lista onde cada elemento é uma palavra de string.

frase = "na semana da prova".split()
maisQueKVogais = lambda frase, k: [palavra for palavra in frase if vogais(palavra) > k]

print maisQueKVogais(frase, 1)

  • Implemente a função maioria que tem como parâmetros uma propriedade (descrita como uma função anônima) e uma lista e retorna True se mais que metade dos elementos na lista têm a propriedade.
  Ex: maioria(lambda x:x>1, [1, 2, 1, 3, 0, 2, 4]) = True

lista = [1, 2, 1, 3, 0, 2, 4]

boleanoParaInteiro =lambda valor: 1 if valor else 0
elementos = lambda p, l: map(p,  l) 
soma = lambda x, y: x+y

lfuncao = lambda f, l: [boleanoParaInteiro(valor) for valor in elementos(f, l)]

def maioria(propriedade, lista):
 return True if reduce(soma, lfuncao(propriedade, lista)) > len(lista)/2 else False


print maioria(lambda x:x>1, lista)
Tagged under: , ,

Programação Funcional - Python







O objetivo desse post é apresentar da forma simples e fácil de algumas das características do paradigma funcional aplicado na linguagem de programação Python. Como existem inúmeras literaturas na web falando sobre o que séria programação funcional e a sua diferença em relação a outros paradigmas optei por focar nas seguinte característica:

  • Expressão lambda
  • Funções de alta ordem: map(), filter(), reduce() e zip()

Importante: O aspecto funcional de Python permite escrever código compacto e eventualmente mais rápido, por outro lado corre-se o risco de deixar o código obscuro e de manutenção mais complicada.

permite escrever funções anônimas/sem-nome usando apenas uma linha de código.

Sintaxe:

lambda [ var1, var2, ..., varN ]: expr -> expr_ret

Onde var1, var2, ..., varN são variáveis que representam o argumento da função e expr é qualquer expressão válida em Python envolvendo essas variáveis.O resultado é uma nova expressão expr_ret.
Um exemplo trivial de lamba é a função identidade, que retorna o próprio elemento. Um exemplo prático de lambda é uma função que recebe dois valores (x e y) e retorna a soma desses elementos.

Exemplos:

Função identidade.
lambda x: x
Resultado: <function <lambda> at 0x1e3630>
Soma de dois valores.
lambda x, y: x+y
Resultado:<function <lambda> at 0x1e3670>
Note que o resultado é uma expressão do tipo lambda. Mas como posso obter algo útil, por exemplo, calcular 1+2 com lambda?

(lambda x, y: x+y)(1,2)
Resultado: 3

Esta forma de expressar um função é conhecida como função anonima, visto que a função não recebe um nome especifico pra ela.Agora caso queira dar um nome para ajudar a "lembrar" uma expressão lambda é necessário apenas guardá-la em uma variável.

identidade = lambda x: x
identidade('Python')
Resultado'Python'
soma = lambda x, y: x+y
soma(1, 2)
Resultado:3
Aparentemente lambda sozinho não tem muita graça ou utilidade, mas nas seções que se seguem faremos melhor uso dela. O importante é ter em mente que uma expressão lambda pode responder igual a qualquer função em Python.

Mapeamento - Map

O mapeamento consiste em aplicar uma função a todos os itens de uma sequência, gerando outra lista contendo os resultados e com o mesmo tamanho da lista inicial.

A forma mais simples de se usar o map é aplicando uma função função uma sequência seq, o resultado é sempre uma lista cujo os elementos são obtidos aplicando-se individualmente cada elemento de seq a função func. Ao mapear-se uma lista com None retorna-se os elementos originais da sequência.

Sintaxe:
map(funcão ou None, seq) ->lista

Exemplos:

map(None, [1, 3, 5])
resultado: [1, 3, 5]

map(abs, [-1, -2, -3])
Resultado: [1, 2, 3]

map(str, [2, 4, 6])
Resultado: ['2', '4', '6']

map(hex, (10, 11, 12))
Resulado: ['0xa', '0xb', '0xc']

Um exemplo mais interessante com uso da expressão lambda.
map(lambda x: x*x*x, [1, 2, 3, 4])
Resultado: [1, 8, 27, 64]

Forma Completa de Map

A forma completa de map admite uma função func (ou None) e um conjunto de sequencias (seq1, seq2, ..., seqN) como parâmetros.
Sintaxe:
map(func ou None, seq1, seq2, ..., seqN) ->lista

Atribuindo-se None ao map este retorna sempre uma tupla de N elementos que são os elementos cuja ordem deles é a ordem das sequencias até o tamanho da maior lista, índices maiores que as sequências são retornados como None.
Exemplos:
map(None, [135], [246])
[(1, 2), (3, 4), (5, 6)]
map(None, [1, 3, 5], [2, 4, 6, 8, 10])
[(1, 2), (3, 4), (5, 6), (None, 8), (None, 10)]
Fica fácil entender que se oferecermos ao map três listas é necessário então que a função aceite três variáveis como parâmetro. As seqüencias menoresque M são automaticamente preenchidas com o valor None e isso pode ser um inconveniente caso se tente aplicar a uma função que espera valores numéricos, pois None nunca é tratado como um valor numérico.

Exemplos:
map(lambda xyx*y, [135], [246])
[2, 12, 30]
map(lambda a, b, x: a*x+b, [1, 3, 5], [2, 4, 8], [0, 0, 0])
[2, 4, 8]

Redução – reduce

Redução significa aplicar uma função que recebe dois parâmetros, nos dois primeiros elementos de uma sequência, aplicar novamente a função usando como parâmetros o resultado do primeiro par e o terceiro elemento, seguindo assim até o final da sequência. O resultado final da redução é apenas um elemento.

A função reduce aplica acumuladamente os itens de uma sequência de entrada seq (da esquerda para a direita) a uma função func de dois parâmetros até reduzir esse cálculo a um único valor de resposta. Opcionalmente pode-se atribuir um valor inicial como parâmetro.

Sintaxe:
reduce(func, seq[, inicial]) -> valor
Exemplos:
reduce(lambda x, y: x+y, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
Resultado:55

reduce(lambda x, y: x+y, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 100)
Resultado:155

A função reduce() também pode ser usada para calcular fatorial:
fatorial = lambda n: reduce(lambda x, y: x*y, range(1, n))

Filtragem - filter

Na filtragem, uma função é aplicada em todos os itens de uma sequência, se a função retornar um valor que seja avaliado como verdadeiro, o item original fará parte da sequência resultante.

A função filter retorna uma sequência seq_ret cujos valores são os elementos da sequência de entrada seq que respeitam o seguinte critério: se a função for None os elementos que são verdadeiros são adicionados, caso uma função func esteja definida o valor de retorno da função é utilizado como valor verdade e apenas esses elementos vão fazer parte da sequência de retorno.

Sintaxe:
filter(func ou None, seq) -> seq_ret

A sequência seq_ret tem sempre o mesmo tipo de seq.

Exemplos:

filter(None, [0, 1, 2, None, 2>1, 'ola'])
Resultado:[1, 2, True, 'ola']
filter(lambda x: x > 3, [0, 1, 2, 3, 4, 5])
Resultado:[4, 5]

filter(lambda s: s > 'a', 'python r0cks!')
Resultado:'pythonrcks'

filter(lambda x: x % 2, [1, 2, 3, 4, 5, 6, 7])

Transposição - Zip

Transposição é construir uma série de sequências a partir de outra série de sequências, aonde a primeira nova sequência contém o primeiro elemento de cada sequência original, a segunda nova sequência contém o segundo elemento de cada sequência original, até que alguma das sequências originais acabe.

A função zip retorna uma sequência seq_ret cujos elementos são tuplas resultantes de cada um dos elementos de uma ou mais sequências de entradaseq1, seq2, ..., seqN. A sequência resultante é sempre truncada ao tamanho da menor sequência apresentada.

Sintaxe:
zip(seq1, seq2, ..., seqN) -> seq_ret

O valor de m é o comprimento da menor lista em seq.
Exemplos:

zip([1, 3, 5], [2, 4, 6])
Resultado: [(1, 2), (3, 4), (5, 6)]
zip([1, 3, 5], [2, 4, 6, 8, 10])
Resultado:[(1, 2), (3, 4), (5, 6)]