




'''simple docstring'''







from __future__ import annotations

from math import pi, pow






def 						_lowercase						(      lowercase_    ):



		'''simple docstring'''







		if side_length < 0:
				raise ValueError("vol_cube() only accepts non-negative values"    )
		return pow(lowercase_		,				3    )






def 						_lowercase						(      lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if height < 0 or radius < 0:
				raise ValueError("vol_spherical_cap() only accepts non-negative values"    )
		# Volume is 1/3 pi * height squared * (3 * radius - height)
		return 1 / 3 * pi * pow(lowercase_		,				2    ) * (3 * radius - height)






def 						_lowercase						(      lowercase_		,				lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if radius_a < 0 or radius_a < 0 or centers_distance < 0:
				raise ValueError("vol_spheres_intersect() only accepts non-negative values"    )
		if centers_distance == 0:
				return vol_sphere(min(lowercase_		,				lowercase_    )    )

		_snake_case      			=			(
		    (radius_a - radius_a + centers_distance)
		    * (radius_a + radius_a - centers_distance)
		    / (2 * centers_distance)
		)
		_snake_case      			=			(
		    (radius_a - radius_a + centers_distance)
		    * (radius_a + radius_a - centers_distance)
		    / (2 * centers_distance)
		)

		return vol_spherical_cap(lowercase_		,				lowercase_    ) + vol_spherical_cap(lowercase_		,				lowercase_    )






def 						_lowercase						(      lowercase_		,				lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if radius_a <= 0 or radius_a <= 0 or centers_distance < 0:
				raise ValueError(
				    "vol_spheres_union() only accepts non-negative values, non-zero radius"    )

		if centers_distance == 0:
				return vol_sphere(max(lowercase_		,				lowercase_    )    )

		return (
		    vol_sphere(lowercase_    )
		    + vol_sphere(lowercase_    )
		    - vol_spheres_intersect(lowercase_		,				lowercase_		,				lowercase_    )
		)






def 						_lowercase						(      lowercase_		,				lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if width < 0 or height < 0 or length < 0:
				raise ValueError("vol_cuboid() only accepts non-negative values"    )
		return float(width * height * length    )






def 						_lowercase						(      lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if height < 0 or area_of_base < 0:
				raise ValueError("vol_cone() only accepts non-negative values"    )
		return area_of_base * height / 3.0






def 						_lowercase						(      lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if height < 0 or radius < 0:
				raise ValueError("vol_right_circ_cone() only accepts non-negative values"    )
		return pi * pow(lowercase_		,				2    ) * height / 3.0






def 						_lowercase						(      lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if height < 0 or area_of_base < 0:
				raise ValueError("vol_prism() only accepts non-negative values"    )
		return float(area_of_base * height    )






def 						_lowercase						(      lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if height < 0 or area_of_base < 0:
				raise ValueError("vol_pyramid() only accepts non-negative values"    )
		return area_of_base * height / 3.0






def 						_lowercase						(      lowercase_    ):



		'''simple docstring'''







		if radius < 0:
				raise ValueError("vol_sphere() only accepts non-negative values"    )
		# Volume is 4/3 * pi * radius cubed
		return 4 / 3 * pi * pow(lowercase_		,				3    )






def 						_lowercase						(      lowercase_    ):



		'''simple docstring'''







		if radius < 0:
				raise ValueError("vol_hemisphere() only accepts non-negative values"    )
		# Volume is radius cubed * pi * 2/3
		return pow(lowercase_		,				3    ) * pi * 2 / 3






def 						_lowercase						(      lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if height < 0 or radius < 0:
				raise ValueError("vol_circular_cylinder() only accepts non-negative values"    )
		# Volume is radius squared * height * pi
		return pow(lowercase_		,				2    ) * height * pi






def 						_lowercase						(      lowercase_		,				lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if inner_radius < 0 or outer_radius < 0 or height < 0:
				raise ValueError(
				    "vol_hollow_circular_cylinder() only accepts non-negative values"    )
		if outer_radius <= inner_radius:
				raise ValueError("outer_radius must be greater than inner_radius"    )
		return pi * (pow(lowercase_		,				2    ) - pow(lowercase_		,				2    )) * height






def 						_lowercase						(      lowercase_		,				lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if radius_a < 0 or radius_a < 0 or height < 0:
				raise ValueError("vol_conical_frustum() only accepts non-negative values"    )
		return (
		    1
		    / 3
		    * pi
		    * height
		    * (pow(lowercase_		,				2    ) + pow(lowercase_		,				2    ) + radius_a * radius_a)
		)






def 						_lowercase						(      lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if torus_radius < 0 or tube_radius < 0:
				raise ValueError("vol_torus() only accepts non-negative values"    )
		return 2 * pow(lowercase_		,				2    ) * torus_radius * pow(lowercase_		,				2    )






def 						_lowercase						(      ):



		'''simple docstring'''







		print("Volumes:"    )
		print(f'''Cube: {vol_cube(2    ) = }'''    )  # = 8
		print(f'''Cuboid: {vol_cuboid(2		,				2		,				2    ) = }'''    )  # = 8
		print(f'''Cone: {vol_cone(2		,				2    ) = }'''    )  # ~= 1.33
		print(f'''Right Circular Cone: {vol_right_circ_cone(2		,				2    ) = }'''    )  # ~= 8.38
		print(f'''Prism: {vol_prism(2		,				2    ) = }'''    )  # = 4
		print(f'''Pyramid: {vol_pyramid(2		,				2    ) = }'''    )  # ~= 1.33
		print(f'''Sphere: {vol_sphere(2    ) = }'''    )  # ~= 33.5
		print(f'''Hemisphere: {vol_hemisphere(2    ) = }'''    )  # ~= 16.75
		print(f'''Circular Cylinder: {vol_circular_cylinder(2		,				2    ) = }'''    )  # ~= 25.1
		print(f'''Torus: {vol_torus(2		,				2    ) = }'''    )  # ~= 157.9
		print(f'''Conical Frustum: {vol_conical_frustum(2		,				2		,				4    ) = }'''    )  # ~= 58.6
		print(f'''Spherical cap: {vol_spherical_cap(1		,				2    ) = }'''    )  # ~= 5.24
		print(f'''Spheres intersetion: {vol_spheres_intersect(2		,				2		,				1    ) = }'''    )  # ~= 21.21
		print(f'''Spheres union: {vol_spheres_union(2		,				2		,				1    ) = }'''    )  # ~= 45.81
		print(
		    f'''Hollow Circular Cylinder: {vol_hollow_circular_cylinder(1		,				2		,				3    ) = }'''    )  # ~= 28.3


if __name__ == "__main__":
						main()











'''simple docstring'''







import numpy as np






def 						_lowercase						(      lowercase_		,				lowercase_="utf-8"		,				lowercase_="surrogatepass"    ):



		'''simple docstring'''







		_snake_case      			=			bin(int.from_bytes(text.encode(lowercase_		,				lowercase_    )		,				"big"    )    )[2:]
		return bits.zfill(8 * ((len(lowercase_    ) + 7) // 8)    )






def 						_lowercase						(      lowercase_		,				lowercase_="utf-8"		,				lowercase_="surrogatepass"    ):



		'''simple docstring'''







		_snake_case      			=			int(lowercase_		,				2    )
		return n.to_bytes((n.bit_length() + 7) // 8		,				"big"    ).decode(lowercase_		,				lowercase_    ) or "\0"






def 						_lowercase						(      lowercase_		,				lowercase_    ):



		'''simple docstring'''







		if size_par + len(lowercase_    ) <= 2**size_par - (len(lowercase_    ) - 1):
				raise ValueError("size of parity don't match with size of data"    )

		_snake_case      			=			[]
		_snake_case      			=			[]
		_snake_case      			=			[bin(lowercase_    )[2:] for x in range(1		,				size_par + len(lowercase_    ) + 1    )]

		# sorted information data for the size of the output data
		_snake_case      			=			[]
		# data position template + parity
		_snake_case      			=			[]
		# parity bit counter
		_snake_case      			=			0
		# counter position of data bits
		_snake_case      			=			0

		for x in range(1		,				size_par + len(lowercase_    ) + 1    ):
				# Performs a template of bit positions - who should be given,
				# and who should be parity
				if qtd_bp < size_par:
						if (np.log(lowercase_    ) / np.log(2    )).is_integer():
								data_out_gab.append("P"    )
								_snake_case      			=			qtd_bp + 1
						else:
								data_out_gab.append("D"    )
				else:
						data_out_gab.append("D"    )

				# Sorts the data to the new output size
				if data_out_gab[-1] == "D":
						data_ord.append(data[cont_data]    )
						cont_data += 1
				else:
						data_ord.append(lowercase_    )

    # Calculates parity
		_snake_case      			=			0  # parity bit counter
		for bp in range(1		,				size_par + 1    ):
				# Bit counter one for a given parity
				_snake_case      			=			0
				# counter to control the loop reading
				_snake_case      			=			0
				for x in data_ord:
						if x is not None:
								try:
										_snake_case      			=			(bin_pos[cont_loop])[-1 * (bp)]
								except IndexError:
										_snake_case      			=			"0"
								if aux == "1" and x == "1":
										cont_bo += 1
						cont_loop += 1
				parity.append(cont_bo % 2    )

				qtd_bp += 1

		# Mount the message
		_snake_case      			=			0  # parity bit counter
		for x in range(0		,				size_par + len(lowercase_    )    ):
				if data_ord[x] is None:
						data_out.append(str(parity[cont_bp]    )    )
						cont_bp += 1
				else:
						data_out.append(data_ord[x]    )

		return data_out






def 						_lowercase						(      lowercase_		,				lowercase_    ):



		'''simple docstring'''







		_snake_case      			=			[]
		# Parity bit counter
		_snake_case      			=			0
		# Counter p data bit reading
		_snake_case      			=			0
		# list of parity received
		_snake_case      			=			[]
		_snake_case      			=			[]

		for x in range(1		,				len(lowercase_    ) + 1    ):
				# Performs a template of bit positions - who should be given,
				#  and who should be parity
				if qtd_bp < size_par and (np.log(lowercase_    ) / np.log(2    )).is_integer():
						data_out_gab.append("P"    )
						_snake_case      			=			qtd_bp + 1
				else:
						data_out_gab.append("D"    )

				# Sorts the data to the new output size
				if data_out_gab[-1] == "D":
						data_output.append(data[cont_data]    )
				else:
						parity_received.append(data[cont_data]    )
				cont_data += 1

		# -----------calculates the parity with the data
		_snake_case      			=			[]
		_snake_case      			=			[]
		_snake_case      			=			[bin(lowercase_    )[2:] for x in range(1		,				size_par + len(lowercase_    ) + 1    )]

		#  sorted information data for the size of the output data
		_snake_case      			=			[]
		# Data position feedback + parity
		_snake_case      			=			[]
		# Parity bit counter
		_snake_case      			=			0
		# Counter p data bit reading
		_snake_case      			=			0

		for x in range(1		,				size_par + len(lowercase_    ) + 1    ):
				# Performs a template position of bits - who should be given,
				# and who should be parity
				if qtd_bp < size_par and (np.log(lowercase_    ) / np.log(2    )).is_integer():
						data_out_gab.append("P"    )
						_snake_case      			=			qtd_bp + 1
				else:
						data_out_gab.append("D"    )

				# Sorts the data to the new output size
				if data_out_gab[-1] == "D":
						data_ord.append(data_output[cont_data]    )
						cont_data += 1
				else:
						data_ord.append(lowercase_    )

    # Calculates parity
		_snake_case      			=			0  # parity bit counter
		for bp in range(1		,				size_par + 1    ):
				# Bit counter one for a certain parity
				_snake_case      			=			0
				# Counter to control loop reading
				_snake_case      			=			0
				for x in data_ord:
						if x is not None:
								try:
										_snake_case      			=			(bin_pos[cont_loop])[-1 * (bp)]
								except IndexError:
										_snake_case      			=			"0"
								if aux == "1" and x == "1":
										cont_bo += 1
						cont_loop += 1
				parity.append(str(cont_bo % 2    )    )

				qtd_bp += 1

		# Mount the message
		_snake_case      			=			0  # Parity bit counter
		for x in range(0		,				size_par + len(lowercase_    )    ):
				if data_ord[x] is None:
						data_out.append(str(parity[cont_bp]    )    )
						cont_bp += 1
				else:
						data_out.append(data_ord[x]    )

		_snake_case      			=			parity_received == parity
		return data_output, ack





