from collections.abc import Callable


class 	lowerCamelCase_     :






    '''simple docstring'''






    def __init__(	self , __lowercase = None)       ->	None:
        # Stores actual heap items.
        __UpperCamelCase     :list			  =		[]
        # Stores indexes of each item for supporting updates and deletion.
        __UpperCamelCase     :dict			  =		{}
        # Stores current size of heap.
        __UpperCamelCase     :str			  =		0
        # Stores function used to evaluate the score of an item on which basis ordering
        # will be done.
        __UpperCamelCase     :int			  =		key or (lambda __lowercase: x)







    def 			UpperCamelCase__   (	self , __lowercase)       ->	int | None:
        return int((i - 1) / 2) if i > 0 else None







    def 			UpperCamelCase__   (	self , __lowercase)       ->	int | None:
        __UpperCamelCase     :Union[str, Any]			  =		int(2 * i + 1)
        return left if 0 < left < self.size else None







    def 			UpperCamelCase__   (	self , __lowercase)       ->	int | None:
        __UpperCamelCase     :Optional[int]			  =		int(2 * i + 2)
        return right if 0 < right < self.size else None







    def 			UpperCamelCase__   (	self , __lowercase , __lowercase)       ->	None:
        __UpperCamelCase  ,       __UpperCamelCase     :Optional[int]			  =		(
            self.pos_map[self.arr[j][0]],
            self.pos_map[self.arr[i][0]],
        )
        # Then swap the items in the list.
        __UpperCamelCase  ,       __UpperCamelCase     :List[Any]			  =		self.arr[j], self.arr[i]







    def 			UpperCamelCase__   (	self , __lowercase , __lowercase)       ->	bool:
        return self.arr[i][1] < self.arr[j][1]







    def 			UpperCamelCase__   (	self , __lowercase)       ->	int:
        __UpperCamelCase     :List[str]			  =		self._left(__lowercase)
        __UpperCamelCase     :Tuple			  =		self._right(__lowercase)
        __UpperCamelCase     :List[str]			  =		i

        if left is not None and not self._cmp(__lowercase , __lowercase):
            __UpperCamelCase     :Optional[Any]			  =		left
        if right is not None and not self._cmp(__lowercase , __lowercase):
            __UpperCamelCase     :Optional[Any]			  =		right

        return valid_parent







    def 			UpperCamelCase__   (	self , __lowercase)       ->	None:
        __UpperCamelCase     :Optional[int]			  =		self._parent(__lowercase)
        while parent is not None and not self._cmp(__lowercase , __lowercase):
            self._swap(__lowercase , __lowercase)
            __UpperCamelCase  ,       __UpperCamelCase     :Union[str, Any]			  =		parent, self._parent(__lowercase)







    def 			UpperCamelCase__   (	self , __lowercase)       ->	None:
        __UpperCamelCase     :List[str]			  =		self._get_valid_parent(__lowercase)
        while valid_parent != index:
            self._swap(__lowercase , __lowercase)
            __UpperCamelCase  ,       __UpperCamelCase     :Dict			  =		valid_parent, self._get_valid_parent(__lowercase)







    def 			UpperCamelCase__   (	self , __lowercase , __lowercase)       ->	None:
        if item not in self.pos_map:
            return
        __UpperCamelCase     :Any			  =		self.pos_map[item]
        __UpperCamelCase     :Union[str, Any]			  =		[item, self.key(__lowercase)]
        # Make sure heap is right in both up and down direction.
        # Ideally only one of them will make any change.
        self._heapify_up(__lowercase)
        self._heapify_down(__lowercase)







    def 			UpperCamelCase__   (	self , __lowercase)       ->	None:
        if item not in self.pos_map:
            return
        __UpperCamelCase     :Any			  =		self.pos_map[item]
        del self.pos_map[item]
        __UpperCamelCase     :Any			  =		self.arr[self.size - 1]
        __UpperCamelCase     :Optional[int]			  =		index
        self.size -= 1
        # Make sure heap is right in both up and down direction. Ideally only one
        # of them will make any change- so no performance loss in calling both.
        if self.size > index:
            self._heapify_up(__lowercase)
            self._heapify_down(__lowercase)







    def 			UpperCamelCase__   (	self , __lowercase , __lowercase)       ->	None:
        __UpperCamelCase     :Optional[Any]			  =		len(self.arr)
        if arr_len == self.size:
            self.arr.append([item, self.key(__lowercase)])
        else:
            __UpperCamelCase     :Optional[Any]			  =		[item, self.key(__lowercase)]
        __UpperCamelCase     :List[Any]			  =		self.size
        self.size += 1
        self._heapify_up(self.size - 1)







    def 			UpperCamelCase__   (	self)       ->	tuple | None:
        return self.arr[0] if self.size else None







    def 			UpperCamelCase__   (	self)       ->	tuple | None:
        __UpperCamelCase     :Any			  =		self.get_top()
        if top_item_tuple:
            self.delete_item(top_item_tuple[0])
        return top_item_tuple



def lowerCamelCase  (   ):
    '''simple docstring'''









if __name__ == "__main__":
    import doctest

    doctest.testmod()










'''simple docstring'''





from collections import UserDict
from typing import List, Union

from ..utils import (
    add_end_docstrings,
    is_tf_available,
    is_torch_available,
    is_vision_available,
    logging,
    requires_backends,
)
from .base import PIPELINE_INIT_ARGS, Pipeline


if is_vision_available():
 from PIL import Image

 from ..image_utils import load_image

if is_torch_available():
 from ..models.auto.modeling_auto import MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING

if is_tf_available():
 from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING
 from ..tf_utils import stable_softmax

_lowerCAmelCase      						=	logging.get_logger(__name__)






@add_end_docstrings(SCREAMING_SNAKE_CASE_     )
class        lowerCAmelCase_(				SCREAMING_SNAKE_CASE_     ):
  '''simple docstring'''




  def __init__(    self  ,**__UpperCAmelCase      )    ->		Tuple:
      super().__init__(**__UpperCAmelCase      )

      requires_backends(self  ,"""vision"""      )
      self.check_model_type(
          TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING
          if self.framework == """tf"""
          else MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING      )




  def __call__(    self  ,__UpperCAmelCase  ,**__UpperCAmelCase      )    ->		str:
      return super().__call__(__UpperCAmelCase  ,**__UpperCAmelCase      )




  def 							UpperCAmelCase_	(    self  ,**__UpperCAmelCase      )    ->		str:
      lowerCAmelCase__ :  List[Any]							      =					{}
      if "candidate_labels" in kwargs:
          lowerCAmelCase__ :  int							      =					kwargs["""candidate_labels"""]
      if "hypothesis_template" in kwargs:
          lowerCAmelCase__ :  Optional[int]							      =					kwargs["""hypothesis_template"""]

      return preprocess_params, {}, {}




  def 							UpperCAmelCase_	(    self  ,__UpperCAmelCase  ,__UpperCAmelCase=None  ,__UpperCAmelCase="This is a photo of {}."      )    ->		int:
      lowerCAmelCase__ :  str							      =					load_image(__UpperCAmelCase      )
      lowerCAmelCase__ :  Dict							      =					self.image_processor(images=[image]  ,return_tensors=self.framework      )
      lowerCAmelCase__ :  List[Any]							      =					candidate_labels
      lowerCAmelCase__ :  List[str]							      =					[hypothesis_template.format(__UpperCAmelCase      ) for x in candidate_labels]
      lowerCAmelCase__ :  Optional[Any]							      =					self.tokenizer(__UpperCAmelCase  ,return_tensors=self.framework  ,padding=__UpperCAmelCase      )
      lowerCAmelCase__ :  Tuple							      =					[text_inputs]
      return inputs




  def 							UpperCAmelCase_	(    self  ,__UpperCAmelCase      )    ->		Union[str, Any]:
      lowerCAmelCase__ :  Tuple							      =					model_inputs.pop("""candidate_labels"""      )
      lowerCAmelCase__ :  Union[str, Any]							      =					model_inputs.pop("""text_inputs"""      )
      if isinstance(text_inputs[0]  ,__UpperCAmelCase      ):
          lowerCAmelCase__ :  int							      =					text_inputs[0]
      else:
          # Batching case.
          lowerCAmelCase__ :  Dict							      =					text_inputs[0][0]

      lowerCAmelCase__ :  Any							      =					self.model(**__UpperCAmelCase  ,**__UpperCAmelCase      )

      lowerCAmelCase__ :  Union[str, Any]							      =					{
          """candidate_labels""": candidate_labels,
          """logits""": outputs.logits_per_image,
      }
      return model_outputs






  def 							UpperCAmelCase_	(    self  ,__UpperCAmelCase      )    ->		Any:
      lowerCAmelCase__ :  Union[str, Any]							      =					model_outputs.pop("""candidate_labels"""      )
      lowerCAmelCase__ :  List[str]							      =					model_outputs["""logits"""][0]
      if self.framework == "pt":
          lowerCAmelCase__ :  List[str]							      =					logits.softmax(dim=-1      ).squeeze(-1      )
          lowerCAmelCase__ :  Optional[Any]							      =					probs.tolist()
          if not isinstance(__UpperCAmelCase  ,__UpperCAmelCase      ):
              lowerCAmelCase__ :  Dict							      =					[scores]
      elif self.framework == "tf":
          lowerCAmelCase__ :  Any							      =					stable_softmax(__UpperCAmelCase  ,axis=-1      )
          lowerCAmelCase__ :  List[Any]							      =					probs.numpy().tolist()
      else:
          raise ValueError(F"""Unsupported framework: {self.framework}"""      )

      lowerCAmelCase__ :  Tuple							      =					[
          {"""score""": score, """label""": candidate_label}
          for score, candidate_label in sorted(zip(__UpperCAmelCase  ,__UpperCAmelCase      )  ,key=lambda __UpperCAmelCase      : -x[0]      )
      ]
      return result


