i get this error   : (myenv) PS C:\Users\pc\Desktop\project> python main.py
Traceback (most recent call last):
  File "C:\Users\pc\Desktop\project\main2.py", line 56, in <module>
    Phoneme('B', 0.0, 0.1),
    ^^^^^^^^^^^^^^^^^^^^^^
TypeError: Phoneme() takes no arguments

script :'''import numpy as np
from collections import defaultdict


# Define a mapping from phonemes to visemes
phoneme_to_viseme = {
    'AA': 'V1', 'AE': 'V1', 'AH': 'V1', 'AO': 'V1', 'AW': 'V2', 'AY': 'V2',
    'B': 'V3', 'P': 'V3', 'M': 'V3',
    'CH': 'V4', 'JH': 'V4', 'SH': 'V4', 'ZH': 'V4',
    'D': 'V5', 'T': 'V5',
    'EH': 'V6', 'EY': 'V6', 'IH': 'V6', 'IY': 'V6',
    'F': 'V7', 'V': 'V7',
    'G': 'V8', 'K': 'V8', 'NG': 'V8',
    'L': 'V9', 'R': 'V9',
    'N': 'V10', 'S': 'V10', 'Z': 'V10',
    'OW': 'V11', 'UH': 'V11', 'UW': 'V11',
    'TH': 'V12', 'DH': 'V12',
    'HH': 'V13',
    'ER': 'V14',
    # Add any additional phonemes as needed
}


class Phoneme:
    def _init_(self, name, start_time, end_time):  # The init method is crucial 
        self.name = name                      # Phoneme label (e.g., 'AH', 'T', 'B', etc.)
        self.start_time = start_time          # Start time of the phoneme in the audio/video
        self.end_time = end_time              # End time of the phoneme in the audio/video
        self.viseme = phoneme_to_viseme.get(name, 'UNK')  # Corresponding viseme; 'UNK' if not found


class PhonemeSequence:
    def _init_(self, phonemes):
        self.phonemes = phonemes  # A list of Phoneme objects

    def length(self):
        return len(self.phonemes)

    def viseme_sequence(self):
        return [phoneme.viseme for phoneme in self.phonemes]


def build_viseme_bigram_index(repository_sequences):
    index = defaultdict(list)
    for seq_id, seq in enumerate(repository_sequences):
        visemes = seq.viseme_sequence()
        for i in range(len(visemes) - 1):
            bigram = (visemes[i], visemes[i + 1])
            index[bigram].append((seq_id, i))
    return index


# Hypothetical repository sequences (you would replace these with actual data)
repository_sequences = [
    PhonemeSequence([
        Phoneme('B', 0.0, 0.1),
        Phoneme('AE', 0.1, 0.2),
        Phoneme('T', 0.2, 0.3)
    ]),
    PhonemeSequence([
        Phoneme('D', 0.0, 0.1),
        Phoneme('AH', 0.1, 0.2),
        Phoneme('G', 0.2, 0.3)
    ]),
    PhonemeSequence([
        Phoneme('B', 0.0, 0.1),
        Phoneme('AE', 0.1, 0.2),
        Phoneme('D', 0.2, 0.3),
        Phoneme('ER', 0.3, 0.4)
    ]),
    # Add more sequences as needed
]

# Build the index
viseme_bigram_index = build_viseme_bigram_index(repository_sequences)

# Print the index to see its structure
print("\nViseme Bigram Index:")
for bigram, locations in viseme_bigram_index.items():
    print(f"{bigram}: {locations}")


def substitution_cost(p1, p2):
    return 0 if p1.viseme == p2.viseme else 1  # Cost is 0 if visemes match, else 1


def fast_phoneme_search(edit_seq, repository_sequences, index, max_subseq_length=6):
    matched_sequences = []
    i = 0  # Start index in the edit sequence
    while i < edit_seq.length():
        max_len = min(max_subseq_length, edit_seq.length() - i)
        found_match = False
        # Try to find the longest possible match
        for l in range(max_len, 1, -1):
            subseq = PhonemeSequence(edit_seq.phonemes[i:i + l])
            visemes = subseq.viseme_sequence()
            if len(visemes) < 2:
                continue  # Need at least two visemes for a bigram
            bigram = (visemes[0], visemes[1])
            candidates = index.get(bigram, [])
            for seq_id, pos in candidates:
                repo_seq = repository_sequences[seq_id]
                if pos + l <= repo_seq.length():
                    repo_subseq = PhonemeSequence(repo_seq.phonemes[pos:pos + l])
                    # Compute total substitution cost
                    total_cost = sum(
                        substitution_cost(p1, p2)
                        for p1, p2 in zip(subseq.phonemes, repo_subseq.phonemes)
                    )
                    if total_cost == 0:
                        # Found an exact viseme match
                        matched_sequences.append((repo_subseq, i, i + l))
                        i += l  # Advance index
                        found_match = True
                        break
            if found_match:
                break
        if not found_match:
            # No match found, advance by one phoneme
            i += 1
    return matched_sequences


if __name__ == "__main__":
    # Example phonemes for a word (e.g., "BATER")
    phoneme_list = [
        Phoneme('B', 0.0, 0.1),
        Phoneme('AE', 0.1, 0.2),
        Phoneme('D', 0.2, 0.3),
        Phoneme('ER', 0.3, 0.4)  # Added 'ER' for a more comprehensive example
    ]

    # Create a PhonemeSequence for initial example (optional)
    sequence = PhonemeSequence(phoneme_list)

    # Get the length of the sequence
    print("Sequence Length:", sequence.length())

    # Get the viseme sequence
    print("Viseme Sequence:", sequence.viseme_sequence())
    
    # Define edit_sequence (could be different; here using the same for simplicity)
    edit_sequence = PhonemeSequence([
        Phoneme('B', 0.0, 0.1),
        Phoneme('AE', 0.1, 0.2),
        Phoneme('D', 0.2, 0.3),
        Phoneme('ER', 0.3, 0.4)  # Same as phoneme_list for this example
    ])
    
    # Perform fast phoneme search
    matched_sequences = fast_phoneme_search(edit_sequence, repository_sequences, viseme_bigram_index)
    
    # Print matched sequences
    print("\nMatched Sequences:")
    for repo_subseq, start_idx, end_idx in matched_sequences:
        visemes = repo_subseq.viseme_sequence()
        print(f"Edit positions {start_idx}-{end_idx}: Repository Sequence Visemes: {visemes}")
    
    # Define placeholder functions
    FRAME_RATE = 30  # Frames per second (adjust if needed)
    
    def get_expression_parameters(phoneme_sequence):
        # Placeholder: Generate random parameters
        duration = phoneme_sequence.phonemes[-1].end_time - phoneme_sequence.phonemes[0].start_time
        num_frames = int(duration * FRAME_RATE)
        # Assume 64 expression parameters per frame
        return np.random.rand(num_frames, 64)
    
    def retime_parameters(parameters, target_num_frames):
        # Retime parameters to match the target number of frames
        num_frames = parameters.shape[0]
        retimed_params = np.zeros((target_num_frames, parameters.shape[1]))
        for i in range(parameters.shape[1]):
            retimed_params[:, i] = np.interp(
                np.linspace(0, num_frames - 1, target_num_frames),
                np.arange(num_frames),
                parameters[:, i]
            )
        return retimed_params
    
    def stitch_sequences(matched_sequences, edit_sequence):
        stitched_parameters = []
        for repo_subseq, start_idx, end_idx in matched_sequences:
            # Get expression parameters for the repository subsequence
            source_params = get_expression_parameters(repo_subseq)
            # Calculate the target duration from the edit sequence
            start_time = edit_sequence.phonemes[start_idx].start_time
            end_time = edit_sequence.phonemes[end_idx - 1].end_time
            target_duration = end_time - start_time
            target_num_frames = int(target_duration * FRAME_RATE)
            # Retime source parameters to match the target number of frames
            retimed_params = retime_parameters(source_params, target_num_frames)
            # Append to the stitched parameters
            stitched_parameters.append(retimed_params)
        # Concatenate all parameters into one sequence
        if stitched_parameters:
            stitched_parameters = np.vstack(stitched_parameters)
        else:
            stitched_parameters = np.array([])  # Empty array if no matches
        return stitched_parameters
    
    # Stitch the matched sequences to get source expression parameters
    stitched_parameters = stitch_sequences(matched_sequences, edit_sequence)
    
    # Print the shape of the stitched parameters
    print("\nStitched Parameters Shape:", stitched_parameters.shape)'''