Good programmer 4 - 설계하고 테스트하기

agile(51)
Published in
#kr-dev
Words
442
Reading
2 min
Listen
Play
9y

이벤트 문제를 가지고 예를 들겠습니다.
문제는 "N 명의 리스트에서 랜덤으로 k명을 뽑아서 출력한다." 입니다.

저는 코드가 짧은 것을 좋아해서 파이선에서는 권하지 않는 1줄 코딩을 선호합니다.
왜냐하면 의미상으로 "1~m-1 range 에서 c 개를 sample 해서 sorted"
명확하기 때문입니다. 마치 영어의 복문을 읽는 것과 유사하며,
잘 이해가 되지 않는 다고 하더라도 의미를 알면 파라미터를 유추해 낼 수 있습니다.

from random import sample
(lambda m, c: sorted(sample(range(1,m+1), c)))(45, 6)

저렇게 짜면 날로먹는 것이 아니냐, 랜덤을 이용해서 소중히 정성스럽게 짜야하는것 아니냐?
날로먹는것이 맞는데, 날로먹어야 할 것은 날로 먹는 것이 정답입니다.
DIY (Do not repeat yourself)

제가 랜덤 라이브러리를 잘 몰랐을때 random 을 이용해서 짠 적이 있습니다.
시험때여서 1분이 아까웠지만, 직접 짜느라 5분여를 까먹었습니다.
끝나고 나서 shuffle, sample 과 같은 라이브러리 도구가 있다는 사실을 알고는 허무했습니다.
라이브러리를 써야 하는 이유는 사실 다른 곳에 있습니다. (DRY 로 얻을 수 있는 이익)
내가 만든 로직보다 많은 사람들이 고민해서 이미 만들어 놓은 것입니다.
더 이상 잘 짤 수 없습니다. 물론 테스트도 필요 없습니다. 믿고 쓰면 되지요.
새로운 라이브러리를 사용하는 경우라면 이리 저리 따져봐야합니다만,
shuffle 이나 sample 은 이미 오랜 시간 사용되어져 왔고 검증되었습니다.
지금 python 이나 java 에서 라이브러리 소스를 보십시오.

그럼 라이브러리를 모른다고 했을때, 어떻게 접근해야 하는지 알아 봅니다.

입출력에 따라서 흐름을 먼저 살펴봅니다.

(1. 입력) --> (2. N 에서 K 개를 뽑는다) --> (3. 출력)

두번째 함수의 꼴은 어떠한 형태가 되어야 할까요?

입력 : n, k
출력 : list

파이선이나 자바라면와 같이 list 를 쓸 수 있다면,

list random_select_from(n, k)



C 의 경우에는

int** random_select_from(int n, int k)



또는

void random_select(int n, int k, int *list)



첫번째 경우에는 리턴 되는 배열은 함수내에서 malloc 을 사용해서 리턴할 수 있습니다.
두번째는 그냥 호출부에서 list 의 크기를 k 개로 잡아서 호출하는 것입니다.
지금과 같은 경우에는 두번째 방법이 좀 더 편합니다. (** 는 거부감이 듭니다)

중요한 것은 언어에 따라서 함수의 꼴이 차이가 난다는 점이고,
C 는 그러한 면에서 유연성이 떨어집니다.

파이선 자바스크립트 루비 등의 언어는 기본적으로 리스트, 딕셔너리를 가지고 있습니다.
자바의 경우는 기본형은 아니지만 라이브러리에서 충분히 지원하니 사용법이 까다롭긴 해도 쓸만 합니다.

C 에서도 라이브러리를 쓰면 비슷하게 쓸 수 있습니만,
DRY (Do not repeat yourself : 있는 것을 또 만들지 말라)라는 말이 있지요.
인터넷 어디엔가 C 에서도 리스트와 같이 쓸 수 있도록 만든 라이브러리가 있을 겁니다. (반드시)

question1.jpg

함수의 테스트는 어떻게 하면 될까요? (유닛테스트)

list 의 모든 원소는 중복되지 않아야 하며, 갯수는 k개 (이하)여야 한다.
list 의 모든 원소는 n 보다 작거나 같아야 한다.
위 과정을 N 번 반복해서 N 번 다 통과하면 유닛테스트가 통과하는 것으로 한다.

파이선 unittest 나 자바 junit 등을 이용해서 테스트를 만들면
random_select_from 함수는 만들 수 있을 것 같습니다.

글이 좀 길어져서, 테스트와 리팩토링은 1회 더 진행하도록 하겠습니다.
감사합니다.

  1. 내가 관리할 수 있는 코드량은? https://steemit.com/kr-dev/@agile/good-programmer-1
  2. HOWTO be Professional https://steemit.com/kr-dev/@agile/good-programmer-2-howto-be-professional
  3. 최소화 하기 https://steemit.com/kr-dev/@agile/good-programmer-3
  4. 설계하고 테스트 하기
  5. 테스트와 리팩토링
Good programmer 4 - 설계하고 테스트하기 | Ecency