





from typing import Any
class      UpperCamelCase_						:




					def __init__(						self			,  lowerCAmelCase_					)						->							Optional[int]:
										_snake_case													=			data
										_snake_case													=			None






					def __repr__(						self					)						->							str:
										return F'''Node({self.data})'''





class      UpperCamelCase_						:




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




					def __iter__(						self					)						->							Any:
										_snake_case													=			self.head
										while node:
															yield node.data
															_snake_case													=			node.next




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




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




					def __getitem__(						self			,  lowerCAmelCase_					)						->							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			,  lowerCAmelCase_			,  lowerCAmelCase_					)						->							None:
										if not 0 <= index < len(self					):
															raise ValueError('list index out of range.'					)
										_snake_case													=			self.head
										for _ in range(lowerCAmelCase_					):
															_snake_case													=			current.next
										_snake_case													=			data




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							None:
										self.insert_nth(len(self					)			,  lowerCAmelCase_					)




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_					)						->							None:
										self.insert_nth(0			,  lowerCAmelCase_					)




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_			,  lowerCAmelCase_					)						->							None:
										if not 0 <= index <= len(self					):
															raise IndexError('list index out of range'					)
										_snake_case													=			Node(lowerCAmelCase_					)
										if self.head is None:
															_snake_case													=			new_node
										elif index == 0:
															_snake_case													=			self.head  # link new_node to head
															_snake_case													=			new_node
										else:
															_snake_case													=			self.head
															for _ in range(index - 1					):
																				_snake_case													=			temp.next
															_snake_case													=			temp.next
															_snake_case													=			new_node




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




					def 		lowerCAmelCase     (						self					)						->							Any:
										return self.delete_nth(0					)




					def 		lowerCAmelCase     (						self					)						->							Any:  # delete from tail
										return self.delete_nth(len(self					) - 1					)




					def 		lowerCAmelCase     (						self			,  lowerCAmelCase_ = 0					)						->							Any:
										if not 0 <= index <= len(self					) - 1:  # test if index is valid
															raise IndexError('List index out of range.'					)
										_snake_case													=			self.head  # default first node
										if index == 0:
															_snake_case													=			self.head.next
										else:
															_snake_case													=			self.head
															for _ in range(index - 1					):
																				_snake_case													=			temp.next
															_snake_case													=			temp.next
															_snake_case													=			temp.next.next
										return delete_node.data




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






					def 		lowerCAmelCase     (						self					)						->							None:
										_snake_case													=			None
										_snake_case													=			self.head

										while current:
															# Store the current node's next node.
															_snake_case													=			current.next
															# Make the current node's next point backwards
															_snake_case													=			prev
															# Make the previous node be the current node
															_snake_case													=			current
															# Make the current node the next node (to progress iteration)
															_snake_case													=			next_node
										# Return prev in order to put the head at the end
										_snake_case													=			prev





def   lowerCamelCase__       (       )     ->	None:



					'''simple docstring'''




					_snake_case													=			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													=			-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   lowerCamelCase__       (       )     ->	None:



					'''simple docstring'''




					_snake_case													=			[
					    -9,
					    100,
					    Node(77_345_112  ),
					    'dlrow olleH',
					    7,
					    5_555,
					    0,
					    -192.5_5555,
					    'Hello, world!',
					    77.9,
					    Node(10  ),
					    None,
					    None,
					    12.20,
					]
					_snake_case													=			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													=			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													=			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													=			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   lowerCamelCase__       (       )     ->	List[Any]:



					'''simple docstring'''




					from doctest import testmod

					testmod()

					_snake_case													=			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													=			input('Enter New Value: '  ).strip()
					print('New list:'  )
					print(UpperCamelCase__  )
					print(F'''length of linked_list is : {len(UpperCamelCase__  )}'''  )


if __name__ == "__main__":
					main()










import random





def   lowerCamelCase__       (       UpperCamelCase__     :    int    ,      UpperCamelCase__     :    float    ,      UpperCamelCase__     :    bool = False  )     ->	dict:



					'''simple docstring'''




					_snake_case													=			{i: [] for i in range(UpperCamelCase__  )}

					# if probability is greater or equal than 1, then generate a complete graph
					if probability >= 1:
										return complete_graph(UpperCamelCase__  )
					# if probability is lower or equal than 0, then return a graph without edges
					if probability <= 0:
										return graph

					# for each couple of nodes, add an edge from u to v
					# if the number randomly generated is greater than probability probability
					for i in range(UpperCamelCase__  ):
										for j in range(i + 1    ,      UpperCamelCase__  ):
															if random.random() < probability:
																				graph[i].append(UpperCamelCase__  )
																				if not directed:
																									# if the graph is undirected, add an edge in from j to i, either
																									graph[j].append(UpperCamelCase__  )
					return graph





def   lowerCamelCase__       (       UpperCamelCase__     :    int  )     ->	dict:



					'''simple docstring'''




					return {
					    i: [j for j in range(UpperCamelCase__  ) if i != j] for i in range(UpperCamelCase__  )
					}


if __name__ == "__main__":
					import doctest

					doctest.testmod()



