note
pernod
<p>I'm off on a tangent here, so please excuse the off-topicness of this quick example.</p>
<blockquote>How do you test your shuffling or die rolling technique is fair and produces results according to your specifications (say, according to a Gaussing distribution), and isn't biased favouring certain outcomes?</blockquote>
<p>By using [cpan://Test::LectroTest]! Given this trivial implementation of an n-sided die, which returns a number between 1 and the number of sides on your die. Default number of sides is 6.</p>
<code>
package Die;
sub new {
my ( $pck, $sides ) = @_;
return bless( { sides => $sides || 6 }, $pck );
}
sub roll {
my ( $self ) = @_;
return int( rand( $self->{ sides } ) ) + 1;
}
1;
</code>
<p>We then express how we want our die to perform with a Test::LectroTest property that generates a thousand tests with dies with from 1 to 100 sides. We roll the die, and check that the result is legal for this kind of die (eg. within the limits). The second propery generates a thousand six sided dies and rolls each of them once. The results are stored in the the LectroTest controller object with the <code>tcon->label()</code>-call, that automatically spits out the distribution of the roll.</p>
<code>
#! /usr/bin/perl
use Test::LectroTest;
use Die;
Property {
##[ x <- Int( range => [ 1, 100 ], sized => 0 ) #]##
my $die = Die->new( $x );
my $roll = $die->roll();
( 0 < $roll && $x >= $roll );
}, name => "My die returns something between 1 and the number of sides of the die.";
Property {
##[ x <- Unit( 6 ) #]##
my $die = Die->new( $x );
my $roll = $die->roll();
$tcon->label( $roll );
( 0 < $roll && $x >= $roll );
}, name => "With a six sided die, I get this distribution";
</code>
<p>When I run this, I get:</p>
<code>
1..2
ok 1 - 'My die returns something between 1 and the number of sides of the die.' (1000 attempts)
ok 2 - 'With a six sided die, I get this distribution' (1000 attempts)
# 18% 2
# 17% 3
# 16% 1
# 16% 5
# 16% 6
# 15% 4
</code>
<p>What this means is that the number 2 showed up 18% of the time, 3 17% etc. The numbers don't add up to a 100%, but I presume this is because of rounding in the presentation. In any case, this looks like acceptable behavior for a six sided die to me. I'm sure it's possible to automatically analyze the distribution and build this into the test, but I don't have the time to find out how right now. And please remember that this example was hacked together in a hurry, so I'm sure it can be improved.</p>
<p>I like [cpan://Test::LectroTest] :)</p>
<p><b>Edit:</b> Removed an erroneous line in the second property.</p>
<!-- Node text goes above. Div tags should contain sig only -->
<div class="pmsig"><div class="pmsig-224955">
<p>pernod<br>
-- <br>
Mischief. Mayhem. Soap.</p>
</div></div>
<p><small>Retitled by [davido] from '<em>OT: Test::LectroTest and pseudo random distributions</em>'.</small></p>
480680
480791