this my code.At the end of this process I want to collect name and sum results with ascending order and want to print.I tried to take the as @sum1 and @sum2 but it couldn't know @sum functions.How can I do that or any idea will be very valuable.
#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw( sum );
use Data::Dumper qw(Dumper);
my %grades;
$grades{"Ahmet"}{quiz1} = 97;
$grades{"Ahmet"}{quiz2} = 67;
$grades{"Ahmet"}{quiz3} = 93;
$grades{"Mehmet"}{quiz1} = 88;
$grades{"Mehmet"}{quiz2} = 82;
$grades{"Mehmet"}{quiz3} = 99;
print Dumper \%grades;
print "----------------\n";
foreach my $name ( sort keys %grades ) {
my %hash1 = (
'Ahmet' => [ 97, 67, 93 ],
'Mehmet' => [ 88, 82, 99 ],
);
my @sums;
for my $key ( keys %hash1 ) {
my $sum = sum @{ $hash1{$key} };
push @sums, "$key: $sum\n";
}
foreach my $sum ( keys %{ $grades{$name} } ) {
print "$name : $grades{$name}{$sum}\n";
}
print @sums;
}
foreach my $name ( sort keys %grades ) {
print "$grades{$name}\n";
}
my %grades2;
$grades2{"Merve"}{quiz1} = 33;
$grades2{"Merve"}{quiz2} = 41;
$grades2{"Merve"}{quiz3} = 59;
$grades2{"Aslı"}{quiz1} = 79;
$grades2{"Aslı"}{quiz2} = 31;
$grades2{"Aslı"}{quiz3} = 62;
print Dumper \%grades2;
print "----------------\n";
foreach my $name2 ( sort keys %grades2 ) {
my %hash = (
'Merve' => [ 33, 41, 59 ],
'Aslı' => [ 79, 31, 62 ],
);
my @sums2;
for my $key ( keys %hash ) {
my $sum = sum @{ $hash{$key} };
push @sums2, "$key: $sum\n";
}
foreach my $sum ( keys %{ $grades2{$name2} } ) {
print "$name2 : $grades2{$name2}{$sum}\n";
}
print @sums2;
}
foreach my $name2 ( sort keys %grades2 ) {
print "$grades2{$name2}\n";
}
my %info;
$info{$_} .= "A" for keys %grades;
$info{$_} .= "B" for keys %grades2;
for ( sort keys %info ) {
print "$_ : $info{$_}\n";
}
You seem to duplicate some information in your code. Once you populate the %grades, there's no need to create the %hash - it can be extracted from the %grades directly.
To populate the hashes, you don't have to repeat the keys all the time, describe the substructure as shown below.
Also, your code contains "ı", which isn't an ASCII character. It would be nicer to tell Perl that by using utf8 and also declaring the encoding of the output.
To sort the output by sums, use the sort function with a custom block that compares the hash elements:
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use open ':encoding(UTF-8)', ':std';
use List::Util qw( sum );
my %grades = (
Ahmet => {
quiz1 => 97,
quiz2 => 67,
quiz3 => 93,
},
Mehmet => {
quiz1 => 88,
quiz2 => 82,
quiz3 => 99,
}
);
my %sum;
for my $name (keys %grades)
{
$sum{$name} = sum(values %{ $grades{$name} });
}
for my $name (sort { $sum{$a} <=> $sum{$b} } keys %sum)
{
print $name, ' ', $sum{$name}, "\n";
}
my %grades2 = (
Merve => {
quiz1 => 33,
quiz2 => 41,
quiz3 => 59,
},
Aslı => {
quiz1 => 79,
quiz2 => 31,
quiz3 => 62,
},
);
my %sum2;
for my $name (keys %grades2)
{
$sum2{$name} = sum(values %{ $grades2{$name} });
}
for my $name (sort { $sum2{$a} <=> $sum2{$b} } keys %sum2)
{
print $name, ' ', $sum2{$name}, "\n";
}
Here is a way to do it. You are creating a hash of hash ref, which is explicitly done like this (I have added one more student to make the example more interesting):
my %grades = (
'Ahmet' => {
quiz1 => 97,
quiz2 => 67,
quiz3 => 93,
},
'Mehmet' => {
quiz1 => 88,
quiz2 => 82,
quiz3 => 99,
},
'Abdul' => {
quiz1 => 99,
quiz2 => 89,
quiz3 => 99,
},
);
To print the students and their grades, you may use:
# Printing the students and grades
foreach my $student ( keys %grades ) {
print $student, ":\n";
foreach my $test ( keys %{$grades{$student}} ) {
print " - ", $test, "\t", $grades{$student}{$test}, "\n";
}
}
To generate the sum for each student:
# Generating a sum for each student
my %sums;
foreach my $student ( keys %grades ) {
$sums{$student} = sum0 map { $grades{$student}{$_} } keys %{$grades{$student}};
}
I use sum0
which will return 0
instead of undef
when the list it is given is empty. You should use use List::Util qw( sum0 );
at the beginning.
Then printing the generated sum in ascending order:
# Printing the sum
foreach my $student ( sort { $sums{$a} <=> $sums{$b} } keys %sums ) {
print $student, ":\t", $sums{$student}, "\n";
}
For the opposite order, you may use sort { $sums{$b} <=> $sums{$a} } keys %sums
. For the rest of your code, you would do the same...
The output of the students:
Ahmet:
- quiz1 97
- quiz3 93
- quiz2 67
Mehmet:
- quiz2 82
- quiz3 99
- quiz1 88
Abdul:
- quiz2 89
- quiz3 99
- quiz1 99
Then the sum of the grades:
Ahmet: 257
Mehmet: 269
Abdul: 287