본문 바로가기
파이썬/파이썬 완성

[파이썬] TIL6 : 카렐 로봇 프로그래밍을 이용한 함수의 이해 및 활용

by charlie-lyc 2021. 4. 19.
728x90
반응형

▣ 함수(Function)

앞서 For 반복문을 이용하여 len(), sum(), max(), min()의 핵심 기능을 구현하였듯이 필요한 기능을 사용자 스스로 정의해서 이용하는 것이 함수입니다. 모듈화와 마찬가지로 복잡한 연산과정을 간략화함으로써 고차원의 사고를 가능하게 하는 코딩의 핵심이라고 할 수 있습니다.  

 

1. 기본 구조

 

# Define Function

def my_function():
  # Do that
  # Then do it
  # Finally do this

 

예약 키워드인 'def', 사용할 '함수의 이름', 그리고 '():' 기호를 차례대로 작성하면 함수를 정의할 수 있습니다. 필요에 따라 괄호 안에는 인자로 매개변수를 입력할 수도 있습니다. 특히 들여 쓰기에 주의하기 바랍니다.

 

 

2. 함수 호출 및 예시

 

def my_function():
    print('hello')

# Call Function
my_function()

 

'함수의 이름'과 '()'기호를 차례대로 작성하여 함수를 호출할 수 있습니다.

 

🖥 코드 및 실행 결과

 


 

 카렐(Karel)

카렐 로봇에 대한 자세한 설명은 링크를 참조하기 바라며, 먼저 '리보그의 세계(Reeborg's World)'라는사이트에 접속하여 간단한 카렐 명령어를 이용하여 로봇 '리보그(Reeborg)'를 움직여 보겠습니다.

 

Reeborg's World

 

reeborg.ca

 

 

사이트에 처음 접속했을 때의 화면입니다.

 

상단의 메뉴에서 Alone  Python」을 선택하기 바랍니다.

 

처음으로 명령어 move()를 실행했을 때의 화면입니다. 명령을 실행하고자 할 때는 실행(▷; Run) 버튼을 누릅니다.

 

그리고 상단의 Reeborg's keyboard 메뉴를 클릭하면 Commands 탭에서 move() 이외의 다양한 명령어 함수들을 볼 수 있으며, Conditions 탭에서는 제어와 관련된 다양한 조건식 함수들을 볼수 있습니다. 일일이 타이핑하기 번거롭다면 클릭하여 이용할 수도 있습니다.

 

위의 명령어나 조건식에서 볼수 있듯이 카렐 로봇을 제어하는 모든 명령은 매개변수가 없는 함수입니다. 이번에는 turn_left()move()를 이용하여 로봇을 움직여 보겠습니다. 새로운 명령어를 실행하고 싶을 때는 화살표(Reload) 버튼을 누르고 한번 더 실행(▷) 버튼을 누르면 됩니다.

 

그리고 단계별로 실행하고 싶을 때는 단계별 실행(▷| ; Step)을 누르면 명령어가 한 개씩 실행되며, 실행을 잠시 지연하고 싶다면 일시 멈춤( || ; Pause) 버튼, 그리고 실행을 취소하고 싶을 때는 멈춤(□; Stop) 버튼을 사용합니다. 

이제 조작법을 대충 익혔으니 본격적으로 카렐 로봇을 이용하여 몇 가지 실습을 해 보겠습니다.

 


□ 함수를 이용하여 다른 카렐 명령어 만들기

실습을 시작하기 전에 먼저 필요한 명령어 한 가지를 함수로 정의하여 만들어 보겠습니다. 위의 Reeborg's keyboard 메뉴에서 Commands 탭 항목을 보면 기존의 명령어 중에 turn_left() 명령은 있는데 turn_right() 명령이 없습니다. 기존의 명령어를 이용하여 turn_rihgt() 기능을 함수로 정의하고 호출하여 실행해 봅시다.

 

※ 힌트 : 만약 '뒤돌아서기(turn_around)'를 함수로 정의하고 실행한다면 다음과 같을 것입니다.

def turn_around():
    turn_left()
    turn_left()
    
    
turn_around()

아래와 같이 작성하고 실행한 결과 오른쪽을 향하고 있던 로봇이 정면을 마주 바라보고 있는 상태로 바뀌었다면  turn_right() 명령어가 성공적으로 작성된 것입니다.

 


반응형

 

▣ Other Worlds

실습을 위해 아래의 그림과 같이 상단 메뉴에서 '다른 세계(Other Worlds)'를 선택하고 '리보그 소개(Go to Introduction Reeborg)'로 이동합니다. 

 

그런 다음에, 다시 상단 메뉴를 선택해서 보면 튜토리얼과 여러 과제들이 있습니다. 대부분 과제들의 목표는 카렐 로봇을 배터리가 방전되기 전에 목표지점에 도착시키는 것입니다.

 


□ 허들 1 실습

위의 그림에서 로봇이 이동해야 하는 경로를 살펴보면 파악할 수 있는 몇 가지 특징들이 있습니다.

1. 고정된 목표(Goal) 지점

2. 정해진 개수(6개)의 허들

3. 일정한 간격의 허들 배치

4. 일정한 높이의 허들

5. 목표지점에 이르지 못하거나 이동 중 벽에 부딪치면 실패

6. 목표 지점에 도착하면 성공

 

일단 힌트를 얻기 위해서 필요한 turn_right()을 정의해 두고,  몇 번의 시행착오를 거쳐 로봇을 움직이면서 이동시켜 보겠습니다.

 

위와 같이 작성하여 실행시켜보니 명령어들이 반복되는 일정한 패턴이 있다는 것을 파악할 수 있습니다. 그 패턴을 찾아내어 '오른쪽으로 돌아서기'와 마찬가지로 함수화하고, 그 함수를 이용하여 로봇을 목표지점에 도착시켜 봅시다.


 


□ 허들 1 실습 - 반복문 이용

위에서 코드를 성공적으로 작성했다면 이번에는 앞서 익힌 반복문을 이용해서 작성한 코드를 좀 더 간략화해 보겠습니다. 힌트는 허들 6개를 같은 패턴으로 넘으므로 6번 반복되는 명령문을 작성하는 것입니다. 

 

1. For 반복문

허들 1 과제의 코드를 For 반복문을 이용하여 작성하면 아래와 같습니다.

 

def turn_right():
    turn_left()
    turn_left()
    turn_left()


def jump():
    move()
    turn_left()
    move()
    turn_right()
    move()
    turn_right()
    move()
    turn_left()


for number_hurdle in range(6):
    jump()

 

2. While 반복문

반복의 횟수를 정하고 실행하는 것이 For 반복문이라면, While 반복문은 조건식을 만족하지 않을 때까지 계속 반복 실행하는 명령문입니다. 기본 구조는 아래와 같습니다. 

 

# While Loop

# Initializing <iterator>
while <condition>:
    # Do something repeatedly
    # <iterator> increment or decrement

 

허들 1 과제의 코드를 While 반복문을 이용하여 작성하면 아래와 같습니다.

 

def turn_right():
    turn_left()
    turn_left()
    turn_left()


def jump():
    move()
    turn_left()
    move()
    turn_right()
    move()
    turn_right()
    move()
    turn_left()


number_hurdle = 6
while number_hurdle > 0:
    jump()
    number_hurdle -= 1

 


□ 허들 2 실습

 

위의 그림에서 로봇이 이동해야 하는 경로를 살펴보면 파악할 수 있는 몇 가지 특징이 있습니다.

1. 목표(Goal) 지점 임의 설정

2. 정해지는 않은 개수의 허들

3. 일정한 간격의 허들 배치

4. 일정한 높이의 허들

5. 목표지점에 이르지 못하거나 이동 중 벽에 부딪치면 실패

6. 목표 지점에 도착하면 성공

 

힌트는 목표 지점이 고정되어 있지 않기 때문에 넘어야 할 허들의 개수가 정해지지 않았고 따라서 For 반복문이 아닌 While 반복문을 사용해야 합니다.

목표 지점에 도착했는지 아닌지를 확인하는 함수는 Reeborg's keyboard 메뉴의 Conditions 탭에 준비되어 있습니다. 카렐 로봇을 목표지점에 도착시켜 봅시다.



결국 while 반복문의 조건식은 로봇이 목표지점에 있는지 아닌지를 판명해 주는 역할을 해야하므로 미리 준비된 함수 중에서 at_goal()을 이용하여 작성되는데 아래와 같이 몇 가지의 다른 형식으로 작성될 수 있습니다.

 

# Different expressions of condition
    
# ex1    
while at_goal() is not True:
    jump()
    
# ex2  
while at_goal() != True:
    jump()

# ex3
while True:
    if at_goal():
        break
    jump()

 


□ 허들 3 실습

 

위의 그림에서 로봇이 이동해야 하는 경로를 살펴보면 파악할 수 있는 몇 가지 특징이 있습니다.

1. 고정된 목표(Goal) 지점

2. 정해지는 않은 개수의 허들

3. 불규칙적인 간격의 허들 배치

3. 일정한 높이의 허들

5. 목표지점에 이르지 못하거나 이동 중 벽에 부딪치면 실패

6. 목표 지점에 도착하면 성공

 

힌트는 허들의 간격이 일정하지 않기 때문에 기존의 jump() 함수를 수정해서 사용해야 합니다. 이전에는 일단 움직인 다음 허들을 넘는 패턴이었다면 이번에는 벽에 부딪치지 않기 위해서 먼저 앞에 벽이 있는지 없는지 확인한 다음에 허들을 넘어야 합니다.

앞에 벽이 있는지 없는지 확인하기 위해 필요한 함수는 Reeborg's keyboard 메뉴의 Conditions 탭에 준비되어 있습니다. 카렐 로봇을 목표지점에 도착시켜 봅시다.


 


□ 허들 4 실습

 

위의 그림에서 로봇이 이동해야 하는 경로를 살펴보면 파악할 수 있는 몇 가지 특징이 있습니다.

1. 고정된 목표(Goal) 지점

2. 정해지는 않은 개수의 허들

3. 불규칙적인 간격의 허들 배치

4. 다양한 높이의 허들

5. 목표지점에 이르지 못하거나 이동 중 벽에 부딪치면 실패

6. 목표 지점에 도착하면 성공

 

힌트는 허들의 간격과 높이가 일정하지 않기 때문에 마찬가지로 기존의 jump() 함수를 수정해서 사용해야 합니다. 이전에는 벽이 있는지 확인하고 허들을 넘는 패턴이었다면 이번에는 허들의 높이를 알 수 없으므로 로봇의 오른쪽 옆에 벽이 없을 때까지 계속 움직인 다음에 허들을 넘을 수 있습니다.

오른쪽에 벽이 있는지 없는지 확인하기 위해 필요한 함수는 Reeborg's keyboard 메뉴의 Conditions 탭에 준비되어 있습니다. 카렐 로봇을 목표지점에 도착시켜 봅시다.


이번 과제는 앞에서 다루었던 과제에 비해 힘들 수도 있습니다. 그러나 어려울수록 해결할 수 있는 방법 중 하나는 현상을 좀 더 세세한 부분으로 쪼개어 보고 다시 전체를 보는 것입니다. 로봇의 행동을 좀더 세분하여 제어하고 그 사이에 필요한 행동을 추가하여 문제를 해결해봅시다.

 


 

728x90
반응형

댓글