Aula 30

python interativo

1 Lei de benford

funcao que recebe 1 string e imprime a proporcão que cada um dos digitos (1 a 9) aparece no texto como o primeiro digito de um numero - essa é a verdadeira lei de Benford - nao a que implementamos em haskell

2 OO em python

class C:
  def __init__(self,...)

  def __repl__(self)

  def __str__(self)

  def __eq__(self, other)   self == other?

  def __add__(self,other)   self + other

Pyhton data model

uso mais comum de objetos em bibliotecas Python - para guardar um estado aprendizado de maquina

http

3 Iterators

coisas que podem estar no =for=

for x in z:

implementam o metodo =__next__= que é chamado pela funcao =next= que levanta a excecao =StopIteration= quando nao há proximo

try:
   it = iter(z)
   while True:
     x = next(it)
     ...
except StopIteration:
   pass
class meurange:
  def __init__(self,baixo,alto):
      self.baixo=baixo
      self.alto=alto
      self.i = baixo-1
  def __iter__(self):
      return self
  def __next__(self):
      if self.i<self.alto:
         self.i = self.i+1
         return self.i
      else: 
         raise StopIteration

alguns iterators sao como os thunk de haskell - promessas de computacao

range(1,10)

map(lambda x: x+1,[1,2,3])

mas imprimir na tela nao força a execuçao das promessas. =list= executa as promessas e cria uma lista

range(1,20)

print(range(1,20))

list(range(1,20))

4 Generators

Funcoes que guardam o estado entre uma chamada e outra e fazem o papel de um iterator

Use =yield= em vez de =return= - na proxima chamada a funçao executa do =yield= ate o proximo =yield=

def meurange(baixo,alto):
   baixo=baixo-1
   while baixo< alto:
      baixo = baixo+1
      yield baixo

modulo itertools

5 Decorators

Funcoes que recebem uma funcao e retornam outra funçao que "envolve" aquela:

import time

def tempo(func):
  def aux():
      t1=time.time()
      for i in range(1000):
         func()
      t2=time.time()
      print(t2-t1)
  return aux
def a():
   y=[]
   for x in range(10):
       y.append(x)

def b():
  y=[0]*10
  for x in range(10):
    y[x]=x


a()

a=tempo(a)
b=tempo(b)

a()
b()

decorators sao essas funcoes + syntatic sugar

@tempo
def a():
   y=[]
   for x in range(10):
       y.append(x)

@tempo
def b():
  y=[0]*10
  for x in range(10):
    y[x]=x

Como fazer decorators para funcoes com argumentos:

def trac(funcao):
   def aux(*args):
     print("inicio args:",args)
     x = funcao(*args)
     print("fim resultado :",x)
     return x
   return aux

@trac
def f(a,b,c):
   return a*b-c

memorizador

def memoriza(f):
   mem={}
   def aux(*args): 
     if args in mem:
        return mem[args]
     else:
        x = f(*args)
        mem[args] = x
        return x
   return aux

utilizando uma classe como decorator memoizador o metodo =__call__= é executado quando o objeto é chamado como funcao.

5.1 execicios

sem olhar o itertools implemente os generators

  • zip(iter1,iter2) que retorna tuplas de iter1 e iter2
  • loop(iter) => loop("abc") -> "abcabcabc…"
  • produto(it1, it2) - retorna todos os pares de tuplas (a,b) onde a vem de it1 e b de it2
  • esimo(k,iter) - retorna cada k-esimo elemento de iter
  • prob(k,iter) - retorna cada k-esimo elemento de iter probailisticamente - cada elemento tem uma chance de 1/k de ser retornado - no infinito isso retorna 1/k dos elementos de iter mas vc nao sabe dizer quais. Use a biblioteca =random=

decorators

  • decorator para contar o numero de chamadas de uma funcao. Um metodo diferente retorna o numero de chamadas e outro metodo zera a contagem
  • decorator para

Author: Jacques Wainer

Created: 2018-06-11 Mon 15:03

Validate