# Student Grade Calculation

Develop a smart application as Student Grade Calculator(SGC).

Create a class Student with following private attribute :

int id, String name, marks(integer array), float average and char grade. Include appropriate getters and setters methods and constructor.

public void calculateAvg() - This method should calculate average and set average mark for the current student.

public void findGrade()- This method should set the grade based on the average calculated. If the average is between 80 and 100 then, then return grade as 'O', else 'A' .If the student gets less than 50 in any of the subjects then return grade as 'F'. Using appropriate setter method set the grade to the student.

(Note : number of subject should be greater than zero, if not display as 'Invalid number of subject' and get number of subject again, Assume mark for a subject should be in the range 0 - 100. If not display a message "Invalid Mark" and get the mark again)

Write a class StudentMain and write the main method.

In this class, write a method

public static Student getStudentDetails() - this method should get the input from the user for a student, create a student object with those details and return that object.

In main create student’s object by invoking the getStudentDetails method. Also calculate average and grade for that student object using appropriate methods.

SGC app should get the input and display the output as specified in the snapshot:

Sample Input 1:
Enter the id:
123
Enter the name:
Tom
Enter the no of subjects:
3
Enter mark for subject 1:
95
Enter mark for subject 2:
80
Enter mark for subject 3:
75

Sample Output 1:

Id:123
Name:Tom
Average:83.33
Grade:O

Sample Input 2:

Enter the id:
123
Enter the name:
Tom
Enter the no of subjects:
0

Invalid number of subject

Enter the no of subjects:

3
Enter mark for subject 1:
75
Enter mark for subject 2:
49
Enter mark for subject 3:
90

Sample Output 2:

Id:123
Name:Tom
Average:71.33
Grade:F


public class Student{
private int id;
private String name;
private Integer[] marks;
private float average;
private char grade;

public Student(int id, String name, Integer[] marks){
this.id=id;
this.name=name;
this.marks=marks;
}
public void setId(int id){
this.id=id;
}
public int getId(){
return id;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public Integer[] setMarks(Integer[] marks){
return this.marks = getMarks();
}
public Integer[] getMarks(){
return marks;
}
public void setAverage(float average){
this.average=average;
}
public float getAverage(){
return average;
}
public void setGrade(char grade){
this.grade=grade;
}
public char getGrade(){
return grade;
}

public void calculateAvg(){
StudentMain sm = new StudentMain ();
int sum=0;
//int no=0;
for(int i=0;i<marks.length;i++){
sum+=marks[i];
}
float avg=sum/sm.n;
//System.out.println(sum);
setAverage(avg);
}
public void findGrade(){
float avg=getAverage();
if (avg>+80 && avg<+100){
setGrade('O');
}
else if (avg>=50 && avg<80){
setGrade('A');
}
else {
setGrade('F');
}
}
}

import java.util.*;
import java.io.*;

public class StudentMain{
static Scanner sc = new Scanner(System.in);
static int n;
static List<Integer> al = new ArrayList<Integer>();
public static Student getStudentDetails(){
System.out.println("Enter the id:");
int id=sc.nextInt();
System.out.println("Enter name:");
String name=sc.next();
System.out.println("Enter the no of subjects");
n = sc.nextInt();
if (n<=0){
System.out.println("Invalid number of subjects");
System.out.println("Enter the number of subjects");
n=sc.nextInt();
}

//List<Integer> al = new ArrayList<Integer>();
for (int i=0; i<n;i++){
int t=i+1;
System.out.println("Enter mark for subject" +t);
int m =sc.nextInt();
//List<Integer> al = new ArrayList<Integer>();
//System.out.println(m);
al.add(m);

}

Integer[] marks = new Integer[al.size()];
for (int i =0; i<al.size(); i++){
marks[i] = al.get(i);
}
for (Integer x : marks){
//return marks;
}

//int [] marks = null;
Student s = new Student(id,name,marks);
return s;

}
public static void main (String[] args) {
Student s2 = getStudentDetails();
System.out.println("Id:" + s2.getId());
System.out.println("Name:" + s2.getName());
s2.calculateAvg();
System.out.println("Average:"+s2.getAverage());
s2.findGrade();
System.out.println("Grade:"+s2.getGrade());
}
}

• Why is this question being downvoted and flagged to be closed? I see nothing wrong with it. – RoToRa Jun 4 '20 at 7:32
• It appears that the poster has included the full specification that they received for the problem, what is unclear to those that down voted or VTC? – pacmaninbw Jun 4 '20 at 13:22

## 3 Answers

First off, I must say the task as written is not very good. It encourages some bad practices, mostly requiring separate calculateAvg() and findGrade() methods. Instead this functionality should be integrated in getAverage() and getGrade().

# Class StudentMain

All three static fields are unnecessary. They are only used/needed inside the method getStudentDetails() so they should be local variables inside that method. And the case of the field n is especially bad, since it is accessed later on in a way that never should be used (more on that later).

Furthermore the names are bad. Don't unnecessarily abbreviate them and do call them after what they hold, not what they are. sc should be called scanner and al should be called marks.

## Method getStudentDetails()

Don't leave in commented out code lines and remove the for loop that doesn't do anything.

You are missing the part of the task requiring you check that the marks are between 0 and 100.

There is no need to manually copy the contents of the ArrayList to an array. For one Lists have a method toArray() to do that for you (although it is a bit awkward to use due to limitations of the Java language).

But more importantly, since know the number of elements ahead of time, it would be sensible to store the marks directly in an array:

Integer[] marks = new Integer[n];

for (int i = 0; i < n; i++) { // It is convention to use spaced around operators
int subjectNr = i + 1; // Use readable variable names, not random single letters
System.out.println("Enter mark for subject " + subjectNr);
int mark = sc.nextInt();
marks[i] = mark;
}


# class Student

Another of the weaknesses of this task is requirement to add "appropriate" setters. I'd argue that it's appropriate to have no setters at all, since they are not needed.

## Method calculateAvg()

This method contains the biggest flaw in your code. This class should never access the field n from StudentMain for many reasons:

• The class Student has no business even to know about StudentMain. A method in Student should only access its parameters and members (fields and methods) of Student.
• Since n is static there only one value, but if you had more than one Student there is a good chance, that the value n contains the information from a different Student than the one you are currently calculating the average of.
• StudentMain only contains static members, so creating a new instance with new is generally pointless. Actually your IDE/compiler should be warning you about accessing the static field n via an instance. Especially as a beginner you should consider warnings errors.
• You don't even need to get the number of marks from StudentMain. marks.length contains the same information.

## Method findGrade()

You have some errors in here.

• Averages of exactly 80 or 100 will return an 'F'.
• The task asks you return an 'F' if the student has less than 50 in any subject, not less than 50 in average.
    private Integer[] marks;


There's a difference between int and Integer, be aware of it.

private char grade;


For better clarity, you want to use an enum:

public enum Grade {
O,
A,
B,
C,
D,
E,
F
}


You could even assign it ranges, which would make it easy to fetch one:

public enum Grade {
O(80, 100),
A(50, 80),
F(0, 50);

private int lowerBound;
private int upperBound;

private Grade(int lowerBound, int upperBound) {
this.lowerBound = lowerBound;
this.upperBound = upperBound;
}

public static final Grade getGrade(float gradeAverage) {
for (Grade grade : values()) {
if (grade.lowerBound >= gradeAverage && grade.upperBound <= gradeAverage) {
return grade;
}
}

return null; // IllegalStateException?
}
}


public Integer[] setMarks(Integer[] marks){
return this.marks = getMarks();
}


That's an odd pattern I haven't seen before, the traditional pattern is to return nothing. But [the fluent pattern](https://en.wikipedia.org/wiki/Fluent_interface#Java0 is also very nice:

public Student setMarks(Integer[] marks){
this.marks = marks;

return this;
}


return this.marks = getMarks();


That's a nice typo.

public void calculateAvg(){
StudentMain sm = new StudentMain ();
int sum=0;
//int no=0;
for(int i=0;i<marks.length;i++){
sum+=marks[i];
}
float avg=sum/sm.n;
//System.out.println(sum);
setAverage(avg);
}


Now that's an odd one, and an error I believe. You don't want to create a new instance of StudentMain here, you want to pass the values you need.

float avg=sum/sm.n;


That's a bug, dividing and int by an int will yield an int, not a float:

float result = 5/2; // == 2 int
float result = 5/(float)2; // == 2.5 float


if (avg>+80 && avg<+100){
setGrade('O');
}
else if (avg>=50 && avg<80){
setGrade('A');
}
else {
setGrade('F');
}


That's another bug, a student with a perfect 100 (though, unlikely because of float), will get an F.

Also, the leading "+" is unconventional.

static Scanner sc = new Scanner(System.in);
static int n;
static List<Integer> al = new ArrayList<Integer>();


Stop shorting your (variable) names, you're gaining nothing from it, the code is only harder to read because of it.

Also, keep your code clean, use git or mercurial and commit your code and then remove what you don't need anymore.

• Why would a perfect 100 be "unlikely because of float"? I very much doubt that. Java guarantees that 300.0 / 3.0 == 100.0. – Roland Illig Jun 4 '20 at 20:52
• @RolandIllig My point, the test is for value < 100, so if somebody does a perfect score, they will get an "F". – Bobby Jun 5 '20 at 18:17
• And what does this have to do with float? – Roland Illig Jun 6 '20 at 22:15

Some Basic things i would like to mention here

1. Why did you use Wrapper class Integer when you had to create array of integer you have option of int[] or Integer[], for using wrapper classes you should have reasons to use it, please read the use cases of wrapper class

2. Variable names Always give your variable meaningful name, because it is not just about writing the code but also the maintainability and readability of code.

3. Your calculateAvg() method Why are you accessing main class here, you have array to get the size(which is equal to the number of subject)

4. While taking input subject marks Directly use int[] not list, that way you need not do the conversation from list to array.

5. enum for the grade you can use enum for the grade that way you will not have constants in your code base.

• This answer is not useful for a beginner because it is way too abstract. For a beginner, it is important to get clear advice at what to do exactly, not just a high level overview. – Roland Illig Jun 6 '20 at 22:17
• I am not talking about some random java concept i have picked these points from his code only, and moreover these are not java advanced topic too. – Anshul Sharma Jun 7 '20 at 1:44
• A beginner typically does not know how to "use enum", and the "use cases of wrapper class" is an advanced concept. A few links to useful tutorials would be helpful. Especially "maintainability and readability" are not known yet to the OP, otherwise the code would look completely different. It's as if I would tell you "add more quality to your answer". – Roland Illig Jun 7 '20 at 6:35