
import tempfile
import unittest

import numpy as np

from diffusers import (
    DDIMScheduler,
    DPMSolverMultistepScheduler,
    EulerAncestralDiscreteScheduler,
    EulerDiscreteScheduler,
    LMSDiscreteScheduler,
    OnnxStableDiffusionPipeline,
    PNDMScheduler,
)
from diffusers.utils.testing_utils import is_onnx_available, nightly, require_onnxruntime, require_torch_gpu

from ..test_pipelines_onnx_common import OnnxPipelineTesterMixin


if is_onnx_available():
		import onnxruntime as ort

class 							snake_case_ (				lowerCAmelCase   ,  unittest.TestCase    ):
			__lowerCamelCase							:     List[str]						=			"""hf-internal-testing/tiny-random-OnnxStableDiffusionPipeline"""





			def 						__A						(		self      ,						__lowerCAmelCase=0      ):
					SCREAMING_SNAKE_CASE_					:	str		  =			np.random.RandomState(_lowercase      )
					SCREAMING_SNAKE_CASE_					:	Dict		  =			{
					    'prompt': 'A painting of a squirrel eating a burger',
					    'generator': generator,
					    'num_inference_steps': 2,
					    'guidance_scale': 7.5,
					    'output_type': 'numpy',
					}
					return inputs





			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	Any		  =			OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint      ,						provider='CPUExecutionProvider'      )
					pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	List[Any]		  =			self.get_dummy_inputs()
					SCREAMING_SNAKE_CASE_					:	Dict		  =			pipe(**_lowercase      ).images
					SCREAMING_SNAKE_CASE_					:	Dict		  =			image[0, -3:, -3:, -1]

					assert image.shape == (1, 128, 128, 3)
					SCREAMING_SNAKE_CASE_					:	List[Any]		  =			np.array([0.6_50_72, 0.5_84_92, 0.4_82_19, 0.5_55_21, 0.5_31_80, 0.5_59_39, 0.5_06_97, 0.3_98_00, 0.4_64_55]      )

					assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2





			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	List[Any]		  =			OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint      ,						provider='CPUExecutionProvider'      )
					SCREAMING_SNAKE_CASE_					:	Dict		  =			PNDMScheduler.from_config(pipe.scheduler.config      ,						skip_prk_steps=_lowercase      )
					pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	int		  =			self.get_dummy_inputs()
					SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			pipe(**_lowercase      ).images
					SCREAMING_SNAKE_CASE_					:	Tuple		  =			image[0, -3:, -3:, -1]

					assert image.shape == (1, 128, 128, 3)
					SCREAMING_SNAKE_CASE_					:	List[str]		  =			np.array([0.6_58_63, 0.5_94_25, 0.4_93_26, 0.5_63_13, 0.5_38_75, 0.5_66_27, 0.5_10_65, 0.3_97_77, 0.4_63_30]      )

					assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2





			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	Tuple		  =			OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint      ,						provider='CPUExecutionProvider'      )
					SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			LMSDiscreteScheduler.from_config(pipe.scheduler.config      )
					pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	Tuple		  =			self.get_dummy_inputs()
					SCREAMING_SNAKE_CASE_					:	List[Any]		  =			pipe(**_lowercase      ).images
					SCREAMING_SNAKE_CASE_					:	List[str]		  =			image[0, -3:, -3:, -1]

					assert image.shape == (1, 128, 128, 3)
					SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			np.array([0.5_37_55, 0.6_07_86, 0.4_74_02, 0.4_94_88, 0.5_18_69, 0.4_98_19, 0.4_79_85, 0.3_89_57, 0.4_42_79]      )

					assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2





			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint      ,						provider='CPUExecutionProvider'      )
					SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			EulerDiscreteScheduler.from_config(pipe.scheduler.config      )
					pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	Tuple		  =			self.get_dummy_inputs()
					SCREAMING_SNAKE_CASE_					:	str		  =			pipe(**_lowercase      ).images
					SCREAMING_SNAKE_CASE_					:	Dict		  =			image[0, -3:, -3:, -1]

					assert image.shape == (1, 128, 128, 3)
					SCREAMING_SNAKE_CASE_					:	Optional[int]		  =			np.array([0.5_37_55, 0.6_07_86, 0.4_74_02, 0.4_94_88, 0.5_18_69, 0.4_98_19, 0.4_79_85, 0.3_89_57, 0.4_42_79]      )

					assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2





			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	Any		  =			OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint      ,						provider='CPUExecutionProvider'      )
					SCREAMING_SNAKE_CASE_					:	Optional[Any]		  =			EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config      )
					pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	Any		  =			self.get_dummy_inputs()
					SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			pipe(**_lowercase      ).images
					SCREAMING_SNAKE_CASE_					:	Optional[Any]		  =			image[0, -3:, -3:, -1]

					assert image.shape == (1, 128, 128, 3)
					SCREAMING_SNAKE_CASE_					:	Any		  =			np.array([0.5_38_17, 0.6_08_12, 0.4_73_84, 0.4_95_30, 0.5_18_94, 0.4_98_14, 0.4_79_84, 0.3_89_58, 0.4_42_71]      )

					assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2





			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	List[Any]		  =			OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint      ,						provider='CPUExecutionProvider'      )
					SCREAMING_SNAKE_CASE_					:	Tuple		  =			DPMSolverMultistepScheduler.from_config(pipe.scheduler.config      )
					pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			self.get_dummy_inputs()
					SCREAMING_SNAKE_CASE_					:	str		  =			pipe(**_lowercase      ).images
					SCREAMING_SNAKE_CASE_					:	int		  =			image[0, -3:, -3:, -1]

					assert image.shape == (1, 128, 128, 3)
					SCREAMING_SNAKE_CASE_					:	Optional[Any]		  =			np.array([0.5_38_95, 0.6_08_08, 0.4_79_33, 0.4_96_08, 0.5_18_86, 0.4_99_50, 0.4_80_53, 0.3_89_57, 0.4_42_00]      )

					assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-2





			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	int		  =			OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint      ,						provider='CPUExecutionProvider'      )
					pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	str		  =			self.get_dummy_inputs()
					SCREAMING_SNAKE_CASE_					:	Tuple		  =			3 * [inputs['prompt']]

					# forward
					SCREAMING_SNAKE_CASE_					:	Any		  =			pipe(**_lowercase      )
					SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			output.images[0, -3:, -3:, -1]

					SCREAMING_SNAKE_CASE_					:	Optional[Any]		  =			self.get_dummy_inputs()
					SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			3 * [inputs.pop('prompt'      )]

					SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			pipe.tokenizer(
					    _lowercase      ,						padding='max_length'      ,						max_length=pipe.tokenizer.model_max_length      ,						truncation=_lowercase      ,						return_tensors='np'      ,						)
					SCREAMING_SNAKE_CASE_					:	str		  =			text_inputs['input_ids']

					SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			pipe.text_encoder(input_ids=text_inputs.astype(np.intaa      )      )[0]

					SCREAMING_SNAKE_CASE_					:	Optional[Any]		  =			prompt_embeds

					# forward
					SCREAMING_SNAKE_CASE_					:	Tuple		  =			pipe(**_lowercase      )
					SCREAMING_SNAKE_CASE_					:	Any		  =			output.images[0, -3:, -3:, -1]

					assert np.abs(image_slice_a.flatten() - image_slice_a.flatten()      ).max() < 1e-4






			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	Any		  =			OnnxStableDiffusionPipeline.from_pretrained(self.hub_checkpoint      ,						provider='CPUExecutionProvider'      )
					pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	Tuple		  =			self.get_dummy_inputs()
					SCREAMING_SNAKE_CASE_					:	str		  =			3 * ['this is a negative prompt']
					SCREAMING_SNAKE_CASE_					:	List[str]		  =			negative_prompt
					SCREAMING_SNAKE_CASE_					:	Optional[int]		  =			3 * [inputs['prompt']]

					# forward
					SCREAMING_SNAKE_CASE_					:	Any		  =			pipe(**_lowercase      )
					SCREAMING_SNAKE_CASE_					:	Any		  =			output.images[0, -3:, -3:, -1]

					SCREAMING_SNAKE_CASE_					:	Optional[int]		  =			self.get_dummy_inputs()
					SCREAMING_SNAKE_CASE_					:	Dict		  =			3 * [inputs.pop('prompt'      )]

					SCREAMING_SNAKE_CASE_					:	Optional[Any]		  =			[]
					for p in [prompt, negative_prompt]:
							SCREAMING_SNAKE_CASE_					:	List[Any]		  =			pipe.tokenizer(
							    _lowercase      ,						padding='max_length'      ,						max_length=pipe.tokenizer.model_max_length      ,						truncation=_lowercase      ,						return_tensors='np'      ,						)
							SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			text_inputs['input_ids']

							embeds.append(pipe.text_encoder(input_ids=text_inputs.astype(np.intaa      )      )[0]      )

					SCREAMING_SNAKE_CASE_  ,      SCREAMING_SNAKE_CASE_					:	Optional[Any]		  =			embeds

					# forward
					SCREAMING_SNAKE_CASE_					:	List[Any]		  =			pipe(**_lowercase      )
					SCREAMING_SNAKE_CASE_					:	List[str]		  =			output.images[0, -3:, -3:, -1]

					assert np.abs(image_slice_a.flatten() - image_slice_a.flatten()      ).max() < 1e-4

@nightly
@require_onnxruntime
@require_torch_gpu
class 							snake_case_ (				unittest.TestCase    ):





			@property
			def 						__A						(		self      ):
					return (
					    "CUDAExecutionProvider",
					    {
					        "gpu_mem_limit": "15000000000",  # 15GB
					        "arena_extend_strategy": "kSameAsRequested",
					    },
					)





			@property
			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	str		  =			ort.SessionOptions()
					SCREAMING_SNAKE_CASE_					:	Optional[int]		  =			False
					return options





			def 						__A						(		self      ):
					# using the PNDM scheduler by default
					SCREAMING_SNAKE_CASE_					:	int		  =			OnnxStableDiffusionPipeline.from_pretrained(
					    'CompVis/stable-diffusion-v1-4'      ,						revision='onnx'      ,						safety_checker=_lowercase      ,						feature_extractor=_lowercase      ,						provider=self.gpu_provider      ,						sess_options=self.gpu_options      ,						)
					sd_pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	Optional[Any]		  =			'A painting of a squirrel eating a burger'
					np.random.seed(0      )
					SCREAMING_SNAKE_CASE_					:	List[str]		  =			sd_pipe([prompt]      ,						guidance_scale=6.0      ,						num_inference_steps=10      ,						output_type='np'      )
					SCREAMING_SNAKE_CASE_					:	Optional[int]		  =			output.images

					SCREAMING_SNAKE_CASE_					:	Any		  =			image[0, -3:, -3:, -1]

					assert image.shape == (1, 512, 512, 3)
					SCREAMING_SNAKE_CASE_					:	Dict		  =			np.array([0.04_52, 0.03_90, 0.00_87, 0.03_50, 0.06_17, 0.03_64, 0.05_44, 0.05_23, 0.07_20]      )

					assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-3





			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	Any		  =			DDIMScheduler.from_pretrained(
					    'runwayml/stable-diffusion-v1-5'      ,						subfolder='scheduler'      ,						revision='onnx'      )
					SCREAMING_SNAKE_CASE_					:	int		  =			OnnxStableDiffusionPipeline.from_pretrained(
					    'runwayml/stable-diffusion-v1-5'      ,						revision='onnx'      ,						scheduler=_lowercase      ,						safety_checker=_lowercase      ,						feature_extractor=_lowercase      ,						provider=self.gpu_provider      ,						sess_options=self.gpu_options      ,						)
					sd_pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	Optional[Any]		  =			'open neural network exchange'
					SCREAMING_SNAKE_CASE_					:	int		  =			np.random.RandomState(0      )
					SCREAMING_SNAKE_CASE_					:	List[str]		  =			sd_pipe([prompt]      ,						guidance_scale=7.5      ,						num_inference_steps=10      ,						generator=_lowercase      ,						output_type='np'      )
					SCREAMING_SNAKE_CASE_					:	Optional[int]		  =			output.images
					SCREAMING_SNAKE_CASE_					:	Tuple		  =			image[0, -3:, -3:, -1]

					assert image.shape == (1, 512, 512, 3)
					SCREAMING_SNAKE_CASE_					:	Any		  =			np.array([0.28_67, 0.19_74, 0.14_81, 0.72_94, 0.72_51, 0.66_67, 0.41_94, 0.56_42, 0.64_86]      )

					assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-3





			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	List[str]		  =			LMSDiscreteScheduler.from_pretrained(
					    'runwayml/stable-diffusion-v1-5'      ,						subfolder='scheduler'      ,						revision='onnx'      )
					SCREAMING_SNAKE_CASE_					:	Dict		  =			OnnxStableDiffusionPipeline.from_pretrained(
					    'runwayml/stable-diffusion-v1-5'      ,						revision='onnx'      ,						scheduler=_lowercase      ,						safety_checker=_lowercase      ,						feature_extractor=_lowercase      ,						provider=self.gpu_provider      ,						sess_options=self.gpu_options      ,						)
					sd_pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	Optional[int]		  =			'open neural network exchange'
					SCREAMING_SNAKE_CASE_					:	str		  =			np.random.RandomState(0      )
					SCREAMING_SNAKE_CASE_					:	Any		  =			sd_pipe([prompt]      ,						guidance_scale=7.5      ,						num_inference_steps=10      ,						generator=_lowercase      ,						output_type='np'      )
					SCREAMING_SNAKE_CASE_					:	Optional[Any]		  =			output.images
					SCREAMING_SNAKE_CASE_					:	int		  =			image[0, -3:, -3:, -1]

					assert image.shape == (1, 512, 512, 3)
					SCREAMING_SNAKE_CASE_					:	str		  =			np.array([0.23_06, 0.19_59, 0.15_93, 0.65_49, 0.63_94, 0.54_08, 0.50_65, 0.60_10, 0.61_61]      )

					assert np.abs(image_slice.flatten() - expected_slice      ).max() < 1e-3





			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	int		  =			0

					def test_callback_fn(__lowerCAmelCase      ,						__lowerCAmelCase      ,						__lowerCAmelCase      ) -> None:
							SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			True
							nonlocal number_of_steps
							number_of_steps += 1
							if step == 0:
									assert latents.shape == (1, 4, 64, 64)
									SCREAMING_SNAKE_CASE_					:	Tuple		  =			latents[0, -3:, -3:, -1]
									SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			np.array(
									    [-0.67_72, -0.38_35, -1.24_56, 0.19_05, -1.09_74, 0.69_67, -1.93_53, 0.01_78, 1.01_67]      )

									assert np.abs(latents_slice.flatten() - expected_slice      ).max() < 1e-3
							elif step == 5:
									assert latents.shape == (1, 4, 64, 64)
									SCREAMING_SNAKE_CASE_					:	str		  =			latents[0, -3:, -3:, -1]
									SCREAMING_SNAKE_CASE_					:	Union[str, Any]		  =			np.array(
									    [-0.33_51, 0.22_41, -0.18_37, -0.23_25, -0.65_77, 0.33_93, -0.02_41, 0.58_99, 1.38_75]      )

									assert np.abs(latents_slice.flatten() - expected_slice      ).max() < 1e-3

					SCREAMING_SNAKE_CASE_					:	List[Any]		  =			False

					SCREAMING_SNAKE_CASE_					:	Dict		  =			OnnxStableDiffusionPipeline.from_pretrained(
					    'runwayml/stable-diffusion-v1-5'      ,						revision='onnx'      ,						safety_checker=_lowercase      ,						feature_extractor=_lowercase      ,						provider=self.gpu_provider      ,						sess_options=self.gpu_options      ,						)
					pipe.set_progress_bar_config(disable=_lowercase      )

					SCREAMING_SNAKE_CASE_					:	Tuple		  =			'Andromeda galaxy in a bottle'

					SCREAMING_SNAKE_CASE_					:	Any		  =			np.random.RandomState(0      )
					pipe(
					    prompt=_lowercase      ,						num_inference_steps=5      ,						guidance_scale=7.5      ,						generator=_lowercase      ,						callback=_lowercase      ,						callback_steps=1      ,						)
					assert test_callback_fn.has_been_called
					assert number_of_steps == 6






			def 						__A						(		self      ):
					SCREAMING_SNAKE_CASE_					:	Tuple		  =			OnnxStableDiffusionPipeline.from_pretrained(
					    'runwayml/stable-diffusion-v1-5'      ,						revision='onnx'      ,						safety_checker=_lowercase      ,						feature_extractor=_lowercase      ,						provider=self.gpu_provider      ,						sess_options=self.gpu_options      ,						)
					assert isinstance(_lowercase      ,						_lowercase      )
					assert pipe.safety_checker is None

					SCREAMING_SNAKE_CASE_					:	List[Any]		  =			pipe('example prompt'      ,						num_inference_steps=2      ).images[0]
					assert image is not None

					# check that there's no error when saving a pipeline with one of the models being None
					with tempfile.TemporaryDirectory() as tmpdirname:
							pipe.save_pretrained(_lowercase      )
							SCREAMING_SNAKE_CASE_					:	Dict		  =			OnnxStableDiffusionPipeline.from_pretrained(_lowercase      )

					# sanity check that the pipeline still works
					assert pipe.safety_checker is None
					SCREAMING_SNAKE_CASE_					:	Optional[Any]		  =			pipe('example prompt'      ,						num_inference_steps=2      ).images[0]
					assert image is not None









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()
