code: 
  
  
  
  
  
  
  from __future__ import annotations
  
  from collections import deque
  from enum import Enum
  from math import atana, degrees
  from sys import maxsize
  
  
  
  
  
  class     __a						(					A__ ):
   _lowerCAmelCase : List[str] 				=				1
   _lowerCAmelCase : Optional[Any] 				=				2
   _lowerCAmelCase : Dict 				=				3
  
  
  
  
  
  
  
   def __repr__(	self      :     List[Any]		):
  
  
        '''simple docstring'''
  
  
  
  
  
  
        return F'{self.__class__.__name__}.{self.name}'
  
  
  
  
  
  
  
  def 	SCREAMING_SNAKE_CASE							(      __lowerCAmelCase      ,					__lowerCAmelCase      ,					__lowerCAmelCase    )				->			float:
       UpperCamelCase__       ,  UpperCamelCase__    :     Any        =						point
       return degrees(atana(y - miny      ,					x - minx    )    )
  
  
  
  
  
  
  
  def 	SCREAMING_SNAKE_CASE							(      __lowerCAmelCase      ,					__lowerCAmelCase      ,					__lowerCAmelCase    )				->			Direction:
       UpperCamelCase__       ,  UpperCamelCase__    :     Optional[Any]        =						starting
       UpperCamelCase__       ,  UpperCamelCase__    :     Tuple        =						via
       UpperCamelCase__       ,  UpperCamelCase__    :     Optional[Any]        =						target
       UpperCamelCase__    :     List[str]        =						degrees(atana(ya - ya      ,					xa - xa    )    )
       via_angle %= 360
       UpperCamelCase__    :     int        =						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 	SCREAMING_SNAKE_CASE							(      __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
       UpperCamelCase__    :     Any        =						0
       UpperCamelCase__       ,  UpperCamelCase__    :     Optional[int]        =						maxsize, maxsize
       for i, point in enumerate(__lowerCAmelCase    ):
            UpperCamelCase__    :     List[str]        =						point[0]
            UpperCamelCase__    :     Any        =						point[1]
            if y < miny:
                 UpperCamelCase__    :     str        =						y
                 UpperCamelCase__    :     int        =						x
                 UpperCamelCase__    :     List[str]        =						i
            if y == miny and x < minx:
                 UpperCamelCase__    :     Any        =						x
                 UpperCamelCase__    :     Union[str, Any]        =						i
  
      # remove the lowest and the most left point from points for preparing for sort
       points.pop(__lowerCAmelCase    )
  
       UpperCamelCase__    :     List[Any]        =						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)    )
  
       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(__lowerCAmelCase    )    ):
            while True:
                 UpperCamelCase__    :     Dict        =						stack[-2]
                 UpperCamelCase__    :     List[str]        =						stack[-1]
                 UpperCamelCase__    :     List[str]        =						sorted_points[i]
                 UpperCamelCase__    :     Optional[int]        =						check_direction(__lowerCAmelCase      ,					__lowerCAmelCase      ,					__lowerCAmelCase    )
  
                 if next_direction == Direction.left:
                      UpperCamelCase__    :     Dict        =						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    )
style_context: 
  
  
  
  
  
  
  def 	SCREAMING_SNAKE_CASE							(      __lowerCAmelCase    )				->			str:
       if len(__lowerCAmelCase    ) == 0 or not all(len(__lowerCAmelCase    ) == 2 for pair in coordinates    ):
            raise ValueError("The program cannot work out a fitting polynomial."    )
  
       if len({tuple(__lowerCAmelCase    ) for pair in coordinates}    ) != len(__lowerCAmelCase    ):
            raise ValueError("The program cannot work out a fitting polynomial."    )
  
       UpperCamelCase__    :     List[str]        =						{x for x, _ in coordinates}
       if len(__lowerCAmelCase    ) == 1:
            return f'x={coordinates[0][0]}'
  
       if len(__lowerCAmelCase    ) != len(__lowerCAmelCase    ):
            raise ValueError("The program cannot work out a fitting polynomial."    )
  
       UpperCamelCase__    :     Any        =						len(__lowerCAmelCase    )
  
       UpperCamelCase__    :     str        =						0
       UpperCamelCase__    :     list[list[float]]        =						[]
       # put the x and x to the power values in a matrix
       while count_of_line < x:
            UpperCamelCase__    :     int        =						0
            UpperCamelCase__    :     List[Any]        =						coordinates[count_of_line][0]
            UpperCamelCase__    :     list[float]        =						[]
            while count_in_line < x:
                 count_line.append(a ** (x - (count_in_line + 1))    )
                 count_in_line += 1
            matrix.append(__lowerCAmelCase    )
            count_of_line += 1
  
       UpperCamelCase__    :     List[Any]        =						0
       # put the y values into a vector
       UpperCamelCase__    :     list[float]        =						[]
       while count_of_line < x:
            vector.append(coordinates[count_of_line][1]    )
            count_of_line += 1
  
       UpperCamelCase__    :     Tuple        =						0
  
       while count < x:
            UpperCamelCase__    :     Dict        =						0
            while zahlen < x:
                 if count == zahlen:
                      zahlen += 1
                 if zahlen == x:
                      break
                 UpperCamelCase__    :     Optional[Any]        =						matrix[zahlen][count] / matrix[count][count]
                 for counting_columns, item in enumerate(matrix[count]    ):
                      # manipulating all the values in the matrix
                      matrix[zahlen][counting_columns] -= item * bruch
                 # manipulating the values in the vector
                 vector[zahlen] -= vector[count] * bruch
                 zahlen += 1
            count += 1
  
       UpperCamelCase__    :     Tuple        =						0
       # make solutions
       UpperCamelCase__    :     list[str]        =						[]
       while count < x:
            solution.append(str(vector[count] / matrix[count][count]    )    )
            count += 1
  
       UpperCamelCase__    :     int        =						0
       UpperCamelCase__    :     List[str]        =						"f(x)="
  
       while count < x:
            UpperCamelCase__    :     list[str]        =						solution[count].split("E"    )
            if len(__lowerCAmelCase    ) > 1:
                 UpperCamelCase__    :     Union[str, Any]        =						f'{remove_e[0]}*10^{remove_e[1]}'
            solved += f'x^{x - (count + 1)}*{solution[count]}'
            if count + 1 != x:
                 solved += "+"
            count += 1
  
       return solved
  
  
  if __name__ == "__main__":
   print(points_to_polynomial([]))
   print(points_to_polynomial([[]]))
   print(points_to_polynomial([[1, 0], [2, 0], [3, 0]]))
   print(points_to_polynomial([[1, 1], [2, 1], [3, 1]]))
   print(points_to_polynomial([[1, 3], [2, 3], [3, 3]]))
   print(points_to_polynomial([[1, 1], [2, 2], [3, 3]]))
   print(points_to_polynomial([[1, 1], [2, 4], [3, 9]]))
   print(points_to_polynomial([[1, 3], [2, 6], [3, 11]]))
   print(points_to_polynomial([[1, -3], [2, -6], [3, -11]]))
   print(points_to_polynomial([[1, 5], [2, 2], [3, 9]]))