import collections
import itertools
import typing
from . import _getlib, _iterlib, _updatelib
from . import cyclictuple as _cyclictuple
from . import duration as _duration
from . import enums as _enums
from . import iterate as _iterate
from . import math as _math
from . import parentage as _parentage
from . import pattern as _pattern
from . import pcollections as _pcollections
from . import score as _score
from . import sequence as _sequence
from . import typings as _typings
def _head_filter_subresult(result, head):
result_ = []
for item in result:
if isinstance(item, _score.Component):
leaves = _iterlib._get_logical_tie_leaves(item)
if head == (item is leaves[0]):
result_.append(item)
else:
pass
else:
if not all(isinstance(_, _score.Component) for _ in item):
raise NotImplementedError(item)
selection = []
for component in item:
leaves = _iterlib._get_logical_tie_leaves(component)
if head == leaves[0]:
selection.append(item)
else:
pass
result_.append(selection)
assert isinstance(result_, list), repr(result_)
return result_
def _is_immediate_child_of_outermost_voice(component):
parentage = _parentage.Parentage(component)
context = parentage.get(_score.Voice, -1) or parentage.get(_score.Context)
if context is not None:
return parentage.component._parent is context
return None
def _tail_filter_subresult(result, tail):
result_ = []
for item in result:
if isinstance(item, _score.Component):
leaves = _iterlib._get_logical_tie_leaves(item)
if tail == (item is leaves[-1]):
result_.append(item)
else:
pass
else:
if not all(isinstance(_, _score.Component) for _ in item):
raise NotImplementedError(item)
selection = []
for component in item:
leaves = _iterlib._get_logical_tie_leaves(component)
if tail == leaves[-1]:
selection.append(item)
else:
pass
result_.append(selection)
assert isinstance(result_, list), repr(result_)
return result_
def _trim_subresult(result, trim):
assert trim in (True, _enums.LEFT)
prototype = (_score.MultimeasureRest, _score.Rest, _score.Skip)
result_ = []
found_good_component = False
for item in result:
if isinstance(item, _score.Component):
if not isinstance(item, prototype):
found_good_component = True
else:
if not all(isinstance(_, _score.Component) for _ in item):
raise NotImplementedError(item)
selection = []
for component in item:
if not isinstance(component, prototype):
found_good_component = True
if found_good_component:
selection.append(component)
item = selection
if found_good_component:
result_.append(item)
if trim is _enums.LEFT:
result = result_
else:
result__ = []
found_good_component = False
for item in reversed(result_):
if isinstance(item, _score.Component):
if not isinstance(item, prototype):
found_good_component = True
else:
if not all(isinstance(_, _score.Component) for _ in item):
raise NotImplementedError(item)
selection = []
for component in reversed(item):
if not isinstance(component, prototype):
found_good_component = True
if found_good_component:
selection.insert(0, component)
item = selection
if found_good_component:
result__.insert(0, item)
assert isinstance(result__, list), repr(result__)
result = result__
return result
[docs]class LogicalTie(collections.abc.Sequence):
"""
Logical tie of a component.
.. container:: example
>>> staff = abjad.Staff("c' d' e' ~ e'")
>>> abjad.show(staff) # doctest: +SKIP
>>> abjad.select.logical_tie(staff[2])
LogicalTie(items=[Note("e'4"), Note("e'4")])
"""
__slots__ = ("_items",)
def __init__(self, items=None):
if items is None:
items = []
if isinstance(items, _score.Component):
items = [items]
items = tuple(items)
for item in items:
if not isinstance(item, _score.Component):
raise Exception("components only:\n {items!r}")
self._items = tuple(items)
[docs] def __contains__(self, argument) -> bool:
"""
Is true when ``argument`` is in selection.
"""
return argument in self.items
[docs] def __eq__(self, argument) -> bool:
"""
Is true when selection and ``argument`` are of the same type
and when items in selection equal item in ``argument``.
"""
if isinstance(argument, type(self)):
return self.items == argument.items
elif isinstance(argument, collections.abc.Sequence):
return self.items == tuple(argument)
return False
[docs] def __hash__(self) -> int:
"""
Hashes selection.
"""
return id(self)
[docs] def __len__(self) -> int:
"""
Gets number of items in selection.
"""
return len(self.items)
[docs] def __repr__(self) -> str:
"""
Gets interpreter representation of selection.
"""
return f"{type(self).__name__}(items={list(self.items)!r})"
[docs] def __getitem__(self, argument):
"""
Gets ``argument``.
Returns component or list (not logical tie).
"""
result = self.items.__getitem__(argument)
if isinstance(result, tuple):
result = list(result)
return result
def _scale(self, multiplier):
for leaf in list(self):
leaf._scale(multiplier)
@property
def head(self) -> _score.Leaf:
"""
Reference to element ``0`` in logical tie.
"""
assert self.items
return self.items[0]
@property
def items(self) -> tuple:
"""
Gets items in selection.
"""
return self._items
@property
def is_pitched(self) -> bool:
"""
Is true when logical tie head is a note or chord.
"""
return hasattr(self.head, "written_pitch") or hasattr(
self.head, "written_pitches"
)
@property
def is_trivial(self) -> bool:
"""
Is true when length of logical tie is less than or equal to ``1``.
"""
return len(self) <= 1
@property
def tail(self) -> _score.Leaf:
"""
Gets last leaf in logical tie.
"""
assert self.items
return self.items[-1]
@property
def written_duration(self) -> _duration.Duration:
"""
Sum of written duration of all components in logical tie.
"""
return _duration.Duration(sum([_.written_duration for _ in self]))
[docs]def chord(
argument,
n: int,
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
) -> _score.Chord:
r"""
Selects chord ``n`` in ``argument``.
Selects chord -1:
.. container:: example
>>> tuplets = [
... "r16 bf'16 <a'' b''>16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 bf'16 <a'' b''>16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 bf'16 <a'' b''>16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.chord(staff, -1)
>>> result
Chord("<fs' gs'>16")
>>> abjad.label.by_selector(result, lone=True)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\time 7/4
r16
bf'16
<a'' b''>16
c'16
<d' e'>4
~
<d' e'>16
}
\times 8/9
{
r16
bf'16
<a'' b''>16
d'16
<e' fs'>4
~
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
r16
bf'16
<a'' b''>16
e'16
<fs' gs'>4
~
\abjad-color-music #'green
<fs' gs'>16
}
}
}
}
"""
return chords(argument, exclude=exclude, grace=grace)[n]
[docs]def chords(
argument, *, exclude: _typings.Exclude | None = None, grace: bool | None = None
) -> list[_score.Chord]:
r"""
Selects chords in ``argument``.
Selects chords:
.. container:: example
>>> tuplets = [
... "r16 bf'16 <a'' b''>16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 bf'16 <a'' b''>16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 bf'16 <a'' b''>16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.chords(staff)
>>> for item in result:
... item
...
Chord("<a'' b''>16")
Chord("<d' e'>4")
Chord("<d' e'>16")
Chord("<a'' b''>16")
Chord("<e' fs'>4")
Chord("<e' fs'>16")
Chord("<a'' b''>16")
Chord("<fs' gs'>4")
Chord("<fs' gs'>16")
>>> abjad.label.by_selector(result, True)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\time 7/4
r16
bf'16
\abjad-color-music #'red
<a'' b''>16
c'16
\abjad-color-music #'blue
<d' e'>4
~
\abjad-color-music #'red
<d' e'>16
}
\times 8/9
{
r16
bf'16
\abjad-color-music #'blue
<a'' b''>16
d'16
\abjad-color-music #'red
<e' fs'>4
~
\abjad-color-music #'blue
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
r16
bf'16
\abjad-color-music #'red
<a'' b''>16
e'16
\abjad-color-music #'blue
<fs' gs'>4
~
\abjad-color-music #'red
<fs' gs'>16
}
}
}
}
"""
items = []
prototype = _score.Chord
for item in components(argument, prototype=prototype, exclude=exclude, grace=grace):
assert isinstance(item, prototype)
items.append(item)
return items
[docs]def components(
argument,
prototype=None,
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
reverse: bool | None = None,
) -> list[_score.Component]:
r"""
Selects components.
Selects notes:
.. container:: example
>>> staff = abjad.Staff("c'4 d'8 ~ d'16 e'16 ~ e'8 r4 g'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.components(staff, abjad.Note)
>>> for item in result:
... item
...
Note("c'4")
Note("d'8")
Note("d'16")
Note("e'16")
Note("e'8")
Note("g'8")
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'4
\abjad-color-music #'blue
d'8
~
\abjad-color-music #'red
d'16
\abjad-color-music #'blue
e'16
~
\abjad-color-music #'red
e'8
r4
\abjad-color-music #'blue
g'8
}
.. container:: example
Selects both main notes and graces when ``grace=None``:
>>> staff = abjad.Staff("c'8 d'8 e'8 f'8")
>>> container = abjad.BeforeGraceContainer("cf''16 bf'16")
>>> abjad.attach(container, staff[1])
>>> container = abjad.AfterGraceContainer("af'16 gf'16")
>>> abjad.attach(container, staff[1])
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.components(staff, abjad.Leaf, grace=None)
>>> for item in result:
... item
...
Note("c'8")
Note("cf''16")
Note("bf'16")
Note("d'8")
Note("af'16")
Note("gf'16")
Note("e'8")
Note("f'8")
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\grace {
\abjad-color-music #'blue
cf''16
\abjad-color-music #'red
bf'16
}
\abjad-color-music #'blue
\afterGrace
d'8
{
\abjad-color-music #'red
af'16
\abjad-color-music #'blue
gf'16
}
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
f'8
}
.. container:: example
Excludes grace notes when ``grace=False``:
>>> staff = abjad.Staff("c'8 d'8 e'8 f'8")
>>> container = abjad.BeforeGraceContainer("cf''16 bf'16")
>>> abjad.attach(container, staff[1])
>>> container = abjad.AfterGraceContainer("af'16 gf'16")
>>> abjad.attach(container, staff[1])
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.components(staff, abjad.Leaf, grace=False)
>>> for item in result:
... item
...
Note("c'8")
Note("d'8")
Note("e'8")
Note("f'8")
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\grace {
cf''16
bf'16
}
\abjad-color-music #'blue
\afterGrace
d'8
{
af'16
gf'16
}
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
f'8
}
.. container:: example
Selects only grace notes when ``grace=True``:
>>> staff = abjad.Staff("c'8 d'8 e'8 f'8")
>>> container = abjad.BeforeGraceContainer("cf''16 bf'16")
>>> abjad.attach(container, staff[1])
>>> container = abjad.AfterGraceContainer("af'16 gf'16")
>>> abjad.attach(container, staff[1])
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.components(staff, abjad.Leaf, grace=True)
>>> for item in result:
... item
...
Note("cf''16")
Note("bf'16")
Note("af'16")
Note("gf'16")
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
c'8
\grace {
\abjad-color-music #'red
cf''16
\abjad-color-music #'blue
bf'16
}
\afterGrace
d'8
{
\abjad-color-music #'red
af'16
\abjad-color-music #'blue
gf'16
}
e'8
f'8
}
"""
generator = _iterlib._public_iterate_components(
argument, prototype=prototype, exclude=exclude, grace=grace, reverse=reverse
)
return list(generator)
[docs]def exclude(argument, indices: typing.Sequence[int], period: int | None = None) -> list:
r"""
Excludes items at ``indices`` by ``period``.
Excludes every other leaf:
.. container:: example
>>> string = r"c'8 d'8 ~ d'8 e'8 ~ e'8 ~ e'8 r8 f'8"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.exclude(result, [0], 2)
>>> for item in result:
... item
...
Note("d'8")
Note("e'8")
Note("e'8")
Note("f'8")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
c'8
\abjad-color-music #'red
d'8
~
d'8
\abjad-color-music #'blue
e'8
~
e'8
~
\abjad-color-music #'red
e'8
r8
\abjad-color-music #'blue
f'8
}
.. container:: example
Excludes every other logical tie:
>>> string = r"c'8 d'8 ~ d'8 e'8 ~ e'8 ~ e'8 r8 f'8"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff, pitched=True)
>>> result = abjad.select.exclude(result, [0], 2)
>>> for item in result:
... item
...
LogicalTie(items=[Note("d'8"), Note("d'8")])
LogicalTie(items=[Note("f'8")])
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
c'8
\abjad-color-music #'red
d'8
~
\abjad-color-music #'red
d'8
e'8
~
e'8
~
e'8
r8
\abjad-color-music #'blue
f'8
}
.. container:: example
Excludes note 1 (or nothing) in each pitched logical tie:
>>> staff = abjad.Staff(r"c'8 d'8 ~ d'8 e'8 ~ e'8 ~ e'8 r8 f'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff, pitched=True)
>>> result = [abjad.select.leaves(_) for _ in result]
>>> result = [abjad.select.exclude(_, [1]) for _ in result]
>>> for item in result:
... item
...
[Note("c'8")]
[Note("d'8")]
[Note("e'8"), Note("e'8")]
[Note("f'8")]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'blue
d'8
~
d'8
\abjad-color-music #'red
e'8
~
e'8
~
\abjad-color-music #'red
e'8
r8
\abjad-color-music #'blue
f'8
}
"""
pattern = _pattern.Pattern(indices, period=period, inverted=True)
items = _sequence.retain_pattern(argument, pattern)
return list(items)
[docs]def filter(argument, predicate=None) -> list:
r"""
Filters ``argument`` by ``predicate``.
Selects runs with duration equal to 2/8:
.. container:: example
>>> staff = abjad.Staff("c'8 r8 d'8 e'8 r8 f'8 g'8 a'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.runs(staff)
>>> result = abjad.select.filter(
... result, lambda _ : abjad.get.duration(_) == abjad.Duration((2, 8))
... )
>>> for item in result:
... item
...
[Note("d'8"), Note("e'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
c'8
r8
\abjad-color-music #'red
d'8
\abjad-color-music #'red
e'8
r8
f'8
g'8
a'8
}
"""
if predicate is None:
return list(argument)
items = [_ for _ in argument if predicate(_)]
return items
[docs]def flatten(argument, depth: int = 1) -> list:
r"""
Flattens ``argument``.
Selects first two leaves of each tuplet:
.. container:: example
>>> tuplets = [
... "r16 bf'16 <a'' b''>16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 bf'16 <a'' b''>16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 bf'16 <a'' b''>16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.tuplets(staff)
>>> result = [abjad.select.leaves(_)[:2] for _ in result]
>>> for item in result:
... item
[Rest('r16'), Note("bf'16")]
[Rest('r16'), Note("bf'16")]
[Rest('r16'), Note("bf'16")]
>>> abjad.label.by_selector(result, True)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\abjad-color-music #'red
\time 7/4
r16
\abjad-color-music #'red
bf'16
<a'' b''>16
c'16
<d' e'>4
~
<d' e'>16
}
\times 8/9
{
\abjad-color-music #'blue
r16
\abjad-color-music #'blue
bf'16
<a'' b''>16
d'16
<e' fs'>4
~
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\abjad-color-music #'red
r16
\abjad-color-music #'red
bf'16
<a'' b''>16
e'16
<fs' gs'>4
~
<fs' gs'>16
}
}
}
}
.. container:: example
Selects first two leaves of all tuplets:
>>> tuplets = [
... "r16 bf'16 <a'' b''>16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 bf'16 <a'' b''>16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 bf'16 <a'' b''>16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.tuplets(staff)
>>> result = [abjad.select.leaves(_)[:2] for _ in result]
>>> result = abjad.select.flatten(result)
>>> for item in result:
... item
Rest('r16')
Note("bf'16")
Rest('r16')
Note("bf'16")
Rest('r16')
Note("bf'16")
>>> abjad.label.by_selector(result, True)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\abjad-color-music #'red
\time 7/4
r16
\abjad-color-music #'blue
bf'16
<a'' b''>16
c'16
<d' e'>4
~
<d' e'>16
}
\times 8/9
{
\abjad-color-music #'red
r16
\abjad-color-music #'blue
bf'16
<a'' b''>16
d'16
<e' fs'>4
~
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\abjad-color-music #'red
r16
\abjad-color-music #'blue
bf'16
<a'' b''>16
e'16
<fs' gs'>4
~
<fs' gs'>16
}
}
}
}
"""
items = _sequence.flatten(argument, depth=depth)
return list(items)
[docs]def get(
argument,
indices: typing.Sequence[int] | tuple[list[int], int] | _pattern.Pattern,
period: int | None = None,
*,
invert: bool = False,
) -> list:
r"""
Gets items in ``argument`` at ``indices`` according to ``period``.
Gets every other leaf:
.. container:: example
>>> string = r"c'8 d'8 ~ d'8 e'8 ~ e'8 ~ e'8 r8 f'8"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.get(result, [0], 2)
>>> for item in result:
... item
...
Note("c'8")
Note("d'8")
Note("e'8")
Rest('r8')
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
d'8
~
\abjad-color-music #'blue
d'8
e'8
~
\abjad-color-music #'red
e'8
~
e'8
\abjad-color-music #'blue
r8
f'8
}
.. container:: example
Gets every other logical tie:
>>> string = r"c'8 d'8 ~ d'8 e'8 ~ e'8 ~ e'8 r8 f'8"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff, pitched=True)
>>> result = abjad.select.get(result, [0], 2)
>>> for item in result:
... item
...
LogicalTie(items=[Note("c'8")])
LogicalTie(items=[Note("e'8"), Note("e'8"), Note("e'8")])
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
d'8
~
d'8
\abjad-color-music #'blue
e'8
~
\abjad-color-music #'blue
e'8
~
\abjad-color-music #'blue
e'8
r8
f'8
}
.. container:: example
Gets note 1 (or nothing) in each pitched logical tie:
>>> staff = abjad.Staff(r"c'8 d'8 ~ d'8 e'8 ~ e'8 ~ e'8 r8 f'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff, pitched=True)
>>> result = [abjad.select.leaves(_) for _ in result]
>>> result = [abjad.select.get(_, [1]) for _ in result]
>>> for item in result:
... item
[]
[Note("d'8")]
[Note("e'8")]
[]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
c'8
d'8
~
\abjad-color-music #'blue
d'8
e'8
~
\abjad-color-music #'red
e'8
~
e'8
r8
f'8
}
"""
if isinstance(indices, _pattern.Pattern):
assert period is None
pattern = indices
elif isinstance(indices, tuple):
assert len(indices) == 2, repr(indices)
indices, period = indices
assert isinstance(indices, list), repr(indices)
assert isinstance(period, int), repr(period)
pattern = _pattern.Pattern(indices, period=period)
else:
pattern = _pattern.Pattern(indices, period=period)
if invert is True:
pattern = ~pattern
items = _sequence.retain_pattern(argument, pattern)
return list(items)
[docs]def group(argument) -> list[list]:
r"""
Groups ``argument`` in selection.
.. container:: example
>>> staff = abjad.Staff(r'''
... c'8 ~ c'16 c'16 r8 c'16 c'16
... d'8 ~ d'16 d'16 r8 d'16 d'16
... ''')
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff, pitched=True)
>>> result = abjad.select.group(result)
>>> for item in result:
... item
...
[Note("c'8"), Note("c'16"), Note("c'16"), Note("c'16"), Note("c'16"), Note("d'8"), Note("d'16"), Note("d'16"), Note("d'16"), Note("d'16")]
>>> abjad.label.by_selector(result, lone=True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'green
c'8
~
\abjad-color-music #'green
c'16
\abjad-color-music #'green
c'16
r8
\abjad-color-music #'green
c'16
\abjad-color-music #'green
c'16
\abjad-color-music #'green
d'8
~
\abjad-color-music #'green
d'16
\abjad-color-music #'green
d'16
r8
\abjad-color-music #'green
d'16
\abjad-color-music #'green
d'16
}
"""
return group_by(argument)
[docs]def group_by(argument, predicate=None) -> list[list]:
r'''
Groups items in ``argument`` by ``predicate``.
Wraps selection in selection when ``predicate`` is none:
.. container:: example
>>> staff = abjad.Staff(r"""
... c'8 ~ c'16 c'16 r8 c'16 c'16
... d'8 ~ d'16 d'16 r8 d'16 d'16
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff, pitched=True)
>>> result = abjad.select.group_by(result)
>>> for item in result:
... item
...
[Note("c'8"), Note("c'16"), Note("c'16"), Note("c'16"), Note("c'16"), Note("d'8"), Note("d'16"), Note("d'16"), Note("d'16"), Note("d'16")]
>>> abjad.label.by_selector(result, lone=True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'green
c'8
~
\abjad-color-music #'green
c'16
\abjad-color-music #'green
c'16
r8
\abjad-color-music #'green
c'16
\abjad-color-music #'green
c'16
\abjad-color-music #'green
d'8
~
\abjad-color-music #'green
d'16
\abjad-color-music #'green
d'16
r8
\abjad-color-music #'green
d'16
\abjad-color-music #'green
d'16
}
'''
items = []
if predicate is None:
def predicate(argument):
return True
pairs = itertools.groupby(argument, predicate)
for count, group in pairs:
items.append(list(group))
return items
[docs]def group_by_contiguity(argument) -> list[list]:
r'''
Groups items in ``argument`` by contiguity.
Groups pitched leaves by contiguity:
.. container:: example
>>> string = r"c'8 d' r \times 2/3 { e' r f' } g' a' r"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> staff.extend("r8 <c' e' g'>8 ~ <c' e' g'>4")
>>> result = abjad.select.leaves(staff, pitched=True)
>>> result = abjad.select.group_by_contiguity(result)
>>> for item in result:
... item
...
[Note("c'8"), Note("d'8")]
[Note("e'8")]
[Note("f'8"), Note("g'8"), Note("a'8")]
[Chord("<c' e' g'>8"), Chord("<c' e' g'>4")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
d'8
r8
\times 2/3
{
\abjad-color-music #'blue
e'8
r8
\abjad-color-music #'red
f'8
}
\abjad-color-music #'red
g'8
\abjad-color-music #'red
a'8
r8
r8
\abjad-color-music #'blue
<c' e' g'>8
~
\abjad-color-music #'blue
<c' e' g'>4
}
.. container:: example
Groups sixteenths by contiguity:
>>> staff = abjad.Staff("c'4 d'16 d' d' d' e'4 f'16 f' f' f'")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.filter(
... result, lambda _: abjad.get.duration(_) == abjad.Duration(1, 16)
... )
>>> result = abjad.select.group_by_contiguity(result)
>>> for item in result:
... item
...
[Note("d'16"), Note("d'16"), Note("d'16"), Note("d'16")]
[Note("f'16"), Note("f'16"), Note("f'16"), Note("f'16")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
c'4
\abjad-color-music #'red
d'16
\abjad-color-music #'red
d'16
\abjad-color-music #'red
d'16
\abjad-color-music #'red
d'16
e'4
\abjad-color-music #'blue
f'16
\abjad-color-music #'blue
f'16
\abjad-color-music #'blue
f'16
\abjad-color-music #'blue
f'16
}
.. container:: example
Groups short-duration logical ties by contiguity; then gets leaf 0 in each
group:
>>> staff = abjad.Staff("c'4 d'8 ~ d'16 e'16 ~ e'8 f'4 g'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff)
>>> result = abjad.select.filter(
... result, lambda _: abjad.get.duration(_) < abjad.Duration(1, 4)
... )
>>> result = abjad.select.group_by_contiguity(result)
>>> result = [abjad.select.leaf(_, 0) for _ in result]
>>> for item in result:
... item
Note("d'8")
Note("g'8")
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
c'4
\abjad-color-music #'red
d'8
~
d'16
e'16
~
e'8
f'4
\abjad-color-music #'blue
g'8
}
.. container:: example
Groups pitched leaves pitch; then regroups each group by contiguity:
>>> staff = abjad.Staff(r"""
... c'8 ~ c'16 c'16 r8 c'16 c'16
... d'8 ~ d'16 d'16 r8 d'16 d'16
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff, pitched=True)
>>> result = abjad.select.group_by_pitch(result)
>>> result = [abjad.select.group_by_contiguity(_) for _ in result]
>>> result = abjad.select.flatten(result)
>>> for item in result:
... item
[Note("c'8"), Note("c'16"), Note("c'16")]
[Note("c'16"), Note("c'16")]
[Note("d'8"), Note("d'16"), Note("d'16")]
[Note("d'16"), Note("d'16")]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
~
\abjad-color-music #'red
c'16
\abjad-color-music #'red
c'16
r8
\abjad-color-music #'blue
c'16
\abjad-color-music #'blue
c'16
\abjad-color-music #'red
d'8
~
\abjad-color-music #'red
d'16
\abjad-color-music #'red
d'16
r8
\abjad-color-music #'blue
d'16
\abjad-color-music #'blue
d'16
}
.. container:: example
Groups pitched logical ties by contiguity; then regroups each group by pitch:
>>> staff = abjad.Staff(r"""
... c'8 ~ c'16 c'16 r8 c'16 c'16
... d'8 ~ d'16 d'16 r8 d'16 d'16
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff, pitched=True)
>>> result = abjad.select.group_by_contiguity(result)
>>> result = [abjad.select.group_by_pitch(_) for _ in result]
>>> result = abjad.select.flatten(result)
>>> for item in result:
... item
...
[LogicalTie(items=[Note("c'8"), Note("c'16")]), LogicalTie(items=[Note("c'16")])]
[LogicalTie(items=[Note("c'16")]), LogicalTie(items=[Note("c'16")])]
[LogicalTie(items=[Note("d'8"), Note("d'16")]), LogicalTie(items=[Note("d'16")])]
[LogicalTie(items=[Note("d'16")]), LogicalTie(items=[Note("d'16")])]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
~
\abjad-color-music #'red
c'16
\abjad-color-music #'red
c'16
r8
\abjad-color-music #'blue
c'16
\abjad-color-music #'blue
c'16
\abjad-color-music #'red
d'8
~
\abjad-color-music #'red
d'16
\abjad-color-music #'red
d'16
r8
\abjad-color-music #'blue
d'16
\abjad-color-music #'blue
d'16
}
'''
result = []
selection = []
selection.extend(argument[:1])
for item in argument[1:]:
this_timespan = _getlib._get_timespan(selection[-1])
that_timespan = _getlib._get_timespan(item)
# remove displacement
this_stop_offset = this_timespan.stop_offset
this_stop_offset = _duration.Offset(this_stop_offset.pair)
that_start_offset = that_timespan.start_offset
that_start_offset = _duration.Offset(that_start_offset.pair)
# if this_timespan.stop_offset == that_timespan.start_offset:
if this_stop_offset == that_start_offset:
selection.append(item)
else:
result.append(selection)
selection = [item]
if selection:
result.append(selection)
return result
[docs]def group_by_duration(argument) -> list[list]:
r"""
Groups items in ``argument`` by duration.
Groups logical ties by duration:
.. container:: example
>>> string = "c'4 ~ c'16 d' ~ d' d' e'4 ~ e'16 f' ~ f' f'"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff)
>>> result = abjad.select.group_by_duration(result)
>>> for item in result:
... item
...
[LogicalTie(items=[Note("c'4"), Note("c'16")])]
[LogicalTie(items=[Note("d'16"), Note("d'16")])]
[LogicalTie(items=[Note("d'16")])]
[LogicalTie(items=[Note("e'4"), Note("e'16")])]
[LogicalTie(items=[Note("f'16"), Note("f'16")])]
[LogicalTie(items=[Note("f'16")])]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'4
~
\abjad-color-music #'red
c'16
\abjad-color-music #'blue
d'16
~
\abjad-color-music #'blue
d'16
\abjad-color-music #'red
d'16
\abjad-color-music #'blue
e'4
~
\abjad-color-music #'blue
e'16
\abjad-color-music #'red
f'16
~
\abjad-color-music #'red
f'16
\abjad-color-music #'blue
f'16
}
"""
def predicate(argument):
return _getlib._get_duration(argument)
return group_by(argument, predicate=predicate)
[docs]def group_by_length(argument) -> list[list]:
r"""
Groups items in ``argument`` by length.
Groups logical ties by length:
.. container:: example
>>> string = "c'4 ~ c'16 d' ~ d' d' e'4 ~ e'16 f' ~ f' f'"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff)
>>> result = abjad.select.group_by_length(result)
>>> for item in result:
... item
...
[LogicalTie(items=[Note("c'4"), Note("c'16")]), LogicalTie(items=[Note("d'16"), Note("d'16")])]
[LogicalTie(items=[Note("d'16")])]
[LogicalTie(items=[Note("e'4"), Note("e'16")]), LogicalTie(items=[Note("f'16"), Note("f'16")])]
[LogicalTie(items=[Note("f'16")])]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'4
~
\abjad-color-music #'red
c'16
\abjad-color-music #'red
d'16
~
\abjad-color-music #'red
d'16
\abjad-color-music #'blue
d'16
\abjad-color-music #'red
e'4
~
\abjad-color-music #'red
e'16
\abjad-color-music #'red
f'16
~
\abjad-color-music #'red
f'16
\abjad-color-music #'blue
f'16
}
"""
def predicate(argument):
if isinstance(argument, _score.Leaf):
return 1
return len(argument)
return group_by(argument, predicate)
[docs]def group_by_measure(argument) -> list[list]:
r"""
Groups items in ``argument`` by measure.
Groups leaves by measure:
.. container:: example
>>> staff = abjad.Staff("c'8 d' e' f' g' a' b' c''")
>>> score = abjad.Score([staff], name="Score")
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.attach(abjad.TimeSignature((2, 8)), staff[0])
>>> abjad.attach(abjad.TimeSignature((3, 8)), staff[4])
>>> abjad.attach(abjad.TimeSignature((1, 8)), staff[7])
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.group_by_measure(result)
>>> for item in result:
... item
...
[Note("c'8"), Note("d'8")]
[Note("e'8"), Note("f'8")]
[Note("g'8"), Note("a'8"), Note("b'8")]
[Note("c''8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
\time 2/8
c'8
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
e'8
\abjad-color-music #'blue
f'8
\abjad-color-music #'red
\time 3/8
g'8
\abjad-color-music #'red
a'8
\abjad-color-music #'red
b'8
\abjad-color-music #'blue
\time 1/8
c''8
}
.. container:: example
Groups leaves by measure and joins pairs of consecutive groups:
>>> staff = abjad.Staff("c'8 d' e' f' g' a' b' c''")
>>> score = abjad.Score([staff], name="Score")
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.attach(abjad.TimeSignature((2, 8)), staff[0])
>>> abjad.attach(abjad.TimeSignature((3, 8)), staff[4])
>>> abjad.attach(abjad.TimeSignature((1, 8)), staff[7])
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.group_by_measure(result)
>>> result = abjad.select.partition_by_counts(result, [2], cyclic=True)
>>> result = [abjad.select.flatten(_) for _ in result]
>>> for item in result:
... item
...
[Note("c'8"), Note("d'8"), Note("e'8"), Note("f'8")]
[Note("g'8"), Note("a'8"), Note("b'8"), Note("c''8")]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
\time 2/8
c'8
\abjad-color-music #'red
d'8
\abjad-color-music #'red
e'8
\abjad-color-music #'red
f'8
\abjad-color-music #'blue
\time 3/8
g'8
\abjad-color-music #'blue
a'8
\abjad-color-music #'blue
b'8
\abjad-color-music #'blue
\time 1/8
c''8
}
.. container:: example
Groups leaves by measure; then gets item 0 in each group:
>>> staff = abjad.Staff("c'8 d' e' f' g' a' b' c''")
>>> score = abjad.Score([staff], name="Score")
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.attach(abjad.TimeSignature((2, 8)), staff[0])
>>> abjad.attach(abjad.TimeSignature((3, 8)), staff[4])
>>> abjad.attach(abjad.TimeSignature((1, 8)), staff[7])
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.group_by_measure(result)
>>> result = [_[0] for _ in result]
>>> for item in result:
... item
Note("c'8")
Note("e'8")
Note("g'8")
Note("c''8")
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
\time 2/8
c'8
d'8
\abjad-color-music #'blue
e'8
f'8
\abjad-color-music #'red
\time 3/8
g'8
a'8
b'8
\abjad-color-music #'blue
\time 1/8
c''8
}
.. container:: example
Groups leaves by measure; then gets item -1 in each group:
>>> staff = abjad.Staff("c'8 d' e' f' g' a' b' c''")
>>> score = abjad.Score([staff], name="Score")
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.attach(abjad.TimeSignature((2, 8)), staff[0])
>>> abjad.attach(abjad.TimeSignature((3, 8)), staff[4])
>>> abjad.attach(abjad.TimeSignature((1, 8)), staff[7])
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.group_by_measure(result)
>>> result = [_[-1] for _ in result]
>>> for item in result:
... item
...
Note("d'8")
Note("f'8")
Note("b'8")
Note("c''8")
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\time 2/8
c'8
\abjad-color-music #'red
d'8
e'8
\abjad-color-music #'blue
f'8
\time 3/8
g'8
a'8
\abjad-color-music #'red
b'8
\abjad-color-music #'blue
\time 1/8
c''8
}
.. container:: example
Works with implicit time signatures:
>>> staff = abjad.Staff("c'4 d' e' f' g' a' b' c''")
>>> abjad.setting(staff).autoBeaming = False
>>> score = abjad.Score([staff])
>>> string = "#(ly:make-moment 1 16)"
>>> abjad.setting(score).proportionalNotationDuration = string
>>> result = abjad.select.leaves(score)
>>> result = abjad.select.group_by_measure(result)
>>> for item in result:
... item
...
[Note("c'4"), Note("d'4"), Note("e'4"), Note("f'4")]
[Note("g'4"), Note("a'4"), Note("b'4"), Note("c''4")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'4
\abjad-color-music #'red
d'4
\abjad-color-music #'red
e'4
\abjad-color-music #'red
f'4
\abjad-color-music #'blue
g'4
\abjad-color-music #'blue
a'4
\abjad-color-music #'blue
b'4
\abjad-color-music #'blue
c''4
}
.. container:: example
Groups logical ties by measure:
>>> staff = abjad.Staff("c'8 d' ~ d' e' ~ e' f' g' ~ g'")
>>> score = abjad.Score([staff], name="Score")
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.attach(abjad.TimeSignature((2, 8)), staff[0])
>>> abjad.attach(abjad.TimeSignature((3, 8)), staff[4])
>>> abjad.attach(abjad.TimeSignature((1, 8)), staff[7])
>>> result = abjad.select.logical_ties(staff)
>>> result = abjad.select.group_by_measure(result)
>>> for item in result:
... item
...
[LogicalTie(items=[Note("c'8")]), LogicalTie(items=[Note("d'8"), Note("d'8")])]
[LogicalTie(items=[Note("e'8"), Note("e'8")])]
[LogicalTie(items=[Note("f'8")]), LogicalTie(items=[Note("g'8"), Note("g'8")])]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
\time 2/8
c'8
\abjad-color-music #'red
d'8
~
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
e'8
~
\abjad-color-music #'blue
\time 3/8
e'8
\abjad-color-music #'red
f'8
\abjad-color-music #'red
g'8
~
\abjad-color-music #'red
\time 1/8
g'8
}
.. container:: example
REGRESSION: works for pickup measure:
>>> staff = abjad.Staff(r"c'4 | d'4 e'4 f'4 | g'4 a'4 b'4")
>>> score = abjad.Score([staff], name="Score")
>>> time_signature = abjad.TimeSignature((3, 4), partial=abjad.Duration(1, 4))
>>> abjad.attach(time_signature, staff[0])
>>> leaves = abjad.select.leaves(staff)
>>> for measure in abjad.select.group_by_measure(leaves):
... print(measure)
...
[Note("c'4")]
[Note("d'4"), Note("e'4"), Note("f'4")]
[Note("g'4"), Note("a'4"), Note("b'4")]
"""
def _get_first_component(argument):
component = components(argument)[0]
assert isinstance(component, _score.Component)
return component
def _get_measure_number(argument):
first_component = _get_first_component(argument)
assert first_component._measure_number is not None
return first_component._measure_number
selections = []
first_component = _get_first_component(argument)
_updatelib._update_measure_numbers(first_component)
pairs = itertools.groupby(argument, _get_measure_number)
for value, group in pairs:
selections.append(list(group))
return selections
[docs]def group_by_pitch(argument) -> list[list]:
r"""
Groups items in ``argument`` by pitch.
Groups logical ties by pitches:
.. container:: example
>>> string = "c'4 ~ c'16 d' ~ d' d' e'4 ~ e'16 f' ~ f' f'"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> lts = abjad.select.logical_ties(staff)
>>> result = abjad.select.group_by_pitch(lts)
>>> for item in result:
... item
...
[LogicalTie(items=[Note("c'4"), Note("c'16")])]
[LogicalTie(items=[Note("d'16"), Note("d'16")]), LogicalTie(items=[Note("d'16")])]
[LogicalTie(items=[Note("e'4"), Note("e'16")])]
[LogicalTie(items=[Note("f'16"), Note("f'16")]), LogicalTie(items=[Note("f'16")])]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'4
~
\abjad-color-music #'red
c'16
\abjad-color-music #'blue
d'16
~
\abjad-color-music #'blue
d'16
\abjad-color-music #'blue
d'16
\abjad-color-music #'red
e'4
~
\abjad-color-music #'red
e'16
\abjad-color-music #'blue
f'16
~
\abjad-color-music #'blue
f'16
\abjad-color-music #'blue
f'16
}
"""
def predicate(argument):
generator = _iterate.pitches(argument)
return _pcollections.PitchSet(generator)
return group_by(argument, predicate)
[docs]def leaf(
argument,
n: int,
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
head: bool | None = None,
pitched: bool | None = None,
prototype=None,
reverse: bool | None = None,
tail: bool | None = None,
trim: bool | _enums.Horizontal | None = None,
) -> _score.Leaf:
r"""
Selects leaf ``n` in ``argument``.
Selects leaf -1:
.. container:: example
>>> tuplets = [
... "r16 bf'16 <a'' b''>16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 bf'16 <a'' b''>16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 bf'16 <a'' b''>16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.leaf(staff, -1)
>>> result
Chord("<fs' gs'>16")
>>> abjad.label.by_selector(result, lone=True)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\time 7/4
r16
bf'16
<a'' b''>16
c'16
<d' e'>4
~
<d' e'>16
}
\times 8/9
{
r16
bf'16
<a'' b''>16
d'16
<e' fs'>4
~
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
r16
bf'16
<a'' b''>16
e'16
<fs' gs'>4
~
\abjad-color-music #'green
<fs' gs'>16
}
}
}
}
"""
return leaves(
argument,
exclude=exclude,
grace=grace,
head=head,
pitched=pitched,
prototype=prototype,
reverse=reverse,
tail=tail,
trim=trim,
)[n]
@typing.overload
def leaves(
argument,
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
head: bool | None = None,
pitched: bool | None = None,
reverse: bool | None = None,
tail: bool | None = None,
trim: bool | _enums.Horizontal | None = None,
) -> list[_score.Leaf]:
...
@typing.overload
def leaves(
argument,
prototype: typing.Type[_score.Chord],
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
head: bool | None = None,
pitched: bool | None = None,
reverse: bool | None = None,
tail: bool | None = None,
trim: bool | _enums.Horizontal | None = None,
) -> list[_score.Chord]:
...
@typing.overload
def leaves(
argument,
prototype: typing.Type[_score.MultimeasureRest],
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
head: bool | None = None,
pitched: bool | None = None,
reverse: bool | None = None,
tail: bool | None = None,
trim: bool | _enums.Horizontal | None = None,
) -> list[_score.MultimeasureRest]:
...
@typing.overload
def leaves(
argument,
prototype: typing.Type[_score.Note],
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
head: bool | None = None,
pitched: bool | None = None,
reverse: bool | None = None,
tail: bool | None = None,
trim: bool | _enums.Horizontal | None = None,
) -> list[_score.Note]:
...
[docs]def leaves(
argument,
prototype=None,
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
head: bool | None = None,
pitched: bool | None = None,
reverse: bool | None = None,
tail: bool | None = None,
trim: bool | _enums.Horizontal | None = None,
):
r'''
Selects leaves in ``argument``.
.. container:: example
Selects leaves:
>>> staff = abjad.Staff(r"""
... \times 2/3 { r8 d' e' } f' r
... r f' \times 2/3 { e' d' r8 }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> for item in result:
... item
...
Rest('r8')
Note("d'8")
Note("e'8")
Note("f'8")
Rest('r8')
Rest('r8')
Note("f'8")
Note("e'8")
Note("d'8")
Rest('r8')
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
\abjad-color-music #'red
r8
\abjad-color-music #'blue
d'8
\abjad-color-music #'red
e'8
}
\abjad-color-music #'blue
f'8
\abjad-color-music #'red
r8
\abjad-color-music #'blue
r8
\abjad-color-music #'red
f'8
\times 2/3
{
\abjad-color-music #'blue
e'8
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
r8
}
}
.. container:: example
Selects pitched leaves:
>>> staff = abjad.Staff(r"""
... \times 2/3 { r8 d' e' } f' r
... r f' \times 2/3 { e' d' r8 }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff, pitched=True)
>>> for item in result:
... item
...
Note("d'8")
Note("e'8")
Note("f'8")
Note("f'8")
Note("e'8")
Note("d'8")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
r8
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
e'8
}
\abjad-color-music #'red
f'8
r8
r8
\abjad-color-music #'blue
f'8
\times 2/3
{
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
d'8
r8
}
}
.. container:: example
Trimmed leaves are the correct selection for ottava brackets.
Selects trimmed leaves:
>>> staff = abjad.Staff(r"""
... \times 2/3 { r8 d' e' } f' r
... r f' \times 2/3 { e' d' r8 }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff, trim=True)
>>> for item in result:
... item
...
Note("d'8")
Note("e'8")
Note("f'8")
Rest('r8')
Rest('r8')
Note("f'8")
Note("e'8")
Note("d'8")
>>> abjad.ottava(result)
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
r8
\abjad-color-music #'red
\ottava 1
d'8
\abjad-color-music #'blue
e'8
}
\abjad-color-music #'red
f'8
\abjad-color-music #'blue
r8
\abjad-color-music #'red
r8
\abjad-color-music #'blue
f'8
\times 2/3
{
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
d'8
\ottava 0
r8
}
}
.. container:: example
Set ``trim`` to ``abjad.LEFT`` to trim rests at left (and preserve rests at
right):
>>> staff = abjad.Staff(r"""
... \times 2/3 { r8 d' e' } f' r
... r f' \times 2/3 { e' d' r8 }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff, trim=abjad.LEFT)
>>> for item in result:
... item
...
Note("d'8")
Note("e'8")
Note("f'8")
Rest('r8')
Rest('r8')
Note("f'8")
Note("e'8")
Note("d'8")
Rest('r8')
>>> abjad.ottava(result)
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
r8
\abjad-color-music #'red
\ottava 1
d'8
\abjad-color-music #'blue
e'8
}
\abjad-color-music #'red
f'8
\abjad-color-music #'blue
r8
\abjad-color-music #'red
r8
\abjad-color-music #'blue
f'8
\times 2/3
{
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
d'8
\abjad-color-music #'red
r8
\ottava 0
}
}
.. container:: example
REGRESSION: selects trimmed leaves (even when there are no rests to trim):
>>> staff = abjad.Staff(r"""
... \times 2/3 { c'8 d' e' } f' r
... r f' \times 2/3 { e' d' c' }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff, trim=True)
>>> for item in result:
... item
...
Note("c'8")
Note("d'8")
Note("e'8")
Note("f'8")
Rest('r8')
Rest('r8')
Note("f'8")
Note("e'8")
Note("d'8")
Note("c'8")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
\abjad-color-music #'red
c'8
\abjad-color-music #'blue
d'8
\abjad-color-music #'red
e'8
}
\abjad-color-music #'blue
f'8
\abjad-color-music #'red
r8
\abjad-color-music #'blue
r8
\abjad-color-music #'red
f'8
\times 2/3
{
\abjad-color-music #'blue
e'8
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
c'8
}
}
.. container:: example
Selects leaves in tuplets:
>>> staff = abjad.Staff(r"""
... \times 2/3 { r8 d' e' } f' r
... r f' \times 2/3 { e' d' r8 }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.components(staff, abjad.Tuplet)
>>> result = abjad.select.leaves(result)
>>> for item in result:
... item
...
Rest('r8')
Note("d'8")
Note("e'8")
Note("e'8")
Note("d'8")
Rest('r8')
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
\abjad-color-music #'red
r8
\abjad-color-music #'blue
d'8
\abjad-color-music #'red
e'8
}
f'8
r8
r8
f'8
\times 2/3
{
\abjad-color-music #'blue
e'8
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
r8
}
}
.. container:: example
Selects trimmed leaves in tuplets:
>>> staff = abjad.Staff(r"""
... \times 2/3 { r8 d' e' } f' r
... r f' \times 2/3 { e' d' r8 }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.components(staff, abjad.Tuplet)
>>> result = abjad.select.leaves(result, trim=True)
>>> for item in result:
... item
...
Note("d'8")
Note("e'8")
Note("e'8")
Note("d'8")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
r8
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
e'8
}
f'8
r8
r8
f'8
\times 2/3
{
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
d'8
r8
}
}
.. container:: example
Pitched heads is the correct selection for most articulations.
Selects pitched heads in tuplets:
>>> staff = abjad.Staff(r"""
... \times 2/3 { c'8 d' ~ d' } e' r
... r e' \times 2/3 { d' ~ d' c' }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.components(staff, abjad.Tuplet)
>>> result = abjad.select.leaves(result, head=True, pitched=True)
>>> for item in result:
... item
...
Note("c'8")
Note("d'8")
Note("d'8")
Note("c'8")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
\abjad-color-music #'red
c'8
\abjad-color-music #'blue
d'8
~
d'8
}
e'8
r8
r8
e'8
\times 2/3
{
\abjad-color-music #'red
d'8
~
d'8
\abjad-color-music #'blue
c'8
}
}
.. container:: example
Pitched tails in the correct selection for laissez vibrer.
Selects pitched tails in tuplets:
>>> staff = abjad.Staff(r"""
... \times 2/3 { c'8 d' ~ d' } e' r
... r e' \times 2/3 { d' ~ d' c' }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.components(staff, abjad.Tuplet)
>>> result = abjad.select.leaves(result, tail=True, pitched=True)
>>> for item in result:
... item
...
Note("c'8")
Note("d'8")
Note("d'8")
Note("c'8")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
\abjad-color-music #'red
c'8
d'8
~
\abjad-color-music #'blue
d'8
}
e'8
r8
r8
e'8
\times 2/3
{
d'8
~
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
c'8
}
}
.. container:: example
Chord heads are the correct selection for arpeggios.
Selects chord heads in tuplets:
>>> staff = abjad.Staff(r"""
... \times 2/3 { <c' e' g'>8 ~ <c' e' g'> d' } e' r
... r <g d' fs'> \times 2/3 { e' <c' d'> ~ <c' d'> }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.components(staff, abjad.Tuplet)
>>> result = abjad.select.leaves(result, abjad.Chord, head=True)
>>> for item in result:
... item
...
Chord("<c' e' g'>8")
Chord("<c' d'>8")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
\abjad-color-music #'red
<c' e' g'>8
~
<c' e' g'>8
d'8
}
e'8
r8
r8
<g d' fs'>8
\times 2/3
{
e'8
\abjad-color-music #'blue
<c' d'>8
~
<c' d'>8
}
}
.. container:: example
Excludes leaves with ``"HIDDEN"`` indicator:
>>> staff = abjad.Staff(r"""
... \times 2/3 { r8 d' e' } f' r
... r f' \times 2/3 { e' d' r8 }
... """)
>>> abjad.attach("HIDDEN", staff[-1][-2])
>>> abjad.attach("HIDDEN", staff[-1][-1])
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff, exclude="HIDDEN")
>>> for item in result:
... item
...
Rest('r8')
Note("d'8")
Note("e'8")
Note("f'8")
Rest('r8')
Rest('r8')
Note("f'8")
Note("e'8")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
\abjad-color-music #'red
r8
\abjad-color-music #'blue
d'8
\abjad-color-music #'red
e'8
}
\abjad-color-music #'blue
f'8
\abjad-color-music #'red
r8
\abjad-color-music #'blue
r8
\abjad-color-music #'red
f'8
\times 2/3
{
\abjad-color-music #'blue
e'8
d'8
r8
}
}
.. container:: example
Selects both main notes and graces when ``grace=None``:
>>> staff = abjad.Staff("c'8 d'8 e'8 f'8")
>>> container = abjad.BeforeGraceContainer("cf''16 bf'16")
>>> abjad.attach(container, staff[1])
>>> container = abjad.AfterGraceContainer("af'16 gf'16")
>>> abjad.attach(container, staff[1])
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff, grace=None)
>>> for item in result:
... item
...
Note("c'8")
Note("cf''16")
Note("bf'16")
Note("d'8")
Note("af'16")
Note("gf'16")
Note("e'8")
Note("f'8")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\grace {
\abjad-color-music #'blue
cf''16
\abjad-color-music #'red
bf'16
}
\abjad-color-music #'blue
\afterGrace
d'8
{
\abjad-color-music #'red
af'16
\abjad-color-music #'blue
gf'16
}
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
f'8
}
.. container:: example
Excludes grace notes when ``grace=False``:
>>> staff = abjad.Staff("c'8 d'8 e'8 f'8")
>>> container = abjad.BeforeGraceContainer("cf''16 bf'16")
>>> abjad.attach(container, staff[1])
>>> container = abjad.AfterGraceContainer("af'16 gf'16")
>>> abjad.attach(container, staff[1])
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff, grace=False)
>>> for item in result:
... item
...
Note("c'8")
Note("d'8")
Note("e'8")
Note("f'8")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\grace {
cf''16
bf'16
}
\abjad-color-music #'blue
\afterGrace
d'8
{
af'16
gf'16
}
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
f'8
}
.. container:: example
Selects only grace notes when ``grace=True``:
>>> staff = abjad.Staff("c'8 d'8 e'8 f'8")
>>> container = abjad.BeforeGraceContainer("cf''16 bf'16")
>>> abjad.attach(container, staff[1])
>>> container = abjad.AfterGraceContainer("af'16 gf'16")
>>> abjad.attach(container, staff[1])
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff, grace=True)
>>> for item in result:
... item
...
Note("cf''16")
Note("bf'16")
Note("af'16")
Note("gf'16")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
c'8
\grace {
\abjad-color-music #'red
cf''16
\abjad-color-music #'blue
bf'16
}
\afterGrace
d'8
{
\abjad-color-music #'red
af'16
\abjad-color-music #'blue
gf'16
}
e'8
f'8
}
'''
assert trim in (True, False, _enums.LEFT, None)
if pitched:
prototype = (_score.Chord, _score.Note)
elif prototype is None:
prototype = _score.Leaf
prototype = prototype or _score.Component
if not isinstance(prototype, tuple):
prototype = (prototype,)
result = []
generator = _iterlib._public_iterate_components(
argument, prototype, exclude=exclude, grace=grace
)
components = list(generator)
if components:
if trim in (True, _enums.LEFT):
components = _trim_subresult(components, trim)
if head is not None:
components = _head_filter_subresult(components, head)
if tail is not None:
components = _tail_filter_subresult(components, tail)
result.extend(components)
return result
[docs]def logical_tie(
argument,
n: int = 0,
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
nontrivial: bool | None = None,
pitched: bool | None = None,
reverse: bool | None = None,
) -> LogicalTie:
r"""
Selects logical tie ``n`` in ``argument``.
.. todo:: Make work on nonhead leaves.
.. todo:: Write examples.
.. todo:: Remove ``abjad.get.logical_tie()``.
"""
return logical_ties(
argument,
exclude=exclude,
grace=grace,
nontrivial=nontrivial,
pitched=pitched,
reverse=reverse,
)[n]
[docs]def logical_ties(
argument,
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
nontrivial: bool | None = None,
pitched: bool | None = None,
reverse: bool | None = None,
) -> list[LogicalTie]:
r'''
Selects logical ties in ``argument``.
Selects logical ties:
.. container:: example
>>> staff = abjad.Staff("c'8 d' ~ { d' e' r f'~ } f' r")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff)
>>> for item in result:
... item
...
LogicalTie(items=[Note("c'8")])
LogicalTie(items=[Note("d'8"), Note("d'8")])
LogicalTie(items=[Note("e'8")])
LogicalTie(items=[Rest('r8')])
LogicalTie(items=[Note("f'8"), Note("f'8")])
LogicalTie(items=[Rest('r8')])
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'blue
d'8
~
{
\abjad-color-music #'blue
d'8
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
r8
\abjad-color-music #'red
f'8
~
}
\abjad-color-music #'red
f'8
\abjad-color-music #'blue
r8
}
.. container:: example
Selects pitched logical ties:
>>> staff = abjad.Staff("c'8 d' ~ { d' e' r f'~ } f' r")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff, pitched=True)
>>> for item in result:
... item
...
LogicalTie(items=[Note("c'8")])
LogicalTie(items=[Note("d'8"), Note("d'8")])
LogicalTie(items=[Note("e'8")])
LogicalTie(items=[Note("f'8"), Note("f'8")])
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'blue
d'8
~
{
\abjad-color-music #'blue
d'8
\abjad-color-music #'red
e'8
r8
\abjad-color-music #'blue
f'8
~
}
\abjad-color-music #'blue
f'8
r8
}
.. container:: example
Selects pitched nontrivial logical ties:
>>> staff = abjad.Staff("c'8 d' ~ { d' e' r f'~ } f' r")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(
... staff,
... pitched=True,
... nontrivial=True,
... )
>>> for item in result:
... item
LogicalTie(items=[Note("d'8"), Note("d'8")])
LogicalTie(items=[Note("f'8"), Note("f'8")])
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
c'8
\abjad-color-music #'red
d'8
~
{
\abjad-color-music #'red
d'8
e'8
r8
\abjad-color-music #'blue
f'8
~
}
\abjad-color-music #'blue
f'8
r8
}
.. container:: example
Selects pitched logical ties (starting) in each tuplet:
>>> staff = abjad.Staff(r"""
... \times 2/3 { c'8 d' e' ~ } e' f' ~
... \times 2/3 { f' g' a' ~ } a' b' ~
... \times 2/3 { b' c'' d'' }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.components(staff, abjad.Tuplet)
>>> result = [abjad.select.logical_ties(_, pitched=True) for _ in result]
>>> for item in result:
... item
...
[LogicalTie(items=[Note("c'8")]), LogicalTie(items=[Note("d'8")]), LogicalTie(items=[Note("e'8"), Note("e'8")])]
[LogicalTie(items=[Note("g'8")]), LogicalTie(items=[Note("a'8"), Note("a'8")])]
[LogicalTie(items=[Note("c''8")]), LogicalTie(items=[Note("d''8")])]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
d'8
\abjad-color-music #'red
e'8
~
}
\abjad-color-music #'red
e'8
f'8
~
\times 2/3
{
f'8
\abjad-color-music #'blue
g'8
\abjad-color-music #'blue
a'8
~
}
\abjad-color-music #'blue
a'8
b'8
~
\times 2/3
{
b'8
\abjad-color-music #'red
c''8
\abjad-color-music #'red
d''8
}
}
.. container:: example
Selects pitched logical ties (starting) in each of the last two tuplets:
>>> staff = abjad.Staff(r"""
... \times 2/3 { c'8 d' e' ~ } e' f' ~
... \times 2/3 { f' g' a' ~ } a' b' ~
... \times 2/3 { b' c'' d'' }
... """)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.components(staff, abjad.Tuplet)[-2:]
>>> result = [abjad.select.logical_ties(_, pitched=True) for _ in result]
>>> for item in result:
... item
...
[LogicalTie(items=[Note("g'8")]), LogicalTie(items=[Note("a'8"), Note("a'8")])]
[LogicalTie(items=[Note("c''8")]), LogicalTie(items=[Note("d''8")])]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\times 2/3
{
c'8
d'8
e'8
~
}
e'8
f'8
~
\times 2/3
{
f'8
\abjad-color-music #'red
g'8
\abjad-color-music #'red
a'8
~
}
\abjad-color-music #'red
a'8
b'8
~
\times 2/3
{
b'8
\abjad-color-music #'blue
c''8
\abjad-color-music #'blue
d''8
}
}
.. container:: example
Selects both main notes and graces when ``grace=None``:
>>> staff = abjad.Staff("c'8 d'8 e'8 f'8")
>>> container = abjad.BeforeGraceContainer("cf''16 bf'16")
>>> abjad.attach(container, staff[1])
>>> container = abjad.AfterGraceContainer("af'16 gf'16")
>>> abjad.attach(container, staff[1])
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff, grace=None)
>>> for item in result:
... item
...
LogicalTie(items=[Note("c'8")])
LogicalTie(items=[Note("cf''16")])
LogicalTie(items=[Note("bf'16")])
LogicalTie(items=[Note("d'8")])
LogicalTie(items=[Note("af'16")])
LogicalTie(items=[Note("gf'16")])
LogicalTie(items=[Note("e'8")])
LogicalTie(items=[Note("f'8")])
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\grace {
\abjad-color-music #'blue
cf''16
\abjad-color-music #'red
bf'16
}
\abjad-color-music #'blue
\afterGrace
d'8
{
\abjad-color-music #'red
af'16
\abjad-color-music #'blue
gf'16
}
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
f'8
}
.. container:: example
Excludes grace notes when ``grace=False``:
>>> staff = abjad.Staff("c'8 d'8 e'8 f'8")
>>> container = abjad.BeforeGraceContainer("cf''16 bf'16")
>>> abjad.attach(container, staff[1])
>>> container = abjad.AfterGraceContainer("af'16 gf'16")
>>> abjad.attach(container, staff[1])
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff, grace=False)
>>> for item in result:
... item
...
LogicalTie(items=[Note("c'8")])
LogicalTie(items=[Note("d'8")])
LogicalTie(items=[Note("e'8")])
LogicalTie(items=[Note("f'8")])
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\grace {
cf''16
bf'16
}
\abjad-color-music #'blue
\afterGrace
d'8
{
af'16
gf'16
}
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
f'8
}
.. container:: example
Selects only grace notes when ``grace=True``:
>>> staff = abjad.Staff("c'8 d'8 e'8 f'8")
>>> container = abjad.BeforeGraceContainer("cf''16 bf'16")
>>> abjad.attach(container, staff[1])
>>> container = abjad.AfterGraceContainer("af'16 gf'16")
>>> abjad.attach(container, staff[1])
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff, grace=True)
>>> for item in result:
... item
...
LogicalTie(items=[Note("cf''16")])
LogicalTie(items=[Note("bf'16")])
LogicalTie(items=[Note("af'16")])
LogicalTie(items=[Note("gf'16")])
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
c'8
\grace {
\abjad-color-music #'red
cf''16
\abjad-color-music #'blue
bf'16
}
\afterGrace
d'8
{
\abjad-color-music #'red
af'16
\abjad-color-music #'blue
gf'16
}
e'8
f'8
}
'''
generator = _iterlib._iterate_logical_ties(
argument,
exclude=exclude,
grace=grace,
nontrivial=nontrivial,
pitched=pitched,
reverse=reverse,
)
return list(generator)
[docs]def nontrivial(argument) -> list:
r"""
Selects nontrivial items in ``argument``.
Selects nontrivial runs:
.. container:: example
>>> staff = abjad.Staff("c'8 r8 d'8 e'8 r8 f'8 g'8 a'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.runs(staff)
>>> result = abjad.select.nontrivial(result)
>>> for item in result:
... item
...
[Note("d'8"), Note("e'8")]
[Note("f'8"), Note("g'8"), Note("a'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
c'8
r8
\abjad-color-music #'red
d'8
\abjad-color-music #'red
e'8
r8
\abjad-color-music #'blue
f'8
\abjad-color-music #'blue
g'8
\abjad-color-music #'blue
a'8
}
"""
items = [_ for _ in argument if len(_) > 1]
return items
[docs]def note(
argument,
n: int,
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
) -> _score.Note:
r"""
Selects note ``n`` in ``argument``.
Selects note -1:
.. container:: example
>>> tuplets = [
... "r16 bf'16 <a'' b''>16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 bf'16 <a'' b''>16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 bf'16 <a'' b''>16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.note(staff, -1)
>>> result
Note("e'16")
>>> abjad.label.by_selector(result, lone=True)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\time 7/4
r16
bf'16
<a'' b''>16
c'16
<d' e'>4
~
<d' e'>16
}
\times 8/9
{
r16
bf'16
<a'' b''>16
d'16
<e' fs'>4
~
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
r16
bf'16
<a'' b''>16
\abjad-color-music #'green
e'16
<fs' gs'>4
~
<fs' gs'>16
}
}
}
}
"""
return notes(argument, exclude=exclude, grace=grace)[n]
[docs]def notes(
argument, *, exclude: _typings.Exclude | None = None, grace: bool | None = None
) -> list[_score.Note]:
r"""
Selects notes in ``argument``.
Selects notes:
.. container:: example
>>> tuplets = [
... "r16 bf'16 <a'' b''>16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 bf'16 <a'' b''>16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 bf'16 <a'' b''>16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.notes(staff)
>>> for item in result:
... item
...
Note("bf'16")
Note("c'16")
Note("bf'16")
Note("d'16")
Note("bf'16")
Note("e'16")
>>> abjad.label.by_selector(result)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\time 7/4
r16
\abjad-color-music #'red
bf'16
<a'' b''>16
\abjad-color-music #'blue
c'16
<d' e'>4
~
<d' e'>16
}
\times 8/9
{
r16
\abjad-color-music #'red
bf'16
<a'' b''>16
\abjad-color-music #'blue
d'16
<e' fs'>4
~
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
r16
\abjad-color-music #'red
bf'16
<a'' b''>16
\abjad-color-music #'blue
e'16
<fs' gs'>4
~
<fs' gs'>16
}
}
}
}
"""
items = []
for item in components(argument, _score.Note, exclude=exclude, grace=grace):
assert isinstance(item, _score.Note)
items.append(item)
return items
[docs]def partition_by_counts(
argument,
counts,
*,
cyclic=False,
enchain=False,
fuse_overhang=False,
nonempty=False,
overhang=False,
) -> list[list]:
r"""
Partitions items in ``argument`` by ``counts``.
Partitions leaves into a single part of length 3; truncates overhang:
.. container:: example
>>> staff = abjad.Staff("c'8 r8 d'8 e'8 r8 f'8 g'8 a'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_counts(
... result,
... [3],
... cyclic=False,
... overhang=False,
... )
>>> for item in result:
... item
...
[Note("c'8"), Rest('r8'), Note("d'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
r8
\abjad-color-music #'red
d'8
e'8
r8
f'8
g'8
a'8
}
.. container:: example
Cyclically partitions leaves into parts of length 3; truncates overhang:
>>> staff = abjad.Staff("c'8 r8 d'8 e'8 r8 f'8 g'8 a'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_counts(
... result,
... [3],
... cyclic=True,
... overhang=False,
... )
>>> for item in result:
... item
...
[Note("c'8"), Rest('r8'), Note("d'8")]
[Note("e'8"), Rest('r8'), Note("f'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
r8
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
e'8
\abjad-color-music #'blue
r8
\abjad-color-music #'blue
f'8
g'8
a'8
}
.. container:: example
Cyclically partitions leaves into parts of length 3; returns overhang at end:
>>> staff = abjad.Staff("c'8 r8 d'8 e'8 r8 f'8 g'8 a'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_counts(
... result,
... [3],
... cyclic=True,
... overhang=True,
... )
>>> for item in result:
... item
...
[Note("c'8"), Rest('r8'), Note("d'8")]
[Note("e'8"), Rest('r8'), Note("f'8")]
[Note("g'8"), Note("a'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
r8
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
e'8
\abjad-color-music #'blue
r8
\abjad-color-music #'blue
f'8
\abjad-color-music #'red
g'8
\abjad-color-music #'red
a'8
}
.. container:: example
Cyclically partitions leaves into parts of length 3; fuses overhang to last
part:
>>> staff = abjad.Staff("c'8 r8 d'8 e'8 r8 f'8 g'8 a'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_counts(
... result,
... [3],
... cyclic=True,
... fuse_overhang=True,
... overhang=True,
... )
>>> for item in result:
... item
...
[Note("c'8"), Rest('r8'), Note("d'8")]
[Note("e'8"), Rest('r8'), Note("f'8"), Note("g'8"), Note("a'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
r8
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
e'8
\abjad-color-music #'blue
r8
\abjad-color-music #'blue
f'8
\abjad-color-music #'blue
g'8
\abjad-color-music #'blue
a'8
}
.. container:: example
Cyclically partitions leaves into parts of length 3; returns overhang at end:
>>> string = "c'8 r8 d'8 e'8 r8 f'8 g'8 a'8 b'8 r8 c''8"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> leaves = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_counts(
... leaves,
... [1, 2, 3],
... cyclic=True,
... overhang=True,
... )
>>> for item in result:
... item
...
[Note("c'8")]
[Rest('r8'), Note("d'8")]
[Note("e'8"), Rest('r8'), Note("f'8")]
[Note("g'8")]
[Note("a'8"), Note("b'8")]
[Rest('r8'), Note("c''8")]
>>> abjad.label.by_selector(result, colors=["#red", "#blue", "#cyan"])
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'blue
r8
\abjad-color-music #'blue
d'8
\abjad-color-music #'cyan
e'8
\abjad-color-music #'cyan
r8
\abjad-color-music #'cyan
f'8
\abjad-color-music #'red
g'8
\abjad-color-music #'blue
a'8
\abjad-color-music #'blue
b'8
\abjad-color-music #'cyan
r8
\abjad-color-music #'cyan
c''8
}
.. container:: example
With negative ``counts``.
Partitions leaves alternately into parts 2 and -3 (without overhang):
>>> string = "c'8 r8 d'8 e'8 r8 f'8 g'8 a'8 b'8 r8 c''8"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> leaves = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_counts(
... leaves,
... [2, -3],
... cyclic=True,
... )
>>> for item in result:
... item
...
[Note("c'8"), Rest('r8')]
[Note("f'8"), Note("g'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
r8
d'8
e'8
r8
\abjad-color-music #'blue
f'8
\abjad-color-music #'blue
g'8
a'8
b'8
r8
c''8
}
.. container:: example
With negative ``counts``.
Partitions leaves alternately into parts 2 and -3 (with overhang):
>>> string = "c'8 r8 d'8 e'8 r8 f'8 g'8 a'8 b'8 r8 c''8"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> leaves = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_counts(
... leaves,
... [2, -3],
... cyclic=True,
... overhang=True,
... )
>>> for item in result:
... item
...
[Note("c'8"), Rest('r8')]
[Note("f'8"), Note("g'8")]
[Note("c''8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
r8
d'8
e'8
r8
\abjad-color-music #'blue
f'8
\abjad-color-music #'blue
g'8
a'8
b'8
r8
\abjad-color-music #'red
c''8
}
.. container:: example
REGRESSION. Noncyclic counts work when ``overhang`` is true:
>>> string = "c'8 r8 d'8 e'8 r8 f'8 g'8 a'8 b'8 r8 c''8"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> leaves = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_counts(
... leaves,
... [3],
... overhang=True,
... )
>>> for item in result:
... item
...
[Note("c'8"), Rest('r8'), Note("d'8")]
[Note("e'8"), Rest('r8'), Note("f'8"), Note("g'8"), Note("a'8"), Note("b'8"), Rest('r8'), Note("c''8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
r8
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
e'8
\abjad-color-music #'blue
r8
\abjad-color-music #'blue
f'8
\abjad-color-music #'blue
g'8
\abjad-color-music #'blue
a'8
\abjad-color-music #'blue
b'8
\abjad-color-music #'blue
r8
\abjad-color-music #'blue
c''8
}
"""
result = []
groups_ = _sequence.partition_by_counts(
argument,
[abs(_) for _ in counts],
cyclic=cyclic,
enchain=enchain,
overhang=overhang,
)
groups = list(groups_)
total = len(groups)
if overhang and fuse_overhang and 1 < len(groups):
last_count = counts[(len(groups) - 1) % len(counts)]
if len(groups[-1]) != last_count:
last_group = groups.pop()
groups[-1] += last_group
subresult = []
if cyclic:
counts = _cyclictuple.CyclicTuple(counts)
for i, group in enumerate(groups):
if overhang and i == total - 1:
pass
else:
try:
count = counts[i]
except Exception:
raise Exception(counts, i)
if count < 0:
continue
subresult.append(group)
if nonempty and not subresult:
subresult.append(groups[0])
result.extend(subresult)
return result
[docs]def partition_by_durations(
argument,
durations,
*,
cyclic=False,
fill=None,
in_seconds=False,
overhang=False,
) -> list[list]:
r"""
Partitions items in ``argument`` by ``durations``.
Cyclically partitions leaves into parts equal to exactly 3/8; returns
overhang at end:
.. container:: example
>>> staff = abjad.Staff([
... abjad.Container("c'8 d'"),
... abjad.Container("e'8 f'"),
... abjad.Container("g'8 a'"),
... abjad.Container("b'8 c''"),
... ])
>>> score = abjad.Score([staff], name="Score")
>>> for container in staff:
... time_signature = abjad.TimeSignature((2, 8))
... abjad.attach(time_signature, container[0])
...
>>> abjad.setting(staff).autoBeaming = False
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> leaves = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_durations(
... leaves,
... [abjad.Duration(3, 8)],
... cyclic=True,
... fill=abjad.EXACT,
... in_seconds=False,
... overhang=True,
... )
>>> for item in result:
... item
...
[Note("c'8"), Note("d'8"), Note("e'8")]
[Note("f'8"), Note("g'8"), Note("a'8")]
[Note("b'8"), Note("c''8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
{
\abjad-color-music #'red
\time 2/8
c'8
\abjad-color-music #'red
d'8
}
{
\abjad-color-music #'red
\time 2/8
e'8
\abjad-color-music #'blue
f'8
}
{
\abjad-color-music #'blue
\time 2/8
g'8
\abjad-color-music #'blue
a'8
}
{
\abjad-color-music #'red
\time 2/8
b'8
\abjad-color-music #'red
c''8
}
}
.. container:: example
Partitions leaves into one part equal to exactly 3/8; truncates overhang:
>>> staff = abjad.Staff([
... abjad.Container("c'8 d'"),
... abjad.Container("e'8 f'"),
... abjad.Container("g'8 a'"),
... abjad.Container("b'8 c''"),
... ])
>>> score = abjad.Score([staff], name="Score")
>>> for container in staff:
... time_signature = abjad.TimeSignature((2, 8))
... abjad.attach(time_signature, container[0])
...
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_durations(
... result,
... [abjad.Duration(3, 8)],
... cyclic=False,
... fill=abjad.EXACT,
... in_seconds=False,
... overhang=False,
... )
>>> for item in result:
... item
...
[Note("c'8"), Note("d'8"), Note("e'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
{
\abjad-color-music #'red
\time 2/8
c'8
\abjad-color-music #'red
d'8
}
{
\abjad-color-music #'red
\time 2/8
e'8
f'8
}
{
\time 2/8
g'8
a'8
}
{
\time 2/8
b'8
c''8
}
}
.. container:: example
Cyclically partitions leaves into parts equal to (or just less than) 3/16 and
1/16; returns overhang at end:
>>> staff = abjad.Staff([
... abjad.Container("c'8 d'"),
... abjad.Container("e'8 f'"),
... abjad.Container("g'8 a'"),
... abjad.Container("b'8 c''"),
... ])
>>> score = abjad.Score([staff], name="Score")
>>> for container in staff:
... time_signature = abjad.TimeSignature((2, 8))
... abjad.attach(time_signature, container[0])
...
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_durations(
... result,
... [abjad.Duration(3, 16), abjad.Duration(1, 16)],
... cyclic=True,
... fill=abjad.MORE,
... in_seconds=False,
... overhang=True,
... )
>>> for item in result:
... item
...
[Note("c'8"), Note("d'8")]
[Note("e'8")]
[Note("f'8"), Note("g'8")]
[Note("a'8")]
[Note("b'8"), Note("c''8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
{
\abjad-color-music #'red
\time 2/8
c'8
\abjad-color-music #'red
d'8
}
{
\abjad-color-music #'blue
\time 2/8
e'8
\abjad-color-music #'red
f'8
}
{
\abjad-color-music #'red
\time 2/8
g'8
\abjad-color-music #'blue
a'8
}
{
\abjad-color-music #'red
\time 2/8
b'8
\abjad-color-music #'red
c''8
}
}
.. container:: example
Cyclically partitions leaves into parts equal to (or just less than) 3/16;
truncates overhang:
>>> staff = abjad.Staff([
... abjad.Container("c'8 d'"),
... abjad.Container("e'8 f'"),
... abjad.Container("g'8 a'"),
... abjad.Container("b'8 c''"),
... ])
>>> score = abjad.Score([staff], name="Score")
>>> for container in staff:
... time_signature = abjad.TimeSignature((2, 8))
... abjad.attach(time_signature, container[0])
...
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_durations(
... result,
... [abjad.Duration(3, 16)],
... cyclic=True,
... fill=abjad.LESS,
... in_seconds=False,
... overhang=False,
... )
>>> for item in result:
... item
...
[Note("c'8")]
[Note("d'8")]
[Note("e'8")]
[Note("f'8")]
[Note("g'8")]
[Note("a'8")]
[Note("b'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
{
\abjad-color-music #'red
\time 2/8
c'8
\abjad-color-music #'blue
d'8
}
{
\abjad-color-music #'red
\time 2/8
e'8
\abjad-color-music #'blue
f'8
}
{
\abjad-color-music #'red
\time 2/8
g'8
\abjad-color-music #'blue
a'8
}
{
\abjad-color-music #'red
\time 2/8
b'8
c''8
}
}
.. container:: example
Partitions leaves into a single part equal to (or just less than) 3/16;
truncates overhang:
>>> staff = abjad.Staff([
... abjad.Container("c'8 d'"),
... abjad.Container("e'8 f'"),
... abjad.Container("g'8 a'"),
... abjad.Container("b'8 c''"),
... ])
>>> score = abjad.Score([staff], name="Score")
>>> for container in staff:
... time_signature = abjad.TimeSignature((2, 8))
... abjad.attach(time_signature, container[0])
...
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_durations(
... result,
... [abjad.Duration(3, 16)],
... cyclic=False,
... fill=abjad.LESS,
... in_seconds=False,
... overhang=False,
... )
>>> for item in result:
... item
...
[Note("c'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
{
\abjad-color-music #'red
\time 2/8
c'8
d'8
}
{
\time 2/8
e'8
f'8
}
{
\time 2/8
g'8
a'8
}
{
\time 2/8
b'8
c''8
}
}
.. container:: example
Cyclically partitions leaves into parts equal to exactly 1.5 seconds;
truncates overhang:
>>> staff = abjad.Staff([
... abjad.Container("c'8 d'"),
... abjad.Container("e'8 f'"),
... abjad.Container("g'8 a'"),
... abjad.Container("b'8 c''"),
... ])
>>> score = abjad.Score([staff], name="Score")
>>> for container in staff:
... time_signature = abjad.TimeSignature((2, 8))
... abjad.attach(time_signature, container[0])
...
>>> abjad.setting(staff).autoBeaming = False
>>> mark = abjad.MetronomeMark(abjad.Duration(1, 4), 60)
>>> leaf = abjad.get.leaf(staff, 0)
>>> abjad.attach(mark, leaf, context='Staff')
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_durations(
... result,
... [1.5],
... cyclic=True,
... fill=abjad.EXACT,
... in_seconds=True,
... overhang=False,
... )
>>> for item in result:
... item
...
[Note("c'8"), Note("d'8"), Note("e'8")]
[Note("f'8"), Note("g'8"), Note("a'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
{
\abjad-color-music #'red
\tempo 4=60
\time 2/8
c'8
\abjad-color-music #'red
d'8
}
{
\abjad-color-music #'red
\time 2/8
e'8
\abjad-color-music #'blue
f'8
}
{
\abjad-color-music #'blue
\time 2/8
g'8
\abjad-color-music #'blue
a'8
}
{
\time 2/8
b'8
c''8
}
}
.. container:: example
Cyclically partitions leaves into parts equal to exactly 1.5 seconds; returns
overhang at end:
>>> staff = abjad.Staff([
... abjad.Container("c'8 d'"),
... abjad.Container("e'8 f'"),
... abjad.Container("g'8 a'"),
... abjad.Container("b'8 c''"),
... ])
>>> score = abjad.Score([staff], name="Score")
>>> for container in staff:
... time_signature = abjad.TimeSignature((2, 8))
... abjad.attach(time_signature, container[0])
...
>>> abjad.setting(staff).autoBeaming = False
>>> mark = abjad.MetronomeMark(abjad.Duration(1, 4), 60)
>>> leaf = abjad.get.leaf(staff, 0)
>>> abjad.attach(mark, leaf, context='Staff')
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_durations(
... result,
... [1.5],
... cyclic=True,
... fill=abjad.EXACT,
... in_seconds=True,
... overhang=True,
... )
>>> for item in result:
... item
...
[Note("c'8"), Note("d'8"), Note("e'8")]
[Note("f'8"), Note("g'8"), Note("a'8")]
[Note("b'8"), Note("c''8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
{
\abjad-color-music #'red
\tempo 4=60
\time 2/8
c'8
\abjad-color-music #'red
d'8
}
{
\abjad-color-music #'red
\time 2/8
e'8
\abjad-color-music #'blue
f'8
}
{
\abjad-color-music #'blue
\time 2/8
g'8
\abjad-color-music #'blue
a'8
}
{
\abjad-color-music #'red
\time 2/8
b'8
\abjad-color-music #'red
c''8
}
}
.. container:: example
Partitions leaves into a single part equal to exactly 1.5 seconds; truncates
overhang:
>>> staff = abjad.Staff([
... abjad.Container("c'8 d'"),
... abjad.Container("e'8 f'"),
... abjad.Container("g'8 a'"),
... abjad.Container("b'8 c''"),
... ])
>>> score = abjad.Score([staff], name="Score")
>>> for container in staff:
... time_signature = abjad.TimeSignature((2, 8))
... abjad.attach(time_signature, container[0])
...
>>> abjad.setting(staff).autoBeaming = False
>>> mark = abjad.MetronomeMark(abjad.Duration(1, 4), 60)
>>> leaf = abjad.get.leaf(staff, 0)
>>> abjad.attach(mark, leaf, context='Staff')
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_durations(
... result,
... [1.5],
... cyclic=False,
... fill=abjad.EXACT,
... in_seconds=True,
... overhang=False,
... )
>>> for item in result:
... item
...
[Note("c'8"), Note("d'8"), Note("e'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
{
\abjad-color-music #'red
\tempo 4=60
\time 2/8
c'8
\abjad-color-music #'red
d'8
}
{
\abjad-color-music #'red
\time 2/8
e'8
f'8
}
{
\time 2/8
g'8
a'8
}
{
\time 2/8
b'8
c''8
}
}
.. container:: example
Cyclically partitions leaves into parts equal to (or just less than) 0.75
seconds; truncates overhang:
>>> staff = abjad.Staff([
... abjad.Container("c'8 d'"),
... abjad.Container("e'8 f'"),
... abjad.Container("g'8 a'"),
... abjad.Container("b'8 c''"),
... ])
>>> score = abjad.Score([staff], name="Score")
>>> for container in staff:
... time_signature = abjad.TimeSignature((2, 8))
... abjad.attach(time_signature, container[0])
...
>>> abjad.setting(staff).autoBeaming = False
>>> mark = abjad.MetronomeMark(abjad.Duration(1, 4), 60)
>>> leaf = abjad.get.leaf(staff, 0)
>>> abjad.attach(mark, leaf, context='Staff')
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_durations(
... result,
... [0.75],
... cyclic=True,
... fill=abjad.LESS,
... in_seconds=True,
... overhang=False,
... )
>>> for item in result:
... item
...
[Note("c'8")]
[Note("d'8")]
[Note("e'8")]
[Note("f'8")]
[Note("g'8")]
[Note("a'8")]
[Note("b'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
{
\abjad-color-music #'red
\tempo 4=60
\time 2/8
c'8
\abjad-color-music #'blue
d'8
}
{
\abjad-color-music #'red
\time 2/8
e'8
\abjad-color-music #'blue
f'8
}
{
\abjad-color-music #'red
\time 2/8
g'8
\abjad-color-music #'blue
a'8
}
{
\abjad-color-music #'red
\time 2/8
b'8
c''8
}
}
.. container:: example
Partitions leaves into one part equal to (or just less than) 0.75 seconds;
truncates overhang:
>>> staff = abjad.Staff([
... abjad.Container("c'8 d'"),
... abjad.Container("e'8 f'"),
... abjad.Container("g'8 a'"),
... abjad.Container("b'8 c''"),
... ])
>>> score = abjad.Score([staff], name="Score")
>>> for container in staff:
... time_signature = abjad.TimeSignature((2, 8))
... abjad.attach(time_signature, container[0])
...
>>> abjad.setting(staff).autoBeaming = False
>>> mark = abjad.MetronomeMark(abjad.Duration(1, 4), 60)
>>> leaf = abjad.get.leaf(staff, 0)
>>> abjad.attach(mark, leaf, context='Staff')
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_durations(
... result,
... [0.75],
... cyclic=False,
... fill=abjad.LESS,
... in_seconds=True,
... overhang=False,
... )
>>> for item in result:
... item
...
[Note("c'8")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
{
\abjad-color-music #'red
\tempo 4=60
\time 2/8
c'8
d'8
}
{
\time 2/8
e'8
f'8
}
{
\time 2/8
g'8
a'8
}
{
\time 2/8
b'8
c''8
}
}
Interprets ``fill`` as ``Exact`` when ``fill`` is none.
Parts must equal ``durations`` exactly when ``fill`` is ``Exact``.
Parts must be less than or equal to ``durations`` when ``fill`` is ``Less``.
Parts must be greater or equal to ``durations`` when ``fill`` is ``More``.
Reads ``durations`` cyclically when ``cyclic`` is true.
Reads component durations in seconds when ``in_seconds`` is true.
Returns remaining components at end in final part when ``overhang`` is true.
"""
fill = fill or _enums.EXACT
durations = [_duration.Duration(_) for _ in durations]
if cyclic:
durations = _cyclictuple.CyclicTuple(durations)
result = []
part = []
current_duration_index = 0
target_duration = durations[current_duration_index]
cumulative_duration = _duration.Duration(0)
components_copy = list(argument)
while True:
try:
component = components_copy.pop(0)
except IndexError:
break
component_duration = component._get_duration()
if in_seconds:
component_duration = _getlib._get_duration_in_seconds(component)
candidate_duration = cumulative_duration + component_duration
if candidate_duration < target_duration:
part.append(component)
cumulative_duration = candidate_duration
elif candidate_duration == target_duration:
part.append(component)
result.append(part)
part = []
cumulative_duration = _duration.Duration(0)
current_duration_index += 1
try:
target_duration = durations[current_duration_index]
except IndexError:
break
elif target_duration < candidate_duration:
if fill is _enums.EXACT:
raise Exception("must partition exactly.")
elif fill is _enums.LESS:
result.append(part)
part = [component]
if in_seconds:
sum_ = sum([_getlib._get_duration_in_seconds(_) for _ in part])
cumulative_duration = _duration.Duration(sum_)
else:
sum_ = sum([_getlib._get_duration(_) for _ in part])
cumulative_duration = _duration.Duration(sum_)
current_duration_index += 1
try:
target_duration = durations[current_duration_index]
except IndexError:
break
if target_duration < cumulative_duration:
message = f"target duration {target_duration} is less"
message += " than cumulative duration"
message += f" {cumulative_duration}."
raise Exception(message)
elif fill is _enums.MORE:
part.append(component)
result.append(part)
part = []
cumulative_duration = _duration.Duration(0)
current_duration_index += 1
try:
target_duration = durations[current_duration_index]
except IndexError:
break
if len(part):
if overhang:
result.append(part)
if len(components_copy):
if overhang:
result.append(components_copy)
selections = [list(_) for _ in result]
return selections
[docs]def partition_by_ratio(argument, ratio) -> list[list]:
r"""
Partitions items in ``argument`` by ``ratio``.
Partitions leaves by a ratio of 1:1:
.. container:: example
>>> string = r"c'8 d' r \times 2/3 { e' r f' } g' a' r"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_ratio(result, (1, 1))
>>> for item in result:
... item
...
[Note("c'8"), Note("d'8"), Rest('r8'), Note("e'8"), Rest('r8')]
[Note("f'8"), Note("g'8"), Note("a'8"), Rest('r8')]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
d'8
\abjad-color-music #'red
r8
\times 2/3
{
\abjad-color-music #'red
e'8
\abjad-color-music #'red
r8
\abjad-color-music #'blue
f'8
}
\abjad-color-music #'blue
g'8
\abjad-color-music #'blue
a'8
\abjad-color-music #'blue
r8
}
.. container:: example
Partitions leaves by a ratio of 1:1:1:
>>> string = r"c'8 d' r \times 2/3 { e' r f' } g' a' r"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.partition_by_ratio(result, (1, 1, 1))
>>> for item in result:
... item
...
[Note("c'8"), Note("d'8"), Rest('r8')]
[Note("e'8"), Rest('r8'), Note("f'8")]
[Note("g'8"), Note("a'8"), Rest('r8')]
>>> abjad.label.by_selector(result, colors=["#red", "#blue", "#cyan"])
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
d'8
\abjad-color-music #'red
r8
\times 2/3
{
\abjad-color-music #'blue
e'8
\abjad-color-music #'blue
r8
\abjad-color-music #'blue
f'8
}
\abjad-color-music #'cyan
g'8
\abjad-color-music #'cyan
a'8
\abjad-color-music #'cyan
r8
}
"""
ratio = ratio or (1,)
counts = _math.partition_integer_by_ratio(len(argument), ratio)
parts = _sequence.partition_by_counts(argument, counts=counts)
selections = [list(_) for _ in parts]
return selections
[docs]def rest(
argument,
n: int,
*,
exclude: _typings.Exclude | None = None,
grace: bool | None = None,
) -> _score.Rest | _score.MultimeasureRest:
r"""
Selects rest ``n`` in ``argument``.
Selects rest -1:
.. container:: example
>>> tuplets = [
... "r16 bf'16 <a'' b''>16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 bf'16 <a'' b''>16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 bf'16 <a'' b''>16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.rest(staff, -1)
>>> result
Rest('r16')
>>> abjad.label.by_selector(result, lone=True)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\time 7/4
r16
bf'16
<a'' b''>16
c'16
<d' e'>4
~
<d' e'>16
}
\times 8/9
{
r16
bf'16
<a'' b''>16
d'16
<e' fs'>4
~
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\abjad-color-music #'green
r16
bf'16
<a'' b''>16
e'16
<fs' gs'>4
~
<fs' gs'>16
}
}
}
}
"""
return rests(argument, exclude=exclude, grace=grace)[n]
[docs]def rests(
argument, *, exclude: _typings.Exclude | None = None, grace: bool | None = None
) -> list[_score.Rest | _score.MultimeasureRest]:
r"""
Selects rests in ``argument``.
Selects rests:
.. container:: example
>>> tuplets = [
... "r16 bf'16 <a'' b''>16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 bf'16 <a'' b''>16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 bf'16 <a'' b''>16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.rests(staff)
>>> for item in result:
... item
...
Rest('r16')
Rest('r16')
Rest('r16')
>>> abjad.label.by_selector(result)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\abjad-color-music #'red
\time 7/4
r16
bf'16
<a'' b''>16
c'16
<d' e'>4
~
<d' e'>16
}
\times 8/9
{
\abjad-color-music #'blue
r16
bf'16
<a'' b''>16
d'16
<e' fs'>4
~
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\abjad-color-music #'red
r16
bf'16
<a'' b''>16
e'16
<fs' gs'>4
~
<fs' gs'>16
}
}
}
}
"""
items = []
prototype = (_score.MultimeasureRest, _score.Rest)
for item in components(argument, prototype=prototype, exclude=exclude, grace=grace):
assert isinstance(item, prototype)
items.append(item)
return items
[docs]def run(
argument, n: int, *, exclude: _typings.Exclude | None = None
) -> list[_score.Leaf]:
r"""
Selects run ``n`` in ``argument``.
Selects run -1:
.. container:: example
>>> tuplets = [
... "r16 c'16 c'16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 d'16 d'16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 e'16 e'16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.run(staff, -1)
>>> result
[Note("e'16"), Note("e'16"), Note("e'16"), Chord("<fs' gs'>4"), Chord("<fs' gs'>16")]
>>> abjad.label.by_selector(result, lone=True)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\time 7/4
r16
c'16
c'16
c'16
<d' e'>4
~
<d' e'>16
}
\times 8/9
{
r16
d'16
d'16
d'16
<e' fs'>4
~
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
r16
\abjad-color-music #'green
e'16
\abjad-color-music #'green
e'16
\abjad-color-music #'green
e'16
\abjad-color-music #'green
<fs' gs'>4
~
\abjad-color-music #'green
<fs' gs'>16
}
}
}
}
"""
return runs(argument, exclude=exclude)[n]
[docs]def runs(
argument, *, exclude: _typings.Exclude | None = None, grace: bool | None = None
) -> list[list]:
r"""
Selects runs in ``argument``.
Selects runs:
.. container:: example
>>> tuplets = [
... "r16 c'16 c'16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 d'16 d'16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 e'16 e'16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.runs(staff)
>>> for item in result:
... item
...
[Note("c'16"), Note("c'16"), Note("c'16"), Chord("<d' e'>4"), Chord("<d' e'>16")]
[Note("d'16"), Note("d'16"), Note("d'16"), Chord("<e' fs'>4"), Chord("<e' fs'>16")]
[Note("e'16"), Note("e'16"), Note("e'16"), Chord("<fs' gs'>4"), Chord("<fs' gs'>16")]
>>> abjad.label.by_selector(result)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\time 7/4
r16
\abjad-color-music #'red
c'16
\abjad-color-music #'red
c'16
\abjad-color-music #'red
c'16
\abjad-color-music #'red
<d' e'>4
~
\abjad-color-music #'red
<d' e'>16
}
\times 8/9
{
r16
\abjad-color-music #'blue
d'16
\abjad-color-music #'blue
d'16
\abjad-color-music #'blue
d'16
\abjad-color-music #'blue
<e' fs'>4
~
\abjad-color-music #'blue
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
r16
\abjad-color-music #'red
e'16
\abjad-color-music #'red
e'16
\abjad-color-music #'red
e'16
\abjad-color-music #'red
<fs' gs'>4
~
\abjad-color-music #'red
<fs' gs'>16
}
}
}
}
.. container:: example
REGRESSION. Works with grace note (and containers):
>>> music_voice = abjad.Voice(
... "c'16 d' e' r d'4 e' r8 f'", name="MusicVoice"
... )
>>> container = abjad.BeforeGraceContainer("cs'16")
>>> abjad.attach(container, music_voice[4])
>>> container = abjad.on_beat_grace_container(
... "g'16 gs' a' as'", music_voice[5:7]
... )
>>> abjad.attach(abjad.Articulation(">"), container[0])
>>> container = abjad.AfterGraceContainer("fs'16")
>>> abjad.attach(container, music_voice[-1])
>>> staff = abjad.Staff([music_voice])
>>> result = abjad.select.runs(staff)
>>> for item in result:
... item
...
[Note("c'16"), Note("d'16"), Note("e'16")]
[Note("cs'16"), Note("d'4"), Chord("<e' g'>16"), Note("gs'16"), Note("a'16"), Note("as'16"), Note("e'4")]
[Note("f'8"), Note("fs'16")]
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
{
\context Voice = "MusicVoice"
{
\abjad-color-music #'red
c'16
\abjad-color-music #'red
d'16
\abjad-color-music #'red
e'16
r16
\grace {
\abjad-color-music #'blue
cs'16
}
\abjad-color-music #'blue
d'4
<<
\context Voice = "On_Beat_Grace_Container"
{
\abjad-color-music #'blue
\set fontSize = #-3
\slash
\voiceOne
<
\tweak font-size 0
\tweak transparent ##t
e'
g'
>16
- \accent
[
(
\abjad-color-music #'blue
gs'16
\abjad-color-music #'blue
a'16
\abjad-color-music #'blue
as'16
)
]
}
\context Voice = "MusicVoice"
{
\abjad-color-music #'blue
\voiceTwo
e'4
r8
}
>>
\abjad-color-music #'red
\oneVoice
\afterGrace
f'8
{
\abjad-color-music #'red
fs'16
}
}
}
"""
result = leaves(argument, exclude=exclude, grace=grace, pitched=True)
groups = group_by_contiguity(result)
return groups
[docs]def top(argument, *, exclude: _typings.Exclude | None = None) -> list[_score.Component]:
r"""
Selects top components in ``argument``.
Selects top components (up from leaves):
.. container:: example
>>> string = r"c'8 d' r \times 2/3 { e' r f' } g' a' r"
>>> staff = abjad.Staff(string)
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.leaves(staff)
>>> result = abjad.select.top(result)
>>> for item in result:
... item
...
Note("c'8")
Note("d'8")
Rest('r8')
Tuplet('3:2', "e'8 r8 f'8")
Note("g'8")
Note("a'8")
Rest('r8')
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'blue
d'8
\abjad-color-music #'red
r8
\times 2/3
{
\abjad-color-music #'blue
e'8
\abjad-color-music #'blue
r8
\abjad-color-music #'blue
f'8
}
\abjad-color-music #'red
g'8
\abjad-color-music #'blue
a'8
\abjad-color-music #'red
r8
}
"""
result = []
for component in _iterlib._public_iterate_components(argument, exclude=exclude):
for component_ in _parentage.Parentage(component):
if (
_is_immediate_child_of_outermost_voice(component_)
and component_ not in result
):
result.append(component_)
return result
[docs]def tuplet(
argument,
n: int,
*,
exclude: _typings.Exclude | None = None,
level: int | None = None,
) -> _score.Tuplet:
r"""
Selects tuplet ``n`` in ``argument``.
Selects tuplet -1:
.. container:: example
>>> tuplets = [
... "r16 bf'16 <a'' b''>16 c'16 <d' e'>4 ~ <d' e'>16",
... "r16 bf'16 <a'' b''>16 d'16 <e' fs'>4 ~ <e' fs'>16",
... "r16 bf'16 <a'' b''>16 e'16 <fs' gs'>4 ~ <fs' gs'>16",
... ]
>>> tuplets = zip([(10, 9), (8, 9), (10, 9)], tuplets)
>>> tuplets = [abjad.Tuplet(*_) for _ in tuplets]
>>> lilypond_file = abjad.illustrators.components(tuplets)
>>> staff = lilypond_file["Staff"]
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.override(staff).TupletBracket.direction = abjad.UP
>>> abjad.override(staff).TupletBracket.staff_padding = 3
>>> abjad.show(lilypond_file) # doctest: +SKIP
>>> result = abjad.select.tuplet(staff, -1)
>>> result
Tuplet('9:10', "r16 bf'16 <a'' b''>16 e'16 <fs' gs'>4 <fs' gs'>16")
>>> abjad.label.by_selector(result, lone=True)
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> score = lilypond_file["Score"]
>>> string = abjad.lilypond(score)
>>> print(string)
\context Score = "Score"
{
\context Staff = "Staff"
\with
{
\override TupletBracket.direction = #up
\override TupletBracket.staff-padding = 3
autoBeaming = ##f
}
{
\context Voice = "Voice"
{
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\time 7/4
r16
bf'16
<a'' b''>16
c'16
<d' e'>4
~
<d' e'>16
}
\times 8/9
{
r16
bf'16
<a'' b''>16
d'16
<e' fs'>4
~
<e' fs'>16
}
\tweak text #tuplet-number::calc-fraction-text
\times 10/9
{
\abjad-color-music #'green
r16
\abjad-color-music #'green
bf'16
\abjad-color-music #'green
<a'' b''>16
\abjad-color-music #'green
e'16
\abjad-color-music #'green
<fs' gs'>4
~
\abjad-color-music #'green
<fs' gs'>16
}
}
}
}
"""
return tuplets(argument, exclude=exclude, level=level)[n]
[docs]def tuplets(
argument, *, exclude: _typings.Exclude | None = None, level: int | None = None
) -> list[_score.Tuplet]:
r"""
Selects tuplets in ``argument``.
Selects tuplets at every level:
.. container:: example
>>> staff = abjad.Staff(
... r"\times 2/3 { c'2 \times 2/3 { d'8 e' f' } } \times 2/3 { c'4 d' e' }"
... )
>>> result = abjad.select.tuplets(staff)
>>> for item in result:
... item
...
Tuplet('3:2', "c'2 { 2/3 d'8 e'8 f'8 }")
Tuplet('3:2', "d'8 e'8 f'8")
Tuplet('3:2', "c'4 d'4 e'4")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
{
\times 2/3
{
\abjad-color-music #'red
c'2
\times 2/3
{
\abjad-color-music #'blue
\abjad-color-music #'red
d'8
\abjad-color-music #'blue
\abjad-color-music #'red
e'8
\abjad-color-music #'blue
\abjad-color-music #'red
f'8
}
}
\times 2/3
{
\abjad-color-music #'red
c'4
\abjad-color-music #'red
d'4
\abjad-color-music #'red
e'4
}
}
.. container:: example
Selects tuplets at level -1:
>>> staff = abjad.Staff(
... r"\times 2/3 { c'2 \times 2/3 { d'8 e' f' } } \times 2/3 { c'4 d' e' }"
... )
>>> result = abjad.select.tuplets(staff, level=-1)
>>> for item in result:
... item
...
Tuplet('3:2', "d'8 e'8 f'8")
Tuplet('3:2', "c'4 d'4 e'4")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
{
\times 2/3
{
c'2
\times 2/3
{
\abjad-color-music #'red
d'8
\abjad-color-music #'red
e'8
\abjad-color-music #'red
f'8
}
}
\times 2/3
{
\abjad-color-music #'blue
c'4
\abjad-color-music #'blue
d'4
\abjad-color-music #'blue
e'4
}
}
Tuplets at level -1 are bottom-level tuplet: tuplets at level -1 contain only
one tuplet (themselves) and do not contain any other tuplets.
.. container:: example
Selects tuplets at level 1:
>>> staff = abjad.Staff(
... r"\times 2/3 { c'2 \times 2/3 { d'8 e' f' } } \times 2/3 { c'4 d' e' }"
... )
>>> result = abjad.select.tuplets(staff, level=1)
>>> for item in result:
... item
...
Tuplet('3:2', "c'2 { 2/3 d'8 e'8 f'8 }")
Tuplet('3:2', "c'4 d'4 e'4")
>>> abjad.label.by_selector(result)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
{
\times 2/3
{
\abjad-color-music #'red
c'2
\times 2/3
{
\abjad-color-music #'red
d'8
\abjad-color-music #'red
e'8
\abjad-color-music #'red
f'8
}
}
\times 2/3
{
\abjad-color-music #'blue
c'4
\abjad-color-music #'blue
d'4
\abjad-color-music #'blue
e'4
}
}
Tuplets at level 1 are top-level tuplets: level-1 tuplets contain only 1
tuplet (themselves) and are not contained by any other tuplets.
"""
tuplets: list[_score.Tuplet] = []
for item in components(argument, _score.Tuplet, exclude=exclude):
assert isinstance(item, _score.Tuplet)
tuplets.append(item)
if level is None:
return tuplets
elif level < 0:
result = []
for tuplet in tuplets:
count = 0
for component in _iterlib._iterate_descendants(tuplet):
if isinstance(component, _score.Tuplet):
count += 1
if -count == level:
result.append(tuplet)
else:
result = []
for tuplet in tuplets:
if _parentage.Parentage(tuplet).count(_score.Tuplet) == level:
result.append(tuplet)
return result
[docs]def with_next_leaf(argument, *, grace: bool | None = None) -> list[_score.Leaf]:
r"""
Extends ``argument`` with next leaf.
Selects runs (each with next leaf):
.. container:: example
>>> staff = abjad.Staff("c'8 r8 d'8 e'8 r8 f'8 g'8 a'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.runs(staff)
>>> result = [abjad.select.with_next_leaf(_) for _ in result]
>>> for item in result:
... item
...
[Note("c'8"), Rest('r8')]
[Note("d'8"), Note("e'8"), Rest('r8')]
[Note("f'8"), Note("g'8"), Note("a'8")]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
r8
\abjad-color-music #'blue
d'8
\abjad-color-music #'blue
e'8
\abjad-color-music #'blue
r8
\abjad-color-music #'red
f'8
\abjad-color-music #'red
g'8
\abjad-color-music #'red
a'8
}
.. container:: example
Selects pitched tails (each with next leaf):
>>> staff = abjad.Staff(r"c'8 r d' ~ d' e' ~ e' r8 f'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff, pitched=True)
>>> result = [abjad.select.with_next_leaf(_[-1:]) for _ in result]
>>> for item in result:
... item
...
[Note("c'8"), Rest('r8')]
[Note("d'8"), Note("e'8")]
[Note("e'8"), Rest('r8')]
[Note("f'8")]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'red
r8
d'8
~
\abjad-color-music #'blue
d'8
\abjad-color-music #'blue
e'8
~
\abjad-color-music #'red
e'8
\abjad-color-music #'red
r8
\abjad-color-music #'blue
f'8
}
.. container:: example
Pitched logical ties (each with next leaf) is the correct selection
for single-pitch sustain pedal applications.
Selects pitched logical ties (each with next leaf):
>>> staff = abjad.Staff(r"c'8 r d' ~ d' e' ~ e' r8 f'8")
>>> abjad.setting(staff).autoBeaming = False
>>> abjad.setting(staff).pedalSustainStyle = "#'mixed"
>>> result = abjad.select.logical_ties(staff, pitched=True)
>>> result = [abjad.select.with_next_leaf(_) for _ in result]
>>> for item in result:
... item
...
[Note("c'8"), Rest('r8')]
[Note("d'8"), Note("d'8"), Note("e'8")]
[Note("e'8"), Note("e'8"), Rest('r8')]
[Note("f'8")]
>>> for item in result:
... abjad.piano_pedal(item, context="Staff")
...
>>> abjad.label.by_selector(result, True)
>>> abjad.override(staff).SustainPedalLineSpanner.staff_padding = 6
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
\override SustainPedalLineSpanner.staff-padding = 6
autoBeaming = ##f
pedalSustainStyle = #'mixed
}
{
\abjad-color-music #'red
c'8
\sustainOn
\abjad-color-music #'red
r8
\sustainOff
\abjad-color-music #'blue
d'8
\sustainOn
~
\abjad-color-music #'blue
d'8
\abjad-color-music #'blue
\abjad-color-music #'red
e'8
\sustainOff
\sustainOn
~
\abjad-color-music #'red
e'8
\abjad-color-music #'red
r8
\sustainOff
\abjad-color-music #'blue
f'8
\sustainOff
\sustainOn
}
.. container:: example
REGRESSION. Works with grace note (and containers):
>>> music_voice = abjad.Voice("c'4 d' e' f'", name="MusicVoice")
>>> container = abjad.BeforeGraceContainer("cs'16")
>>> abjad.attach(container, music_voice[1])
>>> container = abjad.on_beat_grace_container(
... "g'16 gs' a' as'", music_voice[2:3]
... )
>>> abjad.attach(abjad.Articulation(">"), container[0])
>>> container = abjad.AfterGraceContainer("fs'16")
>>> abjad.attach(container, music_voice[3])
>>> staff = abjad.Staff([music_voice])
>>> prototype = (
... abjad.BeforeGraceContainer,
... abjad.OnBeatGraceContainer,
... abjad.AfterGraceContainer,
... )
>>> result = abjad.select.components(staff, prototype)
>>> result = [abjad.select.leaves(_) for _ in result]
>>> result = [abjad.select.with_next_leaf(_) for _ in result]
>>> for item in result:
... item
...
[Note("cs'16"), Note("d'4")]
[Chord("<e' g'>16"), Note("gs'16"), Note("a'16"), Note("as'16"), Note("e'4")]
[Note("fs'16")]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
{
\context Voice = "MusicVoice"
{
c'4
\grace {
\abjad-color-music #'red
cs'16
}
\abjad-color-music #'red
d'4
<<
\context Voice = "On_Beat_Grace_Container"
{
\abjad-color-music #'blue
\set fontSize = #-3
\slash
\voiceOne
<
\tweak font-size 0
\tweak transparent ##t
e'
g'
>16
- \accent
[
(
\abjad-color-music #'blue
gs'16
\abjad-color-music #'blue
a'16
\abjad-color-music #'blue
as'16
)
]
}
\context Voice = "MusicVoice"
{
\abjad-color-music #'blue
\voiceTwo
e'4
}
>>
\oneVoice
\afterGrace
f'4
{
\abjad-color-music #'red
fs'16
}
}
}
"""
items = leaves(argument)
previous_leaf = items[-1]
while True:
next_leaf = _iterlib._get_leaf(previous_leaf, n=1)
if next_leaf is None:
break
if (
grace is None
or (grace is True and _getlib._get_grace_container(next_leaf))
or (grace is False and not _getlib._get_grace_container(next_leaf))
):
items.append(next_leaf)
break
previous_leaf = next_leaf
return items
[docs]def with_previous_leaf(argument) -> list[_score.Leaf]:
r"""
Extends ``argument`` with previous leaf.
Selects runs (each with previous leaf):
.. container:: example
>>> staff = abjad.Staff("c'8 r8 d'8 e'8 r8 f'8 g'8 a'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.runs(staff)
>>> result = [abjad.select.with_previous_leaf(_) for _ in result]
>>> for item in result:
... item
...
[Note("c'8")]
[Rest('r8'), Note("d'8"), Note("e'8")]
[Rest('r8'), Note("f'8"), Note("g'8"), Note("a'8")]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'blue
r8
\abjad-color-music #'blue
d'8
\abjad-color-music #'blue
e'8
\abjad-color-music #'red
r8
\abjad-color-music #'red
f'8
\abjad-color-music #'red
g'8
\abjad-color-music #'red
a'8
}
.. container:: example
Selects pitched heads (each with previous leaf):
>>> staff = abjad.Staff(r"c'8 r d' ~ d' e' ~ e' r8 f'8")
>>> abjad.setting(staff).autoBeaming = False
>>> result = abjad.select.logical_ties(staff, pitched=True)
>>> result = [abjad.select.with_previous_leaf(_[:1]) for _ in result]
>>> for item in result:
... item
...
[Note("c'8")]
[Rest('r8'), Note("d'8")]
[Note("d'8"), Note("e'8")]
[Rest('r8'), Note("f'8")]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
\with
{
autoBeaming = ##f
}
{
\abjad-color-music #'red
c'8
\abjad-color-music #'blue
r8
\abjad-color-music #'blue
d'8
~
\abjad-color-music #'red
d'8
\abjad-color-music #'red
e'8
~
e'8
\abjad-color-music #'blue
r8
\abjad-color-music #'blue
f'8
}
.. container:: example
REGRESSION. Works with grace note (and containers):
>>> music_voice = abjad.Voice("c'4 d' e' f'", name="MusicVoice")
>>> container = abjad.BeforeGraceContainer("cs'16")
>>> abjad.attach(container, music_voice[1])
>>> container = abjad.on_beat_grace_container(
... "g'16 gs' a' as'", music_voice[2:3]
... )
>>> abjad.attach(abjad.Articulation(">"), container[0])
>>> container = abjad.AfterGraceContainer("fs'16")
>>> abjad.attach(container, music_voice[3])
>>> staff = abjad.Staff([music_voice])
>>> prototype = (
... abjad.BeforeGraceContainer,
... abjad.OnBeatGraceContainer,
... abjad.AfterGraceContainer,
... )
>>> result = abjad.select.components(staff, prototype)
>>> result = [abjad.select.leaves(_) for _ in result]
>>> result = [abjad.select.with_previous_leaf(_) for _ in result]
>>> for item in result:
... item
...
[Note("c'4"), Note("cs'16")]
[Note("d'4"), Chord("<e' g'>16"), Note("gs'16"), Note("a'16"), Note("as'16")]
[Note("f'4"), Note("fs'16")]
>>> abjad.label.by_selector(result, True)
>>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', staff])
>>> abjad.show(lilypond_file) # doctest: +SKIP
.. docs::
>>> string = abjad.lilypond(staff)
>>> print(string)
\new Staff
{
\context Voice = "MusicVoice"
{
\abjad-color-music #'red
c'4
\grace {
\abjad-color-music #'red
cs'16
}
\abjad-color-music #'blue
d'4
<<
\context Voice = "On_Beat_Grace_Container"
{
\abjad-color-music #'blue
\set fontSize = #-3
\slash
\voiceOne
<
\tweak font-size 0
\tweak transparent ##t
e'
g'
>16
- \accent
[
(
\abjad-color-music #'blue
gs'16
\abjad-color-music #'blue
a'16
\abjad-color-music #'blue
as'16
)
]
}
\context Voice = "MusicVoice"
{
\voiceTwo
e'4
}
>>
\abjad-color-music #'red
\oneVoice
\afterGrace
f'4
{
\abjad-color-music #'red
fs'16
}
}
}
"""
items = leaves(argument)
previous_leaf = _iterlib._get_leaf(items[0], n=-1)
if previous_leaf is not None:
items.insert(0, previous_leaf)
return items