Added pick and select for lists
Pick: (1 2 3 4)?4 or (1 2 3 4)?(3 2) Select: (1 2 3 4)~2 or (1 2 3 4)~(2 3)
This commit is contained in:
@ -433,7 +433,7 @@ class RomanNumeral(Event):
|
||||
pitch_classes: list = field(default=None, init=False)
|
||||
inversions: int = field(default=None)
|
||||
evaluated_chord: Chord = None
|
||||
|
||||
|
||||
def set_notes(self, chord_notes: list[int]):
|
||||
"""Set notes to roman numeral
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
from dataclasses import dataclass, field, replace
|
||||
from itertools import product
|
||||
from math import floor
|
||||
import random
|
||||
from types import LambdaType
|
||||
from copy import deepcopy
|
||||
import operator
|
||||
@ -403,6 +404,47 @@ class ListOperation(Sequence):
|
||||
|
||||
return flattened_list
|
||||
|
||||
def _pick_from_list(left, right, options):
|
||||
"""Pick random numbers from a list"""
|
||||
if isinstance(left, Sequence):
|
||||
left = _filter_operation(left, options)
|
||||
|
||||
if isinstance(right, Sequence):
|
||||
right = _filter_operation(right, options)
|
||||
|
||||
if not isinstance(right, (list, Sequence)):
|
||||
right = Sequence(values=[right])
|
||||
|
||||
result = []
|
||||
|
||||
for num in right.values:
|
||||
for _ in range(num.get_value(options)):
|
||||
result.append(random.choice(left.values))
|
||||
return flatten(result)
|
||||
|
||||
|
||||
def _select_from_list(left, right, options):
|
||||
"""Select number of items from shuffled list"""
|
||||
if isinstance(left, Sequence):
|
||||
left = _filter_operation(left, options)
|
||||
|
||||
if isinstance(right, Sequence):
|
||||
right = _filter_operation(right, options)
|
||||
|
||||
if not isinstance(right, (list, Sequence)):
|
||||
right = Sequence(values=[right])
|
||||
|
||||
result = []
|
||||
left = left.values
|
||||
|
||||
for num in right.values:
|
||||
random.shuffle(left)
|
||||
num = num.get_value(options)
|
||||
new_list = [left[i % len(left)] for i in range(num)]
|
||||
result += new_list
|
||||
|
||||
return flatten(result)
|
||||
|
||||
def _vertical_arpeggio(left, right, options):
|
||||
"""Vertical arpeggio operation, eg. (135)@(q 1 2 021)"""
|
||||
left = _filter_operation(left, options)
|
||||
@ -537,8 +579,13 @@ class ListOperation(Sequence):
|
||||
left = _vertical_arpeggio(left, right, options)
|
||||
elif operation == "horizontal":
|
||||
left = _horizontal_arpeggio(left, right, options)
|
||||
if operation == "zip":
|
||||
elif operation == "zip":
|
||||
left = _cyclic_zip(left, right, options)
|
||||
elif operation == "pick":
|
||||
left = _pick_from_list(left, right, options)
|
||||
elif operation == "select":
|
||||
left = _select_from_list(left, right, options)
|
||||
|
||||
else:
|
||||
left = _python_operations(left, right, options)
|
||||
return left
|
||||
|
||||
@ -62,7 +62,9 @@ OPERATORS = MappingProxyType({
|
||||
">>": operator.irshift,
|
||||
"@": "vertical",
|
||||
"#": "horizontal",
|
||||
"<>": "zip"
|
||||
"<>": "zip",
|
||||
"?": "pick",
|
||||
"~": "select"
|
||||
})
|
||||
|
||||
|
||||
|
||||
@ -431,7 +431,7 @@ class ZiffersTransformer(Transformer):
|
||||
def lisp_operation(self, items):
|
||||
"""Parse lisp like list operation"""
|
||||
op = items[0]
|
||||
values = items[1:]
|
||||
values = items[2]
|
||||
return LispOperation(
|
||||
operator=op,
|
||||
values=values,
|
||||
|
||||
@ -73,7 +73,6 @@ def zparse(expr: str, **opts) -> Ziffers:
|
||||
parsed.init_opts(opts)
|
||||
return parsed
|
||||
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
|
||||
|
||||
|
||||
@ -56,8 +56,9 @@
|
||||
right_op: list | number
|
||||
// Operators that work only on lists: | << >>
|
||||
list_operator: /(\||<<|>>|<>|#|@)(?=[(\d])/
|
||||
// /(\||<<|>>|<>|#|@)(?=[(\d])/
|
||||
// Common operators that works with numbers 3+5 3-5 etc.
|
||||
operator: /([\+\-\*\/%\&])/
|
||||
operator: /(\+|-|\*|\/|%|&|\?|~)/
|
||||
|
||||
// Euclidean cycles
|
||||
// TODO: Support randomization etc.
|
||||
@ -66,7 +67,8 @@
|
||||
?euclid_operator: /<[0-9]+,[0-9]+(,[0-9])?>/
|
||||
|
||||
// Lisp like list operation
|
||||
lisp_operation: "(" operator WS sequence ")"
|
||||
lisp_operator: /([\+\-\*\/%\&])/
|
||||
lisp_operation: "(" lisp_operator WS sequence ")"
|
||||
|
||||
// Subdivision
|
||||
subdivision: "[" subitems "]"
|
||||
|
||||
Reference in New Issue
Block a user