세 후보 중 내가 고른 한 장
- 형식
- 목표 달성형 개인 실습
- 최대 시간
- 50분
- 선택
- 표현 3종 × 팔레트 3종 × 시드 후보 3장
- 제출물
- 실행 결과가 있는 .ipynb + 선택한 .png
실습 결과물
내가 정한 규칙으로 그래픽 포스터 세 장을 만들고, 그중 한 장을 선택합니다. 모티프는 반복해서 사용하는 작은 도형 묶음입니다. 600 × 600 캔버스에 모티프 40~80개를 배치하고, 크기 조건에 따라 모티프의 표현을 바꿉니다. 같은 시드와 설정으로 선택한 이미지를 다시 만들 수 있어야 합니다.
아래 세 이미지는 제공 노트북을 실제로 실행한 결과입니다. 모두 시드 73, 모티프 56개, 경계 42·64를 사용합니다. 위치와 크기는 같고 표현 방식과 팔레트가 다릅니다.



색면의 무게감, 동심원의 겹침, 가로·세로 띠의 리듬 중 어떤 표현을 만들고 싶은지 고릅니다. “겹침이 밀집된 포스터”, “여백이 남는 가벼운 패턴”처럼 원하는 인상을 한 문장으로 적습니다.
크기 조건이 바꾸는 그래픽
| 크기 구간 | tiles · 색면 | rings · 동심원 | stripes · 신호 |
|---|---|---|---|
| 큰 구간 | 겹친 강조 사각형 | 강조색 동심원 | 가로 띠 5개 |
| 중간 구간 | 가운데 선이 있는 채운 원 | 두꺼운 고리 | 세로 띠 4개 |
| 작은 구간 | 윤곽 사각형 | 얇은 고리 | 십자 표시 |
모티프 하나에 여러 그리기 명령이 들어갈 수 있습니다. 가로 띠 다섯 개를 그려도 모티프 수는 하나입니다. 생성 횟수는 출력에 표시되며, 겹침 때문에 일부 모티프는 가려질 수 있습니다.
실습 과정
- CHOOSE방향 선택표현 방식과 팔레트 고르기
- GENERATE세 후보 생성같은 규칙, 서로 다른 시드
- COMPARE비교와 조정겹침·강조·여백 살펴보기
- SELECT한 장 선택선택 이유와 규칙 설명
- CHECK저장과 제출전체 실행 PASS, 두 파일 제출
완료 기준
- 생성 규칙무엇을 고정하고 무작위로 선택하며 조건에 따라 어떻게 그리는지 20자 이상 설명했습니다.
- 세 후보서로 다른 시드 세 개로 600 × 600 RGB 후보 이미지를 만들었습니다.
- 조건과 여백모티프 40~80개, 40픽셀 안전 여백, 두 종류 이상의 조건 분기를 확인했습니다.
- 선택 이유겹침·강조·여백 중 하나를 근거로 고른 이유를 20자 이상 작성했습니다.
- 검사와 제출새 세션 전체 실행 PASS를 확인하고 노트북과 최종 PNG를 제출했습니다.
작품의 선택은 학생이 합니다
제공된 팔레트나 경계값을 그대로 사용해도 됩니다. 자동 검사는 난수·조건·여백·선택한 파일의 일치와 재실행을 확인합니다. 특정 스타일이나 색이 더 높은 점수를 받지 않습니다.
완료와 귀가
자동 검사를 통과하고 두 파일 제출을 확인하면 즉시 귀가할 수 있습니다. 최대 50분 안에서 각자의 속도로 진행합니다. 세 후보의 비교 이미지는 노트북 출력에 남기며 별도 파일로 제출하지 않습니다.
실습 노트북 준비
페이지 상단의 새 실습 노트북 받기 버튼으로 이 교안에 맞는 파일을 내려받습니다. Colab 열기에서 업로드를 선택해 해당 파일을 엽니다. 이미 노트북이 열려 있다면 파일 → 노트 업로드를 사용합니다.
- 업로드한 노트북을 Drive에 사본으로 저장합니다.
- 파일명을
week05_학번_이름.ipynb로 바꿉니다. - 위에서부터 준비·제출 정보·설계값·생성 셀을 실행합니다.
난수 네 줄과 조건별 그리기 코드는 이미 완성되어 있습니다. 다른 곳의 코드를 찾아 붙이거나 빈칸을 채울 필요가 없습니다. EDIT가 있는 제출 정보·설정·최종 후보 번호를 정하면 됩니다.
준비 셀에서 이미지가 보이지 않을 때
정상입니다. 설계값 셀에서는 다섯 색의 팔레트가, 생성 셀에서는 세 후보가 함께 표시됩니다. 빨간 오류가 있다면 마지막 한글 안내를 읽고 위쪽 셀부터 순서대로 실행합니다.
세 후보의 첫 결과 확인
처음에는 rings, night, 시드 [21, 73, 137]으로 실행합니다. 아래처럼 같은 표현과 색을 사용하면서 배치가 다른 세 후보가 나옵니다. 실제 노트북에는 세 장이 나란히 표시됩니다.



- 강조색 동심원이 한곳에 모이는 후보는 무엇인가요?
- 작은 고리가 만든 빈 공간과 겹침은 어떻게 다른가요?
- 지금 한 장을 고른다면 무엇을 고르고, 그 이유는 무엇인가요?
제출 정보와 생성 규칙 작성
노트북의 제출 정보 셀에 학번·이름과 두 설명을 작성합니다. 처음에는 학번과 이름을 적고, 후보를 비교한 뒤 생성 규칙과 선택 이유를 완성합니다.
| 변수 | 담을 내용 | 문장 예시 |
|---|---|---|
| design_rule | 고정 요소 + 무작위 요소 + 조건 결과 | 밤 팔레트와 여백은 고정하고 위치·크기·색을 무작위로 고르며, 큰 크기는 강조 동심원으로 그린다. |
| selection_reason | 어느 후보 + 눈으로 확인한 근거 | 후보 2는 오른쪽의 동심원 겹침이 눈에 띄고 왼쪽 여백이 남아 있어 선택했다. |
표현 방식과 시드·조건 설계
설계값은 노트북의 한 셀에 모여 있습니다. 표현 방식과 팔레트는 서로 독립적으로 고를 수 있어 stripes + night처럼 예시와 다른 조합도 가능합니다.
| 설정 | 가능한 값 | 화면에서 바뀌는 것 |
|---|---|---|
| graphic_style | tiles / rings / stripes | 같은 위치에 그리는 모티프의 모양 |
| palette_name | paper / night / pop | 배경과 모티프의 색·대비 |
| candidate_seeds | 서로 다른 0~9999 정수 3개 | 크기·위치·기본색의 선택 순서 |
| shape_count | 40~80 | 밀도와 겹침 |
| medium_threshold / large_threshold | 권장 42 / 64 | 작은·중간·큰 모티프의 비율 |
경계값은 20 < medium_threshold < large_threshold < 80 순서를 유지하며, 각 경계 사이의 차이를 10 이상 둡니다. 42·64라면 작은 구간은 20~41, 중간은 42~63, 큰 구간은 64~80입니다.
어떤 설정부터 바꿀지 모르겠다면
표현과 팔레트를 먼저 고른 뒤 시드 세 개를 비교합니다. 지나치게 겹쳐 보이면 개수를 40에 가깝게 줄이고, 강한 모티프를 줄이고 싶으면 큰 경계를 높여 봅니다. 한 번에 한 설정만 바꾸어 원인을 비교합니다.
시드나 경계값 오류가 나올 때
시드 목록은 대괄호 안의 서로 다른 정수 세 개입니다. 경계값은 권장값 42·64에서 시작하고, 20부터 중간 경계까지, 중간부터 큰 경계까지, 큰 경계부터 80까지의 차이를 각각 10 이상 유지합니다.
전체 코드로 세 후보 생성
생성 셀에서는 후보마다 시드를 설정하고, 모티프마다 크기 → 안전한 x·y → 기본색을 선택합니다. 같은 크기로 조건을 검사한 뒤 선택한 표현 방식의 그리기 명령을 실행합니다. 모티프 안에서는 난수를 추가로 선택하지 않아, 스타일만 바꿔도 같은 시드의 위치와 크기가 유지됩니다.
크기 70, 경계 42·64라면 큰 분기가 실행됩니다. tiles에서는 겹친 사각형, rings에서는 강조 동심원, stripes에서는 가로 띠가 그려집니다. shape_count는 선이나 원의 총수가 아니라 이 모티프 묶음을 생성한 횟수입니다.
새 Colab 셀에서 바로 실행하는 전체 미리보기 코드
이미지 생성만 따로 확인할 때 사용하는 전체 코드입니다. 제출 정보·저장·자동 검사는 내려받은 실습 노트북에 있습니다.
# 0. 준비 / 이 셀은 그대로 실행합니다.
from pathlib import Path
import random
from PIL import Image, ImageDraw
from IPython.display import display
canvas_width = 600
canvas_height = 600
min_size = 20
max_size = 80
margin = 40
# 순서: 배경 / 주조 / 보조 / 강조 / 윤곽
PALETTES = {
"paper": ((246, 240, 225), (40, 52, 61), (116, 150, 132), (224, 89, 62), (64, 70, 64)),
"night": ((24, 29, 58), (230, 232, 213), (119, 136, 208), (215, 242, 93), (174, 179, 217)),
"pop": ((237, 220, 237), (56, 53, 104), (242, 167, 107), (218, 61, 118), (85, 55, 85)),
}
STYLE_NAMES = {"tiles": "겹친 색면", "rings": "동심원 리듬", "stripes": "스트라이프 신호"}
# 2. EDIT / 표현 방식·팔레트·시드·밀도·경계를 설계합니다.
graphic_style = "rings" # "tiles", "rings", "stripes"
palette_name = "night" # "paper", "night", "pop"
candidate_seeds = [21, 73, 137]
shape_count = 56
medium_threshold = 42
large_threshold = 64
background_color, primary_color, secondary_color, accent_color, outline_color = PALETTES[palette_name]
palette = [primary_color, secondary_color, accent_color]
# 3. 전체 생성 코드 / 난수 네 줄과 조건문이 이미 들어 있습니다.
# 설정을 바꿀 때는 2번 셀부터 다시 실행합니다.
candidate_images = []
candidate_records = []
candidate_branch_counts = []
for seed_number in candidate_seeds:
image = Image.new("RGB", (canvas_width, canvas_height), background_color)
draw = ImageDraw.Draw(image)
random.seed(seed_number)
generation_records = []
branch_counts = {"large": 0, "medium": 0, "small": 0}
for shape_number in range(shape_count):
# 선택: 크기 -> 안전한 위치 -> 기본색
size = random.randint(min_size, max_size)
x = random.randint(margin, canvas_width - margin - size)
y = random.randint(margin, canvas_height - margin - size)
base_color = random.choice(palette)
# 같은 size를 조건 검사와 그리기에 함께 사용합니다.
if size >= large_threshold:
branch_name = "large"
if graphic_style == "tiles":
draw.rectangle((x + 8, y + 8, x + size, y + size), fill=outline_color)
draw.rectangle((x, y, x + size - 8, y + size - 8), fill=accent_color)
elif graphic_style == "rings":
draw.ellipse((x, y, x + size, y + size), fill=accent_color)
inset = size // 5
draw.ellipse((x + inset, y + inset, x + size - inset, y + size - inset), fill=background_color)
inset = size // 3
draw.ellipse((x + inset, y + inset, x + size - inset, y + size - inset), fill=base_color)
else:
for stripe in range(5):
top = y + stripe * size // 5
bottom = y + (stripe + 1) * size // 5 - 3
draw.rectangle((x, top, x + size, bottom), fill=accent_color)
elif size >= medium_threshold:
branch_name = "medium"
if graphic_style == "tiles":
draw.ellipse((x, y, x + size, y + size), fill=base_color)
draw.line((x + size // 4, y + size // 2, x + 3 * size // 4, y + size // 2), fill=background_color, width=3)
elif graphic_style == "rings":
draw.ellipse((x, y, x + size, y + size), fill=base_color)
draw.ellipse((x + 6, y + 6, x + size - 6, y + size - 6), fill=background_color)
else:
for stripe in range(4):
left = x + stripe * size // 4
right = x + (stripe + 1) * size // 4 - 3
draw.rectangle((left, y, right, y + size), fill=base_color)
else:
branch_name = "small"
if graphic_style == "tiles":
draw.rectangle((x, y, x + size, y + size), outline=base_color, width=2)
elif graphic_style == "rings":
draw.ellipse((x, y, x + size, y + size), outline=base_color, width=2)
else:
draw.line((x, y + size // 2, x + size, y + size // 2), fill=base_color, width=3)
draw.line((x + size // 2, y, x + size // 2, y + size), fill=base_color, width=3)
branch_counts[branch_name] += 1
generation_records.append((shape_number, size, x, y, base_color, branch_name))
candidate_images.append(image)
candidate_records.append(generation_records)
candidate_branch_counts.append(branch_counts)
# 세 장을 함께 비교합니다. 미리보기만 축소하고 원본은 600 x 600으로 유지합니다.
preview = Image.new("RGB", (960, 350), background_color)
preview_draw = ImageDraw.Draw(preview)
for i in range(3):
preview.paste(candidate_images[i].resize((300, 300)), (10 + i * 320, 35))
preview_draw.text((10 + i * 320, 12), str(i + 1) + " / seed " + str(candidate_seeds[i]), fill=primary_color)
display(preview)
for i in range(3):
print("후보", i + 1, "시드", candidate_seeds[i], "분기 횟수", candidate_branch_counts[i])
generated_settings = (graphic_style, palette_name, tuple(candidate_seeds), shape_count, medium_threshold, large_threshold)세 후보 비교와 한 번의 조정
세 후보를 보고 마음에 드는 부분과 바꾸고 싶은 부분을 하나씩 적습니다. 바꾸고 싶은 인상에 맞춰 설정 하나를 조정하고, 설계값 셀과 생성 셀을 다시 실행합니다.
| 원하는 변화 | 바꿀 설정 | 비교할 것 |
|---|---|---|
| 겹침을 줄이고 여백 늘리기 | shape_count를 줄임 | 가려지는 모티프와 빈 공간 |
| 강조 모티프 줄이기 | large_threshold를 높임 | 큰 분기의 횟수와 강조색 면적 |
| 같은 배치에서 표현 바꾸기 | graphic_style만 변경 | 같은 자리의 모티프 모양 |
| 같은 구조에서 분위기 바꾸기 | palette_name만 변경 | 배경·전경의 대비 |
| 새로운 배치 탐색 | candidate_seeds 변경 | 세 후보의 강조 위치와 겹침 |
분기 횟수는 생성 횟수입니다. 큰 분기가 같아도 겹침에 따라 보이는 강조 면적은 달라질 수 있습니다. 숫자와 이미지를 함께 확인합니다.
세 후보가 모두 비슷해 보일 때
같은 규칙을 공유하므로 공통된 인상은 유지됩니다. 큰 모티프의 위치, 모티프가 몰린 구역, 가장 넓은 여백을 짚어 비교합니다. 더 큰 변화를 원하면 스타일이나 밀도를 한 번 조정합니다.
한 장 선택하고 PNG 저장
선택·저장 셀의 selected_candidate를 1, 2, 3 중 하나로 정합니다. 셀을 실행하면 고른 원본을 크게 보여 주고 week05_학번_이름_seed시드번호.png로 저장합니다. 비교용 미리보기는 축소 이미지이며, 최종 PNG는 600 × 600 원본입니다.
기본 설정에서 후보 2를 고르면 파일명에 seed73이 들어갑니다. 같은 세 후보에서 선택만 바꾸려면 후보 번호를 바꾸고 선택·저장 셀을 다시 실행하면 됩니다. 규칙을 바꿨다면 설계값 → 생성 → 선택·저장 순서로 실행합니다.
자동 검사 통과 확인
- 제출 정보 셀의 생성 규칙과 선택 이유를 완성합니다.
- 최종 후보 번호와 설정값이 저장되어 있는지 확인합니다.
- 런타임 → 세션 다시 시작 → 모두 실행을 진행합니다.
- 아래 완료 문구와 저장 파일명을 확인합니다.
자동 검사에는 아직 배우지 않은 딕셔너리·집합·파일 비교 코드가 포함되어 있습니다. 이 부분은 제공된 확인 도구입니다. 오류의 마지막 한글 안내를 읽고 해당 설정을 수정하며, 검사 코드는 그대로 둡니다. 두 설명의 내용과 이미지의 관계는 직접 확인합니다.
선택 이유를 다시 작성하라는 안내가 나올 때
“예뻐서”만 적는 대신 후보 번호와 겹침·강조·여백 중 하나를 연결해 20자 이상 설명합니다. 생성 규칙에는 무작위로 선택하는 값과 조건에 따른 표현을 포함합니다.
현재 이미지와 PNG가 다르다는 안내가 나올 때
최신 결과를 만든 뒤 선택·저장 셀도 실행했는지 확인합니다. 최종 제출 전에는 새 세션에서 모두 실행해 코드와 파일을 함께 갱신합니다.
새 세션 전체 실행 안내가 나올 때
개별 셀을 여러 번 실행한 기록이 남아 있습니다. 수정 내용을 저장하고 세션을 다시 시작한 뒤 모두 실행합니다. 자동 검사 셀은 수정하지 않습니다.
두 파일 제출
- 완료 문구를 확인합니다.
- Colab의 파일 → 다운로드 → .ipynb 다운로드로 실행 결과가 포함된 노트북을 받습니다.
- 왼쪽 파일 목록에서 선택한 시드의 PNG를 내려받습니다.
week05_학번_이름.ipynb와 최종 PNG 두 파일을 제출합니다.- 제출 완료 상태를 확인하면 남은 시간과 관계없이 귀가할 수 있습니다.
선택 확장
필수 제출을 마쳤다면 같은 시드·팔레트에서 세 표현을 차례로 적용해 한 시리즈를 만들어 봅니다. 각 결과에서 위치와 크기가 같은데도 인상이 달라지는 이유를 비교합니다. 추가 점수나 귀가 조건은 없습니다.
6주차 학습 내용
오늘은 반복문 안에서 같은 규칙으로 세 후보를 만들었습니다. 다음 주에는 이미지 한 장을 만드는 과정을 이름이 있는 함수로 묶습니다. 함수를 호출할 때 시드·개수·경계값을 전달하고, 완성된 이미지를 돌려받아 비교합니다.
| 이번 주에 사용한 것 | 다음 주에 배울 것 | 제작에 사용하는 방법 |
|---|---|---|
| 후보 한 장을 그리는 코드 | def로 함수 정의 | 생성 작업에 이름을 붙여 다시 호출 |
| 시드·개수·두 경계값 | 매개변수와 인자 | 함수를 호출할 때 작품마다 다른 값 전달 |
| 생성한 이미지 | return image | 함수 밖에서 여러 결과를 보관하고 비교·저장 |
오늘의 난수·반복·조건·Pillow 코드가 재료가 됩니다. 다음 주의 핵심은 코드를 함수로 묶는 방법, 설정값을 전달하는 방법, 결과를 함수 밖으로 돌려받는 방법입니다.
참고 자료
- Google Colab 입문노트북 업로드와 코드 셀 실행
- Python randomseed, randint, choice
- Python 조건문if·elif·else의 검사 순서
- Pillow ImageDraw사각형·원·선 그리기