Gossamer Forum
Home : Products : DBMan : Customization :

Random display - again

Quote Reply
Random display - again
Hi, (esp. JPDENI)

I'm using your random routine:

if ($in{'random'}) {
#srand ( );
$values[25]=int(rand(1000)) + 1;
$in{'sb'} = 25;

}

In html.pl I'm using the short-dsiplay:

sub html_record_short {
my (%rec) = @_; # Load any defaults to put in the VALUE field.
($db_auto_generate and print &build_html_record(%rec) and return);
print qq|
<td bgcolor=#F0CC91><font face="verdana, arial" size=1>
<a href="$db_script_link_url&ID=$rec{'ID'}&format=long&view_records=1">Details</a></font></td>
<td bgcolor=#F4F4F4>......


Settings:
30 records, maxhits=10

the first 10 hits: random is o.k.

but:
when I go to next 10 hits, random starts again and sometimes a record from the first 10 hits appears again in the next 10 hits?

the query string is
...db.cgi?db=deafault&uid=default&random=1&ID=&andsoon....

any hints for stopping the random, when I go to "...next hits" ?

thanks in advance!

HP

[This message has been edited by hanspeter (edited August 09, 1999).]
Quote Reply
Re: Random display - again In reply to
In db.cgi, sub query, after

Code:
local (%sortby);

add

Code:
if ((!$in{'nh'}) && ($in{'sb'} == 25)) {
srand( time() ^ ($$ + ($$ << 15)) ); # try this and see if it works for you. If not, delete it.
open (DB, "<$db_file_name") or &cgierr("error in modify_records.
unable to open db file: $db_file_name.\nReason: $!");
if ($db_use_flock) { flock(DB, 1); }
@lines = <DB>;
close DB;
LINE: foreach $line (@lines) {
if ($line =~ /^$/) { next LINE; }
if ($line =~ /^#/) { $output .= $line; next LINE; }
chomp $line;
@data = split /\|/, $line;
$data[25] = int(rand(1000)) + 1;
$output .= join '|',@data;
$output .= "\n";
}
open (DB, ">$db_file_name") or &cgierr("error in delete_records.
unable to open db file: $db_file_name.\nReason: $!");
if ($db_use_flock) {
flock(DB, 2) or &cgierr("unable to get exclusive lock on $db_file_name.\nReason: $!");
}
print DB $output;
close DB;
}

When you use this, all you have to do is use

&sb=25

in your link or if people choose to sort by that field when they do a search, it will come up in random order.

You don't need to use &random=1 any more.

Also, delete the other code you have used. This will take care of it.

Remember that I haven't tested this. Don't use it on data that you can't replace! Back up everything first!!!!!

------------------
JPD







[This message has been edited by JPDeni (edited August 09, 1999).]
Quote Reply
Re: Random display - again In reply to
I don't know of a way to make it do that. I think, when I gave you the original code, I said that you wouldn't be able to go from page to page with it.

The only thing I can think of is that you would have to go through and modify every record first, saving the random number to the field and then doing the sort after the search. But it would slow down the performance of your script a lot.


------------------
JPD





Quote Reply
Re: Random display - again In reply to
thanks for the prompt answer!

I'm not a perlguru

what's about this code?

sub misch_masch {
my $array = shift;
my $i;
for ($i = @array; --$i ; ) {
my $j = int rand ($i+1);
next if $i == $j;
@array[$i,$j] = @$array[$j, $i];
}
}


Is there no way to include this in the script?

regards,
HP


[This message has been edited by hanspeter (edited August 09, 1999).]
Quote Reply
Re: Random display - again In reply to
I have no idea. I don't know what that script does.

Let me explain the code I gave you before and a little bit about how DBMan works. If I can. Smile

The line

$values[25]=int(rand(1000)) + 1;

sticks a random number into a dummy field.

The line

$in{'sb'} = 25;

makes the script sort by the value of that field, giving you a random sort.

However, later on in sub query, when it actually does the searching, the script only collects the records that are on the first page (or second page, or whatever page you're on, based on the value of $in{'nh'}).

When you go to the next page in your search results, it assigns new numbers to the dummy field and does the entire search all over again, this time only collecting the records for the page you're on this time.

Unless you save the random values to the records, they are forgotten from one click to another.

The only way you can have a random search span multiple pages is to save the random numbers to the .db file each time a random search is called for.


------------------
JPD





Quote Reply
Re: Random display - again In reply to
 
Quote:
The only way you can have a random search span multiple pages is to save the random numbers to the .db file each time a random search is called for.

o.k. let's do this.
There are max. 250 records in the database, so the speedlost is acceptable.

but I wrote, I'm not a perlguru

I think:
before the script grubs the querystring, the randomfield must be filled.

...aehm...
do you have a little bit perl-code?

thanks a lot!

best regards from germany

HP
Quote Reply
Re: Random display - again In reply to
When I get finished with Anthony's script, I'll see what I can come up with for you.


------------------
JPD





Quote Reply
Re: Random display - again In reply to
Oh thanks!

the first test looks good, but a little
bug in your new code crashes the db Smile

--> the randomnumber is on the right place,
but all pipes are lost in cyberspace, so
the output looks a little bit Smile
the record is now one field.

I hope not a big prob for you?

regards
HP


Quote Reply
Re: Random display - again In reply to
Sorry 'bout that. You did have a backup, didn't you? Smile

One line wrong.

$output .= join /\|/,@data;

should be

$output .= join '|',@data;

I'll change it in the original, too.


------------------
JPD





Quote Reply
Re: Random display - again In reply to
 
Quote:
Fred comes to your database and does a search, the results of which are displayed in random order. Ethel comes
to your database and does the same thing, while Fred is reading his first page. Fred will get Ethel's second page. I don't know of a way around this.

*hmmpf* I tested it with two simultan sessions ---> Frown

Another idea: one random per day is enough.
So the first visitor of the database starts the random-routine.
His action is logged in a randomdate.txt
Before the randomroutine in db.cgi starts, we (esp. me) need a little code:
--> open randomdate.txt
--> if randomdate < todaydate
--> start random and logging
--> else ignore random

what do you think about this?

regards
HP
Quote Reply
Re: Random display - again In reply to
 
Quote:
Sorry 'bout that. You did have a backup, didn't you?
Oh Mensch Meier! I know that I've forgot something.... Wink for this perfect service!)

Best regards again from Germany,
HP
Quote Reply
Re: Random display - again In reply to
I'm glad it is working for you now, after my goofs. Smile

One thing that occurred to me about this, though, is that there still could be a problem. An example would be the best way to explain it.

Fred comes to your database and does a search, the results of which are displayed in random order. Ethel comes to your database and does the same thing, while Fred is reading his first page. Fred will get Ethel's second page. I don't know of a way around this.


------------------
JPD





Quote Reply
Re: Random display - again In reply to
Okay. I think I can do that.

Code:
if ((!$in{'nh'}) && ($in{'sb'} == 25)) {
open (DATE, "<$db_script_path/random.txt") or &cgierr("error in random routine. \nReason: $!");
if ($db_use_flock) { flock(DATE, 1); }
$old_date=<DATE>;
$today = &get_date;
unless ($old_date eq $today) {
srand( time() ^ ($$ + ($$ << 15)) ); # try this and see if it works for you. If not, delete it.
open (DB, "<$db_file_name") or &cgierr("error in modify_records.
unable to open db file: $db_file_name.\nReason: $!");
if ($db_use_flock) { flock(DB, 1); }
@lines = <DB>;
close DB;
LINE: foreach $line (@lines) {
if ($line =~ /^$/) { next LINE; }
if ($line =~ /^#/) { $output .= $line; next LINE; }
chomp $line;
@data = split /\|/, $line;
$data[25] = int(rand(1000)) + 1;
$output .= join '|',@data;
$output .= "\n";
}
open (DB, ">$db_file_name") or &cgierr("error in delete_records.
unable to open db file: $db_file_name.\nReason: $!");
if ($db_use_flock) {
flock(DB, 2) or &cgierr("unable to get exclusive lock on $db_file_name.\nReason: $!");
}
print DB $output;
close DB;
open (DATE, ">$db_script_path/random.txt") or &cgierr("error in random routine. \nReason: $!");
if ($db_use_flock) {
flock(DATE, 2) or &cgierr("unable to get exclusive lock on date file.\nReason: $!");
}
print DATE $today;
close DATE;
}
}

You'll have to save a blank file to your dbman directory called random.txt. I checked the syntax of the code, but that's all.

------------------
JPD







[This message has been edited by JPDeni (edited August 11, 1999).]
Quote Reply
Re: Random display - again In reply to
Perfect again!
thanks!

Your little test of my perl knowledges: 1:0 for me Smile

Code:
open (DATE, "<$db_script_path/random.txt")

should be

Code:
open (DATE, ">$db_script_path/random.txt")

regards,
HP
Quote Reply
Re: Random display - again In reply to
 Smile Glad you caught that! It always makes me feel good when I know that folks really look at the code instead of just pasting it in.

You're welcome! Smile


------------------
JPD





Quote Reply
Re: Random display - again In reply to
My best friend:

a book called "PERL for dummies" Smile

HP