
from __future__ import annotations

import unittest

import numpy as np

from transformers import LayoutLMConfig, is_tf_available
from transformers.testing_utils import require_tf, slow

from ...test_configuration_common import ConfigTester
from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_tf_available():
	import tensorflow as tf

	from transformers.models.layoutlm.modeling_tf_layoutlm import (
	    TF_LAYOUTLM_PRETRAINED_MODEL_ARCHIVE_LIST,
	    TFLayoutLMForMaskedLM,
	    TFLayoutLMForQuestionAnswering,
	    TFLayoutLMForSequenceClassification,
	    TFLayoutLMForTokenClassification,
	    TFLayoutLMModel,
	)







class 			A_  :




	'''simple docstring'''


	def __init__(			self						,       snake_case						,       snake_case=13						,       snake_case=7						,       snake_case=True						,       snake_case=True						,       snake_case=True						,       snake_case=True						,       snake_case=99						,       snake_case=32						,       snake_case=2						,       snake_case=4						,       snake_case=37						,       snake_case="gelu"						,       snake_case=0.1						,       snake_case=0.1						,       snake_case=512						,       snake_case=16						,       snake_case=2						,       snake_case=0.02						,       snake_case=3						,       snake_case=4						,       snake_case=None						,       snake_case=1000						,       ):
		lowercase	    =       parent
		lowercase	    =       batch_size
		lowercase	    =       seq_length
		lowercase	    =       is_training
		lowercase	    =       use_input_mask
		lowercase	    =       use_token_type_ids
		lowercase	    =       use_labels
		lowercase	    =       vocab_size
		lowercase	    =       hidden_size
		lowercase	    =       num_hidden_layers
		lowercase	    =       num_attention_heads
		lowercase	    =       intermediate_size
		lowercase	    =       hidden_act
		lowercase	    =       hidden_dropout_prob
		lowercase	    =       attention_probs_dropout_prob
		lowercase	    =       max_position_embeddings
		lowercase	    =       type_vocab_size
		lowercase	    =       type_sequence_label_size
		lowercase	    =       initializer_range
		lowercase	    =       num_labels
		lowercase	    =       num_choices
		lowercase	    =       scope
		lowercase	    =       range_bbox





	def       SCREAMING_SNAKE_CASE__		(			self			):
		lowercase	    =       ids_tensor([self.batch_size, self.seq_length]						,       self.vocab_size			)

		# convert bbox to numpy since TF does not support item assignment
		lowercase	    =       ids_tensor([self.batch_size, self.seq_length, 4]						,       self.range_bbox			).numpy()
		# Ensure that bbox is legal
		for i in range(bbox.shape[0]			):
			for j in range(bbox.shape[1]			):
				if bbox[i, j, 3] < bbox[i, j, 1]:
					lowercase	    =       bbox[i, j, 3]
					lowercase	    =       bbox[i, j, 1]
					lowercase	    =       t
				if bbox[i, j, 2] < bbox[i, j, 0]:
					lowercase	    =       bbox[i, j, 2]
					lowercase	    =       bbox[i, j, 0]
					lowercase	    =       t
		lowercase	    =       tf.convert_to_tensor(snake_case			)

		lowercase	    =       None
		if self.use_input_mask:
			lowercase	    =       random_attention_mask([self.batch_size, self.seq_length]			)

		lowercase	    =       None
		if self.use_token_type_ids:
			lowercase	    =       ids_tensor([self.batch_size, self.seq_length]						,       self.type_vocab_size			)

		lowercase	    =       None
		lowercase	    =       None
		lowercase	    =       None
		if self.use_labels:
			lowercase	    =       ids_tensor([self.batch_size]						,       self.type_sequence_label_size			)
			lowercase	    =       ids_tensor([self.batch_size, self.seq_length]						,       self.num_labels			)
			lowercase	    =       ids_tensor([self.batch_size]						,       self.num_choices			)

		lowercase	    =       LayoutLMConfig(
		    vocab_size=self.vocab_size						,       hidden_size=self.hidden_size						,       num_hidden_layers=self.num_hidden_layers						,       num_attention_heads=self.num_attention_heads						,       intermediate_size=self.intermediate_size						,       hidden_act=self.hidden_act						,       hidden_dropout_prob=self.hidden_dropout_prob						,       attention_probs_dropout_prob=self.attention_probs_dropout_prob						,       max_position_embeddings=self.max_position_embeddings						,       type_vocab_size=self.type_vocab_size						,       initializer_range=self.initializer_range						,       )

		return config, input_ids, bbox, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels





	def       SCREAMING_SNAKE_CASE__		(			self						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case			):
		lowercase	    =       TFLayoutLMModel(config=snake_case			)

		lowercase	    =       model(snake_case						,       snake_case						,       attention_mask=snake_case						,       token_type_ids=snake_case			)
		lowercase	    =       model(snake_case						,       snake_case						,       token_type_ids=snake_case			)
		lowercase	    =       model(snake_case						,       snake_case			)
		self.parent.assertEqual(result.last_hidden_state.shape						,       (self.batch_size, self.seq_length, self.hidden_size)			)
		self.parent.assertEqual(result.pooler_output.shape						,       (self.batch_size, self.hidden_size)			)





	def       SCREAMING_SNAKE_CASE__		(			self						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case			):
		lowercase	    =       TFLayoutLMForMaskedLM(config=snake_case			)

		lowercase	    =       model(snake_case						,       snake_case						,       attention_mask=snake_case						,       token_type_ids=snake_case						,       labels=snake_case			)
		self.parent.assertEqual(result.logits.shape						,       (self.batch_size, self.seq_length, self.vocab_size)			)





	def       SCREAMING_SNAKE_CASE__		(			self						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case			):
		lowercase	    =       self.num_labels
		lowercase	    =       TFLayoutLMForSequenceClassification(config=snake_case			)

		lowercase	    =       model(snake_case						,       snake_case						,       attention_mask=snake_case						,       token_type_ids=snake_case			)
		self.parent.assertEqual(result.logits.shape						,       (self.batch_size, self.num_labels)			)





	def       SCREAMING_SNAKE_CASE__		(			self						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case			):
		lowercase	    =       self.num_labels
		lowercase	    =       TFLayoutLMForTokenClassification(config=snake_case			)

		lowercase	    =       model(snake_case						,       snake_case						,       attention_mask=snake_case						,       token_type_ids=snake_case						,       labels=snake_case			)
		self.parent.assertEqual(result.logits.shape						,       (self.batch_size, self.seq_length, self.num_labels)			)





	def       SCREAMING_SNAKE_CASE__		(			self						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case						,       snake_case			):
		lowercase	    =       TFLayoutLMForQuestionAnswering(config=snake_case			)

		lowercase	    =       model(snake_case						,       snake_case						,       attention_mask=snake_case						,       token_type_ids=snake_case			)
		self.parent.assertEqual(result.start_logits.shape						,       (self.batch_size, self.seq_length)			)
		self.parent.assertEqual(result.end_logits.shape						,       (self.batch_size, self.seq_length)			)





	def       SCREAMING_SNAKE_CASE__		(			self			):
		lowercase	    =       self.prepare_config_and_inputs()
		(
		    (
		    lowercase
		)    ,   (
		    lowercase
		)    ,   (
		    lowercase
		)    ,   (
		    lowercase
		)    ,   (
		    lowercase
		)    ,   (
		    lowercase
		)    ,   (
		    lowercase
		)    ,   (
		    lowercase
		)    ,   
		)	    =       config_and_inputs
		lowercase	    =       {
		    'input_ids': input_ids,
		    'bbox': bbox,
		    'token_type_ids': token_type_ids,
		    'attention_mask': input_mask,
		}
		return config, inputs_dict







@require_tf
class 			A_  (     __lowerCamelCase ,      __lowerCamelCase ,      unittest.TestCase  ):




	'''simple docstring'''


	_UpperCamelCase	:	Optional[Any]									=			(
	    (
	        TFLayoutLMModel,
	        TFLayoutLMForMaskedLM,
	        TFLayoutLMForTokenClassification,
	        TFLayoutLMForSequenceClassification,
	        TFLayoutLMForQuestionAnswering,
	    )
	    if is_tf_available()
	    else ()
	)
	_UpperCamelCase	:	Tuple									=			(
	    {
	        """feature-extraction""": TFLayoutLMModel,
	        """fill-mask""": TFLayoutLMForMaskedLM,
	        """text-classification""": TFLayoutLMForSequenceClassification,
	        """token-classification""": TFLayoutLMForTokenClassification,
	        """zero-shot""": TFLayoutLMForSequenceClassification,
	    }
	    if is_tf_available()
	    else {}
	)
	_UpperCamelCase	:	List[str]									=			False
	_UpperCamelCase	:	Union[str, Any]									=			True
	_UpperCamelCase	:	Optional[int]									=			10





	def       SCREAMING_SNAKE_CASE__		(			self			):
		lowercase	    =       TFLayoutLMModelTester(self			)
		lowercase	    =       ConfigTester(self						,       config_class=snake_case						,       hidden_size=37			)





	def       SCREAMING_SNAKE_CASE__		(			self			):
		self.config_tester.run_common_tests()





	def       SCREAMING_SNAKE_CASE__		(			self			):
		lowercase	    =       self.model_tester.prepare_config_and_inputs()
		self.model_tester.create_and_check_model(*snake_case			)





	def       SCREAMING_SNAKE_CASE__		(			self			):
		lowercase	    =       self.model_tester.prepare_config_and_inputs()
		self.model_tester.create_and_check_for_masked_lm(*snake_case			)





	def       SCREAMING_SNAKE_CASE__		(			self			):
		lowercase	    =       self.model_tester.prepare_config_and_inputs()
		self.model_tester.create_and_check_for_sequence_classification(*snake_case			)





	def       SCREAMING_SNAKE_CASE__		(			self			):
		lowercase	    =       self.model_tester.prepare_config_and_inputs()
		self.model_tester.create_and_check_for_token_classification(*snake_case			)





	def       SCREAMING_SNAKE_CASE__		(			self			):
		lowercase	    =       self.model_tester.prepare_config_and_inputs()
		self.model_tester.create_and_check_for_question_answering(*snake_case			)





	@slow
	def       SCREAMING_SNAKE_CASE__		(			self			):
		for model_name in TF_LAYOUTLM_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
			lowercase	    =       TFLayoutLMModel.from_pretrained(snake_case			)
			self.assertIsNotNone(snake_case			)





	@unittest.skip('Onnx compliancy broke with TF 2.10'			)
	def       SCREAMING_SNAKE_CASE__		(			self			):
		pass






def 				UpperCAmelCase_						(				):
	# Here we prepare a batch of 2 sequences to test a LayoutLM forward pass on:
	# fmt: off
	lowercase	    =       tf.convert_to_tensor([[101,1019,1014,1016,1037,1_2849,4747,1004,1_4246,2278,5439,4524,5002,2930,2193,2930,4341,3208,1005,1055,2171,2848,1_1300,3531,102],[101,4070,4034,7020,1024,3058,1015,1013,2861,1013,6070,1_9274,2772,6205,2_7814,1_6147,1_6147,4343,2047,1_0283,1_0969,1_4389,1012,2338,102]]				)  # noqa: E231
	lowercase	    =       tf.convert_to_tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],]				)  # noqa: E231
	lowercase	    =       tf.convert_to_tensor([[[0,0,0,0],[423,237,440,251],[427,272,441,287],[419,115,437,129],[961,885,992,912],[256,38,330,58],[256,38,330,58],[336,42,353,57],[360,39,401,56],[360,39,401,56],[411,39,471,59],[479,41,528,59],[533,39,630,60],[67,113,134,131],[141,115,209,132],[68,149,133,166],[141,149,187,164],[195,148,287,165],[195,148,287,165],[195,148,287,165],[295,148,349,165],[441,149,492,166],[497,149,546,164],[64,201,125,218],[1000,1000,1000,1000]],[[0,0,0,0],[662,150,754,166],[665,199,742,211],[519,213,554,228],[519,213,554,228],[134,433,187,454],[130,467,204,480],[130,467,204,480],[130,467,204,480],[130,467,204,480],[130,467,204,480],[314,469,376,482],[504,684,582,706],[941,825,973,900],[941,825,973,900],[941,825,973,900],[941,825,973,900],[610,749,652,765],[130,659,168,672],[176,657,237,672],[238,657,312,672],[443,653,628,672],[443,653,628,672],[716,301,825,317],[1000,1000,1000,1000]]]				)  # noqa: E231
	lowercase	    =       tf.convert_to_tensor([[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]				)  # noqa: E231
	# these are sequence labels (i.e. at the token level)
	lowercase	    =       tf.convert_to_tensor([[-100,10,10,10,9,1,-100,7,7,-100,7,7,4,2,5,2,8,8,-100,-100,5,0,3,2,-100],[-100,12,12,12,-100,12,10,-100,-100,-100,-100,10,12,9,-100,-100,-100,10,10,10,9,12,-100,10,-100]]				)  # noqa: E231
	# fmt: on

	return input_ids, attention_mask, bbox, token_type_ids, labels







@require_tf
class 			A_  (     unittest.TestCase  ):




	'''simple docstring'''


	@slow
	def       SCREAMING_SNAKE_CASE__		(			self			):
		lowercase	    =       TFLayoutLMModel.from_pretrained('microsoft/layoutlm-base-uncased'			)

		lowercase    ,   lowercase    ,   lowercase    ,   lowercase    ,   lowercase	    =       prepare_layoutlm_batch_inputs()

		# forward pass
		lowercase	    =       model(input_ids=snake_case						,       bbox=snake_case						,       attention_mask=snake_case						,       token_type_ids=snake_case			)

		# test the sequence output on [0, :3, :3]
		lowercase	    =       tf.convert_to_tensor(
		    [[0.1_785, -0.1_947, -0.0_425], [-0.3_254, -0.2_807, 0.2_553], [-0.5_391, -0.3_322, 0.3_364]]						,       )

		self.assertTrue(np.allclose(outputs.last_hidden_state[0, :3, :3]						,       snake_case						,       atol=1E-3			)			)

		# test the pooled output on [1, :3]
		lowercase	    =       tf.convert_to_tensor([-0.6_580, -0.0_214, 0.8_552]			)

		self.assertTrue(np.allclose(outputs.pooler_output[1, :3]						,       snake_case						,       atol=1E-3			)			)





	@slow
	def       SCREAMING_SNAKE_CASE__		(			self			):
		# initialize model with randomly initialized sequence classification head
		lowercase	    =       TFLayoutLMForSequenceClassification.from_pretrained('microsoft/layoutlm-base-uncased'						,       num_labels=2			)

		lowercase    ,   lowercase    ,   lowercase    ,   lowercase    ,   lowercase	    =       prepare_layoutlm_batch_inputs()

		# forward pass
		lowercase	    =       model(
		    input_ids=snake_case						,       bbox=snake_case						,       attention_mask=snake_case						,       token_type_ids=snake_case						,       labels=tf.convert_to_tensor([1, 1]			)						,       )

		# test whether we get a loss as a scalar
		lowercase	    =       outputs.loss
		lowercase	    =       (2,)
		self.assertEqual(loss.shape						,       snake_case			)

		# test the shape of the logits
		lowercase	    =       outputs.logits
		lowercase	    =       (2, 2)
		self.assertEqual(logits.shape						,       snake_case			)





	@slow
	def       SCREAMING_SNAKE_CASE__		(			self			):
		# initialize model with randomly initialized token classification head
		lowercase	    =       TFLayoutLMForTokenClassification.from_pretrained('microsoft/layoutlm-base-uncased'						,       num_labels=13			)

		lowercase    ,   lowercase    ,   lowercase    ,   lowercase    ,   lowercase	    =       prepare_layoutlm_batch_inputs()

		# forward pass
		lowercase	    =       model(
		    input_ids=snake_case						,       bbox=snake_case						,       attention_mask=snake_case						,       token_type_ids=snake_case						,       labels=snake_case			)

		# test the shape of the logits
		lowercase	    =       outputs.logits
		lowercase	    =       tf.convert_to_tensor((2, 25, 13)			)
		self.assertEqual(logits.shape						,       snake_case			)





	@slow
	def       SCREAMING_SNAKE_CASE__		(			self			):
		# initialize model with randomly initialized token classification head
		lowercase	    =       TFLayoutLMForQuestionAnswering.from_pretrained('microsoft/layoutlm-base-uncased'			)

		lowercase    ,   lowercase    ,   lowercase    ,   lowercase    ,   lowercase	    =       prepare_layoutlm_batch_inputs()

		# forward pass
		lowercase	    =       model(input_ids=snake_case						,       bbox=snake_case						,       attention_mask=snake_case						,       token_type_ids=snake_case			)

		# test the shape of the logits
		lowercase	    =       tf.convert_to_tensor((2, 25)			)
		self.assertEqual(outputs.start_logits.shape						,       snake_case			)
		self.assertEqual(outputs.end_logits.shape						,       snake_case			)








"""simple docstring"""
from typing import Any







class       a							:



 def __init__(     self				,       _snake_case     ):







  """simple docstring"""






  lowerCAmelCase    				= data
  lowerCAmelCase    				= None



 def __repr__(     self     ):







  """simple docstring"""






  return F'Node({self.data})'







class       a							:



 def __init__(     self     ):







  """simple docstring"""






  lowerCAmelCase    				= None



 def __iter__(     self     ):







  """simple docstring"""






  lowerCAmelCase    				= self.head
  while node:
   yield node.data
   lowerCAmelCase    				= node.next



 def __len__(     self     ):







  """simple docstring"""






  return sum(1 for _ in self     )



 def __repr__(     self     ):







  """simple docstring"""






  return "->".join([str(_snake_case     ) for item in self]     )



 def __getitem__(     self				,       _snake_case     ):







  """simple docstring"""






  if not 0 <= index < len(self     ):
   raise ValueError('list index out of range.'     )
  for i, node in enumerate(self     ):
   if i == index:
    return node
  return None



 def __setitem__(     self				,       _snake_case				,       _snake_case     ):







  """simple docstring"""






  if not 0 <= index < len(self     ):
   raise ValueError('list index out of range.'     )
  lowerCAmelCase    				= self.head
  for _ in range(_snake_case     ):
   lowerCAmelCase    				= current.next
  lowerCAmelCase    				= data



 def    UpperCamelCase__  (     self				,       _snake_case     ):







  """simple docstring"""






  self.insert_nth(len(self     )				,       _snake_case     )



 def    UpperCamelCase__  (     self				,       _snake_case     ):







  """simple docstring"""






  self.insert_nth(0				,       _snake_case     )



 def    UpperCamelCase__  (     self				,       _snake_case				,       _snake_case     ):







  """simple docstring"""






  if not 0 <= index <= len(self     ):
   raise IndexError('list index out of range'     )
  lowerCAmelCase    				= Node(_snake_case     )
  if self.head is None:
   lowerCAmelCase    				= new_node
  elif index == 0:
   lowerCAmelCase    				= self.head  # link new_node to head
   lowerCAmelCase    				= new_node
  else:
   lowerCAmelCase    				= self.head
   for _ in range(index - 1     ):
    lowerCAmelCase    				= temp.next
   lowerCAmelCase    				= temp.next
   lowerCAmelCase    				= new_node



 def    UpperCamelCase__  (     self     ):  # print every node data







  """simple docstring"""






  print(self     )



 def    UpperCamelCase__  (     self     ):







  """simple docstring"""






  return self.delete_nth(0     )



 def    UpperCamelCase__  (     self     ):  # delete from tail







  """simple docstring"""






  return self.delete_nth(len(self     ) - 1     )



 def    UpperCamelCase__  (     self				,       _snake_case = 0     ):







  """simple docstring"""






  if not 0 <= index <= len(self     ) - 1:  # test if index is valid
   raise IndexError('List index out of range.'     )
  lowerCAmelCase    				= self.head  # default first node
  if index == 0:
   lowerCAmelCase    				= self.head.next
  else:
   lowerCAmelCase    				= self.head
   for _ in range(index - 1     ):
    lowerCAmelCase    				= temp.next
   lowerCAmelCase    				= temp.next
   lowerCAmelCase    				= temp.next.next
  return delete_node.data



 def    UpperCamelCase__  (     self     ):







  """simple docstring"""






  return self.head is None



 def    UpperCamelCase__  (     self     ):







  """simple docstring"""






  lowerCAmelCase    				= None
  lowerCAmelCase    				= self.head

  while current:
   # Store the current node's next node.
   lowerCAmelCase    				= current.next
   # Make the current node's next point backwards
   lowerCAmelCase    				= prev
   # Make the previous node be the current node
   lowerCAmelCase    				= current
   # Make the current node the next node (to progress iteration)
   lowerCAmelCase    				= next_node
  # Return prev in order to put the head at the end
  lowerCAmelCase    				= prev


def 		_SCREAMING_SNAKE_CASE			():
 lowerCAmelCase    				= LinkedList()
 assert linked_list.is_empty() is True
 assert str(_UpperCAmelCase			) == ""

 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(_UpperCAmelCase			) == i
  linked_list.insert_nth(_UpperCAmelCase  ,     i + 1			)
 assert str(_UpperCAmelCase			) == "->".join(str(_UpperCAmelCase			) for i in range(1  ,     11			)			)

 linked_list.insert_head(0			)
 linked_list.insert_tail(11			)
 assert str(_UpperCAmelCase			) == "->".join(str(_UpperCAmelCase			) for i in range(0  ,     12			)			)

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

 assert all(linked_list[i] == i + 1 for i in range(0  ,     9			)			) is True

 for i in range(0  ,     9			):
  lowerCAmelCase    				= -i
 assert all(linked_list[i] == -i for i in range(0  ,     9			)			) is True

 linked_list.reverse()
 assert str(_UpperCAmelCase			) == "->".join(str(_UpperCAmelCase			) for i in range(-8  ,     1			)			)

def 		_SCREAMING_SNAKE_CASE			():
 lowerCAmelCase    				= [
     -9,
     100,
     Node(7734_5112			),
     'dlrow olleH',
     7,
     5555,
     0,
     -192.5_5555,
     'Hello, world!',
     77.9,
     Node(10			),
     None,
     None,
     12.20,
 ]
 lowerCAmelCase    				= LinkedList()

 for i in test_input:
  linked_list.insert_tail(_UpperCAmelCase			)

 # Check if it's empty or not
 assert linked_list.is_empty() is False
 assert (
     str(_UpperCAmelCase			) == "-9->100->Node(77345112)->dlrow olleH->7->5555->0->"
     "-192.55555->Hello, world!->77.9->Node(10)->None->None->12.2"
 )

 # Delete the head
 lowerCAmelCase    				= linked_list.delete_head()
 assert result == -9
 assert (
     str(_UpperCAmelCase			) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
     "Hello, world!->77.9->Node(10)->None->None->12.2"
 )

 # Delete the tail
 lowerCAmelCase    				= linked_list.delete_tail()
 assert result == 12.2
 assert (
     str(_UpperCAmelCase			) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
     "Hello, world!->77.9->Node(10)->None->None"
 )

 # Delete a node in specific location in linked list
 lowerCAmelCase    				= linked_list.delete_nth(10			)
 assert result is None
 assert (
     str(_UpperCAmelCase			) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
     "Hello, world!->77.9->Node(10)->None"
 )

 # Add a Node instance to its head
 linked_list.insert_head(Node('Hello again, world!'			)			)
 assert (
     str(_UpperCAmelCase			)
     == "Node(Hello again, world!)->100->Node(77345112)->dlrow olleH->"
     "7->5555->0->-192.55555->Hello, world!->77.9->Node(10)->None"
 )

 # Add None to its tail
 linked_list.insert_tail(_UpperCAmelCase			)
 assert (
     str(_UpperCAmelCase			)
     == "Node(Hello again, world!)->100->Node(77345112)->dlrow olleH->"
     "7->5555->0->-192.55555->Hello, world!->77.9->Node(10)->None->None"
 )

 # Reverse the linked list
 linked_list.reverse()
 assert (
     str(_UpperCAmelCase			)
     == "None->None->Node(10)->77.9->Hello, world!->-192.55555->0->5555->"
     "7->dlrow olleH->Node(77345112)->100->Node(Hello again, world!)"
 )

def 		_SCREAMING_SNAKE_CASE			():
 from doctest import testmod

 testmod()

 lowerCAmelCase    				= LinkedList()
 linked_list.insert_head(input('Inserting 1st at head '			).strip()			)
 linked_list.insert_head(input('Inserting 2nd at head '			).strip()			)
 print('\nPrint list:'			)
 linked_list.print_list()
 linked_list.insert_tail(input('\nInserting 1st at tail '			).strip()			)
 linked_list.insert_tail(input('Inserting 2nd at tail '			).strip()			)
 print('\nPrint list:'			)
 linked_list.print_list()
 print('\nDelete head'			)
 linked_list.delete_head()
 print('Delete tail'			)
 linked_list.delete_tail()
 print('\nPrint list:'			)
 linked_list.print_list()
 print('\nReverse linked list'			)
 linked_list.reverse()
 print('\nPrint list:'			)
 linked_list.print_list()
 print('\nString representation of linked list:'			)
 print(_UpperCAmelCase			)
 print('\nReading/changing Node data using indexing:'			)
 print(F'Element at Position 1: {linked_list[1]}'			)
 lowerCAmelCase    				= input('Enter New Value: '			).strip()
 print('New list:'			)
 print(_UpperCAmelCase			)
 print(F'length of linked_list is : {len(_UpperCAmelCase			)}'			)


if __name__ == "__main__":
       main()





