'''simple docstring'''





from typing import Any





class       lowercase__		:


						def __init__( self			:       str					,	UpperCamelCase__			:       Any		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					List[str]           =							data
												SCREAMING_SNAKE_CASE							:					str           =							None



						def __repr__( self			:       int		):





												'''simple docstring'''





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






class       lowercase__		:


						def __init__( self			:       int		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Dict           =							None


						def __iter__( self			:       List[str]		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Any           =							self.head
												while node:
																		yield node.data
																		SCREAMING_SNAKE_CASE							:					List[Any]           =							node.next


						def __len__( self			:       int		):





												'''simple docstring'''





												return sum(1 for _ in self		)


						def __repr__( self			:       Optional[int]		):





												'''simple docstring'''





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


						def __getitem__( self			:       int					,	UpperCamelCase__			:       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			:       Tuple					,	UpperCamelCase__			:       int					,	UpperCamelCase__			:       Any		):





												'''simple docstring'''





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


						def  __A ( self			:       int					,	UpperCamelCase__			:       Any		):





												'''simple docstring'''





												self.insert_nth(len(self		)					,	__A		)


						def  __A ( self			:       List[str]					,	UpperCamelCase__			:       Any		):





												'''simple docstring'''





												self.insert_nth(0					,	__A		)


						def  __A ( self			:       str					,	UpperCamelCase__			:       int					,	UpperCamelCase__			:       Any		):





												'''simple docstring'''





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


						def  __A ( self			:       Union[str, Any]		):  # print every node data





												'''simple docstring'''





												print(self		)


						def  __A ( self			:       Dict		):





												'''simple docstring'''





												return self.delete_nth(0		)


						def  __A ( self			:       Tuple		):  # delete from tail





												'''simple docstring'''





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


						def  __A ( self			:       Optional[Any]					,	UpperCamelCase__			:       int = 0		):





												'''simple docstring'''





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


						def  __A ( self			:       Any		):





												'''simple docstring'''





												return self.head is None



						def  __A ( self			:       Any		):





												'''simple docstring'''





												SCREAMING_SNAKE_CASE							:					Tuple           =							None
												SCREAMING_SNAKE_CASE							:					Dict           =							self.head

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






def    A			(					):
						SCREAMING_SNAKE_CASE							:					Any           =							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		):
												SCREAMING_SNAKE_CASE							:					Optional[int]           =							-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    A			(					):
						SCREAMING_SNAKE_CASE							:					Optional[int]           =							[
						    -9,
						    100,
						    Node(77_345_112		),
						    '''dlrow olleH''',
						    7,
						    5_555,
						    0,
						    -192.55_555,
						    '''Hello, world!''',
						    77.9,
						    Node(10		),
						    None,
						    None,
						    12.20,
						]
						SCREAMING_SNAKE_CASE							:					Tuple           =							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
						SCREAMING_SNAKE_CASE							:					Any           =							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
						SCREAMING_SNAKE_CASE							:					Optional[Any]           =							linked_list.delete_tail()
						assert result == 12.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
						SCREAMING_SNAKE_CASE							:					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    A			(					):
						from doctest import testmod

						testmod()

						SCREAMING_SNAKE_CASE							:					Tuple           =							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]}"""		)
						SCREAMING_SNAKE_CASE							:					Tuple           =							input('''Enter New Value: '''		).strip()
						print('''New list:'''		)
						print(_lowercase		)
						print(f"""length of linked_list is : {len(_lowercase		)}"""		)


if __name__ == "__main__":
					main()






from __future__ import annotations

import math
from collections import Counter
from string import ascii_lowercase
def    A			(					_lowercase		):
						SCREAMING_SNAKE_CASE       ,						SCREAMING_SNAKE_CASE							:					Union[str, Any]           =							analyze_text(_lowercase		)
						SCREAMING_SNAKE_CASE							:					Any           =							list(''' ''' + ascii_lowercase		)
						# what is our total sum of probabilities.
						SCREAMING_SNAKE_CASE							:					Tuple           =							sum(single_char_strings.values()		)

						# one length string
						SCREAMING_SNAKE_CASE							:					Tuple           =							0
						# for each alpha we go in our dict and if it is in it we calculate entropy
						for ch in my_alphas:
												if ch in single_char_strings:
																		SCREAMING_SNAKE_CASE							:					Tuple           =							single_char_strings[ch]
																		SCREAMING_SNAKE_CASE							:					List[str]           =							my_str / all_sum
																		my_fir_sum += prob * math.loga(_lowercase		)  # entropy formula.

    # print entropy
						print(f"""{round(-1 * my_fir_sum		):.1f}"""		)

						# two len string
						SCREAMING_SNAKE_CASE							:					Optional[Any]           =							sum(two_char_strings.values()		)
						SCREAMING_SNAKE_CASE							:					List[str]           =							0
						# for each alpha (two in size) calculate entropy.
						for cha in my_alphas:
												for cha in my_alphas:
																		SCREAMING_SNAKE_CASE							:					Union[str, Any]           =							cha + cha
																		if sequence in two_char_strings:
																								SCREAMING_SNAKE_CASE							:					Any           =							two_char_strings[sequence]
																								SCREAMING_SNAKE_CASE							:					Dict           =							int(_lowercase		) / all_sum
																								my_sec_sum += prob * math.loga(_lowercase		)

    # print second entropy
						print(f"""{round(-1 * my_sec_sum		):.1f}"""		)

						# print the difference between them
						print(f"""{round((-1 * my_sec_sum) - (-1 * my_fir_sum)		):.1f}"""		)
def    A			(					_lowercase		):
						SCREAMING_SNAKE_CASE							:					Tuple           =							Counter()  # type: ignore
						SCREAMING_SNAKE_CASE							:					Any           =							Counter()  # type: ignore
						single_char_strings[text[-1]] += 1

						# first case when we have space at start.
						two_char_strings[" " + text[0]] += 1
						for i in range(0	,						len(_lowercase		) - 1		):
												single_char_strings[text[i]] += 1
												two_char_strings[text[i : i + 2]] += 1
						return single_char_strings, two_char_strings
def    A			(					):
						import doctest

						doctest.testmod()
						# text = (
						#     "Had repulsive dashwoods suspicion sincerity but advantage now him. Remark "
						#     "easily garret nor nay. Civil those mrs enjoy shy fat merry. You greatest "
						#     "jointure saw horrible. He private he on be imagine suppose. Fertile "
						#     "beloved evident through no service elderly is. Blind there if every no so "
						#     "at. Own neglected you preferred way sincerity delivered his attempted. To "
						#     "of message cottage windows do besides against uncivil.  Delightful "
						#     "unreserved impossible few estimating men favourable see entreaties. She "
						#     "propriety immediate was improving. He or entrance humoured likewise "
						#     "moderate. Much nor game son say feel. Fat make met can must form into "
						#     "gate. Me we offending prevailed discovery. "
						# )

						# calculate_prob(text)


if __name__ == "__main__":
					main()





