2
\$\begingroup\$

This is a program I typed up for a project pertaining to GPA calculation. However, I want to find an alternative to if then statements that are NOT conditionals, loops, or arrays. Is there an alternative solution to changing this format?

import java.util.Scanner;

public class Part1 {

    public static void main(String args[]) {

        String grade = "";
        String[] letters = {"A+", "A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D", "F"};
        // Creates strings above and the GPA values below
        double[] grades = {4.33, 4.00, 3.67, 3.33, 3.00, 2.67, 2.33, 2.00, 1.67, 1.00, 0.00};
        double credit1;
        double credit2;
        double credit3;
        double credit4;
        double gradeValue = 0;
        // Creates 4 credits
        double totPtsClass1 = 0;
        double totPtsClass2 = 0;
        double totPtsClass3 = 0;
        double totPtsClass4 = 0;
        double totPts = 0;
        double totalCredits = 0;
        double gpa;
        // Points in classes, GPA
        System.out.println("Welcome to the UNG GPA Calculator!");
        String message;

        Scanner scan = new Scanner(System.in);
        System.out.println("Enter your first name: ");
        message = scan.nextLine();
        System.out.println("Enter your last name: ");
        message = scan.nextLine();
        System.out.println("Enter your major: ");
        message = scan.nextLine();
        System.out.println("Enter the number of your first class: ");
        message = scan.nextLine();

        Scanner console = new Scanner(System.in);

        System.out.println("Please enter the number of credits of the class 1 (A number)");
        credit1 = console.nextDouble();
        System.out.println("Please enter your grades for the class 1(Capital letters such as A,B+, C-)");
        grade = console.next();

        if (grade.equals("A")) gradeValue = 4.00;
        else if (grade.equals("A-")) gradeValue = 3.67;
        else if (grade.equals("B+")) gradeValue = 3.33;
        else if (grade.equals("B")) gradeValue = 3.00;
        else if (grade.equals("B-")) gradeValue = 2.67;
        else if (grade.equals("C+")) gradeValue = 2.33;
        else if (grade.equals("C")) gradeValue = 2.00;
        else if (grade.equals("D+")) gradeValue = 1.33;
        else if (grade.equals("D")) gradeValue = 1.00;
        else if (grade.equals("F")) gradeValue = 0;
        else if (grade.equals("FX")) gradeValue = 0;
        else System.out.println("Invalid Grade");

        totPtsClass1 = gradeValue * credit1;

        System.out.println("Please enter the number of credits of the class 2 (A number)");
        credit2 = console.nextDouble();
        System.out.println("Please enter your grades for the class 2 (Capital letters such as A,B+, C-)");
        grade = console.next();

        if (grade.equals("A")) gradeValue = 4.00;
        else if (grade.equals("A-")) gradeValue = 3.67;
        else if (grade.equals("B+")) gradeValue = 3.33;
        else if (grade.equals("B")) gradeValue = 3.00;
        else if (grade.equals("B-")) gradeValue = 2.67;
        else if (grade.equals("C+")) gradeValue = 2.33;
        else if (grade.equals("C")) gradeValue = 2.00;
        else if (grade.equals("D+")) gradeValue = 1.33;
        else if (grade.equals("D")) gradeValue = 1.00;
        else if (grade.equals("F")) gradeValue = 0;
        else if (grade.equals("FX")) gradeValue = 0;
        else System.out.println("Invalid Grade");

        totPtsClass2 = gradeValue * credit2;

        System.out.println("Please enter the number of credits of the class 3 (A number)");
        credit3 = console.nextDouble();
        System.out.println("Please enter your grades for the class 3 (Capital letters such as A,B+, C-)");
        grade = console.next();

        if (grade.equals("A")) gradeValue = 4.00;
        else if (grade.equals("A-")) gradeValue = 3.67;
        else if (grade.equals("B+")) gradeValue = 3.33;
        else if (grade.equals("B")) gradeValue = 3.00;
        else if (grade.equals("B-")) gradeValue = 2.67;
        else if (grade.equals("C+")) gradeValue = 2.33;
        else if (grade.equals("C")) gradeValue = 2.00;
        else if (grade.equals("D+")) gradeValue = 1.33;
        else if (grade.equals("D")) gradeValue = 1.00;
        else if (grade.equals("F")) gradeValue = 0;
        else if (grade.equals("FX")) gradeValue = 0;
        else System.out.println("Invalid Grade");

        totPtsClass3 = gradeValue * credit3;

        System.out.println("Please enter the number of credits of the class 4 (A number)");
        credit4 = console.nextDouble();
        System.out.println("Please enter your grades for the class 4 (Capital letters such as A,B+, C-)");
        grade = console.next();

        if (grade.equals("A")) gradeValue = 4.00;
        else if (grade.equals("A-")) gradeValue = 3.67;
        else if (grade.equals("B+")) gradeValue = 3.33;
        else if (grade.equals("B")) gradeValue = 3.00;
        else if (grade.equals("B-")) gradeValue = 2.67;
        else if (grade.equals("C+")) gradeValue = 2.33;
        else if (grade.equals("C")) gradeValue = 2.00;
        else if (grade.equals("D+")) gradeValue = 1.33;
        else if (grade.equals("D")) gradeValue = 1.00;
        else if (grade.equals("F")) gradeValue = 0;
        else if (grade.equals("FX")) gradeValue = 0;
        else System.out.println("Invalid Grade");
        totPtsClass4 = gradeValue * credit4;

        totPts = totPtsClass1 + totPtsClass2 + totPtsClass3 + totPtsClass4;
        totalCredits = credit1 + credit2 + credit3 + credit4;
        gpa = totPts / totalCredits;

        System.out.printf("Your GPA is: %.2f\n", +gpa);
    }
}

I would like a solution other than the three above, but I'm unfamiliar with anything to substitute for all those if then statements.

\$\endgroup\$
1
\$\begingroup\$

Put the Grade-Score mapping in a HashMap and read it from there.

Do this once:

    Map<String, Double> gradeToScore = new HashMap<>();
    gradeToScore.put("A", 4.00);
    gradeToScore.put("A-", 3.67);
    gradeToScore.put("B+", 3.33);
    gradeToScore.put("B", 3.00);
    gradeToScore.put("B-", 2.67);
    gradeToScore.put("C+", 2.33);
    gradeToScore.put("C", 2.00);
    gradeToScore.put("D+", 1.33);
    gradeToScore.put("D", 1.00);
    gradeToScore.put("F", 0.0);
    gradeToScore.put("FX", 0.0);

Then you can use it as many times as needed:

    if(gradeToScore.containsKey(grade)) {
        gradeValue = gradeToScore.get(grade); 
    }else{
        System.out.println("Invalid Grade");
    }

If you want to go several steps further in optimizing things for readability, you can get to something like this:

public class GradeCalculator {
    //MAIN 
    public static void main(String args[]) {
        GradeCalculator calc = new GradeCalculator();
        calc.startInteraction();
    }

    //DATA CLASS
    private static class Student{
        public String firstName;
        public String lastName;
        public String major;
        public String numFirstClass;
        public final List<Double> credits = new ArrayList<>();
        public final List<Double> points = new ArrayList<>();
    }

    //PROPERTIES & CONSTRUCTOR  
    private final Map<String, Double> gradeToScore = new HashMap<>();
    public GradeCalculator() {
        gradeToScore.put("A+", 4.33);
        gradeToScore.put("A", 4.00);
        gradeToScore.put("A-", 3.67);
        gradeToScore.put("B+", 3.33);
        gradeToScore.put("B", 3.00);
        gradeToScore.put("B-", 2.67);
        gradeToScore.put("C+", 2.33);
        gradeToScore.put("C", 2.00);
        gradeToScore.put("C-", 1.67);
        gradeToScore.put("D+", 1.33);
        gradeToScore.put("D", 1.00);
        gradeToScore.put("F", 0.0);
        gradeToScore.put("FX", 0.0);
    }

    //PUBLIC 
    public void startInteraction() {
        System.out.println("Welcome to the UNG GPA Calculator!");

        try(Scanner scan = new Scanner(System.in);){
            Student student = new Student();
            loadStudentInfo(student, scan);

            loadCreditsAndPoints(student, scan, 1);
            loadCreditsAndPoints(student, scan, 2);
            loadCreditsAndPoints(student, scan, 3);
            loadCreditsAndPoints(student, scan, 4);

            double gpa = calculateGpa(student);
            System.out.printf("Your GPA is: %.2f\n", +gpa);
        }
    }

    //PRIVATE
    private void loadStudentInfo(Student student, Scanner scan) {
        System.out.println("Enter your first name: ");
        student.firstName = scan.nextLine();
        System.out.println("Enter your last name: ");
        student.lastName = scan.nextLine();
        System.out.println("Enter your major: ");
        student.major = scan.nextLine();
        System.out.println("Enter the number of your first class: ");
        student.numFirstClass = scan.nextLine();
    } 

    private void loadCreditsAndPoints(Student student, Scanner scan, int classNumber) {
        System.out.println("Please enter the number of credits of the class " + classNumber + " (A number)");
        double credit = scan.nextDouble();
        student.credits.add( credit );

        System.out.println("Please enter your grades for the class " + classNumber + " (Capital letters such as A,B+, C-)");
        String grade = scan.nextLine();

        double gradeValue = 0;
        if(gradeToScore.containsKey(grade)) {
            gradeValue = gradeToScore.get(grade); 
        }else{
            System.out.println("Invalid Grade");
        }
        double classTotPts = gradeValue * credit;
        student.points.add(classTotPts);
    }

    private double calculateGpa(Student student) {
        double totalCredits = getTotal(student.credits);
        double totPts = getTotal(student.points);
        double gpa = totPts / totalCredits;
        return gpa;
    }

    private double getTotal(List<Double> doubles) {
        double total = 0;
        for(Double d:doubles) {
            total += d;
        }
        return total;
    }
}

And, I would prefer to stay away from streams and lambdas till you completely nail down core Java.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

I know this is an old question but this answer could be helpful to others.

Since the letters and symbols we're dealing with are relatively close to each other in terms of character value, we can use that to our advantage by doing some simple math.

NOTE: This code is largely unchecked and rather verbose - optimize as desired

class Student {
    private double points = 0.0;
    private int credits = 0;
    private final String name = "";

    /**
     * This returns the student's GPA as a double
     *
     * @return The calculated GPA
     */
    public double getGPA() {
        return ((points / credits) * 100) / 100;
    }

    /**
     * This adds a grade to the student's GPA
     *
     * @param gradeString Grade the student received
     * @param credits     Total credit hours of the course
     */
    public void addGrade(String gradeString, int credits) {
        if (gradeString.equals("F")) {
            gradeString = "E";
        }

        // As we get closer to the letter 'E', the lower the total points
        // The ASCII value of 'A" is 65, and the value for 'E' is 69
        // 69 / 65 is 1, with a remainder of 4
        // The remainder is what we're after, so use modulo
        //
        // For example, the program passes in the grade "C-" and the first
        // character of that the string gradeString is C and we can get this
        // value by using the charAt() method. Since Java is a 0-based index
        // language we pass 0 into the charAt method to get the first character
        // of the string. The decimal value of that character is 67. We know that
        // the decimal value of the character 'E' is 69, so we can use the formula
        // 69 % 67 which will give us 2.

        double gradeVal = 'E' % gradeString.charAt(0);

        if (gradeString.length() == 2) {
            int c = gradeString.charAt(1);

            // A little bit of error checking is required using these methods
            if (c != 'X' &&
                    (gradeVal != 'D' && c != '-') &&
                    (gradeVal != 'A' && c != '+')) {
                double point = -((c - (double) ',') / 3);
                gradeVal += point;
            }
        }

        // Add the number of credits to our running total
        this.credits += credits;

        // Calculate this course's grade
        double courseGrade = Math.round((gradeVal * credits) * 100) / 100.0;

        // Add the course grade to our running total
        points += courseGrade;
    }

    /**
     * Get the student's name
     *
     * @return The student's name
     */
    public String getName() {
        return name;
    }

    /**
     * The Student class
     *
     * @param name The student's name
     */
    public Student(String name) {
        this.name = name;
    }
}

public class Program {
    public static void main(String[] args) {
        // Create a new Student object named student1
        // student1's name is set with Robert
        Student student1 = new Student("Robert");

        // Add various grades to student's history
        student1.addGrade("A", 4); // CPS-171
        student1.addGrade("A", 3); // ENG-107
        student1.addGrade("A", 4); // CPS-161
        student1.addGrade("C-", 4); // Some math class I'll have to take

        // Store the student's GPA into student1Gpa
        double student1Gpa = student1.getGPA();
        System.out.printf("Student %s has a GPA of %.2f\n", student1.getName(), student1Gpa);
    }
}
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.