

"""simple docstring"""

class 			_snake_case     :







						def __init__(self     ,							UpperCAmelCase_							)			->						Optional[Any]:
											__lowercase												=			data
											__lowercase												=			None
											__lowercase												=			None







						def __str__(self							)			->						int:
											return f'''{self.data}'''



class 			_snake_case     :







						def __init__(self							)			->						Union[str, Any]:
											__lowercase												=			None
											__lowercase												=			None







						def __iter__(self							)			->						Union[str, Any]:
											__lowercase												=			self.head
											while node:
																yield node.data
																__lowercase												=			node.next







						def __str__(self							)			->						Union[str, Any]:
											return "->".join([str(UpperCAmelCase_							) for item in self]							)







						def __len__(self							)			->						List[str]:
											return sum(1 for _ in self							)







						def        _UpperCamelCase    (self     ,							UpperCAmelCase_							)			->						Tuple:
											self.insert_at_nth(0     ,							UpperCAmelCase_							)







						def        _UpperCamelCase    (self     ,							UpperCAmelCase_							)			->						Tuple:
											self.insert_at_nth(len(self							)     ,							UpperCAmelCase_							)







						def        _UpperCamelCase    (self     ,							UpperCAmelCase_     ,							UpperCAmelCase_							)			->						List[str]:
											__lowercase												=			len(self							)

											if not 0 <= index <= length:
																raise IndexError('''list index out of range'''							)
											__lowercase												=			Node(UpperCAmelCase_							)
											if self.head is None:
																__lowercase												=			__lowercase												=			new_node
											elif index == 0:
																__lowercase												=			new_node
																__lowercase												=			self.head
																__lowercase												=			new_node
											elif index == length:
																__lowercase												=			new_node
																__lowercase												=			self.tail
																__lowercase												=			new_node
											else:
																__lowercase												=			self.head
																for _ in range(0     ,							UpperCAmelCase_							):
																					__lowercase												=			temp.next
																__lowercase												=			new_node
																__lowercase												=			temp.previous
																__lowercase												=			temp
																__lowercase												=			new_node







						def        _UpperCamelCase    (self							)			->						str:
											return self.delete_at_nth(0							)







						def        _UpperCamelCase    (self							)			->						int:
											return self.delete_at_nth(len(self							) - 1							)







						def        _UpperCamelCase    (self     ,							UpperCAmelCase_							)			->						Optional[Any]:
											__lowercase												=			len(self							)

											if not 0 <= index <= length - 1:
																raise IndexError('''list index out of range'''							)
											__lowercase												=			self.head  # default first node
											if length == 1:
																__lowercase												=			__lowercase												=			None
											elif index == 0:
																__lowercase												=			self.head.next
																__lowercase												=			None
											elif index == length - 1:
																__lowercase												=			self.tail
																__lowercase												=			self.tail.previous
																__lowercase												=			None
											else:
																__lowercase												=			self.head
																for _ in range(0     ,							UpperCAmelCase_							):
																					__lowercase												=			temp.next
																__lowercase												=			temp
																__lowercase												=			temp.previous
																__lowercase												=			temp.next
											return delete_node.data







						def        _UpperCamelCase    (self     ,							UpperCAmelCase_							)			->						str:
											__lowercase												=			self.head

											while current.data != data:  # Find the position to delete
																if current.next:
																					__lowercase												=			current.next
																else:  # We have reached the end an no value matches
																					raise ValueError('''No data matching given value'''							)

											if current == self.head:
																self.delete_head()

											elif current == self.tail:
																self.delete_tail()

											else:  # Before: 1 <--> 2(current) <--> 3
																__lowercase												=			current.next  # 1 --> 3
																__lowercase												=			current.previous  # 1 <--> 3
											return data







						def        _UpperCamelCase    (self							)			->						Optional[Any]:
											return len(self							) == 0





def 				__UpperCamelCase   (    )				->			None:




					"""simple docstring"""



					__lowercase												=			DoublyLinkedList()
					assert linked_list.is_empty() is True
					assert str(a__			) == ""

					try:
										linked_list.delete_head()
										raise AssertionError  # This should not happen.
					except IndexError:
										assert True  # This should happen.

					try:
										linked_list.delete_tail()
										raise AssertionError  # This should not happen.
					except IndexError:
										assert True  # This should happen.

					for i in range(10			):
										assert len(a__			) == i
										linked_list.insert_at_nth(a__ ,	i + 1			)
					assert str(a__			) == "->".join(str(a__			) for i in range(1 ,	11			)			)

					linked_list.insert_at_head(0			)
					linked_list.insert_at_tail(11			)
					assert str(a__			) == "->".join(str(a__			) for i in range(0 ,	12			)			)

					assert linked_list.delete_head() == 0
					assert linked_list.delete_at_nth(9			) == 10
					assert linked_list.delete_tail() == 11
					assert len(a__			) == 9
					assert str(a__			) == "->".join(str(a__			) for i in range(1 ,	10			)			)


if __name__ == "__main__":
							from doctest import testmod

							testmod()





"""simple docstring"""

def 				__UpperCamelCase   (    a__: int ,	a__: int = 10_00			)				->			str:




					"""simple docstring"""



					if (not isinstance(a__ ,	a__			)) or (digit_position <= 0):
										raise ValueError('''Digit position must be a positive integer'''			)
					elif (not isinstance(a__ ,	a__			)) or (precision < 0):
										raise ValueError('''Precision must be a nonnegative integer'''			)

					# compute an approximation of (16 ** (n - 1)) * pi whose fractional part is mostly
					# accurate
					__lowercase												=			(
					    4 * _subsum(a__ ,	1 ,	a__			)
					    - 2 * _subsum(a__ ,	4 ,	a__			)
					    - _subsum(a__ ,	5 ,	a__			)
					    - _subsum(a__ ,	6 ,	a__			)
					)

					# return the first hex digit of the fractional part of the result
					return hex(int((sum_result % 1) * 16			)			)[2:]





def 				__UpperCamelCase   (    a__: int ,	a__: int ,	a__: int			)				->			float:




					"""simple docstring"""



					__lowercase												=			0.0
					for sum_index in range(digit_pos_to_extract + precision			):
										__lowercase												=			8 * sum_index + denominator_addend
										if sum_index < digit_pos_to_extract:
															# if the exponential term is an integer and we mod it by the denominator
															# before dividing, only the integer part of the sum will change;
															# the fractional part will not
															__lowercase												=			pow(
															    16 ,	digit_pos_to_extract - 1 - sum_index ,	a__			)
										else:
															__lowercase												=			pow(16 ,	digit_pos_to_extract - 1 - sum_index			)
										total += exponential_term / denominator
					return total


if __name__ == "__main__":
							import doctest

							doctest.testmod()


