看完這一節,真心覺得處理使用者輸入是一門學問,不過在玩自己寫的東西時也察覺到這一點了,如果是其他人來輸入的話,說不定就不用玩了。
每乙個房間都需要一套自己的語句,而且只有使用者完全輸入正確後才能執行。所以,我們需要對使用者的輸入進行掃瞄,不管使用者以什麼方式輸入詞彙,都能執**間**。甚至如果使用者的輸入和常用英語很接近也應該是可以的,而你的遊戲要識別出它們的意思。像下面的都要能夠識別出來。
open door
open the door
go through the door
punch bear
punch the bear in the face
當然,前提是假設玩這個遊戲的是乙個正常人(手動滑稽) 。
作者的建議是專門寫乙個模組,搭配若干類,互相配合,接受使用者輸入,並將其轉化成遊戲可以識別的命令。
首先是英文的簡單格式:
我們要最先處理使用者輸入的詞彙,並判斷出來它們是什麼。
遊戲裡建立了下面這些語彙:
表示方向: north, south, east, west, down, up, left, right, back.
動詞: go, stop, kill, eat.
修飾詞: the, in, of, from, at, it
名詞: door, bear, princess, cabinet.
數詞: 由 0-9 構成的數字
斷句
有了詞彙表,為了分析句子的意思,我們需要找到乙個斷句的方法,因為我們對於句子的定義是「空格隔開的單詞」,所以用split方法就好了。當然,這是英文,處理中文的話還需要第三方庫。
stuff = raw_input('> ')
words = stuff.split()
語彙元組
先將句子轉化成詞彙列表,剩下的就是逐一檢查這些詞彙,看它們是什麼型別,並且對它執行指令。
使用元組(tuple)儲存詞彙和其型別,它是一種不能原地修改的序列型別,這樣使得使用者輸入的詞彙不會改變。
# (type, word)
first_word = ('direction', 'north')
second_word = ('verb', 'go')
sentence = [first_word, second_word] # 元組的列表
接受使用者輸入,用split將其分隔成單詞列表,然後分析這些單詞,識別它們的型別,最後重新組成乙個句子。下面是自己要寫的掃瞄器**:
"""
direction : north, south, east, west, down, up, left, right, back;
verb : go, stop, kill, eat;
stop : the, in, of, from, at, it;
noun : door, bear, princess, cabinet;
number : 0-9 number
"""def
scan
(stuff):
stuff = stuff.lower() # 為識別任意大小寫的詞彙,將其統一轉換為小寫
words = stuff.split()
direction = ['north', 'south', 'east', 'west', 'down', 'up', 'left', 'right', 'back']
verb = ['go', 'stop', 'kill', 'eat']
stop = ['the', 'in', 'of', 'from', 'at', 'it']
noun = ['door', 'bear', 'princess', 'cabinet']
result = [ ]
for word in words:
if word in direction:
elif word in verb:
elif word in stop:
elif word in noun:
elif convert_number(word):
else:
return result
defconvert_number
(num):
# 如果沒有作者的提醒,這裡不一定會想到
try:
return int(num)
except valueerror:
return
none
測試**from nose.tools import *
from ex48 import lexicon
deftest_upper_lower
():# 更新**
assert_equal(lexicon.scan("north"), [('direction', 'north')])
result = lexicon.scan("south kill eat")
assert_equal(result, [('direction', 'south'),
('verb', 'kill'),
('verb', 'eat')])
deftest_directions
():# 測試表中方位詞
assert_equal(lexicon.scan("north"), [('direction', 'north')])
result = lexicon.scan("north south east")
assert_equal(result, [('direction', 'north'),
('direction', 'south'),
('direction', 'east')])
deftest_verbs
():# 測試表中動詞
assert_equal(lexicon.scan("go"), [('verb', 'go')])
result = lexicon.scan("go kill eat")
assert_equal(result, [('verb', 'go'),
('verb', 'kill'),
('verb', 'eat')])
deftest_stop
():# 測試表中停用詞
assert_equal(lexicon.scan("the"), [('stop', 'the')])
result = lexicon.scan("the in of")
assert_equal(result, [('stop', 'the'),
('stop', 'in'),
('stop', 'of')])
deftest_nouns
():# 測試表中名詞
assert_equal(lexicon.scan("bear", [('noun', 'bear')])
result = lexicon.scan("bear princess")
assert_equal(result, [('noun', 'bear'),
('noun', 'princess')])
deftest_number
():# 測試數字
assert_equal(lexicon.scan("1234"), [('number', 1234)])
result = lexicon.scan("3 91234")
assert_equal(result, [('number', 3),
('number', 91234)])
deftest_errors
():# 測試錯誤
assert_equal(lexicon.scan("asdfadfasdf"), [('error', 'asdfadfasdf')])
result = lexicon.scan("bear ias princess")
assert_equal(result, [('noun', 'bear'),
('error', 'ias'),
('noun', 'princess')])
測試結果
學會使用異常(exceptions)
。
異常指的是你執行某個函式時得到的錯誤。你的函式在碰到錯誤時,就會提出(raise)
乙個異常,如果不使用異常處理的話,程式就會終止。所以,我們要學會去處理(handle)異常。
python使用try-except
來做異常處理,我們會把要試著執行的**放到try
的區段裡,再將出錯後要執行的**放到except
區段裡。
在掃瞄數字的時候,用int()
來將字串轉換為數字,如果不是數字的話,該函式就會丟擲valueerror
異常。我們要做的就是中間出了錯,就抓住這個錯誤,然後返回none
,這樣if語句
判斷時就是false了。
學習筆記 day43
位址列輸入 超連結form表單 ajax 請求 重定向常用方法 描述getrequesturl 獲取客戶端發出的請求時的完整 url getrequesturi 獲取請求行中的資源名稱部分 專案名稱開始 getquerystring 獲取請求行中的引數部分 getmethod 獲取客戶端請求方式 g...
每日演算法 day 43
那些你早出晚歸付出的刻苦努力,你不想訓練,當你覺的太累了但還是要咬牙堅持的時候,那就是在追逐夢想,不要在意終點有什麼,要享受路途的過程,或許你不能成就夢想,但一定會有更偉大的事情隨之而來。mamba out 2020.3.29 我太菜了 今天開始補cfdiv3 include include inc...
python學習 Day43 多執行緒
python中提供了threading模組來對多執行緒的操作。執行緒是應用程式中工作的最小單元。多執行緒實現有兩種方式 一 將要執行的方法作為引數傳給thread的構造方法 和多程序類似 t threading,thread target action,args i,二 從thread繼承,並重寫r...