

"""simple docstring"""






import collections
import json
import os
import re
from typing import TYPE_CHECKING, List, Optional, Tuple

import numpy as np

from ...tokenization_utils_fast import PreTrainedTokenizer
from ...utils import logging


if TYPE_CHECKING:
	from transformers.pipelines.conversational import Conversation


snake_case_   :   Optional[Any]        =       logging.get_logger(__name__)

snake_case_   :   Tuple        =       {"""vocab_file""": """vocab.txt""", """emoji_file""": """emoji.json"""}

snake_case_   :   List[Any]        =       {
    """vocab_file""": {
        """abeja/gpt-neox-japanese-2.7b""": """https://huggingface.co/abeja/gpt-neox-japanese-2.7b/resolve/main/vocab.txt""",
    },
    """emoji_file""": {
        """abeja/gpt-neox-japanese-2.7b""": """https://huggingface.co/abeja/gpt-neox-japanese-2.7b/resolve/main/emoji.json""",
    },
}

snake_case_   :   List[Any]        =       {
    """abeja/gpt-neox-japanese-2.7b""": 2_0_4_8,
}



def   lowercase_	(    _lowercase       :		Optional[int]							,      _lowercase       :		Optional[int]	):




					'''simple docstring'''






					with open(_lowercase							,      "r"							,      encoding="utf-8"	) as f:
										UpperCAmelCase			:   Union[str, Any]      =				json.loads(f.read()	)

					UpperCAmelCase			:   Tuple      =				collections.OrderedDict()
					UpperCAmelCase			:   Optional[Any]      =				collections.OrderedDict()
					UpperCAmelCase			:   Union[str, Any]      =				collections.OrderedDict()
					with open(_lowercase							,      "r"							,      encoding="utf-8"	) as f:
										UpperCAmelCase			:   List[Any]      =				f.readlines()
					UpperCAmelCase			:   Optional[int]      =				[[t.rstrip("\n"	)] if (t == "," or "," not in t) else t.rstrip("\n"	).split(","	) for t in token]
					for idx, b in enumerate(_lowercase	):
										UpperCAmelCase			:   str      =				b
										UpperCAmelCase			:   Any      =				idx
										for wd in b:
															UpperCAmelCase			:   List[str]      =				idx

					return vocab, raw_vocab, ids_to_tokens, emoji







class       snake_case__  ( lowerCAmelCase_     ):
			SCREAMING_SNAKE_CASE__     				=						VOCAB_FILES_NAMES
			SCREAMING_SNAKE_CASE__     				=						PRETRAINED_VOCAB_FILES_MAP
			SCREAMING_SNAKE_CASE__     				=						PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
			SCREAMING_SNAKE_CASE__     				=						['''input_ids''', '''attention_mask''']







			def __init__(			self			: str			,  lowercase			: Optional[Any]			,  lowercase			: Tuple			,  lowercase			: Union[str, Any]="<|endoftext|>"			,  lowercase			: List[str]="<|endoftext|>"			,  lowercase			: Dict="<|startoftext|>"			,  lowercase			: Union[str, Any]="<|endoftext|>"			,  lowercase			: Any=False			,  **lowercase			: List[str]			,  ):





								'''simple docstring'''



								super().__init__(
								    unk_token=lowercase			,  pad_token=lowercase			,  bos_token=lowercase			,  eos_token=lowercase			,  do_clean_text=lowercase			,  **lowercase			,  )
								if not os.path.isfile(lowercase  ):
													raise ValueError(
													    f"""Can't find a vocabulary file at path '{vocab_file}'. To load the vocabulary from a Google pretrained"""
													    " model use `tokenizer = GPTNeoXJapaneseokenizer.from_pretrained(PRETRAINED_MODEL_NAME)`"  )
								if not os.path.isfile(lowercase  ):
													raise ValueError(
													    f"""Can't find a emoji file at path '{emoji_file}'. To load the emoji information from a Google"""
													    " pretrained model use `tokenizer = GPTNeoXJapaneseokenizer.from_pretrained(PRETRAINED_MODEL_NAME)`"  )
								UpperCAmelCase			:   List[Any]      =				do_clean_text
								UpperCAmelCase      ,							UpperCAmelCase      ,							UpperCAmelCase      ,							UpperCAmelCase			:   int      =				load_vocab_and_emoji(lowercase			,  lowercase  )
								UpperCAmelCase			:   Dict      =				SubWordJapaneseTokenizer(
								    vocab=self.vocab			,  ids_to_tokens=self.ids_to_tokens			,  emoji=self.emoji  )







			@property
			def 			__lowerCAmelCase				(			self			: Any  ):





								'''simple docstring'''



								return len(self.raw_vocab  )







			def 			__lowerCAmelCase				(			self			: str  ):





								'''simple docstring'''



								return dict(self.raw_vocab			,  **self.added_tokens_encoder  )







			def 			__lowerCAmelCase				(			self			: Optional[int]			,  lowercase			: Any  ):





								'''simple docstring'''



								return self.subword_tokenizer.tokenize(lowercase			,  clean=self.do_clean_text  )







			def 			__lowerCAmelCase				(			self			: List[str]			,  lowercase			: Tuple  ):





								'''simple docstring'''



								return self.vocab.get(lowercase			,  self.vocab.get(self.unk_token  )  )







			def 			__lowerCAmelCase				(			self			: Any			,  lowercase			: Union[str, Any]  ):





								'''simple docstring'''



								return self.subword_tokenizer.convert_id_to_token(lowercase  )







			def 			__lowerCAmelCase				(			self			: Optional[Any]			,  lowercase			: Optional[int]  ):





								'''simple docstring'''



								UpperCAmelCase			:   Tuple      =				"".join(lowercase  ).strip()
								return out_string







			def 			__lowerCAmelCase				(			self			: List[Any]			,  lowercase			: "Conversation"  ):





								'''simple docstring'''



								UpperCAmelCase			:   Tuple      =				[]
								for is_user, text in conversation.iter_texts():
													input_ids.extend(self.encode(lowercase			,  add_special_tokens=lowercase  ) + [self.eos_token_id]  )

								if len(lowercase  ) > self.model_max_length:
													UpperCAmelCase			:   Dict      =				input_ids[-self.model_max_length :]
								return input_ids







			def 			__lowerCAmelCase				(			self			: List[Any]			,  lowercase			: str			,  lowercase			: Optional[str] = None  ):





								'''simple docstring'''



								UpperCAmelCase			:   List[str]      =				0
								if os.path.isdir(lowercase  ):
													UpperCAmelCase			:   Tuple      =				os.path.join(
													    lowercase			,  (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"]  )
													UpperCAmelCase			:   Optional[int]      =				os.path.join(
													    lowercase			,  (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["emoji_file"]  )
								else:
													UpperCAmelCase			:   Union[str, Any]      =				(
													    (filename_prefix + "-" if filename_prefix else "") + save_directory + VOCAB_FILES_NAMES["vocab_file"]
													)
													UpperCAmelCase			:   str      =				(
													    (filename_prefix + "-" if filename_prefix else "") + save_directory + VOCAB_FILES_NAMES["emoji_file"]
													)
								with open(lowercase			,  "w"			,  encoding="utf-8"  ) as writer:
													for token_index, token in self.ids_to_tokens.items():
																		if index != token_index:
																							logger.warning(
																							    f"""Saving vocabulary to {vocab_file}: vocabulary indices are not consecutive."""
																							    " Please check that the vocabulary is not corrupted!"  )
																							UpperCAmelCase			:   Dict      =				token_index
																		writer.write(",".join(lowercase  ) + "\n"  )
																		index += 1
								with open(lowercase			,  "w"			,  encoding="utf-8"  ) as writer:
													json.dump(self.emoji			,  lowercase  )
								return vocab_file, emoji_file







class       snake_case__  ( lowerCAmelCase_     ):







			def __init__(			self			: int			,  lowercase			: Optional[int]			,  lowercase			: Dict			,  lowercase			: List[Any]  ):





								'''simple docstring'''



								UpperCAmelCase			:   Optional[int]      =				vocab  # same as swe
								UpperCAmelCase			:   str      =				ids_to_tokens  # same as bpe
								UpperCAmelCase			:   Any      =				emoji
								UpperCAmelCase			:   List[Any]      =				np.max([len(lowercase  ) for w in self.vocab.keys()]  )
								UpperCAmelCase			:   Dict      =				re.compile(r"(https?|ftp)(:\/\/[-_\.!~*\'()a-zA-Z0-9;\/?:\@&=\+$,%#]+)"  )
								UpperCAmelCase			:   int      =				re.compile(r"[A-Za-z0-9\._+]*@[\-_0-9A-Za-z]+(\.[A-Za-z]+)*"  )
								UpperCAmelCase			:   List[str]      =				re.compile(r"[\(]{0,1}[0-9]{2,4}[\)\-\(]{0,1}[0-9]{2,4}[\)\-]{0,1}[0-9]{3,4}"  )
								UpperCAmelCase			:   Tuple      =				re.compile(
								    r"([12]\d{3}[/\-年])*(0?[1-9]|1[0-2])[/\-月]((0?[1-9]|[12][0-9]|3[01])日?)*(\d{1,2}|:|\d{1,2}時|\d{1,2}分|\(日\)|\(月\)|\(火\)|\(水\)|\(木\)|\(金\)|\(土\)|㈰|㈪|㈫|㈬|㈭|㈮|㈯)*"  )
								UpperCAmelCase			:   Dict      =				re.compile(
								    r"(明治|大正|昭和|平成|令和|㍾|㍽|㍼|㍻|\u32ff)\d{1,2}年(0?[1-9]|1[0-2])月(0?[1-9]|[12][0-9]|3[01])日(\d{1,2}|:|\d{1,2}時|\d{1,2}分|\(日\)|\(月\)|\(火\)|\(水\)|\(木\)|\(金\)|\(土\)|㈰|㈪|㈫|㈬|㈭|㈮|㈯)*"  )
								UpperCAmelCase			:   Dict      =				re.compile(
								    r"((0|[1-9]\d*|[1-9]\d{0,2}(,\d{3})+)*億)*((0|[1-9]\d*|[1-9]\d{0,2}(,\d{3})+)*万)*((0|[1-9]\d*|[1-9]\d{0,2}(,\d{3})+)*千)*(0|[1-9]\d*|[1-9]\d{0,2}(,\d{3})+)*(千円|万円|千万円|円|千ドル|万ドル|千万ドル|ドル|千ユーロ|万ユーロ|千万ユーロ|ユーロ)+(\(税込\)|\(税抜\)|\+tax)*"  )
								UpperCAmelCase			:   Dict      =				"─━│┃┄┅┆┇┈┉┊┋┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬╭╮╯╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿"
								UpperCAmelCase			:   Dict      =				"▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▐░▒▓▔▕▖▗▘▙▚▛▜▝▞▟"
								UpperCAmelCase			:   Tuple      =				str.maketrans({k: "<BLOCK>" for k in keisen + blocks}  )







			def __len__(			self			: Any  ):





								'''simple docstring'''



								return len(self.ids_to_tokens  )







			def 			__lowerCAmelCase				(			self			: Optional[Any]			,  lowercase			: Dict  ):





								'''simple docstring'''



								UpperCAmelCase			:   Dict      =				self.content_repattera.sub("<URL>"			,  lowercase  )
								UpperCAmelCase			:   Union[str, Any]      =				self.content_repattera.sub("<EMAIL>"			,  lowercase  )
								UpperCAmelCase			:   List[Any]      =				self.content_repattera.sub("<TEL>"			,  lowercase  )
								UpperCAmelCase			:   Optional[int]      =				self.content_repattera.sub("<DATE>"			,  lowercase  )
								UpperCAmelCase			:   int      =				self.content_repattera.sub("<DATE>"			,  lowercase  )
								UpperCAmelCase			:   Dict      =				self.content_repattera.sub("<PRICE>"			,  lowercase  )
								UpperCAmelCase			:   Tuple      =				content.translate(self.content_transa  )
								while "<BLOCK><BLOCK>" in content:
													UpperCAmelCase			:   Optional[Any]      =				content.replace("<BLOCK><BLOCK>"			,  "<BLOCK>"  )
								return content







			def 			__lowerCAmelCase				(			self			: int			,  lowercase			: str			,  lowercase			: List[str]=False  ):





								'''simple docstring'''



								UpperCAmelCase			:   List[Any]      =				text.replace(" "			,  "<SP>"  )
								UpperCAmelCase			:   str      =				text.replace("　"			,  "<SP>"  )
								UpperCAmelCase			:   str      =				text.replace("\r\n"			,  "<BR>"  )
								UpperCAmelCase			:   Optional[Any]      =				text.replace("\n"			,  "<BR>"  )
								UpperCAmelCase			:   Tuple      =				text.replace("\r"			,  "<BR>"  )
								UpperCAmelCase			:   Optional[int]      =				text.replace("\t"			,  "<TAB>"  )
								UpperCAmelCase			:   Union[str, Any]      =				text.replace("—"			,  "ー"  )
								UpperCAmelCase			:   Optional[Any]      =				text.replace("−"			,  "ー"  )
								for k, v in self.emoji["emoji"].items():
													if k in text:
																		UpperCAmelCase			:   Dict      =				text.replace(lowercase			,  lowercase  )
								if clean:
													UpperCAmelCase			:   Any      =				self.clean_text(lowercase  )

								def check_simbol(lowercase			: Optional[Any]  ):
													UpperCAmelCase			:   int      =				x.encode()
													if len(lowercase  ) == 1 and len(lowercase  ) == 2:
																		UpperCAmelCase			:   List[Any]      =				(int(e[0]  ) << 8) + int(e[1]  )
																		if (
																		    (c >= 0XC2A1 and c <= 0XC2BF)
																		    or (c >= 0XC780 and c <= 0XC783)
																		    or (c >= 0XCAB9 and c <= 0XCBBF)
																		    or (c >= 0XCC80 and c <= 0XCDA2)
																		):
																							return True
													return False

								def checkuae(lowercase			: List[str]  ):
													UpperCAmelCase			:   Optional[int]      =				x.encode()
													if len(lowercase  ) == 1 and len(lowercase  ) == 3:
																		UpperCAmelCase			:   Union[str, Any]      =				(int(e[0]  ) << 16) + (int(e[1]  ) << 8) + int(e[2]  )
																		if c >= 0XE28080 and c <= 0XE2B07F:
																							return True
													return False

								UpperCAmelCase			:   Optional[int]      =				0
								UpperCAmelCase			:   str      =				[]
								while pos < len(lowercase  ):
													UpperCAmelCase			:   Tuple      =				min(len(lowercase  )			,  pos + self.maxlen + 1  ) if text[pos] == "<" else pos + 3
													UpperCAmelCase			:   Optional[Any]      =				[]  # (token_id, token, pos)
													for e in range(lowercase			,  lowercase			,  -1  ):
																		UpperCAmelCase			:   List[str]      =				text[pos:e]
																		if wd in self.vocab:
																							if wd[0] == "<" and len(lowercase  ) > 2:
																												UpperCAmelCase			:   Optional[Any]      =				[(self.vocab[wd], wd, e)]
																												break
																							else:
																												candidates.append((self.vocab[wd], wd, e)  )
													if len(lowercase  ) > 0:
																		# the smallest token_id is adopted
																		UpperCAmelCase      ,							UpperCAmelCase      ,							UpperCAmelCase			:   List[str]      =				sorted(lowercase			,  key=lambda lowercase  : x[0]  )[0]
																		result.append(lowercase  )
																		UpperCAmelCase			:   List[Any]      =				e
													else:
																		UpperCAmelCase			:   Dict      =				pos + 1
																		UpperCAmelCase			:   Any      =				text[pos:end]
																		if check_simbol(lowercase  ):
																							result.append("<KIGOU>"  )
																		elif checkuae(lowercase  ):
																							result.append("<U2000U2BFF>"  )
																		else:
																							for i in wd.encode("utf-8"  ):
																												result.append("<|byte%d|>" % i  )
																		UpperCAmelCase			:   Optional[int]      =				end
								return result







			def 			__lowerCAmelCase				(			self			: List[Any]			,  lowercase			: Tuple			,  lowercase			: Union[str, Any]="\n"  ):





								'''simple docstring'''



								UpperCAmelCase			:   Any      =				[]
								UpperCAmelCase			:   str      =				[]
								UpperCAmelCase			:   Any      =				self.ids_to_tokens[index][0]
								if word[:6] == "<|byte" and word[-2:] == "|>":
													byte_tokens.append(int(word[6:-2]  )  )
								else:
													if len(lowercase  ) > 0:
																		words.append(bytearray(lowercase  ).decode("utf-8"			,  errors="replace"  )  )
																		UpperCAmelCase			:   Optional[int]      =				[]
													if word[:7] == "<|emoji" and word[-2:] == "|>":
																		words.append(self.emoji["emoji_inv"][word]  )
													elif word == "<SP>":
																		words.append(" "  )
													elif word == "<BR>":
																		words.append(lowercase  )
													elif word == "<TAB>":
																		words.append("\t"  )
													elif word == "<BLOCK>":
																		words.append("▀"  )
													elif word == "<KIGOU>":
																		words.append("ǀ"  )
													elif word == "<U2000U2BFF>":
																		words.append("‖"  )
													else:
																		words.append(lowercase  )
								if len(lowercase  ) > 0:
													words.append(bytearray(lowercase  ).decode("utf-8"			,  errors="replace"  )  )
								UpperCAmelCase			:   Optional[int]      =				"".join(lowercase  )
								return text





"""simple docstring"""






from typing import Any







class       snake_case__  :







			def __init__(			self			: Union[str, Any]			,  lowercase			: Any  ):





								'''simple docstring'''



								UpperCAmelCase			:   Dict      =				data
								UpperCAmelCase			:   Optional[Any]      =				None







			def __repr__(			self			: str  ):





								'''simple docstring'''



								return f"""Node({self.data})"""







class       snake_case__  :







			def __init__(			self			: Optional[Any]  ):





								'''simple docstring'''



								UpperCAmelCase			:   Optional[Any]      =				None







			def __iter__(			self			: Dict  ):





								'''simple docstring'''



								UpperCAmelCase			:   str      =				self.head
								while node:
													yield node.data
													UpperCAmelCase			:   Tuple      =				node.next







			def __len__(			self			: Tuple  ):





								'''simple docstring'''



								return sum(1 for _ in self  )







			def __repr__(			self			: Any  ):





								'''simple docstring'''



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







			def __getitem__(			self			: List[str]			,  lowercase			: int  ):





								'''simple docstring'''



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







			def __setitem__(			self			: str			,  lowercase			: int			,  lowercase			: Any  ):





								'''simple docstring'''



								if not 0 <= index < len(self  ):
													raise ValueError("list index out of range."  )
								UpperCAmelCase			:   List[str]      =				self.head
								for _ in range(lowercase  ):
													UpperCAmelCase			:   List[Any]      =				current.next
								UpperCAmelCase			:   List[str]      =				data







			def 			__lowerCAmelCase				(			self			: Optional[Any]			,  lowercase			: Any  ):





								'''simple docstring'''



								self.insert_nth(len(self  )			,  lowercase  )







			def 			__lowerCAmelCase				(			self			: List[str]			,  lowercase			: Any  ):





								'''simple docstring'''



								self.insert_nth(0			,  lowercase  )







			def 			__lowerCAmelCase				(			self			: List[str]			,  lowercase			: int			,  lowercase			: Any  ):





								'''simple docstring'''



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







			def 			__lowerCAmelCase				(			self			: Dict  ):  # print every node data





								'''simple docstring'''



								print(self  )







			def 			__lowerCAmelCase				(			self			: Optional[Any]  ):





								'''simple docstring'''



								return self.delete_nth(0  )







			def 			__lowerCAmelCase				(			self			: str  ):  # delete from tail





								'''simple docstring'''



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







			def 			__lowerCAmelCase				(			self			: Optional[Any]			,  lowercase			: int = 0  ):





								'''simple docstring'''



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







			def 			__lowerCAmelCase				(			self			: List[Any]  ):





								'''simple docstring'''



								return self.head is None







			def 			__lowerCAmelCase				(			self			: int  ):





								'''simple docstring'''



								UpperCAmelCase			:   List[Any]      =				None
								UpperCAmelCase			:   str      =				self.head

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



def   lowercase_	(    ):




					'''simple docstring'''






					UpperCAmelCase			:   Optional[int]      =				LinkedList()
					assert linked_list.is_empty() is True
					assert str(_lowercase	) == ""

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

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

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



def   lowercase_	(    ):




					'''simple docstring'''






					UpperCAmelCase			:   Optional[Any]      =				[
					    -9,
					    1_00,
					    Node(77_34_51_12	),
					    "dlrow olleH",
					    7,
					    55_55,
					    0,
					    -1_9_2.5_5_5_5_5,
					    "Hello, world!",
					    7_7.9,
					    Node(10	),
					    None,
					    None,
					    1_2.2_0,
					]
					UpperCAmelCase			:   Optional[Any]      =				LinkedList()

					for i in test_input:
										linked_list.insert_tail(_lowercase	)

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

					# Delete the tail
					UpperCAmelCase			:   Any      =				linked_list.delete_tail()
					assert result == 1_2.2
					assert (
					    str(_lowercase	) == "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			:   Union[str, Any]      =				linked_list.delete_nth(10	)
					assert result is None
					assert (
					    str(_lowercase	) == "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(_lowercase	)
					    == "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(_lowercase	)
					assert (
					    str(_lowercase	)
					    == "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(_lowercase	)
					    == "None->None->Node(10)->77.9->Hello, world!->-192.55555->0->5555->"
					    "7->dlrow olleH->Node(77345112)->100->Node(Hello again, world!)"
					)



def   lowercase_	(    ):




					'''simple docstring'''






					from doctest import testmod

					testmod()

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


if __name__ == "__main__":
	main()


