繁体   English   中英

为什么我的while循环在底部运行一次?

[英]Why does my while loop at the bottom run once?

凯撒密码

alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', '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', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

def caesar(text, shift, direction):
  cipher_text = ""
  for letter in text:
    text_position = alphabet.index(letter)
    if direction == "encode":
      new_text_position = text_position + shift
    elif direction == "decode":
     new_text_position = text_position - shift
    else:
      print("Error, invalid entry.")
    cipher_text += alphabet[new_text_position]
  print(f"Your cipher text is {cipher_text}")

direction = input("Type 'encode' to encrypt, or 'decode' to decrypt:\n")
while direction != "encode" or direction != "decode":
  direction = input("Invalid entry. Type 'encode' to encrypt, or 'decode' to decrypt:\n")
  if direction == "encode" or direction == "decode":
    text = input("Type your message:\n").lower()
    shift = int(input("Type the shift number:\n"))
    caesar(text, shift, direction)

这是 Angela Yu 在 Python 上的 Udemy 课程中的凯撒密码程序。底部的想法只是让用户只要输入“编码”或“解码”就可以继续。 如您所见,即使输入是有效答案,while 循环也会运行一次。 它应该直接跳到“if”语句。

我试图根据某人在 4chan 技术板上的建议将“方向”变量的逻辑从“或”更改为“和”,但这不起作用,因为它只接受一个输入。 因此,我尝试将 while 更改为 if,这有效,但如果输入不是两个选项之一,则不允许用户重复。 我还尝试将 if 语句移出 while 循环的域,但这只会导致程序运行 while 循环,即使输入了正确的答案也是如此。

  1. 您在 while 循环中使用 OR 运算符而不是 AND
  2. while 循环内的 if 语句应该在外面

这是一个固定的代码:

alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
            'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', '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', 'q', 'r', 's',
            't', 'u', 'v', 'w', 'x', 'y', 'z']

def caesar(text: str, shift: int, direction: str) -> str:
    cipher = ""
    for letter in text:
        if letter not in alphabet:
            cipher += letter
            continue
        pos = alphabet.index(letter)
        new = pos + shift if direction == "encode" else pos - shift
        cipher += alphabet[new]
    return cipher

direction = input("Type 'encode' to encrypt, or 'decode' to decrypt: ")
while direction != "encode" and direction != "decode":
  direction = input("Invalid entry. Type 'encode' to encrypt, or 'decode' to decrypt: ")
text = input("Type your message: ").lower()
shift = int(input("Type the shift number: "))
print(caesar(text, shift, direction))
  1. while 循环中的运算符应该是 AND 而不是 OR

这是一个示例,假设用户键入“编码”。

使用 OR 运算符:

while direction != "encode" or direction != "decode":

while 循环只有在至少有 1 个条件为真时才会运行

是“编码”?=“编码”? 错误的

是“编码”?=“解码”? 真的

即使它是一个有效的答案,循环仍然运行,因为第二个条件是 True

使用 AND 运算符:

while direction != "encode" and direction != "decode":

while 循环只有在两个参数都为真时才会运行

是“编码”?=“编码”? 错误的

是“编码”?=“解码”? 真的

在这种情况下,while 循环只会在答案既不等于“编码”也不等于“解码”时运行

  1. if 语句是不必要的
while direction != "encode" or direction != "decode":
  direction = input("Invalid entry. Type 'encode' to encrypt, or 'decode' to decrypt:\n")
  if direction == "encode" or direction == "decode":
    text = input("Type your message:\n").lower()
    shift = int(input("Type the shift number:\n"))
    caesar(text, shift, direction)

if 语句在 while 循环内,所以如果用户在第一次尝试时输入了有效答案,while 循环将不会运行,if 语句内的内容也不会运行,因此 if 语句需要在 while 之外环形

但是如果代码在 while 循环之外,那就意味着用户已经输入了正确的答案,没有必要再次检查它,所以你可以删除就删除它

while direction != "encode" and direction != "decode":
  direction = input("Invalid entry. Type 'encode' to encrypt, or 'decode' to decrypt: ")
text = input("Type your message: ").lower()
shift = int(input("Type the shift number: "))
print(caesar(text, shift, direction))

注意:最好直接附上你的代码而不是上传截图,这样任何有兴趣回答的人都可以运行/调试它。

逻辑错误是由2个错误引起的。

首先while循环的条件是它始终为True ,因为:

  1. 如果您输入“encode”: direction != "encode"将为False ,但direction != "decode"将为True ,因此or条件将为True
  2. 如果您输入“decode”: direction != "decode"将为False ,但direction != "encode"将为True ,因此or条件将为True

因此,您必须使用and运算符and以便仅当direction不等于“encode”“decode”时才执行循环。

其次,即使您将or替换为and ,错误仍将存在,因为您通过保持相同的缩进级别将最后一个if语句放置该 while 循环中。 这意味着只有进入 while 循环才会执行if语句。 否则,解释器将 go 遍历整个while循环,其中包括if语句。 因此,您必须取消缩进该if语句,以便它与while循环分开。

它应该是这样的:

direction = input("Type 'encode' to encrypt, or 'decode' to decrypt:\n")
while direction != "encode" and direction != "decode":
    direction = input("Invalid entry. Type 'encode' to encrypt, or 'decode' to decrypt:\n")

if direction == "encode" or direction == "decode":
    text = input("Type your message:\n").lower()
    shift = int(input("Type the shift number:\n"))
    caesar(text, shift, direction)

此外,while 循环看起来更好/更像这样的 pythonic:

while True:
direction = input("Type 'encode' to encrypt, or 'decode' to decrypt:\n")
if direction != "encode" and direction != "decode":
    print("Invalid input. ", end="")
    continue
else:
    break

默认情况下循环是无限的,因为实际条件被替换为True并将永远保持不变,这意味着我将不得不做一些其他事情来“打破”循环,因为while循环没有条件来检查为了。 如果在接受用户输入后, direction不是“编码”或“解码”,它会打印"Invalid input. "并且end=""参数指定字符串的“结尾”。 默认情况下它是end=\n ,这就是为什么你总是得到一个带有print function 的换行符。所以现在,下面的print函数的字符串打印在这个字符串的旁边,因为它们在同一行。 但是,如果满足条件,它会跟随else子句并“跳出”循环。

最后,最后一个if语句是不必要的,因为while循环将负责输入验证。 您的最终代码应如下所示:

alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', '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', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']


def caesar(text, shift, direction):
    cipher_text = ""
    for letter in text:
        text_position = alphabet.index(letter)
        if direction == "encode":
            new_text_position = text_position + shift
        elif direction == "decode":
            new_text_position = text_position - shift
        else:
            print("Error, invalid entry")
        cipher_text += alphabet[new_text_position]
    print(f"Your cipher text is {cipher_text}")


while True:
    direction = input("Type 'encode' to encrypt, or 'decode' to decrypt:\n")
    if direction != "encode" and direction != "decode":
        print("Invalid input. ", end="")
        continue
    else:
        break


if direction == "encode" or direction == "decode":
    text = input("Type your message:\n").lower()
    shift = int(input("Type the shift number:\n"))
    caesar(text, shift, direction)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM