WeniVooks

검색

위니브 월드(선생님용)

자동화하자!

1. 챕터의 목표

함수: 함수를 정의하고 활용할 수 있습니다.

2. 스토리

라이캣의 생선 회사는 어느덧 위니브 월드 전체에서 가장 빠르게 성장하는 유통 회사가 되었습니다. 하지만 단순 반복 작업으로 지친 직원들의 불만이 늘어가고 있었습니다.

"자율성과 창의적 생각이 보장되고, 개인이 성장하면서, 각자 하는 일에 대한 명료한 목적과 동기부여를 줄 수는 없을까냥?"

라이캣은 각자 개인이 하고 있는 업무를 분석하여 직원들이 어떤 업무에 가장 많은 시간을 할애하는지 확인해 보았습니다. 가장 단순하고 반복적인 어업과 포장, 주문 확인과 배송 작업이었습니다.

다음 날, 라이캣은 회의에서 말했습니다.

"반복적인 작업을 대신하는 로봇을 만들자냥! 우리가 좀 더 창의적인 일에 집중하게 해줄 것이다냥!"

하지만 이미 불만이 가득 차 있는 직원들은 냉담한 반응이었습니다.

"누가 만드냥!? 대표가 만드냥!?"

"이미 만들어 왔다냥! 자, 각자 이 로봇을 가져가 설치하자냥!"

2.1 임무

자동으로 물고기를 잡고, 포장하여 배송해 주는 함수를 만드세요. 아래 코드에서 pass 부분을 지우고 기능을 작성하면 됩니다. 함수는 다음 기능을 해야 합니다.

  1. 물고기를 줍고 맨 위로 올라가서 배송 3개 완료 와 같이 말해야 합니다.
  2. 물고기는 몇 마리가 있는지, 어디에 있는지 알지 못합니다.
기본 코드
def delivery():
    pass
repeat(4, delivery)
def delivery():
    pass
repeat(4, delivery)
2.2 사용 코드

아래 코드들을 조합하여 문제를 풀어주세요.

mission_start()
mission_end()
move()
turn_left()
repeat(2, move)
pick()
put('fish-1')
print('hello world!')
front_is_clear()
left_is_clear()
right_is_clear()
mission_start()
mission_end()
move()
turn_left()
repeat(2, move)
pick()
put('fish-1')
print('hello world!')
front_is_clear()
left_is_clear()
right_is_clear()

3. 문제 풀이

3.1 함수

함수는 코드를 재활용하고 전체적인 코드 구조를 한눈에 파악하기 좋게 만들어줍니다. 아래 코드로 확인해 보도록 하겠습니다.

def hello(): # 함수 정의
    print('hello') # 함수 안 코드
    print('world')
 
hello() # 함수 호출
def hello(): # 함수 정의
    print('hello') # 함수 안 코드
    print('world')
 
hello() # 함수 호출

위와 같이 실행하면 파이썬은 함수 정의만 읽고 내려갑니다. 함수 안 코드를 읽지 않아요. 그리고 함수가 호출되면 다시 올라와서 함수 안에 코드를 읽고 작동시킵니다. 이렇게 사용하면 어디서나 ‘hello’와 ‘world’를 출력하고 싶을 때 hello()만 사용하면 됩니다.

간단하게 더하기를 하는 함수도 만들어 보도록 하겠습니다. 아래와 같이 실행하면 30이 나옵니다. return은 반환한다고 얘기하는데요. 해당 함수의 호출했던 자리에 return 값이 들어가게 됩니다. 10과 20이 각각 a와 b에 들어가고 a와 b를 더한 값이 30이니 a(10, 20)이 있던 자리에 30이 들어가는 것이죠.

def add(a, b): # 함수 정의
    return a + b # 함수 안 코드
 
add(10, 20) # 함수 호출
def add(a, b): # 함수 정의
    return a + b # 함수 안 코드
 
add(10, 20) # 함수 호출

아래 예제도 살펴보도록 하겠습니다.

def add(a, b): # 함수 정의
    return a + b # 함수 안 코드
 
print(add(10, 20) + add(30, 20) + 30)
def add(a, b): # 함수 정의
    return a + b # 함수 안 코드
 
print(add(10, 20) + add(30, 20) + 30)

add(10, 20)은 그 리턴 값인 30이, add(30, 20)은 그 리턴 값인 50이 들어가게 되어 110이 출력되게 될 텐데요. 아래 결과와 같습니다.

print(add(10, 20) + add(30, 20) + 30)
print(         30 +          50 + 30)
print(add(10, 20) + add(30, 20) + 30)
print(         30 +          50 + 30)

여기서 a와 b를 파라미터라고 하고, 10과 20처럼 실제 넣는 값을 아규먼트라고 합니다.


3.2 문제풀이
Before After
def delivery():
    pass
repeat(4, delivery)
def delivery():
    pass
repeat(4, delivery)

기본 코드만 보았을 때 함수를 정의해서 4번 반복하는 것으로 되어 있는데 동일한 행동을 5번 해야 하므로 아래처럼 5로 고쳐주도록 하겠습니다.

def delivery():
    pass
repeat(5, delivery)
def delivery():
    pass
repeat(5, delivery)

이제 동일한 행동을 만들어야 하는데요. 라이캣이 오른쪽으로 회전한 다음 아래 아이템이 있다면 모두 줍고 다시 뒤를 돌아 맨 위로 올라온 뒤 배송을 했다고 외쳐야 합니다. 이를 코드로 표현하면 아래와 같습니다. 함수 없이 일단 코드를 작성하도록 하겠습니다.

while not on_item():
    move()
while not on_item():
    move()

위 코드는 아래 아이템이 있을 때까지 앞으로 이동하는 코드입니다. on_item을 사용했습니다. 이 코드는 아래 아이템이 있으면 True를 없으면 False를 반환합니다.

while on_item():
    pick()
while on_item():
    pick()

위 코드는 아래 아이템이 있다면 계속해서 줍는 코드입니다. 이 2개의 코드를 이용하여 아이템이 있는 곳까지 이동하고 아래 있는 아이템을 모두 주울 수 있습니다.

이제 뒤를 돌아 맨 꼭대기까지 올라가야 하는데요. 아래처럼 작성할 수 있습니다.

repeat(2, turn_left)
while front_is_clear():
    move()
repeat(2, turn_left)
while front_is_clear():
    move()

위 코드는 뒤를 돌아 맨 꼭대기까지 올라가게 됩니다. front_is_clear()는 앞이 비어있으면 True, 비어있지 않으면 False를 반환합니다. 앞이 비어있는 동안만 움직이니 맨 꼭대기에 도달하게 됩니다.

이제 물고기를 몇 마리 주웠는지 출력하고 마릿수를 초기화하기만 하면 됩니다.

say(f'배송 {item()["fish-1"]}개 완료')
item()["fish-1"] = 0
say(f'배송 {item()["fish-1"]}개 완료')
item()["fish-1"] = 0

위와 같은 동작을 5번 하도록 함수로만 감싸주면 됩니다. 다만 맨 마지막에는 다음 칸으로 이동하지 않아야 하니 아래와 같은 코드를 추가합니다.

if front_is_clear():
    move()
if front_is_clear():
    move()

4. 정답 코드

초기화 후 한 번에 실행시킬 수 있는 정답 코드입니다.

mission_start()
 
def delivery():
    repeat(3, turn_left)
    while not on_item():
        move()
    while on_item():
        pick()
    repeat(2, turn_left)
    while front_is_clear():
        move()
    say(f'배송 {item()["fish-1"]}개 완료')
    item()["fish-1"] = 0
    repeat(3, turn_left)
    if front_is_clear():
        move()
repeat(5, delivery)
 
mission_end()
mission_start()
 
def delivery():
    repeat(3, turn_left)
    while not on_item():
        move()
    while on_item():
        pick()
    repeat(2, turn_left)
    while front_is_clear():
        move()
    say(f'배송 {item()["fish-1"]}개 완료')
    item()["fish-1"] = 0
    repeat(3, turn_left)
    if front_is_clear():
        move()
repeat(5, delivery)
 
mission_end()
2.8 창고 통합2.10 청소하고 정리합시다!