


"""simple docstring"""






import re
import string
from collections import Counter

import sacrebleu
import sacremoses
from packaging import version

import datasets


__snake_case		=       "\n@inproceedings{xu-etal-2016-optimizing,\n    title = {Optimizing Statistical Machine Translation for Text Simplification},\n    authors={Xu, Wei and Napoles, Courtney and Pavlick, Ellie and Chen, Quanze and Callison-Burch, Chris},\n    journal = {Transactions of the Association for Computational Linguistics},\n    volume = {4},\n    year={2016},\n    url = {https://www.aclweb.org/anthology/Q16-1029},\n    pages = {401--415\n},\n@inproceedings{post-2018-call,\n    title = \"A Call for Clarity in Reporting {BLEU} Scores\",\n    author = \"Post, Matt\",\n    booktitle = \"Proceedings of the Third Conference on Machine Translation: Research Papers\",\n    month = oct,\n    year = \"2018\",\n    address = \"Belgium, Brussels\",\n    publisher = \"Association for Computational Linguistics\",\n    url = \"https://www.aclweb.org/anthology/W18-6319\",\n    pages = \"186--191\",\n}\n"

__snake_case		=       "\\nWIKI_SPLIT is the combination of three metrics SARI, EXACT and SACREBLEU\nIt can be used to evaluate the quality of machine-generated texts.\n"


__snake_case		=       "\nCalculates sari score (between 0 and 100) given a list of source and predicted\nsentences, and a list of lists of reference sentences. It also computes the BLEU score as well as the exact match score.\nArgs:\n    sources: list of source sentences where each sentence should be a string.\n    predictions: list of predicted sentences where each sentence should be a string.\n    references: list of lists of reference sentences where each sentence should be a string.\nReturns:\n    sari: sari score\n    sacrebleu: sacrebleu score\n    exact: exact score\n\nExamples:\n    >>> sources=[\"About 95 species are currently accepted .\"]\n    >>> predictions=[\"About 95 you now get in .\"]\n    >>> references=[[\"About 95 species are currently known .\"]]\n    >>> wiki_split = datasets.load_metric(\"wiki_split\")\n    >>> results = wiki_split.compute(sources=sources, predictions=predictions, references=references)\n    >>> print(results)\n    {'sari': 21.805555555555557, 'sacrebleu': 14.535768424205482, 'exact': 0.0}\n"
def       A_   (   _lowerCAmelCase     :					Any       ):






     """simple docstring"""

     def remove_articles(_lowerCAmelCase     :					Union[str, Any]       ):
          _a    	=				re.compile(R'''\b(a|an|the)\b''',     re.UNICODE       )
          return re.sub(_lowerCAmelCase,     ''' ''',     _lowerCAmelCase       )

     def white_space_fix(_lowerCAmelCase     :					Tuple       ):
          return " ".join(text.split()       )

     def remove_punc(_lowerCAmelCase     :					Union[str, Any]       ):
          _a    	=				set(string.punctuation       )
          return "".join(ch for ch in text if ch not in exclude       )

     def lower(_lowerCAmelCase     :					Optional[Any]       ):
          return text.lower()

     return white_space_fix(remove_articles(remove_punc(lower(_lowerCAmelCase       )       )       )       )
def       A_   (   _lowerCAmelCase     :					str,     _lowerCAmelCase     :					List[Any]       ):






     """simple docstring"""

     return int(normalize_answer(_lowerCAmelCase       ) == normalize_answer(_lowerCAmelCase       )       )
def       A_   (   _lowerCAmelCase     :					str,     _lowerCAmelCase     :					Tuple       ):






     """simple docstring"""

     _a    	=				[any(compute_exact(_lowerCAmelCase,     _lowerCAmelCase       ) for ref in refs       ) for pred, refs in zip(_lowerCAmelCase,     _lowerCAmelCase       )]
     return (sum(_lowerCAmelCase       ) / len(_lowerCAmelCase       )) * 1_00
def       A_   (   _lowerCAmelCase     :					Tuple,     _lowerCAmelCase     :					Optional[Any],     _lowerCAmelCase     :					Any,     _lowerCAmelCase     :					List[Any]       ):






     """simple docstring"""

     _a    	=				[rgram for rgrams in rgramslist for rgram in rgrams]
     _a    	=				Counter(_lowerCAmelCase       )

     _a    	=				Counter(_lowerCAmelCase       )
     _a    	=				Counter()
     for sgram, scount in sgramcounter.items():
          _a    	=				scount * numref

     _a    	=				Counter(_lowerCAmelCase       )
     _a    	=				Counter()
     for cgram, ccount in cgramcounter.items():
          _a    	=				ccount * numref

     # KEEP
     _a    	=				sgramcounter_rep & cgramcounter_rep
     _a    	=				keepgramcounter_rep & rgramcounter
     _a    	=				sgramcounter_rep & rgramcounter

     _a    	=				0
     _a    	=				0
     for keepgram in keepgramcountergood_rep:
          keeptmpscorea += keepgramcountergood_rep[keepgram] / keepgramcounter_rep[keepgram]
          # Fix an alleged bug [2] in the keep score computation.
          # keeptmpscore2 += keepgramcountergood_rep[keepgram] / keepgramcounterall_rep[keepgram]
          keeptmpscorea += keepgramcountergood_rep[keepgram]
     # Define 0/0=1 instead of 0 to give higher scores for predictions that match
     #      a target exactly.
     _a    	=				1
     _a    	=				1
     if len(_lowerCAmelCase       ) > 0:
          _a    	=				keeptmpscorea / len(_lowerCAmelCase       )
     if len(_lowerCAmelCase       ) > 0:
          # Fix an alleged bug [2] in the keep score computation.
          # keepscore_recall = keeptmpscore2 / len(keepgramcounterall_rep)
          _a    	=				keeptmpscorea / sum(keepgramcounterall_rep.values()       )
     _a    	=				0
     if keepscore_precision > 0 or keepscore_recall > 0:
          _a    	=				2 * keepscore_precision * keepscore_recall / (keepscore_precision + keepscore_recall)

     # DELETION
     _a    	=				sgramcounter_rep - cgramcounter_rep
     _a    	=				delgramcounter_rep - rgramcounter
     _a    	=				sgramcounter_rep - rgramcounter
     _a    	=				0
     _a    	=				0
     for delgram in delgramcountergood_rep:
          deltmpscorea += delgramcountergood_rep[delgram] / delgramcounter_rep[delgram]
          deltmpscorea += delgramcountergood_rep[delgram] / delgramcounterall_rep[delgram]
     # Define 0/0=1 instead of 0 to give higher scores for predictions that match
     # a target exactly.
     _a    	=				1
     if len(_lowerCAmelCase       ) > 0:
          _a    	=				deltmpscorea / len(_lowerCAmelCase       )

     # ADDITION
     _a    	=				set(_lowerCAmelCase       ) - set(_lowerCAmelCase       )
     _a    	=				set(_lowerCAmelCase       ) & set(_lowerCAmelCase       )
     _a    	=				set(_lowerCAmelCase       ) - set(_lowerCAmelCase       )

     _a    	=				0
     for addgram in addgramcountergood:
          addtmpscore += 1

     # Define 0/0=1 instead of 0 to give higher scores for predictions that match
     # a target exactly.
     _a    	=				1
     _a    	=				1
     if len(_lowerCAmelCase       ) > 0:
          _a    	=				addtmpscore / len(_lowerCAmelCase       )
     if len(_lowerCAmelCase       ) > 0:
          _a    	=				addtmpscore / len(_lowerCAmelCase       )
     _a    	=				0
     if addscore_precision > 0 or addscore_recall > 0:
          _a    	=				2 * addscore_precision * addscore_recall / (addscore_precision + addscore_recall)

     return (keepscore, delscore_precision, addscore)
def       A_   (   _lowerCAmelCase     :					List[Any],     _lowerCAmelCase     :					Union[str, Any],     _lowerCAmelCase     :					Optional[Any]       ):






     """simple docstring"""

     _a    	=				len(_lowerCAmelCase       )

     _a    	=				ssent.split(''' '''       )
     _a    	=				csent.split(''' '''       )
     _a    	=				[]
     _a    	=				[]
     _a    	=				[]
     _a    	=				[]
     _a    	=				[]
     _a    	=				[]

     _a    	=				[]
     _a    	=				[]
     _a    	=				[]
     _a    	=				[]
     for rsent in rsents:
          _a    	=				rsent.split(''' '''       )
          _a    	=				[]
          _a    	=				[]
          _a    	=				[]
          ragramslist.append(_lowerCAmelCase       )
          for i in range(0,     len(_lowerCAmelCase       ) - 1       ):
               if i < len(_lowerCAmelCase       ) - 1:
                    _a    	=				ragrams[i] + ''' ''' + ragrams[i + 1]
                    ragrams.append(_lowerCAmelCase       )
               if i < len(_lowerCAmelCase       ) - 2:
                    _a    	=				ragrams[i] + ''' ''' + ragrams[i + 1] + ''' ''' + ragrams[i + 2]
                    ragrams.append(_lowerCAmelCase       )
               if i < len(_lowerCAmelCase       ) - 3:
                    _a    	=				ragrams[i] + ''' ''' + ragrams[i + 1] + ''' ''' + ragrams[i + 2] + ''' ''' + ragrams[i + 3]
                    ragrams.append(_lowerCAmelCase       )
          ragramslist.append(_lowerCAmelCase       )
          ragramslist.append(_lowerCAmelCase       )
          ragramslist.append(_lowerCAmelCase       )

     for i in range(0,     len(_lowerCAmelCase       ) - 1       ):
          if i < len(_lowerCAmelCase       ) - 1:
               _a    	=				sagrams[i] + ''' ''' + sagrams[i + 1]
               sagrams.append(_lowerCAmelCase       )
          if i < len(_lowerCAmelCase       ) - 2:
               _a    	=				sagrams[i] + ''' ''' + sagrams[i + 1] + ''' ''' + sagrams[i + 2]
               sagrams.append(_lowerCAmelCase       )
          if i < len(_lowerCAmelCase       ) - 3:
               _a    	=				sagrams[i] + ''' ''' + sagrams[i + 1] + ''' ''' + sagrams[i + 2] + ''' ''' + sagrams[i + 3]
               sagrams.append(_lowerCAmelCase       )

     for i in range(0,     len(_lowerCAmelCase       ) - 1       ):
          if i < len(_lowerCAmelCase       ) - 1:
               _a    	=				cagrams[i] + ''' ''' + cagrams[i + 1]
               cagrams.append(_lowerCAmelCase       )
          if i < len(_lowerCAmelCase       ) - 2:
               _a    	=				cagrams[i] + ''' ''' + cagrams[i + 1] + ''' ''' + cagrams[i + 2]
               cagrams.append(_lowerCAmelCase       )
          if i < len(_lowerCAmelCase       ) - 3:
               _a    	=				cagrams[i] + ''' ''' + cagrams[i + 1] + ''' ''' + cagrams[i + 2] + ''' ''' + cagrams[i + 3]
               cagrams.append(_lowerCAmelCase       )

     (_a)    	=				SARIngram(_lowerCAmelCase,     _lowerCAmelCase,     _lowerCAmelCase,     _lowerCAmelCase       )
     (_a)    	=				SARIngram(_lowerCAmelCase,     _lowerCAmelCase,     _lowerCAmelCase,     _lowerCAmelCase       )
     (_a)    	=				SARIngram(_lowerCAmelCase,     _lowerCAmelCase,     _lowerCAmelCase,     _lowerCAmelCase       )
     (_a)    	=				SARIngram(_lowerCAmelCase,     _lowerCAmelCase,     _lowerCAmelCase,     _lowerCAmelCase       )
     _a    	=				sum([keepascore, keepascore, keepascore, keepascore]       ) / 4
     _a    	=				sum([delascore, delascore, delascore, delascore]       ) / 4
     _a    	=				sum([addascore, addascore, addascore, addascore]       ) / 4
     _a    	=				(avgkeepscore + avgdelscore + avgaddscore) / 3
     return finalscore
def       A_   (   _lowerCAmelCase     :					Dict,     _lowerCAmelCase     :					bool = True,     _lowerCAmelCase     :					str = "13a",     _lowerCAmelCase     :					bool = True       ):






     """simple docstring"""

     if lowercase:
          _a    	=				sentence.lower()

     if tokenizer in ["13a", "intl"]:
          if version.parse(sacrebleu.__version__       ).major >= 2:
               _a    	=				sacrebleu.metrics.bleu._get_tokenizer(_lowerCAmelCase       )()(_lowerCAmelCase       )
          else:
               _a    	=				sacrebleu.TOKENIZERS[tokenizer]()(_lowerCAmelCase       )
     elif tokenizer == "moses":
          _a    	=				sacremoses.MosesTokenizer().tokenize(_lowerCAmelCase,     return_str=_lowerCAmelCase,     escape=_lowerCAmelCase       )
     elif tokenizer == "penn":
          _a    	=				sacremoses.MosesTokenizer().penn_tokenize(_lowerCAmelCase,     return_str=_lowerCAmelCase       )
     else:
          _a    	=				sentence

     if not return_str:
          _a    	=				normalized_sent.split()

     return normalized_sent
def       A_   (   _lowerCAmelCase     :					Optional[Any],     _lowerCAmelCase     :					str,     _lowerCAmelCase     :					List[Any]       ):






     """simple docstring"""

     if not (len(_lowerCAmelCase       ) == len(_lowerCAmelCase       ) == len(_lowerCAmelCase       )):
          raise ValueError('''Sources length must match predictions and references lengths.'''       )
     _a    	=				0
     for src, pred, refs in zip(_lowerCAmelCase,     _lowerCAmelCase,     _lowerCAmelCase       ):
          sari_score += SARIsent(normalize(_lowerCAmelCase       ),     normalize(_lowerCAmelCase       ),     [normalize(_lowerCAmelCase       ) for sent in refs]       )
     _a    	=				sari_score / len(_lowerCAmelCase       )
     return 1_00 * sari_score
def       A_   (   _lowerCAmelCase     :					Tuple,     _lowerCAmelCase     :					Union[str, Any],     _lowerCAmelCase     :					Tuple="exp",     _lowerCAmelCase     :					int=None,     _lowerCAmelCase     :					Dict=False,     _lowerCAmelCase     :					str=False,     _lowerCAmelCase     :					int=False,     ):






     """simple docstring"""

     _a    	=				len(references[0]       )
     if any(len(_lowerCAmelCase       ) != references_per_prediction for refs in references       ):
          raise ValueError('''Sacrebleu requires the same number of references for each prediction'''       )
     _a    	=				[[refs[i] for refs in references] for i in range(_lowerCAmelCase       )]
     _a    	=				sacrebleu.corpus_bleu(
         _lowerCAmelCase,     _lowerCAmelCase,     smooth_method=_lowerCAmelCase,     smooth_value=_lowerCAmelCase,     force=_lowerCAmelCase,     lowercase=_lowerCAmelCase,     use_effective_order=_lowerCAmelCase,     )
     return output.score


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

     '''simple docstring'''


     def 							_UpperCAmelCase      (      self							)       ->							int:
          return datasets.MetricInfo(
              description=_DESCRIPTION    ,				citation=_CITATION    ,				inputs_description=_KWARGS_DESCRIPTION    ,				features=datasets.Features(
                  {
                      '''predictions''': datasets.Value('''string'''    ,				id='''sequence'''							),
                      '''references''': datasets.Sequence(datasets.Value('''string'''    ,				id='''sequence'''							)    ,				id='''references'''							),
                  }							)    ,				codebase_urls=[
                  '''https://github.com/huggingface/transformers/blob/master/src/transformers/data/metrics/squad_metrics.py''',
                  '''https://github.com/cocoxu/simplification/blob/master/SARI.py''',
                  '''https://github.com/tensorflow/tensor2tensor/blob/master/tensor2tensor/utils/sari_hook.py''',
                  '''https://github.com/mjpost/sacreBLEU''',
              ]    ,				reference_urls=[
                  '''https://www.aclweb.org/anthology/Q16-1029.pdf''',
                  '''https://github.com/mjpost/sacreBLEU''',
                  '''https://en.wikipedia.org/wiki/BLEU''',
                  '''https://towardsdatascience.com/evaluating-text-output-in-nlp-bleu-at-your-own-risk-e8609665a213''',
              ]    ,				)





     def 							_UpperCAmelCase      (      self    ,				__UpperCAmelCase    ,				__UpperCAmelCase    ,				__UpperCAmelCase							)       ->							List[Any]:
          _a    	=				{}
          result.update({'''sari''': compute_sari(sources=lowerCamelCase__    ,				predictions=lowerCamelCase__    ,				references=lowerCamelCase__							)}							)
          result.update({'''sacrebleu''': compute_sacrebleu(predictions=lowerCamelCase__    ,				references=lowerCamelCase__							)}							)
          result.update({'''exact''': compute_em(predictions=lowerCamelCase__    ,				references=lowerCamelCase__							)}							)
          return result



"""simple docstring"""






from typing import List, Optional, Union

import numpy as np

from ...feature_extraction_sequence_utils import SequenceFeatureExtractor
from ...feature_extraction_utils import BatchFeature
from ...utils import PaddingStrategy, TensorType, logging


__snake_case		=       logging.get_logger(__name__)


class     __lowerCamelCase  (					a__				):

     '''simple docstring'''
     A_       :	Union[str, Any]    =		['input_values', 'padding_mask']


     def __init__(      self    ,				__UpperCAmelCase = 1    ,				__UpperCAmelCase = 24000    ,				__UpperCAmelCase = 0.0    ,				__UpperCAmelCase = None    ,				__UpperCAmelCase = None    ,				**__UpperCAmelCase    ,				)       ->							List[str]:
          super().__init__(feature_size=__UpperCAmelCase    ,				sampling_rate=__UpperCAmelCase    ,				padding_value=__UpperCAmelCase    ,				**__UpperCAmelCase							)
          _a    	=				chunk_length_s
          _a    	=				overlap


     @property
     def 							_UpperCAmelCase      (      self							)       ->							Optional[int]:
          if self.chunk_length_s is None:
               return None
          else:
               return int(self.chunk_length_s * self.sampling_rate							)


     @property
     def 							_UpperCAmelCase      (      self							)       ->							Optional[int]:
          if self.chunk_length_s is None or self.overlap is None:
               return None
          else:
               return max(1    ,				int((1.0 - self.overlap) * self.chunk_length							)							)





     def __call__(      self    ,				__UpperCAmelCase    ,				__UpperCAmelCase = None    ,				__UpperCAmelCase = False    ,				__UpperCAmelCase = None    ,				__UpperCAmelCase = None    ,				__UpperCAmelCase = None    ,				)       ->							BatchFeature:
          if sampling_rate is not None:
               if sampling_rate != self.sampling_rate:
                    raise ValueError(
                        F'The model corresponding to this feature extractor: {self} was trained using a sampling rate of'
                        F' {self.sampling_rate}. Please make sure that the provided audio input was sampled with'
                        F' {self.sampling_rate} and not {sampling_rate}.'							)
          else:
               logger.warning(
                   '''It is strongly recommended to pass the `sampling_rate` argument to this function. '''
                   '''Failing to do so can result in silent errors that might be hard to debug.'''							)

          if padding and truncation:
               raise ValueError('''Both padding and truncation were set. Make sure you only set one.'''							)
          elif padding is None:
               # by default let's pad the inputs
               _a    	=				True

          _a    	=				bool(
              isinstance(__UpperCAmelCase    ,				(list, tuple)							) and (isinstance(raw_audio[0]    ,				(np.ndarray, tuple, list)							))							)

          if is_batched:
               _a    	=				[np.asarray(__UpperCAmelCase    ,				dtype=np.floataa							).T for audio in raw_audio]
          elif not is_batched and not isinstance(__UpperCAmelCase    ,				np.ndarray							):
               _a    	=				np.asarray(__UpperCAmelCase    ,				dtype=np.floataa							)
          elif isinstance(__UpperCAmelCase    ,				np.ndarray							) and raw_audio.dtype is np.dtype(np.floataa							):
               _a    	=				raw_audio.astype(np.floataa							)

          # always return batch
          if not is_batched:
               _a    	=				[np.asarray(__UpperCAmelCase							).T]

          # verify inputs are valid
          for idx, example in enumerate(__UpperCAmelCase							):
               if example.ndim > 2:
                    raise ValueError(F'Expected input shape (channels, length) but got shape {example.shape}'							)
               if self.feature_size == 1 and example.ndim != 1:
                    raise ValueError(F'Expected mono audio but example has {example.shape[-1]} channels'							)
               if self.feature_size == 2 and example.shape[-1] != 2:
                    raise ValueError(F'Expected stereo audio but example has {example.shape[-1]} channels'							)

          _a    	=				None
          _a    	=				BatchFeature({'''input_values''': raw_audio}							)
          if self.chunk_stride is not None and self.chunk_length is not None and max_length is None:
               if truncation:
                    _a    	=				min(array.shape[0] for array in raw_audio							)
                    _a    	=				int(np.floor(max_length / self.chunk_stride							)							)
                    _a    	=				(nb_step - 1) * self.chunk_stride + self.chunk_length
               elif padding:
                    _a    	=				max(array.shape[0] for array in raw_audio							)
                    _a    	=				int(np.ceil(max_length / self.chunk_stride							)							)
                    _a    	=				(nb_step - 1) * self.chunk_stride + self.chunk_length
                    _a    	=				'''max_length'''
               else:
                    _a    	=				input_values

        # normal padding on batch
          if padded_inputs is None:
               _a    	=				self.pad(
                   __UpperCAmelCase    ,				max_length=__UpperCAmelCase    ,				truncation=__UpperCAmelCase    ,				padding=__UpperCAmelCase    ,				return_attention_mask=__UpperCAmelCase    ,				)
               if padding:
                    _a    	=				padded_inputs.pop('''attention_mask'''							)

          _a    	=				[]
          for example in padded_inputs.pop('''input_values'''							):
               if self.feature_size == 1:
                    _a    	=				example[..., None]
               input_values.append(example.T							)

          _a    	=				input_values
          if return_tensors is not None:
               _a    	=				padded_inputs.convert_to_tensors(__UpperCAmelCase							)

          return padded_inputs