code: def crack(ciphertext, *fitness_functions, min_key=0, max_key=26, shift_function=shift_case_english):
      
      if min_key >= max_key:
          raise ValueError("min_key cannot exceed max_key")
  
      decryptions = []
      for key in range(min_key, max_key):
          plaintext = decrypt(key, ciphertext, shift_function=shift_function)
          decryptions.append(Decryption(plaintext, key, score(plaintext, *fitness_functions)))
  
      return sorted(decryptions, reverse=True)
docs: Break ``ciphertext`` by enumerating keys between ``min_key`` and ``max_key``.
  
      Example:
          >>> decryptions = crack("KHOOR", fitness.english.quadgrams)
          >>> print(''.join(decryptions[0].plaintext))
          HELLO
  
      Args:
          ciphertext (iterable): The symbols to decrypt
          *fitness_functions (variable length argument list): Functions to score decryption with
  
      Keyword Args:
          min_key (int): Key to start with
          max_key (int): Key to stop at (exclusive)
          shift_function (function(shift, symbol)): Shift function to use
  
      Returns:
          Sorted list of decryptions
  
      Raises:
          ValueError: If min_key exceeds max_key
          ValueError: If no fitness_functions are given