[Python 100일 챌린지] Day 21 - 조건문 if - 심화
Day 8에서 if-elif-else 문법을 배웠죠? 🤔 ──이제는 “왜 그렇게 동작하는가”를 파헤칠 차례입니다. 😊
if-elif-else는 단순해 보이지만, 실전에서는 생각보다 함정이 많습니다. 예를 들어, 성적 계산에서 “90점 이상은 A”인데 왜 B가 나올까요? 할인율 계산에서 조건 순서만 바꿨는데 왜 결과가 달라질까요?
Day 8이 “if문 사용법”을 배웠다면, 오늘은 “if문을 제대로 쓰는 법”을 마스터합니다. 삼항 연산자로 코드를 1줄로 줄이는 법까지 함께요! 💡
(20분 완독 ⭐⭐)
🎯 오늘의 학습 목표
📚 사전 지식
- Day 8: 조건문 if - 기본 if문 이해
- Day 14: 불린 (bool) - 참과 거짓 - True/False 값과 비교 연산자
🔄 Day 8에서 배운 것 vs 오늘 배울 것
Day 8 (기초편)에서는:
- if, elif, else 문법을 배웠습니다
- 비교 연산자와 논리 연산자 사용법을 익혔습니다
- 중첩 if문을 어떻게 쓰는지 알았습니다
Day 21 (심화편)에서는:
- if-elif-else가 왜 그렇게 동작하는지 이해합니다
- 조건 순서가 결과에 미치는 영향을 배웁니다
- 코드를 더 짧고 효율적으로 작성하는 법을 익힙니다
- 삼항 연산자로 1줄 코드를 만드는 법을 배웁니다
💡 Day 8이 “자전거 타는 법”이라면, Day 21은 “자전거를 잘 타는 법”입니다!
🎯 학습 목표 1: if-elif-else 흐름을 완벽히 이해하기
if-elif-else의 동작 방식
1
2
3
4
5
6
7
8
age = 25
if age >= 18:
print("성인입니다")
elif age >= 13:
print("청소년입니다")
else:
print("어린이입니다")
실행 순서:
- ✅
age >= 18체크 → True → “성인입니다” 출력 → 종료 - ⏭️ elif와 else는 실행되지 않음 (건너뜀)
💡 중요: if 조건이 True면 나머지는 무시됩니다!
조건 순서의 중요성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
score = 95
# ❌ 잘못된 순서
if score >= 60:
grade = "D" # 95 >= 60이므로 여기서 끝!
elif score >= 90:
grade = "A" # 실행 안 됨
print(grade) # D (잘못된 결과!)
# ✅ 올바른 순서 (큰 값부터!)
if score >= 90:
grade = "A" # 95 >= 90이므로 A
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
else:
grade = "D"
print(grade) # A (정확!)
🎯 학습 목표 2: 중첩 조건문과 논리 연산자 비교하기
기본 중첩
1
2
3
4
5
6
7
8
9
10
11
12
13
age = 25
has_license = True
# 중첩된 if문
if age >= 18:
print("성인입니다")
if has_license:
print("운전 가능합니다")
else:
print("면허를 취득하세요")
else:
print("미성년자입니다")
print("운전 불가능합니다")
출력:
1
2
성인입니다
운전 가능합니다
중첩 vs 논리 연산자
중첩 조건문:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
age = 25
has_license = True
has_car = True
if age >= 18:
if has_license:
if has_car:
print("운전하실 수 있습니다")
else:
print("차량이 필요합니다")
else:
print("면허가 필요합니다")
else:
print("나이가 부족합니다")
논리 연산자 사용 (더 깔끔!):
1
2
3
4
5
6
7
8
9
10
11
12
age = 25
has_license = True
has_car = True
if age >= 18 and has_license and has_car:
print("운전하실 수 있습니다")
elif age >= 18 and has_license:
print("차량이 필요합니다")
elif age >= 18:
print("면허가 필요합니다")
else:
print("나이가 부족합니다")
💡 가독성 팁: 3단계 이상 중첩되면 논리 연산자 사용을 고려하세요!
🎯 학습 목표 3: 삼항 연산자로 간결하게 작성하기
기본 형태
일반 if문 (4줄):
1
2
3
4
5
6
7
8
age = 20
if age >= 18:
status = "성인"
else:
status = "미성년"
print(status) # 성인
삼항 연산자 (1줄):
1
2
3
age = 20
status = "성인" if age >= 18 else "미성년"
print(status) # 성인
문법: 참일때값 if 조건 else 거짓일때값
실전 활용 예제
예제 1: 짝수/홀수 판별
1
2
3
4
5
6
7
8
9
10
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 리스트 컴프리헨션과 함께
labels = ["짝수" if n % 2 == 0 else "홀수" for n in numbers]
print(labels)
# ['홀수', '짝수', '홀수', '짝수', '홀수', '짝수', '홀수', '짝수', '홀수', '짝수']
# 결과를 바로 출력
for n in numbers:
print(f"{n}은(는) {'짝수' if n % 2 == 0 else '홀수'}입니다")
예제 2: 최댓값/최솟값
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a = 10
b = 20
# 최댓값
max_value = a if a > b else b
print(f"최댓값: {max_value}") # 20
# 최솟값
min_value = a if a < b else b
print(f"최솟값: {min_value}") # 10
# ⚠️ 복잡한 예 (권장하지 않음 - 너무 어려움!)
x, y, z = 15, 8, 23
max_of_three = x if (x > y and x > z) else (y if y > z else z)
print(f"최댓값: {max_of_three}") # 23
# 💡 이런 복잡한 경우는 일반 if문이 더 좋습니다
예제 3: 리스트 필터링
1
2
3
4
5
6
7
8
9
numbers = [-5, 3, -2, 8, -10, 6, 0, -1, 4]
# 음수는 0으로 변환
positive_only = [n if n > 0 else 0 for n in numbers]
print(positive_only) # [0, 3, 0, 8, 0, 6, 0, 0, 4]
# 절댓값 변환
absolute_values = [n if n >= 0 else -n for n in numbers]
print(absolute_values) # [5, 3, 2, 8, 10, 6, 0, 1, 4]
🔀 여러 조건 체크하기
범위 체크
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
score = 85
# 방법 1: 여러 elif 사용
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
print(f"점수 {score}점: {grade}등급") # 점수 85점: B등급
# 방법 2: and 사용
if 90 <= score <= 100:
grade = "A"
elif 80 <= score < 90:
grade = "B"
elif 70 <= score < 80:
grade = "C"
elif 60 <= score < 70:
grade = "D"
else:
grade = "F"
💡 Python의 특별한 기능:
80 <= score < 90처럼 범위를 직관적으로 쓸 수 있습니다!
여러 값 중 하나인지 체크 (in 연산자)
1
2
3
4
5
6
7
8
9
10
11
12
13
# ❌ 비효율적인 방법
fruit = "apple"
if fruit == "apple" or fruit == "banana" or fruit == "grape" or fruit == "orange":
print("과일입니다")
# ✅ 리스트로 체크 (더 깔끔)
if fruit in ["apple", "banana", "grape", "orange"]:
print("과일입니다")
# ✅✅ 세트로 체크 (가장 빠름!)
fruits = {"apple", "banana", "grape", "orange"}
if fruit in fruits:
print("과일입니다")
성능 비교:
or연결: 각각 비교 (많으면 느림)in [리스트]: 앞에서부터 하나씩 찾음in {세트}: 빠르게 찾음 ⚡ (데이터가 많을수록 차이 큼)
💡 지금은 “세트가 빠르다”만 기억하세요! 자세한 이유는 나중에 배웁니다.
실전 예제: 사용자 권한 체크
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def check_permission(user_role):
"""사용자 권한에 따른 접근 가능한 메뉴"""
admin_menus = {"대시보드", "사용자관리", "설정", "통계", "로그"}
manager_menus = {"대시보드", "통계", "보고서"}
user_menus = {"대시보드"}
if user_role == "admin":
return admin_menus
elif user_role == "manager":
return manager_menus
elif user_role == "user":
return user_menus
else:
return set() # 빈 세트
# 테스트
user = "manager"
accessible_menus = check_permission(user)
print(f"{user}가 접근 가능한 메뉴: {accessible_menus}")
# 특정 메뉴 접근 가능한지 체크
menu = "사용자관리"
if menu in accessible_menus:
print(f"{menu} 접근 가능")
else:
print(f"{menu} 접근 불가")
🎯 학습 목표 4: 조건문 최적화 패턴 익히기
패턴 1: Early Return (Guard Clauses)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# ❌ 나쁜 예: 깊은 중첩
def process(value):
if value is not None:
if value > 0:
if value < 100:
result = value * 2
return result
return None
# ✅ 좋은 예: Early Return
def process(value):
# 잘못된 입력은 먼저 처리하고 반환
if value is None:
return None
if value <= 0:
return None
if value >= 100:
return None
# 정상 로직은 깊이 1단계에서 처리
return value * 2
# 테스트
print(process(50)) # 100
print(process(None)) # None
print(process(-5)) # None
print(process(150)) # None
장점:
- 코드를 읽기 쉬워집니다 (들여쓰기가 적음)
- 에러 케이스를 먼저 처리해서 안전합니다
- 정상 로직이 더 명확히 보입니다
패턴 2: 딕셔너리 매핑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# ❌ 나쁜 예: 긴 if-elif 체인
def get_weekday_old(num):
if num == 0:
return "월요일"
elif num == 1:
return "화요일"
elif num == 2:
return "수요일"
elif num == 3:
return "목요일"
elif num == 4:
return "금요일"
elif num == 5:
return "토요일"
elif num == 6:
return "일요일"
else:
return "잘못된 요일"
# ✅ 좋은 예: 딕셔너리 사용
def get_weekday(num):
days = {
0: "월요일",
1: "화요일",
2: "수요일",
3: "목요일",
4: "금요일",
5: "토요일",
6: "일요일"
}
return days.get(num, "잘못된 요일")
# 더 간단하게
WEEKDAYS = ["월요일", "화요일", "수요일", "목요일", "금요일", "토요일", "일요일"]
def get_weekday_simple(num):
if 0 <= num < 7:
return WEEKDAYS[num]
return "잘못된 요일"
# 테스트
for i in range(8):
print(f"{i}: {get_weekday(i)}")
패턴 3: 함수 딕셔너리 (전략 패턴) 🌟 심화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return "0으로 나눌 수 없습니다"
return a / b
# ❌ 나쁜 예
def calculate_old(a, b, operator):
if operator == "+":
return add(a, b)
elif operator == "-":
return subtract(a, b)
elif operator == "*":
return multiply(a, b)
elif operator == "/":
return divide(a, b)
else:
return "잘못된 연산자"
# ✅ 좋은 예: 함수를 딕셔너리 값으로
def calculate(a, b, operator):
operations = {
"+": add, # 함수를 값으로 저장! (Phase 3 후반에 배움)
"-": subtract,
"*": multiply,
"/": divide
}
# 연산자가 있으면 해당 함수 실행
if operator in operations:
return operations[operator](a, b)
return "잘못된 연산자"
# 테스트
print(calculate(10, 5, "+")) # 15
print(calculate(10, 5, "-")) # 5
print(calculate(10, 5, "*")) # 50
print(calculate(10, 5, "/")) # 2.0
print(calculate(10, 0, "/")) # 0으로 나눌 수 없습니다
💡 실전 팁 & 주의사항
Tip 1: 조건 순서 (큰 값부터 체크)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
score = 75
# ❌ 잘못된 순서 (넓은 범위가 먼저)
if score >= 60:
print("D") # 75 >= 60이므로 여기서 끝!
elif score >= 70:
print("C") # 실행 안 됨!
elif score >= 80:
print("B")
# 결과: D (잘못됨)
# ✅ 올바른 순서 (좁은 범위가 먼저)
if score >= 80:
print("B")
elif score >= 70:
print("C") # 이게 실행됨!
elif score >= 60:
print("D")
# 결과: C (정확함)
Tip 2: 삼항 연산자는 간단할 때만
1
2
3
4
5
6
7
8
9
10
11
12
# ❌ 너무 복잡한 삼항 연산자
result = "A" if score >= 90 else ("B" if score >= 80 else ("C" if score >= 70 else "F"))
# ✅ 이럴 땐 일반 if문 사용
if score >= 90:
result = "A"
elif score >= 80:
result = "B"
elif score >= 70:
result = "C"
else:
result = "F"
💡 가독성 원칙: 삼항 연산자는 간단한 경우에만! 복잡하면 일반 if문 사용
Tip 3: 논리 연산자 우선순위 (괄호로 명확하게)
1
2
3
4
5
6
7
8
9
10
11
12
# ❌ 의도와 다를 수 있음
age = 25
has_license = False
# and가 or보다 우선순위가 높음!
if age >= 18 or age < 65 and has_license:
print("조건 만족")
# 실제 평가: age >= 18 or (age < 65 and has_license)
# ✅ 명확하게 괄호 사용
if (age >= 18 or age < 65) and has_license:
print("조건 만족")
Tip 4: 조건 디버깅 (print로 값 확인)
1
2
3
4
5
6
7
8
9
10
# 조건이 예상대로 동작하지 않을 때
age = 15
# 디버깅: 값과 조건 결과 출력
print(f"나이: {age}, 18 이상?: {age >= 18}") # False 확인
if age >= 18:
print("성인")
else:
print("미성년") # 이유를 알 수 있음
Tip 5: elif vs 여러 if (실행 차이 이해)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
score = 85
# 패턴 1: elif (하나만 실행) - 상호 배타적 조건
if score >= 90:
print("A")
elif score >= 80:
print("B") # 이것만 실행
elif score >= 70:
print("C")
# 패턴 2: 여러 if (모두 체크) - 독립적 조건
if score >= 90:
print("우수")
if score >= 80:
print("우수") # 실행됨
if score >= 70:
print("보통") # 실행됨
💡 용도: 하나만 실행하려면 elif, 모든 조건을 확인하려면 여러 if
🧪 연습 문제
문제 1: 상세 BMI 계산기 (Pattern 1: 요구사항 → 힌트 → 정답)
요구사항:
다음 기능을 가진 BMI 계산 함수를 만들어보세요:
- 키(미터 단위)와 몸무게(kg)를 입력받아 BMI 계산
- 입력값 검증 (0 이하 값 거부)
- BMI 범위별 판정 출력:
- 18.5 미만: 저체중
- 18.5~23 미만: 정상
- 23~25 미만: 과체중
- 25~30 미만: 경도 비만
- 30 이상: 중등도 이상 비만
- 각 판정에 맞는 건강 조언 메시지 반환
실행 예시:
1
2
3
4
키: 1.75m, 체중: 70kg
BMI: 22.9
판정: 정상
조언: 건강한 체중입니다!
💡 힌트
단계별 접근 방법:
- BMI 계산 공식:
체중(kg) / (키(m) ** 2) - 입력 검증은 함수 시작 부분에서 처리 (Early Return 패턴)
- elif를 사용해 범위를 좁은 것부터 체크
- 각 조건마다 category와 advice를 다르게 설정
- 튜플로 (bmi, category, advice) 반환
체크 포인트:
- ✅ 0 이하 입력값 처리했나요?
- ✅ BMI 범위 경계값이 정확한가요?
- ✅ 모든 범위를 빠짐없이 처리했나요?
✅ 정답 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def calculate_bmi_detailed(height, weight):
"""
BMI 계산 및 상세 판정
- 입력 검증 포함
- 건강 조언 포함
"""
# 입력 검증 (Early Return)
if height <= 0 or weight <= 0:
return None, "잘못된 입력값", ""
# BMI 계산
bmi = weight / (height ** 2)
# BMI 판정 (좁은 범위부터 체크)
if bmi < 18.5:
category = "저체중"
advice = "영양 섭취를 늘리세요"
elif bmi < 23:
category = "정상"
advice = "건강한 체중입니다!"
elif bmi < 25:
category = "과체중"
advice = "가벼운 운동을 시작하세요"
elif bmi < 30:
category = "경도 비만"
advice = "식단 조절과 운동이 필요합니다"
else:
category = "중등도 이상 비만"
advice = "전문가 상담을 권장합니다"
return bmi, category, advice
# 테스트
height = 1.75 # 미터
weight = 70 # 킬로그램
bmi, category, advice = calculate_bmi_detailed(height, weight)
if bmi:
print(f"키: {height}m, 체중: {weight}kg")
print(f"BMI: {bmi:.1f}")
print(f"판정: {category}")
print(f"조언: {advice}")
출력:
1
2
3
4
키: 1.75m, 체중: 70kg
BMI: 22.9
판정: 정상
조언: 건강한 체중입니다!
문제 2: 시간대별 인사말 시스템 (Pattern 2: 빈칸 채우기)
문제 설명:
다음 코드의 빈 칸(____)을 채워서 시간대별 인사말 함수를 완성하세요.
시간대 기준:
- 새벽: 5~6시
- 아침: 7~11시
- 점심: 12~13시
- 오후: 14~17시
- 저녁: 18~21시
- 밤: 22~4시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def greet_by_time(hour, name=""):
"""
시간대별 맞춤 인사말
"""
# 입력 검증: 0~23시 범위 체크
if not ____ <= hour < ____:
return "잘못된 시간입니다"
# 이름이 있으면 "이름님, " 형식으로, 없으면 빈 문자열
greeting_name = f"{name}님, " if ____ else ""
# 시간대별 인사 (빈칸을 채워보세요!)
if 5 <= hour < 7:
return f"{greeting_name}____! 일찍 일어나셨어요 🌅"
elif ____ <= hour < ____: # 아침 시간 (7~11시)
return f"{greeting_name}좋은 아침입니다! ☀️"
elif 12 <= hour < 14:
return f"{greeting_name}____! 🍱"
elif ____ <= hour < ____: # 오후 시간 (14~17시)
return f"{greeting_name}좋은 오후입니다! 🌤️"
elif ____ <= hour < ____: # 저녁 시간 (18~21시)
return f"{greeting_name}____! 🌙"
else: # 밤 시간 (22~4시)
return f"{greeting_name}편안한 밤 되세요! 😴"
# 테스트 코드
test_times = [6, 9, 13, 16, 19, 23]
for hour in test_times:
print(f"{hour}시: {greet_by_time(hour, '홍길동')}")
예상 출력:
1
2
3
4
5
6
6시: 홍길동님, 새벽이네요! 일찍 일어나셨어요 🌅
9시: 홍길동님, 좋은 아침입니다! ☀️
13시: 홍길동님, 점심 맛있게 드세요! 🍱
16시: 홍길동님, 좋은 오후입니다! 🌤️
19시: 홍길동님, 좋은 저녁입니다! 🌙
23시: 홍길동님, 편안한 밤 되세요! 😴
💡 힌트
빈칸별 힌트:
- 입력 검증 부분: hour가 0 이상 24 미만인지 체크 (
0 <= hour < 24) - 이름 처리 부분: name 변수가 비어있지 않으면 사용 (
if name) - 새벽 인사: “새벽이네요”
- 아침 시간: 7시부터 12시 전까지 (
7 <= hour < 12) - 점심 인사: “점심 맛있게 드세요”
- 오후 시간: 14시부터 18시 전까지 (
14 <= hour < 18) - 저녁 시간: 18시부터 22시 전까지 (
18 <= hour < 22) - 저녁 인사: “좋은 저녁입니다”
✅ 정답 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def greet_by_time(hour, name=""):
"""
시간대별 맞춤 인사말
"""
# 입력 검증
if not 0 <= hour < 24:
return "잘못된 시간입니다"
# 이름 처리
greeting_name = f"{name}님, " if name else ""
# 시간대별 인사
if 5 <= hour < 7:
return f"{greeting_name}새벽이네요! 일찍 일어나셨어요 🌅"
elif 7 <= hour < 12:
return f"{greeting_name}좋은 아침입니다! ☀️"
elif 12 <= hour < 14:
return f"{greeting_name}점심 맛있게 드세요! 🍱"
elif 14 <= hour < 18:
return f"{greeting_name}좋은 오후입니다! 🌤️"
elif 18 <= hour < 22:
return f"{greeting_name}좋은 저녁입니다! 🌙"
else:
return f"{greeting_name}편안한 밤 되세요! 😴"
# 테스트
test_times = [6, 9, 13, 16, 19, 23]
for hour in test_times:
print(f"{hour}시: {greet_by_time(hour, '홍길동')}")
📝 오늘 배운 내용 정리
- 조건 순서: 좁은 범위 → 넓은 범위 (큰 값부터 체크)
- 중첩 vs 논리 연산자: 3단계 이상이면 and/or 사용
- 삼항 연산자:
값1 if 조건 else 값2(간단할 때만!) - in 연산자: 여러 값 체크 시 리스트/세트 활용
- Early Return: 에러 케이스 먼저 처리
- 딕셔너리 매핑: 긴 if-elif 체인 대체
- 가독성: 복잡하면 일반 if문, 간단하면 최적화
🎯 실습 과제
다음 기능을 가진 종합 성적 관리 시스템을 만들어보세요:
- 점수 입력 받기 (0-100)
- 학점 계산 (A+~F)
- 등급별 코멘트 출력
- 재수강 여부 판정 (F면 재수강)
- 장학금 대상 여부 (A+ 또는 A)
🔗 관련 자료
📚 이전 학습
Day 20: Phase 2 프로젝트: 학생 점수 관리 프로그램 ⭐⭐⭐
어제는 Phase 2 마무리 프로젝트로 학생 점수 관리 프로그램을 만들었습니다!
📚 다음 학습
Day 22: while문 ⭐⭐⭐
내일은 조건 기반 반복문인 while문을 배웁니다!
“늦었다고 생각할 때가 가장 빠른 시기입니다!” 🚀
Day 21/100 Phase 3: 제어문과 함수 #100DaysOfPython
