"""simple docstring"""







import inspect
import tempfile
import unittest

from huggingface_hub import hf_hub_download

from transformers import is_torch_available
from transformers.testing_utils import is_flaky, 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


_a  :  Tuple=				1e-4

if is_torch_available():
		import torch

		from transformers import AutoformerConfig, AutoformerForPrediction, AutoformerModel
		from transformers.models.autoformer.modeling_autoformer import AutoformerDecoder, AutoformerEncoder

@require_torch
class 	UpperCamelCase    :



				def __init__(self       :   Any			,						_A       :   str			,						_A       :   List[str]=16			,						_A       :   List[str]=13			,						_A       :   Union[str, Any]=7			,						_A       :   int=14			,						_A       :   Dict=10			,						_A       :   str=19			,						_A       :   Tuple=5			,						_A       :   int=4			,						_A       :   List[Any]=True			,						_A       :   Union[str, Any]=16			,						_A       :   Union[str, Any]=2			,						_A       :   int=4			,						_A       :   List[Any]=4			,						_A       :   List[str]="gelu"			,						_A       :   List[Any]=0.1			,						_A       :   Optional[int]=0.1			,						_A       :   Tuple=[1, 2, 3, 4, 5]			,						_A       :   Any=25			,						_A       :   int=5			,						)					->			Dict:
					__snake_case    :							int   	=				d_model
					__snake_case    :							int   	=				parent
					__snake_case    :							Optional[Any]   	=				batch_size
					__snake_case    :							str   	=				prediction_length
					__snake_case    :							Optional[int]   	=				context_length
					__snake_case    :							Optional[Any]   	=				cardinality
					__snake_case    :							str   	=				num_time_features
					__snake_case    :							Tuple   	=				lags_sequence
					__snake_case    :							Optional[Any]   	=				embedding_dimension
					__snake_case    :							Optional[Any]   	=				is_training
					__snake_case    :							Any   	=				hidden_size
					__snake_case    :							Dict   	=				num_hidden_layers
					__snake_case    :							List[Any]   	=				num_attention_heads
					__snake_case    :							Optional[Any]   	=				intermediate_size
					__snake_case    :							Optional[int]   	=				hidden_act
					__snake_case    :							int   	=				hidden_dropout_prob
					__snake_case    :							List[str]   	=				attention_probs_dropout_prob

					__snake_case    :							Tuple   	=				context_length
					__snake_case    :							List[str]   	=				prediction_length + label_length
					__snake_case    :							int   	=				label_length

					__snake_case    :							List[str]   	=				moving_average
					__snake_case    :							List[str]   	=				autocorrelation_factor



				def       _lowercase  (self       :   Optional[int])					->			List[str]:
					return AutoformerConfig(
					    d_model=self.d_model			,						encoder_layers=self.num_hidden_layers			,						decoder_layers=self.num_hidden_layers			,						encoder_attention_heads=self.num_attention_heads			,						decoder_attention_heads=self.num_attention_heads			,						encoder_ffn_dim=self.intermediate_size			,						decoder_ffn_dim=self.intermediate_size			,						dropout=self.hidden_dropout_prob			,						attention_dropout=self.attention_probs_dropout_prob			,						prediction_length=self.prediction_length			,						context_length=self.context_length			,						label_length=self.label_length			,						lags_sequence=self.lags_sequence			,						num_time_features=self.num_time_features			,						num_static_categorical_features=1			,						cardinality=[self.cardinality]			,						embedding_dimension=[self.embedding_dimension]			,						moving_average=self.moving_average			,						)



				def       _lowercase  (self       :   Any			,						_A       :   Union[str, Any])					->			Optional[Any]:
					__snake_case    :							Dict   	=				config.context_length + max(config.lags_sequence)

					__snake_case    :							Optional[int]   	=				ids_tensor([self.batch_size, 1]			,						config.cardinality[0])
					__snake_case    :							Any   	=				floats_tensor([self.batch_size, _past_length, config.num_time_features])
					__snake_case    :							Union[str, Any]   	=				floats_tensor([self.batch_size, _past_length])
					__snake_case    :							int   	=				floats_tensor([self.batch_size, _past_length]) > 0.5

					# decoder inputs
					__snake_case    :							Union[str, Any]   	=				floats_tensor([self.batch_size, config.prediction_length, config.num_time_features])
					__snake_case    :							List[Any]   	=				floats_tensor([self.batch_size, config.prediction_length])

					__snake_case    :							List[str]   	=				{
					    "past_values": past_values,
					    "static_categorical_features": static_categorical_features,
					    "past_time_features": past_time_features,
					    "past_observed_mask": past_observed_mask,
					    "future_time_features": future_time_features,
					    "future_values": future_values,
					}
					return inputs_dict



				def       _lowercase  (self       :   int)					->			List[Any]:
					__snake_case    :							List[str]   	=				self.get_config()
					__snake_case    :							Tuple   	=				self.prepare_autoformer_inputs_dict(a_)
					return config, inputs_dict



				def       _lowercase  (self       :   Union[str, Any])					->			Dict:
					__snake_case    :							List[Any]   	=				self.prepare_config_and_inputs()
					return config, inputs_dict






				def       _lowercase  (self       :   List[str]			,						_A       :   List[Any]			,						_A       :   str)					->			List[Any]:
					__snake_case    :							List[str]   	=				AutoformerModel(config=a_).to(a_).eval()
					__snake_case    :							Union[str, Any]   	=				model(**a_)

					__snake_case    :							List[str]   	=				outputs.encoder_last_hidden_state
					__snake_case    :							Optional[int]   	=				outputs.last_hidden_state

					with tempfile.TemporaryDirectory() as tmpdirname:
						__snake_case    :							List[str]   	=				model.get_encoder()
						encoder.save_pretrained(a_)
						__snake_case    :							Optional[Any]   	=				AutoformerEncoder.from_pretrained(a_).to(a_)

					__snake_case    :							int   	=				model.create_network_inputs(**a_)
					__snake_case    :							Tuple   	=				model.decomposition_layer(transformer_inputs[:, : config.context_length, ...])

					__snake_case    :							List[Any]   	=				torch.cat(
					    (transformer_inputs[:, : config.context_length, ...], feature[:, : config.context_length, ...])			,						dim=-1			,						)
					__snake_case    :							List[Any]   	=				encoder(inputs_embeds=a_)[0]
					self.parent.assertTrue((encoder_last_hidden_state_a - encoder_last_hidden_state).abs().max().item() < 1E-3)

					__snake_case    :							Union[str, Any]   	=				(
					    torch.mean(transformer_inputs[:, : config.context_length, ...]			,						dim=1)
					    .unsqueeze(1)
					    .repeat(1			,						config.prediction_length			,						1)
					)
					__snake_case    :							Tuple   	=				torch.zeros(
					    [transformer_inputs.shape[0], config.prediction_length, transformer_inputs.shape[2]]			,						device=enc_input.device			,						)

					__snake_case    :							Optional[Any]   	=				torch.cat(
					    (
					        torch.cat((seasonal_input[:, -config.label_length :, ...], zeros)			,						dim=1),
					        feature[:, config.context_length - config.label_length :, ...],
					    )			,						dim=-1			,						)
					__snake_case    :							str   	=				torch.cat(
					    (
					        torch.cat((trend_input[:, -config.label_length :, ...], mean)			,						dim=1),
					        feature[:, config.context_length - config.label_length :, ...],
					    )			,						dim=-1			,						)

					with tempfile.TemporaryDirectory() as tmpdirname:
						__snake_case    :							Optional[int]   	=				model.get_decoder()
						decoder.save_pretrained(a_)
						__snake_case    :							List[str]   	=				AutoformerDecoder.from_pretrained(a_).to(a_)

					__snake_case    :							Dict   	=				decoder(
					    trend=a_			,						inputs_embeds=a_			,						encoder_hidden_states=a_			,						)[0]

					self.parent.assertTrue((last_hidden_state_a - last_hidden_state).abs().max().item() < 1E-3)







@require_torch
class 	UpperCamelCase    (					__lowerCamelCase   ,			__lowerCamelCase   ,			unittest.TestCase		):
				UpperCAmelCase       :   Dict					=	(AutoformerModel, AutoformerForPrediction) if is_torch_available() else ()
				UpperCAmelCase       :   List[Any]					=	(AutoformerForPrediction,) if is_torch_available() else ()
				UpperCAmelCase       :   Optional[int]					=	{'''feature-extraction''': AutoformerModel} if is_torch_available() else {}
				UpperCAmelCase       :   int					=	False
				UpperCAmelCase       :   Optional[Any]					=	False
				UpperCAmelCase       :   List[str]					=	False
				UpperCAmelCase       :   Tuple					=	False
				UpperCAmelCase       :   Union[str, Any]					=	False
				UpperCAmelCase       :   int					=	False



				def       _lowercase  (self       :   int)					->			Optional[int]:
					__snake_case    :							Tuple   	=				AutoformerModelTester(self)
					__snake_case    :							Union[str, Any]   	=				ConfigTester(self			,						config_class=a_			,						has_text_modality=a_)



				def       _lowercase  (self       :   int)					->			int:
					self.config_tester.run_common_tests()



				def       _lowercase  (self       :   str)					->			Any:
					__snake_case    :							int   	=				self.model_tester.prepare_config_and_inputs()
					for model_class in self.all_model_classes:
						__snake_case    :							Dict   	=				model_class(a_)

						with tempfile.TemporaryDirectory() as tmpdirname:
							model.save_pretrained(a_)
							__snake_case    :							str   	=				model_class.from_pretrained(a_			,						output_loading_info=a_)
						self.assertEqual(info['missing_keys']			,						[])



				def       _lowercase  (self       :   Union[str, Any])					->			List[Any]:
					__snake_case    :							Dict   	=				self.model_tester.prepare_config_and_inputs_for_common()
					self.model_tester.check_encoder_decoder_model_standalone(*a_)



				@unittest.skip(reason='Model has no tokens embeddings')
				def       _lowercase  (self       :   Optional[int])					->			List[str]:
					pass



				def       _lowercase  (self       :   Optional[Any])					->			Optional[Any]:
					__snake_case    :							Union[str, Any]   	=				inspect.signature(getattr(a_			,						'forward'))
					# The main input is the name of the argument after `self`
					__snake_case    :							Optional[int]   	=				list(model_signature.parameters.keys())[1]
					self.assertEqual(AutoformerModel.main_input_name			,						a_)



				def       _lowercase  (self       :   Optional[Any])					->			int:
					__snake_case    :							Union[str, Any]   	=				self.model_tester.prepare_config_and_inputs_for_common()

					for model_class in self.all_model_classes:
						__snake_case    :							Tuple   	=				model_class(a_)
						__snake_case    :							List[Any]   	=				inspect.signature(model.forward)
						# signature.parameters is an OrderedDict => so arg_names order is deterministic
						__snake_case    :							Union[str, Any]   	=				[*signature.parameters.keys()]

						__snake_case    :							List[Any]   	=				[
						    "past_values",
						    "past_time_features",
						    "past_observed_mask",
						    "static_categorical_features",
						    "static_real_features",
						    "future_values",
						    "future_time_features",
						]

						if model.__class__.__name__ in ["AutoformerForPrediction"]:
							expected_arg_names.append('future_observed_mask')

						expected_arg_names.extend(
						    [
						        'decoder_attention_mask',
						        'head_mask',
						        'decoder_head_mask',
						        'cross_attn_head_mask',
						        'encoder_outputs',
						        'past_key_values',
						        'output_hidden_states',
						        'output_attentions',
						        'use_cache',
						        'return_dict',
						    ])

						self.assertListEqual(arg_names[: len(a_)]			,						a_)



				def       _lowercase  (self       :   Any)					->			List[str]:
					__snake_case    :							str   	=				self.model_tester.prepare_config_and_inputs_for_common()
					__snake_case    :							Optional[Any]   	=				True

					__snake_case    :							Any   	=				getattr(self.model_tester			,						'seq_length'			,						a_)
					__snake_case    :							Union[str, Any]   	=				getattr(self.model_tester			,						'decoder_seq_length'			,						a_)
					__snake_case    :							Tuple   	=				getattr(self.model_tester			,						'encoder_seq_length'			,						a_)
					__snake_case    :							Tuple   	=				getattr(self.model_tester			,						'd_model'			,						a_)
					__snake_case    :							Optional[int]   	=				getattr(self.model_tester			,						'num_attention_heads'			,						a_)
					__snake_case    :							Dict   	=				d_model // num_attention_heads

					for model_class in self.all_model_classes:
						__snake_case    :							Optional[Any]   	=				True
						__snake_case    :							Dict   	=				False
						__snake_case    :							Dict   	=				True
						__snake_case    :							List[Any]   	=				model_class(a_)
						model.to(a_)
						model.eval()
						with torch.no_grad():
							__snake_case    :							Tuple   	=				model(**self._prepare_for_class(a_			,						a_))
						__snake_case    :							Dict   	=				outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions
						self.assertEqual(len(a_)			,						self.model_tester.num_hidden_layers)

						# check that output_attentions also work using config
						del inputs_dict["output_attentions"]
						__snake_case    :							List[Any]   	=				True
						__snake_case    :							Tuple   	=				model_class(a_)
						model.to(a_)
						model.eval()
						with torch.no_grad():
							__snake_case    :							Union[str, Any]   	=				model(**self._prepare_for_class(a_			,						a_))
						__snake_case    :							Optional[Any]   	=				outputs.encoder_attentions
						self.assertEqual(len(a_)			,						self.model_tester.num_hidden_layers)

						self.assertListEqual(
						    list(attentions[0].shape[-3:])			,						[self.model_tester.num_attention_heads, encoder_seq_length, dim]			,						)
						__snake_case    :							List[str]   	=				len(a_)

						__snake_case    :							List[Any]   	=				7

						if "last_hidden_state" in outputs:
							correct_outlen += 1

						if "trend" in outputs:
							correct_outlen += 1

						if "past_key_values" in outputs:
							correct_outlen += 1  # past_key_values have been returned

						if "loss" in outputs:
							correct_outlen += 1

						if "params" in outputs:
							correct_outlen += 1

						self.assertEqual(a_			,						a_)

						# decoder attentions
						__snake_case    :							int   	=				outputs.decoder_attentions
						self.assertIsInstance(a_			,						(list, tuple))
						self.assertEqual(len(a_)			,						self.model_tester.num_hidden_layers)
						self.assertListEqual(
						    list(decoder_attentions[0].shape[-3:])			,						[self.model_tester.num_attention_heads, decoder_seq_length, dim]			,						)

						# cross attentions
						__snake_case    :							Optional[Any]   	=				outputs.cross_attentions
						self.assertIsInstance(a_			,						(list, tuple))
						self.assertEqual(len(a_)			,						self.model_tester.num_hidden_layers)
						self.assertListEqual(
						    list(cross_attentions[0].shape[-3:])			,						[self.model_tester.num_attention_heads, decoder_seq_length, dim]			,						)

					# Check attention is always last and order is fine
					__snake_case    :							Union[str, Any]   	=				True
					__snake_case    :							Tuple   	=				True
					__snake_case    :							str   	=				model_class(a_)
					model.to(a_)
					model.eval()
					with torch.no_grad():
						__snake_case    :							str   	=				model(**self._prepare_for_class(a_			,						a_))

					self.assertEqual(out_len + 2			,						len(a_))

					__snake_case    :							Union[str, Any]   	=				outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions

					self.assertEqual(len(a_)			,						self.model_tester.num_hidden_layers)
					self.assertListEqual(
					    list(self_attentions[0].shape[-3:])			,						[self.model_tester.num_attention_heads, encoder_seq_length, dim]			,						)






				@is_flaky()
				def       _lowercase  (self       :   Dict)					->			Union[str, Any]:
					super().test_retain_grad_hidden_states_attentions()







def 						__UpperCAmelCase       (					UpperCAmelCase_					:       Optional[Any]="train-batch.pt"						)							->    Union[str, Any]:

	'''simple docstring'''





	__snake_case    :							Any   	=				hf_hub_download(repo_id='hf-internal-testing/tourism-monthly-batch'    ,							filename=lowerCAmelCase_    ,							repo_type='dataset'						)
	__snake_case    :							Union[str, Any]   	=				torch.load(lowerCAmelCase_    ,							map_location=lowerCAmelCase_						)
	return batch

@require_torch
@slow
class 	UpperCamelCase    (					unittest.TestCase		):



				def       _lowercase  (self       :   Optional[Any])					->			Union[str, Any]:
					__snake_case    :							Union[str, Any]   	=				AutoformerModel.from_pretrained('huggingface/autoformer-tourism-monthly').to(a_)
					__snake_case    :							Union[str, Any]   	=				prepare_batch()

					with torch.no_grad():
						__snake_case    :							str   	=				model(
						    past_values=batch['past_values']			,						past_time_features=batch['past_time_features']			,						past_observed_mask=batch['past_observed_mask']			,						static_categorical_features=batch['static_categorical_features']			,						future_values=batch['future_values']			,						future_time_features=batch['future_time_features']			,						)[0]

					__snake_case    :							Dict   	=				torch.Size(
					    (64, model.config.prediction_length + model.config.label_length, model.config.feature_size))
					self.assertEqual(output.shape			,						a_)

					__snake_case    :							str   	=				torch.tensor(
					    [[0.3_593, -1.3_398, 0.6_330], [0.2_279, 1.5_396, -0.1_792], [0.0_450, 1.3_225, -0.2_335]]			,						device=a_)
					self.assertTrue(torch.allclose(output[0, :3, :3]			,						a_			,						atol=a_))



				def       _lowercase  (self       :   Optional[Any])					->			Any:
					__snake_case    :							List[Any]   	=				AutoformerForPrediction.from_pretrained('huggingface/autoformer-tourism-monthly').to(a_)
					__snake_case    :							Union[str, Any]   	=				prepare_batch('val-batch.pt')
					with torch.no_grad():
						__snake_case    :							int   	=				model(
						    past_values=batch['past_values']			,						past_time_features=batch['past_time_features']			,						past_observed_mask=batch['past_observed_mask']			,						static_categorical_features=batch['static_categorical_features']			,						).encoder_last_hidden_state
					__snake_case    :							str   	=				torch.Size((64, model.config.context_length, model.config.d_model))
					self.assertEqual(output.shape			,						a_)

					__snake_case    :							str   	=				torch.tensor(
					    [[-0.0_734, -0.9_036, 0.8_358], [4.7_186, 2.4_113, 1.9_581], [1.7_953, 2.3_558, 1.2_970]]			,						device=a_)
					self.assertTrue(torch.allclose(output[0, :3, :3]			,						a_			,						atol=a_))






				def       _lowercase  (self       :   Optional[int])					->			int:
					__snake_case    :							Optional[int]   	=				AutoformerForPrediction.from_pretrained('huggingface/autoformer-tourism-monthly').to(a_)
					__snake_case    :							Optional[int]   	=				prepare_batch('val-batch.pt')
					with torch.no_grad():
						__snake_case    :							Dict   	=				model.generate(
						    static_categorical_features=batch['static_categorical_features']			,						past_time_features=batch['past_time_features']			,						past_values=batch['past_values']			,						future_time_features=batch['future_time_features']			,						past_observed_mask=batch['past_observed_mask']			,						)
					__snake_case    :							Union[str, Any]   	=				torch.Size((64, model.config.num_parallel_samples, model.config.prediction_length))
					self.assertEqual(outputs.sequences.shape			,						a_)

					__snake_case    :							int   	=				torch.tensor([31_30.67_63, 40_56.52_93, 70_53.07_86]			,						device=a_)
					__snake_case    :							List[str]   	=				outputs.sequences.mean(dim=1)
					self.assertTrue(torch.allclose(mean_prediction[0, -3:]			,						a_			,						rtol=1E-1))






"""simple docstring"""







from typing import Any

class 	UpperCamelCase    :



				def __init__(self       :   List[str]			,						_A       :   Any)					->			int:
					__snake_case    :							Any   	=				data
					__snake_case    :							Dict   	=				None






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







class 	UpperCamelCase    :



				def __init__(self       :   Union[str, Any])					->			Union[str, Any]:
					__snake_case    :							Any   	=				None



				def __iter__(self       :   Tuple)					->			Any:
					__snake_case    :							List[str]   	=				self.head
					while node:
						yield node.data
						__snake_case    :							Any   	=				node.next



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



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



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



				def       _lowercase  (self       :   List[Any]			,						_A       :   Any)					->			None:
					self.insert_nth(len(self)			,						_A)



				def       _lowercase  (self       :   List[str]			,						_A       :   Any)					->			None:
					self.insert_nth(0			,						_A)



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



				def       _lowercase  (self       :   Optional[int])					->			None:  # print every node data
					print(self)



				def       _lowercase  (self       :   Optional[Any])					->			Any:
					return self.delete_nth(0)



				def       _lowercase  (self       :   List[str])					->			Any:  # delete from tail
					return self.delete_nth(len(self) - 1)



				def       _lowercase  (self       :   int			,						_A       :   int = 0)					->			Any:
					if not 0 <= index <= len(self) - 1:  # test if index is valid
						raise IndexError('List index out of range.')
					__snake_case    :							int   	=				self.head  # default first node
					if index == 0:
						__snake_case    :							Any   	=				self.head.next
					else:
						__snake_case    :							List[Any]   	=				self.head
						for _ in range(index - 1):
							__snake_case    :							List[str]   	=				temp.next
						__snake_case    :							Union[str, Any]   	=				temp.next
						__snake_case    :							str   	=				temp.next.next
					return delete_node.data



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






				def       _lowercase  (self       :   Tuple)					->			None:
					__snake_case    :							List[Any]   	=				None
					__snake_case    :							Optional[Any]   	=				self.head

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







def 						__UpperCAmelCase       (					)							->    None:

	'''simple docstring'''





	__snake_case    :							Union[str, Any]   	=				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						):
		__snake_case    :							Tuple   	=				-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 						__UpperCAmelCase       (					)							->    None:

	'''simple docstring'''





	__snake_case    :							str   	=				[
	    -9,
	    1_00,
	    Node(77_34_51_12						),
	    'dlrow olleH',
	    7,
	    55_55,
	    0,
	    -192.55_555,
	    'Hello, world!',
	    77.9,
	    Node(10						),
	    None,
	    None,
	    12.20,
	]
	__snake_case    :							Optional[Any]   	=				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
	__snake_case    :							int   	=				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
	__snake_case    :							Any   	=				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
	__snake_case    :							Tuple   	=				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 						__UpperCAmelCase       (					)							->    List[Any]:

	'''simple docstring'''





	from doctest import testmod

	testmod()

	__snake_case    :							int   	=				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]}"						)
	__snake_case    :							Optional[Any]   	=				input('Enter New Value: '						).strip()
	print('New list:'						)
	print(UpperCAmelCase_						)
	print(F"length of linked_list is : {len(UpperCAmelCase_						)}"						)


if __name__ == "__main__":
	main()





