학원 프로젝트 회고록

이혁진·2022년 9월 9일

학원 외주

목록 보기
2/5

1. 진행 과정
현재 프로젝트가 거의 끝나가고 있다. 이전에 일차원성 검증을 하기 위한 준비를 했었는데, 결국 값들이 적절하게 나와줘서 IRT를 적용하는 것이 문제가 없음을 확인하였다.

IRT를 적용해서 문항의 난이도에 비례한 시험을 만들고자 했으나, 측정된 난이도가 높은 수준에만 많이 분포해있었다. 원래대로라면 IRT의 능력추정기법을 활용해서 학생들의 능력 수준이 어디쯤인지 확인하고, 검사정보함수에서 해당 능력 수준에서의 작용을 최대화하도록 가중치를 조정해야 한다. 하지만 그것까지 하기에는 시간이 부족했기 때문에, 난이도 순위대로 문항의 배점을 설정하였다.

배점을 설정한 뒤에는 해당 데이터를 정리하고 분포를 조정하는 일을 했다. 우정이형이 내가 설정한 배점대로 학생들의 시험 점수를 확인했는데, 분포가 별로 깔끔하지 않았다. 원래대로라면 이 부분도 배점 설정 시에 고려했어야 하는 사항인데, 내가 하기에는 너무 벅찼던 것 같다. 하는 수 없이, 결과에 보정을 가하기로 했다. 단순히 더하고 곱하는 과정이라 어렵지는 않았으나, 원래 작성했던 코드가 잘 정돈되지 않은 탓에 생각보다 시간이 많이 걸렸다.

그리고 추가적으로 점수에 대한 통계 정보를 구하는 일도 있었다. 점수의 백분위, 등급, 레벨별 백분위, 유형별 레벨별 백분위 등이 그것이었다. 이게 특히 어려웠는데, 원래라면 로컬 데이터베이스에서 처리했으면 금방 끝날 것을 리스트로 해버리니 엄청 느리고 복잡했다. 전자의 경우 쿼리 4줄? 정도면 끝날 일을 후자로는 200줄 가까이 써가면서 처리했어야 했을 정도이다. 그래도 울며 겨자 먹기로 완성은 할 수 있었다.

저 일이 끝나고 나서도 새로운 통계를 구하는 작업을 해야 했다. 원래 우정이형이 해야할 일이지만, 우정이형이 너무 피곤해해서 그냥 대신해줬다. 이번 일을 할 때에는 지난번을 반면교사로 삼아 SQLITE 로 로컬 데이터베이스를 만들고, 통계 정보를 구했다. 데이터베이스를 만드는 데는 좀 시간이 걸렸지만, 그 뒤로는 너무 편했다. 몇백줄을 써야 할 것을 한두줄의 쿼리로 처리해버리니 너무너무 편했다.

이후에는 개발 속도가 빨라져서, 하루종일 일을 하지 않아도 되었다. 나가서 놀기도 하고 일 때문에 밀려있던 TIL도 썼었다. 그런 다음에 맡은 일을 했기 때문에 빨리 좀 하라고 우정이형에게 혼나기도 했다.

언제 우정이형이 나에게 일을 더 시킬지는 모르겠지만, 현재는 내 역할이 끝난 상태이다. 진즉에 배점하는 것을 하고 끝났어야 했는데, 우정이형의 교묘한 말솜씨에 속아서 지금까지 일을 하고 있었다. 며칠 밤을 새우며 너무 힘들었지만 꽤나 배운 것이 많았고, 나의 부족함을 다시금 깨닫게 해주는 프로젝트였다.

2. 배운 내용
2.1. 유닛 테스트
이전에 켄트 백의 테스트 주도 개발(TDD)이라는 책을 읽은 적이 있었다. 기억은 잘 안나지만 테스트 메소드 - 스텁 - 메소드 구현 - 리팩토링?의 과정의 반복만으로 몇 가지 예제를 구현하는 책이었다. 저자는 몇 십줄만으로 간단히 끝날 구현을 몇백줄을 늘여서 구현했다. 책에는 그렇게 하는 이유가 충분히 기술되어있었지만, 아직 경험이 모자라서인지 잘 이해되지 않았다. 아마 심리적 안정감, 테스트를 통해 짠 코드가 더 좋은 코드라서? 그랬던 것 같다.
이번에 프로젝트를 시작할 때, TDD를 적용해보자 생각했다. assertion과 책에서 나왔던 삼각측량법?같은 것이나 테스트를 테스트하는 코드를 작성한다던지 하는 자잘한 것들은 전부 생략하고, 몇 가지 원칙을 세워 테스트를 작성했다.

  1. 테스트 메소드는 기존 로직에 독립적일 것

말 그대로 테스트가 함수 인자나 전역 변수같은 것에 의존하지 않게 만들어서 그것들이 어떻게 변하든지 같은 결과를 내도록 한다는 것이다. 물론 어떤 것에도 의존하지 않을 수는 없지만, 최대한 그렇게 했다는 뜻이다.

  1. print로 결과 확인하기

원래라면 assertion으로 True, True 이런식으로 테스트의 통과를 나타내야 했지만, 처음이니까 그냥 print로 결과를 확인할 수 있게 했다.

  1. 테스트를 메소드보다 먼저 구현할 것

예를 들어 더하기 메소드를 만든다고 할 때, 보통 add(..){..} 이렇게 바로 구현하는데, 그것이 아니라 add_test(){...} 같은 테스트를 구현하고, 그 내용을 메소드로 캡슐화, 캡슐화된 메소드로 다시 테스트하는 세 단계를 거쳐 메소드를 완성하는 것이다.

이상의 원칙으로 매우 야매스러운 TDD를 적용해보았다. 확실히 해보니까 좋은 것 같긴 했다. 우선, 캡슐화를 나름 적절히, 자주 하게 된다. 덕분에 전체적 코드 수정 시에 관리할 포인트가 줄었고, 만든 코드를 여러 상황에 똑같이 적용해도 잘 돌아갔다. 전문 용어로 이를 응집도가 높아지고 결합도가 낮아진다고 하는 듯 하다. 다음으로는 내가 짠 코드를 까먹어도 된다는 점이다. 테스트를 쓰면서 이전에 스프링 강의에서 들었던 "테스트 없이도 프로그램 만들 수는 있는데, 큰 프로그램은 테스트 없이 절대 못만듭니다." 라는 말이 떠올랐다. 이게 정말 맞다. 몇 일을 개발을 할 때면, 과거에 내가 짠 코드의 내용을 잘 모른다. 그래서 지금 짜는 코드가 잘못되면, 오류를 찾아야 하는 지점이 굉장히 많다. 지금 짠 것은 당연하고, 이전에 짠 코드가 뽀록으로 돌아갔을 수도 있다. 이러면 새로운 코드를 짜는 시간보다 원래 코드를 이해하는 시간이 몇 배는 더 걸린다. 테스트는 이러한 상황에서 보증서나 길잡이 같은 느낌이다. 지금 에러가 떴는데 한달 전에 짰던 메소드가 의심되면, 대응되는 테스트 메소드를 호출하면 된다. 통과한다면 다른 부분이 잘못된 것이고, 통과하지 않는다면 그 메소드를 고치면 된다.

그럼에도 불구하고 내가 짠 코드가 엉망진창이 된 이유는 간단하다. 처음에는 테스트 과정을 잘 따르다가, 마지막 쯤 되니까 뒤찮아서 캡슐화를 안하고 테스트로 주요 로직을 돌렸기 때문이다. 그래서 마지막 테스트 메소드가 굉장히 길이가 길다. 다겸이한테 이 코드를 넘긴 상태인데, 적잖이 당황한 것 같다. 다음에는 좀 더 분발해보도록 하자

2.2. SQL 조인, 그룹, 서브쿼리

그룹 : https://youtu.be/rG8yQ7yKGTE

조인 : https://youtu.be/E-khvKjjVv4

서브쿼리 : https://youtu.be/lwmwlA2WhFc

추석이라 본가에 가면서 위에 세 영상을 보았다. 옛날에 SQL 공부할 때, 어려워서 대충 넘겼던 부분인데, 프로젝트에 도움이 될 것 같아서 봤다. 지하철에서 영상 보면서 예제를 머릿속으로 풀었다. 이전에 그 레벨별 유형별 점수 백분위? 기능 구현할 때 막 리스트로 난리를 쳤는데, 딱 그게 저거였다. 진짜 처음부터 디비 쓸 걸 그랬다. 한편으로는 지하철에서 저 영상 안봤으면 어땠을까 싶다. 아마 쿼리로 데이터 불러놓고 또 리스트로 똑같은 일을 했을 것이다. 저 영상 보고 연습한 덕분에 우정이형이 이번에 시킨 일을 쿼리 몇줄로 끝냈다.

select R.test_type, max(D.total_score), min(D.total_score)
from testData D inner join testType T on D.level == T.level inner join wideRank R on T.test_type == R.test_type
group by R.test_type

select D.no, D.total_score, R.sup_percentile, R.inf_percentile, R.sup_point, R.inf_point
from testData D inner join testType T on D.level == T.level inner join wideRank R on T.test_type == R.test_type
where D.total_score <= R.sup_point and R.inf_point < D.total_score
order by D.no

최적화? 같은 것도 안되어있고, 쓸데없이 길 수도 있지만 나름 3시간의 공부 끝에 완성한 것이다. 지금이야 이게 최선이지만, 나중에 쿼리 고수가 되었을 때 보면 어떨까 싶어서 올린다. 스프링 공부할 때 보니까 쿼리도 막 동적 쿼리라 했던가 이상한 것이 많았다. 문법만 안다고 전부가 아니라는 것을 깨달았다. 쿼리 쏘는게 데이터베이스시스템 중간고사에서 제일 중요하다고 했던 것 같은데, 이번 기회에 쿼리를 제대로 공부해보고 싶다.

profile
한양대학교 정보시스템학과 22학번 이혁진입니다. 컴퓨터 아키텍처와 시스템 등 다양한 주제로 공부한 내용을 기록합니다.

0개의 댓글