이번 시간에는 지난 Top-down Design (Link) 시간에 설명했던 신문 배달 상황을 그대로 코딩해보고자 한다.
우선은 아래에 일부 코드는 이미 주어진채로 시작하자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from cs1robots import * load_world( 'worlds/newspaper.wld' ) hubo = Robot( color = 'yellow' , beepers = 1 ) hubo.set_trace( 'blue' ) # function definitions def turn_around(): for i in range ( 2 ): hubo.turn_left() def turn_right(): for i in range ( 3 ): hubo.turn_left() |
목표는 다음 명령어들을 구현하는 것이다.
climb_up_four_stairs() climb_down_four_stairs()
지난 디자인 시간에서 썼던 흐름 그대로를 가져올 것이다.
다음 4줄을 실행시키면 신문 배달이 완료된다.
36 37 38 39 40 41 | # program starts climb_up_four_stairs() hubo.drop_beeper() turn_around() climb_down_four_stairs() |
구현에 앞서 팁이 있다면, 명령어의 시작 상황과 종료 상황을 주의 깊게 살펴보길 바란다.
1줄에 있는 climb_up_four_stairs()는 함수 이름에서도 알 수 있듯이 계단 1개를 4번 오르는 과정이 들어가 있다.
계단 1개를 오르는 과정도 세분화해야한다.
hubo가 한 칸을 움직이고 왼쪽으로 돌고 다시 움직이고 오른쪽으로 돌고 한 칸 더 움직이게 된다.
캡쳐 사진들을 통해 흐름을 보자.
계단 1개를 오르는 과정을 묶어서 하나의 새로운 명령어로 만들면 코딩의 반복을 줄일 수 있다.
17 18 19 20 21 22 | def one_stair(): hubo.move() hubo.turn_left() hubo.move() turn_right() hubo.move() |
무튼 이렇게 만든 명령어를 이용해 남은 계단 3개를 오르면 다음 사진의 상황이 된다.
24 25 26 | def four_stairs(): for i in range ( 4 ): one_stair() |
이쯤에서 아까 언급한 팁이 도움이 될 것이라 생각된다.
2줄의 hubo.drop_beeper() 이전에 hubo가 한 칸 움직일 필요가 있다.
따라서 climb_up_four_stairs()의 마지막 명령어는 hubo.move()가 될 것이다.
28 29 30 | def climb_up_four_stairs(): four_stairs() hubo.move() |
2줄은 그대로 쓰면 되고, 3줄도 크게 어렵지 않다. 그냥 뒤돌면 된다.
climb_down_four_stairs()는 1줄과 그 기능이 매우 유사하다.
다만, 한 칸 먼저 움직인 뒤, 4개의 계단을 내려와야한다는 차이가 있다.
사실상 climb_up_four_stairs()의 명령어들을 정확히 역순으로 돌리면 된다.
32 33 34 | def climb_down_four_stairs(): hubo.move() four_stairs() |
36 37 38 39 40 41 | # program starts climb_up_four_stairs() hubo.drop_beeper() turn_around() climb_down_four_stairs() |
이러고 끝난다.
-The End-
드 모르간의 법칙 (Link) 에 대해 알아볼 것이다.
중학교 1학년, 고등학교 1학년 집합과 명제 단원에서 줄창 다루는 탓에 이미 많은 학생들이 익숙하다고는 하는데 True, False로 바꿔놓으니까 모르겠다는 사람들이 있어서 글을 쓴다.
조건들의 검사 결과들을 나타내는 원소들을 모두 가진 전체 집합 U를 가정한다.
조건 p를 참으로 만드는 원소들을 포함한 집합을 집합 A로, 조건 q를 참으로 만드는 원소들을 포함한 집합을 집합 B로 가정한다.
참고로 p를 거짓으로 만드는 원소들은 ~p (not p) 조건을 참으로 만드는 것이므로 집합 A의 여집합으로 나타낼 수 있으며 B의 경우도 마찬가지다.
벤 다이어그램으로 드 모르간 법칙을 나타낸 사진이다. 색칠 공부한다고 생각하면서 하나씩 알아보면 금방 와닿을 것이다.
이를 True, False (bool 대수)로 표현해보자.
p? 라는 질문에 True 결과를 뱉는 원소들이 집합 A에 속하고, q? 라는 질문에 True 결과를 뱉는 원소들이 집합 B에 속한다.
반대로 p?에 False 인 원소들은 A의 여집합에 속할 것이고, q?에 False 인 원소들은 B의 여집합에 속할 것이다.
즉 not p?에 True 인 원소들이 A의 여집합으로, not q?에 True인 원소들이 B의 여집합으로 표현된다.
또한 p? and q? 에 True인 원소는 A∩B 에 속할 것이고, p? or q? 에 True인 원소는 A∪B 에 속할 것이다.
이제 복합적인 연산으로 not (p? or q?) 에 대해 알아보자.
p? or q?가 A∪B로 표현되는 것을 보았고 not 은 여집합으로 표현된다는 것을 보았다. 따라서 not (p? or q?)는 (A∪B)의 여집합에 해당된다. 위 사진에서 보면 A 여집합과 B 여집합의 교집합으로 표현되는 것도 알 수 있다. 이를 다시 옮겨적으면 not p? and not q? 가 된다.
not (p? and q?)에 대해서도 똑같다. not p? or not q? 로 쓸 수 있을 것이다.
부정의 부정, 즉 이중 부정의 경우로 표현하면 복잡한 식이 간단해지기도 한다.
이중 부정은 조건식의 결과에 전혀 영향을 주지 않는다. 참의 부정은 거짓이고 거짓의 부정은 참이므로 참의 부정의 부정은 참이고 거짓의 부정의 부정은 거짓이다. 따라서 검사 결과에 전혀 영향을 주지 않으므로 not not 연산을 이용해서 수식을 수정할 수 있을 것이다.
예를 들어, not p? and not q? 라는 검사가 있다고 하자. 이 검사에 not not 연산을 덧붙이면 not( not ( not p? and not q? ) ) 와 같다.
안쪽의 not을 드모르간 법칙을 사용해서 바꿔쓰면 not( (not( not p?)) or (not( not q?)) ) 가 된다.
not( not p?)는 p? 와 같고, not( not q?)는 q? 와 같다. 따라서 위 수식은 다시 not( p? and q?)로 바꿔쓸 수 있다. 되돌아보니 드모르간 법칙을 이용해 역으로 묶어내는 것과 동일한 결과가 나왔다.
주어진 숫자가 양수인가? 소수인가? 와 같이 True, False만을 내뱉는 어떤 질문들, 함수들(predicate)을 가지고 연산하다보면 not 연산들을 적절히 이용해서 수식을 간편히 바꿀 수 있는 경우가 많다.
혹은 제공되는 함수가 [양수인가?] 만을 검사할 수 있는데 음수들을 다루는 어떤 프로그램을 이용해야할 경우도 있다.
드 모르간 법칙을 이용해서 수식을 자유자재로 수정하다보면 논리 오류들을 찾아내기 쉬워질 수 있으니 익숙해지는 것이 좋다.
'Lecture (CS) > Introduction' 카테고리의 다른 글
#8. Environment Setting (0) | 2015.10.18 |
---|---|
#7. Short Circuit Evaluation (0) | 2015.10.14 |
#6. True or False (0) | 2015.10.14 |
#4. Instruction (0) | 2015.09.15 |
#3. Top-down Design (0) | 2015.09.13 |