
"""simple docstring"""


import argparse
import logging
import os
from pathlib import Path
from typing import Any, Dict

import pytorch_lightning as pl
from pytorch_lightning.utilities import rank_zero_info

from transformers import (
    AdamW,
    AutoConfig,
    AutoModel,
    AutoModelForPreTraining,
    AutoModelForQuestionAnswering,
    AutoModelForSeqaSeqLM,
    AutoModelForSequenceClassification,
    AutoModelForTokenClassification,
    AutoModelWithLMHead,
    AutoTokenizer,
    PretrainedConfig,
    PreTrainedTokenizer,
)
from transformers.optimization import (
    Adafactor,
    get_cosine_schedule_with_warmup,
    get_cosine_with_hard_restarts_schedule_with_warmup,
    get_linear_schedule_with_warmup,
    get_polynomial_decay_schedule_with_warmup,
)
from transformers.utils.versions import require_version


__A 		= logging.getLogger(__name__)

require_version('pytorch_lightning>=1.0.4')

__A 		= {
    'base': AutoModel,
    'sequence-classification': AutoModelForSequenceClassification,
    'question-answering': AutoModelForQuestionAnswering,
    'pretraining': AutoModelForPreTraining,
    'token-classification': AutoModelForTokenClassification,
    'language-modeling': AutoModelWithLMHead,
    'summarization': AutoModelForSeqaSeqLM,
    'translation': AutoModelForSeqaSeqLM,
}


# update this and the import above to support new schedulers from transformers.optimization
__A 		= {
    'linear': get_linear_schedule_with_warmup,
    'cosine': get_cosine_schedule_with_warmup,
    'cosine_w_restarts': get_cosine_with_hard_restarts_schedule_with_warmup,
    'polynomial': get_polynomial_decay_schedule_with_warmup,
    # '': get_constant_schedule,             # not supported for now
    # '': get_constant_schedule_with_warmup, # not supported for now
}
__A 		= sorted(arg_to_scheduler.keys())
__A 		= '{' + ', '.join(arg_to_scheduler_choices) + '}'







class 	lowerCamelCase__      (      pl.LightningModule       ):



			def __init__(							self  ,  __UpperCAmelCase  ,  __UpperCAmelCase=None  ,  __UpperCAmelCase="base"  ,  __UpperCAmelCase=None  ,  __UpperCAmelCase=None  ,  __UpperCAmelCase=None  ,  **__UpperCAmelCase  ,  )				->  Optional[int]:
				super().__init__()
				# TODO: move to self.save_hyperparameters()
				# self.save_hyperparameters()
				# can also expand arguments into trainer signature for easier reading

				self.save_hyperparameters(__UpperCAmelCase						)
				_lowerCAmelCase			=0
				_lowerCAmelCase			=Path(self.hparams.output_dir						)
				_lowerCAmelCase			=self.hparams.cache_dir if self.hparams.cache_dir else None
				if config is None:
					_lowerCAmelCase			=AutoConfig.from_pretrained(
					    self.hparams.config_name if self.hparams.config_name else self.hparams.model_name_or_path  ,  **({"""num_labels""": num_labels} if num_labels is not None else {})  ,  cache_dir=__UpperCAmelCase  ,  **__UpperCAmelCase  ,  )
				else:
					_lowerCAmelCase			=config

				_lowerCAmelCase			=("""encoder_layerdrop""", """decoder_layerdrop""", """dropout""", """attention_dropout""")
				for p in extra_model_params:
					if getattr(self.hparams  ,  __UpperCAmelCase  ,  __UpperCAmelCase						):
						assert hasattr(self.config  ,  __UpperCAmelCase						), f'''model config doesn\'t have a `{p}` attribute'''
						setattr(self.config  ,  __UpperCAmelCase  ,  getattr(self.hparams  ,  __UpperCAmelCase						)						)

				if tokenizer is None:
					_lowerCAmelCase			=AutoTokenizer.from_pretrained(
					    self.hparams.tokenizer_name if self.hparams.tokenizer_name else self.hparams.model_name_or_path  ,  cache_dir=__UpperCAmelCase  ,  )
				else:
					_lowerCAmelCase			=tokenizer
				_lowerCAmelCase			=MODEL_MODES[mode]
				if model is None:
					_lowerCAmelCase			=self.model_type.from_pretrained(
					    self.hparams.model_name_or_path  ,  from_tf=bool(""".ckpt""" in self.hparams.model_name_or_path						)  ,  config=self.config  ,  cache_dir=__UpperCAmelCase  ,  )
				else:
					_lowerCAmelCase			=model



			def       _lowerCAmelCase	(							self  ,  *__UpperCAmelCase  ,  **__UpperCAmelCase						)				->  Optional[Any]:
				_lowerCAmelCase			=self.model_type.from_pretrained(*__UpperCAmelCase  ,  **__UpperCAmelCase						)



			def       _lowerCAmelCase	(							self						)				->  Tuple:
				_lowerCAmelCase			=arg_to_scheduler[self.hparams.lr_scheduler]
				_lowerCAmelCase			=get_schedule_func(
				    self.opt  ,  num_warmup_steps=self.hparams.warmup_steps  ,  num_training_steps=self.total_steps()						)
				_lowerCAmelCase			={"""scheduler""": scheduler, """interval""": """step""", """frequency""": 1}
				return scheduler



			def       _lowerCAmelCase	(							self						)				->  List[str]:
				_lowerCAmelCase			=self.model
				_lowerCAmelCase			=["""bias""", """LayerNorm.weight"""]
				_lowerCAmelCase			=[
				    {
				        """params""": [p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay						)],
				        """weight_decay""": self.hparams.weight_decay,
				    },
				    {
				        """params""": [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay						)],
				        """weight_decay""": 0.0,
				    },
				]
				if self.hparams.adafactor:
					_lowerCAmelCase			=Adafactor(
					    __UpperCAmelCase  ,  lr=self.hparams.learning_rate  ,  scale_parameter=__UpperCAmelCase  ,  relative_step=__UpperCAmelCase						)

				else:
					_lowerCAmelCase			=AdamW(
					    __UpperCAmelCase  ,  lr=self.hparams.learning_rate  ,  eps=self.hparams.adam_epsilon						)
				_lowerCAmelCase			=optimizer

				_lowerCAmelCase			=self.get_lr_scheduler()

				return [optimizer], [scheduler]



			def       _lowerCAmelCase	(							self  ,  __UpperCAmelCase  ,  __UpperCAmelCase						)				->  str:
				return self.validation_step(__UpperCAmelCase  ,  __UpperCAmelCase						)



			def       _lowerCAmelCase	(							self  ,  __UpperCAmelCase						)				->  int:
				return self.validation_end(__UpperCAmelCase						)



			def       _lowerCAmelCase	(							self						)				->  int:
				_lowerCAmelCase			=max(1  ,  self.hparams.gpus						)  # TODO: consider num_tpu_cores
				_lowerCAmelCase			=self.hparams.train_batch_size * self.hparams.accumulate_grad_batches * num_devices
				return (self.dataset_size / effective_batch_size) * self.hparams.max_epochs



			def       _lowerCAmelCase	(							self  ,  __UpperCAmelCase						)				->  Union[str, Any]:
				if stage == "test":
					_lowerCAmelCase			=len(self.test_dataloader().dataset						)
				else:
					_lowerCAmelCase			=self.get_dataloader("""train"""  ,  self.hparams.train_batch_size  ,  shuffle=__UpperCAmelCase						)
					_lowerCAmelCase			=len(self.train_dataloader().dataset						)



			def       _lowerCAmelCase	(							self  ,  __UpperCAmelCase  ,  __UpperCAmelCase  ,  __UpperCAmelCase = False						)				->  Optional[Any]:
				raise NotImplementedError("""You must implement this for your task"""						)



			def       _lowerCAmelCase	(							self						)				->  List[Any]:
				return self.train_loader



			def       _lowerCAmelCase	(							self						)				->  Optional[Any]:
				return self.get_dataloader("""dev"""  ,  self.hparams.eval_batch_size  ,  shuffle=__UpperCAmelCase						)



			def       _lowerCAmelCase	(							self						)				->  int:
				return self.get_dataloader("""test"""  ,  self.hparams.eval_batch_size  ,  shuffle=__UpperCAmelCase						)



			def       _lowerCAmelCase	(							self  ,  __UpperCAmelCase						)				->  Dict:
				return os.path.join(
				    self.hparams.data_dir  ,  """cached_{}_{}_{}""".format(
				        __UpperCAmelCase  ,  list(filter(__UpperCAmelCase  ,  self.hparams.model_name_or_path.split("""/"""						)						)						).pop()  ,  str(self.hparams.max_seq_length						)  ,  )  ,  )



			@pl.utilities.rank_zero_only
			def       _lowerCAmelCase	(							self  ,  __UpperCAmelCase						)				->  None:
				_lowerCAmelCase			=self.output_dir.joinpath("""best_tfmr"""						)
				_lowerCAmelCase			=self.step_count
				self.model.save_pretrained(__UpperCAmelCase						)
				self.tokenizer.save_pretrained(__UpperCAmelCase						)



			@staticmethod
			def       _lowerCAmelCase	(							__UpperCAmelCase  ,  __UpperCAmelCase						)				->  Union[str, Any]:
				parser.add_argument(
				    """--model_name_or_path"""  ,  default=__UpperCAmelCase  ,  type=__UpperCAmelCase  ,  required=__UpperCAmelCase  ,  help="""Path to pretrained model or model identifier from huggingface.co/models"""  ,  )
				parser.add_argument(
				    """--config_name"""  ,  default=""""""  ,  type=__UpperCAmelCase  ,  help="""Pretrained config name or path if not the same as model_name"""						)
				parser.add_argument(
				    """--tokenizer_name"""  ,  default=__UpperCAmelCase  ,  type=__UpperCAmelCase  ,  help="""Pretrained tokenizer name or path if not the same as model_name"""  ,  )
				parser.add_argument(
				    """--cache_dir"""  ,  default=""""""  ,  type=__UpperCAmelCase  ,  help="""Where do you want to store the pre-trained models downloaded from huggingface.co"""  ,  )
				parser.add_argument(
				    """--encoder_layerdrop"""  ,  type=__UpperCAmelCase  ,  help="""Encoder layer dropout probability (Optional). Goes into model.config"""  ,  )
				parser.add_argument(
				    """--decoder_layerdrop"""  ,  type=__UpperCAmelCase  ,  help="""Decoder layer dropout probability (Optional). Goes into model.config"""  ,  )
				parser.add_argument(
				    """--dropout"""  ,  type=__UpperCAmelCase  ,  help="""Dropout probability (Optional). Goes into model.config"""  ,  )
				parser.add_argument(
				    """--attention_dropout"""  ,  type=__UpperCAmelCase  ,  help="""Attention dropout probability (Optional). Goes into model.config"""  ,  )
				parser.add_argument("""--learning_rate"""  ,  default=5e-5  ,  type=__UpperCAmelCase  ,  help="""The initial learning rate for Adam."""						)
				parser.add_argument(
				    """--lr_scheduler"""  ,  default="""linear"""  ,  choices=__UpperCAmelCase  ,  metavar=__UpperCAmelCase  ,  type=__UpperCAmelCase  ,  help="""Learning rate scheduler"""  ,  )
				parser.add_argument("""--weight_decay"""  ,  default=0.0  ,  type=__UpperCAmelCase  ,  help="""Weight decay if we apply some."""						)
				parser.add_argument("""--adam_epsilon"""  ,  default=1e-8  ,  type=__UpperCAmelCase  ,  help="""Epsilon for Adam optimizer."""						)
				parser.add_argument("""--warmup_steps"""  ,  default=0  ,  type=__UpperCAmelCase  ,  help="""Linear warmup over warmup_steps."""						)
				parser.add_argument("""--num_workers"""  ,  default=4  ,  type=__UpperCAmelCase  ,  help="""kwarg passed to DataLoader"""						)
				parser.add_argument("""--num_train_epochs"""  ,  dest="""max_epochs"""  ,  default=3  ,  type=__UpperCAmelCase						)
				parser.add_argument("""--train_batch_size"""  ,  default=32  ,  type=__UpperCAmelCase						)
				parser.add_argument("""--eval_batch_size"""  ,  default=32  ,  type=__UpperCAmelCase						)
				parser.add_argument("""--adafactor"""  ,  action="""store_true"""						)







class 	lowerCamelCase__      (      pl.Callback       ):



			def       _lowerCAmelCase	(							self  ,  __UpperCAmelCase  ,  __UpperCAmelCase						)				->  str:
				if (
				    trainer.is_global_zero and trainer.global_rank == 0
				):  # we initialize the retriever only on master worker with RAY. In new pytorch-lightning accelorators are removed.
					pl_module.model.rag.retriever.init_retrieval()  # better to use hook functions.







class 	lowerCamelCase__      (      pl.Callback       ):



			def       _lowerCAmelCase	(							self  ,  __UpperCAmelCase  ,  __UpperCAmelCase						)				->  Optional[int]:
				_lowerCAmelCase			=trainer.lr_schedulers[0]["""scheduler"""]
				_lowerCAmelCase			={f'''lr_group_{i}''': lr for i, lr in enumerate(lr_scheduler.get_lr()						)}
				pl_module.logger.log_metrics(__UpperCAmelCase						)



			def       _lowerCAmelCase	(							self  ,  __UpperCAmelCase  ,  __UpperCAmelCase						)				->  Dict:
				rank_zero_info("""***** Validation results *****"""						)
				_lowerCAmelCase			=trainer.callback_metrics
				# Log results
				for key in sorted(__UpperCAmelCase						):
					if key not in ["log", "progress_bar"]:
						rank_zero_info("""{} = {}\n""".format(__UpperCAmelCase  ,  str(metrics[key]						)						)						)



			def       _lowerCAmelCase	(							self  ,  __UpperCAmelCase  ,  __UpperCAmelCase						)				->  str:
				rank_zero_info("""***** Test results *****"""						)
				_lowerCAmelCase			=trainer.callback_metrics
				# Log and save results to file
				_lowerCAmelCase			=os.path.join(pl_module.hparams.output_dir  ,  """test_results.txt"""						)
				with open(__UpperCAmelCase  ,  """w"""						) as writer:
					for key in sorted(__UpperCAmelCase						):
						if key not in ["log", "progress_bar"]:
							rank_zero_info("""{} = {}\n""".format(__UpperCAmelCase  ,  str(metrics[key]						)						)						)
							writer.write("""{} = {}\n""".format(__UpperCAmelCase  ,  str(metrics[key]						)						)						)







def 					_lowerCamelCase(__UpperCamelCase					,				__UpperCamelCase )       ->				None:
	#  To allow all pl args uncomment the following line
	#  parser = pl.Trainer.add_argparse_args(parser)
	parser.add_argument(
	    """--output_dir"""					,				default=__UpperCamelCase					,				type=__UpperCamelCase					,				required=__UpperCamelCase					,				help="""The output directory where the model predictions and checkpoints will be written."""					,				)
	parser.add_argument(
	    """--fp16"""					,				action="""store_true"""					,				help="""Whether to use 16-bit (mixed) precision (through NVIDIA apex) instead of 32-bit"""					,				)

	parser.add_argument(
	    """--fp16_opt_level"""					,				type=__UpperCamelCase					,				default="""O2"""					,				help=(
	        """For fp16: Apex AMP optimization level selected in ['O0', 'O1', 'O2', and 'O3']."""
	        """See details at https://nvidia.github.io/apex/amp.html"""
	    )					,				)
	parser.add_argument("""--n_tpu_cores"""					,				dest="""tpu_cores"""					,				type=__UpperCamelCase )
	parser.add_argument("""--max_grad_norm"""					,				dest="""gradient_clip_val"""					,				default=1.0					,				type=__UpperCamelCase					,				help="""Max gradient norm""" )
	parser.add_argument("""--do_train"""					,				action="""store_true"""					,				help="""Whether to run training.""" )
	parser.add_argument("""--do_predict"""					,				action="""store_true"""					,				help="""Whether to run predictions on the test set.""" )
	parser.add_argument(
	    """--gradient_accumulation_steps"""					,				dest="""accumulate_grad_batches"""					,				type=__UpperCamelCase					,				default=1					,				help="""Number of updates steps to accumulate before performing a backward/update pass."""					,				)
	parser.add_argument("""--seed"""					,				type=__UpperCamelCase					,				default=42					,				help="""random seed for initialization""" )
	parser.add_argument(
	    """--data_dir"""					,				default=__UpperCamelCase					,				type=__UpperCamelCase					,				required=__UpperCamelCase					,				help="""The input data dir. Should contain the training files for the CoNLL-2003 NER task."""					,				)



def 					_lowerCamelCase(__UpperCamelCase					,				__UpperCamelCase					,				__UpperCamelCase=None					,				__UpperCamelCase=True					,				__UpperCamelCase=None					,				__UpperCamelCase=[]					,				__UpperCamelCase=None					,				__UpperCamelCase=None					,				**__UpperCamelCase					,				)       ->				Optional[Any]:
	pl.seed_everything(args.seed )

	# init model
	_lowerCAmelCase			=Path(model.hparams.output_dir )
	odir.mkdir(exist_ok=__UpperCamelCase )

	# add custom checkpoints
	if checkpoint_callback is None:
		_lowerCAmelCase			=pl.callbacks.ModelCheckpoint(
		    filepath=args.output_dir					,				prefix="""checkpoint"""					,				monitor="""val_loss"""					,				mode="""min"""					,				save_top_k=1 )
	if early_stopping_callback:
		extra_callbacks.append(__UpperCamelCase )
	if logging_callback is None:
		_lowerCAmelCase			=LoggingCallback()

	_lowerCAmelCase			={}

	# TODO: remove with PyTorch 1.6 since pl uses native amp
	if args.fpaa:
		_lowerCAmelCase			=16
		# train_params["amp_level"] = args.fp16_opt_level

	if args.gpus > 1:
		_lowerCAmelCase			="""auto"""  # "ddp"
		_lowerCAmelCase			="""ddp"""

	_lowerCAmelCase			=args.accumulate_grad_batches
	_lowerCAmelCase			=None  # extra_train_kwargs.get("profiler", None) #get unwanted logs
	_lowerCAmelCase			="""auto"""

	_lowerCAmelCase			=pl.Trainer.from_argparse_args(
	    __UpperCamelCase					,				weights_summary=__UpperCamelCase					,				callbacks=[logging_callback] + extra_callbacks + [checkpoint_callback] + [InitCallback()]					,				logger=__UpperCamelCase					,				**__UpperCamelCase					,				)

	if args.do_train:
		trainer.fit(__UpperCamelCase )

	return trainer





"""simple docstring"""


import os
import sys

from . import rsa_key_generator as rkg

__A 		= 128
__A 		= 256



def 					_lowerCamelCase(__UpperCamelCase					,				__UpperCamelCase = DEFAULT_BLOCK_SIZE )       ->				list[int]:
	_lowerCAmelCase			=message.encode("""ascii""" )

	_lowerCAmelCase			=[]
	for block_start in range(0					,				len(__UpperCamelCase )					,				__UpperCamelCase ):
		_lowerCAmelCase			=0
		for i in range(__UpperCamelCase					,				min(block_start + block_size					,				len(__UpperCamelCase ) ) ):
			block_int += message_bytes[i] * (BYTE_SIZE ** (i % block_size))
		block_ints.append(__UpperCamelCase )
	return block_ints



def 					_lowerCamelCase(__UpperCamelCase					,				__UpperCamelCase					,				__UpperCamelCase = DEFAULT_BLOCK_SIZE )       ->				str:
	_lowerCAmelCase			=[]
	for block_int in block_ints:
		_lowerCAmelCase			=[]
		for i in range(block_size - 1					,				-1					,				-1 ):
			if len(__UpperCamelCase ) + i < message_length:
				_lowerCAmelCase			=block_int // (BYTE_SIZE**i)
				_lowerCAmelCase			=block_int % (BYTE_SIZE**i)
				block_message.insert(0					,				chr(__UpperCamelCase ) )
		message.extend(__UpperCamelCase )
	return "".join(__UpperCamelCase )



def 					_lowerCamelCase(__UpperCamelCase					,				__UpperCamelCase					,				__UpperCamelCase = DEFAULT_BLOCK_SIZE )       ->				list[int]:
	_lowerCAmelCase			=[]
	_lowerCAmelCase		,							_lowerCAmelCase			=key

	for block in get_blocks_from_text(__UpperCamelCase					,				__UpperCamelCase ):
		encrypted_blocks.append(pow(__UpperCamelCase					,				__UpperCamelCase					,				__UpperCamelCase ) )
	return encrypted_blocks



def 					_lowerCamelCase(__UpperCamelCase					,				__UpperCamelCase					,				__UpperCamelCase					,				__UpperCamelCase = DEFAULT_BLOCK_SIZE					,				)       ->				str:
	_lowerCAmelCase			=[]
	_lowerCAmelCase		,							_lowerCAmelCase			=key
	for block in encrypted_blocks:
		decrypted_blocks.append(pow(__UpperCamelCase					,				__UpperCamelCase					,				__UpperCamelCase ) )
	return get_text_from_blocks(__UpperCamelCase					,				__UpperCamelCase					,				__UpperCamelCase )



def 					_lowerCamelCase(__UpperCamelCase )       ->				tuple[int, int, int]:
	with open(__UpperCamelCase ) as fo:
		_lowerCAmelCase			=fo.read()
	_lowerCAmelCase		,							_lowerCAmelCase		,							_lowerCAmelCase			=content.split(""",""" )
	return (int(__UpperCamelCase ), int(__UpperCamelCase ), int(__UpperCamelCase ))



def 					_lowerCamelCase(__UpperCamelCase					,				__UpperCamelCase					,				__UpperCamelCase					,				__UpperCamelCase = DEFAULT_BLOCK_SIZE					,				)       ->				str:
	_lowerCAmelCase		,							_lowerCAmelCase		,							_lowerCAmelCase			=read_key_file(__UpperCamelCase )
	if key_size < block_size * 8:
		sys.exit(
		    """ERROR: Block size is {} bits and key size is {} bits. The RSA cipher """
		    """requires the block size to be equal to or greater than the key size. """
		    """Either decrease the block size or use different keys.""".format(
		        block_size * 8					,				__UpperCamelCase ) )

	_lowerCAmelCase			=[str(__UpperCamelCase ) for i in encrypt_message(__UpperCamelCase					,				(n, e)					,				__UpperCamelCase )]

	_lowerCAmelCase			=""",""".join(__UpperCamelCase )
	_lowerCAmelCase			=F'''{len(__UpperCamelCase )}_{block_size}_{encrypted_content}'''
	with open(__UpperCamelCase					,				"""w""" ) as fo:
		fo.write(__UpperCamelCase )
	return encrypted_content



def 					_lowerCamelCase(__UpperCamelCase					,				__UpperCamelCase )       ->				str:
	_lowerCAmelCase		,							_lowerCAmelCase		,							_lowerCAmelCase			=read_key_file(__UpperCamelCase )
	with open(__UpperCamelCase ) as fo:
		_lowerCAmelCase			=fo.read()
	_lowerCAmelCase		,							_lowerCAmelCase		,							_lowerCAmelCase			=content.split("""_""" )
	_lowerCAmelCase			=int(__UpperCamelCase )
	_lowerCAmelCase			=int(__UpperCamelCase )

	if key_size < block_size * 8:
		sys.exit(
		    """ERROR: Block size is {} bits and key size is {} bits. The RSA cipher """
		    """requires the block size to be equal to or greater than the key size. """
		    """Did you specify the correct key file and encrypted file?""".format(
		        block_size * 8					,				__UpperCamelCase ) )

	_lowerCAmelCase			=[]
	for block in encrypted_message.split(""",""" ):
		encrypted_blocks.append(int(__UpperCamelCase ) )

	return decrypt_message(__UpperCamelCase					,				__UpperCamelCase					,				(n, d)					,				__UpperCamelCase )



def 					_lowerCamelCase()       ->				None:
	_lowerCAmelCase			="""encrypted_file.txt"""
	_lowerCAmelCase			=input(R"""Encrypt\Decrypt [e\d]: """ )

	if response.lower().startswith("""e""" ):
		_lowerCAmelCase			="""encrypt"""
	elif response.lower().startswith("""d""" ):
		_lowerCAmelCase			="""decrypt"""

	if mode == "encrypt":
		if not os.path.exists("""rsa_pubkey.txt""" ):
			rkg.make_key_files("""rsa"""					,				1024 )

		_lowerCAmelCase			=input("""\nEnter message: """ )
		_lowerCAmelCase			="""rsa_pubkey.txt"""
		print(F'''Encrypting and writing to {filename}...''' )
		_lowerCAmelCase			=encrypt_and_write_to_file(__UpperCamelCase					,				__UpperCamelCase					,				__UpperCamelCase )

		print("""\nEncrypted text:""" )
		print(__UpperCamelCase )

	elif mode == "decrypt":
		_lowerCAmelCase			="""rsa_privkey.txt"""
		print(F'''Reading from {filename} and decrypting...''' )
		_lowerCAmelCase			=read_from_file_and_decrypt(__UpperCamelCase					,				__UpperCamelCase )
		print("""writing decryption to rsa_decryption.txt...""" )
		with open("""rsa_decryption.txt"""					,				"""w""" ) as dec:
			dec.write(__UpperCamelCase )

		print("""\nDecryption:""" )
		print(__UpperCamelCase )


if __name__ == "__main__":
			main()



