https://github.com/ppintosilva/casino-royale
A small python library for tossing biased coins and rolling loaded dices!
https://github.com/ppintosilva/casino-royale
Last synced: 2 months ago
JSON representation
A small python library for tossing biased coins and rolling loaded dices!
- Host: GitHub
- URL: https://github.com/ppintosilva/casino-royale
- Owner: ppintosilva
- License: mit
- Created: 2016-03-17T17:55:40.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2016-03-24T00:07:01.000Z (about 9 years ago)
- Last Synced: 2025-01-23T07:26:39.082Z (4 months ago)
- Language: Python
- Size: 174 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# CasinoRoyale.py
##### A small python library for tossing coins and rolling dices!

---
## Motivation:
This is a small python module that was motived by a very interesting piece written by Keith Schwarz, entitled:
[*Darts, Dice, and Coins: Sampling from a Discrete Distribution*](http://www.keithschwarz.com/darts-dice-coins)
In this article, he analyses different data structures and algorithms for representing and rolling a loaded die.
I find his presentation of the problem and various solutions to be an example of how to approach computational problems.
This is exacly the kind of step-by-step problem-solving and analysis skills we want to foster in early coders.So, I decided to implement the data structures and algorithms in a python module which may be easily used on a different project, or even provide a good teaching tool someday.
---
## Coins:
+ Create a fair coin, with equal tossing chances:
```python
from casino.coins import FairCoin
fair_coin = FairCoin()
```+ Create a biased coin:
```python
from casino.coins import BiasedCoin
biased_coin = BiasedCoin(0.7)
# or with
biased_coin = BiasedCoin(pheads=0.7)
```+ Or just create an arbitrary coin:
```python
from casino.coins import Coin
coin = Coin(0.1337)
# or with
coin = Coin(pheads=0.1337)
```+ Toss any coin with:
```python
result = coin.toss()
```
result is evaluated to **1** if **heads** or **0** if **tails****Constructors raise _Value Error_ when:**
+ Probability of heads is lower than zero **or** greater than 1.
+ You try to create a **Biased** Coin as a **Fair** Coin (i.e. with pheads = 0.5)---
## Dices:
+ Create a fair die with *n* sides, with equal rolling chances for all sides:
```python
from casino.dices import FairDie
fair_die = FairDie(6)
# or
fair_die = FairDie(nsides=6)
```+ Roll any die with:
```python
face = die.roll()
```
face is an integer value **between 0 and n-1**#### Creating loaded dices:
Creating a loaded die requires a list containing the probability of rolling each face of the die.
The length of the list corresponds to the number of faces of the die.However, **LoadedDie** is an abstract class used as a common base for different possible implementations.
We provide 7 different implementations of the **Loaded Die** (5 currently), based on Keith's post:| Implementation | Simulates a loaded die using | Implemented (y/n) |
| ------------- |:-------------:|:-----------------------------:|
| *MutatedDie* | A fair die | y |
| *CoinedDie* | Biased coins | y |
| *RouletteDie* | The roulette wheel selection method | y|
| *HybridDie* | A combination of fair dices and biased coins | y |
| *NaiveDie* | The Naive Alias method | n |
| *AliasDie* | The Alias method | n |
| *VosesDie* | The Voses Alias method | y |The constructor parameters and methods for all classes are the same.
For instance, you can create Mutated Dies like this:```python
from casino.dices import MutantDie
mutant = MutatedDie([0.3, 0.2, 0.5])
# or
mutant2 = MutatedDie(psides = [0.7, 0.2, 0.1])
# or
mutant3 = MutatedDie(psides = [0.5, 0.1, 0.1, 0.3], verifyInput = True)
# or
# this does not raise a ValueError exception
mutant4 = MutatedDie(psides = [0.4, 0.5, 0.2], verifyInput = False)
# or
# this raises a ValueError exception
mutant5 = MutatedDie([0.4, 0.5, 0.2], True)
```
Or use other implementations of LoadedDie in the same manner:```python
from casino.dices import CoinedDie, RouletteDie, HybridDie, VosesDie
psides = [0.2, 0.3, 0.5]
die1 = CoinedDie(psides)
die2 = RouletteDie(psides)
die3 = HybridDie(psides)
die4 = VosesDie(psides)
```You can review the differences between the several implementations in the table below, extracted from
Keith's post (I hope that's okay with him):
#### Implementing your own loaded die:
You can implement your own loaded die by extending the **LoadedDie** class
and implementing the two base abstract methods: *pre_process(self)* and *roll(self)*:```python
MyBadassDie(LoadedDie):
def __init__(self, psides, verifyInput = True):
super(MyBadassDie, self).__init__(psides, verifyInput)
def pre_process(self):
...
def roll(self):
...
```**Note**: You don't need to call *pre_process()* because the parent class **LoadedDie**
already does that work for you.---
#### Additional Considerations:
+ The second parameter in the LoadedDice constructor takes a **boolean** which if *True* checks if the passed list
of probabilities respects the following (obvious) properties:
* The sum of probabilities must equal 1 and only 1.
* There can be no probability greater than one or lower/equal to zero.
* All probabilites can not hold the same value (1/nfaces) - that would make it a fair die.+ On the implementation of a Loaded Die using a Fair Die, we capped the *psides* list size based
on an answer provided at [stackoverflow](http://stackoverflow.com/questions/855191/how-big-can-a-python-array-get).
Nevertheless, as stated by Keith, the usable memory required to hold in memory the size of the *L* array can easily
be larger than the available memory in RAM. Thus, checking the size of the array against the value of MAX_LIST_SIZE, when you can trigger an overflow error with just a two value list (see Keith's example) does look in fact like a useless, pointless operation. Nevertheless it's there and if you don't like it you can just simply take it off.+ I am using nose for unit-testing, but you can run them at (/casino/tests) using your favourite python testing framework or library.
---
## The End
Any comments or suggestions, email me to [email protected]
Pedro Pinto da Silva,
Porto, Portugal - March, 2016