Shuffler

class auxjad.Shuffler(contents: abjad.score.Container, *, pitch_only: bool = False, preserve_rest_position: bool = False, disable_rewrite_meter: bool = False, omit_time_signatures: bool = False, boundary_depth: Optional[int] = None, maximum_dot_count: Optional[int] = None, rewrite_tuplets: bool = True, process_on_first_call: bool = True, prettify_rewrite_meter: bool = True, extract_trivial_tuplets: bool = True, fuse_across_groups_of_beats: bool = True, fuse_quadruple_meter: bool = True, fuse_triple_meter: bool = True, swap_limit: Optional[int] = None)[source]

Takes an abjad.Container (or child class) and shuffles or rotates its logical ties or pitches. When shuffling or rotating pitches only, tuplets are supported, otherwise tuplets are not supported.

Basic usage:

Calling the object will output a shuffled selection of the input container.

>>> container = abjad.Container(r"c'4 d'4 e'4 f'4")
>>> abjad.show(container)
../_images/Shuffler-1oLQZeQNPo.png
>>> shuffler = auxjad.Shuffler(container)
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-z2om98675v.png
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-xu7sln4vt7n.png

To get the result of the last operation, use the property current_window.

>>> notes = shuffler.current_window
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-gphtpqn9jb.png

Calling the object outputs the same result as using the method shuffle().

>>> notes = shuffler.shuffle()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-g965k0d03if.png

Warning

Unlike the other classes in Auxjad, the very first call of an instance of this class will already process the initial container. To disable this behaviour and output the initial container once before shuffling or rotating it, initialise the class with the keyword argument process_on_first_call set to False.

>>> container = abjad.Container(r"c'4 d'4 e'4 f'4")
>>> shuffler = auxjad.Shuffler(container,
...                            process_on_first_call=False,
...                            )
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-76039tn5b9k.png
len():

Applying the len() function to the shuffler will return the number of logical ties of contents.

>>> container = abjad.Container(r"c'4 d'4 e'4 f'4 ~ | f'2 g'2")
>>> shuffler = auxjad.Shuffler(container)
>>> len(shuffler)
5

Do note that consecutive rests are considered as a single logical tie, so in the example below the len() function returns 5 and not 6. When shuffling or rotating logical ties, consecutive rests are also shuffled and rotated together.

>>> container = abjad.Container(r"c'8. d'4 r8 r8. e'16 f'8.")
>>> shuffler = auxjad.Shuffler(container)
>>> len(shuffler)
5
Arguments and properties:

This class has many keyword arguments, all of which can be altered after instantiation using properties with the same names as shown below. Setting pitch_only to True will enable pitch mode; by default, this class shuffles and rotates logical ties, but in pitch mode only pitches are shuffled or rotated. By setting preserve_rest_position to True the shuffle and rotation operations will not change the position or duration of rests. disable_rewrite_meter disables the abjad.Meter.rewrite_meter() mutation which is applied to the container after every call, and omit_time_signatures will remove all time signatures from the output (both are False by default). The properties boundary_depth, maximum_dot_count, and rewrite_tuplets are passed as arguments to abjad.Meter.rewrite_meter(), see its documentation for more information. By default, calling the object will first return the original container and subsequent calls will process it; set process_on_first_call to True and the shuffling process will be applied on the very first call.

>>> container = abjad.Container(
...     r"\time 3/4 c'4 d'4 e'4 \time 2/4 f'4 g'4"
... )
>>> shuffler = auxjad.Shuffler(container,
...                            pitch_only=False,
...                            preserve_rest_position=True,
...                            disable_rewrite_meter=False,
...                            omit_time_signatures=True,
...                            boundary_depth=0,
...                            maximum_dot_count=1,
...                            rewrite_tuplets=False,
...                            process_on_first_call=True,
...                            swap_limit=3,
...                            )
>>> shuffler.pitch_only
False
>>> shuffler.preserve_rest_position
True
>>> shuffler.disable_rewrite_meter
False
>>> shuffler.omit_time_signatures
True
>>> shuffler.boundary_depth
0
>>> shuffler.maximum_dot_count
1
>>> shuffler.rewrite_tuplets
False
>>> shuffler.process_on_first_call
True
>>> shuffler.swap_limit
3

Use the properties below to change these values after initialisation.

>>> shuffler.pitch_only = True
>>> shuffler.preserve_rest_position = False
>>> shuffler.disable_rewrite_meter = True
>>> shuffler.omit_time_signatures = False
>>> shuffler.boundary_depth = 1
>>> shuffler.maximum_dot_count = 2
>>> shuffler.rewrite_tuplets = True
>>> shuffler.process_on_first_call = False
>>> shuffler.swap_limit = None
>>> shuffler.pitch_only
True
>>> shuffler.preserve_rest_position
True
>>> shuffler.disable_rewrite_meter
True
>>> shuffler.omit_time_signatures
False
>>> shuffler.boundary_depth
1
>>> shuffler.maximum_dot_count
2
>>> shuffler.rewrite_tuplets
True
>>> shuffler.process_on_first_call
False
>>> shuffler.swap_limit
None
pitch_only:

By default, the shuffling operation will shuffle logical ties:

>>> container = abjad.Container(r"c'8. d'4 r8 r8. e'16 f'8.")
>>> shuffler = auxjad.Shuffler(container)
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-5j79m0wuxu.png

Setting pitch_only to True enables pitch mode, so only pitches are shuffled (and not durations). Note how in the example below the duration of each leaf is the same as the input container.

>>> container = abjad.Container(r"c'8. d'4 r8 r8. e'16 f'8.")
>>> shuffler = auxjad.Shuffler(container, pitch_only=True)
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-f9jbzqkrkdf.png

Note

Altering the value of pitch_only: will replace the original contents: with the contents of current_window. Note how in the example below, the shuffled leaves in measure 3 comes from the previous measure and not from the initial contents:.

>>> container = abjad.Container(r"c'4.. d'16 e'4. f'8")
>>> shuffler = auxjad.Shuffler(container, pitch_only=True)
>>> notes = shuffler.shuffle_n(2)
>>> staff = abjad.Staff(notes)
>>> shuffler.pitch_only = False
>>> notes = shuffler.shuffle_n(2)
>>> staff.append(notes)
>>> auxjad.mutate.remove_repeated_time_signatures(staff[:])
>>> abjad.show(staff)
../_images/Shuffler-tyq8y6q8zr9.png
swap_limit:

The attribute swap_limit can be used to set the number of times that pairs of elements are swapped on a single invocation of the shuffling process. Set swap_limit to None to not limit the shuffling process.

>>> container = abjad.Container(r"c'8 d'8 e'8 f'8 g'8 a'8 b'8 c''8")
>>> shuffler = auxjad.Shuffler(container,
...                            swap_limit=1,
...                            )
>>> notes = shuffler.shuffle_n(3)
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-Nbo5S6wcfQ.png
rotate():

Besides shuffling, logical ties and pitches can also be rotated using the rotate() method. Similarly to shuffling, it can be applied to logical ties or pitches only depending on the property pitch_only.

>>> container = abjad.Container(
...     r"\time 3/4 c'16 d'8. ~ d'4 e'4 r4 f'4 ~ f'8.. g'32"
... )
>>> shuffler = auxjad.Shuffler(container)
>>> notes = shuffler.rotate()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-7vamgsxlr6.png
>>> container = abjad.Container(
...     r"\time 3/4 c'16 d'8. ~ d'4 e'4 r4 f'4 ~ f'8.. g'32"
... )
>>> shuffler = auxjad.Shuffler(container, pitch_only=True)
>>> notes = shuffler.rotate()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-89cx79bjji8.png

This method can also take the optional parameters n_rotations and anticlockwise. The first is an int setting the number of rotations applied to the material, and the second is a bool setting the direction of the rotation (default False).

>>> container = abjad.Container(
...     r"\time 3/4 c'16 d'8. ~ d'4 e'4 r4 f'4 ~ f'8.. g'32"
... )
>>> shuffler = auxjad.Shuffler(container, pitch_only=True)
>>> notes = shuffler.rotate(n_rotations=2, anticlockwise=True)
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-g6v6wjm12ub.png
preserve_rest_position:

If preserve_rest_position is set to True, the positions of all rests will remain the same after either shuffling and rotation. In pitch mode (when pitch_only is set to True), this means that only the pitched notes will be shuffled or rotated, while the rests remain in the exact same place.

>>> container = abjad.Container(r"c'8. d'4 r8 r8. e'16 f'8.")
>>> shuffler = auxjad.Shuffler(container,
...                            pitch_only=True,
...                            preserve_rest_position=True,
...                            )
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-pmou83f7rlj.png

In logical ties mode, the rests will remain at the same index and will have the same total duration as before, but their position in the measure might vary since the duration of the pitched logical ties preceding it might change.

>>> container = abjad.Container(r"c'8. d'4 r8 r8. e'16 f'8.")
>>> shuffler = auxjad.Shuffler(container, preserve_rest_position=True)
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-7hbp2kdpqof.png
disable_rewrite_meter:

If disable_rewrite_meter is set to True, then the automatic behaviour of rewriting the leaves according to the meter is disabled.

>>> container = abjad.Container(r"c'4 d'8 e'8 f'2")
>>> shuffler = auxjad.Shuffler(container,
...                            disable_rewrite_meter=True,
...                            )
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-tb78izpzvjp.png
shuffle_n() and rotate_n():

To output several shuffled containers at once, use the methods shuffle_n() and rotate_n(), inputting the desired number of iterations. rotate_n() can also take the optional arguments n_rotations and anticlockwise, similarly to rotate().

>>> container = abjad.Container(r"c'4 d'8 e'4. f'8. g'16")
>>> shuffler = auxjad.Shuffler(container)
>>> notes = shuffler.shuffle_n(2)
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-vtia65lbk5.png
>>> container = abjad.Container(r"c'4 d'8 e'4. f'8. g'16")
>>> shuffler = auxjad.Shuffler(container)
>>> notes = shuffler.rotate_n(2)
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-3dqhy8eoiez.png
omit_time_signatures:

To disable time signatures altogether, initialise this class with the keyword argument omit_time_signatures set to True (default is False), or change the omit_time_signatures property after initialisation.

>>> container = abjad.Container(r"\time 3/4 c'16 d'4.. e'4 | r4 f'2")
>>> shuffler = auxjad.Shuffler(container,
...                            omit_time_signatures=True,
...                            )
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-1v3lwhj430b.png

Tip

All methods that return an abjad.Selection will add an initial time signature to it. The shuffle_n() and rotate_n() methods automatically remove repeated time signatures. When joining selections output by multiple method calls, use auxjad.mutate.remove_repeated_time_signatures() on the whole container after fusing the selections to remove any unecessary time signature changes.

Time signature changes:

This class handles time signature changes too:

>>> container = abjad.Container(
...     r"\time 3/4 c'8. d'4 r8 r8. \time 2/4 e'16 f'4.."
... )
>>> shuffler = auxjad.Shuffler(container)
>>> notes = shuffler.shuffle_n(2)
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-yx11u6o14v.png
Tuplet support:

Tuplets are supported when pitch_only is True (pitch-only mode).

>>> container = abjad.Container(
...     r"\time 5/4 r4 \times 2/3 {c'4 d'2} e'4. f'8"
... )
>>> shuffler = auxjad.Shuffler(container, pitch_only=True)
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-mjxubkel8y.png

Error

Tuplets are not supported when pitch_only is False (logical tie mode). Using a container with tuplets and pitch_only set to True will raise a TypeError exception.

>>> container = abjad.Container(
...     r"\time 5/4 r4 \times 2/3 {c'4 d'2} e'4. f'8"
... )
>>> shuffler = auxjad.Shuffler(container)
>>> notes = shuffler()
TypeError: 'contents' contain one ore more tuplets, which are not
currently supported by the shuffle method
Indicators:

This class can also handle dynamics and articulations.

>>> container = abjad.Container(
...     r"<c' e' g'>4--\p d'8-. e'8-. f'4-^\f r4"
... )
>>> shuffler = auxjad.Shuffler(container)
>>> notes = shuffler.shuffle_n(3)
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-2ibui58pj8w.png

Tip

The functions auxjad.mutate.remove_repeated_dynamics() and auxjad.mutate.reposition_clefs() can be used to clean the output and remove repeated dynamics and unnecessary clef changes.

Warning

Do note that some elements that span multiple notes (such as ottava indicators, manual beams, etc.) can become problematic when notes containing them are split into two. As a rule of thumb, it is always better to attach those to the music after the fading process has ended. In the case of shuffling logical ties, slurs and hairpins can also become a problem, since their start and end position can shift around. Dynamics are shuffled together with their leaves, so the initial leaf may lack a dynamic marking.

contents:

Use the property contents to get the input container upon which the shuffler operates. Notice that contents remains invariant after any shuffling or rotation operations (use current_window for the transformed selection of music). contents can be used to change the abjad.Container to be shuffled.

>>> container = abjad.Container(r"c'4 d'4 e'4 f'4")
>>> shuffler = auxjad.Shuffler(container)
>>> abjad.show(shuffler.contents)
../_images/Shuffler-qsee7chymo.png
>>> shuffler()
>>> abjad.show(shuffler.contents)
../_images/Shuffler-ii3fxe001ki.png
>>> shuffler.contents = abjad.Container(r"cs2 ds2")
>>> abjad.show(shuffler.contents)
../_images/Shuffler-p2vd4mfvucp.png
Tweaking abjad.Meter.rewrite_meter():

This function uses the default logical tie splitting algorithm from abjad.Meter.rewrite_meter().

>>> container = abjad.Container(r"c'4. d'8 e'2")
>>> shuffler = auxjad.Shuffler(container)
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-t4lsqxg18ab.png

Set boundary_depth to a different number to change its behaviour.

>>> shuffler = auxjad.Shuffler(container,
...                            boundary_depth=1,
...                            )
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-7na5znnhhwe.png

Other arguments available for tweaking the output of abjad.Meter.rewrite_meter() are maximum_dot_count and rewrite_tuplets, which work exactly as the identically named arguments of abjad.Meter.rewrite_meter().

This class also accepts the arguments fuse_across_groups_of_beats, fuse_quadruple_meter, fuse_triple_meter, and extract_trivial_tuplets, which are passed on to auxjad.mutate.prettify_rewrite_meter() (the latter can be disabled by setting prettify_rewrite_meter to False). See the documentation of this function for more details on these arguments.

disable_rewrite_meter:

By default, this class uses the abjad.Meter.rewrite_meter() mutation.

>>> container = abjad.Container(r"c'4 d'8 e'8 f'2")
>>> shuffler = auxjad.Shuffler(container)
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-7cfnxx7shci.png

Set disable_rewrite_meter to True in order to disable this behaviour.

>>> container = abjad.Container(r"c'4 d'8. e'16 f'2")
>>> abjad.show(container)
../_images/Shuffler-6gm4ev48j9k.png
>>> shuffler = auxjad.Shuffler(container,
...                            disable_rewrite_meter=True,
...                            )
>>> notes = shuffler()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/Shuffler-xlr4x3bhj6n.png
Using as iterator:

The instances of this class can also be used as an iterator, which can then be used in a for loop. Note that unlike the methods shuffle_n() and rotate_n(), time signatures are added to each window returned by the shuffler. Use the function auxjad.mutate.remove_repeated_time_signatures() to clean the output when using this class in this way. It is also important to note that a break statement is needed when using this class as an iterator. The reason is that shuffling is a process that can happen indefinitely (unlike some of the other classes in this library).

>>> container = abjad.Container(r"\time 3/4 c'4 d'4 e'4")
>>> shuffler = auxjad.Shuffler(container)
>>> staff = abjad.Staff()
>>> for window in shuffler:
...     staff.append(window)
...     if abjad.get.duration(staff) == abjad.Duration((9, 4)):
...         break
>>> auxjad.mutate.remove_repeated_time_signatures(staff[:])
>>> abjad.show(staff)
../_images/Shuffler-3gyz7atvemx.png

Methods

__call__()

Calls the shuffling process, returning an abjad.Selection

__init__(contents, *[, pitch_only, …])

Initialises self.

__iter__()

Returns an iterator, allowing instances to be used as iterators.

__len__()

Returns the number of logical ties of contents.

__next__()

Calls the shuffling process for one iteration, returning an abjad.Selection.

__repr__()

Returns interpreter representation of contents.

rotate(*[, n_rotations, anticlockwise])

Rotates logical ties or pitches of contents.

rotate_n(n, *[, n_rotations, anticlockwise])

Goes through n iterations of the pitch shuffling process and outputs a single abjad.Selection.

shuffle()

Shuffles logical ties or pitches of contents.

shuffle_n(n)

Goes through n iterations of the shuffling process and outputs a single abjad.Selection.

Attributes

boundary_depth

Sets the argument boundary_depth of abjad.Meter.rewrite_meter().

contents

The abjad.Container to be shuffled.

current_window

Read-only property, returns the result of the last operation.

disable_rewrite_meter

When True, the durations of the notes in the output will not be rewritten by the abjad.Meter.rewrite_meter() mutation.

extract_trivial_tuplets

Sets the argument extract_trivial_tuplets of auxjad.mutate.prettify_rewrite_meter().

fuse_across_groups_of_beats

Sets the argument fuse_across_groups_of_beats of auxjad.mutate.prettify_rewrite_meter().

fuse_quadruple_meter

Sets the argument fuse_quadruple_meter of auxjad.mutate.prettify_rewrite_meter().

fuse_triple_meter

Sets the argument fuse_triple_meter of auxjad.mutate.prettify_rewrite_meter().

maximum_dot_count

Sets the argument maximum_dot_count of abjad.Meter.rewrite_meter().

omit_time_signatures

When True, the output will contain no time signatures.

pitch_only

When True, only the pitches will be shuffled or rotated while the durations remain the same.

preserve_rest_position

When True, shuffle operations will preserve rest positions and durations.

prettify_rewrite_meter

Used to enable or disable the mutation auxjad.mutate.prettify_rewrite_meter() (default True).

process_on_first_call

If True then contents will be processed in the very first call.

rewrite_tuplets

Sets the argument rewrite_tuplets of abjad.Meter.rewrite_meter().

swap_limit

If int then it dictates how instances of random swapping of pairs of elements are applied to contents in each iteration.

__call__()abjad.select.Selection[source]

Calls the shuffling process, returning an abjad.Selection

__init__(contents: abjad.score.Container, *, pitch_only: bool = False, preserve_rest_position: bool = False, disable_rewrite_meter: bool = False, omit_time_signatures: bool = False, boundary_depth: Optional[int] = None, maximum_dot_count: Optional[int] = None, rewrite_tuplets: bool = True, process_on_first_call: bool = True, prettify_rewrite_meter: bool = True, extract_trivial_tuplets: bool = True, fuse_across_groups_of_beats: bool = True, fuse_quadruple_meter: bool = True, fuse_triple_meter: bool = True, swap_limit: Optional[int] = None)None[source]

Initialises self.

__iter__()None[source]

Returns an iterator, allowing instances to be used as iterators.

__len__()int[source]

Returns the number of logical ties of contents.

__next__()abjad.select.Selection[source]

Calls the shuffling process for one iteration, returning an abjad.Selection.

__repr__()str[source]

Returns interpreter representation of contents.

property boundary_depth: Optional[int]

Sets the argument boundary_depth of abjad.Meter.rewrite_meter().

property contents: abjad.score.Container

The abjad.Container to be shuffled.

property current_window: abjad.select.Selection

Read-only property, returns the result of the last operation.

property disable_rewrite_meter: bool

When True, the durations of the notes in the output will not be rewritten by the abjad.Meter.rewrite_meter() mutation.

property extract_trivial_tuplets: bool

Sets the argument extract_trivial_tuplets of auxjad.mutate.prettify_rewrite_meter().

property fuse_across_groups_of_beats: bool

Sets the argument fuse_across_groups_of_beats of auxjad.mutate.prettify_rewrite_meter().

property fuse_quadruple_meter: bool

Sets the argument fuse_quadruple_meter of auxjad.mutate.prettify_rewrite_meter().

property fuse_triple_meter: bool

Sets the argument fuse_triple_meter of auxjad.mutate.prettify_rewrite_meter().

property maximum_dot_count: Optional[int]

Sets the argument maximum_dot_count of abjad.Meter.rewrite_meter().

property omit_time_signatures: bool

When True, the output will contain no time signatures.

property pitch_only: bool

When True, only the pitches will be shuffled or rotated while the durations remain the same.

property preserve_rest_position: bool

When True, shuffle operations will preserve rest positions and durations.

property prettify_rewrite_meter: bool

Used to enable or disable the mutation auxjad.mutate.prettify_rewrite_meter() (default True).

property process_on_first_call: bool

If True then contents will be processed in the very first call.

property rewrite_tuplets: bool

Sets the argument rewrite_tuplets of abjad.Meter.rewrite_meter().

rotate(*, n_rotations: int = 1, anticlockwise: bool = False)abjad.select.Selection[source]

Rotates logical ties or pitches of contents.

rotate_n(n: int, *, n_rotations: int = 1, anticlockwise: bool = False)abjad.select.Selection[source]

Goes through n iterations of the pitch shuffling process and outputs a single abjad.Selection.

shuffle()abjad.select.Selection[source]

Shuffles logical ties or pitches of contents.

shuffle_n(n: int)abjad.select.Selection[source]

Goes through n iterations of the shuffling process and outputs a single abjad.Selection.

property swap_limit: int

If int then it dictates how instances of random swapping of pairs of elements are applied to contents in each iteration. If None then contents is completely shuffled at each iteration.