1
数学部分
https://class.coursera.org/principlescomputing-001/wiki/view?page=enumeration
https://class.coursera.org/principlescomputing-001/wiki/view?page=permutations
2 代码部分
http://www.codeskulptor.org/#poc_enumeration.py
demo debugging http://www.codeskulptor.org/#examples_math_dice_errors.py
3 测试
测试框架的定义 http://www.codeskulptor.org/#poc_simpletest.py
测试框架的使用 http://www.codeskulptor.org/#poc_holds_testsuite.py
4 如何使用factorial
import math
print math.factorial(n)
5 Debug注意事项
5.1 制造可复现的稳定输入
5.2 把复杂逻辑变得简单,使得程序更加可以控制。
6 tuple 是hashable的,可以作为字典中的key和set中的元素
sorted_sequences = [tuple(sorted(sequence)) for sequence in all_sequences]
为什么要转换为tuple呢?
因为Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally
7 tuple如果只有一个元素,要在圆括号中加上逗号
tuple如果只含有1个元素,s=(1),则应该写为s=(1,)否则python会识别为s=(int)1
# correct
s = (1,2,3,4,5)
for i in s:
print i
# correct
s = (1,)
for i in s:
print i
#Line 1: ValueError: expecting Array or iterable
s = (1)
for i in s:
print i
8 set.copy()的使用
如果在对set的iteration中要修改set,可以使用set_cur.copy()避免进入无限循环。
9 mini project Yahtzee
数学部分
https://class.coursera.org/principlescomputing-001/wiki/view?page=enumeration
https://class.coursera.org/principlescomputing-001/wiki/view?page=permutations
2 代码部分
http://www.codeskulptor.org/#poc_enumeration.py
demo debugging http://www.codeskulptor.org/#examples_math_dice_errors.py
3 测试
测试框架的定义 http://www.codeskulptor.org/#poc_simpletest.py
测试框架的使用 http://www.codeskulptor.org/#poc_holds_testsuite.py
4 如何使用factorial
import math
print math.factorial(n)
5 Debug注意事项
5.1 制造可复现的稳定输入
5.2 把复杂逻辑变得简单,使得程序更加可以控制。
6 tuple 是hashable的,可以作为字典中的key和set中的元素
sorted_sequences = [tuple(sorted(sequence)) for sequence in all_sequences]
为什么要转换为tuple呢?
因为Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally
7 tuple如果只有一个元素,要在圆括号中加上逗号
tuple如果只含有1个元素,s=(1),则应该写为s=(1,)否则python会识别为s=(int)1
# correct
s = (1,2,3,4,5)
for i in s:
print i
# correct
s = (1,)
for i in s:
print i
#Line 1: ValueError: expecting Array or iterable
s = (1)
for i in s:
print i
8 set.copy()的使用
如果在对set的iteration中要修改set,可以使用set_cur.copy()避免进入无限循环。
for each in set_cur.copy():
set_cur.add("aaa");
9 mini project Yahtzee
"""
Planner for Yahtzee
Simplifications: only allow discard and roll, only score against upper level
"""
# Used to increase the timeout, if necessary
import codeskulptor
codeskulptor.set_timeout(20)
def gen_all_sequences(outcomes, length):
"""
Iterative function that enumerates the set of all sequences of
outcomes of given length.
"""
answer_set = set([()])
for dummy_idx in range(length):
temp_set = set()
for partial_sequence in answer_set:
for item in outcomes:
new_sequence = list(partial_sequence)
new_sequence.append(item)
temp_set.add(tuple(new_sequence))
answer_set = temp_set
return answer_set
def score(hand):
"""
Compute the maximal score for a Yahtzee hand according to the
upper section of the Yahtzee score card.
hand: full yahtzee hand
Returns an integer score
"""
max_score = 0
dict_score = dict((handitem,0) for handitem in hand)
for eachitem1 in hand:
dict_score[eachitem1] += eachitem1
if dict_score[eachitem1] > max_score :
max_score = dict_score[eachitem1]
return max_score;
def expected_value(held_dice, num_die_sides, num_free_dice):
"""
Compute the expected value of the held_dice given that there
are num_free_dice to be rolled, each with num_die_sides.
held_dice: dice that you will hold
num_die_sides: number of sides on each die
num_free_dice: number of dice to be rolled
Returns a floating point expected value
"""
tuples1 = tuple([x+1 for x in range(num_die_sides)])
set1=gen_all_sequences(tuples1, num_free_dice)
sum1 = 0;
for each in set1:
hand_cur = tuple(held_dice + each);
sum1 += score(hand_cur)
return float(sum1)/len(set1)
def gen_all_holds(hand):
"""
Generate all possible choices of dice from hand to hold.
hand: full yahtzee hand
Returns a set of tuples, where each tuple is dice to hold
"""
set_cur = set([()])
for hand_ele in hand:
for each in set_cur.copy():
new_each = list(each)
new_each.append(hand_ele)
set_cur.add(tuple(new_each))
return set_cur
def strategy(hand, num_die_sides):
"""
Compute the hold that maximizes the expected value when the
discarded dice are rolled.
hand: full yahtzee hand
num_die_sides: number of sides on each die
Returns a tuple where the first element is the expected score and
the second element is a tuple of the dice to hold
"""
all_holds = gen_all_holds(hand)
max_score = 0.0
max_hold = ()
for each in all_holds:
num_free_dice = len(hand) - len(each)
each_score = expected_value(each, num_die_sides, num_free_dice)
if each_score > max_score:
max_score = each_score
max_hold = each
return (max_score, max_hold)
def run_example():
"""
Compute the dice to hold and expected score for an example hand
"""
num_die_sides = 6
hand = (1, )
hand_score, hold = strategy(hand, num_die_sides)
print "Best strategy for hand", hand, "is to hold", hold, "with expected score", hand_score
run_example()
#import poc_holds_testsuite
#poc_holds_testsuite.run_suite(gen_all_holds)