


from __future__ import annotations

import math
from collections import Counter
from string import ascii_lowercase
def 	_UpperCamelCase					(    lowerCAmelCase_ )    ->None:
   UpperCAmelCase					,	UpperCAmelCase      					=  analyze_text(lowerCAmelCase_ )
   UpperCAmelCase      					=  list(""" """ + ascii_lowercase )
   # what is our total sum of probabilities.
   UpperCAmelCase      					=  sum(single_char_strings.values() )

   # one length string
   UpperCAmelCase      					=  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:
         UpperCAmelCase      					=  single_char_strings[ch]
         UpperCAmelCase      					=  my_str / all_sum
         my_fir_sum += prob * math.loga(lowerCAmelCase_ )  # entropy formula.

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

   # two len string
   UpperCAmelCase      					=  sum(two_char_strings.values() )
   UpperCAmelCase      					=  0
   # for each alpha (two in size) calculate entropy.
   for cha in my_alphas:
      for cha in my_alphas:
         UpperCAmelCase      					=  cha + cha
         if sequence in two_char_strings:
            UpperCAmelCase      					=  two_char_strings[sequence]
            UpperCAmelCase      					=  int(lowerCAmelCase_ ) / all_sum
            my_sec_sum += prob * math.loga(lowerCAmelCase_ )

    # 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 	_UpperCamelCase					(    lowerCAmelCase_ )    ->tuple[dict, dict]:
   UpperCAmelCase      					=  Counter()  # type: ignore
   UpperCAmelCase      					=  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(lowerCAmelCase_ ) - 1 ):
      single_char_strings[text[i]] += 1
      two_char_strings[text[i : i + 2]] += 1
   return single_char_strings, two_char_strings
def 	_UpperCamelCase					(    )    ->Union[str, Any]:
   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()







class 	__lowercase					:





      def __init__(		self    :       Optional[int]							)     -> int:






         """simple docstring"""







         UpperCAmelCase      					=  {}





      def 							_lowercase					(		self    :       str							)     -> None:






         """simple docstring"""







         print(self.vertex							)
         for i in self.vertex:
            print(__lowerCamelCase       ,							""" -> """       ,							""" -> """.join([str(__lowerCamelCase							) for j in self.vertex[i]]							)							)





      def 							_lowercase					(		self    :       Optional[Any]       ,							__lowerCamelCase    :       int       ,							__lowerCamelCase    :       int							)     -> None:






         """simple docstring"""







         if from_vertex in self.vertex:
            self.vertex[from_vertex].append(__lowerCamelCase							)
         else:
            # else make a new vertex
            UpperCAmelCase      					=  [to_vertex]





      def 							_lowercase					(		self    :       str							)     -> None:






         """simple docstring"""







         UpperCAmelCase      					=  [False] * len(self.vertex							)

         # call the recursive helper function
         for i in range(len(self.vertex							)							):
            if not visited[i]:
               self.dfs_recursive(__lowerCamelCase       ,							__lowerCamelCase							)





      def 							_lowercase					(		self    :       Optional[int]       ,							__lowerCamelCase    :       int       ,							__lowerCamelCase    :       list							)     -> None:






         """simple docstring"""







         UpperCAmelCase      					=  True

         print(__lowerCamelCase       ,							end=""" """							)

         # Recur for all the vertices that are adjacent to this node
         for i in self.vertex:
            if not visited[i]:
               self.dfs_recursive(__lowerCamelCase       ,							__lowerCamelCase							)


if __name__ == "__main__":
 __a	 =      Graph()
 g.add_edge(0, 1)
 g.add_edge(0, 2)
 g.add_edge(1, 2)
 g.add_edge(2, 0)
 g.add_edge(2, 3)
 g.add_edge(3, 3)

 g.print_graph()
 print("""DFS:""")
 g.dfs()

 # OUTPUT:
 # 0  ->  1 -> 2
 # 1  ->  2
 # 2  ->  0 -> 3
 # 3  ->  3
 # DFS:
 #  0 1 2 3



