britney has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,
I am learning perl , I just wonder if I have a flat file.

record.txt

Toyota|California||||| Toyota|California||||| Toyota|Arizona||||| Toyota|Nevada||||| Toyota|Florida||||| Honda|California||||| Honda|Florida||||| Honda|Arizona|||||
How we write a code to have a result is:
MADE CALIFORINA ARIZONA NEVADA FLORIDA TOTAL ==== ========== ======= ====== ======= ===== Toyota 2 1 1 1 5 Honda 1 1 0 1 3
I can only do:
MADE TOTAL ==== ===== Toyota 5 Honda 3
Here are some of my code:
#!/opt/WWW/tools/perl5/perl #summarize.cgi open (DATA,"record.txt") || die ("Can't Open data File \n"); @data=<DATA>; close DATA; foreach $line (@data) { ($made, $state, $tmp , $tmp, $tmp, $tmp)=split(/\|/,$line); if ($made) { $count{$made}++; } if ($state) { $countstate{$state}++; } } &header_response; $x=0; foreach $made (keys %count) { $x++; print "<TR ><TD>$x</TD><TD><b>$made&nbsp;</b></TD><TD>$count{$made} +&nbsp;</TD></TR> \n"; } &close_response; &log_response; $z=0; foreach $LogOp (keys %countstate) { $z++; print "<TR ><TD>$z</TD><TD><b>$state&nbsp;</b></TD><TD>$countstate +{$state}&nbsp;</TD></TR> \n"; } &footer_response;
Can you help me to solve this problem ?

Thank you very much

Edit by dws to rescue formatting

Replies are listed 'Best First'.
Re: Need help , newbie cgi
by kabel (Chaplain) on Sep 13, 2002 at 07:29 UTC
    the problem arises NOT from the fact that you consider yourself a "cgi newbie". your data structure is too flat :) i used a HoH for that. the first hash is "entered" with the name and returns another hash which is "entered" by the state.
    use strict; use warnings; use diagnostics; my $file = "c:\\test.data"; my ($type, $state); my %data; my %states; open (FH, $file) or die "[$file]:[$!]"; while (<FH>) { ($type, $state) = split (/\|/, $_); if ((defined $type) and (defined $state)) { $type =~ s/^\s*//; $type =~ s/\s*$//; $state =~ s/^\s*//; $state =~ s/\s*$//; $data{$type}->{$state} ++; $states{$state} = 1; } } close (FH); print qq~<table border="1">\n~; print_header (\%states); print_data (\%data, \%states); print "</table>\n"; ############################################################ sub print_data { ############################################################ my ($data_ref, $states_ref) = @_; foreach my $type (keys %$data_ref) { my $total_for_this_type = 0; print "<tr>\n"; print "\t<td>$type</td>\n"; foreach my $state (keys %$states_ref) { $data_ref->{$type}->{$state} or $data_ref->{$type}->{$stat +e} = 0; print "\t<td>", $data_ref->{$type}->{$state}, "</td>\n"; $total_for_this_type += $data_ref->{$type}->{$state}; } print "\t<td>$total_for_this_type</td>\n"; print "</tr>\n"; } } ############################################################ sub print_header { ############################################################ my ($states_ref) = @_; print "<tr>\n"; print "\t<td>MADE</td>\n"; foreach (keys %$states_ref) { print "\t<td>$_</td>\n"; } print "\t<td>TOTAL</td>\n"; print "</tr>\n"; print "<tr>\n"; print "\t<td>====</td>\n"; foreach (keys %$states_ref) { print "\t<td>", "=" x length ($_), "</td>\n"; } print "\t<td>=====</td>\n"; print "</tr>\n"; }
    this code can surely be improved (the whole print stuff, %states is not beautiful etc). i just wanted to provide a starting point for you. perl scripts like that (first process data, then print it out) "live" from their datastructure.
      Hi Kabel, I works great, but I still stuck one more thing. How can I sort it by State when it display ? Do you think we can do it ? Thanks

        replace

        foreach my $state (keys %$states_ref) { by foreach my $state (sort keys %$states_ref) {
      Hi Kabel, Thank for your help, can you show me how to make it appear on the web ? I can make it run, but can not show on web. Thanks again.
        try this code:
        use strict; use warnings; use CGI; my $cgi = CGI::->new (); print $cgi->header (); print $cgi->start_html (); # # whatever you want, do it here ;) # print $cgi->h1 ("hello, world!"); print $cgi->hr (); print $cgi->end_html ();
        instead of the two print statements, put in the code from my first posting. then copy the resulting script inside the /cgi-bin directory in your document root and try get it from a browser. enjoy!