


'''simple docstring'''
from __future__ import annotations

from collections import deque
from enum import Enum
from math import atana, degrees
from sys import maxsize






class 		UpperCamelCase_		(					A   ):





						"""simple docstring"""




						UpperCAmelCase__	:       int         =     1
						UpperCAmelCase__	:       Optional[int]         =     2
						UpperCAmelCase__	:       Union[str, Any]         =     3
						def __repr__( self				:					Tuple  )							->					str:
										return f'{self.__class__.__name__}.{self.name}'





def      __snake_case       (       lowerCamelCase_ :				tuple[int, int]	,  lowerCamelCase_ :				int	,  lowerCamelCase_ :				int						):
				'''simple docstring'''




				__magic_name__  ,      __magic_name__	  = point
				return degrees(atana(y - miny	,  x - minx						)						)




def      __snake_case       (       lowerCamelCase_ :				tuple[int, int]	,  lowerCamelCase_ :				tuple[int, int]	,  lowerCamelCase_ :				tuple[int, int]						):
				'''simple docstring'''




				__magic_name__  ,      __magic_name__	  = starting
				__magic_name__  ,      __magic_name__	  = via
				__magic_name__  ,      __magic_name__	  = target
				__magic_name__	  = degrees(atana(ya - ya	,  xa - xa						)						)
				via_angle %= 360
				__magic_name__	  = degrees(atana(ya - ya	,  xa - xa						)						)
				target_angle %= 360
				# t-
				#  \ \
				#   \ v
				#    \|
				#     s
				# via_angle is always lower than target_angle, if direction is left.
				# If they are same, it means they are on a same line of convex hull.
				if target_angle > via_angle:
								return Direction.left
				elif target_angle == via_angle:
								return Direction.straight
				else:
								return Direction.right




def      __snake_case       (       lowerCamelCase_ :				list[tuple[int, int]]						):
				'''simple docstring'''




				if len(lowerCamelCase_						) <= 2:
								# There is no convex hull
								raise ValueError("graham_scan: argument must contain more than 3 points."						)
				if len(lowerCamelCase_						) == 3:
								return points
				# find the lowest and the most left point
				__magic_name__	  = 0
				__magic_name__  ,      __magic_name__	  = maxsize, maxsize
				for i, point in enumerate(lowerCamelCase_						):
								__magic_name__	  = point[0]
								__magic_name__	  = point[1]
								if y < miny:
												__magic_name__	  = y
												__magic_name__	  = x
												__magic_name__	  = i
								if y == miny and x < minx:
												__magic_name__	  = x
												__magic_name__	  = i

    # remove the lowest and the most left point from points for preparing for sort
				points.pop(lowerCamelCase_						)

				__magic_name__	  = sorted(lowerCamelCase_	,  key=lambda lowerCamelCase_						: angle_comparer(lowerCamelCase_	,  lowerCamelCase_	,  lowerCamelCase_						)						)
				# This insert actually costs complexity,
				# and you should instead add (minx, miny) into stack later.
				# I'm using insert just for easy understanding.
				sorted_points.insert(0	,  (minx, miny)						)

				__magic_name__	  = deque()
				stack.append(sorted_points[0]						)
				stack.append(sorted_points[1]						)
				stack.append(sorted_points[2]						)
				# In any ways, the first 3 points line are towards left.
				# Because we sort them the angle from minx, miny.
				__magic_name__	  = Direction.left

				for i in range(3	,  len(lowerCamelCase_						)						):
								while True:
												__magic_name__	  = stack[-2]
												__magic_name__	  = stack[-1]
												__magic_name__	  = sorted_points[i]
												__magic_name__	  = check_direction(lowerCamelCase_	,  lowerCamelCase_	,  lowerCamelCase_						)

												if next_direction == Direction.left:
																__magic_name__	  = Direction.left
																break
												if next_direction == Direction.straight:
																if current_direction == Direction.left:
																				# We keep current_direction as left.
																				# Because if the straight line keeps as straight,
																				# we want to know if this straight line is towards left.
																				break
																elif current_direction == Direction.right:
																				# If the straight line is towards right,
																				# every previous points on those straigh line is not convex hull.
																				stack.pop()
												if next_direction == Direction.right:
																stack.pop()
								stack.append(sorted_points[i]						)
				return list(lowerCamelCase_						)







'''simple docstring'''
import os
import sys
import time

from . import transposition_cipher as trans_cipher




def      __snake_case       (       ):
				'''simple docstring'''




				__magic_name__	  = "Prehistoric Men.txt"
				__magic_name__	  = "Output.txt"
				__magic_name__	  = int(input("Enter key: "						)						)
				__magic_name__	  = input("Encrypt/Decrypt [e/d]: "						)

				if not os.path.exists(lowerCamelCase_						):
								print(F'File {input_file} does not exist. Quitting...'						)
								sys.exit()
				if os.path.exists(lowerCamelCase_						):
								print(F'Overwrite {output_file}? [y/n]'						)
								__magic_name__	  = input("> "						)
								if not response.lower().startswith("y"						):
												sys.exit()

				__magic_name__	  = time.time()
				if mode.lower().startswith("e"						):
								with open(lowerCamelCase_						) as f:
												__magic_name__	  = f.read()
								__magic_name__	  = trans_cipher.encrypt_message(lowerCamelCase_	,  lowerCamelCase_						)
				elif mode.lower().startswith("d"						):
								with open(lowerCamelCase_						) as f:
												__magic_name__	  = f.read()
								__magic_name__	  = trans_cipher.decrypt_message(lowerCamelCase_	,  lowerCamelCase_						)

				with open(lowerCamelCase_	,  "w"						) as output_obj:
								output_obj.write(lowerCamelCase_						)

				__magic_name__	  = round(time.time() - start_time	,  2						)
				print(("Done (", total_time, "seconds )")						)


if __name__ == "__main__":
						main()



