
"""simple docstring"""





from __future__ import annotations

_a														=		tuple[int, int, int]
_a														=		tuple[str, str, str]


# used alphabet --------------------------
# from string.ascii_uppercase
_a														=		"""ABCDEFGHIJKLMNOPQRSTUVWXYZ"""

# -------------------------- default selection --------------------------
# rotors --------------------------
_a														=		"""EGZWVONAHDCLFQMSIPJBYUKXTR"""
_a														=		"""FOBHMDKEXQNRAULPGSJVTYICZW"""
_a														=		"""ZJXESIUQLHAVRMDOYGTNFWPBKC"""
# reflector --------------------------
_a														=		{
    """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 --------------------------
_a														=		"""RMDJXFUWGISLHVTCQNKYPBEZOA"""
_a														=		"""SGLCPQWZHKXAREONTFBVIYJUDM"""
_a														=		"""HVSICLTYKQUBXDWAJZOMFGPREN"""
_a														=		"""RZWQHFMVDBKICJLNTUXAGYPSOE"""
_a														=		"""LFKIJODBEGAMQPXVUHYSTCZRWN"""
_a														=		"""KOAEGVDHXPQZMLFTYWJNBRCIUS"""



def       lowerCamelCase__		(			__snake_case,     __snake_case,     __snake_case	)							->		Optional[int]:


					"""simple docstring"""





					if (unique_rotsel := len(set(lowerCAmelCase__	)	)) < 3:
										_UpperCamelCase							 =  F'''Please use 3 unique rotors (not {unique_rotsel})'''
										raise Exception(lowerCAmelCase__	)

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

					# Validates string and returns dict
					_UpperCamelCase							 =  _plugboard(lowerCAmelCase__	)

					return rotpos, rotsel, pbdict



def       lowerCamelCase__		(			__snake_case	)							->		List[str]:


					"""simple docstring"""





					if not isinstance(lowerCAmelCase__,     lowerCAmelCase__	):
										_UpperCamelCase							 =  F'''Plugboard setting isn\'t type string ({type(lowerCAmelCase__	)})'''
										raise TypeError(lowerCAmelCase__	)
					elif len(lowerCAmelCase__	) % 2 != 0:
										_UpperCamelCase							 =  F'''Odd number of symbols ({len(lowerCAmelCase__	)})'''
										raise Exception(lowerCAmelCase__	)
					elif pbstring == "":
										return {}

					pbstring.replace(''' ''',     ''''''	)

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

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

					return pb



def       lowerCamelCase__		(			__snake_case,     __snake_case,     __snake_case = (rotora, rotora, rotora),     __snake_case = "",     )							->		List[Any]:


					"""simple docstring"""





					_UpperCamelCase							 =  text.upper()
					_UpperCamelCase							 =  _validator(
					    lowerCAmelCase__,     lowerCAmelCase__,     plugb.upper()	)

					_UpperCamelCase							 =  rotor_position
					_UpperCamelCase							 =  rotor_selection
					rotorposa -= 1
					rotorposa -= 1
					rotorposa -= 1

					_UpperCamelCase							 =  []

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

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

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

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

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

															_UpperCamelCase							 =  reflector[symbol]

															# 2nd rotors
															_UpperCamelCase							 =  abc[rotora.index(lowerCAmelCase__	) - rotorposa]
															_UpperCamelCase							 =  abc[rotora.index(lowerCAmelCase__	) - rotorposa]
															_UpperCamelCase							 =  abc[rotora.index(lowerCAmelCase__	) - rotorposa]

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

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

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

					return "".join(lowerCAmelCase__	)


if __name__ == "__main__":
				_a														=		"""This is my Python script that emulates the Enigma machine from WWII."""
				_a														=		(1, 1, 1)
				_a														=		"""pictures"""
				_a														=		(rotora, rotora, rotora)
				_a														=		enigma(message, rotor_pos, rotor_sel, pb)

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








import string

# frequency taken from https://en.wikipedia.org/wiki/Letter_frequency
lowercase__       ={
    'E': 12.70,
    'T': 9.06,
    'A': 8.17,
    'O': 7.51,
    'I': 6.97,
    'N': 6.75,
    'S': 6.33,
    'H': 6.09,
    'R': 5.99,
    'D': 4.25,
    'L': 4.03,
    'C': 2.78,
    'U': 2.76,
    'M': 2.41,
    'W': 2.36,
    'F': 2.23,
    'G': 2.02,
    'Y': 1.97,
    'P': 1.93,
    'B': 1.29,
    'V': 0.98,
    'K': 0.77,
    'J': 0.15,
    'X': 0.15,
    'Q': 0.10,
    'Z': 0.07,
}
lowercase__       ='ETAOINSHRDLCUMWFGYPBVKJXQZ'
lowercase__       ='ABCDEFGHIJKLMNOPQRSTUVWXYZ'




def    __UpperCamelCase     (				lowerCAmelCase__							:				str  ):
 __a :  List[Any]						=  {letter: 0 for letter in string.ascii_uppercase}
 for letter in message.upper():
  if letter in LETTERS:
   letter_count[letter] += 1

 return letter_count




def    __UpperCamelCase     (				lowerCAmelCase__							:				tuple  ):
 return x[0]




def    __UpperCamelCase     (				lowerCAmelCase__							:				str  ):
 __a :  Optional[Any]						=  get_letter_count(lowerCAmelCase__  )
 __a :  dict[int, list[str]]						=  {
     freq: [] for letter, freq in letter_to_freq.items()
 }
 for letter in LETTERS:
  freq_to_letter[letter_to_freq[letter]].append(lowerCAmelCase__  )

 __a :  dict[int, str]						=  {}

 for freq in freq_to_letter:
  freq_to_letter[freq].sort(key=ETAOIN.find  ,   reverse=lowerCAmelCase__  )
  __a :  int						=  ''''''.join(freq_to_letter[freq]  )

 __a :  Any						=  list(freq_to_letter_str.items()  )
 freq_pairs.sort(key=lowerCAmelCase__  ,   reverse=lowerCAmelCase__  )

 __a :  list[str]						=  [freq_pair[1] for freq_pair in freq_pairs]

 return "".join(lowerCAmelCase__  )




def    __UpperCamelCase     (				lowerCAmelCase__							:				str  ):
 __a :  int						=  get_frequency_order(lowerCAmelCase__  )
 __a :  str						=  0
 for common_letter in ETAOIN[:6]:
  if common_letter in freq_order[:6]:
   match_score += 1

 for uncommon_letter in ETAOIN[-6:]:
  if uncommon_letter in freq_order[-6:]:
   match_score += 1

 return match_score


if __name__ == "__main__":
      import doctest

      doctest.testmod()
