code: 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)
  A_:      Optional[int]        =			'\\n'
  
  A_:      Any        =			'\\n    XTREME-S is a benchmark to evaluate universal cross-lingual speech representations in many languages.\n    XTREME-S covers four task families: speech recognition, classification, speech-to-text translation and retrieval.\n'
  
  A_:      Optional[Any]        =			'\nCompute XTREME-S evaluation metric associated to each XTREME-S dataset.\nArgs:\n    predictions: list of predictions to score.\n        Each translation should be tokenized into a list of tokens.\n    references: list of lists of references for each translation.\n        Each reference should be tokenized into a list of tokens.\n    bleu_kwargs: optional dict of keywords to be passed when computing \'bleu\'.\n        Keywords include Dict can be one of \'smooth_method\', \'smooth_value\', \'force\', \'lowercase\',\n        \'tokenize\', \'use_effective_order\'.\n    wer_kwargs: optional dict of keywords to be passed when computing \'wer\' and \'cer\'.\n        Keywords include \'concatenate_texts\'.\nReturns: depending on the XTREME-S task, one or several of:\n    "accuracy": Accuracy - for \'fleurs-lang_id\', \'minds14\'\n    "f1": F1 score - for \'minds14\'\n    "wer": Word error rate - for \'mls\', \'fleurs-asr\', \'voxpopuli\', \'babel\'\n    "cer": Character error rate - for \'mls\', \'fleurs-asr\', \'voxpopuli\', \'babel\'\n    "bleu": BLEU score according to the `sacrebleu` metric - for \'covost2\'\nExamples:\n\n    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'mls\')  # \'mls\', \'voxpopuli\', \'fleurs-asr\' or \'babel\'\n    >>> references = ["it is sunny here", "paper and pen are essentials"]\n    >>> predictions = ["it\'s sunny", "paper pen are essential"]\n    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)\n    >>> print({k: round(v, 2) for k, v in results.items()})\n    {\'wer\': 0.56, \'cer\': 0.27}\n\n    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'covost2\')\n    >>> references = ["bonjour paris", "il est necessaire de faire du sport de temps en temp"]\n    >>> predictions = ["bonjour paris", "il est important de faire du sport souvent"]\n    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)\n    >>> print({k: round(v, 2) for k, v in results.items()})\n    {\'bleu\': 31.65}\n\n    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'fleurs-lang_id\')\n    >>> references = [0, 1, 0, 0, 1]\n    >>> predictions = [0, 1, 1, 0, 0]\n    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)\n    >>> print({k: round(v, 2) for k, v in results.items()})\n    {\'accuracy\': 0.6}\n\n    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'minds14\')\n    >>> references = [0, 1, 0, 0, 1]\n    >>> predictions = [0, 1, 1, 0, 0]\n    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)\n    >>> print({k: round(v, 2) for k, v in results.items()})\n    {\'f1\': 0.58, \'accuracy\': 0.6}\n'
  
  A_:      Any        =			['fleurs-asr', 'mls', 'voxpopuli', 'babel', 'covost2', 'fleurs-lang_id', 'minds14']
  A_:      Tuple        =			''
  
  try:
      from jiwer import transforms as tr
  
      A_:      List[str]        =			True
  except ImportError:
      A_:      Dict        =			False
  
  if _jiwer_available and version.parse(importlib_metadata.version('jiwer')) < version.parse('2.3.0'):
  
  
      class _lowercase					(       tr.AbstractTransform						):
  
  
  
  
  
             """simple docstring"""
  
  
  
  
             def __init__(    self     ,   UpperCAmelCase = " "  ):
  
  
  
  
  
  
  
                    '''simple docstring'''
  
  
  
  
  
  
                    _lowercase				=	sentence_delimiter
  
  
  
             def     _UpperCAmelCase       (    self     ,   UpperCAmelCase  ):
  
  
  
  
  
  
  
                    '''simple docstring'''
  
  
  
  
  
  
                    return list(UpperCAmelCase  )
  
  
  
             def     _UpperCAmelCase       (    self     ,   UpperCAmelCase  ):
  
  
  
  
  
  
  
                    '''simple docstring'''
  
  
  
  
  
  
                    _lowercase				=	[]
                    for sent_idx, sentence in enumerate(UpperCAmelCase  ):
                           chars.extend(self.process_string(UpperCAmelCase  )  )
                           if self.sentence_delimiter is not None and self.sentence_delimiter != "" and sent_idx < len(UpperCAmelCase  ) - 1:
                                  chars.append(self.sentence_delimiter  )
                    return chars
  
  
  
  
  
  
      A_:      Any        =			tr.Compose(
          [tr.RemoveMultipleSpaces(), tr.Strip(), SentencesToListOfCharacters(SENTENCE_DELIMITER)]
      )
  elif _jiwer_available:
      A_:      List[str]        =			tr.Compose(
          [
              tr.RemoveMultipleSpaces(),
              tr.Strip(),
              tr.ReduceToSingleSentence(SENTENCE_DELIMITER),
              tr.ReduceToListOfListOfChars(),
          ]
      )
  else:
      A_:      Optional[Any]        =			None
  
  
  def 					__lowerCAmelCase			(  _A ,_A					):
  
  
  
         """simple docstring"""
  
  
         return float((preds == labels).mean()					)
  
  
  def 					__lowerCAmelCase			(  _A ,_A					):
  
  
  
         """simple docstring"""
  
  
         return {
             "f1": float(fa_score(y_true=_A ,y_pred=_A ,average="""macro"""					)					),
             "accuracy": simple_accuracy(_A ,_A					),
         }
  
  
  def 					__lowerCAmelCase			(  _A ,_A ,_A="exp" ,_A=None ,_A=False ,_A=False ,_A=None ,_A=False ,):
  
  
  
         """simple docstring"""
  
  
         _lowercase				=	[[label] for label in labels]
         _lowercase				=	list(_A					)
         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\"`."""					)
  
         _lowercase				=	len(labels[0]					)
         if any(len(_A					) != references_per_prediction for refs in labels					):
                raise ValueError("""Sacrebleu requires the same number of references for each prediction"""					)
         _lowercase				=	[[refs[i] for refs in labels] for i in range(_A					)]
         _lowercase				=	scb.corpus_bleu(
             _A ,_A ,smooth_method=_A ,smooth_value=_A ,force=_A ,lowercase=_A ,use_effective_order=_A ,**({"""tokenize""": tokenize} if tokenize else {}) ,)
         return {"bleu": output.score}
  
  
  def 					__lowerCAmelCase			(  _A ,_A ,_A ,_A					):
  
  
  
         """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:
                _lowercase				=	compute_measures(_A ,_A					)["""wer"""]
  
                _lowercase				=	compute_measures(_A ,_A ,truth_transform=_A ,hypothesis_transform=_A					)["""wer"""]
                return {"wer": wer, "cer": cer}
         else:
  
                def compute_score(_A ,_A ,_A="wer"					):
                       _lowercase				=	0
                       _lowercase				=	0
                       for prediction, reference in zip(_A ,_A					):
                              if score_type == "wer":
                                     _lowercase				=	compute_measures(_A ,_A					)
                              elif score_type == "cer":
                                     _lowercase				=	compute_measures(
                                         _A ,_A ,truth_transform=_A ,hypothesis_transform=_A					)
                              incorrect += measures["substitutions"] + measures["deletions"] + measures["insertions"]
                              total += measures["substitutions"] + measures["deletions"] + measures["hits"]
                       return incorrect / total
  
                return {"wer": compute_score(_A ,_A ,"""wer"""					), "cer": compute_score(_A ,_A ,"""cer"""					)}
  
  
  
  
  
  
  
  @datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION   ,				_KWARGS_DESCRIPTION						)
  class _lowercase					(       datasets.Metric						):
  
  
  
  
  
         """simple docstring"""
  
  
  
  
         def     _UpperCAmelCase       (    self  ):
  
  
  
  
  
  
  
                '''simple docstring'''
  
  
  
  
  
  
                if self.config_name not in _CONFIG_NAMES:
                       raise KeyError(F'''You should supply a configuration name selected in {_CONFIG_NAMES}'''  )
  
                _lowercase				=	"""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(UpperCAmelCase  ), """references""": datasets.Value(UpperCAmelCase  )}  )     ,   codebase_urls=[]     ,   reference_urls=[]     ,   format="""numpy"""     ,   )
  
  
  
         def     _UpperCAmelCase       (    self     ,   UpperCAmelCase     ,   UpperCAmelCase     ,   UpperCAmelCase=None     ,   UpperCAmelCase=None  ):
  
  
  
  
  
  
  
                '''simple docstring'''
  
  
  
  
  
  
                _lowercase				=	bleu_kwargs if bleu_kwargs is not None else {}
                _lowercase				=	wer_kwargs if wer_kwargs is not None else {}
  
                if self.config_name == "fleurs-lang_id":
                       return {"accuracy": simple_accuracy(UpperCAmelCase     ,   UpperCAmelCase  )}
                elif self.config_name == "minds14":
                       return fa_and_simple_accuracy(UpperCAmelCase     ,   UpperCAmelCase  )
                elif self.config_name == "covost2":
                       _lowercase				=	bleu_kwargs.pop("""smooth_method"""     ,   """exp"""  )
                       _lowercase				=	bleu_kwargs.pop("""smooth_value"""     ,   UpperCAmelCase  )
                       _lowercase				=	bleu_kwargs.pop("""force"""     ,   UpperCAmelCase  )
                       _lowercase				=	bleu_kwargs.pop("""lowercase"""     ,   UpperCAmelCase  )
                       _lowercase				=	bleu_kwargs.pop("""tokenize"""     ,   UpperCAmelCase  )
                       _lowercase				=	bleu_kwargs.pop("""use_effective_order"""     ,   UpperCAmelCase  )
                       return bleu(
                           preds=UpperCAmelCase     ,   labels=UpperCAmelCase     ,   smooth_method=UpperCAmelCase     ,   smooth_value=UpperCAmelCase     ,   force=UpperCAmelCase     ,   lowercase=UpperCAmelCase     ,   tokenize=UpperCAmelCase     ,   use_effective_order=UpperCAmelCase     ,   )
                elif self.config_name in ["fleurs-asr", "mls", "voxpopuli", "babel"]:
                       _lowercase				=	wer_kwargs.pop("""concatenate_texts"""     ,   UpperCAmelCase  )
                       return wer_and_cer(UpperCAmelCase     ,   UpperCAmelCase     ,   UpperCAmelCase     ,   self.config_name  )
                else:
                       raise KeyError(F'''You should supply a configuration name selected in {_CONFIG_NAMES}'''  )
  
  
  
style_context: import numpy as np
  
  
  def 					__lowerCAmelCase			(  _A ,_A="utf-8" ,_A="surrogatepass"					):
  
  
  
  							"""simple docstring"""
  
  
  							_lowercase				=	bin(int.from_bytes(text.encode(_A ,_A					) ,"""big"""					)					)[2:]
  							return bits.zfill(8 * ((len(_A					) + 7) // 8)					)
  
  
  def 					__lowerCAmelCase			(  _A ,_A="utf-8" ,_A="surrogatepass"					):
  
  
  
  							"""simple docstring"""
  
  
  							_lowercase				=	int(_A ,2					)
  							return n.to_bytes((n.bit_length() + 7) // 8 ,"""big"""					).decode(_A ,_A					) or "\0"
  
  
  def 					__lowerCAmelCase			(  _A ,_A					):
  
  
  
  							"""simple docstring"""
  
  
  							if size_par + len(_A					) <= 2**size_par - (len(_A					) - 1):
  														raise ValueError("""size of parity don't match with size of data"""					)
  
  							_lowercase				=	[]
  							_lowercase				=	[]
  							_lowercase				=	[bin(_A					)[2:] for x in range(1 ,size_par + len(_A					) + 1					)]
  
  							# sorted information data for the size of the output data
  							_lowercase				=	[]
  							# data position template + parity
  							_lowercase				=	[]
  							# parity bit counter
  							_lowercase				=	0
  							# counter position of data bits
  							_lowercase				=	0
  
  							for x in range(1 ,size_par + len(_A					) + 1					):
  														# Performs a template of bit positions - who should be given,
  														# and who should be parity
  														if qtd_bp < size_par:
  																					if (np.log(_A					) / np.log(2					)).is_integer():
  																												data_out_gab.append("""P"""					)
  																												_lowercase				=	qtd_bp + 1
  																					else:
  																												data_out_gab.append("""D"""					)
  														else:
  																					data_out_gab.append("""D"""					)
  
  														# Sorts the data to the new output size
  														if data_out_gab[-1] == "D":
  																					data_ord.append(data[cont_data]					)
  																					cont_data += 1
  														else:
  																					data_ord.append(_A					)
  
      # Calculates parity
  							_lowercase				=	0  # parity bit counter
  							for bp in range(1 ,size_par + 1					):
  														# Bit counter one for a given parity
  														_lowercase				=	0
  														# counter to control the loop reading
  														_lowercase				=	0
  														for x in data_ord:
  																					if x is not None:
  																												try:
  																																			_lowercase				=	(bin_pos[cont_loop])[-1 * (bp)]
  																												except IndexError:
  																																			_lowercase				=	"""0"""
  																												if aux == "1" and x == "1":
  																																			cont_bo += 1
  																					cont_loop += 1
  														parity.append(cont_bo % 2					)
  
  														qtd_bp += 1
  
  							# Mount the message
  							_lowercase				=	0  # parity bit counter
  							for x in range(0 ,size_par + len(_A					)					):
  														if data_ord[x] is None:
  																					data_out.append(str(parity[cont_bp]					)					)
  																					cont_bp += 1
  														else:
  																					data_out.append(data_ord[x]					)
  
  							return data_out
  
  
  def 					__lowerCAmelCase			(  _A ,_A					):
  
  
  
  							"""simple docstring"""
  
  
  							_lowercase				=	[]
  							# Parity bit counter
  							_lowercase				=	0
  							# Counter p data bit reading
  							_lowercase				=	0
  							# list of parity received
  							_lowercase				=	[]
  							_lowercase				=	[]
  
  							for x in range(1 ,len(_A					) + 1					):
  														# Performs a template of bit positions - who should be given,
  														#  and who should be parity
  														if qtd_bp < size_par and (np.log(_A					) / np.log(2					)).is_integer():
  																					data_out_gab.append("""P"""					)
  																					_lowercase				=	qtd_bp + 1
  														else:
  																					data_out_gab.append("""D"""					)
  
  														# Sorts the data to the new output size
  														if data_out_gab[-1] == "D":
  																					data_output.append(data[cont_data]					)
  														else:
  																					parity_received.append(data[cont_data]					)
  														cont_data += 1
  
  							# -----------calculates the parity with the data
  							_lowercase				=	[]
  							_lowercase				=	[]
  							_lowercase				=	[bin(_A					)[2:] for x in range(1 ,size_par + len(_A					) + 1					)]
  
  							#  sorted information data for the size of the output data
  							_lowercase				=	[]
  							# Data position feedback + parity
  							_lowercase				=	[]
  							# Parity bit counter
  							_lowercase				=	0
  							# Counter p data bit reading
  							_lowercase				=	0
  
  							for x in range(1 ,size_par + len(_A					) + 1					):
  														# Performs a template position of bits - who should be given,
  														# and who should be parity
  														if qtd_bp < size_par and (np.log(_A					) / np.log(2					)).is_integer():
  																					data_out_gab.append("""P"""					)
  																					_lowercase				=	qtd_bp + 1
  														else:
  																					data_out_gab.append("""D"""					)
  
  														# Sorts the data to the new output size
  														if data_out_gab[-1] == "D":
  																					data_ord.append(data_output[cont_data]					)
  																					cont_data += 1
  														else:
  																					data_ord.append(_A					)
  
      # Calculates parity
  							_lowercase				=	0  # parity bit counter
  							for bp in range(1 ,size_par + 1					):
  														# Bit counter one for a certain parity
  														_lowercase				=	0
  														# Counter to control loop reading
  														_lowercase				=	0
  														for x in data_ord:
  																					if x is not None:
  																												try:
  																																			_lowercase				=	(bin_pos[cont_loop])[-1 * (bp)]
  																												except IndexError:
  																																			_lowercase				=	"""0"""
  																												if aux == "1" and x == "1":
  																																			cont_bo += 1
  																					cont_loop += 1
  														parity.append(str(cont_bo % 2					)					)
  
  														qtd_bp += 1
  
  							# Mount the message
  							_lowercase				=	0  # Parity bit counter
  							for x in range(0 ,size_par + len(_A					)					):
  														if data_ord[x] is None:
  																					data_out.append(str(parity[cont_bp]					)					)
  																					cont_bp += 1
  														else:
  																					data_out.append(data_ord[x]					)
  
  							_lowercase				=	parity_received == parity
  							return data_output, ack
  
  
  