Displaying a letter grade based on a percentage

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 < 0)< System.out.println("Please put in a percent from 0 - 100!\n"); >while (x > 100 || x < 0 )< System.out.print("What is the percentage of the student: "); x = grades.nextInt(); if (x >100 || x < 0)< System.out.println("Please put in a percent from 0 - 100!\n"); >> if (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 > > 
34.9k 13 13 gold badges 133 133 silver badges 237 237 bronze badges asked Nov 25, 2014 at 20:19 Bjorn Lustic Bjorn Lustic 51 1 1 gold badge 1 1 silver badge 3 3 bronze badges

6 Answers 6

\$\begingroup\$

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

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

  1. Ask for a number
  2. 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 Maplimits; 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 System.out.println("Please put in a percent from 0 - 100!\n"); > > public static String getGrade(int score) < for (Map.Entryentry : 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()