いきなりコード
Bingo.py
# -*- coding: utf-8 -*-
u"""BINGO の確率をシミュレーションするスクリプト
input:
times = 抽選機を回す回数, card_num = カードの数
outpu:
1本でも揃う確率
"""
import sys
from random import sample
# 穴
HIT = True
NOHIT = False
def generate_card():
u"""カードを生成
5x5で中心(3行3列)に穴が空いたカード
B(1列目) 1 - 15
I(2列目) 16 - 30
N(3列目) 31 - 45
G(4列目) 46 - 60
O(5列目) 61 - 75
:returns: array card, length=25
"""
cards = []
for i in range(5):
cards.extend(sample(range(15 * i + 1, 15 * (i + 1)), 5))
cards[12] = HIT
return cards
def check_bingo(card):
u"""BINGOしているかどうか
判定のみかえす
param: array
:returns: boolean
"""
if card.count(HIT) < 5:
return False
for i in range(5):
if NOHIT not in card[i * 5: (i + 1) * 5]:
return True
for i in range(5):
if NOHIT not in card[i: i + 21: 5]:
return True
if NOHIT not in card[0: 24: 6]:
return True
if NOHIT not in card[4: 21: 4]:
return True
return False
def print_card(card):
for i, v in enumerate(card):
if v == HIT:
v = "o"
elif v == NOHIT:
v = "x"
sys.stdout.write("%3s" % str(v))
if (i % 5 == 4):
print()
print()
try:
times = int(sys.argv[1])
except IndexError:
times = 5
try:
card_num = int(sys.argv[2])
except IndexError:
card_num = 10000
hit_count = 0
for i in range(card_num):
card = generate_card()
lots = sample(range(1, 76), times)
card_hole = [(HIT if (x == HIT or x in lots) else NOHIT) for x in card]
# print_card(card)
# print_card(card_hole)
if check_bingo(card_hole):
hit_count += 1
print(str(times) + u"回目で1本でもBINGOしてる確率:")
p = hit_count / card_num
print("%s (%.1f %%)" % (str(p), p * 100))
Gist: https://gist.github.com/0c11f757334ba9ef7b1f
入力:
抽選機を回す回数
カードの数(シミュレーション回数)
output:
一本でもBINGOする確率
それぞれの関数の説明はコメントで大方わかるはず
- カードの生成
- 引かれたくじの一括生成
- カードに穴を開ける
- BINGO判定
のループ
Pythonらしい書き方が出来た部分
card(BINGOカード) について当たりが出ているかどうかを判定する部分がPythonらしい書き方が出来たと思う(ぶっちゃけここの処理を作ってみたかっただけ)
# 4列目の判定
NOHIT not in card[3:3 + 21:5]
# 左上から右下斜めの判定
NOHIT not in card[0:24:6]
Pythonの配列は array[start :end :step] で取り出せるのでスマートに判定が書ける
実行出力例
>> python3 bingo.py 5 10000
5回目で1本でもBINGOしてる確率:
0.0003 (0.0 %)
関係ないけど今回Pythonのコーディング規約として今回Flake8で覚えたこと
関数同士の間は2行開けないといけない
配列コロンの右側にスペースを入れてはいけない(引数のカンマと同じ)
docブロックの書き方がいまいちまだわからないので勉強していこうと思う