코딩항해기

[과제/JAVA] 학생부 프로그램에 객체 더하기 (+풀이 0703) 본문

problem solving/과제&실습 코딩

[과제/JAVA] 학생부 프로그램에 객체 더하기 (+풀이 0703)

miniBcake 2024. 7. 2. 17:06

 

 

기존 진행했던 학생부 프로그램을 디벨롭 시켜 객체를 더하고 기능을 추가했다.

(재시험 기능은 자유)

 

 

[과제/JAVA] 학생부 프로그램 함수화 (+풀이 0701)

기존 실습 때 진행했던 학생부 프로그램 코드를 메소드를 활용한 방식으로 디벨롭 시켜보자.240701 풀이 추가  [실습][JAVA] 출석부 프로그램 만들기 (+풀이비교 0628추가)배열에 대해 공부하기 위

minibcake.tistory.com

 

[코드]

package class05;

import java.util.Random;
import java.util.Scanner;

class Student {
	int num; //학번
	String name; //이름
	int score; //점수
	char grade; //등급
	
	//신규학생 생성자
	Student(int num,String name){
		this(num,name,0);
	}
	//기존학생 생성자
	Student(int num,String name,int score){
		this.num=num;
		this.name=name;
		this.score=score;
		this.grade='C';
		if(this.score>=80) {
			this.grade='A';
		}
		else if(this.score>=60) {
			this.grade='B';
		}
	}
}

public class Test01 {
	
	//학생부에 값이 있는지 확인
	public boolean isEmpty(int cnt) {
		if(cnt <= 0) {
			System.out.println("보여줄 데이터가 없습니다!");
			return true;
		}
		return false;
	}

	//학생부에 저장할 공간이 있는지 확인
	public boolean isFull(int cnt, Student[] datas) {
		if(cnt >= datas.length) {
			System.out.println("저장가능한 공간이 없습니다.");
			return true;
		}
		return false;
	}

	//입력값으로 결정할 것인지 확인
	public boolean isCheckY(String answer) {
		Scanner sc=new Scanner(System.in);
		System.out.print(answer+"(으)로 하시겠습니까? (Y/N) >> ");
		String ans = sc.next();
		if(ans.equals("Y")||ans.equals("y")) {
			return true;
		}
		return false;
	}

	//학생부 안에 있는 이름인지 확인 후 있다면 인덱스번호 반환, 아니라면 -1 반환
	public int checkStuName(Student[] datas, int cnt, String name) {
		for(int i=0;i<cnt;i++) {
			if(name.equals(datas[i].name)) {
				return i;
			}
		}
		return -1;
	}
	
	//학생 정보 출력
	public void printStu(Student[] datas,int num) {
		System.out.println(datas[num].num+"번 "+datas[num].name+" "+datas[num].score+"점 "+datas[num].grade+"등급");
	}
	//학생 클래스 class에 배치하여 this.필드명으로 푸는 게 더 자연스러움
	
	//이름을 입력받고 해당값을 검증하여 이름을 반환
	public String insertName(Student[] datas, int cnt) {
		Scanner sc=new Scanner(System.in);
		String name;
		while(true) {
			System.out.print("이름 입력 >> ");
			name = sc.next();
			if(isCheckY(name)) {
				if(checkStuName(datas,cnt,name)<0) {
					break;
				}
				System.out.println(name+"(은)는 이미 등록된 학생입니다.");
			}
			System.out.println("다시 입력해주세요.");
		}
		return name;
	}
	
	//번오를 입력받고 해당값을 검증하여 해당하는 index를 반환
	public int selectNum(int PK, int cnt) {
		Scanner sc=new Scanner(System.in);
		int num;
		while(true) {
			System.out.print("번호 입력 >> ");
			num = sc.nextInt()-(PK-cnt);
			if(0<=num && num<cnt) {
				break;
			}
			System.out.println("해당 번호를 가진 학생이 존재하지 않습니다.");
			//지금은 삭제가 없으니 이런 방식이 가능하지만 삭제가 생기게 되면 불가함
			//flag를 사용하여 범위만큼 입력받고, 별도의 조건문으로 해당 검색결과가 있는지 없는지를 반환하여야함
			//pk있을 때는 index가 아닌 pk로 검색해야한다.
		}
		return num;
	}

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		Random rd = new Random(); 
		Test01 ts = new Test01();
		
		System.out.println("-=[학생부 프로그램]=-");
		
		int PK = 1001; //시스템에서 부여하는 PK값
		int cnt = 0; // 현재 배열에 저장된 데이터의 개수
		Student[] datas = new Student[3]; //저장할 학생부 공간

		//샘플데이터 확보
		datas[0] = new Student(PK++, "티모", 50);
		cnt++;

		while(true) {
			System.out.println("===== 메 뉴 =====");
			System.out.println("1. 학생추가");
			System.out.println("2. 전체목록출력");
			System.out.println("3. 번호검색");
			System.out.println("4. 이름검색");
			System.out.println("5. 1등출력");
			System.out.println("6. 등급검색");
			System.out.println("7. 재시험");
			System.out.println("0. 프로그램 종료");
			System.out.println("===============");
			System.out.print("메뉴입력 >> ");
			int menu=sc.nextInt();  
			
			if(menu==0) {
				System.out.println("프로그램을 종료합니다.");
				break;
			}//if(menu==0)
			
			else if(menu==1) {
				// 학생추가
				while(true) {
					System.out.println("--------[학생 추가]--------");
					System.out.println("1. 기존 학생 추가 (이름, 성적)");
					System.out.println("2. 신규 학생 추가 (이름)");
					System.out.println("0. 메뉴로 돌아가기");
					System.out.println("--------------------------");
					System.out.print("메뉴 입력 >> ");
					menu = sc.nextInt();
					
					if(menu==1) {
						//기존학생 이름, 성적
						if(ts.isFull(cnt,datas)) {
							break;
						}
						String name = ts.insertName(datas, cnt);
						int score;
						while(true) {
							System.out.print("성적 입력 >> ");
							score = sc.nextInt();
							if(ts.isCheckY(score+"")) {
								if(0<=score && score<=100) {
									break;
								}
								System.out.println("성적은 1부터 100점까지만 입력가능합니다.");
							}
							System.out.println("다시 입력해주세요.");
						}
						System.out.println(PK+"번 "+name+" 학생이 저장되었습니다.");
						datas[cnt++] = new Student(PK++, name, score);
						break;//메뉴로 돌아가기
					}//if(menu==1)
					else if(menu==2) {
						//신규학생 : 이름만 입력받음
						if(ts.isFull(cnt,datas)) {
							break;
						}
						String name = ts.insertName(datas, cnt);
						System.out.println(PK+"번 "+name+" 학생이 저장되었습니다.");
						datas[cnt++] = new Student(PK++, name);
						break;//메뉴로 돌아가기
					}//else if(menu==2)
					else if(menu==0) {
						break;
					}//else if(menu==0)
					else {
						System.out.println("잘못된 입력입니다!");
					}//menu else
				}//while
				
			}//else if(menu==1)
			else if(menu==2) {
				// selectAll
				if(ts.isEmpty(cnt)) {//보여줄 데이터가 없다면
					continue;
				}

				System.out.println("********************");
				for(int i=0;i<cnt;i++) {
					ts.printStu(datas,i);
				}
				System.out.println("********************");
			}//else if(menu==2)
			else if(menu==3) {
				// pk
				if(ts.isEmpty(cnt)) {//보여줄 데이터가 없다면
					continue;
				}
				int num = ts.selectNum(PK, cnt);
				System.out.println("********************");
				ts.printStu(datas,num);
				System.out.println("********************");
			}//else if(menu==3)
			else if(menu==4) {
				// 이름
				if(ts.isEmpty(cnt)) {//보여줄 데이터가 없다면
					continue;
				}
				
				String name;
				while(true) {
					System.out.print("이름 입력 >> ");
					name = sc.next();
					int index = ts.checkStuName(datas,cnt,name);
					if(index >= 0) {
						System.out.println("********************");
						ts.printStu(datas,index);
						System.out.println("********************");
						break;
					}
					else{
						System.out.println(name+" 학생이 존재하지 않습니다.");
					}
				}
			}//else if(menu==4)
			else if(menu==5) {
				// 1등
				if(ts.isEmpty(cnt)) {//보여줄 데이터가 없다면
					continue;
				}
				
				int pivot = datas[0].score;
				for(int i=1;i<cnt;i++) {
					if(pivot<datas[i].score) {
						pivot = datas[i].score;
					}
				}
				System.out.println("********************");
				System.out.println("우리 반 1등은?");
				System.out.println("--------------------");
				for(int i=0;i<cnt;i++) {
					if(pivot == datas[i].score) {
						ts.printStu(datas,i);
					}
				}
				System.out.println("********************");
			}//else if(menu==5)
			else if(menu==6) {
				// 등급
				if(ts.isEmpty(cnt)) {//보여줄 데이터가 없다면
					continue;
				}
				char grade;
				while(true) {
					System.out.print("등급 입력 >> ");
					grade = sc.next().charAt(0);
					if('A'<=grade && grade<='C'||'a'<=grade && grade<='c') {
						break;
					}
					System.out.println("등급은 A, B, C 등급이 있습니다.");
					System.out.println("올바른 등급을 입력해주세요.");
				}
				boolean flag = false;
				System.out.println("********************");
				for(int i=0;i<cnt;i++) {
					if(grade == datas[i].grade) {
						ts.printStu(datas,i);
						flag = true;
					}
				}
				if(!flag) {
					System.out.println(grade+"등급의 학생이 없습니다.");
				}
				System.out.println("********************");
				
			}//else if(menu==6)
			else if(menu==7) {
				// 재시험
				if(ts.isEmpty(cnt)) {//응시할 학생이 없다면
					continue;
				}
				//재시험 칠 학생의 번호
				System.out.println("--------[시험장]--------");
				System.out.println("재시험 응시할 학생 정보 입력");
				int num = ts.selectNum(PK, cnt);
				System.out.println(datas[num].name+" 학생이 시험 치는 중..");
				System.out.println("------------------------");
				int tmp = datas[num].score;
				int score = rd.nextInt(100)+1;
				datas[num] = new Student(datas[num].num,datas[num].name,score);
				if(tmp < score) {
					System.out.println(datas[num].name+" 학생의 점수가 "+(score - tmp)+"점 올랐습니다.");
				}
				else if(tmp > score) {
					System.out.println(datas[num].name+" 학생의 점수가 "+(tmp - score)+"점 떨어졌습니다.");
				}
				else {
					System.out.println(datas[num].name+" 학생의 점수는 변동이 없습니다.");
				}
				System.out.println("점수 : "+datas[num].score+", 등급 : "+datas[num].grade+"등급");
			}//else if(menu==7)
			else {
				System.out.println("잘못된 입력입니다!");
			}//else
		}//while

	}//main
}//class

 

[최종 풀이 전 아쉬웠던 점]

학생 정보 출력하는 메소드 위치가 다소 아쉬웠다.

학생 class안으로 옮겨 this.필드명 출력으로 진행하는 것이 더 알맞은 위치였다.

 

번호 검색을 index값을 구해서 풀어 pk를 활용하지 못해 아쉬웠다.

그리고 유효한 검색값이 나올 때까지 while(true)로 반복하였는데,

범위만 지정하고 검색 결과 없음으로 푸는게 더 좋은 코드였을 것 같다.

이미 메소드로 활용해버려서 수정이 애매해진 부분이 더 아쉬웠다.

 

[최종 풀이 후 아쉬웠던 점]

이름 검색 기능을 지난 번에 contains()로 맞게 해놓고, 이번에는 동일한 이름으로 검색되도록 넣었다...

디벨롭하면서 기능이 달라지진 않았는지 다시 확인하면서 진행해야겠다고 생각했다.

 

등급 부분도 풀이에서는 메뉴선택지를 제공하는 방식으로 했는데, 그 방식도 좋았을 것 같다. (키오스크처럼)

 

재시험 부분의 코드도 학생 class의 메서드로 작성하는게 더 알맞은 위치였을 것 같으며,

등급 나누는 부분도 메소드로 분리하여 update시에도 등급 메서드를 따로 사용할 수 있도록 하는 편이 좋았을 것 같다.

지금 작성한 코드는 동일한 값도 다시 저장하는 코드이기 때문이다.