


from __future__ import annotations






def  __lowerCAmelCase					(SCREAMING_SNAKE_CASE      ,      SCREAMING_SNAKE_CASE = None      ,      SCREAMING_SNAKE_CASE = None      ,      SCREAMING_SNAKE_CASE = False      ,      )->						Dict:




      """simple docstring"""

      snake_case_ =   cipher_alphabet or [chr(lowerCamelCase_      ) for i in range(97      ,      123      )]

      # If the argument is None or the user provided an empty dictionary
      if not frequencies_dict:
            # Frequencies of letters in the english language (how much they show up)
            snake_case_ =   {
                '''a''': 0.0_8_4_9_7,
                '''b''': 0.0_1_4_9_2,
                '''c''': 0.0_2_2_0_2,
                '''d''': 0.0_4_2_5_3,
                '''e''': 0.1_1_1_6_2,
                '''f''': 0.0_2_2_2_8,
                '''g''': 0.0_2_0_1_5,
                '''h''': 0.0_6_0_9_4,
                '''i''': 0.0_7_5_4_6,
                '''j''': 0.0_0_1_5_3,
                '''k''': 0.0_1_2_9_2,
                '''l''': 0.0_4_0_2_5,
                '''m''': 0.0_2_4_0_6,
                '''n''': 0.0_6_7_4_9,
                '''o''': 0.0_7_5_0_7,
                '''p''': 0.0_1_9_2_9,
                '''q''': 0.0_0_0_9_5,
                '''r''': 0.0_7_5_8_7,
                '''s''': 0.0_6_3_2_7,
                '''t''': 0.0_9_3_5_6,
                '''u''': 0.0_2_7_5_8,
                '''v''': 0.0_0_9_7_8,
                '''w''': 0.0_2_5_6_0,
                '''x''': 0.0_0_1_5_0,
                '''y''': 0.0_1_9_9_4,
                '''z''': 0.0_0_0_7_7,
            }
      else:
            # Custom frequencies dictionary
            snake_case_ =   frequencies_dict

      if not case_sensitive:
            snake_case_ =   ciphertext.lower()

      # Chi squared statistic values
      snake_case_ =   {}

      # cycle through all of the shifts
      for shift in range(len(lowerCamelCase_      )      ):
            snake_case_ =   ''''''

            # decrypt the message with the shift
            for letter in ciphertext:
                  try:
                        # Try to index the letter in the alphabet
                        snake_case_ =   (alphabet_letters.index(letter.lower()      ) - shift) % len(
                            lowerCamelCase_      )
                        decrypted_with_shift += (
                            alphabet_letters[new_key].upper()
                            if case_sensitive and letter.isupper()
                            else alphabet_letters[new_key]
                        )
                  except ValueError:
                        # Append the character if it isn't in the alphabet
                        decrypted_with_shift += letter

            snake_case_ =   0.0

            # Loop through each letter in the decoded message with the shift
            for letter in decrypted_with_shift:
                  if case_sensitive:
                        snake_case_ =   letter.lower()
                        if letter in frequencies:
                              # Get the amount of times the letter occurs in the message
                              snake_case_ =   decrypted_with_shift.lower().count(lowerCamelCase_      )

                              # Get the excepcted amount of times the letter should appear based
                              # on letter frequencies
                              snake_case_ =   frequencies[letter] * occurrences

                              # Complete the chi squared statistic formula
                              snake_case_ =   ((occurrences - expected) ** 2) / expected

                              # Add the margin of error to the total chi squared statistic
                              chi_squared_statistic += chi_letter_value
                  else:
                        if letter.lower() in frequencies:
                              # Get the amount of times the letter occurs in the message
                              snake_case_ =   decrypted_with_shift.count(lowerCamelCase_      )

                              # Get the excepcted amount of times the letter should appear based
                              # on letter frequencies
                              snake_case_ =   frequencies[letter] * occurrences

                              # Complete the chi squared statistic formula
                              snake_case_ =   ((occurrences - expected) ** 2) / expected

                              # Add the margin of error to the total chi squared statistic
                              chi_squared_statistic += chi_letter_value

        # Add the data to the chi_squared_statistic_values dictionary
            snake_case_ =   (
                chi_squared_statistic,
                decrypted_with_shift,
            )

      # Get the most likely cipher by finding the cipher with the smallest chi squared
      # statistic
      def chi_squared_statistic_values_sorting_key(SCREAMING_SNAKE_CASE      ) -> tuple[float, str]:
            return chi_squared_statistic_values[key]

      snake_case_ =   min(
          lowerCamelCase_      ,      key=lowerCamelCase_      ,      )

      # Get all the data from the most likely cipher (key, decoded message)
      (
          snake_case_	
      ) =   chi_squared_statistic_values[most_likely_cipher]

      # Return the data on the most likely shift
      return (
          most_likely_cipher,
          most_likely_cipher_chi_squared_value,
          decoded_most_likely_cipher,
      )



from collections import namedtuple

UpperCAmelCase    =					namedtuple("""from_to""", """from_ to""")

UpperCAmelCase    =					{
    """cubicmeter""": from_to(1, 1),
    """litre""": from_to(0.001, 1000),
    """kilolitre""": from_to(1, 1),
    """gallon""": from_to(0.00_454, 264.172),
    """cubicyard""": from_to(0.76_455, 1.30_795),
    """cubicfoot""": from_to(0.028, 35.3_147),
    """cup""": from_to(0.000_236_588, 4_226.75),
}






def  __lowerCAmelCase					(SCREAMING_SNAKE_CASE      ,      SCREAMING_SNAKE_CASE      ,      SCREAMING_SNAKE_CASE      )->						float:




      """simple docstring"""

      if from_type not in METRIC_CONVERSION:
            raise ValueError(
                f'''Invalid \'from_type\' value: {from_type!r}  Supported values are:\n'''
                + ''', '''.join(SCREAMING_SNAKE_CASE      )      )
      if to_type not in METRIC_CONVERSION:
            raise ValueError(
                f'''Invalid \'to_type\' value: {to_type!r}.  Supported values are:\n'''
                + ''', '''.join(SCREAMING_SNAKE_CASE      )      )
      return value * METRIC_CONVERSION[from_type].from_ * METRIC_CONVERSION[to_type].to


if __name__ == "__main__":
   import doctest

   doctest.testmod()