Licence 3 Informatique – Génie Logiciel

Exercice 1 : Fizz Buzz L'énoncé rappelle que le code doit être guidé par les tests (approche Test Driven Development). Nous devons donc obligatoirement commencer par écrire la classe de test. Création des tests unitaires pour FizzBuzz Nous allons utiliser la méthode assertEquals(expected, value) pour vérifier que les retours de la méthode getResult(int val) correspondent aux spécifications.

D'après le document Licence 3 Informatique – Génie Logiciel

Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Licence 3 Informatique – Génie Logiciel

Document source

Licence 3 Informatique – Génie Logiciel

Programming, Testing, Software Engineering · PDF · 2 pages · 1975

Afficher l'aperçu du document

Consulter le document original →

Exercice 1 : Fizz Buzz

L'énoncé rappelle que le code doit être guidé par les tests (approche Test Driven Development). Nous devons donc obligatoirement commencer par écrire la classe de test.

Création des tests unitaires pour FizzBuzz

Nous allons utiliser la méthode assertEquals(expected, value) pour vérifier que les retours de la méthode getResult(int val) correspondent aux spécifications. Il est important de tester les différents cas de figure :

  • Un multiple de 3 (ex: 3, 9)
  • Un multiple de 5 (ex: 5, 10)
  • Un multiple de 15 (ex: 15, 30)
  • Un nombre qui n'est dans aucun de ces cas (ex: 7)
  • Le cas particulier du 0 (qui est divisible par 15, 3 et 5)
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class FizzBuzzTest {

    @Test
    public void testGetResult() {
        FizzBuzz fb = new FizzBuzz();
        
        // Test des cas classiques (ni multiples de 3, ni de 5)
        assertEquals("7", fb.getResult(7));
        assertEquals("22", fb.getResult(22));
        
        // Test de la divisibilité par 3
        assertEquals("Fizz", fb.getResult(3));
        assertEquals("Fizz", fb.getResult(9));
        
        // Test de la divisibilité par 5
        assertEquals("Buzz", fb.getResult(5));
        assertEquals("Buzz", fb.getResult(10));
        
        // Test de la divisibilité par 15 (3 et 5)
        assertEquals("FizzBuzz", fb.getResult(15));
        assertEquals("FizzBuzz", fb.getResult(30));
        
        // Test du 0 (mathématiquement divisible par 15, 3 et 5)
        assertEquals("FizzBuzz", fb.getResult(0));
    }
}

Implémentation de la solution et méthode principale

L'implémentation doit tester la divisibilité par 15 avant celle par 3 ou 5. En effet, si l'on vérifiait val % 3 == 0 en premier, la valeur 15 retournerait "Fizz" et l'exécution s'arrêterait là, ce qui est incorrect.

public class FizzBuzz {

    public String getResult(int val) {
        // L'ordre est crucial : on teste d'abord le multiple commun
        if (val % 15 == 0) {
            return "FizzBuzz";
        } else if (val % 3 == 0) {
            return "Fizz";
        } else if (val % 5 == 0) {
            return "Buzz";
        } else {
            return String.valueOf(val);
        }
    }

    public static void main(String[] args) {
        FizzBuzz fb = new FizzBuzz();
        // L'énoncé demande d'afficher les valeurs comprises entre 0 et 100
        for (int i = 0; i <= 100; i++) {
            System.out.println(fb.getResult(i));
        }
    }
}

Implémentation du mode avancé

Pour le mode avancé, nous devons inclure la vérification de la présence d'un chiffre dans le nombre. La méthode la## Exercice 1 : Fizz Buzz

L'objectif de cet exercice est de mettre en pratique le développement piloté par les tests (TDD). Nous devons donc écrire les tests pour vérifier la logique métier avant d'écrire l'algorithme lui-même.

Bien que l'énoncé ne précise pas explicitement ce qui doit être retourné lorsqu'un nombre n'est divisible ni par 3, ni par 5, le comportement standard du kata FizzBuzz est de retourner le nombre lui-même sous forme de chaîne de caractères. Nous allons tester ce cas par défaut en plus des conditions demandées.

Question 1 - Tests unitaires de la classe FizzBuzz

Nous utilisons le framework JUnit pour écrire nos tests. Nous allons vérifier les quatre cas possibles : un multiple de 3, un multiple de 5, un multiple de 15, et un nombre quelconque.

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class FizzBuzzTest {

    @Test
    public void testGetResultMultipleDeTrois() {
        FizzBuzz fb = new FizzBuzz();
        // 9 est divisible par 3 seulement
        assertEquals("Fizz", fb.getResult(9)); 
    }

    @Test
    public void testGetResultMultipleDeCinq() {
        FizzBuzz fb = new FizzBuzz();
        // 10 est divisible par 5 seulement
        assertEquals("Buzz", fb.getResult(10)); 
    }

    @Test
    public void testGetResultMultipleDeQuinze() {
        FizzBuzz fb = new FizzBuzz();
        // 30 est divisible par 15 (donc par 3 et 5)
        assertEquals("FizzBuzz", fb.getResult(30)); 
    }

    @Test
    public void testGetResultAutreNombre() {
        FizzBuzz fb = new FizzBuzz();
        // 7 n'est divisible ni par 3 ni par 5
        assertEquals("7", fb.getResult(7)); 
    }
}

Question 2 - Implémentation de la classe FizzBuzz et méthode principale

L'ordre des conditions est crucial : il faut vérifier la divisibilité par 15 (ou par 3 et par 5 simultanément) en premier, sinon le programme s'arrêtera prématurément sur la condition "divisible par 3" ou "divisible par 5" et renverra un résultat partiel incorrect.

public class FizzBuzz {

    public String getResult(int val) {
        if (val % 15 == 0) {
            return "FizzBuzz";
        } else if (val % 3 == 0) {
            return "Fizz";
        } else if (val % 5 == 0) {
            return "Buzz";
        } else {
            return String.valueOf(val);
        }
    }

    public static void main(String[] args) {
        FizzBuzz fb = new FizzBuzz();
        // L'énoncé demande d'afficher les valeurs de 0 à 100
        for (int i = 0; i <= 100; i++) {
            System.out.println(fb.getResult(i));
        }
    }
}

Note sur le zéro : En mathématiques, 0 est un multiple de tout entier (0 = 15 × 0). Par conséquent, pour i = 0, le programme affichera FizzBuzz. C'est le comportement attendu selon les règles strictes de divisibilité.

Question 3 - Mode avancé pour les conditions étendues

Dans cette variante, nous ajoutons une condition logique "OU" pour rechercher la présence du chiffre dans l'écriture décimale du nombre. La conversion en String permet d'utiliser la méthode contains.

public class FizzBuzzAvance {

    public String getResult(int val) {
        String stringVal = String.valueOf(val);
        boolean condition3 = (val % 3 == 0) || stringVal.contains("3");
        boolean condition5 = (val % 5 == 0) || stringVal.contains("5");

        if (condition3 && condition5) {
            return "FizzBuzz";
        } else if (condition3) {
            return "Fizz";
        } else if (condition5) {
            return "Buzz";
        } else {
            return stringVal;
        }
    }
}

Exercice 2 : Berlin-Uhr

L'horloge berlinoise divise le temps en blocs. Pour convertir une heure (ex: 12:18:48), il faut utiliser les divisions euclidiennes et les modulos (le reste de la division). L'énoncé donne les états R (Rouge), J (Jaune) et O (Off).

Calcul pour 12:18:48 :

  • Secondes (48) : 48 est pair. La lampe ronde est allumée. Disons J (Jaune) pour allumée, et O pour éteinte. Résultat : J
  • Ligne 1 (Blocs de 5h) : 12 ÷ 5 = 2 blocs pleins. 2 lampes rouges sur 4. Résultat : RROO
  • Ligne 2 (Blocs de 1h) : 12 reste 2 (12 % 5 = 2). 2 lampes rouges sur 4. Résultat : RROO
  • Ligne 3 (Blocs de 5min) : 18 ÷ 5 = 3 blocs. 3 lampes sur 11. La 3ème lampe est rouge, les autres jaunes. Résultat : JJROOOOOOOO
  • Ligne 4 (Blocs de 1min) : 18 % 5 = 3. 3 lampes jaunes sur 4. Résultat : JJJO

Question 1 - Tests unitaires de la classe BerlinUhr

Nous allons tester individuellement les composants de l'horloge avec la valeur d'exemple pour nous assurer que chaque ligne est correctement formatée.

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class BerlinUhrTest {

    @Test
    public void testSecondesPair() {
        BerlinUhr horloge = new BerlinUhr();
        assertEquals("J", horloge.calculerSecondes(48));
    }

    @Test
    public void testSecondesImpair() {
        BerlinUhr horloge = new BerlinUhr();
        assertEquals("O", horloge.calculerSecondes(59));
    }

    @Test
    public void testLigneHeuresSuperieures() {
        BerlinUhr horloge = new BerlinUhr();
        // 12 heures -> 12 / 5 = 2 lampes
        assertEquals("RROO", horloge.calculerLigne5Heures(12));
    }

    @Test
    public void testLigneHeuresInferieures() {
        BerlinUhr horloge = new BerlinUhr();
        // 12 heures -> 12 % 5 = 2 lampes
        assertEquals("RROO", horloge.calculerLigne1Heure(12));
    }

    @Test
    public void testLigneMinutesSuperieures() {
        BerlinUhr horloge = new BerlinUhr();
        // 18 minutes -> 18 / 5 = 3 lampes. La 3eme est un quart d'heure (Rouge)
        assertEquals("JJROOOOOOOO", horloge.calculerLigne5Minutes(18));
    }

    @Test
    public void testLigneMinutesInferieures() {
        BerlinUhr horloge = new BerlinUhr();
        // 18 minutes -> 18 % 5 = 3 lampes
        assertEquals("JJJO", horloge.calculerLigne1Minute(18));
    }
}

Question 2 - Implémentation de la classe BerlinUhr

L'implémentation repose sur des constructeurs de chaînes (StringBuilder) pour générer dynamiquement les lignes avec les caractères R, J et O.

public class BerlinUhr {

    public String calculerSecondes(int secondes) {
        return (secondes % 2 == 0) ? "J" : "O";
    }

    public String calculerLigne5Heures(int heures) {
        return genererLigne(heures / 5, 4, "R");
    }

    public String calculerLigne1Heure(int heures) {
        return genererLigne(heures % 5, 4, "R");
    }

    public String calculerLigne5Minutes(int minutes) {
        int lampesAllumees = minutes / 5;
        StringBuilder ligne = new StringBuilder();
        for (int i = 1; i <= 11; i++) {
            if (i <= lampesAllumees) {
                // Les lampes 3, 6 et 9 représentent les quarts d'heure en rouge
                if (i % 3 == 0) {
                    ligne.append("R");
                } else {
                    ligne.append("J");
                }
            } else {
                ligne.append("O");
            }
        }
        return ligne.toString();
    }

    public String calculerLigne1Minute(int minutes) {
        return genererLigne(minutes % 5, 4, "J");
    }

    private String genererLigne(int allumees, int total, String couleur) {
        StringBuilder ligne = new StringBuilder();
        for (int i = 0; i < allumees; i++) {
            ligne.append(couleur);
        }
        for (int i = allumees; i < total; i++) {
            ligne.append("O");
        }
        return ligne.toString();
    }

    public void afficherHorloge(String temps) {
        String[] parts = temps.split(":");
        int heures = Integer.parseInt(parts[0]);
        int minutes = Integer.parseInt(parts[1]);
        int secondes = Integer.parseInt(parts[2]);

        System.out.println(calculerSecondes(secondes));
        System.out.println(calculerLigne5Heures(heures));
        System.out.println(calculerLigne1Heure(heures));
        System.out.println(calculerLigne5Minutes(minutes));
        System.out.println(calculerLigne1Minute(minutes));
    }
}

Exercice 3 : Calculatrice Postfixée ou calculatrice polonaise

La notation polonaise inverse (NPI) évalue l'opérateur dès qu'il est rencontré en utilisant les opérandes qui le précèdent immédiatement.

Question 1 - Structure de données adaptée et justification

La structure de données la plus adaptée est la Pile (Stack), qui fonctionne sur le principe LIFO (Last In, First Out / Dernier entré, premier sorti).

Pourquoi ? L'algorithme d'évaluation de la notation postfixée est naturel avec une pile## Exercice 1 : Fizz Buzz

L'objectif de cet exercice est d'appliquer le développement piloté par les tests (TDD). Les instructions précisent bien qu'il faut écrire le test avant le code de la solution.

Écriture des tests unitaires (Classe FizzBuzzTest)

Pour concevoir nos tests, nous devons anticiper le comportement attendu de la méthode getResult(int val). Les cas de test doivent couvrir les classes d'équivalence suivantes :

  • Un nombre divisible par 15 (ex: 15, 30) doit retourner "FizzBuzz". Note importante : 0 est divisible par 15 (le reste de 0 ÷ 15 est 0), donc 0 devrait également retourner "FizzBuzz".
  • Un nombre divisible uniquement par 3 (ex: 3, 9) doit retourner "Fizz".
  • Un nombre divisible uniquement par 5 (ex: 5, 10) doit retourner "Buzz".
  • Un nombre quelconque non divisible par 3 ou 5 (ex: 1, 2, 4) doit retourner le nombre sous forme de chaîne de caractères.
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class FizzBuzzTest {

    @Test
    public void testGetResultStandard() {
        FizzBuzz fb = new FizzBuzz();
        
        // Tests des nombres standards non divisibles par 3 ou 5
        assertEquals("1", fb.getResult(1));
        assertEquals("2", fb.getResult(2));
        assertEquals("4", fb.getResult(4));
        
        // Tests des multiples de 3
        assertEquals("Fizz", fb.getResult(3));
        assertEquals("Fizz", fb.getResult(9));
        
        // Tests des multiples de 5
        assertEquals("Buzz", fb.getResult(5));
        assertEquals("Buzz", fb.getResult(10));
        
        // Tests des multiples de 15
        assertEquals("FizzBuzz", fb.getResult(15));
        assertEquals("FizzBuzz", fb.getResult(30));
        
        // Test du cas particulier du zéro
        assertEquals("FizzBuzz", fb.getResult(0));
    }
}

Écriture de la classe FizzBuzz et de la méthode principale

L'ordre des conditions est crucial dans l'implémentation. Si l'on vérifie la divisibilité par 3 en premier, le nombre 15 renverra "Fizz" au lieu de "FizzBuzz", car 15 modulo 3 vaut 0 et le programme n'ira pas plus loin. Il faut toujours vérifier la condition la plus restrictive (modulo 15) en premier.

public class FizzBuzz {

    public String getResult(int val) {
        // La condition la plus stricte (divisible par 3 ET par 5, soit 15)
        // doit absolument être testée en premier.
        if (val % 15 == 0) {
            return "FizzBuzz";
        }
        if (val % 3 == 0) {
            return "Fizz";
        }
        if (val % 5 == 0) {
            return "Buzz";
        }
        // Si aucune condition n'est remplie, on retourne le nombre en texte
        return String.valueOf(val);
    }

    public static void main(String[] args) {
        FizzBuzz fb = new FizzBuzz();
        // Affichage de toutes les valeurs comprises entre 0 et 100
        for (int i = 0; i <= 100; i++) {
            System.out.println(fb.getResult(i));
        }
    }
}

Mode avancé pour les plus rapides

Les règles s'enrichissent : "divisible par" devient "divisible par OU composé de".

  • Pour "Fizz" : un nombre comme 13 contient le caractère '3', il doit retourner "Fizz".
  • Pour "Buzz" : un nombre comme 52 contient '5', il doit retourner "Buzz".
  • Un nombre comme 53 (contient 5 et 3) ou 35 (divisible par 5 et contient 3) doit retourner "FizzBuzz".

Voici l'ajout des tests correspondants, suivi de l'implémentation :

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class FizzBuzzAvanceTest {

    @Test
    public void testGetResultAvance() {
        FizzBuzz fb = new FizzBuzz();
        
        // Contient un 3
        assertEquals("Fizz", fb.getResultAvance(13));
        assertEquals("Fizz", fb.getResultAvance(31));
        
        // Contient un 5
        assertEquals("Buzz", fb.getResultAvance(52));
        
        // Combinaisons (contient 5 et 3, ou divisible par 5 et contient 3)
        assertEquals("FizzBuzz", fb.getResultAvance(35)); 
        assertEquals("FizzBuzz", fb.getResultAvance(53)); 
    }
}
// Méthode à ajouter à la classe FizzBuzz existante
public String getResultAvance(int val) {
    String strVal = String.valueOf(val);
    
    boolean estFizz = (val % 3 == 0) || strVal.contains("3");
    boolean estBuzz = (val % 5 == 0) || strVal.contains("5");
    
    if (estFizz && estBuzz) {
        return "FizzBuzz";
    } else if (estFizz) {
        return "Fizz";
    } else if (estBuzz) {
        return "Buzz";
    } else {
        return strVal;
    }
}

Exercice 2 : Berlin-Uhr

Écriture des tests de la classe BerlinUhr

Pour la représentation des ampoules allumées ou éteintes, nous allons utiliser les caractères définis dans le sujet :

  • 'R' : Rouge
  • 'J' : Jaune
  • 'O' : Off (éteint)

La lampe des secondes (tout en haut) clignote. Le sujet indique "allumée lorsque pair, éteinte sinon", nous utiliserons 'J' pour allumée car c'est la couleur historique de l'horloge de Berlin (et la lettre R serait ambiguë avec les lignes rouges). L'horloge renverra un tableau de 5 chaînes de caractères représentant les 5 éléments (Seconde, Heures x5, Heures x1, Minutes x5, Minutes x1).

Prenons l'exemple fourni : 12:18:48.

  • Secondes (48) : pair, donc allumé -> "J"
  • Heures (12) : 12 / 5 = 2 lampes rouges sur 4 -> "RROO"
  • Heures unité (12 % 5) = 2 lampes rouges sur 4 -> "RROO"
  • Minutes (18) : 18 / 5 = 3 lampes allumées. La 3ème (le quart d'heure) est rouge, les autres jaunes -> "JJROOOOOOOO"
  • Minutes unité (18 % 5) = 3 lampes jaunes sur 4 -> "JJJO"
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;

public class BerlinUhrTest {

    @Test
    public void testAfficherHeureBerlin() {
        BerlinUhr horloge = new BerlinUhr();
        
        String[] resultatAttendu = {
            "J",            // Secondes
            "RROO",         // Ligne 5 heures
            "RROO",         // Ligne 1 heure
            "JJROOOOOOOO",  // Ligne 5 minutes (le 3ème R marque 15 min)
            "JJJO"          // Ligne 1 minute
        };
        
        assertArrayEquals(resultatAttendu, horloge.convertirHeure("12:18:48"));
    }
}

Écriture de la classe BerlinUhr

Pour construire les lignes, une bonne pratique est d'isoler la logique de remplissage avec O (Off) dans une méthode utilitaire.

public class BerlinUhr {

    public String[] convertirHeure(String heureAConvertir) {
        String[] timeParts = heureAConvertir.split(":");
        int heures = Integer.parseInt(timeParts[0]);
        int minutes = Integer.parseInt(timeParts[1]);
        int secondes = Integer.parseInt(timeParts[2]);

        String[] affichage = new String[5];

        // 1. Grosse lampe des secondes
        affichage[0] = (secondes % 2 == 0) ? "J" : "O";

        // 2. Ligne des 5 heures (4 lampes, couleur R)
        affichage[1] = construireLigne(heures / 5, 4, "R");

        // 3. Ligne de 1 heure (4 lampes, couleur R)
        affichage[2] = construireLigne(heures % 5, 4, "R");

        // 4. Ligne des 5 minutes (11 lampes, couleurs J et R pour les quarts)
        affichage[3] = construireLigneMinutes(minutes / 5);

        // 5. Ligne de 1 minute (4 lampes, couleur J)
        affichage[4] = construireLigne(minutes % 5, 4, "J");

        return affichage;
    }

    // Méthode utilitaire pour construire des lignes simples
    private String construireLigne(int lampesAllumees, int totalLampes, String couleur) {
        StringBuilder ligne = new StringBuilder();
        for (int i = 0; i < totalLampes; i++) {
            if (i < lampesAllumees) {
                ligne.append(couleur);
            } else {
                ligne.append("O");
            }
        }
        return ligne.toString();
    }

    // Méthode spécifique pour la ligne des 5 minutes (gestion du quart d'heure rouge)
    private String construireLigneMinutes(int lampesAllumees) {
        StringBuilder ligne = new StringBuilder();
        for (int i = 1; i <= 11; i++) {
            if (i <= lampesAllumees) {
                // Les lampes 3, 6 et 9 (multiples de 3) sont rouges
                if (i % 3 == 0) {
                    ligne.append("R");
                } else {
                    ligne.append("J");
                }
            } else {
                ligne.append("O");
            }
        }
        return ligne.toString();
    }
}

Exercice 3 : Calculatrice Postfixée ou calculatrice polonaise

Choix de la structure de données

La structure de données la plus adaptée est la Pile (Stack en Java). Pourquoi ? La notation polonaise inverse (NPI) fonctionne naturellement avec le principe LIFO (Last In, First Out / Dernier arrivé, premier sorti). Chaque fois qu'on rencontre un nombre (opérande), on l'empile. Lorsqu'on rencontre un opérateur, on dépile les deux derniers nombres, on effectue l'opération, puis on empile le résultat pour la suite du calcul.

Différenciation entre les chiffres et les nombres

Pour distinguer un chiffre simple (ex: 3) d'un nombre (ex: 34), on sépare chaque élément de la chaîne de caractères (les "tokens") par un séparateur fixe, traditionnellement l'espace. Lors de la lecture, on va découper la chaîne (fonction split(" ")). Ainsi, "3 4" générera deux éléments "3" et "4", tandis que "34" génèrera un seul élément "34".

Gestion des nombres négatifs

Les nombres négatifs sont gérés en collant le signe "-" directement devant les chiffres, sans espace (par exemple : "-3"). Lors de la lecture d'un élément, si la chaîne est exactement "-" (taille de 1), c'est l'opérateur de soustraction. S'il y a un signe "-" suivi de chiffres (ex: "-3"), l'analyseur lexical (parser) le convertira nativement en une valeur négative.

Écriture des tests

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class CalculatricePolonaiseTest {

    @Test
    public void testCalculsSimples() {
        CalculatricePolonaise calc = new CalculatricePolonaise();
        
        // 3 + 4 = 7
        assertEquals(7.0, calc.calculer("3 4 +"), 0.001);
        
        // (3 + 4) * 5 = 35
        assertEquals(35.0, calc.calculer("3 4 + 5 *"), 0.001);
        
        // Test nombre négatif et soustraction : 10 - (-5) = 15
        assertEquals(15.0, calc.calculer("10 -5 -"), 0.001);
        
        // Test avec des nombres à plusieurs chiffres : 100 / 4 = 25
        assertEquals(25.0, calc.calculer("100 4 /"), 0.001);
    }
}

Écriture de la classe CalculatricePolonaise

Le code inclut la méthode de calcul ainsi qu'une méthode principale main permettant l'interaction au clavier avec la classe Scanner.

import java.util.Scanner;
import java.util.Stack;

public class CalculatricePolonaise {

    public double calculer(String expression) {
        Stack<Double> pile = new Stack<>();
        // On sépare la chaîne selon les espaces multiples
        String[] elements = expression.trim().split("\\s+");

        for (String element : elements) {
            if (element.isEmpty()) continue;

            switch (element) {
                case "+":
                    pile.push(pile.pop() + pile.pop());
                    break;
                case "*":
                    pile.push(pile.pop() * pile.pop());
                    break;
                case "-":
                    // Attention à l'ordre : le premier dépilé est l'opérande droit
                    double droiteSous = pile.pop();
                    double gaucheSous = pile.pop();
                    pile.push(gaucheSous - droiteSous);
                    break;
                case "/":
                    double droiteDiv = pile.pop();
                    double gaucheDiv = pile.pop();
                    if (droiteDiv == 0) {
                        throw new ArithmeticException("Division par zéro");
                    }
                    pile.push(gaucheDiv / droiteDiv);
                    break;
                default:
                    // Si ce n'est pas un opérateur, c'est un nombre. On le convertit.
                    pile.push(Double.parseDouble(element));
                    break;
            }
        }
        
        // À la fin, le résultat final est le seul élément restant dans la pile
        return pile.pop();
    }

    public static void main(String[] args) {
        CalculatricePolonaise calc = new CalculatricePolonaise();
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("--- Calculatrice Polonaise ---");
        System.out.println("Entrez une expression postfixée (ex: '3 4 + 5 *') ou 'q' pour quitter :");
        
        while (scanner.hasNextLine()) {
            String ligne = scanner.nextLine();
            
            if ("q".equalsIgnoreCase(ligne.trim())) {
                System.out.println("Fin du programme.");
                break;
            }
            
            try {
                double resultat = calc.calculer(ligne);
                System.out.println("Résultat : " + resultat);
            } catch (Exception e) {
                System.out.println("Erreur dans l'expression : vérifier la syntaxe (" + e.getMessage() + ")");
            }
        }
        scanner.close();
    }
}

Méthode

Face à une épreuve centrée sur les tests unitaires et le TDD (Test-Driven Development), votre démarche doit être systématique :

  1. Testez avant de coder : Le sujet l'exige. N'écrivez pas un seul algorithme avant d'avoir formalisé vos attentes. Les tests doivent prévoir les cas nominaux (fonctionnement normal), les cas limites (les zéros, l'ordre des opérateurs) et les cas erronés (divisions par zéro).
  2. Identifiez les "classes d'équivalence" : Dans l'exercice 1, ne testez pas tous les nombres. Prenez un représentant pour les multiples exclusifs de 3, un pour les multiples de 5, un pour les multiples de 15, et un pour les nombres standard. N'oubliez pas les frontières (comme 0).
  3. Misez sur la structure de données appropriée : Dans l'exercice 3, la notation polonaise est un cas d'école. La reconnaissance immédiate que ce problème relève d'une structure de Pile (Stack) résout 90 % de l'algorithme. Soyez attentif au sens de dépilement pour la soustraction et la division (premier élément sorti = opérande de droite !).
  4. Isolez la logique complexe : Dans l'horloge de Berlin (Exercice 2), découper le formatage visuel ("RROO", "JJRO...") dans une méthode utilitaire construireLigne évite de répéter de nombreuses boucles for et rend le code principal lisible.

Partager

Commentaires

Aucun commentaire pour le moment. Posez la première question.

Les commentaires sont relus avant publication. Votre e-mail n'est jamais affiché.

← Toutes les révisions