Compare / Branch / Control

우연에 조건을 더하기

난수 값을 비교하고 분기해 크기와 위치에 따라 다른 형태와 색을 선택합니다.

크기에 따라 윤곽 원과 채운 원, 사각형으로 나뉜 조건문 구성을 보여 주는 5주차 2교시 이미지

선택된 값을 질문하고 서로 다른 시각적 행동으로 연결하기

형식
기본 50분 / 확장 60분 · + 10 MIN EXTENSION
핵심
if, elif, else, 비교식
연결
무작위 값 → 시각적 의미와 행동

오늘의 학습 목표

  • 비교식이 숫자가 아니라 True 또는 False라는 bool 값을 만든다는 사실을 설명할 수 있습니다.
  • 값을 저장하는 =와 같은지 비교하는 ==의 역할을 구분할 수 있습니다.
  • <, >, <=, >=, ==, !=로 시각적 질문을 작성할 수 있습니다.
  • if / elif / else를 위에서 아래로 확인하고 처음 참이 된 한 갈래만 실행되는 과정을 추적할 수 있습니다.
  • 조건문의 콜론과 들여쓰기가 각 분기의 코드 범위를 나타낸다는 사실을 구분할 수 있습니다.
  • 난수를 한 번 선택해 변수에 저장한 뒤 같은 값을 조건 검사와 도형 그리기에 재사용할 수 있습니다.
  • 반복문, 리스트, 난수, 조건문을 결합한 Pillow 프로그램을 묶음별로 읽고 대표 오류를 진단할 수 있습니다.

수업 운영: 기본 50분과 확장 60분

기본 50분에서는 1교시 회상, 비교식과 bool, 두 갈래와 세 갈래 조건문, 조건 순서, 전체 생성 프로그램, 3교시 설계까지 진행합니다. 모든 코드 추적은 먼저 종이에 참·거짓과 실행 분기를 표시한 뒤 기준 답안을 확인합니다. 진도가 빠르면 50-60분 확장에서 random.random()과 비교식을 이용해 드문 강조가 나타나는 규칙을 분석합니다.

조건문을 처음 보는 학생을 위한 읽기 순서

  1. 질문에 사용되는 값을 찾습니다. 이번 예에서는 먼저 선택해 둔 size입니다.
  2. 비교식을 일상 문장으로 읽습니다. size >= 60은 “크기가 60 이상인가?”입니다.
  3. 참 또는 거짓을 적습니다. 머릿속으로 다음 줄로 넘어가지 않습니다.
  4. 참인 분기의 들여쓴 줄만 표시합니다. 실행하지 않는 분기에는 선을 긋습니다.
  5. 선택 결과가 화면의 무엇을 바꾸는지 연결합니다. 색, 형태, 위치 가운데 실제로 달라지는 속성을 말합니다.

0-5분 · 난수가 후보를 만들었지만 아직 의미는 정하지 않았다

1교시에는 random.randint(20, 80)로 도형 크기를 선택했습니다. 가능한 값의 범위와 안전한 좌표는 정했지만, 큰 원과 작은 원을 모두 같은 색과 같은 도형 명령으로 그렸습니다.

size = random.randint(20, 80)
color = random.choice(palette)

draw.ellipse(
    (x, y, x + size, y + size),
    fill=color,
)

이 코드에서 size는 화면의 크기 차이를 만들지만, 크기가 어떤 역할을 하는지는 정하지 않았습니다. 예를 들어 제작자는 “큰 값은 강조색 사각형으로, 중간 값은 채운 원으로, 작은 값은 윤곽선 원으로 표현한다”라는 규칙을 추가할 수 있습니다. 조건문은 난수의 결과를 다시 뽑는 기능이 아니라, 이미 선택된 값에 질문하고 그 답에 따라 실행할 코드를 고르는 구조입니다.

1 / Candidate값 선택

randint()가 허용 범위에서 크기 하나를 만듭니다.

2 / Question조건 확인

선택된 크기가 어느 구간에 들어가는지 질문합니다.

3 / Response시각적 행동

해당 구간의 색상과 형태로 도형을 그립니다.

개별 회상 · 90초

크기 20부터 80까지를 두 그룹으로 나누기

20 이상 80 이하의 크기를 “강조”와 “기본” 두 그룹으로 나눈다고 가정합니다. 자신이 정한 경계값과 각 그룹에 부여할 색상 또는 형태를 적습니다.

두 그룹 규칙의 기준 예시

예를 들어 55 이상은 강조색 사각형, 55 미만은 팔레트 색 원으로 정할 수 있습니다. 경계값은 다른 숫자도 가능하지만 20~80 범위 안에 있어야 두 그룹이 실제로 나타날 가능성이 있습니다.

5-16분 · 비교식은 True 또는 False를 만든다

컴퓨터에게 조건을 전달하려면 예 또는 아니요로 답할 수 있는 문장을 작성해야 합니다. Python에서는 두 값을 비교한 결과가 True 또는 False가 됩니다. 두 값은 2주차에서 배운 불리언 자료형, 즉 bool입니다. 첫 글자가 대문자이며 따옴표를 사용하지 않습니다.

size = 72

print(size >= 60)  # True
print(size < 40)   # False

size >= 60은 “size가 60 이상인가?”라는 질문입니다. 현재 size가 72이므로 답은 True입니다. 비교식은 size를 바꾸지 않으며, 질문의 결과만 새로 만듭니다.

생성 이미지에서 자주 쓰는 비교 연산자
기호읽는 방법시각 규칙 예시경계 포함
>보다 크다size > 60: 60보다 큰 도형60 제외
>=크거나 같다, 이상size >= 60: 60 이상인 도형60 포함
<보다 작다x < 300: 화면 왼쪽 절반300 제외
<=작거나 같다, 이하y <= 300: 중앙선까지의 위쪽300 포함
==같다color == accent_color: 강조색인지 확인정확히 같을 때만 참
!=같지 않다color != background_color: 배경색이 아닌지 확인다른 모든 경우 참

=는 저장이고 ==는 질문이다

Assignment
size=60

size = 60은 오른쪽 값 60을 변수에 저장합니다. 질문이 아니므로 참·거짓 결과를 만들지 않습니다.

Comparison
size==60

size == 60은 현재 값이 60과 같은지 질문하고 True 또는 False를 만듭니다.

if size = 60:처럼 조건 자리에 대입 기호 하나를 쓰면 Python 문법에 맞지 않아 SyntaxError가 발생합니다. 같음을 질문할 때에는 반드시 등호 두 개를 사용합니다. 또한 “이상”은 =>가 아니라 >= 순서로 작성합니다.

개별 판정 · 2분

경계값의 참·거짓 적기

size = 60일 때 다음 네 비교식의 결과를 순서대로 적습니다: size > 60, size >= 60, size == 60, size != 60.

경계값 판정 답안

순서대로 False, True, True, False입니다. “보다 크다”에는 60이 포함되지 않지만 “이상”과 “같다”에는 60이 포함됩니다.

시각적 속성을 예·아니요 질문으로 바꾸기

화면 설계 문장과 비교식의 대응
화면 설계 문장비교식참일 때 가능한 행동
크기가 60 이상인가?size >= 60강조색 사각형으로 그림
도형이 왼쪽 절반에 있는가?x < 300차가운 색을 사용
도형이 위쪽 영역에 있는가?y < 300원으로 그림
선택 색이 강조색과 같은가?color == accent_color윤곽선을 더 굵게 그림

16-27분 · if와 else는 두 갈래 가운데 하나를 실행한다

비교식만 작성하면 참·거짓 결과를 확인할 수 있지만 이미지에는 아직 변화가 없습니다. if는 조건이 참일 때 실행할 코드 블록을 정하고, else는 그 조건이 거짓인 나머지 경우를 담당합니다.

if size >= 55:
    color = accent_color
else:
    color = base_color
1if첫 번째 조건 검사를 시작합니다.
2size >= 55선택된 크기가 55 이상인지 질문합니다.
3:이 조건에 속한 코드 블록이 아래에 시작됨을 표시합니다.
4 color = accent_color조건이 참일 때만 실행하는 들여쓴 문장입니다.
5else:앞 조건이 거짓인 모든 나머지 경우를 받습니다. 별도 조건을 쓰지 않습니다.
6 color = base_color조건이 거짓일 때만 실행하는 들여쓴 문장입니다.

한 번의 실행에서는 두 대입문 가운데 하나만 실행됩니다. size = 70이면 color = accent_color만 실행되고, size = 42이면 color = base_color만 실행됩니다. else는 “반대 조건을 다시 검사한다”가 아니라 앞의 조건에 들어가지 않은 모든 경우를 받습니다.

Questionsize >= 55
True 또는 False
True pathcolor = accent_color
if 블록 실행
False pathcolor = base_color
else 블록 실행

콜론은 블록의 시작, 들여쓰기는 블록의 범위다

Inside branch
if size >= 55:
    color = accent_color
    outline_width = 4

같은 깊이로 들여쓴 두 문장은 조건이 참일 때 함께 실행됩니다.

After branch
if size >= 55:
    color = accent_color

print(color)

들여쓰기가 끝난 print()는 조건문 바깥이므로 다음 순서에서 실행됩니다.

if 줄과 else 줄 끝에는 모두 콜론이 필요합니다. 같은 분기에 속한 문장은 스페이스 네 칸으로 같은 깊이에 맞춥니다. 들여쓰기는 보기 좋게 정렬하는 장식이 아니라 Python이 실행 관계를 구분하는 문법입니다.

size가 55일 때 어느 분기가 실행되는가?

size >= 55는 55를 포함하므로 True입니다. if 블록의 color = accent_color가 실행되고 else 블록은 건너뜁니다.

27-38분 · elif는 앞 조건이 거짓일 때 다음 질문을 한다

두 갈래보다 세밀한 분류가 필요하면 elif를 추가합니다. elif는 “else if”의 줄임말이며, 앞의 if 또는 elif가 거짓일 때만 다음 조건을 확인합니다. 아래 코드는 20~80의 크기를 큰 값, 중간 값, 작은 값의 세 구간으로 나눕니다.

if size >= 60:
    visual_role = "large accent"
elif size >= 40:
    visual_role = "medium base"
else:
    visual_role = "small outline"

Python은 위에서 아래로 조건을 확인하고 처음 참이 된 한 분기만 실행한 뒤 조건문 전체를 빠져나갑니다. size = 72이면 첫 조건이 이미 참이므로 72 >= 40도 사실이지만 두 번째 조건은 확인하지 않습니다.

세 크기값의 분기 추적
sizesize >= 60size >= 40실행 분기역할
72True확인하지 않음if큰 강조
51FalseTrueelif중간 기본
32FalseFalseelse작은 윤곽
60True확인하지 않음if큰 강조
40FalseTrueelif중간 기본

조건의 순서는 큰 경계에서 작은 경계로 내려온다

아래처럼 작은 경계를 먼저 검사하면 size = 72도 첫 조건 size >= 40에서 참이 됩니다. 그 결과 size >= 60 분기는 한 번도 실행될 수 없습니다.

# 잘못된 순서: 60 이상도 첫 조건에서 이미 잡힙니다.
if size >= 40:
    visual_role = "medium base"
elif size >= 60:
    visual_role = "large accent"
20~80 범위를 빠짐없이 나눈 결과
분기실제 담당 범위경계값빠진 값
if size >= 6060~8060 포함없음
elif size >= 4040~5940 포함, 60은 앞 분기없음
else20~39나머지 전부없음

난수는 한 번 뽑고 같은 값을 질문과 그리기에 사용한다

One candidate
size = random.randint(20, 80)

if size >= 60:
    color = accent_color

draw.ellipse((x, y, x + size, y + size), fill=color)

조건이 확인한 크기와 실제로 그린 크기가 같습니다. 결과를 설명하고 오류를 재현할 수 있습니다.

Two candidates
if random.randint(20, 80) >= 60:
    color = accent_color

size = random.randint(20, 80)

조건이 확인한 값과 실제 크기가 서로 다른 두 난수입니다. 작은 도형이 강조색이 되는 이유를 추적하기 어렵습니다.

개별 추적 · 3분

다섯 크기의 실행 분기 기록하기

다음 값이 순서대로 선택되었다고 가정합니다: 24, 40, 59, 60, 78. 각 값이 if, elif, else 가운데 어느 분기로 들어가는지 적고, 각 분기가 실행되는 횟수를 셉니다.

다섯 크기 추적 답안

24는 else, 40과 59는 elif, 60과 78은 if입니다. 따라서 큰 강조 분기 2회, 중간 기본 분기 2회, 작은 윤곽 분기 1회입니다.

38-46분 · 반복·난수·조건을 하나의 생성 규칙으로 결합하기

아래 이미지는 크기 범위를 세 구간으로 나누고 각 구간을 다른 시각 행동에 연결한 수업용 결과입니다. 모든 요소의 크기는 우연히 선택되지만, 작은 값은 초록색 윤곽 원, 중간 값은 황토색 원, 큰 값은 산호색 사각형이라는 관계는 변하지 않습니다.

세 줄에 무작위 크기의 도형이 배열되어 있으며 작은 값은 초록 윤곽 원, 중간 값은 황토 원, 큰 값은 산호색 사각형으로 표현된 이미지
수업용 개념도. 난수는 각 요소의 크기를 선택하고, 조건문은 그 크기를 작은 값·중간 값·큰 값으로 분류해 서로 다른 형태와 색상을 부여합니다.

다음 완전한 코드는 1교시의 안전한 좌표 계산과 오늘의 세 갈래 조건을 결합합니다. 처음부터 한 글자씩 외우지 않고, 고정 규칙 → 이미지 준비 → 난수 선택 → 조건 분기 → 확인과 저장의 다섯 단계로 읽습니다.

from PIL import Image, ImageDraw
import random

# 1. 고정 규칙
canvas_width = 600
canvas_height = 600
background_color = (245, 240, 228)
outline_color = (37, 62, 78)
accent_color = (201, 111, 93)
medium_color = (211, 155, 42)
small_color = (111, 143, 126)
margin = 40
shape_count = 45
seed_number = 29

# 2. 이미지와 난수 시작점
image = Image.new(
    "RGB",
    (canvas_width, canvas_height),
    background_color,
)
draw = ImageDraw.Draw(image)
random.seed(seed_number)

# 3. 반복마다 후보 선택
for shape_number in range(shape_count):
    size = random.randint(20, 80)
    x = random.randint(
        margin,
        canvas_width - margin - size,
    )
    y = random.randint(
        margin,
        canvas_height - margin - size,
    )

    # 4. 같은 size를 조건과 도형에 함께 사용
    if size >= 60:
        draw.rectangle(
            (x, y, x + size, y + size),
            fill=accent_color,
        )
    elif size >= 40:
        draw.ellipse(
            (x, y, x + size, y + size),
            fill=medium_color,
        )
    else:
        draw.ellipse(
            (x, y, x + size, y + size),
            fill=small_color,
            outline=outline_color,
            width=3,
        )

# 5. 확인과 저장
image
image.save("week05_controlled_chance_seed29.png")
전체 코드에서 이전 학습과 새 학습 찾기
코드 요소배운 주차현재 역할
변수와 정수·문자열2주차캔버스, 색상, 개수, 시드, 파일명 저장
좌표·RGB·Pillow 도형3주차선택된 값을 실제 이미지 픽셀에 기록
forrange()4주차도형 생성 절차를 45번 반복
randint()seed()5주차 1교시크기·위치 후보 선택과 결과 재현
if / elif / else5주차 2교시크기 구간을 색상과 형태의 세 행동으로 연결

코드를 자연어 규칙으로 다시 설명하기

Input크기·위치 후보

20~80의 크기와 안전한 x·y를 난수로 선택합니다.

Rule크기 구간 분류

60 이상, 40~59, 20~39의 세 갈래로 나눕니다.

Output형태와 색상

큰 사각형, 중간 원, 작은 윤곽 원으로 기록합니다.

이 설명이 가능해야 조건문의 역할을 이해한 것입니다. “조건문을 사용했다”라는 문장은 문법 이름만 말합니다. “무작위 크기를 세 구간으로 분류하고 큰 값은 강조 사각형으로 보이게 했다”라고 말하면 데이터, 조건, 시각 결과의 관계가 드러납니다.

조건문에서 자주 만나는 문제와 점검 순서

대표 오류와 진단 방법
오류 또는 현상가능한 원인첫 점검
SyntaxError조건 끝의 콜론 누락, == 대신 = 사용ifelif 줄의 기호
IndentationError분기 안의 도형 명령 깊이가 섞임각 분기의 네 칸 들여쓰기
NameError: size난수 선택 전에 조건을 검사함size = random.randint(...) 실행 위치
큰 도형 분기가 한 번도 안 나옴작은 경계를 먼저 검사하거나 기준이 난수 최댓값보다 큼조건 순서와 randint 범위
작은 도형인데 강조색조건에 사용한 난수와 그리기에 사용한 난수가 다름난수를 한 번만 뽑아 size에 저장했는지 확인
일부 크기가 어느 분기에도 안 들어감서로 떨어진 if만 쓰고 나머지 범위를 처리하지 않음elifelse가 전체 범위를 덮는지 확인

오류가 없다는 것과 규칙이 맞다는 것은 다르다

조건 순서를 잘못 작성해도 Python 문법에는 맞을 수 있으므로 오류 메시지가 나오지 않습니다. 실행되지만 의도와 다른 논리 오류는 경계값 39, 40, 59, 60처럼 분기가 바뀌는 숫자를 직접 대입해 확인합니다. 무작위 실행만 여러 번 보면서 추측하는 것보다 경계값 검사가 빠르고 정확합니다.

수업 후 개별 복습

1. size = 45일 때 size >= 60의 자료형과 값은?

자료형은 bool이고 값은 False입니다. 비교식은 원래의 정수 45를 바꾸지 않습니다.

2. if와 elif 조건이 모두 참일 수 있으면 어느 분기가 실행되는가?

위에서부터 확인해 처음 참이 된 분기 하나만 실행됩니다. 그래서 겹치는 크기 조건은 큰 경계를 먼저 적어야 합니다.

3. else 뒤에는 왜 비교식을 적지 않는가?

else는 앞의 모든 조건이 거짓인 나머지 경우 전체를 담당하기 때문입니다. else size < 40:처럼 작성하지 않습니다.

4. 조건 검사와 도형 크기에 같은 변수를 써야 하는 이유는?

분류한 값과 실제로 그린 값이 같아야 “큰 값은 강조한다”라는 규칙이 화면에서 성립하고, 결과를 다시 추적할 수 있기 때문입니다.

5. 크기 대신 위치를 조건으로 사용한다면 어떤 규칙이 가능한가?

예를 들어 if x < 300:이면 왼쪽은 차가운 색, else:이면 오른쪽은 따뜻한 색을 사용할 수 있습니다. 선택된 x좌표가 화면의 색상 영역을 결정합니다.

46-50분 · 3교시 연결: 통제된 우연 포스터 설계하기

3교시는 정해진 시간을 모두 채우는 방식이 아니라, 필수 목표를 완성하고 자동 검사와 파일 제출을 통과하면 종료하는 목표 달성형 개인 실습으로 이어집니다. 2교시 마지막에는 코드를 완성하지 않고 자신이 사용할 고정층, 변화층, 조건 규칙을 먼저 결정합니다.

통제된 우연 포스터의 예정 필수 목표
목표최소 기준2교시에서 결정할 것
캔버스와 여백600 × 600 RGB, 모든 도형이 안전 영역 안에 배치배경색과 여백
색상 후보서로 다른 RGB 색상 4개 이상의 리스트기본 팔레트와 강조색
재현 가능한 우연정수 시드와 randint(), choice() 사용최종 결과의 시드번호
충분한 반복for로 도형 30개 이상 생성도형 개수와 크기 범위
조건 규칙if / elif / else가 색상 또는 형태에 실제 영향질문할 값과 분기별 행동
설명 가능성고정 요소·변화 요소·조건 결과를 한 문장으로 작성생성 규칙 문장
결과 제출전체 실행 PASS, PNG와 Colab 노트북학번·이름·시드를 포함한 파일명
개별 사전 설계 · 3분

한 문장 규칙 카드 완성하기

  1. 고정할 요소 두 개: ________, ________
  2. 무작위로 선택할 요소 두 개: ________, ________
  3. 조건 질문: “________이/가 ________인가?”
  4. 참일 때 행동: ________
  5. 그 밖의 행동: ________
  6. 전체 문장: “________은 고정하고, ________을 무작위로 선택하며, ________이면 ________한다.”
규칙 카드 완성 예시

“600 × 600 캔버스와 네 색 팔레트는 고정하고, 원의 위치와 크기를 무작위로 선택하며, 크기가 60 이상이면 강조색 사각형으로 그린다.” 이 문장에는 고정층, 변화층, 조건, 시각적 행동이 모두 들어 있습니다.

이번 시간에 아직 다루지 않는 것

사용자 정의 함수와 매개변수는 6주차, 외부 이미지 불러오기와 합성은 7주차에서 다룹니다. 이번 기본 수업에서는 while, 딕셔너리, 리스트 컴프리헨션, 복잡한 확률 분포, 애니메이션을 추가하지 않습니다. 코드가 반복되어 보이더라도 먼저 조건의 실행 원리를 정확히 이해하고, 다음 주에 함수로 정리합니다.

2교시 핵심 문장

난수는 후보를 만들고, 조건문은 그 후보를 분류하여 서로 다른 시각적 행동으로 연결합니다.

50-60분 · 드문 강조를 만드는 확률 조건

확장 시간에는 random.random()을 한 번만 소개합니다. 이 함수는 0.0 이상 1.0 미만의 실수 하나를 만듭니다. 선택된 값이 0.2보다 작은지 비교하면 매 반복에서 약 20%의 가능성으로 강조 분기에 들어가는 규칙을 만들 수 있습니다.

chance = random.random()

if chance < 0.2:
    color = accent_color
else:
    color = base_color

chance < 0.2의 가능한 구간은 0.0 이상 0.2 미만이며 전체 0.0~1.0 범위의 약 20%입니다. 하지만 원을 10개 그린다고 강조색이 정확히 2개 나온다는 뜻은 아닙니다. 한 번의 짧은 실행에서는 0개나 4개가 나올 수도 있으며, 반복 횟수가 충분히 커질 때 전체 비율이 기준에 가까워지는 경향을 기대합니다.

확률 문턱과 시각적 인상
조건기대되는 강조 비율시각적 역할보장 여부
chance < 0.1약 10%매우 드문 사건 또는 강한 초점정확한 개수 보장 안 됨
chance < 0.2약 20%드문 강조와 기본 요소의 대비정확한 개수 보장 안 됨
chance < 0.5약 50%두 상태가 비슷한 빈도로 나타남정확한 개수 보장 안 됨
chance < 0.9약 90%강조가 기본처럼 자주 나타남정확한 개수 보장 안 됨
50-60분 확장 운영
시간활동남겨야 할 결과
50-53분0.1, 0.2, 0.5의 구간을 수직선에 표시각 조건의 참 구간
53-56분도형 10개에서 예상되는 강조 수와 실제 보장 여부 구분“기대”와 “보장” 문장
56-59분같은 시드로 문턱 0.2와 0.5 결과 비교강조 밀도 차이
59-60분작품 의도에 맞는 문턱 하나 선택선택 이유 한 문장
도형 10개와 20% 조건이면 강조는 반드시 2개인가?

아닙니다. 각 반복에서 20% 구간에 들어갈 가능성이 있다는 뜻이며 짧은 실행의 실제 개수는 달라질 수 있습니다. 정확히 2개를 반드시 강조해야 한다면 확률 선택이 아니라 강조할 인덱스나 위치를 직접 정하는 다른 규칙이 필요합니다.

참고 자료