Originalgeschichte: [Ich habe versucht, die Wahrscheinlichkeit eines Bingospiels mit Python zu simulieren] (http://qiita.com/elzup/items/d532ffa1d326fbf75d01)
Es war interessant zu lesen, deshalb habe ich es ein wenig modifiziert, während ich mir Pythons Manieren angesehen habe.
if __name__ == '__main__':
main()
Ich mache gerne * main () *, aber indem Sie die Verarbeitung trennen, wenn sie als Skript ausgeführt wird, können Sie die interaktive Shell in einem anderen Terminal usw. starten und als Modul importieren und debuggen. Praktisch.
Versuchen Sie beispielsweise, die Implementierung von * generate_card () * zu ändern.
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
Messen Sie die Leistung mit 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
Verwenden Sie argparse, um Argumente so oft wie * try ... außer * zu verarbeiten. Die Verwendung von Argparse ist ebenfalls Standard. Wenn Sie sich erst einmal daran gewöhnt haben, ist dies ganz einfach. Nebenbei habe ich kürzlich Cli-Tools wie click und clip gesehen. Ich verstehe jedoch den Zweck und die Notwendigkeit nicht wirklich.
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)')
Da ich versucht habe, die Argumente zu verarbeiten, werde ich versuchen, die Debug-Ausgabe mithilfe der Protokollierung zu wechseln. Die Verwendung des Protokollierungsmoduls ist ebenfalls Standard.
logger = getLogger(__name__)
_handler = StreamHandler()
_handler.setLevel(DEBUG)
logger.addHandler(_handler)
...
logger.setLevel(DEBUG)
Eigentlich wollte ich das nur als Antwort auf das ↓ des Originalartikels sagen.
Ich weiß immer noch nicht, wie man einen Dokumentblock schreibt, also werde ich lernen
Eine der Funktionen von Python ist doctest. Wenn Sie das Dokument zur Verwendung der Funktion mit einem einfachen Test kombinieren, können es zwei Fliegen mit einer Klappe sein.
Wenn Sie die Logik des ursprünglichen Codes so ändern, dass Sie sich nicht damit anlegen, ist die Prüfung des geänderten Codes nicht gut. Wenn Sie jedoch versuchen, sich beim Schreiben der Prüfung zu entwickeln, wird die Perspektive der zu verwendenden Position erweitert und die Funktion ist auf natürliche Weise einfach zu verwenden Und Module können implementiert werden.
Nachtrag: Ich habe mich gerächt, weil es nicht funktioniert hat => Ich schrieb einen Test in "Ich habe versucht, die Wahrscheinlichkeit eines Bingospiels mit Python zu simulieren"
"""
>>> 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
"""
Ich benutze * random.sample *, daher ist es schwierig, einen Test ohne Mock zu schreiben ...: Schweiß:
Als ich es versuchte, konnte ich es nicht so gut reparieren, dass es zu dem passte, was ich sagen wollte ...: enttäuscht_relieved:
Dieser Code läuft auf Python3.
Bingo_kai.py
# -*- coding: utf-8 -*-
u"""Skript, das die Wahrscheinlichkeit von BINGO simuliert
input:
times =Häufigkeit, mit der der Lotteriemaschine gedreht wird, card_num =Anzahl der Karten
outpu:
Wahrscheinlichkeit, auch nur einen zu bekommen
"""
import argparse
import sys
from logging import DEBUG, StreamHandler, getLogger
from random import sample
#Loch
HIT = True
NOHIT = False
#Protokollausgabe
logger = getLogger(__name__)
_handler = StreamHandler()
_handler.setLevel(DEBUG)
logger.addHandler(_handler)
def generate_card():
u"""Karte generieren
5x5 Mitte(3 Zeilen 3 Spalten)Karte mit einem Loch in
B(1. Reihe) 1 - 15
I(2. Reihe) 16 - 30
N(3. Reihe) 31 - 45
G(4. Reihe) 46 - 60
O(5. Reihe) 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"""Ob Sie BINGO sind
Nur Urteil
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"Wahrscheinlichkeit von nur einem BINGO beim ersten Mal:")
p = hit_count / args.num
print("%s (%.1f %%)" % (str(p), p * 100))
if __name__ == '__main__':
main()
So was.
$ 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
Wahrscheinlichkeit von nur einem BINGO zum 45. Mal:
0.6666666666666666 (66.7 %)
Recommended Posts