"""simple docstring"""




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

import numpy as np


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

__lowerCamelCase							 =     None






def      UpperCAmelCase    (		):






							"""simple docstring"""





							A__		   =							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      UpperCAmelCase    (		UpperCamelCase__ ):






							"""simple docstring"""





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






def      UpperCAmelCase    (		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__ ):
														A__		   =							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      UpperCAmelCase    (		UpperCamelCase__ ):






							"""simple docstring"""





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






def      UpperCAmelCase    (		UpperCamelCase__				,			UpperCamelCase__ ):






							"""simple docstring"""





							return int(normalize_answer(__lowerCamelCase ) == normalize_answer(__lowerCamelCase ) )






def      UpperCAmelCase    (		UpperCamelCase__				,			UpperCamelCase__ ):






							"""simple docstring"""





							A__		   =							get_tokens(__lowerCamelCase )
							A__		   =							get_tokens(__lowerCamelCase )
							A__		   =							collections.Counter(__lowerCamelCase ) & collections.Counter(__lowerCamelCase )
							A__		   =							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
							A__		   =							1.0 * num_same / len(__lowerCamelCase )
							A__		   =							1.0 * num_same / len(__lowerCamelCase )
							A__		   =							(2 * precision * recall) / (precision + recall)
							return fa






def      UpperCAmelCase    (		UpperCamelCase__				,			UpperCamelCase__ ):






							"""simple docstring"""





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






def      UpperCAmelCase    (		UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__ ):






							"""simple docstring"""





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






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






							"""simple docstring"""





							if not qid_list:
														A__		   =							len(__lowerCamelCase )
														return collections.OrderedDict(
														    [
														        ('exact', 100.0 * sum(exact_scores.values() ) / total),
														        ('f1', 100.0 * sum(fa_scores.values() ) / total),
														        ('total', total),
														    ] )
							else:
														A__		   =							len(__lowerCamelCase )
														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      UpperCAmelCase    (		UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__ ):






							"""simple docstring"""





							for k in new_eval:
														A__		   =							new_eval[k]






def      UpperCAmelCase    (		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.0_5] )
							plt.ylim([0.0, 1.0_5] )
							plt.title(__lowerCamelCase )
							plt.savefig(__lowerCamelCase )
							plt.clf()






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






							"""simple docstring"""





							A__		   =							sorted(__lowerCamelCase				,			key=lambda UpperCamelCase__ : na_probs[k] )
							A__		   =							0.0
							A__		   =							1.0
							A__		   =							0.0
							A__		   =							[1.0]
							A__		   =							[0.0]
							A__		   =							0.0
							for i, qid in enumerate(__lowerCamelCase ):
														if qid_to_has_ans[qid]:
																					true_pos += scores[qid]
														A__		   =							true_pos / float(i + 1 )
														A__		   =							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": 100.0 * avg_prec}






def      UpperCAmelCase    (		UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__ ):






							"""simple docstring"""





							if out_image_dir and not os.path.exists(__lowerCamelCase ):
														os.makedirs(__lowerCamelCase )
							A__		   =							sum(1 for v in qid_to_has_ans.values() if v )
							if num_true_pos == 0:
														return
							A__		   =							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'				,			)
							A__		   =							make_precision_recall_eval(
							    __lowerCamelCase				,			__lowerCamelCase				,			__lowerCamelCase				,			__lowerCamelCase				,			out_image=os.path.join(__lowerCamelCase				,			'pr_f1.png' )				,			title='Precision-Recall curve for F1 score'				,			)
							A__		   =							{k: float(__lowerCamelCase ) for k, v in qid_to_has_ans.items()}
							A__		   =							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      UpperCAmelCase    (		UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__ ):






							"""simple docstring"""





							if not qid_list:
														return
							A__		   =							[na_probs[k] for k in qid_list]
							A__		   =							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      UpperCAmelCase    (		UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__ ):






							"""simple docstring"""





							A__		   =							sum(1 for k in qid_to_has_ans if not qid_to_has_ans[k] )
							A__		   =							num_no_ans
							A__		   =							cur_score
							A__		   =							0.0
							A__		   =							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]:
																					A__		   =							scores[qid]
														else:
																					if preds[qid]:
																												A__		   =							-1
																					else:
																												A__		   =							0
														cur_score += diff
														if cur_score > best_score:
																					A__		   =							cur_score
																					A__		   =							na_probs[qid]
							return 100.0 * best_score / len(__lowerCamelCase ), best_thresh






def      UpperCAmelCase    (		UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__				,			UpperCamelCase__ ):






							"""simple docstring"""





							A__		   =							find_best_thresh(__lowerCamelCase				,			__lowerCamelCase				,			__lowerCamelCase				,			__lowerCamelCase )
							A__		   =							find_best_thresh(__lowerCamelCase				,			__lowerCamelCase				,			__lowerCamelCase				,			__lowerCamelCase )
							A__		   =							best_exact
							A__		   =							exact_thresh
							A__		   =							best_fa
							A__		   =							fa_thresh






def      UpperCAmelCase    (		):






							"""simple docstring"""





							with open(OPTS.data_file ) as f:
														A__		   =							json.load(__lowerCamelCase )
														A__		   =							dataset_json["""data"""]
							with open(OPTS.pred_file ) as f:
														A__		   =							json.load(__lowerCamelCase )
							if OPTS.na_prob_file:
														with open(OPTS.na_prob_file ) as f:
																					A__		   =							json.load(__lowerCamelCase )
							else:
														A__		   =							{k: 0.0 for k in preds}
							A__		   =							make_qid_to_has_ans(__lowerCamelCase )  # maps qid to True/False
							A__		   =							[k for k, v in qid_to_has_ans.items() if v]
							A__		   =							[k for k, v in qid_to_has_ans.items() if not v]
							A__		   =							get_raw_scores(__lowerCamelCase				,			__lowerCamelCase )
							A__		   =							apply_no_ans_threshold(__lowerCamelCase				,			__lowerCamelCase				,			__lowerCamelCase				,			OPTS.na_prob_thresh )
							A__		   =							apply_no_ans_threshold(__lowerCamelCase				,			__lowerCamelCase				,			__lowerCamelCase				,			OPTS.na_prob_thresh )
							A__		   =							make_eval_dict(__lowerCamelCase				,			__lowerCamelCase )
							if has_ans_qids:
														A__		   =							make_eval_dict(__lowerCamelCase				,			__lowerCamelCase				,			qid_list=__lowerCamelCase )
														merge_eval(__lowerCamelCase				,			__lowerCamelCase				,			'HasAns' )
							if no_ans_qids:
														A__		   =							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__":
				__lowerCamelCase							 =     parse_args()
				if OPTS.out_image_dir:
								import matplotlib

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













from math import log

from scipy.constants import Boltzmann, physical_constants

a		:       Any			     = 300  # TEMPERATURE (unit = K)






def 				lowerCamelCase__      (    __lowerCamelCase			:     float  ,		__lowerCamelCase			:     float  ,		__lowerCamelCase			:     float  ,		):

  if donor_conc <= 0:
    raise ValueError("""Donor concentration should be positive"""		)
  elif acceptor_conc <= 0:
    raise ValueError("""Acceptor concentration should be positive"""		)
  elif intrinsic_conc <= 0:
    raise ValueError("""Intrinsic concentration should be positive"""		)
  elif donor_conc <= intrinsic_conc:
    raise ValueError(
        """Donor concentration should be greater than intrinsic concentration"""		)
  elif acceptor_conc <= intrinsic_conc:
    raise ValueError(
        """Acceptor concentration should be greater than intrinsic concentration"""		)
  else:
    return (
        Boltzmann
        * T
        * log((donor_conc * acceptor_conc) / intrinsic_conc**2		)
        / physical_constants["electron volt"][0]
    )


if __name__ == "__main__":
       import doctest

       doctest.testmod()


