Troisième semaine

Rappel sur la notion de conditionnelle

Exercice 1
Création d'une classe permettant la manipulation d'intervalles Intervalle & TestIntervalle
Exercice 2
Création d'une classe permettant de manipulation des Dates (jour/mois/années) Date & TestDate
Exercice 2 bis
Ajout à la classe date d'une méthode permettant l'affichage d'une date toString & TestDate2

Rappel sur la notion de conditionnelle :

Nous avons vu cette semaine une nouvelle notion permettant de modifier le flux d'exécution du programme. Avant, nos programmes s'exécutaient séquentiellement (c'est à dire que les intructions étaient exécutées les unes à la suite des autres), maintenant nous possédons un outil nous permettant de choisir entre deux paquets d'instructions en fonction d'une condition.

Qu'est ce qu'une condition ?

Une condition est une expression qui retourne un booléen. Nous avons vu qu'il existait 8 types primitifs en Java, le type boolean en fait partie. Il a la particularité de ne pouvoir prendre que deux valeur : soit vrai, soit faux, ou encore true ou false. Ce type permet de réprésenter le fait qu'une condition soit vérifiée ou non. Pour manipuler ce type, on dispose de différents opérateurs.

A l'aide de ses opérateurs, nous pouvons construire des expressions booléennes qui représenteront des conditions complexes :
int a,b, c;
(( 4 < a) && (a < 8)) a est strictement compris entre 4 et 8.
((a == b) || (a == c)) a doit etre égal à b ou à c (ou les deux).
((a != 0) && ((a == b) || !(a < c))) a ne doit pas etre nul, et doit etre égal à b ou supérieur ou égal à c.

Il est très important de bien parenthéser les expressions booléennes car les priorités entre les différents opérateurs ne sont pas identiques. Voici le tableau des opérateurs classés par ordre de priorité (de haut en bas et de gauche à droite)

Precedence des opérateurs Java

Les expressions contenant des sous-expressions sont évaluées en suivant les règles de précédances. Le tableau suivant donne les règles concernant l'ordre d'évaluation d'expresssions Java, avec les opérateurs de priorité la plus élevée en haut du tableau (i.e. ceux qui seront évalués en premier)

Les opérateurs se trouvant sur la meme ligne ont la meme priorité. Dans ces groupes, l'ordre d'évaluation d'une expression s'effectue de gauche à droite.

Comme une expression ne peut etre évaluée tant que ses sous-expressions ne l'ont pas été, les règles de priorité détermine le lien entre opérandes et opérateurs.
 

++, --, +, -, ~, !, cast 
*, /, % 
+, - 
<<, >>, >>> 
<, <=, >, >=, instanceof 
==, != 
&& 
|| 
?: 
=

Maintenant que nous savons comment créer et manipuler des conditions, nous pouvons introduire la structure de controle qui va nous permettre d'écrire des alternatives : le if. La forme générale de cette instruction est la suivante :
 

class TestIf
{
    public static void main(String[] args)
    {
        // Déclaration des variables
         int a, b;

        // Saisie des données auprès de l'utilisateur
        System.out.print("Entrez un nombre a = ");
        a = Clavier.readInt();
        System.out.print("Entrez un nombre b = ");
        b = Clavier.readInt();

        // Réalisation des calculs et affichages
        if (a > b) {
          System.out.println(a+" est plus grand que "+b);
        } else {
          System.out.println(b+" est plus grand que "+a);
        }
        System.out.println("Merci.");

    }
}

Ce petit exemple illustre l'utilisation de l'instruction conditionnelle if : on demande à l'utilisateur deux entiers, et l'on affiche le plus grand des deux entiers en premier. Comme vous le constaterez en faisant tourner ce programme, en fonction des nombres saisis, on passera dans l'une ou l'autre des branches du if, cependant les instrauctions suivant le if sont toujours exécutées (le "Merci." est toujours affiché).

Voici un autre exemple illustrant l'utilisation d'un if ne comportant qu'une seul branche :
 

class TestIf2
{
    public static void main(String[] args)
    {
        // Déclaration des variables
         int a;

        // Saisie des données auprès de l'utilisateur
        System.out.print("Entrez un nombre : ");
        a = Clavier.readInt();

        // Réalisation des calculs et affichages
        System.out.print("Le nombre "+a+" est ");
        if ((a % 2) != 0) {
          System.out.print("non");
        }
        System.out.println(" pair.");

    }
}

Ce petit exemple illustre une instruction conditionnelle ne comportant qu'une seule branche. De nouveau on remarque que quelque soit le résultat de la condition, les instructions suivantes sont exécutées.



Exercice 1 :
Nous cherchons à écrire une classe permettant de définir des intervalles sur les réels. Nous ne nous intéresserons qu'aux intervalles fermés, c'est à dire ceux dont les bornes sont comprises dans l'intervalle. Nous désirons pouvoir tester si un nombre appartient ou non à un intervalle. Il faudra écrire aussi la méthode toString pour générer l'affichage de l'intervalle correspondant à la notation mathématique.


C:\Java\Algo> java TestIntervalle
Entrez la borne inferieure : -4.5
Entrez la borne superieure : 3.2
Entrez un nombre quelconque : 35.9
35.9 n'appartient pas à l'intervalle [-4.5, 3.2].
C:\Java\Algo>

C:\Java\Algo> java TestIntervalle
Entrez la borne inferieure : -4.5
Entrez la borne superieure : 3.2
Entrez un nombre quelconque : 0.9
0.9 appartient à l'intervalle [-4.5, 3.2].
C:\Java\Algo>

Bonus : Ecrivez une méthode permettant de savoir si un intervalle en contient un autre (dans ce cas on passera un intervalle en paramètre de la méthode).


C:\Java\Algo> java TestIntervalle2
Entrez la borne inferieure : -4.5
Entrez la borne superieure : 3.2
Entrez la borne inferieure : -2.3
Entrez la borne superieure : 1.0
L'intervalle [-2.3, 1.0] est compris dans l'intervalle [-4.5, 3.2].
C:\Java\Algo>

C:\Java\Algo> java TestIntervalle2
Entrez la borne inferieure : -4.5
Entrez la borne superieure : 3.2
Entrez la borne inferieure : -2.3
Entrez la borne superieure : 4.0
L'intervalle [-2.3, 4.0] n'est pas compris dans l'intervalle [-4.5, 3.2].
C:\Java\Algo>

Rappel : aucun affichage ne doit etre fait dans les classes "Boites à outils". Le profil de la méthode à écrire devra ressembler à public boolean estContenuDans(Intervalle intervalle).



Exercice 2 :
Maintenant, on aimerait pouvoir manipuler des dates de la forme jour/mois/année. Cependant, il faudra vérifier que les dates que l'on créera soient valides (en effet une date comme 30/02/2000 n'est pas valide). Pour cela on doit suivre certaines règles : Enfin, pour déterminer le nombre de jour d'un mois, on devra regarder les numéros des mois, et lorsque l'on s'occupe de Février il faudra vérifier si l'année est bissextile. On pourra pour cela s'aider de la définition suivante : une année est bissextile si elle est divisible par 4 mais pas par 100, ou si elle est divisible par 400 (par exemple, 1900 n'est pas bissextile alors que 2000 l'est).

C:\Java\Algo> java Date
Entrez le nombre de jour : 12
Entrez le nombre de mois : 8
Entrez le nombre d'année : 2000
La date 31/8/2000 est valide.
Le lendemain de cette date est le 1/09/2000.
C:\Java\Algo>

Si la date saisie n'est pas valide, on ne peut pas effectuer le calcul du lendemain :
 


C:\Java\Algo> java Date
Entrez le nombre de jour : 29
Entrez le nombre de mois : 2
Entrez le nombre d'année : 1999
La date 29/2/1999 n'est pas valide.
C:\Java\Algo>

Rappel : Il sera utile de définir une méthode permettant de calculer le nombre de jours d'un mois donné.



Exercice 2 bis :
Dans cet exercice, on va écrire la méthode toString de la classe Date pour produire un affichage plus "naturel" d'une date. Pour cela il est possible d'utiliser l'algorithme suivant :
 
Algorithme du calcul du code du jour de la semaine d'une date :

Codage :  Dimanche à 0, Lundi à1, ... Samedi à 6.

Deux cas sont à envisager selon la valeur du mois:
        1) le mois n'est ni Janvier (1) ni Février (2) : retrancher 2 au mois.
        2) le mois est Janvier ou Février : ajouter 10 au mois et retrancher 1 à l'année.

Calculer ensuite le numéro du siècle et le numéro de l'année dans le siècle (par exemple, pour l'année 1995 le numéro du siècle est 19 et le numéro de l'année dans le siècle est 95).

Calculer alors: ((13*Mois - 1)/5) + (Numéro année/4) + (Numéro siècle/4)    (où "/" dénote la division entière).

Enfin, ajouter au nombre obtenu, le numéro de l'année, puis le jour, retrancher le double du numéro de siècle. Ce résultat pouvant dans certains cas être négatif il convient de lui ajouter un multiple de 7 (par exemple 49) puis prendre le reste de la division par 7 ce qui donne le résultat c'est à dire le code du jour de la semaine.

Ce qui nous permettra d'obtenir l'affichage suivant :


C:\Java\Algo> java Date
Entrez le nombre de jour : 10
Entrez le nombre de mois : 10
Entrez le nombre d'annee : 2000
Le mardi 10 octobre 2000 est une date valide.
Le lendemain de cette date est le mercredi 11 octobre 2000.
C:\Java\Algo>

En utilisant la class TestDate suivante :
 

class TestDate
{
    public static void main(String[] args)
    {
        // Déclaration des variables
         int jour, mois, annee;
        Date date;

        // Saisie des données auprès de l'utilisateur
        System.out.print("Entrez le nombre de jour : ");
        jour = Clavier.readInt();
        System.out.print("Entrez le nombre de mois : ");
        mois = Clavier.readInt();
        System.out.print("Entrez le nombre d'annee : ");
        annee = Clavier.readInt();

        date = new Date(jour, mois, annee);

        // Réalisation des calculs et affichages
        if (date.estValide()) {
          System.out.println("Le "+date+" est une date valide.");
          System.out.println("Le lendemain de cette date est le "+date.lendemain());
        } else {
          System.out.println("La date "+jour+"/"+mois+"/"+annee+" n'est pas valide.");
        }
    }
}