Accessing hashes and converting into an array

R

Rohit S

==========================================================================
Using DBI Perl Programming I get a database o/p as
below
Student SubjectCode Marks
------------------------------------------------
A Ma 90
A Sc 89
B Ma 70
B Sc 71
B Ge 71
C Sc 73
C Ge 97
... ... ...
-------------------------------------------------
Subject code may vary to any value.
I need a report o/p in the following format and
displayed in HTML
Student Ma Sc Ge .....
------------------------------------------------
A 90 89
B 70 71 71
C 73 97
-------------------------------------------------


# chuck all the data into an array
my $students;
while (my $row = $sth->fetchrow_hashref) {
$students->{$row->{$student}}->{$row->{$subject}} = $row->{$mark};


foreach $student(sort keys %$students) {
print $student, "\t";
foreach $subject(sort keys %{$students->{$student}}) {
print "\t", $students->{$student}->{$subject};
}
print "\n";
}


================================================================
The subject field would vary
But this doesnt seem to work.I also need to put the values in an matrix.

Could anyone pls help me out in this.

Regards
Rohit
 
P

Paul Lalli

in message AND in message
Please don't do that. Post once. And for damned sure don't change
subjects.

# chuck all the data into an array
my $students;
while (my $row = $sth->fetchrow_hashref) {
$students->{$row->{$student}}->{$row->{$subject}} = $row->{$mark};

Is there some reason you don't have your while loop being ended?
Please post real code. Have you seen the guidelines that are posted
here frequently?
foreach $student(sort keys %$students) {
print $student, "\t";
foreach $subject(sort keys %{$students->{$student}}) {
print "\t", $students->{$student}->{$subject};
}
print "\n";
}


================================================================
The subject field would vary
But this doesnt seem to work.I also need to put the values in an
matrix.

"Doesn't Work" is an absolutely abhorrent phrase. It tells us
absolutely nothing. How did it not work? What were you expecting, and
in what way did the results differ? Have you seen the guidelines that
are posted here frequently?
Could anyone pls help me out in this.

The following quick script, based on your code above (modified to
populate with dummy data and make it strict compliant only), works fine
for me.

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

my $students;

$students->{Paul}->{CS1} = 95;
$students->{Paul}->{Math} = 90;
$students->{Paul}->{Phil} = 100;
$students->{Justin}->{CS1} = 85;
$students->{Justin}->{Math} = 80;
$students->{Justin}->{Phil} = 70;

foreach my $student(sort keys %$students) {
print $student, "\t";
foreach my $subject(sort keys %{$students->{$student}}) {
print "\t", $students->{$student}->{$subject};
}
print "\n";
}
__END__
Justin 85 80 70
Paul 95 90 100

I surmise then, that the problem is with how you are either storing the
data in your database or with how you are retrieving it.

So here's a huge hint: Make your script strict-compliant. Add use
strict; to the beginning of your script. Declare your variables. You
should almost immediately see the problem with how you are retrieving
your data.

Paul Lalli
 
A

A. Sinan Unur

(e-mail address removed) (Rohit S) wrote in

Don't post the same message repeatedly (and with different subject lines
at that).
Using DBI Perl Programming I get a database o/p as

What is o/p?
below
Student SubjectCode Marks
------------------------------------------------
A Ma 90
A Sc 89
B Ma 70
B Sc 71
B Ge 71
C Sc 73
C Ge 97
... ... ...
I need a report o/p in the following format and
displayed in HTML

What is o/p?
Student Ma Sc Ge .....
------------------------------------------------
A 90 89
B 70 71 71
C 73 97
-------------------------------------------------


# chuck all the data into an array
my $students;
while (my $row = $sth->fetchrow_hashref) {
$students->{$row->{$student}}->{$row->{$subject}} = $row->{$mark};


foreach $student(sort keys %$students) {
print $student, "\t";
foreach $subject(sort keys %{$students->{$student}}) {
print "\t", $students->{$student}->{$subject};
}
print "\n";
}

Huh? Post code others can run.
The subject field would vary
But this doesnt seem to work.

Define "work".
I also need to put the values in an matrix.

And what does that mean?
Could anyone pls help me out in this.

I am going to suggest reading the posting guidelines for this group.

#! perl

use strict;
use warnings;

use DBI;

my $dir = $ENV{TMP};
$dir =~ s{\\}{/}g;

my $dbh = DBI->connect("DBI:CSV:f_dir=$dir")
or die "Cannot connect: @{[$DBI::errstr]}";


my $sth = $dbh->prepare(qq{
CREATE TABLE a (
student CHAR(1),
subject CHAR(2),
marks INTEGER
)}
) or die "Cannot prepare: @{[$dbh->errstr]}";

$sth->execute or die "Cannot execute: @{[$sth->errstr]}";

while(<DATA>) {
my ($student, $subject, $marks) = split;

$dbh->do("INSERT INTO a VALUES (
@{[$dbh->quote($student)]},
@{[$dbh->quote($subject)]},
$marks)"
);
}

$sth = $dbh->prepare("SELECT * from a");
$sth->execute or die "Cannot execute: @{[$sth->errstr]}";

my $students = {};

while(my $row = $sth->fetchrow_hashref) {
$students->{$row->{student}}->{$row->{subject}}->{marks} = $row->
{marks};
}

for my $student (sort {$a cmp $b} keys %{$students}) {
print "$student\t";
for my $subject (sort {$a cmp $b} keys %{$students->{$student}}) {
print $students->{$student}->{$subject}->{marks}."\t";
}
print "\n";
}

$sth->finish;
$dbh->disconnect;

__DATA__
A Ma 90
A Sc 89
B Ma 70
B Sc 71
B Ge 71
C Sc 73
C Ge 97
 
C

ctcgag

=========================================================================
=
Using DBI Perl Programming I get a database o/p as
below
Student SubjectCode Marks
------------------------------------------------
A Ma 90
A Sc 89
B Ma 70
B Sc 71
B Ge 71
C Sc 73
C Ge 97
... ... ...

What is o/p?
Student Ma Sc Ge .....

What array would that be?
my $students;
while (my $row = $sth->fetchrow_hashref) {
$students->{$row->{$student}}->{$row->{$subject}} = $row->{$mark};

You didn't close the loop, nor did you indent properly.

You may want to keep track of all actually occuring courses:
$seen{$row->{$subject}}++;
}

foreach $student(sort keys %$students) {
print $student, "\t";
foreach $subject(sort keys %{$students->{$student}}) {

## You want all the subjects to line up under each other, so:
foreach $subject(sort keys %seen) {
## (of course, you should reall sort once, store in array)
print "\t", $students->{$student}->{$subject};
}
print "\n";
}


Xho
 
R

Rohit S

I need to store the data in an array of hash.

Here the value of the key(subject) varies to as many.
i.e
student M Sc Ge ... ... ...
$ora_data[0] John 70 80 90
$ora_data[1] Paul 30 40 50
$ora_data[2] brian 55 35 46
================================================================================

#!/usr/bin/perl

use strict;
use CgiLib;
use HTML;
#template engine uses the HTML template file and the db_results array
to
#display the report data.
use template
use Datetime;
use oracle;
use CGI::Carp qw(fatalsToBrowser);
use DBI;


sub getData {
# Call the oracle database and get the report information requested
my ($pagename,$strClass,$dataView,$dbh) = @_;
my @ora_data;
my $loopindex = 0;
my $student = 0;
my $subject = 0;
my $marks = 0;
my @acsubjects;
my $isubjects = 0;


my $query = "select distinct subject from V_API_STUDENT_REPORT ";
$query.= "order by subject";
# Database handler is already open, just need a statement handler.
my $sth = $dbh->prepare($query);
$sth->execute ();
$sth->bind_columns (\$isubjects);
while ($sth->fetch) {
$acsubjects[$loopindex] = $isubjects;
$ora_data[$loopindex]{'SUBJECT'} = $isubjects;
$loopindex++;
}
my $ilengacsubjects = @acsubjects;

my $sql = "select student_code||student_name as student, subject,
marks ";
$sql .= "from V_API_STUDENT_REPORT ";
$sql .= "where class = UPPER('$strClass') "; #The class 1st
standard, ie. the grade

# Database handler is already open, just need a statement handler.
my $sth = $dbh->prepare($sql);
$sth->execute ();
$sth->bind_columns (\$student,
\$subject,
\$marks);

# chuck all the data into an array
my $index=0;
my $count=1;
while ($sth->fetch)
{
#checks for the first record
if (($count == 1) && ($student ne "")){
$ora_data[$index]{'student'} = $student;
$count++;
}
#if the student record is not equal to the next record create
another row
if (( $ora_data[$index]{'student'} ne $student) && ($student ne
"")){
$index++;
$ora_data[$index]{'student'} = $student;
}
#if the student record is equal to the next record compare the
subject code
#and populate the marks column.
if (($ora_data[$index]{'student'} eq $student) && ($student ne
"")) {

for (my $iIndex = 0 ; $iIndex < $ilengacsubjects ;$iIndex++) {

if ($subject == $acsubjects[$iIndex]) {
$ora_data[$index]{$iIndex}{'MARKS'} = $marks;

}
}
}
}
# close statement handler and pass the results back.
$sth->finish;
return @ora_data;
}
#-----------------------------------------------------------------
the main function calls the getData subroutine.
The below code is a piece of code from the main.I have done some basic
data validations which I have not shown here.
#-------------------------------------------------------------
main :
{
@db_results = getData($pagename,$strClass,$dataView,$dbh);
template::displayTemplate("show_marks.html.tem",@db_results);

}



========================================================================

The other code that I tried is


# Database handler is already open, just need a statement handler.
my $sth = $dbh->prepare($sql);
$sth->execute ();
$sth->bind_columns (\$student,
\$subject,
\$marks);
my $students;
while ( my $row = $sth->fetchrow_hashref) {
$students->{$row->{'STUDENT'}}->{$row->{'SUBJECT'}} =
$row->{'MARKS'};

}

my $index = 0;

foreach $student (sort keys %$students) {
print $student, "\t";
$ora_data[$index]{"STUDENT"} = $student;
foreach $subject (sort keys %{$students->{$subject}}) {
$ora_data[$index]{"SUBJECT"}{"MARKS"} = $mark;
print "\t", $students->{$student}->{$subject};
}
$index++;
print "\n";
}

==============================================================
In the above code I am getting only the 3rd students name .

The process is as follows.
I have a HTML template which parses the value defined i.e "STUDENT"
in the perl file.
A HTML template engine is used to display the rows.

The HTML template is given below.Name of the HTML :
show_marks.html.tem

---------------------------------------------------------------

<DIV ALIGN="center">
<TABLE BORDER="1" WIDTH="90%" BORDERCOLOR="#000000" CELLSPACING="0">

<TR BGCOLOR="#4682B4">
<TD width="9%"><FONT face="Verdana,Arial" size="2"
color="WHITE"><B>Student</B></FONT></TD>
|<|CELL:4|>|
<TD width="9%"><FONT face="Verdana,Arial" size="2"
color="WHITE"><B>|<|SUBJECT|>|</B></FONT></TD>
|<|ECELL|>|
</TR>
|<|BODY|>|
|<|DR|>|
<TR BGCOLOR="#ffffff">
<TD><FONT face="Verdana,Arial" size="2"
color="BLACK">|<|STUDENT|>|</FONT>&nbsp;</TD>
|<|CELL:4|>|
<TD><FONT face="Verdana,Arial" size="2"
color="BLACK">|<|MARKS|>|</FONT>&nbsp;</TD>
|<|ECELL|>|
</TR>
|<|EBODY|>|
</TABLE>
</DIV>

<BR></FONT>
------------------------------------------------------------------------------------------

The template engine parses the BODY tag and loops thru the
ora_data(array in which the data is stored)
and displays the data row.
The CELL tag is used to display variable columns.
the DR tag rewinds the ora_data array to the first index.
 
E

Eric Bohlman

^^
^^ where is the semicolon?


Looks like we are not looking that the same code that you
are looking at, since our's will not even compile, and it
sounds like your's is executing...

Which is so bad that it made Tad forget how to use apostrophe's :)
 
R

Rohit S

Ok Let me put this way
How do I print the following

ora_data[0]{'STUDENT' => joe,
'SUBJECT' => { 'M' => 78,
'SC' => 80
}
}

ora_data[1]{'STUDENT' => phil,
'SUBJECT' => { 'M' => 84,
'GE' => 89
}
}

ora_data[2]{'STUDENT' => steve,
'SUBJECT' => { 'SC' => 84,
'GE' => 89,
'ENG' => 95
}
}
------------------------------------------------------------
 
T

Tad McClellan

Rohit S said:
How do I print the following

ora_data[0]{'STUDENT' => joe,
'SUBJECT' => { 'M' => 78,
'SC' => 80
}
}

ora_data[1]{'STUDENT' => phil,
'SUBJECT' => { 'M' => 84,
'GE' => 89
}
}

ora_data[2]{'STUDENT' => steve,
'SUBJECT' => { 'SC' => 84,
'GE' => 89,
'ENG' => 95
}
}


Easy!


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

print <<ENDSTUFF;
ora_data[0]{'STUDENT' => joe,
'SUBJECT' => { 'M' => 78,
'SC' => 80
}
}

ora_data[1]{'STUDENT' => phil,
'SUBJECT' => { 'M' => 84,
'GE' => 89
}
}

ora_data[2]{'STUDENT' => steve,
'SUBJECT' => { 'SC' => 84,
'GE' => 89,
'ENG' => 95
}
}
ENDSTUFF
----------------------


The quality of the answer is often directly proportional to the
care taken in composing the question.

Have you seent the Posting Guidelines that are posted here frequently?
 
T

Tad McClellan

Rohit S said:
How do I print the following

ora_data[0]{'STUDENT' => joe,
'SUBJECT' => { 'M' => 78,
'SC' => 80
}
}

ora_data[1]{'STUDENT' => phil,
'SUBJECT' => { 'M' => 84,
'GE' => 89
}
}

ora_data[2]{'STUDENT' => steve,
'SUBJECT' => { 'SC' => 84,
'GE' => 89,
'ENG' => 95
}
}
 
T

Tad McClellan

Rohit S said:
How do I print the following

ora_data[0]{'STUDENT' => joe,
'SUBJECT' => { 'M' => 78,
'SC' => 80
}
}


print "$ora_data[0]{STUDENT}\n"; # prints "joe"
print "$ora_data[0]{SUBJECT}{SC}\n"; # prints "80"
 
J

Jürgen Exner

Rohit said:
Ok Let me put this way
How do I print the following

ora_data[0]{'STUDENT' => joe,
'SUBJECT' => { 'M' => 78,
'SC' => 80
}
[...]

I'd use Data::Dumper

jue
 
A

A. Sinan Unur

Rohit said:
Ok Let me put this way
How do I print the following

ora_data[0]{'STUDENT' => joe,
'SUBJECT' => { 'M' => 78,
'SC' => 80
}
[...]

I'd use Data::Dumper
Oh, but the OP wanted HTML output! :)

#! perl

use strict;
use warnings;

use Data::HTMLDumper;
$Data::Dumper::Sortkeys = 1;

my @ora_data = (
{
STUDENT => 'joe',
SUBJECT => { 'M' => 78, 'SC' => 80 }
},
{
STUDENT => 'phil',
SUBJECT => { 'M' => 84, 'GE' => 89 }
},
{
STUDENT => 'steve',
SUBJECT => { 'SC' => 84, 'GE' => 89, 'ENG' => 95 }
},
);

print Dumper \@ora_data;

To the OP: Don't expect to get any more serious answers until you have
shown that you are taking the first round of serious answers seriously.

Sinan.
 

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

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,076
Latest member
OrderKetoBeez

Latest Threads

Top