



"""simple docstring"""







from __future__ import annotations

from scipy.special import comb  # type: ignore







class 				UpperCamelCase__       :




      """simple docstring"""




      def __init__(				self    :				Dict   ,      SCREAMING_SNAKE_CASE_    :				list[tuple[float, float]]	):
        lowerCAmelCase_       :    List[str]								=			list_of_points
        # Degree determines the flexibility of the curve.
        # Degree = 1 will produce a straight line.
        lowerCAmelCase_       :    Any								=			len(UpperCAmelCase__	) - 1



      def 					SCREAMING_SNAKE_CASE__			(				self    :				str   ,      SCREAMING_SNAKE_CASE_    :				float	):
        assert 0 <= t <= 1, "Time t must be between 0 and 1."
        lowerCAmelCase_       :    Optional[Any]								=			[]
        for i in range(len(self.list_of_points	)	):
          # basis function for each i
          output_values.append(
              comb(self.degree   ,      UpperCAmelCase__	) * ((1 - t) ** (self.degree - i)) * (t**i)	)
        # the basis must sum up to 1 for it to produce a valid Bezier curve.
        assert round(sum(UpperCAmelCase__	)   ,      5	) == 1
        return output_values



      def 					SCREAMING_SNAKE_CASE__			(				self    :				Union[str, Any]   ,      SCREAMING_SNAKE_CASE_    :				float	):
        assert 0 <= t <= 1, "Time t must be between 0 and 1."

        lowerCAmelCase_       :    Union[str, Any]								=			self.basis_function(UpperCAmelCase__	)
        lowerCAmelCase_       :    Any								=			0.0
        lowerCAmelCase_       :    Optional[Any]								=			0.0
        for i in range(len(self.list_of_points	)	):
          # For all points, sum up the product of i-th basis function and i-th point.
          x += basis_function[i] * self.list_of_points[i][0]
          y += basis_function[i] * self.list_of_points[i][1]
        return (x, y)





      def 					SCREAMING_SNAKE_CASE__			(				self    :				Optional[int]   ,      SCREAMING_SNAKE_CASE_    :				float = 0.01	):
        from matplotlib import pyplot as plt  # type: ignore

        lowerCAmelCase_       :    str								=			[]  # x coordinates of points to plot
        lowerCAmelCase_       :    List[str]								=			[]  # y coordinates of points to plot

        lowerCAmelCase_       :    List[str]								=			0.0
        while t <= 1:
          lowerCAmelCase_       :    Any								=			self.bezier_curve_function(UpperCAmelCase__	)
          to_plot_x.append(value[0]	)
          to_plot_y.append(value[1]	)
          t += step_size

        lowerCAmelCase_       :    List[Any]								=			[i[0] for i in self.list_of_points]
        lowerCAmelCase_       :    List[str]								=			[i[1] for i in self.list_of_points]

        plt.plot(
            UpperCAmelCase__   ,      UpperCAmelCase__   ,      color='blue'   ,      label='Curve of Degree ' + str(self.degree	)   ,      )
        plt.scatter(UpperCAmelCase__   ,      UpperCAmelCase__   ,      color='red'   ,      label='Control Points'	)
        plt.legend()
        plt.show()


if __name__ == "__main__":
     import doctest

     doctest.testmod()

     BezierCurve([(1, 2), (3, 5)]).plot_curve()  # degree 1
     BezierCurve([(0, 0), (5, 5), (5, 0)]).plot_curve()  # degree 2
     BezierCurve([(0, 0), (5, 5), (5, 0), (2.5, -2.5)]).plot_curve()  # degree 3










"""simple docstring"""







from __future__ import annotations

def     UpperCamelCase_   (   lowerCAmelCase__				:    int						)						->       list[int]:

  """simple docstring"""




  lowerCAmelCase_       :    Any								=			2
  lowerCAmelCase_       :    List[Any]								=			[]
  while i * i <= n:
    if n % i:
      i += 1
    else:
      n //= i
      factors.append(lowerCAmelCase__						)
  if n > 1:
    factors.append(lowerCAmelCase__						)
  return factors


if __name__ == "__main__":
     import doctest

     doctest.testmod()





