SlideShare uma empresa Scribd logo
1 de 21
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
Strategy (Design Pattern)Strategy (Design Pattern)
e seu uso com dicionário e Multitone seu uso com dicionário e Multiton
Segunda reunião em 2014 do grupo de estudos deSegunda reunião em 2014 do grupo de estudos de
Design patterns em linguagens dinâmicasDesign patterns em linguagens dinâmicas
nono
Garoa Hacker ClubeGaroa Hacker Clube
Slides com a preparação deSlides com a preparação de
Danilo J. S. BelliniDanilo J. S. Bellini
para discussão durante reuniãopara discussão durante reunião
2014-04-162014-04-16
Código dos slides disponível em:
https://github.com/danilobellini/design_patterns
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
ProblemaProblema
●
Muitas soluções para um mesmo problemaMuitas soluções para um mesmo problema
– Ordenação (sort), programação não-linear,Ordenação (sort), programação não-linear,
reconhecimento de padrões, otimização,reconhecimento de padrões, otimização,
processamento de sinais, …processamento de sinais, …
– Família de algoritmosFamília de algoritmos
●
Decisão em tempo de execução do algoritmo aDecisão em tempo de execução do algoritmo a
ser utilizadoser utilizado
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
StrategyStrategy
●
3 conceitos:3 conceitos:
– InterfaceInterface
– EstratégiasEstratégias
– Contexto (de uso)Contexto (de uso)
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
UML?! Muito chato! Cadê o código?UML?! Muito chato! Cadê o código?
Não é nested o suficiente?
#!/usr/bin/env python3
from abc import ABCMeta, abstractmethod
class Estratégia(metaclass=ABCMeta):
@abstractmethod
def executar(self, a, b): # Dois inteiros
pass
class Soma(Estratégia):
def executar(self, a, b):
return a + b
class Subtração(Estratégia):
def executar(self, a, b):
return a - b
class Multiplicação(Estratégia):
def executar(self, a, b):
return a * b
class Contexto:
def __init__(self, estratégia, símbolo):
self.estratégia = estratégia
self.símbolo = símbolo
def tarefa(self, a, b):
resultado = self.estratégia.executar(a, b)
args = (a, self.símbolo, b, resultado)
print("{} {} {} = {}".format(*args))
#!/usr/bin/env python3
from abc import ABCMeta, abstractmethod
class Estratégia(metaclass=ABCMeta):
@abstractmethod
def executar(self, a, b): # Dois inteiros
pass
class Soma(Estratégia):
def executar(self, a, b):
return a + b
class Subtração(Estratégia):
def executar(self, a, b):
return a - b
class Multiplicação(Estratégia):
def executar(self, a, b):
return a * b
class Contexto:
def __init__(self, estratégia, símbolo):
self.estratégia = estratégia
self.símbolo = símbolo
def tarefa(self, a, b):
resultado = self.estratégia.executar(a, b)
args = (a, self.símbolo, b, resultado)
print("{} {} {} = {}".format(*args))
if __name__ == "__main__":
Contexto(Soma(), "+").tarefa(22, 3)
ctx = Contexto(Subtração(), "-")
ctx.tarefa(22, 3)
ctx.estratégia = Multiplicação()
ctx.símbolo = "*"
ctx.tarefa(22, 3)
if __name__ == "__main__":
Contexto(Soma(), "+").tarefa(22, 3)
ctx = Contexto(Subtração(), "-")
ctx.tarefa(22, 3)
ctx.estratégia = Multiplicação()
ctx.símbolo = "*"
ctx.tarefa(22, 3)
strategy_0.py
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
Burocracia...é necessária?Burocracia...é necessária?
●
Definição de classes para cada algoritmoDefinição de classes para cada algoritmo
– Mais de uma instância de um único algoritmo?Mais de uma instância de um único algoritmo?
– Memória (efeito colaterais)?Memória (efeito colaterais)?
– Instante da instanciação?Instante da instanciação?
●
Definição explícita da interfaceDefinição explícita da interface
– Tipos estáticos e explícitos?Tipos estáticos e explícitos?
– Quantidades/nomes de argumentos sempreQuantidades/nomes de argumentos sempre
idênticos?idênticos?
●
Orientação a objetos?Orientação a objetos?
Não!Não!
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
InterfaceInterface
em Pythonem Python
●
Duck typingDuck typing
““When I see a bird thatWhen I see a bird that
●
walks like a duck andwalks like a duck and
●
swims like a duck andswims like a duck and
●
quacks like a duck,quacks like a duck,
I call that bird a duck.”I call that bird a duck.”
●
ABC (Abstract Base Classes)ABC (Abstract Base Classes)
– Dunder __subclasshook__Dunder __subclasshook__
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
#!/usr/bin/env python3
class Soma:
def executar(self, a, b):
return a + b
class Subtração:
def executar(self, a, b):
return a - b
class Multiplicação:
def executar(self, a, b):
return a * b
class Contexto:
def __init__(self, estratégia, símbolo):
self.estratégia = estratégia
self.símbolo = símbolo
def tarefa(self, a, b):
resultado = self.estratégia.executar(a, b)
args = (a, self.símbolo, b, resultado)
print("{} {} {} = {}".format(*args))
#!/usr/bin/env python3
class Soma:
def executar(self, a, b):
return a + b
class Subtração:
def executar(self, a, b):
return a - b
class Multiplicação:
def executar(self, a, b):
return a * b
class Contexto:
def __init__(self, estratégia, símbolo):
self.estratégia = estratégia
self.símbolo = símbolo
def tarefa(self, a, b):
resultado = self.estratégia.executar(a, b)
args = (a, self.símbolo, b, resultado)
print("{} {} {} = {}".format(*args))
if __name__ == "__main__":
Contexto(Soma(), "+").tarefa(22, 3)
ctx = Contexto(Subtração(), "-")
ctx.tarefa(22, 3)
ctx.estratégia = Multiplicação()
ctx.símbolo = "*"
ctx.tarefa(22, 3)
if __name__ == "__main__":
Contexto(Soma(), "+").tarefa(22, 3)
ctx = Contexto(Subtração(), "-")
ctx.tarefa(22, 3)
ctx.estratégia = Multiplicação()
ctx.símbolo = "*"
ctx.tarefa(22, 3)
Sem classe abstrataSem classe abstrata
(interface implícita)(interface implícita)
strategy_1.py
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
#!/usr/bin/env python3
from abc import ABCMeta, abstractmethod
class Estratégia(metaclass=ABCMeta):
@abstractmethod
def executar(self, a, b): # Dois inteiros
pass
@classmethod
def __subclasshook__(cls, C):
return any("executar" in vars(B) for B in C.mro()) or NotImplemented
class Soma:
def executar(self, a, b):
return a + b
print(isinstance(Soma(), Estratégia)) # True
print(issubclass(Soma, Estratégia)) # True
#!/usr/bin/env python3
from abc import ABCMeta, abstractmethod
class Estratégia(metaclass=ABCMeta):
@abstractmethod
def executar(self, a, b): # Dois inteiros
pass
@classmethod
def __subclasshook__(cls, C):
return any("executar" in vars(B) for B in C.mro()) or NotImplemented
class Soma:
def executar(self, a, b):
return a + b
print(isinstance(Soma(), Estratégia)) # True
print(issubclass(Soma, Estratégia)) # True
Subclass HookSubclass Hook subclasshook.py
In [5]: B.mro()
Out[5]: [__main__.B, __main__.A, builtins.object]
In [6]: D.mro() # MRO = Method Resolution Order
Out[6]: [__main__.D, __main__.B, __main__.C, __main__.A, builtins.object]
In [7]: vars(B) # Atributos (métodos, propriedades, etc.)
Out[7]: dict_proxy({'__module__': '__main__', '__doc__': None})
In [5]: B.mro()
Out[5]: [__main__.B, __main__.A, builtins.object]
In [6]: D.mro() # MRO = Method Resolution Order
Out[6]: [__main__.D, __main__.B, __main__.C, __main__.A, builtins.object]
In [7]: vars(B) # Atributos (métodos, propriedades, etc.)
Out[7]: dict_proxy({'__module__': '__main__', '__doc__': None})
In [1]: class A: pass
In [2]: class B(A): pass
In [3]: class C(A): pass
In [4]: class D(B, C): pass
In [1]: class A: pass
In [2]: class B(A): pass
In [3]: class C(A): pass
In [4]: class D(B, C): pass
O que é MRO?
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
EstratégiaEstratégia
●
Qualquer callableQualquer callable
– Método, função, __call__, operadores, etc.Método, função, __call__, operadores, etc.
●
Funções como objetos de segunda classeFunções como objetos de segunda classe
– Utilização do método de um objetosUtilização do método de um objetos
– Classes para possibilitar objetosClasses para possibilitar objetos
– InstanciaçãoInstanciação
●
Python, Ruby, JavaScript, …Python, Ruby, JavaScript, …
– Funções de primeira classeFunções de primeira classe
– Funções de ordem superiorFunções de ordem superior
– Fechamentos (closures)Fechamentos (closures)
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
#!/usr/bin/env python3
def soma(a, b):
return a + b
def subtração(a, b):
return a - b
def multiplicação(a, b):
return a * b
class Contexto:
def __init__(self, estratégia, símbolo):
self.estratégia = estratégia
self.símbolo = símbolo
def tarefa(self, a, b):
resultado = self.estratégia(a, b)
args = (a, self.símbolo, b, resultado)
print("{} {} {} = {}".format(*args))
#!/usr/bin/env python3
def soma(a, b):
return a + b
def subtração(a, b):
return a - b
def multiplicação(a, b):
return a * b
class Contexto:
def __init__(self, estratégia, símbolo):
self.estratégia = estratégia
self.símbolo = símbolo
def tarefa(self, a, b):
resultado = self.estratégia(a, b)
args = (a, self.símbolo, b, resultado)
print("{} {} {} = {}".format(*args))
if __name__ == "__main__":
Contexto(soma, "+").tarefa(22, 3)
ctx = Contexto(subtração, "-")
ctx.tarefa(22, 3)
ctx.estratégia = multiplicação
ctx.símbolo = "*"
ctx.tarefa(22, 3)
if __name__ == "__main__":
Contexto(soma, "+").tarefa(22, 3)
ctx = Contexto(subtração, "-")
ctx.tarefa(22, 3)
ctx.estratégia = multiplicação
ctx.símbolo = "*"
ctx.tarefa(22, 3)
Funções de primeira classe!Funções de primeira classe!
strategy_2.py
●
Funções comoFunções como
valores (ou objetos)valores (ou objetos)
●
““Callback”Callback”
●
““Handler”Handler”
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
PythonPython
lambda e namedtuplelambda e namedtuple
#!/usr/bin/env python3
from collections import namedtuple
Strategy = namedtuple("Strategy", ["func", "symbol"])
sum = lambda a, b: a + b
sub = lambda a, b: a - b
mul = lambda a, b: a * b
apply = lambda st, a, b: st.func(a, b)
strategies = [Strategy(sum, "+"), Strategy(sub, "-"), Strategy(mul, "*")]
for st in strategies:
print("2 %c 3 = %d" % (st.symbol, apply(st, 2, 3)))
print("7 %c 5 = %d" % (st.symbol, apply(st, 7, 5)))
#!/usr/bin/env python3
from collections import namedtuple
Strategy = namedtuple("Strategy", ["func", "symbol"])
sum = lambda a, b: a + b
sub = lambda a, b: a - b
mul = lambda a, b: a * b
apply = lambda st, a, b: st.func(a, b)
strategies = [Strategy(sum, "+"), Strategy(sub, "-"), Strategy(mul, "*")]
for st in strategies:
print("2 %c 3 = %d" % (st.symbol, apply(st, 2, 3)))
print("7 %c 5 = %d" % (st.symbol, apply(st, 7, 5)))
strategy_3.py
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
CC
#include <stdio.h>
typedef int (*BinaryOpPtr)(int, int);
typedef struct{
BinaryOpPtr func;
char symbol;
} Strategy;
int sum(int a, int b){ return a + b; }
int sub(int a, int b){ return a - b; }
int mul(int a, int b){ return a * b; }
int apply(Strategy st, int a, int b){
return st.func(a, b);
}
Strategy strategies[] = {{sum, '+'}, {sub, '-'}, {mul, '*'}};
int main(){
Strategy st;
int idx;
for(idx = 0; idx < 3; idx++){
st = strategies[idx];
printf("2 %c 3 = %dn", st.symbol, apply(st, 2, 3));
printf("7 %c 5 = %dn", st.symbol, apply(st, 7, 5));
}
return 0;
}
#include <stdio.h>
typedef int (*BinaryOpPtr)(int, int);
typedef struct{
BinaryOpPtr func;
char symbol;
} Strategy;
int sum(int a, int b){ return a + b; }
int sub(int a, int b){ return a - b; }
int mul(int a, int b){ return a * b; }
int apply(Strategy st, int a, int b){
return st.func(a, b);
}
Strategy strategies[] = {{sum, '+'}, {sub, '-'}, {mul, '*'}};
int main(){
Strategy st;
int idx;
for(idx = 0; idx < 3; idx++){
st = strategies[idx];
printf("2 %c 3 = %dn", st.symbol, apply(st, 2, 3));
printf("7 %c 5 = %dn", st.symbol, apply(st, 7, 5));
}
return 0;
}
O mesmo
exemplo do
slide
anterior
strategy.c
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
ScipyScipy
(e muitos outros)(e muitos outros)
●
Duas maneiras diferentes de resolver o problema:Duas maneiras diferentes de resolver o problema:
– Diversas funções dispersas com assinatura similar, usar noDiversas funções dispersas com assinatura similar, usar no
contextocontexto
●
e.g. funções do scipy.optimizee.g. funções do scipy.optimize
– String com o nome da estratégia como parâmetroString com o nome da estratégia como parâmetro
●
e.g. projeto de filtros IIR com o scipy.signal.iirdesigne.g. projeto de filtros IIR com o scipy.signal.iirdesign
– ftype = “ellip”ftype = “ellip” → Elíptico→ Elíptico
– ftype = “butter”ftype = “butter” → Butterworth→ Butterworth
– ftype = “cheby1”ftype = “cheby1” → Chebyshev I→ Chebyshev I
– ftype = “cheby2”ftype = “cheby2” → Chebyshev II→ Chebyshev II
– ftype = “bessel”ftype = “bessel” → Bessel→ Bessel
– Saída chaveada pela stringSaída chaveada pela string “ba”“ba” ouou “zpk”“zpk” no parâmetro de entradano parâmetro de entrada outputoutput
Em alguns casos (e.g. fmin), é possível
usar os nomes com o built-in dir para
possíveis consultas
Estratégias existentes
apresentadas em docstring
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
ContextoContexto
●
Completamente aberto, basta que utilize ouCompletamente aberto, basta que utilize ou
possa utilizar a estratégiapossa utilizar a estratégia
– ““Executa o algoritmo”Executa o algoritmo”
●
Outros possíveis requisitos, reflection “CRUD”:Outros possíveis requisitos, reflection “CRUD”:
– Conhecer/consultar todas as estratégiasConhecer/consultar todas as estratégias
– Varrer por todas as estratégiasVarrer por todas as estratégias
– Modificar, remover ou criar novas estratégiasModificar, remover ou criar novas estratégias
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
DicionárioDicionário
(Mapping / Hash / Vetor associativo)(Mapping / Hash / Vetor associativo)
●
Pares chave-valorPares chave-valor
●
Sem “ordenação”Sem “ordenação”
●
VariantesVariantes
– OrderedDictOrderedDict
– defaultdictdefaultdict
●
3 métodos para iterar:3 métodos para iterar:
– Dict.keys()Dict.keys()
– Dict.values()Dict.values()
– Dict.items()Dict.items() → Pares chave, valor→ Pares chave, valor
#!/usr/bin/env python3
strategies = {
"+": lambda a, b: a + b,
"-": lambda a, b: a - b,
"*": lambda a, b: a * b,
}
for key, value in strategies.items():
print("2 %c 3 = %d" % (key, value(2, 3)))
print("7 %c 5 = %d" % (key, value(7, 5)))
#!/usr/bin/env python3
strategies = {
"+": lambda a, b: a + b,
"-": lambda a, b: a - b,
"*": lambda a, b: a * b,
}
for key, value in strategies.items():
print("2 %c 3 = %d" % (key, value(2, 3)))
print("7 %c 5 = %d" % (key, value(7, 5)))
strategy_4.py
No Python 3, devolvem
iteráveis. No Python 2,
devolvem listas, mas os
métodos com prefixo “iter”
(e.g. “dict.iteritems()”)
devolvem iteradores.
Função
(anônima)
como valor
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
E quando o elemento com aE quando o elemento com a
“chave” não está no dicionário?“chave” não está no dicionário?
●
__missing____missing__
– Criar elemento?Criar elemento?
– Responder?Responder?
●
Há análogos:Há análogos:
– __getitem____getitem__
– __getattr____getattr__
#!/usr/bin/env python3
class MeuDicionário(dict):
def __missing__(self, chave):
if chave.strip() != chave:
valor = self[chave.strip()]
self[chave] = valor
return valor
raise KeyError("Not Found")
estratégias = MeuDicionário([
("+", lambda a, b: a + b),
("-", lambda a, b: a - b),
("*", lambda a, b: a * b),
])
for símbolo in ["+", " +", " - ", "n* n"]:
função = estratégias[símbolo]
print("2 %s 3 = %d" % (símbolo, função(2, 3)))
print("7 %s 5 = %d" % (símbolo, função(7, 5)))
print(estratégias["/"])
#!/usr/bin/env python3
class MeuDicionário(dict):
def __missing__(self, chave):
if chave.strip() != chave:
valor = self[chave.strip()]
self[chave] = valor
return valor
raise KeyError("Not Found")
estratégias = MeuDicionário([
("+", lambda a, b: a + b),
("-", lambda a, b: a - b),
("*", lambda a, b: a * b),
])
for símbolo in ["+", " +", " - ", "n* n"]:
função = estratégias[símbolo]
print("2 %s 3 = %d" % (símbolo, função(2, 3)))
print("7 %s 5 = %d" % (símbolo, função(7, 5)))
print(estratégias["/"])
missing.py
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
MultitonMultiton
●
Multi + singletonMulti + singleton
– ““Registro deRegistro de
singletons”singletons”
– LazyLazy
●
Similar aoSimilar ao
dicionáriodicionário
– Valores definidosValores definidos
(ou instanciados)(ou instanciados)
no primeiro usono primeiro uso
●
““Cache”Cache”
#!/usr/bin/env python3
op = {
"+": lambda a, b: a + b,
"-": lambda a, b: a - b,
"*": lambda a, b: a * b,
}
class MeuDicionário(dict):
def __missing__(self, chave):
if chave[0] in op:
b = int(chave[1:])
func = op[chave[0]]
resultado = lambda a: func(a, b)
else:
a = int(chave[:-1])
func = op[chave[-1]]
resultado = lambda b: func(a, b)
self[chave] = resultado
return resultado
estratégias = MeuDicionário()
for símbolo in ["+2", "5-", "-3", "4*", "+2"]:
função = estratégias[símbolo]
print("2, %s -> %d" % (símbolo, função(2)))
print("-1, %s -> %d" % (símbolo, função(-1)))
print("7, %s -> %d" % (símbolo, função(7)))
#!/usr/bin/env python3
op = {
"+": lambda a, b: a + b,
"-": lambda a, b: a - b,
"*": lambda a, b: a * b,
}
class MeuDicionário(dict):
def __missing__(self, chave):
if chave[0] in op:
b = int(chave[1:])
func = op[chave[0]]
resultado = lambda a: func(a, b)
else:
a = int(chave[:-1])
func = op[chave[-1]]
resultado = lambda b: func(a, b)
self[chave] = resultado
return resultado
estratégias = MeuDicionário()
for símbolo in ["+2", "5-", "-3", "4*", "+2"]:
função = estratégias[símbolo]
print("2, %s -> %d" % (símbolo, função(2)))
print("-1, %s -> %d" % (símbolo, função(-1)))
print("7, %s -> %d" % (símbolo, função(7)))
multiton.py
Closure
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
AudioLazyAudioLazy
●
StrategyDict (dicionário de estratégias)StrategyDict (dicionário de estratégias)
– IterávelIterável
●
Padrão por estratégias (valores)Padrão por estratégias (valores)
– Múltiplas chaves (nomes)Múltiplas chaves (nomes)
●
e.g.e.g. window[“rectangular”] is window[“rect”]window[“rectangular”] is window[“rect”] → True→ True
– Acesso como atributosAcesso como atributos
●
e.g.e.g. lowpass.pole_exp(pi/7)lowpass.pole_exp(pi/7)
– Estratégia padrão do dicionárioEstratégia padrão do dicionário
●
Consultável no atributo “default”Consultável no atributo “default”
●
e.g.e.g. lowpass(pi/7)lowpass(pi/7) equivale aequivale a lowpass.pole(pi/7)lowpass.pole(pi/7)
Docstrings com
“resumos”
automáticos das
docstrings das
estratégias
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
Uso da StrategyDict na AudioLazyUso da StrategyDict na AudioLazy
In [1]: import audiolazy
In [2]: from audiolazy import StrategyDict
In [3]: [name for name in dir(audiolazy)
...: if isinstance(getattr(audiolazy, name), StrategyDict)]
Out[3]:
['accumulate',
'almost_eq',
'chain',
'chunks',
'comb',
'envelope',
'erb',
'float_str',
'gammatone',
'highpass',
'izip',
'lagrange',
'lowpass',
'lpc',
'maverage',
'resonator',
'window']
In [4]: len(_) # Total de nomes de instâncias de StrategyDict na AudioLazy
Out[4]: 17
In [5]: len(audiolazy.window) # Todos atualmente com pelo menos 2 estratégias
Out[5]: 6
In [1]: import audiolazy
In [2]: from audiolazy import StrategyDict
In [3]: [name for name in dir(audiolazy)
...: if isinstance(getattr(audiolazy, name), StrategyDict)]
Out[3]:
['accumulate',
'almost_eq',
'chain',
'chunks',
'comb',
'envelope',
'erb',
'float_str',
'gammatone',
'highpass',
'izip',
'lagrange',
'lowpass',
'lpc',
'maverage',
'resonator',
'window']
In [4]: len(_) # Total de nomes de instâncias de StrategyDict na AudioLazy
Out[4]: 17
In [5]: len(audiolazy.window) # Todos atualmente com pelo menos 2 estratégias
Out[5]: 6
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
strategy_sort.py
#!/usr/bin/env python3
from operator import itemgetter
from audiolazy import StrategyDict
sort = StrategyDict("sort")
@sort.strategy("slow", "bad")
def sort(data):
for idx, el in enumerate(data):
idx_min, el_min = min(enumerate(data[idx:], idx), key=itemgetter(1))
data[idx], data[idx_min] = el_min, el
@sort.strategy("bubble")
def sort(data):
. . .
@sort.strategy("merge")
def sort(data):
. . .
#!/usr/bin/env python3
from operator import itemgetter
from audiolazy import StrategyDict
sort = StrategyDict("sort")
@sort.strategy("slow", "bad")
def sort(data):
for idx, el in enumerate(data):
idx_min, el_min = min(enumerate(data[idx:], idx), key=itemgetter(1))
data[idx], data[idx_min] = el_min, el
@sort.strategy("bubble")
def sort(data):
. . .
@sort.strategy("merge")
def sort(data):
. . .
if __name__ == "__main__":
from random import shuffle
data = list(range(30))
print(sort.default.__name__) # slow (primeira)
print()
print(sort.bubble is sort["bubble"]) # True
print()
print(sort) # As 3 estratégias
for st in sort:
print()
shuffle(data)
print(data) # Scrambled
st(data)
print(data) # [0, 1, 2, ...]
if __name__ == "__main__":
from random import shuffle
data = list(range(30))
print(sort.default.__name__) # slow (primeira)
print()
print(sort.bubble is sort["bubble"]) # True
print()
print(sort) # As 3 estratégias
for st in sort:
print()
shuffle(data)
print(data) # Scrambled
st(data)
print(data) # [0, 1, 2, ...]
Contexto
Exemplo: Ordenação com um StrategyDict
● “slow”: Ordenar coletando valores mínimos
● “bubble”: Alone bubble sort
● “merge”: Merge sort
2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini
Fim!Fim!
Obrigado =)
Repositório com o código dos slides:
https://github.com/danilobellini/design_patterns

Mais conteúdo relacionado

Mais procurados

Programando para web com python - Introdução a Python
Programando para web com python - Introdução a PythonProgramando para web com python - Introdução a Python
Programando para web com python - Introdução a PythonAlvaro Oliveira
 
Python: programação divertida novamente
Python: programação divertida novamentePython: programação divertida novamente
Python: programação divertida novamenteRodrigo Amaral
 
Python - Programando em alto nível
Python - Programando em alto nívelPython - Programando em alto nível
Python - Programando em alto nívelIgor Sobreira
 
09 programando em python - classes
 09   programando em python - classes 09   programando em python - classes
09 programando em python - classesVictor Marcelino
 

Mais procurados (9)

Introducao Google GO
Introducao Google GOIntroducao Google GO
Introducao Google GO
 
Ponteiros2
Ponteiros2Ponteiros2
Ponteiros2
 
Dojo de Python
Dojo de PythonDojo de Python
Dojo de Python
 
Aula1
Aula1Aula1
Aula1
 
Programando para web com python - Introdução a Python
Programando para web com python - Introdução a PythonProgramando para web com python - Introdução a Python
Programando para web com python - Introdução a Python
 
Python: programação divertida novamente
Python: programação divertida novamentePython: programação divertida novamente
Python: programação divertida novamente
 
Python - Programando em alto nível
Python - Programando em alto nívelPython - Programando em alto nível
Python - Programando em alto nível
 
09 programando em python - classes
 09   programando em python - classes 09   programando em python - classes
09 programando em python - classes
 
Aula4
Aula4Aula4
Aula4
 

Destaque

From Dot-com-y to Altmami
From Dot-com-y to AltmamiFrom Dot-com-y to Altmami
From Dot-com-y to Altmamigattygirl
 
กิจกรรมการทดลอง
กิจกรรมการทดลองกิจกรรมการทดลอง
กิจกรรมการทดลองtangkwa2
 
GRASP Local Chapters Development Strategy - 10 pasi
GRASP Local Chapters Development Strategy - 10 pasiGRASP Local Chapters Development Strategy - 10 pasi
GRASP Local Chapters Development Strategy - 10 pasiiustiniftime
 
News jan 4 -10
News jan 4 -10News jan 4 -10
News jan 4 -10nuthorn
 
An introductory guide_to_facebook_for_business
An introductory guide_to_facebook_for_businessAn introductory guide_to_facebook_for_business
An introductory guide_to_facebook_for_businessJacques Bouchard
 
Duffy, Daniel J. Current Resume
Duffy, Daniel J. Current ResumeDuffy, Daniel J. Current Resume
Duffy, Daniel J. Current Resumedanduffy49
 
Meclab 夏遊 美食部2
Meclab 夏遊 美食部2Meclab 夏遊 美食部2
Meclab 夏遊 美食部2Badoyau
 
News Mar 30 - Apr 5
News Mar 30 - Apr 5News Mar 30 - Apr 5
News Mar 30 - Apr 5nuthorn
 

Destaque (20)

From Dot-com-y to Altmami
From Dot-com-y to AltmamiFrom Dot-com-y to Altmami
From Dot-com-y to Altmami
 
Tumblr workshop 3
Tumblr workshop 3Tumblr workshop 3
Tumblr workshop 3
 
Buddhism comic
Buddhism comicBuddhism comic
Buddhism comic
 
กิจกรรมการทดลอง
กิจกรรมการทดลองกิจกรรมการทดลอง
กิจกรรมการทดลอง
 
GRASP Local Chapters Development Strategy - 10 pasi
GRASP Local Chapters Development Strategy - 10 pasiGRASP Local Chapters Development Strategy - 10 pasi
GRASP Local Chapters Development Strategy - 10 pasi
 
Jaquelinne yoanna ruizachury_actividad4
Jaquelinne yoanna ruizachury_actividad4Jaquelinne yoanna ruizachury_actividad4
Jaquelinne yoanna ruizachury_actividad4
 
Bliss
BlissBliss
Bliss
 
News jan 4 -10
News jan 4 -10News jan 4 -10
News jan 4 -10
 
Alluvia Specialist Winery
Alluvia Specialist WineryAlluvia Specialist Winery
Alluvia Specialist Winery
 
An introductory guide_to_facebook_for_business
An introductory guide_to_facebook_for_businessAn introductory guide_to_facebook_for_business
An introductory guide_to_facebook_for_business
 
The Importance of Proper Pool Maintenance
The Importance of Proper Pool Maintenance The Importance of Proper Pool Maintenance
The Importance of Proper Pool Maintenance
 
Bar Stock Threaded End Thermowell
Bar Stock Threaded End ThermowellBar Stock Threaded End Thermowell
Bar Stock Threaded End Thermowell
 
Green roof promo 28 02 12
Green roof promo 28 02 12Green roof promo 28 02 12
Green roof promo 28 02 12
 
Babae Ako
Babae AkoBabae Ako
Babae Ako
 
Duffy, Daniel J. Current Resume
Duffy, Daniel J. Current ResumeDuffy, Daniel J. Current Resume
Duffy, Daniel J. Current Resume
 
Hizb 48
Hizb 48Hizb 48
Hizb 48
 
Meclab 夏遊 美食部2
Meclab 夏遊 美食部2Meclab 夏遊 美食部2
Meclab 夏遊 美食部2
 
Mod1
Mod1Mod1
Mod1
 
Love
LoveLove
Love
 
News Mar 30 - Apr 5
News Mar 30 - Apr 5News Mar 30 - Apr 5
News Mar 30 - Apr 5
 

Semelhante a (2014-04-16) [Garoa HC] Strategy

Orientação a Objetos com Python e UML - XIII FGSL
Orientação a Objetos com Python e UML - XIII FGSLOrientação a Objetos com Python e UML - XIII FGSL
Orientação a Objetos com Python e UML - XIII FGSLGeorge Mendonça
 
Visual Studio Summit 2016: C# 7 - Olhando para o futuro
Visual Studio Summit 2016: C# 7 - Olhando para o futuroVisual Studio Summit 2016: C# 7 - Olhando para o futuro
Visual Studio Summit 2016: C# 7 - Olhando para o futuroRogério Moraes de Carvalho
 
Ruby
RubyRuby
Rubybesen
 
http://www.dm.ufscar.br/~waldeck/curso/java/
http://www.dm.ufscar.br/~waldeck/curso/java/http://www.dm.ufscar.br/~waldeck/curso/java/
http://www.dm.ufscar.br/~waldeck/curso/java/Rodrigo Vieira
 
Design de código: princípios e práticas para ter um código sustentável
Design de código: princípios e práticas para ter um código sustentávelDesign de código: princípios e práticas para ter um código sustentável
Design de código: princípios e práticas para ter um código sustentávelAndrews Medina
 
Programando Melhor - Flisol
Programando Melhor - FlisolProgramando Melhor - Flisol
Programando Melhor - FlisolLeonn Leite
 
Palestra python
Palestra pythonPalestra python
Palestra pythonRony Cruch
 
Desenvolvimento Web com PHP - Aula 3
Desenvolvimento Web com PHP - Aula 3Desenvolvimento Web com PHP - Aula 3
Desenvolvimento Web com PHP - Aula 3Thyago Maia
 
Desenvolvendo Extensões PECL
Desenvolvendo Extensões PECLDesenvolvendo Extensões PECL
Desenvolvendo Extensões PECLW3P Projetos Web
 
Python e django na prática
Python e django na práticaPython e django na prática
Python e django na práticaRafael Cassau
 
Conceito de funçao e modularizaçao
Conceito de funçao e modularizaçaoConceito de funçao e modularizaçao
Conceito de funçao e modularizaçaossuserc6132d
 
Aop Aspect J 1.5.4 Capitulo 03
Aop Aspect J 1.5.4 Capitulo 03Aop Aspect J 1.5.4 Capitulo 03
Aop Aspect J 1.5.4 Capitulo 03Diego Pacheco
 
Fundamentos da Programação PHP OO - Aula 2
Fundamentos da Programação PHP OO - Aula 2Fundamentos da Programação PHP OO - Aula 2
Fundamentos da Programação PHP OO - Aula 2Thyago Maia
 
Minicurso Python
Minicurso PythonMinicurso Python
Minicurso Pythonguestac3de
 
Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Luciano Ramalho
 
Aprendizado de Máquina em Linguagem Natural
Aprendizado de Máquina em Linguagem NaturalAprendizado de Máquina em Linguagem Natural
Aprendizado de Máquina em Linguagem NaturalBeatriz Albiero
 

Semelhante a (2014-04-16) [Garoa HC] Strategy (20)

Orientação a Objetos com Python e UML - XIII FGSL
Orientação a Objetos com Python e UML - XIII FGSLOrientação a Objetos com Python e UML - XIII FGSL
Orientação a Objetos com Python e UML - XIII FGSL
 
Visual Studio Summit 2016: C# 7 - Olhando para o futuro
Visual Studio Summit 2016: C# 7 - Olhando para o futuroVisual Studio Summit 2016: C# 7 - Olhando para o futuro
Visual Studio Summit 2016: C# 7 - Olhando para o futuro
 
Meta-programacao em python
Meta-programacao em pythonMeta-programacao em python
Meta-programacao em python
 
Ruby
RubyRuby
Ruby
 
http://www.dm.ufscar.br/~waldeck/curso/java/
http://www.dm.ufscar.br/~waldeck/curso/java/http://www.dm.ufscar.br/~waldeck/curso/java/
http://www.dm.ufscar.br/~waldeck/curso/java/
 
Design de código: princípios e práticas para ter um código sustentável
Design de código: princípios e práticas para ter um código sustentávelDesign de código: princípios e práticas para ter um código sustentável
Design de código: princípios e práticas para ter um código sustentável
 
Workshop Python.2
Workshop Python.2Workshop Python.2
Workshop Python.2
 
Aula python
Aula pythonAula python
Aula python
 
Programando Melhor - Flisol
Programando Melhor - FlisolProgramando Melhor - Flisol
Programando Melhor - Flisol
 
Palestra python
Palestra pythonPalestra python
Palestra python
 
Desenvolvimento Web com PHP - Aula 3
Desenvolvimento Web com PHP - Aula 3Desenvolvimento Web com PHP - Aula 3
Desenvolvimento Web com PHP - Aula 3
 
Desenvolvendo Extensões PECL
Desenvolvendo Extensões PECLDesenvolvendo Extensões PECL
Desenvolvendo Extensões PECL
 
Python e django na prática
Python e django na práticaPython e django na prática
Python e django na prática
 
Conceito de funçao e modularizaçao
Conceito de funçao e modularizaçaoConceito de funçao e modularizaçao
Conceito de funçao e modularizaçao
 
Aop Aspect J 1.5.4 Capitulo 03
Aop Aspect J 1.5.4 Capitulo 03Aop Aspect J 1.5.4 Capitulo 03
Aop Aspect J 1.5.4 Capitulo 03
 
Fundamentos da Programação PHP OO - Aula 2
Fundamentos da Programação PHP OO - Aula 2Fundamentos da Programação PHP OO - Aula 2
Fundamentos da Programação PHP OO - Aula 2
 
Minicurso Python
Minicurso PythonMinicurso Python
Minicurso Python
 
Programando com Python
Programando com PythonProgramando com Python
Programando com Python
 
Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011Jython no JavaOne Latin America 2011
Jython no JavaOne Latin America 2011
 
Aprendizado de Máquina em Linguagem Natural
Aprendizado de Máquina em Linguagem NaturalAprendizado de Máquina em Linguagem Natural
Aprendizado de Máquina em Linguagem Natural
 

Mais de Danilo J. S. Bellini

(2018-10-18) [ETEC Uirapuru] Segurança da Informação
(2018-10-18) [ETEC Uirapuru] Segurança da Informação(2018-10-18) [ETEC Uirapuru] Segurança da Informação
(2018-10-18) [ETEC Uirapuru] Segurança da InformaçãoDanilo J. S. Bellini
 
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask AssíncronoDanilo J. S. Bellini
 
(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!Danilo J. S. Bellini
 
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)Danilo J. S. Bellini
 
(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!Danilo J. S. Bellini
 
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)Danilo J. S. Bellini
 
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0Danilo J. S. Bellini
 
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?Danilo J. S. Bellini
 
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)Danilo J. S. Bellini
 
(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e tox(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e toxDanilo J. S. Bellini
 
(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazy(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazyDanilo J. S. Bellini
 
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!Danilo J. S. Bellini
 
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...Danilo J. S. Bellini
 
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)Danilo J. S. Bellini
 
(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em PythonDanilo J. S. Bellini
 
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...Danilo J. S. Bellini
 
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazyDanilo J. S. Bellini
 
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com PythonDanilo J. S. Bellini
 

Mais de Danilo J. S. Bellini (20)

(2018-10-18) [ETEC Uirapuru] Segurança da Informação
(2018-10-18) [ETEC Uirapuru] Segurança da Informação(2018-10-18) [ETEC Uirapuru] Segurança da Informação
(2018-10-18) [ETEC Uirapuru] Segurança da Informação
 
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
 
(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!
 
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
 
(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!
 
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
 
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
 
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?
(2015-03-14) [Grupy-SP] Projetos Open Source, como colaborar?
 
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
 
(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e tox(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e tox
 
(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazy(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazy
 
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
 
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
 
(2013-12-18) [Garoa HC] AudioLazy
(2013-12-18) [Garoa HC] AudioLazy(2013-12-18) [Garoa HC] AudioLazy
(2013-12-18) [Garoa HC] AudioLazy
 
(2014-03-26) [7masters] AudioLazy
(2014-03-26) [7masters] AudioLazy(2014-03-26) [7masters] AudioLazy
(2014-03-26) [7masters] AudioLazy
 
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
 
(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python
 
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
 
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
 
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
 

(2014-04-16) [Garoa HC] Strategy

  • 1. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini Strategy (Design Pattern)Strategy (Design Pattern) e seu uso com dicionário e Multitone seu uso com dicionário e Multiton Segunda reunião em 2014 do grupo de estudos deSegunda reunião em 2014 do grupo de estudos de Design patterns em linguagens dinâmicasDesign patterns em linguagens dinâmicas nono Garoa Hacker ClubeGaroa Hacker Clube Slides com a preparação deSlides com a preparação de Danilo J. S. BelliniDanilo J. S. Bellini para discussão durante reuniãopara discussão durante reunião 2014-04-162014-04-16 Código dos slides disponível em: https://github.com/danilobellini/design_patterns
  • 2. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini ProblemaProblema ● Muitas soluções para um mesmo problemaMuitas soluções para um mesmo problema – Ordenação (sort), programação não-linear,Ordenação (sort), programação não-linear, reconhecimento de padrões, otimização,reconhecimento de padrões, otimização, processamento de sinais, …processamento de sinais, … – Família de algoritmosFamília de algoritmos ● Decisão em tempo de execução do algoritmo aDecisão em tempo de execução do algoritmo a ser utilizadoser utilizado
  • 3. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini StrategyStrategy ● 3 conceitos:3 conceitos: – InterfaceInterface – EstratégiasEstratégias – Contexto (de uso)Contexto (de uso)
  • 4. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini UML?! Muito chato! Cadê o código?UML?! Muito chato! Cadê o código? Não é nested o suficiente? #!/usr/bin/env python3 from abc import ABCMeta, abstractmethod class Estratégia(metaclass=ABCMeta): @abstractmethod def executar(self, a, b): # Dois inteiros pass class Soma(Estratégia): def executar(self, a, b): return a + b class Subtração(Estratégia): def executar(self, a, b): return a - b class Multiplicação(Estratégia): def executar(self, a, b): return a * b class Contexto: def __init__(self, estratégia, símbolo): self.estratégia = estratégia self.símbolo = símbolo def tarefa(self, a, b): resultado = self.estratégia.executar(a, b) args = (a, self.símbolo, b, resultado) print("{} {} {} = {}".format(*args)) #!/usr/bin/env python3 from abc import ABCMeta, abstractmethod class Estratégia(metaclass=ABCMeta): @abstractmethod def executar(self, a, b): # Dois inteiros pass class Soma(Estratégia): def executar(self, a, b): return a + b class Subtração(Estratégia): def executar(self, a, b): return a - b class Multiplicação(Estratégia): def executar(self, a, b): return a * b class Contexto: def __init__(self, estratégia, símbolo): self.estratégia = estratégia self.símbolo = símbolo def tarefa(self, a, b): resultado = self.estratégia.executar(a, b) args = (a, self.símbolo, b, resultado) print("{} {} {} = {}".format(*args)) if __name__ == "__main__": Contexto(Soma(), "+").tarefa(22, 3) ctx = Contexto(Subtração(), "-") ctx.tarefa(22, 3) ctx.estratégia = Multiplicação() ctx.símbolo = "*" ctx.tarefa(22, 3) if __name__ == "__main__": Contexto(Soma(), "+").tarefa(22, 3) ctx = Contexto(Subtração(), "-") ctx.tarefa(22, 3) ctx.estratégia = Multiplicação() ctx.símbolo = "*" ctx.tarefa(22, 3) strategy_0.py
  • 5. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini Burocracia...é necessária?Burocracia...é necessária? ● Definição de classes para cada algoritmoDefinição de classes para cada algoritmo – Mais de uma instância de um único algoritmo?Mais de uma instância de um único algoritmo? – Memória (efeito colaterais)?Memória (efeito colaterais)? – Instante da instanciação?Instante da instanciação? ● Definição explícita da interfaceDefinição explícita da interface – Tipos estáticos e explícitos?Tipos estáticos e explícitos? – Quantidades/nomes de argumentos sempreQuantidades/nomes de argumentos sempre idênticos?idênticos? ● Orientação a objetos?Orientação a objetos? Não!Não!
  • 6. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini InterfaceInterface em Pythonem Python ● Duck typingDuck typing ““When I see a bird thatWhen I see a bird that ● walks like a duck andwalks like a duck and ● swims like a duck andswims like a duck and ● quacks like a duck,quacks like a duck, I call that bird a duck.”I call that bird a duck.” ● ABC (Abstract Base Classes)ABC (Abstract Base Classes) – Dunder __subclasshook__Dunder __subclasshook__
  • 7. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini #!/usr/bin/env python3 class Soma: def executar(self, a, b): return a + b class Subtração: def executar(self, a, b): return a - b class Multiplicação: def executar(self, a, b): return a * b class Contexto: def __init__(self, estratégia, símbolo): self.estratégia = estratégia self.símbolo = símbolo def tarefa(self, a, b): resultado = self.estratégia.executar(a, b) args = (a, self.símbolo, b, resultado) print("{} {} {} = {}".format(*args)) #!/usr/bin/env python3 class Soma: def executar(self, a, b): return a + b class Subtração: def executar(self, a, b): return a - b class Multiplicação: def executar(self, a, b): return a * b class Contexto: def __init__(self, estratégia, símbolo): self.estratégia = estratégia self.símbolo = símbolo def tarefa(self, a, b): resultado = self.estratégia.executar(a, b) args = (a, self.símbolo, b, resultado) print("{} {} {} = {}".format(*args)) if __name__ == "__main__": Contexto(Soma(), "+").tarefa(22, 3) ctx = Contexto(Subtração(), "-") ctx.tarefa(22, 3) ctx.estratégia = Multiplicação() ctx.símbolo = "*" ctx.tarefa(22, 3) if __name__ == "__main__": Contexto(Soma(), "+").tarefa(22, 3) ctx = Contexto(Subtração(), "-") ctx.tarefa(22, 3) ctx.estratégia = Multiplicação() ctx.símbolo = "*" ctx.tarefa(22, 3) Sem classe abstrataSem classe abstrata (interface implícita)(interface implícita) strategy_1.py
  • 8. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini #!/usr/bin/env python3 from abc import ABCMeta, abstractmethod class Estratégia(metaclass=ABCMeta): @abstractmethod def executar(self, a, b): # Dois inteiros pass @classmethod def __subclasshook__(cls, C): return any("executar" in vars(B) for B in C.mro()) or NotImplemented class Soma: def executar(self, a, b): return a + b print(isinstance(Soma(), Estratégia)) # True print(issubclass(Soma, Estratégia)) # True #!/usr/bin/env python3 from abc import ABCMeta, abstractmethod class Estratégia(metaclass=ABCMeta): @abstractmethod def executar(self, a, b): # Dois inteiros pass @classmethod def __subclasshook__(cls, C): return any("executar" in vars(B) for B in C.mro()) or NotImplemented class Soma: def executar(self, a, b): return a + b print(isinstance(Soma(), Estratégia)) # True print(issubclass(Soma, Estratégia)) # True Subclass HookSubclass Hook subclasshook.py In [5]: B.mro() Out[5]: [__main__.B, __main__.A, builtins.object] In [6]: D.mro() # MRO = Method Resolution Order Out[6]: [__main__.D, __main__.B, __main__.C, __main__.A, builtins.object] In [7]: vars(B) # Atributos (métodos, propriedades, etc.) Out[7]: dict_proxy({'__module__': '__main__', '__doc__': None}) In [5]: B.mro() Out[5]: [__main__.B, __main__.A, builtins.object] In [6]: D.mro() # MRO = Method Resolution Order Out[6]: [__main__.D, __main__.B, __main__.C, __main__.A, builtins.object] In [7]: vars(B) # Atributos (métodos, propriedades, etc.) Out[7]: dict_proxy({'__module__': '__main__', '__doc__': None}) In [1]: class A: pass In [2]: class B(A): pass In [3]: class C(A): pass In [4]: class D(B, C): pass In [1]: class A: pass In [2]: class B(A): pass In [3]: class C(A): pass In [4]: class D(B, C): pass O que é MRO?
  • 9. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini EstratégiaEstratégia ● Qualquer callableQualquer callable – Método, função, __call__, operadores, etc.Método, função, __call__, operadores, etc. ● Funções como objetos de segunda classeFunções como objetos de segunda classe – Utilização do método de um objetosUtilização do método de um objetos – Classes para possibilitar objetosClasses para possibilitar objetos – InstanciaçãoInstanciação ● Python, Ruby, JavaScript, …Python, Ruby, JavaScript, … – Funções de primeira classeFunções de primeira classe – Funções de ordem superiorFunções de ordem superior – Fechamentos (closures)Fechamentos (closures)
  • 10. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini #!/usr/bin/env python3 def soma(a, b): return a + b def subtração(a, b): return a - b def multiplicação(a, b): return a * b class Contexto: def __init__(self, estratégia, símbolo): self.estratégia = estratégia self.símbolo = símbolo def tarefa(self, a, b): resultado = self.estratégia(a, b) args = (a, self.símbolo, b, resultado) print("{} {} {} = {}".format(*args)) #!/usr/bin/env python3 def soma(a, b): return a + b def subtração(a, b): return a - b def multiplicação(a, b): return a * b class Contexto: def __init__(self, estratégia, símbolo): self.estratégia = estratégia self.símbolo = símbolo def tarefa(self, a, b): resultado = self.estratégia(a, b) args = (a, self.símbolo, b, resultado) print("{} {} {} = {}".format(*args)) if __name__ == "__main__": Contexto(soma, "+").tarefa(22, 3) ctx = Contexto(subtração, "-") ctx.tarefa(22, 3) ctx.estratégia = multiplicação ctx.símbolo = "*" ctx.tarefa(22, 3) if __name__ == "__main__": Contexto(soma, "+").tarefa(22, 3) ctx = Contexto(subtração, "-") ctx.tarefa(22, 3) ctx.estratégia = multiplicação ctx.símbolo = "*" ctx.tarefa(22, 3) Funções de primeira classe!Funções de primeira classe! strategy_2.py ● Funções comoFunções como valores (ou objetos)valores (ou objetos) ● ““Callback”Callback” ● ““Handler”Handler”
  • 11. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini PythonPython lambda e namedtuplelambda e namedtuple #!/usr/bin/env python3 from collections import namedtuple Strategy = namedtuple("Strategy", ["func", "symbol"]) sum = lambda a, b: a + b sub = lambda a, b: a - b mul = lambda a, b: a * b apply = lambda st, a, b: st.func(a, b) strategies = [Strategy(sum, "+"), Strategy(sub, "-"), Strategy(mul, "*")] for st in strategies: print("2 %c 3 = %d" % (st.symbol, apply(st, 2, 3))) print("7 %c 5 = %d" % (st.symbol, apply(st, 7, 5))) #!/usr/bin/env python3 from collections import namedtuple Strategy = namedtuple("Strategy", ["func", "symbol"]) sum = lambda a, b: a + b sub = lambda a, b: a - b mul = lambda a, b: a * b apply = lambda st, a, b: st.func(a, b) strategies = [Strategy(sum, "+"), Strategy(sub, "-"), Strategy(mul, "*")] for st in strategies: print("2 %c 3 = %d" % (st.symbol, apply(st, 2, 3))) print("7 %c 5 = %d" % (st.symbol, apply(st, 7, 5))) strategy_3.py
  • 12. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini CC #include <stdio.h> typedef int (*BinaryOpPtr)(int, int); typedef struct{ BinaryOpPtr func; char symbol; } Strategy; int sum(int a, int b){ return a + b; } int sub(int a, int b){ return a - b; } int mul(int a, int b){ return a * b; } int apply(Strategy st, int a, int b){ return st.func(a, b); } Strategy strategies[] = {{sum, '+'}, {sub, '-'}, {mul, '*'}}; int main(){ Strategy st; int idx; for(idx = 0; idx < 3; idx++){ st = strategies[idx]; printf("2 %c 3 = %dn", st.symbol, apply(st, 2, 3)); printf("7 %c 5 = %dn", st.symbol, apply(st, 7, 5)); } return 0; } #include <stdio.h> typedef int (*BinaryOpPtr)(int, int); typedef struct{ BinaryOpPtr func; char symbol; } Strategy; int sum(int a, int b){ return a + b; } int sub(int a, int b){ return a - b; } int mul(int a, int b){ return a * b; } int apply(Strategy st, int a, int b){ return st.func(a, b); } Strategy strategies[] = {{sum, '+'}, {sub, '-'}, {mul, '*'}}; int main(){ Strategy st; int idx; for(idx = 0; idx < 3; idx++){ st = strategies[idx]; printf("2 %c 3 = %dn", st.symbol, apply(st, 2, 3)); printf("7 %c 5 = %dn", st.symbol, apply(st, 7, 5)); } return 0; } O mesmo exemplo do slide anterior strategy.c
  • 13. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini ScipyScipy (e muitos outros)(e muitos outros) ● Duas maneiras diferentes de resolver o problema:Duas maneiras diferentes de resolver o problema: – Diversas funções dispersas com assinatura similar, usar noDiversas funções dispersas com assinatura similar, usar no contextocontexto ● e.g. funções do scipy.optimizee.g. funções do scipy.optimize – String com o nome da estratégia como parâmetroString com o nome da estratégia como parâmetro ● e.g. projeto de filtros IIR com o scipy.signal.iirdesigne.g. projeto de filtros IIR com o scipy.signal.iirdesign – ftype = “ellip”ftype = “ellip” → Elíptico→ Elíptico – ftype = “butter”ftype = “butter” → Butterworth→ Butterworth – ftype = “cheby1”ftype = “cheby1” → Chebyshev I→ Chebyshev I – ftype = “cheby2”ftype = “cheby2” → Chebyshev II→ Chebyshev II – ftype = “bessel”ftype = “bessel” → Bessel→ Bessel – Saída chaveada pela stringSaída chaveada pela string “ba”“ba” ouou “zpk”“zpk” no parâmetro de entradano parâmetro de entrada outputoutput Em alguns casos (e.g. fmin), é possível usar os nomes com o built-in dir para possíveis consultas Estratégias existentes apresentadas em docstring
  • 14. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini ContextoContexto ● Completamente aberto, basta que utilize ouCompletamente aberto, basta que utilize ou possa utilizar a estratégiapossa utilizar a estratégia – ““Executa o algoritmo”Executa o algoritmo” ● Outros possíveis requisitos, reflection “CRUD”:Outros possíveis requisitos, reflection “CRUD”: – Conhecer/consultar todas as estratégiasConhecer/consultar todas as estratégias – Varrer por todas as estratégiasVarrer por todas as estratégias – Modificar, remover ou criar novas estratégiasModificar, remover ou criar novas estratégias
  • 15. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini DicionárioDicionário (Mapping / Hash / Vetor associativo)(Mapping / Hash / Vetor associativo) ● Pares chave-valorPares chave-valor ● Sem “ordenação”Sem “ordenação” ● VariantesVariantes – OrderedDictOrderedDict – defaultdictdefaultdict ● 3 métodos para iterar:3 métodos para iterar: – Dict.keys()Dict.keys() – Dict.values()Dict.values() – Dict.items()Dict.items() → Pares chave, valor→ Pares chave, valor #!/usr/bin/env python3 strategies = { "+": lambda a, b: a + b, "-": lambda a, b: a - b, "*": lambda a, b: a * b, } for key, value in strategies.items(): print("2 %c 3 = %d" % (key, value(2, 3))) print("7 %c 5 = %d" % (key, value(7, 5))) #!/usr/bin/env python3 strategies = { "+": lambda a, b: a + b, "-": lambda a, b: a - b, "*": lambda a, b: a * b, } for key, value in strategies.items(): print("2 %c 3 = %d" % (key, value(2, 3))) print("7 %c 5 = %d" % (key, value(7, 5))) strategy_4.py No Python 3, devolvem iteráveis. No Python 2, devolvem listas, mas os métodos com prefixo “iter” (e.g. “dict.iteritems()”) devolvem iteradores. Função (anônima) como valor
  • 16. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini E quando o elemento com aE quando o elemento com a “chave” não está no dicionário?“chave” não está no dicionário? ● __missing____missing__ – Criar elemento?Criar elemento? – Responder?Responder? ● Há análogos:Há análogos: – __getitem____getitem__ – __getattr____getattr__ #!/usr/bin/env python3 class MeuDicionário(dict): def __missing__(self, chave): if chave.strip() != chave: valor = self[chave.strip()] self[chave] = valor return valor raise KeyError("Not Found") estratégias = MeuDicionário([ ("+", lambda a, b: a + b), ("-", lambda a, b: a - b), ("*", lambda a, b: a * b), ]) for símbolo in ["+", " +", " - ", "n* n"]: função = estratégias[símbolo] print("2 %s 3 = %d" % (símbolo, função(2, 3))) print("7 %s 5 = %d" % (símbolo, função(7, 5))) print(estratégias["/"]) #!/usr/bin/env python3 class MeuDicionário(dict): def __missing__(self, chave): if chave.strip() != chave: valor = self[chave.strip()] self[chave] = valor return valor raise KeyError("Not Found") estratégias = MeuDicionário([ ("+", lambda a, b: a + b), ("-", lambda a, b: a - b), ("*", lambda a, b: a * b), ]) for símbolo in ["+", " +", " - ", "n* n"]: função = estratégias[símbolo] print("2 %s 3 = %d" % (símbolo, função(2, 3))) print("7 %s 5 = %d" % (símbolo, função(7, 5))) print(estratégias["/"]) missing.py
  • 17. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini MultitonMultiton ● Multi + singletonMulti + singleton – ““Registro deRegistro de singletons”singletons” – LazyLazy ● Similar aoSimilar ao dicionáriodicionário – Valores definidosValores definidos (ou instanciados)(ou instanciados) no primeiro usono primeiro uso ● ““Cache”Cache” #!/usr/bin/env python3 op = { "+": lambda a, b: a + b, "-": lambda a, b: a - b, "*": lambda a, b: a * b, } class MeuDicionário(dict): def __missing__(self, chave): if chave[0] in op: b = int(chave[1:]) func = op[chave[0]] resultado = lambda a: func(a, b) else: a = int(chave[:-1]) func = op[chave[-1]] resultado = lambda b: func(a, b) self[chave] = resultado return resultado estratégias = MeuDicionário() for símbolo in ["+2", "5-", "-3", "4*", "+2"]: função = estratégias[símbolo] print("2, %s -> %d" % (símbolo, função(2))) print("-1, %s -> %d" % (símbolo, função(-1))) print("7, %s -> %d" % (símbolo, função(7))) #!/usr/bin/env python3 op = { "+": lambda a, b: a + b, "-": lambda a, b: a - b, "*": lambda a, b: a * b, } class MeuDicionário(dict): def __missing__(self, chave): if chave[0] in op: b = int(chave[1:]) func = op[chave[0]] resultado = lambda a: func(a, b) else: a = int(chave[:-1]) func = op[chave[-1]] resultado = lambda b: func(a, b) self[chave] = resultado return resultado estratégias = MeuDicionário() for símbolo in ["+2", "5-", "-3", "4*", "+2"]: função = estratégias[símbolo] print("2, %s -> %d" % (símbolo, função(2))) print("-1, %s -> %d" % (símbolo, função(-1))) print("7, %s -> %d" % (símbolo, função(7))) multiton.py Closure
  • 18. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini AudioLazyAudioLazy ● StrategyDict (dicionário de estratégias)StrategyDict (dicionário de estratégias) – IterávelIterável ● Padrão por estratégias (valores)Padrão por estratégias (valores) – Múltiplas chaves (nomes)Múltiplas chaves (nomes) ● e.g.e.g. window[“rectangular”] is window[“rect”]window[“rectangular”] is window[“rect”] → True→ True – Acesso como atributosAcesso como atributos ● e.g.e.g. lowpass.pole_exp(pi/7)lowpass.pole_exp(pi/7) – Estratégia padrão do dicionárioEstratégia padrão do dicionário ● Consultável no atributo “default”Consultável no atributo “default” ● e.g.e.g. lowpass(pi/7)lowpass(pi/7) equivale aequivale a lowpass.pole(pi/7)lowpass.pole(pi/7) Docstrings com “resumos” automáticos das docstrings das estratégias
  • 19. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini Uso da StrategyDict na AudioLazyUso da StrategyDict na AudioLazy In [1]: import audiolazy In [2]: from audiolazy import StrategyDict In [3]: [name for name in dir(audiolazy) ...: if isinstance(getattr(audiolazy, name), StrategyDict)] Out[3]: ['accumulate', 'almost_eq', 'chain', 'chunks', 'comb', 'envelope', 'erb', 'float_str', 'gammatone', 'highpass', 'izip', 'lagrange', 'lowpass', 'lpc', 'maverage', 'resonator', 'window'] In [4]: len(_) # Total de nomes de instâncias de StrategyDict na AudioLazy Out[4]: 17 In [5]: len(audiolazy.window) # Todos atualmente com pelo menos 2 estratégias Out[5]: 6 In [1]: import audiolazy In [2]: from audiolazy import StrategyDict In [3]: [name for name in dir(audiolazy) ...: if isinstance(getattr(audiolazy, name), StrategyDict)] Out[3]: ['accumulate', 'almost_eq', 'chain', 'chunks', 'comb', 'envelope', 'erb', 'float_str', 'gammatone', 'highpass', 'izip', 'lagrange', 'lowpass', 'lpc', 'maverage', 'resonator', 'window'] In [4]: len(_) # Total de nomes de instâncias de StrategyDict na AudioLazy Out[4]: 17 In [5]: len(audiolazy.window) # Todos atualmente com pelo menos 2 estratégias Out[5]: 6
  • 20. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini strategy_sort.py #!/usr/bin/env python3 from operator import itemgetter from audiolazy import StrategyDict sort = StrategyDict("sort") @sort.strategy("slow", "bad") def sort(data): for idx, el in enumerate(data): idx_min, el_min = min(enumerate(data[idx:], idx), key=itemgetter(1)) data[idx], data[idx_min] = el_min, el @sort.strategy("bubble") def sort(data): . . . @sort.strategy("merge") def sort(data): . . . #!/usr/bin/env python3 from operator import itemgetter from audiolazy import StrategyDict sort = StrategyDict("sort") @sort.strategy("slow", "bad") def sort(data): for idx, el in enumerate(data): idx_min, el_min = min(enumerate(data[idx:], idx), key=itemgetter(1)) data[idx], data[idx_min] = el_min, el @sort.strategy("bubble") def sort(data): . . . @sort.strategy("merge") def sort(data): . . . if __name__ == "__main__": from random import shuffle data = list(range(30)) print(sort.default.__name__) # slow (primeira) print() print(sort.bubble is sort["bubble"]) # True print() print(sort) # As 3 estratégias for st in sort: print() shuffle(data) print(data) # Scrambled st(data) print(data) # [0, 1, 2, ...] if __name__ == "__main__": from random import shuffle data = list(range(30)) print(sort.default.__name__) # slow (primeira) print() print(sort.bubble is sort["bubble"]) # True print() print(sort) # As 3 estratégias for st in sort: print() shuffle(data) print(data) # Scrambled st(data) print(data) # [0, 1, 2, ...] Contexto Exemplo: Ordenação com um StrategyDict ● “slow”: Ordenar coletando valores mínimos ● “bubble”: Alone bubble sort ● “merge”: Merge sort
  • 21. 2014-04-16 – Strategy – Design patterns em linguagens dinâmicas – Danilo J. S. Bellini Fim!Fim! Obrigado =) Repositório com o código dos slides: https://github.com/danilobellini/design_patterns