





'''simple docstring'''

from __future__ import annotations

__lowerCAmelCase							:	List[str]			=tuple[int, int, int]
__lowerCAmelCase							:	Union[str, Any]			=tuple[str, str, str]


# used alphabet --------------------------
# from string.ascii_uppercase
__lowerCAmelCase							:	Optional[Any]			="ABCDEFGHIJKLMNOPQRSTUVWXYZ"

# -------------------------- default selection --------------------------
# rotors --------------------------
__lowerCAmelCase							:	str			="EGZWVONAHDCLFQMSIPJBYUKXTR"
__lowerCAmelCase							:	Union[str, Any]			="FOBHMDKEXQNRAULPGSJVTYICZW"
__lowerCAmelCase							:	int			="ZJXESIUQLHAVRMDOYGTNFWPBKC"
# reflector --------------------------
__lowerCAmelCase							:	Dict			={
    "A": "N",
    "N": "A",
    "B": "O",
    "O": "B",
    "C": "P",
    "P": "C",
    "D": "Q",
    "Q": "D",
    "E": "R",
    "R": "E",
    "F": "S",
    "S": "F",
    "G": "T",
    "T": "G",
    "H": "U",
    "U": "H",
    "I": "V",
    "V": "I",
    "J": "W",
    "W": "J",
    "K": "X",
    "X": "K",
    "L": "Y",
    "Y": "L",
    "M": "Z",
    "Z": "M",
}

# -------------------------- extra rotors --------------------------
__lowerCAmelCase							:	List[Any]			="RMDJXFUWGISLHVTCQNKYPBEZOA"
__lowerCAmelCase							:	int			="SGLCPQWZHKXAREONTFBVIYJUDM"
__lowerCAmelCase							:	str			="HVSICLTYKQUBXDWAJZOMFGPREN"
__lowerCAmelCase							:	Dict			="RZWQHFMVDBKICJLNTUXAGYPSOE"
__lowerCAmelCase							:	List[str]			="LFKIJODBEGAMQPXVUHYSTCZRWN"
__lowerCAmelCase							:	Optional[Any]			="KOAEGVDHXPQZMLFTYWJNBRCIUS"





def 						UpperCamelCase				(							_lowerCamelCase					:					RotorPositionT						,       _lowerCamelCase					:					RotorSelectionT						,       _lowerCamelCase					:					str       ):
    # Checks if there are 3 unique rotors

    if (unique_rotsel := len(set(_lowerCamelCase       )       )) < 3:
        A__				=			F"Please use 3 unique rotors (not {unique_rotsel})"
        raise Exception(_lowerCamelCase       )

    # Checks if rotor positions are valid
    A__,	A__,	A__				=			rotpos
    if not 0 < rotorposa <= len(_lowerCamelCase       ):
        A__				=			F"First rotor position is not within range of 1..26 ({rotorposa}"
        raise ValueError(_lowerCamelCase       )
    if not 0 < rotorposa <= len(_lowerCamelCase       ):
        A__				=			F"Second rotor position is not within range of 1..26 ({rotorposa})"
        raise ValueError(_lowerCamelCase       )
    if not 0 < rotorposa <= len(_lowerCamelCase       ):
        A__				=			F"Third rotor position is not within range of 1..26 ({rotorposa})"
        raise ValueError(_lowerCamelCase       )

    # Validates string and returns dict
    A__				=			_plugboard(_lowerCamelCase       )

    return rotpos, rotsel, pbdict





def 						UpperCamelCase				(							_lowerCamelCase					:					str       ):

    # tests the input string if it
    # a) is type string
    # b) has even length (so pairs can be made)
    if not isinstance(_lowerCamelCase						,       _lowerCamelCase       ):
        A__				=			F"Plugboard setting isn't type string ({type(_lowerCamelCase       )})"
        raise TypeError(_lowerCamelCase       )
    elif len(_lowerCamelCase       ) % 2 != 0:
        A__				=			F"Odd number of symbols ({len(_lowerCamelCase       )})"
        raise Exception(_lowerCamelCase       )
    elif pbstring == "":
        return {}

    pbstring.replace(" "						,       ""       )

    # Checks if all characters are unique
    A__				=			set()
    for i in pbstring:
        if i not in abc:
            A__				=			F"'{i}' not in list of symbols"
            raise Exception(_lowerCamelCase       )
        elif i in tmppbl:
            A__				=			F"Duplicate symbol ({i})"
            raise Exception(_lowerCamelCase       )
        else:
            tmppbl.add(_lowerCamelCase       )
    del tmppbl

    # Created the dictionary
    A__				=			{}
    for j in range(0						,       len(_lowerCamelCase       ) - 1						,       2       ):
        A__				=			pbstring[j + 1]
        A__				=			pbstring[j]

    return pb





def 						UpperCamelCase				(							_lowerCamelCase					:					str						,       _lowerCamelCase					:					RotorPositionT						,       _lowerCamelCase					:					RotorSelectionT = (rotora, rotora, rotora)						,       _lowerCamelCase					:					str = ""						,       ):
    A__				=			text.upper()
    A__,	A__,	A__				=			_validator(
        _lowerCamelCase						,       _lowerCamelCase						,       plugb.upper()       )

    A__,	A__,	A__				=			rotor_position
    A__,	A__,	A__				=			rotor_selection
    rotorposa -= 1
    rotorposa -= 1
    rotorposa -= 1

    A__				=			[]

    # encryption/decryption process --------------------------
    for symbol in text:
        if symbol in abc:
            # 1st plugboard --------------------------
            if symbol in plugboard:
                A__				=			plugboard[symbol]

            # rotor ra --------------------------
            A__				=			abc.index(_lowerCamelCase       ) + rotorposa
            A__				=			rotora[index % len(_lowerCamelCase       )]

            # rotor rb --------------------------
            A__				=			abc.index(_lowerCamelCase       ) + rotorposa
            A__				=			rotora[index % len(_lowerCamelCase       )]

            # rotor rc --------------------------
            A__				=			abc.index(_lowerCamelCase       ) + rotorposa
            A__				=			rotora[index % len(_lowerCamelCase       )]

            # reflector --------------------------
            # this is the reason you don't need another machine to decipher

            A__				=			reflector[symbol]

            # 2nd rotors
            A__				=			abc[rotora.index(_lowerCamelCase       ) - rotorposa]
            A__				=			abc[rotora.index(_lowerCamelCase       ) - rotorposa]
            A__				=			abc[rotora.index(_lowerCamelCase       ) - rotorposa]

            # 2nd plugboard
            if symbol in plugboard:
                A__				=			plugboard[symbol]

            # moves/resets rotor positions
            rotorposa += 1
            if rotorposa >= len(_lowerCamelCase       ):
                A__				=			0
                rotorposa += 1
            if rotorposa >= len(_lowerCamelCase       ):
                A__				=			0
                rotorposa += 1
            if rotorposa >= len(_lowerCamelCase       ):
                A__				=			0

        # else:
        #    pass
        #    Error could be also raised
        #    raise ValueError(
        #       'Invalid symbol('+repr(symbol)+')')
        result.append(_lowerCamelCase       )

    return "".join(_lowerCamelCase       )


if __name__ == "__main__":
  __lowerCAmelCase							:	Any			="This is my Python script that emulates the Enigma machine from WWII."
  __lowerCAmelCase							:	Tuple			=(1, 1, 1)
  __lowerCAmelCase							:	Union[str, Any]			="pictures"
  __lowerCAmelCase							:	Any			=(rotora, rotora, rotora)
  __lowerCAmelCase							:	Any			=enigma(message, rotor_pos, rotor_sel, pb)

  print("Encrypted message:", en)
  print("Decrypted message:", enigma(en, rotor_pos, rotor_sel, pb))










'''simple docstring'''

import math
import time

from transformers import Trainer, 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    UpperCAmelCase	(       UpperCamelCase__				):
 def __init__(				self      :Optional[Any]						,       *lowercase_      :int						,       lowercase_      :Any=None						,       lowercase_      :List[str]=None						,       **lowercase_      :Any							)->							Any:
     super().__init__(*lowercase_						,       **lowercase_							)
     A__				=			eval_examples
     A__				=			post_process_function
 def      UpperCAmelCase_							(				self      :str						,       lowercase_      :str=None						,       lowercase_      :Optional[int]=None						,       lowercase_      :Optional[int]=None						,       lowercase_      :str = "eval"							)->							Union[str, Any]:
     A__				=			self.eval_dataset if eval_dataset is None else eval_dataset
     A__				=			self.get_eval_dataloader(lowercase_							)
     A__				=			self.eval_examples if eval_examples is None else eval_examples

     # Temporarily disable metric computation, we will do it in the loop here.
     A__				=			self.compute_metrics
     A__				=			None
     A__				=			self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop
     A__				=			time.time()
     try:
         A__				=			eval_loop(
             lowercase_						,       description="Evaluation"						,       prediction_loss_only=True if compute_metrics is None else None						,       ignore_keys=lowercase_						,       metric_key_prefix=lowercase_						,       )
     finally:
         A__				=			compute_metrics
     A__				=			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(
             lowercase_						,       lowercase_						,       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
         A__				=			self.post_process_function(lowercase_						,       lowercase_						,       output.predictions							)
         A__				=			self.compute_metrics(lowercase_							)

         # Prefix all keys with metric_key_prefix + '_'
         for key in list(metrics.keys()							):
             if not key.startswith(F"{metric_key_prefix}_"							):
                 A__				=			metrics.pop(lowercase_							)
         metrics.update(output.metrics							)
     else:
         A__				=			output.metrics

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

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

     A__				=			self.callback_handler.on_evaluate(self.args						,       self.state						,       self.control						,       lowercase_							)
     return metrics



 def      UpperCAmelCase_							(				self      :List[str]						,       lowercase_      :List[Any]						,       lowercase_      :str						,       lowercase_      :Any=None						,       lowercase_      :str = "test"							)->							List[Any]:
     A__				=			self.get_test_dataloader(lowercase_							)

     # Temporarily disable metric computation, we will do it in the loop here.
     A__				=			self.compute_metrics
     A__				=			None
     A__				=			self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop
     A__				=			time.time()
     try:
         A__				=			eval_loop(
             lowercase_						,       description="Prediction"						,       prediction_loss_only=True if compute_metrics is None else None						,       ignore_keys=lowercase_						,       metric_key_prefix=lowercase_						,       )
     finally:
         A__				=			compute_metrics
     A__				=			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(
             lowercase_						,       lowercase_						,       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

     A__				=			self.post_process_function(lowercase_						,       lowercase_						,       output.predictions						,       "predict"							)
     A__				=			self.compute_metrics(lowercase_							)

     # Prefix all keys with metric_key_prefix + '_'
     for key in list(metrics.keys()							):
         if not key.startswith(F"{metric_key_prefix}_"							):
             A__				=			metrics.pop(lowercase_							)
     metrics.update(output.metrics							)
     return PredictionOutput(predictions=predictions.predictions						,       label_ids=predictions.label_ids						,       metrics=lowercase_							)



