HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Displaying a letter grade based on a percentage

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
gradedisplayingbasedletterpercentage

Problem

Here is a class I made that is able to ask a teacher what percentage their student has in a class and gives them back a grade. The code is very repetitive and I am wondering what I can do to simplify the class below before inputting any more grades.

import java.util.Scanner;

public class Grades{
    public static void main(String [] args){
        Scanner grades = new Scanner(System.in);

        int x = 0;

        System.out.print("What is the percentage of the student: ");
        x = grades.nextInt();

        if (x > 100 || x  100 || x  100 || x = 96){
             System.out.print("A+");
        }
         if (x = 92){
             System.out.print("A");
        }
         if (x = 90){
             System.out.print("A-");
        }
         if (x = 50){
             System.out.print("B+");
        }
         if (x = 0){
             System.out.print("B");
        }
        // so on and so forth down the grading scale
    }
}

Solution

It would be good to split the different sub-tasks to different functions,
for example:

  • int promptScore(): a method to prompt for score



  • String getGrade(int score): a method to return the grade from the score



The promptScore method could use an infinite loop with two steps:

  • Ask for a number



  • If the number is within the range, return it



The getGrade method could use a sorted map that stores the limits and the corresponding grades.
You could iterate over the entries in this map,
and when you find a value that is below the limit, then you return the corresponding grade.

Something like this:

class Grades {

    private static final Map limits;

    static {
        limits = new TreeMap<>();
        limits.put(50, "B");
        limits.put(90, "B+");
        limits.put(92, "A-");
        limits.put(96, "A");
        limits.put(101, "A+");
    }

    public static int promptScore() {
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.print("What is the percentage of the student: ");
            int x = scanner.nextInt();

            if (0  entry : limits.entrySet()) {
            int limit = entry.getKey();
            if (score < limit) {
                return entry.getValue();
            }
        }
        throw new AssertionError("Impossible case");
    }

    public static void main(String[] args) {
        System.out.println(getGrade(promptScore()));
    }
}


The benefit of splitting up the functions like this is that writing unit tests becomes easy:

@Test
public void testB() {
    assertEquals("B", Grades.getGrade(0));
    assertEquals("B", Grades.getGrade(49));
}

@Test
public void testB_Plus() {
    assertEquals("B+", Grades.getGrade(50));
    assertEquals("B+", Grades.getGrade(89));
}

@Test
public void testA_Minus() {
    assertEquals("A-", Grades.getGrade(90));
    assertEquals("A-", Grades.getGrade(91));
}

@Test
public void testA() {
    assertEquals("A", Grades.getGrade(92));
    assertEquals("A", Grades.getGrade(95));
}

@Test
public void testA_Plus() {
    assertEquals("A+", Grades.getGrade(96));
    assertEquals("A+", Grades.getGrade(100));
}

Code Snippets

class Grades {

    private static final Map<Integer, String> limits;

    static {
        limits = new TreeMap<>();
        limits.put(50, "B");
        limits.put(90, "B+");
        limits.put(92, "A-");
        limits.put(96, "A");
        limits.put(101, "A+");
    }

    public static int promptScore() {
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.print("What is the percentage of the student: ");
            int x = scanner.nextInt();

            if (0 <= x && x <= 100) {
                return x;
            }
            System.out.println("Please put in a percent from 0 - 100!\n");
        }
    }

    public static String getGrade(int score) {
        for (Map.Entry<Integer, String> entry : limits.entrySet()) {
            int limit = entry.getKey();
            if (score < limit) {
                return entry.getValue();
            }
        }
        throw new AssertionError("Impossible case");
    }

    public static void main(String[] args) {
        System.out.println(getGrade(promptScore()));
    }
}
@Test
public void testB() {
    assertEquals("B", Grades.getGrade(0));
    assertEquals("B", Grades.getGrade(49));
}

@Test
public void testB_Plus() {
    assertEquals("B+", Grades.getGrade(50));
    assertEquals("B+", Grades.getGrade(89));
}

@Test
public void testA_Minus() {
    assertEquals("A-", Grades.getGrade(90));
    assertEquals("A-", Grades.getGrade(91));
}

@Test
public void testA() {
    assertEquals("A", Grades.getGrade(92));
    assertEquals("A", Grades.getGrade(95));
}

@Test
public void testA_Plus() {
    assertEquals("A+", Grades.getGrade(96));
    assertEquals("A+", Grades.getGrade(100));
}

Context

StackExchange Code Review Q#70844, answer score: 5

Revisions (0)

No revisions yet.