
    3j                       d Z ddlmZ ddlZddlZddl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 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 ddlmZ ddlmZ ddlmZ ddZddZ G d d      Z G d d      ZeeeegZ G d dej:                        Z G d dej>                        Z e!dk(  rddl	Z	 e	jD                  e        yy)aV  
This module, the heart of fbRealizer, is all about realizing
a bass line of (bassNote, notationString)
pairs. All it takes to create well-formed realizations of a
bass line is a few lines of music21 code,
from start to finish. See :class:`~music21.figuredBass.realizer.FiguredBassLine` for more details.

>>> from music21.figuredBass import realizer
>>> fbLine = realizer.FiguredBassLine()
>>> fbLine.addElement(note.Note('C3'))
>>> fbLine.addElement(note.Note('D3'), '4,3')
>>> fbLine.addElement(note.Note('C3', quarterLength = 2.0))
>>> allSols = fbLine.realize()
>>> allSols.getNumSolutions()
30
>>> #_DOCS_SHOW allSols.generateRandomRealizations(14).show()

    .. image:: images/figuredBass/fbRealizer_intro.*
        :width: 500

The same can be accomplished by taking the notes and notations
from a :class:`~music21.stream.Stream`.
See :meth:`~music21.figuredBass.realizer.figuredBassFromStream` for more details.

>>> s = converter.parse('tinynotation: C4 D4_4,3 C2', makeNotation=False)
>>> fbLine = realizer.figuredBassFromStream(s)
>>> allSols2 = fbLine.realize()
>>> allSols2.getNumSolutions()
30
    )annotationsN)chord)clef)exceptions21)key)meter)note)pitch)stream)checker)notation)realizerScale)rules)segmentFiguredBassLinec                   | j                         }|j                  t        j                        }|t        j
                     j                         x}r|}nJ|t        j                     j                         x}r|j                  d      }nt	        j
                  d      }|t        j                     j                         x}r|}nt        j                  d      }t        ||      }| j                         r?| j                  dd      }	t        j                  r|	J |	j                   }
|
dk7  r|
|_        dfd|D ]  }|j$                  rd	}t'        |j$                        D ]c  \  }}|j(                  d
v rd|j(                  v r|j(                  }n ||j(                        }|dz   t+        |j$                        k  s_|dz  }e |j-                  ||       |j-                  |        |S )a  
    Takes a :class:`~music21.stream.Part` (or another :class:`~music21.stream.Stream` subclass)
    and returns a :class:`~music21.figuredBass.realizer.FiguredBassLine` object whose bass notes
    have notations taken from the lyrics in the source stream. This method along with the
    :meth:`~music21.figuredBass.realizer.FiguredBassLine.realize` method provide the easiest
    way of converting from a notated version of a figured bass (such as in a MusicXML file) to
    a realized version of the same line.

    >>> s = converter.parse('tinynotation: 4/4 C4 D8_6 E8_6 F4 G4_7 c1', makeNotation=False)
    >>> fb = figuredBass.realizer.figuredBassFromStream(s)
    >>> fb
    <music21.figuredBass.realizer.FiguredBassLine object at 0x...>

    >>> fbRules = figuredBass.rules.Rules()
    >>> fbRules.partMovementLimits = [(1, 2), (2, 12), (3, 12)]
    >>> fbRealization = fb.realize(fbRules)
    >>> fbRealization.getNumSolutions()
    13
    >>> #_DOCS_SHOW fbRealization.generateRandomRealizations(8).show()

    .. image:: images/figuredBass/fbRealizer_fbStreamPart.*
        :width: 500

    * Changed in v7.3: multiple figures in same lyric (e.g. '64') now supported.
    majorC4/4r   T)indicesNotNumbers        c                    d}|d   dv r$t        |      dkD  r|d   j                         rd}n|d   j                         rd}nd}| |d| z  } ||d r| dz  }  | ||d       } | S )z
        Continue building the working `annotationString` based on some `inputText`
        that has yet to be processed. Called recursively until `inputText` is exhausted
        or contains unexpected characters.
        r   +#bn      i  N, )len	isnumeric)annotationString	inputTextstop_index_exclusiveupdateAnnotationStrings      I/DATA/.local/lib/python3.12/site-packages/music21/figuredBass/realizer.pyr"   z5figuredBassFromStream.<locals>.updateAnnotationStringt   s     %&Q<6!c)nq&8Yq\=S=S=U#$ q\##%#$  $( I&;';<<)*+$5 ),@,A"B D     )Nr%   ,r   r   )r   strr    r'   returnr'   )flattengetElementsByClassr	   Noter   KeyfirstKeySignatureasKeyr   TimeSignaturer   hasMeasuresmeasuretTYPE_CHECKINGpaddingLeft_paddingLeftlyrics	enumeratetextr   
addElement)
streamPartsfsfnfirstKeymyKeyfirstKeySignaturefirst_tstsfbm_firstr5   nr   i
lyric_liner"   s                  @r#   figuredBassFromStreamrH   ?   s   6 
			B


		
*Ccgg;$$&&x& !1!1288:	:		:!''0 e))*0022x2  '		#B$$Q$$???&&&))#)BO . 88$&!*188!4:??j0*//) (2$ (>>NPZP_P_'`$q53qxx=($,$ "5 MM!-.MM!# & Ir$   c                L   g | _         t        j                  |      }|j                  syt	        |j                  D cg c]  }t        |       c}      }|j                  D ];  }d}t        |t        |      z
        D ]  }|dz  }	 | j                  ||z   d       = yc c}w )a  
    Takes in a bassNote and a corresponding notationString as arguments.
    Adds the parsed notationString as lyrics to the bassNote, which is
    useful when displaying the figured bass in external software.

    >>> from music21.figuredBass import realizer
    >>> n1 = note.Note('G3')
    >>> realizer.addLyricsToBassNote(n1, '6,4')
    >>> n1.lyrics[0].text
    '6'
    >>> n1.lyrics[1].text
    '4'
    >>> #_DOCS_SHOW n1.show()

    .. image:: images/figuredBass/fbRealizer_lyrics.*
        :width: 100
    Nr%    T)applyRaw)r7   r   NotationfigureStringsmaxr   rangeaddLyric)bassNotenotationStringrE   fs	maxLengthspacesInFrontrF   s          r#   addLyricsToBassNoterV      s    $ HO.)A??q7SW78Iooy3r7*+AS M ,-",t<	  8s   B!c                  b    e Zd ZU dZg dZdddZded<   dd	Zddd
Zd Z	ddZ
d ZddZd Zy)r   a  
    A FiguredBassLine is an interface for realization of a line of (bassNote, notationString) pairs.
    Currently, only 1:1 realization is supported, meaning that every bassNote is realized and the
    :attr:`~music21.note.GeneralNote.quarterLength` or duration of a realization above a bassNote
    is identical to that of the bassNote.

    `inKey` defaults to C major.

    `inTime` defaults to 4/4.

    >>> from music21.figuredBass import realizer
    >>> fbLine = realizer.FiguredBassLine(key.Key('B'), meter.TimeSignature('3/4'))
    >>> fbLine.inKey
    <music21.key.Key of B major>
    >>> fbLine.inTime
    <music21.meter.TimeSignature 3/4>
    )r:   generateBassLinerealizez
            A :class:`~music21.key.Key` which implies a scale value,
            scale mode, and key signature for a
            :class:`~music21.figuredBass.realizerScale.FiguredBassScale`.
            z
            A :class:`~music21.meter.TimeSignature` which specifies the
            time signature of realizations outputted to a
            :class:`~music21.stream.Score`.
            )inKeyinTimedict[str, str]	_DOC_ATTRNc                2   |t        j                  d      }|t        j                  d      }|| _        || _        d| _        t        j                         | _	        t        j                  |j                  d      |j                        | _        g | _        y )Nr   r   r   r   )r   r,   r   r0   rZ   r[   r6   r   Part_overlaidPartsr   FiguredBassScalepitchFromDegreemode_fbScale_fbList)selfrZ   r[   s      r#   __init__zFiguredBassLine.__init__   sz    =GGCLE>((/F
$kkm%66u7L7LQ7OQVQ[Q[\r$   c                    ||j                   _        |j                  }d|v r*| j                  j	                  ||f       t        ||       yd|v sd|v r| j                  j	                  |       yt        d|      )a  
        Use this method to add (bassNote, notationString) pairs to the bass line. Elements
        are realized in the order they are added.

        >>> from music21.figuredBass import realizer
        >>> fbLine = realizer.FiguredBassLine(key.Key('B'), meter.TimeSignature('3/4'))
        >>> fbLine.addElement(note.Note('B2'))
        >>> fbLine.addElement(note.Note('C#3'), '6')
        >>> fbLine.addElement(note.Note('D#3'), '6')
        >>> #_DOCS_SHOW fbLine.generateBassLine().show()

        .. image:: images/figuredBass/fbRealizer_bassLine.*
            :width: 200

        OMIT_FROM_DOCS

        >>> fbLine = realizer.FiguredBassLine(key.Key('C'), meter.TimeSignature('4/4'))
        >>> fbLine.addElement(harmony.ChordSymbol('C'))
        >>> fbLine.addElement(harmony.ChordSymbol('G'))

        >>> fbLine = realizer.FiguredBassLine(key.Key('C'), meter.TimeSignature('4/4'))
        >>> fbLine.addElement(roman.RomanNumeral('I'))
        >>> fbLine.addElement(roman.RomanNumeral('V'))
        r+   RomanNumeralChordSymbolzcNot a valid bassObject (only note.Note, harmony.ChordSymbol, and roman.RomanNumeral supported) was N)	editorialrR   classesre   appendrV   FiguredBassLineException)rf   
bassObjectrR   cs       r#   r:   zFiguredBassLine.addElement   s    2 /=
+Q;LL^ <=
N;q MQ$6LL
+*NNX^] r$   c                *   t        j                         }|j                  t        j                                |j                  t        j                  | j                  j                               |j                  t        j                  | j                               d}| j                  dk7  r1t        j                  | j                        }|j                  |       | j                  D ]  \  }}|j                  |        |j!                  dd      }|y|j#                  t         j$                        j'                         }|j)                  |j#                  t        j                        j'                                |j+                          |S )a  
        Generates the bass line as a :class:`~music21.stream.Score`.

        >>> from music21.figuredBass import realizer
        >>> fbLine = realizer.FiguredBassLine(key.Key('B'), meter.TimeSignature('3/4'))
        >>> fbLine.addElement(note.Note('B2'))
        >>> fbLine.addElement(note.Note('C#3'), '6')
        >>> fbLine.addElement(note.Note('D#3'), '6')
        >>> #_DOCS_SHOW fbLine.generateBassLine().show()

        .. image:: images/figuredBass/fbRealizer_bassLine.*
            :width: 200

        >>> sBach = corpus.parse('bach/bwv307')
        >>> sBach.parts.last().measure(0).show('text')
        {0.0} ...
        {0.0} <music21.clef.BassClef>
        {0.0} <music21.key.Key of B- major>
        {0.0} <music21.meter.TimeSignature 4/4>
        {0.0} <music21.note.Note B->
        {0.5} <music21.note.Note C>

        >>> fbLine = realizer.figuredBassFromStream(sBach.parts.last())
        >>> fbLine.generateBassLine().measure(1).show('text')
        {0.0} <music21.clef.BassClef>
        {0.0} <music21.key.KeySignature of 2 flats>
        {0.0} <music21.meter.TimeSignature 4/4>
        {3.0} <music21.note.Note B->
        {3.5} <music21.note.Note C>
        Nr   quarterLengthFinPlacecautionaryNotImmediateRepeat)r   r_   rm   r   BassClefr   r.   rZ   sharpscopydeepcopyr[   r6   r	   Restre   makeNotationr*   Measurer-   removepadAsAnacrusis)rf   bassLinerrQ   unused_notationStringbl2m0s          r#   rX   z FiguredBassLine.generateBassLine  s   > ;;=((():):;<dkk23#		(9(9:AOOA15-X,OOH% 2> ##EPU#V=''7==?BIIb++DII6<<>?
r$   c           	         |t        j                         }|t        j                  d      }g }| j	                         }t        | j                        dk\  r;| j                  j                  |       t        j                  | j                        }nt        j                  |      }t        |j                               }|j                         j                  }d}||   }	||d      d   }
t        j                   |
|
j"                  j$                  | j&                  |||      }|	j(                  |_        |j                  |       |dd D ].  }|\  }}||   d   }
t        j                   |
|
j"                  j$                  | j&                  |||      }t+        dt        ||               D ]4  }||   |dz
     }|j,                  j.                  j                  ||f       6 ||	j0                  |	j(                  z   k(  r|dz  }||   }	|	j(                  |_        nLt+        t        ||         |dz         D ]'  }|j,                  j2                  j                  |       ) d|_        |j                  |       |}1 |S )z
        generates the segmentList from an fbList, including any overlaid Segments

        if fbRules is None, creates a new rules.Rules() object

        if maxPitch is None, uses pitch.Pitch('B5')
        NB5r   r   r   )r   Rulesr
   PitchrX   r   r`   rm   r   extractHarmoniescreateOffsetMappingsortedkeysr)   notesr   OverlaidSegmentrk   rR   rd   rs   rO   fbRules_partPitchLimitsoffset_partsToCheck)rf   r   numPartsmaxPitchsegmentListr   currentMappingallKeysbassNoteIndexpreviousBassNoterQ   previousSegmentk	startTimeunused_endTimecurrentSegment
partNumber
upperPitchs                     r#   retrieveSegmentsz FiguredBassLine.retrieveSegmentsE  se    ?kkmG{{4(H((*t""#q(&&x0$55d6I6IJN$88BN,,./##%++#M2!'!*-b1!11(H<N<N<]<]37==3:HhP )9(F(F%?+A*+'Y%a(,H$44Xx?Q?Q?`?`6:mm6=xSN $As>!+<'=>
+A.zA~>
&&77>>
J?WX ? ,336F6T6TTT"#+M#: /?/M/M,"'N1,=(>1"MJ#++99@@L #N 03,~.,O) * r$   c                :    | j                   j                  |       y N)r`   rm   )rf   music21Parts     r#   overlayPartzFiguredBassLine.overlayParty  s    "";/r$   c           	     \   |t        j                         }|t        j                  d      }g }d}| j                  D ]!  }	 |j
                  }d|v r nd|v sd|v sd} n |r| j                  D ]  }g }	|j                  D ]  }
|	j                  |
j                          i }|	D ]  }|||<   	 |j                         }d }t        j                  |j                         j                   ||j                  j                               }t#        j$                  || j&                  ||||	      } ||j                  j                         |_        |j                  |        n| j)                  |||      }t+        |      d
k\  rt-        t+        |      dz
        D ]q  }||   }||dz      }|j/                  |      }t1        j2                  t4              |_        t5        |      }|D ]#  \  }}|j6                  |   j                  |       % s | j9                  |       n?t+        |      dk(  r$|d   }t5        |j;                               |_        n|st?        d      tA        || jB                  | jD                  | jF                  dd | jH                        S # t        $ r Y lw xY w)aA	  
        Creates a :class:`~music21.figuredBass.segment.Segment`
        for each (bassNote, notationString) pair
        added using :meth:`~music21.figuredBass.realizer.FiguredBassLine.addElement`.
        Each Segment is associated
        with the :class:`~music21.figuredBass.rules.Rules` object provided, meaning that rules are
        universally applied across all Segments. The number of parts in a realization
        (including the bass) can be controlled through numParts, and the maximum pitch can
        likewise be controlled through maxPitch.
        Returns a :class:`~music21.figuredBass.realizer.Realization`.

        If this method is called without having provided any (bassNote, notationString) pairs,
        a FiguredBassLineException is raised. If only one pair is provided, the Realization will
        contain :meth:`~music21.figuredBass.segment.Segment.allCorrectConsecutivePossibilities`
        for the one note.

        if `fbRules` is None, creates a new rules.Rules() object

        if `maxPitch` is None, uses pitch.Pitch('B5')

        >>> from music21.figuredBass import realizer
        >>> from music21.figuredBass import rules
        >>> fbLine = realizer.FiguredBassLine(key.Key('B'), meter.TimeSignature('3/4'))
        >>> fbLine.addElement(note.Note('B2'))
        >>> fbLine.addElement(note.Note('C#3'), '6')
        >>> fbLine.addElement(note.Note('D#3'), '6')
        >>> fbRules = rules.Rules()
        >>> r1 = fbLine.realize(fbRules)
        >>> r1.getNumSolutions()
        208
        >>> fbRules.forbidVoiceOverlap = False
        >>> r2 = fbLine.realize(fbRules)
        >>> r2.getNumSolutions()
        7908

        OMIT_FROM_DOCS
        >>> fbLine3 = realizer.FiguredBassLine(key.Key('C'), meter.TimeSignature('2/4'))
        >>> h1 = harmony.ChordSymbol('C')
        >>> h1.bass().octave = 4
        >>> fbLine3.addElement(h1)
        >>> h2 = harmony.ChordSymbol('G')
        >>> h2.bass().octave = 4
        >>> fbLine3.addElement(h2)
        >>> r3 = fbLine3.realize()
        >>> r3.getNumSolutions()
        13
        >>> fbLine4 = realizer.FiguredBassLine(key.Key('C'), meter.TimeSignature('2/4'))
        >>> fbLine4.addElement(roman.RomanNumeral('I'))
        >>> fbLine4.addElement(roman.RomanNumeral('IV'))
        >>> r4 = fbLine4.realize()
        >>> r4.getNumSolutions()
        13

        r   Fr+   ri   rj   Tc                    | dk7  r| S dS )Nr   g      ? )ys    r#   gz"FiguredBassLine.realize.<locals>.g  s     !S11c1r$   rr   )rQ   fbScaler   r   r   listOfPitchesr   r   r   z/No (bassNote, notationString) pairs to realize.r   )realizedSegmentListrZ   r[   overlaidPartsr5   )%r   r   r
   r   re   rl   AttributeErrorpitchesrm   namevaluesr	   r+   bassnameWithOctavedurationrs   r   Segmentrd   r   r   rO   "allCorrectConsecutivePossibilitiescollectionsdefaultdictlist	movements_trimAllMovementsallCorrectSinglePossibilitiescorrectArn   RealizationrZ   r[   r`   r6   )rf   r   r   r   r   listOfHarmonyObjectsitemrp   harmonyObjectlistOfPitchesJustNames	thisPitchdx
outputListr   
passedNotecorrespondingSegmentsegmentIndexsegmentAsegmentB	correctABlistABpossibApossibBs                           r#   rY   zFiguredBassLine.realize|  s   p ?kkmG{{4(H$LLDLL {"mq&8'+$ !  !%)+&!.!6!6I*11)..A "7 /AAaD 0XXZ
2 "YY}'9'9';'J'J56}7M7M7[7[5\^
'.
?C}}?F@H@HEO(Q$ 67}7M7M7[7[5\$2""#78- ".2 //8LK{q  %c+&6&: ;&|4&|a'78$GGQ	%0%<%<T%B"i*0&Wg&&w/66w? +1 !< "";/""1~H $X%K%K%M NH*+\]]{$**"&++T=P=PQRSU=V'+'8'8: 	:k " s   J	J+*J+c                2   t        |      dk(  st        |      dk(  ryt        |      dk\  r|j                          d}t        dt        |      dz
        D ]  }||dz      j                  }||   j                  t	        j                               D ]  \  }}|r	|=  t	        |j                               D ]   \  }}t	        t        fd|            ||<   "  t	        |j                               D ]  \  }}|r	||=  |j                          yy)a  
        Each :class:`~music21.figuredBass.segment.Segment` which resolves to another
        defines a list of movements, nextMovements. Keys for nextMovements are correct
        single possibilities of the current Segment. For a given key, a value is a list
        of correct single possibilities in the subsequent Segment representing acceptable
        movements between the two. There may be movements in a string of Segments which
        directly or indirectly lead nowhere. This method is designed to be called on
        a list of Segments **after** movements are found, as happens in
        :meth:`~music21.figuredBass.realizer.FiguredBassLine.realize`.
        r   r   T   Nc                    | v S r   r   )possibBBmovementsBCs    r#   <lambda>z3FiguredBassLine._trimAllMovements.<locals>.<lambda>  s
    [1Hr$   )r   reverserO   r   r   itemsfilter)	rf   r   movementsABr   r   possibCListr   possibBListr   s	           @r#   r   z!FiguredBassLine._trimAllMovements  s$    {q C$4$9"!K %a[)9A)= >),*:;EE),7AA.2;3D3D3F.G*Wk&'0 /H /3;3D3D3F.G*Wk+/I;W,YK( /H !? +/{/@/@/B*C&+"#G, +D !) #r$   )NNr   )ro   z	note.Note)N   N)__name__
__module____qualname____doc__
_DOC_ORDERr]   __annotations__rg   r:   rX   r   r   rY   r   r   r$   r#   r   r      sN    " ?J
!I~ %N0d2h0z:x!r$   c                  ^    e Zd ZU dZg dZddiZded<   d Zd Zd	 Z	d
 Z
d Zd Zd ZddZy)r   a@  
    Returned by :class:`~music21.figuredBass.realizer.FiguredBassLine` after calling
    :meth:`~music21.figuredBass.realizer.FiguredBassLine.realize`. Allows for the
    generation of realizations as a :class:`~music21.stream.Score`.

    * See the :mod:`~music21.figuredBass.examples` module for examples on the generation
      of realizations.
    * A possibility progression is a valid progression through a string of
      :class:`~music21.figuredBass.segment.Segment` instances.
      See :mod:`~music21.figuredBass.possibility` for more details on possibilities.
    )getNumSolutionsgenerateRandomRealizationgenerateRandomRealizationsgenerateAllRealizationsgetAllPossibilityProgressionsgetRandomPossibilityProgression-generateRealizationFromPossibilityProgressionkeyboardStyleOutputa  
            True by default. If True, generated realizations
            are represented in keyboard style, with two staves. If False,
            realizations are represented in chorale style with n staves,
            where n is the number of parts. SATB if n = 4.r\   r]   c                    d|v r
|d   | _         d|v r8|d   | _        t        j                  | j                  j                        | _        d|v r
|d   | _        d|v r
|d   | _        d|v r
|d   | _        d| _	        y )Nr   rZ   r[   r   r5   T)
_segmentList_inKeyr   r.   rx   _keySig_inTimer`   r6   r   )rf   fbLineOutputss     r#   rg   zRealization.__init__4  s     M1 -.C DDm#'0DK++DKK,>,>?DL}$(2DLm+"/"@DM) -m <D#' r$   c                <   t        | j                        dk(  r"t        | j                  d   j                        S | j                  j                          i }t	        dt        | j                              D ]x  }| j                  |   }i }|s-|j
                  D ]  }t        |j
                  |         ||<    n4|j
                  D ]%  }d}|j
                  |   D ]
  }|||   z  } |||<   ' |}z d}|D ]
  }|||   z  } | j                  j                          |S )a  
        Returns the number of solutions (unique realizations) to a Realization by calculating
        the total number of paths through a string of :class:`~music21.figuredBass.segment.Segment`
        movements. This is faster and more efficient than compiling each unique realization into a
        list, adding it to a master list, and then taking the length of the master list.

        >>> from music21.figuredBass import examples
        >>> fbLine = examples.exampleB()
        >>> fbRealization = fbLine.realize()
        >>> fbRealization.getNumSolutions()
        422
        >>> fbLine2 = examples.exampleC()
        >>> fbRealization2 = fbLine2.realize()
        >>> fbRealization2.getNumSolutions()
        833
        r   r   )r   r   r   r   rO   r   )	rf   pathListr   r   newPathListr   	prevValuer   numSolutionss	            r#   r   zRealization.getNumSolutionsC  s,   " t  !Q&t((+4455!!#!!S):):%;<L((6HK'11G+.x/A/A'/J+KK(  2  (11G !I#+#5#5g#>!Xg%66	 $?+4K(	  2
 #H = GHW--L  !!#r$   c                |   g }t        | j                        dk(  r2| j                  d   j                  D ]  }|j                  |g        |S | j                  d   j                  }|D ]!  }||   }|D ]  }|j                  ||g        # t        dt        | j                        dz
        D ]  }| j                  |   j                  }t        t        |            D ]Y  }|j                  d      }|d   }||   D ]9  }	t        j                  |      }
|
j                  |	       |j                  |
       ; [  |S )a  
        Compiles each unique possibility progression, adding
        it to a master list. Returns the master list.

        .. warning:: This method is unoptimized, and may take a prohibitive amount
            of time for a Realization which has more than 200,000 solutions.
        r   r   r   )r   r   r   rm   r   rO   popry   )rf   progressionsr   currMovementsr   r   r   unused_progressionIndexprogressionpossibCnewProgressions              r#   r   z)Realization.getAllPossibilityProgressionsm  s>    t  !Q&,,Q/88##WI. 9))!,66$G'0K&##Wg$67 ' %
 "!S):):%;a%?@L --l;EEM+0\1B+C'*..q1%b/,W5G%)YY{%;N"))'2 ''7  6 ,D A r$   c                z   g }t        | j                        dk(  rCt        j                  | j                  d   j                  d      d   }|j                  |       |S | j                  d   j                  }| j                         dk(  rt        d      t        j                  |j                         d      d   }|j                  |       t        t        | j                        dz
        D ]J  }| j                  |   j                  }t        j                  ||   d      d   }|j                  |       |}L |S )zB
        Returns a random unique possibility progression.
        r   r   Zero solutions)r   r   randomsampler   rm   r   r   rn   r   rO   )rf   r   r   r   
prevPossibr   
nextPossibs          r#   r   z+Realization.getRandomPossibilityProgression  s    t  !Q&mmD$5$5a$8$A$A1EaHGw'))!,66!Q&*+;<<]]=#5#5#7;A>
:&!#d&7&7"81"<=L --l;EEM}Z'@!DQGJz*#J	 > r$   c                	   t        j                         }t        j                         }|j                  t	        j
                  | j                        t	        j
                  | j                        g       d}| j                  dk7  rDt        j                  | j                        }|j                  t	        j
                  |             | j                  rt        j                         }|j                  d|       |j                  t	        j
                  | j                        t	        j
                  | j                        g       |$|j                  t	        j
                  |             t        t        | j                              D ]  }||   }| j                  |   j                   }|j                  t	        j
                  |             |dd }	t#        j$                  |	      }
| j                  |   j&                  |
_        |j                  |
        |j                  dt)        j*                                |j-                  dd       |-|d   j/                  d	       |d   j1                          ng }t        t        |d         d
z
        D ]  }t        j                         }|j                  d|       |j                  t	        j
                  | j                        t	        j
                  | j                        g       |$|j                  t	        j
                  |             |j                  |        t        t        | j                              D ]  }||   }| j                  |   j                   }|j                  t	        j
                  |             t        t        |      d
z
        D ]L  }t        j2                  ||         }| j                  |   j&                  |_        ||   j                  |       N  |D ]i  }t)        j4                  |dd      }|j                  d|       |j-                  dd       |C|d   j/                  d	       |d   j1                          k |j                  dt)        j6                                |j-                  dd       |'|d   j/                  d	       |d   j1                          |j                  d|       |S )zn
        Generates a realization as a :class:`~music21.stream.Score` given a possibility progression.
        Nr   rr   r   r   TFrt   r   r   )allowTreble8vbrecurse)r   Scorer_   rm   ry   rz   r   r   r6   r	   r{   r   insertrO   r   r   rQ   r   Chordrs   r   
TrebleClefr|   r   r   r+   bestClefrw   )rf   possibilityProgressionsolr   r   	rightHandr   r   rQ   	rhPitchesrhChord
upperParts_partNumberfbPartr   n1	upperPartrp   s                     r#   r   z9Realization.generateRealizationFromPossibilityProgression  s    lln;;=t||4dmmDLL6QRS#		(9(9:AOODMM!,-##IJJsI&dmmDLL94==;VWX}  q!12 %c$*;*;&< =0>,,\:CCh 78#AbM	++i0(,(9(9,(G(U(U%  ) !> S$//"34""4e"T}!  #!++- J$S)?)B%Ca%GH

3't}}T\\:DMM$,,<WXY=MM$--"23!!&)  I !&c$*;*;&< =0>,,\:CCh 78"'Gq(8"9J7:#67B'+'8'8'F'T'TB$z*11"5 #: !> (	MM)D$O  a(&&tRW&X=aL$$Q'aL//1 ( 	T]]_-dO=QKOOAQK&&(

3!
r$   c                   t        j                         }| j                         }|st        d      | j	                  |d         }|D ]  }|j                  |        t        dt        |            D ]M  }| j	                  ||         }t        t        |            D ]   }||   D ]  }||   j                  |        " O |S )z
        Generates all unique realizations as a :class:`~music21.stream.Score`.

        .. warning:: This method is unoptimized, and may take a prohibitive amount
            of time for a Realization which has more than 100 solutions.
        r  r   r   )r   r
  r   rn   r   rm   rO   r   )	rf   allSolspossibilityProgressionssol0r   possibIndexsolX	partIndexmusic21Measures	            r#   r   z#Realization.generateAllRealizations  s     ,,."&"D"D"F&*+;<<AABYZ[B\]KNN;'   !C(?$@AKEE'46D"3t9-	&*9oNI&--n= '6 . B r$   c                D    | j                         }| j                  |      S )z\
        Generates a random unique realization as a :class:`~music21.stream.Score`.
        )r   r   )rf   r  s     r#   r   z%Realization.generateRandomRealization  s%     "&!E!E!GAABXYYr$   c                t   || j                         kD  r| j                         S t        j                         }| j	                         }|D ]  }|j                  |        t        d|      D ]I  }| j	                         }t        t        |            D ]   }||   D ]  }||   j                  |        " K |S )z
        Generates *amountToGenerate* unique realizations as a :class:`~music21.stream.Score`.

        .. warning:: This method is unoptimized, and may take a prohibitive amount
            of time if amountToGenerate is more than 100.
        r   )r   r   r   r
  r   rm   rO   r   )	rf   amountToGenerater  r  r   unused_counter_solutionr  r  r   s	            r#   r   z&Realization.generateRandomRealizations  s     d2244//11,,.--/KNN;'   (-Q0@'A#113D"3t9-	&*9oNI&--n= '6 . (B r$   N)   )r   r   r   r   r   r]   r   rg   r   r   r   r   r   r   r   r   r$   r#   r   r     sT    
CJ
 	  >!I~ ((T@0EN0Zr$   r   c                      e Zd Zy)rn   N)r   r   r   r   r$   r#   rn   rn   '  s    r$   rn   c                      e Zd Zd Zy)Testc                   ddl m} |j                  dd      }|t        j                     d   }| j                  |j                  d       t        |      }| j                  |j                  j                  d       d	|_        t        |      }| j                  |j                  j                  d
       d|_        t        |      }| j                  |j                  j                  d       d|_        t        |      }| j                  |j                  j                  d       dD ]U  }| j                  |      5  ||_        t        |      }| j                  |j                  j                  |       d d d        W y # 1 sw Y   bxY w)Nr   )	converterz#tinynotation: 4/4 C4 F4 G4_64 G4 C1F)r|   r   64z6, 4z#6#42z	#6, #4, 2z#64#2z	#6, 4, #2z6
4r   )single_symbol)music21r*  parser	   r+   assertEquallyricrH   rk   rR   subTest)rf   r*  s
third_note	unused_fbr,  s         r#   testMultipleFiguresInLyriczTest.testMultipleFiguresInLyric.  sI   %OOAPUOVtyy\!_
))40)!,	--<<fE"
)!,	--<<kJ"
)!,	--<<kJ "
)!,	--<<fE $MM:#0
 1!4	  !5!5!D!DmT ;: $::s   <9F  F		N)r   r   r   r5  r   r$   r#   r(  r(  -  s    Ur$   r(  __main__)r;   zstream.Streamr(   r   r   )#r   
__future__r   r   ry   r  typingr3   unittestr-  r   r   r   r   r   r	   r
   r   music21.figuredBassr   r   r   r   r   rH   rV   r   r   r   Music21Exceptionrn   TestCaser(  r   mainTestr   r$   r#   <module>r>     s   < #               ' ( - % '_D=<Z Zz
D DN $%8{,
	|<< 	U8 U> zGT r$   