






"""simple docstring"""


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

import numpy as np


_UpperCamelCase    :   Optional[Any]   			=						re.compile(r'\b(a|an|the)\b', re.UNICODE)

_UpperCamelCase    :   str   			=						None




def       snake_case  ():







  '''simple docstring'''

  a					:      Any    =       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=A_     ,      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=A_     ,      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       snake_case  (A_				:Optional[int]				):







  '''simple docstring'''

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




def       snake_case  (A_				:List[Any]				):







  '''simple docstring'''

  def remove_articles(A_				:str				):
    return ARTICLES_REGEX.sub(' '     ,      A_				)

  def white_space_fix(A_				:str				):
    return " ".join(text.split()				)

  def remove_punc(A_				:Dict				):
    a					:      int    =       set(string.punctuation				)
    return "".join(ch for ch in text if ch not in exclude				)

  def lower(A_				:Union[str, Any]				):
    return text.lower()

  return white_space_fix(remove_articles(remove_punc(lower(A_				)				)				)				)




def       snake_case  (A_				:str				):







  '''simple docstring'''

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




def       snake_case  (A_				:int     ,      A_				:Union[str, Any]				):







  '''simple docstring'''

  return int(normalize_answer(A_				) == normalize_answer(A_				)				)




def       snake_case  (A_				:Optional[int]     ,      A_				:str				):







  '''simple docstring'''

  a					:      int    =       get_tokens(A_				)
  a					:      Tuple    =       get_tokens(A_				)
  a					:      List[Any]    =       collections.Counter(A_				) & collections.Counter(A_				)
  a					:      Dict    =       sum(common.values()				)
  if len(A_				) == 0 or len(A_				) == 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
  a					:      List[Any]    =       1.0 * num_same / len(A_				)
  a					:      Optional[Any]    =       1.0 * num_same / len(A_				)
  a					:      Union[str, Any]    =       (2 * precision * recall) / (precision + recall)
  return fa




def       snake_case  (A_				:Any     ,      A_				:Dict				):







  '''simple docstring'''

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




def       snake_case  (A_				:Union[str, Any]     ,      A_				:List[Any]     ,      A_				:List[Any]     ,      A_				:Dict				):







  '''simple docstring'''

  a					:      List[str]    =       {}
  for qid, s in scores.items():
    a					:      Union[str, Any]    =       na_probs[qid] > na_prob_thresh
    if pred_na:
      a					:      int    =       float(not qid_to_has_ans[qid]				)
    else:
      a					:      Union[str, Any]    =       s
  return new_scores




def       snake_case  (A_				:Tuple     ,      A_				:int     ,      A_				:Tuple=None				):







  '''simple docstring'''

  if not qid_list:
    a					:      Optional[int]    =       len(A_				)
    return collections.OrderedDict(
        [
            ('exact', 100.0 * sum(exact_scores.values()				) / total),
            ('f1', 100.0 * sum(fa_scores.values()				) / total),
            ('total', total),
        ]				)
  else:
    a					:      List[Any]    =       len(A_				)
    return collections.OrderedDict(
        [
            ('exact', 100.0 * sum(exact_scores[k] for k in qid_list				) / total),
            ('f1', 100.0 * sum(fa_scores[k] for k in qid_list				) / total),
            ('total', total),
        ]				)




def       snake_case  (A_				:str     ,      A_				:Dict     ,      A_				:List[Any]				):







  '''simple docstring'''

  for k in new_eval:
    a					:      Union[str, Any]    =       new_eval[k]




def       snake_case  (A_				:Optional[Any]     ,      A_				:Any     ,      A_				:Dict     ,      A_				:Optional[int]				):







  '''simple docstring'''

  plt.step(A_     ,      A_     ,      color='b'     ,      alpha=0.2     ,      where='post'				)
  plt.fill_between(A_     ,      A_     ,      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(A_				)
  plt.savefig(A_				)
  plt.clf()




def       snake_case  (A_				:List[str]     ,      A_				:str     ,      A_				:Any     ,      A_				:Any     ,      A_				:List[Any]=None     ,      A_				:Union[str, Any]=None				):







  '''simple docstring'''

  a					:      Optional[int]    =       sorted(A_     ,      key=lambda A_				: na_probs[k]				)
  a					:      Tuple    =       0.0
  a					:      Tuple    =       1.0
  a					:      Any    =       0.0
  a					:      int    =       [1.0]
  a					:      int    =       [0.0]
  a					:      str    =       0.0
  for i, qid in enumerate(A_				):
    if qid_to_has_ans[qid]:
      true_pos += scores[qid]
    a					:      Tuple    =       true_pos / float(i + 1				)
    a					:      Any    =       true_pos / float(A_				)
    if i == len(A_				) - 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(A_				)
      recalls.append(A_				)
  if out_image:
    plot_pr_curve(A_     ,      A_     ,      A_     ,      A_				)
  return {"ap": 100.0 * avg_prec}




def       snake_case  (A_				:Optional[int]     ,      A_				:Any     ,      A_				:List[Any]     ,      A_				:int     ,      A_				:int     ,      A_				:List[str]				):







  '''simple docstring'''

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




def       snake_case  (A_				:List[str]     ,      A_				:List[str]     ,      A_				:List[Any]     ,      A_				:str				):







  '''simple docstring'''

  if not qid_list:
    return
  a					:      List[Any]    =       [na_probs[k] for k in qid_list]
  a					:      List[str]    =       np.ones_like(A_				) / float(len(A_				)				)
  plt.hist(A_     ,      weights=A_     ,      bins=2_0     ,      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(A_     ,      f'''na_prob_hist_{name}.png'''				)				)
  plt.clf()




def       snake_case  (A_				:Tuple     ,      A_				:Tuple     ,      A_				:List[str]     ,      A_				:List[str]				):







  '''simple docstring'''

  a					:      Any    =       sum(1 for k in qid_to_has_ans if not qid_to_has_ans[k]				)
  a					:      List[str]    =       num_no_ans
  a					:      List[str]    =       cur_score
  a					:      str    =       0.0
  a					:      Union[str, Any]    =       sorted(A_     ,      key=lambda A_				: na_probs[k]				)
  for i, qid in enumerate(A_				):
    if qid not in scores:
      continue
    if qid_to_has_ans[qid]:
      a					:      Optional[int]    =       scores[qid]
    else:
      if preds[qid]:
        a					:      Dict    =       -1
      else:
        a					:      Optional[Any]    =       0
    cur_score += diff
    if cur_score > best_score:
      a					:      List[Any]    =       cur_score
      a					:      str    =       na_probs[qid]
  return 100.0 * best_score / len(A_				), best_thresh




def       snake_case  (A_				:List[Any]     ,      A_				:List[Any]     ,      A_				:str     ,      A_				:int     ,      A_				:Optional[Any]     ,      A_				:Union[str, Any]				):







  '''simple docstring'''

  a					:      Any    =       find_best_thresh(A_     ,      A_     ,      A_     ,      A_				)
  a					:      List[Any]    =       find_best_thresh(A_     ,      A_     ,      A_     ,      A_				)
  a					:      Union[str, Any]    =       best_exact
  a					:      List[Any]    =       exact_thresh
  a					:      List[str]    =       best_fa
  a					:      Any    =       fa_thresh




def       snake_case  ():







  '''simple docstring'''

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


if __name__ == "__main__":
   _UpperCamelCase    :   Tuple   			=						parse_args()
   if OPTS.out_image_dir:
      import matplotlib

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












"""simple docstring"""


_UpperCamelCase    :   List[Any]   			=						8.31_44_62  # Unit - J mol-1 K-1




def       snake_case  (A_				:float     ,      A_				:float     ,      A_				:float				):







  '''simple docstring'''

  if moles < 0 or kelvin < 0 or volume < 0:
    raise ValueError('Invalid inputs. Enter positive value.'				)
  return moles * kelvin * UNIVERSAL_GAS_CONSTANT / volume




def       snake_case  (A_				:float     ,      A_				:float     ,      A_				:float				):







  '''simple docstring'''

  if moles < 0 or kelvin < 0 or pressure < 0:
    raise ValueError('Invalid inputs. Enter positive value.'				)
  return moles * kelvin * UNIVERSAL_GAS_CONSTANT / pressure


if __name__ == "__main__":
   from doctest import testmod

   testmod()




