A yield
kulcsszó a return
-höz hasonló, kivéve hogy a létrehozott objektum nem függvény, hanem generátor. Ha meghívjuk, a generátorfüggvény kódja nem fut le, csak visszaad egy generátor objektumot, ami iterálható. Az első iterációnál a kód elejétől lefut az első yield
-ig, és visszaadja az abban megadott értéket. A következő ciklusban innen folytatja a futást egészen a következő yield
-ig, és egészen addig folytatódik így, amíg már nem talál több yield
-et. (yield = hozadék)
# A generator function that yields four values
def generator1():
yield 2
yield 3
yield 5
yield 7
# Iterate by the above generator function
for prime in generator1():
print(prime, end=" ")
2 3 5 7
def generator2():
for i in range(4):
yield i*i
print(generator2()) # does not give a value back
for s in generator2():
print(s, end=" ")
<generator object generator2 at 0x7f89dde90e40> 0 1 4 9
Legyen $X$ egy diszkrét valószínűségi változó. Az $X$ várható értékén az $$ \mathbb{E}[X]=\sum\limits_{x\in X}{x\mathop{\mathbb{P}}(X=x)}. $$ értéket értjük.
Példa: Számítsuk ki két kockadobás összegének várható értékét!
ev = 0
for i in range(1,7):
for j in range(1,7):
ev = ev + i + j
ev = ev/36
print(ev)
7.0
Mennyi a tapasztalati várható érték, azaz az átlag? Pl. 1000 kísérletből?
from random import randint
ev = 0
n = 1000
for _ in range(n):
i, j = randint(1,6), randint(1,6)
ev = ev + i + j
ev = ev/n
print(ev)
7.053
attacker = [randint(1, 6) for _ in range(3)]
defender = [randint(1, 6) for _ in range(2)]
attacker
[6, 2, 6]
attacker.sort(reverse=True)
defender.sort(reverse=True)
attacker, defender
([6, 6, 2], [4, 4])
if attacker[0] > defender[0]:
# attacker wins
print("A")
else:
# defender wins
print("D")
A
# to counting probablity
attackers = [[i, j, k] for i in range(1,7) for j in range(1,7) for k in range(1,7)]
defenders = [[i, j] for i in range(1,7) for j in range(1,7)]
# or another possibility
from itertools import product
dice = range(1, 7)
attackers = product(dice, dice, dice)
defenders = product(dice, dice)
from random import randint
def gen_rand(n):
'''
Generátor n véletlen csatához.
'''
for _ in range(n):
attacker = [randint(1, 6) for _ in range(3)]
defender = [randint(1, 6) for _ in range(2)]
attacker.sort(reverse=True)
defender.sort(reverse=True)
yield attacker, defender
def gen_prob():
'''
Generátor az összes lehetséges csatához.
'''
attackers = [[i, j, k] for i in range(1,7) for j in range(1,7) for k in range(1,7)]
defenders = [[i, j] for i in range(1,7) for j in range(1,7)]
for x in attackers:
for y in defenders:
x.sort(reverse=True)
y.sort(reverse=True)
yield x, y
def evaluate(a, d):
'''
A támadó győzelmeinek száma. (2, 1 vagy 0)
a:: attacker
d:: defender
'''
att = 0
if a[0] > d[0]:
att += 1
if a[1] > d[1]:
att += 1
return att
def main():
'''
A győzelmek relatív gyakoriságának és
valószínűségének kiszámítása.
'''
n = [1000, 1000000, 6**5]
f = [gen_rand(n[0]), gen_rand(n[1]), gen_prob()]
t = [f"{n[0]} kísérlet", f"{n[1]} kísérlet", "valószínűség"]
for c in range(3):
c_at, c_dr, c_de = 0, 0, 0
for i in f[c]:
e = evaluate(*i)
if e == 2:
c_at += 1
elif e == 1:
c_dr += 1
else:
c_de += 1
print(f"{t[c]:<20}{c_at/n[c]:.5f} {c_dr/n[c]:.5f} {c_de/n[c]:.5f}")
if __name__ == "__main__":
main()
1000 kísérlet 0.37200 0.35700 0.27100
Egy kaszinó a következő játékot ajánlja: egy érmével addig dobunk, míg a fej oldalára nem esik. Ha ez az $n$-edik feldobáskor történik meg, akkor a játékos $2^n$ forintot nyer (ld. Wikipédia). Szimuláljunk $m$ játékot (azaz $m$ fej dobásig játszunk). Mennyi a nyeremény átlaga $m=100$, $m=10000$ és $m=1000000$ esetén?
A program kimenete e három átlag három tizedesjegy pontossággal megadva (3 tizedes a tizedespont után) és szóközzel elválasztva.
A feladat célja egy végtelen várható értékű valószínűségi változóval való tapasztalatszerzés. A kérdés az, hogy vajon mennyiért adjon egy ilyen játékot a kaszinó, hogy ne járjon rosszul (e kérdésre nem kell válaszolni).
A feladat a példatárban 3.21 sorszámmal szerepel.