






from typing import List, Union

import numpy as np

from ..tokenization_utils import TruncationStrategy
from ..utils import add_end_docstrings, logging
from .base import PIPELINE_INIT_ARGS, ArgumentHandler, ChunkPipeline


a_							=    logging.get_logger(__name__)


class      lowercase__     (			_UpperCAmelCase	):

	def 		UpperCAmelCase  (							self		,    __UpperCAmelCase       )->					Dict:







							'''simple docstring'''





							if isinstance(__UpperCAmelCase		,    __UpperCAmelCase       ):
													lowerCAmelCase__       =						[label.strip() for label in labels.split(","       ) if label.strip()]
							return labels


	def __call__(							self		,    __UpperCAmelCase		,    __UpperCAmelCase		,    __UpperCAmelCase       )->					Dict:







							'''simple docstring'''





							if len(__UpperCAmelCase       ) == 0 or len(__UpperCAmelCase       ) == 0:
													raise ValueError("You must include at least one label and at least one sequence."       )
							if hypothesis_template.format(labels[0]       ) == hypothesis_template:
													raise ValueError(
													    (
													        "The provided hypothesis_template \"{}\" was not able to be formatted with the target labels. "
													        "Make sure the passed template includes formatting syntax such as {{}} where the label should go."
													    ).format(__UpperCAmelCase       )       )

							if isinstance(__UpperCAmelCase		,    __UpperCAmelCase       ):
													lowerCAmelCase__       =						[sequences]

							lowerCAmelCase__       =						[]
							for sequence in sequences:
													sequence_pairs.extend([[sequence, hypothesis_template.format(__UpperCAmelCase       )] for label in labels]       )

							return sequence_pairs, sequences





@add_end_docstrings(_UpperCAmelCase	)
class      lowercase__     (			_UpperCAmelCase	):

	def __init__(							self		,    __UpperCAmelCase=ZeroShotClassificationArgumentHandler()		,    *__UpperCAmelCase		,    **__UpperCAmelCase       )->					List[Any]:







							'''simple docstring'''





							lowerCAmelCase__       =						args_parser
							super().__init__(*__UpperCAmelCase		,    **__UpperCAmelCase       )
							if self.entailment_id == -1:
													logger.warning(
													    "Failed to determine 'entailment' label id from the label2id mapping in the model config. Setting to "
													    "-1. Define a descriptive label2id mapping in the model config to ensure correct outputs."       )

	@property
	def 		UpperCAmelCase  (							self       )->					List[str]:







							'''simple docstring'''





							for label, ind in self.model.config.labelaid.items():
													if label.lower().startswith("entail"       ):
																			return ind
							return -1

	def 		UpperCAmelCase  (							self		,    __UpperCAmelCase		,    __UpperCAmelCase=True		,    __UpperCAmelCase=True		,    __UpperCAmelCase=TruncationStrategy.ONLY_FIRST		,    **__UpperCAmelCase       )->					Any:







							'''simple docstring'''





							lowerCAmelCase__       =						self.framework
							if self.tokenizer.pad_token is None:
													# Override for tokenizers not supporting padding
													logger.error(
													    "Tokenizer was not supporting padding necessary for zero-shot, attempting to use "
													    " `pad_token=eos_token`"       )
													lowerCAmelCase__       =						self.tokenizer.eos_token
							try:
													lowerCAmelCase__       =						self.tokenizer(
													    __UpperCAmelCase		,    add_special_tokens=__UpperCAmelCase		,    return_tensors=__UpperCAmelCase		,    padding=__UpperCAmelCase		,    truncation=__UpperCAmelCase		,    )
							except Exception as e:
													if "too short" in str(__UpperCAmelCase       ):
																			# tokenizers might yell that we want to truncate
																			# to a value that is not even reached by the input.
																			# In that case we don't want to truncate.
																			# It seems there's not a really better way to catch that
																			# exception.

																			lowerCAmelCase__       =						self.tokenizer(
																			    __UpperCAmelCase		,    add_special_tokens=__UpperCAmelCase		,    return_tensors=__UpperCAmelCase		,    padding=__UpperCAmelCase		,    truncation=TruncationStrategy.DO_NOT_TRUNCATE		,    )
													else:
																			raise e

							return inputs

	def 		UpperCAmelCase  (							self		,    **__UpperCAmelCase       )->					Optional[Any]:







							'''simple docstring'''





							if kwargs.get("multi_class"		,    __UpperCAmelCase       ) is not None:
													lowerCAmelCase__       =						kwargs["multi_class"]
													logger.warning(
													    "The `multi_class` argument has been deprecated and renamed to `multi_label`. "
													    "`multi_class` will be removed in a future version of Transformers."       )
							lowerCAmelCase__       =						{}
							if "candidate_labels" in kwargs:
													lowerCAmelCase__       =						self._args_parser._parse_labels(kwargs["candidate_labels"]       )
							if "hypothesis_template" in kwargs:
													lowerCAmelCase__       =						kwargs["hypothesis_template"]

							lowerCAmelCase__       =						{}
							if "multi_label" in kwargs:
													lowerCAmelCase__       =						kwargs["multi_label"]
							return preprocess_params, {}, postprocess_params

	def __call__(							self		,    __UpperCAmelCase		,    *__UpperCAmelCase		,    **__UpperCAmelCase		,    )->					List[str]:







							'''simple docstring'''





							if len(__UpperCAmelCase       ) == 0:
													pass
							elif len(__UpperCAmelCase       ) == 1 and "candidate_labels" not in kwargs:
													lowerCAmelCase__       =						args[0]
							else:
													raise ValueError(F"Unable to understand extra arguments {args}"       )

							return super().__call__(__UpperCAmelCase		,    **__UpperCAmelCase       )

	def 		UpperCAmelCase  (							self		,    __UpperCAmelCase		,    __UpperCAmelCase=None		,    __UpperCAmelCase="This example is {}."       )->					List[Any]:







							'''simple docstring'''





							lowerCAmelCase__      ,							lowerCAmelCase__       =						self._args_parser(__UpperCAmelCase		,    __UpperCAmelCase		,    __UpperCAmelCase       )

							for i, (candidate_label, sequence_pair) in enumerate(zip(__UpperCAmelCase		,    __UpperCAmelCase       )       ):
													lowerCAmelCase__       =						self._parse_and_tokenize([sequence_pair]       )

													yield {
													    "candidate_label": candidate_label,
													    "sequence": sequences[0],
													    "is_last": i == len(__UpperCAmelCase       ) - 1,
													    **model_input,
													}

	def 		UpperCAmelCase  (							self		,    __UpperCAmelCase       )->					Optional[Any]:







							'''simple docstring'''





							lowerCAmelCase__       =						inputs["candidate_label"]
							lowerCAmelCase__       =						inputs["sequence"]
							lowerCAmelCase__       =						{k: inputs[k] for k in self.tokenizer.model_input_names}
							lowerCAmelCase__       =						self.model(**__UpperCAmelCase       )

							lowerCAmelCase__       =						{
							    "candidate_label": candidate_label,
							    "sequence": sequence,
							    "is_last": inputs["is_last"],
							    **outputs,
							}
							return model_outputs


	def 		UpperCAmelCase  (							self		,    __UpperCAmelCase		,    __UpperCAmelCase=False       )->					List[str]:







							'''simple docstring'''





							lowerCAmelCase__       =						[outputs["candidate_label"] for outputs in model_outputs]
							lowerCAmelCase__       =						[outputs["sequence"] for outputs in model_outputs]
							lowerCAmelCase__       =						np.concatenate([output["logits"].numpy() for output in model_outputs]       )
							lowerCAmelCase__       =						logits.shape[0]
							lowerCAmelCase__       =						len(__UpperCAmelCase       )
							lowerCAmelCase__       =						N // n
							lowerCAmelCase__       =						logits.reshape((num_sequences, n, -1)       )

							if multi_label or len(__UpperCAmelCase       ) == 1:
													# softmax over the entailment vs. contradiction dim for each label independently
													lowerCAmelCase__       =						self.entailment_id
													lowerCAmelCase__       =						-1 if entailment_id == 0 else 0
													lowerCAmelCase__       =						reshaped_outputs[..., [contradiction_id, entailment_id]]
													lowerCAmelCase__       =						np.exp(__UpperCAmelCase       ) / np.exp(__UpperCAmelCase       ).sum(-1		,    keepdims=__UpperCAmelCase       )
													lowerCAmelCase__       =						scores[..., 1]
							else:
													# softmax the "entailment" logits over all candidate labels
													lowerCAmelCase__       =						reshaped_outputs[..., self.entailment_id]
													lowerCAmelCase__       =						np.exp(__UpperCAmelCase       ) / np.exp(__UpperCAmelCase       ).sum(-1		,    keepdims=__UpperCAmelCase       )

							lowerCAmelCase__       =						list(reversed(scores[0].argsort()       )       )
							return {
							    "sequence": sequences[0],
							    "labels": [candidate_labels[i] for i in top_inds],
							    "scores": scores[0, top_inds].tolist(),
							}














def        _a  (     UpperCamelCase_					:				list    ,   UpperCamelCase_					:				list   ) ->   float:
						"""simple docstring"""







						_validate_point(UpperCamelCase_   )
						_validate_point(UpperCamelCase_   )
						if len(UpperCamelCase_   ) != len(UpperCamelCase_   ):
												raise ValueError("Both points must be in the same n-dimensional space"   )

						return float(sum(abs(a - b   ) for a, b in zip(UpperCamelCase_    ,   UpperCamelCase_   )   )   )


def        _a  (     UpperCamelCase_					:				list[float]   ) ->   None:
						"""simple docstring"""







						if point:
												if isinstance(UpperCamelCase_    ,   UpperCamelCase_   ):
																		for item in point:
																								if not isinstance(UpperCamelCase_    ,   (int, float)   ):
																														lowerCAmelCase__       =						(
																														    "Expected a list of numbers as input, found "
																														    F"{type(UpperCamelCase_   ).__name__}"
																														)
																														raise TypeError(UpperCamelCase_   )
												else:
																		lowerCAmelCase__       =						F"Expected a list of numbers as input, found {type(UpperCamelCase_   ).__name__}"
																		raise TypeError(UpperCamelCase_   )
						else:
												raise ValueError("Missing an input"   )


def        _a  (     UpperCamelCase_					:				list    ,   UpperCamelCase_					:				list   ) ->   float:
						"""simple docstring"""







						_validate_point(UpperCamelCase_   )
						_validate_point(UpperCamelCase_   )
						if len(UpperCamelCase_   ) != len(UpperCamelCase_   ):
												raise ValueError("Both points must be in the same n-dimensional space"   )

						return float(sum(abs(x - y   ) for x, y in zip(UpperCamelCase_    ,   UpperCamelCase_   )   )   )


if __name__ == "__main__":
	import doctest

	doctest.testmod()






