Objectifs: Le but de ce TD est de vous faire expérimenter les constructions de base du langage JavaScript (types simples, déclarations de variables, instructions de contrôle, itérations) qui sont très proches syntaxiquement de celles utilisées par le langage C. Les programmes que vous aurez à écrire ne font appel qu'aux constructions de base du langage JavaScript (Core JavaScript) mis à part pour la lecture de valeurs au clavier. C'est pourquoi afin de simplifier leur écriture et leur exécution, vous utiliserez l'environnement Node.js qui vous affranchira de l'intégration de vos scripts dans du code HTML et de l'utilisation d'un navigateur.
Les
exercices proposés dans ce TP sont indépendants et sont organisés selon 4 thèmes
thèmes : expressions , instructions conditionnelles, itérations, fonctions. Une 5ème partie propose
un ensemble d'exercices facultatifs que vous pourrez réaliser pour vous entrainer.
Ressources utiles
-
Les supports de cours pour l'introduction à JavaScript:
-
La documentation JavaScript in Visual Studio Code pour le support de JavaScript dans VSCode.
Prenez dès maintenant de bonnes habitudes de codage JavaScript. Il vous est demandé de respecter impérativement les 3 règles ci-dessus.
- tout programme source JavaScript doit avoir comme suffixe .js.
- Les noms de variables et de fonctions sont définis par un identificateur débutant par une minuscule (camelCase).
- Les programmes doivent être correctement indentés. (Utilisez l'outil d'identation automatique de VSCode !)
0. Préparation de l'environnement de développement
1. Créer et exécuter un programme JavaScript
Pour la réalisation de ce TP vous avez besoin d'un éditeur de texte et d'un environnement Javascript (Node.js). Pour
exécuter un programme JavaScript contenu dans un fichier monProgramme.js
il suffit d'ouvrir un terminal
dans le répertoire contenant ce fichier et d'éxécuter la commande
node monProgramme.js
Cependant il est possible de tout faire depuis l'IDE VScode comme le montre les figures ci-dessous
![](images/fig1BisVSCode.png)
VScode utilise IntelliSense pour l'édition du code et offre de nombreuses possibilités d'autocomplétion du code comme indiqu sur la figure ci dessous.
![](images/fig2BisVSCode.png)
Une fois votre code écrit et enregistré vous pouvez directement l'exécuter en ouvrant un terminal dans VSCode et en invoquant l'interpréeteur de Node.js
![](images/fig2VSCode.png)
2. Lire des données au clavier avec readline-sync
console.log
est une fonction standard de JavaScript qui permet d'afficher du texte sur la console de votre environnement
d'exécution JavaScript (que ce soit un navigateur ou Node.js). Par contre, Core Javascript tel qu'il est défini par le standard
ECMAScript ne définit pas de moyen de saisir des données à partir du clavier. La manière de procéder va dépendre de votre environnement
d'éxécution. En ce qui concerne Node.js, nous allons utiliser un module complémentaire
(readline-sync)
qu'il va falloir installer à l'aide de
npm, le gestionnaire de paquets officiel de Node.js (voir
Node.js NPM).
![](images/fig3VSCode.png)
Une fois readline-sync installé, pour pouvoir l'utiliser dans vos programmes il vous faudra procéder en deux temps
- importer le module à l'aide d'une instruction require que vous placerez au debut de votre programme
const readline = require('readline-sync');
-
ensuite pour invoquer l'une des fonction du module il suffit de préfixer l'appel par readline..
Par exemple :
permet d'invoquer la fonction question qui affiche un message sur la console et attend un réponse de l'utilisateur. Une fois que l'utilisateur a entré sa réponse la valeur de celle-ci est renvoyée et ici est stockée dans la variable prenom.let prenom = readline.question("entrez votre prénom ");
readline-sync propose différentes fonctions (méthodes) selon la nature de la valeur que vous voulez saisir.
- question() qui renvoie une chaîne de caractères (valeur de type string)
- questionInt() qui renvoie une valeur entière (valeur de type number)
- questionFloat() qui renvoie une valeur réelle (valeur de type number)
Se référer à la documentation de readline-sync pour voir le detail des ces fonctions et leurs différents paramètres d'appel.
Thème 1 : Expressions
Exercice 1 : Conversion de températures
En utilisant la formule \(tempC = (5/9)(tempF-32)\) écrire en langage JavaScript un programme
degres.js
qui lit une température exprimée en degrés
Fahrenheit et affiche sa valeur en degrés centigrades ou degrés
Celsius.
Exemples d'exécution du programme (en vert les valeurs introduites par l'utilisateur) :
P:\PLAI\TP5>node degres.js
donnez une temperature en Fahrenheit : O.O
cette temperature equivaut a -17.8 degres Celsius
P:\PLAI\TP5>node degres.js
donnez une temperature en Fahrenheit : 60.0
cette temperature equivaut a 15.6 degre Celsius
P:\PLAI\TP5>
Par défaut, lorsqu'un nombre flottant est affiché sur la console, tous les chiffres qu'il contient après le séparateur décimal apparaissent. Ainsi le code
let x = 17/7;
console.log("x = " + x);
donne l'affichage suivant
x = 2.4285714285714284
Il est néanmoins possible de formatter les nombres pour fixer le nombre de chiffres à conserver après
le point décimal à l'aide de la méthode toFixed
(voir w3schools
ou MDN)
Exercice 2 : Conversion de durées
Ecrire un programme hjms.js
en langage JavaScript qui pour un nombre de
secondes donné calcule et affiche son équivalent en nombre de
jours, d'heures, de minutes et de secondes.
exemples d'exécution du programme :
P:\PLAI\TP5>node hjms donnez une durée en secondes : 235789 cette durée equivaut à 2 jours 17 heures 29 minutes 49 secondes P:\PLAI\TP5>node hjms donnez une durée en secondes : 567231 cette durée équivaut à 6 jours 13 heures 33 minutes et 51 secondes P:\PLAI\TP5>
L'opérateur %
(modulo) permet d'obtenir le reste de la division entière de deux nombres. Par exemple
console.log("17 % 7 --> " + 17 % 7);
console.log("17 / 7 --> " + 17/7);
donne l'affichage suivant
17 % 7 --> 3
17 / 7 --> 2.4285714285714284
Pour obtenir la division entière de 17 par 7 (qui vaut 2) il faut passer par la méthode Math.floor
(voir
w3schools
ou MDN)
Thème 2 : Instructions conditionnelles
Exercice 1 : Améliorer le programme de conversion de durées
Si ce n'est déjà fait, améliorez votre programme hjms.js
de sorte que lorsqu'une valeur (nombre de jours, d'heures , de minutes ou de secondes) est nulle
elle n'apparaisse pas dans l'affichage, et que si elle vaut 1 l'unité soit affichée au singulier (sans s) comme dans l'exemple ci-dessous.
P:\PLAI\TP5>node hjms donnez une durée en secondes : 3621 Cette durée equivaut à 1 heure 21 secondes P:\PLAI\TP5>
Exercice 2 : Classer 3 nombres
Ecrire un programme troisNombres.js
qui lit 3 nombres au clavier et les affiche sur la console dans l'ordre croissant
(du plus petit au plus grand).
P:\PLAI\TP5>node troisNombres 1er nombre : 14 2ème nombre : 10 3ème nombre : 17 les nombres dans l'ordre croissant : 10 14 17 P:\PLAI\TP5>
Thème 3 : itérations
Exercice 1 : Affichage de motifs - escaliers
Ecrire un programme qui affiche un motif triangulaire dont la taille est fixée par une valeur lue au clavier.
Exemple de trace d'exécution:
P:\PLAI\TP5>node triangle1 donnez taille du motif : 7 * ** *** **** ***** ****** ******* P:\PLAI\TP5>
a) écrire un programme triangle1.js
affichant
ce motif en utilisant uniquement des instructions tant que (while()
).
b) écrire un programme triangle2.js
affichant
ce motif en utilisant uniquement des instructions pour (for
).
Exercice 2 : Affichage de motifs - pyramides
Même exercice que le précédent mais le motif affiché n'est plus un triangle mais une pyramide (voir ci-dessous) et le choix des instructions pour le réaliser est laissé à votre jugement.
Exemple de trace d'exécution (en vert les valeurs introduites par l'utilisateur):
P:\PLAI\TP5>node pyramide donnez taille du motif : 7 * *** ***** ******* ********* *********** ************* P:\PLAI\TP5>
Thème 4 : fonctions
Exercice 1 : Moyenne olympique
Sans utiliser de tableau écrire un programme moyenneOlympique.js
qui lit au clavier une suite de nombres réels positifs
ou nuls (correspondant à des notes comprises entre 0 et 10), terminée par la valeur -1,
et calcule la moyenne olympique de ces valeurs, c'est à dire la moyenne
des notes sans prendre en compte la note la plus élevée ni la
note la moins élevée (c'est ce qui se passe dans les compétitions de gymnastique ou de patinage artistique
pour limiter les abus dans la notation).
Exemple de trace d'exécution (en vert les valeurs introduites par l'utilisateur):
P:\PLAI\TP5>node moyenneOlympique.js Donner un note entre 0 et 10 (-1 pour terminer la saisie) : 7.89 Donner un note entre 0 et 10 (-1 pour terminer la saisie) : 8.76 Donner un note entre 0 et 10 (-1 pour terminer la saisie) : 8.45 Donner un note entre 0 et 10 (-1 pour terminer la saisie) : 9.10 Donner un note entre 0 et 10 (-1 pour terminer la saisie) : 7.75 Donner un note entre 0 et 10 (-1 pour terminer la saisie) : 9.30 Donner un note entre 0 et 10 (-1 pour terminer la saisie) : 7.50 Donner un note entre 0 et 10 (-1 pour terminer la saisie) : -1 Nombre de notes saisies 7 La note la plus élevée (9.3)et la note plus basse (7.5) ont été retirées La moyenne olympique est : 8.39 P:\PLAI\TP5>
Pour la lecture de la séquence de notes, vous écrirez une fonction lireNote
qui vérifie que les données saisies sont correctes. Les traitements effectués par cette
fonctions sont les suivants:
- afficher le message d'invite (prompt) indiquant l'intervalle de validité des notes et la valeur de fin de séquence.
- lecture d'une valeur
- vérification que cette valeur est bien dans l'intervalle de valeurs autorisées ou est égale à la valeur de fin de séquence. Si c'est le cas la valeur lue est retournée, sinon un message d'erreur est affiché est une nouvelle valeur est demandée à l'utilisateur.
Exercice 2: Introduction aux modules
Dans les programmes degres.js
et hjms.js
, vus lors de l'exercice 1,
il n'est possible de faire qu'une seule saisie. Si l'utilisateur veut effectuer
plusieurs conversions, il doit relancer l'exécution du programme. On souhaite modifier
le comportement de ces programmes de manière à ce que l'utilisateur puisse
renouveler le traitement jusqu'à ce qu'il dise explicitement qu'il désire terminer l'exécution.
Le déroulement de l'exécution de ces programmes serait alors le suivant :
P:\PLAI\TP5>node degres2.js
donnez une température en degrés Fahrenheit : 32
la température en degrés Celsius est 0.00
voulez-vous recommencer ? (O/N): O
donnez une température en degrés Fahrenheit : 45
la température en degrés Celsius est 7.22
voulez-vous recommencer ? (O/N): 33
désolé nous n'avons pas compris votre réponse
voulez-vous recommencer ? (O/N): o
donnez une température en degrés Fahrenheit : 23
la température en degrés Celsius est -5.00
voulez-vous recommencer ? (O/N): n
Au revoir !
P:\PLAI\TP5>node hjms
entrez une durée (en sec.) : 345678
Cette durée equivaut à 4 jours 1 minute 18 secondes
encore ? (O/N): o
entrez une durée (en sec.) : 3567912
Cette durée equivaut à 41 jours 7 heures 5 minutes 12 secondes
encore ? (O/N): p
désolé nous n'avons pas compris votre réponse
encore ? (O/N): n
P:\PLAI\TP5>
a) Pour cela vous allez écrire une fonction encore
qui affiche un message
demandant à l'utilisateur si il veut poursuivre ou non le traitement et qui selon la valeur saisie
retourne un booléen (true si il veut poursuivre, false sinon).
.
Dans un premier temps écrivez et testez cette fonction dans le programme degres.js
.
b) Ensuite pour pouvoir utiliser cette fonction dans d'autres programmes (par exemple hjms.js
)
il vaut mieux l'isoler dans un module que vous pourrez importer à la manière du module
readline-async
utilisé pour les lectures au clavier. Pour cela procédez comme suit :
-
créez un fichier
utils.js
-
effacez la function
encore
du fichierdegres.js
et récopiez son code dansutils.js
-
modifiez la signature de la fonction en utilisant une directive
exports
et une fonction anonyme comme indiqué ci dessous// pour utiliser le module readline const readline = require('readline-sync'); exports.encore = function(message) { .... les instructions de la fonction }
-
pour utiliser la fonction dans un autre de vos programmes, utilisez une instruction
require
comme pourreadline-async
pour déclarer le moduleconst utils = require('./utils.js'); ... utils.encore("encore ? "); // pour appler la fonction
Modifiez les programmes degres.js
et hjms.js
pour permettre à l'utilisateur d'effectuer autant de traitements
qu'il le souhaite.
5: Autres exercices
Exercice 1 : Tester si un nombre est premier
Un nombre est n premier si il a seulement deux diviseurs : 1 et n.
Ecrire un programme Premier.js
qui permet de tester si un
nombre introduit par l'utilisateur est premier ou non.
Exemple de trace d'exécution (en vert les valeurs introduites par l'utilisateur):
P:\PLAI\TP5>node Premier donnez un entier positif : 7 7 est un nombre premier Voulez-vous essayer un autre nombre O/N ? o donnez un entier positif : 25 25 n'est pas un nombre premier, il est divisible par 5 Voulez-vous essayer un autre nombre O/N ? n Au revoir P:\PLAI\TP5>
Exercice 2 : Suite de Fibonacci
La suite de Fibonacci est définie par la formule de récurrence
suivante:
u0 = 0
u1 = 1
un = un-1 + un-2 (n >= 3).
a) Ecrire un programme Fibo1.js
qui permet de calculer le nième terme de la suite de Fibonacci,
n étant fixé par l'utilisateur.
b) Ecrire un programme Fibo2.js
qui permet d'obtenir la valeur et le rang du premier terme de cette suite supérieure
à une valeur donnée par l'utilisateur.
Exercice 3 : Prix d'un lot
a) Le jeu consiste à découvrir par essais successifs le prix d'un lot . Pour chaque essai, le joueur reçoit un message : "Trop grand", "Trop petit" ou "BRAVO ! Vous avez trouvé en K essais". Le jeu est fini quand le joueur a trouvé le prix du lot.
On propose d'écrire un programme JavaScript PrixLot1.js
qui joue
le rôle de meneur de jeu ; l'exécution de ce programme vous fera
tenir le rôle du joueur. Le programme Prixlot1
doit définir
le prix du lot en tirant un entier aléatoire entre 1 et 1000 et dialoguer
avec le joueur pendant le jeu.
Pour choisir un nombre au hasard on utilisera la méthode random
de la classe Math
qui retourne un réel (double) tiré
au hasard et de manière uniforme dans l'intervalle [0 1].
exemple :
double x;
x = Math.random();
exemple d'exécution du programme PrixLot1
P:\PLAI\TP5>node PrixLot1 Le but est de chercher un prix entre 0 et 1000 Tapez un prix : 566 Trop grand Tapez un prix : 400 Trop grand Tapez un prix : 150 Trop petit Tapez un prix : 200 Trop petit Tapez un prix : 214 BRAVO ! Vous avez gagné en 5 essais P:\PLAI\TP5>
b) Copier dans le fichier PrixLot2.js
le fichier
PrixLot1.js
, et modifier PrixLot2.js
de manière
à pouvoir :
-
enchaîner plusieurs jeux consécutifs lors d'une même exécution du programme (à la fin de chaque jeu, il est demandé au joueur de préciser s'il veut s'arrêter ou rejouer)
-
limiter le nombre d'essais du joueur lors d'une partie (au début de chaque partie, le programme demandera le nombre maximum d'essais autorisés).
Exemple d'exécution du porgramme PrixLot2
P:\PLAI\TP5>node PrixLot2 Le but est de chercher un prix entre 0 et 1000 1ère partie. Nombre maximum d'essais : 4 Tapez un prix : 678 Trop petit Tapez un prix : 920 Trop grand Tapez un prix : 860 Trop petit Tapez un prix : 910 Trop petit PERDU ! Vous avez épuisé le nombre d'essais autorisés Le prix était : 917 Voulez-vous rejouer O/N ? o 2ème partie. Nombre maximm d'essais : 8 Tapez un prix : 678 Trop grand Tapez un prix : 333 Trop grand Tapez un prix : 300 Trop petit Tapez un prix : 320 Trop petit Tapez un prix : 324 BRAVO ! Vous avez gagné en 5 essais Voulez-vous rejouer O/N ? n P:\PLAI\TP5>
c) En jouant avec le programme précédent, essayer
de trouver une stratégie systématique et efficace. Ecrire un programme
PrixLot3.js
qui fait jouer l'ordinateur à votre place suivant
la tactique que vous venez de définir ; les deux rôles de meneur
de jeu et de joueur sont donc à la charge du programme, le joueur "ignorant"
évidemment le prix connu du meneur de jeu, mais "sachant" si son essai
est plus grand ou plus petit que le prix.
Le programme PrixLot3
effectue 20 parties ; il affiche pour chaque
partie le prix tiré au sort et le nombre d'essais successifs qui ont
été nécessaires pour le trouver avec la tactique programmée.
Pouvez-vous prévoir, pour la tactique que vous avez choisie, l'ordre
de grandeur des nombres d'essais ? Compléter le programme PrixLot3
en lui faisant calculer la moyenne des 20 nombres d'essais obtenus pour les
20 parties.
Exercice 4 : Valeur approchée de la racine carrée d'un nombre réel positif
On considère un nombre réel positif A ; on sait que la suite (un) n=0,1,2,... définie par la donnée d'un réel u0 positif et par la relation de récurrence un = (un-1 + A / un-1) * 0,5 (pour n > 0) converge vers la racine carrée de A . On suppose le nombre A compris entre 1 et 100, et on prend u0 = A / 2.
Pour obtenir une valeur approchée de racine carrée de A, on cherche le premier terme un tel que | un2 - A | < E-5 . Le nombre trouvé est une valeur approchée de racine carrée de A ( en effet | un2 - A | < E-5 implique que | un- rac(A) | < E-5 / ( un+ rac(A) où rac(A) correspond à la racine carrée de A).
a) Ecrire un programme JavaScript Raca1.js
qui permet
de lire le nombre A,
de calculer et d'afficher les approximations intermédiaires et la valeur approchée de la racine carrée de A définie ci-dessus.
Exemple de l'état de l'écran obtenu par exécution du programme Raca1
:
Entrer un nombre A entre 1 et 100: 19.23 Approximations successives : u0 = 9.615 u1 = 5.8075 u2 = 4.559367735686612 u3 = 4.388528900180239 u4 = 4.385203650605606 Valeur approchée de la racine carrée = 4.385202389856321Indications pour écrire le programme :
- définir une constante :
static final double EPS = 1E-5;
- utiliser une boucle tant que :
while (. . . . . . . >= EPS) { . . . . . . . . . }
b) à partir du programme Raca1.js
écrire un
programme Raca2.js
qui vérifie que le nombre introduit au
clavier est bien un nombre positif supérieur à 1, et dans le cas
contraire affiche un message d'erreur et redemande une nouvelle valeur à
l'utilisateur.