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.
.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.
.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.
.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.
.palindrome()🔗
Adiciona o inverso de um padrão a si mesmo, de modo a criar um palíndromo de números.
.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.
.undup()🔗
Remove quaisquer valores duplicados consecutivos para que não haja valores repetidos no padrão.
.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.
.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.
.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.
.offmul(value, dur=0.5)🔗
Semelhante a offadd, mas multiplica os valores em vez de somá-los.
.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: