

"""simple docstring"""


from typing import Any





class    snake_case     :

				def __init__(     self							:    Any					,  UpperCamelCase__							:    Any)->       Dict:



						'''simple docstring'''


						__lowerCAmelCase:	Tuple   				=      data
						__lowerCAmelCase:	Any   				=      None




				def __repr__(     self							:    str)->       str:



						'''simple docstring'''


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





class    snake_case     :

				def __init__(     self							:    Optional[Any])->       List[Any]:



						'''simple docstring'''


						__lowerCAmelCase:	Union[str, Any]   				=      None

				def __iter__(     self							:    Optional[Any])->       Any:



						'''simple docstring'''


						__lowerCAmelCase:	List[str]   				=      self.head
						while node:
								yield node.data
								__lowerCAmelCase:	List[str]   				=      node.next

				def __len__(     self							:    List[str])->       int:



						'''simple docstring'''


						return sum(1 for _ in self)

				def __repr__(     self							:    List[Any])->       str:



						'''simple docstring'''


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

				def __getitem__(     self							:    Any					,  UpperCamelCase__							:    int)->       Any:



						'''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							:    List[Any]					,  UpperCamelCase__							:    int					,  UpperCamelCase__							:    Any)->       None:



						'''simple docstring'''


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

				def 							lowercase_					(     self							:    Union[str, Any]					,  UpperCamelCase__							:    Any)->       None:



						'''simple docstring'''


						self.insert_nth(len(self)					,  UpperCamelCase__)

				def 							lowercase_					(     self							:    str					,  UpperCamelCase__							:    Any)->       None:



						'''simple docstring'''


						self.insert_nth(0					,  UpperCamelCase__)

				def 							lowercase_					(     self							:    Dict					,  UpperCamelCase__							:    int					,  UpperCamelCase__							:    Any)->       None:



						'''simple docstring'''


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

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



						'''simple docstring'''


						print(self)

				def 							lowercase_					(     self							:    Tuple)->       Any:



						'''simple docstring'''


						return self.delete_nth(0)

				def 							lowercase_					(     self							:    Dict)->       Any:  # delete from tail



						'''simple docstring'''


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

				def 							lowercase_					(     self							:    Optional[Any]					,  UpperCamelCase__							:    int = 0)->       Any:



						'''simple docstring'''


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

				def 							lowercase_					(     self							:    str)->       bool:



						'''simple docstring'''


						return self.head is None




				def 							lowercase_					(     self							:    Any)->       None:



						'''simple docstring'''


						__lowerCAmelCase:	List[str]   				=      None
						__lowerCAmelCase:	int   				=      self.head

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






def    a__   (   )     ->     None:
		__lowerCAmelCase:	Optional[Any]   				=      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			):
				__lowerCAmelCase:	str   				=      -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    a__   (   )     ->     None:
		__lowerCAmelCase:	Union[str, Any]   				=      [
		    -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,
		]
		__lowerCAmelCase:	int   				=      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
		__lowerCAmelCase:	Union[str, Any]   				=      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
		__lowerCAmelCase:	List[str]   				=      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
		__lowerCAmelCase:	List[str]   				=      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    a__   (   )     ->     str:
		from doctest import testmod

		testmod()

		__lowerCAmelCase:	Optional[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(__SCREAMING_SNAKE_CASE			)
		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(__SCREAMING_SNAKE_CASE			)
		print(F"length of linked_list is : {len(__SCREAMING_SNAKE_CASE			)}"			)


if __name__ == "__main__":
			main()





"""simple docstring"""


from math import ceil






def    a__   (   __SCREAMING_SNAKE_CASE ,			__SCREAMING_SNAKE_CASE			)     ->     str:
		__lowerCAmelCase:	Tuple   				=      list(range(0 ,			__SCREAMING_SNAKE_CASE			)			)

		__lowerCAmelCase:	Optional[Any]   				=      [item for sublist in list(device_map.values()			) for item in sublist]

		# Duplicate check
		__lowerCAmelCase:	List[Any]   				=      []
		for i in device_map_blocks:
				if device_map_blocks.count(__SCREAMING_SNAKE_CASE			) > 1 and i not in duplicate_blocks:
						duplicate_blocks.append(__SCREAMING_SNAKE_CASE			)
    # Missing blocks
		__lowerCAmelCase:	Optional[Any]   				=      [i for i in blocks if i not in device_map_blocks]
		__lowerCAmelCase:	List[Any]   				=      [i for i in device_map_blocks if i not in blocks]

		if len(__SCREAMING_SNAKE_CASE			) != 0:
				raise ValueError(
				    "Duplicate attention blocks specified in device_map. Attention blocks must be specified to one device."
				    " These attention blocks were specified more than once: " + str(__SCREAMING_SNAKE_CASE			)			)
		if len(__SCREAMING_SNAKE_CASE			) != 0:
				raise ValueError(
				    "There are attention blocks for this model that are not specified in the device_map. Add these attention "
				    "blocks to a device on the device_map: " + str(__SCREAMING_SNAKE_CASE			)			)
		if len(__SCREAMING_SNAKE_CASE			) != 0:
				raise ValueError(
				    "The device_map contains more attention blocks than this model has. Remove these from the device_map:"
				    + str(__SCREAMING_SNAKE_CASE			)			)






def    a__   (   __SCREAMING_SNAKE_CASE ,			__SCREAMING_SNAKE_CASE			)     ->     str:
		__lowerCAmelCase:	List[Any]   				=      list(range(__SCREAMING_SNAKE_CASE			)			)
		__lowerCAmelCase:	Dict   				=      int(ceil(n_layers / len(__SCREAMING_SNAKE_CASE			)			)			)
		__lowerCAmelCase:	Union[str, Any]   				=      [layers[i : i + n_blocks] for i in range(0 ,			__SCREAMING_SNAKE_CASE ,			__SCREAMING_SNAKE_CASE			)]

		return dict(zip(__SCREAMING_SNAKE_CASE ,			__SCREAMING_SNAKE_CASE			)			)


