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
m (Loizbek a déplacé la page Cours:Mathieu Loiseau/Cours/Master DDL — Parcours DILIPEM/M2 — technologies avancées du eLearning 2/exercices/Élèves vers Cours:Technologies avancées du eLearning 2/exercices/Élèves sans laisser de redirection) |
|||
(19 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 30 : | Ligne 30 : | ||
* <syntaxhighlight lang="javascript" inline>Number("25")</syntaxhighlight> → <syntaxhighlight lang="javascript" inline>25</syntaxhighlight> (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 == | + | == Méthode 1 : une analyse descendante == |
On va procéder progressivement et créer un ensemble de fonctions que nous regrouperons ensuite : | On va procéder progressivement et créer un ensemble de fonctions que nous regrouperons ensuite : | ||
* <syntaxhighlight lang="javascript" inline>function getEleves(id)</syntaxhighlight> | * <syntaxhighlight lang="javascript" inline>function getEleves(id)</syntaxhighlight> | ||
Ligne 60 : | Ligne 60 : | ||
<span class="mw-customtoggle-correction1">Voir une correction</span> | <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){ | |
− | |||
− | // | ||
− | function | ||
var i=0; | var i=0; | ||
− | var resultat = ""; | + | var resultat = {"prenom":"", |
+ | "notes":[ ], | ||
+ | "moyenne":false}; | ||
while (i < ligne.length | while (i < ligne.length | ||
&& ligne.charAt(i) != " " | && ligne.charAt(i) != " " | ||
&& ligne.charAt(i) != ":"){ | && ligne.charAt(i) != ":"){ | ||
− | resultat += ligne.charAt(i); | + | resultat.prenom += ligne.charAt(i); |
i++; | i++; | ||
} | } | ||
if(i==ligne.length){ | if(i==ligne.length){ | ||
resultat=false; | 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; | return resultat; | ||
} | } | ||
− | //pour savoir si un caractère est un nombre (ou peut en faire partie) | + | function ecrireLigne(semestre){ |
− | function | + | var resultat = "<i>" + semestre.prenom + "</i> : "; |
+ | 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; | var resultat; | ||
switch(char){ | switch(char){ | ||
Ligne 110 : | Ligne 202 : | ||
} | } | ||
− | function | + | //Pour récupérer toutes les informations nécessaires |
− | + | function traiterLigne(ligne){ | |
− | + | var i=0; | |
− | + | var resultat = {"prenom":"", | |
− | + | "notes":[ ], | |
− | if(ligne.charAt(i) == " | + | "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 = ""; | nbCourant = ""; | ||
} | } | ||
+ | i++; | ||
} | } | ||
− | + | if(resultat.notes.length>0){ | |
− | + | resultat.moyenne = somme/resultat.notes.length | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
− | + | return resultat; | |
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | function | + | function ecrireLigne(semestre){ |
− | + | var resultat = "<i>" + semestre.prenom + "</i> : "; | |
− | + | for(let i=0; i<semestre.notes.length;i++){ | |
− | + | if(i > 0){//pour les séparateurs | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | for(let i=0; i< | ||
− | if( | ||
resultat = resultat +", " | resultat = resultat +", " | ||
} | } | ||
− | if( | + | if(semestre.notes[i]>=10){ |
− | resultat = resultat + "<b>" + | + | resultat = resultat + "<b>" + semestre.notes[i] + "</b>"; |
} | } | ||
else{ | else{ | ||
− | resultat = resultat + | + | resultat = resultat + semestre.notes[i]; |
} | } | ||
} | } | ||
− | resultat = resultat + " → <u>" + moyenne | + | resultat = resultat + " → <u>" + semestre.moyenne + "</u>"; |
return resultat; | return resultat; | ||
} | } | ||
− | console.log( | + | //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> : "; | ||
+ | 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
DOMelt.children
→ renvoie un tableau avec la liste des enfants d’un élément ;mot.charAt(i)
→ (i+1)e caractère d’une chaine ;chaineOuTableau.length
→ nombre d’éléments ;Number("25")
→25
(en tant queNumber
).
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 unestring
de longueur 1 ;- renvoie un booléen :
true
si le caractère peut être contenu dans l'écriture d'un nombre ;false
sinon ;
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> : ";
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 unestring
de longueur 1 ;- renvoie un booléen :
true
si le caractère peut être contenu dans l'écriture d'un nombre ;false
sinon ;
function traiterLigne(ligne)
est la fonction qui regroupe les traitements degetPrenom()
,getNotes()
etmoy()
.- 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 deNumber
avec les notes de l'élève ;moyenne
, unNumber
, 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 ;
- prend un objet tel que celui renvoyé par
- 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.
- prend
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> : ";
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 unestring
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'objetEleve
concerné ;getMoy()
: renvoie la moyenne de l'objetEleve
concerné ;getTabNotes()
: renvoie un tableau des notes de l'objetEleve
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);
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> : ";
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");