Find Average Marks in an Array

Hello Experts!

I already got help on how to calculate Total and Average per Student. Now, I want to find Average Marks per SUBJECT as in the following :

SN       Name                     Eng           Maths         No_of_Subjects    Total      Avg
1          Stu1                        40             45                2                             85          42.5
2          Stu2                        50             55                2                             105        52.5
            Subject Avg.          45              50    

This is the code I'm currently using:
class Student
{
  public $ID;
  public $Name;
  public $Subjects = array();

  // Functions to get Total and Average marks per student
  public function getTotalMarks()
  {
    $total = 0;
    foreach($this->Subjects as $subject => $marks)
    {
      $total += $marks;
    }
    return $total;
  } 

  public function getAverageMarks()
  {
    if(!count($this->Subjects)) { return 0; }
    return round($this->getTotalMarks() / count($this->Subjects), 1);
  } 
}

class ClassName
{
  public $ID;
  public $Name;
  public $Students = array();
  public $SubjectList = array();
}

Open in new window


Thank you so much
Opeyemi AbdulRasheedAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

gr8gonzoConsultantCommented:
I'm guessing you want the averages per each class, so you would adjust the definition of the ClassName. It would looks something like this:

class ClassName
{
  public $ID;
  public $Name;
  public $Students = array();
  public $SubjectList = array();

  public function getSubjectAverages()
  {
    $results = array();
    foreach($this->SubjectList as $subjectName)
    {
      $results[$subjectName] = $this->getSubjectAverage($subjectName);
    }
    return $results;
  }

  // Get the average marks of all students for one subject
  public function getSubjectAverage($subjectName)
  {
      $subjectTotalMarks = 0;
      $subjectStudentsWithMarks = 0;

      foreach$(this->Students as $student)
      {
        if(isset($student->Subjects[$subjectName]))
        {
          $subjectStudentsWithMarks++;
          $subjectTotalMarks += $student->Subjects[$subjectName];
        }
      }

      if($subjectStudentsWithMarks == 0) { return 0; }
      return $subjectTotalMarks / $subjectStudentsWithMarks;
  }
}

Open in new window


And you would call $classObjectHere->getSubjectAverages() to get an array that looked like:

[Eng] = 45
[Maths] = 50
1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Opeyemi AbdulRasheedAuthor Commented:
Please help me out. Which one is $classObject?

I tried it like this but nothing happend:

foreach($Class->SubjectList as $subject)
    {
      $pdf->Cell(10, 5, $subjectName->getSubjectAverage(), 1, 0, 'C');
    }

Open in new window

0
gr8gonzoConsultantCommented:
$Class->getSubjectAverage($subjectName)
0
PMI ACP® Project Management

Prepare for the PMI Agile Certified Practitioner (PMI-ACP)® exam, which formally recognizes your knowledge of agile principles and your skill with agile techniques.

Opeyemi AbdulRasheedAuthor Commented:
Getting zeroes. getting_zeroes.pngPlease see attached.
0
gr8gonzoConsultantCommented:
I noticed I have a typo in my code:
foreach$(this->Students as $student)

should be:
foreach($this->Students as $student)

If you didn't fix that already, that could be the issue. If you DID fix it, then try logging the two variables out somewhere:

      ...
      file_put_contents("/path/to/a/log.file", "{$subjectTotalMarks} / {$subjectStudentsWithMarks}");
      if($subjectStudentsWithMarks == 0) { return 0; }
      return $subjectTotalMarks / $subjectStudentsWithMarks;

...and then check that log file to see which value is 0.
0
Opeyemi AbdulRasheedAuthor Commented:
I already fixed that. The log file shows that both variables are 0

0 / 0
0
gr8gonzoConsultantCommented:
Can you show the actual code you're using for that function?
0
Opeyemi AbdulRasheedAuthor Commented:
Everything:
<?php

require('../assets/library/fpdf.php');
require('../includes/connection.php');
error_reporting(0);
// ================== CLASS DEFINITIONS ==================
class Student
{
  public $ID;
  public $Name;
  public $Subjects = array();

  // Functions to get Total and Average marks per student
  public function getTotalMarks()
  {
    $total = 0;
    foreach($this->Subjects as $subject => $marks)
    {
      $total += $marks;
    }
    return $total;
  } 

  public function getAverageMarks()
  {
    if(!count($this->Subjects)) { return 0; }
    return round($this->getTotalMarks() / count($this->Subjects), 1);
  } 
}

class ClassName
{
  public $ID;
  public $Name;
  public $Students = array();
  public $SubjectList = array();

  public function getSubjectAverages()
  {
    $results = array();
    foreach($this->SubjectList as $subjectName)
    {
      $results[$subjectName] = $this->getSubjectAverage($subjectName);
    }
    return $results;
  }

  // Get the average marks of all students for one subject
  public function getSubjectAverage($subjectName)
  {
      $subjectTotalMarks = 0;
      $subjectStudentsWithMarks = 0;

      foreach($this->Students as $student)
      {
        if(isset($student->Subjects[$subjectName]))
        {
          $subjectStudentsWithMarks++;
          $subjectTotalMarks += $student->Subjects[$subjectName];
        }
      }
      file_put_contents("../assets/log.file", "{$subjectTotalMarks} / {$subjectStudentsWithMarks}");
      if($subjectStudentsWithMarks == 0) { return 0; }
      return $subjectTotalMarks / $subjectStudentsWithMarks;
  }
}

$session = $_POST['session'];
$term = $_POST['term'];
$class_name = $_POST['class_name'];

// ================== QUERY AND ORGANIZE DATA INTO CLASS OBJECTS ==================
// Our top-level data array
$classes = array();

// Query the data and organize it into objects
$rs = $conn->query("SELECT Student_ID, Student_Name, Class_Name, Subject_Code, Total FROM view_subjects_enrollment WHERE Session = '$session' AND Term = '$term' AND Class_Name = '$class_name' ORDER BY Subject_Code");
while($row = $rs->fetch_assoc())
{
  $id      = $row["Student_ID"];
  $name    = $row["Student_Name"];
  $class   = $row["Class_Name"];
  $subject = $row["Subject_Code"];
  $marks   = $row["Total"];

  // Initialize new Class
  if(!isset($classes[$class]))
  {
    $classes[$class] = new ClassName();
    $classes[$class]->Name = $class;    
  }

  // Record the subject for the class
  $classes[$class]->SubjectList[$subject] = $subject;

  // Initialize student
  if(!isset($classes[$class]->Students[$name]))
  {
    $classes[$class]->Students[$name] = new Student();
    $classes[$class]->Students[$name]->ID = $id;
    $classes[$class]->Students[$name]->Name = $name;
  }

  // Add subject marks
  $classes[$class]->Students[$name]->Subjects[$subject] = $marks;
}

class PDF extends FPDF
{
// Page header
function Header() {

  include ('../includes/connection.php');

  $term = $_POST['term'];
  $session = $_POST['session'];
  
    // Logo
    $this->Image('../assets/img/logo.png',10,5,20);
       
    // Title
    $sql = "SELECT * FROM tbl_school WHERE Status = 1";
    $result = $conn->query($sql);

    while($row = $result->fetch_assoc()) {
    $this->SetFont('Arial','B',14);
    $this->Cell(277, 5, $row['Sch_Name'], 0, 1, 'C');
    $this->SetFont('Arial','',10);
    $this->Cell(277, 5, $row['Sch_Address'], 0, 1, 'C');
  }
    $this->SetFont('Arial','B',12);
    $this->Cell(277, 10, 'BROAD SHEET', 0, 1, 'C');
    
}

// Page footer
function Footer()
{
    $currentDate = date("d-m-Y");
    // Position at 1.5 cm from bottom
    $this->SetY(-15);
    $this->SetFont('Arial','B',8);
    $this->Cell(92,5,'Powered by : HardSoft Tech.', 'T', 0, 'L');
    // Page number
    $this->Cell(92,5,'Page '.$this->PageNo().'/{nb}', 'T', 0, 'C');
    $this->Cell(92,5,'Printed @ '.$currentDate, 'T', 1, 'R');
}
}

// Instanciation of inherited class
$pdf = new PDF('L', 'mm', 'A4');
$pdf->AliasNbPages();
$pdf->AddPage();

$pdf->SetFont('Arial','B',9);
$pdf->Cell(92, 5, 'CLASS: '.$class_name, 'B', 0, 'C');
$pdf->Cell(92, 5, 'TERM: '.$term, 'B', 0, 'C');
$pdf->Cell(92, 5, 'SESSION: '.$session, 'B', 1, 'C');

// ================== BUILD OUTPUT TABLE ==================

$pdf->SetFont('Arial','B',8); 
// Now loop through our data
$cnt = 1;
foreach($classes as $Class)
{
  // Build table - column headers
  $pdf->Cell(10, 5, 'SN', 1, 0, 'C');
  $pdf->Cell(20, 5, 'ADM. NO', 1, 0, 'C');
  $pdf->Cell(60, 5, 'NAME', 1, 0, 'C');
  foreach($Class->SubjectList as $subject)
  {
      $pdf->Cell(10, 5, $subject, 1, 0, 'C');
  }

  $pdf->SetFont('Arial','B',6);
  $pdf->Cell(15, 5, 'NO OF SUB.', 1, 0, 'C');

  $pdf->SetFont('Arial','B',8);
  $pdf->Cell(15, 5, 'TOTAL', 1, 0, 'C');
  $pdf->Cell(15, 5, 'AVG', 1, 1, 'C');

  $pdf->SetFont('Arial','',8);
  // Loop through students and populate the table
  foreach($Class->Students as $Student)
  {
    $pdf->Cell(10, 5, $cnt++, 1, 0, 'C');
    $pdf->Cell(20, 5, $Student->ID, 1, 0, 'L');
    $pdf->Cell(60, 5, $Student->Name, 1, 0, 'L');

    foreach($Class->SubjectList as $subject)
    {
        // Display the marks if the student has them for that subject, otherwise display a blank string
    $pdf->Cell(10, 5, (isset($Student->Subjects[$subject]) ? $Student->Subjects[$subject] : ""), 1, 0, 'C');

    }

    $pdf->Cell(15, 5, count($Student->Subjects), 1, 0, 'C');
    $pdf->Cell(15, 5, $Student->getTotalMarks(), 1, 0, 'C');
    $pdf->Cell(15, 5, $Student->getAverageMarks(), 1, 1, 'C');

  }
  $pdf->Cell(10, 5, '', 1, 0, 'C');
  $pdf->Cell(20, 5, '', 1, 0, 'C');
  $pdf->Cell(60, 5, 'Subject Average', 1, 0, 'C');

  foreach($Class->SubjectList as $subject)
    {
      $pdf->Cell(10, 5, $Class->getSubjectAverage($subjectName), 1, 0, 'C');
    }
  $pdf->Cell(15, 5, '', 1, 0, 'C');
  $pdf->Cell(15, 5, '', 1, 0, 'C');
  $pdf->Cell(15, 5, '', 1, 0, 'C');

}

$pdf->Output('I', $class_name.'_BroadSheet.pdf', false);
?>

Open in new window

0
gr8gonzoConsultantCommented:
Ah.

    foreach($Class->SubjectList as $subject)
    {
      $pdf->Cell(10, 5, $Class->getSubjectAverage($subjectName), 1, 0, 'C');
    }

Those variables have to match.
0
Opeyemi AbdulRasheedAuthor Commented:
You're such an excellent dev. Million thanks. It's working
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.