선택 제어문

이 장에서는 거북이(turtle), if 문에 대해서 알아본다.

거북이(turtle) 모듈 소개

거북이는 파이썬 표준 모듈 중의 하나로 도형 또는 패턴을 그리기 편리하고 초보자가 사용하기 쉽다.

거북이 프로그램 실행

간단한 거북이 프로그램을 실행해보자.

import turtle # turtle 모듈 사용

window = turtle.Screen() # 거북이 창 만들기

jiwon = turtle.Turtle() # 거북이 객체 생성해서 jiwon에게 할당

jiwon.forward(100) # 지원에게 앞으로 100 움직이라고 시킴
jiwon.left(90) # 지원에게 왼쪽으로 90도 회전하라고 시킴
jiwon.forward(50) # 그 상태에서 앞으로 50 이동

window.mainloop() # 거북이를 끝내기까지 기다림
  1. import turtle 문장을 이용하여 거북이(turtle)를 사용할 수 있게 불러 온다.
  2. window = turtle.Screen()을 이용하여 거북이창을 만든다.
  3. turtle.Turtle()를 이용하여 새로운 거북이를 만들어 이름을 지원(jiwon)이라고 짓는다.
  4. 지원 거북이에게 forward(거리)를 이용하여 거리만큼 앞으로 움직이라고 시킨다.
  5. left(각도) 각도 만큼 왼쪽으로 회전하라고 시킨다.
  6. 마지막 상태에서 다시 앞으로 50만큼 움직인다.
  7. window.mainloop() 메소드를 이용하여 사용자가 프로그램을 끝낼 때까지 기다린다.

거북이를 사용하기 위해서는 import turtle이라는 문장을 통하여 거북이를 사용할 수 있는 상태로 만들어야 한다. import는 “불러오다, 가져오다”라는 뜻으로 turtle이름을 갖고 있는 모듈을 불러오겠다는 뜻이다. 모듈은 특별한 용도로 사용될 함수들과 속성(attributes)들을 정의한 파일이다. 자세한 내용은 나중에 설명할 모듈부분에서 다루게 된다. window = turtle.Screen()Screen()이란 함수를 이용하여 거북이가 활동할 창을 하나 만들어 window변수에 할당하라는 뜻이다. turtle.Turtle()이란 turtle 모듈 안에 정의된 Turtle() 이란 함수를 실행한다는 뜻으로 turtle.Turtle이란 객체를 반환한다. 아무튼 거북이를 만들어서 반환한다. 이 반환된 거북이를 jiwon = turtle.Turtle()를 이용해서 지원이란 변수 이름에 할당한 것이다. 거북이에게 주어진 기능(함수)들을 이용해서 거북이를 조정할 수 있게 한다. 여기서는 간단하게 forward(), left() 메소드만을 이용했지만 그 외에도 선의 굵기, 색깔 및 거북이 이동 등의 다양한 기능들이 있다. 거북이에 대한 기능들을 사용하려면 지원(jiwon) 거북이에게 명령을 내려야 한다. 즉, jiwon.명령함수()와 같이 거북이 이름(jiwon) 바로 뒤에 점(.)을 찍고 명령함수(forward(), left())들을 사용해야 한다. 거북이가 가지고 있는 모든 기능들에 대해서 알려면 거북이 매뉴얼 페이지 https://docs.python.org/3.6/library/turtle.html를 확인해본다.

거북이 창 정중앙의 좌표는 (0,0)이고 수학에서 사용하는 좌표계를 따른다. 거북이 창이 실행이 되면 거북이가 처음 위치하는 좌표는 (0,0)이고 방향은 오른쪽(동쪽)을 향하고 있다. 거북이 방향은 육십분법 각도를 사용하며 현재 거북이가 향하고 있는 방향을 기준으로 left(각도) 메소드를 이용하여 왼쪽(시계반대 방향)으로 주어진 각도만큼 회전하거나 right(각도) 메소드를 이용하여 오른쪽(시계방향)으로 주어진 각도만큼 회전한다. forward(거리) 메소드는 거북이가 향하고 있는 방향으로 주어진 거리만큼 움직이고 backward(거리) 메소드는 현위치에서 뒤쪽으로 주어진 거리만큼 움직인다. 이 때 방향은 변하지 않는다. 선을 그리지 않고 움직이려면 penup() 메소드를 이용하면 되고 다시 선을 그리고 싶으면 pendown() 메소드를 이용하면 된다.

거북이 모듈은 창(Screen)과 거북이(Turtle)로 구분해서 명령을 내릴 수 있다. 창과 관련해서는 창 제목(title), 창의 배경색(bgcolor), 창 끝내기(mainloop)등에 관련된 기능을 담당하고 있고 거북이는 그림 그리는 활동에 관련된 기능들, 앞으로 가기(forward), 뒤로 가기(backward), 연필 두께(pensize), 연필 색(pencolor), 거북이 방향(left, right)등이 있다.

직접하기

  • 거북이를 이용하여 가로 길이가 100, 세로의 길이가 300인 직사각형을 만들자.

  • 거북이를 이용하여 한 변의 길이가 200인 정삼각형을 만들자.

  • 거북이를 이용하여 반지름이 100인 원을 만들자.(turtle.circle(반지름) 메소드를 이용하자)

  • 거북이를 이용하여 같은 점에서 접하는 반지름 50, 100, 150인 원들을 만들자.

거북이 설정 변경

import turtle

window = turtle.Screen() # 창 만들기

window.bgcolor("lightgreen") # 창 배경색 설정
window.title("지수 안녕!") # 창 제목 설정

jisoo = turtle.Turtle() # 새로운 거북이 만들기
jisoo.color("blue") # 지수 거북이 펜색깔 변경
jisoo.pensize(3) # 지수 거북이 펜굵기  변경

jisoo.forward(50)
jisoo.left(120)
jisoo.forward(50)

window.mainloop()
  • bgcolor(색)을 이용하여 거북이 창의 배경색을 변경한다. 색깔 이름은 https://www.tcl.tk/man/tcl8.6/TkCmd/colors.htm 사이트를 참조한다.
  • title(제목)을 이용하여 창의 제목을 설정할 수 있다.
  • color(색)을 이용하여 거북이 연필 색깔을 변경한다. 거북이는 연필(pen)이라고 부른다.
  • pensize(두께)를 이용하여 연필의 두께를 변경한다.

직접하기

  • (100, 100) 위치로 이동하여 거기서 반지름이 100인 원을 그려보자. 지정된 좌표 (x,y)로 이동하는 함수는 goto(x,y)를 이용하면 된다.
  • 위의 문제에서 (100, 100)으로 이동할 때 선을 그리지 않고 이동해서 원을 그려보자. penup(), pendown()함수를 이용하면 된다.
  • 거북이를 이용하여 오륜기를 그려보자.

여러 마리의 거북이들

import turtle

window = turtle.Screen()
window.bgcolor("lightgreen")
window.title("지원 & 지수")

jiwon = turtle.Turtle() # 지원 거북이 만들기
jiwon.color("hotpink") # 지원 거북이 색깔
jiwon.pensize(3) # 지원 거북이 굵기

jisoo = turtle.Turtle() # 지수 거북이 만들기

jiwon.forward(80) # 지원 거북이 삼각형 만들기
jiwon.left(120)
jiwon.forward(80)
jiwon.left(120)
jiwon.forward(80)
jiwon.left(120) # 삼각형 완성

jiwon.right(180) # 지원 거북이 반대 방향으로 회전
jiwon.forward(80) # 80만큼 이동
jiwon.write("지원") # 이름 쓰기

jisoo.forward(50) # 지수 그리기
jisoo.left(90)
jisoo.forward(50)
jisoo.left(90)
jisoo.forward(50)
jisoo.right(90)
jisoo.forward(50)
jisoo.write("지수") # 지수 이름 쓰기

window.mainloop()

if 문

우리는 매일 선택을 하면서 살아간다. 오늘 점심은 무엇을 먹을까? 이번 주말에는 무얼하지? 선택의 순간 우리는 나름의 기준을 세워서 결정한다. 점심을 어떤 것을 먹을까는 그 때의 날씨와 분위기에 의해 결정될 수도 있다. 결정이 나면 그 다음은 행동에 옮긴다. 이렇듯 의사결정은 두 단계로 이루어진다. 먼저 나름의 기준을 갖고 어떤 것을 판단을 하고 다음으로 그것을 실행으로 옮기는 것이다.

컴퓨터에서도 의사결정은 마찬가지로 두 단계로 이루어 진다. 파이썬에서는 if 문을 이용해 결정을 한다. if 뒤에 참, 거짓을 판별할 수 있는 식이와서 참이면 원하는 코드를 실행시키는 것이다. if문 문법은 다음과 같다.

if <참, 거짓을 판별할 수 있는 식>:
    참일때 실행되는 구역
    들여쓰기 공간이 같으면 같은 구역으로 간주한다.

참일 때 실행되는 구역은 if 문 아랫줄부터 같은 양의 들여쓰기로 구분을 한다. 예를 들어 만 19세 미만이면 선거권이 없다는 것을 알리기 위해서 다음과 같이 if 문을 이용해 판단을 하고 결과를 알려줄 수 있다.

if 나이 < 19:
    print("선거권이 없습니다.")

관계 연산자

관계 연산자를 표로 나타내면 다음과 같다.

연산자 설명 예제
a == b ab가 같은면 참 if (나이 == 19)
a != b ab가 같지 않으면 참 if (점수 != 90)
a > b ab보다 크면 참 if (사람수 > 50)
a < b ab보다 작으면 참 if (가격 < 25)
a >= b ab보다 크거나 같으면 참 if (합 >= 50)
a <= b ab보다 작거나 같으면 참 if (값 <= 30)

직접하기

  • 다음 if 문 문법이 맞는지 틀린지를 말해보시오.
if (x > 4)
if ㄱ == 2
if (y =< 4)
if (y = 5)
if (3 <= a)
if (1 - 1)
if ((1 - 1) <= 0)
if (이름 == "주완")
  • 다음 실행 결과를 말해보시오.
x = 2

if x > 3:
    print("이 숫자는")
print("3보다 크다.")

pass 문

각 구역에는 적어도 하나의 문장이 존재해야 한다.

if True:
    pass
else:
    pass

코드가 아직 완성되지 않았을 때 실행되지 않는 문장을 나타내는 pass 예약어를 사용하면 편리하다. pass는 아무것도 실행되지 않으면서 문장이 존재하는 것을 나타낸다.

else 절

실내 온도가 24도를 넘어가면 에어컨을 켜고 그렇지 않으면 꺼지게 할 필요가 있을 때 조건문을 사용할 수 있다. 알람을 맞춘 시간이 되면 알람이 울리게 하고 싶을 때도 조건문을 사용할 수 있다. 조건문은 주어진 조건이 참이면 주어진 구역이 실행되고 그렇지 않으면 다른 구역이 실행될 수 있게 하는 문장이다. 예를 들면,

if x % 2 == 0:
    print("{}는 짝수이다.".format(x)
else:
    print("{}는 홀수이다.".format(x)

위 문장이 실행되기 위해서는 x 변수에 정수값이 먼저 정의되어 있어야 한다. if문장의 사용법은 if 예약어 뒤에 참, 거짓을 판별할 수 있는 문장이 나오고 이어서 콜론 :이 나온다. 새로운 줄부터는 if 조건문이 참일 때 실행되는 구역이 시작된다. 이 구역은 들여쓰기를 시작하면서 시작되고 들여쓰기가 끝나는 첫번째 문장 앞에서 구역이 끝난다. 조건문이 참이면 구역에 있는 문장들이 차례로 실행이 되고, 거짓이면 else 절이 실행이 된다. else 절은 if 조건문이 거짓일 때 실행되는 부분으로 else에 이어서 콜론 :을 입력하고 구역이 시작된다. 마찬가지로 들여쓰기로 같은 구역임을 나타낸다.

if <, 거짓을 판별할  있는 조건 수식>:
    참일때 실행되는 구역
    들여쓰기 공간이 같으면 같은 구역으로 간주한다.
    ...
else:
    거짓일  실행되는 구역
    마찬가지로 들여쓰기로 같은 구역임을 나타낸다.

if 문장에서 else 절이 없이 사용할 수 있다. if 조건문장이 참이면 if 절이 실행되고 거짓이면 if 문장 다음이 차례대로 실행된다.

x = -21

if x < 0:
    print("음수", x, "는 여기서 사용할 수 없습니다.")
    x = 21
    print("대신에", x, "로 대체하겠습니다.")
print(x, "의 제곱근은", x ** 0.5, "입니다.")

직접하기

  • 15세 이상만 볼 수 있는 영화가 있다고 하자. 사용자의 나이를 물어봐서 영화를 볼 수 있는지 없는지를 출력하는 프로그램을 작성하자.

  • 다음 코드를 더 간단히 고쳐보시오.

    • 가)

      if bool(a) == True:
      print("a is true")
      
    • 나)

      if x > 50:
      b += 1
      a = 5
      else:
      b -= 1
      a = 5
      

거북이를 이용하여 입력받은 수가 양수이면 왼쪽으로 100만큼, 그렇지 않으면 오른쪽으로 100만큼 진행하는 프로그램을 만들어 보자.

import turtle

jisoo = turtle.Turtle() # jisoo 거북이 만들기
jisoo.shape('turtle') # 거북이 모양 변경

x = turtle.numinput("좌, 우회전", "숫자를 입력하시오:") # 팝업창을 이용하여 숫자를 입력받는다.
if x > 0:
    jisoo.left(90) # 양수이면 왼쪽으로 회전
    jisoo.forward(100) # 100만큼 거북이 움직이기
else:
    jisoo.right(90) # 양수가 아니면 오른쪽으로 회전
    jisoo.forward(100) # 100만큼 거북이 움직이기

turtle.mainloop()

jisoo = turtle.Turtle() 거북이 객체를 만들어 jisoo라는 이름을 할당한다. shape(name)을 통하여 거북이 모양을 변경할 수 있다. 인자 name은 거북이 모양 이름이 올 수 있고 arrow, turtle, circle, square, triangle, classic등이 있다. turtle.numinput(title, prompt)는 팝업창을 띄워 숫자를 입력받을 수 있게 한다. 첫번째 인자는 팝업창의 제목을 설정하고 두번째 인자는 메시지를 설정한다. 입력받은 값을 x에 할당한다. if 문장을 이용하여 x가 양수이면 왼쪽으로 90도 회전하고 100만큼 이동한다. 그렇지 않으면 오른쪽으로 90도 회전하고 100만큼 이동한다.

직접하기

  • 위 문제에서 펜 두께는 3, 펜 색깔은 왼쪽은 빨간색, 그렇지 않으면 파란색으로 움직이는 프로그램을 만드시오. 펜색깔을 바꾸려면 jisoo.color("color_name") 메소드를 이용하면 된다. color_namered, blue를 사용하면 된다.

if - elif 절

조건을 판단할 때, 3가지 이상으로 분류해야 할 필요가 있을 경우가 있다. 가령 숫자 x가 음수인가 아니면 0인가 아니면 양수인가를 판단하고 싶을 때가 있을 것이다. 이럴 때는 다음과 같은 문장을 이용한다.

if <판별 수식1>:
    구역1
elif <판별 수식2>:
    구역2
else:
    구역3

순서도로 표현하면 다음과 같다.

양수, 음수, 0을 판별하는 코드는 다음과 같다.

if x < 0:
    print(x, "는 음수입니다.")
elif x > 0:
    print(x, "는 양수입니다.")
else:
    print(x, "는 영(0)입니다.")

if 조건문이 참이면 if 절을 실행한 후 if 문장을 끝내고 그렇지 않고 거짓이면 바로 밑에 있는 elif 절의 조건문을 판단해서 참이면 elif 절을 실행한 후 끝내고 elif 조건문이 거짓이면 else 절을 실행한 후 if 문장을 끝낸다. elif는 else if의 준임말이며 elif 대신 사용할 수는 없다.

직접하기

  • 거북이를 이용하여 사용자로부터 숫자를 입력받아 양수이면 왼쪽, 0이면 직진, 음수이면 오른쪽으로 회전하면서 100만큼 움직이는 프로그램을 만드시오.
  • 거북이를 이용하여 사용자로부터 0부터 90까지 숫자를 입력받아 30보다 작거나 같으면 30도, 30보다 크고 60보다 작거나 같으면 60도, 60보다 크고 90보다 작거나 같으면 90도 회전하고 각각 100만큼 움직이는 프로그램을 만드시오.

중첩 if문

if문 안에 if문을 중첩으로 사용할 수 있다. 위의 양, 음, 0을 판별하는 예제는 다음과 같이 바꿀 수 있다.

if x < 0:
    print(x, "는 음수입니다.")
else:
    if x > 0:
        print(x, "는 양수입니다.")
    else:
        print(x, "는 영(0)입니다.")

else 절 안에서 if문을 다시 사용할 수 있다. 물론 안에 있는 if문에서 다시 if문을 사용할 수 있다. 중첩문을 사용하면 들여쓰기때문에 한 눈에 알아보기는 편하지만 논리를 이해하는데는 어려울 수가 있다. 논리 연산자를 이용하면 중첩문을 사용하는 것보다 간단하게 표현할 수 있다. 다음 중첩문은 논리 연산자를 이용하면 하나의 if문으로 표현할 수 있다.

if 0 < x: # x 는 정수
    if x < 10:
        print("x는 한자리 양의 정수이다.")

위 식에서 if문을 동시에 만족해야 하므로 논리 연산자 and를 이용하여 다음과 같이 바꿀 수 있다.

if 0 < x and x < 10:
    print("x는 한자리 양의 정수이다.")

더 간단하게 다음과 같이 쓸 수 있다.

if 0 < x < 10:
    print("x는 한자리 양의 정수이다.")

논리 연산자

논리 연산자를 표로 나타내면 다음과 같다.

연산자 설명 예제
== 같다 if (나이 == 19)
!= 같지 않다 if (점수 != 90)
> 크다 if (사람수 > 50)
< 작다 if (가격 < 25)
>= 크거나 같다 if (합 >= 50)
<= 작거나 같다 if (값 <= 30)
x not x
True False
False True
x y x and y x or y
True True True True
True False False True
False True False True
False False False False

부정 연산자(not)

not xxTrue이면, False 를 반환하고 xFalse이면 True를 반환한다.

In [1]:
x = True
print(not x)
False

논리곱 연산자(and)

x and y를 계산할 경우, xFalse 이면 False를 반환하며 True 이면 y와의 and 연산값을 반환한다. x = False; y = True; x and y를 계산할 경우, xFalse 이므로 y값에 관계없이 x and y 의 값은 False 임이 자명하므로, x의 값이 False임이 확인되는 즉시 곧바로 결과값 False 가 반환되며 이때 y의 값은 계산되지 않는다. 이것을 단축 계산(short-circuit evalulation)이라고 부른다.

In [2]:
print(1 < 2 and 2 < 3) # 참 and 참이므로 참을 출력
True
In [3]:
print(2 < 1 and 2 < 3) # 거짓 and 참이므로 거짓을 출력
False

더 일반적으로 x and y 연산을 할 때 xFalse에 해당되는 객체면 x 객체를 반환하고 그렇지 않으면 y 객체를 반환한다. 파이썬 숫자는 논리 연산을 할 때 0은 거짓, 0이 아닌 모든 수는 참으로 간주한다. 또한 문자열형에서도 문자가 없는 빈 문자열 ""은 거짓, 그렇지 않으면 참으로 간주한다. 문자열 중에 공백문자도 문자로 인식하기 때문에 " "와 같이 따옴표 사이에 공백을 사용하면 참으로 인식한다.

In [4]:
print("문자가 하나라도 존재하면 참" and 1) # and 앞 수식이 참이므로 and 뒤 수식인 숫자 1을 반환한다.
1
In [5]:
print(0 and "문자") # and 앞 수식이 0, 즉 거짓이므로 and 뒤에 있는 수식을 평가하지 않고 앞 수식 0을 반환한다.
0

논리합 연산자(or)

xTrue 이면 True 가 반환되며, False이면 y 와의 or 연산값을 반환한다. x = True; y = False; x or yTrue가 반환된다. 여기서도 논리곱에서와 같이 단축 계산이 적용된다.