簡體   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