docs: def cipher(self):
          """Applies the Caesar shift cipher.
  
          Based on the attributes of the object, applies the Caesar shift cipher
          to the message attribute. Accepts positive and negative integers as
          offsets.
  
          Required attributes:
              message
              offset
  
          Returns:
              String with cipher applied.
          """
          # If no offset is selected, pick random one with sufficient distance
          # from original.
          if self.offset is False:
              self.offset = randrange(5, 25)
              logging.info("Random offset selected: {0}".format(self.offset))
          logging.debug("Offset set: {0}".format(self.offset))
  
          # Cipher
          ciphered_message_list = list(self.message)
          for i, letter in enumerate(ciphered_message_list):
              if letter.isalpha():
                  # Use default upper and lower case characters if alphabet
                  # not supplied by user.
                  if letter.isupper():
                      alphabet = [character.upper()
                                  for character in self.alphabet]
                  else:
                      alphabet = self.alphabet
  
                  logging.debug("Letter: {0}".format(letter))
                  logging.debug("Alphabet: {0}".format(alphabet))
                  value = alphabet.index(letter)
                  cipher_value = value + self.offset
                  if cipher_value > 25 or cipher_value < 0:
                      cipher_value = cipher_value % 26
                  logging.debug("Cipher value: {0}".format(cipher_value))
                  ciphered_message_list[i] = alphabet[cipher_value]
                  logging.debug("Ciphered letter: {0}".format(letter))
          self.message = ''.join(ciphered_message_list)
          return self.message