Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decisions and if method

Question in book:

Write a program that translates a letter grade into a number grade. Letter grades are A, B, C, D, and F, possibly followed by + or . Their numeric values are 4, 3, 2, 1, and 0. 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.

Enter a letter grade: B- The numeric value is 2.7. Use a class Grade with a method getNumericGrade.

So my question is : I know my code is right, I can run it. But I was curious whether there is a shortcut or a better version of this code that makes it look more professional and easier to read. Any suggestions or examples would greatly be appreciated.

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;
    }
}
like image 241
Can't see me Avatar asked Dec 12 '22 11:12

Can't see me


2 Answers

You can define the mappings and rules separately:

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");
        }
    }
}

Then just use them (example assumes you have validated the input):

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;
    }
}
like image 109
S.D. Avatar answered Jan 02 '23 20:01

S.D.


I would use a lookup table:

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

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

numericValue = gradeLookup.get(grade);

Another good option is a switch statement, which as of Java 7 finally works with Strings.

Both options give you built-in input validation, so that the user cannot enter things like 'G' or 'F+' or 'foo'.

like image 39
Thilo Avatar answered Jan 02 '23 18:01

Thilo