无法弄清楚为什么我的字母在 Python 中的凯撒密码中没有旋转
cannot figure out why my letters are not rotating in the Caesar code in Python
我已经研究这个问题大约一个星期了,但无法弄清楚为什么我的字母没有旋转。我不是在找人为我编写代码,而是帮助我找出我的问题所在。基本上,我正在寻找一只橡皮鸭来帮助解决这个问题。我看到它旋转了最后一个字母,但没有旋转其余字母。这是我现在所在的位置。
from string import ascii_uppercase, ascii_lowercase
def caeser_encrypt(string, step):
new_string = list(string)
for i in range(len(new_string)):
new_ascii = ord(new_string[i]) + step
if string[i] in ascii_uppercase:
if new_ascii > 90:
new_ascii = new_ascii - 90 + 64
elif new_ascii < 65:
new_ascii = 91 - 65 - new_ascii
if string[i] in ascii_lowercase:
if new_ascii > 122:
new_ascii = new_ascii - 122 + 96
elif new_ascii < 97:
new_ascii = 123 - 97 - new_ascii
new_string[i] = chr(new_ascii)
return ''.join(new_string)
def main ():
string = input('Enter word(s)')
step = input("How many rotations do you want?")
step = int(step)
print(caeser_encrypt(string, step))
if __name__ == "__main__":
main()
那里有几个缩进问题:
for i in range(len(new_string)):
循环中只发生了一件事,即设置new_ascii
。当该循环结束时,i
等于 len(new_string) - 1
,因此它将设置最后一个字符,但不会设置任何其他字符。
new_string[i] = chr(new_ascii)
行是您的代码向新字符串添加字母的位置,但请检查您的缩进 - 它仅在 if string[i] in ascii_lowercase:
为真时发生,因此仅适用于小写字母.
这应该有效:
def caeser_encrypt(string, step):
new_string = list(string)
for i in range(len(new_string)):
new_ascii = ord(new_string[i]) + step
if string[i] in ascii_uppercase:
if new_ascii > 90:
new_ascii = new_ascii - 90 + 64
elif new_ascii < 65:
new_ascii = 91 - 65 - new_ascii
if string[i] in ascii_lowercase:
if new_ascii > 122:
new_ascii = new_ascii - 122 + 96
elif new_ascii < 97:
new_ascii = 123 - 97 - new_ascii
new_string[i] = chr(new_ascii)
return ''.join(new_string)
只有最后一个字母被旋转,因为这个缩进:
for i in range(len(new_string)):
new_ascii = ord(new_string[i]) + step
if string[i] in ascii_uppercase:
if new_ascii > 90:
new_ascii = new_ascii - 90 + 64
elif new_ascii < 65:
new_ascii = 91 - 65 - new_ascii
你的意思是这样的:
for i in range(len(new_string)):
new_ascii = ord(new_string[i]) + step
if string[i] in ascii_uppercase:
if new_ascii > 90:
new_ascii = new_ascii - 90 + 64
elif new_ascii < 65:
new_ascii = 91 - 65 - new_ascii
也就是说,if
语句应该在for
语句下面缩进。
如果 if
语句没有那样缩进,
那么它们就不会在循环中执行,
但只执行一次,在 for
循环之后。
当时i
设置为最后一个字母的索引,
这就是为什么只旋转最后一个字母的原因。
代码审查
许多其他改进都是可能的。
而不是像 90、65 这样的神奇数字,
最好使用 ord('z')
和 ord('a')
.
if string[i] in ascii_uppercase
和if string[i] in ascii_lowercase
是互斥条件,
所以它们应该与 elif
.
链接在一起
而不是 if string[i] in ascii_uppercase
,
它在 ascii_uppercase
中执行线性搜索(检查 ascii_uppercase
中的每个值,直到找到匹配项),
使用范围检查会更有效,
if 'A' <= string[i] <= 'Z'
.
该实现也替换了非字母字符。
如果我想旋转"hello world",
这会给出一个有趣的结果,
因为 space。
也许这样也好,
这样单词边界就无法区分了。
所以这不是批评,只是旁注。
放在一起,
以及其他一些小的改进,
你可以这样写:
def caeser_encrypt(string, step):
new_string = list(string)
for i, c in enumerate(new_string):
new_ascii = ord(c) + step
if 'A' <= c <= 'Z':
new_ascii = ord('A') + (new_ascii - ord('A')) % 26
elif 'a' <= c <= 'z':
new_ascii = ord('a') + (new_ascii - ord('a')) % 26
new_string[i] = chr(new_ascii)
return ''.join(new_string)
我已经研究这个问题大约一个星期了,但无法弄清楚为什么我的字母没有旋转。我不是在找人为我编写代码,而是帮助我找出我的问题所在。基本上,我正在寻找一只橡皮鸭来帮助解决这个问题。我看到它旋转了最后一个字母,但没有旋转其余字母。这是我现在所在的位置。
from string import ascii_uppercase, ascii_lowercase
def caeser_encrypt(string, step):
new_string = list(string)
for i in range(len(new_string)):
new_ascii = ord(new_string[i]) + step
if string[i] in ascii_uppercase:
if new_ascii > 90:
new_ascii = new_ascii - 90 + 64
elif new_ascii < 65:
new_ascii = 91 - 65 - new_ascii
if string[i] in ascii_lowercase:
if new_ascii > 122:
new_ascii = new_ascii - 122 + 96
elif new_ascii < 97:
new_ascii = 123 - 97 - new_ascii
new_string[i] = chr(new_ascii)
return ''.join(new_string)
def main ():
string = input('Enter word(s)')
step = input("How many rotations do you want?")
step = int(step)
print(caeser_encrypt(string, step))
if __name__ == "__main__":
main()
那里有几个缩进问题:
for i in range(len(new_string)):
循环中只发生了一件事,即设置new_ascii
。当该循环结束时,i
等于len(new_string) - 1
,因此它将设置最后一个字符,但不会设置任何其他字符。new_string[i] = chr(new_ascii)
行是您的代码向新字符串添加字母的位置,但请检查您的缩进 - 它仅在if string[i] in ascii_lowercase:
为真时发生,因此仅适用于小写字母.
这应该有效:
def caeser_encrypt(string, step):
new_string = list(string)
for i in range(len(new_string)):
new_ascii = ord(new_string[i]) + step
if string[i] in ascii_uppercase:
if new_ascii > 90:
new_ascii = new_ascii - 90 + 64
elif new_ascii < 65:
new_ascii = 91 - 65 - new_ascii
if string[i] in ascii_lowercase:
if new_ascii > 122:
new_ascii = new_ascii - 122 + 96
elif new_ascii < 97:
new_ascii = 123 - 97 - new_ascii
new_string[i] = chr(new_ascii)
return ''.join(new_string)
只有最后一个字母被旋转,因为这个缩进:
for i in range(len(new_string)): new_ascii = ord(new_string[i]) + step if string[i] in ascii_uppercase: if new_ascii > 90: new_ascii = new_ascii - 90 + 64 elif new_ascii < 65: new_ascii = 91 - 65 - new_ascii
你的意思是这样的:
for i in range(len(new_string)):
new_ascii = ord(new_string[i]) + step
if string[i] in ascii_uppercase:
if new_ascii > 90:
new_ascii = new_ascii - 90 + 64
elif new_ascii < 65:
new_ascii = 91 - 65 - new_ascii
也就是说,if
语句应该在for
语句下面缩进。
如果 if
语句没有那样缩进,
那么它们就不会在循环中执行,
但只执行一次,在 for
循环之后。
当时i
设置为最后一个字母的索引,
这就是为什么只旋转最后一个字母的原因。
代码审查
许多其他改进都是可能的。
而不是像 90、65 这样的神奇数字,
最好使用 ord('z')
和 ord('a')
.
if string[i] in ascii_uppercase
和if string[i] in ascii_lowercase
是互斥条件,
所以它们应该与 elif
.
而不是 if string[i] in ascii_uppercase
,
它在 ascii_uppercase
中执行线性搜索(检查 ascii_uppercase
中的每个值,直到找到匹配项),
使用范围检查会更有效,
if 'A' <= string[i] <= 'Z'
.
该实现也替换了非字母字符。 如果我想旋转"hello world", 这会给出一个有趣的结果, 因为 space。 也许这样也好, 这样单词边界就无法区分了。 所以这不是批评,只是旁注。
放在一起, 以及其他一些小的改进, 你可以这样写:
def caeser_encrypt(string, step):
new_string = list(string)
for i, c in enumerate(new_string):
new_ascii = ord(c) + step
if 'A' <= c <= 'Z':
new_ascii = ord('A') + (new_ascii - ord('A')) % 26
elif 'a' <= c <= 'z':
new_ascii = ord('a') + (new_ascii - ord('a')) % 26
new_string[i] = chr(new_ascii)
return ''.join(new_string)