93
Pythonでやる ショートコーディング momo_*(tututen) 1 2011730日土曜日

Pysap#3.1 Pythonでショートコーディング

Embed Size (px)

DESCRIPTION

2011/07/30 発表したスライド sourceは、 https://bitbucket.org/tututen/pysap3.1/

Citation preview

Page 1: Pysap#3.1 Pythonでショートコーディング

Pythonでやるショートコーディング

momo_*(@tututen)1

2011年7月30日土曜日

Page 2: Pysap#3.1 Pythonでショートコーディング

自己紹介

2

2011年7月30日土曜日

Page 3: Pysap#3.1 Pythonでショートコーディング

自己紹介

3

• 北海道北見市在住

• Python歴は約半年

• つまみ食いプログラマ

• お仕事ではC言語でサーバ書き書き

2011年7月30日土曜日

Page 4: Pysap#3.1 Pythonでショートコーディング

北見ってどこ?

4札幌←→北見間 294km(高速道路を使用しない)

2011年7月30日土曜日

Page 5: Pysap#3.1 Pythonでショートコーディング

対戦者募集中!

5

• パネルでポン対戦者募集中!!

• ニコニコ代表タグ

• 友達がいないとこうなります

• 人間やめましたシリーズ

2011年7月30日土曜日

Page 6: Pysap#3.1 Pythonでショートコーディング

ATTENTION

6

2011年7月30日土曜日

Page 7: Pysap#3.1 Pythonでショートコーディング

お約束

7

• これから書くことはPEP8を無視しています

• 「Pythonっぽくない」かも

• Pythonの基本技術は省くよ!(オライリーが何とかしてくれる)

• 「もっと短く書けるよ」という意見歓迎

2011年7月30日土曜日

Page 8: Pysap#3.1 Pythonでショートコーディング

ショートコーディングとは?

8

2011年7月30日土曜日

Page 9: Pysap#3.1 Pythonでショートコーディング

ショートコーディングとは

9

• 「コードゴルフ」というのが一般的

2011年7月30日土曜日

Page 10: Pysap#3.1 Pythonでショートコーディング

ショートコーディングとは

10

• 「コードゴルフ」というのが一般的

• より少ないバイト数で所与の課題をプログラミングする遊び。より少ない打(鍵)数を競うところがゴルフに似ているところからの命名(hatena keyword 引用)

2011年7月30日土曜日

Page 11: Pysap#3.1 Pythonでショートコーディング

ショートコーディングとは

11

• 「コードゴルフ」というのが一般的

• より少ないバイト数で所与の課題をプログラミングする遊び。より少ない打(鍵)数を競うところがゴルフに似ているところからの命名(hatena keyword 引用)

• ショートコーディング攻略wikiなるものがある

2011年7月30日土曜日

Page 12: Pysap#3.1 Pythonでショートコーディング

Pythonでよく言われていること

12

2011年7月30日土曜日

Page 13: Pysap#3.1 Pythonでショートコーディング

Pythonでは多くのユーザによって書かれた同一の仕事をするプログラムは、だいたいどれも同じようなコードに収束する。(wikipedia 引用)

13

2011年7月30日土曜日

Page 14: Pysap#3.1 Pythonでショートコーディング

本当に?

14

2011年7月30日土曜日

Page 15: Pysap#3.1 Pythonでショートコーディング

例:偶数のリスト作成

15

2011年7月30日土曜日

Page 16: Pysap#3.1 Pythonでショートコーディング

偶数のリスト作成

16

• range(0, max_value, 2)

2011年7月30日土曜日

Page 17: Pysap#3.1 Pythonでショートコーディング

偶数のリスト作成

17

• range(0, max_value, 2)

• [i * 2 for i in range(num)]

2011年7月30日土曜日

Page 18: Pysap#3.1 Pythonでショートコーディング

偶数のリスト作成

18

• range(0, max_value, 2)

• [i * 2 for i in range(num)]

• a = []for i in range(num): a.append(i * 2)

2011年7月30日土曜日

Page 19: Pysap#3.1 Pythonでショートコーディング

いくつも道がある!

19

2011年7月30日土曜日

Page 20: Pysap#3.1 Pythonでショートコーディング

いくつでも抜け道がある!

20

2011年7月30日土曜日

Page 21: Pysap#3.1 Pythonでショートコーディング

3目並べ

21

2011年7月30日土曜日

Page 22: Pysap#3.1 Pythonでショートコーディング

3目並べ

22

• 別称:OXゲーム

• 基礎プログラミングの集大成

• ループ文

• 条件分岐

• 入出力処理

2011年7月30日土曜日

Page 23: Pysap#3.1 Pythonでショートコーディング

3目並べの流れ

23

• フィールド初期化• フィールド表示• 座標入力• マスにマーク(O or X)が置けるか• 縦横斜に同じマークが3つ並んでるか• 余白はまだあるか• 次ターンに移行• ゲームの結果を表示

{ここでル|プ

2011年7月30日土曜日

Page 24: Pysap#3.1 Pythonでショートコーディング

3目並べの流れ

24

• フィールド初期化• フィールド表示• 座標入力• マスにマーク(O or X)が置けるか• 縦横斜に同じマークが3つ並んでるか• 余白はまだあるか• 次ターンに移行• ゲームの結果を表示

{ここでル|プ

2011年7月30日土曜日

Page 25: Pysap#3.1 Pythonでショートコーディング

フィールドの初期化

25

2011年7月30日土曜日

Page 26: Pysap#3.1 Pythonでショートコーディング

フィールドの初期化

26

• フィールドをリストで管理

• 1次元、2次元を使用するのは個々人の好みが分れる

• フィールドの中で管理するのは数字か?文字か?

2011年7月30日土曜日

Page 27: Pysap#3.1 Pythonでショートコーディング

フィールドの初期化

27

• フィールドをリストで管理

• 1次元、2次元を使用するのは個々人の好みが分れる

‣ 私は1次元での管理が好き

• フィールドの中で管理するのは数字か?文字か?

2011年7月30日土曜日

Page 28: Pysap#3.1 Pythonでショートコーディング

フィールドの初期化

28

• フィールドをリストで管理

• 1次元、2次元を使用するのは個々人の好みが分れる

‣ 私は1次元での管理が好き

• フィールドの中で管理する値は数値か?文字か?

‣ 数値を使用することが多いが、今回は文字を使用

2011年7月30日土曜日

Page 29: Pysap#3.1 Pythonでショートコーディング

フィールドの初期化

29

• field = []for i in range(9): field.append(‘_‘)

2011年7月30日土曜日

Page 30: Pysap#3.1 Pythonでショートコーディング

フィールドの初期化

30

• field = []for i in range(9): field.append(‘_‘)

• field = [‘_‘ for i in range(9)]

2011年7月30日土曜日

Page 31: Pysap#3.1 Pythonでショートコーディング

フィールドの初期化

31

• field = []for i in range(9): field.append(‘_‘)

• field = [‘_‘ for i in range(9)]

• field = [‘_‘] * 9

2011年7月30日土曜日

Page 32: Pysap#3.1 Pythonでショートコーディング

3目並べの流れ

32

• フィールド初期化• フィールド表示• 座標入力• マスにマーク(O or X)が置けるか• 縦横斜に同じマークが3つ並んでるか• 余白はまだあるか• 次ターンに移行• ゲームの結果を表示

{ここでル|プ

2011年7月30日土曜日

Page 33: Pysap#3.1 Pythonでショートコーディング

フィールドの表示

33

2011年7月30日土曜日

Page 34: Pysap#3.1 Pythonでショートコーディング

フィールドの表示

34

• 現在の3x3のフィールド

• O or Xのターン表示

‣1と−1で管理する

2011年7月30日土曜日

Page 35: Pysap#3.1 Pythonでショートコーディング

フィールドの表示

35

• turn = 1for x range(3): for y range(3): print field[x + y * 3], print ‘’if turn == 1: print ‘o turn’else : print ‘x turn’

2011年7月30日土曜日

Page 36: Pysap#3.1 Pythonでショートコーディング

フィールドの表示

36

• turn = 1for x range(3): for y range(3): print field[x + y * 3], print ‘’if turn == 1: print ‘o turn’else : print ‘x turn’

2011年7月30日土曜日

Page 37: Pysap#3.1 Pythonでショートコーディング

フィールドの表示

37

• turn = 1print “%s%s%s¥n%s%s%s¥n%s%s%s” % tuple(field)if turn == 1: print ‘o turn’else : print ‘x turn’

2011年7月30日土曜日

Page 38: Pysap#3.1 Pythonでショートコーディング

フィールドの表示

38

• turn = 1print “%s%s%s¥n%s%s%s¥n%s%s%s” % tuple(field)if turn == 1: print ‘o turn’else : print ‘x turn’

2011年7月30日土曜日

Page 39: Pysap#3.1 Pythonでショートコーディング

フィールドの表示

39

• turn = 1print “%s%s%s¥n%s%s%s¥n%s%s%s” % tuple(field)marks = ‘_ox’print ‘%s turn’ % marks[turn]

✴marks[1] == ‘o’

✴marks[-1] == marks[2] == ‘x’

2011年7月30日土曜日

Page 40: Pysap#3.1 Pythonでショートコーディング

3目並べの流れ

40

• フィールド初期化• フィールド表示• 座標入力• マスにマーク(O or X)が置けるか• 縦横斜に同じマークが3つ並んでるか• 余白はまだあるか• 次ターンに移行• ゲームの結果を表示

{ここでル|プ

2011年7月30日土曜日

Page 41: Pysap#3.1 Pythonでショートコーディング

座標入力

41

2011年7月30日土曜日

Page 42: Pysap#3.1 Pythonでショートコーディング

座標入力

42

• raw_inputでOK

• intにコンバートする必要あり

• エラー処理をどうするか

• 値範囲のチェック(0<=x<=2、 0<=y<=2)

2011年7月30日土曜日

Page 43: Pysap#3.1 Pythonでショートコーディング

座標入力

43

• while(True): try: x = int(raw_input(‘x(0-2) -> ‘)) y = int(raw_input(‘y(0-2) -> ‘)) except: continue if 0 <= x <= 2 and 0 <= y <= 2: break

2011年7月30日土曜日

Page 44: Pysap#3.1 Pythonでショートコーディング

座標入力

44

• while(True): try: x = int(raw_input(‘x(0-2) -> ‘)) y = int(raw_input(‘y(0-2) -> ‘)) except: continue if 0 <= x <= 2 and 0 <= y <= 2: break

2011年7月30日土曜日

Page 45: Pysap#3.1 Pythonでショートコーディング

座標入力

45

• while(True): inp = lambda n: raw_input(‘%s(0-2) -> ‘%n) x, y = inp(‘x’), inp(‘y’) try: x = int(x) y = int(y) except: continue vr = lambda n: 0 <= n <= 2 if vr(x) and vr(y): break

2011年7月30日土曜日

Page 46: Pysap#3.1 Pythonでショートコーディング

座標入力

46

• while(True): inp = lambda n: raw_input(‘%s(0-2) -> ‘%n) x, y = inp(‘x’), inp(‘y’) vr = lambda n: 0 <= n <= 2 if vr(x) and vr(y): break try: x = int(x) y = int(y) except: continue

2011年7月30日土曜日

Page 47: Pysap#3.1 Pythonでショートコーディング

座標入力

47

• while(True): inp = lambda n: raw_input(‘%s(0-2) -> ‘%n) x, y = inp(‘x’), inp(‘y’) vr = lambda n: len(n)==1 and ‘0’ <= n <= ‘2’ if vr(x) and vr(y): breaktry: x = int(x) y = int(y)except: continue

2011年7月30日土曜日

Page 48: Pysap#3.1 Pythonでショートコーディング

座標入力

48

• while(True): inp = lambda n: raw_input(‘%s(0-2) -> ‘%n) x, y = inp(‘x’), inp(‘y’) vr = lambda n: len(n)==1 and ‘0’ <= n <= ‘2’ if vr(x) and vr(y): breaktry: x = int(x) y = int(y)except: continue

2011年7月30日土曜日

Page 49: Pysap#3.1 Pythonでショートコーディング

座標入力

49

• while(True): inp = lambda n: raw_input(‘%s(0-2) -> ‘%n) x, y = inp(‘x’), inp(‘y’) vr = lambda n: len(n)==1 and ‘0’ <= n <= ‘2’ if vr(x) and vr(y): breakx, y = int(x), int(y)

2011年7月30日土曜日

Page 50: Pysap#3.1 Pythonでショートコーディング

座標入力

50

• inp = lambda n: raw_input(‘%s(0-2) -> ‘%n)vr = lambda n: len(n)==1 and ‘0’ <= n <= ‘2’while(True): x, y = inp(‘x’), inp(‘y’) if vr(x) and vr(y): breakx, y = int(x), int(y)

2011年7月30日土曜日

Page 51: Pysap#3.1 Pythonでショートコーディング

座標入力

51

• while(True): try: x = int(raw_input(‘x(0-2) -> ‘)) y = int(raw_input(‘y(0-2) -> ‘)) except: continue if 0 <= x <= 2 and 0 <= y <= 2: break

2011年7月30日土曜日

Page 52: Pysap#3.1 Pythonでショートコーディング

座標入力

52

• inp = lambda n: raw_input(‘%s(0-2) -> ‘%n)vr = lambda n: len(n)==1 and ‘0’ <= n <= ‘2’while(True): x, y = inp(‘x’), inp(‘y’) if vr(x) and vr(y): breakx, y = int(x), int(y)

2011年7月30日土曜日

Page 53: Pysap#3.1 Pythonでショートコーディング

3目並べの流れ

53

• フィールド初期化• フィールド表示• 座標入力• マスにマーク(O or X)が置けるか• 縦横斜に同じマークが3つ並んでるか• 余白はまだあるか• 次ターンに移行• ゲームの結果を表示

{ここでル|プ

2011年7月30日土曜日

Page 54: Pysap#3.1 Pythonでショートコーディング

マスにマーク(O or X)が置けるか

54

2011年7月30日土曜日

Page 55: Pysap#3.1 Pythonでショートコーディング

マスのチェック

55

• 指定した座標に空白があるかどうか

• すでに置かれていたら座標入力からやり直す

2011年7月30日土曜日

Page 56: Pysap#3.1 Pythonでショートコーディング

マスのチェック

56

• if field[x + y * 3] != ‘_’: continue

2011年7月30日土曜日

Page 57: Pysap#3.1 Pythonでショートコーディング

マスのチェック

57

• if field[x + y * 3] != ‘_’: continue

• フィールドは各一文字なのでif field[x + y * 3] - ‘_’: continueとか、出来ますが、この辺は最後のチューニングで

2011年7月30日土曜日

Page 58: Pysap#3.1 Pythonでショートコーディング

マスのチェック

58

• if field[x + y * 3] != ‘_’: continue

• フィールドは各一文字なのでif field[x + y * 3] - ‘_’: continueとか、出来ますが、この辺は最後のチューニングで

• 短くなる方法募集!

2011年7月30日土曜日

Page 59: Pysap#3.1 Pythonでショートコーディング

3目並べの流れ

59

• フィールド初期化• フィールド表示• 座標入力• マスにマーク(O or X)が置けるか• 縦横斜に同じマークが3つ並んでるか• 余白はまだあるか• 次ターンに移行• ゲームの結果を表示

{ここでル|プ

2011年7月30日土曜日

Page 60: Pysap#3.1 Pythonでショートコーディング

勝利判定

60

2011年7月30日土曜日

Page 61: Pysap#3.1 Pythonでショートコーディング

勝利判定

61

• 8ラインの3要素ずつ比較する

• すべての値が同一場合、置いた人の勝利(スペースは除く)

2011年7月30日土曜日

Page 62: Pysap#3.1 Pythonでショートコーディング

勝利判定

62

• 8ラインの3要素ずつ比較する

• すべての値が同一場合、置いた人の勝利(スペースは除く)

• 勝利判定を制するコードゴルファーは、OXゲームを制す

2011年7月30日土曜日

Page 63: Pysap#3.1 Pythonでショートコーディング

なぜ難しい?

63

• ループで回すのが難しい

0 1 2

3 4 5

6 7 8

0,1,23,4,56,7,80,3,61,4,72,5,80,4,82,4,6

2011年7月30日土曜日

Page 64: Pysap#3.1 Pythonでショートコーディング

なぜ難しい?

64

• ループで回すのが難しい

0 1 2

3 4 5

6 7 8

0,1,23,4,56,7,80,3,61,4,72,5,80,4,82,4,6

n,n+1,n+2

n,n+3,n+6

????

2011年7月30日土曜日

Page 65: Pysap#3.1 Pythonでショートコーディング

なぜ難しい?

65

• ループで回すのが難しい

0 1 2

3 4 5

6 7 8

0,1,23,4,56,7,80,3,61,4,72,5,80,4,82,4,6

n,n+1,n+2

n,n+3,n+6

????

わからん!

2011年7月30日土曜日

Page 66: Pysap#3.1 Pythonでショートコーディング

なぜ難しい?

66

• ループで回すのが難しい

0 1 2

3 4 5

6 7 8

0,4,81,4,72,4,63,4,50,1,26,7,80,3,62,5,8

n,4,8-n

n,n+1,n+2

n,n+3,n+6

2011年7月30日土曜日

Page 67: Pysap#3.1 Pythonでショートコーディング

なぜ難しい?

67

• ループで回すのが難しい

0 1 2

3 4 5

6 7 8

0,4,81,4,72,4,63,4,50,1,26,7,80,3,62,5,8

n,4,8-n

n,n+1,n+2

n,n+3,n+6

要素数が合わない!

2011年7月30日土曜日

Page 68: Pysap#3.1 Pythonでショートコーディング

解決策

68

• 調べるラインを増やす(重複部分をつくる)

0 1 2

3 4 5

6 7 8

0,4,81,4,72,4,60,1,23,4,56,7,80,3,61,4,72,5,8

n,4,8-n

n,n+1,n+2

n,n+3,n+6

2011年7月30日土曜日

Page 69: Pysap#3.1 Pythonでショートコーディング

勝利判定

69

• for i in range(3): if (field[i] != ‘_’ and field[i] == field[i + 1] and field[i] == field[i + 2]): judge = True if (field[4] != ‘_’ and field[4] == field[i] and field[4] == field[8 - i]): judge = True...

2011年7月30日土曜日

Page 70: Pysap#3.1 Pythonでショートコーディング

勝利判定

70

• for i in range(3): if (field[i] != ‘_’ and field[i] == field[i + 1] and field[i] == field[i + 2]): judge = True if (field[4] != ‘_’ and field[4] == field[i] and field[4] == field[8 - i]): judge = True...

2011年7月30日土曜日

Page 71: Pysap#3.1 Pythonでショートコーディング

勝利判定

71

• mark = ‘ ox’[turn]for i in range(3): if [mark]*3 == [field[i], field[i+1],field[i+2]]: judge = True if [mark]*3 == [field[i],field[4],field[8-i]]: judge = True if [mark]*3 == [field[i], field[i+3],field[i+6]]: judge = True...

2011年7月30日土曜日

Page 72: Pysap#3.1 Pythonでショートコーディング

勝利判定

72

• mark = ‘ ox’[turn]jl = lambda line: [mark]*3 == linefor i in range(3): if jl([field[i], field[i+1],field[i+2]]): judge = True if jl([field[i],field[4],field[8-i]]): judge = True if jl([field[i], field[i+3],field[i+6]]): judge = True...

2011年7月30日土曜日

Page 73: Pysap#3.1 Pythonでショートコーディング

勝利判定

73

• mark = ‘ ox’[turn]jl = lambda line: [mark]*3 == linefor i in range(3): if jl([field[i], field[i+1],field[i+2]]): judge = True if jl([field[i],field[4],field[8-i]]): judge = True if jl([field[i], field[i+3],field[i+6]]): judge = True...

2011年7月30日土曜日

Page 74: Pysap#3.1 Pythonでショートコーディング

勝利判定

74

• mark = ‘ ox’[turn]jl = lambda line: [mark]*3 == linefor i in range(3): if jl(field[i*3:i*3+3]): judge = True if jl(field[i:9-i:4-i]): judge = True if jl(field[i::3]): judge = True

2011年7月30日土曜日

Page 75: Pysap#3.1 Pythonでショートコーディング

勝利判定

75

• mark = ‘ ox’[turn]jl = lambda line: [mark]*3 == linejudge = Falsefor i in range(3): judge = judge or jl(field[i*3:i*3+3]) judge = judge or jl(field[i:9-i:4-i]) judge = judge or jl(field[i::3])

2011年7月30日土曜日

Page 76: Pysap#3.1 Pythonでショートコーディング

3目並べの流れ

76

• フィールド初期化• フィールド表示• 座標入力• マスにマーク(O or X)が置けるか• 縦横斜に同じマークが3つ並んでるか• 余白はまだあるか• 次ターンに移行• ゲームの結果を表示

{ここでル|プ

2011年7月30日土曜日

Page 77: Pysap#3.1 Pythonでショートコーディング

余白の判定

77

2011年7月30日土曜日

Page 78: Pysap#3.1 Pythonでショートコーディング

余白の判定

78

• for 文で回して、if 文で空白を見つけたら、ループを抜ける

2011年7月30日土曜日

Page 79: Pysap#3.1 Pythonでショートコーディング

余白の判定

79

• for 文で回して、if 文で空白を見つけたら、ループを抜ける

• とかやっちゃうと、駆け出しPythonista

ということが。。。

2011年7月30日土曜日

Page 80: Pysap#3.1 Pythonでショートコーディング

余白の判定

80

• space_flag = Falsefor val in field: if val == ‘_’: space_flag = Trueif not space_flag: break

2011年7月30日土曜日

Page 81: Pysap#3.1 Pythonでショートコーディング

余白の判定

81

• space_flag = Falsefor val in field: if val == ‘_’: space_flag = Trueif not space_flag: break

2011年7月30日土曜日

Page 82: Pysap#3.1 Pythonでショートコーディング

余白の判定

82

• space_flag = Falsefor val in field: if val == ‘_’: space_flag = Trueif not space_flag: break

• if not ‘_’ in field: break

2011年7月30日土曜日

Page 83: Pysap#3.1 Pythonでショートコーディング

ターンの移行

83

2011年7月30日土曜日

Page 84: Pysap#3.1 Pythonでショートコーディング

ターンの移行

84

• ここはマスの空白判定同様書くことがない

• 数字(1,ー1)でターン保持

‣ turn*=-1

‣ turn=-turn

2011年7月30日土曜日

Page 85: Pysap#3.1 Pythonでショートコーディング

ターンの移行

85

• ここはマスの判定同様書きようがない

• 数字(1,ー1)でターン保持

‣ turn*=-1

‣ turn=-turn

‣ t*=-1

‣ t=-t

2011年7月30日土曜日

Page 86: Pysap#3.1 Pythonでショートコーディング

ゲームの結果表示

86

2011年7月30日土曜日

Page 87: Pysap#3.1 Pythonでショートコーディング

ゲームの結果表示

87

• judgeのフラグで引き分けかそれ以外かを見極める

• 勝敗判定時に使ったmarkを使うと良い

2011年7月30日土曜日

Page 88: Pysap#3.1 Pythonでショートコーディング

ゲームの結果表示

88

• if judge: print ‘%s win’ % markelse: print ‘draw’

2011年7月30日土曜日

Page 89: Pysap#3.1 Pythonでショートコーディング

ゲームの結果表示

89

• if judge: print ‘%s win’ % markelse: print ‘draw’

• print (‘%s win’ % mark) if judge else ‘draw’

2011年7月30日土曜日

Page 90: Pysap#3.1 Pythonでショートコーディング

短くなったソース

90

• まずはじめに、Pythonの基本機能をそれほど使って無いソースを見てみましょう。

2011年7月30日土曜日

Page 91: Pysap#3.1 Pythonでショートコーディング

短くなったソース

91

• まずはじめに、Pythonの基本機能をそれほど使って無いソースを見てみましょう。

• 次に、これらのコーディングを駆使したソースコードを見てみましょう。

2011年7月30日土曜日

Page 92: Pysap#3.1 Pythonでショートコーディング

短くなったソース

92

• まずはじめに、Pythonの基本機能をそれほど使って無いソースを見てみましょう。

• 次に、これらのコーディングを駆使したソースコードを見てみましょう。

• さぁ、これで君も立派なコードゴルファーだ

2011年7月30日土曜日

Page 93: Pysap#3.1 Pythonでショートコーディング

Fin

93

2011年7月30日土曜日