Python Rot13与模的使用

Python Rot13与模的使用,python,string,modulo,rot13,Python,String,Modulo,Rot13,我一直在阅读Allen B.Downey的《思考Python》,其中有一个练习(8.12),作者要求创建一个ROT13函数。我做了我的,它部分地起作用了,因为我在和大写字母作斗争 以下是作者提供的解决方案的一部分: def rotate_letter(letter, n): """Rotates a letter by n places. Does not change other chars. letter: single-letter string n: int Returns: si

我一直在阅读Allen B.Downey的《思考Python》,其中有一个练习(8.12),作者要求创建一个ROT13函数。我做了我的,它部分地起作用了,因为我在和大写字母作斗争

以下是作者提供的解决方案的一部分:

def rotate_letter(letter, n):
"""Rotates a letter by n places.  Does not change other chars.

letter: single-letter string
n: int

Returns: single-letter string
"""
if letter.isupper():
    start = ord('A')
elif letter.islower():
    start = ord('a')
else:
    return letter

c = ord(letter) - start
i = (c + n) % 26 + start
return chr(i)
这里使用模使函数对大写字母起作用,但我不明白为什么!
很明显,通过使用它,我们可以在大写ASCII值的开头重新启动,但我无法理解其背后的机制。

尝试将其分解为步骤,并打印出中间数字。或者,更好的办法是,在一台计算机上运行它

例如,字母
'Q'
和数字13,您将得到:

'Q'.isupper() is true
start = ord('A') = 65
c = ord('Q') - start = 81 - 65 = 16
i = (c + n) % 26 + start = (16 + 13) % 26 + 65 = 29 % 26 + 65 = 3 + 65 = 68
chr(i) is 'D'
如您所见,神奇的部分是
(16+13)%26
。因此,让我们试着在从0(对于
A
)到25(对于
Z
)的每一个数字上运行它,看看会发生什么:

>>> for i in range(26):
...     print ((i + 13) % 26),
13 14 15 16 17 18 19 20 21 22 23 24 25 0 1 2 3 4 5 6 7 8 9 10 11 12

加上,然后用26取余数,意味着当你到26时,你回到0。就像在时钟上加1小时到23:00等于00:00(或者,如果你是美国人,加1小时到12:00等于1:00)。

试着把它分解成几个步骤,并打印出中间的数字。或者,更好的办法是,在一台计算机上运行它

例如,字母
'Q'
和数字13,您将得到:

'Q'.isupper() is true
start = ord('A') = 65
c = ord('Q') - start = 81 - 65 = 16
i = (c + n) % 26 + start = (16 + 13) % 26 + 65 = 29 % 26 + 65 = 3 + 65 = 68
chr(i) is 'D'
如您所见,神奇的部分是
(16+13)%26
。因此,让我们试着在从0(对于
A
)到25(对于
Z
)的每一个数字上运行它,看看会发生什么:

>>> for i in range(26):
...     print ((i + 13) % 26),
13 14 15 16 17 18 19 20 21 22 23 24 25 0 1 2 3 4 5 6 7 8 9 10 11 12

加上,然后用26取余数,意味着当你到26时,你回到0。就像在时钟上加1小时到23:00会让你到00:00(或者,如果你是美国人,加1小时到12:00会让你到1:00)。

模26本身与大小写无关,需要让序列回到开头

考虑一个简单的“rot 1”:将字母表中的字母视为1到26之间的数字,然后加1。如果输入为“a”,则取1+1=2,得到“b”;如果输入为“z”,则取26+1=27——但字母表中没有第27个字母!所以你计算27模26=1,它“旋转”回“a”


在上面的实现中,大写和小写的实际技巧是定义
start
,它在应用旋转之前将ASCII位置转换为数字1到26,然后使用相同的偏移量将结果转回。

模26本身与大写和小写无关,需要将序列回卷到开头

考虑一个简单的“rot 1”:将字母表中的字母视为1到26之间的数字,然后加1。如果输入为“a”,则取1+1=2,得到“b”;如果输入为“z”,则取26+1=27——但字母表中没有第27个字母!所以你计算27模26=1,它“旋转”回“a”


在上面的实现中,大写和小写的实际技巧是
start
的定义,它在应用旋转之前将ASCII位置转换为数字1到26,然后使用相同的偏移量将结果转回。

我认为它实际上是0到25,但基本上是相同的。是的,它是0到25。我一直不明白为什么在美国他们把模作为“时钟算术”来教,时钟从1到12,这让人很困惑,但别这么说,在其他国家,时钟从0到23,工作得很好……我认为它实际上是0到25,但基本上是一样的。是的,它是0到25。我一直不明白为什么他们在美国把模作为“时钟算术”来教授,在美国,时钟从1到12,这让人很困惑,但在其他国家,不要这样说,在其他国家,时钟从0到23,它会工作得很好…