Partage
  • Partager sur Facebook
  • Partager sur Twitter

manipulation de variable

Sujet résolu
    24 janvier 2022 à 23:22:02

    Bonsoir, débutant dans le java j'essaie de faire un exercice où je dois rentrer des notes puis calculer la moyenne de ces notes sans la note la plus haute et sans la note la plus basse. 

    Mon problème est que bien qu'en debuggant, j'ai l'impression (avec le debugger) que la note la plus basse n'est jamais compté et donc n'est pas initialisé lors que je verife dans mes conditions. Pourquoi ? pourtant j'ai l'impression que j'ai bien fait. Par exemple pour 2 ; 3; 4 et 5. Je devrais obtenir 3,5 en moyenne or là j'ai 9,5. 

    package com.company;
    
    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            float note = 0;
            float totNotes = 0;
            float nMax = 0;
            float nMin = 0;
            int compteurNotes = 0;
            System.out.println("Entrer une note (finir par -1) : ");
            note = sc.nextFloat();
    
            while(note != -1) {
                if ((note < 0) && (note != 1)) { 
                    System.out.println("Svp entrer une note non négative (finir par -1) : ");
                    note = sc.nextFloat();
                }
    
                if (note > nMax){
                    nMax = note;
                }
    
                if (note < nMin) {
                    nMin = note;
                }
    
                if (note == -1) { 
                    note = 0;
                    break;
                }
                totNotes += note; 
                System.out.println("le total des notes: " + totNotes);
                compteurNotes = compteurNotes + 1;
    
                System.out.println("Entrer une note (finir par -1) : ");
                note = sc.nextFloat();
            }
            if (compteurNotes == 2) {
                System.out.println("la moyenne est de : " + (totNotes/2));
            }
            else if (compteurNotes > 2) {
                totNotes = totNotes - (nMin - nMax);
                compteurNotes -= 2;
                System.out.println("La moyenne est de : " + (totNotes / compteurNotes));
            }
            else System.out.println("aucune notes entrée");
        }
    }
    

    Merci d'avance

    • Partager sur Facebook
    • Partager sur Twitter
      25 janvier 2022 à 2:08:16

      Salut,
      Dans la ligne suivante, pourquoi demander si note<0 et note!=1? Si c'est négatif, ça ne peut pas être égal à +1.
                  if ((note < 0) && (note != 1)) {
      Tu dois faire une autre boucle while dans la première pour valider.
      Ton minimum est mal initialisé, il doit être initialisé à la plus grande valeur possible. Essaies un milliard pour l'instant.
      Tu affiches le total à chaque note? Attend de sortir de la boucle.
      Et si j'entre une seule note? Tu dis qu'il n'y a aucune note. Il faut tester 1 ou 2
      Je n'ai pas compris comment tu obtiens 9.5. J'aurais attendu 4.5 avec ton erreur.
      • Partager sur Facebook
      • Partager sur Twitter

      Le Tout est souvent plus grand que la somme de ses parties.

        25 janvier 2022 à 2:15:46

        Hello,

        revérifie comment tu retires les notes min et max.

        Mais, ce n'est pas le seul problème.

        Tu initialises nMin à zéro. Résultat tu ne vas jamais rien trouver d'inférieur.

        Tu pourrais gérer ça en forçant la lecture d'une première note. Et en définissant une méthode qui lit une note pour simplifier.

        Sinon tu pourrais utiliser un OptionalDouble (il n'y a pas d'OptionalFloat et puis de toute façon il ne faut pas utiliser float sans raison), ou alors un Double avec un grand D qui commencerait à null, ou alors garder un boolean qui dit si oui ou non tu as déjà lu un nMin.

        • Partager sur Facebook
        • Partager sur Twitter
          25 janvier 2022 à 4:07:41

          @Kumesana:
                      totNotes = totNotes - (nMin - nMax);
          Ça m'a échappé ... shame on me ...
          Je ne connais pas Java, mais c'est incroyablement facile à comprendre quand on connait le C ou le C++
          Existe-t-il un "double maximum" en Java?
          Le truc du booléen marchera, mais je trouve ça plutôt lourd.
          Je suppose que le PO ne connait pas encore les tableaux. C'est nettement plus facile.
          Tu assignes la première valeur au minimum et au maximum. Et tu continues à partir de la seconde valeur.
          Peut-on faire des append() comme en Python ou des push_back comme en C++ dans les tableaux Java?


          • Partager sur Facebook
          • Partager sur Twitter

          Le Tout est souvent plus grand que la somme de ses parties.

            25 janvier 2022 à 7:49:44

            Bonjour,

            Pour être honnête, ton code, c'est un peu le bazar. Ca part dans tous les sens.

            Le code pour lire une note est dupliqué trois fois. La condition pour sortir de la boucle est à deux endroits. Ton calcul de min est faux. Ton calcul de moyenne est faux.

            Commençons par le min. Ca a déjà été dit, il faut l'initialiser avec une valeur haute (la note max ou Float.MAX_VALUE).

            Ceci étant dit, le min et le max n'ont rien à faire dans le calcul de la moyenne. Ici, tu enlèves le min (qui reste à 0) et tu ajoutes le max puis tu divises par le nombre de notes - 2. Ca n'a pas de sens. (2 + 3 + 4 + 5 - 0 + 5) / 2 = 19 / 2 = 9,5

            La moyenne, c'est "total des notes / nombre de notes". (2 + 3 + 4 + 5) / 4 = 14 / 4 = 3,5

            Concernant la duplication de code, on essaye en général de l'éviter (principe DRY = Don't Repeat Yourself). Si tu dois changer ou corriger ce bout de code dupliqué, tu devras le faire à plusieurs endroits. C'est long et fastidieux et ça risque de causer des bugs si oublies de changer un bout de code ou pire, si tu dupliques une erreur.

            La plupart du temps, on met le code dupliqué dans une fonction mais ici, on peut juste éviter la répétition en réorganisant un peu le code de façon plus simple. La saisie des données doit se répéter donc on le met dans la boucle, au début puisque c'est par ça qu'on commence.

            Le break en cas de -1 pour sortir de la boucle, c'est très bien mais du coup, la condition du while ne servira jamais à sortir. On peut donc la remplacer par true. Ca donnerait quelque chose comme ça:

            while (true) {
                // 1. lire un nombre
                // 2. si c'est -1, sortir de la boucle (break)
                // 3. traiter le nombre
            }

            Ici, pas de répétition de code et pas de condition qui ne sera jamais utilisée.

            @PierrotLeFou

            Non, on ne peut pas ajouter des éléments à un tableau en java car ils ont une taille fixe. Par contre, on peut le faire avec les listes.

            List<Integer> nombres = new ArrayList<>();
            nombres.add(42);



            -
            Edité par brubru777 25 janvier 2022 à 7:59:05

            • Partager sur Facebook
            • Partager sur Twitter
              25 janvier 2022 à 9:01:50

              Bonjour, 

              Merci pour vos réponses. J'ai refait le code afin qu'il soit plus lisible.

              Pour répondre aux divers questions : Le fait que je doive calculer la moyenne olympique (sans la valeur la plus haute et la plus basse), je dois obligatoirement retirer dans la somme des notes ces deux valeurs. Pareil pour le nombre de notes (-2) , dans le cas où le nombre de notes > 2.

              La condition (note < 0) && (note != -1) est là pour vérifier que je ne rentre pas une note négative et éviter aussi que je ne donne la condition d'arret des le début. 

              EDIT : j'ai trouvé ^^, le problème était au niveau de la condition d'arrêt, il ne faut pas tenir compte du note = 0.

              Le code refait : J'ai suivi les conseils de brubru777.

              Merci à tous pour votre aide 

              Scanner sc = new Scanner(System.in);
                      float note = 0;
                      Boolean pass = true;
                      float t_notes = 0;
                      int nbNotes = 0;
                      float max = 0;
                      float min = Float.MAX_VALUE;
              
                      while(pass == true) {
                          do {
                              System.out.println("Entrez une note (si plus de notes, entrez -1) : " );
                              note = sc.nextFloat();
                          } while ((note < 0) && (note != -1));
              
                          if(note == -1) { // condition d'arrêt de saisie de notes
                              pass = false;
                          }
              
                          if (note > max) {
                              max = note;
                          }
                          if (note < min) {
                              min = note;
                          }
              
                          t_notes += note; // ajout de la nouvelle note dans la "liste de notes"
                          nbNotes += 1; // compteur de notes
                      }
                      if (nbNotes == 1) {
                          System.out.println("La moyenne est de : " + t_notes);
                      }
                      else if (nbNotes == 2) {
                          System.out.println("La moyenne est de : " + t_notes/2);
                      }
                      else {
                          System.out.println("min : " + min);
                          System.out.println("max : " + max);
                          t_notes = t_notes - min - max;
                          System.out.println("la moyenne est de : " + t_notes / (nbNotes - 2));
                      }



              -
              Edité par Kidorich 25 janvier 2022 à 9:18:09

              • Partager sur Facebook
              • Partager sur Twitter
                25 janvier 2022 à 11:30:41

                Un dernier petit bug. Avec le booléen pass dans le if, tu vas compter -1 dans la moyenne et le min. Un break serait mieux.
                • Partager sur Facebook
                • Partager sur Twitter
                  25 janvier 2022 à 14:53:47

                  Tu as oublié le cas où on n'entre pas de note.
                  Je ferais ceci:
                  si nbNotes == 0: {
                     J'affiche pas de note
                  }
                  else {
                  if nbNotes > 2 {
                      total = total - min - max
                  nbNotes -= 2
                  }
                  après:
                  affiche totNotes / nbNotes   pour tout le monde
                  }
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Le Tout est souvent plus grand que la somme de ses parties.

                  manipulation de variable

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown