code: 
  
  
  
  class 	lowercase		:
  
  
  
  
  
  
  	"""simple docstring"""
  
  
  	def __init__(			self			:		List[str]		,						__UpperCAmelCase			:		int  )    ->				Any:
  							UpperCAmelCase_=     data
  							UpperCAmelCase_=     None
  							UpperCAmelCase_=     None
  
  
  
  
  	def __str__(			self			:		str  )    ->				Tuple:
  							return F"""{self.data}"""
  
  
  
  
  
  
  class 	lowercase		:
  
  
  
  
  
  
  	"""simple docstring"""
  
  
  	def __init__(			self			:		Union[str, Any]  )    ->				List[str]:
  							UpperCAmelCase_=     None
  							UpperCAmelCase_=     None
  
  
  
  
  	def __iter__(			self			:		List[str]  )    ->				str:
  							UpperCAmelCase_=     self.head
  							while node:
  													yield node.data
  													UpperCAmelCase_=     node.next
  
  
  
  
  	def __str__(			self			:		List[str]  )    ->				Union[str, Any]:
  							return "->".join([str(__SCREAMING_SNAKE_CASE  ) for item in self]  )
  
  
  
  
  	def __len__(			self			:		Tuple  )    ->				Any:
  							return sum(1 for _ in self  )
  
  
  
  
  	def 						_SCREAMING_SNAKE_CASE	(			self			:		List[str]		,						__UpperCAmelCase			:		int  )    ->				Dict:
  							self.insert_at_nth(0		,						__SCREAMING_SNAKE_CASE  )
  
  
  
  
  	def 						_SCREAMING_SNAKE_CASE	(			self			:		Tuple		,						__UpperCAmelCase			:		List[Any]  )    ->				Dict:
  							self.insert_at_nth(len(self  )		,						__SCREAMING_SNAKE_CASE  )
  
  
  
  
  	def 						_SCREAMING_SNAKE_CASE	(			self			:		List[Any]		,						__UpperCAmelCase			:		Optional[int]		,						__UpperCAmelCase			:		Tuple  )    ->				Optional[Any]:
  							UpperCAmelCase_=     len(self  )
  
  							if not 0 <= index <= length:
  													raise IndexError("""list index out of range"""  )
  							UpperCAmelCase_=     Node(__SCREAMING_SNAKE_CASE  )
  							if self.head is None:
  													UpperCAmelCase_=     UpperCAmelCase_=     new_node
  							elif index == 0:
  													UpperCAmelCase_=     new_node
  													UpperCAmelCase_=     self.head
  													UpperCAmelCase_=     new_node
  							elif index == length:
  													UpperCAmelCase_=     new_node
  													UpperCAmelCase_=     self.tail
  													UpperCAmelCase_=     new_node
  							else:
  													UpperCAmelCase_=     self.head
  													for _ in range(0		,						__SCREAMING_SNAKE_CASE  ):
  																			UpperCAmelCase_=     temp.next
  													UpperCAmelCase_=     new_node
  													UpperCAmelCase_=     temp.previous
  													UpperCAmelCase_=     temp
  													UpperCAmelCase_=     new_node
  
  
  
  
  	def 						_SCREAMING_SNAKE_CASE	(			self			:		str  )    ->				str:
  							return self.delete_at_nth(0  )
  
  
  
  
  	def 						_SCREAMING_SNAKE_CASE	(			self			:		str  )    ->				Optional[Any]:
  							return self.delete_at_nth(len(self  ) - 1  )
  
  
  
  
  	def 						_SCREAMING_SNAKE_CASE	(			self			:		str		,						__UpperCAmelCase			:		Optional[Any]  )    ->				Optional[Any]:
  							UpperCAmelCase_=     len(self  )
  
  							if not 0 <= index <= length - 1:
  													raise IndexError("""list index out of range"""  )
  							UpperCAmelCase_=     self.head  # default first node
  							if length == 1:
  													UpperCAmelCase_=     UpperCAmelCase_=     None
  							elif index == 0:
  													UpperCAmelCase_=     self.head.next
  													UpperCAmelCase_=     None
  							elif index == length - 1:
  													UpperCAmelCase_=     self.tail
  													UpperCAmelCase_=     self.tail.previous
  													UpperCAmelCase_=     None
  							else:
  													UpperCAmelCase_=     self.head
  													for _ in range(0		,						__SCREAMING_SNAKE_CASE  ):
  																			UpperCAmelCase_=     temp.next
  													UpperCAmelCase_=     temp
  													UpperCAmelCase_=     temp.previous
  													UpperCAmelCase_=     temp.next
  							return delete_node.data
  
  
  
  
  	def 						_SCREAMING_SNAKE_CASE	(			self			:		Optional[Any]		,						__UpperCAmelCase			:		Union[str, Any]  )    ->				Any:
  							UpperCAmelCase_=     self.head
  
  							while current.data != data:  # Find the position to delete
  													if current.next:
  																			UpperCAmelCase_=     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
  													UpperCAmelCase_=     current.next  # 1 --> 3
  													UpperCAmelCase_=     current.previous  # 1 <--> 3
  							return data
  
  
  
  
  	def 						_SCREAMING_SNAKE_CASE	(			self			:		Tuple  )    ->				List[Any]:
  							return len(self  ) == 0
  
  
  
  def  __a  (					)   ->				None:
  
  
  
  
  
  
  						'''simple docstring'''
  
  
  
  						UpperCAmelCase_=     DoublyLinkedList()
  						assert linked_list.is_empty() is True
  						assert str(lowerCAmelCase_       ) == ""
  
  						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(lowerCAmelCase_       ) == i
  												linked_list.insert_at_nth(lowerCAmelCase_    ,i + 1       )
  						assert str(lowerCAmelCase_       ) == "->".join(str(lowerCAmelCase_       ) for i in range(1    ,11       )       )
  
  						linked_list.insert_at_head(0       )
  						linked_list.insert_at_tail(11       )
  						assert str(lowerCAmelCase_       ) == "->".join(str(lowerCAmelCase_       ) 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(lowerCAmelCase_       ) == 9
  						assert str(lowerCAmelCase_       ) == "->".join(str(lowerCAmelCase_       ) for i in range(1    ,10       )       )
  
  
  if __name__ == "__main__":
  	from doctest import testmod
  
  	testmod()
  
  
  
  
  
style_context: 
  
  
  
  from .prime_check import Test
  
  Test()
  
  
  
  
  