


from typing import List

from packaging import version
from sklearn.metrics import fa_score

import datasets
from datasets.config import PY_VERSION


if PY_VERSION < version.parse('''3.8'''):
     import importlib_metadata
else:
     import importlib.metadata as importlib_metadata


# TODO(Patrick/Anton)
snake_case       :					Tuple        =  '''\
'''

snake_case       :					Any        =  '''\
    XTREME-S is a benchmark to evaluate universal cross-lingual speech representations in many languages.
    XTREME-S covers four task families: speech recognition, classification, speech-to-text translation and retrieval.
'''

snake_case       :					List[str]        =  '''
Compute XTREME-S evaluation metric associated to each XTREME-S dataset.
Args:
    predictions: list of predictions to score.
        Each translation should be tokenized into a list of tokens.
    references: list of lists of references for each translation.
        Each reference should be tokenized into a list of tokens.
    bleu_kwargs: optional dict of keywords to be passed when computing \'bleu\'.
        Keywords include Dict can be one of \'smooth_method\', \'smooth_value\', \'force\', \'lowercase\',
        \'tokenize\', \'use_effective_order\'.
    wer_kwargs: optional dict of keywords to be passed when computing \'wer\' and \'cer\'.
        Keywords include \'concatenate_texts\'.
Returns: depending on the XTREME-S task, one or several of:
    "accuracy": Accuracy - for \'fleurs-lang_id\', \'minds14\'
    "f1": F1 score - for \'minds14\'
    "wer": Word error rate - for \'mls\', \'fleurs-asr\', \'voxpopuli\', \'babel\'
    "cer": Character error rate - for \'mls\', \'fleurs-asr\', \'voxpopuli\', \'babel\'
    "bleu": BLEU score according to the `sacrebleu` metric - for \'covost2\'
Examples:

    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'mls\')  # \'mls\', \'voxpopuli\', \'fleurs-asr\' or \'babel\'
    >>> references = ["it is sunny here", "paper and pen are essentials"]
    >>> predictions = ["it\'s sunny", "paper pen are essential"]
    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)
    >>> print({k: round(v, 2) for k, v in results.items()})
    {\'wer\': 0.56, \'cer\': 0.27}

    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'covost2\')
    >>> references = ["bonjour paris", "il est necessaire de faire du sport de temps en temp"]
    >>> predictions = ["bonjour paris", "il est important de faire du sport souvent"]
    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)
    >>> print({k: round(v, 2) for k, v in results.items()})
    {\'bleu\': 31.65}

    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'fleurs-lang_id\')
    >>> references = [0, 1, 0, 0, 1]
    >>> predictions = [0, 1, 1, 0, 0]
    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)
    >>> print({k: round(v, 2) for k, v in results.items()})
    {\'accuracy\': 0.6}

    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'minds14\')
    >>> references = [0, 1, 0, 0, 1]
    >>> predictions = [0, 1, 1, 0, 0]
    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)
    >>> print({k: round(v, 2) for k, v in results.items()})
    {\'f1\': 0.58, \'accuracy\': 0.6}
'''

snake_case       :					List[Any]        =  ['''fleurs-asr''', '''mls''', '''voxpopuli''', '''babel''', '''covost2''', '''fleurs-lang_id''', '''minds14''']
snake_case       :					Optional[Any]        =  ''''''

try:
     from jiwer import transforms as tr

     snake_case       :					Any        =  True
except ImportError:
     snake_case       :					Any        =  False

if _jiwer_available and version.parse(importlib_metadata.version('''jiwer''')) < version.parse('''2.3.0'''):







     class 	_snake_case						(   tr.AbstractTransform							):




      def __init__(	self      ,						_lowerCamelCase = " "					):
            a		:Union[str, Any]											= sentence_delimiter




      def  SCREAMING_SNAKE_CASE__       (	self      ,						_lowerCamelCase					):
            return list(_lowerCamelCase					)




      def  SCREAMING_SNAKE_CASE__       (	self      ,						_lowerCamelCase					):
            a		:Optional[int]											= []
            for sent_idx, sentence in enumerate(_lowerCamelCase					):
                  chars.extend(self.process_string(_lowerCamelCase					)					)
                  if self.sentence_delimiter is not None and self.sentence_delimiter != "" and sent_idx < len(_lowerCamelCase					) - 1:
                        chars.append(self.sentence_delimiter					)
            return chars







     snake_case       :					int        =  tr.Compose(
         [tr.RemoveMultipleSpaces(), tr.Strip(), SentencesToListOfCharacters(SENTENCE_DELIMITER)]
     )
elif _jiwer_available:
     snake_case       :					Any        =  tr.Compose(
         [
             tr.RemoveMultipleSpaces(),
             tr.Strip(),
             tr.ReduceToSingleSentence(SENTENCE_DELIMITER),
             tr.ReduceToListOfListOfChars(),
         ]
     )
else:
     snake_case       :					str        =  None
def        __lowerCamelCase		(				UpperCAmelCase_		:	Dict				,						UpperCAmelCase_		:	str		):




      """simple docstring"""





      return float((preds == labels).mean()		)
def        __lowerCamelCase		(				UpperCAmelCase_		:	int				,						UpperCAmelCase_		:	Optional[Any]		):




      """simple docstring"""





      return {
          "f1": float(fa_score(y_true=UpperCAmelCase_				,						y_pred=UpperCAmelCase_				,						average='''macro'''		)		),
          "accuracy": simple_accuracy(UpperCAmelCase_				,						UpperCAmelCase_		),
      }
def        __lowerCamelCase		(				UpperCAmelCase_		:	Optional[Any]				,						UpperCAmelCase_		:	Optional[Any]				,						UpperCAmelCase_		:	Dict="exp"				,						UpperCAmelCase_		:	Union[str, Any]=None				,						UpperCAmelCase_		:	List[Any]=False				,						UpperCAmelCase_		:	List[Any]=False				,						UpperCAmelCase_		:	Optional[Any]=None				,						UpperCAmelCase_		:	int=False				,						):




      """simple docstring"""





      a		:Dict											= [[label] for label in labels]
      a		:Any											= list(UpperCAmelCase_		)
      try:
            import sacrebleu as scb
      except ImportError:
            raise ValueError(
                '''sacrebleu has to be installed in order to apply the bleu metric for covost2.'''
                '''You can install it via `pip install sacrebleu`.'''		)

      if version.parse(scb.__version__		) < version.parse('''1.4.12'''		):
            raise ImportWarning(
                '''To use `sacrebleu`, the module `sacrebleu>=1.4.12` is required, and the current version of `sacrebleu` doesn\'t match this condition.\n'''
                '''You can install it with `pip install "sacrebleu>=1.4.12"`.'''		)

      a		:List[Any]											= len(labels[0]		)
      if any(len(UpperCAmelCase_		) != references_per_prediction for refs in labels		):
            raise ValueError('''Sacrebleu requires the same number of references for each prediction'''		)
      a		:Union[str, Any]											= [[refs[i] for refs in labels] for i in range(UpperCAmelCase_		)]
      a		:Optional[int]											= scb.corpus_bleu(
          UpperCAmelCase_				,						UpperCAmelCase_				,						smooth_method=UpperCAmelCase_				,						smooth_value=UpperCAmelCase_				,						force=UpperCAmelCase_				,						lowercase=UpperCAmelCase_				,						use_effective_order=UpperCAmelCase_				,						**({'''tokenize''': tokenize} if tokenize else {})				,						)
      return {"bleu": output.score}
def        __lowerCamelCase		(				UpperCAmelCase_		:	str				,						UpperCAmelCase_		:	Optional[Any]				,						UpperCAmelCase_		:	Dict				,						UpperCAmelCase_		:	int		):




      """simple docstring"""





      try:
            from jiwer import compute_measures
      except ImportError:
            raise ValueError(
                F'''jiwer has to be installed in order to apply the wer metric for {config_name}.'''
                '''You can install it via `pip install jiwer`.'''		)

      if concatenate_texts:
            a		:Any											= compute_measures(UpperCAmelCase_				,						UpperCAmelCase_		)['''wer''']

            a		:List[Any]											= compute_measures(UpperCAmelCase_				,						UpperCAmelCase_				,						truth_transform=UpperCAmelCase_				,						hypothesis_transform=UpperCAmelCase_		)['''wer''']
            return {"wer": wer, "cer": cer}
      else:

            def compute_score(UpperCAmelCase_		:	Any				,						UpperCAmelCase_		:	Dict				,						UpperCAmelCase_		:	Any="wer"		):
                  a		:int											= 0
                  a		:Union[str, Any]											= 0
                  for prediction, reference in zip(UpperCAmelCase_				,						UpperCAmelCase_		):
                        if score_type == "wer":
                              a		:Dict											= compute_measures(UpperCAmelCase_				,						UpperCAmelCase_		)
                        elif score_type == "cer":
                              a		:Dict											= compute_measures(
                                  UpperCAmelCase_				,						UpperCAmelCase_				,						truth_transform=UpperCAmelCase_				,						hypothesis_transform=UpperCAmelCase_		)
                        incorrect += measures["substitutions"] + measures["deletions"] + measures["insertions"]
                        total += measures["substitutions"] + measures["deletions"] + measures["hits"]
                  return incorrect / total

            return {"wer": compute_score(UpperCAmelCase_				,						UpperCAmelCase_				,						'''wer'''		), "cer": compute_score(UpperCAmelCase_				,						UpperCAmelCase_				,						'''cer'''		)}







@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION		,					_KWARGS_DESCRIPTION							)
class 	_snake_case						(   datasets.Metric							):




 def  SCREAMING_SNAKE_CASE__       (	self					):
       if self.config_name not in _CONFIG_NAMES:
             raise KeyError(F'''You should supply a configuration name selected in {_CONFIG_NAMES}'''					)

       a		:str											= '''int64''' if self.config_name in ['''fleurs-lang_id''', '''minds14'''] else '''string'''

       return datasets.MetricInfo(
           description=_DESCRIPTION      ,						citation=_CITATION      ,						inputs_description=_KWARGS_DESCRIPTION      ,						features=datasets.Features(
               {'''predictions''': datasets.Value(_lowerCamelCase					), '''references''': datasets.Value(_lowerCamelCase					)}					)      ,						codebase_urls=[]      ,						reference_urls=[]      ,						format='''numpy'''      ,						)




 def  SCREAMING_SNAKE_CASE__       (	self      ,						_lowerCamelCase      ,						_lowerCamelCase      ,						_lowerCamelCase=None      ,						_lowerCamelCase=None					):
       a		:Any											= bleu_kwargs if bleu_kwargs is not None else {}
       a		:Optional[Any]											= wer_kwargs if wer_kwargs is not None else {}

       if self.config_name == "fleurs-lang_id":
             return {"accuracy": simple_accuracy(_lowerCamelCase      ,						_lowerCamelCase					)}
       elif self.config_name == "minds14":
             return fa_and_simple_accuracy(_lowerCamelCase      ,						_lowerCamelCase					)
       elif self.config_name == "covost2":
             a		:Union[str, Any]											= bleu_kwargs.pop('''smooth_method'''      ,						'''exp'''					)
             a		:Union[str, Any]											= bleu_kwargs.pop('''smooth_value'''      ,						_lowerCamelCase					)
             a		:Any											= bleu_kwargs.pop('''force'''      ,						_lowerCamelCase					)
             a		:Any											= bleu_kwargs.pop('''lowercase'''      ,						_lowerCamelCase					)
             a		:Any											= bleu_kwargs.pop('''tokenize'''      ,						_lowerCamelCase					)
             a		:str											= bleu_kwargs.pop('''use_effective_order'''      ,						_lowerCamelCase					)
             return bleu(
                 preds=_lowerCamelCase      ,						labels=_lowerCamelCase      ,						smooth_method=_lowerCamelCase      ,						smooth_value=_lowerCamelCase      ,						force=_lowerCamelCase      ,						lowercase=_lowerCamelCase      ,						tokenize=_lowerCamelCase      ,						use_effective_order=_lowerCamelCase      ,						)
       elif self.config_name in ["fleurs-asr", "mls", "voxpopuli", "babel"]:
             a		:int											= wer_kwargs.pop('''concatenate_texts'''      ,						_lowerCamelCase					)
             return wer_and_cer(_lowerCamelCase      ,						_lowerCamelCase      ,						_lowerCamelCase      ,						self.config_name					)
       else:
             raise KeyError(F'''You should supply a configuration name selected in {_CONFIG_NAMES}'''					)









from typing import Optional, Union

from ...file_utils import TensorType
from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import BatchEncoding, PaddingStrategy, TruncationStrategy







class 	_snake_case						(   _snake_case							):
 SCREAMING_SNAKE_CASE__   = 'MarkupLMFeatureExtractor'
 SCREAMING_SNAKE_CASE__   = ('MarkupLMTokenizer', 'MarkupLMTokenizerFast')
 SCREAMING_SNAKE_CASE__   = True




 def __call__(	self      ,						_lowerCamelCase=None      ,						_lowerCamelCase=None      ,						_lowerCamelCase=None      ,						_lowerCamelCase=None      ,						_lowerCamelCase=None      ,						_lowerCamelCase = True      ,						_lowerCamelCase = False      ,						_lowerCamelCase = None      ,						_lowerCamelCase = None      ,						_lowerCamelCase = 0      ,						_lowerCamelCase = None      ,						_lowerCamelCase = None      ,						_lowerCamelCase = None      ,						_lowerCamelCase = False      ,						_lowerCamelCase = False      ,						_lowerCamelCase = False      ,						_lowerCamelCase = False      ,						_lowerCamelCase = True      ,						_lowerCamelCase = None      ,						**_lowerCamelCase      ,						):
       # first, create nodes and xpaths
       if self.parse_html:
             if html_strings is None:
                   raise ValueError('''Make sure to pass HTML strings in case `parse_html` is set to `True`'''					)

             if nodes is not None or xpaths is not None or node_labels is not None:
                   raise ValueError(
                       '''Please don\'t pass nodes, xpaths nor node labels in case `parse_html` is set to `True`'''					)

             a		:int											= self.feature_extractor(_lowerCamelCase					)
             a		:Tuple											= features['''nodes''']
             a		:Dict											= features['''xpaths''']
       else:
             if html_strings is not None:
                   raise ValueError('''You have passed HTML strings but `parse_html` is set to `False`.'''					)
             if nodes is None or xpaths is None:
                   raise ValueError('''Make sure to pass nodes and xpaths in case `parse_html` is set to `False`'''					)

        # # second, apply the tokenizer
       if questions is not None and self.parse_html:
             if isinstance(_lowerCamelCase      ,						_lowerCamelCase					):
                   a		:Tuple											= [questions]  # add batch dimension (as the feature extractor always adds a batch dimension)

       a		:Optional[int]											= self.tokenizer(
           text=questions if questions is not None else nodes      ,						text_pair=nodes if questions is not None else None      ,						xpaths=_lowerCamelCase      ,						node_labels=_lowerCamelCase      ,						add_special_tokens=_lowerCamelCase      ,						padding=_lowerCamelCase      ,						truncation=_lowerCamelCase      ,						max_length=_lowerCamelCase      ,						stride=_lowerCamelCase      ,						pad_to_multiple_of=_lowerCamelCase      ,						return_token_type_ids=_lowerCamelCase      ,						return_attention_mask=_lowerCamelCase      ,						return_overflowing_tokens=_lowerCamelCase      ,						return_special_tokens_mask=_lowerCamelCase      ,						return_offsets_mapping=_lowerCamelCase      ,						return_length=_lowerCamelCase      ,						verbose=_lowerCamelCase      ,						return_tensors=_lowerCamelCase      ,						**_lowerCamelCase      ,						)

       return encoded_inputs




 def  SCREAMING_SNAKE_CASE__       (	self      ,						*_lowerCamelCase      ,						**_lowerCamelCase					):
       return self.tokenizer.batch_decode(*_lowerCamelCase      ,						**_lowerCamelCase					)




 def  SCREAMING_SNAKE_CASE__       (	self      ,						*_lowerCamelCase      ,						**_lowerCamelCase					):
       return self.tokenizer.decode(*_lowerCamelCase      ,						**_lowerCamelCase					)




 @property
 def  SCREAMING_SNAKE_CASE__       (	self					):
       a		:Any											= self.tokenizer.model_input_names
       return tokenizer_input_names





