
    3jd              	         U d Z ddlmZ ddlmZmZ ddlZddlZddl	m
Z
 ddl	mZ ddl	mZ ddl	mZ dd	l	mZ ej                  rdd
l	mZ  ej"                  d      ZdZ G d dej(                        Z G d de
j,                        Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d d e      Z G d! d"e      Z  G d# d$e      Z! G d% d&e      Z" G d' d(e      Z# G d) d*e#      Z$ G d+ d,e#      Z% G d- d.e#      Z& G d/ d0e#      Z' G d1 d2e#      Z( G d3 d4e      Z) G d5 d6e)      Z* G d7 d8e)      Z+ G d9 d:e)      Z, G d; d<e)      Z- G d= d>e)      Z.deee"ddgde$e%e&e'e(gddde*e+e.gdddddegd?Z/d@e0dA<   dGdHdBZ1	 	 dI	 dJdCZ2 G dD dEejf                        Z4eee+gZ5e6dFk(  rddl	Z	 e	jn                  e4       yy)Kz
This module defines numerous subclasses of
:class:`~music21.clef.Clef`, providing object representations for all
commonly used clefs. Clef objects are often found
within :class:`~music21.stream.Measure` objects.
    )annotations)IterableSequenceN)base)exceptions21)environment)pitch)style)streamclef#   c                      e Zd Zy)ClefExceptionN)__name__
__module____qualname__     9/DATA/.local/lib/python3.12/site-packages/music21/clef.pyr   r   (   s    r   r   c                       e Zd ZU dZdZdddZded<   ej                  Z	dZ
d fd	Zd
 Zedd       Zej                  dd       Zedd       Zddd	 	 	 	 	 	 	 ddZ xZS )Clefa  
    A Clef is a basic `music21` object for representing musical clefs
    (Treble, Bass, etc.)

    Some clefs only represent the graphical element of the clef,
    such as G clef, which is subclassed by TrebleClef() and FrenchViolinClef().

    >>> tc = clef.TrebleClef()
    >>> tc
    <music21.clef.TrebleClef>
    >>> tc.sign
    'G'
    >>> tc.line
    2

    Most clefs also have a "lowestLine" function which represents the
    :attr:`~music21.pitch.Pitch.diatonicNoteNum` of the note that would fall on the
    lowest line if the Clef were put on a five-line staff. (Where C4,C#4,C##4,C-4
    etc. = 29, all types of D4 = 30, etc.)

    >>> tc.lowestLine
    31

    **Equality**

    Two Clefs are equal if their class is the same, their sign is the same,
    their line is the same and their octaveChange is the same.

    >>> c1 = clef.PercussionClef()
    >>> c2 = clef.NoClef()
    >>> c1 == c2
    False
    >>> c3 = clef.TrebleClef()
    >>> c4 = clef.TrebleClef()
    >>> c3 == c4
    True
    >>> c4.octaveChange = -1
    >>> c3 == c4
    False

    Note that these are not equal:

    >>> clef.TrebleClef() == clef.GClef(line=2)
    False
    )signlineoctaveChangea  
            The sign of the clef, generally, 'C', 'G', 'F', 'percussion', 'none' or None.

            >>> alto = clef.AltoClef()
            >>> alto.sign
            'C'
            >>> percussion = clef.PercussionClef()
            >>> percussion.sign
            'percussion'

            Note the difference here:

            >>> clef.Clef().sign is None
            True
            >>> clef.NoClef().sign
            'none'

            a  
            The line, counting from the bottom up, that the clef resides on.

            >>> clef.AltoClef().line
            3
            >>> clef.TenorClef().line
            4

            May be None:

            >>> print(clef.NoClef().line)
            None
            )r   r   dict[str, str]	_DOC_ATTRr   c                N    t        |   di | d | _        d | _        d| _        y )Nr   r   )super__init__r   r   _octaveChangeselfkeywords	__class__s     r   r   zClef.__init__   s)    $8$"	"	"#r   c                     y)N r   r"   s    r   _reprInternalzClef._reprInternal   s    r   c                    | j                   S )z
        The number of octaves that the clef "transposes", generally 0.

        >>> tc = clef.TrebleClef()
        >>> tc.octaveChange
        0
        >>> clef.Treble8vbClef().octaveChange
        -1
        r    r'   s    r   r   zClef.octaveChange   s     !!!r   c                    || _         y Nr*   )r"   newValues     r   r   zClef.octaveChange   s
    %r   c                    | j                   j                  j                  dd      }|r|d   j                         |dd z   S y)as  
        Returns the "name" of the clef, from the class name

        >>> tc = clef.TrebleClef()
        >>> tc.name
        'treble'

        >>> tc = clef.Treble8vbClef()
        >>> tc.name
        'treble8vb'

        >>> tc = clef.MezzoSopranoClef()
        >>> tc.name
        'mezzoSoprano'

        OMIT_FROM_DOCS

        >>> clef.Clef().name
        ''
        r   r&   r      N)r$   r   replacelower)r"   	classNames     r   namez	Clef.name   sD    , NN++33FB?	Q<%%')AB-77r   TFfirstLastOnlyextremePitchOnlyc                  t        |t        j                        r|g}n|}|st        d      |r!t	        |d       }t        |d       }||g}n|rt        |      dkD  r|d   |d   g}n|}d}t        | t        t        f      r| j                  | j                  dz   }	nt        }	|D ]  }
|
j                  |	z
  }||z  } |dk\  ry	y
)a  
        Return a string representing the stem direction for a single
        :class:`~music21.pitch.Pitch` object or a list/tuple/Stream of pitches.

        >>> P = pitch.Pitch
        >>> bc = clef.BassClef()
        >>> bc.getStemDirectionForPitches(P('C3'))
        'up'

        For two pitches, the most extreme pitch determines the direction:

        >>> pitchList = [P('C3'), P('B3')]
        >>> bc.getStemDirectionForPitches(pitchList)
        'down'

        If `firstLastOnly` is True (as by default) then only the first and last pitches are
        examined, as in a beam group.  Here we have C3, B3, C3, so despite the B in bass
        clef being much farther from the center line than either of the Cs, it is stem up:

        >>> pitchList.append(P('C3'))
        >>> bc.getStemDirectionForPitches(pitchList)
        'up'

        If `firstLastOnly` is False, then each of the pitches has a weight on the process

        >>> bc.getStemDirectionForPitches(pitchList, firstLastOnly=False)
        'down'

        If extremePitchOnly is True, then whatever pitch is farthest from the center line
        determines the direction, regardless of order.  (default False).

        >>> bc.getStemDirectionForPitches(pitchList, extremePitchOnly=True)
        'down'
        >>> pitchList.insert(1, P('C2'))
        >>> bc.getStemDirectionForPitches(pitchList, extremePitchOnly=True)
        'up'
        z:getStemDirectionForPitches cannot operate on an empty listc                    | j                   S r,   diatonicNoteNumpps    r   <lambda>z1Clef.getStemDirectionForPitches.<locals>.<lambda>   
    R5G5Gr   )keyc                    | j                   S r,   r9   r;   s    r   r=   z1Clef.getStemDirectionForPitches.<locals>.<lambda>   r>   r   r/   r      downup)
isinstancer	   Pitch
ValueErrorminmaxlenPercussionClef	PitchClef
lowestLineTREBLE_MID_LINE_DNNr:   )r"   pitchesr5   r6   	pitchListpitchMinpitchMaxrelevantPitchesdifferenceSummidLinepdistanceFromMidLines               r   getStemDirectionForPitcheszClef.getStemDirectionForPitches   s    \ gu{{+ 	II YZZ9*GHH9*GHH'2Os9~1(|Yr];O'Od^Y78T__=Xoo)G)G A"#"3"3g"=00M ! Ar   returnNonerZ   intr-   r]   )rZ   str)rO   z#pitch.Pitch | Sequence[pitch.Pitch]r5   boolr6   r`   rZ   r_   )r   r   r   __doc__equalityAttributesr   __annotations__r
   	TextStyle_styleClassclassSortOrderr   r(   propertyr   setterr3   rX   __classcell__r$   s   @r   r   r   -   s    ,Z :$' !I~  D //KN$ 
" 
" & &  > #!&N2N 	N
 N 
Nr   r   c                  t     e Zd ZU dZddiZded<   d	 fdZed
 fd       Zej                  dd       Z xZ
S )rL   zD
    Superclass for all other clef subclasses that use pitches.
    rM   z
            The diatonicNoteNumber of the lowest line of the clef.
            (Can be `None`)

            >>> clef.TrebleClef().lowestLine
            31
            r   r   c                2    t        |   di | d| _        y )N   r   )r   r   rM   r!   s     r   r   zPitchClef.__init__  s    $8$!r   c                    t         |   S )a  
        The number of octaves that the clef "transposes", generally 0.

        >>> tc = clef.TrebleClef()
        >>> tc.octaveChange
        0
        >>> clef.Treble8vbClef().octaveChange
        -1

        Changing octaveChange changes lowestLine (but not vice versa)

        >>> tc.lowestLine
        31
        >>> tc.octaveChange = 1
        >>> tc.lowestLine
        38
        >>> tc.octaveChange = -1
        >>> tc.lowestLine
        24
        )r   r   )r"   r$   s    r   r   zPitchClef.octaveChange#  s    , w##r   c                z    | j                   }|| _         | j                  | xj                  ||z
  dz  z  c_        y y )N   )r    rM   )r"   r-   oldOctaveChanges      r   r   zPitchClef.octaveChange;  s<    ,,%??&OO? :a??O 'r   rY   r\   r^   )r   r   r   ra   r   rc   r   rg   r   rh   ri   rj   s   @r   rL   rL     sU     	 !I~ " $ $. @ @r   rL   c                  2     e Zd ZU dZi Zded<    fdZ xZS )rK   a  
    represents a Percussion clef.

    >>> pc = clef.PercussionClef()
    >>> pc.sign
    'percussion'
    >>> pc.line is None
    True

    Percussion clefs should not, technically have a
    "lowestLine," but it is a common usage to assume that
    in pitch-centric contexts to use the pitch numbers
    from treble clef for percussion clefs.  Thus:

    >>> pc.lowestLine == clef.TrebleClef().lowestLine
    True

    * Changed in v7.3: setting `octaveChange` no longer affects `lowestLine`.
    r   r   c                @    t        |   di | d| _        d| _        y )N
percussionrm   r   )r   r   r   rM   r!   s     r   r   zPercussionClef.__init__Y  s!    $8$ 	%r   r   r   r   ra   r   rc   r   ri   rj   s   @r   rK   rK   C  s    & !#I~"& &r   rK   c                  2     e Zd ZU dZi Zded<    fdZ xZS )NoClefz
    represents the absence of a Clef.

    >>> nc = clef.NoClef()
    >>> nc.sign
    'none'

    Note that the sign is the string 'none' not the None object

    >>> nc.sign is None
    False
    r   r   c                2    t        |   di | d| _        y )Nnoner   r   r   r   r!   s     r   r   zNoClef.__init__n  s    $8$	r   ru   rj   s   @r   rw   rw   _  s     !#I~" r   rw   c                  "     e Zd ZdZ fdZ xZS )
JianpuClefz
    Jianpu notation does not use a clef, but musicxml marks it
    with a specialized "jianpu" sign.

    >>> jc = clef.JianpuClef()
    >>> jc.sign
    'jianpu'
    c                2    t        |   di | d| _        y )Njianpur   rz   r!   s     r   r   zJianpuClef.__init__}  s    $8$	r   r   r   r   ra   r   ri   rj   s   @r   r|   r|   s  s     r   r|   c                  @     e Zd ZdZ fdZddd	 	 	 	 	 	 	 ddZ xZS )TabClefz[
    represents a Tablature clef.

    >>> a = clef.TabClef()
    >>> a.sign
    'TAB'
    c                @    t        |   di | d| _        d| _        y )NTAB   r   )r   r   r   r   r!   s     r   r   zTabClef.__init__  s!    $8$		r   TFr4   c                    y)zE
        Overridden to simply return 'down' for guitar tabs.
        rC   r   )r"   rP   r5   r6   s       r   rX   z"TabClef.getStemDirectionForPitches  s     r   )rP   z#pitch.Pitch | Iterable[pitch.Pitch]r5   r`   r6   r`   rZ   r_   )r   r   r   ra   r   rX   ri   rj   s   @r   r   r     s@     #!&
4
 	

 
 

r   r   c                  "     e Zd ZdZ fdZ xZS )GClefz
    A generic G Clef

    >>> a = clef.GClef()
    >>> a.sign
    'G'

    If not defined, the lowestLine is set as a Treble Clef (E4 = 31)

    >>> a.lowestLine
    31
    c                2    t        |   di | d| _        y )NGr   rz   r!   s     r   r   zGClef.__init__      $8$	r   r   rj   s   @r   r   r     s     r   r   c                  "     e Zd ZdZ fdZ xZS )FrenchViolinClefz
    A G Clef that appears in many old French Violin scores,
    appearing on the lowest line, and thus higher than
    a treble clef.

    >>> a = clef.FrenchViolinClef()
    >>> a.sign
    'G'
    >>> a.line
    1
    c                @    t        |   di | d| _        d| _        y )Nr/   !   r   r   r   r   rM   r!   s     r   r   zFrenchViolinClef.__init__  !    $8$	%r   r   rj   s   @r   r   r         
& &r   r   c                  "     e Zd ZdZ fdZ xZS )
TrebleClefz
    The most common clef of all, a treble clef.

    >>> a = clef.TrebleClef()
    >>> a.sign
    'G'
    >>> a.line
    2
    >>> a.lowestLine
    31
    >>> note.Note('E4').pitch.diatonicNoteNum
    31
    c                @    t        |   di | d| _        d| _        y )N   rm   r   r   r!   s     r   r   zTrebleClef.__init__  r   r   r   rj   s   @r   r   r     s    & &r   r   c                  "     e Zd ZdZ fdZ xZS )Treble8vbClefz
    A vocal tenor treble clef. Also for guitars.

    >>> a = clef.Treble8vbClef()
    >>> a.sign
    'G'
    >>> a.octaveChange
    -1
    c                @    t        |   di | d| _        d| _        y )NrA      r   r   r   r   rM   r!   s     r   r   zTreble8vbClef.__init__  s"    $8$%r   r   rj   s   @r   r   r         & &r   r   c                  "     e Zd ZdZ fdZ xZS )Treble8vaClefz
    A treble clef an octave up (such as for piccolos)

    >>> a = clef.Treble8vaClef()
    >>> a.sign
    'G'
    >>> a.octaveChange
    1
    c                @    t        |   di | d| _        d| _        y )Nr/   r   r   r   r!   s     r   r   zTreble8vaClef.__init__  s"    $8$%r   r   rj   s   @r   r   r     r   r   r   c                  "     e Zd ZdZ fdZ xZS )GSopranoClefz
    A G clef on the middle line, formerly occasionally used
    for soprano parts.

    >>> a = clef.GSopranoClef()
    >>> a.sign
    'G'
    >>> a.line
    3
    c                @    t        |   di | d| _        d| _        y )N      r   r   r!   s     r   r   zGSopranoClef.__init__  r   r   r   rj   s   @r   r   r         	& &r   r   c                  "     e Zd ZdZ fdZ xZS )CClefz]
    A generic C Clef, with no line set

    >>> a = clef.CClef()
    >>> a.sign
    'C'
    c                2    t        |   di | d| _        y )NCr   rz   r!   s     r   r   zCClef.__init__  r   r   r   rj   s   @r   r   r          r   r   c                  "     e Zd ZdZ fdZ xZS )SopranoClefz
    A soprano clef, with C on the lowest line
    (found in Bach often)

    >>> a = clef.SopranoClef()
    >>> a.sign
    'C'
    >>> a.line
    1
    c                @    t        |   di | d| _        d| _        y )Nr/   r   r   r   r!   s     r   r   zSopranoClef.__init__*  r   r   r   rj   s   @r   r   r     r   r   r   c                  "     e Zd ZdZ fdZ xZS )MezzoSopranoClefz
    A C clef with C on the second line.  Perhaps
    the rarest of the C clefs

    >>> a = clef.MezzoSopranoClef()
    >>> a.sign
    'C'
    >>> a.line
    2
    c                @    t        |   di | d| _        d| _        y )Nr      r   r   r!   s     r   r   zMezzoSopranoClef.__init__<  r   r   r   rj   s   @r   r   r   0  r   r   r   c                  "     e Zd ZdZ fdZ xZS )AltoClefzs
    A C AltoClef, common for violas.

    >>> a = clef.AltoClef()
    >>> a.sign
    'C'
    >>> a.line
    3
    c                @    t        |   di | d| _        d| _        y )Nr      r   r   r!   s     r   r   zAltoClef.__init__M  r   r   r   rj   s   @r   r   r   B  r   r   r   c                  "     e Zd ZdZ fdZ xZS )	TenorClefz
    A C Tenor Clef, often used in bassoon and cello parts
    and orchestral trombone parts.

    >>> a = clef.TenorClef()
    >>> a.sign
    'C'
    >>> a.line
    4

    c                @    t        |   di | d| _        d| _        y )NrB      r   r   r!   s     r   r   zTenorClef.__init__`  r   r   r   rj   s   @r   r   r   S  r   r   r   c                  "     e Zd ZdZ fdZ xZS )CBaritoneClefz
    A Baritone C clef (as opposed to an F Baritone Clef)

    >>> a = clef.CBaritoneClef()
    >>> a.sign
    'C'
    >>> a.line
    5
    c                @    t        |   di | d| _        d| _        y )Nr      r   r   r!   s     r   r   zCBaritoneClef.__init__q  r   r   r   rj   s   @r   r   r   f  r   r   r   c                  "     e Zd ZdZ fdZ xZS )FClefz]
    A generic F-Clef, like a Bass clef

    >>> a = clef.FClef()
    >>> a.sign
    'F'
    c                2    t        |   di | d| _        y )NFr   rz   r!   s     r   r   zFClef.__init__  r   r   r   rj   s   @r   r   r   x  r   r   r   c                  "     e Zd ZdZ fdZ xZS )FBaritoneClefz
    an F Baritone Clef

    >>> a = clef.FBaritoneClef()
    >>> a.sign
    'F'
    >>> a.line
    3
    >>> b = clef.CBaritoneClef()
    >>> a.lowestLine == b.lowestLine
    True
    >>> a.sign == b.sign
    False
    c                @    t        |   di | d| _        d| _        y )Nr   r   r   r   r!   s     r   r   zFBaritoneClef.__init__  r   r   r   rj   s   @r   r   r     s    & &r   r   c                  "     e Zd ZdZ fdZ xZS )BassClefzR
    A standard Bass Clef

    >>> a = clef.BassClef()
    >>> a.sign
    'F'
    c                @    t        |   di | d| _        d| _        y )NrB      r   r   r!   s     r   r   zBassClef.__init__  r   r   r   rj   s   @r   r   r         & &r   r   c                  "     e Zd ZdZ fdZ xZS )Bass8vbClefz
    A bass clef configured to be an octave lower.

    >>> a = clef.Bass8vbClef()
    >>> a.sign
    'F'
    >>> a.octaveChange
    -1
    c                N    t        |   di | d| _        d| _        d| _        y )NrB   rA   r   r   r   r   r   r   rM   r!   s     r   r   zBass8vbClef.__init__  s)    $8$	%r   r   rj   s   @r   r   r     s    & &r   r   c                  "     e Zd ZdZ fdZ xZS )Bass8vaClefzj
    A rarely used Bass Clef an octave higher.

    >>> a = clef.Bass8vaClef()
    >>> a.sign
    'F'
    c                N    t        |   di | d| _        d| _        d| _        y )NrB   r/   r   r   r   r!   s     r   r   zBass8vaClef.__init__  s)    $8$	%r   r   rj   s   @r   r   r     s    & &r   r   c                  "     e Zd ZdZ fdZ xZS )SubBassClefz[
    An F clef on the top line.

    >>> a = clef.SubBassClef()
    >>> a.sign
    'F'
    c                @    t        |   di | d| _        d| _        y )Nr      r   r   r!   s     r   r   zSubBassClef.__init__  r   r   r   rj   s   @r   r   r     r   r   r   )r   r   r   r   z"dict[str, list[type[Clef] | None]]CLASS_FROM_TYPEc                   | j                         }|j                         dv rt|j                         dk(  r
t               S |j                         dk(  r
t               S |j                         dk(  r
t	               S |j                         dk(  r
t               S t        |      dk(  r"|d   j                         t        |d         }}nt        |      dk(  r.|d   j                         }|d	k(  rd}n|d
k(  rd}n|dk(  rd}nd}nt        |      dkD  rddl	m
} |j                         }t        |      D ]V  }d|vr||j                         k7  r|dz   |j                         k7  r2t        ||      }t        |t              sO |       c S  t        d|z         t        d      |dk7  rA|||f}	|	dk(  r
t!               S |	dk(  r
t#               S |	dk(  r
t%               S |	dk(  r
t'               S |du s|du rt        d| d      |dk  s|dkD  rt        d|      |t(        v rt(        |   }
t        |
t*              sJ |
|   R|d	k(  rt-               }n:|d
k(  rt/               }n*|dk(  rt1               }n|dk(  rt               }n
t3               }||_        nK|
|   }t6        j8                  r|J t;        |t2              sJ  |       }nt3               }||_        ||_        |dk7  r||_        |S )aM  
    Returns a Clef object given a string like "G2" or "F4" etc.

    Does not refer to a violin/guitar string.

    >>> tc = clef.clefFromString('G2')
    >>> tc
    <music21.clef.TrebleClef>
    >>> nonStandard1 = clef.clefFromString('F1')
    >>> nonStandard1
    <music21.clef.FClef>
    >>> nonStandard1.line
    1
    >>> nonStandard2 = clef.clefFromString('D4')
    >>> nonStandard2
    <music21.clef.PitchClef>
    >>> nonStandard2.sign
    'D'
    >>> nonStandard2.line
    4

    >>> tc8vb = clef.clefFromString('G2', -1)
    >>> tc8vb
    <music21.clef.Treble8vbClef>

    Three special clefs, Tab, Percussion, and None are also supported.

    >>> tabClef = clef.clefFromString('TAB')
    >>> tabClef
    <music21.clef.TabClef>

    Case does not matter.

    >>> tc8vb = clef.clefFromString('g2', -1)
    >>> tc8vb
    <music21.clef.Treble8vbClef>

    >>> percussionClef = clef.clefFromString('Percussion')
    >>> percussionClef
    <music21.clef.PercussionClef>

    >>> noClef = clef.clefFromString('None')
    >>> noClef
    <music21.clef.NoClef>

    Invalid line numbers raise an exception:

    >>> invalidClef = clef.clefFromString('F6')
    Traceback (most recent call last):
    music21.clef.ClefException: line number (second character) must be 1-5;
                do not use this function for clefs on special staves such as 'F6'

    Can find any clef in the module

    >>> clef.clefFromString('Treble')
    <music21.clef.TrebleClef>
    >>> clef.clefFromString('trebleclef')
    <music21.clef.TrebleClef>
    >>> clef.clefFromString('treble8vb')
    <music21.clef.Treble8vbClef>
    )tabrt   ry   r~   r   rt   ry   r~   r   r   r/   r   r   rB   r   r   F)r   r   r   zCould not find clef z)Entry has clef info but no clef specified)r   r   rA   )r   r   r/   )r   rB   rA   )r   rB   r/   zcannot read z$ as clef str, should be G2, F4, etc.r   ziline number (second character) must be 1-5; do not use this function for clefs on special staves such as r   ) stripr1   r   rK   rw   r|   rJ   upperr]   music21r   dirgetattrrE   typer   r   r   r   r   r   listr   r   r   rL   r   tTYPE_CHECKING
issubclassr   r   )
clefStringoctaveShiftxnStrthisTypelineNummyselfxnLowerxobjTypeparams	line_listclefObjClefTypes                r   clefFromStringr     s   | E{{}??;;=E!9[[]l*!##[[]f$8O[[]h&<
5zQ$Qx~~/U1X7	Uq8>>#s?G_G_GG	Ua*++-VAQ!'')#&(8AGGI(Efa(G'4(y   2U:;;GHHaG[1\! ?"{" ?"|#= {"=  5Gu,l5'1UVWW{gk LLQ9V W 	W ?"#H-	)T***W%3'S'S'U"!)#+"GL )H+++!(I666jG+a*Nr   c                   d }d}d}|r| j                         n| j                         }|j                  }|D ]#  }|j                  D ]  }	|dz  }| ||	      z  } % |dk(  rd}
n||z  }
|
dkD  r
t	               S |r|
dkD  r
t               S |s|
dkD  r
t               S |r|
dkD  r
t               S |
d	kD  r
t               S t               S )
aL  
    Returns the clef that is the best fit for notes and chords found in this Stream.

    >>> import random
    >>> a = stream.Stream()
    >>> for x in range(30):
    ...    n = note.Note()
    ...    n.pitch.midi = random.randint(70, 81)
    ...    a.insert(n)
    >>> b = clef.bestClef(a)
    >>> b
    <music21.clef.TrebleClef>
    >>> b.line
    2
    >>> b.sign
    'G'

    >>> c = stream.Stream()
    >>> for x in range(10):
    ...    n = note.Note()
    ...    n.pitch.midi = random.randint(45, 54)
    ...    c.insert(n)
    >>> d = clef.bestClef(c)
    >>> d
    <music21.clef.BassClef>
    >>> d.line
    4
    >>> d.sign
    'F'

    This does not automatically get a flat representation of the Stream.

    There are a lot more high notes in `a` (30) than low notes in `c` (10),
    but it will not matter here, because the pitches in `a` will not be found:

    >>> c.insert(0, a)
    >>> clef.bestClef(c)
    <music21.clef.BassClef>

    But with recursion, it will matter:

    >>> clef.bestClef(c, recurse=True)
    <music21.clef.TrebleClef>

    Notes around middle C can get Treble8vb if the setting is allowed:

    >>> clef.bestClef(stream.Stream([note.Note('D4')]))
    <music21.clef.TrebleClef>
    >>> clef.bestClef(stream.Stream([note.Note('D4')]), allowTreble8vb=True)
    <music21.clef.Treble8vbClef>

    Streams of extremely high notes or extremely low notes can get
    Treble8va or Bass8vb clefs:

    >>> clef.bestClef(stream.Stream([note.Note('D7')]))
    <music21.clef.Treble8vaClef>
    >>> clef.bestClef(stream.Stream([note.Note('C0')]))
    <music21.clef.Bass8vbClef>
    c                r    | j                   }| j                   dkD  r|dz  }|S | j                   dk  r|dz  }|S )Nr   r   r   r9   )pInnerheights     r   
findHeightzbestClef.<locals>.findHeight  sI    ''!!B&aKF  ##b(bLFr   r   r/   g      =@1             
   )	recurseiternotesAndRestsrO   r   r   r   r   r   )	streamObjallowTreble8vbr   r   totalPitchestotalHeightsIternotesnrV   averageHeights              r   bestClefr  ~  s    ~ LK#*I	0@EEAAL:a=(K   q#l2 r	MB.| 2|	MB.		z}r   c                      e Zd Zd Zy)Testc                2    ddl m}  || t                      y )Nr   )testCopyAll)music21.test.commonTestr	  globals)r"   r	  s     r   testCopyAndDeepcopyzTest.testCopyAndDeepcopy  s    7D')$r   N)r   r   r   r  r   r   r   r  r    s    %r   r  __main__)r   )rZ   r   )FF)r   zstream.StreamrZ   rL   )8ra   
__future__r   collections.abcr   r   typingr   unittestr   r   r   r   r	   r
   r   r   EnvironmentenvironLocalrN   Music21Exceptionr   Music21Objectr   rL   rK   rw   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rc   r   r  TestCaser  
_DOC_ORDERr   mainTestr   r   r   <module>r     s?   # .         ?? '{&&v. 	L11 	
\4 \H/@ /@d&T &8T ( i :I &&u &&& &*&J &"&J &"&5 &(I &% &$&u &$&u &"& &&&E &$I &E &,&u &&% &$&% & &% &"  *lD$	G
-xM	R
dM8[	A$dD'2	51 Vt "d(dR%8 % J)
 zGT r   