선택된 값을 질문하고 서로 다른 시각적 행동으로 연결하기
- 형식
- 기본 50분 / 확장 60분 · + 10 MIN EXTENSION
- 핵심
if,elif,else, 비교식- 연결
- 무작위 값 → 시각적 의미와 행동
오늘의 학습 목표
- 비교식이 숫자가 아니라
True또는False라는bool값을 만든다는 사실을 설명할 수 있습니다. - 값을 저장하는
=와 같은지 비교하는==의 역할을 구분할 수 있습니다. <,>,<=,>=,==,!=로 시각적 질문을 작성할 수 있습니다.if / elif / else를 위에서 아래로 확인하고 처음 참이 된 한 갈래만 실행되는 과정을 추적할 수 있습니다.- 조건문의 콜론과 들여쓰기가 각 분기의 코드 범위를 나타낸다는 사실을 구분할 수 있습니다.
- 난수를 한 번 선택해 변수에 저장한 뒤 같은 값을 조건 검사와 도형 그리기에 재사용할 수 있습니다.
- 반복문, 리스트, 난수, 조건문을 결합한 Pillow 프로그램을 묶음별로 읽고 대표 오류를 진단할 수 있습니다.
- 0-5 min난수 선택 회상
1교시의 크기 선택 코드에서 아직 정하지 않은 시각적 의미를 찾습니다.
- 5-16 min비교식과 bool
숫자에 질문을 던지고 참·거짓 결과와 경계값을 확인합니다.
- 16-27 minif와 else
두 갈래 분기의 실행 흐름과 콜론·들여쓰기의 역할을 읽습니다.
- 27-38 minelif와 조건 순서
세 크기 구간을 추적하고 처음 참인 분기만 실행되는 원리를 확인합니다.
- 38-46 min전체 생성 규칙
반복·난수·조건·Pillow 도형을 하나의 프로그램으로 연결합니다.
- 46-50 min3교시 설계 연결
통제된 우연 포스터의 필수 조건과 규칙 문장을 확정합니다.
수업 운영: 기본 50분과 확장 60분
기본 50분에서는 1교시 회상, 비교식과 bool, 두 갈래와 세 갈래 조건문, 조건 순서, 전체 생성 프로그램, 3교시 설계까지 진행합니다. 모든 코드 추적은 먼저 종이에 참·거짓과 실행 분기를 표시한 뒤 기준 답안을 확인합니다. 진도가 빠르면 50-60분 확장에서 random.random()과 비교식을 이용해 드문 강조가 나타나는 규칙을 분석합니다.
조건문을 처음 보는 학생을 위한 읽기 순서
- 질문에 사용되는 값을 찾습니다. 이번 예에서는 먼저 선택해 둔
size입니다. - 비교식을 일상 문장으로 읽습니다.
size >= 60은 “크기가 60 이상인가?”입니다. - 참 또는 거짓을 적습니다. 머릿속으로 다음 줄로 넘어가지 않습니다.
- 참인 분기의 들여쓴 줄만 표시합니다. 실행하지 않는 분기에는 선을 긋습니다.
- 선택 결과가 화면의 무엇을 바꾸는지 연결합니다. 색, 형태, 위치 가운데 실제로 달라지는 속성을 말합니다.
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는 화면의 크기 차이를 만들지만, 크기가 어떤 역할을 하는지는 정하지 않았습니다. 예를 들어 제작자는 “큰 값은 강조색 사각형으로, 중간 값은 채운 원으로, 작은 값은 윤곽선 원으로 표현한다”라는 규칙을 추가할 수 있습니다. 조건문은 난수의 결과를 다시 뽑는 기능이 아니라, 이미 선택된 값에 질문하고 그 답에 따라 실행할 코드를 고르는 구조입니다.
randint()가 허용 범위에서 크기 하나를 만듭니다.
선택된 크기가 어느 구간에 들어가는지 질문합니다.
해당 구간의 색상과 형태로 도형을 그립니다.
크기 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: 배경색이 아닌지 확인 | 다른 모든 경우 참 |
=는 저장이고 ==는 질문이다
size = 60은 오른쪽 값 60을 변수에 저장합니다. 질문이 아니므로 참·거짓 결과를 만들지 않습니다.
size == 60은 현재 값이 60과 같은지 질문하고 True 또는 False를 만듭니다.
if size = 60:처럼 조건 자리에 대입 기호 하나를 쓰면 Python 문법에 맞지 않아 SyntaxError가 발생합니다. 같음을 질문할 때에는 반드시 등호 두 개를 사용합니다. 또한 “이상”은 =>가 아니라 >= 순서로 작성합니다.
경계값의 참·거짓 적기
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
한 번의 실행에서는 두 대입문 가운데 하나만 실행됩니다. size = 70이면 color = accent_color만 실행되고, size = 42이면 color = base_color만 실행됩니다. else는 “반대 조건을 다시 검사한다”가 아니라 앞의 조건에 들어가지 않은 모든 경우를 받습니다.
size >= 55color = accent_colorcolor = base_color콜론은 블록의 시작, 들여쓰기는 블록의 범위다
if size >= 55:
color = accent_color
outline_width = 4
같은 깊이로 들여쓴 두 문장은 조건이 참일 때 함께 실행됩니다.
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도 사실이지만 두 번째 조건은 확인하지 않습니다.
| size | size >= 60 | size >= 40 | 실행 분기 | 역할 |
|---|---|---|---|---|
| 72 | True | 확인하지 않음 | if | 큰 강조 |
| 51 | False | True | elif | 중간 기본 |
| 32 | False | False | else | 작은 윤곽 |
| 60 | True | 확인하지 않음 | if | 큰 강조 |
| 40 | False | True | elif | 중간 기본 |
조건의 순서는 큰 경계에서 작은 경계로 내려온다
아래처럼 작은 경계를 먼저 검사하면 size = 72도 첫 조건 size >= 40에서 참이 됩니다. 그 결과 size >= 60 분기는 한 번도 실행될 수 없습니다.
# 잘못된 순서: 60 이상도 첫 조건에서 이미 잡힙니다.
if size >= 40:
visual_role = "medium base"
elif size >= 60:
visual_role = "large accent"
| 분기 | 실제 담당 범위 | 경계값 | 빠진 값 |
|---|---|---|---|
if size >= 60 | 60~80 | 60 포함 | 없음 |
elif size >= 40 | 40~59 | 40 포함, 60은 앞 분기 | 없음 |
else | 20~39 | 나머지 전부 | 없음 |
난수는 한 번 뽑고 같은 값을 질문과 그리기에 사용한다
size = random.randint(20, 80)
if size >= 60:
color = accent_color
draw.ellipse((x, y, x + size, y + size), fill=color)
조건이 확인한 크기와 실제로 그린 크기가 같습니다. 결과를 설명하고 오류를 재현할 수 있습니다.
if random.randint(20, 80) >= 60:
color = accent_color
size = random.randint(20, 80)
조건이 확인한 값과 실제 크기가 서로 다른 두 난수입니다. 작은 도형이 강조색이 되는 이유를 추적하기 어렵습니다.
다섯 크기의 실행 분기 기록하기
다음 값이 순서대로 선택되었다고 가정합니다: 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주차 | 선택된 값을 실제 이미지 픽셀에 기록 |
for와 range() | 4주차 | 도형 생성 절차를 45번 반복 |
randint()와 seed() | 5주차 1교시 | 크기·위치 후보 선택과 결과 재현 |
if / elif / else | 5주차 2교시 | 크기 구간을 색상과 형태의 세 행동으로 연결 |
코드를 자연어 규칙으로 다시 설명하기
20~80의 크기와 안전한 x·y를 난수로 선택합니다.
60 이상, 40~59, 20~39의 세 갈래로 나눕니다.
큰 사각형, 중간 원, 작은 윤곽 원으로 기록합니다.
이 설명이 가능해야 조건문의 역할을 이해한 것입니다. “조건문을 사용했다”라는 문장은 문법 이름만 말합니다. “무작위 크기를 세 구간으로 분류하고 큰 값은 강조 사각형으로 보이게 했다”라고 말하면 데이터, 조건, 시각 결과의 관계가 드러납니다.
조건문에서 자주 만나는 문제와 점검 순서
| 오류 또는 현상 | 가능한 원인 | 첫 점검 |
|---|---|---|
SyntaxError | 조건 끝의 콜론 누락, == 대신 = 사용 | if와 elif 줄의 기호 |
IndentationError | 분기 안의 도형 명령 깊이가 섞임 | 각 분기의 네 칸 들여쓰기 |
NameError: size | 난수 선택 전에 조건을 검사함 | size = random.randint(...) 실행 위치 |
| 큰 도형 분기가 한 번도 안 나옴 | 작은 경계를 먼저 검사하거나 기준이 난수 최댓값보다 큼 | 조건 순서와 randint 범위 |
| 작은 도형인데 강조색 | 조건에 사용한 난수와 그리기에 사용한 난수가 다름 | 난수를 한 번만 뽑아 size에 저장했는지 확인 |
| 일부 크기가 어느 분기에도 안 들어감 | 서로 떨어진 if만 쓰고 나머지 범위를 처리하지 않음 | elif와 else가 전체 범위를 덮는지 확인 |
오류가 없다는 것과 규칙이 맞다는 것은 다르다
조건 순서를 잘못 작성해도 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 노트북 | 학번·이름·시드를 포함한 파일명 |
한 문장 규칙 카드 완성하기
- 고정할 요소 두 개: ________, ________
- 무작위로 선택할 요소 두 개: ________, ________
- 조건 질문: “________이/가 ________인가?”
- 참일 때 행동: ________
- 그 밖의 행동: ________
- 전체 문장: “________은 고정하고, ________을 무작위로 선택하며, ________이면 ________한다.”
규칙 카드 완성 예시
“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-53분 | 0.1, 0.2, 0.5의 구간을 수직선에 표시 | 각 조건의 참 구간 |
| 53-56분 | 도형 10개에서 예상되는 강조 수와 실제 보장 여부 구분 | “기대”와 “보장” 문장 |
| 56-59분 | 같은 시드로 문턱 0.2와 0.5 결과 비교 | 강조 밀도 차이 |
| 59-60분 | 작품 의도에 맞는 문턱 하나 선택 | 선택 이유 한 문장 |
도형 10개와 20% 조건이면 강조는 반드시 2개인가?
아닙니다. 각 반복에서 20% 구간에 들어갈 가능성이 있다는 뜻이며 짧은 실행의 실제 개수는 달라질 수 있습니다. 정확히 2개를 반드시 강조해야 한다면 확률 선택이 아니라 강조할 인덱스나 위치를 직접 정하는 다른 규칙이 필요합니다.
참고 자료
- Python 공식 튜토리얼: if Statements0개 이상의
elif와 선택적인else, 위에서 아래로 이어지는 조건 분기의 공식 설명 - Python 언어 참조: Comparisons비교 연산자의 의미와 비교 결과가 불리언 값을 만드는 방식에 관한 공식 설명
- Python 공식 문서: Truth Value Testing
True,False와 조건 검사에서 값이 해석되는 방식에 관한 공식 설명 - Python 공식 문서: random0.0 이상 1.0 미만의 값을 만드는
random(),randint(),seed()의 공식 설명 - Pillow 공식 문서: ImageDraw조건 분기에서 사용하는 타원·사각형의 경계 상자, 내부색, 윤곽선, 선 굵기에 관한 공식 설명