






import datasets

from .evaluate import (
    apply_no_ans_threshold,
    find_all_best_thresh,
    get_raw_scores,
    make_eval_dict,
    make_qid_to_has_ans,
    merge_eval,
)


A__     :      Union[str, Any]             =			'\\n@inproceedings{Rajpurkar2016SQuAD10,\n  title={SQuAD: 100, 000+ Questions for Machine Comprehension of Text},\n  author={Pranav Rajpurkar and Jian Zhang and Konstantin Lopyrev and Percy Liang},\n  booktitle={EMNLP},\n  year={2016}\n}\n'

A__     :      Union[str, Any]             =			'\nThis metric wrap the official scoring script for version 2 of the Stanford Question\nAnswering Dataset (SQuAD).\n\nStanford Question Answering Dataset (SQuAD) is a reading comprehension dataset, consisting of questions posed by\ncrowdworkers on a set of Wikipedia articles, where the answer to every question is a segment of text, or span,\nfrom the corresponding reading passage, or the question might be unanswerable.\n\nSQuAD2.0 combines the 100,000 questions in SQuAD1.1 with over 50,000 unanswerable questions\nwritten adversarially by crowdworkers to look similar to answerable ones.\nTo do well on SQuAD2.0, systems must not only answer questions when possible, but also\ndetermine when no answer is supported by the paragraph and abstain from answering.\n'

A__     :      Optional[int]             =			'\nComputes SQuAD v2 scores (F1 and EM).\nArgs:\n    predictions: List of triple for question-answers to score with the following elements:\n        - the question-answer \'id\' field as given in the references (see below)\n        - the text of the answer\n        - the probability that the question has no answer\n    references: List of question-answers dictionaries with the following key-values:\n            - \'id\': id of the question-answer pair (see above),\n            - \'answers\': a list of Dict {\'text\': text of the answer as a string}\n    no_answer_threshold: float\n        Probability threshold to decide that a question has no answer.\nReturns:\n    \'exact\': Exact match (the normalized answer exactly match the gold answer)\n    \'f1\': The F-score of predicted tokens versus the gold answer\n    \'total\': Number of score considered\n    \'HasAns_exact\': Exact match (the normalized answer exactly match the gold answer)\n    \'HasAns_f1\': The F-score of predicted tokens versus the gold answer\n    \'HasAns_total\': Number of score considered\n    \'NoAns_exact\': Exact match (the normalized answer exactly match the gold answer)\n    \'NoAns_f1\': The F-score of predicted tokens versus the gold answer\n    \'NoAns_total\': Number of score considered\n    \'best_exact\': Best exact match (with varying threshold)\n    \'best_exact_thresh\': No-answer probability threshold associated to the best exact match\n    \'best_f1\': Best F1 (with varying threshold)\n    \'best_f1_thresh\': No-answer probability threshold associated to the best F1\nExamples:\n\n    >>> predictions = [{\'prediction_text\': \'1976\', \'id\': \'56e10a3be3433e1400422b22\', \'no_answer_probability\': 0.}]\n    >>> references = [{\'answers\': {\'answer_start\': [97], \'text\': [\'1976\']}, \'id\': \'56e10a3be3433e1400422b22\'}]\n    >>> squad_v2_metric = datasets.load_metric("squad_v2")\n    >>> results = squad_v2_metric.compute(predictions=predictions, references=references)\n    >>> print(results)\n    {\'exact\': 100.0, \'f1\': 100.0, \'total\': 1, \'HasAns_exact\': 100.0, \'HasAns_f1\': 100.0, \'HasAns_total\': 1, \'best_exact\': 100.0, \'best_exact_thresh\': 0.0, \'best_f1\': 100.0, \'best_f1_thresh\': 0.0}\n'
@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION		,_KWARGS_DESCRIPTION     )
class 				_UpperCAmelCase (	datasets.Metric     ):

				"""simple docstring"""




				def     lowercase__       (					self						:   List[Any]  ):

								'''simple docstring'''
								return datasets.MetricInfo(
								    description=_DESCRIPTION,  citation=_CITATION,  inputs_description=_KWARGS_DESCRIPTION,  features=datasets.Features(
								        {
								            '''predictions''': {
								                '''id''': datasets.Value('''string'''  ),
								                '''prediction_text''': datasets.Value('''string'''  ),
								                '''no_answer_probability''': datasets.Value('''float32'''  ),
								            },
								            '''references''': {
								                '''id''': datasets.Value('''string'''  ),
								                '''answers''': datasets.features.Sequence(
								                    {'''text''': datasets.Value('''string'''  ), '''answer_start''': datasets.Value('''int32'''  )}  ),
								            },
								        }  ),  codebase_urls=['''https://rajpurkar.github.io/SQuAD-explorer/'''],  reference_urls=['''https://rajpurkar.github.io/SQuAD-explorer/'''],  )




				def     lowercase__       (					self						:   Union[str, Any],  lowerCamelCase						:   Optional[int],  lowerCamelCase						:   List[Any],  lowerCamelCase						:   Union[str, Any]=1.0  ):

								'''simple docstring'''
								lowercase__       			=      {p['''id''']: p['''no_answer_probability'''] for p in predictions}
								lowercase__       			=      [{'''paragraphs''': [{'''qas''': references}]}]
								lowercase__       			=      {p['''id''']: p['''prediction_text'''] for p in predictions}

								lowercase__       			=      make_qid_to_has_ans(lowerCamelCase  )  # maps qid to True/False
								lowercase__       			=      [k for k, v in qid_to_has_ans.items() if v]
								lowercase__       			=      [k for k, v in qid_to_has_ans.items() if not v]

								lowercase__			,						lowercase__       			=      get_raw_scores(lowerCamelCase,  lowerCamelCase  )
								lowercase__       			=      apply_no_ans_threshold(lowerCamelCase,  lowerCamelCase,  lowerCamelCase,  lowerCamelCase  )
								lowercase__       			=      apply_no_ans_threshold(lowerCamelCase,  lowerCamelCase,  lowerCamelCase,  lowerCamelCase  )
								lowercase__       			=      make_eval_dict(lowerCamelCase,  lowerCamelCase  )

								if has_ans_qids:
												lowercase__       			=      make_eval_dict(lowerCamelCase,  lowerCamelCase,  qid_list=lowerCamelCase  )
												merge_eval(lowerCamelCase,  lowerCamelCase,  '''HasAns'''  )
								if no_ans_qids:
												lowercase__       			=      make_eval_dict(lowerCamelCase,  lowerCamelCase,  qid_list=lowerCamelCase  )
												merge_eval(lowerCamelCase,  lowerCamelCase,  '''NoAns'''  )
								find_all_best_thresh(lowerCamelCase,  lowerCamelCase,  lowerCamelCase,  lowerCamelCase,  lowerCamelCase,  lowerCamelCase  )
								return dict(lowerCamelCase  )












import dataclasses
import enum
import functools
import math
import re

# The following script is adapted from the script of TaPas.
# Original: https://github.com/google-research/tapas/master/wikisql_utils.py
from typing import Any, List, Text


A__     :      Dict             =			'none'
A__     :      Optional[Any]             =			'none'






def   a      (						lowerCamelCase_		,       lowerCamelCase_    ):






				'''simple docstring'''
				lowercase__       			=      value.split(lowerCamelCase_    )
				return len(lowerCamelCase_    ) > 1 and any((len(lowerCamelCase_    ) == 3 for x in split)    )






def   a      (						lowerCamelCase_    ):






				'''simple docstring'''
				if isinstance(lowerCamelCase_		,       lowerCamelCase_    ):
								return value
				if isinstance(lowerCamelCase_		,       lowerCamelCase_    ):
								return float(lowerCamelCase_    )
				if not isinstance(lowerCamelCase_		,       lowerCamelCase_    ):
								raise ValueError('''Argument value is not a string. Can\'t parse it as float'''    )
				lowercase__       			=      value

				try:
								# Example: 1,000.7
								if "." in sanitized and "," in sanitized:
												return float(sanitized.replace(''','''		,       ''''''    )    )
								# 1,000
								if "," in sanitized and _split_thousands(''','''		,       lowerCamelCase_    ):
												return float(sanitized.replace(''','''		,       ''''''    )    )
								# 5,5556
								if "," in sanitized and sanitized.count(''','''    ) == 1 and not _split_thousands(''','''		,       lowerCamelCase_    ):
												return float(sanitized.replace(''','''		,       '''.'''    )    )
								# 0.0.0.1
								if sanitized.count('''.'''    ) > 1:
												return float(sanitized.replace('''.'''		,       ''''''    )    )
								# 0,0,0,1
								if sanitized.count(''','''    ) > 1:
												return float(sanitized.replace(''','''		,       ''''''    )    )
								return float(lowerCamelCase_    )
				except ValueError:
								# Avoid adding the sanitized value in the error message.
								raise ValueError('''Unable to convert value to float'''    )






def   a      (						lowerCamelCase_    ):






				'''simple docstring'''
				if answer is None:
								return None
				try:
								lowercase__       			=      convert_to_float(lowerCamelCase_    )
								if isinstance(lowerCamelCase_		,       lowerCamelCase_    ) and math.isnan(lowerCamelCase_    ):
												return None
								return value
				except ValueError:
								return answer.lower()


A__     :      Tuple             =			{
    'text': lambda x: x,
    'real': convert_to_float,
}
class 				_UpperCAmelCase (	enum.Enum     ):

				"""simple docstring"""




				lowercase__    							=	0
				lowercase__    							=	1
				lowercase__    							=	2
				lowercase__    							=	3
				lowercase__    							=	4
				lowercase__    							=	5



class 				_UpperCAmelCase (	enum.Enum     ):

				"""simple docstring"""




				lowercase__    							=	0
				lowercase__    							=	1
				lowercase__    							=	2



@dataclasses.dataclass
class 				_UpperCAmelCase :

				"""simple docstring"""




				lowercase__    							=	42
				lowercase__    							=	42
				lowercase__    							=	42



A__     :      str             =			re.compile(r'\w+|[^\w\s]+', re.UNICODE | re.MULTILINE | re.DOTALL)






def   a      (						lowerCamelCase_    ):






				'''simple docstring'''
				return list(_TOKENIZER.findall(x.lower()    )    )






def   a      (						lowerCamelCase_		,       lowerCamelCase_		,       lowerCamelCase_    ):






				'''simple docstring'''
				if operator == _Operator.EQUALS:
								return src == tgt
				elif operator == _Operator.GREATER:
								return src > tgt
				elif operator == _Operator.LESSER:
								return src < tgt
				raise ValueError(F"""Unknown operator: {operator}"""    )






def   a      (						lowerCamelCase_		,       lowerCamelCase_		,       lowerCamelCase_    ):






				'''simple docstring'''
				lowercase__       			=      table['''types''']
				return _TYPE_CONVERTER[types[column]](lowerCamelCase_    )






def   a      (						lowerCamelCase_    ):






				'''simple docstring'''
				return isinstance(lowerCamelCase_		,       lowerCamelCase_    )






def   a      (						lowerCamelCase_		,       lowerCamelCase_		,       lowerCamelCase_    ):






				'''simple docstring'''
				for cond in conditions:
								lowercase__       			=      row[cond.column]

								lowercase__       			=      _parse_value(lowerCamelCase_		,       cond.column		,       cond.cmp_value    )

								if _is_string(lowerCamelCase_    ) and _is_string(lowerCamelCase_    ):
												lowercase__       			=      _normalize_for_match(lowerCamelCase_    )
												lowercase__       			=      _normalize_for_match(lowerCamelCase_    )

								if not isinstance(lowerCamelCase_		,       type(lowerCamelCase_    )    ):
												raise ValueError('''Type difference {} != {}'''.format(type(lowerCamelCase_    )		,       type(lowerCamelCase_    )    )    )

								if not _compare(cond.operator		,       lowerCamelCase_		,       lowerCamelCase_    ):
												return False
				return True






def   a      (						lowerCamelCase_		,       lowerCamelCase_		,       lowerCamelCase_    ):






				'''simple docstring'''
				if not answer_coordinates:
								if aggregation_op == _Aggregation.COUNT:
												return 0.0
								else:
												return EMPTY_ANSWER_AGG

    # Count can support non numeric answers.
				if aggregation_op == _Aggregation.COUNT:
								return float(len(lowerCamelCase_    )    )

				# If we have just one answer, if float returns it or try a conversion.
				lowercase__       			=      [table['''rows'''][i][j] for (i, j) in answer_coordinates]
				if len(lowerCamelCase_    ) == 1:
								try:
												return convert_to_float(values[0]    )
								except ValueError as e:
												if aggregation_op != _Aggregation.NONE:
																raise e

				if aggregation_op == _Aggregation.NONE:
								return None

				# Other aggregation only support numeric values. Bail out if we have strings.
				if not all((isinstance(lowerCamelCase_		,       (int, float)    ) for v in values)    ):
								return None

				if aggregation_op == _Aggregation.SUM:
								return float(sum(lowerCamelCase_    )    )
				elif aggregation_op == _Aggregation.AVERAGE:
								return sum(lowerCamelCase_    ) / len(lowerCamelCase_    )
				else:
								raise ValueError(F"""Unknown aggregation: {aggregation_op}"""    )






def   a      (						lowerCamelCase_		,       lowerCamelCase_    ):






				'''simple docstring'''
				lowercase__       			=      sql_query['''agg''']
				if aggregation_op_index >= 3:
								lowercase__       			=      _Aggregation(lowerCamelCase_    )
				else:
								lowercase__       			=      _Aggregation.NONE

				lowercase__       			=      sql_query['''sel''']
				lowercase__       			=      [
				    _Condition(lowerCamelCase_		,       _Operator(lowerCamelCase_    )		,       lowerCamelCase_    )
				    for column, operator, cmp_value in zip(
				        sql_query['''conds''']['''column_index''']		,       sql_query['''conds''']['''operator_index''']		,       sql_query['''conds''']['''condition''']    )
				]

				lowercase__       			=      []
				for row in range(len(table['''rows''']    )    ):
								if _respect_conditions(lowerCamelCase_		,       table['''rows'''][row]		,       lowerCamelCase_    ):
												indices.append((row, target_column)    )

				if not indices:
								return [], aggregation_op

				if len(lowerCamelCase_    ) == 1:
								return indices, aggregation_op

				# Parsing of MIN/MAX.
				if aggregation_op_index in (1, 2):
								lowercase__       			=      {2: min, 1: max}
								lowercase__       			=      [(table['''rows'''][i][j], index) for index, (i, j) in enumerate(lowerCamelCase_    )]
								lowercase__       			=      functools.reduce(operators[sql_query['''agg''']]		,       lowerCamelCase_    )

								lowercase__       			=      [indices[reduced[1]]]
								return ret, _Aggregation.NONE

				return indices, aggregation_op






def   a      (						lowerCamelCase_		,       lowerCamelCase_		,       lowerCamelCase_    ):






				'''simple docstring'''
				if float_answer is not None:
								return [str(lowerCamelCase_    )]
				return [str(table['''real_rows'''][r][c]    ) for r, c in answer_coordinates]






def   a      (						lowerCamelCase_		,       lowerCamelCase_    ):






				'''simple docstring'''
				lowercase__			,						lowercase__       			=      _get_answer_coordinates(lowerCamelCase_		,       lowerCamelCase_    )
				lowercase__       			=      _get_float_answer(lowerCamelCase_		,       lowerCamelCase_		,       lowerCamelCase_    )
				lowercase__       			=      _get_answer_text(lowerCamelCase_		,       lowerCamelCase_		,       lowerCamelCase_    )
				# keep the original data the same with TaPas
				if len(lowerCamelCase_    ) == 0:
								lowercase__       			=      [EMPTY_ANSWER]
				return answer_text




