Recipes¶
Produce Collisions¶
Quick check if two random sets might overlap:
In [121]: SG(r'[\u\d]{5}').render_set(10000) & SG(r'[\u\d]{5}').render_set(10000)
Out[121]: {'PH8AX'}
In this case, we had a single overlap. Easy to make that more overlapping by increasing set size with the same pattern:
In [59]: len(SG(r'[\u\d]{5}').render_set(100000) & SG(r'[\u\d]{5}').render_set(100000))
Out[58]: 150
150 overlaps.
Or make it very unlikely that an overlap will exist by making the results more characters:
In [35]: len(SG(r'[\u\d]{50}').render_set(100000) & SG(r'[\u\d]{50}').render_set(100000))
Out[35]: 0
It would be nice to know what the count of the sets of potential results are:
In [19]: SG(r'[\u\d]{5}').count()
Out[19]: 60466176
In [18]: SG(r'[\u\d]{50}').count()
Out[18]: 653318623500070906096690267158057820537143710472954871543071966369497141477376
The set \u\d
:
ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
is 36 characters, so 36^5 = 60466176
, permutation with replacement. And likewise 36^50 = a big number
.
Coin Flip¶
Flip a coin 10000 times and count heads and tails:
import collections
In [64]: collections.Counter(SG("heads|tails").render_list(10000))
Out[64]: Counter({'tails': 5046, 'heads': 4954})
Flip two coins and check how the combinations were distributed:
In [81]: collections.Counter(list(zip(SG("heads|tails").render_list(100), SG("heads|tails").render_list(100))))
Out[81]:
Counter({('heads', 'heads'): 20,
('tails', 'heads'): 21,
('heads', 'tails'): 25,
('tails', 'tails'): 34})
Roll two die 1000 times:
In [7]: d = list(zip(SG(r'[123456]').render_list(1000), SG(r'[123456]').render_list(1000)))
In [8]: Counter(d)
Out[8]:
Counter({('2', '2'): 28,
('3', '1'): 28,
('4', '1'): 27,
('5', '2'): 32,
('1', '5'): 28,
('6', '2'): 42,
('4', '3'): 19,
('1', '4'): 40,
...
We counted where order matters, 36 potential outcomes.
Pick a card from a deck¶
First setup some definitions:
SPADE = "♠"
HEART = "♥"
DIAMOND = "♦"
CLUB = "♣"
def is_face_card(s):
return s[0] in "JQK"
def is_black_suit(s):
return s[-1] in (SPADE, CLUB)
def is_red_suit(s):
return s[-1] in (DIAMOND, HEART)
Now let’s randomly pick a card 1000 times:
In [208]: d = SG(f"J|Q|K|A|2|3|4|5|6|7|8|9|10[{HEART}{SPADE}{DIAMOND}{CLUB}]").render_list(1000)
collections.Counter([is_face_card(x) & is_black_suit(x) for x in d])
In [209]: collections.Counter([is_face_card(x) & is_black_suit(x) for x in d])
Out[209]: Counter({False: 887, True: 113})
We expect the probability of getting a black face card to be 11.5%:
In [210]: 113/1000
Out[210]: 0.113
Close enough
Normal Distribution¶
We expect the distribution of picking one of 0 - 9 digits to be normally distributed if we try 100 times over 1000 times.
In [11]: import statistics
In [12]: d = [statistics.mean([int(SG("0|1|2|3|4|5|6|7|8|9").render()) for _ in range(100)]) for _ in range(1000)]
...: nd = statistics.NormalDist.from_samples(d)
...: nd.stdev
Out[12]: 0.29718859089567784
In [13]: nd.mean
Out[13]: 4.51675
4.5 is the mean for 0 - 9.