Lesson access পরীক্ষা করা হচ্ছে...
Project: Build a Console-Based Grade Calculator
Build a menu-driven grade calculator that reads and validates marks, tracks totals, highs and lows, and calculates a final grade.
আপনি একটি free preview lesson দেখছেন।
Project Overview
So far, we have learned Java's fundamental building blocks separately. In this project, we combine them into one complete interactive console application: a Grade Calculator. It reads a student's name and the mark for each subject, checks every input, and reports the total, average, highest and lowest marks, the passed and failed subjects, a grade and a final result. It is menu-driven, so it keeps running until the user chooses to exit.
The project uses almost everything from this module: constants, String values, operators and casting, Scanner input with normalization, if-else, switch, for, while, do-while, break, continue, range validation and a text block.
Learning Objectives
After completing this project, you will be able to:
- Build a complete console application
- Collect user input
- Validate required text and numeric ranges
- Read multiple marks using loops
- Calculate a total using an accumulator
- Track highest and lowest values
- Count passed and failed subjects
- Calculate a grade based on the average
- Build a menu-driven program
- Use
switch,break, andcontinuepractically - Combine multiple programming concepts together
Build It Yourself First
Before reading any of our code, build the program yourself from the requirements below. You decide how to structure it; everything fits in one main method.
Requirements
- Menu. Show the menu below, read an option, act on it, and show the menu again until the user chooses Exit.
- Student name. Option
1first asks for the student's name. A name that is empty or only spaces is rejected and asked for again. - Subject count. Next it asks for the number of subjects, which must be
1to10. A value outside that range is asked for again. - Marks. Then it asks for one mark per subject,
0to100. An invalid mark is asked for again for the same subject. - Pass rule. A subject is passed with a mark of
40or more. If any subject is below40, the grade isFand the result isFailed, whatever the average. - Grade rules. If every subject is passed, the grade comes from the average in the table below, and the result is
Passed. - Result. Print the student, the subject count, the total out of the maximum possible (
subjects × 100), the average, the highest and lowest mark, the passed and failed subject counts, the grade, the result and a performance message:Excellent performance(A),Very good performance(B),Good performance(C),Satisfactory performance(D),Passed, but improvement is needed(E) orOne or more subjects were failed(F). - Rules and exit. Option
2prints the grade rules. Option3printsGrade calculator closed.and ends the program. Any other number printsInvalid option. Choose 1, 2, or 3.
The menu:
=== Grade Calculator ===
1. Calculate student result
2. View grade rules
3. Exit
Choose an option:
The grade rules for a student who passed every subject:
| Average Mark | Grade |
|---|---|
80 to 100 | A |
70 to under 80 | B |
60 to under 70 | C |
50 to under 60 | D |
40 to under 50 | E |
The average is a double, so it can fall between whole numbers: an average of 79.67 is still a B. You may assume the user types a whole number at every numeric prompt; text such as eighty needs exception handling, which comes later (see Current Input Limitation).
Acceptance Criteria
Each item is behaviour you can check by running your program. The messages are the ones the reference solution uses.
- Option
2prints the grade rules and shows the menu again - Option
4printsInvalid option. Choose 1, 2, or 3.and shows the menu again - Option
3printsGrade calculator closed.and the program ends - An empty or spaces-only name prints
Student name is required.and asks again - Subject counts
0and11printSubject count must be between 1 and 10.and ask again;1and10are accepted - Marks
-1and101printMark must be between 0 and 100.and ask again for the same subject;0and100are accepted - Marks
90,85and80giveTotal marks: 255 out of 300,Average mark: 85.0, gradeAand resultPassed - A single subject with mark
80gives gradeA, with70gradeB, and with40gradeEand resultPassed: a mark or average exactly on a boundary belongs to the higher band - A single subject with mark
75gives highest and lowest mark75and gradeB - Marks
100,100and39give gradeFand resultFailed, although the average is about79.7 - Marks
0,0and0give total0, average0.0, gradeFand resultFailed - After every result, the menu is shown again
Sample Run
With the inputs 1, an empty name, Nur, 0, 2, 101, 75, 39, 4 and 3, the session looks like this:
=== Grade Calculator ===
1. Calculate student result
2. View grade rules
3. Exit
Choose an option: 1
--- Student Information ---
Enter student name:
Student name is required.
Enter student name: Nur
Enter number of subjects (1-10): 0
Subject count must be between 1 and 10.
Enter number of subjects (1-10): 2
--- Enter Subject Marks ---
Enter mark for subject 1 (0-100): 101
Mark must be between 0 and 100.
Enter mark for subject 1 (0-100): 75
Enter mark for subject 2 (0-100): 39
=== Student Result ===
Student: Nur
Subjects: 2
Total marks: 114 out of 200
Average mark: 57.0
Highest mark: 75
Lowest mark: 39
Passed subjects: 1
Failed subjects: 1
Grade: F
Result: Failed
Performance: One or more subjects were failed
=== Grade Calculator ===
1. Calculate student result
2. View grade rules
3. Exit
Choose an option: 4
Invalid option. Choose 1, 2, or 3.
=== Grade Calculator ===
1. Calculate student result
2. View grade rules
3. Exit
Choose an option: 3
Grade calculator closed.
The average 57.0 is in the D band, but the failed subject makes the grade F.
Try it before reading on. The rest of this lesson builds a reference solution step by step; compare it with yours.
Program Flow
From here on, we build the reference solution. Its overall flow:
Diagram আঁকা হচ্ছে…
Step 1: Define Constants
We will store the program's fixed rules as constants. This reduces unexplained magic numbers in the code.
static final int CALCULATE_RESULT_OPTION = 1;
static final int VIEW_RULES_OPTION = 2;
static final int EXIT_OPTION = 3;
static final int MINIMUM_SUBJECT_COUNT = 1;
static final int MAXIMUM_SUBJECT_COUNT = 10;
static final int MINIMUM_MARK = 0;
static final int MAXIMUM_MARK = 100;
static final int PASSING_MARK = 40;
Step 2: Create the Scanner
Scanner scanner = new Scanner(System.in);
In this project, following our previous convention, we will generally read input using scanner.nextLine(). When a numeric value is required, we will parse it with Integer.parseInt(...).
Step 3: Create the Menu Loop
The menu must be displayed at least once. Therefore, do-while is suitable:
int menuOption;
do {
// Display menu
// Read option
// Process option
} while (menuOption != EXIT_OPTION);
Step 4: Validate Student Name
The student name cannot be blank:
String studentName;
while (true) {
System.out.print("Enter student name: ");
studentName = scanner.nextLine().strip();
if (studentName.isBlank()) {
System.out.println("Student name is required.");
continue;
}
break;
}
We do not know in advance how many attempts the user will need, so a while (true) loop keeps asking: an invalid name leads to continue (try again), a valid one to break (leave the validation loop). Steps 5 and 8 use the same pattern for the subject count and each mark.
Step 5: Validate Subject Count
int subjectCount;
while (true) {
System.out.print(
"Enter number of subjects ("
+ MINIMUM_SUBJECT_COUNT + "-" + MAXIMUM_SUBJECT_COUNT + "): ");
subjectCount = Integer.parseInt(scanner.nextLine().strip());
if (subjectCount < MINIMUM_SUBJECT_COUNT
|| subjectCount > MAXIMUM_SUBJECT_COUNT) {
System.out.println(
"Subject count must be between "
+ MINIMUM_SUBJECT_COUNT + " and " + MAXIMUM_SUBJECT_COUNT + ".");
continue;
}
break;
}
The loop continues until the subject count is valid.
Step 6: Prepare Result Variables
Before processing marks, create the required accumulators and counters:
int totalMarks = 0;
int highestMark = MINIMUM_MARK;
int lowestMark = MAXIMUM_MARK;
int passedSubjectCount = 0;
int failedSubjectCount = 0;
totalMarks works as an accumulator. The highest and lowest marks will be compared with every valid mark.
Step 7: Read Subject Marks
The subject count is already known. Therefore, a for loop is suitable:
for (int subjectNumber = 1; subjectNumber <= subjectCount; subjectNumber++) {
// Read one valid mark
}
Step 8: Validate Each Mark
The prompt for the same subject must repeat until a valid mark is provided:
int mark;
while (true) {
System.out.print(
"Enter mark for subject "
+ subjectNumber + " (" + MINIMUM_MARK + "-" + MAXIMUM_MARK + "): ");
mark = Integer.parseInt(scanner.nextLine().strip());
if (mark < MINIMUM_MARK || mark > MAXIMUM_MARK) {
System.out.println(
"Mark must be between "
+ MINIMUM_MARK + " and " + MAXIMUM_MARK + ".");
continue;
}
break;
}
Step 9: Process Each Valid Mark
After receiving a valid mark, we add it to the total, update the highest and lowest marks, and count the subject as passed or failed:
totalMarks += mark;
if (mark > highestMark) {
highestMark = mark;
}
if (mark < lowestMark) {
lowestMark = mark;
}
if (mark >= PASSING_MARK) {
passedSubjectCount++;
} else {
failedSubjectCount++;
}
Step 10: Calculate the Average
double averageMark = totalMarks / (double) subjectCount;
The cast is needed because totalMarks / subjectCount would perform integer division, since both operands are int.
Step 11: Determine the Final Result
The student has passed all subjects if failedSubjectCount == 0:
boolean passedAllSubjects = failedSubjectCount == 0;
Final result:
String finalResult;
if (passedAllSubjects) {
finalResult = "Passed";
} else {
finalResult = "Failed";
}
Step 12: Determine the Grade
Subject failure takes priority over the average:
String grade;
if (!passedAllSubjects) {
grade = "F";
} else if (averageMark >= 80) {
grade = "A";
} else if (averageMark >= 70) {
grade = "B";
} else if (averageMark >= 60) {
grade = "C";
} else if (averageMark >= 50) {
grade = "D";
} else {
grade = "E";
}
Even if the student's average is very high, a failed subject makes the grade F.
Step 13: Create a Performance Message
The grade is a fixed exact category: A, B, C, D, E, or F. Therefore, a switch expression is suitable:
String performanceMessage = switch (grade) {
case "A" -> "Excellent performance";
case "B" -> "Very good performance";
case "C" -> "Good performance";
case "D" -> "Satisfactory performance";
case "E" -> "Passed, but improvement is needed";
case "F" -> "One or more subjects were failed";
default -> "Result unavailable";
};
Complete Java Program
import java.util.Scanner;
public class Main {
static final int CALCULATE_RESULT_OPTION = 1;
static final int VIEW_RULES_OPTION = 2;
static final int EXIT_OPTION = 3;
static final int MINIMUM_SUBJECT_COUNT = 1;
static final int MAXIMUM_SUBJECT_COUNT = 10;
static final int MINIMUM_MARK = 0;
static final int MAXIMUM_MARK = 100;
static final int PASSING_MARK = 40;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int menuOption;
do {
System.out.println();
System.out.println("=== Grade Calculator ===");
System.out.println();
System.out.println("1. Calculate student result");
System.out.println("2. View grade rules");
System.out.println("3. Exit");
System.out.println();
System.out.print("Choose an option: ");
menuOption = Integer.parseInt(scanner.nextLine().strip());
switch (menuOption) {
case CALCULATE_RESULT_OPTION -> {
System.out.println();
System.out.println("--- Student Information ---");
String studentName;
while (true) {
System.out.print("Enter student name: ");
studentName = scanner.nextLine().strip();
if (studentName.isBlank()) {
System.out.println("Student name is required.");
continue;
}
break;
}
int subjectCount;
while (true) {
System.out.print(
"Enter number of subjects ("
+ MINIMUM_SUBJECT_COUNT + "-" + MAXIMUM_SUBJECT_COUNT + "): ");
subjectCount = Integer.parseInt(scanner.nextLine().strip());
if (subjectCount < MINIMUM_SUBJECT_COUNT
|| subjectCount > MAXIMUM_SUBJECT_COUNT) {
System.out.println(
"Subject count must be between "
+ MINIMUM_SUBJECT_COUNT + " and " + MAXIMUM_SUBJECT_COUNT + ".");
continue;
}
break;
}
int totalMarks = 0;
int highestMark = MINIMUM_MARK;
int lowestMark = MAXIMUM_MARK;
int passedSubjectCount = 0;
int failedSubjectCount = 0;
System.out.println();
System.out.println("--- Enter Subject Marks ---");
for (int subjectNumber = 1; subjectNumber <= subjectCount; subjectNumber++) {
int mark;
while (true) {
System.out.print(
"Enter mark for subject "
+ subjectNumber + " (" + MINIMUM_MARK + "-" + MAXIMUM_MARK + "): ");
mark = Integer.parseInt(scanner.nextLine().strip());
if (mark < MINIMUM_MARK || mark > MAXIMUM_MARK) {
System.out.println(
"Mark must be between "
+ MINIMUM_MARK + " and " + MAXIMUM_MARK + ".");
continue;
}
break;
}
totalMarks += mark;
if (mark > highestMark) {
highestMark = mark;
}
if (mark < lowestMark) {
lowestMark = mark;
}
if (mark >= PASSING_MARK) {
passedSubjectCount++;
} else {
failedSubjectCount++;
}
}
double averageMark = totalMarks / (double) subjectCount;
boolean passedAllSubjects = failedSubjectCount == 0;
String finalResult;
if (passedAllSubjects) {
finalResult = "Passed";
} else {
finalResult = "Failed";
}
String grade;
if (!passedAllSubjects) {
grade = "F";
} else if (averageMark >= 80) {
grade = "A";
} else if (averageMark >= 70) {
grade = "B";
} else if (averageMark >= 60) {
grade = "C";
} else if (averageMark >= 50) {
grade = "D";
} else {
grade = "E";
}
String performanceMessage = switch (grade) {
case "A" -> "Excellent performance";
case "B" -> "Very good performance";
case "C" -> "Good performance";
case "D" -> "Satisfactory performance";
case "E" -> "Passed, but improvement is needed";
case "F" -> "One or more subjects were failed";
default -> "Result unavailable";
};
int maximumPossibleMarks = subjectCount * MAXIMUM_MARK;
System.out.println();
System.out.println("=== Student Result ===");
System.out.println("Student: " + studentName);
System.out.println("Subjects: " + subjectCount);
System.out.println(
"Total marks: " + totalMarks + " out of " + maximumPossibleMarks);
System.out.println("Average mark: " + averageMark);
System.out.println("Highest mark: " + highestMark);
System.out.println("Lowest mark: " + lowestMark);
System.out.println("Passed subjects: " + passedSubjectCount);
System.out.println("Failed subjects: " + failedSubjectCount);
System.out.println("Grade: " + grade);
System.out.println("Result: " + finalResult);
System.out.println("Performance: " + performanceMessage);
}
case VIEW_RULES_OPTION -> {
String gradeRules = """
=== Grade Rules ===
Passing mark per subject: 40
Average 80 to 100 → Grade A
Average 70 to under 80 → Grade B
Average 60 to under 70 → Grade C
Average 50 to under 60 → Grade D
Average 40 to under 50 → Grade E
If any subject mark is below 40:
Grade F and final result Failed
""";
System.out.println();
System.out.println(gradeRules);
}
case EXIT_OPTION -> System.out.println("Grade calculator closed.");
default -> System.out.println("Invalid option. Choose 1, 2, or 3.");
}
} while (menuOption != EXIT_OPTION);
scanner.close();
}
}
Sample Run: Passed Student
With the inputs 1, Sakib, 3, 90, 85, 80 and 3, the reference solution prints:
=== Grade Calculator ===
1. Calculate student result
2. View grade rules
3. Exit
Choose an option: 1
--- Student Information ---
Enter student name: Sakib
Enter number of subjects (1-10): 3
--- Enter Subject Marks ---
Enter mark for subject 1 (0-100): 90
Enter mark for subject 2 (0-100): 85
Enter mark for subject 3 (0-100): 80
=== Student Result ===
Student: Sakib
Subjects: 3
Total marks: 255 out of 300
Average mark: 85.0
Highest mark: 90
Lowest mark: 80
Passed subjects: 3
Failed subjects: 0
Grade: A
Result: Passed
Performance: Excellent performance
=== Grade Calculator ===
1. Calculate student result
2. View grade rules
3. Exit
Choose an option: 3
Grade calculator closed.
Testing Checklist
The acceptance criteria in Build It Yourself First are your test plan. Run them against your version (or the reference solution), using at least the following values:
Menu
1
2
3
4
Subject Count
0
1
10
11
Marks
-1
0
39
40
79
80
100
101
Result Scenarios
- All subjects passed
- One subject failed
- All subjects failed
- One subject
- Highest and lowest are the same
Current Input Limitation
In this project, we validate the range of numeric input, such as -10 or 150. However, if the user enters non-numeric text such as eighty, then Integer.parseInt(...) can produce a NumberFormatException.
Malformed input can be recovered from more cleanly after learning exception handling. For this project, we assume valid numeric text is provided at numeric prompts.
Common Mistakes
Integer Division
double averageMark = totalMarks / subjectCount; compiles, but for the marks 90, 85 and 79 it gives 84.0 instead of 84.66666666666667, because the division happens with int values (see Step 10).
Calculating the Grade Before Checking Failure
Wrong:
if (averageMark >= 80) {
grade = "A";
}
This can ignore a failed subject: the marks 100, 100 and 39 would get an A-range average and no F. Correct:
if (!passedAllSubjects) {
grade = "F";
} else if (averageMark >= 80) {
grade = "A";
}
Processing an Invalid Mark
Wrong order:
totalMarks += mark;
if (mark < MINIMUM_MARK || mark > MAXIMUM_MARK) {
continue;
}
The invalid mark has already been added to the total. Validate first, process later.
Project Improvement Exercises
Solutions: lesson 1.25.
Exercise 1: Percentage
Calculate:
percentage =
total marks
÷ maximum possible marks
× 100
Exercise 2: Distinction Count
Count subjects where the mark is 80 or above.
Exercise 3: Highest Subject
Track the subject number where the highest mark was received. Example:
Highest mark: 95
Highest subject: 3
Exercise 4: Lowest Subject
Track the subject number with the lowest mark.
Exercise 5: Grade Point
Create a grade point based on the grade:
| Grade | Point |
|---|---|
A | 5.0 |
B | 4.0 |
C | 3.0 |
D | 2.0 |
E | 1.0 |
F | 0.0 |
Use a switch expression.
Exercise 6: Calculate Another Student
After completing one result, ask Calculate another student? yes/no. If the answer is yes, calculate another student's result.
Exercise 7: Text Menu
Instead of numeric options, use:
calculate
rules
exit
Normalize the input with .strip().toLowerCase().
Knowledge Check
Question 1
Why is do-while suitable for the menu?
Question 2
Why is for suitable for subject marks?
Question 3
Why is while suitable for mark validation?
Question 4
What does continue do when a mark is invalid?
Question 5
What does break do when a mark is valid?
Question 6
Why is a cast used in the average calculation?
Question 7
What kind of variable is totalMarks?
Question 8
How is the highest mark updated?
Question 9
How is the lowest mark updated?
Question 10
Why is the grade F if one subject is failed?
Question 11
Why is switch suitable for the performance message?
Question 12
When does the menu loop end?
Knowledge Check Answers
Answer 1
The menu must be displayed at least once and should repeat until exit is selected.
Answer 2
The subject count is known before the marks are read.
Answer 3
We do not know in advance how many attempts will be needed to obtain a valid mark.
Answer 4
It ends the current validation iteration and returns to the prompt.
Answer 5
It terminates the nearest validation loop.
Answer 6
To avoid integer division and produce a decimal average.
Answer 7
An accumulator.
Answer 8
The highest mark is updated when the current mark is greater than the existing highest mark.
if (mark > highestMark) {
highestMark = mark;
}
Answer 9
The lowest mark is updated when the current mark is lower than the existing lowest mark.
if (mark < lowestMark) {
lowestMark = mark;
}
Answer 10
According to the project rule, every subject must be passed individually.
Answer 11
The grade is a fixed exact category: A, B, C, D, E, or F.
Answer 12
When the user selects option 3.
Lesson Summary
- The project combined the module's building blocks: constants, variables,
Stringvalues, operators, casting,Scannerinput,if-else,switch, loops,break,continue, and a text block. - A
do-whileloop shows the menu at least once and repeats it until the user chooses exit. while (true)loops withcontinueandbreakkeep asking until the name, subject count, or mark is valid.- A
forloop reads the marks because the subject count is known before the loop starts. - An accumulator collects the total, comparisons track the highest and lowest marks, and counters track passed and failed subjects.
- A cast to
doubleavoids integer division when calculating the average. - The failure check comes before the average-based grade, so one failed subject always gives grade
F.
আগে ভাবুন
শীঘ্রই আসছেCheckpoint প্রশ্ন, যেখানে lesson উত্তর দেখানোর আগে আপনাকে একটি উত্তর বেছে নিতে হবে।