






from __future__ import annotations

from collections import deque
from enum import Enum
from math import atana, degrees
from sys import maxsize
class 							A_      (  __lowercase     ):






 '''simple docstring'''




 _SCREAMING_SNAKE_CASE							:     Optional[Any]	=   1
 _SCREAMING_SNAKE_CASE							:     Dict	=   2
 _SCREAMING_SNAKE_CASE							:     Tuple	=   3


 def __repr__(		self)	->						List[str]:

     """simple docstring"""



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



def        _lowerCamelCase		(  __A      :							tuple[int, int]						,						__A      :							int						,						__A      :							int	) ->   float:
    _UpperCAmelCase					,	_UpperCAmelCase			: Tuple     					=			point
    return degrees(atana(y - miny						,						x - minx	)	)

def        _lowerCamelCase		(  __A      :							tuple[int, int]						,						__A      :							tuple[int, int]						,						__A      :							tuple[int, int]	) ->   Direction:
    _UpperCAmelCase					,	_UpperCAmelCase			: Tuple     					=			starting
    _UpperCAmelCase					,	_UpperCAmelCase			: List[Any]     					=			via
    _UpperCAmelCase					,	_UpperCAmelCase			: List[str]     					=			target
    _UpperCAmelCase			: Dict     					=			degrees(atana(ya - ya						,						xa - xa	)	)
    via_angle %= 360
    _UpperCAmelCase			: Dict     					=			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        _lowerCamelCase		(  __A      :							list[tuple[int, int]]	) ->   list[tuple[int, int]]:

    if len(__A	) <= 2:
        # There is no convex hull
        raise ValueError('''graham_scan: argument must contain more than 3 points.'''	)
    if len(__A	) == 3:
        return points
    # find the lowest and the most left point
    _UpperCAmelCase			: Dict     					=			0
    _UpperCAmelCase					,	_UpperCAmelCase			: List[Any]     					=			maxsize, maxsize
    for i, point in enumerate(__A	):
        _UpperCAmelCase			: Optional[int]     					=			point[0]
        _UpperCAmelCase			: str     					=			point[1]
        if y < miny:
            _UpperCAmelCase			: Optional[Any]     					=			y
            _UpperCAmelCase			: List[Any]     					=			x
            _UpperCAmelCase			: str     					=			i
        if y == miny and x < minx:
            _UpperCAmelCase			: Dict     					=			x
            _UpperCAmelCase			: List[Any]     					=			i

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

    _UpperCAmelCase			: Optional[int]     					=			sorted(__A						,						key=lambda __A	: angle_comparer(__A						,						__A						,						__A	)	)
    # 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)	)

    _UpperCAmelCase			: deque[tuple[int, int]]     					=			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.
    _UpperCAmelCase			: Dict     					=			Direction.left

    for i in range(3						,						len(__A	)	):
        while True:
            _UpperCAmelCase			: Any     					=			stack[-2]
            _UpperCAmelCase			: str     					=			stack[-1]
            _UpperCAmelCase			: List[Any]     					=			sorted_points[i]
            _UpperCAmelCase			: Tuple     					=			check_direction(__A						,						__A						,						__A	)

            if next_direction == Direction.left:
                _UpperCAmelCase			: List[Any]     					=			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(__A	)












from unittest.mock import patch

import datasets
from datasets import Dataset

def        _lowerCamelCase		(  ) ->   Tuple:
    _UpperCAmelCase			: Union[str, Any]     					=			Dataset.from_dict({'''col_1''': [3, 2, 0, 1]}	)

    with patch('''tqdm.auto.tqdm'''	) as mock_tqdm:
        datasets.disable_progress_bar()
        dset.map(lambda __A	: {"col_2": x["col_1"] + 1}	)
        mock_tqdm.assert_not_called()

        mock_tqdm.reset_mock()

        datasets.enable_progress_bar()
        dset.map(lambda __A	: {"col_2": x["col_1"] + 1}	)
        mock_tqdm.assert_called()




