1. 变量前加星号的意义
2. 关键字nonlocal 和global
3. Problem 1-3学习笔记
Problem1
def roll_dice(num_rolls, dice=six_sided):
"""Simulate rolling the DICE exactly NUM_ROLLS > 0 times. Return the sum of
the outcomes unless any of the outcomes is 1. In that case, return 1.
num_rolls: The number of dice rolls that will be made.
dice: A function that simulates a single dice roll outcome.
"""
# These assert statements ensure that num_rolls is a positive integer.
assert type(num_rolls) == int, 'num_rolls must be an integer.'
assert num_rolls > 0, 'Must roll at least once.'
# BEGIN PROBLEM 1
"*** YOUR CODE HERE ***"
sum = 0
k = 0
while num_rolls > 0:
m = dice()
# print(m)
sum = m + sum
num_rolls -= 1
'''wrong statement
if dice() == 1:'''
if m == 1:
k = 1
if k == 1:
return k
else:
return sum
# END PROBLEM 1
可以看到标记为wrong statement的判断if dice() == 1
,这里要判断是否存在为1的值不能再次用dice()
,因为从dice.py
中可以知道dice()
会返回dice
,而此处调用dice()
是将当前位去和1比较大小,而并不会被加在sum
中,会导致往后走一位,所以需要引入一个新变量m
存储当前位的值。
Problem3
# dice.py
from random import randint
def make_fair_dice(sides):
assert type(sides) == int and sides >= 1, 'Illegal value for sides'
def dice():
return randint(1, sides) # dice ∈ [1,sides]
return dice
six_sided = make_fair_dice(6)
def make_test_dice(*outcomes): # return的是dice,然后再调用dice() !!!
assert len(outcomes) > 0, 'You must supply outcomes to make_test_dice'
for o in outcomes:
assert type(o) == int and o >= 1, 'Outcome is not a positive integer'
index = len(outcomes) - 1
def dice():
nonlocal index # nonlocal只能在嵌套函数中使用,即在def()下的def()中使用,可以在o-p-t中尝试去掉这一句,就可以知道这句话的作用了!!
index = (index + 1) % len(outcomes)
return outcomes[index]
return dice
# hog.py
def roll_dice(num_rolls, dice = six_sided):
# These assert statements ensure that num_rolls is a positive integer.
assert type(num_rolls) == int, 'num_rolls must be an integer.'
assert num_rolls > 0, 'Must roll at least once.'
sum = 0
k = 0
while num_rolls > 0:
m = dice()
print(m)
sum = m + sum
num_rolls -= 1
if m == 1:
k = 1
if k == 1:
return k
else:
return sum
def free_bacon(score):
assert score < 100, 'The game should be over.'
# BEGIN PROBLEM 2
"*** YOUR CODE HERE ***"
return abs(score % 10 - score // 10) + 2
# END PROBLEM 2
def take_turn(num_rolls, opponent_score, dice=six_sided):
assert type(num_rolls) == int, 'num_rolls must be an integer.'
assert num_rolls >= 0, 'Cannot roll a negative number of dice in take_turn.'
assert num_rolls <= 10, 'Cannot roll more than 10 dice.'
assert opponent_score < 100, 'The game should be over.'
# BEGIN PROBLEM 3
"*** YOUR CODE HERE ***"
if num_rolls == 0:
return free_bacon(opponent_score)
else:
return roll_dice(num_rolls)
# END PROBLEM 3
这里把dice.py中的函数和hog.py中的前几个函数放到了一个文件中进行测试。
以下是我关于重复出现的dice及缺省值six_sided的思考:
1.在def statement语句:def roll_dice(num_rolls, dice = six_sided)
中,可以看到形参dice
的缺省值为 six_sided
,即make_fair_dice(6)
。
2.在写到take_turn()
函数中最后一句return roll_dice()
函数的时候(为方便省略掉括号中的参数),考虑到def statement 语句:def roll_dice(num_rolls, dice = six_sided)
中参数dice是有缺省值的,于是想到:那return roll_dice()
的dice是不是可以省略呢?
3.But unfortunately,如果写成 return roll_dice(num_rolls)
,省略掉dice,让其为默认值six_sided。在terminal 中测试,可以看到测试了 take_turn(2,0,make_test_dice(4,6,1))
,却没有得到正确的结果。
4.通过观察代码以及在online python tutor中一步步地运行,找到了原因:
① make_fair_dice(sides)
与 make_test_dice(*outcomes)
两个函数返回的都叫dice,但是former是产生一个随机数, latter是通过一次次调用将一个元祖中的数依次print出来。姑且叫做dice1 & dice2 ,分别绑定func dice1() & func dice2()
。
② 因为测试语句为take_turn(2,0,make_test_dice(4,6,1))
,因为make_test_dice(4,6,1)
函数的返回值是dice2, 也就是说call take_turn()函数时,实参make_test_dice(4,5,7)
绑定的是func dice2()
。
③ 既然take_turn()函数的实参dice对应的是func dice2()
,并不是默认的缺省值six_sided对应的func dice1()
。那么take_turn()函数中最后返回的roll_dice()函数中就不能省略dice参数了,而必须写上dice,即写为return roll_dice(num_rolls,dice)
。
④ 总结:
测试语句 take_turn()中第三个实参如果为make_test_dice()
,那么不能省略dice,必须写成return roll_dice(num_rolls,dice)
,此时make_test_dice()
与dice
均对应make_test_dice()
的返回值 func dice2。
如果想省略dice,写成return roll_dice(num_rolls)
,那么在终端中测试的语句应该改为take_turn(2,0),这表示take_turn()的传入参数即是缺省值six_sided对应的func dice1()。这是return roll_dice(num_rolls)
也省略了dice值,表示dice是默认的缺省值six_sided。