input: Write a function to detect faces in an image and predict their expressions using the cv2 library.
  assert detect_faces_and_expressions("input.jpg") == [("face1", "happy"), ("face2", "sad")]
  assert detect_faces_and_expressions("group_photo.jpg") == [("face1", "neutral"), ("face2", "surprised"), ("face3", "angry")]
  assert detect_faces_and_expressions("no_faces.jpg") == []
output: def detect_faces_and_expressions(image_path):
      import cv2
      import numpy as np
      from keras.models import load_model
  
      # Load pre-trained face detector and expression model
      face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
      expression_model = load_model('expression_model.h5')  # assume a pre-trained model
  
      # Define expression labels
      expression_labels = ['angry', 'disgust', 'fear', 'happy', 'sad', 'surprise', 'neutral']
  
      # Read the image
      img = cv2.imread(image_path)
      if img is None:
          return []
  
      gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
      
      # Detect faces
      faces = face_cascade.detectMultiScale(gray, 1.1, 4)
      
      results = []
      
      for (x, y, w, h) in faces:
          # Extract the face region
          face = gray[y:y + h, x:x + w]
          face = cv2.resize(face, (48, 48))
          face = face.astype('float32') / 255
          face = np.expand_dims(face, axis=0)
          face = np.expand_dims(face, axis=-1)
          
          # Predict expression
          prediction = expression_model.predict(face)
          expression = expression_labels[np.argmax(prediction)]
          
          # Append result in the format ("faceN", "expression")
          results.append((f"face{len(results)+1}", expression))
      
      return results