250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 오버라이딩
- __annotations__
- 파이썬
- Database
- randrange()
- fnmatch
- choice()
- glob
- count()
- decode()
- node.js
- __sub__
- __len__
- shuffle()
- remove()
- locals()
- fileinput
- HTML
- __getitem__
- MySQL
- items()
- CSS
- shutil
- discard()
- MySqlDB
- zipfile
- View
- inplace()
- mro()
- JS
Archives
- Today
- Total
흰둥이는 코드를 짤 때 짖어 (왈!왈!왈!왈!왈!왈!왈!왈!왈!왈!왈!)
(파이썬, MySQL, 시험) 학생 성적 관리 프로그램 본문
728x90
반응형
시험문제
1. 학생을 등록한다.
2. 학생의 등록된 정보를 성적(평균)으로 내림차순으로 출력한다.
(단, 학생의 점수가 있을 경우 점수도 같이 출력한다. 등록된 학생의 전체 수와 해당 학생의 석차를 같이 출력한다. 동점인 경우 학번으로 내림차순으로 함)
3. 학생정보를 수정한다.
4. 학생정보를 삭제한다. 학생정보를 삭제할 경우 점수도 같이 삭제한다.
5. 학생정보를 검색한다.
(단, 학생의 점수가 있을 경우 점수도 같이 출력한다.)
6. 학생점수를 등록한다. 점수를 등록할 때 총점, 평균을 계산하여 같이 저장한다.
7. 학생점수를 수정한다. 점수를 수정할 경우 총점, 평균을 계산하여 같이 저장한다.
8. 학생점수를 삭제한다.
9. DAO, DTO를 작성한다.
10. View를 이용하여 데이터를 불러온다.
MySQL
use kdt;
# 학생 테이블
create table tb_student(
s_num int primary key,
s_name varchar(20) not null,
s_hp varchar(20) not null,
s_email varchar(50) not null,
s_address varchar(100) not null,
s_regdate datetime default now()
);
# 성적 테이블
create table tb_grade(
s_num int primary key,
g_java int default 0,
g_python int default 0,
g_c int default 0,
g_total int default 0,
g_avg float default 0,
g_regdate datetime default now(),
foreign key(s_num) references tb_student(s_num)
);
# 학생 뷰
create view vw_student_profile as select s.s_num, s.s_name, s.s_hp, s.s_email, s.s_address, g.g_java, g.g_python, g.g_c, g.g_total, g.g_avg from tb_student as s left outer join tb_grade as g on s.s_num=g.s_num order by g.g_avg desc, s.s_num desc;
DTO
# 학생 DTO
class StudentDTO:
def __init__(self, sNum, sName, sHp, sEmail, sAddress):
self.sNum = sNum
self.sName = sName
self.sHp = sHp
self.sEmail = sEmail
self.sAddress = sAddress
def setSNum(self, sNum):
self.sNum = sNum
def getSNum(self):
return self.sNum
def setSName(self, sName):
self.sName = sName
def getSName(self):
return self.sName
def setSHp(self, sHp):
self.sHp = sHp
def getSHp(self):
return self.sHp
def setSEmail(self, sEmail):
self.sEmail = sEmail
def getSEmail(self):
return self.sEmail
def setSAddress(self, sAddress):
self.sAddress = sAddress
def getSAddress(self):
return self.sAddress
# 성적 DTO
class GradeDTO:
def __init__(self, sNum, gJava, gPython, gC, gTotal, gAvg):
self.sNum = sNum
self.gJava = gJava
self.gPython = gPython
self.gC = gC
self.gTotal = gTotal
self.gAvg = gAvg
def setSNum(self, sNum):
self.sNum = sNum
def getSNum(self):
return self.sNum
def setGJava(self, gJava):
self.gJava = gJava
def getGJava(self):
return self.gJava
def setGPython(self, gPython):
self.gPython = gPython
def getGPython(self):
return self.gPython
def setGC(self, gC):
self.gC = gC
def getGC(self):
return self.gC
def setGTotal(self, gTotal):
self.gTotal = gTotal
def getGTotal(self):
return self.gTotal
def setGAvg(self, gAvg):
self.gAvg = gAvg
def getGAvg(self):
return self.gAvg
DAO
# MySQLdb 라이브러리
import MySQLdb
# 학생 DAO
class StudentDAO:
def __init__(self):
self.db = None
# MySQL 연결
def connect(self):
self.db = MySQLdb.connect('localhost', 'root', '1234', 'kdt')
# db 연결 해제
def disconnect(self):
self.db.close()
# 학생 전체 조회
def selectAll(self):
self.connect()
# 학생 정보를 딕셔너리로 가져온다.
cur = self.db.cursor(MySQLdb.cursors.DictCursor)
# 가져올 때 미리 성적순으로 정렬을 해둔 뷰를 select한다.
sql = "select s_num, s_name, s_hp, s_email, s_address, g_java, g_python, g_c, g_total, g_avg from vw_student_profile"
cur.execute(sql)
# 가져올 값을 딕셔너리 형태로 한 row씩 리스트에 담는다.
datas = []
while True:
data = cur.fetchone()
if data:
datas.append(data)
else:
break
self.disconnect()
return datas
# 학생 등록
def insert(self, sDto):
self.connect()
cur = self.db.cursor()
sql = "insert into tb_student (s_num, s_name, s_hp, s_email, s_address) values(%s, %s, %s, %s, %s)"
# sql에서 %s에 담을 값들을 학생DTO에서 getter를 사용하여 튜플형식으로 생성한다.
data = (sDto.getSNum(), sDto.getSName(), sDto.getSHp(), sDto.getSEmail(), sDto.getSAddress())
# 등록이 되었는지 여부를 result에 담아 반환한다.
result = cur.execute(sql, data)
self.db.commit()
self.disconnect()
return result
# 학생 수정
def update(self, column, content, sNum):
self.connect()
cur = self.db.cursor()
# 수정할 컬럼도 입력을 받아 문자열 연결 연산자로 붙인다.
sql = "update tb_student set " + column + " = %s where s_num = %s"
data = (content, sNum)
# 수정이 되었는지 여부를 result에 담아 반환한다.
result = cur.execute(sql, data)
self.db.commit()
self.disconnect()
return result
# 학생 삭제
def delete(self, sNum):
self.connect()
cur = self.db.cursor()
data = (sNum,)
# 외래키로 연결되어있는 row를 삭제하기 위해 먼저 성적 테이블에서 삭제를 진행한다.
sql = "delete from tb_grade where s_num = %s"
cur.execute(sql, data)
# 성적 테이블에서 삭제가 완료되면 이후에 학생 테이블에서 삭제를 진행한다.
sql = "delete from tb_student where s_num = %s"
# 삭제가 되었는지 여부를 result에 담아 반환한다.
result = cur.execute(sql, data)
self.db.commit()
self.disconnect()
return result
# 학생 검색
def select(self, column, content):
self.connect()
# 학생 정보를 딕셔너리로 가져온다.
cur = self.db.cursor(MySQLdb.cursors.DictCursor)
# 검색할 컬럼도 입력을 받아 문자열 연결 연산자로 붙인다. 이후 한번 순서로 정렬을 한다.
sql = "select s_num, s_name, s_hp, s_email, s_address, g_java, g_python, g_c, g_total, g_avg from vw_student_profile where " + column + " like %s order by s_num desc"
# like로 검색어가 포함되어있는 모든 row를 가져오기위해 '% %'를 연결 연산자로 붙인다.
data = ("%" + content + "%",)
cur.execute(sql, data)
# 가져올 값을 딕셔너리 형태로 한 row씩 리스트에 담는다.
datas = []
while True:
data = cur.fetchone()
if data:
datas.append(data)
else:
break
self.disconnect()
return datas
# 성적 DAO
class GradeDAO:
def __init__(self):
self.db = None
def connect(self):
self.db = MySQLdb.connect('localhost', 'root', '1234', 'kdt')
def disconnect(self):
self.db.close()
# 성적 등록
def insert(self, gDto):
self.connect()
cur = self.db.cursor()
sql = "insert into tb_grade (s_num, g_java, g_python, g_c, g_total, g_avg) values(%s, %s, %s, %s, %s, %s)"
# sql에서 %s에 담을 값들을 성적DTO에서 getter를 사용하여 튜플형식으로 생성한다.
data = (gDto.getSNum(), gDto.getGJava(), gDto.getGPython(), gDto.getGC(), gDto.getGTotal(), gDto.getGAvg())
# 등록이 되었는지 여부를 result에 담아 반환한다.
result = cur.execute(sql, data)
self.db.commit()
self.disconnect()
return result
# 성적 수정
def update(self, gDto):
self.connect()
cur = self.db.cursor()
sql = "update tb_grade set g_java = %s, g_python = %s, g_c = %s, g_total = %s, g_avg = %s where s_num = %s"
# sql에서 %s에 담을 값들을 성적DTO에서 getter를 사용하여 튜플형식으로 생성한다.
data = (gDto.getGJava(), gDto.getGPython(), gDto.getGC(), gDto.getGTotal(), gDto.getGAvg(), gDto.getSNum())
# 수정이 되었는지 여부를 result에 담아 반환한다.
result = cur.execute(sql, data)
self.db.commit()
self.disconnect()
return result
# 성적 삭제
def delete(self, sNum):
self.connect()
cur = self.db.cursor()
sql = "delete from tb_grade where s_num = %s"
data = (sNum,)
# 삭제가 되었는지 여부를 result에 담아 반환한다.
result = cur.execute(sql, data)
self.db.commit()
self.disconnect()
return result
Service
# 학생 Service
class StudentService:
# 학생 DAO를 생성자로 먼저 호출해준다.
def __init__(self):
self.sDao = StudentDAO()
# 학생 전체 조회
def showAll(self):
datas = self.sDao.selectAll()
# 이미 datas안에 등수 순서대로 담겨 있기 때문에 순서대로 등수를 적을 i값을 설정해준다.
i = 1
for data in datas:
# data안에 딕셔너리 구조로 되어있으므로 key값으로 value를 출력한다.
print(f"\n등수: {i} | 학번: {data['s_num']} | 이름: {data['s_name']} | 연락처: {data['s_hp']} | 이메일: {data['s_email']} | 주소: {data['s_address']}")
print(f"자바: {data['g_java']} | 파이썬: {data['g_python']} | C언어: {data['g_c']} | 총점: {data['g_total']} | 평균: {data['g_avg']}")
# 다음 사람의 등수를 +1 해준다.
i += 1
# 학생 등록
def create(self):
# 등록할 학생 정보를 입력 받는다.
sNum = int(input('학번을 입력하세요: '))
sName = input('이름을 입력하세요: ')
sHp = input('연락처를 입력하세요: ')
sEmail = input('이메일을 입력하세요: ')
sAddress = input('주소를 입력하세요: ')
# 입력받은 값으로 학생DTO를 생성한다.
sDto = StudentDTO(sNum, sName, sHp, sEmail, sAddress)
# 학번이 Primary key로 설정되어 있으므로 중복할 경우 예외처리로 잡아내어 화면에 실패했다고 출력해준다.
try:
self.sDao.insert(sDto)
print('학생이 등록되었습니다.')
except:
print('실패했습니다. 학번을 확인해주세요.')
# 학생 수정
def modify(self):
# 사용자가 수정할 항목을 숫자로 선택시 column명을 value로 반환해줄 딕셔너리를 생성한다.
columns = {1:'s_name', 2:'s_hp', 3:'s_email', 4:'s_address'}
# 수정할 학번과 항목 그리고 수정값을 입력받는다.
sNum = int(input('수정할 학생의 학번을 입력하세요: '))
columnNum = int(input('수정할 항목 1.학생이름 2.연락처 3. 이메일 4.주소'))
content = input('수정값을 입력하세요: ')
# 수정할 column을 딕셔너리 key값으로 value를 가져와 저장한다.
column = columns[columnNum]
# 수정이 정상적으로 완료되었는지 조건문으로 검사한다.
if self.sDao.update(column, content, sNum):
print('학생수정이 완료되었습니다.')
else:
print('실패했습니다. 학번을 확인해주세요.')
# 학생 삭제
def drop(self):
# 삭제할 학생의 학번을 입력한다.
sNum = int(input('삭제할 학생 학번을 입력하세요: '))
# 삭제가 정상적으로 완료되었는지 조건문으로 검사한다.
if self.sDao.delete(sNum):
print('학생삭제가 완료되었습니다.')
else:
print('실패했습니다. 학번을 확인해주세요.')
# 학생 검색
def show(self):
# 사용자가 검색할 항목을 숫자로 선택시 column명을 value로 반환해줄 딕셔너리를 생성한다.
columns = {1:'s_name', 2:'s_hp', 3:'s_email', 4:'s_address'}
# 검색할 항목과 검색어를 입력받는다.
columnNum = int(input('검색할 항목 1.학생이름 2.연락처 3. 이메일 4.주소'))
content = input('검색단어를 입력하세요: ')
# 검색할 column을 딕셔너리 key값으로 value를 가져와 저장한다.
column = columns[columnNum]
datas = self.sDao.select(column, content)
for data in datas:
# data안에 딕셔너리 구조로 되어있으므로 key값으로 value를 출력한다.
print(f"\n학번: {data['s_num']} | 이름: {data['s_name']} | 연락처: {data['s_hp']} | 이메일: {data['s_email']} | 주소: {data['s_address']}")
print(f"자바: {data['g_java']} | 파이썬: {data['g_python']} | C언어: {data['g_c']} | 총점: {data['g_total']} | 평균: {data['g_avg']}")
# 검색 결과가 없을경우를 알려주는 출력문이다.
if not datas:
print('검색결과가 없습니다.')
# 성적 Service
class GradeService:
# 성적 DAO를 생성자로 먼저 호출해준다.
def __init__(self):
self.gDao = GradeDAO()
# 성적 등록
def create(self):
# 등록할 성적을 입력 받는다.
sNum = int(input('학번을 입력하세요: '))
gJava = int(input('Java 점수를 입력하세요: '))
gPython = int(input('Python 점수를 입력하세요: '))
gC = int(input('C언어 점수를 입력하세요: '))
# 이후 총점과 평균값을 각각 연산하여 저장한다.
gTotal = gJava + gPython + gC
gAvg = gTotal / 3
# 입력받은 값으로 성적DTO를 생성한다.
gDto = GradeDTO(sNum, gJava, gPython, gC, gTotal, gAvg)
# 학번이 Primary key와 Foreign key로 설정되어 있으므로 중복할 경우와 학생테이블에 학번이 없는경우를 예외처리로 잡아내어 화면에 실패했다고 출력해준다.
try:
self.gDao.insert(gDto)
print('성적이 등록되었습니다.')
except:
print('실패했습니다. 학번을 확인해주세요.')
# 성적 수정
def modify(self):
# 수정할 성적을 입력 받는다.
sNum = int(input('수정할 학생의 학번을 입력하세요: '))
gJava = int(input('Java 점수를 입력하세요: '))
gPython = int(input('Python 점수를 입력하세요: '))
gC = int(input('C언어 점수를 입력하세요: '))
# 이후 총점과 평균값을 각각 연산하여 저장한다.
gTotal = gJava + gPython + gC
gAvg = gTotal / 3
# 입력받은 값으로 성적DTO를 생성한다.
gDto = GradeDTO(sNum, gJava, gPython, gC, gTotal, gAvg)
# 수정이 정상적으로 완료되었는지 조건문으로 검사한다.
if self.gDao.update(gDto):
print('성적이 수정되었습니다.')
else:
print('실패했습니다. 학번을 확인해주세요.')
# 성적 삭제
def drop(self):
# 삭제할 학생의 학번을 입력한다.
sNum = int(input('삭제할 성적의 학번을 입력하세요: '))
# 삭제가 정상적으로 완료되었는지 조건문으로 검사한다.
if self.gDao.delete(sNum):
print('성적이 삭제되었습니다.')
else:
print('실패했습니다. 학번을 확인해주세요.')
View
# 화면
class View:
# 먼저 학생 Service와 성적 Service를 생성자로 호출해준다.
def __init__(self):
self.sService = StudentService()
self.gService = GradeService()
# 화면 동작
def run(self):
# 프로그램이 멈추지 않도록 무한루프를 돌려준다.
while True:
# 사용자가 이용할 서비스를 입력 받는다.
menu = int(input('1.학생등록 2.전체학생출력 3.학생수정 4.학생삭제 5.학생검색 6.점수등록 7.점수수정 8.성적삭제 0.종료'))
# 학생 등록
if menu == 1:
self.sService.create()
# 학생 전체 조회
elif menu == 2:
self.sService.showAll()
# 학생 수정
elif menu == 3:
self.sService.modify()
# 학생 삭제
elif menu == 4:
self.sService.drop()
# 학생 검색
elif menu == 5:
self.sService.show()
# 성적 등록
elif menu == 6:
self.gService.create()
# 성적 수정
elif menu == 7:
self.gService.modify()
# 성적 삭제
elif menu == 8:
self.gService.drop()
# 프로그램 종료
elif menu == 0:
break
print()
프로그램 동작
start = View()
start.run()
728x90
반응형
'시험' 카테고리의 다른 글
(Node.js, MySQL, ORM) 학생 성적 API (0) | 2023.05.15 |
---|---|
(파이썬, 시험) 전화번호부 만들기 (0) | 2023.03.17 |
Comments