# Go deh!

Mainly Tech projects on Python and Electronic Design Automation.

# A Python version of theMind boggling card trick.

Get a pack of 52 cards, half red - half black. (You might need to find those missing cards from that old pack)
In :
```n = 52
Black, Red = 'Black', 'Red'
blacks = [Black] * (n // 2)
reds = [Red] * (n // 2)
pack = blacks + reds
```

### Shuffle the pack!

Give the pack a good shuffle. (Don't drop any).
In :
```import random
random.shuffle(pack)
```

### Deal those random cards

1. Assemble the cards face down.
2. Turn up the top card, if it is black then add the next card, unseen, to the black-stack. If it is red then instead add that next card, unseen, to the red-stack.
3. Add the card you turned over to see what colour it was above to the discard stack.
4. Repeat the above for the whole pack.
In :
```black_stack, red_stack, discard = [], [], []
while pack:
top = pack.pop()
print(top, end=' ')
if top == Black:
black_stack.append(pack.pop())
else:
red_stack.append(pack.pop())
print()

```
```R B R R B R R R B B B B B B B B R R B B B R R R R R
```
There is still randomness present. The discard stack shown above seems pretty random.

### Swap the same, random, number of cards between the two stacks.

We can't swap more than the number of cards in a stack.
In :
```max_swaps = min(len(black_stack), len(red_stack))
```
Randomly choose the number of cards to swap. (You could use a dice).
In :
```swap_count = random.randint(0, max_swaps)
print('Swapping', swap_count)
```
```Swapping 11
```
Randomly choose that number of cards out of each stack to swap. (Without knowing those cards - they could be red or black cards from the stacks, we don't know)
In :
```def random_partition(stack, count):
"Partition the stack into 'count' randomly selected members and the rest"
sample = random.sample(stack, count)
rest = stack[::]
for card in sample:
rest.remove(card)
return rest, sample

black_stack, black_swap = random_partition(black_stack, swap_count)
red_stack, red_swap = random_partition(red_stack, swap_count)
```
Perform the swap.
In :
```black_stack += red_swap
red_stack += black_swap
```

## Order from randomness?

The mathematician asserts that:
• The number of black cards in the black pile equals the number of red cards in the red pile
In :
```if black_stack.count(Black) == red_stack.count(Red):
print('Yea! The mathematician is right.')
else:
print('Woops - That mathematician (or my card manipulations) are flakey')
```
`Yea! The mathematician is right.`

1. "If it is red then instead add that next card, unseen, to the black-stack."
Shouldn’t it read "red-stack"?

1. Well caught,! Now fixed.

Thanks Martin :-)