[英]Python Vigenere working, but I can't account for the spaces and non alphabetical characters using functions
我目前正在为初学者python课程开发密码程序。 首先,我们被告知要创建一个函数,该函数使用一串字母作为参考来返回给定字母的位置(这是我的Alphabet_position函数。)接下来,我们被告知要创建一个函数,该函数允许单个字母旋转一个选定的数字(即我的rotate_character函数)。 第三,我们的任务是使用前两个功能创建基本的凯撒密码。 我能够完成所有这些工作,如下面的代码所示。
然而,事实证明,困难得多。 实际上,我能够找到一段代码,如果仅使用字母字符,但是只要输入任何非字母字符(例如!或?),就可以使用第一个函数(alphabet_position)进行修改以使工作正常我得到ValueError的返回:找不到子字符串。 当程序遇到这些非字母字符时,该键应跳过它们并将键的第N个字符携带到下一个字母字符。
我猜想答案就在于将我的rotate_character函数合并到我的Encrypt函数中,但是我不确定该怎么做,因为rotate_character函数需要一个字母字符,而vigenere函数会在运行该参数之前将该参数转换为一个int。
有什么建议吗? 当我是一名新程序员时,我很乐意对您可能想灌输的我的编码实践提出任何其他有用的批评!
> #Create function alphabet_position(letter) to turn letter into number
> #such as a=0 or e=4, using lowercase to make sure case doesnt matter.
alphabet = "abcdefghijklmnopqrstuvwxyz"
def alphabet_position(letter):
> lower_letter = letter.lower() #Makes any input lowercase.
> return alphabet.index(lower_letter) #Returns the position of input
as a number.
>
> def rotate_character(char, rot):
> if char.isalpha():
> a = alphabet_position(char);
> a = (a + rot) % (int(len(alphabet))); #needs modulo
> a = (alphabet[a]);
> if char.isupper():
> a = a.title()
> return a
> else:
> return char
>
> def caesar(text, rot):
> list1 = ""
> for char in text:
> list1 += rotate_character(char, rot)
> return list1
>
> def vigenere(text,key):
m = len(key)
>
> newList = ""
>
> for i in range(len(text)):
text_position = alphabet_position(text[i])
key_position = alphabet_position(key[i % m])
value = (text_position + key_position) % 26
newList += alphabet[value]
return newList
>
> def main():
> x = input("Type a message: ")
> y = input("Rotate by: ")
> result = vigenere(x, y)
> print (result)
>
> if __name__ == '__main__':
main()
不,您不再需要旋转功能。 您只需要直接将字母中没有的任何字符添加到新列表中,然后跳过加密部分即可。
现在,执行此操作的次佳方法是if ... in ...
使用if ... in ...
:
if text[i] in alphabet:
# do your thing
else:
newList += text[i]
当然,更好的选择是只遍历一次字母并使用一个变量:
pt_c = text[i]
pt_i = alphabet.find(pt_c) # returns -1 instead of an error when not found
if pt_i == -1:
newList += pt_c
else:
newList += pt_c
# do your thing *with the given index*
当然,对于Vigenère密码,这在运行时间上不会有任何区别。 但是它向您展示了如何在以后考虑有效的编程:无需搜索两次。
您也可以continue
循环,而不必使用else语句:
pt_c = text[i]
pt_i = alphabet.find(pt_c) # returns -1 instead of an error when not found
if pt_i == -1:
continue
# do your thing with the given index
这将使循环的缩进深度(范围的数量)减少,并具有使循环更复杂(创建本地出口点)的不幸副作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.