포스트(post)

20. 조건에 따라 다른 기능 실행하기 5 - (cond)

목표

조건문을 만들 수 있는 또 다른 함수인 (cond)를 사용 해 봅시다



switch

(if)함수는 조건이 인경우와 거짓인 경우 둘 중 하나인 경우에 사용하면 좋습니다. 만약 선택지가 다양한 상황이라면(cond)함수를 사용하는 것이 더 좋은 방법입니다.

condCONDition의 줄임말입니다. (cond)함수는 조건(경우의 수)가 여러가지일 때 사용하기에 적합한 함수입니다.

(cond)함수는 여러 조건과 그 조건을 만족할 때 실행할 코드의 묶음으로 이루어집니다. 다른 프로그램언어에서는 switch와 유사한 함수라고 볼 수 있습니다.

사용 형식은 다음과 같습니다

1
2
3
4
5
6
7
8
9
10
11
12
(cond
	(조건1
		조건1 만족할 경우 실행할 코드들
	)
	(조건2
		조건2 만족할 경우 실행할 코드들
	)
	...
	(조건n
		조건n 만족할 경우 실행할 코드들
	)
)

점수(score)에 따라서 학점(grade)을 결정하는 예를 들어보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(cond
	((>= score 90) ;1
		(setq grade "A")
	)
	((>= score 80) ;2
		(setq grade "B")
	)
	((>= score 70) ;3
		(setq grade "C")
	)
	((>= score 60) ;4
		(setq grade "D")
	)
	(T ;5
		(setq grade "F")
	)
)
  1. 점수가 90점 이상이면 grade변수에 "A"를 저장하고 (cond)함수를 종료합니다.
  2. 이 조건을 확인한 다는 것은, 1.의 조건에 해당하지 않아서 (cond)함수가 종료되지 않은 것이므로, 점수는 90점 미만입니다. 그 중에서 80점 이상이라면 grade변수에 "B"를 저장하고 (cond)함수를 종료합니다.
  3. 마찬가지로 80점 미만이면서 70점 이상인 경우에 grade변수에 "C"를 저장하고 (cond)함수를 종료합니다.
  4. 마찬가지로 70점 미만이면서 60점 이상인 경우에 grade변수에 "D"를 저장하고 (cond)함수를 종료합니다.
  5. 조건이 T이므로(nil이 아니므로) 위의 어느 경우에도 해당하지 않을 경우에 실행되며, grade변수에 "F"를 저장하고 (cond)함수를 종료합니다.

이처럼 (cond)함수는 위에부터 순서대로 조건을 확인하다가, 일치하는 조건을 만나면 해당하는 코드들을 실행후에 (cond)함수를 종료합니다. 만약 어느 조건도 만족하지 않을 때 아무것도 실행하고 싶지않다면, (cond)함수의 마지막에 조건을 T로 한 부분을 삭제하면 됩니다.

(cond)함수는 마지막으로 실행한 결과를 반환합니다. 따라서 이렇게 작성할 수도 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(setq grade
	(cond
		((>= score 90)
			"A"
		)
		((>= score 80)
			"B"
		)
		((>= score 70)
			"C"
		)
		((>= score 60)
			"D"
		)
		(T
			"F"
		)
	)
)
  • (cond)함수에서 조건을 만족하는 부분의 학점이 반환되며, 이 학점이 grade변수에 저장됩니다.



활용

(if)함수대신 (cond)함수 사용

지난번에 알아본 (getkword)의 예문은 다음과 같았습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(progn
	(initget "Apple Banana Cherry")
	(setq kword
		(getkword "\n과일 선택 - 사과(a), 바나나(b), 체리(c) : ")
	)
	(if (= kword "Apple")
		(setq kword "사과")
	)
	(if (= kword "Banana")
		(setq kword "바나나")
	)
	(if (= kword "Cherry")
		(setq kword "체리")
	)
	(if kword ;4
		(princ (strcat "\n선택하신 과일은 " kword "입니다"))
		(princ "\n과일을 선택하지 않았습니다")
	)
	(princ)
)

여기서 영어 키워드를 한글로 변경하는 부분은 (if)함수를 사용하기보다는 (cond)함수를 사용하는 것이 더 적절한 방법입니다. 수정하면 다음과 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(progn
	(initget "Apple Banana Cherry")
	(setq kword
		(getkword "\n과일 선택 - 사과(a), 바나나(b), 체리(c) : ")
	)
	(setq kword
		(cond
			((= kword "Apple") "사과")
			((= kword "Banana") "바나나")
			((= kword "Cherry") "체리")
		)
	)
	(if kword
		(princ (strcat "\n선택하신 과일은 " kword "입니다"))
		(princ "\n과일을 선택하지 않았습니다")
	)
	(princ)
)

어떤가요? 보기 좀 더 편하지 않나요? 이처럼 경우의 수가 다양한 경우에는 (cond)함수를 쓰는 것이 더 좋습니다.

선택한 키워드에 따라 다른 명령어 실행

이번에는 사용자가 선택한 키워드에 따라서 다른 명령어를 실행하도록 만들어 봅시다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(progn
	(initget "Circle Line Rectangle Pline")
	(setq kword
		(getkword "\n명령어 선택 - 원(c), 선(l), 사각형(r), 폴리선(p)")
	)
	(cond
		((= kword "Circle") (command "circle"))
		((= kword "Line") (command "line"))
		((= kword "Rectangle") (command "rectangle"))
		((= kword "Pline") (command "pline"))
	)
	(if (null kword) ;1
		(princ "\n명령어를 선택하지 않았습니다")
	)
	(princ)
)
  1. (null)함수는 인자가 nil이면 T를 반환하고, nil이 아니면 nil을 반환하는 함수입니다. (not)함수와 동일한 결과를 내므로, 문맥에 따라서 더 적절한 것을 사용하면 됩니다. 사용자가 아무 값도 입력하지 않아서 kwordnil인 경우에는 (cond)함수에서 어느것에도 해당하지 않으므로, 사용자에게 명령어를 선택하지 않았다는 메시지를 띄어주었습니다.

음, 생각해보니

이건 (cond)함수를 알려드리기에 좋은 예는 아니었던 것 같습니다. kword값과 명령어동일하다보니, 이건 (cond)함수를 사용하지 않고 kword를 직접 command안에 넣어도 되겠네요. 그러면 이렇게 변경할 수도 있겠습니다.

1
2
3
4
5
6
7
8
9
10
11
(progn
	(initget "Circle Line Rectangle Pline")
	(setq kword
		(getkword "\n명령어 선택 - 원(c), 선(l), 사각형(r), 폴리선(p)")
	)
	(if kword ;1
		(command kword)
		(princ "\n명령어를 선택하지 않았습니다")
	)
	(princ)
)
  1. 사용자가 키워드를 입력해서 kwordnil이 아니면 명령어를 실행하고, nil이면 메시지를 보여줍니다.

이렇게 코드를 최적화 해 가는 과정도 중요합니다 ^^;;

© IsaacGo. All rights reserved.