Actions

Cours

Différences entre versions de « Technologies avancées du eLearning 2/exercices/Élèves »

De GBLL, TAL, ALAO, etc.

< Cours:Technologies avancées du eLearning 2
(Page créée avec « == Énoncé == On a un document HTML, qui contient une liste d’étudiant avec les notes obtenues lors du semestre, sous la forme suivante : <syntaxhighlight lang="html">... »)
 
 
(29 versions intermédiaires par le même utilisateur non affichées)
Ligne 28 : Ligne 28 :
 
* <syntaxhighlight lang="javascript" inline>mot.charAt(i)</syntaxhighlight> → (i+1){{exp|e}} caractère d’une chaine ;
 
* <syntaxhighlight lang="javascript" inline>mot.charAt(i)</syntaxhighlight> → (i+1){{exp|e}} caractère d’une chaine ;
 
* <syntaxhighlight lang="javascript" inline>chaineOuTableau.length</syntaxhighlight> → nombre d’éléments ;
 
* <syntaxhighlight lang="javascript" inline>chaineOuTableau.length</syntaxhighlight> → nombre d’éléments ;
* <syntaxhighlight lang="javascript" inline>Number("25")</syntaxhighlight> →  25 (en tant que {{code|Number}}.
+
* <syntaxhighlight lang="javascript" inline>Number("25")</syntaxhighlight> →  <syntaxhighlight lang="javascript" inline>25</syntaxhighlight> (en tant que {{code|Number}}).
 +
 
 +
== Méthode 1 : une analyse descendante ==
 +
On va procéder progressivement et créer un ensemble de fonctions que nous regrouperons ensuite :
 +
* <syntaxhighlight lang="javascript" inline>function getEleves(id)</syntaxhighlight>
 +
** {{code|id}} est une chaine de caractères contenant l'identifiant d'un élément du DOM ;
 +
** renvoie la liste des éléments contenus dans l'élément d'identifiant du DOM ;
 +
* <syntaxhighlight lang="javascript" inline>function getPrenom(ligne)</syntaxhighlight>
 +
** {{code|ligne}} est une chaine de caractères (telle que le contenu des <syntaxhighlight lang="html" inline><li></syntaxhighlight> ci-dessus ;
 +
** renvoie une chaine de caractères ne contenant que le prénom de l'élève ;
 +
* <syntaxhighlight lang="javascript" inline>function getNotes(ligne)</syntaxhighlight>
 +
** {{code|ligne}} est une chaine de caractères (telle que le contenu des <syntaxhighlight lang="html" inline><li></syntaxhighlight> ci-dessus ;
 +
** renvoie un tableau de <syntaxhighlight lang="javascript" inline>Number</syntaxhighlight> avec toutes les notes ;
 +
** cette fonction nécessite une autre fonction :<br /><syntaxhighlight lang="javascript" inline>function estNombre(caractere)</syntaxhighlight>
 +
*** {{code|caractere}} est un caractère (ou une <syntaxhighlight lang="javascript" inline>string</syntaxhighlight> de longueur 1 ;
 +
*** renvoie un booléen :
 +
****<syntaxhighlight lang="javascript" inline>true</syntaxhighlight> si le caractère peut être contenu dans l'écriture d'un nombre ;
 +
****<syntaxhighlight lang="javascript" inline>false</syntaxhighlight>sinon ;
 +
* <syntaxhighlight lang="javascript" inline>function moy(tabNotes)</syntaxhighlight>
 +
** {{code|tabNotes}} est un tableau de notes (<syntaxhighlight lang="javascript" inline>Number</syntaxhighlight>) ;
 +
** renvoie un <syntaxhighlight lang="javascript" inline>Number</syntaxhighlight> représentant la moyenne des nombres dans le tableau ;
 +
* <syntaxhighlight lang="javascript" inline>function bilan(ligne)</syntaxhighlight>
 +
** {{code|ligne}} est une chaine de caractères (telle que le contenu des <syntaxhighlight lang="html" inline><li></syntaxhighlight> ci-dessus ;
 +
** renvoie une chaine de caractère répondant aux contraintes de l'énoncé ;
 +
* <syntaxhighlight lang="javascript" inline>function traite(id)</syntaxhighlight>
 +
** {{code|id}} est un identifiant d'élément du DOM qui contient une liste d'élève ;
 +
** remplace le contenu de l'élément par les informations mises en forme.
 +
 
 +
=== Correction ===
 +
* https://codepen.io/lzbk/pen/EbLGKQ
 +
 
 +
<span class="mw-customtoggle-correction1">Voir une correction</span>
 +
 
 +
<syntaxhighlight lang="javascript" line="line" class="mw-collapsible mw-collapsed" id="mw-customcollapsible-correction1">//pour savoir si un caractère est un nombre (ou peut en faire partie)
 +
function estNombre(char){
 +
  var resultat;
 +
  switch(char){
 +
    case "0":
 +
    case "1":
 +
    case "2":
 +
    case "3":
 +
    case "4":
 +
    case "5":
 +
    case "6":
 +
    case "7":
 +
    case "8":
 +
    case "9":
 +
    case ".":
 +
      resultat = true;
 +
      break;
 +
    default:
 +
      resultat = false;
 +
  }
 +
  return resultat;
 +
}
 +
 
 +
//Pour récupérer toutes les informations nécessaires
 +
function traiterLigne(ligne){
 +
var i=0;
 +
var resultat = {"prenom":"",
 +
                  "notes":[ ],
 +
                  "moyenne":false};
 +
while (i < ligne.length
 +
&& ligne.charAt(i) != " "
 +
&& ligne.charAt(i) != ":"){
 +
resultat.prenom += ligne.charAt(i);
 +
i++;
 +
}
 +
  if(i==ligne.length){
 +
    resultat=false;
 +
  }
 +
  else{
 +
    let nbCourant = "",
 +
        somme = 0;
 +
    while(i <= ligne.length){
 +
      if (i < ligne.length
 +
      && estNombre(ligne.charAt(i))){
 +
        nbCourant += ligne.charAt(i); //chaine de caractère
 +
      }
 +
      else if(nbCourant!==""){
 +
        let laNote = Number(nbCourant);
 +
        somme += laNote ;
 +
        resultat.notes.push(laNote);
 +
        nbCourant = "";
 +
      }
 +
      i++;
 +
    }
 +
    if(resultat.notes.length>0){
 +
      resultat.moyenne = somme/resultat.notes.length
 +
    }
 +
  }
 +
return resultat;
 +
}
 +
 
 +
function ecrireLigne(semestre){
 +
  var resultat = "<i>" + semestre.prenom + "</i>&nbsp;: ";
 +
  for(let i=0; i<semestre.notes.length;i++){
 +
    if(i > 0){//pour les séparateurs
 +
      resultat = resultat +", "
 +
    }
 +
    if(semestre.notes[i]>=10){
 +
      resultat = resultat + "<b>" + semestre.notes[i] + "</b>";
 +
    }
 +
    else{
 +
      resultat = resultat + semestre.notes[i];
 +
    }
 +
  }
 +
  resultat = resultat + " → <u>" + semestre.moyenne + "</u>";
 +
  return resultat;
 +
}
 +
 
 +
//prend un tableau du DOM et stocke les données extraites
 +
//dans un tableau d'objets composites
 +
function traiterClasse(id){
 +
  var elt = document.getElementById(id),
 +
      tableauDOM = elt.children;
 +
  for(let i=0;i<tableauDOM.length;i++){
 +
    tableauDOM[i].innerHTML = ecrireLigne(traiterLigne(tableauDOM[i].innerHTML));
 +
  }
 +
}
 +
 
 +
//Programme principal
 +
traiterClasse("fastoche");
 +
traiterClasse("moyen");
 +
traiterClasse("chaud");</syntaxhighlight>
 +
 
 +
== Méthode 2 : création d'objets pour limiter le nombre de tours de boucles ==
 +
Dans cette méthode, le code sera moins lisible car, en substance, les fonctions <syntaxhighlight lang="javascript" inline>getPrenom()</syntaxhighlight>, <syntaxhighlight lang="javascript" inline>getNotes()</syntaxhighlight>, <syntaxhighlight lang="javascript" inline>moy()</syntaxhighlight> seront traitées en une seule fonction.
 +
 
 +
* <syntaxhighlight lang="javascript" inline>function estNombre(caractere)</syntaxhighlight>
 +
** {{code|caractere}} est un caractère (ou une <syntaxhighlight lang="javascript" inline>string</syntaxhighlight> de longueur 1 ;
 +
** renvoie un booléen :
 +
***<syntaxhighlight lang="javascript" inline>true</syntaxhighlight> si le caractère peut être contenu dans l'écriture d'un nombre ;
 +
***<syntaxhighlight lang="javascript" inline>false</syntaxhighlight>sinon ;
 +
* <syntaxhighlight lang="javascript" inline>function traiterLigne(ligne)</syntaxhighlight> est la fonction qui regroupe les traitements de <syntaxhighlight lang="javascript" inline>getPrenom()</syntaxhighlight>, <syntaxhighlight lang="javascript" inline>getNotes()</syntaxhighlight> et <syntaxhighlight lang="javascript" inline>moy()</syntaxhighlight>.
 +
** cette fonction prendra en entrée une chaine de caractères contenant les informations non mises en forme ;
 +
** elle renverra un objet composite muni de 3 attributs :
 +
*** <syntaxhighlight lang="javascript" inline>prenom</syntaxhighlight>, le prénom de l'élève (<syntaxhighlight lang="javascript" inline>string</syntaxhighlight>) ;
 +
*** <syntaxhighlight lang="javascript" inline>notes</syntaxhighlight>, un tableau de <syntaxhighlight lang="javascript" inline>Number</syntaxhighlight> avec les notes de l'élève ;
 +
*** <syntaxhighlight lang="javascript" inline>moyenne</syntaxhighlight>, un <syntaxhighlight lang="javascript" inline>Number</syntaxhighlight>, sa moyenne ;
 +
* <syntaxhighlight lang="javascript" inline>function ecrireLigne(semestre)</syntaxhighlight>
 +
** prend un objet tel que celui renvoyé par <syntaxhighlight lang="javascript" inline>traiterLigne</syntaxhighlight> ;
 +
** et génère en conséquences une <syntaxhighlight lang="javascript" inline>string</syntaxhighlight> mise en forme en HTML ;
 +
* enfin <syntaxhighlight lang="javascript" inline>function traiterClasse(id)</syntaxhighlight> :
 +
** prend {{code|id}} : une chaine de caractères contenant l'identifiant d'un élément du DOM ;
 +
** et modifie en conséquence cet élément du DOM.
 +
=== Correction ===
 +
https://codepen.io/lzbk/pen/OOBYJq
 +
 
 +
<span class="mw-customtoggle-correction2">Voir une correction</span>
 +
 
 +
<syntaxhighlight lang="javascript" line="line" class="mw-collapsible mw-collapsed" id="mw-customcollapsible-correction2">//pour savoir si un caractère est un nombre (ou peut en faire partie)
 +
function estNombre(char){
 +
  var resultat;
 +
  switch(char){
 +
    case "0":
 +
    case "1":
 +
    case "2":
 +
    case "3":
 +
    case "4":
 +
    case "5":
 +
    case "6":
 +
    case "7":
 +
    case "8":
 +
    case "9":
 +
    case ".":
 +
      resultat = true;
 +
      break;
 +
    default:
 +
      resultat = false;
 +
  }
 +
  return resultat;
 +
}
 +
 
 +
//Pour récupérer toutes les informations nécessaires
 +
function traiterLigne(ligne){
 +
var i=0;
 +
var resultat = {"prenom":"",
 +
                  "notes":[ ],
 +
                  "moyenne":false};
 +
while (i < ligne.length
 +
&& ligne.charAt(i) != " "
 +
&& ligne.charAt(i) != ":"){
 +
resultat.prenom += ligne.charAt(i);
 +
i++;
 +
}
 +
  if(i==ligne.length){
 +
    resultat=false;
 +
  }
 +
  else{
 +
    let nbCourant = "",
 +
        somme = 0;
 +
    while(i <= ligne.length){
 +
      if (i < ligne.length
 +
      && estNombre(ligne.charAt(i))){
 +
        nbCourant += ligne.charAt(i); //chaine de caractère
 +
      }
 +
      else if(nbCourant!==""){
 +
        let laNote = Number(nbCourant);
 +
        somme += laNote ;
 +
        resultat.notes.push(laNote);
 +
        nbCourant = "";
 +
      }
 +
      i++;
 +
    }
 +
    if(resultat.notes.length>0){
 +
      resultat.moyenne = somme/resultat.notes.length
 +
    }
 +
  }
 +
return resultat;
 +
}
 +
 
 +
function ecrireLigne(semestre){
 +
  var resultat = "<i>" + semestre.prenom + "</i>&nbsp;: ";
 +
  for(let i=0; i<semestre.notes.length;i++){
 +
    if(i > 0){//pour les séparateurs
 +
      resultat = resultat +", "
 +
    }
 +
    if(semestre.notes[i]>=10){
 +
      resultat = resultat + "<b>" + semestre.notes[i] + "</b>";
 +
    }
 +
    else{
 +
      resultat = resultat + semestre.notes[i];
 +
    }
 +
  }
 +
  resultat = resultat + " → <u>" + semestre.moyenne + "</u>";
 +
  return resultat;
 +
}
 +
 
 +
//prend un tableau du DOM et stocke les données extraites
 +
//dans un tableau d'objets composites
 +
function traiterClasse(id){
 +
  var elt = document.getElementById(id),
 +
      tableauDOM = elt.children;
 +
  for(let i=0;i<tableauDOM.length;i++){
 +
    tableauDOM[i].innerHTML = ecrireLigne(traiterLigne(tableauDOM[i].innerHTML));
 +
  }
 +
}
 +
 
 +
//Programme principal
 +
traiterClasse("fastoche");
 +
traiterClasse("moyen");
 +
traiterClasse("chaud");</syntaxhighlight>
 +
 
 +
== Méthode 3 ==
 +
Pour gagner en modularité et donc en maintenabilité, nous allons créer une [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class classe] d'objets <syntaxhighlight lang="javascript" inline>Eleve</syntaxhighlight>, qui '''encapsulera''' données et traitements.
 +
 
 +
{{encart|NB : contrairement à ce qui a été dit en cours, il n'y a plus besoin du [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode <syntaxhighlight lang="javascript" inline>"use strict";</syntaxhighlight>], pour utiliser les classes dans les navigateurs modernes.}}
 +
 
 +
La <syntaxhighlight lang="javascript" inline>class Eleve</syntaxhighlight> :
 +
* devra faire figurer les trois '''attributs''' des objets de la [[#Méthode 2|méthode 2]], qui seront initialisés dans son '''constructeur''' (<syntaxhighlight lang="javascript" inline>constructor(prenom)</syntaxhighlight>) ;
 +
* elle possèdera un ''setter'' :
 +
** <syntaxhighlight lang="javascript" inline>setNom(prenom)</syntaxhighlight> : prend une <syntaxhighlight lang="javascript" inline>string</syntaxhighlight> en entrée et la stocke dans l'attribut correspondant ;
 +
* la méthode <syntaxhighlight lang="javascript" inline>ajouterNote(note)</syntaxhighlight> prend un nombre et l'ajoute à la liste de notes, tout en mettant à jour la moyenne de l'élève en conséquence ;
 +
* et une liste de ''getters'' :
 +
** <syntaxhighlight lang="javascript" inline>getNom()</syntaxhighlight> : renvoie le nom de l'objet <syntaxhighlight lang="javascript" inline>Eleve</syntaxhighlight> concerné ;
 +
** <syntaxhighlight lang="javascript" inline>getMoy()</syntaxhighlight> : renvoie la moyenne de l'objet <syntaxhighlight lang="javascript" inline>Eleve</syntaxhighlight> concerné ;
 +
** <syntaxhighlight lang="javascript" inline>getTabNotes()</syntaxhighlight> : renvoie un tableau des notes de l'objet <syntaxhighlight lang="javascript" inline>Eleve</syntaxhighlight> concerné ;
 +
** <syntaxhighlight lang="javascript" inline>getNbNotes()</syntaxhighlight> : renvoie le nombre de notes obtenues par l'élève ;
 +
* enfin la méthode <syntaxhighlight lang="javascript" inline>toString()</syntaxhighlight> : transforme l'objet en chaine de caractère au format défini ci-dessus.
 +
 
 +
Pour tester la classe vous pourrez utiliser le code suivant :
 +
<syntaxhighlight lang="javascript">//test du code
 +
var meg = new Eleve("Megan");
 +
console.log("¿Megan? → ",meg.getNom());
 +
console.log("¿notes et moyenne quand il n'y en a pas encore? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
 +
meg.ajouterNote(12);
 +
console.log("¿[12], 1, 12? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
 +
meg.ajouterNote(15.5);
 +
console.log("¿[12,15.5], 2, 13.75? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
 +
meg.ajouterNote(13);
 +
console.log("¿[12,15.5,13], 3, 13.5? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
 +
console.log("<li>"+meg+"</li>");
 +
</syntaxhighlight>
 +
 
 +
Quand cela sera fait vous pourrez modifier le constructeur pour qu'il puisse prendre une ligne ou un prénom :
 +
<syntaxhighlight lang="javascript" inline>constructor(prenomOuLigne, isLigne)</syntaxhighlight> traite une ligne quand <syntaxhighlight lang="javascript" inline>isLigne</syntaxhighlight> est vrai, traite un prénom sinon.
 +
=== Correction ===
 +
<span class="mw-customtoggle-correction3">Voir une correction</span>
 +
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-correction3">
 +
<syntaxhighlight lang="javascript" line="line">var msg = "Nooooooon, enfin… ",
 +
    msgs = ["C'est un peu tôt pour ",
 +
            "vous creuser les méninges. ",
 +
            "Mais on va y arriver. ",
 +
            "Là, il faut encore ",
 +
            "que je mette une correction. "
 +
            ];
 +
for(var i=0; i<=msgs.length/2-1;i++){
 +
  if(i%2==0){
 +
    msg += msgs[i]+msgs[msgs.length-1-i];
 +
  }
 +
  else{
 +
    msg += msgs[msgs.length-1-i]+msgs[i];
 +
  }
 +
}
 +
if(i !== msgs.length/2){
 +
  msg = msg+msgs[i];
 +
}
 +
console.log(msg);</syntaxhighlight>
 +
<span class="mw-customtoggle-correction4">La vraie correction</span></div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-correction4">https://codepen.io/lzbk/pen/xQYdrj
 +
<syntaxhighlight lang="javascript" line="line">
 +
//pour savoir si un caractère est un nombre (ou peut en faire partie)
 +
function estNombre(char){
 +
/* cf. précédemment */
 +
}
 +
 
 +
//La classe élève
 +
class Eleve{
 +
//prend une ligne et crée un élève en conséquence…
 +
constructor(ligneOrPrenom, isLigne){
 +
this.notes = [] ;
 +
this.moy = false;
 +
this.prenom = "";
 +
if(typeof isLigne == "undefined" || isLigne === false){
 +
//constructeur de base quand isLigne est indéfini ou faux
 +
this.setNom(ligneOrPrenom) ;
 +
}
 +
else{//sinon cf. traiterLigne
 +
var i=0;
 +
while (i < ligneOrPrenom.length
 +
&& ligneOrPrenom.charAt(i) != " "
 +
&& ligneOrPrenom.charAt(i) != ":"){
 +
this.prenom += ligneOrPrenom.charAt(i);
 +
i++;
 +
}
 +
if(i<ligneOrPrenom.length){
 +
let nbCourant = "";
 +
while(i <= ligneOrPrenom.length){
 +
if (i < ligneOrPrenom.length
 +
&& estNombre(ligneOrPrenom.charAt(i))){
 +
nbCourant += ligneOrPrenom.charAt(i); //chaine de caractère
 +
}
 +
else if(nbCourant!==""){
 +
this.ajouterNote(Number(nbCourant));
 +
nbCourant="";
 +
}
 +
i++;
 +
}
 +
}
 +
}
 +
}
 +
 
 +
setNom(prenom){
 +
this.prenom = prenom;
 +
}
 +
 
 +
getNom(){
 +
return this.prenom;
 +
}
 +
 
 +
getNbNotes(){
 +
return this.notes.length ;
 +
}
 +
 
 +
getNotes(){
 +
return this.notes;
 +
}
 +
 
 +
getMoy(){
 +
return this.moy ;
 +
}
 +
 
 +
ajouterNote(note){
 +
if(this.getNbNotes() > 0){
 +
this.moy = (this.moy * this.getNbNotes() + note)/(this.getNbNotes()+1);
 +
}
 +
else{
 +
this.moy = note ;
 +
}
 +
this.notes.push(note);
 +
}
 +
 
 +
toString(){
 +
var resultat = "<i>" + this.getNom() + "</i>&nbsp;: ";
 +
for(let i=0; i<this.getNbNotes();i++){
 +
if(i > 0){//pour les séparateurs
 +
resultat = resultat +", "
 +
}
 +
if(this.notes[i]>=10){
 +
resultat = resultat + "<b>" + this.notes[i] + "</b>";
 +
}
 +
else{
 +
resultat = resultat + this.notes[i];
 +
}
 +
}
 +
resultat = resultat + " → <u>" + this.getMoy() + "</u>";
 +
return resultat;
 +
}
 +
}
 +
 
 +
//Le programme principal adapté
 +
function traiterClasse(id){
 +
var tableauDOM = document.getElementById(id).children;
 +
for(let i=0;i<tableauDOM.length;i++){
 +
tableauDOM[i].innerHTML = "" + new Eleve(tableauDOM[i].innerHTML, true);
 +
//transcodé en string avec toString() automatiquement
 +
}
 +
}
 +
 
 +
//test de la classe
 +
var meg = new Eleve("Megan");
 +
console.log("¿Megan? → ",meg.getNom());
 +
console.log("¿notes et moyenne quand il n'y en a pas encore? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
 +
meg.ajouterNote(12);
 +
console.log("¿[12], 1, 12? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
 +
meg.ajouterNote(15.5);
 +
console.log("¿[12,15.5], 2, 13.75? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
 +
meg.ajouterNote(13);
 +
console.log("¿[12,15.5,13], 3, 13.5? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
 +
console.log("<li>"+meg+"</li>");
 +
 
 +
//Programme principal
 +
traiterClasse("fastoche");
 +
traiterClasse("moyen");
 +
traiterClasse("chaud");
 +
 
 +
</syntaxhighlight></div>

Version actuelle datée du 18 novembre 2020 à 12:28

Énoncé

On a un document HTML, qui contient une liste d’étudiant avec les notes obtenues lors du semestre, sous la forme suivante :

<h2>Facile</h2>
<ul id="fastoche">
  <li>Maegan : 4, 8, 10, 12</li>
  <li>Ajay : 15, 16, 12, 16</li>
  <li>Sheri : 9, 10, 11, 15</li>
  <li>Marianne : 10, 10, 10, 10</li>
</ul>
<h2>Moins facile</h2>
<ul id = "moyen">
  <li>Gus : 4, 5.5, 9, 9.5, 10</li>
  <li>Sammy : 3, 17</li>
  <li>Belinda : 8.5, 11, 20</li>
</ul>
<h2>Très difficile</h2>
<ul id="chaud">
  <li>Brayden: 12, 14  , 8.5 ; 12 ;</li>
  <li>Kassidy : 13, 3.5 ;</li>
  <li>Jonas : 18, 19, 16.5, 10.</li>
</ul>

On veut créer du code qui permette automatiquement de :

  • Mettre en italiques le nom de l’élève ;
  • Mettre en gras les notes supérieures à la moyenne ;
  • Calculer et souligner la moyenne.

Informations utiles

Méthode 1 : une analyse descendante

On va procéder progressivement et créer un ensemble de fonctions que nous regrouperons ensuite :

  • function getEleves(id)
    • id est une chaine de caractères contenant l'identifiant d'un élément du DOM ;
    • renvoie la liste des éléments contenus dans l'élément d'identifiant du DOM ;
  • function getPrenom(ligne)
    • ligne est une chaine de caractères (telle que le contenu des <li> ci-dessus ;
    • renvoie une chaine de caractères ne contenant que le prénom de l'élève ;
  • function getNotes(ligne)
    • ligne est une chaine de caractères (telle que le contenu des <li> ci-dessus ;
    • renvoie un tableau de Number avec toutes les notes ;
    • cette fonction nécessite une autre fonction :
      function estNombre(caractere)
      • caractere est un caractère (ou une string de longueur 1 ;
      • renvoie un booléen :
        • true si le caractère peut être contenu dans l'écriture d'un nombre ;
        • falsesinon ;
  • function moy(tabNotes)
    • tabNotes est un tableau de notes (Number) ;
    • renvoie un Number représentant la moyenne des nombres dans le tableau ;
  • function bilan(ligne)
    • ligne est une chaine de caractères (telle que le contenu des <li> ci-dessus ;
    • renvoie une chaine de caractère répondant aux contraintes de l'énoncé ;
  • function traite(id)
    • id est un identifiant d'élément du DOM qui contient une liste d'élève ;
    • remplace le contenu de l'élément par les informations mises en forme.

Correction

Voir une correction

 1 //pour savoir si un caractère est un nombre (ou peut en faire partie)
 2 function estNombre(char){
 3   var resultat;
 4   switch(char){
 5     case "0":
 6     case "1":
 7     case "2":
 8     case "3":
 9     case "4":
10     case "5":
11     case "6":
12     case "7":
13     case "8":
14     case "9":
15     case ".":
16       resultat = true;
17       break;
18     default:
19       resultat = false;
20   }
21   return resultat;
22 }
23 
24 //Pour récupérer toutes les informations nécessaires
25 function traiterLigne(ligne){
26 	var i=0;
27 	var resultat = {"prenom":"",
28                   "notes":[ ],
29                   "moyenne":false};
30 	while (i < ligne.length
31 		 && ligne.charAt(i) != " "
32 		 && ligne.charAt(i) != ":"){
33 		resultat.prenom += ligne.charAt(i);
34 		i++;
35 	}
36   if(i==ligne.length){
37     resultat=false;
38   }
39   else{
40     let nbCourant = "",
41         somme = 0;
42     while(i <= ligne.length){
43       if (i < ligne.length
44        && estNombre(ligne.charAt(i))){
45         nbCourant += ligne.charAt(i); //chaine de caractère
46       }
47       else if(nbCourant!==""){
48         let laNote = Number(nbCourant);
49         somme += laNote ;
50         resultat.notes.push(laNote);
51         nbCourant = "";
52       }
53       i++;
54     }
55     if(resultat.notes.length>0){
56       resultat.moyenne = somme/resultat.notes.length
57     }
58   }
59 	return resultat;
60 }
61 
62 function ecrireLigne(semestre){
63   var resultat = "<i>" + semestre.prenom + "</i>&nbsp;: ";
64   for(let i=0; i<semestre.notes.length;i++){
65     if(i > 0){//pour les séparateurs
66       resultat = resultat +", "
67     }
68     if(semestre.notes[i]>=10){
69       resultat = resultat + "<b>" + semestre.notes[i] + "</b>";
70     }
71     else{
72       resultat = resultat + semestre.notes[i];
73     }
74   }
75   resultat = resultat + " → <u>" + semestre.moyenne + "</u>";
76   return resultat;
77 }
78 
79 //prend un tableau du DOM et stocke les données extraites
80 //dans un tableau d'objets composites
81 function traiterClasse(id){
82   var elt = document.getElementById(id),
83       tableauDOM = elt.children;
84   for(let i=0;i<tableauDOM.length;i++){
85     tableauDOM[i].innerHTML = ecrireLigne(traiterLigne(tableauDOM[i].innerHTML));
86   }
87 }
88 
89 //Programme principal
90 traiterClasse("fastoche");
91 traiterClasse("moyen");
92 traiterClasse("chaud");

Méthode 2 : création d'objets pour limiter le nombre de tours de boucles

Dans cette méthode, le code sera moins lisible car, en substance, les fonctions getPrenom(), getNotes(), moy() seront traitées en une seule fonction.

  • function estNombre(caractere)
    • caractere est un caractère (ou une string de longueur 1 ;
    • renvoie un booléen :
      • true si le caractère peut être contenu dans l'écriture d'un nombre ;
      • falsesinon ;
  • function traiterLigne(ligne) est la fonction qui regroupe les traitements de getPrenom(), getNotes() et moy().
    • cette fonction prendra en entrée une chaine de caractères contenant les informations non mises en forme ;
    • elle renverra un objet composite muni de 3 attributs :
      • prenom, le prénom de l'élève (string) ;
      • notes, un tableau de Number avec les notes de l'élève ;
      • moyenne, un Number, sa moyenne ;
  • function ecrireLigne(semestre)
    • prend un objet tel que celui renvoyé par traiterLigne ;
    • et génère en conséquences une string mise en forme en HTML ;
  • enfin function traiterClasse(id) :
    • prend id : une chaine de caractères contenant l'identifiant d'un élément du DOM ;
    • et modifie en conséquence cet élément du DOM.

Correction

https://codepen.io/lzbk/pen/OOBYJq

Voir une correction

 1 //pour savoir si un caractère est un nombre (ou peut en faire partie)
 2 function estNombre(char){
 3   var resultat;
 4   switch(char){
 5     case "0":
 6     case "1":
 7     case "2":
 8     case "3":
 9     case "4":
10     case "5":
11     case "6":
12     case "7":
13     case "8":
14     case "9":
15     case ".":
16       resultat = true;
17       break;
18     default:
19       resultat = false;
20   }
21   return resultat;
22 }
23 
24 //Pour récupérer toutes les informations nécessaires
25 function traiterLigne(ligne){
26 	var i=0;
27 	var resultat = {"prenom":"",
28                   "notes":[ ],
29                   "moyenne":false};
30 	while (i < ligne.length
31 		 && ligne.charAt(i) != " "
32 		 && ligne.charAt(i) != ":"){
33 		resultat.prenom += ligne.charAt(i);
34 		i++;
35 	}
36   if(i==ligne.length){
37     resultat=false;
38   }
39   else{
40     let nbCourant = "",
41         somme = 0;
42     while(i <= ligne.length){
43       if (i < ligne.length
44        && estNombre(ligne.charAt(i))){
45         nbCourant += ligne.charAt(i); //chaine de caractère
46       }
47       else if(nbCourant!==""){
48         let laNote = Number(nbCourant);
49         somme += laNote ;
50         resultat.notes.push(laNote);
51         nbCourant = "";
52       }
53       i++;
54     }
55     if(resultat.notes.length>0){
56       resultat.moyenne = somme/resultat.notes.length
57     }
58   }
59 	return resultat;
60 }
61 
62 function ecrireLigne(semestre){
63   var resultat = "<i>" + semestre.prenom + "</i>&nbsp;: ";
64   for(let i=0; i<semestre.notes.length;i++){
65     if(i > 0){//pour les séparateurs
66       resultat = resultat +", "
67     }
68     if(semestre.notes[i]>=10){
69       resultat = resultat + "<b>" + semestre.notes[i] + "</b>";
70     }
71     else{
72       resultat = resultat + semestre.notes[i];
73     }
74   }
75   resultat = resultat + " → <u>" + semestre.moyenne + "</u>";
76   return resultat;
77 }
78 
79 //prend un tableau du DOM et stocke les données extraites
80 //dans un tableau d'objets composites
81 function traiterClasse(id){
82   var elt = document.getElementById(id),
83       tableauDOM = elt.children;
84   for(let i=0;i<tableauDOM.length;i++){
85     tableauDOM[i].innerHTML = ecrireLigne(traiterLigne(tableauDOM[i].innerHTML));
86   }
87 }
88 
89 //Programme principal
90 traiterClasse("fastoche");
91 traiterClasse("moyen");
92 traiterClasse("chaud");

Méthode 3

Pour gagner en modularité et donc en maintenabilité, nous allons créer une classe d'objets Eleve, qui encapsulera données et traitements.

NB : contrairement à ce qui a été dit en cours, il n'y a plus besoin du "use strict";, pour utiliser les classes dans les navigateurs modernes.

La class Eleve :

  • devra faire figurer les trois attributs des objets de la méthode 2, qui seront initialisés dans son constructeur (constructor(prenom)) ;
  • elle possèdera un setter :
    • setNom(prenom) : prend une string en entrée et la stocke dans l'attribut correspondant ;
  • la méthode ajouterNote(note) prend un nombre et l'ajoute à la liste de notes, tout en mettant à jour la moyenne de l'élève en conséquence ;
  • et une liste de getters :
    • getNom() : renvoie le nom de l'objet Eleve concerné ;
    • getMoy() : renvoie la moyenne de l'objet Eleve concerné ;
    • getTabNotes() : renvoie un tableau des notes de l'objet Eleve concerné ;
    • getNbNotes() : renvoie le nombre de notes obtenues par l'élève ;
  • enfin la méthode toString() : transforme l'objet en chaine de caractère au format défini ci-dessus.

Pour tester la classe vous pourrez utiliser le code suivant :

//test du code
var meg = new Eleve("Megan");
console.log("¿Megan? → ",meg.getNom());
console.log("¿notes et moyenne quand il n'y en a pas encore? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
meg.ajouterNote(12);
console.log("¿[12], 1, 12? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
meg.ajouterNote(15.5);
console.log("¿[12,15.5], 2, 13.75? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
meg.ajouterNote(13);
console.log("¿[12,15.5,13], 3, 13.5? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
console.log("<li>"+meg+"</li>");

Quand cela sera fait vous pourrez modifier le constructeur pour qu'il puisse prendre une ligne ou un prénom : constructor(prenomOuLigne, isLigne) traite une ligne quand isLigne est vrai, traite un prénom sinon.

Correction

Voir une correction

 1 var msg = "Nooooooon, enfin… ",
 2     msgs = ["C'est un peu tôt pour ",
 3             "vous creuser les méninges. ",
 4             "Mais on va y arriver. ",
 5             "Là, il faut encore ",
 6             "que je mette une correction. "
 7             ];
 8 for(var i=0; i<=msgs.length/2-1;i++){
 9   if(i%2==0){
10     msg += msgs[i]+msgs[msgs.length-1-i];
11   }
12   else{
13     msg += msgs[msgs.length-1-i]+msgs[i];
14   }
15 }
16 if(i !== msgs.length/2){
17   msg = msg+msgs[i];
18 }
19 console.log(msg);
La vraie correction
https://codepen.io/lzbk/pen/xQYdrj
  1 //pour savoir si un caractère est un nombre (ou peut en faire partie)
  2 function estNombre(char){
  3 	/* cf. précédemment */
  4 }
  5 
  6 //La classe élève
  7 class Eleve{
  8 	//prend une ligne et crée un élève en conséquence…
  9 	constructor(ligneOrPrenom, isLigne){
 10 		this.notes = [] ;
 11 		this.moy = false;
 12 		this.prenom = "";
 13 		if(typeof isLigne == "undefined" || isLigne === false){
 14 		//constructeur de base quand isLigne est indéfini ou faux
 15 			this.setNom(ligneOrPrenom) ;
 16 		}
 17 		else{//sinon cf. traiterLigne
 18 			var i=0;
 19 			while (i < ligneOrPrenom.length
 20 				 && ligneOrPrenom.charAt(i) != " "
 21 				 && ligneOrPrenom.charAt(i) != ":"){
 22 				this.prenom += ligneOrPrenom.charAt(i);
 23 				i++;
 24 			}
 25 			if(i<ligneOrPrenom.length){
 26 				let nbCourant = "";
 27 				while(i <= ligneOrPrenom.length){
 28 					if (i < ligneOrPrenom.length
 29 						&& estNombre(ligneOrPrenom.charAt(i))){
 30 							nbCourant += ligneOrPrenom.charAt(i); //chaine de caractère
 31 					}
 32 					else if(nbCourant!==""){
 33 						this.ajouterNote(Number(nbCourant));
 34 						nbCourant="";
 35 					}
 36 					i++;
 37 				}
 38 			}
 39 		}
 40 	}
 41 
 42 	setNom(prenom){
 43 		this.prenom = prenom;
 44 	}
 45 
 46 	getNom(){
 47 		return this.prenom;
 48 	}
 49 
 50 	getNbNotes(){
 51 		return this.notes.length ;
 52 	}
 53 
 54 	getNotes(){
 55 		return this.notes;
 56 	}
 57 
 58 	getMoy(){
 59 		return this.moy ;
 60 	}
 61 
 62 	ajouterNote(note){
 63 		if(this.getNbNotes() > 0){
 64 			this.moy = (this.moy * this.getNbNotes() + note)/(this.getNbNotes()+1);
 65 		}
 66 		else{
 67 			this.moy = note ;
 68 		}
 69 		this.notes.push(note);
 70 	}
 71 
 72 	toString(){
 73 		var resultat = "<i>" + this.getNom() + "</i>&nbsp;: ";
 74 		for(let i=0; i<this.getNbNotes();i++){
 75 			if(i > 0){//pour les séparateurs
 76 				resultat = resultat +", "
 77 			}
 78 			if(this.notes[i]>=10){
 79 				resultat = resultat + "<b>" + this.notes[i] + "</b>";
 80 			}
 81 			else{
 82 				resultat = resultat + this.notes[i];
 83 			}
 84 		}
 85 		resultat = resultat + " → <u>" + this.getMoy() + "</u>";
 86 		return resultat;
 87 	}
 88 }
 89 
 90 //Le programme principal adapté
 91 function traiterClasse(id){
 92 	var tableauDOM = document.getElementById(id).children;
 93 	for(let i=0;i<tableauDOM.length;i++){
 94 		tableauDOM[i].innerHTML = "" + new Eleve(tableauDOM[i].innerHTML, true);
 95 		//transcodé en string avec toString() automatiquement
 96 	}
 97 }
 98 
 99 //test de la classe
100 var meg = new Eleve("Megan");
101 console.log("¿Megan? → ",meg.getNom());
102 console.log("¿notes et moyenne quand il n'y en a pas encore? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
103 meg.ajouterNote(12);
104 console.log("¿[12], 1, 12? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
105 meg.ajouterNote(15.5);
106 console.log("¿[12,15.5], 2, 13.75? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
107 meg.ajouterNote(13);
108 console.log("¿[12,15.5,13], 3, 13.5? →",meg.getNotes(), meg.getNbNotes(), meg.getMoy());
109 console.log("<li>"+meg+"</li>");
110 
111 //Programme principal
112 traiterClasse("fastoche");
113 traiterClasse("moyen");
114 traiterClasse("chaud");