

import argparse
import collections
import json
import os
import re
import string
import sys

import numpy as np


_UpperCAmelCase						:  Tuple									=			re.compile(R"""\b(a|an|the)\b""", re.UNICODE)

_UpperCAmelCase						:  List[str]									=			None





def    __lowerCamelCase      (					):







							'''simple docstring'''






							snake_case_     							=       argparse.ArgumentParser('Official evaluation script for SQuAD version 2.0.' )
							parser.add_argument('data_file'  ,				metavar='data.json'  ,				help='Input data JSON file.' )
							parser.add_argument('pred_file'  ,				metavar='pred.json'  ,				help='Model predictions.' )
							parser.add_argument(
							    '--out-file'  ,				'-o'  ,				metavar='eval.json'  ,				help='Write accuracy metrics to file (default is stdout).' )
							parser.add_argument(
							    '--na-prob-file'  ,				'-n'  ,				metavar='na_prob.json'  ,				help='Model estimates of probability of no answer.' )
							parser.add_argument(
							    '--na-prob-thresh'  ,				'-t'  ,				type=lowerCAmelCase__  ,				default=1.0  ,				help='Predict \"\" if no-answer probability exceeds this (default = 1.0).'  ,				)
							parser.add_argument(
							    '--out-image-dir'  ,				'-p'  ,				metavar='out_images'  ,				default=lowerCAmelCase__  ,				help='Save precision-recall curves to directory.' )
							parser.add_argument('--verbose'  ,				'-v'  ,				action='store_true' )
							if len(sys.argv ) == 1:
														parser.print_help()
														sys.exit(1 )
							return parser.parse_args()





def    __lowerCamelCase      (					UpperCamelCase__ ):







							'''simple docstring'''






							snake_case_     							=       {}
							for article in dataset:
														for p in article["paragraphs"]:
																					for qa in p["qas"]:
																												snake_case_     							=       bool(qa['answers']['text'] )
							return qid_to_has_ans





def    __lowerCamelCase      (					UpperCamelCase__ ):







							'''simple docstring'''






							def remove_articles(UpperCamelCase__ ):
														return ARTICLES_REGEX.sub(' '  ,				lowerCAmelCase__ )

							def white_space_fix(UpperCamelCase__ ):
														return " ".join(text.split() )

							def remove_punc(UpperCamelCase__ ):
														snake_case_     							=       set(string.punctuation )
														return "".join(ch for ch in text if ch not in exclude )

							def lower(UpperCamelCase__ ):
														return text.lower()

							return white_space_fix(remove_articles(remove_punc(lower(lowerCAmelCase__ ) ) ) )





def    __lowerCamelCase      (					UpperCamelCase__ ):







							'''simple docstring'''






							if not s:
														return []
							return normalize_answer(lowerCAmelCase__ ).split()





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__ ):







							'''simple docstring'''






							return int(normalize_answer(lowerCAmelCase__ ) == normalize_answer(lowerCAmelCase__ ) )





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__ ):







							'''simple docstring'''






							snake_case_     							=       get_tokens(lowerCAmelCase__ )
							snake_case_     							=       get_tokens(lowerCAmelCase__ )
							snake_case_     							=       collections.Counter(lowerCAmelCase__ ) & collections.Counter(lowerCAmelCase__ )
							snake_case_     							=       sum(common.values() )
							if len(lowerCAmelCase__ ) == 0 or len(lowerCAmelCase__ ) == 0:
														# If either is no-answer, then F1 is 1 if they agree, 0 otherwise
														return int(gold_toks == pred_toks )
							if num_same == 0:
														return 0
							snake_case_     							=       1.0 * num_same / len(lowerCAmelCase__ )
							snake_case_     							=       1.0 * num_same / len(lowerCAmelCase__ )
							snake_case_     							=       (2 * precision * recall) / (precision + recall)
							return fa





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__ ):







							'''simple docstring'''






							snake_case_     							=       {}
							snake_case_     							=       {}
							for article in dataset:
														for p in article["paragraphs"]:
																					for qa in p["qas"]:
																												snake_case_     							=       qa['id']
																												snake_case_     							=       [t for t in qa['answers']['text'] if normalize_answer(lowerCAmelCase__ )]
																												if not gold_answers:
																																			# For unanswerable questions, only correct answer is empty string
																																			snake_case_     							=       ['']
																												if qid not in preds:
																																			print(F'''Missing prediction for {qid}''' )
																																			continue
																												snake_case_     							=       preds[qid]
																												# Take max over all gold answers
																												snake_case_     							=       max(compute_exact(lowerCAmelCase__  ,				lowerCAmelCase__ ) for a in gold_answers )
																												snake_case_     							=       max(compute_fa(lowerCAmelCase__  ,				lowerCAmelCase__ ) for a in gold_answers )
							return exact_scores, fa_scores





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__ ):







							'''simple docstring'''






							snake_case_     							=       {}
							for qid, s in scores.items():
														snake_case_     							=       na_probs[qid] > na_prob_thresh
														if pred_na:
																					snake_case_     							=       float(not qid_to_has_ans[qid] )
														else:
																					snake_case_     							=       s
							return new_scores





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__=None ):







							'''simple docstring'''






							if not qid_list:
														snake_case_     							=       len(lowerCAmelCase__ )
														return collections.OrderedDict(
														    [
														        ('exact', 1_00.0 * sum(exact_scores.values() ) / total),
														        ('f1', 1_00.0 * sum(fa_scores.values() ) / total),
														        ('total', total),
														    ] )
							else:
														snake_case_     							=       len(lowerCAmelCase__ )
														return collections.OrderedDict(
														    [
														        ('exact', 1_00.0 * sum(exact_scores[k] for k in qid_list ) / total),
														        ('f1', 1_00.0 * sum(fa_scores[k] for k in qid_list ) / total),
														        ('total', total),
														    ] )





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__ ):







							'''simple docstring'''






							for k in new_eval:
														snake_case_     							=       new_eval[k]





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__ ):







							'''simple docstring'''






							plt.step(lowerCAmelCase__  ,				lowerCAmelCase__  ,				color='b'  ,				alpha=0.2  ,				where='post' )
							plt.fill_between(lowerCAmelCase__  ,				lowerCAmelCase__  ,				step='post'  ,				alpha=0.2  ,				color='b' )
							plt.xlabel('Recall' )
							plt.ylabel('Precision' )
							plt.xlim([0.0, 1.05] )
							plt.ylim([0.0, 1.05] )
							plt.title(lowerCAmelCase__ )
							plt.savefig(lowerCAmelCase__ )
							plt.clf()





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__=None  ,				UpperCamelCase__=None ):







							'''simple docstring'''






							snake_case_     							=       sorted(lowerCAmelCase__  ,				key=lambda UpperCamelCase__ : na_probs[k] )
							snake_case_     							=       0.0
							snake_case_     							=       1.0
							snake_case_     							=       0.0
							snake_case_     							=       [1.0]
							snake_case_     							=       [0.0]
							snake_case_     							=       0.0
							for i, qid in enumerate(lowerCAmelCase__ ):
														if qid_to_has_ans[qid]:
																					true_pos += scores[qid]
														snake_case_     							=       true_pos / float(i + 1 )
														snake_case_     							=       true_pos / float(lowerCAmelCase__ )
														if i == len(lowerCAmelCase__ ) - 1 or na_probs[qid] != na_probs[qid_list[i + 1]]:
																					# i.e., if we can put a threshold after this point
																					avg_prec += cur_p * (cur_r - recalls[-1])
																					precisions.append(lowerCAmelCase__ )
																					recalls.append(lowerCAmelCase__ )
							if out_image:
														plot_pr_curve(lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__ )
							return {"ap": 1_00.0 * avg_prec}





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__ ):







							'''simple docstring'''






							if out_image_dir and not os.path.exists(lowerCAmelCase__ ):
														os.makedirs(lowerCAmelCase__ )
							snake_case_     							=       sum(1 for v in qid_to_has_ans.values() if v )
							if num_true_pos == 0:
														return
							snake_case_     							=       make_precision_recall_eval(
							    lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				out_image=os.path.join(lowerCAmelCase__  ,				'pr_exact.png' )  ,				title='Precision-Recall curve for Exact Match score'  ,				)
							snake_case_     							=       make_precision_recall_eval(
							    lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				out_image=os.path.join(lowerCAmelCase__  ,				'pr_f1.png' )  ,				title='Precision-Recall curve for F1 score'  ,				)
							snake_case_     							=       {k: float(lowerCAmelCase__ ) for k, v in qid_to_has_ans.items()}
							snake_case_     							=       make_precision_recall_eval(
							    lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				out_image=os.path.join(lowerCAmelCase__  ,				'pr_oracle.png' )  ,				title='Oracle Precision-Recall curve (binary task of HasAns vs. NoAns)'  ,				)
							merge_eval(lowerCAmelCase__  ,				lowerCAmelCase__  ,				'pr_exact' )
							merge_eval(lowerCAmelCase__  ,				lowerCAmelCase__  ,				'pr_f1' )
							merge_eval(lowerCAmelCase__  ,				lowerCAmelCase__  ,				'pr_oracle' )





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__ ):







							'''simple docstring'''






							if not qid_list:
														return
							snake_case_     							=       [na_probs[k] for k in qid_list]
							snake_case_     							=       np.ones_like(lowerCAmelCase__ ) / float(len(lowerCAmelCase__ ) )
							plt.hist(lowerCAmelCase__  ,				weights=lowerCAmelCase__  ,				bins=20  ,				range=(0.0, 1.0) )
							plt.xlabel('Model probability of no-answer' )
							plt.ylabel('Proportion of dataset' )
							plt.title(F'''Histogram of no-answer probability: {name}''' )
							plt.savefig(os.path.join(lowerCAmelCase__  ,				F'''na_prob_hist_{name}.png''' ) )
							plt.clf()





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__ ):







							'''simple docstring'''






							snake_case_     							=       sum(1 for k in qid_to_has_ans if not qid_to_has_ans[k] )
							snake_case_     							=       num_no_ans
							snake_case_     							=       cur_score
							snake_case_     							=       0.0
							snake_case_     							=       sorted(lowerCAmelCase__  ,				key=lambda UpperCamelCase__ : na_probs[k] )
							for i, qid in enumerate(lowerCAmelCase__ ):
														if qid not in scores:
																					continue
														if qid_to_has_ans[qid]:
																					snake_case_     							=       scores[qid]
														else:
																					if preds[qid]:
																												snake_case_     							=       -1
																					else:
																												snake_case_     							=       0
														cur_score += diff
														if cur_score > best_score:
																					snake_case_     							=       cur_score
																					snake_case_     							=       na_probs[qid]
							return 1_00.0 * best_score / len(lowerCAmelCase__ ), best_thresh





def    __lowerCamelCase      (					UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__  ,				UpperCamelCase__ ):







							'''simple docstring'''






							snake_case_							,       snake_case_     							=       find_best_thresh(lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__ )
							snake_case_							,       snake_case_     							=       find_best_thresh(lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__ )
							snake_case_     							=       best_exact
							snake_case_     							=       exact_thresh
							snake_case_     							=       best_fa
							snake_case_     							=       fa_thresh





def    __lowerCamelCase      (					):







							'''simple docstring'''






							with open(OPTS.data_file ) as f:
														snake_case_     							=       json.load(lowerCAmelCase__ )
														snake_case_     							=       dataset_json['data']
							with open(OPTS.pred_file ) as f:
														snake_case_     							=       json.load(lowerCAmelCase__ )
							if OPTS.na_prob_file:
														with open(OPTS.na_prob_file ) as f:
																					snake_case_     							=       json.load(lowerCAmelCase__ )
							else:
														snake_case_     							=       {k: 0.0 for k in preds}
							snake_case_     							=       make_qid_to_has_ans(lowerCAmelCase__ )  # maps qid to True/False
							snake_case_     							=       [k for k, v in qid_to_has_ans.items() if v]
							snake_case_     							=       [k for k, v in qid_to_has_ans.items() if not v]
							snake_case_							,       snake_case_     							=       get_raw_scores(lowerCAmelCase__  ,				lowerCAmelCase__ )
							snake_case_     							=       apply_no_ans_threshold(lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				OPTS.na_prob_thresh )
							snake_case_     							=       apply_no_ans_threshold(lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				OPTS.na_prob_thresh )
							snake_case_     							=       make_eval_dict(lowerCAmelCase__  ,				lowerCAmelCase__ )
							if has_ans_qids:
														snake_case_     							=       make_eval_dict(lowerCAmelCase__  ,				lowerCAmelCase__  ,				qid_list=lowerCAmelCase__ )
														merge_eval(lowerCAmelCase__  ,				lowerCAmelCase__  ,				'HasAns' )
							if no_ans_qids:
														snake_case_     							=       make_eval_dict(lowerCAmelCase__  ,				lowerCAmelCase__  ,				qid_list=lowerCAmelCase__ )
														merge_eval(lowerCAmelCase__  ,				lowerCAmelCase__  ,				'NoAns' )
							if OPTS.na_prob_file:
														find_all_best_thresh(lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__ )
							if OPTS.na_prob_file and OPTS.out_image_dir:
														run_precision_recall_analysis(lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				lowerCAmelCase__  ,				OPTS.out_image_dir )
														histogram_na_prob(lowerCAmelCase__  ,				lowerCAmelCase__  ,				OPTS.out_image_dir  ,				'hasAns' )
														histogram_na_prob(lowerCAmelCase__  ,				lowerCAmelCase__  ,				OPTS.out_image_dir  ,				'noAns' )
							if OPTS.out_file:
														with open(OPTS.out_file  ,				'w' ) as f:
																					json.dump(lowerCAmelCase__  ,				lowerCAmelCase__ )
							else:
														print(json.dumps(lowerCAmelCase__  ,				indent=2 ) )


if __name__ == "__main__":
					_UpperCAmelCase						:  str									=			parse_args()
					if OPTS.out_image_dir:
										import matplotlib

										matplotlib.use("""Agg""")
										import matplotlib.pyplot as plt
					main()





"""simple docstring"""






import os
from shutil import copyfile
from typing import Any, Dict, List, Optional, Tuple

import sentencepiece as spm

from ...tokenization_utils import AddedToken, PreTrainedTokenizer
from ...utils import logging


__lowerCAmelCase       :			List[str]   	=logging.get_logger(__name__)

__lowerCAmelCase       :			str   	={"""vocab_file""": """sentencepiece.bpe.model"""}

__lowerCAmelCase       :			Dict   	={
    """vocab_file""": {
        """moussaKam/mbarthez""": """https://huggingface.co/moussaKam/mbarthez/resolve/main/sentencepiece.bpe.model""",
        """moussaKam/barthez""": """https://huggingface.co/moussaKam/barthez/resolve/main/sentencepiece.bpe.model""",
        """moussaKam/barthez-orangesum-title""": (
            """https://huggingface.co/moussaKam/barthez-orangesum-title/resolve/main/sentencepiece.bpe.model"""
        ),
    },
}

__lowerCAmelCase       :			Tuple   	={
    """moussaKam/mbarthez""": 1_0_2_4,
    """moussaKam/barthez""": 1_0_2_4,
    """moussaKam/barthez-orangesum-title""": 1_0_2_4,
}

__lowerCAmelCase       :			Optional[int]   	="""▁"""





class 					_A		(			lowerCAmelCase      ):
      snake_case__     :  Tuple				    =      VOCAB_FILES_NAMES
      snake_case__     :  Optional[Any]				    =      PRETRAINED_VOCAB_FILES_MAP
      snake_case__     :  Dict				    =      PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
      snake_case__     :  Optional[Any]				    =      ['input_ids', 'attention_mask']

      def __init__(		self						,			__lowerCAmelCase						,			__lowerCAmelCase="<s>"						,			__lowerCAmelCase="</s>"						,			__lowerCAmelCase="</s>"						,			__lowerCAmelCase="<s>"						,			__lowerCAmelCase="<unk>"						,			__lowerCAmelCase="<pad>"						,			__lowerCAmelCase="<mask>"						,			__lowerCAmelCase = None						,			**__lowerCAmelCase						,			):







            """simple docstring"""



            lowercase								=      AddedToken(__lowerCAmelCase						,			lstrip=__lowerCAmelCase						,			rstrip=__lowerCAmelCase		) if isinstance(__lowerCAmelCase						,			__lowerCAmelCase		) else mask_token

            lowercase								=      {} if sp_model_kwargs is None else sp_model_kwargs

            super().__init__(
                bos_token=__lowerCAmelCase						,			eos_token=__lowerCAmelCase						,			unk_token=__lowerCAmelCase						,			sep_token=__lowerCAmelCase						,			cls_token=__lowerCAmelCase						,			pad_token=__lowerCAmelCase						,			mask_token=__lowerCAmelCase						,			sp_model_kwargs=self.sp_model_kwargs						,			**__lowerCAmelCase						,			)

            lowercase								=      vocab_file
            lowercase								=      spm.SentencePieceProcessor(**self.sp_model_kwargs		)
            self.sp_model.Load(str(__lowerCAmelCase		)		)

            lowercase								=      {"""<s>""": 0, """<pad>""": 1, """</s>""": 2, """<unk>""": 3}

            lowercase								=      len(self.sp_model		) - 1
            lowercase								=      {v: k for k, v in self.fairseq_tokens_to_ids.items()}

      def 							A__			(		self						,			__lowerCAmelCase						,			__lowerCAmelCase = None		):







            """simple docstring"""



            if token_ids_a is None:
                  return [self.cls_token_id] + token_ids_a + [self.sep_token_id]
            lowercase								=      [self.cls_token_id]
            lowercase								=      [self.sep_token_id]
            return cls + token_ids_a + sep + sep + token_ids_a + sep

      def 							A__			(		self						,			__lowerCAmelCase						,			__lowerCAmelCase = None						,			__lowerCAmelCase = False		):







            """simple docstring"""



            if already_has_special_tokens:
                  return super().get_special_tokens_mask(
                      token_ids_a=__lowerCAmelCase						,			token_ids_a=__lowerCAmelCase						,			already_has_special_tokens=__lowerCAmelCase		)

            if token_ids_a is None:
                  return [1] + ([0] * len(__lowerCAmelCase		)) + [1]
            return [1] + ([0] * len(__lowerCAmelCase		)) + [1, 1] + ([0] * len(__lowerCAmelCase		)) + [1]

      def 							A__			(		self						,			__lowerCAmelCase						,			__lowerCAmelCase = None		):







            """simple docstring"""



            lowercase								=      [self.sep_token_id]
            lowercase								=      [self.cls_token_id]

            if token_ids_a is None:
                  return len(cls + token_ids_a + sep		) * [0]
            return len(cls + token_ids_a + sep + sep + token_ids_a + sep		) * [0]

      @property
      def 							A__			(		self		):







            """simple docstring"""



            return len(self.sp_model		)

      def 							A__			(		self		):







            """simple docstring"""



            lowercase								=      {self.convert_ids_to_tokens(__lowerCAmelCase		): i for i in range(self.vocab_size		)}
            vocab.update(self.added_tokens_encoder		)
            return vocab

      def 							A__			(		self						,			__lowerCAmelCase		):







            """simple docstring"""



            return self.sp_model.encode(__lowerCAmelCase						,			out_type=__lowerCAmelCase		)

      def 							A__			(		self						,			__lowerCAmelCase		):







            """simple docstring"""



            if token in self.fairseq_tokens_to_ids:
                  return self.fairseq_tokens_to_ids[token]
            lowercase								=      self.sp_model.PieceToId(__lowerCAmelCase		)

            return spm_id if spm_id else self.unk_token_id

      def 							A__			(		self						,			__lowerCAmelCase		):







            """simple docstring"""



            if index in self.fairseq_ids_to_tokens:
                  return self.fairseq_ids_to_tokens[index]
            return self.sp_model.IdToPiece(__lowerCAmelCase		)

      def 							A__			(		self						,			__lowerCAmelCase		):







            """simple docstring"""



            lowercase								=      []
            lowercase								=      """"""
            lowercase								=      False
            for token in tokens:
                  # make sure that special tokens are not decoded using sentencepiece model
                  if token in self.all_special_tokens:
                        if not prev_is_special:
                              out_string += " "
                        out_string += self.sp_model.decode(__lowerCAmelCase		) + token
                        lowercase								=      True
                        lowercase								=      []
                  else:
                        current_sub_tokens.append(__lowerCAmelCase		)
                        lowercase								=      False
            out_string += self.sp_model.decode(__lowerCAmelCase		)
            return out_string.strip()

      def __getstate__(		self		):







            """simple docstring"""



            lowercase								=      self.__dict__.copy()
            lowercase								=      None
            return state

      def __setstate__(		self						,			__lowerCAmelCase		):







            """simple docstring"""



            lowercase								=      d

            # for backward compatibility
            if not hasattr(self						,			"""sp_model_kwargs"""		):
                  lowercase								=      {}

            lowercase								=      spm.SentencePieceProcessor(**self.sp_model_kwargs		)
            self.sp_model.Load(self.vocab_file		)







      def 							A__			(		self						,			__lowerCAmelCase						,			__lowerCAmelCase = None		):







            """simple docstring"""



            if not os.path.isdir(__lowerCAmelCase		):
                  logger.error(f'Vocabulary path ({save_directory}) should be a directory'		)
                  return
            lowercase								=      os.path.join(
                __lowerCAmelCase						,			(filename_prefix + """-""" if filename_prefix else """""") + VOCAB_FILES_NAMES["""vocab_file"""]		)

            if os.path.abspath(self.vocab_file		) != os.path.abspath(__lowerCAmelCase		) and os.path.isfile(self.vocab_file		):
                  copyfile(self.vocab_file						,			__lowerCAmelCase		)
            elif not os.path.isfile(self.vocab_file		):
                  with open(__lowerCAmelCase						,			"""wb"""		) as fi:
                        lowercase								=      self.sp_model.serialized_model_proto()
                        fi.write(__lowerCAmelCase		)

            return (out_vocab_file,)



