






"""simple docstring"""



class        __lowercase:






						def __init__(					self    ,						_SCREAMING_SNAKE_CASE)			->  str:




											"""simple docstring"""





											lowerCamelCase__				=val
											# Number of nodes in left subtree
											lowerCamelCase__				=0
											lowerCamelCase__				=None
											lowerCamelCase__				=None
											lowerCamelCase__				=None






						def 		lowerCAmelCase   (					self    ,						_SCREAMING_SNAKE_CASE)			->  Tuple:




											"""simple docstring"""





											assert self.left_tree_size == other.left_tree_size, "Unequal Sizes of Blocks"

											if self.val < other.val:
																lowerCamelCase__				=self.right
																lowerCamelCase__				=None
																if self.right:
																					lowerCamelCase__				=other
																lowerCamelCase__				=other
																lowerCamelCase__				=self.left_tree_size * 2 + 1
																return self
											else:
																lowerCamelCase__				=other.right
																lowerCamelCase__				=None
																if other.right:
																					lowerCamelCase__				=self
																lowerCamelCase__				=self
																lowerCamelCase__				=other.left_tree_size * 2 + 1
																return other




class        __lowercase:






						def __init__(					self    ,						_SCREAMING_SNAKE_CASE=None    ,						_SCREAMING_SNAKE_CASE=None    ,						_SCREAMING_SNAKE_CASE=0)			->  Union[str, Any]:




											"""simple docstring"""





											lowerCamelCase__				=heap_size
											lowerCamelCase__				=bottom_root
											lowerCamelCase__				=min_node






						def 		lowerCAmelCase   (					self    ,						_SCREAMING_SNAKE_CASE)			->  int:




											"""simple docstring"""





											if other.size == 0:
																return None
											if self.size == 0:
																lowerCamelCase__				=other.size
																lowerCamelCase__				=other.bottom_root
																lowerCamelCase__				=other.min_node
																return None
											# Update size
											lowerCamelCase__				=self.size + other.size

											# Update min.node
											if self.min_node.val > other.min_node.val:
																lowerCamelCase__				=other.min_node
											# Merge

											# Order roots by left_subtree_size
											lowerCamelCase__				=[]
											lowerCamelCase__				,     lowerCamelCase__				=self.bottom_root, other.bottom_root
											while i or j:
																if i and ((not j) or i.left_tree_size < j.left_tree_size):
																					combined_roots_list.append((i, True))
																					lowerCamelCase__				=i.parent
																else:
																					combined_roots_list.append((j, False))
																					lowerCamelCase__				=j.parent
        # Insert links between them
											for i in range(len(_SCREAMING_SNAKE_CASE) - 1):
																if combined_roots_list[i][1] != combined_roots_list[i + 1][1]:
																					lowerCamelCase__				=combined_roots_list[i + 1][0]
																					lowerCamelCase__				=combined_roots_list[i][0]
        # Consecutively merge roots with same left_tree_size
											lowerCamelCase__				=combined_roots_list[0][0]
											while i.parent:
																if (
																    (i.left_tree_size == i.parent.left_tree_size) and (not i.parent.parent)
																) or (
																    i.left_tree_size == i.parent.left_tree_size
																    and i.left_tree_size != i.parent.parent.left_tree_size
																):
																					# Neighbouring Nodes
																					lowerCamelCase__				=i.left
																					lowerCamelCase__				=i.parent.parent

																					# Merging trees
																					lowerCamelCase__				=i.merge_trees(i.parent)

																					# Updating links
																					lowerCamelCase__				=previous_node
																					lowerCamelCase__				=next_node
																					if previous_node:
																										lowerCamelCase__				=i
																					if next_node:
																										lowerCamelCase__				=i
																else:
																					lowerCamelCase__				=i.parent
        # Updating self.bottom_root
											while i.left:
																lowerCamelCase__				=i.left
											lowerCamelCase__				=i

											# Update other
											lowerCamelCase__				=self.size
											lowerCamelCase__				=self.bottom_root
											lowerCamelCase__				=self.min_node

											# Return the merged heap
											return self






						def 		lowerCAmelCase   (					self    ,						_SCREAMING_SNAKE_CASE)			->  Any:




											"""simple docstring"""





											if self.size == 0:
																lowerCamelCase__				=Node(_SCREAMING_SNAKE_CASE)
																lowerCamelCase__				=1
																lowerCamelCase__				=self.bottom_root
											else:
																# Create new node
																lowerCamelCase__				=Node(_SCREAMING_SNAKE_CASE)

																# Update size
																self.size += 1

																# update min_node
																if val < self.min_node.val:
																					lowerCamelCase__				=new_node
																# Put new_node as a bottom_root in heap
																lowerCamelCase__				=new_node
																lowerCamelCase__				=self.bottom_root
																lowerCamelCase__				=new_node

																# Consecutively merge roots with same left_tree_size
																while (
																    self.bottom_root.parent
																    and self.bottom_root.left_tree_size
																    == self.bottom_root.parent.left_tree_size
																):
																					# Next node
																					lowerCamelCase__				=self.bottom_root.parent.parent

																					# Merge
																					lowerCamelCase__				=self.bottom_root.merge_trees(self.bottom_root.parent)

																					# Update Links
																					lowerCamelCase__				=next_node
																					lowerCamelCase__				=None
																					if next_node:
																										lowerCamelCase__				=self.bottom_root






						def 		lowerCAmelCase   (					self)			->  Any:




											"""simple docstring"""





											return self.min_node.val






						def 		lowerCAmelCase   (					self)			->  List[Any]:




											"""simple docstring"""





											return self.size == 0






						def 		lowerCAmelCase   (					self)			->  Any:




											"""simple docstring"""





											lowerCamelCase__				=self.min_node.val

											# Last element in heap corner case
											if self.size == 1:
																# Update size
																lowerCamelCase__				=0

																# Update bottom root
																lowerCamelCase__				=None

																# Update min_node
																lowerCamelCase__				=None

																return min_value
											# No right subtree corner case
											# The structure of the tree implies that this should be the bottom root
											# and there is at least one other root
											if self.min_node.right is None:
																# Update size
																self.size -= 1

																# Update bottom root
																lowerCamelCase__				=self.bottom_root.parent
																lowerCamelCase__				=None

																# Update min_node
																lowerCamelCase__				=self.bottom_root
																lowerCamelCase__				=self.bottom_root.parent
																while i:
																					if i.val < self.min_node.val:
																										lowerCamelCase__				=i
																					lowerCamelCase__				=i.parent
																return min_value
											# General case
											# Find the BinomialHeap of the right subtree of min_node
											lowerCamelCase__				=self.min_node.right
											lowerCamelCase__				=None
											lowerCamelCase__				=bottom_of_new
											lowerCamelCase__				=1

											# Size, min_node and bottom_root
											while bottom_of_new.left:
																lowerCamelCase__				=size_of_new * 2 + 1
																lowerCamelCase__				=bottom_of_new.left
																if bottom_of_new.val < min_of_new.val:
																					lowerCamelCase__				=bottom_of_new
        # Corner case of single root on top left path
											if (not self.min_node.left) and (not self.min_node.parent):
																lowerCamelCase__				=size_of_new
																lowerCamelCase__				=bottom_of_new
																lowerCamelCase__				=min_of_new
																# print("Single root, multiple nodes case")
																return min_value
											# Remaining cases
											# Construct heap of right subtree
											lowerCamelCase__				=BinomialHeap(
											    bottom_root=_SCREAMING_SNAKE_CASE    ,						min_node=_SCREAMING_SNAKE_CASE    ,						heap_size=_SCREAMING_SNAKE_CASE)

											# Update size
											lowerCamelCase__				=self.size - 1 - size_of_new

											# Neighbour nodes
											lowerCamelCase__				=self.min_node.left
											lowerCamelCase__				=self.min_node.parent

											# Initialize new bottom_root and min_node
											lowerCamelCase__				=previous_node or next_node
											lowerCamelCase__				=next_node

											# Update links of previous_node and search below for new min_node and
											# bottom_root
											if previous_node:
																lowerCamelCase__				=next_node

																# Update bottom_root and search for min_node below
																lowerCamelCase__				=previous_node
																lowerCamelCase__				=previous_node
																while self.bottom_root.left:
																					lowerCamelCase__				=self.bottom_root.left
																					if self.bottom_root.val < self.min_node.val:
																										lowerCamelCase__				=self.bottom_root
											if next_node:
																lowerCamelCase__				=previous_node

																# Search for new min_node above min_node
																lowerCamelCase__				=next_node
																while i:
																					if i.val < self.min_node.val:
																										lowerCamelCase__				=i
																					lowerCamelCase__				=i.parent
        # Merge heaps
											self.merge_heaps(_SCREAMING_SNAKE_CASE)

											return min_value






						def 		lowerCAmelCase   (					self)			->  List[str]:




											"""simple docstring"""





											lowerCamelCase__				=self.bottom_root
											while top_root.parent:
																lowerCamelCase__				=top_root.parent
											# preorder
											lowerCamelCase__				=[]
											self.__traversal(_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE)
											return heap_pre_order






						def 		lowerCAmelCase   (					self    ,						_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE=0)			->  List[Any]:




											"""simple docstring"""





											if curr_node:
																preorder.append((curr_node.val, level))
																self.__traversal(curr_node.left    ,						_SCREAMING_SNAKE_CASE    ,						level + 1)
																self.__traversal(curr_node.right    ,						_SCREAMING_SNAKE_CASE    ,						level + 1)
											else:
																preorder.append(('#', level))






						def __str__(					self)			->  Union[str, Any]:




											"""simple docstring"""





											if self.is_empty():
																return ""
											lowerCamelCase__				=self.pre_order()

											return "\n".join(('-' * level + str(_SCREAMING_SNAKE_CASE)) for value, level in preorder_heap)


# Unit Tests
if __name__ == "__main__":
						import doctest

						doctest.testmod()







"""simple docstring"""



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,
)


_snake_case       :      Dict       =					"\\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"

_snake_case       :      List[str]       =					"\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"

_snake_case       :      Dict       =					"\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        __lowercase(       datasets.Metric  ):






						def 		lowerCAmelCase   (					self)			->  int:




											"""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 		lowerCAmelCase   (					self    ,						_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE=1.0)			->  Optional[int]:




											"""simple docstring"""





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

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

											lowerCamelCase__				,     lowerCamelCase__				=get_raw_scores(_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE)
											lowerCamelCase__				=apply_no_ans_threshold(_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE)
											lowerCamelCase__				=apply_no_ans_threshold(_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE)
											lowerCamelCase__				=make_eval_dict(_SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE)

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