ズンドコで勉強する

# むしゃくしゃしてやった

```py3:zun.py
import random
def r(a, b):
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
try:
    r(4, 0)
except:
    print('キ・ヨ・シ！')
```
これで所期の結果が得られますが、exceptをfinallyにするとどうなるかというと。

```py3:zun_2.py
import random
def r(a, b):
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
try:
    r(4, 0)
finally:
    print('キ・ヨ・シ！')
```

```text:finallyにしたときのメッセージ
ズン
ドコ
ズン
ズン
ズン
ズン
ドコ
キ・ヨ・シ！
Traceback (most recent call last):
  File "zun_2.py", line 5, in <module>
    r(4, 0)
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
ZeroDivisionError: division by zero
```
これはちょっと馬鹿っぽい。。。
lambdaでやってもかわらない。

```py3:zun_2.py
import random
r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
try:
    r(4, 0)
finally:
    print('キ・ヨ・シ！')
```

```text:結果の一部
Traceback (most recent call last):
  File "zun_2.py", line 4, in <module>
    r(4, 0)
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
ZeroDivisionError: division by zero
```
うーむ。。。
そういえば無名関数の再帰かけないのかなーと思って
http://fj.hatenablog.jp/entry/2014/06/15/032135
みたいな話を見かけたりしたが、性能は良くないらしい。

色々と綺麗にしたバージョン：

```py3:zun_3.py
import random
r=lambda a: print('ズン') or r(a-1) if random.random() < 0.5 else print('ドコ') or a <= 0 or r(4)
r(4) or print('キ・ヨ・シ！')
```
これは<=を==にすると、ちょうどズンが４つの場合以外はスルーするすぐれもの。５つ以上のズンを認めてよいかどうか、という議論はあってしかるべき。