Fields won't add when reading a text file

N

NevadaSam

In learning CGI/Perl I am trying to write a script that will read
records and print the total number of people registered for each
seminar.
This is the script I have been working on all day and the text file
which it reads follows it.


#!/usr/bin/perl
#list.cgi - reads form data to a file, and creates a dynamic
#Web page that displays people registering for different seminars.
print "Content-type: text/html\n\n";
use CGI qw:)standard -debug);
use strict;

#declare variables
my ($name, $seminar, @records, %sem_count);
my @name_count = (0);
my %sem_count = ("Computer Maintenance", 0,
"Microsoft Office", 0,
"Unix Essentials", 0,
"CGI/Perl", 0);

#calculate people registered and seminar count
open(INFILE, "<", "list.txt")
or die "Error opening list.txt. $!, stopped";
my @records = <INFILE>;
close(INFILE);
foreach my $rec (@records) {
chomp($rec);
($name, $seminar) = split(/,/ , $rec);
$name_count [$name] = $name_count[$name] + 1;
$sem_count {$seminar} = $sem_count{$seminar} +1;
}

#generate HTML
print "<html><head><title>Seminar Workshop</title></head>\n";
print "<body>\n";
print "<table>\n";
print "<tr align='left'><th>Seminar</th> <th>Registered</th></tr>\n";
foreach my $key ("Computer Maintenance", "Microsoft Office", "Unix
Essentials", "CGI/Perl") {
print "<tr><td>$key</td> <td>$sem_count{$key}</td></tr>\n";
}
print "</table>\n";
print "<br /><br />Total registered: $name_count[$name]\n";
print "</body></html>\n";



Text file:

Janice Alto,3
Nancy Perez,1
James Houza,2
Beth Jimminez,2
Michael Hiller,4
Inez Smith,4
Paul Eniudo,3
Tess Bacza,2
Robert Hau,1
Opal Jones,2



The first field in the text file is a name which I have been able to
add all together to get a total of 10. What I haven't figured out how
to do is total the second field to get the number attending each
seminar. The numbers represent which seminar by 1-Computer Maintenance,
2-Microsoft Office, 3-Unix Essentials, and 4-CGI/Perl. I keep coming up
with 0 for each event.

Thanks for any ideas you may have.
 
G

Gunnar Hjalmarsson

This is the script I have been working on all day and the text file
which it reads follows it.

<script and data snipped>

These are a few hints:
The numbers represent which seminar by 1-Computer Maintenance,
2-Microsoft Office, 3-Unix Essentials, and 4-CGI/Perl.

You need to tell Perl that, too. This is one way to do so:

my %translate = (
1 => 'Computer Maintenance',
2 => 'Microsoft Office',
3 => 'Unix Essentials',
4 => 'CGI/Perl',
);

And in the loop:

$sem_count{ $translate{$seminar} } ++;

As regards the number of names/records, you can just use the @records
array in scalar context:

print "<br /><br />Total registered: " . @records . "\n";

Your use of a @name_count array is incorrect, and generates a bunch of
warnings if warnings are enabled (which should be the case...).

Warnings may give you a couple of other hints.
 
T

Tad McClellan

In learning CGI/Perl


Learning two things at once makes it more than twice as hard.

It will be easier if you learn one at a time.

Start with learning Perl.

Learn your application area after you have at least some
familiarity with the programming language.

Also, please see the Posting Guidelines that are posted here frequently.

I am trying to write a script that will read
records and print the total number of people registered for each
seminar.
use CGI qw:)standard -debug);


There is no point in including a module if you are not going
to make use of any of its features.

use strict;


You should always enable warnings when developing Perl code:

use warnings;

#declare variables
my ($name, $seminar, @records, %sem_count);


You should declare each variable at its first use, rather
than all at the top.

my @name_count = (0);


Why is this an array?

my %sem_count = ("Computer Maintenance", 0,
"Microsoft Office", 0,
"Unix Essentials", 0,
"CGI/Perl", 0);

#calculate people registered and seminar count
open(INFILE, "<", "list.txt")
or die "Error opening list.txt. $!, stopped";
my @records = <INFILE>;
close(INFILE);
foreach my $rec (@records) {
chomp($rec);


Reading them all into an array only to process them one-at-a-time
anyway is silly.

If you are going to process them one-at-a-time, then simply
read them one at a time.

($name, $seminar) = split(/,/ , $rec);
$name_count [$name] = $name_count[$name] + 1;


You should always enable warnings when developing Perl code.

It would have pointed out what your problem is.

What is in $name? A string.

You are using a string as an array index, so the string
will be converted to a number to use for indexing the array.

All of your strings will evaluate to zero when you use them
where Perl was expecting a number (like in an array index).

So, you keep adding things to $array[0], and never have
any other elements in the array.

Why? A scalar can hold a number (count) just fine, you don't
need an array for that.

$sem_count {$seminar} = $sem_count{$seminar} +1;


What is in $seminar? A number.

So, the hash keys here will all be numbers, while you earlier
put 4 _string_ keys in there.

You should print out your intermediate data structures when
debugging to see if they contain what you think they contain:

print "$_ ==> $sem_count{$_}\n" for sort keys %sem_count;

}

#generate HTML


If you are not having a problem printing the HTML, then we don't
need to see the printing of the HTML.

foreach my $key ("Computer Maintenance", "Microsoft Office", "Unix
Essentials", "CGI/Perl") {


You only examine the stringy keys, you never look a the numbery keys.

print "<tr><td>$key</td> <td>$sem_count{$key}</td></tr>\n";
}

What I haven't figured out how
to do is total the second field to get the number attending each
seminar. The numbers represent which seminar by 1-Computer Maintenance,
2-Microsoft Office, 3-Unix Essentials, and 4-CGI/Perl. I keep coming up
with 0 for each event.


That is because you are adding to $sem_count{1} instead of
to $sem_count{'Computer Maintenance'} when counting.


---------------------------------
#!/usr/bin/perl
use warnings;
use strict;

my %course_codes = ( 1 => 'Computer Maintenance',
2 => 'Microsoft Office',
3 => 'Unix Essentials',
4 => 'CGI/Perl'
);

my $name_count;
my %sem_count;
while ( my $rec = <DATA> ) {
chomp($rec);
my($name, $sem_num) = split(/,/ , $rec);
$name_count++;
$sem_count{ $course_codes{$sem_num} }++;
}

foreach my $key ("Computer Maintenance", "Microsoft Office",
"Unix Essentials", "CGI/Perl") {
print "$key ==> $sem_count{$key}\n";
}
print "Total registered: $name_count\n";

__DATA__
Janice Alto,3
Nancy Perez,1
James Houza,2
Beth Jimminez,2
Michael Hiller,4
Inez Smith,4
Paul Eniudo,3
Tess Bacza,2
Robert Hau,1
Opal Jones,2
---------------------------------

Thanks for any ideas you may have.


Indent your code to help show the structure of your program.

Get your program working from the command line before moving
it to a CGI environment for further testing.
 
N

NevadaSam

Thanks everyone. The information I have received has been very helpful.
I am new at learning this and the text I am using is not the best. My
problem with this is solved. Thanks again.
 
T

Tad McClellan

I am new at learning this and the text I am using is not the best.


What text are you using?

Helping to save others from poor books is something you can
contribute even when learning...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top