Python Caesar函数输出错误

2024-06-11 12:26:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在跟踪100天的代码,我很难理解为什么这个函数不能正常工作

alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","r","s","t","u","v","w","x","y","z",
            "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","r","s","t","u","v","w","x","y","z",
            "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","r","s","t","u","v","w","x","y","z"]

direction = input("Type 'encode' for Encode type 'decode' for Decode")
text = input("Type your message: \n").lower()
shift = int(input("Type the shift number: \n"))

def cesar(input_text,shift_ammount,which_direction):
    word = ""
    for letter in input_text:
        position = alphabet.index(letter)
        if which_direction == "decode":
            shift_ammount *= -1
        new_position = position + shift_ammount
        word += alphabet[new_position]
    print(f"the {which_direction}d text is {word}")

cesar(input_text=text,shift_ammount=shift,which_direction=direction)

假设我正在尝试解码字符串“bcd”。 它返回“adc”而不是“abc”。 出于某种原因,它在第二个位置加而不是减,并返回错误的值。 欢迎任何帮助


Tags: thetextwhichforinputshifttypeposition
3条回答

我检查了你的代码:

如果我用移位1编码abcdef,它会给我bcdefg-它能工作

如果我用移位1解码bcdefg,它会给我adcfeh-每秒钟一个字母都会被打断。这是因为shift_amout *= -1在解码时切换每个循环的方向

我的解决方案是将if decode放在for循环之上,如

alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","r","s","t","u","v","w","x","y","z",
            "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","r","s","t","u","v","w","x","y","z",
            "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","r","s","t","u","v","w","x","y","z"]

direction = input("Type 'encode' for Encode type 'decode' for Decode: \n") #not part of the question, but you forgot the /n here 
text = input("Type your message: \n").lower()
shift = int(input("Type the shift number: \n"))

def cesar(input_text,shift_ammount,which_direction):
    if which_direction == "decode":
        shift_ammount *= -1

    word = ""
    for letter in input_text:
        position = alphabet.index(letter)
        new_position = position + shift_ammount
        word += alphabet[new_position]
    print(f"the {which_direction}d text is {word}")

cesar(input_text=text,shift_ammount=shift,which_direction=direction)

代码中的问题已经被线程中的其他人解决了,所以我想说,Cesar密码是一个完美的例子,其中^{}是问题的完美解决方案

使用^{}offset结合使用,我们可以使用两种dict理解动态翻译字符串:

import string
def cesar(text: str, offset: int, decode=False) -> str:
    alpha = string.ascii_lowercase
    if decode:
        cipher = {let: alpha[(idx - offset) % len(alpha)] for idx, let in enumerate(alpha)}
    else:
        cipher = {let: alpha[(idx + offset) % len(alpha)] for idx, let in enumerate(alpha)}
    return text.translate(str.maketrans(cipher))

x = "this is a test-string!"
newx = cesar(x, 1)
print(x)
print(newx)
print(cesar(newx, 1, decode=True))

输出:

this is a test-string!
uijt jt b uftu-tusjoh!
this is a test-string!

问题在于线路:

shift_ammount *= -1

此行位于for循环内,这意味着shift_ammount将在每次迭代中更改值。将这部分代码放在for循环之外以获得正确的结果

更新代码:

def cesar(input_text, shift_ammount, which_direction):
    word = ""
    if which_direction == "decode":
        shift_ammount *= -1
    for letter in input_text:
        position = alphabet.index(letter)
        new_position = position + shift_ammount
        word += alphabet[new_position]
    print(f"the {which_direction}d text is {word}")

相关问题 更多 >