
    rh                       S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSK	J
r
  SSK	Jr  SSK	Jr  SSK	Jr  SSK	Jr  SS	K	Jr  SS
K	Jr  SSK	Jr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  \R0                  (       a  SSKJr  SS jrSS jr " S S5      r " S S5      r\\\\/r " S S\R@                  5      r! " S S\RD                  5      r#\$S:X  a  SSK	r	\	RJ                  " \#5        gg)aX  
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)StreamIteratorFiguredBassLinec                6  ^ U R                  5       nUR                  [        R                  5      nU[        R
                     R                  5       =n(       a  UnOPU[        R                     R                  5       =n(       a  UR                  S5      nO[        R
                  " S5      nU[        R                     R                  5       =n(       a  UnO[        R                  " S5      n[        XG5      nU R                  5       (       aB  U R                  SSS9n	[        R                  (       a  U	c   eU	R                   n
U
S:w  a  Xl        SU4S jjmU H  nUR$                  (       a  S	n['        UR$                  5       Hi  u  pUR(                  S
;   a  M  SUR(                  ;   a  UR(                  nOT" XR(                  5      nUS-   [+        UR$                  5      :  d  Md  US-  nMk     UR-                  X5        M  UR-                  U5        M     U$ )aN  
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                   > SnUS   S;   a*  [        U5      S:  a  US   R                  5       (       a  SnOUS   R                  5       (       a  SnOSnXSU -  n XS (       a  U S-  n T" XUS 5      n U $ )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      V/home/james-whalen/.local/lib/python3.13/site-packages/music21/figuredBass/realizer.pyr#   5figuredBassFromStream.<locals>.updateAnnotationStringz   s     %&Q<6!c)nq&8Yq\=S=S=U=U#$ q\##%%#$  $( &;';<<*+$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_firstr7   nr    i
lyric_liner#   s                  @r$   figuredBassFromStreamrJ   E   s   6 
			B


		
*Ccgg;$$&&x& !1!1288:	:		:!''0 e))*0022x2  '		#B$$Q$$???&&&))#)O . 88$&!*188!4??j0*//) (2$ (>>NP_P_'`$q53qxx=($,$ "5 MM!.MM!# & Ir&   c                ^   / U l         [        R                  " U5      nUR                  (       d  g[	        UR                   Vs/ s H  n[        U5      PM     sn5      nUR                   H:  nSn[        U[        U5      -
  5       H  nUS-  nM
     U R                  XS-   SS9  M<     gs  snf )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)r9   r   NotationfigureStringsmaxr   rangeaddLyric)bassNotenotationStringrG   fs	maxLengthspacesInFrontrH   s          r$   addLyricsToBassNoterX      s    $ HO.)A??q7SW78Iooy3r7*+AS M ,-,t<	  8s   B*c                  t    \ rS rSr% Sr/ SQrSSS.rS\S'   SS
 jrSSS jjr	S r
SS jrS rSS jrS rSrg	)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                :   Uc  [         R                  " S5      nUc  [        R                  " S5      nXl        X l        SU l        [        R                  " 5       U l	        [        R                  " UR                  S5      UR                  5      U l        / U l        g )Nr   r   r   r   )r   r.   r   r2   r]   r^   r8   r   Part_overlaidPartsr   FiguredBassScalepitchFromDegreemode_fbScale_fbList)selfr]   r^   s      r$   __init__FiguredBassLine.__init__   sv    =GGCLE>((/F
$kkm%66u7L7LQ7OQVQ[Q[\r&   c                
   X!R                   l        UR                  nSU;   a(  U R                  R	                  X45        [        X5        gSU;   d  SU;   a  U R                  R	                  U5        g[        SSU< 3-   5      e)ad  
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ChordSymbolz(Not a valid bassObject (only note.Note, z;harmony.ChordSymbol, and roman.RomanNumeral supported) was N)	editorialrT   classesrh   appendrX   FiguredBassLineException)ri   
bassObjectrT   cs       r$   r<   FiguredBassLine.addElement   s    4 /=+Q;LL <=
;q MQ$6LL
+*:OPZ~^_` `r&   c                .   [         R                  " 5       nUR                  [        R                  " 5       5        UR                  [
        R                  " U R                  R                  5      5        UR                  [        R                  " U R                  5      5        SnU R                  S:w  a/  [        R                  " U R                  S9nUR                  U5        U R                   H  u  p4UR                  U5        M     UR!                  SSS9nUby  UR#                  [         R$                  5      R'                  5       nUR)                  UR#                  [        R                  5      R'                  5       5        UR+                  5         U$ )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   rb   rq   r   BassClefr   r0   r]   sharpscopydeepcopyr^   r8   r	   Restrh   makeNotationr,   Measurer/   removepadAsAnacrusis)ri   bassLinerrS   unused_notationStringbl2m0s          r$   r[    FiguredBassLine.generateBassLine  s   @ ;;=((():):;<dkk23#		(9(9:AOOA15-XOOH% 2> ##EPU#V=''7==?BIIb++DII6<<>?
r&   c           	        Uc  [         R                  " 5       nUc  [        R                  " S5      n/ nU R	                  5       n[        U R                  5      S:  a<  U R                  R                  U5        [        R                  " U R                  5      nO[        R                  " U5      n[        UR                  5       5      nUR                  5       R                  nSnXX   n	XgS      S   n
[        R                   " XR"                  R$                  U R&                  XU5      nU	R(                  Ul        UR                  U5        USS  GH,  nUu  pXl   S   n
[        R                   " XR"                  R$                  U R&                  XU5      n[+        S[        Xl   5      5       H4  nXl   US-
     nUR,                  R.                  R                  UU45        M6     XR0                  U	R(                  -   :X  a  US-  nXX   n	U	R(                  Ul        OM[+        [        Xl   5      US-   5       H(  nUR,                  R2                  R                  U5        M*     SUl        UR                  U5        UnGM/     U$ )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
   Pitchr[   r   rc   rq   r   extractHarmoniescreateOffsetMappingsortedkeysr+   notesr   OverlaidSegmentro   rT   rg   rx   rQ   fbRules_partPitchLimitsoffset_partsToCheck)ri   r   numPartsmaxPitchsegmentListr   currentMappingallKeysbassNoteIndexpreviousBassNoterS   previousSegmentk	startTimeunused_endTimecurrentSegment
partNumber
upperPitchs                     r$   retrieveSegments FiguredBassLine.retrieveSegmentsM  sJ    ?kkmG{{4(H((*t""#q(&&x0$55d6I6IJN$88BN,,./##%++#2!!*-b1!11(<N<N<]<]37==3:hP )9(F(F%?+A*+'Y%(,H$44X?Q?Q?`?`6:mm6=SN $As>+<'=>
+.zA~>
&&77>>
J?WX ? 336F6T6TTT"#+#: /?/M/M,"'N,=(>1"MJ#++99@@L #N 03,~.,O) * r&   c                :    U R                   R                  U5        g N)rc   rq   )ri   music21Parts     r$   overlayPartFiguredBassLine.overlayPart  s    "";/r&   c           
        Uc  [         R                  " 5       nUc  [        R                  " S5      n/ nSnU R                   H(  n UR
                  nSU;   a    OSU;   d  SU;   d  M&  Sn  O   U(       Ga  U R                   H  n/ n	UR                   H  n
U	R                  U
R                  5        M      0 nU	 H  nXU'   M	     UR                  5       nS n[        R                  " UR                  5       R                  U" UR                  R                   5      S9n["        R$                  " UU R&                  UUUUS	9nU" UR                  R                   5      Ul        UR                  U5        M     OU R)                  XU5      n[+        U5      S
:  a  [-        [+        U5      S-
  5       Hu  nUU   nUUS-      nUR/                  U5      n[0        R2                  " [4        5      Ul        [5        U5      nU H$  u  nnUR6                  U   R                  U5        M&     Mw     U R9                  U5        OE[+        U5      S:X  a$  US   n[5        UR;                  5       5      Ul        OU(       d  [?        S5      e[A        X@RB                  U RD                  U RF                  SS U RH                  S9$ ! [         a     GM  f = f)a  
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-   rm   rn   Tc                    U S:w  a  U $ S$ )Nr   g      ? )ys    r$   g"FiguredBassLine.realize.<locals>.g  s     !S11c1r&   rw   )rS   fbScaler   r   r   listOfPitchesr   r   r   z/No (bassNote, notationString) pairs to realize.r   )realizedSegmentListr]   r^   overlaidPartsr7   )%r   r   r
   r   rh   rp   AttributeErrorpitchesrq   namevaluesr	   r-   bassnameWithOctavedurationrx   r   Segmentrg   r   r   rQ   "allCorrectConsecutivePossibilitiescollectionsdefaultdictlist	movements_trimAllMovementsallCorrectSinglePossibilitiescorrectArr   Realizationr]   r^   rc   r8   )ri   r   r   r   r   listOfHarmonyObjectsitemrt   harmonyObjectlistOfPitchesJustNames	thisPitchdx
outputListr   
passedNotecorrespondingSegmentsegmentIndexsegmentAsegmentB	correctABlistABpossibApossibBs                           r$   r\   FiguredBassLine.realize  s   p ?kkmG{{4(H$LLDLL {"mq&8'+$ !  !%)+&!.!6!6I*11)..A "7 /AaD 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   J77
KKc                T  ^ [        U5      S:X  d  [        U5      S:X  a  g[        U5      S:  a  UR                  5         Sn[        S[        U5      S-
  5       H  nXS-      R                  nX   R                  m[	        TR                  5       5       H  u  pEU(       a  M  TU	 M     [	        UR                  5       5       H   u  pg[	        [        U4S jU5      5      X&'   M"     M     [	        UR                  5       5       H  u  pgU(       a  M  X&	 M     UR                  5         gg)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                   > U T;   $ r   r   )possibBBmovementsBCs    r$   <lambda>3FiguredBassLine._trimAllMovements.<locals>.<lambda>  s
    [1Hr&   )r   reverserQ   r   r   itemsfilter)	ri   r   movementsABr   r   possibCListr   possibBListr   s	           @r$   r   !FiguredBassLine._trimAllMovements   s    {q C$4$9"!K %a[)9A)= >)*:;EE)7AA.2;3D3D3F.G*W&;'0 /H /3;3D3D3F.G*W+/I;W,YK( /H !? +/{/@/@/B*C&"{#, +D !) #r&   )rh   rg   rc   r8   r]   r^   )NNr   )rs   z	note.Note)N   N)__name__
__module____qualname____firstlineno____doc__
_DOC_ORDERr`   __annotations__rj   r<   r[   r   r   r\   r   __static_attributes__r   r&   r$   r   r      sO    $ ?J
!I~ %`N1f2h0z:x!r&   c                  h    \ rS rSr% Sr/ SQrSS0rS\S'   S rS	 r	S
 r
S rS rS rS rSS jrSrg)r   i$  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                   SU;   a
  US   U l         SU;   a9  US   U l        [        R                  " U R                  R                  5      U l        SU;   a
  US   U l        SU;   a
  US   U l        SU;   a
  US   U l        SU l	        g )Nr   r]   r^   r   r7   T)
_segmentList_inKeyr   r0   r}   _keySig_inTimerc   r8   r   )ri   fbLineOutputss     r$   rj   Realization.__init__=  s     M1 -.C DDm#'0DK++DKK,>,>?DL}$(2DLm+"/"@DM) -m <D#' r&   c                T   [        U R                  5      S:X  a"  [        U R                  S   R                  5      $ U R                  R                  5         0 n[	        S[        U R                  5      5       H  nU R                  U   n0 nU(       d.  UR
                   H  n[        UR
                  U   5      XE'   M     O6UR
                   H&  nSnUR
                  U    H
  nXaU   -  nM     XdU'   M(     UnM     SnU H
  nXU   -  nM     U R                  R                  5         U$ )am  
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   rQ   r   )	ri   pathListr   r   newPathListr   	prevValuer   numSolutionss	            r$   r   Realization.getNumSolutionsL  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#>!g%66	 $?+4(	  2
 #H = GW--L  !!#r&   c                   / n[        U R                  5      S:X  a4  U R                  S   R                   H  nUR                  U/5        M     U$ U R                  S   R                  nU H"  nX2   nU H  nUR                  X%/5        M     M$     [        S[        U R                  5      S-
  5       H  nU R                  U   R                  n[        [        U5      5       H\  nUR                  S5      nUS   nX5    H;  n	[        R                  " U5      n
U
R                  U	5        UR                  U
5        M=     M^     M     U$ )z
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   rq   r   rQ   popr~   )ri   progressionsr   currMovementsr   r   r   unused_progressionIndexprogressionpossibCnewProgressions              r$   r   )Realization.getAllPossibilityProgressionsv  s8    t  !Q&,,Q/88##WI. 9))!,66$G'0K&##W$67 ' %
 "!S):):%;a%?@L --l;EEM+0\1B+C'*..q1%b/,5G%)YY{%;N"))'2 ''7  6 ,D A r&   c                   / n[        U R                  5      S:X  aD  [        R                  " U R                  S   R                  S5      S   nUR                  U5        U$ U R                  S   R                  nU R                  5       S:X  a  [        S5      e[        R                  " UR                  5       S5      S   nUR                  U5        [        [        U R                  5      S-
  5       HK  nU R                  U   R                  n[        R                  " X4   S5      S   nUR                  U5        UnMM     U$ )z2
Returns a random unique possibility progression.
r   r   Zero solutions)r   r   randomsampler   rq   r   r   rr   r   rQ   )ri   r  r   r  
prevPossibr   
nextPossibs          r$   r   +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}'@!DQGJz*#J	 > r&   c                "
   [         R                  " 5       n[         R                  " 5       nUR                  [        R
                  " U R                  5      [        R
                  " U R                  5      /5        SnU R                  S:w  aC  [        R                  " U R                  S9nUR                  [        R
                  " U5      5        U R                  (       Ga  [         R                  " 5       nUR                  SU5        UR                  [        R
                  " U R                  5      [        R
                  " U R                  5      /5        Ub%  UR                  [        R
                  " U5      5        [        [        U R                  5      5       H  nX   nU R                  U   R                   nUR                  [        R
                  " U5      5        USS n	["        R$                  " U	5      n
U R                  U   R&                  U
l        UR                  U
5        M     UR                  S[(        R*                  " 5       5        UR-                  SSS9  Ub'  US   R/                  S	5        US   R1                  5         GO/ n[        [        US   5      S
-
  5       H  n[         R                  " 5       nUR                  SU5        UR                  [        R
                  " U R                  5      [        R
                  " U R                  5      /5        Ub%  UR                  [        R
                  " U5      5        UR                  U5        M     [        [        U R                  5      5       H  nX   nU R                  U   R                   nUR                  [        R
                  " U5      5        [        [        U5      S
-
  5       HL  n[        R2                  " X|   5      nU R                  U   R&                  Ul        X   R                  U5        MN     M     U Hg  n[(        R4                  " USSS9nUR                  SU5        UR-                  SSS9  Uc  M@  US   R/                  S	5        US   R1                  5         Mi     UR                  S[(        R6                  " 5       5        UR-                  SSS9  Ub'  US   R/                  S	5        US   R1                  5         UR                  SU5        U$ )z^
Generates a realization as a :class:`~music21.stream.Score` given a possibility progression.
Nr   rw   r   r   TFry   r   r   )allowTreble8vbrecurse)r   Scorerb   rq   r~   r   r   r   r8   r	   r   r   insertrQ   r   r   rS   r   Chordrx   r   
TrebleClefr   r
  r   r-   bestClefr|   )ri   possibilityProgressionsolr   r   	rightHandr   r   rS   	rhPitchesrhChord
upperPartsr   fbPartn1	upperPartrt   s                    r$   r   9Realization.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#C(>q(A$BQ$FG


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

3!
r&   c                   [         R                  " 5       nU R                  5       nU(       d  [        S5      eU R	                  US   5      nU H  nUR                  U5        M     [        S[        U5      5       HO  nU R	                  X%   5      n[        [        U5      5       H!  nXg    H  nX   R                  U5        M     M#     MQ     U$ )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   rr   r   rq   rQ   r   )	ri   allSolspossibilityProgressionssol0r   possibIndexsolX	partIndexmusic21Measures	            r$   r   #Realization.generateAllRealizations  s     ,,."&"D"D"F&*+;<<AABYZ[B\]KNN;'   !C(?$@AKEE'46D"3t9-	&*oN&--n= '6 . B r&   c                D    U R                  5       nU R                  U5      $ )zL
Generates a random unique realization as a :class:`~music21.stream.Score`.
)r   r   )ri   r!  s     r$   r   %Realization.generateRandomRealization  s%     "&!E!E!GAABXYYr&   c                   XR                  5       :  a  U R                  5       $ [        R                  " 5       nU R	                  5       nU H  nUR                  U5        M     [        SU5       HL  nU R	                  5       n[        [        U5      5       H!  nXg    H  nX'   R                  U5        M     M#     MN     U$ )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   rq   rQ   r   )	ri   amountToGenerater,  r.  r   unused_counter_solutionr0  r1  r2  s	            r$   r   &Realization.generateRandomRealizations  s     2244//11,,.--/KNN;'   (-Q0@'A#113D"3t9-	&*oN&--n= '6 . (B r&   )r   r   r   rc   r8   r   r   N)   )r   r   r   r   r   r   r`   r   rj   r   r   r   r   r   r   r   r   r   r&   r$   r   r   $  sT    CJ
 	  >!I~ ((TB0EN2Zr&   r   c                      \ rS rSrSrg)rr   i3  r   N)r   r   r   r   r   r   r&   r$   rr   rr   3  s    r&   rr   c                      \ rS rSrS rSrg)Testi9  c                   SSK Jn  UR                  SSS9nU[        R                     S   nU R                  UR                  S5        [        U5      nU R                  UR                  R                  S5        S	Ul        [        U5      nU R                  UR                  R                  S
5        SUl        [        U5      nU R                  UR                  R                  S5        SUl        [        U5      nU R                  UR                  R                  S5        S HR  nU R                  US9   XSl        [        U5      nU R                  UR                  R                  U5        S S S 5        MT     g ! , (       d  f       Mf  = f)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lyricrJ   ro   rT   subTest)ri   r?  s
third_note	unused_fbrA  s         r$   testMultipleFiguresInLyricTest.testMultipleFiguresInLyric:  sG   %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   68E;;
F
	r   N)r   r   r   r   rJ  r   r   r&   r$   r=  r=  9  s    Ur&   r=  __main__)r=   zstream.Streamr*   r   r   )&r   
__future__r   r   r~   r  typingr5   unittestrB  r   r   r   r   r   r	   r
   r   music21.figuredBassr   r   r   r   r   r6   music21.stream.iteratorr   rJ   rX   r   r   r   Music21Exceptionrr   TestCaser=  r   mainTestr   r&   r$   <module>rU     s   @ #               ' ( - % '??6_D=<\ \~
H HV $%8{,
	|<< 	U8 U> zT r&   