http://www.perlmonks.org?node_id=851351

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

i have a database of student name and score of 5 subjects....and the problem is if a student score is less than 50 in any subject then i have to print out the corresponding student name and the subject or subjects in which he score less than 50.here i made the database but having probs in printing out the subject name when he score less than 50 in more than 1 subject..i want the output to be like

Amir fails in : english Maths hindi

if the marks in these 3 subjects is less than 50.

i have written the code like

#!/usr/bin/perl #%studentbase is the hash, my @header = ("Name","English", "History", "Maths","Science","Geography"); $studentcount =0; while ($input =<STDIN>){ $input=~ s/^\s+|\s+\n$//g;#remove the heading n trailing space @subinfo = split (/\s+/,$input); $studentlist[$studentcount++]= $subinfo[0]; for ($count =1; $count <=@subinfo;$count++){ $studentbase{$subinfo[0].$header[$count-1]}=$subinfo[$count-1] +; } } foreach $student(@studentlist){ print " $student fails in :"; for ($count=1;$count <=@subinfo; $count++){ if ($subinfo[$count] <= 50){ print" $header[$count]"; } } }

I am able to get the output for a single line of input but when i give more that 1 line of input I am not able to get the desire output. plz help

Replies are listed 'Best First'.
Re: database using associative has
by jwkrahn (Monsignor) on Jul 26, 2010 at 11:08 UTC

    You may need something like this UNTESTED:

    #!/usr/bin/perl use warnings; use strict; my @header = qw( English History Maths Science Geography ); my %studentlist; while ( <> ) { my ( $name, @subinfo ) = split; @{ $studentlist{ $name } }{ @header } = @subinfo; } foreach my $student ( keys %studentlist ) { print " $student fails in :", join( ' ', grep $studentlist{ $stude +nt }{ $_ } <= 50, @header ), "\n"; }

      Thanks jwkrahm .... can u plz explain the following lines

      @{ $studentlist{ $name } }{ @header } = @subinfo; and print " $student fails in :", join( ' ', grep $studentlist{ $student } +{ $_ } <= 50, @header ), "\n"; }
Re: database using associative has
by JavaFan (Canon) on Jul 26, 2010 at 10:53 UTC
    You store all the data in %studentbase, then use the temporary variable @subinfo (which gets repopulated for each line) to determine which line to print.

    I'd say you're entire design is wrong. There's no need to store the entire database in memory. Just read a line, determine which subjects the student fails, and print a line stating the name and the subjects. Then move to the next student.