# Wrong result when solving: “chance that two random cards differ in color and value?”

I'm trying to build a simulation for this question:

"There are 50 cards of 5 different colors. Each color has cards numbered between 1 to 10. You pick 2 cards at random. What is the probability that they are not of same color and also not of same number?"

(From Glassdoor)

I should have a result like "73%" but with my code I get (consistently) "72%" or "71.8%".

Here is my code:

import numpy as np

# Building a deck of 10 cards for each of the 5 colors
cards = np.array([c+str(n) for c in ("A", "B", "C", "D", "E") for n in range(1, 11)])

def random_cards_differ():
"""Returns True if two random cards differ"""
a, b = np.random.choice(cards, 2, replace=False)
if a[0] != b[0] and a[1] != b[1]:
return True
else:
return False

nb_success = 0
nb_tries = 100000

for i in range(nb_tries):
if random_cards_differ():
nb_success += 1

print(nb_success / nb_tries)
>>> 0.71892


Is this normal? Is there a mistake in my code or is it a "random gotcha" caused by some seed or something else?

• your code seems fine, the theoretical result 73% is supposed to be accurately reached when numtrials -> infinity, so you get pretty good results. Try running whole simulation 100 times (so 100 * 100000 draws) and get average of 100 simulations this is better estimator – Nikos M. Jul 28 '20 at 13:29
• Well I ran a lot of simulations and got the same result. If I got 72% then 74% I would not suspect a problem, but consistently getting 71.8% instead of 73% seemed weird. Indeed, @bogovicj found the mistake in my code – Be Chiller Too Jul 28 '20 at 15:03
• Yeap, missed that detail. Good catch! In fact creating string tuples and comparing substrings is a bad idea, This is perfect candidate for tuples, if you encoded cards as tuples it would save you a lot of trouble – Nikos M. Jul 28 '20 at 17:03
• I agree 100%, I initially tried np.array([(c, n) for ...]) but np.random.choice wanted 1D arrays, so I used a quick solution, that led to my bug. – Be Chiller Too Jul 29 '20 at 9:04

There's an error in your code:

cards = np.array([c+str(n) for c in ("A", "B", "C", "D", "E") for n in range(1, 11)])


will produce "A10" and "A1" among other values, and

if a[0] != b[0] and a[1] != b[1]:


will return true when a=A10 and b=A1, for example. This is why you're probably consistently underestimating the number of differences.

An easy fix would be to use:

cards = np.array([c+str(n) for c in ("A", "B", "C", "D", "E") for n in range(0, 10)])


instead, which is more readable anyway. But if I were doing this, I might use itertools.product.

Even after this fix it's normal to not always get exactly the theoretical value, but it's bad if there's a bias (i.e. consistent under- or over- estimation).

• Thanks a lot! Indeed I was not expecting the exact theoretical value, but getting the same precise result which was different from the expected result seemed off, thanks for noticing the bug! – Be Chiller Too Jul 28 '20 at 15:02