Как я могу сделать этот код Python более эффективным
Буду очень признателен за ваши отзывы о моем первом проекте Python!:D
По сути, я кодирую Цезарь-Шифр, и я думаю, что он довольно ужасно "оптимизирован / эффективен", если вы понимаете, о чем я, это потому, что я скопировал и вставил метод encrypt() для метода decrypt(), и единственное, что я изменил, было вместо того, чтобы вращать числа больше, я поворачивал их меньше. Вот о чем я говорю:
newPosition = (abc.find(letter) - key) % 26
^^ Instead of having a + (plus) I made it a - (minus) ^^
Можно ли как-то вызвать метод encrypt() только в строке newPosition? Или то, что я сделал, было правильно и не нуждается в исправлении (в чем я очень сомневаюсь)
** Пожалуйста, имейте в виду, что я не очень хорошо разбираюсь в Python (если он вообще есть), так как я только начал сегодня, так что не взрывайте мой мозг каким-нибудь супер сложным кодом. БЛАГОДАРЮ ВАС!!! **
abc = 'abcdefghijklmnopqrstuvwxyz'
def main():
message = input("Would you like to encrypt or decrypt a word?")
if message.lower() == "encrypt":
encrypt()
elif message.lower() == "decrypt":
decrypt()
else:
print("You must enter either 'encrypt' or 'decrypt'.")
main()
def encrypt():
message = input("Enter a message to encrypt: ")
message = message.lower()
key = int(input("What number would you like for your key value?"))
cipherText = ""
for letter in message:
if letter in abc:
newPosition = (abc.find(letter) + key) % 26
cipherText += abc[newPosition]
else:
cipherText += letter
print(cipherText)
return cipherText
def decrypt():
message = input("Enter a message to decrypt: ")
message = message.lower()
key = int(input("What number would you like for your key value?"))
cipherText = ""
for letter in message:
if letter in abc:
newPosition = (abc.find(letter) - key) % 26
cipherText += abc[newPosition]
else:
cipherText += letter
print(cipherText)
return cipherText
main()
1 ответ
В общем, str.find
это плохо с точки зрения производительности. Это сложность O(n), которая не ужасна, но на самом деле она вам редко нужна. В этом случае вы можете использовать ord
преобразовать каждую букву в ее порядковый номер, затем вычесть ord('a')
получить 0-25 вместо 97-122.
Это особенно полезно, потому что вы можете использовать chr
конвертировать обратно без необходимости поиска.
for letter in message:
if letter in string.ascii_lowercase: # same as "abcdef..z"
new_position = ((ord(letter) - ord('a') + key) % 26) + ord('a')
new_ch = chr(new_position)
ciphertext += new_ch
Обратите внимание, что объединение строк с +=
не так быстро, как что-то вроде str.join
,
new_letters = [chr(((ord(letter) - ord('a') + key) % 26) + ord('a')) if letter in ascii_lowercase else letter for letter in message]
ciphertext = "".join(new_letters)
И с тех пор chr(((ord(letter) - ord('a') + key) % 26) + ord('a'))
это так уродливо, я бы превратил это в функцию.
def rotate(letter, key=0):
c_pos = ord(letter) - ord('a')
rotated = c_pos + key
modded = rotated % 26
final_pos = modded + ord('a')
return chr(final_pos)
new_letters = [rotate(c, key) if c in string.ascii_lowercase else c for c in letters]
ciphertext = "".join(new_letters)
Точка ремонтопригодности: легче написать тестируемый хороший код, если вы отделяете свои данные от результатов. Прямо сейчас вы должны будете сделать некоторые исправления обезьяны stdin
написать модульные тесты для любой из ваших функций, но если вы перенесете свои запросы для пользовательского ввода в main
и от их соответствующей функции это становится намного легче.
def main():
message = input("What's the message to encrypt/decrypt? ")
key = int(input("What number would you like for your key value? "))
choice = input("Choose: encrypt or decrypt. ")
if choice == "encrypt":
result = encrypt(message, key)
elif choice == "decrypt":
result = decrypt(message, key)
else:
# something here about a bad user input.
На самом деле, если вы считаете, что Цезарь Шифр обратим, переворачивая знак ключа, вы можете просто сделать:
if choice == "encrypt":
result = encrypt(message, key)
elif choice == "decrypt":
result = encrypt(message, key * (-1))
и не писать decrypt
функционировать на всех!