# Card Shuffling in Python

## CS 101: Intro to Card Shuffling

I always travel with a deck of cards in my purse, backpack, suitcase, etc. I think my total hatred for small talk means that I always come prepared to entertain others. Yet even though I always carry a deck of cards with me, I have never given much thought to the actual mechanics of cards. After my husband had a particularly lucky run with a new deck earlier this year, we started talking about the rules of shuffling. We had both heard that 7 shuffles was the minimum amount of shuffles required to thoroughly shuffle a deck, but neither of us knew if this was a proven fact or an old wives tail.
We also argued about whether it was even possible to quantify a deck of shuffled cards. How do you define shuffledness and more importantly, how do you measure it?

In order to figure all this out, I decided to do a bit of research. It turns out card shuffling is a very complex mathematical topic, and there are a wide variety of approaches and opinions to each question. What better way to exercise my Python skills than to test some of these card related tricks in my Python myself?

To start we'll need a deck, so let's just code one up real quick.

The code is pretty simple here. I created 2 lists, `values` & `suites`, then I iterate through each suite to create a full deck of cards.

### Here's the thing:

There are is an insanely large number of unique card orders for a deck. The math behind this is pretty simple. If you've ever been hoodwinked into playing 52 card pickup, you know there are 52 cards in a deck, but this blog is about using PYTHON so let's double check that.

That means that the number of unique shuffles in a deck is equal to 52!.

Diaconis mentions that if cards are "perfectly shuffled 8 times, they will be in same order that they were before the first shuffle. We can quickly edit our function to become a perfect shuffle by removing the randomness.

`def perfect_riffle(deck):`

`import random`

`k =26`

`first_deck, second_deck = deck[:k], deck[k:]`

`n = 1`

`for i in range(0, 26):`

`first_deck.insert(n, second_deck[i])`

`n = 2 + n`

`return first_deck`

`deck1 = perfect_riffle(deck)`
`deck2 = perfect_riffle(deck1)`
`deck3 = perfect_riffle(deck2)`
`deck4 = perfect_riffle(deck3)`
`deck5 = perfect_riffle(deck4)`
`deck6 = perfect_riffle(deck5)`
`deck7 = perfect_riffle(deck6)`
`deck9 = perfect_riffle(deck7)`

`deck8 == deck` `True`

### Pretty cool, huh?

I had a lot of fun learning about card shuffling, and coding it in Python. I'm actually glad my husband cheated that night by trying to pass off a few shuffles as a thorough shuffling. He did a 3-4 shuffle run at best. So let this blog serve as a reminder to him that cheaters never prosper, at least not on my blog.
I'll definitely write more about card shuffling in the future, but in the mean time, here are some other articles you might find interesting: