making the keys of a hash from parameters collected from a form

making the keys of a hash from parameters collected from a form

am 29.11.2007 05:11:08 von rallabs

Hello everyone:
I have the need to prioritize a number of items from a list and then
print them out in the order in which they were chosen. To be more
specific, I have a list of 12 items and I would like to have the users
indicate which is their first choice, which is their second, etc. up
to 8. I must put the items into a file in the order which has been
prioritized by the user. My thought was to present a form with 12
textboxes, into which they can type the number '1' for their first
choice, the number '2' for their second, etc. Then, when parsing the
form, I could make a hash whose keys are the numbers put into the
boxes, from 1 to 8, with the hash 'values' being the textbox 'names'.
Sorting the hash according to keys would then give me the info I
need. I find, however, that this approach is flawed in that the
collected parameters from the forms are not in the proper format,
apparently, for making into keys. A script or 2 is worth a zillion
words, so I present scaled-down versions of the form and the parsing
script, and if anyone has a solution I sure would like to hear it.
The first script, 'mike.cgi' follows:

#!/usr/bin/perl -wT
use CGI::Carp qw(fatalsToBrowser);
use CGI qw(:standard -no_xhtml);
use strict;
use diagnostics;
my $q = new CGI;
print $q->header;
print $q->start_html(-title=>"mike.cgi",-bgcolor=>"silver",-
text=>"blue",-link=>"blue"),$q->br,$q->br,$q->br;
print $q->h3("Please indicate your favorite fruit with a '1', and your
second favorite with a '2'. \n");
print $q->h3("Leave the rest blank:\n");
print $q->start_form(-method=>"POST", -action=>"parse.cgi");
print $q->start_form(-method=>"POST", -action=>"getparam.cgi");
print $q->h3(textfield(-name=>'app', -size=>1),"apple");
print $q->h3(textfield(-name=>'ora', -size=>1),"orange");
print $q->h3(textfield(-name=>'lem', -size=>1),"lemon");
print $q->h3(textfield(-name=>'lim', -size=>1),"lime");
print $q->h3(textfield(-name=>'ban', -size=>1),"banana");
print $q->submit, $q->reset, $q->endform, end_html;
exit;

The script that is supposed to make and sort the hash is called
'parse.cgi':
#!/usr/bin/perl -wT
use CGI::Carp qw(fatalsToBrowser);
use CGI qw(:standard -no_xhtml);
use strict;
use diagnostics;
my $q = new CGI;
print $q->header;
print $q->start_html(-title=>"mike.cgi",-bgcolor=>"silver",-
text=>"blue",-link=>"blue"),$q->br,$q->br,$q->br;
my %hashfruit=(
"param('app')"=>'app',
"param('lem')"=>'lem',
"param('ora')"=>'ora',
"param('lem')"=>'lem',
"param('lim')"=>'lim',
);
my $k;
foreach $k (keys %hashfruit){
print "

The key is: $k and the value is
$hashfruit{$key}
";
}
end_html; exit;

As you can see, the 'keys' were intended to be the values of
parameters passed to 'parse.cgi', but instead of getting the values (1
and 2), I get as keys the strings 'param(app)' etc. Does anyone
know how to get the actual contents the user typed in so I can use
them as the keys to %hashfruit? Thanks in advance.
Mike

Re: making the keys of a hash from parameters collected from a

am 29.11.2007 05:16:14 von rallabs

On Nov 28, 11:11 pm, mike wrote:
> Hello everyone:
> I have the need to prioritize a number of items from a list and then
> print them out in the order in which they were chosen. To be more
> specific, I have a list of 12 items and I would like to have the users
> indicate which is their first choice, which is their second, etc. up
> to 8. I must put the items into a file in the order which has been
> prioritized by the user. My thought was to present a form with 12
> textboxes, into which they can type the number '1' for their first
> choice, the number '2' for their second, etc. Then, when parsing the
> form, I could make a hash whose keys are the numbers put into the
> boxes, from 1 to 8, with the hash 'values' being the textbox 'names'.
> Sorting the hash according to keys would then give me the info I
> need. I find, however, that this approach is flawed in that the
> collected parameters from the forms are not in the proper format,
> apparently, for making into keys. A script or 2 is worth a zillion
> words, so I present scaled-down versions of the form and the parsing
> script, and if anyone has a solution I sure would like to hear it.
> The first script, 'mike.cgi' follows:
>
> #!/usr/bin/perl -wT
> use CGI::Carp qw(fatalsToBrowser);
> use CGI qw(:standard -no_xhtml);
> use strict;
> use diagnostics;
> my $q = new CGI;
> print $q->header;
> print $q->start_html(-title=>"mike.cgi",-bgcolor=>"silver",-
> text=>"blue",-link=>"blue"),$q->br,$q->br,$q->br;
> print $q->h3("Please indicate your favorite fruit with a '1', and your
> second favorite with a '2'. \n");
> print $q->h3("Leave the rest blank:\n");
> print $q->start_form(-method=>"POST", -action=>"parse.cgi");
> print $q->start_form(-method=>"POST", -action=>"getparam.cgi");
> print $q->h3(textfield(-name=>'app', -size=>1),"apple");
> print $q->h3(textfield(-name=>'ora', -size=>1),"orange");
> print $q->h3(textfield(-name=>'lem', -size=>1),"lemon");
> print $q->h3(textfield(-name=>'lim', -size=>1),"lime");
> print $q->h3(textfield(-name=>'ban', -size=>1),"banana");
> print $q->submit, $q->reset, $q->endform, end_html;
> exit;
>
> The script that is supposed to make and sort the hash is called
> 'parse.cgi':
> #!/usr/bin/perl -wT
> use CGI::Carp qw(fatalsToBrowser);
> use CGI qw(:standard -no_xhtml);
> use strict;
> use diagnostics;
> my $q = new CGI;
> print $q->header;
> print $q->start_html(-title=>"mike.cgi",-bgcolor=>"silver",-
> text=>"blue",-link=>"blue"),$q->br,$q->br,$q->br;
> my %hashfruit=(
> "param('app')"=>'app',
> "param('lem')"=>'lem',
> "param('ora')"=>'ora',
> "param('lem')"=>'lem',
> "param('lim')"=>'lim',
> );
> my $k;
> foreach $k (keys %hashfruit){
> print "

The key is: $k and the value is
> $hashfruit{$k}
";
> }
> end_html; exit;
>
> As you can see, the 'keys' were intended to be the values of
> parameters passed to 'parse.cgi', but instead of getting the values (1
> and 2), I get as keys the strings 'param(app)' etc. Does anyone
> know how to get the actual contents the user typed in so I can use
> them as the keys to %hashfruit? Thanks in advance.
> Mike

Re: making the keys of a hash from parameters collected from a form

am 29.11.2007 06:23:28 von 1usa

mike wrote in news:35f36fbc-c724-4df0-a418-
840e48f9895e@n20g2000hsh.googlegroups.com:

> Hello everyone:
> I have the need to prioritize a number of items from a list and then
> print them out in the order in which they were chosen. To be more
> specific, I have a list of 12 items and I would like to have the users
> indicate which is their first choice, which is their second, etc. up
> to 8. I must put the items into a file in the order which has been
> prioritized by the user.

....

> print $q->h3(textfield(-name=>'app', -size=>1),"apple");

A textfield in h3? We're straying off-topic here but that is awful HTML.

> my %hashfruit=(
> "param('app')"=>'app',
> "param('lem')"=>'lem',
> "param('ora')"=>'ora',
> "param('lem')"=>'lem',
> "param('lim')"=>'lim',

....

> instead of getting the values (1
> and 2), I get as keys the strings 'param(app)'

You are specifying the keys as strings in the form "param('app')"
yourself. That's what you told your program to do. How do you expect
anything else to happen?

If, instead, you had used

my %hashfruit=(
param('app') =>'app',
param('lem') =>'lem',
param('ora') =>'ora',
param('lem') =>'lem',
param('lim') =>'lim',
);

the results of the param calls would be stringified.

Of course, you are not performing any sanity checks on the inputs so
this has the potential of becoming problematic. By giving each textfield
a different name, you are making life unnecessarily hard.

Instead, use the same name, say 'rank', for all the textfields. That
way, things like checking that all the ranks are distinct, all the ranks
are numbers etc becomes a much easier operation and you don't have to
make a whole bunch of changes every time you change the list of fruits.

As your scripts are too messy to modify, here is an alternative:


#!perl

use strict;
use warnings;

use CGI qw( -no_xhtml );

my @FRUITS = qw( apple orange lemon lime banana );

my $cgi = CGI->new;
print $cgi->header( 'text/html' );

unless ( $cgi->param ) {
show_form( $cgi );
}
else {
process_form( $cgi );
}

sub show_form {
my $cgi = shift;
my ( $msg ) = @_;

print $cgi->start_html;

if ( $msg ) {
print $cgi->p( $cgi->em( $msg ) );
}

print $cgi->start_form( -method => 'GET' );

for my $fruit ( @FRUITS ) {
print $cgi->p(
$cgi->textfield( -name => 'rank', -size => 1 ), $fruit
);
}

print $cgi->p( $cgi->submit, $cgi->reset ),
$cgi->end_form,
$cgi->end_html;
return;
}

sub process_form {
my $cgi = shift;
my @ranks = $cgi->param( 'rank' );

for my $rank ( @ranks ) {
$rank =~ s/^\s+//;
$rank =~ s/\s+$//;

unless ( $rank =~ /^(\d+)$/
and $rank => 1
and $rank <= @FRUITS
) {
return show_form(
$cgi,
sprintf(
'Ranks must be integers between %d and %d.',
1, scalar @FRUITS
)
);
}
}

my %ranked;
@ranked{ @ranks } = @FRUITS;

unless ( keys %ranked == @FRUITS ) {
return show_form(
$cgi,
'Please fill in all spaces with distinct ranks.'
);
}

print $cgi->start_html,
$cgi->ol(
$cgi->li(
[ map { $ranked{ $_ } } sort keys %ranked ]
)
),
$cgi->end_html;
return;
}

__END__



--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(remove .invalid and reverse each component for email address)
clpmisc guidelines:

Re: making the keys of a hash from parameters collected from a form

am 29.11.2007 10:34:08 von rallabs

On Nov 29, 12:23 am, "A. Sinan Unur" <1...@llenroc.ude.invalid> wrote:
> mike wrote in news:35f36fbc-c724-4df0-a418-
> 840e48f98...@n20g2000hsh.googlegroups.com:
>
> > Hello everyone:
> > I have the need to prioritize a number of items from a list and then
> > print them out in the order in which they were chosen. To be more
> > specific, I have a list of 12 items and I would like to have the users
> > indicate which is their first choice, which is their second, etc. up
> > to 8. I must put the items into a file in the order which has been
> > prioritized by the user.
>
> ...
>
> > print $q->h3(textfield(-name=>'app', -size=>1),"apple");
>
> A textfield in h3? We're straying off-topic here but that is awful HTML.
>
> > my %hashfruit=(
> > "param('app')"=>'app',
> > "param('lem')"=>'lem',
> > "param('ora')"=>'ora',
> > "param('lem')"=>'lem',
> > "param('lim')"=>'lim',
>
> ...
>
> > instead of getting the values (1
> > and 2), I get as keys the strings 'param(app)'
>
> You are specifying the keys as strings in the form "param('app')"
> yourself. That's what you told your program to do. How do you expect
> anything else to happen?
>
> If, instead, you had used
>
> my %hashfruit=(
> param('app') =>'app',
> param('lem') =>'lem',
> param('ora') =>'ora',
> param('lem') =>'lem',
> param('lim') =>'lim',
> );
>
> the results of the param calls would be stringified.
>
> Of course, you are not performing any sanity checks on the inputs so
> this has the potential of becoming problematic. By giving each textfield
> a different name, you are making life unnecessarily hard.
>
> Instead, use the same name, say 'rank', for all the textfields. That
> way, things like checking that all the ranks are distinct, all the ranks
> are numbers etc becomes a much easier operation and you don't have to
> make a whole bunch of changes every time you change the list of fruits.
>
> As your scripts are too messy to modify, here is an alternative:
>
> #!perl
>
> use strict;
> use warnings;
>
> use CGI qw( -no_xhtml );
>
> my @FRUITS = qw( apple orange lemon lime banana );
>
> my $cgi = CGI->new;
> print $cgi->header( 'text/html' );
>
> unless ( $cgi->param ) {
> show_form( $cgi );}
>
> else {
> process_form( $cgi );
>
> }
>
> sub show_form {
> my $cgi = shift;
> my ( $msg ) = @_;
>
> print $cgi->start_html;
>
> if ( $msg ) {
> print $cgi->p( $cgi->em( $msg ) );
> }
>
> print $cgi->start_form( -method => 'GET' );
>
> for my $fruit ( @FRUITS ) {
> print $cgi->p(
> $cgi->textfield( -name => 'rank', -size => 1 ), $fruit
> );
> }
>
> print $cgi->p( $cgi->submit, $cgi->reset ),
> $cgi->end_form,
> $cgi->end_html;
> return;
>
> }
>
> sub process_form {
> my $cgi = shift;
> my @ranks = $cgi->param( 'rank' );
>
> for my $rank ( @ranks ) {
> $rank =~ s/^\s+//;
> $rank =~ s/\s+$//;
>
> unless ( $rank =~ /^(\d+)$/
> and $rank => 1
> and $rank <= @FRUITS
> ) {
> return show_form(
> $cgi,
> sprintf(
> 'Ranks must be integers between %d and %d.',
> 1, scalar @FRUITS
> )
> );
> }
> }
>
> my %ranked;
> @ranked{ @ranks } = @FRUITS;
>
> unless ( keys %ranked == @FRUITS ) {
> return show_form(
> $cgi,
> 'Please fill in all spaces with distinct ranks.'
> );
> }
>
> print $cgi->start_html,
> $cgi->ol(
> $cgi->li(
> [ map { $ranked{ $_ } } sort keys %ranked ]
> )
> ),
> $cgi->end_html;
> return;
>
> }
>
> __END__
>
> --
> A. Sinan Unur <1...@llenroc.ude.invalid>
> (remove .invalid and reverse each component for email address)
> clpmisc guidelines:

Dr. A. Sinan Unur: Thank you very much for both these approaches and
their explanations. This may have been too elementary a question for
this newsgroup, but I got a lot of bad advice from the beginners'
group. Thanks again.

Re: making the keys of a hash from parameters collected from a form

am 29.11.2007 12:37:29 von krahnj

mike wrote:
>
> Dr. A. Sinan Unur: Thank you very much for both these approaches and
> their explanations. This may have been too elementary a question for
> this newsgroup, but I got a lot of bad advice from the beginners'
> group. Thanks again.

Its a *beginners* mailing list, what did you expect? Maybe you should
have asked on the beginners-cgi mailing list instead?


John
--
use Perl;
program
fulfillment

Re: making the keys of a hash from parameters collected from a form

am 29.11.2007 12:58:19 von 1usa

mike wrote in news:77709129-47b2-42a3-a131-
fcbc069a3034@b15g2000hsa.googlegroups.com:


> Dr. A. Sinan Unur: Thank you very much for both these approaches and
> their explanations. This may have been too elementary a question for
> this newsgroup, but I got a lot of bad advice from the beginners'
> group. Thanks again.

You are welcome. Just a couple of points: First, I appreciate your polite
gesture, but in this group, I am simply Sinan. Second, and more
pertinently, I generally don't use the HTML generation methods provided by
CGI.pm. I would recommend you to look at some of the excellent templating
modules on CPAN (I stick with HTML::Template but there are others) so as
for neater separation between code and presentation. Finally, do read the
posting guidelines for this group, if you read and follow them, you will
find that asking questions (and getting answers) in this group is a much
more rewarding experience than you can get on any beginners list.

Good luck.

Sinan

--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(remove .invalid and reverse each component for email address)
clpmisc guidelines:

Re: making the keys of a hash from parameters collected from a form

am 30.11.2007 03:57:40 von rvtol+news

A. Sinan Unur schreef:

> unless ( $rank =~ /^(\d+)$/
> and $rank => 1
> and $rank <= @FRUITS

s/=>/>=/

--
Affijn, Ruud

"Gewoon is een tijger."

Re: making the keys of a hash from parameters collected from a form

am 30.11.2007 04:10:09 von 1usa

"Dr.Ruud" wrote in news:fio1o8.1hk.1
@news.isolution.nl:

> A. Sinan Unur schreef:
>
>> unless ( $rank =~ /^(\d+)$/
>> and $rank => 1
>> and $rank <= @FRUITS
>
> s/=>/>=/

Thanks for catching that.

Sinan
--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(remove .invalid and reverse each component for email address)
clpmisc guidelines: