




import re
import string
from collections import Counter

import sacrebleu
import sacremoses
from packaging import version

import datasets


__A        =    "\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"

__A        =    "\\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"


__A        =    "\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 			lowerCamelCase_		(       UpperCamelCase__				:      List[Any]      )     ->       Union[str, Any]:





				"""simple docstring"""


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

				def white_space_fix(UpperCamelCase__				:      Union[str, Any]      ):
								return " ".join(text.split()      )

				def remove_punc(UpperCamelCase__				:      List[str]      ):
								__lowerCamelCase		       =    set(string.punctuation      )
								return "".join(ch for ch in text if ch not in exclude      )

				def lower(UpperCamelCase__				:      List[str]      ):
								return text.lower()

				return white_space_fix(remove_articles(remove_punc(lower(UpperCamelCase__      )      )      )      )







def 			lowerCamelCase_		(       UpperCamelCase__				:      str ,     UpperCamelCase__				:      Union[str, Any]      )     ->       List[str]:





				"""simple docstring"""


				return int(normalize_answer(UpperCamelCase__      ) == normalize_answer(UpperCamelCase__      )      )







def 			lowerCamelCase_		(       UpperCamelCase__				:      int ,     UpperCamelCase__				:      Tuple      )     ->       List[str]:





				"""simple docstring"""


				__lowerCamelCase		       =    [any(compute_exact(UpperCamelCase__ ,     UpperCamelCase__      ) for ref in refs      ) for pred, refs in zip(UpperCamelCase__ ,     UpperCamelCase__      )]
				return (sum(UpperCamelCase__      ) / len(UpperCamelCase__      )) * 100







def 			lowerCamelCase_		(       UpperCamelCase__				:      Optional[int] ,     UpperCamelCase__				:      List[str] ,     UpperCamelCase__				:      Tuple ,     UpperCamelCase__				:      str      )     ->       str:





				"""simple docstring"""


				__lowerCamelCase		       =    [rgram for rgrams in rgramslist for rgram in rgrams]
				__lowerCamelCase		       =    Counter(UpperCamelCase__      )

				__lowerCamelCase		       =    Counter(UpperCamelCase__      )
				__lowerCamelCase		       =    Counter()
				for sgram, scount in sgramcounter.items():
								__lowerCamelCase		       =    scount * numref

				__lowerCamelCase		       =    Counter(UpperCamelCase__      )
				__lowerCamelCase		       =    Counter()
				for cgram, ccount in cgramcounter.items():
								__lowerCamelCase		       =    ccount * numref

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

				__lowerCamelCase		       =    0
				__lowerCamelCase		       =    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.
				__lowerCamelCase		       =    1
				__lowerCamelCase		       =    1
				if len(UpperCamelCase__      ) > 0:
								__lowerCamelCase		       =    keeptmpscorea / len(UpperCamelCase__      )
				if len(UpperCamelCase__      ) > 0:
								# Fix an alleged bug [2] in the keep score computation.
								# keepscore_recall = keeptmpscore2 / len(keepgramcounterall_rep)
								__lowerCamelCase		       =    keeptmpscorea / sum(keepgramcounterall_rep.values()      )
				__lowerCamelCase		       =    0
				if keepscore_precision > 0 or keepscore_recall > 0:
								__lowerCamelCase		       =    2 * keepscore_precision * keepscore_recall / (keepscore_precision + keepscore_recall)

				# DELETION
				__lowerCamelCase		       =    sgramcounter_rep - cgramcounter_rep
				__lowerCamelCase		       =    delgramcounter_rep - rgramcounter
				__lowerCamelCase		       =    sgramcounter_rep - rgramcounter
				__lowerCamelCase		       =    0
				__lowerCamelCase		       =    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.
				__lowerCamelCase		       =    1
				if len(UpperCamelCase__      ) > 0:
								__lowerCamelCase		       =    deltmpscorea / len(UpperCamelCase__      )

				# ADDITION
				__lowerCamelCase		       =    set(UpperCamelCase__      ) - set(UpperCamelCase__      )
				__lowerCamelCase		       =    set(UpperCamelCase__      ) & set(UpperCamelCase__      )
				__lowerCamelCase		       =    set(UpperCamelCase__      ) - set(UpperCamelCase__      )

				__lowerCamelCase		       =    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.
				__lowerCamelCase		       =    1
				__lowerCamelCase		       =    1
				if len(UpperCamelCase__      ) > 0:
								__lowerCamelCase		       =    addtmpscore / len(UpperCamelCase__      )
				if len(UpperCamelCase__      ) > 0:
								__lowerCamelCase		       =    addtmpscore / len(UpperCamelCase__      )
				__lowerCamelCase		       =    0
				if addscore_precision > 0 or addscore_recall > 0:
								__lowerCamelCase		       =    2 * addscore_precision * addscore_recall / (addscore_precision + addscore_recall)

				return (keepscore, delscore_precision, addscore)







def 			lowerCamelCase_		(       UpperCamelCase__				:      Union[str, Any] ,     UpperCamelCase__				:      Tuple ,     UpperCamelCase__				:      Union[str, Any]      )     ->       Optional[int]:





				"""simple docstring"""


				__lowerCamelCase		       =    len(UpperCamelCase__      )

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

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

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

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

				((__lowerCamelCase)       ,						(__lowerCamelCase)       ,						(__lowerCamelCase))		       =    SARIngram(UpperCamelCase__ ,     UpperCamelCase__ ,     UpperCamelCase__ ,     UpperCamelCase__      )
				((__lowerCamelCase)       ,						(__lowerCamelCase)       ,						(__lowerCamelCase))		       =    SARIngram(UpperCamelCase__ ,     UpperCamelCase__ ,     UpperCamelCase__ ,     UpperCamelCase__      )
				((__lowerCamelCase)       ,						(__lowerCamelCase)       ,						(__lowerCamelCase))		       =    SARIngram(UpperCamelCase__ ,     UpperCamelCase__ ,     UpperCamelCase__ ,     UpperCamelCase__      )
				((__lowerCamelCase)       ,						(__lowerCamelCase)       ,						(__lowerCamelCase))		       =    SARIngram(UpperCamelCase__ ,     UpperCamelCase__ ,     UpperCamelCase__ ,     UpperCamelCase__      )
				__lowerCamelCase		       =    sum([keepascore, keepascore, keepascore, keepascore]      ) / 4
				__lowerCamelCase		       =    sum([delascore, delascore, delascore, delascore]      ) / 4
				__lowerCamelCase		       =    sum([addascore, addascore, addascore, addascore]      ) / 4
				__lowerCamelCase		       =    (avgkeepscore + avgdelscore + avgaddscore) / 3
				return finalscore







def 			lowerCamelCase_		(       UpperCamelCase__				:      Any ,     UpperCamelCase__				:      bool = True ,     UpperCamelCase__				:      str = "13a" ,     UpperCamelCase__				:      bool = True      )     ->       List[str]:





				"""simple docstring"""


				if lowercase:
								__lowerCamelCase		       =    sentence.lower()

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

				if not return_str:
								__lowerCamelCase		       =    normalized_sent.split()

				return normalized_sent







def 			lowerCamelCase_		(       UpperCamelCase__				:      str ,     UpperCamelCase__				:      List[str] ,     UpperCamelCase__				:      List[str]      )     ->       Union[str, Any]:





				"""simple docstring"""


				if not (len(UpperCamelCase__      ) == len(UpperCamelCase__      ) == len(UpperCamelCase__      )):
								raise ValueError('Sources length must match predictions and references lengths.'      )
				__lowerCamelCase		       =    0
				for src, pred, refs in zip(UpperCamelCase__ ,     UpperCamelCase__ ,     UpperCamelCase__      ):
								sari_score += SARIsent(normalize(UpperCamelCase__      ) ,     normalize(UpperCamelCase__      ) ,     [normalize(UpperCamelCase__      ) for sent in refs]      )
				__lowerCamelCase		       =    sari_score / len(UpperCamelCase__      )
				return 100 * sari_score







def 			lowerCamelCase_		(       UpperCamelCase__				:      Dict ,     UpperCamelCase__				:      Tuple ,     UpperCamelCase__				:      Any="exp" ,     UpperCamelCase__				:      Any=None ,     UpperCamelCase__				:      Tuple=False ,     UpperCamelCase__				:      List[Any]=False ,     UpperCamelCase__				:      Union[str, Any]=False ,     )     ->       List[str]:





				"""simple docstring"""


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







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

			"""simple docstring"""







			def       lowercase_    (      self							)    ->      Tuple:



							'''simple docstring'''
							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       lowercase_    (      self			,						lowerCamelCase__			,						lowerCamelCase__			,						lowerCamelCase__							)    ->      Any:



							'''simple docstring'''
							__lowerCamelCase		       =    {}
							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






import unittest

from transformers.testing_utils import require_bsa
from transformers.utils import is_bsa_available

from ...test_feature_extraction_common import FeatureExtractionSavingTestMixin


if is_bsa_available():
						from transformers import MarkupLMFeatureExtractor
class        _lowercase      (			unittest.TestCase       ):






				'''simple docstring'''



				def __init__(       self			:Optional[Any]			,			lowerCAmelCase__			:Optional[Any]	)		->			str:
										__SCREAMING_SNAKE_CASE						:     Optional[Any]					=		parent



				def 		__magic_name__(       self			:List[Any]	)		->			Tuple:
										return {}




def        _UpperCamelCase							(      ):
						__SCREAMING_SNAKE_CASE						:     Optional[Any]					=		'''<HTML>

    <HEAD>
    <TITLE>sample document</TITLE>
    </HEAD>

    <BODY BGCOLOR="FFFFFF">
    <HR>
    <a href="http://google.com">Goog</a>
    <H1>This is one header</H1>
    <H2>This is a another Header</H2>
    <P>Travel from
        <P>
        <B>SFO to JFK</B>
        <BR>
        <B><I>on May 2, 2015 at 2:00 pm. For details go to confirm.com </I></B>
        <HR>
        <div style="color:#0000FF">
            <h3>Traveler <b> name </b> is
            <p> John Doe </p>
        </div>'''

						__SCREAMING_SNAKE_CASE						:     str					=		'''
    <!DOCTYPE html>
    <html>
    <body>

    <h1>My First Heading</h1>
    <p>My first paragraph.</p>

    </body>
    </html>
    '''

						return [html_string_a, html_string_a]
@require_bsa
class        _lowercase      (			A__						,			unittest.TestCase       ):






				'''simple docstring'''



				SCREAMING_SNAKE_CASE__				:			Optional[int]						=		MarkupLMFeatureExtractor if is_bsa_available() else None


				def 		__magic_name__(       self			:int	)		->			Optional[Any]:
										__SCREAMING_SNAKE_CASE						:     Optional[Any]					=		MarkupLMFeatureExtractionTester(self	)


				@property
				def 		__magic_name__(       self			:Any	)		->			Optional[Any]:
										return self.feature_extract_tester.prepare_feat_extract_dict()



				def 		__magic_name__(       self			:Optional[int]	)		->			Any:
										# Initialize feature_extractor
										__SCREAMING_SNAKE_CASE						:     int					=		self.feature_extraction_class()

										# Test not batched input
										__SCREAMING_SNAKE_CASE						:     Tuple					=		get_html_strings()[0]
										__SCREAMING_SNAKE_CASE						:     Dict					=		feature_extractor(lowerCAmelCase__	)

										# fmt: off
										__SCREAMING_SNAKE_CASE						:     str					=		[['''sample document''', '''Goog''', '''This is one header''', '''This is a another Header''', '''Travel from''', '''SFO to JFK''', '''on May 2, 2015 at 2:00 pm. For details go to confirm.com''', '''Traveler''', '''name''', '''is''', '''John Doe''']]
										__SCREAMING_SNAKE_CASE						:     List[str]					=		[['''/html/head/title''', '''/html/body/a''', '''/html/body/h1''', '''/html/body/h2''', '''/html/body/p''', '''/html/body/p/p/b[1]''', '''/html/body/p/p/b[2]/i''', '''/html/body/p/p/div/h3''', '''/html/body/p/p/div/h3/b''', '''/html/body/p/p/div/h3''', '''/html/body/p/p/div/h3/p''']]
										# fmt: on

										self.assertEqual(encoding.nodes			,			lowerCAmelCase__	)
										self.assertEqual(encoding.xpaths			,			lowerCAmelCase__	)

										# Test batched
										__SCREAMING_SNAKE_CASE						:     Tuple					=		get_html_strings()
										__SCREAMING_SNAKE_CASE						:     Dict					=		feature_extractor(lowerCAmelCase__	)

										# fmt: off
										__SCREAMING_SNAKE_CASE						:     int					=		expected_nodes + [['''My First Heading''', '''My first paragraph.''']]
										__SCREAMING_SNAKE_CASE						:     str					=		expected_xpaths + [['''/html/body/h1''', '''/html/body/p''']]

										self.assertEqual(len(encoding.nodes	)			,			2	)
										self.assertEqual(len(encoding.xpaths	)			,			2	)

										self.assertEqual(encoding.nodes			,			lowerCAmelCase__	)
										self.assertEqual(encoding.xpaths			,			lowerCAmelCase__	)
