2014-02-08 149 views
0

我在問用戶他們是否想先走,並使用輸入驗證,以便只接受「y」「Y」「n」或「N」作爲有效響應。我的代碼似乎崩潰時,我運行它。Python:輸入驗證

choice = raw_input("Would you like to go first or not? (y/Y or n/N): ") 
print "" 

try: 
    valid_choice = False 
    while not valid_choice: 
     if choice == "y" or choice == "Y": 
      users_turn = True 
      valid_choice = True 
     elif choice == "n" or choice == "N": 
      users_turn = False 
      valid_choice = True 
      break 
    else: 
      print "Invalid Choice." 

except NameError: 
    print "You can only enter y/Y or n/N" 
+0

*「我的代碼似乎崩潰了」* - 以何種方式,更準確地說?什麼是錯誤? – Dolda2000

+0

您在if子句 – zhangxaochen

+0

中缺少'break'如果這些答案中的任何一個對您有幫助,您應該選擇一個作爲解決方案。 –

回答

2

啊,你的代碼中的流程有太多可能的路徑。你可能喜歡的東西把它簡化:

question = "Would you like to go first or not? (y/Y or n/N): " 
choice = raw_input(question) 
while choice not in ['y', 'Y', 'n', 'N']: 
    print 'Invalid choice' 
    choice = raw_input(question) 
users_turn = choice in ['y', 'Y'] 

說了這麼多,我應該說這是一個控制檯應用程序使用(Y/n)以表明它接受字母yn作爲響應的通用模式(在大寫和小寫),但大寫字母表示默認選項。

所以,如果你可以信任用戶做出決定你第一次要求輸入的問題,您可以設置這樣的默認響應和代碼是:

choice = raw_input('Would you like to go first? (Y/n)') 
users_turn = choice.lower() not in ['n', 'no'] 
+0

@zhangxaochen我看到你的編輯使用了一個字符串,但我認爲我仍然更喜歡使用一個列表 - 這樣你就可以添加其他可能的答案,比如'yes','no''和首字母以支持其他語言。 – elias

+0

是的,我刪除了該編輯,因爲'ynnN''中的'Yn'給出了'True'。對不起; P – zhangxaochen

+0

@ zhangxaochen哦是的,還有那個! =) – elias

0

,正如替代Elias的答案,我想提出以下幾點:

while True: 
    choice = raw_input("Would you like to go first or not? (y/Y or n/N): ") 
    if choice in ["y", "Y", "n", "N"]: 
     break 
    print "Invalid choice" 
users_turn = choice in ["y", "Y"] 

這是在更好地不重複問線,但在糟糕的while True/break語法是有點難看(它如果Python有do會很好...像C一樣的while,但唉)。選擇你最喜歡的自己。 :)

而且,只是指出一些你有幾個錯誤的在自己的代碼:

  • try ... except NameError塊完全是多餘的,因爲沒有在你的代碼將拋出NameError,並且特別不用於指示實際的用戶錯誤。
  • 你有你的else行在錯誤的縮進。就目前而言,它與while區塊相匹配,而不是if/elif區塊,導致您最不可能打算的行爲。
  • elif塊中的break塊是多餘的,因爲當您將valid_choice設置爲True時,while環路將退出。
  • 最重要的是所有的,當你輸入一個無效的答案時,你不會重新分配用戶,導致你的代碼永遠循環。也許這是你所說的未說明的崩潰?
0
def get_one_of(prompt, options, default=None): 
    options = set(options) 
    while True: 
     val = raw_input(prompt) 
     if val == '' and default is not None: 
      return default 
     elif val in options: 
      return val 

response = get_one_of('Do you want to go first? [Yn] ', 'yYnN', 'y') 
users_turn = response in 'yY'