4 votes

Décisions et si méthode

Question dans le livre :

Écrire un programme qui traduit une note en lettres en une note en chiffres. Les notes en lettres sont A , B , C , D et F , éventuellement suivie de + o . Leurs valeurs numériques sont 4 , 3 , 2 , 1 et 0 . Il n'y a pas de F+ o F– . A + augmente la valeur numérique de 0.3 , a le diminue de 0.3 . Toutefois, un A+ a de la valeur 4.0 .

Saisissez une note en lettres : B- La valeur numérique est 2.7 . Utiliser une classe Grade avec une méthode getNumericGrade .

Ma question est donc la suivante : Je sais que mon code est correct, je peux l'exécuter. Mais je suis curieux de savoir s'il existe un raccourci ou une meilleure version de ce code qui le rendrait plus professionnel et plus facile à lire. Toute suggestion ou exemple serait grandement apprécié.

Code :

import java.util.Scanner;

public class grade
{
    private double numericValue = 0;
    private String grade = "";

    public grade()
    {

        Scanner in = new Scanner(System. in );
        System.out.print("Enter Grade: ");
        grade = in .nextLine();
    }

    public double getNumericGrade()
    {

        if (grade.equals("A+") || grade.equals("A"))
        {
            numericValue = 4.0;
        }
        else if (grade.equals("A-"))
        {
            numericValue = 3.7;
        }
        else if (grade.equals("B+"))
        {
            numericValue = 3.3;
        }
        else if (grade.equals("B"))
        {
            numericValue = 3.0;
        }
        else if (grade.equals("B-"))
        {
            numericValue = 2.7;
        }
        else if (grade.equals("C+"))
        {
            numericValue = 2.3;
        }
        else if (grade.equals("C"))
        {
            numericValue = 2.0;
        }
        else if (grade.equals("C-"))
        {
            numericValue = 1.7;
        }
        else if (grade.equals("D+"))
        {
            numericValue = 1.3;
        }
        else if (grade.equals("D"))
        {
            numericValue = 1.0;
        }
        else if (grade.equals("F"))
        {
            numericValue = 0;
        }
        else
        {
            System.out.println("Letter not in grading system");
        }
        return numericValue;
    }
}

6voto

S.D. Points 12816

Vous pouvez définir les correspondances et les règles séparément :

public static enum Grade {

    // Letter grades are A, B, C, D, and F
    // Their numeric values are 4, 3, 2, 1, and 0

    A(4),B(3),C(2),D(1),F(0);

    public final double score;

    private Grade(double d) {
        this.score = d;
    }

    // Grades are possibly followed by + or –
    // There is no F+ or F–
    // a + increases the numeric value by 0.3, a – decreases it by 0.3
    // However, an A+ has value 4.0

    public double getModifiedScore(char sign) {
        switch (sign) {
            case '+':
                return score + (score < 4 && score > 0 ? 0.3 : 0);
            case '-':
                return score + (score > 0 ? -0.3 : 0);
            default:
                throw new IllegalArgumentException("Invalid sign");
        }
    }
}

Il suffit ensuite de les utiliser (l'exemple suppose que vous avez validé l'entrée) :

public static double getNumericGrade(String s){
    Grade g = Grade.valueOf(s.substring(0, 1));
    if(s.length() > 1){
        return g.getModifiedScore(s.charAt(1));
    }else {
        return g.score;
    }
}

5voto

Thilo Points 108673

J'utiliserais un tableau de consultation :

private final static Map<String,Double> gradeLookup = 
   new HashMap<String, Double>();

gradeLookup.put("A-", 3.7);

numericValue = gradeLookup.get(grade);

Une autre bonne option est l'instruction switch, qui, depuis Java 7, fonctionne enfin avec les chaînes de caractères.

Les deux options offrent une validation intégrée des entrées, de sorte que l'utilisateur ne puisse pas saisir des éléments tels que "G", "F+" ou "foo".

1voto

arshajii Points 65653

Utiliser un Map qui met en correspondance des caractères (dans ce cas A .. D , F ) aux valeurs correspondantes ( 4 .. 0 ).

Lorsque vous traitez vos données :

  • s'il n'y a qu'un seul caractère, il suffit de chercher le caractère dans la carte.
  • s'il existe un + o - à la fin, examine le premier caractère et traite le second de manière appropriée (selon les règles que vous avez affichées, en n'oubliant pas de traiter les cas spéciaux tels que A+ ).

Vous pouvez essayer quelque chose comme ceci :

private static final Map<Character, Double> grades = new HashMap<>();
static {
    grades.put('A', 4.0);
    grades.put('B', 3.0);
    grades.put('C', 2.0);
    grades.put('D', 1.0);
    grades.put('F', 0.0);
}

public static double getNumericGrade(String input) {
    if (input == null || input.isEmpty() || input.length() > 2
            || input.matches("F[+-]")
            || !grades.containsKey(input.charAt(0)))  // validate input
        throw new IllegalArgumentException();

    double val = grades.get(input.charAt(0));

    if (input.length() == 1) {
        return val;
    } else if (input.charAt(1) == '+') {
        return (input.charAt(0) == 'A') ? val : val + 0.3;
    } else if (input.charAt(1) == '-') {
        return val - 0.3;
    } else {
        throw new IllegalArgumentException();
    }
}

1voto

Makoto Points 23751

Une approche consiste à utiliser switch - qui fonctionne avec String dans Java 7.

// Yes, I'm passing grade and shadowing numericValue, since those properties
// aren't used anywhere else in the class.
public double getNumericGrade(String grade) {
    double numericValue = 0;

    switch (grade) {
        case "A+":
        case "A":
            numericValue = 4.0;
            break;
        case "A-":
            numericValue = 3.7;
            break;
        case "B+":
            numericValue = 3.3;
            break;
        case "B":
            numericValue = 3.0;
            break;
        case "B-":
            numericValue = 2.7;
            break;
        case "C+":
            numericValue = 2.3;
            break;
        case "C":
            numericValue = 2.0;
            break;
        case "C-":
            numericValue = 1.7;
            break;
        case "D+":
            numericValue = 1.3;
            break;
        case "D":
            numericValue = 1.0;
            break;
        case "F":
            numericValue = 0;
            break;
        default:
            System.out.println("Letter not in grading system");
            break;
    }
    return numericValue;
}

...mais c'est assez verbeux.

Une autre approche consiste à prendre les règles que nous avons sur les notes numériques et à écrire quelque chose d'un peu plus laconique.

  • Si la note est un point de lettre, il s'agit d'un nombre entier (A = 4, B = 3, C = 2, D = 1, F = 0).
  • Si la note est assortie d'un moins, la valeur est la différence entre le nombre entier et 0,3.
  • Si la note est assortie d'un plus, la valeur est la somme du nombre entier et de 0,3.

Voici une solution qui utilise ces règles. Elle est peut-être un peu plus verbeuse et n'est peut-être pas si différente de l'interrupteur, mais c'est une autre façon de l'écrire.

public double getNumericGradeRefactored(String grade) {
    Map<Character, Double> gradeMap = new HashMap<Character, Double>(){{
        put('A', 4.0);
        put('B', 3.0);
        put('C', 2.0);
        put('D', 1.0);
        put('F', 0.0);
    }};

    // split result
    char[] gradeParts = grade.toCharArray();
    double result = gradeMap.get(gradeParts[0]);
    if(gradeParts.length > 1) {
        switch(gradeParts[1]) {
            case '+':
                result += 0.3;
                break;
            case '-':
                result -= 0.3;
                break;
        }
    }
    return result;

}

0voto

Tsumikiri Points 1

Je traiterais les "+" ou les "-" séparément.

Vérifiez la présence de la lettre, puis ajoutez ou soustrayez la valeur de la note si elle contient un "+" ou un "-".

EDIT : Personnellement, je préfère le switch-case aux longues instructions if-elseif, mais l'un ou l'autre fonctionnera suffisamment bien.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X