



"""simple docstring"""







import os
import string
import sys


UpperCamelCase     =							1 << 8

UpperCamelCase     =							{
    """tab""": ord("""\t"""),
    """newline""": ord("""\r"""),
    """esc""": 27,
    """up""": 65 + ARROW_KEY_FLAG,
    """down""": 66 + ARROW_KEY_FLAG,
    """right""": 67 + ARROW_KEY_FLAG,
    """left""": 68 + ARROW_KEY_FLAG,
    """mod_int""": 91,
    """undefined""": sys.maxsize,
    """interrupt""": 3,
    """insert""": 50,
    """delete""": 51,
    """pg_up""": 53,
    """pg_down""": 54,
}

UpperCamelCase     =							KEYMAP["""up"""]
UpperCamelCase     =							KEYMAP["""left"""]

if sys.platform == "win32":
			UpperCamelCase     =							[]
			UpperCamelCase     =							{
			    b"""\xe0H""": KEYMAP["""up"""] - ARROW_KEY_FLAG,
			    b"""\x00H""": KEYMAP["""up"""] - ARROW_KEY_FLAG,
			    b"""\xe0P""": KEYMAP["""down"""] - ARROW_KEY_FLAG,
			    b"""\x00P""": KEYMAP["""down"""] - ARROW_KEY_FLAG,
			    b"""\xe0M""": KEYMAP["""right"""] - ARROW_KEY_FLAG,
			    b"""\x00M""": KEYMAP["""right"""] - ARROW_KEY_FLAG,
			    b"""\xe0K""": KEYMAP["""left"""] - ARROW_KEY_FLAG,
			    b"""\x00K""": KEYMAP["""left"""] - ARROW_KEY_FLAG,
			}

for i in range(10):
			UpperCamelCase     =							ord(str(i))

def       _lowerCamelCase				(							)	-> int:






	"""simple docstring"""





	if os.name == "nt":
		import msvcrt

		A__											=					"mbcs"
		# Flush the keyboard buffer
		while msvcrt.kbhit():
			msvcrt.getch()
		if len(UpperCAmelCase_     ) == 0:
			# Read the keystroke
			A__											=					msvcrt.getch()

			# If it is a prefix char, get second part
			if ch in (b"\x00", b"\xe0"):
				A__											=					ch + msvcrt.getch()
				# Translate actual Win chars to bullet char types
				try:
					A__											=					chr(WIN_KEYMAP[cha]     )
					WIN_CH_BUFFER.append(chr(KEYMAP["mod_int"]     )     )
					WIN_CH_BUFFER.append(UpperCAmelCase_     )
					if ord(UpperCAmelCase_     ) in (
					    KEYMAP["insert"] - 1 << 9,
					    KEYMAP["delete"] - 1 << 9,
					    KEYMAP["pg_up"] - 1 << 9,
					    KEYMAP["pg_down"] - 1 << 9,
					):
						WIN_CH_BUFFER.append(chr(126     )     )
					A__											=					chr(KEYMAP["esc"]     )
				except KeyError:
					A__											=					cha[1]
			else:
				A__											=					ch.decode(UpperCAmelCase_     )
		else:
			A__											=					WIN_CH_BUFFER.pop(0     )
	elif os.name == "posix":
		import termios
		import tty

		A__											=					sys.stdin.fileno()
		A__											=					termios.tcgetattr(UpperCAmelCase_     )
		try:
			tty.setraw(UpperCAmelCase_     )
			A__											=					sys.stdin.read(1     )
		finally:
			termios.tcsetattr(UpperCAmelCase_,	termios.TCSADRAIN,	UpperCAmelCase_     )
	return ch




def       _lowerCamelCase				(							)	-> List[str]:






	"""simple docstring"""





	A__											=					get_raw_chars()
	if ord(UpperCAmelCase_     ) in [KEYMAP["interrupt"], KEYMAP["newline"]]:
		return char

	elif ord(UpperCAmelCase_     ) == KEYMAP["esc"]:
		A__											=					get_raw_chars()
		if ord(UpperCAmelCase_     ) == KEYMAP["mod_int"]:
			A__											=					get_raw_chars()
			if ord(UpperCAmelCase_     ) >= KEYMAP["arrow_begin"] - ARROW_KEY_FLAG and ord(UpperCAmelCase_     ) <= KEYMAP["arrow_end"] - ARROW_KEY_FLAG:
				return chr(ord(UpperCAmelCase_     ) + ARROW_KEY_FLAG     )
			else:
				return KEYMAP["undefined"]
		else:
			return get_raw_chars()

	else:
		if char in string.printable:
			return char
		else:
			return KEYMAP["undefined"]












"""simple docstring"""







from __future__ import annotations

from scipy.special import comb  # type: ignore


class      UpperCamelCase		:






						def __init__(		self  :Any			, __magic_name__  :list[tuple[float, float]]				)      ->str:
										lowercase    :      List[Any]       = list_of_points
										# Degree determines the flexibility of the curve.
										# Degree = 1 will produce a straight line.
										lowercase    :      Optional[int]       = len(__magic_name__				) - 1






						def      __snake_case      (		self  :List[str]			, __magic_name__  :float				)      ->list[float]:
										assert 0 <= t <= 1, "Time t must be between 0 and 1."
										lowercase    :      list[float]       = []
										for i in range(len(self.list_of_points				)				):
														# basis function for each i
														output_values.append(
														    comb(self.degree			, __magic_name__				) * ((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(__magic_name__				)			, 5				) == 1
										return output_values






						def      __snake_case      (		self  :List[str]			, __magic_name__  :float				)      ->tuple[float, float]:
										assert 0 <= t <= 1, "Time t must be between 0 and 1."

										lowercase    :      str       = self.basis_function(__magic_name__				)
										lowercase    :      Optional[int]       = 0.0
										lowercase    :      List[str]       = 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      __snake_case      (		self  :Tuple			, __magic_name__  :float = 0.01				)      ->List[str]:
										from matplotlib import pyplot as plt  # type: ignore

										lowercase    :      list[float]       = []  # x coordinates of points to plot
										lowercase    :      list[float]       = []  # y coordinates of points to plot

										lowercase    :      int       = 0.0
										while t <= 1:
														lowercase    :      List[Any]       = self.bezier_curve_function(__magic_name__				)
														to_plot_x.append(value[0]				)
														to_plot_y.append(value[1]				)
														t += step_size

										lowercase    :      Union[str, Any]       = [i[0] for i in self.list_of_points]
										lowercase    :      Optional[int]       = [i[1] for i in self.list_of_points]

										plt.plot(
										    __magic_name__			, __magic_name__			, color="""blue"""			, label="""Curve of Degree """ + str(self.degree				)			, )
										plt.scatter(__magic_name__			, __magic_name__			, 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
