PERL newb/idiot question about random nums

software development

#1

Hi there,

I’m working (which is to say google/copy/paste/hacking) on a perl script to generate a random image for a decorative element for my website.

I’ve got an almost decent one going ( http://illovich.com/cgi/random_img.pl) that I’m having a problem with… it generates the images fine (I can use that url in an image call, like and it works great, but the problem is it’s using the time to generate the random number, and since I generate 5 images at a time (http://illovich.com/wp) they all come up being the same image.

Here’s the basic script:[code]# Necessary Variables
$basedir = “http://www.illovich.com/sqicons/”;
@files = (“icon1.jpg”,“icon2.jpg”,“icon3.jpg”, “icon28.jpg”);

srand(time ^ $$);
$num = rand(@files); # Pick a Random Number

Print Out Header With Random Filename and Base Directory

print “Location: $basedir$files[$num]\n\n”;
[/code]So I’m messing around with String::Random (http://search.cpan.org/~steve/String-Random-0.22/lib/String/Random.pm) to try to find a solution to my problem.

Basically, I need to be able to generate a random number between 1-28 that will be random enough that it will be generally 5 different results if the script is execute 5 times in a row on an html page (I’m assuming that the script I have above needs at least a milisecond if not more in between calls to get a different result on each call).

Anyway, according the the String:Random docs, I can use string_random to generate a single digit from an array, like this:[code]!#usr/bin/perl

use String::Random qw(random_string);

print random_string (“0”, [“1”,“2”,“3”], “\n”);[/code]…but I’m getting this error

Can’t use String ("
") as an ARRAY ref while “strict refs” in use at /usr/share/perl5/String/Random.pm line 283.

I know enough to know it might be a configuration problem, but I feel like I’ve hit a wall with my understanding of unix, perl and all that kind of thing.

Could a kind soul point me in the right direction? =)

Thanks much,

ill


#2

This is not a Perl problem.

Take a gander at your HTML again:

<img src="http://illovich.com/cgi/random_img.pl" width="60" height="60" border="0" alt=" " class="sqIcon" /> <img src="http://illovich.com/cgi/random_img.pl" height="60" width="60" border="0" alt=" " class="sqIcon" /> <img src="http://illovich.com/cgi/random_img.pl" height="60" width="60" border="0" alt=" " class="sqIcon" /> <img src="http://illovich.com/cgi/random_img.pl" height="60" width="60" border="0" alt=" " class="sqIcon" /> <img src="http://illovich.com/cgi/random_img.pl" height="60" width="60" border="0" alt=" " class="sqIcon" />The problem is you have one URL repeated five times.

The only thing you need to do to the Perl script is remove the call to srand() - if you read the documentation, you’d know it is unnecessary as srand() is automatically called when perl starts.

:cool: [color=#6600CC]Atropos[/color] | openvein.org


#3

Thanks for the advice. Unfortunately, it doesn’t fix the problem I’m having – removing the srand call doesn’t stop the same image from appearing 5 times in a row on the page.

The problem I’m trying to solve isn’t that I have one url repeated 5 times (I was using this method with another script in the same way, which was fine except that the script had a problem with actual randomness… it tended to favor 8 or 9 of the 28 possible images), it’s that the way I’m generating the random number gets the same result if there isn’t enough time in-between calls.

What I’m trying to figure out is either

  1. a way to change my script so that it will mostly return a different number every time it’s run, even if the same script is run 5 times in a row…

  2. a more elegant way to achieve what I’m going for, which is 5 random images in a row that are selected from a single directory.

I fixed the problem temporarily by copying the script 5 times on the server and then calling random_img.pl, random_img2.pl, etc.

But this is a fairly inelegant solution to the problem, so I was hoping that generating the random number in another way (using String::Random, for example) would enable me to not have to use 5 copies of the same cgi script to achieve the effect I was looking for.

But thanks for the advice, I removed it from my script and it still works so it was good to learn that. :slight_smile:


#4

I’ve done something similar using any of the following in the page’s html (without space between ! and -):

<! --#include virtual="/path/to/script.cgi"–>
<! --#include virtual="/path/to/script.pl"–>
<! --#exec cgi="/path/to/script.pl"–>
<! --#exec cgi="/path/to/script.cgi"–>

With only 28 images, picking 5 at a time, the odds of sometimes picking duplicates seems fairly high (somebody else can do the math).

[quote]I fixed the problem temporarily by copying the script 5 times on the server and then calling random_img.pl, random_img2.pl, etc.

[/quote]

If it works, don’t fix it. :slight_smile:

They recently hired more support help.
DreamHost Customers wiki And Forum


#5

Lol, exactly =)

In a fit of frustration/insight I changed the scope of the question and fixed what was working with php:

[code]<?php
function sqicon()
{
srand(time());
for ($i=0; $i < 5; $i++)
{
$random = (rand()();
$slot[] = $random + 1;
}
echo ’ ’ ;
echo ’ ’ ;
echo ’ ’ ;
echo ’ ’ ;
echo ’ ’ ;
}
?>

<?php sqicon(); ?>

[/code]This seems serviceable enough for the moment, since the website is a wordpress blog, and the page that calls the images is done in php anyway – it just de-complicates the whole business.

If I feel like mucking about with it more, I might add a routine to track what numbers have already been picked, and to pick another if it has, just to finish the thing off once and for all.

Thanks for the thoughts, folks =)


#6

You’re trying to troubleshoot a system involving a web browser, a web server, and a script interpreter. It appears to me you are failing to take into account the interaction of the web browser and the web server and have failed to make any observations.

I on the other hand observed my web browser hitting the web server once and using the same image file five times on the page, and your Apache log files will also show only one hit to the Perl script.

All you had to was use a query string or path_info:


And you’re done.

Or you could use 5 different files (5 different filenames = 5 different URLs) like you found out.

But the PHP solution is better since you don’t have to start perl 5 times.

And there are ways of telling a web browser not to cache the image, but your Perl script was not doing that.

And I never said removing the srand() call would fix the problem. I just said it was not necessary because srand() is automatically called when perl starts.

:cool: [color=#6600CC]Atropos[/color] | openvein.org


#7

[quote]print random_string (“0”, [“1”,“2”,“3”], “\n”);
Can’t use String ("
") as an ARRAY ref while “strict refs” in use at /usr/share/perl5/String/Random.pm line 283.

[/quote]

The paren is in the wrong place. Try this:
print random_string (“0”, [“1”,“2”,“3”]), “\n”;

You want “\n” to be an arg to print. As you had it written, it was an arg to random_string(). You may still have core problems with your script, but that’s the specific bug that generated that error