






from __future__ import annotations

import math
from collections import Counter
from string import ascii_lowercase




def       _SCREAMING_SNAKE_CASE (							__snake_case )				->						None:
       _UpperCAmelCase	,			_UpperCAmelCase							=    analyze_text(__snake_case )
       _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(__snake_case )  # 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(__snake_case ) / all_sum
                            my_sec_sum += prob * math.loga(__snake_case )

    # 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       _SCREAMING_SNAKE_CASE (							__snake_case )				->						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(__snake_case ) - 1 ):
              single_char_strings[text[i]] += 1
              two_char_strings[text[i : i + 2]] += 1
       return single_char_strings, two_char_strings




def       _SCREAMING_SNAKE_CASE (							)				->						str:
       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()







import gc
import threading
import time

import psutil
import torch
class 		SCREAMING_SNAKE_CASE__	:

  '''simple docstring'''







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


         """simple docstring"""
         _UpperCAmelCase							=    psutil.Process()
         _UpperCAmelCase							=    False


  def  lowerCamelCase       (      self		:			List[Any]							)						->	int:


         """simple docstring"""
         _UpperCAmelCase							=    -1

         while True:
                _UpperCAmelCase							=    max(self.process.memory_info().rss       ,				self.cpu_memory_peak							)

                # can't sleep or will not catch the peak right (this comment is here on purpose)
                if not self.peak_monitoring:
                       break


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


         """simple docstring"""
         _UpperCAmelCase							=    True
         _UpperCAmelCase							=    threading.Thread(target=self.peak_monitor							)
         _UpperCAmelCase							=    True
         self.thread.start()





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


         """simple docstring"""
         _UpperCAmelCase							=    False
         self.thread.join()
         return self.cpu_memory_peak



__a:     Union[str, Any]   					=					PeakCPUMemory()




def       _SCREAMING_SNAKE_CASE (							)				->						List[Any]:
       # Time
       _UpperCAmelCase							=    {"""time""": time.time()}

       gc.collect()
       torch.cuda.empty_cache()

       # CPU mem
       _UpperCAmelCase							=    psutil.Process().memory_info().rss
       cpu_peak_tracker.start()

       # GPU mem
       for i in range(torch.cuda.device_count() ):
              _UpperCAmelCase							=    torch.cuda.memory_allocated(__snake_case )
       torch.cuda.reset_peak_memory_stats()

       return measures




def       _SCREAMING_SNAKE_CASE (							__snake_case )				->						Union[str, Any]:
       # Time
       _UpperCAmelCase							=    {"""time""": time.time() - start_measures["""time"""]}

       gc.collect()
       torch.cuda.empty_cache()

       # CPU mem
       _UpperCAmelCase							=    (psutil.Process().memory_info().rss - start_measures["""cpu"""]) / 2**2_0
       _UpperCAmelCase							=    (cpu_peak_tracker.stop() - start_measures["""cpu"""]) / 2**2_0

       # GPU mem
       for i in range(torch.cuda.device_count() ):
              _UpperCAmelCase							=    (torch.cuda.memory_allocated(__snake_case ) - start_measures[str(__snake_case )]) / 2**2_0
              _UpperCAmelCase							=    (torch.cuda.max_memory_allocated(__snake_case ) - start_measures[str(__snake_case )]) / 2**2_0

       return measures





def       _SCREAMING_SNAKE_CASE (							__snake_case   ,      __snake_case )				->						str:
       print(f"""{description}:""" )
       print(f"""- Time: {measures["time"]:.2f}s""" )
       for i in range(torch.cuda.device_count() ):
              print(f"""- GPU {i} allocated: {measures[str(__snake_case )]:.2f}MiB""" )
              _UpperCAmelCase							=    measures[f"""{i}-peak"""]
              print(f"""- GPU {i} peak: {peak:.2f}MiB""" )
       print(f"""- CPU RAM allocated: {measures["cpu"]:.2f}MiB""" )
       print(f"""- CPU RAM peak: {measures["cpu-peak"]:.2f}MiB""" )