본문 바로가기

IT/Java

22_자바로 석차 계산 가능한 성적표 만들기(클래스, ArrayList 활용)

00.

코로나 때문에 꿀같은 주말인데 밖에도 못 나가고 심심해서 옛날에 만들었던 프로그램을 다른 방법으로 만들어봤다.

자바로 석차 계산 가능한 성적 관리 프로그램을 만드는 방법은 다양하다.

예전에는 이차원 배열을 활용해서 만들었지만 이번에는 더 간단하게 클래스를 활용하여 만들었다.

 

 

이번 프로그램의 특징은

1. Student 클래스학번, 이름, 과목별 성적, 총점, 평균, 등급, 석차를 필드로 가지고 있다.

2. Student 클래스는 사용자로부터 입력 받는 메소드 부터 최종 결과 출력 메소드까지 포함하고 있다.

3. 석차를 제외한 모든 필드는 한꺼번에 입력 및 산출이 가능하다

   (예: 1번 학생의 이름을 입력한 후, 과목별 성적을 입력하면 총점과 평균, 등급이 자동으로 계산되어 업데이트 된다.

        그 이후에 2번 학생의 정보를 입력한다.)

4. 그런데 석차는 모든 학생의 정보를 입력한 후에야 계산할 수 있으므로 가장 마지막에 처리한다(중요!!)

5. 동점자가 있을 경우 높은 석차를 부여한다. 

   (예:  1번 학생의 총점이 100점, 2번 학생의 총점이 95점, 3번 학생의 총점이 100점인 경우, 1번과 3번 학생은 공동1등이며 2번 학생은 3등의 석차가 부여된다.)

6. 편의상 처음에 전체 학생 수를 입력하면 1번 부터 전체 학생 수만큼 학번이 부여되도록 하였다.

7. 이렇게 만들어진 Student 객체들을 ArrayList에 담아 한꺼번에 석차 계산 후 출력되도록 하였다.

 

01. Student 클래스_기본구성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public class Student {
    private int sno;
    private String sname;
    private int kor;
    private int eng;
    private int math;
    private int total;
    private double avg;
    private char grade;
    private int rank;
 
    public Student() {
 
    }
 
    public String getSname() {
        return sname;
    }
 
    public void setSname(String sname) {
        this.sname = sname;
    }
 
    public int getSno() {
        return sno;
    }
 
    public void setSno(int sno) {
        this.sno = sno;
    }
 
    public int getKor() {
        return kor;
    }
 
    public void setKor(int kor) {
        this.kor = kor;
    }
 
    public int getEng() {
        return eng;
    }
 
    public void setEng(int eng) {
        this.eng = eng;
    }
 
    public int getMath() {
        return math;
    }
 
    public void setMath(int math) {
        this.math = math;
    }
 
    public int getTotal() {
        return total;
    }
 
    public void setTotal(int total) {
        this.total = total;
    }
 
    public double getAvg() {
        return avg;
    }
 
    public void setAvg(double avg) {
        this.avg = avg;
    }
 
    public char getGrade() {
        return grade;
    }
 
    public void setGrade(char grade) {
        this.grade = grade;
    }
 
    public int getRank() {
        return rank;
    }
 
    public void setRank(int rank) {
        this.rank = rank;
    }
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

02. Student 클래스_사용자 입력단

사용자 입력단에는 여러가지 예외처리를 해주었지만, 코드가 너무 길어져서 포스팅에서는 생략했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Scanner sc = new Scanner(System.in);
 
    // 학생 수를 입력 받는다
    public int setStudNum() throws InterruptedException {
        int numStud = 0;
        System.out.print("전체 학생 수 입력 >> ");
        //유효성 검사는 생략했다.
        numStud = sc.nextInt();
        return numStud;
 
    }// setSNum END
 
    // 입력 받은 학생 수 만큼 Student 객체를 생성하여 ArrayList에 담는다.
    public ArrayList<Student> inputStudInfo(int numStud) throws InterruptedException {
        ArrayList<Student> studList = new ArrayList<Student>();
        for (int i = 0; i < numStud; i++) {
            Student stud = new Student();
//            System.out.println((i + 1) + "번 학생 생성");
            System.out.print("입력한 학생 수 : " + i + "\t남은 학생 수 : " + (numStud - i) + "\t총 학생 수 : " + numStud + "\n\n");
 
            System.out.println("현재 입력 중인 학생 번호 : " + (i + 1));
            stud.setSno(i + 1);
 
            System.out.print("이름 입력 >> ");
            stud.setSname(sc.next());
            // 점수 입력 부분은 유효성 검사 필요. 여기서는 그냥 생략.
            System.out.print("국어 점수 입력 >> ");
            stud.setKor(sc.nextInt());
            System.out.print("영어 점수 입력 >> ");
            stud.setEng(sc.nextInt());
            System.out.print("수학 점수 입력 >> ");
            stud.setMath(sc.nextInt());
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

 03. Student 클래스_마무리

 

이 부분이 중요하다!

먼저 위에서 입력한 점수를 토대로 총점과 평균, 등급을 생성한 학생 객체에 셋팅해준다.

모든 학생들에 대한 점수 셋팅 작업이 끝난 후(즉, for문이 끝난 후)에야 석차 계산이 가능하다.

석차는 계산이 끝난 후 한꺼번에 calcRank()메소드 마지막 부분에서 객체에 셋팅해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
// 총점, 평균, 등급 계산
            stud.setTotal(calcTotal(stud.getKor(), stud.getEng(), stud.getMath()));
            stud.setGrade(calcGrade(stud.getAvg()));
 
            studList.add(stud); // 계산한 총점, 평균, 등급을 먼저 넣어줘야 한다.
        } // for END
 
        // 모든 학생의 총점이 리스트에 입력 된 후에(즉 반복문이 끝난 뒤에), 석차 계산이 가능
        calcRank(studList);
        return studList;
    }// inputSInfo END
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

총점, 평균, 등급, 석차를 계산하는 메소드는 따로 뺐다.

calcRank() 메소드는 석차까지 계산된 최종 학생리스트를 리턴한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    // 개인 총점
    public int calcTotal(int kor, int eng, int math) {
        return kor + eng + math;
 
    } // calcTotal END
 
    // 개인 평균
    public double calcAvg(int total) {
 
//        return Math.round((total / 3.0)*100)/100.0;
        return total / 3.0;
    } // calcAvg END
 
    // 등급 계산
    public char calcGrade(double avg) {
        char grade;
        switch ((int) avg / 10) {
        case 10:
        case 9:
            grade = 'A';
            break;
        case 8:
            grade = 'B';
            break;
        case 7:
            grade = 'C';
            break;
        case 6:
            grade = 'D';
            break;
        default:
            grade = 'F';
            break;
        }
        return grade;
    } // calcGrade
 
    // 석차 계산
    public void calcRank(ArrayList<Student> studList) {
        for (int i = 0; i < studList.size(); i++) {
            int rank = 1;
            for (int j = 0; j < studList.size(); j++) {
                // 일단 나를 1등이라고 가정하고, 다른 값들과 비교하여 작으면 rank 값을 하나씩 올린다.
                // 동점 처리 : 공동 1등인 경우 모두 1등 처리, 그 다음은 3등 처리.
                if (studList.get(i).getTotal() < studList.get(j).getTotal()) {
                    rank++;
                } // end if
            } // end inner for
            studList.get(i).setRank(rank);
        } // end outer for
    } // calcRank END
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

석차까지 계산이 끝났으면 이제 출력이 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 학생 정보 출력
    public void printStudInfo(ArrayList<Student> studList) {
        for (int i = 0; i < studList.size(); i++) {
            System.out.println("======================성적표======================");
            System.out.printf("%s%3d\t" // 학번
                    + "%s%s\t" // 이름
                    + "%s%3d\n" // 석차
                    + "%s%3d\t%s%3d\t%s%3d\n" // 국영수
                    + "%s%3d\t%s%.2f\t%s%c\n"// 총점 평균 등급
 
                    "학번 : "studList.get(i).getSno(), "이름 : "studList.get(i).getSname(), "석차 : ",
                    studList.get(i).getRank(),
 
                    "국어 : "studList.get(i).getKor(), "영어 : "studList.get(i).getEng(), "수학 : ",
                    studList.get(i).getMath(),
 
                    "총점 : "studList.get(i).getTotal(), "평균 : "studList.get(i).getAvg(), "등급 : ",
                    studList.get(i).getGrade());
            System.out.println("================================================\n\n");
        } // for END
    } // printStudInfo END
 
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

04. MainEntry 클래스

메인에서는 Student 객체를 생성한 후 출력메소드를 호출한다.

로직을 다르게 짰으면 메인이 더 간단해졌을텐데 이 부분이 좀 아쉽다.

1
2
3
4
5
6
7
public class MainEntry {
    public static void main(String[] args) throws InterruptedException {
        Student smd = new Student();
        smd.printStudInfo(smd.inputStudInfo(smd.setStudNum()));
    }
 
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter