import math
import time
from typing import Dict, List, Optional

from torch.utils.data import Dataset

from transformers import SeqaSeqTrainer, is_torch_tpu_available
from transformers.trainer_utils import PredictionOutput, speed_metrics


if is_torch_tpu_available(check_device=False):
				import torch_xla.core.xla_model as xm
				import torch_xla.debug.metrics as met





class     lowerCAmelCase__     (				SCREAMING_SNAKE_CASE_			):


		'''simple docstring'''






		def __init__(       self     :     Any     ,  *snake_case__     :     Union[str, Any]     ,  snake_case__     :     str=None     ,  snake_case__     :     Optional[int]=None     ,  **snake_case__     :     Tuple		)      ->	int:
				super().__init__(*snake_case__     ,  **snake_case__		)
				_lowerCamelCase				   =  eval_examples
				_lowerCamelCase				   =  post_process_function
		def   _snake_case       (       self     :     List[str]     ,  snake_case__     :     Optional[Dataset] = None     ,  snake_case__     :     List[Any]=None     ,  snake_case__     :     Optional[List[str]] = None     ,  snake_case__     :     str = "eval"     ,  **snake_case__     :     List[Any]     ,  )      ->	Dict[str, float]:
				_lowerCamelCase				   =  gen_kwargs.copy()
				_lowerCamelCase				   =  (
				    gen_kwargs['max_length'] if gen_kwargs.get('max_length'		) is not None else self.args.generation_max_length
				)
				_lowerCamelCase				   =  (
				    gen_kwargs['num_beams'] if gen_kwargs.get('num_beams'		) is not None else self.args.generation_num_beams
				)
				_lowerCamelCase				   =  gen_kwargs

				_lowerCamelCase				   =  self.eval_dataset if eval_dataset is None else eval_dataset
				_lowerCamelCase				   =  self.get_eval_dataloader(snake_case__		)
				_lowerCamelCase				   =  self.eval_examples if eval_examples is None else eval_examples

				# Temporarily disable metric computation, we will do it in the loop here.
				_lowerCamelCase				   =  self.compute_metrics
				_lowerCamelCase				   =  None
				_lowerCamelCase				   =  time.time()
				_lowerCamelCase				   =  self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop
				try:
						_lowerCamelCase				   =  eval_loop(
						    snake_case__     ,  description='Evaluation'     ,  prediction_loss_only=True if compute_metrics is None else None     ,  ignore_keys=snake_case__     ,  metric_key_prefix=snake_case__     ,  )
				finally:
						_lowerCamelCase				   =  compute_metrics
				_lowerCamelCase				   =  self.args.eval_batch_size * self.args.world_size
				if f"""{metric_key_prefix}_jit_compilation_time""" in output.metrics:
						start_time += output.metrics[f"""{metric_key_prefix}_jit_compilation_time"""]
				output.metrics.update(
				    speed_metrics(
				        snake_case__     ,  snake_case__     ,  num_samples=output.num_samples     ,  num_steps=math.ceil(output.num_samples / total_batch_size		)     ,  )		)

				if self.post_process_function is not None and self.compute_metrics is not None and self.args.should_save:
						# Only the main node write the results by default
						_lowerCamelCase				   =  self.post_process_function(snake_case__     ,  snake_case__     ,  snake_case__		)
						_lowerCamelCase				   =  self.compute_metrics(snake_case__		)

						# Prefix all keys with metric_key_prefix + '_'
						for key in list(metrics.keys()		):
								if not key.startswith(f"""{metric_key_prefix}_"""		):
										_lowerCamelCase				   =  metrics.pop(snake_case__		)

						metrics.update(output.metrics		)
				else:
						_lowerCamelCase				   =  output.metrics

				if self.args.should_log:
						# Only the main node log the results by default
						self.log(snake_case__		)

				if self.args.tpu_metrics_debug or self.args.debug:
						# tpu-comment: Logging debug metrics for PyTorch/XLA (compile, execute times, ops, etc.)
						xm.master_print(met.metrics_report()		)

				_lowerCamelCase				   =  self.callback_handler.on_evaluate(self.args     ,  self.state     ,  self.control     ,  snake_case__		)
				return metrics



		def   _snake_case       (       self     :     List[str]     ,  snake_case__     :     Any     ,  snake_case__     :     Any     ,  snake_case__     :     str=None     ,  snake_case__     :     str = "test"     ,  **snake_case__     :     Optional[int]		)      ->	Union[str, Any]:
				_lowerCamelCase				   =  gen_kwargs.copy()

				_lowerCamelCase				   =  self.get_test_dataloader(snake_case__		)

				# Temporarily disable metric computation, we will do it in the loop here.
				_lowerCamelCase				   =  self.compute_metrics
				_lowerCamelCase				   =  None
				_lowerCamelCase				   =  time.time()
				_lowerCamelCase				   =  self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop
				try:
						_lowerCamelCase				   =  eval_loop(
						    snake_case__     ,  description='Prediction'     ,  prediction_loss_only=True if compute_metrics is None else None     ,  ignore_keys=snake_case__     ,  metric_key_prefix=snake_case__     ,  )
				finally:
						_lowerCamelCase				   =  compute_metrics

				_lowerCamelCase				   =  self.args.eval_batch_size * self.args.world_size
				if f"""{metric_key_prefix}_jit_compilation_time""" in output.metrics:
						start_time += output.metrics[f"""{metric_key_prefix}_jit_compilation_time"""]
				output.metrics.update(
				    speed_metrics(
				        snake_case__     ,  snake_case__     ,  num_samples=output.num_samples     ,  num_steps=math.ceil(output.num_samples / total_batch_size		)     ,  )		)
				if self.post_process_function is None or self.compute_metrics is None:
						return output

				_lowerCamelCase				   =  self.post_process_function(snake_case__     ,  snake_case__     ,  snake_case__     ,  'predict'		)
				_lowerCamelCase				   =  self.compute_metrics(snake_case__		)

				# Prefix all keys with metric_key_prefix + '_'
				for key in list(metrics.keys()		):
						if not key.startswith(f"""{metric_key_prefix}_"""		):
								_lowerCamelCase				   =  metrics.pop(snake_case__		)
				metrics.update(output.metrics		)
				return PredictionOutput(predictions=predictions.predictions     ,  label_ids=predictions.label_ids     ,  metrics=snake_case__		)
def 	lowerCamelCase					(	UpperCamelCase     :				int			,       UpperCamelCase     :				int							)   ->    float:
		return base * power(UpperCamelCase			,       (exponent - 1)							) if exponent else 1


if __name__ == "__main__":
				print('Raise base to the power of exponent using recursion...')
				A						=			int(input('Enter the base: ').strip())
				A						=			int(input('Enter the exponent: ').strip())
				A						=			power(base, abs(exponent))
				if exponent < 0:  # power() does not properly deal w/ negative exponents
								A						=			1 / result
				print(F'''{base} to the power of {exponent} is {result}''')