code: 
  
  
  
  
  
  '''simple docstring'''
  
  
  
  
  
  
  
  class 					_UpperCAmelCase							:
  		def __init__(						self,__SCREAMING_SNAKE_CASE    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       data
  					__lowerCAmelCase      		=       None
  					__lowerCAmelCase      		=       None
  
  
  
  
  
  
  
  		def __str__(						self    ):
  
  
  
  					'''simple docstring'''
  
  					return f'{self.data}'
  
  
  
  
  
  class 					_UpperCAmelCase							:
  		def __init__(						self    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       None
  					__lowerCAmelCase      		=       None
  		def __iter__(						self    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       self.head
  					while node:
  								yield node.data
  								__lowerCAmelCase      		=       node.next
  		def __str__(						self    ):
  
  
  
  					'''simple docstring'''
  
  					return "->".join([str(__SCREAMING_SNAKE_CASE    ) for item in self]    )
  		def __len__(						self    ):
  
  
  
  					'''simple docstring'''
  
  					return sum(1 for _ in self    )
  		def 						lowerCamelCase__    (						self,__SCREAMING_SNAKE_CASE    ):
  
  
  
  					'''simple docstring'''
  
  					self.insert_at_nth(0,__SCREAMING_SNAKE_CASE    )
  		def 						lowerCamelCase__    (						self,__SCREAMING_SNAKE_CASE    ):
  
  
  
  					'''simple docstring'''
  
  					self.insert_at_nth(len(self    ),__SCREAMING_SNAKE_CASE    )
  		def 						lowerCamelCase__    (						self,__SCREAMING_SNAKE_CASE,__SCREAMING_SNAKE_CASE    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       len(self    )
  
  					if not 0 <= index <= length:
  								raise IndexError("""list index out of range"""    )
  					__lowerCAmelCase      		=       Node(__SCREAMING_SNAKE_CASE    )
  					if self.head is None:
  								__lowerCAmelCase      		=       __lowerCAmelCase      		=       new_node
  					elif index == 0:
  								__lowerCAmelCase      		=       new_node
  								__lowerCAmelCase      		=       self.head
  								__lowerCAmelCase      		=       new_node
  					elif index == length:
  								__lowerCAmelCase      		=       new_node
  								__lowerCAmelCase      		=       self.tail
  								__lowerCAmelCase      		=       new_node
  					else:
  								__lowerCAmelCase      		=       self.head
  								for _ in range(0,__SCREAMING_SNAKE_CASE    ):
  											__lowerCAmelCase      		=       temp.next
  								__lowerCAmelCase      		=       new_node
  								__lowerCAmelCase      		=       temp.previous
  								__lowerCAmelCase      		=       temp
  								__lowerCAmelCase      		=       new_node
  		def 						lowerCamelCase__    (						self    ):
  
  
  
  					'''simple docstring'''
  
  					return self.delete_at_nth(0    )
  		def 						lowerCamelCase__    (						self    ):
  
  
  
  					'''simple docstring'''
  
  					return self.delete_at_nth(len(self    ) - 1    )
  		def 						lowerCamelCase__    (						self,__SCREAMING_SNAKE_CASE    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       len(self    )
  
  					if not 0 <= index <= length - 1:
  								raise IndexError("""list index out of range"""    )
  					__lowerCAmelCase      		=       self.head  # default first node
  					if length == 1:
  								__lowerCAmelCase      		=       __lowerCAmelCase      		=       None
  					elif index == 0:
  								__lowerCAmelCase      		=       self.head.next
  								__lowerCAmelCase      		=       None
  					elif index == length - 1:
  								__lowerCAmelCase      		=       self.tail
  								__lowerCAmelCase      		=       self.tail.previous
  								__lowerCAmelCase      		=       None
  					else:
  								__lowerCAmelCase      		=       self.head
  								for _ in range(0,__SCREAMING_SNAKE_CASE    ):
  											__lowerCAmelCase      		=       temp.next
  								__lowerCAmelCase      		=       temp
  								__lowerCAmelCase      		=       temp.previous
  								__lowerCAmelCase      		=       temp.next
  					return delete_node.data
  		def 						lowerCamelCase__    (						self,__SCREAMING_SNAKE_CASE    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       self.head
  
  					while current.data != data:  # Find the position to delete
  								if current.next:
  											__lowerCAmelCase      		=       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
  								__lowerCAmelCase      		=       current.next  # 1 --> 3
  								__lowerCAmelCase      		=       current.previous  # 1 <--> 3
  					return data
  
  
  
  
  
  
  
  		def 						lowerCamelCase__    (						self    ):
  
  
  
  					'''simple docstring'''
  
  					return len(self    ) == 0
  
  
  
  
  
  def      _lowerCAmelCase		(		)      ->      None:
  			__lowerCAmelCase      		=       DoublyLinkedList()
  			assert linked_list.is_empty() is True
  			assert str(lowercase			) == ""
  
  			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(lowercase			) == i
  						linked_list.insert_at_nth(lowercase      ,			i + 1			)
  			assert str(lowercase			) == "->".join(str(lowercase			) for i in range(1      ,			11			)			)
  
  			linked_list.insert_at_head(0			)
  			linked_list.insert_at_tail(11			)
  			assert str(lowercase			) == "->".join(str(lowercase			) 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(lowercase			) == 9
  			assert str(lowercase			) == "->".join(str(lowercase			) for i in range(1      ,			10			)			)
  
  
  if __name__ == "__main__":
  	from doctest import testmod
  
  	testmod()
  
  
style_context: 
  
  
  
  
  
  '''simple docstring'''
  
  
  
  
  
  
  
  from __future__ import annotations
  
  from collections.abc import Iterable, Iterator
  from typing import Any, Generic, TypeVar
  
  _a      :				Dict											=					TypeVar("""T""", bound=bool)
  
  
  
  
  
  class 					_UpperCAmelCase							(		Generic[T]     ):
  		def __init__(						self,__SCREAMING_SNAKE_CASE    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       value
  					__lowerCAmelCase      		=       None
  					__lowerCAmelCase      		=       None
  		@property
  		def 						lowerCamelCase__    (						self    ):
  
  
  
  					'''simple docstring'''
  
  					return self._value
  
  
  
  
  
  
  
  		@staticmethod
  		def 						lowerCamelCase__    (						__SCREAMING_SNAKE_CASE,__SCREAMING_SNAKE_CASE    ):
  
  
  
  					'''simple docstring'''
  
  					if not roota:
  								return roota
  
  					if not roota:
  								return roota
  
  					if roota.value > roota.value:
  								__lowerCAmelCase		, __lowerCAmelCase      		=       roota, roota
  
  					__lowerCAmelCase      		=       roota
  					__lowerCAmelCase      		=       roota.right
  					__lowerCAmelCase      		=       roota.left
  					__lowerCAmelCase      		=       SkewNode.merge(__SCREAMING_SNAKE_CASE,__SCREAMING_SNAKE_CASE    )
  
  					return result
  
  
  
  
  
  class 					_UpperCAmelCase							(		Generic[T]     ):
  		def __init__(						self,__SCREAMING_SNAKE_CASE = ()    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       None
  					if data:
  								for item in data:
  											self.insert(__SCREAMING_SNAKE_CASE    )
  		def __bool__(						self    ):
  
  
  
  					'''simple docstring'''
  
  					return self._root is not None
  		def __iter__(						self    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       []
  					while self:
  								result.append(self.pop()    )
  
  					# Pushing items back to the heap not to clear it.
  					for item in result:
  								self.insert(__SCREAMING_SNAKE_CASE    )
  
  					return iter(__SCREAMING_SNAKE_CASE    )
  		def 						lowerCamelCase__    (						self,__SCREAMING_SNAKE_CASE    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       SkewNode.merge(self._root,SkewNode(__SCREAMING_SNAKE_CASE    )    )
  		def 						lowerCamelCase__    (						self    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       self.top()
  					__lowerCAmelCase      		=       (
  					    SkewNode.merge(self._root.left,self._root.right    ) if self._root else None
  					)
  
  					return result
  		def 						lowerCamelCase__    (						self    ):
  
  
  
  					'''simple docstring'''
  
  					if not self._root:
  								raise IndexError("""Can't get top element for the empty heap."""    )
  					return self._root.value
  
  
  
  
  
  
  
  		def 						lowerCamelCase__    (						self    ):
  
  
  
  					'''simple docstring'''
  
  					__lowerCAmelCase      		=       None
  
  
  if __name__ == "__main__":
  	import doctest
  
  	doctest.testmod()
  
  