






from __future__ import annotations

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




class      __SCREAMING_SNAKE_CASE					(A__					):


  """simple docstring"""


  _a     :   List[str]			 =    1
  _a     :   Optional[Any]			 =    2
  _a     :   Dict			 =    3







  def __repr__( self  ):






         """simple docstring"""


         return f'{self.__class__.__name__}.{self.name}'





def 			__UpperCamelCase				(			lowercase_					:     int      ,					lowercase_					:     List[Any]      ,					lowercase_					:     List[str]      ):
       """simple docstring"""




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


def 			__UpperCamelCase				(			lowercase_					:     List[str]      ,					lowercase_					:     List[Any]      ,					lowercase_					:     Tuple      ):
       """simple docstring"""




       a_	    = starting
       a_	    = via
       a_	    = target
       a_	    = degrees(atana(ya - ya      ,					xa - xa      )      )
       via_angle %= 360
       a_	    = 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 			__UpperCamelCase				(			lowercase_					:     List[str]      ):
       """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
       a_	    = 0
       a_	    = maxsize, maxsize
       for i, point in enumerate(__lowerCAmelCase      ):
              a_	    = point[0]
              a_	    = point[1]
              if y < miny:
                     a_	    = y
                     a_	    = x
                     a_	    = i
              if y == miny and x < minx:
                     a_	    = x
                     a_	    = i

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

       a_	    = sorted(__lowerCAmelCase      ,					key=lambda lowercase_      : 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)      )

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

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

                     if next_direction == Direction.left:
                            a_	    = 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'''







def 			__UpperCamelCase				(			lowercase_					:     int      ):
       """simple docstring"""




       if not isinstance(lowercase_      ,					lowercase_      ):
              raise ValueError('double_factorial() only accepts integral values'      )
       if num < 0:
              raise ValueError('double_factorial() not defined for negative values'      )
       a_	    = 1
       for i in range(lowercase_      ,					0      ,					-2      ):
              value *= i
       return value


if __name__ == "__main__":
  import doctest

  doctest.testmod()




