# 여기에 코드를 작성하세요
score = 85 # 다른 값으로도 테스트해보세요
Exercises: Chapter 8
Chapter 8: Control Flow - 연습문제
문제 1: if-elif-else 조건문
사용자의 점수를 입력받아 학점을 출력하는 프로그램을 작성하세요.
학점 기준:
- 90점 이상: A
- 80점 이상 90점 미만: B
- 70점 이상 80점 미만: C
- 60점 이상 70점 미만: D
- 60점 미만: F
추가 요구사항:
- 점수가 0 미만이거나 100 초과인 경우 “Invalid score” 출력
- A 또는 B 학점인 경우 “Excellent!” 메시지 추가
힌트: if-elif-else 구조와 논리 연산자(and, or)를 사용하세요.
문제 2: match-case 패턴 매칭
다음 작업을 수행하는 함수를 작성하세요:
commands = ["start", "stop", "pause", "resume", 5, "quit", "unknown"]각 명령에 대해 match-case를 사용하여 다음을 프린트:
- “start”: “Starting the system…”
- “stop” 또는 “quit”: “Stopping the system…”
- “pause”: “Pausing the system…”
- “resume”: “Resuming the system…”
- 정수(int): “Received number: {숫자}”
- 기타: “Unknown command: {명령}”
힌트: match-case 구문에서 | 연산자로 여러 케이스를 동시에 처리하고, int()로 타입 매칭을 사용하세요.
# 여기에 코드를 작성하세요
commands = ["start", "stop", "pause", "resume", 5, "quit", "unknown"]
문제 3: while 루프와 break/continue
사용자로부터 숫자를 계속 입력받아 합계를 계산하는 프로그램을 작성하세요.
요구사항:
- 사용자가 “done”을 입력하면 루프 종료
- 음수를 입력하면 “Negative numbers are not allowed” 메시지 출력 후 건너뛰기 (continue)
- 0을 입력하면 “Zero entered, stopping…” 메시지 출력 후 루프 종료 (break)
- 정상 종료(“done” 입력)시 else 블록에서 “Sum completed normally” 출력
- break로 종료시 else 블록 실행 안됨
힌트: while True, break, continue, else를 활용하세요. 이 문제는 실제 input() 대신 미리 정의된 리스트로 시뮬레이션하세요.
# 여기에 코드를 작성하세요
# 실제 input() 대신 미리 정의된 입력 사용
inputs = ["5", "10", "-3", "7", "done"] # 또는 ["5", "10", "0", "7"]로 테스트
문제 4: for 루프와 range
다음 작업을 수행하세요:
- 1부터 20까지의 숫자 중 짝수만 출력 (range 사용)
- 10부터 1까지 역순으로 출력 (range 사용)
- 구구단 7단 출력 (7 x 1 = 7부터 7 x 9 = 63까지)
- 1부터 100까지의 숫자 중 3의 배수이면서 5의 배수인 숫자들의 합 계산
힌트: range(start, stop, step)의 세 가지 매개변수를 활용하세요.
# 여기에 코드를 작성하세요
# 1. 1부터 20까지 짝수
# 2. 10부터 1까지 역순
# 3. 구구단 7단
# 4. 3의 배수이면서 5의 배수인 숫자들의 합
문제 5: enumerate를 활용한 인덱스와 값 처리
다음 온도 데이터에서:
temperatures = [22, 25, 19, -999, 23, -999, 21, 24]다음 작업을 수행하세요:
- -999는 측정 실패를 의미합니다. 모든 -999를 유효한 온도들의 평균값으로 교체
- 교체할 때마다 “인덱스 {i}의 값을 {평균값}으로 수정” 메시지 출력
- 수정된 전체 온도 리스트 출력
- 20도 이상인 온도들의 인덱스와 값을 출력
힌트: enumerate() 함수를 사용하고, 리스트 컴프리헨션으로 유효한 값만 필터링하세요.
# 여기에 코드를 작성하세요
temperatures = [22, 25, 19, -999, 23, -999, 21, 24]
문제 6: zip을 활용한 병렬 처리
세 반의 학생 점수가 다음과 같이 주어집니다:
names = ["Alice", "Bob", "Charlie", "David", "Eve"]
math_scores = [85, 92, 78, 95, 88]
english_scores = [90, 85, 92, 88, 95]다음 작업을 수행하세요:
- zip을 사용하여 각 학생의 이름, 수학 점수, 영어 점수를 동시에 출력
- 각 학생의 평균 점수 계산하여 출력
- 평균이 90점 이상인 학생에게는 “Excellent!” 메시지 추가
- 모든 학생의 정보를 딕셔너리 리스트로 저장 (키: name, math, english, average)
힌트: zip() 함수로 세 리스트를 동시에 순회하세요.
# 여기에 코드를 작성하세요
names = ["Alice", "Bob", "Charlie", "David", "Eve"]
math_scores = [85, 92, 78, 95, 88]
english_scores = [90, 85, 92, 88, 95]
문제 7: 리스트 컴프리헨션 (List Comprehension)
다음 작업을 리스트 컴프리헨션으로 수행하세요:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
words = ["apple", "banana", "cherry", "date", "elderberry", "fig"]- numbers에서 짝수의 제곱만 추출 → [4, 16, 36, 64, 100]
- numbers에서 홀수는 제곱, 짝수는 음수로 변환 → [1, -2, 9, -4, 25, -6, 49, -8, 81, -10]
- words에서 5글자 이상인 단어만 대문자로 변환
- words의 각 단어의 길이로 리스트 생성 → [5, 6, 6, 4, 10, 3]
- 1부터 50까지 중 3으로 나누어떨어지지만 5로는 나누어떨어지지 않는 숫자 리스트
힌트: [표현식 for 변수 in 시퀀스 if 조건], [표현식1 if 조건 else 표현식2 for 변수 in 시퀀스]
# 여기에 코드를 작성하세요
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
words = ["apple", "banana", "cherry", "date", "elderberry", "fig"]
# 1. 짝수의 제곱
# 2. 홀수는 제곱, 짝수는 음수
# 3. 5글자 이상 단어를 대문자로
# 4. 각 단어의 길이
# 5. 3의 배수이지만 5의 배수가 아닌 숫자
문제 8: 딕셔너리 컴프리헨션 (Dictionary Comprehension)
다음 작업을 딕셔너리 컴프리헨션으로 수행하세요:
students = ["Alice", "Bob", "Charlie", "David"]
scores = [85, 92, 78, 95]
products = {"apple": 1.20, "banana": 0.50, "cherry": 3.00, "date": 2.50}- students와 scores를 zip으로 묶어 {이름: 점수} 딕셔너리 생성
- 위 딕셔너리에서 점수가 80점 이상인 학생만 필터링
- products에서 가격이 2.00 이상인 제품만 필터링하고, 가격을 10% 할인
- 1부터 10까지 숫자를 키로, 제곱을 값으로 하는 딕셔너리 생성
- products의 키와 값을 바꾸기 (가격이 키, 제품명이 값)
힌트: {키표현식: 값표현식 for 변수 in 시퀀스 if 조건}
# 여기에 코드를 작성하세요
students = ["Alice", "Bob", "Charlie", "David"]
scores = [85, 92, 78, 95]
products = {"apple": 1.20, "banana": 0.50, "cherry": 3.00, "date": 2.50}
# 1. 이름-점수 딕셔너리
# 2. 80점 이상만 필터링
# 3. 2.00 이상 제품만 10% 할인
# 4. 숫자와 제곱
# 5. 키-값 바꾸기
문제 9: 중첩 루프와 패턴 출력
다음 패턴들을 중첩 루프를 사용하여 출력하세요:
패턴 1: 직각 삼각형
*
**
***
****
*****
패턴 2: 역 직각 삼각형
*****
****
***
**
*
패턴 3: 피라미드
*
***
*****
*******
*********
패턴 4: 구구단 테이블 (2단~5단, 1~5까지만)
2x1=2 3x1=3 4x1=4 5x1=5
2x2=4 3x2=6 4x2=8 5x2=10
...
힌트: 중첩 for 루프와 print()의 end 매개변수를 활용하세요.
# 여기에 코드를 작성하세요
# 패턴 1: 직각 삼각형
print("패턴 1:")
# 패턴 2: 역 직각 삼각형
print("\n패턴 2:")
# 패턴 3: 피라미드
print("\n패턴 3:")
# 패턴 4: 구구단 테이블
print("\n패턴 4:")
문제 10: Boolean 표현식과 조건부 로직
다음 데이터에 대해 복잡한 조건 로직을 구현하세요:
users = [
{"name": "Alice", "age": 25, "premium": True, "login_count": 150},
{"name": "Bob", "age": 17, "premium": False, "login_count": 50},
{"name": "Charlie", "age": 30, "premium": True, "login_count": 300},
{"name": "David", "age": 22, "premium": False, "login_count": 200},
{"name": "Eve", "age": 16, "premium": False, "login_count": 80},
]다음 조건에 따라 사용자를 분류하세요:
- VIP: 나이 18세 이상 AND premium True AND login_count >= 200
- Active: 나이 18세 이상 AND login_count >= 100 (VIP 제외)
- Regular: 나이 18세 이상 (VIP, Active 제외)
- Minor: 나이 18세 미만
각 사용자에 대해 “이름: 등급” 형태로 출력하고, 각 등급별 인원수를 계산하세요.
힌트: and, or, not 연산자와 복합 조건문을 사용하세요. 조건 순서가 중요합니다!
# 여기에 코드를 작성하세요
users = [
{"name": "Alice", "age": 25, "premium": True, "login_count": 150},
{"name": "Bob", "age": 17, "premium": False, "login_count": 50},
{"name": "Charlie", "age": 30, "premium": True, "login_count": 300},
{"name": "David", "age": 22, "premium": False, "login_count": 200},
{"name": "Eve", "age": 16, "premium": False, "login_count": 80},
]
문제 11**: 제너레이터와 메모리 효율적인 데이터 처리
대용량 데이터를 처리하는 시나리오를 시뮬레이션하세요.
상황: 1부터 1,000,000까지의 숫자 중에서:
- 소수(prime number)만 추출
- 추출된 소수의 제곱을 계산
- 제곱값이 1,000,000 이하인 것만 선택
- 최종 결과의 합계 계산
요구사항:
- 제너레이터 함수를 사용하여 메모리 효율적으로 구현
- 리스트 컴프리헨션 버전과 제너레이터 표현식 버전을 모두 구현하여 비교
- 각 단계별로 제너레이터를 체이닝(chaining)하여 파이프라인 구축
출력 예시:
소수의 개수: 168
조건을 만족하는 제곱값의 합계: 10000000
def is_prime(n):
"""
주어진 숫자가 소수인지 판별합니다.
Args:
n: 판별할 숫자
Returns:
bool: 소수이면 True, 아니면 False
"""
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
# 힌트: n의 제곱근까지만 확인하면 됩니다
for i in range(3, int(n**0.5) + 1, 2):
if n % i == 0:
return False
return True
def prime_generator(max_num):
"""
max_num까지의 소수를 생성하는 제너레이터
Args:
max_num: 최대 숫자
Yields:
int: 소수
"""
# 힌트: for 루프로 숫자를 순회하면서 is_prime()으로 체크
# yield를 사용하여 소수를 하나씩 반환
for num in range(2, max_num + 1):
if is_prime(num):
... # 여기에 yield 구문 작성
# 1. 제너레이터 함수 버전
def process_with_generator(max_num, square_limit):
"""
제너레이터를 사용하여 데이터를 처리합니다.
"""
# 힌트: prime_generator()로 소수를 얻고
# 제곱을 계산하고 조건을 체크하여 sum() 계산
primes = prime_generator(max_num)
# 제너레이터 표현식으로 제곱 계산 및 필터링
squared_primes = (p**2 for p in primes if p**2 <= square_limit)
# 결과 계산
... # sum()을 사용하여 합계 계산
# 2. 리스트 컴프리헨션 버전 (비교용 - 메모리 많이 사용)
def process_with_list(max_num, square_limit):
"""
리스트 컴프리헨션을 사용하여 데이터를 처리합니다.
(메모리를 더 많이 사용함)
"""
# 힌트: 리스트 컴프리헨션으로 모든 소수를 먼저 생성
primes = [n for n in range(2, max_num + 1) if is_prime(n)]
# 제곱 계산 및 필터링
squared_primes = [p**2 for p in primes if p**2 <= square_limit]
return sum(squared_primes), len(primes)
# 테스트 (작은 숫자로 먼저 테스트)
print("=== 작은 범위 테스트 (1-100) ===")
result_gen = process_with_generator(100, 10000)
result_list, prime_count = process_with_list(100, 10000)
print(f"제너레이터 버전 합계: {result_gen}")
print(f"리스트 버전 합계: {result_list}")
print(f"소수 개수: {prime_count}")
# 실제 문제 (큰 범위)
# 주의: 이 코드는 실행에 시간이 걸릴 수 있습니다
# print("\n=== 실제 문제 (1-1,000,000) ===")
# result = process_with_generator(1000000, 1000000)
# print(f"최종 합계: {result}")