
    rh#              	         S r SSKJr  SSKJr  SSKJr  SSKJ	r	   " S S\	R                  5      r " S S	\" S	S
5      5      r\" SSSSSSS
9r\" SS\* SSSS
9r\" SS\SSSS
9r\S:X  a  SSKr\R"                  " 5         gg)a  
This module defines a single class, SortTuple, which is a named tuple that can
sort against bare offsets and other SortTuples.

This is a performance-critical object.

It also defines three singleton instances of the SortTupleLow class as ZeroSortTupleDefault,
ZeroSortTupleLow and
ZeroSortTupleHigh which are sortTuple at
offset 0.0, priority [0, -inf, inf] respectively:

>>> sorting.ZeroSortTupleDefault
SortTuple(atEnd=0, offset=0.0, priority=0, classSortOrder=0, isNotGrace=1, insertIndex=0)
>>> sorting.ZeroSortTupleLow
SortTuple(atEnd=0, offset=0.0, priority=-inf, classSortOrder=0, isNotGrace=1, insertIndex=0)
>>> sorting.ZeroSortTupleHigh
SortTuple(atEnd=0, offset=0.0, priority=inf, classSortOrder=0, isNotGrace=1, insertIndex=0)
    )annotations)
namedtuple)inf)exceptions21c                      \ rS rSrSrg)SortingException$    N)__name__
__module____qualname____firstlineno____static_attributes__r
       I/home/james-whalen/.local/lib/python3.13/site-packages/music21/sorting.pyr   r   $   s    r   r   c                  z   ^  \ rS rSrSrU 4S jrU 4S jrU 4S jrU 4S jrS r	S r
S	 rS
 rS rS rS rSrU =r$ )	SortTuple(   a  
Derived class of namedTuple which allows for comparisons with pure ints/fractions.

>>> n = note.Note()
>>> s = stream.Stream()
>>> s.insert(4, n)
>>> st = n.sortTuple()
>>> st
SortTuple(atEnd=0, offset=4.0, priority=0, classSortOrder=20, isNotGrace=1, insertIndex=...)
>>> st.shortRepr()
'4.0 <0.20...>'
>>> st.atEnd
0
>>> st.offset
4.0

>>> st < 5.0
True
>>> 5.0 > st
True
>>> st > 3.0
True
>>> 3.0 < st
True

>>> st == 4.0
True

>>> ts = bar.Barline('double')
>>> s2 = stream.Stream()
>>> s2.storeAtEnd(ts)
>>> ts_st = ts.sortTuple()
>>> ts_st
SortTuple(atEnd=1, offset=0.0, priority=0, classSortOrder=-5, isNotGrace=1, insertIndex=...)
>>> st < ts_st
True
>>> ts_st > 999999
True
>>> import math
>>> ts_st == math.inf
True

Construct one w/ keywords:

>>> st = sorting.SortTuple(atEnd=0, offset=1.0, priority=0, classSortOrder=20,
...           isNotGrace=1, insertIndex=323)
>>> st.shortRepr()
'1.0 <0.20.323>'

or as tuple:

>>> st = sorting.SortTuple(0, 1.0, 0, 20, 1, 323)
>>> st.shortRepr()
'1.0 <0.20.323>'

c                4   > [         [        U ]
  " U /UQ70 UD6$ N)superr   __new__)clstupElskeywords	__class__s      r   r   SortTuple.__new__c   s    Y,SF6FXFFr   c                   > [        U[        5      (       a  [        TU ]  U5      $  U R                  S:X  a  U[
        :w  a  gU R                  S:X  a  gU R                  U:H  $ ! [         a	    [        s $ f = f)N   FT)	
isinstancetupler   __eq__atEndINFINITYoffset
ValueErrorNotImplementedselfotherr   s     r   r"   SortTuple.__eq__g   sk    eU##7>%((	"zzQ5H#4q{{e++ 	"!!	"   A" A" A" "A54A5c                   > [        U[        5      (       a  [        TU ]  U5      $  U R                  S:X  a  gU R
                  U:  $ ! [         a	    [        s $ f = f)Nr   F)r    r!   r   __lt__r#   r%   r&   r'   r(   s     r   r.   SortTuple.__lt__t   sV    eU##7>%((	"zzQ{{U** 	"!!	"s   A A AAc                   > [        U[        5      (       a  [        TU ]  U5      $  U R                  S:X  a  U[
        :w  a  gU R                  S:X  a  gU R                  U:  $ ! [         a	    [        s $ f = f)Nr   TF)	r    r!   r   __gt__r#   r$   r%   r&   r'   r(   s     r   r1   SortTuple.__gt__   sk    eU##7>%((	"zzQ5H#4q{{U** 	"!!	"r,   c                .    U R                  U5      (       + $ r   )r"   r)   r*   s     r   __ne__SortTuple.__ne__   s    ;;u%%%r   c                T    U R                  U5      =(       d    U R                  U5      $ r   )r.   r"   r4   s     r   __le__SortTuple.__le__       {{5!7T[[%77r   c                T    U R                  U5      =(       d    U R                  U5      $ r   )r1   r"   r4   s     r   __ge__SortTuple.__ge__   r:   r   c                X   / nU R                   (       a  UR                  S5        O$UR                  [        U R                  5      5        UR                  S5        UR                  [        U R                  5      5        UR                  S5        UR                  [        U R
                  5      5        U R                  S:X  a  UR                  S5        UR                  S5        UR                  [        U R                  5      5        UR                  S5        SR                  U5      $ )av  
Returns a nice representation of a SortTuple

>>> st = sorting.SortTuple(atEnd=0, offset=1.0, priority=0, classSortOrder=20,
...           isNotGrace=1, insertIndex=323)
>>> st.shortRepr()
'1.0 <0.20.323>'

>>> st = sorting.SortTuple(atEnd=1, offset=1.0, priority=4, classSortOrder=7,
...           isNotGrace=0, insertIndex=200)
>>> st.shortRepr()
'End <4.7.[Grace].200>'
Endz <.r   z.[Grace]> )	r#   appendstrr%   priorityclassSortOrder
isNotGraceinsertIndexjoin)r)   	reprPartss     r   	shortReprSortTuple.shortRepr   s     	::U#S-.T]]+,T0012??aZ(T--./wwy!!r   c           
         U R                    Vs/ s H  o!R                  U[        X5      5      PM     nnU R                  " U6 $ s  snf )a  
return a new SortTuple identical to the previous, except with
the given keyword modified.  Works only with keywords.

>>> st = sorting.SortTuple(atEnd=0, offset=1.0, priority=0, classSortOrder=20,
...           isNotGrace=1, insertIndex=32)
>>> st2 = st.modify(offset=2.0)
>>> st2.shortRepr()
'2.0 <0.20.32>'
>>> st2
SortTuple(atEnd=0, offset=2.0, priority=0, classSortOrder=20, isNotGrace=1, insertIndex=32)

>>> st3 = st2.modify(atEnd=1, isNotGrace=0)
>>> st3.shortRepr()
'End <0.20.[Grace].32>'

The original tuple is never modified (hence tuple):

>>> st.offset
1.0

Changing offset, but nothing else, helps in creating .flatten() positions.
)_fieldsgetgetattrr   )r)   r   attroutLists       r   modifySortTuple.modify   sA    2 HL||T|t<<gd&9:|T~~w'' Us   $Ac           
        [        XR                  5      (       d  [        S5      eU R                   Vs/ s H>  nUS;   a  [	        [        X5      [        X5      5      O[        X5      [        X5      -   PM@     nnU R                  " U6 $ s  snf )aj  
Add all attributes from one sortTuple to another,
returning a new one.

>>> n = note.Note()
>>> n.offset = 10
>>> s = stream.Stream()
>>> s.offset = 10
>>> n.sortTuple()
SortTuple(atEnd=0, offset=10.0, priority=0, classSortOrder=20, isNotGrace=1, insertIndex=0)
>>> s.sortTuple()
SortTuple(atEnd=0, offset=10.0, priority=0, classSortOrder=-20, isNotGrace=1, insertIndex=0)
>>> s.sortTuple().add(n.sortTuple())
SortTuple(atEnd=0, offset=20.0, priority=0, classSortOrder=0, isNotGrace=1, insertIndex=0)

Note that atEnd and isNotGrace are equal to other's value. are upper bounded at 1 and
take the maxValue of either.
,Cannot add attributes from a different classr#   rG   )r    r   r   rN   maxrP   r)   r*   rQ   rR   s       r   addSortTuple.add   s    & %00"#QRR
 !%. !- 66 wt*GE,@A!$-0DDF !- 	 .
 ~~w''.   AB
c           
        [        XR                  5      (       d  [        S5      eU R                   Vs/ s H>  nUS;   a  [	        [        X5      [        X5      5      O[        X5      [        X5      -
  PM@     nnU R                  " U6 $ s  snf )aE  
Subtract all attributes from to another.  atEnd and isNotGrace take the min value of either.

>>> n = note.Note()
>>> n.offset = 10
>>> s = stream.Stream()
>>> s.offset = 10
>>> n.sortTuple()
SortTuple(atEnd=0, offset=10.0, priority=0, classSortOrder=20, isNotGrace=1, insertIndex=0)
>>> s.sortTuple()
SortTuple(atEnd=0, offset=10.0, priority=0, classSortOrder=-20, isNotGrace=1, insertIndex=0)
>>> s.sortTuple().sub(n.sortTuple())
SortTuple(atEnd=0, offset=0.0, priority=0, classSortOrder=-40, isNotGrace=1, insertIndex=0)

Note that atEnd and isNotGrace are lower bounded at 0.
rV   rW   )r    r   r   rN   minrP   rY   s       r   subSortTuple.sub   s    " %00"#QRR
 !%. !- 66 wt*GE,@A!$-0DDF !- 	 .
 ~~w''.r\   r
   )r   r   r   r   __doc__r   r"   r.   r1   r5   r8   r<   rK   rS   rZ   r_   r   __classcell__)r   s   @r   r   r   (   sF    7pG"	""&88">(8(:( (r   r   )r#   r%   rE   rF   rG   rH   g        r   __main__N)ra   
__future__r   collectionsr   mathr   r$   music21r   Music21Exceptionr   r   ZeroSortTupleDefaultZeroSortTupleLowZeroSortTupleHighr   mainTestr
   r   r   <module>rm      s   $ # "    	|44 	^(
; )  ^(B !qqQR,-1>  1SH9UV()q:  AcHUV)*; 
 z r   