« Ritorna al blog

Ritorna alla lista completa degli articoli

Mettiti alla prova: ordina una lista di impiegati in ordine crescente o decrescente - Parte 3 di 4

PHP - SFIDE - novembre 15, 2021

In questo esercizio ordineremo una lista di impiegati determinando quale sia il soggetto più giovane e quello più anziano.

Per comprendere meglio l'esercizio bisognerà aver seguito i due esercizi precedenti:

  1. Mettiti alla prova: calcolo dell'età anagrafica di un impiegato
  2. Mettiti alla prova: chi è l'impiegato più giovane o più anziano?

Attualmente il metodo della classe get_eta() restituisce la differenza di due date di nascita in anni. Cosa succede se due persone sono nate nello stesso anno a poca distanza di mesi o giorni l'uno dall'altra? Secondo il criterio di ordinamento che abbiamo usato, la differenza in anni, risulterebbe sempre 0 e quindi verrebbero ordinate in modo errato, in quanto la differenza in mesi o giorni non verrebbe calcolata; di conseguenza, bisognerà creare un altro metodo della classe Impiegato.class.php, scegliendo la formattazione corretta tra quelle disponibili della classe DateInterval che si compone delle seguenti proprietà:

public 'y' => int
public 'm' => int
public 'd' => int
public 'h' => int
public 'i' => int
public 's' => int
public 'f' => float
public 'weekday' => int
public 'weekday_behavior' => int
public 'first_last_day_of' => int
public 'invert' => int
public 'days' => int
public 'special_type' => int
public 'special_amount' => int
public 'have_weekday_relative' => int
public 'have_special_relative' => int

Il metodo get_eta(), della classe Impiegato.class.php, restituisce il risultato in anni (y). Ai fini dell'ordinamento non è una proprietà corretta. Quale dovremo scegliere? Cercate di capirlo da soli. Il metodo che dovremo aggiungere alla nostra classe Impiegato.class.php si chiamerà provvisoriamente get_eta_v2(). Dovrete sostituire il v2 con la proprietà che avrete scelto. Ad esempio se avete scelto la proprietà m diventerà get_eta_by_month() e cosi via.

File Impiegato.class.php

<?php
    class Impiegato {
        private $nome;
        private $ddn;

        function __construct($nome, $ddn){
            $this->nome = $nome;
            $this->ddn = $ddn;
        }

        public function get_nome(){
            return $this->nome;
        }

        public function get_eta(){
            // da completare
            $data1 = new DateTime($this->ddn);
            $data2 = new DateTime(date('Y-m-d'));
            $eta = $data2->diff($data1);
            return $eta->y;
        }

        public function get_eta_v2(){
            // da completare
        }
    }
?>

Una volta implementato il metodo della classe Impiegato.class.php, dovremo aggiungere due funzioni che si occuperanno di ordinare l'array di dati in senso crescente e decrescente. Le due funzioni devono ordinare in base all'età ma devono sfruttare il nuovo metodo che avete aggiunto alla classe, ossia get_eta_v2():

La due funzioni si troveranno al di fuori della classe e saranno chiamate rispettivamente:

  • ordina_per_eta_asc();
  • ordina_per_eta_desc();

Ecco i file da cui partire:

File start.php

<!-- Classe Impiegato -->
<?php require_once("classi/Impiegato.class.php"); ?>

<!DOCTYPE html>
<html lang="it">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Esercizio: ordinamento lista impiegati</title>
</head>
<body>

<?php
    function print_array($arr){
        echo '<pre>';
        var_dump($arr);
        echo '</pre>';
    }

    function ordina_per_eta_asc($emp1, $emp2){
        // da completare
    }

    function ordina_per_eta_desc($emp1, $emp2){
        // da completare
    }

    $giovanni = new Impiegato('Giovanni', '2010-10-20');
    $filippo = new Impiegato('Filippo', '2012-07-12');
    $enrico = new Impiegato('Enrico', '2009-08-28');
    $teresa = new Impiegato('Teresa', '2017-03-06');
    $michele = new Impiegato('Michele', '2005-04-07');
    $laura = new Impiegato('Laura', '2010-07-12');
    $roberto = new Impiegato('Roberto', '2003-12-16');
    $luisa = new Impiegato('Luisa', '2004-05-20');
    $maria = new Impiegato('Maria', '2010-05-25');
    $boris = new Impiegato('Boris', '2007-01-07');
    $alice = new Impiegato('Alice', '2015-11-13');
    $gennaro = new Impiegato('Gennaro', '2016-12-16');
    $gianluca = new Impiegato('Gianluca', '2007-04-30');
    $carlo = new Impiegato('Carlo', '2010-03-25');

    $impiegati = [ $giovanni, $filippo, $enrico, $teresa, $michele, $laura, $roberto, $luisa, $maria, $boris, $alice, $gennaro, $gianluca,  $carlo ];

    // Da completare: dal più giovane al più anziano (ASC)
    echo "<h3>Dal più giovane al più anziano</h3>";

    // Da completare: il nome dell'impiegato più giovane

    // Stampa
    print_array( $impiegati ); 

    // Da completare: dal più anziano al più giovane (DESC)
    echo "<h3>Dal più anziano al più giovane</h3>";

    // Da completare: il nome dell'impiegato più anziano

    // Stampa
    print_array( $impiegati ); 
    
?>
</body>
</html>

Per costruire le due liste degli impiegati, ordinate in senso ascendente e discendente, dovrete utilizzare le funzioni incorporate di PHP. In questo caso utilizzeremo la funzione usort(). In questa funzione dovrete specificare la regola di confronto seguendo questa logica:

La funzione ordina_per_eta_asc() (ordina in senso ascendente) dovrà ritornare:

  • 0, se hanno la stessa età;
  • 1 se il soggetto è più giovane dell'altro;
  • -1 se il soggetto è più anziano dell'altro;

La funzione ordina_per_eta_dec() (ordina in senso discendente) dovrà ritornare:

  • 0, se hanno la stessa età;
  • 1 se il soggetto è più anziano dell'altro;
  • -1 se il soggetto è più giovane dell'altro;

Una volta completato l'esercizio, dovrete verificare di averlo svolto correttamente. L'output corretto, in ordine crescente (dal più giovane al più anziano), sarà simile al seguente:

Dal più giovane al più anziano

Il più giovane è: Teresa

array (size=14)
  0 => 
    object(Impiegato)[4]
      private 'nome' => string 'Teresa' (length=6)
      private 'ddn' => string '2017-03-06' (length=10)
  1 => 
    object(Impiegato)[12]
      private 'nome' => string 'Gennaro' (length=7)
      private 'ddn' => string '2016-12-16' (length=10)
  2 => 
    object(Impiegato)[11]
      private 'nome' => string 'Alice' (length=5)
      private 'ddn' => string '2015-11-13' (length=10)
  3 => 
    object(Impiegato)[2]
      private 'nome' => string 'Filippo' (length=7)
      private 'ddn' => string '2012-07-12' (length=10)
  4 => 
    object(Impiegato)[1]
      private 'nome' => string 'Giovanni' (length=8)
      private 'ddn' => string '2010-10-20' (length=10)
  5 => 
    object(Impiegato)[6]
      private 'nome' => string 'Laura' (length=5)
      private 'ddn' => string '2010-07-12' (length=10)
  6 => 
    object(Impiegato)[9]
      private 'nome' => string 'Maria' (length=5)
      private 'ddn' => string '2010-05-25' (length=10)
  7 => 
    object(Impiegato)[14]
      private 'nome' => string 'Carlo' (length=5)
      private 'ddn' => string '2010-03-25' (length=10)
  8 => 
    object(Impiegato)[3]
      private 'nome' => string 'Enrico' (length=6)
      private 'ddn' => string '2009-08-28' (length=10)
  9 => 
    object(Impiegato)[13]
      private 'nome' => string 'Gianluca' (length=8)
      private 'ddn' => string '2007-04-30' (length=10)
  10 => 
    object(Impiegato)[10]
      private 'nome' => string 'Boris' (length=5)
      private 'ddn' => string '2007-01-07' (length=10)
  11 => 
    object(Impiegato)[5]
      private 'nome' => string 'Michele' (length=7)
      private 'ddn' => string '2005-04-07' (length=10)
  12 => 
    object(Impiegato)[8]
      private 'nome' => string 'Luisa' (length=5)
      private 'ddn' => string '2004-05-20' (length=10)
  13 => 
    object(Impiegato)[7]
      private 'nome' => string 'Roberto' (length=7)
      private 'ddn' => string '2003-12-16' (length=10)

L'output in ordine decrescente (dal più anziano al più giovane) sarà il seguente:

Dal più anziano al più giovane

Il più anziano è: Roberto

array (size=14)
  0 => 
    object(Impiegato)[7]
      private 'nome' => string 'Roberto' (length=7)
      private 'ddn' => string '2003-12-16' (length=10)
  1 => 
    object(Impiegato)[8]
      private 'nome' => string 'Luisa' (length=5)
      private 'ddn' => string '2004-05-20' (length=10)
  2 => 
    object(Impiegato)[5]
      private 'nome' => string 'Michele' (length=7)
      private 'ddn' => string '2005-04-07' (length=10)
  3 => 
    object(Impiegato)[10]
      private 'nome' => string 'Boris' (length=5)
      private 'ddn' => string '2007-01-07' (length=10)
  4 => 
    object(Impiegato)[13]
      private 'nome' => string 'Gianluca' (length=8)
      private 'ddn' => string '2007-04-30' (length=10)
  5 => 
    object(Impiegato)[3]
      private 'nome' => string 'Enrico' (length=6)
      private 'ddn' => string '2009-08-28' (length=10)
  6 => 
    object(Impiegato)[14]
      private 'nome' => string 'Carlo' (length=5)
      private 'ddn' => string '2010-03-25' (length=10)
  7 => 
    object(Impiegato)[9]
      private 'nome' => string 'Maria' (length=5)
      private 'ddn' => string '2010-05-25' (length=10)
  8 => 
    object(Impiegato)[6]
      private 'nome' => string 'Laura' (length=5)
      private 'ddn' => string '2010-07-12' (length=10)
  9 => 
    object(Impiegato)[1]
      private 'nome' => string 'Giovanni' (length=8)
      private 'ddn' => string '2010-10-20' (length=10)
  10 => 
    object(Impiegato)[2]
      private 'nome' => string 'Filippo' (length=7)
      private 'ddn' => string '2012-07-12' (length=10)
  11 => 
    object(Impiegato)[11]
      private 'nome' => string 'Alice' (length=5)
      private 'ddn' => string '2015-11-13' (length=10)
  12 => 
    object(Impiegato)[12]
      private 'nome' => string 'Gennaro' (length=7)
      private 'ddn' => string '2016-12-16' (length=10)
  13 => 
    object(Impiegato)[4]
      private 'nome' => string 'Teresa' (length=6)
      private 'ddn' => string '2017-03-06' (length=10)

Per vedere la soluzione all'esercizio devi essere un utente registrato

File Impiegato.class.php

<?php
    class Impiegato {
        private $nome;
        private $ddn;

        function __construct($nome, $ddn){
            $this->nome = $nome;
            $this->ddn = $ddn;
        }

        public function get_nome(){
            return $this->nome;
        }

        public function get_eta(){
            // da completare
            $data1 = new DateTime($this->ddn);
            $data2 = new DateTime(date('Y-m-d'));
            $eta = $data2->diff($data1);
            return $eta->y;
        }

        public function get_eta_by_days(){
            // da completare
            $data1 = new DateTime($this->ddn);
            $data2 = new DateTime(date('Y-m-d'));
            $eta = $data2->diff($data1);
            return $eta->days;
        }
    }
?>

File finish.php

<!-- Classe Impiegato -->
<?php require_once("classi/Impiegato.class.php"); ?>

<!DOCTYPE html>
<html lang="it">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Esercizio: ordinamento lista impiegati</title>
</head>
<body>

<?php

    function print_array($arr){
        echo '<pre>';
        var_dump($arr);
        echo '</pre>';
    }

    function ordina_per_eta_asc($emp1, $emp2){
        // da completare
        if($emp1->get_eta_by_days() == $emp2->get_eta_by_days()){
            return 0;
        }

        return $emp1->get_eta_by_days() > $emp2->get_eta_by_days() ? 1 : -1;
    }

    function ordina_per_eta_desc($emp1, $emp2){
        // da completare
        if($emp1->get_eta_by_days() == $emp2->get_eta_by_days()){
            return 0;
        }

        return $emp1->get_eta_by_days() < $emp2->get_eta_by_days() ? 1 : -1;
    }

    $giovanni = new Impiegato('Giovanni', '2010-10-20');
    $filippo = new Impiegato('Filippo', '2012-07-12');
    $enrico = new Impiegato('Enrico', '2009-08-28');
    $teresa = new Impiegato('Teresa', '2017-03-06');
    $michele = new Impiegato('Michele', '2005-04-07');
    $laura = new Impiegato('Laura', '2010-07-12');
    $roberto = new Impiegato('Roberto', '2003-12-16');
    $luisa = new Impiegato('Luisa', '2004-05-20');
    $maria = new Impiegato('Maria', '2010-05-25');
    $boris = new Impiegato('Boris', '2007-01-07');
    $alice = new Impiegato('Alice', '2015-11-13');
    $gennaro = new Impiegato('Gennaro', '2016-12-16');
    $gianluca = new Impiegato('Gianluca', '2007-04-30');
    $carlo = new Impiegato('Carlo', '2010-03-25');

    $impiegati = [ $giovanni, $filippo, $enrico, $teresa, $michele, $laura, $roberto, $luisa, $maria, $boris, $alice, $gennaro, $gianluca,  $carlo ];


    // Da completare: dal più giovane al più anziano (ASC)
    echo "<h3>Dal più giovane al più anziano</h3>";
    usort($impiegati, 'ordina_per_eta_asc');

    // Da completare: il nome dell'impiegato più giovane
    echo 'Il più giovane è: ' . $impiegati[0]->get_nome();

    // Stampa
    print_array( $impiegati ); 

    // Da completare: dal più anziano al più giovane (DESC)
    echo "<h3>Dal più anziano al più giovane</h3>";
    usort($impiegati, 'ordina_per_eta_desc');

    // Da completare: il nome dell'impiegato più anziano
    echo 'Il più anziano è: ' . $impiegati[0]->get_nome();

    // Stampa
    print_array( $impiegati ); 
    
?>
</body>
</html>
Mettiti alla prova: ordina una lista di impiegati in ordine crescente o decrescente - Parte 3 di 4