프로젝트

프로젝트(2)-시험문제

두설날 2024. 4. 4. 08:52

다음의 요구사항에 따라 제공된 필드를 참고하여 학생관리 프로그램의 시나리오를 자유롭게 만들고 프로그램을 작성하세요.

 
   
(학생 테이블 필드 : 학번, 이름, 연락처, 이메일, 주소, 등록된 날짜)

(성적 테이블 필드 : 학번, 자바점수, 파이썬점수, C언어점수, 등록된 날짜, 총점, 평균)

 

메뉴: 학생등록, 학생리스트, 학생정보수정, 학생정보삭제, 점수등록, 점수수정, 점수삭제, 프로그램종료

 

1. 학생을 등록한다. (10점)

2. 학생의 등록된 정보를 학번순 오름차순으로 출력한다. (15점)

(단, 성적테이블에 학생 점수가 등록되어 있는 경우 학과점수와, 총점, 평균을 모두 출력한다.)

3. 학생정보를 수정한다. (10점)

4. 학생정보를 삭제한다. 학생정보를 삭제할 경우 점수도 같이 삭제한다. (10점)

5. 학생정보를 검색한다. (10점)

6. 학생점수를 등록한다. 점수를 등록할 때 총점, 평균을 계산하여 같이 저장한다. (10점)

7. 학생점수를 수정한다. 점수를 수정할 경우 총점, 평균을 계산하여 같이 저장한다. (10점)

8. 학생점수를 삭제한다. (10점)

9. 클래스를 사용하여 코드를 작성한다. (15점)

 

* 아래 내용을 확인해주세요. (아래 내용이 작성되지 않을 경우 부분 감점)

1. 모든 키는 "학번" 필드를 사용. (학생테이블의 학번은 기본키로 등록, 점수테이블의 학번은 외래키로 등록한다.)

2. 학번 문자열이다.

3. 소스코드에는 각 프로그램 라인을 설명할 수 있는 주석문을 자세하게 작성
 
SQL코드

# 새 데이터베이스 만들기
create database school;
# database 선택
use school;

# tabale 만들기
# 학생 테이블 = student table
create table student(
	number varchar(30) primary key,	#학번
    name varchar(40),	#이름
    hp int,	#연락처
    email varchar(50),	#이메일
    address varchar(50),	#주소
    date int	#등록된 날짜
);
# 성적 테이블 = grade table
create table grade(
	number varchar(30),	#학번
    java_score int,	#자바점수
    python_score int,	#파이썬점수
    c_score int,	#C언어점수
    date int ,	#등록된날짜
    total_score int,	#총점
    avg_score int,	#평균 점수
    foreign key (number) references student (number) on delete cascade
);

# 테이블삭제 확인용
drop table student;
drop table grade;


# table확인
select * from student;
select * from grade;

파이썬코드

#라이브러리, 모듈 설치
!pip install mysqlclient
import MySQLdb

# 각 column의 생성자 객체만들기
# student table의 column class객체
class Student_constructor:
    def __init__(self, number, name, hp, email, address, date):
        self.number = number
        self.name = name
        self.hp = hp
        self.email = email
        self.address = address
        self.date = date

    def setNumber(self,number):
        self.number = number
    def getNumber(self):
        return self.number
        
    def setName(self,name):
        self.name = name
    def getName(self):
        return self.name
        
    def setHp(self,hp):
        self.hp = hp
    def getHp(self):
        return self.hp

    def setEmail(self,email):
        self.email = email
    def getEmail(self):
        return self.email

    def setAddress(self,address):
        self.address = address
    def getAddress(self):
        return self.address
        
    def setDate(self,date):
        self.date = date
    def getDate(self):
        return self.date

# grade table의 column class객체 
class Grade_constructor:
    def __init__(self, number, java_score, python_score, c_score, date, total_score, avg_score):
        self.number = number
        self.java_score = java_score
        self.python_score = python_score
        self.c_score = c_score
        self.date = date
        self.total_score = total_score
        self.avg_score = avg_score

    def setNumber(self,number):
        self.number = number
    def getNumber(self):
        return self.number

    def setJava_score(self,java_score):
        self.java_score = java_score
    def getJava_score(self):
        return self.java_score

    def setPython_score(self,python_score):
        self.python_score = python_score
    def getPython_score(self):
        return self.python_score

    def setC_score(self,c_score):
        self.c_score = c_score
    def getC_score(self):
        return self.c_score

    def setDate(self,date):
        self.date = date
    def getDate(self):
        return self.date

    def setTotal_score(self,total_score):
        self.total_score = total_score
    def getTotal_score(self):
        return self.total_score

    def setAvg_score(self,avg_score):
        self.avg_score = avg_score
    def getAvg_score(self):
        return self.avg_score
# 'school' database의 column안에 있는 value값 설정해주는 class객체 설정
# student table의 클래스 객체 먼저 설정
class Student_database:
    def __init__(self): #student table의 초기 value값 None 설정
        self.db1 = None 
    def connect(self): # self.db1에 database연결해주는 함수 설정
        self.db1=MySQLdb.connect('localhost','root','1234','school')
    def disconnect(self): #연결끊는 함수 설정
        self.db1.close()

# self.db1안에 value값 넣기-> 등록기능
    def insert(self, data1):
        self.connect()
        cur = self.db1.cursor()
        # value값을 넣는 쿼리문 설정
        sql = 'insert into student (number, name, hp, email, address, date) values (%s, %s, %s, %s, %s, %s)'
        # 생성자에 넣은 행의 value값 반환해서 getdata1 에 저장
        getdata1 = (data1.getNumber(), data1.getName(), data1.getHp(), data1.getEmail(), data1.getAddress(), data1.getDate())
        cur.execute(sql, getdata1)
        self.db1.commit() #sql안에 저장
        cur.close()
        self.disconnect()

# self.db1안에 넣은 value값을 검색하기
    def search(self, number): #number을 이용하여 검색
        self.connect()
        cur = self.db1.cursor(MySQLdb.cursors.DictCursor)
        # column이 number일때 해당되는 행 가져오는 쿼리문
        sql = "select number, name, hp, email, address, date from student where number like concat('%%',%s,'%%')"
        # number열 1개만 가져오기
        data1 = (number, )
        cur.execute(sql,data1)
        row = cur.fetchall()
        cur.close()
        self.disconnect()
        return row # row리턴값(number~date까지 행) 출력

# self.db1안에 넣은 value값을 수정하기
    def update(self, data1):
        self.connect()
        cur = self.db1.cursor()
        # where조건절 number일때 student table의 모든 column update(갱신)하기
        sql = 'update student set name=%s, hp=%s, email=%s, address=%s, date=%s where number=%s'
        # get메서드 반환값 가져와서 getdata1에 저장
        getdata1 = (data1.getName(), data1.getHp(), data1.getEmail(), data1.getAddress(), data1.getDate(), data1.getNumber())
        result1 = cur.execute(sql,getdata1) #커서 실행
        self.db1.commit() #실행한 수정한 결과값 db1에 저장
        if result1 > 0: 
            print('수정되었습니다')
        else:
            print('에러')
        cur.close()
        self.disconnect()

# self.db1안에 넣은 value값을 삭제하기
    def delete(self, number):
        self.connect()
        cur = self.db1.cursor()
        #sql 특정 행 삭제하기 쿼리문 설정
        sql = 'delete from student where number=%s'
        data1 = (number, )
        result1 = cur.execute(sql, data1)
        self.db1.commit()
        if result1 > 0:
            print('삭제되었습니다')   
        else:
            print('오류')
        cur.close()
        self.disconnect()

# self.db1안에서 특정 행만 출력하기
    def select(self):
        self.connect()
        cur = self.db1.cursor(MySQLdb.cursors.DictCursor) #튜플->딕셔너리로 value값의 자료형 변경
        sql = 'select number, name, hp, email, address, date from student order by number asc'
        cur.execute(sql)
        row = cur.fetchall()
        cur.close()
        self.disconnect()
        return row # row리턴값(number~date까지 행) 출력


# grade table의 클래스 객체 먼저 설정
class Grade_database:
    def __init__(self):
        self.db2 = None
    def connect(self): # self.db2에 database연결해주는 함수 설정
        self.db2=MySQLdb.connect('localhost','root','1234','school')
    def disconnect(self): #연결끊는 함수 설정
        self.db2.close()

# self.db2안에 value값 넣기, 등록기능
    def insert(self, data2):
        self.connect()
        cur = self.db2.cursor()
        # value값을 넣는 쿼리문 설정
        sql = 'insert into grade (number, java_score, python_score, c_score, date, total_score, avg_score) values (%s, %s, %s, %s, %s, %s, %s)'
        # 생성자에 넣은 행의 value값 반환해서 getdata2 에 저장
        getdata2 = (data2.getNumber(), data2.getJava_score(), data2.getPython_score(), data2.getC_score(), data2.getDate(), data2.getTotal_score(), data2.getAvg_score())
        cur.execute(sql, getdata2)
        self.db2.commit() #sql안에 저장
        cur.close()
        self.disconnect()

# self.db2안에 넣은 value값을 검색하기
    def search(self, number): #number을 이용하여 검색
        self.connect()
        cur = self.db2.cursor(MySQLdb.cursors.DictCursor)
        # column이 number일때 해당되는 행 가져오는 쿼리문
        sql = "select number, java_score, python_score, c_score, date, total_score, avg_score from grade where number like concat('%%',%s,'%%')"
        # number열 1개만 가져오기
        data2 = (number, )
        cur.execute(sql,data2)
        row = cur.fetchall()
        cur.close()
        self.disconnect()
        return row # row리턴값(number~date까지 행) 출력
        
# self.db2안에 넣은 value값을 수정하기
    def update(self, data2):
        self.connect()
        cur = self.db2.cursor()
        # where조건절 number일때 grade table의 모든 column update(갱신)하기
        sql = 'update grade set java_score=%s, python_score=%s, c_score=%s, date=%s, total_score=%s avg_score=%s where number=%s'
        # get메서드 반환값 가져와서 getdata2에 저장
        getdata2 = (data2.getJava_score(), data2.getPython_score(), data2.getC_score(), data2.getDate(), data2.getTotal_score(), data2.getAvg_score(), data2.getNumber())
        result2 = cur.execute(sql,getdata2) #커서 실행
        self.db2.commit() #실행한 수정한 결과값 db2에 저장
        if result1 > 0:
            print('수정되었습니다')
        else:
            print('에러')
        cur.close()
        self.disconnect()

# self.db2안에 넣은 value값을 삭제하기
    def delete(self, number):
        self.connect()
        cur = self.db2.cursor()
        #sql 특정 행 삭제하기 쿼리문 설정
        sql = 'delete from grade where number=%s'
        data2 = (number, )
        result2 = cur.execute(sql, data2)
        self.db2.commit()
        if result2 > 0:
            print('삭제되었습니다')
        else:
            print('오류')
        cur.close()
        self.disconnect()
# 1~8번까지 있는 메뉴 기능이 돌아가는 Service 설정
# Student table menu기능
class Student_service:
    def __init__(self):
        self.database1 = Student_database()
        #  self.database2 = Grade_database()
        
# 학생 table에 value값 등록시키는 함수
    def insert(self):
        number = input('학번을 입력하세요')
        name = input('이름을 입력하세요')
        hp = input('연락처를 입력하세요')
        email = input('이메일을 입력하세요')
        address = input('주소를 입력하세요')
        date = input('등록된 날짜를 입력하세요')
        data1 = Student_constructor(number, name, hp, email, address, date) #입력한 value값 data1을 전달인자로 전달
        self.database1.insert(data1) #Student_databse클래스안의 insert함수에 전달

# 등록된 학생 table의 value값 수정하는 함수
    def edit(self):
        number = input('수정할 학번을 입력하세요')
        data1 = self.database1.search(number) #database클래스객체에서 search함수 가져오기
        if not data1:
            print('수정할 학번이 없습니다')
        else:
            name = input('새로운 이름을 입력하세요')
            hp = input('새로운 연락처를 입력하세요')
            email = input('새로운 이메일을 입력하세요')
            address = input('새로운 주소를 입력하세요')
            date = input('새로운 등록된 날짜를 입력하세요')
            data1 = Student_constructor(number, name, hp, email, address, date)
            self.database1.update(data1) #database클래스객체에서 update함수 가져오기

# 등록된 학생 table의 value값 삭제하는 함수
    def delete(self):
        number = input('삭제할 학번을 입력하세요')
        data1 = self.database1.search(number)
        if not data1:
            print('삭제할 학번이 없습니다')
        else:
            self.database1.delete(number)
            # if data2 == None:
            #     self.database1.delete(number) #fk table이 없을 경우
            # else:
            #     self.database2.delete(number) #fk table 행값 먼저 삭제
            #     self.database1.delete(number) #pk table 행값 이후 삭제

# 등록된 학생 table을 확인하는 함수
    def print(self):
        datas = self.database1.select()
        print(datas)
        if datas:
            for i in datas:
                print(f"학번: {i['number']}, 이름: {i['name']}, 연락처: {i['hp']}, 이메일: {i['email']}, 주소: {i['address']}, 학번: {i['date']}")

# 등록된 학생 table중에서 검색한게 나오는 함수
    def search(self):
        number = input('검색하고싶은 학번을 입력하세요')
        datas = self.database1.select()
        if datas:
            for i in datas:
                print(f"학번: {i['number']}, 이름: {i['name']}, 연락처: {i['hp']}, 이메일: {i['email']}, 주소: {i['address']}, 학번: {i['date']}")



# Student table menu기능
class Grade_service:
    def __init__(self):
        self.database2 = Grade_database()

# 성적 table에 value값 등록시키는 함수
    def insert(self):
        number = input('학번을 입력하세요')
        java_score = input('자바점수를 입력하세요')
        python_score = input('파이썬점수를 입력하세요')
        c_score = input('C언어점수를 입력하세요')
        date = input('등록된 날짜를 입력하세요')
        total_score = input('총점 입력하세요')
        avg_score = input('평균을 입력하세요')
        data2 = Grade_constructor(number, java_score, python_score, c_score, date, total_score, avg_score)
        self.database2.insert(data2)

# 등록된 성적 table의 value값 수정하는 함수
    def edit(self):
        number = input('수정할 학번을 입력하세요')
        data2 = self.database2.search(number) #database클래스객체에서 search함수 가져오기
        if not data2:
            print('수정할 학번이 없습니다')
        else:
            java_score = input('새로운 자바점수를 입력하세요')
            python_score = input('새로운 파이썬점수를 입력하세요')
            c_score = input('새로운 C언어점수를 입력하세요')
            date = input('새로운 등록된 날짜를 입력하세요')
            total_score = input('새로운 총점을 입력하세요')
            avg_score = input('새로운 평균을 입력하세요')
            data2 = Grade_constructor(number, java_score, python_score, c_score, date, total_score, avg_score)
            self.database2.update(data2) #database클래스객체에서 update함수 가져오기

# 등록된 성적 table의 value값 삭제하는 함수
    def delete(self):
        number = input('삭제할 학번을 입력하세요')
        data2 = self.database2.search(number)
        if not data2:
            print('삭제할 학번이 없습니다')
        else:
            self.database2.delete(number)
# 1~8번 실행하는 menu 객체 생성
class Menu:
    def __init__(self):
        self.service1 = Student_service() #학생service 클래스객체는 service1 인스턴스로 설정 
        self.service2 = Grade_service() #성적service 클래스객체는 service2 인스턴스로 설정 
    def run(self):
        while True: #while True문으로 계속반복하는 반복문 사용
            try:
                menu = int(input('1.학생등록 2.학생리스트 3.학생정보수정 4.학생정보삭제 5.점수등록 6.점수수정 7.점수삭제 8.프로그램종료'))
                
                if menu == 1:
                    self.service1.insert()
                elif menu == 2:
                    try:
                        menu2 = int(input('1.등록된 학생리스트 확인 2.학생리스트 검색'))
                        if menu2 == 1:
                            self.service1.print()
                        elif menu2 ==2:
                            self.service1.search()
                    except Exception as e:
                        print(e)
                        print('다시 입력하세요')
                elif menu == 3:
                    self.service1.edit()
                elif menu == 4:
                    self.service1.delete()
                elif menu == 5:
                    self.service2.insert()
                elif menu == 6:
                    self.service2.edit()
                elif menu == 7:
                    self.service2.delete()
                elif menu == 8:
                    print('프로그램을 종료합니다')
                    break

            #1~8을 치지 않을 경우 다시 입력하는 것을 예외처리로 출력
            except Exception as e: #예외처리 alias e처리
                print(e) 
                print('다시 입력하세요')
                
start = Menu()
start.run()