

import inspect
import unittest

from transformers import SegformerConfig, is_torch_available, is_vision_available
from transformers.models.auto import get_values
from transformers.testing_utils import require_torch, slow, torch_device

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
 import torch

 from transformers import (
     MODEL_MAPPING,
     SegformerForImageClassification,
     SegformerForSemanticSegmentation,
     SegformerModel,
 )
 from transformers.models.segformer.modeling_segformer import SEGFORMER_PRETRAINED_MODEL_ARCHIVE_LIST


if is_vision_available():
 from PIL import Image

 from transformers import SegformerImageProcessor






class 						__magic_name__					(							snake_case				):






     def 	UpperCAmelCase_				(				self	)->     Any:
         UpperCamelCase_			  =						self.config_class(**self.inputs_dict	)
         self.parent.assertTrue(hasattr(_lowercase		,						"hidden_sizes"	)	)
         self.parent.assertTrue(hasattr(_lowercase		,						"num_attention_heads"	)	)
         self.parent.assertTrue(hasattr(_lowercase		,						"num_encoder_blocks"	)	)






class 						__magic_name__					:






     def __init__(				self		,						_lowercase		,						_lowercase=13		,						_lowercase=64		,						_lowercase=3		,						_lowercase=4		,						_lowercase=[2, 2, 2, 2]		,						_lowercase=[8, 4, 2, 1]		,						_lowercase=[16, 32, 64, 128]		,						_lowercase=[1, 4, 8, 16]		,						_lowercase=[1, 2, 4, 8]		,						_lowercase=True		,						_lowercase=True		,						_lowercase="gelu"		,						_lowercase=0.1		,						_lowercase=0.1		,						_lowercase=0.02		,						_lowercase=3		,						_lowercase=None		,						)->     Union[str, Any]:
         UpperCamelCase_			  =						parent
         UpperCamelCase_			  =						batch_size
         UpperCamelCase_			  =						image_size
         UpperCamelCase_			  =						num_channels
         UpperCamelCase_			  =						num_encoder_blocks
         UpperCamelCase_			  =						sr_ratios
         UpperCamelCase_			  =						depths
         UpperCamelCase_			  =						hidden_sizes
         UpperCamelCase_			  =						downsampling_rates
         UpperCamelCase_			  =						num_attention_heads
         UpperCamelCase_			  =						is_training
         UpperCamelCase_			  =						use_labels
         UpperCamelCase_			  =						hidden_act
         UpperCamelCase_			  =						hidden_dropout_prob
         UpperCamelCase_			  =						attention_probs_dropout_prob
         UpperCamelCase_			  =						initializer_range
         UpperCamelCase_			  =						num_labels
         UpperCamelCase_			  =						scope






     def 	UpperCAmelCase_				(				self	)->     List[Any]:
         UpperCamelCase_			  =						floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]	)

         UpperCamelCase_			  =						None
         if self.use_labels:
             UpperCamelCase_			  =						ids_tensor([self.batch_size, self.image_size, self.image_size]		,						self.num_labels	)

         UpperCamelCase_			  =						self.get_config()
         return config, pixel_values, labels






     def 	UpperCAmelCase_				(				self	)->     List[str]:
         return SegformerConfig(
             image_size=self.image_size		,						num_channels=self.num_channels		,						num_encoder_blocks=self.num_encoder_blocks		,						depths=self.depths		,						hidden_sizes=self.hidden_sizes		,						num_attention_heads=self.num_attention_heads		,						hidden_act=self.hidden_act		,						hidden_dropout_prob=self.hidden_dropout_prob		,						attention_probs_dropout_prob=self.attention_probs_dropout_prob		,						initializer_range=self.initializer_range		,						)






     def 	UpperCAmelCase_				(				self		,						_lowercase		,						_lowercase		,						_lowercase	)->     Any:
         UpperCamelCase_			  =						SegformerModel(config=_lowercase	)
         model.to(_lowercase	)
         model.eval()
         UpperCamelCase_			  =						model(_lowercase	)
         UpperCamelCase_			  =						UpperCamelCase_			  =						self.image_size // (self.downsampling_rates[-1] * 2)
         self.parent.assertEqual(
             result.last_hidden_state.shape		,						(self.batch_size, self.hidden_sizes[-1], expected_height, expected_width)	)






     def 	UpperCAmelCase_				(				self		,						_lowercase		,						_lowercase		,						_lowercase	)->     str:
         UpperCamelCase_			  =						self.num_labels
         UpperCamelCase_			  =						SegformerForSemanticSegmentation(_lowercase	)
         model.to(_lowercase	)
         model.eval()
         UpperCamelCase_			  =						model(_lowercase	)
         self.parent.assertEqual(
             result.logits.shape		,						(self.batch_size, self.num_labels, self.image_size // 4, self.image_size // 4)	)
         UpperCamelCase_			  =						model(_lowercase		,						labels=_lowercase	)
         self.parent.assertEqual(
             result.logits.shape		,						(self.batch_size, self.num_labels, self.image_size // 4, self.image_size // 4)	)
         self.parent.assertGreater(result.loss		,						0.0	)






     def 	UpperCAmelCase_				(				self		,						_lowercase		,						_lowercase		,						_lowercase	)->     List[str]:
         UpperCamelCase_			  =						1
         UpperCamelCase_			  =						SegformerForSemanticSegmentation(config=_lowercase	)
         model.to(_lowercase	)
         model.eval()
         UpperCamelCase_			  =						torch.randint(0		,						1		,						(self.batch_size, self.image_size, self.image_size)	).to(_lowercase	)
         UpperCamelCase_			  =						model(_lowercase		,						labels=_lowercase	)
         self.parent.assertGreater(result.loss		,						0.0	)






     def 	UpperCAmelCase_				(				self	)->     List[str]:
         UpperCamelCase_			  =						self.prepare_config_and_inputs()
         UpperCamelCase_  ,       UpperCamelCase_  ,       UpperCamelCase_			  =						config_and_inputs
         UpperCamelCase_			  =						{"pixel_values": pixel_values}
         return config, inputs_dict






@require_torch
class 						__magic_name__					(							snake_case			,      snake_case			,      unittest.TestCase				):
     UpperCamelCase_	:Optional[int]										=      (
         (
             SegformerModel,
             SegformerForSemanticSegmentation,
             SegformerForImageClassification,
         )
         if is_torch_available()
         else ()
     )
     UpperCamelCase_	:Dict										=      (
         {
             """feature-extraction""": SegformerModel,
             """image-classification""": SegformerForImageClassification,
             """image-segmentation""": SegformerForSemanticSegmentation,
         }
         if is_torch_available()
         else {}
     )

     UpperCamelCase_	:Optional[Any]										=      True
     UpperCamelCase_	:int										=      False
     UpperCamelCase_	:Any										=      False
     UpperCamelCase_	:Dict										=      False






     def 	UpperCAmelCase_				(				self	)->     int:
         UpperCamelCase_			  =						SegformerModelTester(self	)
         UpperCamelCase_			  =						SegformerConfigTester(self		,						config_class=_lowercase	)






     def 	UpperCAmelCase_				(				self	)->     str:
         self.config_tester.run_common_tests()






     def 	UpperCAmelCase_				(				self	)->     List[str]:
         UpperCamelCase_			  =						self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_model(*_lowercase	)






     def 	UpperCAmelCase_				(				self	)->     Tuple:
         UpperCamelCase_			  =						self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_for_binary_image_segmentation(*_lowercase	)






     def 	UpperCAmelCase_				(				self	)->     Dict:
         UpperCamelCase_			  =						self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_for_image_segmentation(*_lowercase	)






     @unittest.skip("SegFormer does not use inputs_embeds"	)
     def 	UpperCAmelCase_				(				self	)->     List[str]:
         pass






     @unittest.skip("SegFormer does not have get_input_embeddings method and get_output_embeddings methods"	)
     def 	UpperCAmelCase_				(				self	)->     Any:
         pass






     def 	UpperCAmelCase_				(				self	)->     List[str]:
         UpperCamelCase_  ,       UpperCamelCase_			  =						self.model_tester.prepare_config_and_inputs_for_common()

         for model_class in self.all_model_classes:
             UpperCamelCase_			  =						model_class(_lowercase	)
             UpperCamelCase_			  =						inspect.signature(model.forward	)
             # signature.parameters is an OrderedDict => so arg_names order is deterministic
             UpperCamelCase_			  =						[*signature.parameters.keys()]

             UpperCamelCase_			  =						["pixel_values"]
             self.assertListEqual(arg_names[:1]		,						_lowercase	)






     def 	UpperCAmelCase_				(				self	)->     int:
         UpperCamelCase_  ,       UpperCamelCase_			  =						self.model_tester.prepare_config_and_inputs_for_common()
         UpperCamelCase_			  =						True

         for model_class in self.all_model_classes:
             UpperCamelCase_			  =						True
             UpperCamelCase_			  =						False
             UpperCamelCase_			  =						True
             UpperCamelCase_			  =						model_class(_lowercase	)
             model.to(_lowercase	)
             model.eval()
             with torch.no_grad():
                 UpperCamelCase_			  =						model(**self._prepare_for_class(_lowercase		,						_lowercase	)	)
             UpperCamelCase_			  =						outputs.attentions

             UpperCamelCase_			  =						sum(self.model_tester.depths	)
             self.assertEqual(len(_lowercase	)		,						_lowercase	)

             # check that output_attentions also work using config
             del inputs_dict["output_attentions"]
             UpperCamelCase_			  =						True
             UpperCamelCase_			  =						model_class(_lowercase	)
             model.to(_lowercase	)
             model.eval()
             with torch.no_grad():
                 UpperCamelCase_			  =						model(**self._prepare_for_class(_lowercase		,						_lowercase	)	)
             UpperCamelCase_			  =						outputs.attentions

             self.assertEqual(len(_lowercase	)		,						_lowercase	)

             # verify the first attentions (first block, first layer)
             UpperCamelCase_			  =						(self.model_tester.image_size // 4) ** 2
             UpperCamelCase_			  =						(self.model_tester.image_size // (4 * self.model_tester.sr_ratios[0])) ** 2
             self.assertListEqual(
                 list(attentions[0].shape[-3:]	)		,						[self.model_tester.num_attention_heads[0], expected_seq_len, expected_reduced_seq_len]		,						)

             # verify the last attentions (last block, last layer)
             UpperCamelCase_			  =						(self.model_tester.image_size // 32) ** 2
             UpperCamelCase_			  =						(self.model_tester.image_size // (32 * self.model_tester.sr_ratios[-1])) ** 2
             self.assertListEqual(
                 list(attentions[-1].shape[-3:]	)		,						[self.model_tester.num_attention_heads[-1], expected_seq_len, expected_reduced_seq_len]		,						)
             UpperCamelCase_			  =						len(_lowercase	)

             # Check attention is always last and order is fine
             UpperCamelCase_			  =						True
             UpperCamelCase_			  =						True
             UpperCamelCase_			  =						model_class(_lowercase	)
             model.to(_lowercase	)
             model.eval()
             with torch.no_grad():
                 UpperCamelCase_			  =						model(**self._prepare_for_class(_lowercase		,						_lowercase	)	)

             self.assertEqual(out_len + 1		,						len(_lowercase	)	)

             UpperCamelCase_			  =						outputs.attentions

             self.assertEqual(len(_lowercase	)		,						_lowercase	)
             # verify the first attentions (first block, first layer)
             UpperCamelCase_			  =						(self.model_tester.image_size // 4) ** 2
             UpperCamelCase_			  =						(self.model_tester.image_size // (4 * self.model_tester.sr_ratios[0])) ** 2
             self.assertListEqual(
                 list(self_attentions[0].shape[-3:]	)		,						[self.model_tester.num_attention_heads[0], expected_seq_len, expected_reduced_seq_len]		,						)






     def 	UpperCAmelCase_				(				self	)->     Dict:
         def check_hidden_states_output(_lowercase		,						_lowercase		,						_lowercase	):
             UpperCamelCase_			  =						model_class(_lowercase	)
             model.to(_lowercase	)
             model.eval()

             with torch.no_grad():
                 UpperCamelCase_			  =						model(**self._prepare_for_class(_lowercase		,						_lowercase	)	)

             UpperCamelCase_			  =						outputs.hidden_states

             UpperCamelCase_			  =						self.model_tester.num_encoder_blocks
             self.assertEqual(len(_lowercase	)		,						_lowercase	)

             # verify the first hidden states (first block)
             self.assertListEqual(
                 list(hidden_states[0].shape[-3:]	)		,						[
                     self.model_tester.hidden_sizes[0],
                     self.model_tester.image_size // 4,
                     self.model_tester.image_size // 4,
                 ]		,						)

         UpperCamelCase_  ,       UpperCamelCase_			  =						self.model_tester.prepare_config_and_inputs_for_common()

         for model_class in self.all_model_classes:
             UpperCamelCase_			  =						True
             check_hidden_states_output(_lowercase		,						_lowercase		,						_lowercase	)

             # check that output_hidden_states also work using config
             del inputs_dict["output_hidden_states"]
             UpperCamelCase_			  =						True

             check_hidden_states_output(_lowercase		,						_lowercase		,						_lowercase	)






     def 	UpperCAmelCase_				(				self	)->     str:
         if not self.model_tester.is_training:
             return

         UpperCamelCase_  ,       UpperCamelCase_			  =						self.model_tester.prepare_config_and_inputs_for_common()
         UpperCamelCase_			  =						True

         for model_class in self.all_model_classes:
             if model_class in get_values(_lowercase	):
                 continue

             UpperCamelCase_			  =						model_class(_lowercase	)
             model.to(_lowercase	)
             model.train()
             UpperCamelCase_			  =						self._prepare_for_class(_lowercase		,						_lowercase		,						return_labels=_lowercase	)
             UpperCamelCase_			  =						model(**_lowercase	).loss
             loss.backward()






     @unittest.skip("Will be fixed soon by reducing the size of the model used for common tests."	)
     def 	UpperCAmelCase_				(				self	)->     Optional[Any]:
         pass






     @slow
     def 	UpperCAmelCase_				(				self	)->     int:
         for model_name in SEGFORMER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
             UpperCamelCase_			  =						SegformerModel.from_pretrained(_lowercase	)
             self.assertIsNotNone(_lowercase	)




def 			lowerCAmelCase(      )->						List[Any]:



    """simple docstring"""






    UpperCamelCase_			  =						Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png"			)
    return image






@require_torch
class 						__magic_name__					(							unittest.TestCase				):






     @slow
     def 	UpperCAmelCase_				(				self	)->     str:
         # only resize + normalize
         UpperCamelCase_			  =						SegformerImageProcessor(
             image_scale=(512, 512)		,						keep_ratio=_lowercase		,						align=_lowercase		,						do_random_crop=_lowercase	)
         UpperCamelCase_			  =						SegformerForSemanticSegmentation.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512"	).to(
             _lowercase	)

         UpperCamelCase_			  =						prepare_img()
         UpperCamelCase_			  =						image_processor(images=_lowercase		,						return_tensors="pt"	)
         UpperCamelCase_			  =						encoded_inputs.pixel_values.to(_lowercase	)

         with torch.no_grad():
             UpperCamelCase_			  =						model(_lowercase	)

         UpperCamelCase_			  =						torch.Size((1, model.config.num_labels, 128, 128)	)
         self.assertEqual(outputs.logits.shape		,						_lowercase	)

         UpperCamelCase_			  =						torch.tensor(
             [
                 [[-4.6_310, -5.5_232, -6.2_356], [-5.1_921, -6.1_444, -6.5_996], [-5.4_424, -6.2_790, -6.7_574]],
                 [[-12.1_391, -13.3_122, -13.9_554], [-12.8_732, -13.9_352, -14.3_563], [-12.9_438, -13.8_226, -14.2_513]],
                 [[-12.5_134, -13.4_686, -14.4_915], [-12.8_669, -14.4_343, -14.7_758], [-13.2_523, -14.5_819, -15.0_694]],
             ]	).to(_lowercase	)
         self.assertTrue(torch.allclose(outputs.logits[0, :3, :3, :3]		,						_lowercase		,						atol=1e-4	)	)






     @slow
     def 	UpperCAmelCase_				(				self	)->     Dict:
         # only resize + normalize
         UpperCamelCase_			  =						SegformerImageProcessor(
             image_scale=(512, 512)		,						keep_ratio=_lowercase		,						align=_lowercase		,						do_random_crop=_lowercase	)
         UpperCamelCase_			  =						SegformerForSemanticSegmentation.from_pretrained(
             "nvidia/segformer-b1-finetuned-cityscapes-1024-1024"	).to(_lowercase	)

         UpperCamelCase_			  =						prepare_img()
         UpperCamelCase_			  =						image_processor(images=_lowercase		,						return_tensors="pt"	)
         UpperCamelCase_			  =						encoded_inputs.pixel_values.to(_lowercase	)

         with torch.no_grad():
             UpperCamelCase_			  =						model(_lowercase	)

         UpperCamelCase_			  =						torch.Size((1, model.config.num_labels, 128, 128)	)
         self.assertEqual(outputs.logits.shape		,						_lowercase	)

         UpperCamelCase_			  =						torch.tensor(
             [
                 [[-13.5_748, -13.9_111, -12.6_500], [-14.3_500, -15.3_683, -14.2_328], [-14.7_532, -16.0_424, -15.6_087]],
                 [[-17.1_651, -15.8_725, -12.9_653], [-17.2_580, -17.3_718, -14.8_223], [-16.6_058, -16.8_783, -16.7_452]],
                 [[-3.6_456, -3.0_209, -1.4_203], [-3.0_797, -3.1_959, -2.0_000], [-1.8_757, -1.9_217, -1.6_997]],
             ]	).to(_lowercase	)
         self.assertTrue(torch.allclose(outputs.logits[0, :3, :3, :3]		,						_lowercase		,						atol=1e-1	)	)






     @slow
     def 	UpperCAmelCase_				(				self	)->     Optional[int]:
         # only resize + normalize
         UpperCamelCase_			  =						SegformerImageProcessor(
             image_scale=(512, 512)		,						keep_ratio=_lowercase		,						align=_lowercase		,						do_random_crop=_lowercase	)
         UpperCamelCase_			  =						SegformerForSemanticSegmentation.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512"	).to(
             _lowercase	)

         UpperCamelCase_			  =						prepare_img()
         UpperCamelCase_			  =						image_processor(images=_lowercase		,						return_tensors="pt"	)
         UpperCamelCase_			  =						encoded_inputs.pixel_values.to(_lowercase	)

         with torch.no_grad():
             UpperCamelCase_			  =						model(_lowercase	)

         UpperCamelCase_			  =						outputs.logits.detach().cpu()

         UpperCamelCase_			  =						image_processor.post_process_semantic_segmentation(outputs=_lowercase		,						target_sizes=[(500, 300)]	)
         UpperCamelCase_			  =						torch.Size((500, 300)	)
         self.assertEqual(segmentation[0].shape		,						_lowercase	)

         UpperCamelCase_			  =						image_processor.post_process_semantic_segmentation(outputs=_lowercase	)
         UpperCamelCase_			  =						torch.Size((128, 128)	)
         self.assertEqual(segmentation[0].shape		,						_lowercase	)



from typing import Any






class 						__magic_name__					:






     def __init__(				self		,						_lowercase	)->     List[str]:
         UpperCamelCase_			  =						data
         UpperCamelCase_			  =						None






     def __repr__(				self	)->     str:
         return F"Node({self.data})"






class 						__magic_name__					:






     def __init__(				self	)->     Optional[Any]:
         UpperCamelCase_			  =						None






     def __iter__(				self	)->     Any:
         UpperCamelCase_			  =						self.head
         while node:
             yield node.data
             UpperCamelCase_			  =						node.next






     def __len__(				self	)->     int:
         return sum(1 for _ in self	)






     def __repr__(				self	)->     str:
         return "->".join([str(_lowercase	) for item in self]	)






     def __getitem__(				self		,						_lowercase	)->     Any:
         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		,						_lowercase		,						_lowercase	)->     None:
         if not 0 <= index < len(self	):
             raise ValueError("list index out of range."	)
         UpperCamelCase_			  =						self.head
         for _ in range(_lowercase	):
             UpperCamelCase_			  =						current.next
         UpperCamelCase_			  =						data






     def 	UpperCAmelCase_				(				self		,						_lowercase	)->     None:
         self.insert_nth(len(self	)		,						_lowercase	)






     def 	UpperCAmelCase_				(				self		,						_lowercase	)->     None:
         self.insert_nth(0		,						_lowercase	)






     def 	UpperCAmelCase_				(				self		,						_lowercase		,						_lowercase	)->     None:
         if not 0 <= index <= len(self	):
             raise IndexError("list index out of range"	)
         UpperCamelCase_			  =						Node(_lowercase	)
         if self.head is None:
             UpperCamelCase_			  =						new_node
         elif index == 0:
             UpperCamelCase_			  =						self.head  # link new_node to head
             UpperCamelCase_			  =						new_node
         else:
             UpperCamelCase_			  =						self.head
             for _ in range(index - 1	):
                 UpperCamelCase_			  =						temp.next
             UpperCamelCase_			  =						temp.next
             UpperCamelCase_			  =						new_node






     def 	UpperCAmelCase_				(				self	)->     None:  # print every node data
         print(self	)






     def 	UpperCAmelCase_				(				self	)->     Any:
         return self.delete_nth(0	)






     def 	UpperCAmelCase_				(				self	)->     Any:  # delete from tail
         return self.delete_nth(len(self	) - 1	)






     def 	UpperCAmelCase_				(				self		,						_lowercase = 0	)->     Any:
         if not 0 <= index <= len(self	) - 1:  # test if index is valid
             raise IndexError("List index out of range."	)
         UpperCamelCase_			  =						self.head  # default first node
         if index == 0:
             UpperCamelCase_			  =						self.head.next
         else:
             UpperCamelCase_			  =						self.head
             for _ in range(index - 1	):
                 UpperCamelCase_			  =						temp.next
             UpperCamelCase_			  =						temp.next
             UpperCamelCase_			  =						temp.next.next
         return delete_node.data






     def 	UpperCAmelCase_				(				self	)->     bool:
         return self.head is None






     def 	UpperCAmelCase_				(				self	)->     None:
         UpperCamelCase_			  =						None
         UpperCamelCase_			  =						self.head

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




def 			lowerCAmelCase(      )->						None:



    """simple docstring"""






    UpperCamelCase_			  =						LinkedList()
    assert linked_list.is_empty() is True
    assert str(SCREAMING_SNAKE_CASE_			) == ""

    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(1_0			):
        assert len(SCREAMING_SNAKE_CASE_			) == i
        linked_list.insert_nth(SCREAMING_SNAKE_CASE_			,						i + 1			)
    assert str(SCREAMING_SNAKE_CASE_			) == "->".join(str(SCREAMING_SNAKE_CASE_			) for i in range(1			,						1_1			)			)

    linked_list.insert_head(0			)
    linked_list.insert_tail(1_1			)
    assert str(SCREAMING_SNAKE_CASE_			) == "->".join(str(SCREAMING_SNAKE_CASE_			) for i in range(0			,						1_2			)			)

    assert linked_list.delete_head() == 0
    assert linked_list.delete_nth(9			) == 1_0
    assert linked_list.delete_tail() == 1_1
    assert len(SCREAMING_SNAKE_CASE_			) == 9
    assert str(SCREAMING_SNAKE_CASE_			) == "->".join(str(SCREAMING_SNAKE_CASE_			) for i in range(1			,						1_0			)			)

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

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

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




def 			lowerCAmelCase(      )->						None:



    """simple docstring"""






    UpperCamelCase_			  =						[
        -9,
        1_0_0,
        Node(7_7_3_4_5_1_1_2			),
        "dlrow olleH",
        7,
        5_5_5_5,
        0,
        -192.5_5555,
        "Hello, world!",
        77.9,
        Node(1_0			),
        None,
        None,
        12.20,
    ]
    UpperCamelCase_			  =						LinkedList()

    for i in test_input:
        linked_list.insert_tail(SCREAMING_SNAKE_CASE_			)

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

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

    # Delete the tail
    UpperCamelCase_			  =						linked_list.delete_tail()
    assert result == 12.2
    assert (
        str(SCREAMING_SNAKE_CASE_			) == "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
    UpperCamelCase_			  =						linked_list.delete_nth(1_0			)
    assert result is None
    assert (
        str(SCREAMING_SNAKE_CASE_			) == "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(SCREAMING_SNAKE_CASE_			)
        == "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(SCREAMING_SNAKE_CASE_			)
    assert (
        str(SCREAMING_SNAKE_CASE_			)
        == "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(SCREAMING_SNAKE_CASE_			)
        == "None->None->Node(10)->77.9->Hello, world!->-192.55555->0->5555->"
        "7->dlrow olleH->Node(77345112)->100->Node(Hello again, world!)"
    )




def 			lowerCAmelCase(      )->						List[Any]:



    """simple docstring"""






    from doctest import testmod

    testmod()

    UpperCamelCase_			  =						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(SCREAMING_SNAKE_CASE_			)
    print("\nReading/changing Node data using indexing:"			)
    print(f"Element at Position 1: {linked_list[1]}"			)
    UpperCamelCase_			  =						input("Enter New Value: "			).strip()
    print("New list:"			)
    print(SCREAMING_SNAKE_CASE_			)
    print(f"length of linked_list is : {len(SCREAMING_SNAKE_CASE_			)}"			)


if __name__ == "__main__":
 main()
