選擇你自己的 Python 冒險 / 徘徊的格魯
外觀
函式案例研究:徘徊的格魯
假設你想要在你神秘的房子裡放一個徘徊的格魯,它會隨機出現在一個房間(或多個房間)裡。
一種方法是建立一個函式,它決定格魯是否在房間裡。
測試框架
在我們的完整程式碼中,我們將看到類似的程式碼
eaten=grue()
if eaten:
print "Sadly, you were torn limb-from-limb by the Grue and suffered a slow, painful death."
else:
print "Congratulations, you have not been eaten by the Grue! May you have a long happy life."
這裡我們介紹了一種新的 Python 資料型別:布林值。Python 布林值可以取兩個值 True 和 False。這些程式碼片段是等效的
if x > 3:
print "yep!"
if x > 3 is True:
print "yep!"
if bool(x>3) is True:
print "yep!"
“if” 語法隱含 如果謂詞為 True。在 Python 中,大多數東西都評估為 True,除了:None、False、0(0.0 等)、空字串、零長度列表、字典,以及其他一些奇特的東西 [1].
變體 1:不太隨機
def grue_always():
''' this grue always appears. returns true'''
return True
我們不太隨機的格魯總是出現。
練習:建立相反情況——一個永遠不出現的格魯。函式的簽名應該是 grue_never() -> False
變體 2:50/50 格魯
import random
## random is a Python module, as mentioned above.
## We need to import it to access the random() function.
## now to begin the function definition
## Everything inside the function definition is indented! Remember, white space matters!
def random_grue():
''' boolean. a grue that appears 50% of the time '''
## we want something that will return True 50% of the time.
## one method: get a random float between (0,1), and return True if it's over .5
## now we need a random number. random() will give us one between 0 and 1
n=random.random() ## the random before the dot tells Python what module to look in for the function, which is the one we imported above
if n > 0.5:
grue=1 ## 1 == True
else:
grue=0 ## 0 == False
return grue ## returning allows us to capture the value
那麼 random_grue() 函式做了什麼?讓我們試試它。在 Python 直譯器中
>>> import random
>>> def random_grue():
n=random.random()
if n>0/5:
grue = 1
else:
grue = 0
return grue
>>> random_grue()
1
第一個命令是匯入 random 模組,第二個是定義函式,第三個是實際呼叫函式。1 是函式的返回值。你可能會得到 1 或 0,具體取決於 random() 生成的數字。(提示:嘗試執行多次)
變體 2:情緒化的格魯
import random
def grue_moody(cutoff=.5):
''' boolean. a grue that appears (100*cutoff)% of the time '''
n=random.random()
above_cutoff = n < cutoff
return above_cutoff
def grue_moody2(cutoff=.5):
''' boolean. a grue that appears (100*cutoff)% of the time '''
return random.random() < cutoff
注意我們透過直接返回布林值(尤其是在 'grue_moody2' 中)簡化了函式,而不是做任何條件邏輯來獲得 1 或 0。此外,我們還為引數 cutoff 指定了一個預設值。
練習
- 預測這些函式呼叫的行為。然後試試它們。
- grue_moody()
- grue_moody(-1)
- grue_moody(1)
- grue_moody("a")
- grue_moody([1,2,3])
- 修復程式碼,以便如果 n 超出區間 (0,1),則列印一條憤怒訊息並返回
None。 - 嘗試
help(grue_moody)。你看到了什麼? random、random.random、random.random()的型別是什麼?
變體 3:位置,位置,位置格魯
在我們最終的變體中,我們想要一個格魯
- 根據頁面的不同,出現百分比不同
- 在主房間“門廳”中應該沒有出現的可能性
- 在沒有其他描述的房間裡,應該有一個預設的 5% 的出現機率
import random
grue_fractions = { 'foyer':0, 'thedark': 1.0, 'nocake': .2 }
def location_grue(room=None, base=.05, cutoffs=dict()):
''' (boolean), does a grue appear in the room?
room : str room name
base : 'cutoff', float between (0,1), for base (room not found)
cutoffs: dict of room_name: cutoff (float between 0,1)
'''
cutoff = cutoffs[room]
return random.random() < cutoff
練習
- 如寫,
location_grue有一些 bug,並且不符合規範。識別並修復它們。- 嘗試:location_grue('foyer', cutoffs=grue_fractions)
- 如果 'room' 不在 'cutoffs' 中會發生什麼?
- 研究字典的 'get' 方法...
help({}.get)。使用此方法來修復程式碼。