The anime kid
The anime kid

Reputation: 1

probability of getting ace of hearts and ace of spades by drawing five cards

So I am new to python and trying to do some exercises to learn. my goal is to simulate a person drawing five cards and getting both the ace of hearts and spades at once, e.g (1,h),(5,s),(7,d),(1,s),(10,c). Before doing the simulation i calculated that it should be around 0.0075 (C(50,3)/C(52,5))

When i simulate it i get around 0.0081 ~ 0.0092, is my math off or is my code wrong? also is there a way to make my code more compact?

Code:

from random import *
from itertools import *
#generating  deck
suits = ["s","d","h","c"]
values = ["1","2","3","4","5","6","7","8","9","10","11","12"]
deck = [i for i in product(values,suits)]
sim = 100000

aces = 0
for i in range(sim):
  aceHeart = False
  aceSpades = False
  shuffle(deck)
  #generating hand
  hand = sample(deck,5)
  #checking for aces
  for i in range(5):
    if hand[i] == ("1","h"):
      aceHeart = True
    elif hand[i] == ("1","s"):
      aceSpades = True
  if aceHeart == True and aceSpades == True:
    aces +=1
probaces = aces/sim
print(probaces)

Upvotes: 0

Views: 736

Answers (3)

user2668284
user2668284

Reputation:

If you want a simulator rather than just doing the math, you could do this:

import random

N = 1_000_000
AceHearts = 1
AceSpades = 14

count = 0
for _ in range(N):
    s = set()
    while len(s) < 5:
        s.add(random.randint(1, 52))
    if AceHearts in s and AceSpades in s:
        count += 1
print(count/N)

Note that the values assigned to AceHearts and AceSpades are arbitrary. They just need to be different and in the inclusive range 1->52

Upvotes: 1

Omar Aflak
Omar Aflak

Reputation: 2962

To complete @mozway's answer, here is a more readable code in my opinion:

from itertools import product
from random import shuffle, sample

suits = ["s","d","h","c"]
values = ["1","2","3","4","5","6","7","8","9","10","11","12"]
deck = list(product(values, suits))
sim = 100000

aces = 0
for i in range(sim):
  shuffle(deck)
  hand = sample(deck, 5)
  if ("1", "h") in hand and ("1", "s") in hand:
      aces += 1

probaces = aces / sim
print(probaces)
  • Avoid import * statements
  • Use list(iterator) in general if you need the values beforehand
  • Use in operator to check if items exist in a container
  • Also, Python is snake_cased

Upvotes: 0

mozway
mozway

Reputation: 262114

As you draw 5 cards, you have 5/48 chances to get the first Ace, then 4/48 chances for the second in the remaining 4 cards.

The probability is 5/48*4/48 -> ~0.00868, which is a correct range for your output. You could calculate a confidence interval for 100000 runs ;)

A few things to improve in your code:

deck = [i for i in product(values,suits)] -> deck = list(product(values,suits))

if aceHeart == True and aceSpades == True: -> if aceHeart and aceSpades:

No need to import everything from the modules:

from random import *
from itertools import *
from random import sample, shuffle
from itertools import product

Upvotes: 2

Related Questions