Partage
  • Partager sur Facebook
  • Partager sur Twitter

Exercices POO

Venez progresser !

Anonyme
    26 novembre 2009 à 7:03:18

    Bonjour,
    J'ai vu sur le forum PHP un certain nombre de sujets proposant des exercices de PHP, mais c'était très souvent (presque exclusivement) des fonctions d'algorithmique, ou d'autres assez inutiles.
    Aujourd'hui, je vous propose que l'on fasse la même chose, mais avec des mini-modules codés en POO.
    Ces mini-modules ne seraient pas forcément à utiliser pour votre site, mais le but est qu'ils vous fassent progresser.

    Exercice 1 : un système de QCM


    Description :



    Vous aurez besoin de trois classes :
    • Qcm ;
    • Question ;
    • Reponse.

    Je vous le rappelle, aucune de ces trois classes ne doit hériter d'une autre : on ne peut parler d'héritage exclusivement quand, avec une classe A et B, on peut dire que B est un A. Or ici une réponse n'est pas une question, une question n'est pas un Qcm.

    Fonctionnalités requises


    • Ajouter une question
      • Pouvoir ajouter les réponses possibles à une question ;
      • Pouvoir définir la bonne réponse comme telle ;
    • Pouvoir définir les explications de la correction d'une question.
    • Pouvoir définir plusieurs appréciations en fonction de la note (sur vingt) obtenue ;

    À la fin, il doit être possible de faire ceci pour générer un Qcm :

    <?php
    $qcm = new Qcm();
    
    $question1 = new Question('Et paf, ça fait ...');
    $question1->ajouterReponse(new Reponse('Des mielpops'));
    $question1->ajouterReponse(new Reponse('Des chocapics', Reponse::BONNE_REPONSE));
    $question1->ajouterReponse(new Reponse('Des actimels'));
    $question1->setExplications('Et oui, la célèbre citation est « Et paf, ça fait des chocapics ! »');
    $qcm->ajouterQuestion($question1);
    
    $question2 = new Question('POO signifie');
    $question2->ajouterReponse(new Reponse('Php Orienté Objet'));
    $question2->ajouterReponse(new Reponse('ProgrammatiOn Orientée'));
    $question2->ajouterReponse(new Reponse('Programmation Orientée Objet', Reponse::BONNE_REPONSE));
    $question2->setExplications('Sans commentaires si vous avez eu faux :-°');
    $qcm->ajouterQuestion($question2);
    
    $qcm->setAppreciation(array('0-10' => 'Pas top du tout ...', 
    					        '10-20' => 'Très bien ...'));
    $qcm->generer();
    


    Résolutions


    Cet exercice n'a pas encore été résolu.

    Indices



    Une fois que le formulaire du QCM a été validé, je vous conseille de vous servir du md5() des questions pour récupérer l'objet qui correspond.
    Exemple :
    <?php
    public function getQuestionFromMd5($md5) {
    	foreach($this->questions as $q) {
    		if(md5($q->getQuestion()) == $md5) {
    			return $q;
    		}
    	}
    	return FALSE;
    }
    




    Une fois que vous pensez avoir fini, postez vos codes en réponse. :)
    La correction sera donnée dans deux semaines à compter d'aujourd'hui, le 26 novembre 2009.
    Si vous voulez me proposer des exercices, envoyez moi un MP. ;)
    Bonne chance à tous !
    Que la force soit avec vous



    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      26 novembre 2009 à 17:43:06

      Bon, je viens de terminer ma classe!

      Avantages :
      • Totalement fonctionnel
      • Possibilité d'avoir plusieurs QCM sur la même page sans risques de conflits
      • Pas besoin de s'occuper de savoir si le formulaire à été envoyé, la classe s'en occupe toute seul dans la méthode générer
      • Un code bien indenté


      Inconvénients :
      • Pas de CSS et difficulté (voir impossibilité) d'en mettre une extérieur
      • Code non commenté
      • Presque aucune gestion des erreurs


      Une dernier truc : les méthodes d'action renvoient toutes (sauf Qcm::Generer) l'instance en cours, ce qui permet de pouvoir le réutiliser directement, et donc de ne pas avoir à réécrire 150 le nom de l'instance ;)
      Qcm::generer fait exception étant donné que compte mettre une option pour qu'il renvoie le code source du QCM et affin de pouvoir le manipuler ensuite.


      <?php
      class Qcm {
         private $questions;
         private $appreciation;
         
         public function __construct() {
            $this->questions = array();
            $this->appreciation = array();
         }
         
         public function ajouterQuestion($question) {
            $this->questions[] = $question;
            return $this;
         }
         
         public function setAppreciation($appreciation) {
            foreach($appreciation as $key=>$appr) {
               if(is_numeric($key))
                  $this->appreciation[(int)$appr] = $appr;
               else {
                  list($min, $max) = explode('-', $key);
                  if($min>$max)
                     list($min, $max) = array($max, $min);
                  for($i=(int)$min;$i<=$max;$i++)
                     $this->appreciation[$i] = $appr;
               }
            }
            return $this;
         }
         
         public function generer() {
            $id = md5(serialize($this));
            if(isset($_POST['qcm_id']) AND $_POST['qcm_id']==$id) {
               $nbrBonneReponses = 0;
               foreach($this->questions as $i=>$question) {
                  echo 'Question '.$i.' : '.htmlspecialchars($question->getQuestion()).'<br /><br />';
                  if($_POST['qcm_q'.$i]==$question->getNumBonneReponse()) {
                     echo 'Bonne réponse!<br /><br />';
                     $nbrBonneReponses++;
                  }
                  else
                     echo 'Mauvaise réponse : '.htmlspecialchars($question->getReponse($_POST['qcm_q'.$i])->getText()).'<br />';
                  echo 'La bonne réponse était : '.htmlspecialchars($question->getBonneReponse()->getText()).'<br /><br />';
                  echo 'Explication : '.htmlspecialchars($question->getExplication());
                  echo '<hr />';
               }
               $note = round($nbrBonneReponses/count($this->questions)*20);
               echo 'Note : '.$note.'/20<br />';
               if(isset($this->appreciation[$note]))
                  echo 'Appréciation : '.htmlspecialchars($this->appreciation[$note]);
            }
            else {
               echo '<form method="post" />';
               echo '<input type="hidden" value="'.$id.'" name="qcm_id" />';
               foreach($this->questions as $i=>$question) {
                  echo '<fieldset>Question '.$i.' : '.htmlspecialchars($question->getQuestion()).'<br />';
                  foreach($question->getReponses() as $j=>$reponse) {
                     echo '<input type="radio" name="qcm_q'.$i.'" value="'.$j.'" />';
                     echo htmlspecialchars($reponse->getText()).'<br />';
                  }
                  echo '</fieldset><br />';
               }
               echo '<input type="submit" value="envoyer" /></form>';
            }
         }
      }
      

      <?php
      class Question {
         private $question;
         private $reponses;
         private $explication;
      
         public function __construct($question) {
            $this->question = $question;
            $this->reponse = array();
         }
      
         public function ajouterReponse($reponse) {
            $this->reponses[] = $reponse;
            return $this;
         }
      
         public function setExplications($explication) {
            $this->explication = $explication;
            return $this;
         }
      
         public function getNumBonneReponse() {
            foreach($this->reponses as $i=>$reponse)
               if($reponse->getStatus())
                  return $i;
         }
      
         public function getBonneReponse() {
            foreach($this->reponses as $reponse)
               if($reponse->getStatus())
                  return $reponse;
         }
      
         public function getReponses() {
            return $this->reponses;
         }
      
         public function getReponse($num) {
            return $this->reponses[$num];
         }
      
         public function getQuestion() {
            return $this->question;
         }
      
         public function getExplication() {
            return $this->explication;
         }
      }
      

      <?php
      class Reponse {
         private $reponse;
         private $status;
         const MAUVAIS_REPONSE = false;
         const BONNE_REPONSE = true;
      
         public function __construct($reponse, $status = self::MAUVAIS_REPONSE) {
            $this->reponse = $reponse;
            $this->status = $status;
         }
      
         public function getStatus() {
            return $this->status;
         }
      
         public function getText() {
            return $this->reponse;
         }
      }
      

      <?php
      $qcm = new Qcm();
      
      $question1 = new Question('Et paf, ça fait ...');
      $question1->ajouterReponse(new Reponse('Des mielpops'))
          ->ajouterReponse(new Reponse('Des chocapics', Reponse::BONNE_REPONSE))
          ->ajouterReponse(new Reponse('Des actimels'))
          ->setExplications('Et oui, la célèbre citation est « Et paf, ça fait des chocapics ! »');
      
      $question2 = new Question('POO signifie');
      $question2->ajouterReponse(new Reponse('Php Orienté Objet'))
          ->ajouterReponse(new Reponse('ProgrammatiOn Orientée'))
          ->ajouterReponse(new Reponse('Programmation Orientée Objet', Reponse::BONNE_REPONSE))
          ->setExplications('Sans commentaires si vous avez eu faux :-°');
      
      $qcm->ajouterQuestion($question1)
          ->ajouterQuestion($question2)
          ->setAppreciation(array(
             '0-10'=>'Pas top du tout ...',
             '10-20'=>'Très bien ...'))
          ->generer();
      


      Comme vous pouvez le voir, le code n'est pas forcément orienté dans la performance, mais plus dans la clarté. Par exemple, je n'hésite pas à faire plusieurs echo à la suite pour éviter des lignes à rallonge.
      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        26 novembre 2009 à 21:32:58

        Berdes1 tes classes marchent, mais mets les codes dans la balise <secret></secret> , mais pense à mettre des labels à tes checkbox. ;)
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          26 novembre 2009 à 21:40:32

          Le problème des <label> ces que quand il y a un choix, un choix sera définie par défaut et ça peut orienter l'utilisateur (oui, je sait, osef...)
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            2 décembre 2009 à 21:10:17

            Elle est pour quand la correction?
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              4 décembre 2009 à 19:32:09

              Je la donne dès que je suis sur mon ordinateur. ;)
              • Partager sur Facebook
              • Partager sur Twitter
                4 décembre 2009 à 22:19:14

                Citation : berdes1

                Le problème des <label>, c'est que quand il y a un choix, il sera défini par défaut et ça peut orienter l'utilisateur


                Je ne vois pas où est le problème... Le label ne fait que donner le focus au contrôle.
                Après, ca peut être utile de faire une option dans le select qui aura une valeur "nulle" (0 si les clés sont des entiers ou '' si les clés sont des chaines), et dont le texte afficher serait "A préciser..." par exemple...
                Ca permet de visualiser que la liste n'a pas encore été modifiée, de définir une valeur par défaut pour le traitement de $_POST, et si tu as un problème avec les lables, cette astuce peut la résoudre. ;)
                • Partager sur Facebook
                • Partager sur Twitter
                  16 octobre 2013 à 19:51:46

                  je pense qu'elle n'arrivera jamais la correction...
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Exercices POO

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown