Évaluation 1 — Sujet
2025-2026 · séances 1 à 3
Informations générales
- Durée : 3 heures
- Note : /20
- Documents autorisés : le site web du cours uniquement — https://remisharrock.gitlab.io/typescript101/
- Internet : non disponible (mode examen hors ligne)
- Intelligence artificielle : interdite
| Partie | Contenu | Points |
|---|---|---|
| Partie 1 | Questions théoriques (6 questions) | 10 points |
| Partie 2 | Exercice de codage — Librairie en ligne | 10 points |
| Total | 20 points |
Mise en place (5 minutes)
Téléchargez l’archive outillage.tar.gz depuis la page Outillage et décompressez-la.
- Copiez le dossier
outillage/projet_templateen entier, renommez la copiemon_projet(à la souris, ou aveccp -R outillage/projet_template mon_projet—-Ren majuscule). - Dans un terminal :
cd mon_projetpuisnpx astro dev - Ouvrez
http://localhost:4321/dans le navigateur. - Vos fichiers
.astrovont danssrc/pages/, vos fichiers.tsdanssrc/scripts/.
Le détail complet et la résolution de problèmes se trouvent dans outillage/README.html.
Partie 1 — Questions théoriques
Durée indicative : 1h30 — 6 questions, 10 points
Répondez dans le fichier reponse_NOM.txt, entre les balises %%%DEBUT_Q1%%% … %%%FIN_Q1%%%, etc. Répondez à chaque question de manière claire et argumentée.
Question 1 — Types et typage en TypeScript (1,5 points)
Considérez le code TypeScript suivant :
const a: number = 10;
const b: string = "Bonjour";
let c = 42;
let d: number | string = "hello";
c = "test";
d = 100;
d = true;
const e: number = parseInt("abc");
console.log(e);
console.log(e + 1);a) Pour chaque affectation (c = "test", d = 100, d = true), indiquez si elle sera acceptée ou refusée par le compilateur TypeScript. Justifiez en expliquant comment TypeScript détermine le type de c alors qu’il n’est pas écrit explicitement, et ce que signifie le type number | string pour d.
b) La fonction parseInt("abc") ne provoque pas d’erreur de compilation. Pourtant, que vaut e à l’exécution ? Que vaut e + 1 ? Expliquez pourquoi TypeScript n’a pas détecté ce problème à la compilation. Qu’est-ce que cela nous apprend sur les limites du typage statique ?
c) Un collègue vous propose de déclarer toutes ses variables avec le type any « pour ne plus jamais avoir d’erreurs de compilation ». Écrivez un court exemple (3-4 lignes) qui compile sans erreur grâce à any mais qui plante à l’exécution. Expliquez pourquoi cette approche est dangereuse et quel type alternatif plus sûr existe en TypeScript (indice : il force à vérifier le type avant utilisation).
Question 2 — HTML, DOM et interaction TypeScript (1,5 points)
Considérez ce code TypeScript exécuté dans un navigateur via Astro :
const champNom = document.getElementById("nom") as HTMLInputElement;
const affichage = document.getElementById("resultat") as HTMLDivElement;
champNom.addEventListener("input", function(event: Event) {
const valeur = champNom.value;
affichage.innerHTML = valeur;
});Un utilisateur tape le texte suivant dans le champ de saisie :
<img src="x" onerror="document.title='Piraté'">
a) Que se passe-t-il quand ce texte est inséré via affichage.innerHTML ? Le navigateur affiche-t-il simplement le texte tel quel, ou se passe-t-il autre chose ? Décrivez le résultat attendu et expliquez pourquoi c’est problématique.
b) Proposez une correction du code pour empêcher ce comportement dangereux. Quelle propriété utiliser à la place de innerHTML et pourquoi protège-t-elle contre ce type d’attaque ?
c) Dans le contexte d’Astro, expliquez pourquoi on peut écrire <script src="../scripts/app.ts"> dans un fichier .astro alors que dans un fichier .html classique il faut référencer un fichier .js. Quel rôle joue le serveur Astro dans cette transformation ?
Question 3 — Modules (1,5 points)
Soit les fichiers suivants :
utils.ts :
export const GRAVITE = 9.81;
export function vitesseChute(hauteur: number): number {
return Math.sqrt(2 * GRAVITE * hauteur);
}
export function tempsChute(hauteur: number): number {
return Math.sqrt(2 * hauteur / GRAVITE);
}app.ts :
import { GRAVITE, vitesseChute } from "./utils.ts";
import { GRAVITE as G_LUNE, vitesseChute as vitesseLune } from "./lune.ts";
console.log(`Terre : g = ${GRAVITE}`);
console.log(`Lune : g = ${G_LUNE}`);
console.log(`Chute de 10m sur Terre : ${vitesseChute(10).toFixed(2)} m/s`);
console.log(`Chute de 10m sur Lune : ${vitesseLune(10).toFixed(2)} m/s`);a) La fonction tempsChute est exportée dans utils.ts mais n’est pas importée dans app.ts. Est-ce un problème ? Le compilateur va-t-il signaler une erreur ? Expliquez ce que signifie le fait d’exporter une fonction sans l’importer ailleurs, et dans quel cas cela pourrait être utile.
b) Dans app.ts, on utilise as pour renommer GRAVITE en G_LUNE et vitesseChute en vitesseLune. Écrivez le contenu du fichier lune.ts pour que ce code fonctionne correctement. La gravité sur la Lune est de 1.62 m/s².
c) Un étudiant écrit par erreur import { GRAVITE } from "./lune.ts" sans renommer, alors qu’il a déjà import { GRAVITE } from "./utils.ts" sur la ligne précédente. Que se passe-t-il ? Expliquez l’erreur obtenue et comment la résoudre.
Question 4 — Fonctions fléchées (1,5 points)
Considérez le code suivant :
const operations: ((a: number, b: number) => number)[] = [
(a, b) => a + b,
(a, b) => a - b,
(a, b) => a * b,
(a, b) => a % b,
];
const appliquerTout = (
x: number,
y: number,
ops: ((a: number, b: number) => number)[]
): number[] => {
return ops.map((op) => op(x, y));
};
const resultats = appliquerTout(17, 5, operations);
console.log(resultats);a) Expliquez le type ((a: number, b: number) => number)[]. Décomposez-le en deux parties : que représente la partie entre parenthèses (a: number, b: number) => number, et que signifie le [] à la fin ? Quel concept cela illustre-t-il (stocker des _____ dans un tableau) ?
b) La fonction appliquerTout utilise .map() avec une fonction fléchée à l’intérieur. Expliquez pas à pas ce qui se passe quand appliquerTout(17, 5, operations) est appelé. Pour chaque élément du tableau operations, quelle opération est effectuée et quel résultat est produit ?
c) Ajoutez au tableau operations une nouvelle fonction fléchée qui retourne le plus grand des deux nombres (sans utiliser Math.max). Puis modifiez appliquerTout pour qu’elle accepte un troisième paramètre optionnel : une fonction fléchée filtrer: (n: number) => boolean. Si ce paramètre est fourni, la fonction doit appliquer un .filter() sur les résultats avant de les retourner. Appliquez un filtre qui ne garde que les résultats strictement positifs. Montrez le code complet et le résultat obtenu.
Question 5 — map, reduce, filter, find, forEach (1,5 points)
Soit le code suivant :
const villes: { nom: string; population: number; superficie: number }[] = [
{ nom: "Paris", population: 2161000, superficie: 105.4 },
{ nom: "Marseille", population: 873076, superficie: 240.6 },
{ nom: "Lyon", population: 522250, superficie: 47.9 },
{ nom: "Toulouse", population: 498003, superficie: 118.3 },
{ nom: "Nice", population: 342522, superficie: 71.9 },
{ nom: "Nantes", population: 318808, superficie: 65.2 },
];a) Écrivez une seule expression chaînée qui, à partir du tableau villes :
- Calcule la densité de population de chaque ville (population / superficie) en créant de nouveaux objets qui ont les mêmes propriétés plus une propriété
densite - Ne garde que les villes ayant une densité supérieure à 5000 hab/km²
- Calcule la densité moyenne de ces villes denses
Indiquez quelles villes sont retenues par le filtre et la densité moyenne obtenue.
b) Un étudiant écrit le code suivant pour augmenter les populations de 10% :
const villesModifiees = villes.map((v) => {
v.population = v.population * 1.1;
return v;
});
console.log(villes[0].population);
console.log(villesModifiees[0].population);Exécutez ce code. Les deux console.log affichent-ils la même valeur ou des valeurs différentes ? Expliquez pourquoi ce résultat est surprenant (ou non). Comment corriger le map pour que le tableau villes original ne soit pas modifié ? (Indice : il faut créer un nouvel objet dans le map.)
c) En utilisant find, écrivez une expression qui cherche la première ville dont le nom contient la lettre “o” (minuscule ou majuscule). Que retourne find si aucune ville ne correspond au critère ? Quel est le type de retour de find et pourquoi TypeScript ajoute-t-il | undefined à ce type ?
Rappel : pour vérifier si une chaîne contient une sous-chaîne, vous pouvez utiliser maChaine.includes("x") ou maChaine.toLowerCase().includes("x").
Question 6 — Programmation Orientée Objet (2,5 points)
Un système de monitoring énergétique modélise différentes sources d’énergie. Voici le code :
interface ISourceEnergie {
getNom(): string;
getProduction(): number; // en MWh par an
getEmissionCO2(): number; // en tonnes de CO2 par an
}
abstract class SourceEnergie implements ISourceEnergie {
protected nom: string;
protected puissance: number; // en MW
constructor(nom: string, puissance: number) {
this.nom = nom;
this.puissance = puissance;
}
getNom(): string {
return this.nom;
}
// production = puissance × heures de fonctionnement par an
abstract getProduction(): number;
abstract getEmissionCO2(): number;
}
class Eolienne extends SourceEnergie {
private nombreTurbines: number;
constructor(nom: string, puissanceParTurbine: number, nombreTurbines: number) {
super(nom, puissanceParTurbine * nombreTurbines);
this.nombreTurbines = nombreTurbines;
}
getProduction(): number {
return this.puissance * 2200; // ~2200h de fonctionnement/an
}
getEmissionCO2(): number {
return this.getProduction() * 0.014; // 14g CO2/kWh → 0.014 t CO2/MWh
}
}
class CentraleGaz extends SourceEnergie {
private rendement: number; // entre 0 et 1
constructor(nom: string, puissance: number, rendement: number) {
super(nom, puissance);
this.rendement = rendement;
}
getProduction(): number {
return this.puissance * 5000 * this.rendement; // ~5000h/an × rendement
}
getEmissionCO2(): number {
return this.getProduction() * 0.49; // 490g CO2/kWh → 0.49 t CO2/MWh
}
}a) On tente d’exécuter le code suivant :
const src = new SourceEnergie("Test", 100);Que se passe-t-il et pourquoi ? Ensuite, on écrit :
const eol = new Eolienne("Parc Alpha", 3, 20);
console.log(eol.puissance);
console.log(eol.nombreTurbines);Quelles lignes provoquent une erreur de compilation ? Expliquez les trois niveaux de visibilité (public, protected, private) et pour chaque propriété de la hiérarchie, indiquez depuis où elle est accessible.
b) On crée un tableau et on l’utilise ainsi :
const sources: ISourceEnergie[] = [
new Eolienne("Parc Alpha", 3, 20),
new CentraleGaz("Centrale Beta", 500, 0.58),
];
sources.forEach((s) => {
console.log(`${s.getNom()} : ${s.getProduction()} MWh, ${s.getEmissionCO2()} t CO2`);
});Quand s.getProduction() est appelé, comment TypeScript/JavaScript sait-il quelle version de la méthode appeler (celle de Eolienne ou celle de CentraleGaz) ? Comment appelle-t-on ce mécanisme ? Calculez les valeurs affichées pour chaque source.
c) On souhaite ajouter une classe PanneauSolaire au système. Un panneau solaire a une surface en m² et produit 0.15 MW par 1000 m² (rendement simplifié). Il fonctionne environ 1200 heures par an et émet 0.043 tonnes de CO2 par MWh. Écrivez la classe PanneauSolaire qui hérite de SourceEnergie. Créez une instance “Ferme Gamma” de 5000 m².
d) Expliquez pourquoi le tableau est typé ISourceEnergie[] (l’interface) plutôt que SourceEnergie[] (la classe abstraite). Les deux fonctionneraient-ils ici ? Dans quel scénario l’interface serait-elle nécessaire ? (Indice : imaginez une source d’énergie qui ne partage pas les propriétés nom et puissance de SourceEnergie.)
e) Ajoutez une propriété static compteur: number à la classe SourceEnergie qui s’incrémente à chaque création d’instance. Après la création de 3 sources, quelle est la valeur de SourceEnergie.compteur ? Expliquez pourquoi on y accède via le nom de la classe (SourceEnergie.compteur) et non via une instance. Si on avait écrit eol.compteur, que se passerait-il ?
f) Un collègue propose d’ajouter la méthode ratio(): number (ratio production / émission CO2) à l’interface ISourceEnergie. Que se passe-t-il dans le code existant si on ajoute cette ligne à l’interface ? Comparez avec ce qui se passerait si on ajoutait plutôt une méthode concrète (non abstraite) ratio() directement dans la classe abstraite SourceEnergie. Quelle approche nécessite le moins de modifications du code existant, et pourquoi ?
Fin de la Partie 1
Partie 2 — Exercice de codage
Durée indicative : 1h30 — 10 points
Contexte
Vous travaillez pour une librairie en ligne. On vous fournit un catalogue de livres sous forme de données dans un module TypeScript. Votre mission est de créer une page web interactive qui permet d’afficher et de manipuler ce catalogue à l’aide de fonctions fléchées et des méthodes de tableaux (map, filter, reduce, find, forEach).
Travaillez dans votre projet mon_projet pour écrire et tester votre code, puis recopiez le code de chaque section dans le fichier reponse_NOM.txt, entre les balises %%%DEBUT_S1%%% … %%%FIN_S6%%%.
Rendez toujours ce que vous avez écrit, même incomplet. Les six sections sont largement indépendantes les unes des autres.
Organisation des fichiers dans votre projet brouillon
mon_projet/
└── src/
├── pages/
│ └── index.astro ← à remplacer par le fichier fourni ci-dessous
└── scripts/
├── catalogueLivres.ts ← à créer avec le contenu fourni ci-dessous
└── app.ts ← à remplacer par le squelette fourni ci-dessous
Aide-mémoire
Voici quelques méthodes utiles pour cet exercice qui n’ont pas été vues en cours :
.join(separateur) — Concaténer un tableau en une chaîne
La méthode .join() transforme un tableau en une seule chaîne de caractères, en insérant un séparateur entre chaque élément :
const fruits: string[] = ["pomme", "banane", "orange"];
console.log(fruits.join(", ")); // "pomme, banane, orange"
console.log(fruits.join(" - ")); // "pomme - banane - orange"
console.log(fruits.join("")); // "pommebananeaorrange" (sans séparateur)Cela est particulièrement utile pour construire du HTML à partir d’un tableau de chaînes :
const lignes: string[] = ["<li>A</li>", "<li>B</li>", "<li>C</li>"];
const html: string = "<ul>" + lignes.join("") + "</ul>";
// Résultat : "<ul><li>A</li><li>B</li><li>C</li></ul>"Créer un nouvel objet avec des propriétés modifiées
Pour créer une copie modifiée d’un objet sans altérer l’original, construisez un nouvel objet manuellement :
const original = { nom: "Alice", age: 25 };
// Créer un nouvel objet avec un age différent :
const modifie = { nom: original.nom, age: original.age + 1 };
// original.age vaut toujours 25, modifie.age vaut 26Fichier fourni 1 — src/scripts/catalogueLivres.ts
Créez ce fichier et recopiez-y ce contenu sans le modifier.
export interface Livre {
titre: string;
auteur: string;
prix: number;
annee: number;
genre: string;
}
export const livres: Livre[] = [
{ titre: "Les Misérables", auteur: "Victor Hugo", prix: 12.50, annee: 1862, genre: "Roman" },
{ titre: "Le Petit Prince", auteur: "Antoine de Saint-Exupéry", prix: 8.90, annee: 1943, genre: "Conte" },
{ titre: "Germinal", auteur: "Émile Zola", prix: 11.00, annee: 1885, genre: "Roman" },
{ titre: "L'Étranger", auteur: "Albert Camus", prix: 7.50, annee: 1942, genre: "Roman" },
{ titre: "Le Seigneur des Anneaux", auteur: "J.R.R. Tolkien", prix: 25.00, annee: 1954, genre: "Fantasy" },
{ titre: "Dune", auteur: "Frank Herbert", prix: 22.50, annee: 1965, genre: "Science-Fiction" },
{ titre: "Fondation", auteur: "Isaac Asimov", prix: 15.90, annee: 1951, genre: "Science-Fiction" },
{ titre: "1984", auteur: "George Orwell", prix: 9.90, annee: 1949, genre: "Dystopie" },
];
export const formatPrix = (prix: number): string => `${prix.toFixed(2)}€`;Fichier fourni 2 — src/pages/index.astro
Remplacez le contenu du fichier existant par celui-ci.
---
---
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Librairie WebDev101</title>
<style>
body {
font-family: sans-serif;
max-width: 900px;
margin: 20px auto;
padding: 0 20px;
}
h1 { color: #2c3e50; }
h2 { color: #34495e; border-bottom: 2px solid #3498db; padding-bottom: 5px; }
.resultat {
background-color: #f9f9f9;
border: 1px solid #ddd;
padding: 10px;
margin: 10px 0;
border-radius: 5px;
}
table {
width: 100%;
border-collapse: collapse;
margin: 10px 0;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #3498db;
color: white;
}
tr:nth-child(even) { background-color: #f2f2f2; }
.cher { color: red; font-weight: bold; }
.abordable { color: green; }
</style>
</head>
<body>
<h1>📚 Librairie WebDev101</h1>
<h2>1. Catalogue complet</h2>
<div id="catalogue" class="resultat"></div>
<h2>2. Livres abordables (moins de 20€)</h2>
<div id="livres-abordables" class="resultat"></div>
<h2>3. Titres en majuscules</h2>
<div id="titres-majuscules" class="resultat"></div>
<h2>4. Statistiques</h2>
<div id="statistiques" class="resultat"></div>
<h2>5. Recherche</h2>
<div id="recherche" class="resultat"></div>
<h2>6. Récapitulatif panier</h2>
<div id="panier" class="resultat"></div>
<script src="../scripts/app.ts"></script>
</body>
</html>Fichier fourni 3 — src/scripts/app.ts (squelette à compléter)
C’est ce fichier que vous devez compléter. Remplacez le contenu du fichier existant par ce squelette. Chaque section est repérée par un commentaire // TODO. Vous devez utiliser des fonctions fléchées et les méthodes map/filter/reduce/find/forEach selon les indications.
// TODO 1 : Importez depuis le module catalogueLivres.ts :
// - l'interface Livre
// - le tableau livres
// - la fonction formatPrix
// ============================================
// SECTION 1 : Affichage du catalogue complet (2 points)
// ============================================
// TODO 2 : Créez une fonction fléchée "creerLigneTableau" qui prend un Livre
// en paramètre et retourne une chaîne de caractères HTML représentant
// une ligne de tableau (<tr>) avec les colonnes : titre, auteur, prix (formaté), année, genre.
// La ligne doit avoir la classe CSS "cher" si le prix est >= 20, sinon "abordable".
// TODO 3 : Utilisez la méthode "map" avec la fonction creerLigneTableau
// pour transformer le tableau "livres" en un tableau de chaînes HTML.
// Puis affichez le résultat dans le div #catalogue sous forme de tableau HTML
// avec les en-têtes : Titre, Auteur, Prix, Année, Genre.
// Rappel : utilisez .join("") pour concaténer les lignes du tableau.
const catalogueDiv = document.getElementById("catalogue") as HTMLDivElement;
// ============================================
// SECTION 2 : Filtrage des livres abordables (1,5 point)
// ============================================
// TODO 4 : Utilisez "filter" avec une fonction fléchée pour ne garder
// que les livres dont le prix est strictement inférieur à 20€.
// Puis affichez la liste sous forme de puces (<ul><li>) dans le div #livres-abordables.
// Chaque puce doit afficher : "Titre - Auteur (prix)"
const abordablesDiv = document.getElementById("livres-abordables") as HTMLDivElement;
// ============================================
// SECTION 3 : Transformation avec map (1,5 point)
// ============================================
// TODO 5 : Utilisez "map" avec une fonction fléchée pour créer un tableau
// contenant uniquement les titres des livres, convertis en MAJUSCULES.
// Utilisez la méthode .toUpperCase() sur chaque titre.
// Affichez le résultat sous forme de liste à puces dans le div #titres-majuscules.
const majusculesDiv = document.getElementById("titres-majuscules") as HTMLDivElement;
// ============================================
// SECTION 4 : Statistiques avec reduce (1,5 point)
// ============================================
// TODO 6 : Utilisez "reduce" pour calculer :
// a) Le prix total de tous les livres
// b) Le prix moyen (prix total / nombre de livres)
// Affichez les résultats dans le div #statistiques :
// "Prix total du catalogue : XX.XX€"
// "Prix moyen : XX.XX€"
// "Nombre de livres : X"
const statsDiv = document.getElementById("statistiques") as HTMLDivElement;
// ============================================
// SECTION 5 : Recherche avec find (1,5 point)
// ============================================
// TODO 7 : Utilisez "find" pour :
// a) Trouver le premier livre de genre "Science-Fiction"
// b) Trouver le premier livre publié avant 1900
// Affichez les résultats dans le div #recherche.
// Attention : find peut retourner undefined si aucun élément ne correspond !
// Gérez ce cas en affichant "Aucun livre trouvé" le cas échéant.
const rechercheDiv = document.getElementById("recherche") as HTMLDivElement;
// ============================================
// SECTION 6 : Panier avec chaînage (2 points)
// ============================================
// TODO 8 : Simulez un panier d'achat.
// a) Filtrez les livres du genre "Roman"
// b) Créez de NOUVEAUX objets Livre avec le prix réduit de 10%
// (ne modifiez pas les objets originaux !)
// Pour créer un nouvel objet : { titre: livre.titre, auteur: livre.auteur, ... , prix: livre.prix * 0.9 }
// c) Calculez le total du panier avec reduce
//
// Puis utilisez forEach sur les livres du panier (romans avec remise)
// pour créer dynamiquement des éléments <p> affichés dans le div #panier.
// Chaque paragraphe doit afficher : "Titre — ancien prix → nouveau prix"
// Enfin, affichez le total du panier.
const panierDiv = document.getElementById("panier") as HTMLDivElement;Travail demandé — détail des sections
Section 1 — Affichage du catalogue complet (2 points) → %%%DEBUT_S1%%%
- Importez depuis le module
catalogueLivres.ts: l’interfaceLivre, le tableaulivres, et la fonctionformatPrix - Créez une fonction fléchée
creerLigneTableauqui prend unLivreen paramètre et retourne une chaîne HTML représentant une ligne de tableau<tr>avec les colonnes : titre, auteur, prix (formaté avecformatPrix), année, genre - La ligne doit avoir la classe CSS
"cher"si le prix ≥ 20, sinon"abordable" - Utilisez
mapavec cette fonction pour transformer le tableaulivresen lignes HTML - Affichez le résultat dans le
div#cataloguesous forme de tableau HTML complet avec les en-têtes
Recopiez la ligne d’import dans la balise %%%DEBUT_S1%%% : elle fait partie de cette section.
Section 2 — Filtrage des livres abordables (1,5 point) → %%%DEBUT_S2%%%
- Utilisez
filteravec une fonction fléchée pour ne garder que les livres dont le prix est < 20€ - Affichez la liste dans le
div#livres-abordablessous forme de puces<ul><li> - Chaque puce :
"Titre - Auteur (prix)"
Section 3 — Transformation avec map (1,5 point) → %%%DEBUT_S3%%%
- Utilisez
mappour créer un tableau contenant uniquement les titres des livres, convertis en MAJUSCULES (méthode.toUpperCase()) - Affichez dans le
div#titres-majusculessous forme de liste à puces
Section 4 — Statistiques avec reduce (1,5 point) → %%%DEBUT_S4%%%
- Utilisez
reducepour calculer le prix total et le prix moyen de tous les livres - Affichez dans le
div#statistiques: prix total, prix moyen, nombre de livres
Section 5 — Recherche avec find (1,5 point) → %%%DEBUT_S5%%%
- Utilisez
findpour trouver : le premier livre de genre “Science-Fiction” et le premier livre publié avant 1900 - Affichez dans le
div#recherche. Attention :findpeut retournerundefined— gérez ce cas
Section 6 — Panier avec chaînage (2 points) → %%%DEBUT_S6%%%
- Filtrez les livres du genre “Roman”
- Créez de nouveaux objets
Livreavec une remise de 10% sur le prix (ne pas modifier les objets originaux) - Calculez le total du panier avec
reduce - Utilisez
forEachpour créer dynamiquement des éléments<p>dans lediv#panier - Chaque paragraphe :
"Titre — ancien prix → nouveau prix" - Affichez le total du panier
Fin de la Partie 2
Rappel du fichier de réponses
Le fichier reponse_NOM.txt fourni dans l’outillage a la structure suivante. En cas de perte, vous pouvez le recréer à l’identique.
%%%DEBUT_IDENTITE%%%
NOM :
PRENOM :
%%%FIN_IDENTITE%%%
%%%DEBUT_Q1%%%
a)
b)
c)
%%%FIN_Q1%%%
%%%DEBUT_Q2%%%
...
%%%FIN_Q2%%%
%%%DEBUT_Q3%%%
...
%%%FIN_Q3%%%
%%%DEBUT_Q4%%%
...
%%%FIN_Q4%%%
%%%DEBUT_Q5%%%
...
%%%FIN_Q5%%%
%%%DEBUT_Q6%%%
...
%%%FIN_Q6%%%
%%%DEBUT_S1%%%
(code de la section 1)
%%%FIN_S1%%%
%%%DEBUT_S2%%%
(code de la section 2)
%%%FIN_S2%%%
%%%DEBUT_S3%%%
(code de la section 3)
%%%FIN_S3%%%
%%%DEBUT_S4%%%
(code de la section 4)
%%%FIN_S4%%%
%%%DEBUT_S5%%%
(code de la section 5)
%%%FIN_S5%%%
%%%DEBUT_S6%%%
(code de la section 6)
%%%FIN_S6%%%
%%%DEBUT_REMARQUES%%%
(facultatif)
%%%FIN_REMARQUES%%%
Bon courage !
Comment rendre votre copie
Un seul fichier
Vous rendez un seul fichier texte : le fichier
reponse_NOM.txtfourni dans l’outillage.outillage/reponse_NOM.txtdans votre éditeur.reponse_DUPONT.txt.Les balises
Le fichier contient des balises de ce type :
Ne modifiez pas, ne déplacez pas et ne supprimez pas les balises. Elles servent à retrouver chacune de vos réponses. Une balise abîmée ou manquante rend la réponse introuvable, et donc non notée.
Les balises attendues pour cette évaluation sont :
%%%DEBUT_IDENTITE%%%…%%%FIN_IDENTITE%%%%%%DEBUT_Q1%%%…%%%FIN_Q1%%%%%%DEBUT_Q2%%%…%%%FIN_Q2%%%%%%DEBUT_Q3%%%…%%%FIN_Q3%%%%%%DEBUT_Q4%%%…%%%FIN_Q4%%%%%%DEBUT_Q5%%%…%%%FIN_Q5%%%%%%DEBUT_Q6%%%…%%%FIN_Q6%%%%%%DEBUT_S1%%%…%%%FIN_S1%%%%%%DEBUT_S2%%%…%%%FIN_S2%%%%%%DEBUT_S3%%%…%%%FIN_S3%%%%%%DEBUT_S4%%%…%%%FIN_S4%%%%%%DEBUT_S5%%%…%%%FIN_S5%%%%%%DEBUT_S6%%%…%%%FIN_S6%%%%%%DEBUT_REMARQUES%%%…%%%FIN_REMARQUES%%%Votre responsabilité
Ctrl+S). Des copies ont déjà été perdues à quelques minutes de la fin.