Pour commencer ce TD, vous devez avoir construit un projet, configuré pour l’utilisation de la classe TC, comme indiqué dans les activités préliminaires. Si ce n’est pas le cas, il faut commencer par cela.
Rappel, toutes les classes que vous écrirez seront dans le paquetage par défaut (default package).
À partir de maintenant et au cours de chaque TD, vous devrez déposer votre travail au fur et à mesure. N’attendez pas la fin pour tout déposer, nous devons suivre votre avancement.
Une fois déposé, votre programme va faire l’objet d’une validation automatique. Attention, si la validation dit “OK”, cela ne veut pas dire que votre programme est parfait, mais simplement qu’il a passé avec succès quelques tests qui détectent les erreurs les plus grossières.
Remarque: Il n’y a pas d’exercice 1 cette semaine, il a été remplacé par les différents exercices préliminaires. Il s’agit maintenant d’exercices qui demandent un peu plus de réflexion. On va devoir en effet déclarer des variables, faire des affectations, écrire des expressions de calculs, des conditions et des boucles.
Récupérez le programme Heures
en cliquant ce lien.
Vous devez compléter la fonction chaineDe
en réalisant le calcul des valeurs des heures, minutes et secondes.
Par exemple, si la valeur qui est passée en paramètre (le nombre total de secondes) est 4000
, comme 4000 secondes = 1 h, 6 mn et 40 s, vous devez calculer ces trois valeurs 1, 6 et 40 et les ranger dans les variables correspondantes. L’instruction return
de chaineDe
assemble ces valeurs pour former la chaîne qui est renvoyée comme valeur de la fonction. Ainsi, pour le paramètre 4000
, la fonction chaineDe
va renvoyer la chaîne 1 : 6 : 40
.
Indications : Si a
et b
sont deux int
positifs, l’expression a / b
calcule le quotient (entier) de a
par b
et l’expression a % b
calcule le reste (entier) de la division de a
par b
.
La fonction main
affiche la valeur de retour de chaineDe
pour quelques exemples. Vous devez obtenir la sortie suivante :
0 : 0 : 0 0 : 0 : 1 0 : 0 : 59 0 : 1 : 0 0 : 1 : 59 0 : 2 : 0 0 : 59 : 59 1 : 0 : 0 1 : 0 : 1 1 : 6 : 40 23 : 59 : 59
Déposez ici votre programme Heures.java
(assurez vous de bien sélectionner le programme Heures.
java qui se trouve dans le répertoire des sources de VSCode, et pas la version initiale qui pourrait se trouver par exemple dans le répertoire de téléchargement).
De manière similaire à la classe TC, on installe le paquetage MacLib. Le programme de test associé permet de vérifier la bonne installation.
Récupérez ensuite la classe DessinHorloge. Vous ne devez pas modifier cette classe mais seulement utiliser ses fonctions tracerHeures
, tracerMinutes
et tracerSecondes
. Vous devez donc lire leur documentation pour leur passer les bons paramètres.
Récupérez ensuite le programme Horloges
.
Vous devez compléter la fonction tracerAiguilles
pour réaliser l’affichage graphique de l’heure. Cette fonction ne doit pas afficher de texte sur la console. Il faut calculer la position angulaire de chaque aiguille et passer cette valeur en paramètre à la fonction tracer...
correspondante. Toute la difficulté de cet exercice réside dans un calcul rigoureux qui utilise correctement les particularités de l’arithmétique en Java lorsque l’on combine des entiers et des flottants.
Le saviez vous ? Dans une horloge, les aiguilles des minutes et des heures avancent d’un petit cran à chaque seconde. Il s’agit de reproduire ce mécanisme.
Le résultat attendu est le suivant (vérifiez bien la position de vos aiguilles) :
On voit notamment sur l’exemple de gauche que la position attendue de l’aiguille des heures n’est pas la verticale (angle 0) mais qu’elle s’est déplacée de l’angle correspondant à la fraction d’heure que représentent 33 minutes et 20 secondes. De même, l’aiguille des minutes n’est pas exactement à la position qui correspond à 33, mais elle est un peu décalée du fait des 20 secondes.
Déposez ici votre programme Horloges.java
.
Ajoutez à la classe Heures
une fonction public static int lireEntier(String invite)
qui doit :
invite
sur la console, en utilisant TC.print
,TC.lireInt();
Vous devez tester. Par exemple, en mettant ces instructions :
String message = "combien de secondes ? "; int secondes_1 = lireEntier(message); TC.println(chaineDe(secondes_1)); int secondes_2 = lireEntier(message); TC.println(chaineDe(secondes_2)); TC.print("total = "); TC.println(chaineDe(secondes_1+secondes_2));
dans la fonction main
de la classe Heures
, on doit obtenir :
combien de secondes ? 2000 0 : 33 : 20 combien de secondes ? 6000 1 : 40 : 0 total = 2 : 13 : 20
où c’est l’utilisateur qui a choisi d’entrer au clavier les valeurs 2000 et 6000 à la fin de la première et de la troisième ligne. Notez que l’espace après le ?
est celui qui est inclus dans le message d’invite. Notez aussi qu’il n’y a pas de retour à la ligne à la fin de ce message. Lorsque l’exécution de TC.lireInt()
commence, le curseur est donc placé en bout de ligne, après l’espace qui suit le ?
et l’exécution de TC.lireInt()
se fige dans l’attente d’une entrée au clavier. Le 2000 qui s’affiche est un écho de l’entrée au clavier et cet écho inclut le retour à la ligne qui valide cette entrée. C’est pourquoi TC.println(chaineDe(...));
commence à écrire au début de la nouvelle ligne. Le retour à la ligne inhérent à la définition de println
se fait à la fin de son écriture.
Déposez ici Heures.java
.
On veut maintenant pouvoir lire une durée sous la forme de trois entiers qui donnent respectivement les heures, les minutes et les secondes. Ajoutez à la classe Heures
une fonction public static int lireHMS(String invite)
qui affiche le texte donné par le paramètre invite
en utilisant les fonctions de la classe TC
, lit 3 entiers et renvoie le nombre total de secondes correspondant.
Indication : L’utilisateur peut placer les 3 nombres sur une même ligne et le programme les récupérera au cours de 3 appels à TC.lireInt()
. Par exemple, une exécution de ces deux instructions :
int secondes = lireHMS("entrer heures minutes secondes : "); TC.println(secondes);
pourra donner :
entrer heures minutes secondes : 0 33 20 2000
Dans cet exemple, quand l’utilisateur aura entré 0 33 20, le premier appel à lireInt
va “consommer” le 0 et il n’ira pas au delà du blanc qui suit, le deuxième appel à lireInt
va, sans attendre, “consommer” le 33 qui est déjà disponible, etc. Finalement, la fonction lireHMS
renverra la valeur 2000
,
c’est le nombre de secondes qui correspond à 33 minutes et 20 secondes. Dans le test ci-dessus, cette valeur est ensuite affichée par l’instruction TC.println(secondes);
. Sans changer le code de lireHMS
, on pourrait aussi entrer les données de la manière suivante et obtenir le même résultat :
entrer heures minutes secondes : 0 33 20 2000
Vous devez tester. Modifiez la fonction main
de la classe Heures
pour permettre une exécution de ce type :
entrer heures minutes secondes : 0 33 20 entrer heures minutes secondes : 1 40 0 total = 2 : 13 : 20
Il s’agit de faire la somme de deux durées qui sont entrées sous la forme de 3 entiers (heures, minutes et secondes). En utilisant les fonctions déjà écrites, une simple addition suffit.
Déposez ici Heures.java
.
On veut calculer la décomposition binaire b3b2b1b0 des entiers de 0 à 15. Complétez le programme Binaire
pour réaliser cette décomposition et afficher le résultat :
0000 = 0 0001 = 1 0010 = 2 0011 = 3 0100 = 4 ... 1111 = 15
Indication : Ces calculs peuvent se faire simplement en utilisant le quotient et le reste de divisions euclidiennes. Il y a aussi une solution plus “geek” consistant à utiliser les opérateurs de décalage et de masquage bit-à-bit définis sur les entiers.
Déposez ici Binaire.java
.
Le codage hexadécimal permet de représenter les nombres de 0 à 15, soit un groupe de 4 bits, par un seul chiffre noté de 0 à 9 puis de A à F. On s’intéresse ici à la programmation d’un afficheur à 7 segments pour les chiffres hexadécimaux, comme illustré dans la figure ci-dessous.
On vous donne la classe Afficheur7Segments
(à ne pas modifier) qui réalise les graphiques, et la classe AffichageHexadecimal
à compléter pour obtenir l’affichage attendu. Pour chaque affichage d’un chiffre hexadécimal, la fonction public static boolean allumeSegment(int segment, int chiffre)
est appelée pour chaque segment afin de déterminer s’il doit être allumé ou non. Les segments sont numérotés de 0 à 6 selon la convention suivante :
Vous devez compléter la fonction allumeSegment
; la valeur de retour sera true
quand, pour afficher le chiffre
considéré, le segment
doit être allumé (en vert) et false
dans le cas contraire (le segment est alors en noir).
Indication : On pourra par exemple enchaîner des instructions conditionnelles du genre :
if ( segment == 1 ) { return chiffre <= 4 || 7 <= chiffre && chiffre <= 10 || chiffre == 13; }
Rappel : en Java, l’opérateur booléen et se note &&
et il a une priorité supérieure à l’opérateur booléen ou qui se note ||
. Notez qu’il est possible de placer des return
dans les instructions conditionnelles, ce qui permet de séparer les cas.
Déposez ici AffichageHexadecimal.java
.
Une année est dite bissextile si elle comporte un 29 février. C’est le cas de toutes les années divisibles par 4, à l’exception de celles divisibles par 100, qui ne sont bissextiles que si elles sont également divisibles par 400.
Écrivez une classe Bissextile
avec une fonction estBissextile
qui prend en paramètre un nombre entier qui est l’année à tester, et qui renvoie true
si cette année est bissextile et false
sinon.
Ajoutez une fonction public static void affichage(int annee)
qui prend en paramètre l’année à tester et qui affiche un message indiquant en clair si l’année est bissextile ou non.
La fonction main
de votre programme sera, par exemple :
public static void main(String[] args) { affichage(1900); affichage(1901); affichage(1904); affichage(2000); affichage(2024); }
Pour cet exemple, l’exécution donne :
1900 n'est pas bissextile. 1901 n'est pas bissextile. 1904 est bissextile. 2000 est bissextile. 2024 est bissextile.
Vous devez respecter exactement le format d’affichage attendu, avec un seul espace de séparation entre les mots et pas d’espace en fin de ligne. Toutes les lignes sont terminées par un point et un retour à la ligne, y compris la dernière.
Indication : Il est rentable de réfléchir quelques minutes à l’imbrication des conditionnelles avant de se lancer dans la programmation. Veillez à tester toutes les branches de votre programme.
Déposez ici Bissextile.java
.
On veut maintenant pouvoir utiliser les fonctions écrites à l’exercice précédent sur autant d’années que l’on veut, sans devoir modifier le programme à chaque fois. On va considérer que l’utilisateur entre au clavier autant d’années positives qu’il veut, et que lorsqu’il souhaite arrêter le programme, il entre alors une valeur strictement négative. Dans ce cas, le programme affiche Au revoir.
et s’arrête.
Par exemple, une exécution donne quelque chose comme :
Entrer une valeur : 1900 1900 n'est pas bissextile. Entrer une valeur : 2000 2000 est bissextile. Entrer une valeur : -1 Au revoir.
Écrivez un nouveau programme BoucleBissextile
avec une fonction main
qui utilise les fonctions de la classe Bissextile
. Les opérations d’écriture se feront en utilisant les fonctions TC.print(…)
et TC.println(…)
à votre convenance. Il ne faut pas utiliser les fonctions similaires System.out.print(…)
et System.out.println(…)
. Vous devez respecter exactement le texte et format d’affichage attendu, avec un seul espace de séparation entre les mots et pas d’espace en fin de ligne (mais notez que l’espace après le :
doit être écrit par le programme). Toutes les lignes, y compris la dernière, sont terminées par un retour à la ligne.
Indication : Vous devez structurer votre programme à l’aide d’une boucle while (annee >= 0) { ... }
en déclarant correctement la variable annee
, en l’affectant au bon moment par des appels à TC.lireInt()
et en complétant le corps de la boucle avec des appels aux fonctions de Bissextile
.
Déposez ici BoucleBissextile.java
.
Écrivez un programme (dans Racines.java) qui calcule et qui affiche les racines réelles d’un polynôme ax2 + bx + c. On distinguera les différents cas selon le nombre de racines. On pourra supposer que a est non nul.
Les valeurs de a, b et c seront de type double
et seront introduites par TC.lireDouble()
.
Écrivez toutes les fonctions qui vous semblent utiles. Cet exercice ne fait pas l’objet d’une correction automatique et vous pouvez structurer votre programme comme bon vous semble.
Voici quelques exemples pour tester, vous pouvez aussi en améliorer la présentation :
Entrer a b c : 1 1 1 Discriminant = -3.0 Pas de racine
Entrer a b c : 1 -2 1 Discriminant = 0.0 Racine double : 1.0
Entrer a b c : 3 2 -1 Discriminant = 16.0 Deux racines : -1.0 et 0.3333333333333333
Entrer a b c : 0.3 0.2 -0.1 Discriminant = 0.16 Deux racines : -1.0000000000000002 et 0.33333333333333337
Entrer a b c : 0.03 0.02 -0.01 Discriminant = 0.0015999999999999999 Deux racines : -1.0 et 0.33333333333333337
Une explication des résultats obtenus sur les deux derniers exemples (en comparaison aux racines mathématiques − 1 et 1/3) est que les fractions décimales n’ont pas de représentation binaire exacte. Ces résultats peuvent varier légèrement selon la manière de les calculer.
Déposez ici votre programme (il n’y a pas de validation automatique et il sera examiné par vos enseignants).