Step 43. 조건문과 반복문 — 판단하고 반복하는 코드
Level 1 — 프로그래밍과 컴퓨터 내부 | 난이도 ★★☆☆☆ | 예상 소요 시간 3.5시간
전제: Step 41~42를 마쳤다. 변수, 입출력, 리스트와 딕셔너리를 다룰 수 있다.
- 준비물: Step 41의 작업대(파이썬 + VSCode), Step 42의 바구니 지식.
- 주의: 오늘 실습은 100% 안전합니다. 다만 무한 반복 실험에서 프로그램이 멈추지 않을 수 있는데,
Ctrl + C로 끄면 됩니다.
지금까지의 프로그램은 위에서 아래로 한 줄씩 곧장 흘렀습니다. 그런데 세상의 일은 곧장만 흐르지 않습니다. "비가 오면 우산을 챙기고, 아니면 그냥 나간다"(판단), "불이 꺼질 때까지 계속 두드린다"(반복). 프로그램이 진짜 일을 하려면 이 두 갈래길이 필요합니다. 오늘 배우는 if(조건 갈림길)와 for/while(반복)이 그것입니다. 포트 65,535개를 손으로 확인할 수 없으니 반복문이 대신 돌고, 로그 백만 줄을 눈으로 볼 수 없으니 조건문이 "수상한 줄"만 걸러 냅니다. 오늘의 구구단과 숫자 게임은 그 뼈대의 연습판입니다.
1. 학습 목표
이 챕터를 끝내면 다음을 할 수 있습니다:
if/elif/else로 조건에 따라 다르게 행동하는 프로그램을 쓴다- 들여쓰기(스페이스 4칸) 규칙을 지키고 IndentationError를 해결한다
for와range()로 정해진 횟수·목록 반복을 만든다while과break/continue로 조건 탈출 반복을 만든다- 비교 연산자(
==,!=)와 논리 연산자(and/or/not)를 구분해 쓴다 - "목록을 돌며 조건으로 걸러내는" 로그 필터 패턴을 조립한다
2. 배경 지식 — 오늘의 도구와 개념
오늘의 도구 한눈에 보기
| 구분 | 내용 |
|---|---|
| 언어·환경 | 파이썬 3.12 이상, VSCode (Step 41의 작업대) |
| 오늘의 명령어·문법 | if/elif/else, 들여쓰기, for ~ in, range(), while, break, continue, ==/!=/</>=, and/or/not, %(나머지) |
| 필요한 개념 | 조건식(참/거짓), 코드 블록과 소속, 경계값 테스트, 무한 루프와 Ctrl+C |
2-1. if — 갈림길의 표지판
if는 "만약 ~라면"입니다.
if 점수 >= 60:
print("합격")
조건(점수 >= 60)이 참이면 들여쓰기된 줄을 실행하고, 거짓이면 건너뜁니다. 갈림길이 여럿이면 elif(else if, "아니면 만약")를 이어 붙이고, 전부 아닐 때는 else가 받습니다. 마지막 else는 안전망입니다. 어떤 값이 와도 받아 주는 곳이 하나는 있어야 프로그램이 허공에 떨어지지 않습니다.
2-2. 들여쓰기 — 파이썬의 소속 증명서
파이썬에는 다른 언어의 { }(중괄호)가 없습니다. 대신 들여쓰기(indentation, 스페이스 4칸)가 "이 줄은 if의 소속입니다"를 표시합니다.
if 점수 >= 60:
print("합격") # if의 소속 (4칸 들여쓰기)
print("축하해요") # 역시 if의 소속
print("수고했어요") # 들여쓰기 없음 — if와 무관, 항상 실행
들여쓰기가 곧 소속 증명서입니다. 칸 수가 틀어지면 파이썬은 실행을 거부합니다. 처음엔 까다롭게 느껴지지만, 이 규칙 덕분에 파이썬 코드는 누가 써도 줄이 반듯하게 맞습니다.
2-3. for — 바구니의 것들을 하나씩
for는 "이 바구니의 것들을 하나씩 꺼내서 반복"입니다.
for ip in ["1.1.1.1", "8.8.8.8"]:
print(ip + " 확인 중...")
Step 42의 리스트가 여기서 빛을 발합니다. "백 개의 IP를 하나씩 확인" 같은 일이 두 줄로 끝납니다. 횟수로 반복하고 싶으면 range()를 씁니다. for i in range(5):는 i가 0, 1, 2, 3, 4로 바뀌며 다섯 번 돕니다 — 0부터 세고 끝 번호는 빠진다는, 슬라이싱과 같은 규칙입니다.
2-4. while — 조건이 끝날 때까지
while은 "조건이 참인 동안 계속"입니다.
count = 0
while count < 3:
print("아직 부족해")
count = count + 1
횟수를 미리 모르는 반복에 씁니다. 단, 조건이 영원히 참이면 영원히 돕니다(무한 루프). 그래서 while 안에는 언젠가 조건을 거짓으로 만들 장치(위 예시의 카운터 증가)가 반드시 있어야 합니다.
2-5. 비교와 논리 연산자
"같다"를 묻는 비교는 등호 두 개(==)입니다. 등호 하나(=)는 대입(이름표 붙이기)이라 뜻이 완전히 다릅니다. "같지 않다"는 !=입니다. 조건을 묶을 때는 and(둘 다 참), or(하나라도 참), not(뒤집기)을 씁니다. %는 나눗셈의 나머지로, i % 2 == 0이면 짝수라는 판별식입니다.
3. 따라 하기
3-1. 첫 갈림길 — 합격 판정기
grade.py 파일을 만듭니다.
score = int(input("점수는? "))
if score >= 60:
print("합격입니다!")
else:
print("아쉽지만 불합격입니다.")
실행해 봅니다 (2026-09-09 실측):
점수는? 72
합격입니다!
60을 넣어도 "합격입니다!"가 나옵니다 (같은 날 실측). >=는 "이상"이라 60도 포함하기 때문입니다.
읽는 법: 조건 뒤의 콜론(:)을 잊지 마세요. 콜론은 "이제 소속 줄들이 나옵니다"라는 신호이고, else에도 붙습니다. 그리고 방금 한 것처럼 경계값(딱 기준선인 60)을 시험해 보는 것은 프로그래머의 기본 버릇입니다. 조건문의 버그는 대부분 경계에서 숨어 있습니다.
3-2. 여러 갈림길 — 등급 나누기
score = int(input("점수는? "))
if score >= 90:
print("A")
elif score >= 80:
print("B")
elif score >= 70:
print("C")
else:
print("F")
점수는? 95
A
(2026-09-09 실측.)
읽는 법: 위에서부터 차례로 묻고, 하나라도 참이면 나머지는 묻지 않습니다. 95점은 첫 문에서 A를 받고 끝납니다. 순서가 중요합니다 — 실측으로 확인해 보면, 조건 순서를 뒤집어 70부터 묻는 코드에 90점을 넣으면 C가 나옵니다 (2026-09-09 실측). 조건은 좁은 것(높은 기준)부터 쓰는 것이 요령입니다.
3-3. for와 리스트 — 바구니 자동 처리
targets = ["192.168.0.1", "192.168.0.10", "192.168.0.20"]
for t in targets:
print(t + " 에 연결 시도 중...")
print("전부 확인 완료")
192.168.0.1 에 연결 시도 중...
192.168.0.10 에 연결 시도 중...
192.168.0.20 에 연결 시도 중...
전부 확인 완료
(2026-09-09 실측.)
읽는 법: 마지막 줄은 들여쓰기가 없으므로 반복이 끝난 뒤 한 번만 실행됩니다. 들여쓰기 칸 수 하나로 "매번 할 일"과 "끝나고 할 일"이 갈립니다. 이 구분이 오늘의 핵심 감각입니다. 이 패턴(목록 + for + 하나씩 처리)은 스캔 스크립트, 로그 분석, 파일 일괄 처리의 표준 골격입니다.
3-4. range와 구구단
dan = int(input("몇 단? "))
for i in range(1, 10):
print(f"{dan} x {i} = {dan * i}")
몇 단? 7
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
(2026-09-09 실측.)
읽는 법: range(1, 10)은 1부터 10 앞까지, 즉 1~9입니다. f-string 안에서 dan * i처럼 계산식도 바로 쓸 수 있습니다. 세 번째 재료까지 쓰면 range(2, 10, 2)는 2, 4, 6, 8을 만듭니다 (2026-09-09 실측) — 세 번째 숫자는 "간격"입니다.
3-5. while과 break — 숫자 맞추기 게임
오늘의 하이라이트입니다. game.py를 만듭니다.
answer = 42
while True:
guess = int(input("숫자를 맞혀 보세요 (1~100): "))
if guess == answer:
print("정답! 축하합니다!")
break
elif guess < answer:
print("더 큰 숫자입니다 (UP)")
else:
print("더 작은 숫자입니다 (DOWN)")
실행 예시 (10 → 50 → 42를 입력) — 2026-09-09 실측:
숫자를 맞혀 보세요 (1~100): 10
더 큰 숫자입니다 (UP)
숫자를 맞혀 보세요 (1~100): 50
더 작은 숫자입니다 (DOWN)
숫자를 맞혀 보세요 (1~100): 42
정답! 축하합니다!
읽는 법: while True:는 조건이 항상 참이라 원칙적으로 무한 반복이고, break(반복 탈출)가 정답 순간에 문을 열어 줍니다. "무한히 돌되, 조건 충족 시 탈출"은 게임·대기·재시도 로직의 표준 패턴입니다. ==(비교)와 =(대입)의 구분도 다시 확인하세요. 이 열 줄에 if·elif·else·while·break·비교가 전부 들어 있습니다.
3-6. continue와 조건 묶기
반복 중 "이번 차례만 건너뛰기"는 continue입니다.
for i in range(1, 11):
if i % 2 == 0: # 짝수이면
continue # 이번 차례는 건너뛰기
print(i)
1
3
5
7
9
(2026-09-09 실측.)
읽는 법: i % 2 == 0은 "2로 나눈 나머지가 0", 즉 짝수 판별의 정석 표현입니다. break는 반복 전체 탈출, continue는 이번 바퀴만 탈출입니다. 둘의 차이를 몸으로 구분해 두세요.
조건 묶기도 확인합니다.
age = int(input("나이는? "))
member = input("회원이니? (y/n) ")
if age >= 20 and member == "y":
print("성인 회원이시군요. 환영합니다!")
and는 두 조건이 모두 참일 때만 통과입니다. or로 바꿔 실행해 보고 차이를 확인하세요.
3-7. 실전 미니 프로젝트 — 수상한 로그 줄 걸러내기
오늘 배운 것을 한 프로그램에 담습니다. 가짜 로그에서 "수상한 줄"만 걸러내는 필터입니다. filter.py:
logs = [
"192.168.0.5 GET /index.html 200",
"10.0.0.7 GET /admin 404",
"192.168.0.5 GET /style.css 200",
"10.0.0.7 GET /admin/login 404",
"192.168.0.9 GET /index.html 200",
"10.0.0.7 POST /admin/delete 403",
]
count = 0
for line in logs:
parts = line.split(" ")
ip = parts[0]
path = parts[2]
status = parts[3]
if "admin" in path and status != "200":
count = count + 1
print(f"수상함: {ip} 이(가) {path} 시도 -> {status}")
print(f"총 {count}건의 수상한 접근을 발견했습니다.")
수상함: 10.0.0.7 이(가) /admin 시도 -> 404
수상함: 10.0.0.7 이(가) /admin/login 시도 -> 404
수상함: 10.0.0.7 이(가) /admin/delete 시도 -> 403
총 3건의 수상한 접근을 발견했습니다.
(2026-09-09 실측.)
읽는 법: Step 42의 split과 인덱스, 오늘의 for와 if, and 조합, 카운터 패턴(count = count + 1)이 전부 들어 있습니다. !=는 "같지 않다"입니다. 이 스무 줄이 로그 분석 스크립트의 알몸 뼈대입니다.
예측 후 확인: 조건을
status == "403"만으로 바꾸면 몇 건이 걸릴까요? 실행 전에 노트에 적고 확인하세요. 조건 하나의 차이가 결과를 어떻게 바꾸는지 체감하는 훈련입니다.
4. 미션과 연습문제
미션 — 업그레이드 숫자 맞추기 게임
3-5의 게임에 다음 세 가지를 추가해 game2.py를 완성하세요.
- 정답이 매번 바뀌게 한다. 힌트: 파일 맨 위에
import random을 쓰고,answer = random.randint(1, 100)으로 바꾼다.import는 남이 만든 부품을 가져오는 것이고,random은 파이썬 기본 부품입니다. - 시도 횟수를 세어 정답 시
5번 만에 맞혔습니다!처럼 출력한다. 힌트:while위에tries = 0을 만들고, 추측할 때마다tries = tries + 1. - 7번을 넘기면
기회 종료!를 출력하고 끝낸다. 힌트:tries >= 7조건과break.
세 요구사항을 모두 달성한 뒤, 일부러 7번을 틀려 보고 종료 경로도 확인하세요.
연습문제
문제 1. 아래 코드에서 print("끝")은 몇 번 실행되며, 그 이유를 들여쓰기로 설명해 보세요.
for i in range(3):
print(i)
print("끝")
문제 2. if guess = answer:가 왜 오류인지, 그리고 실제로 어떤 오류가 나는지 답해 보세요.
문제 3. while True:로 만든 반복이 영원히 끝나지 않으려면 어떤 장치가 필요한가요? 그 장치가 없는 프로그램이 멈추지 않을 때 터미널에서 어떻게 끄나요?
문제 4. 점수가 90점일 때 if score >= 70: ... elif score >= 80: ... elif score >= 90: ... 순서로 쓰면 어느 등급이 나오며, 왜 그런가요? 올바른 작성 요령은 무엇인가요?
5. 모범 답안과 완료 기준
미션 모범 답안
import random
answer = random.randint(1, 100)
tries = 0
while True:
guess = int(input("숫자를 맞혀 보세요 (1~100): "))
tries = tries + 1
if tries >= 7:
print("기회 종료!")
break
if guess == answer:
print(f"정답! {tries}번 만에 맞혔습니다!")
break
elif guess < answer:
print("더 큰 숫자입니다 (UP)")
else:
print("더 작은 숫자입니다 (DOWN)")
해설: ① random.randint(1, 100)은 1~100 사이의 정수를 매번 다르게 뽑습니다. ② tries는 반복 밖에서 0으로 시작해 추측 한 번에 1씩 늘어나는 카운터 패턴입니다. ③ 기회 소진 검사를 추측 직후에 둬야 "7번째 입력"까지는 판정할 수 있습니다. 순서를 바꿔 보며 규칙을 시험해 보는 것도 좋은 연습입니다.
검증하는 법: ① 두 번 실행해 정답이 달라지는지 봅니다. ② 정답을 맞힐 때까지 입력해 횟수 문구가 나오는지 봅니다. ③ 일부러 엉뚱한 숫자만 7번 넣어 "기회 종료!"가 나오고 프로그램이 끝나는지 봅니다. 세 경로가 모두 확인되면 완료입니다.
연습문제 해답
문제 1 해답. 한 번 실행됩니다. print("끝")은 들여쓰기가 없으므로 for의 소속이 아니라, 반복이 끝난 뒤 한 번 실행되는 독립 줄입니다. print(i)만 0, 1, 2 세 번 출력됩니다.
문제 2 해답. =는 대입(이름표 붙이기)이고 비교는 ==인데, 파이썬은 if 안의 대입을 아예 오류로 막아 줍니다. 실제 오류는 이렇습니다 (2026-09-09 실측):
File "...\s43_eqeq.py", line 3
if guess = answer:
^^^^^^^^^^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
"아마 ==을 쓰려던 것 아니냐"는 추천까지 붙는 것이 최근 파이썬의 친절입니다.
문제 3 해답. 반복 안에 언젠가 조건을 거짓으로 만들 장치(카운터 증가) 또는 break가 필요합니다. 장치 없이 멈추지 않는 프로그램은 터미널에서 Ctrl + C로 강제 중단합니다. "지금 도는 프로그램 멈춰"라는 긴급 브레이크입니다.
문제 4 해답. C가 나옵니다. 위에서부터 차례로 묻는데 90은 첫 조건 >= 70을 바로 통과해 버리고, 한 번 통과하면 나머지는 묻지 않기 때문입니다 (2026-09-09 실측). 요령은 좁은 조건(높은 기준)부터 위에 쓰는 것입니다.
완료 기준 체크리스트
- [ ]
if/elif/else로 갈림길을 만들고, 조건은 좁은 것부터 쓴다 - [ ] 들여쓰기(스페이스 4칸)로 소속을 표현하고 IndentationError를 고칠 수 있다
- [ ]
for+ 리스트,for+range()두 반복을 모두 쓸 수 있다 - [ ]
while True+break로 "조건 충족 시 탈출" 패턴을 만들 수 있다 - [ ]
break(전체 탈출)와continue(이번 바퀴 탈출)의 차이를 안다 - [ ]
==와=를 구분하고, 경계값(60점 등)을 시험하는 버릇을 안다 - [ ] 미션(game2.py)의 세 요구사항을 모두 완성하고 세 경로를 검증했다
6. 흔한 실수와 해결
벽 1. IndentationError가 난다
증상 (2026-09-09 실측):
File "...\s43_indent.py", line 3
print("합격")
^^^^^
IndentationError: expected an indented block after 'if' statement on line 2
원인: if의 콜론 다음 줄을 들여쓰지 않았거나, 스페이스와 탭을 섞어 쓴 경우입니다. 메시지 속 "2번째 줄의 if 뒤에 들여쓴 블록이 필요하다"가 그대로 진단입니다.
해결: if/for/while의 콜론 다음 줄은 무조건 스페이스 4칸. VSCode의 들여쓰기 안내선을 기준으로 줄을 맞추고, 탭이 섞였으면 지우고 스페이스로만 다시 씁니다.
벽 2. 무한 루프에 빠졌다
증상: 프로그램이 끝나지 않고 같은 것을 계속 출력합니다.
원인: while의 조건이 영원히 참인데 break도 없거나, 조건을 바꾸는 줄(카운터 증가)을 빠뜨린 것입니다.
해결: Ctrl + C로 강제 중단합니다. 그리고 while 안에 "언젠가 조건을 거짓으로 만드는 줄"이 있는지 확인합니다.
벽 3. =와 ==를 헷갈린다
증상: if guess = answer:에서 SyntaxError (실측 메시지는 5번 섹션 문제 2 참조).
원인: if 안에서 대입(=)을 한 것입니다. 비교는 ==입니다.
해결: "같니? ==, 붙여라 ="로 외우세요. 등호가 두 개여야 묻는 문장, 하나면 시키는 문장입니다.
벽 4. 조건이 항상 else로 빠진다
증상: 분명 90점을 넣었는데 F가 나옵니다.
원인: 대표적으로 두 가지입니다. 점수를 int()로 변환하지 않아 글자끼리 비교가 되었거나(Step 41의 함정), 조건 순서가 뒤집힌 경우입니다.
해결: print(type(score))로 변수가 숫자(<class 'int'>)인지 글자(<class 'str'>)인지 확인합니다 (2026-09-09 실측: 각각 <class 'str'>, <class 'int'>로 출력 확인). type()은 "이 상자의 내용물 종류가 뭐니?"라고 묻는 함수입니다. 그리고 조건은 좁은 것부터 위에 썼는지 점검합니다.
벽 5. 코드가 뜻대로 안 도는데 원인을 모르겠다
증상: 오류는 없는데 결과가 이상합니다.
원인: 내 머릿속 실행 순서와 파이썬의 실제 실행 순서가 다른 것입니다.
해결: 초보가 쓸 수 있는 가장 강력한 디버깅 도구는 print입니다. "여기서 변수가 뭐지?" 하는 지점에 print(f"i는 지금 {i}")를 넣어 보세요. 실행 흐름과 값의 변화가 그대로 보입니다. 전문가의 디버거도 결국 하는 일은 같습니다 — 멈추고, 들여다보고, 한 줄씩 확인하기.
7. 정리
오늘의 개념
| 개념 | 한 줄 설명 |
|---|---|
| 조건식 | 참/거짓으로 답하는 문장 (score >= 60) |
| 들여쓰기 | 스페이스 4칸 — 파이썬의 소속 증명서 |
| 코드 블록 | 같은 들여쓰기로 묶인 소속 줄들 |
| 카운터 패턴 | count = 0 후 count = count + 1로 세기 |
| 무한 루프 | 조건이 영원히 참인 반복 — Ctrl+C로 중단 |
| 경계값 테스트 | 기준선 그 자체(60점 등)를 시험하는 버릇 |
오늘의 문법
| 문법 | 하는 일 |
|---|---|
if / elif / else |
조건 갈림길 — 좁은 것부터, 끝은 안전망 |
for x in 리스트: |
바구니의 것들을 하나씩 반복 |
range(a, b) / range(a, b, 간격) |
a부터 b 앞까지의 숫자 나열 |
while 조건: |
조건이 참인 동안 반복 |
break / continue |
반복 전체 탈출 / 이번 바퀴만 탈출 |
==, !=, <, >= |
비교 (대입 =와 구분) |
and / or / not |
조건 묶기 / 뒤집기 |
% |
나머지 — i % 2 == 0이면 짝수 |
문법보다 중요한 감각
보안 스크립트의 뼈대는 "목록을 돌며(for) 조건으로 걸러내는(if)" 것이고, 오늘의 로그 필터가 그 알몸 모습입니다. 구구단과 숫자 게임이 장난 같아 보여도, 그 구조는 수만 줄짜리 분석 도구와 정확히 같습니다. 자동화는 힘을 증폭시키므로 방향이 더욱 중요합니다. 모든 공격 실습은 내 랩·합법 플랫폼에서만. 실서비스 무단 공격은 범죄입니다.
조건과 반복은 재능이 아니라 근육입니다. 오늘 친 코드 한 줄 한 줄이 그 근육의 첫 세트입니다.
전부 체크되면 Step 43 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.