J'ai essayé de corriger "J'ai essayé la simulation probabiliste du jeu de bingo avec Python"

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.

Faire le processus principal

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

Traitement d'argument avec argparse

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)

Ecrire un doctest

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:

Code modifié

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 %)

Recommended Posts

J'ai essayé de corriger "J'ai essayé la simulation probabiliste du jeu de bingo avec Python"
J'ai essayé de simuler la probabilité d'un jeu de bingo avec Python
J'ai écrit un doctest dans "J'ai essayé de simuler la probabilité d'un jeu de bingo avec Python"
J'ai essayé de trouver l'entropie de l'image avec python
J'ai essayé d'implémenter le blackjack du jeu Trump en Python
J'ai essayé de créer une liste de nombres premiers avec python
J'ai essayé d'améliorer l'efficacité du travail quotidien avec Python
J'ai essayé de collecter automatiquement des images de Kanna Hashimoto avec Python! !!
J'ai essayé des centaines de millions de SQLite avec python
J'ai essayé d'obtenir des données CloudWatch avec Python
J'ai essayé de sortir LLVM IR avec Python
J'ai essayé d'automatiser la fabrication des sushis avec python
J'ai essayé d'obtenir le code d'authentification de l'API Qiita avec Python.
J'ai essayé de rationaliser le rôle standard des nouveaux employés avec Python
J'ai essayé d'obtenir les informations sur le film de l'API TMDb avec Python
J'ai essayé d'implémenter le jeu de cartes de Trump en Python
J'ai essayé fp-growth avec python
J'ai essayé de gratter avec Python
J'ai essayé d'extraire des fonctionnalités avec SIFT d'OpenCV
J'ai essayé de résumer comment utiliser matplotlib de python
J'ai fait une application d'envoi de courrier simple avec tkinter de Python
J'ai essayé d'implémenter Mine Sweeper sur un terminal avec python
J'ai essayé de démarrer avec le script python de blender_Part 01
J'ai essayé de toucher un fichier CSV avec Python
J'ai essayé de résoudre Soma Cube avec python
J'ai essayé de démarrer avec le script python de blender_Partie 02
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé de visualiser facilement les tweets de JAWS DAYS 2017 avec Python + ELK
J'ai essayé de résoudre le problème avec Python Vol.1
J'ai essayé gRPC avec Python
J'ai essayé de gratter avec du python
[Python] J'ai essayé d'obtenir Json de squid ring 2
J'ai essayé la "conversion de morphologie" de l'image avec Python + OpenCV
J'ai essayé d'envoyer automatiquement la littérature du nouveau virus corona à LINE avec Python
J'ai essayé de résumer les opérations de chaîne de Python
J'ai essayé de résoudre la théorie des nombres entiers d'AOJ avec Python
J'ai essayé d'automatiser la mise à jour de l'article du blog Livedoor avec Python et sélénium.
[Python] J'ai essayé de créer automatiquement un rapport quotidien de YWT avec la messagerie Outlook
J'ai essayé de visualiser les données de course du jeu de course (Assetto Corsa) avec Plotly
J'ai essayé de comparer la vitesse de traitement avec dplyr de R et pandas de Python
Le 15e temps réel hors ligne, j'ai essayé de résoudre le problème de l'écriture avec python
J'ai essayé la "correction gamma" de l'image avec Python + OpenCV
J'ai essayé de simuler la propagation de l'infection avec Python
Je souhaite spécifier une autre version de Python avec pyvenv
J'ai essayé de trouver la moyenne de plusieurs colonnes avec TensorFlow
J'ai essayé différentes méthodes pour envoyer du courrier japonais avec Python
J'ai essayé d'exécuter Movidius NCS avec python de Raspberry Pi3
[Python] J'ai essayé de visualiser des tweets sur Corona avec WordCloud
[Python] J'ai essayé de visualiser la relation de suivi de Twitter
Mayungo's Python Learning Episode 3: J'ai essayé d'imprimer des nombres
J'ai essayé d'implémenter ListNet d'apprentissage de rang avec Chainer
J'ai essayé de créer une interface graphique à trois yeux côte à côte avec Python et Tkinter
J'ai essayé de toucher Python (installation)
J'ai essayé webScraping avec python.
Jeu de vie avec Python! (Le jeu de la vie de Conway)
Je veux déboguer avec Python