"""simple docstring"""


from __future__ import annotations

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






class 					a					(				A_							):
  A_ :				Optional[int] 			=							1
  A_ :				int 			=							2
  A_ :				Dict 			=							3



  def __repr__(		self   :    Any     )      -> Optional[Any]:
      return F"""{self.__class__.__name__}.{self.name}"""

def 						UpperCamelCase				(	_lowerCAmelCase   :							tuple[int, int]				, _lowerCAmelCase   :							int				, _lowerCAmelCase   :							int						):
    __a      ,  __a			      =						point
    return degrees(atana(y - miny				, x - minx						)						)

def 						UpperCamelCase				(	_lowerCAmelCase   :							tuple[int, int]				, _lowerCAmelCase   :							tuple[int, int]				, _lowerCAmelCase   :							tuple[int, int]						):
    __a      ,  __a			      =						starting
    __a      ,  __a			      =						via
    __a      ,  __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				(	_lowerCAmelCase   :							list[tuple[int, int]]						):

    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      ,  __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 _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)						)

    __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"""


from doctest import testmod
from math import sqrt

def 						UpperCamelCase				(	_lowerCAmelCase   :							int						):
    __a			      =						[]
    if num < 1:
        return facs
    facs.append(1						)
    if num == 1:
        return facs
    facs.append(_lowerCAmelCase						)
    for i in range(2				, int(sqrt(_lowerCAmelCase						)						) + 1						):
        if num % i == 0:  # If i is a factor of num
            facs.append(_lowerCAmelCase						)
            __a			      =						num // i  # num//i is the other factor of num
            if d != i:  # If d and i are distinct
                facs.append(_lowerCAmelCase						)  # we have found another factor
    facs.sort()
    return facs


if __name__ == "__main__":
 testmod(name="""factors_of_a_number""", verbose=True)
