


'''simple docstring'''




import argparse
import json
from pathlib import Path

import requests
import torch
from huggingface_hub import cached_download, hf_hub_url
from PIL import Image

from transformers import DPTConfig, DPTForDepthEstimation, DPTForSemanticSegmentation, DPTImageProcessor
from transformers.utils import logging


logging.set_verbosity_info()
_lowerCAmelCase  :		str		     =	logging.get_logger(__name__)

def 			__UpperCamelCase    (    _A    :				Tuple				)    ->      Optional[Any]:




	"""simple docstring"""





	lowerCAmelCase					:    List[Any]      							= DPTConfig(embedding_type='hybrid'				)

	if "large" in checkpoint_url:
		lowerCAmelCase					:    Dict      							= 10_24
		lowerCAmelCase					:    List[Any]      							= 40_96
		lowerCAmelCase					:    Optional[Any]      							= 24
		lowerCAmelCase					:    Any      							= 16
		lowerCAmelCase					:    Any      							= [5, 11, 17, 23]
		lowerCAmelCase					:    Optional[int]      							= [2_56, 5_12, 10_24, 10_24]
		lowerCAmelCase					:    Dict      							= (1, 3_84, 3_84)

	if "nyu" or "midas" in checkpoint_url:
		lowerCAmelCase					:    int      							= 7_68
		lowerCAmelCase					:    Optional[int]      							= [1, 1, 1, 0.5]
		lowerCAmelCase					:    Any      							= [2_56, 5_12, 7_68, 7_68]
		lowerCAmelCase					:    Tuple      							= 1_50
		lowerCAmelCase					:    List[str]      							= 16
		lowerCAmelCase					:    Dict      							= (1, 3_84, 3_84)
		lowerCAmelCase					:    List[Any]      							= False
		lowerCAmelCase					:    Tuple      							= 'project'

	if "ade" in checkpoint_url:
		lowerCAmelCase					:    str      							= True
		lowerCAmelCase					:    Tuple      							= 7_68
		lowerCAmelCase					:    Optional[Any]      							= [1, 1, 1, 0.5]
		lowerCAmelCase					:    Optional[int]      							= 1_50
		lowerCAmelCase					:    Optional[Any]      							= 16
		lowerCAmelCase					:    List[Any]      							= 'huggingface/label-files'
		lowerCAmelCase					:    str      							= 'ade20k-id2label.json'
		lowerCAmelCase					:    str      							= json.load(open(cached_download(hf_hub_url(_A					,   _A					,   repo_type='dataset'				)				)					,   'r'				)				)
		lowerCAmelCase					:    Optional[Any]      							= {int(_A				): v for k, v in idalabel.items()}
		lowerCAmelCase					:    str      							= idalabel
		lowerCAmelCase					:    Dict      							= {v: k for k, v in idalabel.items()}
		lowerCAmelCase					:    Optional[int]      							= [1, 1_50, 4_80, 4_80]

	return config, expected_shape

def 			__UpperCamelCase    (    _A    :				int				)    ->      Union[str, Any]:




	"""simple docstring"""





	lowerCAmelCase					:    List[str]      							= ['pretrained.model.head.weight', 'pretrained.model.head.bias']
	for k in ignore_keys:
		state_dict.pop(_A					,   _A				)

def 			__UpperCamelCase    (    _A    :				Optional[Any]				)    ->      str:




	"""simple docstring"""





	if (
	    "pretrained.model" in name
	    and "cls_token" not in name
	    and "pos_embed" not in name
	    and "patch_embed" not in name
	):
		lowerCAmelCase					:    List[str]      							= name.replace('pretrained.model'					,   'dpt.encoder'				)
	if "pretrained.model" in name:
		lowerCAmelCase					:    List[Any]      							= name.replace('pretrained.model'					,   'dpt.embeddings'				)
	if "patch_embed" in name:
		lowerCAmelCase					:    Tuple      							= name.replace('patch_embed'					,   ''				)
	if "pos_embed" in name:
		lowerCAmelCase					:    Union[str, Any]      							= name.replace('pos_embed'					,   'position_embeddings'				)
	if "attn.proj" in name:
		lowerCAmelCase					:    Optional[Any]      							= name.replace('attn.proj'					,   'attention.output.dense'				)
	if "proj" in name and "project" not in name:
		lowerCAmelCase					:    Dict      							= name.replace('proj'					,   'projection'				)
	if "blocks" in name:
		lowerCAmelCase					:    Any      							= name.replace('blocks'					,   'layer'				)
	if "mlp.fc1" in name:
		lowerCAmelCase					:    Union[str, Any]      							= name.replace('mlp.fc1'					,   'intermediate.dense'				)
	if "mlp.fc2" in name:
		lowerCAmelCase					:    str      							= name.replace('mlp.fc2'					,   'output.dense'				)
	if "norm1" in name and "backbone" not in name:
		lowerCAmelCase					:    List[Any]      							= name.replace('norm1'					,   'layernorm_before'				)
	if "norm2" in name and "backbone" not in name:
		lowerCAmelCase					:    Any      							= name.replace('norm2'					,   'layernorm_after'				)
	if "scratch.output_conv" in name:
		lowerCAmelCase					:    Tuple      							= name.replace('scratch.output_conv'					,   'head'				)
	if "scratch" in name:
		lowerCAmelCase					:    List[Any]      							= name.replace('scratch'					,   'neck'				)
	if "layer1_rn" in name:
		lowerCAmelCase					:    Dict      							= name.replace('layer1_rn'					,   'convs.0'				)
	if "layer2_rn" in name:
		lowerCAmelCase					:    Any      							= name.replace('layer2_rn'					,   'convs.1'				)
	if "layer3_rn" in name:
		lowerCAmelCase					:    int      							= name.replace('layer3_rn'					,   'convs.2'				)
	if "layer4_rn" in name:
		lowerCAmelCase					:    Dict      							= name.replace('layer4_rn'					,   'convs.3'				)
	if "refinenet" in name:
		lowerCAmelCase					:    Tuple      							= int(name[len('neck.refinenet'				) : len('neck.refinenet'				) + 1]				)
		# tricky here: we need to map 4 to 0, 3 to 1, 2 to 2 and 1 to 3
		lowerCAmelCase					:    Any      							= name.replace(F"refinenet{layer_idx}"					,   F"fusion_stage.layers.{abs(layer_idx-4				)}"				)
	if "out_conv" in name:
		lowerCAmelCase					:    Any      							= name.replace('out_conv'					,   'projection'				)
	if "resConfUnit1" in name:
		lowerCAmelCase					:    Union[str, Any]      							= name.replace('resConfUnit1'					,   'residual_layer1'				)
	if "resConfUnit2" in name:
		lowerCAmelCase					:    List[Any]      							= name.replace('resConfUnit2'					,   'residual_layer2'				)
	if "conv1" in name:
		lowerCAmelCase					:    Tuple      							= name.replace('conv1'					,   'convolution1'				)
	if "conv2" in name:
		lowerCAmelCase					:    Tuple      							= name.replace('conv2'					,   'convolution2'				)
	# readout blocks
	if "pretrained.act_postprocess1.0.project.0" in name:
		lowerCAmelCase					:    List[Any]      							= name.replace('pretrained.act_postprocess1.0.project.0'					,   'neck.reassemble_stage.readout_projects.0.0'				)
	if "pretrained.act_postprocess2.0.project.0" in name:
		lowerCAmelCase					:    Optional[int]      							= name.replace('pretrained.act_postprocess2.0.project.0'					,   'neck.reassemble_stage.readout_projects.1.0'				)
	if "pretrained.act_postprocess3.0.project.0" in name:
		lowerCAmelCase					:    List[str]      							= name.replace('pretrained.act_postprocess3.0.project.0'					,   'neck.reassemble_stage.readout_projects.2.0'				)
	if "pretrained.act_postprocess4.0.project.0" in name:
		lowerCAmelCase					:    int      							= name.replace('pretrained.act_postprocess4.0.project.0'					,   'neck.reassemble_stage.readout_projects.3.0'				)

	# resize blocks
	if "pretrained.act_postprocess1.3" in name:
		lowerCAmelCase					:    Dict      							= name.replace('pretrained.act_postprocess1.3'					,   'neck.reassemble_stage.layers.0.projection'				)
	if "pretrained.act_postprocess1.4" in name:
		lowerCAmelCase					:    Any      							= name.replace('pretrained.act_postprocess1.4'					,   'neck.reassemble_stage.layers.0.resize'				)
	if "pretrained.act_postprocess2.3" in name:
		lowerCAmelCase					:    Dict      							= name.replace('pretrained.act_postprocess2.3'					,   'neck.reassemble_stage.layers.1.projection'				)
	if "pretrained.act_postprocess2.4" in name:
		lowerCAmelCase					:    Dict      							= name.replace('pretrained.act_postprocess2.4'					,   'neck.reassemble_stage.layers.1.resize'				)
	if "pretrained.act_postprocess3.3" in name:
		lowerCAmelCase					:    List[str]      							= name.replace('pretrained.act_postprocess3.3'					,   'neck.reassemble_stage.layers.2.projection'				)
	if "pretrained.act_postprocess4.3" in name:
		lowerCAmelCase					:    Optional[Any]      							= name.replace('pretrained.act_postprocess4.3'					,   'neck.reassemble_stage.layers.3.projection'				)
	if "pretrained.act_postprocess4.4" in name:
		lowerCAmelCase					:    Dict      							= name.replace('pretrained.act_postprocess4.4'					,   'neck.reassemble_stage.layers.3.resize'				)
	if "pretrained" in name:
		lowerCAmelCase					:    List[Any]      							= name.replace('pretrained'					,   'dpt'				)
	if "bn" in name:
		lowerCAmelCase					:    Union[str, Any]      							= name.replace('bn'					,   'batch_norm'				)
	if "head" in name:
		lowerCAmelCase					:    Union[str, Any]      							= name.replace('head'					,   'head.head'				)
	if "encoder.norm" in name:
		lowerCAmelCase					:    int      							= name.replace('encoder.norm'					,   'layernorm'				)
	if "auxlayer" in name:
		lowerCAmelCase					:    List[str]      							= name.replace('auxlayer'					,   'auxiliary_head.head'				)
	if "backbone" in name:
		lowerCAmelCase					:    List[Any]      							= name.replace('backbone'					,   'backbone.bit.encoder'				)

	if ".." in name:
		lowerCAmelCase					:    List[Any]      							= name.replace('..'					,   '.'				)

	if "stem.conv" in name:
		lowerCAmelCase					:    List[str]      							= name.replace('stem.conv'					,   'bit.embedder.convolution'				)
	if "blocks" in name:
		lowerCAmelCase					:    Optional[int]      							= name.replace('blocks'					,   'layers'				)
	if "convolution" in name and "backbone" in name:
		lowerCAmelCase					:    Union[str, Any]      							= name.replace('convolution'					,   'conv'				)
	if "layer" in name and "backbone" in name:
		lowerCAmelCase					:    str      							= name.replace('layer'					,   'layers'				)
	if "backbone.bit.encoder.bit" in name:
		lowerCAmelCase					:    Any      							= name.replace('backbone.bit.encoder.bit'					,   'backbone.bit'				)
	if "embedder.conv" in name:
		lowerCAmelCase					:    Union[str, Any]      							= name.replace('embedder.conv'					,   'embedder.convolution'				)
	if "backbone.bit.encoder.stem.norm" in name:
		lowerCAmelCase					:    Optional[int]      							= name.replace('backbone.bit.encoder.stem.norm'					,   'backbone.bit.embedder.norm'				)
	return name

def 			__UpperCamelCase    (    _A    :				Dict					,   _A    :				str				)    ->      Union[str, Any]:




	"""simple docstring"""





	for i in range(config.num_hidden_layers				):
		# read in weights + bias of input projection layer (in timm, this is a single matrix + bias)
		lowerCAmelCase					:    Union[str, Any]      							= state_dict.pop(F"dpt.encoder.layer.{i}.attn.qkv.weight"				)
		lowerCAmelCase					:    Optional[Any]      							= state_dict.pop(F"dpt.encoder.layer.{i}.attn.qkv.bias"				)
		# next, add query, keys and values (in that order) to the state dict
		lowerCAmelCase					:    Dict      							= in_proj_weight[: config.hidden_size, :]
		lowerCAmelCase					:    Optional[int]      							= in_proj_bias[: config.hidden_size]
		lowerCAmelCase					:    Any      							= in_proj_weight[
		    config.hidden_size : config.hidden_size * 2, :
		]
		lowerCAmelCase					:    Optional[int]      							= in_proj_bias[
		    config.hidden_size : config.hidden_size * 2
		]
		lowerCAmelCase					:    Union[str, Any]      							= in_proj_weight[
		    -config.hidden_size :, :
		]
		lowerCAmelCase					:    str      							= in_proj_bias[-config.hidden_size :]

def 			__UpperCamelCase    (    )    ->      List[Any]:




	"""simple docstring"""





	lowerCAmelCase					:    int      							= 'http://images.cocodataset.org/val2017/000000039769.jpg'
	lowerCAmelCase					:    Dict      							= Image.open(requests.get(_A					,   stream=_A				).raw				)
	return im

@torch.no_grad()
def 			__UpperCamelCase    (    _A    :				Dict					,   _A    :				Union[str, Any]					,   _A    :				List[str]					,   _A    :				Optional[int]					,   _A    :				Optional[int]				)    ->      Union[str, Any]:




	"""simple docstring"""





	lowerCAmelCase							,   lowerCAmelCase					:    List[str]      							= get_dpt_config(_A				)
	# load original state_dict from URL
	# state_dict = torch.hub.load_state_dict_from_url(checkpoint_url, map_location="cpu")
	lowerCAmelCase					:    str      							= torch.load(_A					,   map_location='cpu'				)
	# remove certain keys
	remove_ignore_keys_(_A				)
	# rename keys
	for key in state_dict.copy().keys():
		lowerCAmelCase					:    str      							= state_dict.pop(_A				)
		lowerCAmelCase					:    Union[str, Any]      							= val
	# read in qkv matrices
	read_in_q_k_v(_A					,   _A				)

	# load HuggingFace model
	lowerCAmelCase					:    Any      							= DPTForSemanticSegmentation(_A				) if 'ade' in checkpoint_url else DPTForDepthEstimation(_A				)
	model.load_state_dict(_A				)
	model.eval()

	# Check outputs on an image
	lowerCAmelCase					:    List[str]      							= 4_80 if 'ade' in checkpoint_url else 3_84
	lowerCAmelCase					:    Any      							= DPTImageProcessor(size=_A				)

	lowerCAmelCase					:    Tuple      							= prepare_img()
	lowerCAmelCase					:    int      							= image_processor(_A					,   return_tensors='pt'				)

	# forward pass
	lowerCAmelCase					:    Optional[Any]      							= model(**_A				).logits if 'ade' in checkpoint_url else model(**_A				).predicted_depth

	if show_prediction:
		lowerCAmelCase					:    Union[str, Any]      							= (
		    torch.nn.functional.interpolate(
		        outputs.unsqueeze(1				)					,   size=(image.size[1], image.size[0])					,   mode='bicubic'					,   align_corners=_A					,   )
		    .squeeze()
		    .cpu()
		    .numpy()
		)

		Image.fromarray((prediction / prediction.max()) * 2_55				).show()

	if pytorch_dump_folder_path is not None:
		Path(_A				).mkdir(exist_ok=_A				)
		print(F"Saving model to {pytorch_dump_folder_path}"				)
		model.save_pretrained(_A				)
		print(F"Saving image processor to {pytorch_dump_folder_path}"				)
		image_processor.save_pretrained(_A				)

	if push_to_hub:
		model.push_to_hub('ybelkada/dpt-hybrid-midas'				)
		image_processor.push_to_hub('ybelkada/dpt-hybrid-midas'				)


if __name__ == "__main__":
				_lowerCAmelCase  :		str		     =	argparse.ArgumentParser()
				# Required parameters
				parser.add_argument(
				    '--checkpoint_url',
				    default='https://github.com/intel-isl/DPT/releases/download/1_0/dpt_large-midas-2f21e586.pt',
				    type=str,
				    help='URL of the original DPT checkpoint you\'d like to convert.',
				)
				parser.add_argument(
				    '--pytorch_dump_folder_path',
				    default=None,
				    type=str,
				    required=False,
				    help='Path to the output PyTorch model directory.',
				)
				parser.add_argument(
				    '--push_to_hub',
				    action='store_true',
				)
				parser.add_argument(
				    '--model_name',
				    default='dpt-large',
				    type=str,
				    help='Name of the model, in case you\'re pushing to the hub.',
				)
				parser.add_argument(
				    '--show_prediction',
				    action='store_true',
				)

				_lowerCAmelCase  :		Any		     =	parser.parse_args()
				convert_dpt_checkpoint(
				    args.checkpoint_url, args.pytorch_dump_folder_path, args.push_to_hub, args.model_name, args.show_prediction
				)




'''simple docstring'''




from typing import Any



class  lowerCAmelCase				:



	def __init__(					self ,					snake_case__    ):
		lowerCAmelCase					:    Optional[int]      							= data
		lowerCAmelCase					:    Optional[Any]      							= None



	def __repr__(					self    ):
		return f"Node({self.data})"



class  lowerCAmelCase				:



	def __init__(					self    ):
		lowerCAmelCase					:    Dict      							= None



	def __iter__(					self    ):
		lowerCAmelCase					:    Optional[Any]      							= self.head
		while node:
			yield node.data
			lowerCAmelCase					:    Optional[int]      							= node.next



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



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



	def __getitem__(					self ,					snake_case__    ):
		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__    ):
		if not 0 <= index < len(self    ):
			raise ValueError('list index out of range.'    )
		lowerCAmelCase					:    Any      							= self.head
		for _ in range(snake_case__    ):
			lowerCAmelCase					:    List[str]      							= current.next
		lowerCAmelCase					:    int      							= data



	def 				lowercase     (					self ,					snake_case__    ):
		self.insert_nth(len(self    ) ,					snake_case__    )



	def 				lowercase     (					self ,					snake_case__    ):
		self.insert_nth(0 ,					snake_case__    )



	def 				lowercase     (					self ,					snake_case__ ,					snake_case__    ):
		if not 0 <= index <= len(self    ):
			raise IndexError('list index out of range'    )
		lowerCAmelCase					:    List[str]      							= Node(snake_case__    )
		if self.head is None:
			lowerCAmelCase					:    int      							= new_node
		elif index == 0:
			lowerCAmelCase					:    List[Any]      							= self.head  # link new_node to head
			lowerCAmelCase					:    List[Any]      							= new_node
		else:
			lowerCAmelCase					:    List[Any]      							= self.head
			for _ in range(index - 1    ):
				lowerCAmelCase					:    Union[str, Any]      							= temp.next
			lowerCAmelCase					:    Any      							= temp.next
			lowerCAmelCase					:    str      							= new_node



	def 				lowercase     (					self    ):  # print every node data
		print(self    )



	def 				lowercase     (					self    ):
		return self.delete_nth(0    )



	def 				lowercase     (					self    ):  # delete from tail
		return self.delete_nth(len(self    ) - 1    )



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



	def 				lowercase     (					self    ):
		return self.head is None



	def 				lowercase     (					self    ):
		lowerCAmelCase					:    List[Any]      							= None
		lowerCAmelCase					:    Any      							= self.head

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


def 			__UpperCamelCase    (    )    ->      None:




	"""simple docstring"""





	lowerCAmelCase					:    Tuple      							= LinkedList()
	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_nth(_A					,   i + 1				)
	assert str(_A				) == "->".join(str(_A				) for i in range(1					,   11				)				)

	linked_list.insert_head(0				)
	linked_list.insert_tail(11				)
	assert str(_A				) == "->".join(str(_A				) 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(_A				) == 9
	assert str(_A				) == "->".join(str(_A				) 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					:    Optional[Any]      							= -i
	assert all(linked_list[i] == -i for i in range(0					,   9				)				) is True

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

def 			__UpperCamelCase    (    )    ->      None:




	"""simple docstring"""





	lowerCAmelCase					:    Optional[int]      							= [
	    -9,
	    1_00,
	    Node(77_34_51_12				),
	    'dlrow olleH',
	    7,
	    55_55,
	    0,
	    -1_92.5_55_55,
	    'Hello, world!',
	    77.9,
	    Node(10				),
	    None,
	    None,
	    12.20,
	]
	lowerCAmelCase					:    Dict      							= LinkedList()

	for i in test_input:
		linked_list.insert_tail(_A				)

	# Check if it's empty or not
	assert linked_list.is_empty() is False
	assert (
	    str(_A				) == "-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					:    Optional[Any]      							= linked_list.delete_head()
	assert result == -9
	assert (
	    str(_A				) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
	    "Hello, world!->77.9->Node(10)->None->None->12.2"
	)

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

def 			__UpperCamelCase    (    )    ->      List[Any]:




	"""simple docstring"""





	from doctest import testmod

	testmod()

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


if __name__ == "__main__":
				main()
