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, 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!
      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) {