





import dataclasses
import re
import string
from typing import Any, Dict, Iterator, List, Mapping, Optional, Sequence, Tuple

import numpy as np

from . import residue_constants


__A									=				Mapping[str, np.ndarray]
__A									=				Mapping[str, Any]  # Is a nested dict.
__A									=				0.0_1



@dataclasses.dataclass(frozen=__SCREAMING_SNAKE_CASE    )
class    _SCREAMING_SNAKE_CASE						:







 '''simple docstring'''
 lowercase_		=			42  # [num_res, num_atom_type, 3]

 # Amino-acid type for each residue represented as an integer between 0 and
 # 20, where 20 is 'X'.
 lowercase_		=			42  # [num_res]

 # Binary float mask to indicate presence of a particular atom. 1.0 if an atom
 # is present and 0.0 if not. This should be used for loss masking.
 lowercase_		=			42  # [num_res, num_atom_type]

 # Residue index as used in PDB. It is not necessarily continuous or 0-indexed.
 lowercase_		=			42  # [num_res]

 # B-factors, or temperature factors, of each residue (in sq. angstroms units),
 # representing the displacement of the residue from its ground truth mean
 # value.
 lowercase_		=			42  # [num_res, num_atom_type]

 # Chain indices for multi-chain predictions
 lowercase_		=			None

 # Optional remark about the protein. Included as a comment in output PDB
 # files
 lowercase_		=			None

 # Templates used to generate this protein (prediction-only)
 lowercase_		=			None

 # Chain corresponding to each parent
 lowercase_		=			None





def      lowerCAmelCase_ (       __a		)     ->		Protein:







  """simple docstring"""





  lowerCamelCase__:      Union[str, Any]			  =R"(\[[A-Z]+\]\n)"
  lowerCamelCase__:      List[str]			  =[tag.strip() for tag in re.split(__a	,    __a		) if len(__a		) > 0]
  lowerCamelCase__:      Iterator[Tuple[str, List[str]]]			  =zip(tags[0::2]	,    [l.split("\n"		) for l in tags[1::2]]		)

  lowerCamelCase__:      List[str]			  =["N", "CA", "C"]
  lowerCamelCase__:      int			  =None
  lowerCamelCase__:      str			  =None
  lowerCamelCase__:      Dict			  =None
  for g in groups:
    if "[PRIMARY]" == g[0]:
      lowerCamelCase__:      Optional[Any]			  =g[1][0].strip()
      for i in range(len(__a		)		):
        if seq[i] not in residue_constants.restypes:
          lowerCamelCase__:      Optional[int]			  ="X"  # FIXME: strings are immutable
      lowerCamelCase__:      Optional[int]			  =np.array(
          [residue_constants.restype_order.get(__a	,    residue_constants.restype_num		) for res_symbol in seq]		)
    elif "[TERTIARY]" == g[0]:
      lowerCamelCase__:      List[List[float]]			  =[]
      for axis in range(3		):
        tertiary.append(list(map(__a	,    g[1][axis].split()		)		)		)
      lowerCamelCase__:      List[str]			  =np.array(__a		)
      lowerCamelCase__:      List[str]			  =np.zeros((len(tertiary[0]		) // 3, residue_constants.atom_type_num, 3)		).astype(np.floataa		)
      for i, atom in enumerate(__a		):
        lowerCamelCase__:      str			  =np.transpose(tertiary_np[:, i::3]		)
      atom_positions *= PICO_TO_ANGSTROM
    elif "[MASK]" == g[0]:
      lowerCamelCase__:      int			  =np.array(list(map({"-": 0, "+": 1}.get	,    g[1][0].strip()		)		)		)
      lowerCamelCase__:      Dict			  =np.zeros(
          (
              len(__a		),
              residue_constants.atom_type_num,
          )		).astype(np.floataa		)
      for i, atom in enumerate(__a		):
        lowerCamelCase__:      int			  =1
      atom_mask *= mask[..., None]

  assert aatype is not None

  return Protein(
      atom_positions=__a	,    atom_mask=__a	,    aatype=__a	,    residue_index=np.arange(len(__a		)		)	,    b_factors=__a	,    )





def      lowerCAmelCase_ (       __a	,    __a = 0		)     ->		List[str]:







  """simple docstring"""





  lowerCamelCase__:      List[str]			  =[]

  lowerCamelCase__:      Optional[Any]			  =prot.remark
  if remark is not None:
    pdb_headers.append(F"""REMARK {remark}"""		)

  lowerCamelCase__:      List[str]			  =prot.parents
  lowerCamelCase__:      Optional[int]			  =prot.parents_chain_index
  if parents is not None and parents_chain_index is not None:
    lowerCamelCase__:      int			  =[p for i, p in zip(__a	,    __a		) if i == chain_id]

  if parents is None or len(__a		) == 0:
    lowerCamelCase__:      Optional[int]			  =["N/A"]

  pdb_headers.append(F"""PARENT {" ".join(__a		)}"""		)

  return pdb_headers





def      lowerCAmelCase_ (       __a	,    __a		)     ->		str:







  """simple docstring"""





  lowerCamelCase__:      List[str]			  =[]
  lowerCamelCase__:      Any			  =pdb_str.split("\n"		)

  lowerCamelCase__:      Optional[Any]			  =prot.remark
  if remark is not None:
    out_pdb_lines.append(F"""REMARK {remark}"""		)

  lowerCamelCase__:      List[List[str]]
  if prot.parents is not None and len(prot.parents		) > 0:
    lowerCamelCase__:      int			  =[]
    if prot.parents_chain_index is not None:
      lowerCamelCase__:      Dict[str, List[str]]			  ={}
      for p, i in zip(prot.parents	,    prot.parents_chain_index		):
        parent_dict.setdefault(str(__a		)	,    []		)
        parent_dict[str(__a		)].append(__a		)

      lowerCamelCase__:      List[Any]			  =max([int(__a		) for chain_idx in parent_dict]		)
      for i in range(max_idx + 1		):
        lowerCamelCase__:      Optional[Any]			  =parent_dict.get(str(__a		)	,    ["N/A"]		)
        parents_per_chain.append(__a		)
    else:
      parents_per_chain.append(list(prot.parents		)		)
  else:
    lowerCamelCase__:      Optional[Any]			  =[["N/A"]]

  def make_parent_line(__a		) -> str:
    return F"""PARENT {" ".join(__a		)}"""

  out_pdb_lines.append(make_parent_line(parents_per_chain[0]		)		)

  lowerCamelCase__:      Optional[int]			  =0
  for i, l in enumerate(__a		):
    if "PARENT" not in l and "REMARK" not in l:
      out_pdb_lines.append(__a		)
    if "TER" in l and "END" not in lines[i + 1]:
      chain_counter += 1
      if not chain_counter >= len(__a		):
        lowerCamelCase__:      Union[str, Any]			  =parents_per_chain[chain_counter]
      else:
        lowerCamelCase__:      int			  =["N/A"]

      out_pdb_lines.append(make_parent_line(__a		)		)

  return "\n".join(__a		)





def      lowerCAmelCase_ (       __a		)     ->		str:







  """simple docstring"""





  lowerCamelCase__:      str			  =residue_constants.restypes + ["X"]

  def res_atoa(__a		) -> str:
    return residue_constants.restype_atoa.get(restypes[r]	,    "UNK"		)

  lowerCamelCase__:      List[str]			  =residue_constants.atom_types

  lowerCamelCase__:      List[str]			  =[]

  lowerCamelCase__:      Any			  =prot.atom_mask
  lowerCamelCase__:      str			  =prot.aatype
  lowerCamelCase__:      Optional[int]			  =prot.atom_positions
  lowerCamelCase__:      List[str]			  =prot.residue_index.astype(np.intaa		)
  lowerCamelCase__:      List[str]			  =prot.b_factors
  lowerCamelCase__:      str			  =prot.chain_index

  if np.any(aatype > residue_constants.restype_num		):
    raise ValueError("Invalid aatypes."		)

  lowerCamelCase__:      str			  =get_pdb_headers(__a		)
  if len(__a		) > 0:
    pdb_lines.extend(__a		)

  lowerCamelCase__:      Dict			  =aatype.shape[0]
  lowerCamelCase__:      Dict			  =1
  lowerCamelCase__:      List[Any]			  =0
  lowerCamelCase__:      Optional[Any]			  =string.ascii_uppercase
  lowerCamelCase__:      List[str]			  =None
  # Add all atom sites.
  for i in range(__a		):
    lowerCamelCase__:      Any			  =res_atoa(aatype[i]		)
    for atom_name, pos, mask, b_factor in zip(__a	,    atom_positions[i]	,    atom_mask[i]	,    b_factors[i]		):
      if mask < 0.5:
        continue

      lowerCamelCase__:      Union[str, Any]			  ="ATOM"
      lowerCamelCase__:      Union[str, Any]			  =atom_name if len(__a		) == 4 else F""" {atom_name}"""
      lowerCamelCase__:      int			  =""
      lowerCamelCase__:      List[str]			  =""
      lowerCamelCase__:      int			  =1.0_0
      lowerCamelCase__:      Optional[int]			  =atom_name[0]  # Protein supports only C, N, O, S, this works.
      lowerCamelCase__:      Dict			  =""

      lowerCamelCase__:      Union[str, Any]			  ="A"
      if chain_index is not None:
        lowerCamelCase__:      Any			  =chain_tags[chain_index[i]]

      # PDB is a columnar format, every space matters here!
      lowerCamelCase__:      str			  =(
          F"""{record_type:<6}{atom_index:>5} {name:<4}{alt_loc:>1}"""
          F"""{res_name_a:>3} {chain_tag:>1}"""
          F"""{residue_index[i]:>4}{insertion_code:>1}   """
          F"""{pos[0]:>8.3f}{pos[1]:>8.3f}{pos[2]:>8.3f}"""
          F"""{occupancy:>6.2f}{b_factor:>6.2f}          """
          F"""{element:>2}{charge:>2}"""
      )
      pdb_lines.append(__a		)
      atom_index += 1

    lowerCamelCase__:      Optional[Any]			  =i == n - 1
    if chain_index is not None:
      if i != n - 1 and chain_index[i + 1] != prev_chain_index:
        lowerCamelCase__:      List[str]			  =True
        lowerCamelCase__:      Optional[int]			  =chain_index[i + 1]

    if should_terminate:
      # Close the chain.
      lowerCamelCase__:      str			  ="TER"
      lowerCamelCase__:      List[Any]			  =(
          F"""{chain_end:<6}{atom_index:>5}      {res_atoa(aatype[i]		):>3} {chain_tag:>1}{residue_index[i]:>4}"""
      )
      pdb_lines.append(__a		)
      atom_index += 1

      if i != n - 1:
        # "prev" is a misnomer here. This happens at the beginning of
        # each new chain.
        pdb_lines.extend(get_pdb_headers(__a	,    __a		)		)

  pdb_lines.append("END"		)
  pdb_lines.append(""		)
  return "\n".join(__a		)





def      lowerCAmelCase_ (       __a		)     ->		np.ndarray:







  """simple docstring"""





  return residue_constants.STANDARD_ATOM_MASK[prot.aatype]






def      lowerCAmelCase_ (       __a	,    __a	,    __a = None	,    __a = None	,    __a = None	,    __a = None	,    __a = None	,    )     ->		Protein:







  """simple docstring"""





  return Protein(
      aatype=features["aatype"]	,    atom_positions=result["final_atom_positions"]	,    atom_mask=result["final_atom_mask"]	,    residue_index=features["residue_index"] + 1	,    b_factors=b_factors if b_factors is not None else np.zeros_like(result["final_atom_mask"]		)	,    chain_index=__a	,    remark=__a	,    parents=__a	,    parents_chain_index=__a	,    )





def 			_a (      SCREAMING_SNAKE_CASE     ):


		"""simple docstring"""




		return credit_card_number.startswith(('''34''', '''35''', '''37''', '''4''', '''5''', '''6''')     )
def 			_a (      SCREAMING_SNAKE_CASE     ):


		"""simple docstring"""




		lowercase__            =      credit_card_number
		lowercase__            =      0
		lowercase__            =      len(SCREAMING_SNAKE_CASE     ) - 2
		for i in range(SCREAMING_SNAKE_CASE						,				-1						,				-2     ):
				#  double the value of every second digit
				lowercase__            =      int(cc_number[i]     )
				digit *= 2
				# If doubling of a number results in a two digit number
				# i.e greater than 9(e.g., 6 × 2 = 12),
				# then add the digits of the product (e.g., 12: 1 + 2 = 3, 15: 1 + 5 = 6),
				# to get a single digit number.
				if digit > 9:
						digit %= 10
						digit += 1
				lowercase__            =      cc_number[:i] + str(SCREAMING_SNAKE_CASE     ) + cc_number[i + 1 :]
				total += digit

		# Sum up the remaining digits
		for i in range(len(SCREAMING_SNAKE_CASE     ) - 1						,				-1						,				-2     ):
				total += int(cc_number[i]     )

		return total % 10 == 0
def 			_a (      SCREAMING_SNAKE_CASE     ):


		"""simple docstring"""




		lowercase__            =      f'{credit_card_number} is an invalid credit card number because'
		if not credit_card_number.isdigit():
				print(f'{error_message} it has nonnumerical characters.'     )
				return False

		if not 13 <= len(SCREAMING_SNAKE_CASE     ) <= 16:
				print(f'{error_message} of its length.'     )
				return False

		if not validate_initial_digits(SCREAMING_SNAKE_CASE     ):
				print(f'{error_message} of its first two digits.'     )
				return False

		if not luhn_validation(SCREAMING_SNAKE_CASE     ):
				print(f'{error_message} it fails the Luhn check.'     )
				return False

		print(f'{credit_card_number} is a valid credit card number.'     )
		return True


if __name__ == "__main__":
			import doctest

			doctest.testmod()
			validate_credit_card_number('4111111111111111')
			validate_credit_card_number('32323')


