


"""simple docstring"""




from __future__ import annotations

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




class  __snake_case      (UpperCamelCase__     ):
							__a				   =					1
							__a				   =					2
							__a				   =					3




							def __repr__(    self:						int      ):
										return f'{self.__class__.__name__}.{self.name}'





def 			a_   (  lowercase__   :tuple[int, int], lowercase__   :int, lowercase__   :int    ):
			__lowerCamelCase        =			point
			return degrees(atana(y - miny, x - minx    )    )





def 			a_   (  lowercase__   :tuple[int, int], lowercase__   :tuple[int, int], lowercase__   :tuple[int, int]    ):
			__lowerCamelCase        =			starting
			__lowerCamelCase        =			via
			__lowerCamelCase        =			target
			__lowerCamelCase        =			degrees(atana(ya - ya, xa - xa    )    )
			via_angle %= 360
			__lowerCamelCase        =			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 			a_   (  lowercase__   :list[tuple[int, int]]    ):



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

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

			__lowerCamelCase        =			sorted(lowercase__, key=lambda lowercase__    : angle_comparer(lowercase__, lowercase__, lowercase__    )    )
			# 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)    )

			__lowerCamelCase        =			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.
			__lowerCamelCase        =			Direction.left

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

									if next_direction == Direction.left:
												__lowerCamelCase        =			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(lowercase__    )








"""simple docstring"""




# Lint as: python3

import hashlib
from typing import Union





def 			a_   (  lowercase__   :Union[str, int, bytes]    ):
			if isinstance(lowercase__, lowercase__    ):
						# Data already in bytes, returns as it as
						return hash_data
			elif isinstance(lowercase__, lowercase__    ):
						# We keep the data as it as for it ot be later encoded to UTF-8
						# However replace `\\` with `/` for Windows compatibility
						__lowerCamelCase        =			hash_data.replace("""\\""", """/"""    )
			elif isinstance(lowercase__, lowercase__    ):
						__lowerCamelCase        =			str(lowercase__    )
			else:
						# If data is not of the required type, raise error
						raise InvalidKeyError(lowercase__    )

			return hash_data.encode("""utf-8"""    )




class  __snake_case      (lowerCamelCase     ):




							def __init__(    self:						Union[str, Any]    ,       A_:						Tuple      ):
										__lowerCamelCase        =			"""\nFAILURE TO GENERATE DATASET: Invalid key type detected"""
										__lowerCamelCase        =			f'\nFound Key {hash_data} of type {type(A_      )}'
										__lowerCamelCase        =			"""\nKeys should be either str, int or bytes type"""
										super().__init__(f'{self.prefix}{self.err_msg}{self.suffix}'      )




class  __snake_case      (lowerCamelCase     ):




							def __init__(    self:						Any    ,       A_:						Dict    ,       A_:						List[Any]    ,       A_:						List[str]=""      ):
										__lowerCamelCase        =			key
										__lowerCamelCase        =			duplicate_key_indices
										__lowerCamelCase        =			fix_msg
										__lowerCamelCase        =			"""Found multiple examples generated with the same key"""
										if len(A_      ) <= 20:
													__lowerCamelCase        =			f'\nThe examples at index {", ".join(A_      )} have the key {key}'
										else:
													__lowerCamelCase        =			f'\nThe examples at index {", ".join(duplicate_key_indices[:20]      )}... ({len(A_      ) - 20} more) have the key {key}'
										__lowerCamelCase        =			"""\n""" + fix_msg if fix_msg else """"""
										super().__init__(f'{self.prefix}{self.err_msg}{self.suffix}'      )




class  __snake_case      :




							def __init__(    self:						Dict    ,       A_:						str      ):
										__lowerCamelCase        =			hashlib.mda(_as_bytes(A_      )      )




							def      __a      (    self:						int    ,       A_:						Union[str, int, bytes]      ):
										__lowerCamelCase        =			self._split_mda.copy()
										__lowerCamelCase        =			_as_bytes(A_      )
										mda.update(A_      )
										# Convert to integer with hexadecimal conversion
										return int(mda.hexdigest()    ,       16      )




