
    3j                       d dl mZ d dlZd dlmZ d dlZd dlmZ d dlmZ d dlm	Z	  ej                  d      Z G d d	      Z G d
 de      Z G d d      Z G d dej                        Zedk(  rd dlZ ej$                  e       yy)    )annotationsN)inf)environment)pitch)musedatazanalysis.enharmonicsc                      e Zd Zd Zy)EnharmonicScoreRulesc                <    d| _         d| _        d| _        d| _        y )NF      )sameStaffLinealterationPenaltyaugDimPenaltymixSharpsFlatsPenaltyselfs    I/DATA/.local/lib/python3.12/site-packages/music21/analysis/enharmonics.py__init__zEnharmonicScoreRules.__init__   s"    "!"%*"    N)__name__
__module____qualname__r    r   r   r	   r	      s    +r   r	   c                       e Zd Z fdZ xZS )ChordEnharmonicScoreRulesc                0    t         |           d| _        y )Nr   )superr   r   )r   	__class__s    r   r   z"ChordEnharmonicScoreRules.__init__    s    %&"r   )r   r   r   r   __classcell__)r   s   @r   r   r      s    ' 'r   r   c                  >    e Zd ZdZefdZd Zd Zd Zd Z	d Z
d Zy	)
EnharmonicSimplifiera  
    Takes any pitch list input and returns the best enharmonic respelling according to the input
    criteria and rule weightings.
    Those criteria and rule weightings are currently fixed, but in future the user should be able
    to select their own combination and weighting of rules according to preferences,
    with predefined defaults for melodic and harmonic norms.
    Note: EnharmonicSimplifier itself returns nothing.
    c                    t        |d   t              r"|D cg c]  }t        j                  |       }}|| _         |       | _        d | _        g | _        | j                          y c c}w )Nr   )	
isinstancestrr   Pitch	pitchList
ruleObjectallPossibleSpellingsallSpellingsgetRepresentations)r   r&   	ruleClassps       r   r   zEnharmonicSimplifier.__init__-   s]    ilC(1:;AQI;"#+$(!! <s   A(c                    g }| j                   D ](  }|g|j                  d      z   }|j                  |       * || _        y)z
        Takes a list of pitches or pitch names and retrieves all enharmonic spellings.
        Note: getRepresentations itself returns nothing.
           N)r&   getAllCommonEnharmonicsappendr)   )r   r)   r,   	spellingss       r   r*   z'EnharmonicSimplifier.getRepresentations7   sF    
 Aa77::I	*   )r   c                n    t        t        j                  | j                         | _        | j                  S )N)list	itertoolsproductr)   r(   r   s    r   
getProductzEnharmonicSimplifier.getProductB   s,    $():):D<M<M)N$O!(((r   c                    | j                          g }t        }| j                  D ]G  }| j                  |      }| j	                  |      }| j                  |      }||z   |z   }||k  sD|}|}I |S )aR  
        Returns a list of pitches in the best enharmonic
        spelling according to the input criteria.

        >>> pList1 = [pitch.Pitch('C'), pitch.Pitch('D'), pitch.Pitch('E')]
        >>> es = analysis.enharmonics.EnharmonicSimplifier(pList1)
        >>> es.bestPitches()
        (<music21.pitch.Pitch C>, <music21.pitch.Pitch D>, <music21.pitch.Pitch E>)
        >>> pList2 = ['D--', 'E', 'F##']
        >>> es = analysis.enharmonics.EnharmonicSimplifier(pList2)
        >>> es.bestPitches()
        (<music21.pitch.Pitch C>, <music21.pitch.Pitch E>, <music21.pitch.Pitch G>)
        )r6   r   r(   getAugDimScoregetAlterationScoregetMixSharpFlatsScore)r   bestPitchesminScorepossibilitythisAugDimScorethisAlterationScorethisMixSharpsFlatScore	thisScores           r   r;   z EnharmonicSimplifier.bestPitchesF   s     	44K"11+>O"&"9"9+"F%)%?%?%L"'*==@VVI8#$) 5 r   c                   | j                   j                  du rydj                  |D cg c]  }|j                   c}      }|j	                  d      }|j	                  d      }||z   dz   | j                   j                  z  }|S c c}w )z
        Returns a score according to the number of sharps and flats in a possible spelling.
        The score is the sum of the flats and sharps + 1, multiplied by the alterationPenalty.
        Fr.    -#)r'   r   joinnamecountr   r=   r,   joinedPossibility	flatCount
sharpCountscores          r   r9   z'EnharmonicSimplifier.getAlterationScorea   s    
 ??,,5GG[$A[QVV[$AB%++C0	&,,S1
Z'!+t/P/PP	 %Bs   Bc                    | j                   j                  du rydj                  |D cg c]  }|j                   c}      }|j	                  d      }|j	                  d      }t        ||g      | j                   j                  z  }|S c c}w )z
        Returns a score based on the mixture of sharps and flats in a possible spelling:
        the score is given by the number of the lesser used accidental (sharps or flats)
        multiplied by the mixSharpsFlatsPenalty.
        Fr.   rC   rD   rE   )r'   r   rF   rG   rH   minrI   s          r   r:   z*EnharmonicSimplifier.getMixSharpFlatsScoreo   s     ??00E9GG[$A[QVV[$AB%++C0	&,,S1
Y
+,t/T/TT	 %Bs   Bc                   | j                   j                  du ryd}t        t        |      dz
        D ]  }t        j
                  j                  ||   j                     }t        j
                  j                  ||dz      j                     }||z
  dz  }|t        j
                  j                  j                  |d      z  } |j                  d      }|j                  d      }||z   dz   | j                   j                  z  }	|	S )z
        Returns a score based on the number of augmented and diminished intervals between
        successive pitches in the given spelling.
        Fr.   rC   (   dddAd)r'   r   rangelenr   base40base40RepresentationrG   base40IntervalTablegetrH   )
r   r=   intervalStrip0p1
base40diffdimCountaugCountrM   s
             r   r8   z#EnharmonicSimplifier.getAugDimScore~   s    
 ??((E1s;'!+,A55k!n6I6IJB55k!a%6H6M6MNBr'RJ8??>>BB:uUUK	 -
 $$S)$$S)H$q(DOO,I,IIr   N)r   r   r   __doc__r	   r   r*   r6   r;   r9   r:   r8   r   r   r   r!   r!   $   s0     -A "	))6r   r!   c                  $    e Zd Zd Zd Zd Zd Zy)Testc                h   t        j                  d      t        j                  d      t        j                  d      g}t        |      }|j                         }| j	                  t        |      d       | j	                  t        |      d       | j                  |d   t         j                         y )NCDE   r   )r   r%   r!   r;   assertEqualrV   assertIsInstance)r   pListesbestPitchLists       r   testBestPitcheszTest.testBestPitches   s    S!5;;s#3U[[5EF!%((UQ']+Q/mA.<r   c                   t        j                  d      t        j                  d      t        j                  d      g}t        |      }t        j                  d      t        j                  d      t        j                  d      g}|j                  |      }| j	                  t        |      d       | j                  |t               y Nrf   rg   rh   ri   )r   r%   r!   r9   rj   rV   rk   int)r   rl   rm   posstestAltScores        r   testGetAlterationScorezTest.testGetAlterationScore   s    S!5;;s#3U[[5EF!%(C %++c"2EKK4DE,,T2UQ'lC0r   c                   t        j                  d      t        j                  d      t        j                  d      g}t        |      }t        j                  d      t        j                  d      t        j                  d      g}|j                  |      }| j	                  t        |      d       | j                  |t               y rq   )r   r%   r!   r:   rj   rV   rk   rr   )r   rl   rm   rs   testMixScores        r   testGetMixSharpFlatsScorezTest.testGetMixSharpFlatsScore   s    S!5;;s#3U[[5EF!%(C %++c"2EKK4DE//5UQ'lC0r   c                   t        j                  d      t        j                  d      t        j                  d      g}t        |      }t        j                  d      t        j                  d      t        j                  d      g}|j                  |      }| j	                  t        |      d       | j                  |t               y rq   )r   r%   r!   r8   rj   rV   rk   rr   )r   rl   rm   rs   testAugDimScores        r   testGetAugDimScorezTest.testGetAugDimScore   s    S!5;;s#3U[[5EF!%(C %++c"2EKK4DE++D1UQ'os3r   N)r   r   r   ro   ru   rx   r{   r   r   r   rd   rd      s    =114r   rd   __main__)
__future__r   r4   mathr   unittestmusic21r   r   r   EnvironmentenvironLocalr	   r   r!   TestCaserd   r   mainTestr   r   r   <module>r      s    #      &{&&'=>+ +' 4 '
k k\$48 $4P zGT r   