Histoire originale: [J'ai essayé de simuler la probabilité d'un jeu de bingo avec Python] (http://qiita.com/elzup/items/d532ffa1d326fbf75d01)
C'était intéressant à lire, donc je l'ai modifié un peu en regardant les manières de Python.
if __name__ == '__main__':
main()
J'aime faire * main () *, mais en séparant le traitement lorsqu'il est exécuté en tant que script, vous pouvez démarrer le shell interactif dans un autre terminal etc. et l'importer en tant que module et le déboguer. Pratique.
Par exemple, essayez de changer l'implémentation de * generate_card () *
def generate_card():
@@ -25,12 +33,22 @@
- cards = []
- for i in range(5):
- cards.extend(sample(range(15 * i + 1, 15 * (i + 1)), 5))
- cards[12] = HIT
- return cards
+ def sampling(k=5):
+ for i in range(k):
+ yield sample(range(15 * i + 1, 15 * (i + 1) + 1), k)
+
+ from itertools import chain
+ card = list(chain.from_iterable(sampling()))
+ card[12] = HIT
+ return card
Mesurez les performances avec ipython.
$ ipython3-3.4
In [1]: import orig_Bingo
In [2]: timeit -n 100 orig_Bingo.generate_card()
100 loops, best of 3: 86.4 us per loop
In [3]: import Bingo_kai
In [4]: timeit -n 100 Bingo_kai.generate_card()
100 loops, best of 3: 95.3 us per loop
Utilisez argparse pour gérer les arguments autant que * try ... sauf *. L'utilisation d'argparse est également standard, donc une fois que vous vous y êtes habitué, c'est facile. En passant, j'ai récemment vu des outils cli comme click et clip. Cependant, je ne comprends pas vraiment le but et la nécessité.
parser = argparse.ArgumentParser()
parser.set_defaults(num=10000, times=5, verbose=False)
parser.add_argument('-n', '--num', type=int, help='set card number')
parser.add_argument('-t', '--times', type=int, help='set times')
parser.add_argument(
'-v', '--verbose', action='store_true',
help='set verbose mode (loglevel=DEBUG)')
Depuis que j'ai essayé de traiter les arguments, j'essaierai de changer la sortie de débogage en utilisant la journalisation. L'utilisation du module de journalisation est également standard.
logger = getLogger(__name__)
_handler = StreamHandler()
_handler.setLevel(DEBUG)
logger.addHandler(_handler)
...
logger.setLevel(DEBUG)
En fait, je voulais juste dire ceci en réponse à la ↓ de l'article original.
Je ne sais toujours pas écrire un bloc doc, donc je vais étudier
L'une des fonctionnalités de Python est doctest. Si vous combinez le document sur l'utilisation de la fonction avec un test simple, il peut s'agir de deux oiseaux avec une pierre.
Si vous modifiez la logique du code original pour ne pas le gâcher, le doctest du code modifié n'est pas bon, mais si vous essayez de développer en écrivant le doctest, la perspective de la position à utiliser va s'étendre et la fonction sera facile à utiliser naturellement. Et des modules peuvent être mis en œuvre.
Post-scriptum: Je me suis vengé parce que ça n'a pas fonctionné => J'ai écrit un doctest dans "J'ai essayé de simuler la probabilité d'un jeu de bingo avec Python"
"""
>>> check_bingo([False, True, False])
False
>>> check_bingo([True] * 5)
True
>>> check_bingo([False, False, True, False, False] * 5)
True
>>> check_bingo([
... True, False, False, False, False,
... False, True, False, False, False,
... False, False, True, False, False,
... False, False, False, True, False,
... False, False, False, False, True,
... ])
True
"""
J'utilise * random.sample *, il est donc difficile d'écrire un test sans simuler ...: suer:
Quand je l'ai essayé, je ne pouvais pas le réparer si bien qu'il correspondait à ce que je voulais dire ...: déçu_relieved:
Ce code fonctionne sur Python3.
Bingo_kai.py
# -*- coding: utf-8 -*-
u"""Script qui simule la probabilité de BINGO
input:
times =Nombre de fois pour tourner la machine de loterie, card_num =Nombre de cartes
outpu:
Probabilité d'en avoir même un
"""
import argparse
import sys
from logging import DEBUG, StreamHandler, getLogger
from random import sample
#trou
HIT = True
NOHIT = False
#Sortie de journal
logger = getLogger(__name__)
_handler = StreamHandler()
_handler.setLevel(DEBUG)
logger.addHandler(_handler)
def generate_card():
u"""Générer une carte
Centre 5x5(3 lignes 3 colonnes)Carte avec un trou dans
B(1ère rangée) 1 - 15
I(2e rangée) 16 - 30
N(3e rangée) 31 - 45
G(4e rangée) 46 - 60
O(5e rangée) 61 - 75
:returns: array card, length=25
>>> from math import floor
>>> card = generate_card()
>>> card_len = len(card)
>>> card_len == 25
True
>>> card[floor(card_len / 2)]
True
"""
def sampling(k=5):
for i in range(k):
yield sample(range(15 * i + 1, 15 * (i + 1) + 1), k)
from itertools import chain
card = list(chain.from_iterable(sampling()))
card[12] = HIT
return card
def check_bingo(card):
u"""Que vous soyez BINGO
Jugement seulement
param: array
:returns: boolean
>>> check_bingo([False, True, False])
False
>>> check_bingo([True] * 5)
True
>>> check_bingo([False, False, True, False, False] * 5)
True
>>> check_bingo([
... True, False, False, False, False,
... False, True, False, False, False,
... False, False, True, False, False,
... False, False, False, True, False,
... False, False, False, False, True,
... ])
True
>>> check_bingo([
... False, False, False, False, True,
... False, False, False, True, False,
... False, False, True, False, False,
... False, True, False, False, False,
... True, False, False, False, False,
... ])
True
"""
if card.count(HIT) < 5:
return False
for i in range(5):
if all(card[i * 5:(i + 1) * 5]): # horizontal
return True
for i in range(5):
if all(card[i:i + 21:5]): # vertical
return True
if all(card[0:25:6]) or all(card[4:21:4]): # skew
return True
return False
def print_card(card):
msg = ''
for i, v in enumerate(card):
if v == HIT:
v = 'o'
elif v == NOHIT:
v = 'x'
msg += '%3s' % v
if i % 5 == 4:
msg += '\n'
logger.debug(msg)
def parse_argument(argv=None):
"""
>>> parse_argument([])
Namespace(num=10000, times=5, verbose=False)
>>> parse_argument(['-n', '3', '-t', '30', '-v'])
Namespace(num=3, times=30, verbose=True)
"""
parser = argparse.ArgumentParser()
parser.set_defaults(num=10000, times=5, verbose=False)
parser.add_argument('-n', '--num', type=int, help='set card number')
parser.add_argument('-t', '--times', type=int, help='set times')
parser.add_argument(
'-v', '--verbose', action='store_true',
help='set verbose mode (loglevel=DEBUG)')
args = parser.parse_args(sys.argv[1:] if argv is None else argv)
if args.verbose:
logger.setLevel(DEBUG)
return args
def do_bingo(args):
card = generate_card()
lots = dict(sample([(i, HIT) for i in range(1, 76)], args.times))
card_hole = [lots.get(i, NOHIT) for i in card]
logger.debug('lots: {}\n'.format(sorted(lots.keys())))
print_card(card)
print_card(card_hole)
return card_hole
def main():
args = parse_argument()
hit_count = 0
for i in range(args.num):
card_hole = do_bingo(args)
if check_bingo(card_hole):
hit_count += 1
print(str(args.times) + u"Probabilité d'un seul BINGO à la première fois:")
p = hit_count / args.num
print("%s (%.1f %%)" % (str(p), p * 100))
if __name__ == '__main__':
main()
Comme ça.
$ python Bingo_kai.py -n 3 -t 45 -v
...
lots: [1, 3, 8, 9, 10, 11, 12, 14, 16, 17, 19, 21, 22, 24, 26, 28, 29, 30,
31, 32, 33, 35, 36, 37, 39, 40, 41, 45, 46, 47, 49, 52, 55, 57, 60,
61, 63, 64, 67, 68, 69, 71, 72, 73, 75]
3 11 5 o 12
20 18 16 26 17
37 42 o 32 40
50 47 48 51 49
67 66 70 74 64
o o x o o
x x o o o
o x o o o
x o x x o
o x x x o
Probabilité d'un seul BINGO à la 45e fois:
0.6666666666666666 (66.7 %)