



from math import pi, sqrt, tan





def 							A     (					_UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if side_length < 0:
						raise ValueError('surface_area_cube() only accepts non-negative values'   )
			return 6 * side_length**2





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if length < 0 or breadth < 0 or height < 0:
						raise ValueError('surface_area_cuboid() only accepts non-negative values'   )
			return 2 * ((length * breadth) + (breadth * height) + (length * height))





def 							A     (					_UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if radius < 0:
						raise ValueError('surface_area_sphere() only accepts non-negative values'   )
			return 4 * pi * radius**2





def 							A     (					_UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if radius < 0:
						raise ValueError('surface_area_hemisphere() only accepts non-negative values'   )
			return 3 * pi * radius**2





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if radius < 0 or height < 0:
						raise ValueError('surface_area_cone() only accepts non-negative values'   )
			return pi * radius * (radius + (height**2 + radius**2) ** 0.5)





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if radius_a < 0 or radius_a < 0 or height < 0:
						raise ValueError(
						    'surface_area_conical_frustum() only accepts non-negative values'   )
			_UpperCAmelCase			=       (height**2 + (radius_a - radius_a) ** 2) ** 0.5
			return pi * ((slant_height * (radius_a + radius_a)) + radius_a**2 + radius_a**2)





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if radius < 0 or height < 0:
						raise ValueError('surface_area_cylinder() only accepts non-negative values'   )
			return 2 * pi * radius * (height + radius)





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if torus_radius < 0 or tube_radius < 0:
						raise ValueError('surface_area_torus() only accepts non-negative values'   )
			if torus_radius < tube_radius:
						raise ValueError(
						    'surface_area_torus() does not support spindle or self intersecting tori'   )
			return 4 * pow(_UpperCAmelCase							,       2   ) * torus_radius * tube_radius





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if length < 0 or width < 0:
						raise ValueError('area_rectangle() only accepts non-negative values'   )
			return length * width





def 							A     (					_UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if side_length < 0:
						raise ValueError('area_square() only accepts non-negative values'   )
			return side_length**2





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if base < 0 or height < 0:
						raise ValueError('area_triangle() only accepts non-negative values'   )
			return (base * height) / 2





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if sidea < 0 or sidea < 0 or sidea < 0:
						raise ValueError('area_triangle_three_sides() only accepts non-negative values'   )
			elif sidea + sidea < sidea or sidea + sidea < sidea or sidea + sidea < sidea:
						raise ValueError('Given three sides do not form a triangle'   )
			_UpperCAmelCase			=       (sidea + sidea + sidea) / 2
			_UpperCAmelCase			=       sqrt(
			    semi_perimeter
			    * (semi_perimeter - sidea)
			    * (semi_perimeter - sidea)
			    * (semi_perimeter - sidea)   )
			return area





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if base < 0 or height < 0:
						raise ValueError('area_parallelogram() only accepts non-negative values'   )
			return base * height





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if basea < 0 or basea < 0 or height < 0:
						raise ValueError('area_trapezium() only accepts non-negative values'   )
			return 1 / 2 * (basea + basea) * height





def 							A     (					_UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if radius < 0:
						raise ValueError('area_circle() only accepts non-negative values'   )
			return pi * radius**2





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if radius_x < 0 or radius_y < 0:
						raise ValueError('area_ellipse() only accepts non-negative values'   )
			return pi * radius_x * radius_y





def 							A     (					_UpperCAmelCase    :       float							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if diagonal_a < 0 or diagonal_a < 0:
						raise ValueError('area_rhombus() only accepts non-negative values'   )
			return 1 / 2 * diagonal_a * diagonal_a





def 							A     (					_UpperCAmelCase    :       int							,       _UpperCAmelCase    :       float   )    ->			float:







			'''simple docstring'''
			if not isinstance(_UpperCAmelCase							,       _UpperCAmelCase   ) or sides < 3:
						raise ValueError(
						    'area_reg_polygon() only accepts integers greater than or \
equal to three as number of sides'   )
			elif length < 0:
						raise ValueError(
						    'area_reg_polygon() only accepts non-negative values as \
length of a side'   )
			return (sides * length**2) / (4 * tan(pi / sides   ))
			return (sides * length**2) / (4 * tan(pi / sides   ))


if __name__ == "__main__":
							import doctest

							doctest.testmod(verbose=True)  # verbose so we can see methods missing tests

							print("[DEMO] Areas of various geometric shapes: \n")
							print(f"""Rectangle: {area_rectangle(10, 20) = }""")
							print(f"""Square: {area_square(10) = }""")
							print(f"""Triangle: {area_triangle(10, 10) = }""")
							print(f"""Triangle: {area_triangle_three_sides(5, 12, 13) = }""")
							print(f"""Parallelogram: {area_parallelogram(10, 20) = }""")
							print(f"""Rhombus: {area_rhombus(10, 20) = }""")
							print(f"""Trapezium: {area_trapezium(10, 20, 30) = }""")
							print(f"""Circle: {area_circle(20) = }""")
							print(f"""Ellipse: {area_ellipse(10, 20) = }""")
							print("\nSurface Areas of various geometric shapes: \n")
							print(f"""Cube: {surface_area_cube(20) = }""")
							print(f"""Cuboid: {surface_area_cuboid(10, 20, 30) = }""")
							print(f"""Sphere: {surface_area_sphere(20) = }""")
							print(f"""Hemisphere: {surface_area_hemisphere(20) = }""")
							print(f"""Cone: {surface_area_cone(10, 20) = }""")
							print(f"""Conical Frustum: {surface_area_conical_frustum(10, 20, 30) = }""")
							print(f"""Cylinder: {surface_area_cylinder(10, 20) = }""")
							print(f"""Torus: {surface_area_torus(20, 10) = }""")
							print(f"""Equilateral Triangle: {area_reg_polygon(3, 10) = }""")
							print(f"""Square: {area_reg_polygon(4, 10) = }""")
							print(f"""Reqular Pentagon: {area_reg_polygon(5, 10) = }""")





def 							A     (					_UpperCAmelCase    :       int   )    ->			"list[int]":







			'''simple docstring'''
			if upper_limit < 0:
						raise ValueError('Limit for the Catalan sequence must be ≥ 0'   )

			_UpperCAmelCase			=       [0] * (upper_limit + 1)

			# Base case: C(0) = C(1) = 1
			_UpperCAmelCase			=       1
			if upper_limit > 0:
						_UpperCAmelCase			=       1

			# Recurrence relation: C(i) = sum(C(j).C(i-j-1)), from j = 0 to i
			for i in range(2							,       upper_limit + 1   ):
						for j in range(_UpperCAmelCase   ):
									catalan_list[i] += catalan_list[j] * catalan_list[i - j - 1]

			return catalan_list


if __name__ == "__main__":
							print("\n********* Catalan Numbers Using Dynamic Programming ************\n")
							print("\n*** Enter -1 at any time to quit ***")
							print("\nEnter the upper limit (≥ 0) for the Catalan number sequence: ", end="")
							try:
														while True:
																					UpperCAmelCase__       =	int(input().strip())
																					if N < 0:
																												print("\n********* Goodbye!! ************")
																												break
																					else:
																												print(f"""The Catalan numbers from 0 through {N} are:""")
																												print(catalan_numbers(N))
																												print("Try another upper limit for the sequence: ", end="")
							except (NameError, ValueError):
														print("\n********* Invalid input, goodbye! ************\n")

							import doctest

							doctest.testmod()
