Calculate and print average grades in subjects associated with students. (Printing of tickets per student in batch)

1

In this FPDF code I print values of n subjects with grades of x students consulted with the SQL statement.

What it does is print a ballot with grades and subjects per student on different pages.
For example, if group 100 has 23 students with 11 subjects, the 23 ballots of that group are printed in PDF in a single file, the subjects and grades of each student are well reflected on the ballot, but now he was looking to calculate the average of each of them inside a while loop.

In the if that is within while , compare the value of a variable initialized with the first idAlumno recovered from the table, if they match, print the first idAlumno , if not match, print the of the other students. But just as I have it, it only prints the correctly calculated average of the first ballot, but from the second onwards it prints other averages, I think it's taking sacked values, maybe it's wrong where I'm placing the impressions or the calculation.

The while loop includes the impressions of the data in cells, inside while the if and the average I put it inside the else.  It tried that the divisor ("accountant") to calculate the average (on the number of matters) is variant, since the number of matters varies.

Any errors that you can see or another way to implement it?

This is the code ( read the comments in the relevant parts ):

<?php

require('conexion.php');
require('fpdf/fpdf.php');

class PDF extends FPDF 
{
    function AcceptPageBreak()
    {
        $this->Addpage();

        //$this->SetFillColor(232,232,232);
        $this->SetFont('Arial','B',8);
        $this->Ln();
    }

        function Header()
    {
        //logo
        $this->Image('logo2.png',10,8,33);
        //fuente
        $this->SetFont('Arial','B',12);
        //movernos a la derecha como sangria
        $this->Cell(65);
        //movernos a la derecha como sangria
        $this->Cell(70,10,'CEB: Listado Grupo',1,0,'C');//tamaños,texto,contorno 1, salto de linea despues de la selda, alineacion
        //salto de linea
        $this->Ln(20);
    }

    function Footer()
    {   //desde hacia arriba 15 puntos, coordenadas, a 1.5 cm del final
        $this->SetY(-15);
        //arial italic 8
        $this->SetFont('Arial','I',8);
        //num de pagina
        $this->Cell(0,10,'Page '.$this->PageNo().'/{nb}',0,0,'C');

    }   
}

if( isset($_GET['periodo']) && isset($_GET['semestre']) && isset($_GET['grupo']) )  {

    $periodo = $_GET['periodo'];  //RECIBIMOS EL PARAMETRO POR URL : EL ID DE LA TABLA ALUMNO_GRUPO
    $semestre = $_GET['semestre'];
    $grupo = $_GET['grupo'];
}
//CONSULTA TRAE TODAS LAS CALIFICACIONES DE TODOS LOS ALUMNOS PERYECIENTES A CIERTO GRUPO,
$consulta = "SELECT A.idAlumno, A.matricula, A.nombre, A.grupo, P.periodo, AG.parcial1 as p1mat, AG.inasisP1 as ina1mat, M.materia, M.idMateria, G.idGrupo, P.descripcion, A.semestre, G.capacitacion FROM alumno A, alumno_grupo AG, grupos G, materias M, periodos P WHERE A.idAlumno = AG.idAlumno and G.idGrupo = AG.idGrupo and M.idMateria = G.materia and P.idPeriodo = G.periodo and P.periodo = $periodo and A.semestre = $semestre and A.grupo = $grupo ORDER BY A.nombre";
/////////////////////////////////////////////
///////////////////////////////////////////
$res=$mysqli->query($consulta);

$pdf = new PDF();

$pdf->Addpage();
$pdf->AliasNbPages();
//////////////////////////////////////////////////////////////////////////// DATOS DEL ALUMNO  AL PRINCIO DE CADA HOJA
if ( $fila2 = $res->fetch_assoc() )   {

$pdf->SetFillColor(232,232,232);
$pdf->SetFont('Arial','B',8);

 //MATRICULA
 $pdf->SetX(19);//posisionamos en 10 de x
 $pdf->Cell(25,5,$fila2['matricula'],1,0,'C',1);

 //NOMBRE ALUMNO COLPLETO
 $pdf->SetX(47);//posisionamos en 10 de x
 $pdf->Cell(100,5,$fila2['nombre'],1,0,'C',1);//colocando ancho de celda

 //SEMESTRE
 $pdf->SetX(150);//posisionamos en 10 de x
 $pdf->Cell(9,5,$fila2['semestre'],1,0,'C',1);

//PERIODO
 $pdf->SetX(161);//posisionamos en 10 de x
 $pdf->Cell(24,5,$fila2['descripcion'],1,0,'C',1);

//CAPACITACION DONDE ESTA INSCRITO
 $pdf->Ln();
 $pdf->Ln();
 $pdf->SetX(78);//posisionamos en 10 de x
 $pdf->Cell(40,5,$fila2['capacitacion'],1,0,'C',1);

//NUMERO DE GRUPO
 $pdf->SetX(120);//posisionamos en 10 de x
 $pdf->Cell(8,5,$fila2['grupo'],1,0,'C',1);

 $pdf->Ln(); 
}
//////////////////////////////////////////////////////////////////////////////////////////

 $pdf->Ln();
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 $pdf->SetX(22);//posisionamos en 10 de x  DATOS DE LA PRIMERA HOJA RECUPERADA CON LAS  CALIFS DE UN ALUMNO
 $pdf->Cell(109,6,'UNIDAD ACADEMICA CURRICULAR',1,0,'C',1);//colocando ancho de celda

 $pdf->SetX(132);//posisionamos en 10 de x
 $pdf->Cell(25,6,'INASISTENCIAS',1,0,'C',1);//

 $pdf->SetX(158);
 $pdf->Cell(24,6,'CALIFICACION',1,0,'C',1);

 $pdf->Ln();
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    $res2=$mysqli->query($consulta);

 //////////////////////////////////////////////// IMPRIMIENDO LOS VALORES DE LA TABLA //////////////////////////////
     $row = mysqli_fetch_array($res,MYSQLI_ASSOC); 
     $bandera = $row['idAlumno'] ;  //asignamos a bandera el valor del idAlumno recuperado del los registros

     //VARIABLES PARA EL CALCULO DEL PROMEDIO
     $suma = 0;
     $promedio = 0;

//WHILE
while ($fila = $res2->fetch_assoc())  //recuperando con array asociativo los califs de la tabla
{   
    //IMPRIMIENDO LAS CALIFICACIONES DEL PRIMER ALUMNO ENCONTRADO
    if ( $bandera ==  $fila['idAlumno'] ) { //si en los registros recuperados, cada idAlumno es igual a baendera
                                            //imprimir los califs que correcponden a ese alumno
    $pdf->SetX(22);
    $pdf->Cell(109,6, $fila['materia'],1,0,'C');

    $pdf->SetX(132);//nombre alumno
    $pdf->Cell(25,6, $fila['ina1mat'],1,0,'C',0);

    $pdf->SetX(158);
    $pdf->Cell(24,6, $fila['p1mat'],1,1,'C',0); 

    //ejemplo: valores obtenidos en la primera boleta (primer alumno)
    //ejemplo: calificaciones impresas = 8.7, 6.3, 6.7, 10, 8, 8.2, 5, 9.7, 8.2, 9.5, 8.4

    //suma = 88.7
   //promedio = 88.7/11 = 8.06 "CORRECTO"


    $valorFila = $fila['p1mat']; //variable toma el valor de la calificacion o nota de la metria
    $suma = $suma + $valorFila;  // variable que va acumulando cada valor
     //¿que funcion ocupar para que el divisor sea variable dependiendo el numero de filas encontradas;?
  } 
        //ELSE  :::  IMPRIMIENDO LAS CALIFICACIONES DEL SEGUNDO ALUMNO Y LOS DEMAS

  else { //si no corresponden imprime el resto de calificaciones recuperadas en hojas separadas

//CALCULO DEL PROMEDIO,////////////////////////////////////////////////
  $contador =11 ;  //n es el número de materias por las que hay que dividir la suma, buscaba que este valor fuera dinamico, de acuerdo al numero de materias encontradas,

  //CALCULO DEL PROMEDIO
  $promedio = $suma/$contador; //operaciomn
  $suma = 0;  //inicializando suma
    $pdf->Ln(3);
    $pdf->SetX(132);
    $pdf->Cell(25,6,'PROMEDIO:',1,0,'C',1); 

    $pdf->SetX(158);
    $pdf->Cell(24,6, round($promedio,2),1,0,'C',1);  //imprime promedio

    //ejemplo: valores obtenidos en la segunda boleta (segundo alumno)
    //ejemplo: calificaciones impresas = 8.2, 9.4, 7.7, 9.5, 8, 9.3, 9, 8.5, 10, 7.5, 10
    //suma = 88.8
   //promedio = 88.8/11 = 7.19 "INCORRECTO"

     ////////////////////////////////////////////////////////////////////   
    $pdf->Addpage();  //AGREGANDO PAGINA SIGUIENTE EN CASO QUE EL IDALUMNO NO SEA EL MISMO
    $bandera = $fila['idAlumno'];

    //MATRICULA
    $pdf->SetX(19);//posisionamos en 10 de x
    $pdf->Cell(25,5,$fila['matricula'],1,0,'C',1);

     //NOMBRE ALUMNO COLPLETO
    $pdf->SetX(47);//posisionamos en 10 de x
    $pdf->Cell(100,5,$fila['nombre'],1,0,'C',1);//colocando ancho de celda

    //SEMESTRE
    $pdf->SetX(150);//posisionamos en 10 de x
    $pdf->Cell(9,5,$fila['semestre'],1,0,'C',1);

    //PERIODO
    $pdf->SetX(161);//posisionamos en 10 de x
    $pdf->Cell(24,5,$fila['descripcion'],1,0,'C',1);

    //CAPACITACION DONDE ESTA INSCRITO
    $pdf->Ln();
    $pdf->Ln();
    $pdf->SetX(78);//posisionamos en 10 de x
    $pdf->Cell(40,5,$fila['capacitacion'],1,0,'C',1);

    //NUMERO DE GRUPO
    $pdf->SetX(120);//posisionamos en 10 de x
    $pdf->Cell(8,5,$fila['grupo'],1,0,'C',1);

    $pdf->Ln();
    $pdf->Ln();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    $pdf->SetX(22);//posisionamos en 10 de x
    $pdf->Cell(109,6,'UNIDAD ACADEMICA CURRICULAR',1,0,'C',1);//colocando ancho de celda

    $pdf->SetX(132);//posisionamos en 10 de x
    $pdf->Cell(25,6,'INASISTENCIAS',1,0,'C',1);//

    $pdf->SetX(158);
    $pdf->Cell(24,6,'CALIFICACION',1,0,'C',1);
    $pdf->Ln();

        $pdf->SetX(22);
        $pdf->Cell(109,6, $fila['materia'],1,0,'C');

        $pdf->SetX(132);//nombre alumno
        $pdf->Cell(25,6, $fila['ina1mat'],1,0,'C',0);

        $pdf->SetX(158);
        $pdf->Cell(24,6, $fila['p1mat'],1,1,'C',0);     
        //por aqui buscaba imprimir el promedio de las calificaciones
  } //fin else
} //fin while (fila = res)

$pdf->Output();

?>
    
asked by Armando Arellano 30.11.2016 в 06:12
source

1 answer

0

Well, I can think of two options.

One is to modify your query so that you delegate to SQL the obtaining of the average and you only commission it to print it as one more field.

The other is that you modify your code a bit so that in the last iteration of the student's question, calculate the average.

For the first option it should be something like:

$consulta = "
SELECT
  A.idAlumno, A.matricula, A.nombre, A.grupo, P.periodo, AG.parcial1 as p1mat, AG.inasisP1 as ina1mat, M.materia, M.idMateria, G.idGrupo, P.descripcion, A.semestre, G.capacitacion,
(SELECT AVG(calificacion1, calificacionN FROM tabla_con_calificaciones WHERE idAlumno = $idAlumno)) AS promedio
FROM
  alumno A, alumno_grupo AG, grupos G, materias M, periodos P
WHERE
  A.idAlumno = AG.idAlumno and G.idGrupo = AG.idGrupo and M.idMateria = G.materia and P.idPeriodo = G.periodo and P.periodo = $periodo and A.semestre = $semestre and A.grupo = $grupo ORDER BY A.nombre"; 

The query is very big, here I put what you could add:

(SELECT AVG(calificacion1, calificacionN FROM tabla_con_calificaciones WHERE idAlumno = $idAlumno)) AS promedio

It is a subquery within your main query where you get the average of the student's grades with id = $ idAlumno, for this the AVG function of sql is used. You just have to place the correct parameters because I do not know in what table these data are and what they are called.

The second option if you do not want to modify your query:

First you create a counter for the while: And create the counter:

$i = 0;
while ($fila = $res2->fetch_assoc())  //recuperando con array asociativo los califs de la tabla

Then place this where you put your comment:

  //¿que funcion ocupar para que el divisor sea variable dependiendo el numero de filas encontradas;?



 if ( $i === count($datos_array->fetch_assoc()) )
    {
       $promedio = $suma/count($datos_array->fetch_assoc();    
    }
$i++;

The logic is:

  

I'm going to get the total number of elements of the array that is iterating.   I will have a counter that records the iterations. When the   counter is equal to the number of array elements, is the last   cycle; then I calculate average and do what I want with it.

And remember to initialize the counter to 0 again, it could be inside the if.

    
answered by 30.11.2016 / 21:04
source