Pular para conteúdo

3.1 Métodos do Padrão🔗

Abaixo está uma lista detalhada de métodos com exemplos que podem ser usados com objetos Pattern. Eles são úteis para transformar sequências de valores e podem ser combinados com objetos Player usando o método every (mais informações aqui).

.shuffle(n=1)🔗

Retorna o padrão com seu conteúdo em ordem aleatória e n é o número de permutações:

# Permutação única de embaralhamento
>>> print(P[0, 1, 2, 3].shuffle())
P[0, 3, 2, 1]

# Duas permutações
>>> print(P[0, 1, 2, 3].shuffle(2))
P[3, 1, 2, 0, 2, 1, 3, 0]

.reverse()🔗

Retorna o padrão com seu conteúdo na ordem inversa. Padrões/grupos aninhados não são invertidos. Use Pattern.mirror para obter esse comportamento:

# Inverte a ordem
>>> P[0, 1, 2, 3].reverse()
P[3, 2, 1, 0]

# Padrões aninhados não são invertidos quando usado o "reverse"
>>> P[[0, 4], 3, 2, 1].reverse()
P[1, 2, 3, P[0, 4]]

# Usar o mirror *reverte* o padrão aninhado
>>> P[[0, 4], 3, 2, 1].mirror()
P[1, 2, 3, P[4, 0]]

.mirror()🔗

Retorna um padrão com seu conteúdo na ordem inversa, incluindo padrões e grupos aninhados:

# Inverte a ordem
>>> P[0, 1, 2, 3].mirror()
P[3, 2, 1, 0]

# Inverte padrões e grupos aninhados
>>> P[[0, 1], 2, 3, (4, 5)].mirror()
P[P(5, 4), 3, 2, P[1, 0]]

.sort(*args, **kwargs)🔗

Retorna um padrão com os valores ordenados. Os *args e **kwargs são aqueles fornecidos à função interna sorted do Python, mas esta retorna um Padrão em vez de uma lista.

# Ordenar em ordem crescente
>>> print(P[1, 3, 2, 0].sort())
P[0, 1, 2, 3]

# Ordenar por tamanho do item
>>> print(P[(1, 2), (3,), (4, 5, 6, 7), (8, 9, 10)].sort(key=lambda x: len(x)))
P[P(3), P(1, 2), P(8, 9, 10), P(4, 5, 6, 7)]

.stutter(n=2)🔗

Retorna um novo padrão com cada valor repetido n vezes. Se n for um padrão em si, cada valor será repetido pelo número no mesmo índice no padrão fornecido.

# Repita cada valor 3 vezes
>>> print(P[0, 1, 2, 3].stutter(3))
P[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]

# Repita cada dois valores por 2
>>> print(P[0, 1, 2, 3].stutter([1, 2]))
P[0, 1, 1, 2, 3, 3]

.arp(seq)🔗

Retorna um novo padrão com cada item repetido len(seq) vezes e incrementado pelos valores em seq. Útil para arpejar.

# Repita por 2 e adicione 4 a cada segundo valor
>>> print(P[0, 1, 2, 3].arp([0, 4]))
P[0, 4, 1, 5, 2, 6, 3, 7]

.splice(seq, *seqs)🔗

Pega um ou mais padrões para "emendar" no padrão original. O novo padrão retornado é composto pelos valores do original e das sequências fornecidas de forma alternada.

# Alternando entre duas sequências
>>> print(P[0, 1, 2, 3].splice([4, 5, 6, 7]))
P[0, 4, 1, 5, 2, 6, 3, 7]

# Alternando entre três sequências
>>> print(P[0, 2, 4].splice([1, 3, 5], [6, 7, 8]))
P[0, 1, 6, 2, 3, 7, 4, 5, 8]

.invert()🔗

Cria uma versão invertida do padrão subtraindo seus valores do maior valor do padrão, de modo que o maior valor do padrão se torne o menor (e vice-versa) e a diferença entre os outros valores e o mínimo/máximo seja trocada:

>>> print(P[2, 5, 1, 11].invert())
P[9.0, 6.0, 10.0, 0.0]

# Inverter uma sequência linear apenas a reverterá
>>> print(P[0, 1, 2, 3].invert())
P[3.0, 2.0, 1.0, 0.0]

.shufflets(n=4)🔗

Retorna um novo padrão que contém o padrão original como um PGroup em ordem aleatória de comprimento n.

>>> print(P[0, 1, 2, 3].shufflets(3))
P[P(2, 3, 1, 0), P(3, 2, 0, 1), P(2, 1, 0, 3)]

.pivot(i)🔗

Retorna um novo padrão que é uma versão invertida do original, mas girado de forma que o elemento no índice i permaneça no mesmo lugar.

# O pivô em 2 manterá o item do meio no mesmo lugar
>>> print(P[5, 1, 6, 2, 3].pivot(2))
P[3, 2, 6, 1, 5]

.accum(n=None)🔗

Retorna um padrão equivalente à lista de somas desse padrão até esse índice (o primeiro valor é sempre 0). O parâmetro n especifica o comprimento do novo padrão. Quando n é None, o novo padrão assume o comprimento do original.

# Acumulação de uma série de valores
>>> print(P[1, 2, 3, 4].accum())
P[0, 1, 3, 6]

# O novo valor pode ser mais longo do que o original
>>> print(P[1, 2, 3, 4].accum(8))
P[0, 1, 3, 6, 10, 11, 13, 16]

.stretch(size)🔗

Retorna um padrão que é repetido até que o comprimento seja igual ao tamanho.

# Estique o padrão
>>> print(P[1, 2, 3, 4].stretch(6))
P[1, 2, 3, 4, 1, 2]

# O tamanho pode ser menor do que o comprimento do original
>>> print(P[1, 2, 3, 4].stretch(3))
P[1, 2, 3]

.trim(size)🔗

Como o stretch, mas o comprimento não pode exceder o comprimento do padrão original.

# Aparar o padrão no comprimento 3
>>> print(P[1, 2, 3, 4, 5].trim(3))
P[1, 2, 3]

# Valores para tamanhos maiores que o comprimento são ignorados
>>> print(P[1, 2, 3, 4, 5].trim(10))
P[1, 2, 3, 4, 5]

.ltrim(size)🔗

Semelhante ao trim, mas remove itens do início do padrão, e não do final.

>>> print(P[1, 2, 3, 4, 5].ltrim(3))
P[3, 4, 5]

.loop(n, func=None)🔗

Repete o padrão n vezes. Útil ao encadear vários padrões. Os padrões aninhados são levados em consideração ao fazer o loop. Uma função pode ser fornecida como o parâmetro secundário opcional, que será aplicado aos valores nos loops subsequentes.

# Repita o padrão duas vezes
>>> print(P[0, 1, 2, 3].loop(2))
P[0, 1, 2, 3, 0, 1, 2, 3]

# Repita duas vezes e encadeie com outro padrão
>>> print(P[0, 1, 2].loop(2) | P[7, 6])
P[0, 1, 2, 0, 1, 2, 7, 6]

# loop com padrões aninhados expande os aninhamentos
>>> print(P[0, [1, 2]].loop(2))
P[0, 1, 0, 2, 0, 1, 0, 2]

# Repita o padrão três vezes e adicione 7 aos loops
>>> print(P[0, 1, 2].loop(3, lambda x: x + 7))
P[0, 1, 2, 7, 8, 9, 14, 15, 16]

.duplicate(n)🔗

Semelhante ao loop, mas mantém os padrões aninhados, de modo que o primeiro valor nos aninhamentos é usado na primeira iteração pela sequência duplicada, etc.

# Manter valores aninhados ao duplicar
>>> print(P[0, [1, 2]].duplicate(2))
P[0, P[1, 2], 0, P[1, 2]]

.iter(n)🔗

Semelhante a loop, mas não leva em consideração padrões aninhados ao calcular o comprimento.

>>> print(P[0, [1, 2]].iter(2))
P[0, 1, 0, 2]

.swap(n)🔗

Troca os lugares dos valores no padrão. Quando n é 2, os valores próximos uns dos outros são trocados; quando n é 3, os valores próximos, exceto 1, são trocados, e assim por diante.

# Trocar valores próximos uns dos outros
>>> print(P[0, 1, 2, 3].swap(2))
P[1, 0, 3, 2]

# Troque valores separados por um passo
>>> print(P[0, 1, 2, 3, 4, 5].swap(3))
P[2, 1, 0, 5, 4, 3]

.rotate(n)🔗

Retorna um padrão com os valores do padrão original deslocados para a esquerda em ordem por n número de posições. Números negativos deslocam os valores para a direita.

# Girar 1 para a esquerda
>>> print(P[0, 1, 2, 3].rotate(1))
P[1, 2, 3, 0]

# Girar 1 para a dreita
>>> print(P[0, 1, 2, 3].rotate(-1))
P[3, 0, 1, 2]

.sample(n)🔗

Retorna um padrão de comprimento n com valores selecionados aleatoriamente do padrão original.

>>> print(P[0, 1, 2, 3].sample(3))
P[3, 2, 0]

.palindrome()🔗

Adiciona o inverso de um padrão a si mesmo, de modo a criar um palíndromo de números.

>>> print(P[0, 1, 2, 3].palindrome())
P[0, 1, 2, 3, 3, 2, 1, 0]

.alt(seq)🔗

Substitui o padrão pelo padrão seq. Útil se você quiser usar um padrão alternativo e atribuí-lo usando o método every.

# Substitui o padrão
>>> print(P[0, 1, 2, 3].alt([4, 5]))
P[4, 5]

# Útil quando usado com um Player
>>> p1 >> pads([0, 1, 2, 3]).every(6, "alt", P[4, 5, 6, 7])

.norm()🔗

Retorna um padrão com todos os valores normalizados, de modo que cada valor no novo padrão esteja entre 0 e 1.

>>> print(P[0, 1, 2, 3].norm())
P[0.0, 0.3333333333333333, 0.6666666666666666, 1.0]

.undup()🔗

Remove quaisquer valores duplicados consecutivos para que não haja valores repetidos no padrão.

>>> print(P[0, 1, 1, 1, 2, 2, 3].undup())
P[0, 1, 2, 3]

.limit(func, value)🔗

Retorna um novo padrão gerado pela adição de valores do original até que func(pattern) exceda o valor. O parâmetro func deve ser uma função válida, como len ou sum.

# Crie um padrão cuja soma não seja maior que 7
>>> print(P[0, 1, 2, 3].limit(sum, 7))
P[0, 1, 2, 3, 0, 1]

.replace(sub, repl)🔗

Retorna um novo padrão com valores iguais a sub substituídos por repl.

# Substitui os valores 0 por 4
>>> print(P[0, 1, 2, 3].replace(0, 4))
P[4, 1, 2, 3]

# Também substitui valores em grupos e padrões aninhados
>>> print(P[0, (1, 0), 2, [3, 0]].replace(0, 4))
P[4, P(1, 4), 2, P[3, 4]]

.submap(mapping)🔗

Semelhante ao replace, mas aceita um dicionário de valores sub para repl para substituir vários itens.

# Substitua 0 por 4 e 1 por 5
>>> print(P[0, 1, 2, 3].submap({0: 4, 1: 5}))
P[4, 5, 2, 3]

# Também funciona com valores aninhados, etc
>>> print(P[0, (1, 0), 2, [3, 0]].submap({0: 4, 1: 5}))
P[4, P(5, 4), 2, P[3, 4]]

.layer(method, *args, **kwargs)🔗

Zipa o padrão original consigo mesmo, mas com o method chamado sobre si mesmo, que pode ser um nome de string de um método de padrão válido (semelhante a Player.every) ou uma função válida (veja o exemplo abaixo).

# Padrão zippado com seu reverso
>>> print(P[0, 1, 2, 3].layer("reverse"))
P[P(0, 3), P(1, 2), P(2, 1), P(3, 0)]

# Padrão compactado com swap(2) chamado nele
>>> print(P[0, 1, 2, 3].layer("swap", 2))
P[P(0, 1), P(1, 0), P(2, 3), P(3, 2)]

# Zipado com uma função que multiplica os valores por 2
>>> print(P[0, 1, 2, 3].layer(lambda x: x + 2 ))
P[P(0, 2), P(1, 3), P(2, 4), P(3, 5)]

# Isso é equivalente ao seguinte:
>>> print(P[0, 1, 2, 3].layer("__add__", 2))
P[P(0, 2), P(1, 3), P(2, 4), P(3, 5)]

.every(n, method, *args, **kwargs)🔗

Repete o padrão original n vezes e aplica o método Pattern (especificado como uma string) na última repetição com args e kwargs fornecidos.

# Inverta o padrão na terceira repetição
>>> print(P[0, 1, 2, 3].every(3, "mirror"))
P[0, 1, 2, 3, 0, 1, 2, 3, 3, 2, 1, 0]

.map(callable)🔗

Retorna um novo Padrão com o parâmetro callable chamado em cada item do padrão.

# Defina todos os números pares como 0
>>> print(P[0, 1, 2, 3].map(lambda x: 0 if x % 2 == 0 else x))
P[0, 1, 0, 3]

.extend(seq)🔗

Estende o padrão com seq no lugar, ou seja, retorna None em vez de um novo padrão. Isso é mais eficiente do que o método concat para combinar várias sequências em um único padrão.

>>> pat = P[0, 1, 2, 3]
>>> pat.extend([4, (5, 6), 7])
>>> print(pat)
P[0, 1, 2, 3, 4, P(5, 6), 7]

.concat(seq)🔗

Retorna um novo padrão com o conteúdo de seq adicionado ao final do padrão original. O método especial __or__ (que usa a sintaxe |) também chama esse método.

# Estas duas linhas são equivalentes
>>> print(P[0, 1, 2, 3].concat([4, 5, 6]))
P[0, 1, 2, 3, 4, 5, 6]
>>> print(P[0, 1, 2, 3] | [4, 5, 6])
P[0, 1, 2, 3, 4, 5, 6]

Isso é útil para combinar vários padrões dentro de um objeto Player, mas não é uma maneira eficiente de criar padrões grandes usando um loop. Experimente executar os dois blocos de código e veja a diferença.

# Isso não é eficiente
pat = P[0, 1, 2]
for n in range(20000):
    pat = pat | [0, 1, 2]
print(pat)

# Isso é eficiente
pat = P[0, 1, 2]
for n in range(20000):
    pat.extend([0,1,2])
print(pat)

.zip(seq)🔗

"Zipping" é o processo de combinar duas sequências em uma, em que cada elemento é um grupo que contém os itens de cada sequência no mesmo índice. Se as sequências tiverem comprimentos diferentes, elas serão compactadas até o comprimento do menor múltiplo comum de ambos os comprimentos.

>>> print(P[0, 1, 2, 3].zip([4, 5]))
P[P(0, 4), P(1, 5), P(2, 4), P(3, 5)]

.offadd(value, dur=0.5)🔗

Adiciona valor ao padrão, zipada com o original e atrasa o valor compactado por dur usando a classe PGroupPrime.

>>> print(P[0, 1, 2, 3].offadd(2, 0.5))
P[P^(0, 2), P^(1, 3), P^(2, 4), P^(3, 5)]

.offmul(value, dur=0.5)🔗

Semelhante a offadd, mas multiplica os valores em vez de somá-los.

>>> print(P[0, 1, 2, 3].offmul(2, 0.5))
P[P^(0, 0), P^(1, 2), P^(2, 4), P^(3, 6)]

.offlayer(method, dur=0.5, *args, **kwargs)🔗

Semelhante a offadd e offmul, mas usa um método ou função especificado pelo usuário em vez de adição/multiplicação. O parâmetro method deve ser um nome válido de um método Pattern como uma string ou um objeto chamável, como uma função. Qualquer parâmetro extras ou parâmetro nomeado são fornecidos após a duração para atrasar a camada; portanto, uma duração deve ser fornecida se os argumentos forem fornecidos como parte de *args.

# Camada com o método "rotate" com valores padrão
>>> print(P[0, 1, 2, 3].offlayer("rotate"))
P[P^(0, 1), P^(1, 2), P^(2, 3), P^(3, 0)]

# O seguinte não se sobrepõe com .rotate(2), mas com dur = 2
>>> print(P[0, 1, 2, 3].offlayer("rotate", 2))
P[P^(0, 1), P^(1, 2), P^(2, 3), P^(3, 0)]

# A duração deve ser especificada para fornecer 2 para rodar
>>> print(P[0, 1, 2, 3].offlayer("rotate", 0.5, 2))
P[P^(0, 2), P^(1, 3), P^(2, 0), P^(3, 1)

# Também é possível usar funções em vez de nomes de métodos
>>> print(P[0, 1, 2, 3].offlayer(lambda x: (x * 2) + 1))
P[P^(0, 1), P^(1, 3), P^(2, 5), P^(3, 7)]

.amen()🔗

Reproduz o ritmo e a ordem do famoso amen break com base em uma sequência de bumbo, chimbal, caixa e chimbal. Ouça o exemplo abaixo:

p1 >> play("x-o-").every(8, "amen")