[sf-perl] randomize particular lines
Paul Makepeace
paul at makepeace.net
Tue Mar 7 03:42:12 PST 2006
Je 2006-03-07 00:50:08 +0000, Quinn Weaver skribis:
> $word = $words[rand @words]; ## rand returns fractional numbers.
> ## Unfortunately Perl uses floating-point
> ## numbers by default, so it allows
> ## fractional array subscripts. However,
> ## you can't reliably take the 1.23'th element
> ## of an array. This expression will
> ## sometimes get you undef, which is
> ## probably not what you want.
This one line is actually quite fine. The $array[rand @array] is a pretty
standard idiom and will do what you want: the rand is rounded down
(i.e. int() is implied) and scalar(@array) is one past the end of the
array so the result is 0..$#array.
> my @scramble = split(//, $word);
> @scramble = sort { (-1,1)[rand 2] } @scramble; ## This code cries out for
> ## documentation. It
> ## also suffers from the
> ## rand problem described
> ## in my preceding comment.
It's wrong too as sort's behavior doesn't permit a random comparison.
perldoc -f sort,
The comparison function is required to behave. If it returns inconsistent results (sometimes saying
$x[1] is less than $x[2] and sometimes saying the opposite, for example) the results are not
well-defined.
Which is sort of a shame, as it's cute :-)
Since we're promoting best practices,
use Algorithm::Numerical::Shuffle 'shuffle';
@scramble = shuffle(@scramble);
> $word = $scramble; #if this line omitted, prints the whole file unchanged
(I wonder how $scramble got past the use strict; ?)
> open (DICT, $dictionary) or die "Cannot open $dictionary: $!";
>
> You could do
>
> open my $dict_fh, $dictionary or die "Cannot open $dictionary: $!";
>
> That way you don't have to worry about whether you already used the
> name DICT, and you can simply pass $dict_fh to other functions. In
> short, it scales better. The other use of open isn't incorrect,
> just suboptimal.
Yeah, or
use File::Slurp 'slurp'; # slurp is preferred Perl 6 name
my @lines = slurp($dictionary);
# process @lines
write_file(\*STDOUT, @lines); # I think this is right
Paul
--
Paul Makepeace .............................. http://paulm.com/inchoate/
"If kerry feels horney, then we will put you in our curry."
-- http://paulm.com/toys/surrealism/
More information about the SanFrancisco-pm
mailing list