Fix this:

```
Traceback (most recent call last):
  File "C:\Users\hp\Downloads\jil.py", line 297, in <module>
    main()
  File "C:\Users\hp\Downloads\jil.py", line 294, in main
    midi_to_sheet_music(args.midi_file, args.output, note_detail=not args.no_details)
  File "C:\Users\hp\Downloads\jil.py", line 214, in midi_to_sheet_music
    convert_notes(left_hand_notes, left_part, hand='Left')
  File "C:\Users\hp\Downloads\jil.py", line 194, in convert_notes
    m21_note.pitch = m21pitch.Pitch(note_name)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\hp\AppData\Local\Programs\Python\Python312\Lib\site-packages\music21\pitch.py", line 1962, in __init__
    self.name = name  # set based on string
    ^^^^^^^^^
  File "C:\Users\hp\AppData\Local\Programs\Python\Python312\Lib\site-packages\music21\pitch.py", line 2820, in name
    self.accidental = Accidental(usrStr[1:])
                      ^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\hp\AppData\Local\Programs\Python\Python312\Lib\site-packages\music21\pitch.py", line 1019, in __init__
    self.set(specifier)
  File "C:\Users\hp\AppData\Local\Programs\Python\Python312\Lib\site-packages\music21\pitch.py", line 1283, in set
    raise AccidentalException(f'{name} is not a supported accidental type')
music21.pitch.AccidentalException: #/eb is not a supported accidental type
```

Script:

```
import pretty_midi
from music21 import stream, note, tempo, meter, key, environment, dynamics, articulations, converter, pitch as m21pitch
import argparse
import os
import sys
import tempfile
import logging

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')

# Piano keys dictionary for advanced mapping
piano_keys = {
    # Octave 0
    'C0': (16.35, 12), 'C#0/Db0': (17.32, 13), 'D0': (18.35, 14), 'D#0/Eb0': (19.45, 15),
    'E0': (20.60, 16), 'F0': (21.83, 17), 'F#0/Gb0': (23.12, 18), 'G0': (24.50, 19),
    'G#0/Ab0': (25.96, 20), 'A0': (27.50, 21), 'A#0/Bb0': (29.14, 22), 'B0': (30.87, 23),
    
    # Octave 1
    'C1': (32.70, 24), 'C#1/Db1': (34.65, 25), 'D1': (36.71, 26), 'D#1/Eb1': (38.89, 27),
    'E1': (41.20, 28), 'F1': (43.65, 29), 'F#1/Gb1': (46.25, 30), 'G1': (49.00, 31),
    'G#1/Ab1': (51.91, 32), 'A1': (55.00, 33), 'A#1/Bb1': (58.27, 34), 'B1': (61.74, 35),
    
    # Octave 2
    'C2': (65.41, 36), 'C#2/Db2': (69.30, 37), 'D2': (73.42, 38), 'D#2/Eb2': (77.78, 39),
    'E2': (82.41, 40), 'F2': (87.31, 41), 'F#2/Gb2': (92.50, 42), 'G2': (98.00, 43),
    'G#2/Ab2': (103.83, 44), 'A2': (110.00, 45), 'A#2/Bb2': (116.54, 46), 'B2': (123.47, 47),
    
    # Octave 3
    'C3': (130.81, 48), 'C#3/Db3': (138.59, 49), 'D3': (146.83, 50), 'D#3/Eb3': (155.56, 51),
    'E3': (164.81, 52), 'F3': (174.61, 53), 'F#3/Gb3': (185.00, 54), 'G3': (196.00, 55),
    'G#3/Ab3': (207.65, 56), 'A3': (220.00, 57), 'A#3/Bb3': (233.08, 58), 'B3': (246.94, 59),
    
    # Octave 4
    'C4': (261.63, 60), 'C#4/Db4': (277.18, 61), 'D4': (293.66, 62), 'D#4/Eb4': (311.13, 63),
    'E4': (329.63, 64), 'F4': (349.23, 65), 'F#4/Gb4': (369.99, 66), 'G4': (392.00, 67),
    'G#4/Ab4': (415.30, 68), 'A4': (440.00, 69), 'A#4/Bb4': (466.16, 70), 'B4': (493.88, 71),
    
    # Octave 5
    'C5': (523.25, 72), 'C#5/Db5': (554.37, 73), 'D5': (587.33, 74), 'D#5/Eb5': (622.25, 75),
    'E5': (659.26, 76), 'F5': (698.46, 77), 'F#5/Gb5': (739.99, 78), 'G5': (783.99, 79),
    'G#5/Ab5': (830.61, 80), 'A5': (880.00, 81), 'A#5/Bb5': (932.33, 82), 'B5': (987.77, 83),
    
    # Octave 6
    'C6': (1046.50, 84), 'C#6/Db6': (1108.73, 85), 'D6': (1174.66, 86), 'D#6/Eb6': (1244.51, 87),
    'E6': (1318.51, 88), 'F6': (1396.91, 89), 'F#6/Gb6': (1479.98, 90), 'G6': (1567.98, 91),
    'G#6/Ab6': (1661.22, 92), 'A6': (1760.00, 93), 'A#6/Bb6': (1864.66, 94), 'B6': (1975.53, 95),
    
    # Octave 7
    'C7': (2093.00, 96), 'C#7/Db7': (2217.46, 97), 'D7': (2349.32, 98), 'D#7/Eb7': (2489.02, 99),
    'E7': (2637.02, 100), 'F7': (2793.83, 101), 'F#7/Gb7': (2959.96, 102), 'G7': (3135.96, 103),
    'G#7/Ab7': (3322.44, 104), 'A7': (3520.00, 105), 'A#7/Bb7': (3729.31, 106), 'B7': (3951.07, 107),
    
    # Octave 8
    'C8': (4186.01, 108), 'C#8/Db8': (4434.92, 109), 'D8': (4698.63, 110), 'D#8/Eb8': (4978.03, 111),
    'E8': (5274.04, 112), 'F8': (5587.65, 113), 'F#8/Gb8': (5919.91, 114), 'G8': (6271.93, 115),
    'G#8/Ab8': (6644.88, 116), 'A8': (7040.00, 117), 'A#8/Bb8': (7458.62, 118), 'B8': (7902.13, 119)
}

# Reverse the piano_keys dictionary for MIDI number to note name mapping
midi_to_note = {v[1]: k for k in piano_keys for v in [piano_keys[k]]}

def get_note_name(midi_number):
    """Retrieve the note name from MIDI number using the piano_keys dictionary."""
    return midi_to_note.get(midi_number, None)

def get_dynamic(velocity):
    """Map MIDI velocity to dynamic markings with more granularity."""
    if velocity >= 115:
        return "fff"  # triple forte
    elif velocity >= 100:
        return "ff"  # forte
    elif velocity >= 85:
        return "f"
    elif velocity >= 70:
        return "mf"
    elif velocity >= 55:
        return "mp"
    elif velocity >= 40:
        return "p"
    elif velocity >= 25:
        return "pp"
    else:
        return "ppp"

def get_articulation(pm_note):
    """Determine articulation based on note properties."""
    velocity = pm_note.velocity
    if velocity >= 100:
        return articulations.Staccato()
    elif velocity <= 30:
        return articulations.Legato()
    else:
        return None

def estimate_key_signature(midi_data):
    """
    Estimate the key signature of the MIDI file using music21's key analysis.
    """
    try:
        # Convert MIDI to music21 stream for key analysis
        s = converter.parse(midi_data)
        key_signature = s.analyze('key')
        return key_signature
    except Exception as e:
        logging.warning(f"Key signature estimation failed: {e}")
        return key.KeySignature(0)  # Default to C major

def midi_to_sheet_music(midi_path, output_pdf_path, note_detail=True):
    """
    Converts a MIDI file with piano tracks into a sheet music PDF.

    Parameters:
    - midi_path: Path to the input MIDI file.
    - output_pdf_path: Path to save the output PDF sheet.
    - note_detail: Whether to include detailed note information (dynamics, articulations).
    """
    try:
        # Load MIDI file
        midi_data = pretty_midi.PrettyMIDI(midi_path)
        logging.info(f"Successfully loaded MIDI file: {midi_path}")
    except Exception as e:
        logging.error(f"Error loading MIDI file: {e}")
        return

    # Initialize music21 stream as a Score
    piano_score = stream.Score()

    # Estimate key signature using music21's analysis
    key_signature = estimate_key_signature(midi_path)
    piano_score.append(key_signature)
    logging.info(f"Estimated Key Signature: {key_signature}")

    # Set tempo
    tempos, tempo_times = midi_data.get_tempo_changes()
    if len(tempos) > 0:
        bpm = tempos[0]
        piano_score.append(tempo.MetronomeMark(number=bpm))
        logging.info(f"Set Tempo: {bpm} BPM")
    else:
        piano_score.append(tempo.MetronomeMark(number=120))  # Default BPM
        logging.info("Default Tempo: 120 BPM")

    # Set time signature
    try:
        ts = midi_data.time_signature_changes[0]
        time_signature = meter.TimeSignature(f"{ts.numerator}/{ts.denominator}")
        piano_score.append(time_signature)
        logging.info(f"Set Time Signature: {time_signature}")
    except IndexError:
        time_signature = meter.TimeSignature("4/4")  # Default time signature
        piano_score.append(time_signature)
        logging.info("Default Time Signature: 4/4")

    # Extract piano instruments (General MIDI program numbers 0-7 for piano)
    piano_instruments = [inst for inst in midi_data.instruments if not inst.is_drum and 0 <= inst.program <= 7]

    if not piano_instruments:
        logging.error("No piano tracks found in the MIDI file.")
        return

    logging.info(f"Found {len(piano_instruments)} piano instrument(s) in the MIDI file.")

    # Separate into left and right hands based on pitch ranges
    left_hand_notes = []
    right_hand_notes = []

    for inst in piano_instruments:
        for pm_note in inst.notes:
            if pm_note.pitch < 60:  # Middle C is 60 in MIDI
                left_hand_notes.append(pm_note)
            else:
                right_hand_notes.append(pm_note)

    # Sort notes by start time
    left_hand_notes.sort(key=lambda x: x.start)
    right_hand_notes.sort(key=lambda x: x.start)

    logging.info(f"Left Hand: {len(left_hand_notes)} notes, Right Hand: {len(right_hand_notes)} notes.")

    # Create separate streams for left and right hands
    left_part = stream.Part(id='Left Hand')
    right_part = stream.Part(id='Right Hand')

    # Function to convert PrettyMIDI notes to music21 notes with details
    def convert_notes(pm_notes, part_stream, hand='Right'):
        for pm_note in pm_notes:
            note_name = get_note_name(pm_note.pitch)
            if not note_name:
                logging.warning(f"Unrecognized MIDI note number: {pm_note.pitch}")
                continue

            m21_note = note.Note()
            m21_note.pitch = m21pitch.Pitch(note_name)
            m21_note.duration.quarterLength = pm_note.end - pm_note.start

            # Set duration based on start time
            m21_note.offset = pm_note.start

            if note_detail:
                # Dynamics
                dyn = get_dynamic(pm_note.velocity)
                dyn_obj = dynamics.Dynamic(dyn)
                m21_note.expressions.append(dyn_obj)

                # Articulations
                articulation = get_articulation(pm_note)
                if articulation:
                    m21_note.articulations.append(articulation)

            part_stream.append(m21_note)

    # Convert notes for both hands
    convert_notes(left_hand_notes, left_part, hand='Left')
    convert_notes(right_hand_notes, right_part, hand='Right')

    # Add parts to the main score
    piano_score.insert(0, left_part)
    piano_score.insert(0, right_part)

    # Arrange parts into measures
    piano_score.makeMeasures()

    # Optional: Show the stream in the console for debugging
    # print(piano_score.show('text'))

    # Save the stream to a temporary MusicXML file
    with tempfile.TemporaryDirectory() as temp_dir:
        musicxml_path = os.path.join(temp_dir, "output.xml")
        try:
            piano_score.write('musicxml', fp=musicxml_path)
            logging.info(f"MusicXML file generated at {musicxml_path}")
        except Exception as e:
            logging.error(f"Error writing MusicXML file: {e}")
            return

        # Convert MusicXML to PDF using music21's converter with MuseScore
        try:
            # Set up music21 environment to use MuseScore
            us = environment.UserSettings()
            # Attempt to auto-detect MuseScore path; user may need to set manually
            if sys.platform == "win32":
                musescore_paths = [
                    'MuseScore3.exe', 'MuseScore4.exe',  # Common executable names
                    'C:\\Program Files\\MuseScore 3\\bin\\MuseScore3.exe',
                    'C:\\Program Files\\MuseScore 4\\bin\\MuseScore4.exe'
                ]
            elif sys.platform == "darwin":
                musescore_paths = [
                    '/Applications/MuseScore 4.app/Contents/MacOS/mscore',
                    '/Applications/MuseScore 3.app/Contents/MacOS/mscore'
                ]
            else:
                musescore_paths = ['musescore', 'MuseScore3', 'MuseScore4']

            # Find the MuseScore executable
            musescore_executable = None
            for path in musescore_paths:
                if shutil.which(path):
                    musescore_executable = shutil.which(path)
                    break

            if not musescore_executable:
                logging.error("MuseScore executable not found. Please install MuseScore and add it to your PATH.")
                return

            us['musescorePath'] = musescore_executable
            logging.info(f"Using MuseScore executable at: {musescore_executable}")

            # Load the MusicXML file
            score = converter.parse(musicxml_path)

            # Write to PDF
            score.write('pdf', fp=output_pdf_path)
            logging.info(f"Sheet music PDF saved to {output_pdf_path}")

        except Exception as e:
            logging.error(f"Error converting MusicXML to PDF: {e}")
            logging.error("Ensure that MuseScore is installed and its path is correctly set.")
            return

def main():
    parser = argparse.ArgumentParser(description="Convert MIDI files with piano tracks into sheet music PDF.")
    parser.add_argument('midi_file', type=str, help='Path to the input MIDI file.')
    parser.add_argument('-o', '--output', type=str, default='enhanced_piano_sheet.pdf', help='Output PDF file for the sheet music.')
    parser.add_argument('--no-details', action='store_true', help='Exclude note details like dynamics and articulations.')

    args = parser.parse_args()

    if not os.path.isfile(args.midi_file):
        logging.error(f"The file {args.midi_file} does not exist.")
        sys.exit(1)

    midi_to_sheet_music(args.midi_file, args.output, note_detail=not args.no_details)

if __name__ == "__main__":
    main()