
"""simple docstring"""


from typing import Dict, Tuple, overload

import torch
import torch.types
from torch import nn

from . import residue_constants as rc
from .rigid_utils import Rigid, Rotation
from .tensor_utils import batched_gather



@overload
def        _lowerCamelCase(__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase			)							->					List[str]:
	...



@overload
def        _lowerCamelCase(__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase			)							->					Union[str, Any]:
	...



def        _lowerCamelCase(__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase			)							->					Optional[int]:
	_lowerCAmelCase								=aatype == rc.restype_order["""G"""]
	_lowerCAmelCase								=rc.atom_order["""CA"""]
	_lowerCAmelCase								=rc.atom_order["""CB"""]
	_lowerCAmelCase								=torch.where(
	    is_gly[..., None].expand(*((-1,) * len(is_gly.shape			))       ,					3			)       ,					all_atom_positions[..., ca_idx, :]       ,					all_atom_positions[..., cb_idx, :]       ,					)

	if all_atom_masks is not None:
		_lowerCAmelCase								=torch.where(
		    lowerCAmelCase__       ,					all_atom_masks[..., ca_idx]       ,					all_atom_masks[..., cb_idx]       ,					)
		return pseudo_beta, pseudo_beta_mask
	else:
		return pseudo_beta



def        _lowerCamelCase(__UpperCamelCase       ,					__UpperCamelCase			)							->					int:
	_lowerCAmelCase								=batched_gather(
	    lowerCAmelCase__       ,					batch["""residx_atom37_to_atom14"""]       ,					dim=-2       ,					no_batch_dims=len(atomaa.shape[:-2]			)       ,					)

	_lowerCAmelCase								=atomaa_data * batch["""atom37_atom_exists"""][..., None]

	return atomaa_data



def        _lowerCamelCase(__UpperCamelCase			)							->					Union[str, Any]:
	_lowerCAmelCase								=template_feats["""template_aatype"""]
	_lowerCAmelCase								=template_feats["""template_torsion_angles_sin_cos"""]
	_lowerCAmelCase								=template_feats["""template_alt_torsion_angles_sin_cos"""]
	_lowerCAmelCase								=template_feats["""template_torsion_angles_mask"""]
	_lowerCAmelCase								=torch.cat(
	    [
	        nn.functional.one_hot(lowerCAmelCase__       ,					22			),
	        torsion_angles_sin_cos.reshape(*torsion_angles_sin_cos.shape[:-2]       ,					14			),
	        alt_torsion_angles_sin_cos.reshape(*alt_torsion_angles_sin_cos.shape[:-2]       ,					14			),
	        torsion_angles_mask,
	    ]       ,					dim=-1       ,					)

	return template_angle_feat



def        _lowerCamelCase(__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase = False       ,					__UpperCamelCase = 1E-2_0       ,					__UpperCamelCase = 1E8       ,					)							->					Dict:
	_lowerCAmelCase								=batch["""template_pseudo_beta_mask"""]
	_lowerCAmelCase								=template_mask[..., None] * template_mask[..., None, :]

	# Compute distogram (this seems to differ slightly from Alg. 5)
	_lowerCAmelCase								=batch["""template_pseudo_beta"""]
	_lowerCAmelCase								=torch.sum((tpb[..., None, :] - tpb[..., None, :, :]) ** 2       ,					dim=-1       ,					keepdim=lowerCAmelCase__			)
	_lowerCAmelCase								=torch.linspace(lowerCAmelCase__       ,					lowerCAmelCase__       ,					lowerCAmelCase__       ,					device=tpb.device			) ** 2
	_lowerCAmelCase								=torch.cat([lower[1:], lower.new_tensor([inf]			)]       ,					dim=-1			)
	_lowerCAmelCase								=((dgram > lower) * (dgram < upper)).type(dgram.dtype			)

	_lowerCAmelCase								=[dgram, template_mask_ad[..., None]]

	_lowerCAmelCase								=nn.functional.one_hot(
	    batch["""template_aatype"""]       ,					rc.restype_num + 2       ,					)

	_lowerCAmelCase								=batch["""template_aatype"""].shape[-1]
	to_concat.append(aatype_one_hot[..., None, :, :].expand(*aatype_one_hot.shape[:-2]       ,					lowerCAmelCase__       ,					-1       ,					-1			)			)
	to_concat.append(aatype_one_hot[..., None, :].expand(*aatype_one_hot.shape[:-2]       ,					-1       ,					lowerCAmelCase__       ,					-1			)			)

	_lowerCAmelCase		,				_lowerCAmelCase		,				_lowerCAmelCase								=[rc.atom_order[a] for a in ["""N""", """CA""", """C"""]]
	_lowerCAmelCase								=Rigid.make_transform_from_reference(
	    n_xyz=batch["""template_all_atom_positions"""][..., n, :]       ,					ca_xyz=batch["""template_all_atom_positions"""][..., ca, :]       ,					c_xyz=batch["""template_all_atom_positions"""][..., c, :]       ,					eps=lowerCAmelCase__       ,					)
	_lowerCAmelCase								=rigids.get_trans()[..., None, :, :]
	_lowerCAmelCase								=rigids[..., None].invert_apply(lowerCAmelCase__			)

	_lowerCAmelCase								=torch.rsqrt(eps + torch.sum(rigid_vec**2       ,					dim=-1			)			)

	_lowerCAmelCase								=batch["""template_all_atom_mask"""]
	_lowerCAmelCase								=t_aa_masks[..., n] * t_aa_masks[..., ca] * t_aa_masks[..., c]
	_lowerCAmelCase								=template_mask[..., None] * template_mask[..., None, :]

	_lowerCAmelCase								=inv_distance_scalar * template_mask_ad
	_lowerCAmelCase								=rigid_vec * inv_distance_scalar[..., None]

	if not use_unit_vector:
		_lowerCAmelCase								=unit_vector * 0.0

	to_concat.extend(torch.unbind(unit_vector[..., None, :]       ,					dim=-1			)			)
	to_concat.append(template_mask_ad[..., None]			)

	_lowerCAmelCase								=torch.cat(lowerCAmelCase__       ,					dim=-1			)
	_lowerCAmelCase								=act * template_mask_ad[..., None]

	return act



def        _lowerCamelCase(__UpperCamelCase			)							->					int:
	_lowerCAmelCase								=nn.functional.one_hot(batch["""extra_msa"""]       ,					23			)
	_lowerCAmelCase								=[
	    msa_ahot,
	    batch["""extra_has_deletion"""].unsqueeze(-1			),
	    batch["""extra_deletion_value"""].unsqueeze(-1			),
	]
	return torch.cat(lowerCAmelCase__       ,					dim=-1			)



def        _lowerCamelCase(__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase       ,					)							->					Dict:
	# [*, N, 8, 4, 4]
	_lowerCAmelCase								=rrgdf[aatype, ...]

	# [*, N, 8] transformations, i.e.
	#   One [*, N, 8, 3, 3] rotation matrix and
	#   One [*, N, 8, 3]    translation matrix
	_lowerCAmelCase								=r.from_tensor_axa(lowerCAmelCase__			)

	_lowerCAmelCase								=alpha.new_zeros((*((1,) * len(alpha.shape[:-1]			)), 2)			)
	_lowerCAmelCase								=1

	# [*, N, 8, 2]
	_lowerCAmelCase								=torch.cat([bb_rot.expand(*alpha.shape[:-2]       ,					-1       ,					-1			), alpha]       ,					dim=-2			)

	# [*, N, 8, 3, 3]
	# Produces rotation matrices of the form:
	# [
	#   [1, 0  , 0  ],
	#   [0, a_2,-a_1],
	#   [0, a_1, a_2]
	# ]
	# This follows the original code rather than the supplement, which uses
	# different indices.

	_lowerCAmelCase								=alpha.new_zeros(default_r.get_rots().get_rot_mats().shape			)
	_lowerCAmelCase								=1
	_lowerCAmelCase								=alpha[..., 1]
	_lowerCAmelCase								=-alpha[..., 0]
	_lowerCAmelCase								=alpha

	_lowerCAmelCase								=default_r.compose(Rigid(Rotation(rot_mats=lowerCAmelCase__			)       ,					lowerCAmelCase__			)			)

	_lowerCAmelCase								=all_frames[..., 5]
	_lowerCAmelCase								=all_frames[..., 6]
	_lowerCAmelCase								=all_frames[..., 7]

	_lowerCAmelCase								=all_frames[..., 4]
	_lowerCAmelCase								=chia_frame_to_bb.compose(lowerCAmelCase__			)
	_lowerCAmelCase								=chia_frame_to_bb.compose(lowerCAmelCase__			)
	_lowerCAmelCase								=chia_frame_to_bb.compose(lowerCAmelCase__			)

	_lowerCAmelCase								=Rigid.cat(
	    [
	        all_frames[..., :5],
	        chia_frame_to_bb.unsqueeze(-1			),
	        chia_frame_to_bb.unsqueeze(-1			),
	        chia_frame_to_bb.unsqueeze(-1			),
	    ]       ,					dim=-1       ,					)

	_lowerCAmelCase								=r[..., None].compose(lowerCAmelCase__			)

	return all_frames_to_global



def        _lowerCamelCase(__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase       ,					__UpperCamelCase       ,					)							->					Optional[Any]:
	# [*, N, 14]
	_lowerCAmelCase								=group_idx[aatype, ...]

	# [*, N, 14, 8]
	_lowerCAmelCase								=nn.functional.one_hot(
	    lowerCAmelCase__       ,					num_classes=default_frames.shape[-3]       ,					)

	# [*, N, 14, 8]
	_lowerCAmelCase								=r[..., None, :] * group_mask_one_hot

	# [*, N, 14]
	_lowerCAmelCase								=t_atoms_to_global.map_tensor_fn(lambda __UpperCamelCase			: torch.sum(lowerCAmelCase__       ,					dim=-1			)			)

	# [*, N, 14, 1]
	_lowerCAmelCase								=atom_mask[aatype, ...].unsqueeze(-1			)

	# [*, N, 14, 3]
	_lowerCAmelCase								=lit_positions[aatype, ...]
	_lowerCAmelCase								=t_atoms_to_global.apply(lowerCAmelCase__			)
	_lowerCAmelCase								=pred_positions * atom_mask

	return pred_positions




import random
import sys

from . import cryptomath_module as cryptomath

lowerCAmelCase__      		=					(
    r' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`'
    r'abcdefghijklmnopqrstuvwxyz{|}~'
)






def  __lowerCamelCase						(		lowerCAmelCase__      ,    lowerCAmelCase__      ,    lowerCAmelCase__      ):
       if mode == "encrypt":
              if key_a == 1:
                     sys.exit(
                         'The affine cipher becomes weak when key '
                         'A is set to 1. Choose different key'      )
              if key_b == 0:
                     sys.exit(
                         'The affine cipher becomes weak when key '
                         'B is set to 0. Choose different key'      )
       if key_a < 0 or key_b < 0 or key_b > len(lowerCAmelCase__      ) - 1:
              sys.exit(
                  'Key A must be greater than 0 and key B must '
                  F"""be between 0 and {len(lowerCAmelCase__      ) - 1}."""      )
       if cryptomath.gcd(lowerCAmelCase__      ,    len(lowerCAmelCase__      )      ) != 1:
              sys.exit(
                  F"""Key A {key_a} and the symbol set size {len(lowerCAmelCase__      )} """
                  'are not relatively prime. Choose a different key.'      )






def  __lowerCamelCase						(		lowerCAmelCase__      ,    lowerCAmelCase__      ):
       lowerCAmelCase__      ,   lowerCAmelCase__	      =   divmod(lowerCAmelCase__      ,    len(lowerCAmelCase__      )      )
       check_keys(lowerCAmelCase__      ,    lowerCAmelCase__      ,    'encrypt'      )
       lowerCAmelCase__	      =   ''
       for symbol in message:
              if symbol in SYMBOLS:
                     lowerCAmelCase__	      =   SYMBOLS.find(lowerCAmelCase__      )
                     cipher_text += SYMBOLS[(sym_index * key_a + key_b) % len(lowerCAmelCase__      )]
              else:
                     cipher_text += symbol
       return cipher_text






def  __lowerCamelCase						(		lowerCAmelCase__      ,    lowerCAmelCase__      ):
       lowerCAmelCase__      ,   lowerCAmelCase__	      =   divmod(lowerCAmelCase__      ,    len(lowerCAmelCase__      )      )
       check_keys(lowerCAmelCase__      ,    lowerCAmelCase__      ,    'decrypt'      )
       lowerCAmelCase__	      =   ''
       lowerCAmelCase__	      =   cryptomath.find_mod_inverse(lowerCAmelCase__      ,    len(lowerCAmelCase__      )      )
       for symbol in message:
              if symbol in SYMBOLS:
                     lowerCAmelCase__	      =   SYMBOLS.find(lowerCAmelCase__      )
                     plain_text += SYMBOLS[
                         (sym_index - key_b) * mod_inverse_of_key_a % len(lowerCAmelCase__      )
                     ]
              else:
                     plain_text += symbol
       return plain_text






def  __lowerCamelCase						(		):
       while True:
              lowerCAmelCase__	      =   random.randint(2      ,    len(lowerCAmelCase__      )      )
              lowerCAmelCase__	      =   random.randint(2      ,    len(lowerCAmelCase__      )      )
              if cryptomath.gcd(lowerCAmelCase__      ,    len(lowerCAmelCase__      )      ) == 1 and key_b % len(lowerCAmelCase__      ) != 0:
                     return key_b * len(lowerCAmelCase__      ) + key_b






def  __lowerCamelCase						(		):
       lowerCAmelCase__	      =   input('Enter message: '      ).strip()
       lowerCAmelCase__	      =   int(input('Enter key [2000 - 9000]: '      ).strip()      )
       lowerCAmelCase__	      =   input('Encrypt/Decrypt [E/D]: '      ).strip().lower()

       if mode.startswith('e'      ):
              lowerCAmelCase__	      =   'encrypt'
              lowerCAmelCase__	      =   encrypt_message(lowerCAmelCase__      ,    lowerCAmelCase__      )
       elif mode.startswith('d'      ):
              lowerCAmelCase__	      =   'decrypt'
              lowerCAmelCase__	      =   decrypt_message(lowerCAmelCase__      ,    lowerCAmelCase__      )
       print(F"""\n{mode.title()}ed text: \n{translated}"""      )


if __name__ == "__main__":
    import doctest

    doctest.testmod()
    # main()
