
import logging

import torch
from torch import nn
from torch.nn import CrossEntropyLoss, MSELoss

from transformers.file_utils import add_start_docstrings, add_start_docstrings_to_model_forward
from transformers.models.albert.modeling_albert import (
    ALBERT_INPUTS_DOCSTRING,
    ALBERT_START_DOCSTRING,
    AlbertModel,
    AlbertPreTrainedModel,
    AlbertTransformer,
)


__lowerCamelCase								=					logging.getLogger(__name__)
class    _UpperCamelCase(   SCREAMING_SNAKE_CASE				):

						def 						a__ (					self		:			Tuple	,						_lowerCamelCase		:			Dict	,						_lowerCamelCase		:			List[str]	,						_lowerCamelCase		:			Dict=None	,						_lowerCamelCase		:			List[Any]=None			):
													if current_layer == 0:
																				_UpperCAmelCase  :			str	       =		self.embedding_hidden_mapping_in(_lowerCamelCase			)
													else:
																				_UpperCAmelCase  :			Any	       =		hidden_states[0]

													_UpperCAmelCase  :			List[Any]	       =		int(self.config.num_hidden_layers / self.config.num_hidden_groups			)

													# Index of the hidden group
													_UpperCAmelCase  :			Optional[int]	       =		int(current_layer / (self.config.num_hidden_layers / self.config.num_hidden_groups)			)

													_UpperCAmelCase  :			Tuple	       =		self.albert_layer_groups[group_idx](
													    _lowerCamelCase	,						_lowerCamelCase	,						head_mask[group_idx * layers_per_group : (group_idx + 1) * layers_per_group]	,						)
													_UpperCAmelCase  :			List[Any]	       =		layer_group_output[0]

													return (hidden_states,)







@add_start_docstrings(
    """The bare ALBERT Model transformer with PABEE outputting raw hidden-states without any specific head on top."""		,						SCREAMING_SNAKE_CASE		,						)
class    _UpperCamelCase(   SCREAMING_SNAKE_CASE				):

						def __init__(					self		:			List[str]	,						_lowerCamelCase		:			Optional[int]			):
													super().__init__(_lowerCamelCase			)

													_UpperCAmelCase  :			List[str]	       =		AlbertTransformerWithPabee(_lowerCamelCase			)

													self.init_weights()
													_UpperCAmelCase  :			str	       =		0
													_UpperCAmelCase  :			List[Any]	       =		0
													_UpperCAmelCase  :			List[str]	       =		0

													_UpperCAmelCase  :			str	       =		0

						def 						a__ (					self		:			List[Any]	,						_lowerCamelCase		:			Optional[Any]			):
													_UpperCAmelCase  :			Optional[int]	       =		threshold

						def 						a__ (					self		:			Optional[int]	,						_lowerCamelCase		:			Optional[Any]			):
													_UpperCAmelCase  :			str	       =		patience

						def 						a__ (					self		:			Union[str, Any]			):
													_UpperCAmelCase  :			int	       =		0
													_UpperCAmelCase  :			Optional[int]	       =		0

						def 						a__ (					self		:			Optional[int]			):
													_UpperCAmelCase  :			Tuple	       =		self.inference_layers_num / self.inference_instances_num
													_UpperCAmelCase  :			Optional[int]	       =		(
													    f"""*** Patience = {self.patience} Avg. Inference Layers = {avg_inf_layers:.2f} Speed Up ="""
													    f""" {1 - avg_inf_layers / self.config.num_hidden_layers:.2f} ***"""
													)
													print(_lowerCamelCase			)






						@add_start_docstrings_to_model_forward(_lowerCamelCase			)
						def 						a__ (					self		:			Dict	,						_lowerCamelCase		:			List[str]=None	,						_lowerCamelCase		:			Optional[Any]=None	,						_lowerCamelCase		:			List[Any]=None	,						_lowerCamelCase		:			Union[str, Any]=None	,						_lowerCamelCase		:			int=None	,						_lowerCamelCase		:			Dict=None	,						_lowerCamelCase		:			Optional[Any]=None	,						_lowerCamelCase		:			Optional[int]=None	,						_lowerCamelCase		:			Union[str, Any]=False	,						):

													if input_ids is not None and inputs_embeds is not None:
																				raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time"			)
													elif input_ids is not None:
																				_UpperCAmelCase  :			List[Any]	       =		input_ids.size()
													elif inputs_embeds is not None:
																				_UpperCAmelCase  :			Optional[Any]	       =		inputs_embeds.size()[:-1]
													else:
																				raise ValueError("You have to specify either input_ids or inputs_embeds"			)

													_UpperCAmelCase  :			int	       =		input_ids.device if input_ids is not None else inputs_embeds.device

													if attention_mask is None:
																				_UpperCAmelCase  :			int	       =		torch.ones(_lowerCamelCase	,						device=_lowerCamelCase			)
													if token_type_ids is None:
																				_UpperCAmelCase  :			Tuple	       =		torch.zeros(_lowerCamelCase	,						dtype=torch.long	,						device=_lowerCamelCase			)

													_UpperCAmelCase  :			Optional[Any]	       =		attention_mask.unsqueeze(1			).unsqueeze(2			)
													_UpperCAmelCase  :			str	       =		extended_attention_mask.to(dtype=self.dtype			)  # fp16 compatibility
													_UpperCAmelCase  :			Any	       =		(1.0 - extended_attention_mask) * -1_00_00.0
													_UpperCAmelCase  :			str	       =		self.get_head_mask(_lowerCamelCase	,						self.config.num_hidden_layers			)

													_UpperCAmelCase  :			str	       =		self.embeddings(
													    _lowerCamelCase	,						position_ids=_lowerCamelCase	,						token_type_ids=_lowerCamelCase	,						inputs_embeds=_lowerCamelCase			)
													_UpperCAmelCase  :			Tuple	       =		embedding_output

													if self.training:
																				_UpperCAmelCase  :			str	       =		[]
																				for i in range(self.config.num_hidden_layers			):
																											_UpperCAmelCase  :			str	       =		self.encoder.adaptive_forward(
																											    _lowerCamelCase	,						current_layer=_lowerCamelCase	,						attention_mask=_lowerCamelCase	,						head_mask=_lowerCamelCase	,						)

																											_UpperCAmelCase  :			List[Any]	       =		self.pooler_activation(self.pooler(encoder_outputs[0][:, 0]			)			)
																											_UpperCAmelCase  :			Any	       =		output_layers[i](output_dropout(_lowerCamelCase			)			)
																											res.append(_lowerCamelCase			)
													elif self.patience == 0:  # Use all layers for inference
																				_UpperCAmelCase  :			List[str]	       =		self.encoder(_lowerCamelCase	,						_lowerCamelCase	,						head_mask=_lowerCamelCase			)
																				_UpperCAmelCase  :			List[str]	       =		self.pooler_activation(self.pooler(encoder_outputs[0][:, 0]			)			)
																				_UpperCAmelCase  :			int	       =		[output_layers[self.config.num_hidden_layers - 1](_lowerCamelCase			)]
													else:
																				_UpperCAmelCase  :			Optional[Any]	       =		0
																				_UpperCAmelCase  :			str	       =		None
																				_UpperCAmelCase  :			Optional[Any]	       =		0
																				for i in range(self.config.num_hidden_layers			):
																											calculated_layer_num += 1
																											_UpperCAmelCase  :			Optional[int]	       =		self.encoder.adaptive_forward(
																											    _lowerCamelCase	,						current_layer=_lowerCamelCase	,						attention_mask=_lowerCamelCase	,						head_mask=_lowerCamelCase	,						)

																											_UpperCAmelCase  :			Any	       =		self.pooler_activation(self.pooler(encoder_outputs[0][:, 0]			)			)
																											_UpperCAmelCase  :			str	       =		output_layers[i](_lowerCamelCase			)
																											if regression:
																																		_UpperCAmelCase  :			Dict	       =		logits.detach()
																																		if patient_result is not None:
																																									_UpperCAmelCase  :			List[Any]	       =		patient_result.detach()
																																		if (patient_result is not None) and torch.abs(patient_result - labels			) < self.regression_threshold:
																																									patient_counter += 1
																																		else:
																																									_UpperCAmelCase  :			str	       =		0
																											else:
																																		_UpperCAmelCase  :			List[str]	       =		logits.detach().argmax(dim=1			)
																																		if patient_result is not None:
																																									_UpperCAmelCase  :			List[Any]	       =		patient_result.detach().argmax(dim=1			)
																																		if (patient_result is not None) and torch.all(labels.eq(_lowerCamelCase			)			):
																																									patient_counter += 1
																																		else:
																																									_UpperCAmelCase  :			Optional[Any]	       =		0

																											_UpperCAmelCase  :			Dict	       =		logits
																											if patient_counter == self.patience:
																																		break
																				_UpperCAmelCase  :			Union[str, Any]	       =		[patient_result]
																				self.inference_layers_num += calculated_layer_num
																				self.inference_instances_num += 1

													return res







@add_start_docstrings(
    """Albert Model transformer with PABEE and a sequence classification/regression head on top (a linear layer on top of
    the pooled output) e.g. for GLUE tasks. """		,						SCREAMING_SNAKE_CASE		,						)
class    _UpperCamelCase(   SCREAMING_SNAKE_CASE				):

						def __init__(					self		:			Dict	,						_lowerCamelCase		:			str			):
													super().__init__(_lowerCamelCase			)
													_UpperCAmelCase  :			str	       =		config.num_labels

													_UpperCAmelCase  :			Optional[Any]	       =		AlbertModelWithPabee(_lowerCamelCase			)
													_UpperCAmelCase  :			Tuple	       =		nn.Dropout(config.classifier_dropout_prob			)
													_UpperCAmelCase  :			Optional[Any]	       =		nn.ModuleList(
													    [nn.Linear(config.hidden_size	,						self.config.num_labels			) for _ in range(config.num_hidden_layers			)]			)

													self.init_weights()






						@add_start_docstrings_to_model_forward(_lowerCamelCase			)
						def 						a__ (					self		:			Optional[Any]	,						_lowerCamelCase		:			Any=None	,						_lowerCamelCase		:			Optional[int]=None	,						_lowerCamelCase		:			Optional[int]=None	,						_lowerCamelCase		:			Union[str, Any]=None	,						_lowerCamelCase		:			List[str]=None	,						_lowerCamelCase		:			Optional[Any]=None	,						_lowerCamelCase		:			List[str]=None	,						):
													_UpperCAmelCase  :			List[str]	       =		self.albert(
													    input_ids=_lowerCamelCase	,						attention_mask=_lowerCamelCase	,						token_type_ids=_lowerCamelCase	,						position_ids=_lowerCamelCase	,						head_mask=_lowerCamelCase	,						inputs_embeds=_lowerCamelCase	,						output_dropout=self.dropout	,						output_layers=self.classifiers	,						regression=self.num_labels == 1	,						)

													_UpperCAmelCase  :			Optional[Any]	       =		(logits[-1],)

													if labels is not None:
																				_UpperCAmelCase  :			int	       =		None
																				_UpperCAmelCase  :			Union[str, Any]	       =		0
																				for ix, logits_item in enumerate(_lowerCamelCase			):
																											if self.num_labels == 1:
																																		#  We are doing regression
																																		_UpperCAmelCase  :			Optional[int]	       =		MSELoss()
																																		_UpperCAmelCase  :			Optional[int]	       =		loss_fct(logits_item.view(-1			)	,						labels.view(-1			)			)
																											else:
																																		_UpperCAmelCase  :			int	       =		CrossEntropyLoss()
																																		_UpperCAmelCase  :			int	       =		loss_fct(logits_item.view(-1	,						self.num_labels			)	,						labels.view(-1			)			)
																											if total_loss is None:
																																		_UpperCAmelCase  :			Optional[Any]	       =		loss
																											else:
																																		total_loss += loss * (ix + 1)
																											total_weights += ix + 1
																				_UpperCAmelCase  :			Optional[int]	       =		(total_loss / total_weights,) + outputs

													return outputs






from __future__ import annotations

from string import ascii_letters




def 		lowerCAmelCase_     (     _SCREAMING_SNAKE_CASE      ,	_SCREAMING_SNAKE_CASE      ,	_SCREAMING_SNAKE_CASE = None  )   ->      str:

							"""simple docstring"""






							_UpperCAmelCase  :			List[Any]	       =		alphabet or ascii_letters

							# The final result string
							_UpperCAmelCase  :			Optional[Any]	       =		""

							for character in input_string:
														if character not in alpha:
																					# Append without encryption if character is not in the alphabet
																					result += character
														else:
																					# Get the index of the new key and make sure it isn't too large
																					_UpperCAmelCase  :			Any	       =		(alpha.index(_SCREAMING_SNAKE_CASE  ) + key) % len(_SCREAMING_SNAKE_CASE  )

																					# Append the encoded character to the alphabet
																					result += alpha[new_key]

							return result




def 		lowerCAmelCase_     (     _SCREAMING_SNAKE_CASE      ,	_SCREAMING_SNAKE_CASE      ,	_SCREAMING_SNAKE_CASE = None  )   ->      str:

							"""simple docstring"""






							key *= -1

							return encrypt(_SCREAMING_SNAKE_CASE      ,	_SCREAMING_SNAKE_CASE      ,	_SCREAMING_SNAKE_CASE  )




def 		lowerCAmelCase_     (     _SCREAMING_SNAKE_CASE      ,	_SCREAMING_SNAKE_CASE = None  )   ->      dict[int, str]:

							"""simple docstring"""






							_UpperCAmelCase  :			Any	       =		alphabet or ascii_letters

							# To store data on all the combinations
							_UpperCAmelCase  :			Dict	       =		{}

							# Cycle through each combination
							for key in range(1      ,	len(_SCREAMING_SNAKE_CASE  ) + 1  ):
														# Decrypt the message and store the result in the data
														_UpperCAmelCase  :			Union[str, Any]	       =		decrypt(_SCREAMING_SNAKE_CASE      ,	_SCREAMING_SNAKE_CASE      ,	_SCREAMING_SNAKE_CASE  )

							return brute_force_data


if __name__ == "__main__":
				while True:
								print(f'''\n{'-' * 1_0}\n Menu\n{'-' * 1_0}''')
								print(*['1.Encrypt', '2.Decrypt', '3.BruteForce', '4.Quit'], sep='\n')

								# get user input
								__lowerCamelCase								=					input('\nWhat would you like to do?: ').strip() or '4'

								# run functions based on what the user chose
								if choice not in ("1", "2", "3", "4"):
												print('Invalid choice, please enter a valid choice')
								elif choice == "1":
												__lowerCamelCase								=					input('Please enter the string to be encrypted: ')
												__lowerCamelCase								=					int(input('Please enter off-set: ').strip())

												print(encrypt(input_string, key))
								elif choice == "2":
												__lowerCamelCase								=					input('Please enter the string to be decrypted: ')
												__lowerCamelCase								=					int(input('Please enter off-set: ').strip())

												print(decrypt(input_string, key))
								elif choice == "3":
												__lowerCamelCase								=					input('Please enter the string to be decrypted: ')
												__lowerCamelCase								=					brute_force(input_string)

												for key, value in brute_force_data.items():
																print(f'''Key: {key} | Message: {value}''')

								elif choice == "4":
												print('Goodbye.')
												break




