파이썬 예시 코드 200선

Python 3.13 · IDLE 실행 기준 · 기초 문법부터 자료구조, 파일 처리, 객체지향, 알고리즘, 데이터베이스, 비동기, 테스트까지 단계별 학습

50기초
49응용
50실전
51심화
200개 표시
모든 예시는 외부 라이브러리 설치 없이 Python 3.13 표준 라이브러리만으로 실행하도록 구성했습니다. 파일·네트워크·데이터베이스 예제는 실행 전에 대상 파일과 인터넷 연결 상태를 확인하세요.
001 기초 출력

문자열 출력

print("안녕하세요, 파이썬!")

상세 설명

print() 함수는 괄호 안의 값을 화면에 출력한다. 문자열은 작은따옴표나 큰따옴표로 감싼다.

예상 결과

안녕하세요, 파이썬!

활용·주의점

한글은 UTF-8로 저장하면 IDLE에서도 정상적으로 표시된다.

002 기초 출력

여러 값 한 번에 출력

name = "인수샘"
age = 30
print(name, age)

상세 설명

print()에 여러 값을 쉼표로 넣으면 값 사이에 공백이 자동으로 들어간다.

예상 결과

인수샘 30

활용·주의점

sep 인자를 사용하면 구분 문자를 바꿀 수 있다.

003 기초 변수

정수 변수 만들기

score = 95
print(score)

상세 설명

변수는 값을 저장하는 이름이다. score에는 정수 95가 저장된다.

예상 결과

95

활용·주의점

변수명은 숫자로 시작할 수 없다.

004 기초 변수

실수 계산

height = 1.72
weight = 68.5
bmi = weight / (height ** 2)
print(round(bmi, 2))

상세 설명

실수 자료형을 이용해 BMI를 계산하고 round()로 소수 둘째 자리까지 표시한다.

예상 결과

23.15

활용·주의점

**는 거듭제곱 연산자이다.

005 기초 입력

이름 입력받기

name = input("이름: ")
print("반갑습니다,", name)

상세 설명

input()은 사용자가 입력한 내용을 문자열로 반환한다.

예상 결과

입력값에 따라 달라짐

활용·주의점

숫자를 입력받아 계산하려면 int()나 float()로 변환해야 한다.

006 기초 입력

정수 두 개 더하기

a = int(input("첫 번째 수: "))
b = int(input("두 번째 수: "))
print("합:", a + b)

상세 설명

input()의 결과를 int()로 변환한 뒤 두 정수를 더한다.

예상 결과

입력값에 따라 달라짐

활용·주의점

숫자가 아닌 값을 입력하면 ValueError가 발생할 수 있다.

007 기초 연산

사칙연산

a = 10
b = 3
print(a + b)
print(a - b)
print(a * b)
print(a / b)

상세 설명

덧셈, 뺄셈, 곱셈, 나눗셈의 기본 연산을 확인한다.

예상 결과

13
7
30
3.3333333333333335

활용·주의점

/ 연산 결과는 항상 실수이다.

008 기초 연산

몫과 나머지

n = 17
print("몫:", n // 5)
print("나머지:", n % 5)

상세 설명

//는 몫, %는 나머지를 구한다.

예상 결과

몫: 3
나머지: 2

활용·주의점

짝수 판별에는 n % 2를 자주 사용한다.

009 기초 문자열

문자열 이어 붙이기

first = "Data"
second = "Science"
print(first + " " + second)

상세 설명

+ 연산자는 문자열을 연결한다.

예상 결과

Data Science

활용·주의점

숫자와 문자열을 바로 더할 수는 없다.

010 기초 문자열

문자열 반복

word = "파이썬 "
print(word * 3)

상세 설명

* 연산자를 사용하면 문자열을 여러 번 반복할 수 있다.

예상 결과

파이썬 파이썬 파이썬 

활용·주의점

반복 횟수는 정수여야 한다.

011 기초 문자열

문자열 길이

text = "인공지능"
print(len(text))

상세 설명

len()은 문자열에 포함된 문자의 개수를 반환한다.

예상 결과

4

활용·주의점

한글도 글자 단위로 계산된다.

012 기초 문자열

문자열 인덱싱

text = "Python"
print(text[0])
print(text[-1])

상세 설명

인덱스 0은 첫 글자, -1은 마지막 글자를 의미한다.

예상 결과

P
n

활용·주의점

존재하지 않는 위치를 사용하면 IndexError가 발생한다.

013 기초 문자열

문자열 슬라이싱

text = "Information"
print(text[0:4])
print(text[4:])

상세 설명

슬라이싱은 시작 위치부터 끝 위치 직전까지 문자열을 잘라낸다.

예상 결과

Info
rmation

활용·주의점

끝 위치는 포함되지 않는다.

014 기초 문자열

대소문자 변환

text = "Python Data"
print(text.upper())
print(text.lower())

상세 설명

upper()는 대문자, lower()는 소문자로 바꾼다.

예상 결과

PYTHON DATA
python data

활용·주의점

원본 문자열은 바뀌지 않고 새 문자열이 생성된다.

015 기초 문자열

공백 제거

text = "   데이터 분석   "
print(text.strip())

상세 설명

strip()은 문자열 양끝의 공백을 제거한다.

예상 결과

데이터 분석

활용·주의점

lstrip()과 rstrip()은 한쪽 공백만 제거한다.

016 기초 문자열

문자열 치환

text = "나는 자바를 배운다."
print(text.replace("자바", "파이썬"))

상세 설명

replace()는 지정한 문자열을 다른 문자열로 바꾼다.

예상 결과

나는 파이썬을 배운다.

활용·주의점

원본 문자열 자체는 변경되지 않는다.

017 기초 문자열

문자열 분리

data = "서울,부산,광주"
cities = data.split(",")
print(cities)

상세 설명

split()은 구분자를 기준으로 문자열을 리스트로 나눈다.

예상 결과

['서울', '부산', '광주']

활용·주의점

구분자를 생략하면 공백을 기준으로 나눈다.

018 기초 문자열

f-string 사용

name = "민수"
score = 88
print(f"{name}의 점수는 {score}점입니다.")

상세 설명

f-string은 문자열 안에 변수 값을 간단히 삽입하는 방법이다.

예상 결과

민수의 점수는 88점입니다.

활용·주의점

중괄호 안에는 계산식도 넣을 수 있다.

019 기초 조건문

양수 판별

n = 7
if n > 0:
    print("양수")

상세 설명

if 문은 조건이 참일 때 들여쓰기된 코드를 실행한다.

예상 결과

양수

활용·주의점

파이썬은 들여쓰기가 문법의 일부이다.

020 기초 조건문

짝수와 홀수 판별

n = 12
if n % 2 == 0:
    print("짝수")
else:
    print("홀수")

상세 설명

나머지가 0이면 짝수, 아니면 홀수로 판별한다.

예상 결과

짝수

활용·주의점

비교 연산자는 ==이고 대입 연산자는 =이다.

021 기초 조건문

성적 등급 판정

score = 87
if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
else:
    grade = "C"
print(grade)

상세 설명

elif를 이용하면 여러 조건을 순서대로 검사할 수 있다.

예상 결과

B

활용·주의점

조건은 위에서 아래로 검사하므로 범위 순서가 중요하다.

022 기초 조건문

범위 비교

age = 17
if 14 <= age <= 19:
    print("청소년")

상세 설명

파이썬은 두 비교식을 연결하여 범위를 간단히 표현할 수 있다.

예상 결과

청소년

활용·주의점

다른 언어보다 직관적인 비교 문법이다.

023 기초 조건문

논리 연산자

temperature = 25
rain = False
if temperature >= 20 and not rain:
    print("야외 활동 가능")

상세 설명

and는 두 조건이 모두 참일 때, not은 참과 거짓을 반대로 바꾼다.

예상 결과

야외 활동 가능

활용·주의점

or는 둘 중 하나만 참이어도 전체가 참이다.

024 기초 반복문

for로 1부터 5 출력

for i in range(1, 6):
    print(i)

상세 설명

range(1, 6)은 1부터 5까지의 정수를 만든다.

예상 결과

1
2
3
4
5

활용·주의점

range의 끝값은 포함되지 않는다.

025 기초 반복문

0부터 9까지 합계

total = 0
for i in range(10):
    total += i
print(total)

상세 설명

반복할 때마다 i를 total에 누적한다.

예상 결과

45

활용·주의점

total += i는 total = total + i와 같다.

026 기초 반복문

2단 구구단

for i in range(1, 10):
    print(f"2 × {i} = {2*i}")

상세 설명

반복문과 f-string을 결합해 구구단을 출력한다.

예상 결과

2 × 1 = 2 ... 2 × 9 = 18

활용·주의점

곱셈 기호는 출력용 문자이고 실제 연산자는 *이다.

027 기초 반복문

역순 출력

for i in range(5, 0, -1):
    print(i)

상세 설명

range의 세 번째 값 -1은 1씩 감소한다는 뜻이다.

예상 결과

5
4
3
2
1

활용·주의점

증가폭이나 감소폭은 0이 될 수 없다.

028 기초 반복문

while 반복

count = 1
while count <= 5:
    print(count)
    count += 1

상세 설명

while은 조건이 참인 동안 코드를 반복한다.

예상 결과

1
2
3
4
5

활용·주의점

조건이 계속 참이면 무한 반복이 발생하므로 변수 갱신이 필요하다.

029 기초 반복문

break 사용

for i in range(1, 11):
    if i == 6:
        break
    print(i)

상세 설명

break는 반복문을 즉시 종료한다.

예상 결과

1
2
3
4
5

활용·주의점

중첩 반복문에서는 가장 가까운 반복문만 종료한다.

030 기초 반복문

continue 사용

for i in range(1, 6):
    if i == 3:
        continue
    print(i)

상세 설명

continue는 현재 반복만 건너뛰고 다음 반복으로 이동한다.

예상 결과

1
2
4
5

활용·주의점

반복문 전체를 종료하지는 않는다.

031 기초 리스트

리스트 만들기

fruits = ["사과", "배", "포도"]
print(fruits)

상세 설명

리스트는 여러 값을 순서대로 저장하는 자료형이다.

예상 결과

['사과', '배', '포도']

활용·주의점

리스트는 값을 추가·삭제·수정할 수 있다.

032 기초 리스트

리스트 항목 접근

numbers = [10, 20, 30, 40]
print(numbers[1])
print(numbers[-1])

상세 설명

인덱스로 원하는 리스트 항목에 접근한다.

예상 결과

20
40

활용·주의점

리스트 인덱스도 0부터 시작한다.

033 기초 리스트

리스트 항목 수정

colors = ["빨강", "파랑", "초록"]
colors[1] = "노랑"
print(colors)

상세 설명

리스트는 인덱스를 이용해 특정 값을 바꿀 수 있다.

예상 결과

['빨강', '노랑', '초록']

활용·주의점

문자열과 달리 리스트는 변경 가능한 자료형이다.

034 기초 리스트

리스트에 값 추가

scores = [80, 90]
scores.append(100)
print(scores)

상세 설명

append()는 리스트 끝에 값을 하나 추가한다.

예상 결과

[80, 90, 100]

활용·주의점

여러 값을 한꺼번에 추가하려면 extend()를 사용한다.

035 기초 리스트

리스트 값 삭제

animals = ["고양이", "개", "토끼"]
animals.remove("개")
print(animals)

상세 설명

remove()는 지정한 값을 찾아 첫 번째 항목을 삭제한다.

예상 결과

['고양이', '토끼']

활용·주의점

없는 값을 삭제하면 ValueError가 발생한다.

036 기초 리스트

리스트 정렬

numbers = [5, 2, 8, 1]
numbers.sort()
print(numbers)

상세 설명

sort()는 리스트 자체를 오름차순으로 정렬한다.

예상 결과

[1, 2, 5, 8]

활용·주의점

sorted()는 정렬된 새 리스트를 반환한다.

037 기초 리스트

최댓값과 최솟값

numbers = [12, 7, 25, 3]
print(max(numbers))
print(min(numbers))

상세 설명

max()와 min()은 리스트에서 가장 큰 값과 작은 값을 찾는다.

예상 결과

25
3

활용·주의점

문자열 리스트에서도 사전식 순서로 비교할 수 있다.

038 기초 리스트

리스트 합계와 평균

scores = [80, 90, 70, 100]
average = sum(scores) / len(scores)
print(average)

상세 설명

sum()으로 합계를 구하고 항목 수로 나누어 평균을 계산한다.

예상 결과

85.0

활용·주의점

빈 리스트는 len()이 0이므로 나눗셈 오류에 주의한다.

039 기초 튜플

튜플 사용

point = (3, 5)
print(point[0], point[1])

상세 설명

튜플은 순서가 있지만 생성 후 값을 변경할 수 없는 자료형이다.

예상 결과

3 5

활용·주의점

좌표처럼 바뀌지 않아야 하는 값에 적합하다.

040 기초 집합

중복 제거

numbers = [1, 2, 2, 3, 3, 3]
unique = set(numbers)
print(unique)

상세 설명

set()은 중복을 제거한 집합을 만든다.

예상 결과

{1, 2, 3}

활용·주의점

집합은 출력 순서가 고정되지 않을 수 있다.

041 기초 집합

교집합 구하기

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a & b)

상세 설명

& 연산자는 두 집합에 공통으로 포함된 값을 구한다.

예상 결과

{3, 4}

활용·주의점

|는 합집합, -는 차집합이다.

042 기초 딕셔너리

딕셔너리 만들기

student = {"이름": "지훈", "점수": 92}
print(student["이름"])

상세 설명

딕셔너리는 키와 값의 쌍으로 데이터를 저장한다.

예상 결과

지훈

활용·주의점

키는 중복될 수 없다.

043 기초 딕셔너리

딕셔너리 값 수정

student = {"이름": "지훈", "점수": 92}
student["점수"] = 95
print(student)

상세 설명

키를 지정해 기존 값을 수정할 수 있다.

예상 결과

{'이름': '지훈', '점수': 95}

활용·주의점

없는 키를 사용하면 새 항목이 추가된다.

044 기초 딕셔너리

딕셔너리 반복

scores = {"민수": 90, "영희": 85}
for name, score in scores.items():
    print(name, score)

상세 설명

items()는 키와 값을 함께 반복할 수 있게 한다.

예상 결과

민수 90
영희 85

활용·주의점

keys()와 values()는 각각 키와 값만 가져온다.

045 기초 형 변환

문자열을 정수로 변환

text = "123"
number = int(text)
print(number + 10)

상세 설명

int()는 숫자 형태의 문자열을 정수로 바꾼다.

예상 결과

133

활용·주의점

소수 문자열은 float()로 변환해야 한다.

046 기초 형 변환

정수를 문자열로 변환

age = 18
message = "나이: " + str(age)
print(message)

상세 설명

str()은 숫자를 문자열로 변환한다.

예상 결과

나이: 18

활용·주의점

f-string을 사용하면 형 변환을 직접 쓰지 않아도 된다.

047 기초 내장함수

반올림

value = 3.141592
print(round(value, 3))

상세 설명

round()의 두 번째 인자는 표시할 소수 자릿수이다.

예상 결과

3.142

활용·주의점

부동소수점 표현 특성 때문에 예상과 다른 반올림이 나타날 수 있다.

048 기초 내장함수

절댓값

print(abs(-15))
print(abs(3.5))

상세 설명

abs()는 숫자의 절댓값을 반환한다.

예상 결과

15
3.5

활용·주의점

거리 계산 등에서 자주 사용한다.

049 기초 내장함수

자료형 확인

x = 10
y = "10"
print(type(x))
print(type(y))

상세 설명

type()은 값의 자료형을 확인한다.

예상 결과

<class 'int'>
<class 'str'>

활용·주의점

겉보기에 같은 10이라도 정수와 문자열은 다르다.

050 기초 주석

주석과 코드 설명

# 원의 넓이를 계산한다.
radius = 5
area = 3.14 * radius ** 2
print(area)

상세 설명

# 뒤의 내용은 실행되지 않고 코드 설명으로 사용된다.

예상 결과

78.5

활용·주의점

좋은 주석은 코드가 왜 필요한지 설명한다.

051 응용 함수

매개변수가 있는 함수

def greet(name):
    return f"{name}님, 반갑습니다."

print(greet("서연"))

상세 설명

함수는 반복되는 작업을 하나의 이름으로 묶는다. 매개변수 name을 받아 문자열을 반환한다.

예상 결과

서연님, 반갑습니다.

활용·주의점

return은 값을 함수 밖으로 전달한다.

052 응용 함수

두 수의 최댓값 함수

def larger(a, b):
    if a > b:
        return a
    return b

print(larger(10, 7))

상세 설명

조건문과 return을 결합해 두 값 중 큰 값을 반환한다.

예상 결과

10

활용·주의점

return이 실행되면 함수는 즉시 종료된다.

053 응용 함수

기본값 매개변수

def power(base, exponent=2):
    return base ** exponent

print(power(5))
print(power(2, 3))

상세 설명

exponent에 기본값 2를 지정하여 인자를 생략할 수 있다.

예상 결과

25
8

활용·주의점

기본값이 있는 매개변수는 뒤쪽에 배치한다.

054 응용 함수

키워드 인자

def profile(name, age, city):
    print(name, age, city)

profile(city="전주", name="민수", age=17)

상세 설명

키워드 인자를 사용하면 호출 순서와 관계없이 값을 전달할 수 있다.

예상 결과

민수 17 전주

활용·주의점

매개변수 이름을 정확히 작성해야 한다.

055 응용 함수

가변 인자

def total(*numbers):
    return sum(numbers)

print(total(1, 2, 3, 4))

상세 설명

*numbers는 전달된 여러 인자를 튜플로 받는다.

예상 결과

10

활용·주의점

인자 개수가 정해지지 않은 함수에 적합하다.

056 응용 함수

지역 변수와 전역 변수

message = "전역"

def show():
    message = "지역"
    print(message)

show()
print(message)

상세 설명

함수 안에서 만든 지역 변수는 함수 밖의 전역 변수와 별개이다.

예상 결과

지역
전역

활용·주의점

전역 변수 변경은 최소화하는 것이 좋다.

057 응용 함수

재귀 함수로 팩토리얼

def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))

상세 설명

재귀 함수는 자기 자신을 호출한다. 종료 조건이 반드시 필요하다.

예상 결과

120

활용·주의점

큰 입력에서는 반복문이 더 안전할 수 있다.

058 응용 람다

람다식으로 제곱

square = lambda x: x ** 2
print(square(6))

상세 설명

lambda는 짧은 함수를 한 줄로 정의한다.

예상 결과

36

활용·주의점

복잡한 로직은 일반 def 함수가 더 읽기 쉽다.

059 응용 리스트

리스트 컴프리헨션

squares = [x ** 2 for x in range(1, 6)]
print(squares)

상세 설명

리스트 컴프리헨션은 반복문으로 새 리스트를 간결하게 만든다.

예상 결과

[1, 4, 9, 16, 25]

활용·주의점

너무 복잡하게 작성하면 가독성이 떨어진다.

060 응용 리스트

조건이 있는 리스트 컴프리헨션

evens = [x for x in range(1, 11) if x % 2 == 0]
print(evens)

상세 설명

if 조건을 추가하여 짝수만 선택한다.

예상 결과

[2, 4, 6, 8, 10]

활용·주의점

필터링과 변환을 동시에 할 수 있다.

061 응용 리스트

중첩 리스트

matrix = [[1, 2], [3, 4], [5, 6]]
print(matrix[1][0])

상세 설명

중첩 리스트는 표나 행렬처럼 2차원 데이터를 표현한다.

예상 결과

3

활용·주의점

첫 번째 인덱스는 행, 두 번째 인덱스는 열이다.

062 응용 리스트

enumerate 사용

fruits = ["사과", "배", "포도"]
for index, fruit in enumerate(fruits, start=1):
    print(index, fruit)

상세 설명

enumerate()는 항목과 순번을 함께 제공한다.

예상 결과

1 사과
2 배
3 포도

활용·주의점

start 값을 생략하면 0부터 시작한다.

063 응용 리스트

zip으로 두 리스트 묶기

names = ["민수", "영희", "철수"]
scores = [90, 85, 88]
for name, score in zip(names, scores):
    print(name, score)

상세 설명

zip()은 여러 반복 가능한 객체의 같은 위치 값을 묶는다.

예상 결과

민수 90
영희 85
철수 88

활용·주의점

길이가 다르면 짧은 쪽에 맞춰 종료된다.

064 응용 정렬

키 함수로 문자열 길이 정렬

words = ["python", "ai", "data"]
print(sorted(words, key=len))

상세 설명

key=len을 지정하면 문자열 길이를 기준으로 정렬한다.

예상 결과

['ai', 'data', 'python']

활용·주의점

reverse=True를 추가하면 내림차순이다.

065 응용 정렬

딕셔너리 목록 정렬

students = [
    {"name": "민수", "score": 88},
    {"name": "영희", "score": 95}
]
result = sorted(students, key=lambda x: x["score"], reverse=True)
print(result)

상세 설명

람다식을 키 함수로 사용해 점수 기준 내림차순 정렬을 수행한다.

예상 결과

[{'name': '영희', 'score': 95}, {'name': '민수', 'score': 88}]

활용·주의점

복합 데이터 정렬에 자주 활용된다.

066 응용 문자열

join으로 문자열 결합

words = ["파이썬", "데이터", "인공지능"]
print(" · ".join(words))

상세 설명

join()은 리스트의 문자열을 지정한 구분자로 연결한다.

예상 결과

파이썬 · 데이터 · 인공지능

활용·주의점

리스트 항목은 모두 문자열이어야 한다.

067 응용 문자열

문자열 포함 여부

text = "파이썬 데이터 분석"
print("데이터" in text)
print("자바" in text)

상세 설명

in 연산자는 문자열이나 리스트에 값이 포함되어 있는지 확인한다.

예상 결과

True
False

활용·주의점

대소문자를 구분한다.

068 응용 문자열

문자 빈도 계산

text = "banana"
counts = {}
for ch in text:
    counts[ch] = counts.get(ch, 0) + 1
print(counts)

상세 설명

get()으로 기존 값을 안전하게 읽어 문자별 등장 횟수를 누적한다.

예상 결과

{'b': 1, 'a': 3, 'n': 2}

활용·주의점

collections.Counter를 사용하면 더 간단히 구현할 수 있다.

069 응용 딕셔너리

딕셔너리 컴프리헨션

squares = {x: x ** 2 for x in range(1, 6)}
print(squares)

상세 설명

딕셔너리 컴프리헨션은 키와 값을 동시에 계산하여 만든다.

예상 결과

{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

활용·주의점

키는 중복되면 마지막 값으로 덮어쓴다.

070 응용 딕셔너리

딕셔너리 병합

a = {"국어": 90, "영어": 85}
b = {"수학": 95}
merged = a | b
print(merged)

상세 설명

| 연산자는 파이썬 3.9 이상에서 딕셔너리를 병합한다.

예상 결과

{'국어': 90, '영어': 85, '수학': 95}

활용·주의점

같은 키가 있으면 오른쪽 딕셔너리 값이 사용된다.

071 응용 집합

대칭 차집합

a = {1, 2, 3}
b = {3, 4, 5}
print(a ^ b)

상세 설명

^ 연산자는 한쪽 집합에만 존재하는 값을 구한다.

예상 결과

{1, 2, 4, 5}

활용·주의점

공통 원소는 결과에서 제외된다.

072 응용 예외처리

0으로 나누기 예외 처리

try:
    print(10 / 0)
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다.")

상세 설명

try에서 오류가 발생하면 해당 except 블록을 실행한다.

예상 결과

0으로 나눌 수 없습니다.

활용·주의점

예상 가능한 오류만 구체적으로 처리하는 것이 좋다.

073 응용 예외처리

숫자 입력 예외 처리

try:
    age = int(input("나이: "))
    print(age)
except ValueError:
    print("정수를 입력하세요.")

상세 설명

정수 변환에 실패할 때 ValueError를 처리한다.

예상 결과

입력값에 따라 달라짐

활용·주의점

사용자 입력 프로그램에 예외 처리는 매우 중요하다.

074 응용 예외처리

finally 사용

try:
    value = int("100")
    print(value)
finally:
    print("작업 종료")

상세 설명

finally는 오류 발생 여부와 관계없이 항상 실행된다.

예상 결과

100
작업 종료

활용·주의점

파일 닫기나 자원 해제에 적합하다.

075 응용 파일

텍스트 파일 쓰기

with open("memo.txt", "w", encoding="utf-8") as file:
    file.write("파이썬 파일 저장")
print("저장 완료")

상세 설명

with 문을 사용하면 파일 작업 후 자동으로 닫힌다.

예상 결과

저장 완료

활용·주의점

w 모드는 기존 내용을 덮어쓴다.

076 응용 파일

텍스트 파일 읽기

with open("memo.txt", "r", encoding="utf-8") as file:
    content = file.read()
print(content)

상세 설명

read()는 파일 전체 내용을 문자열로 읽는다.

예상 결과

파이썬 파일 저장

활용·주의점

파일이 없으면 FileNotFoundError가 발생한다.

077 응용 파일

파일에 내용 추가

with open("memo.txt", "a", encoding="utf-8") as file:
    file.write("\n새로운 줄")

상세 설명

a 모드는 기존 내용을 유지하면서 파일 끝에 추가한다.

예상 결과

파일 내용에 새로운 줄 추가

활용·주의점

줄바꿈 문자는 \n이다.

078 응용 파일

여러 줄 읽기

with open("memo.txt", "r", encoding="utf-8") as file:
    for line in file:
        print(line.strip())

상세 설명

파일 객체를 반복하면 한 줄씩 메모리를 절약하며 읽을 수 있다.

예상 결과

파일 내용에 따라 달라짐

활용·주의점

strip()으로 줄끝 개행 문자를 제거한다.

079 응용 모듈

math 모듈 사용

import math
print(math.sqrt(81))
print(round(math.pi, 4))

상세 설명

표준 라이브러리 math는 제곱근과 원주율 등의 수학 기능을 제공한다.

예상 결과

9.0
3.1416

활용·주의점

외부 설치 없이 사용할 수 있다.

080 응용 모듈

random으로 임의의 정수

import random
number = random.randint(1, 6)
print(number)

상세 설명

randint(1, 6)은 1부터 6까지의 정수 중 하나를 무작위로 반환한다.

예상 결과

실행할 때마다 달라짐

활용·주의점

게임이나 모의실험에 활용할 수 있다.

081 응용 모듈

random 선택

import random
menu = ["김밥", "라면", "비빔밥"]
print(random.choice(menu))

상세 설명

choice()는 리스트에서 항목 하나를 무작위로 선택한다.

예상 결과

실행할 때마다 달라짐

활용·주의점

빈 리스트에서는 오류가 발생한다.

082 응용 모듈

datetime으로 현재 시각

from datetime import datetime
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M"))

상세 설명

datetime.now()로 현재 시각을 얻고 strftime()으로 형식을 지정한다.

예상 결과

실행 시각에 따라 달라짐

활용·주의점

형식 코드에서 %Y는 연도, %m은 월이다.

083 응용 모듈

날짜 차이 계산

from datetime import date
start = date(2026, 3, 1)
end = date(2026, 3, 15)
print((end - start).days)

상세 설명

date 객체끼리 빼면 timedelta가 생성되고 days로 날짜 차이를 구한다.

예상 결과

14

활용·주의점

종료일과 시작일의 차이이므로 시작일 자체는 포함되지 않는다.

084 응용 클래스

간단한 클래스 만들기

class Student:
    def __init__(self, name):
        self.name = name

student = Student("민수")
print(student.name)

상세 설명

클래스는 데이터와 기능을 하나로 묶는 설계도이다.

예상 결과

민수

활용·주의점

__init__은 객체 생성 시 실행되는 초기화 메서드이다.

085 응용 클래스

인스턴스 메서드

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

r = Rectangle(4, 5)
print(r.area())

상세 설명

인스턴스 메서드는 객체의 속성을 이용해 기능을 수행한다.

예상 결과

20

활용·주의점

메서드의 첫 번째 매개변수는 일반적으로 self이다.

086 응용 클래스

문자열 표현 메서드

class Book:
    def __init__(self, title):
        self.title = title

    def __str__(self):
        return f"책: {self.title}"

print(Book("데미안"))

상세 설명

__str__은 객체를 print()로 출력할 때 보여 줄 문자열을 정의한다.

예상 결과

책: 데미안

활용·주의점

사용자 친화적인 객체 표현에 유용하다.

087 응용 클래스

상속

class Animal:
    def sound(self):
        return "소리"

class Dog(Animal):
    def sound(self):
        return "멍멍"

print(Dog().sound())

상세 설명

상속을 사용하면 기존 클래스의 기능을 이어받고 필요한 부분을 재정의할 수 있다.

예상 결과

멍멍

활용·주의점

메서드 재정의를 오버라이딩이라고 한다.

088 응용 클래스

클래스 변수

class Counter:
    count = 0

    def __init__(self):
        Counter.count += 1

Counter()
Counter()
print(Counter.count)

상세 설명

클래스 변수는 모든 인스턴스가 공유한다.

예상 결과

2

활용·주의점

객체별 값은 인스턴스 변수로 저장한다.

089 응용 알고리즘

선형 탐색

numbers = [4, 7, 2, 9, 5]
target = 9
position = -1
for i, value in enumerate(numbers):
    if value == target:
        position = i
        break
print(position)

상세 설명

앞에서부터 하나씩 비교하여 목표값의 위치를 찾는다.

예상 결과

3

활용·주의점

시간 복잡도는 최악의 경우 O(n)이다.

090 응용 알고리즘

버블 정렬

numbers = [5, 3, 8, 1]
for end in range(len(numbers)-1, 0, -1):
    for i in range(end):
        if numbers[i] > numbers[i+1]:
            numbers[i], numbers[i+1] = numbers[i+1], numbers[i]
print(numbers)

상세 설명

인접한 두 값을 비교해 큰 값을 뒤로 보내는 정렬이다.

예상 결과

[1, 3, 5, 8]

활용·주의점

학습용으로 좋지만 큰 데이터에는 느리다.

091 응용 알고리즘

소수 판별

n = 29
is_prime = n >= 2
for i in range(2, int(n ** 0.5) + 1):
    if n % i == 0:
        is_prime = False
        break
print(is_prime)

상세 설명

제곱근까지만 약수를 검사해 소수 여부를 판별한다.

예상 결과

True

활용·주의점

1은 소수가 아니다.

092 응용 알고리즘

최대공약수

a, b = 48, 18
while b:
    a, b = b, a % b
print(a)

상세 설명

유클리드 호제법으로 최대공약수를 빠르게 구한다.

예상 결과

6

활용·주의점

math.gcd()를 사용하면 더 간단하다.

093 응용 알고리즘

피보나치 수열

a, b = 0, 1
for _ in range(10):
    print(a, end=" ")
    a, b = b, a + b

상세 설명

두 변수를 동시에 갱신하여 피보나치 수열을 만든다.

예상 결과

0 1 1 2 3 5 8 13 21 34

활용·주의점

_는 값을 사용하지 않는 반복 변수에 자주 쓴다.

094 응용 자료구조

스택 구현

stack = []
stack.append("A")
stack.append("B")
print(stack.pop())
print(stack)

상세 설명

리스트의 append()와 pop()을 이용해 후입선출 스택을 구현한다.

예상 결과

B
['A']

활용·주의점

괄호 검사나 되돌리기 기능에 활용된다.

095 응용 자료구조

큐 구현

from collections import deque
queue = deque(["A", "B"])
queue.append("C")
print(queue.popleft())
print(queue)

상세 설명

deque는 앞쪽 삭제가 빠른 큐 자료구조이다.

예상 결과

A
deque(['B', 'C'])

활용·주의점

일반 리스트의 pop(0)은 데이터가 많을수록 느리다.

096 응용 자료구조

Counter로 빈도 계산

from collections import Counter
words = ["사과", "배", "사과", "포도", "사과"]
print(Counter(words))

상세 설명

Counter는 항목별 등장 횟수를 자동으로 계산한다.

예상 결과

Counter({'사과': 3, '배': 1, '포도': 1})

활용·주의점

most_common()으로 빈도가 높은 순서를 확인할 수 있다.

097 응용 자료구조

defaultdict로 그룹화

from collections import defaultdict
groups = defaultdict(list)
for name, class_no in [("민수", 1), ("영희", 2), ("철수", 1)]:
    groups[class_no].append(name)
print(dict(groups))

상세 설명

defaultdict는 없는 키에 기본값을 자동으로 만든다.

예상 결과

{1: ['민수', '철수'], 2: ['영희']}

활용·주의점

그룹별 데이터 수집에 편리하다.

098 응용 반복도구

itertools.product

from itertools import product
for item in product(["A", "B"], [1, 2]):
    print(item)

상세 설명

product()는 두 집합의 모든 조합을 만든다.

예상 결과

('A', 1)
('A', 2)
('B', 1)
('B', 2)

활용·주의점

중첩 반복문을 간결하게 표현할 수 있다.

099 응용 반복도구

itertools.combinations

from itertools import combinations
students = ["민수", "영희", "철수"]
print(list(combinations(students, 2)))

상세 설명

combinations()는 순서를 고려하지 않는 조합을 만든다.

예상 결과

[('민수', '영희'), ('민수', '철수'), ('영희', '철수')]

활용·주의점

순서를 고려하려면 permutations()를 사용한다.

100 실전 데이터 처리

CSV 파일 저장

import csv
rows = [["이름", "점수"], ["민수", 90], ["영희", 95]]
with open("scores.csv", "w", newline="", encoding="utf-8-sig") as file:
    writer = csv.writer(file)
    writer.writerows(rows)
print("CSV 저장 완료")

상세 설명

csv 모듈로 표 형태 데이터를 저장한다. utf-8-sig는 엑셀에서 한글 깨짐을 줄인다.

예상 결과

CSV 저장 완료

활용·주의점

Windows에서는 newline=''를 지정하는 것이 좋다.

101 실전 데이터 처리

CSV 파일 읽기

import csv
with open("scores.csv", "r", encoding="utf-8-sig") as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(row["이름"], row["점수"])

상세 설명

DictReader는 첫 행을 열 이름으로 사용하여 각 행을 딕셔너리로 반환한다.

예상 결과

민수 90
영희 95

활용·주의점

숫자도 문자열로 읽히므로 계산 전 형 변환이 필요하다.

102 실전 데이터 처리

JSON 저장

import json
data = {"name": "민수", "scores": [90, 88, 95]}
with open("student.json", "w", encoding="utf-8") as file:
    json.dump(data, file, ensure_ascii=False, indent=2)

상세 설명

json.dump()는 파이썬 객체를 JSON 파일로 저장한다.

예상 결과

student.json 생성

활용·주의점

ensure_ascii=False로 한글을 그대로 저장한다.

103 실전 데이터 처리

JSON 읽기

import json
with open("student.json", "r", encoding="utf-8") as file:
    data = json.load(file)
print(data["scores"])

상세 설명

json.load()는 JSON 파일을 파이썬 딕셔너리나 리스트로 변환한다.

예상 결과

[90, 88, 95]

활용·주의점

파일 구조와 키 이름을 확인해야 한다.

104 실전 파일 시스템

폴더 만들기

from pathlib import Path
folder = Path("results")
folder.mkdir(exist_ok=True)
print(folder.exists())

상세 설명

pathlib.Path는 운영체제에 독립적인 파일 경로 처리를 제공한다.

예상 결과

True

활용·주의점

parents=True를 지정하면 상위 폴더도 함께 만든다.

105 실전 파일 시스템

폴더의 파일 목록

from pathlib import Path
for path in Path(".").glob("*.py"):
    print(path.name)

상세 설명

glob()은 특정 패턴과 일치하는 파일을 찾는다.

예상 결과

현재 폴더의 .py 파일 목록

활용·주의점

**/*.py 패턴은 하위 폴더까지 탐색한다.

106 실전 파일 시스템

파일 크기 확인

from pathlib import Path
path = Path("memo.txt")
if path.exists():
    print(path.stat().st_size)

상세 설명

stat().st_size는 파일 크기를 바이트 단위로 반환한다.

예상 결과

파일에 따라 달라짐

활용·주의점

파일 존재 여부를 먼저 확인하면 안전하다.

107 실전 문자열

정규표현식으로 숫자 추출

import re
text = "온도는 23도, 습도는 58퍼센트입니다."
numbers = re.findall(r"\d+", text)
print(numbers)

상세 설명

정규표현식 \d+는 연속된 숫자를 찾는다.

예상 결과

['23', '58']

활용·주의점

결과는 문자열이므로 계산하려면 int()로 변환한다.

108 실전 문자열

이메일 형식 검사

import re
email = "student@example.com"
pattern = r"^[\w.-]+@[\w.-]+\.[A-Za-z]{2,}$"
print(bool(re.match(pattern, email)))

상세 설명

정규표현식으로 기본적인 이메일 형식을 검사한다.

예상 결과

True

활용·주의점

실제 이메일 표준 전체를 완벽히 검증하는 패턴은 훨씬 복잡하다.

109 실전 보안

SHA-256 해시

import hashlib
text = "mypassword"
digest = hashlib.sha256(text.encode("utf-8")).hexdigest()
print(digest)

상세 설명

SHA-256은 입력을 고정 길이 해시 문자열로 변환한다.

예상 결과

64자리 16진수 문자열

활용·주의점

실제 비밀번호 저장에는 salt와 전용 비밀번호 해시 알고리즘이 필요하다.

110 실전 보안

secrets로 안전한 토큰

import secrets
token = secrets.token_urlsafe(16)
print(token)

상세 설명

secrets는 보안에 적합한 난수를 생성한다.

예상 결과

실행할 때마다 달라짐

활용·주의점

보안 토큰 생성에는 random보다 secrets가 적합하다.

111 실전 보안

HTML 특수문자 이스케이프

import html
text = "<script>alert('XSS')</script>"
print(html.escape(text))

상세 설명

html.escape()는 HTML 특수문자를 안전한 문자로 변환한다.

예상 결과

&lt;script&gt;alert(&#x27;XSS&#x27;)&lt;/script&gt;

활용·주의점

웹 출력에서 사용자 입력을 그대로 삽입하면 위험할 수 있다.

112 실전 통계

평균·중앙값·최빈값

import statistics
data = [10, 20, 20, 30, 100]
print(statistics.mean(data))
print(statistics.median(data))
print(statistics.mode(data))

상세 설명

statistics 모듈은 기초 통계량을 계산한다.

예상 결과

36
20
20

활용·주의점

이상치가 있으면 평균과 중앙값이 크게 달라질 수 있다.

113 실전 통계

표준편차

import statistics
data = [70, 75, 80, 85, 90]
print(round(statistics.pstdev(data), 2))

상세 설명

pstdev()는 모집단 표준편차를 계산한다.

예상 결과

7.07

활용·주의점

표본 표준편차는 stdev()를 사용한다.

114 실전 통계

상관관계 직접 계산

import statistics
x = [1, 2, 3, 4, 5]
y = [2, 4, 5, 4, 5]
mx, my = statistics.mean(x), statistics.mean(y)
num = sum((a-mx)*(b-my) for a, b in zip(x, y))
den = (sum((a-mx)**2 for a in x) * sum((b-my)**2 for b in y)) ** 0.5
print(round(num / den, 3))

상세 설명

피어슨 상관계수 공식을 직접 구현한다.

예상 결과

0.775

활용·주의점

상관관계가 인과관계를 의미하지는 않는다.

115 실전 시뮬레이션

주사위 1000번 실험

import random
counts = {i: 0 for i in range(1, 7)}
for _ in range(1000):
    counts[random.randint(1, 6)] += 1
print(counts)

상세 설명

무작위 실험을 반복해 각 눈의 빈도를 관찰한다.

예상 결과

각 값이 약 167회 전후

활용·주의점

시행 횟수가 많을수록 이론 확률에 가까워진다.

116 실전 시뮬레이션

몬테카를로 원주율

import random
inside = 0
trials = 100000
for _ in range(trials):
    x, y = random.random(), random.random()
    if x*x + y*y <= 1:
        inside += 1
print(4 * inside / trials)

상세 설명

정사각형 안에 무작위 점을 찍어 원 내부 비율로 원주율을 근사한다.

예상 결과

약 3.14

활용·주의점

시행 횟수를 늘리면 대체로 정확도가 높아진다.

117 실전 게임

숫자 맞히기

import random
answer = random.randint(1, 20)
while True:
    guess = int(input("1~20: "))
    if guess == answer:
        print("정답")
        break
    print("더 큼" if guess < answer else "더 작음")

상세 설명

무작위 정답을 정하고 반복적으로 입력받아 힌트를 제공한다.

예상 결과

입력에 따라 달라짐

활용·주의점

실전에서는 잘못된 입력에 대한 예외 처리도 추가한다.

118 실전 게임

가위바위보

import random
choices = ["가위", "바위", "보"]
computer = random.choice(choices)
user = "가위"
if user == computer:
    result = "무승부"
elif (user, computer) in [("가위","보"),("바위","가위"),("보","바위")]:
    result = "승리"
else:
    result = "패배"
print(computer, result)

상세 설명

튜플 조합을 이용해 승리 조건을 간결하게 표현한다.

예상 결과

실행할 때마다 달라짐

활용·주의점

입력값 검증을 추가하면 완성도가 높아진다.

119 실전 객체지향

은행 계좌 클래스

class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        if amount > 0:
            self.balance += amount

    def withdraw(self, amount):
        if 0 < amount <= self.balance:
            self.balance -= amount
            return True
        return False

account = BankAccount("민수", 10000)
account.deposit(5000)
account.withdraw(3000)
print(account.balance)

상세 설명

입금과 출금 규칙을 메서드로 캡슐화한다.

예상 결과

12000

활용·주의점

금액 검증 로직을 객체 내부에 두면 일관성이 높아진다.

120 실전 객체지향

프로퍼티로 값 검증

class Temperature:
    def __init__(self, celsius):
        self.celsius = celsius

    @property
    def celsius(self):
        return self._celsius

    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("절대영도보다 낮을 수 없습니다.")
        self._celsius = value

print(Temperature(25).celsius)

상세 설명

property를 이용해 속성 접근은 간단하게 유지하면서 값 검증을 수행한다.

예상 결과

25

활용·주의점

내부 저장 변수는 관례적으로 밑줄로 시작한다.

121 실전 객체지향

추상 기반 다형성

class Circle:
    def area(self):
        return 3.14 * 2 ** 2

class Square:
    def area(self):
        return 4 ** 2

shapes = [Circle(), Square()]
print([shape.area() for shape in shapes])

상세 설명

서로 다른 클래스가 같은 이름의 메서드를 제공하면 동일한 방식으로 처리할 수 있다.

예상 결과

[12.56, 16]

활용·주의점

이를 다형성이라고 한다.

122 실전 객체지향

데이터 클래스

from dataclasses import dataclass

@dataclass
class Student:
    name: str
    score: int

student = Student("민수", 95)
print(student)

상세 설명

dataclass는 데이터 중심 클래스의 초기화와 문자열 표현을 자동 생성한다.

예상 결과

Student(name='민수', score=95)

활용·주의점

파이썬 3.7 이상에서 사용할 수 있다.

123 실전 객체지향

클래스 메서드

class Person:
    count = 0

    def __init__(self, name):
        self.name = name
        Person.count += 1

    @classmethod
    def total(cls):
        return cls.count

Person("민수")
Person("영희")
print(Person.total())

상세 설명

classmethod는 클래스 자체를 첫 인자 cls로 받아 클래스 상태를 다룬다.

예상 결과

2

활용·주의점

인스턴스 없이도 호출할 수 있다.

124 실전 객체지향

정적 메서드

class Calculator:
    @staticmethod
    def add(a, b):
        return a + b

print(Calculator.add(3, 4))

상세 설명

staticmethod는 객체 상태와 무관한 보조 기능을 클래스 안에 묶는다.

예상 결과

7

활용·주의점

self나 cls를 받지 않는다.

125 실전 함수

데코레이터

def announce(func):
    def wrapper():
        print("시작")
        func()
        print("끝")
    return wrapper

@announce
def study():
    print("파이썬 공부")

study()

상세 설명

데코레이터는 기존 함수의 코드를 바꾸지 않고 앞뒤 기능을 추가한다.

예상 결과

시작
파이썬 공부
끝

활용·주의점

functools.wraps를 사용하면 원래 함수 정보가 유지된다.

126 실전 함수

클로저

def make_multiplier(n):
    def multiply(x):
        return x * n
    return multiply

double = make_multiplier(2)
print(double(7))

상세 설명

클로저는 바깥 함수의 변수를 기억하는 내부 함수이다.

예상 결과

14

활용·주의점

설정값을 가진 함수를 만들 때 유용하다.

127 실전 제너레이터

yield 사용

def countdown(n):
    while n > 0:
        yield n
        n -= 1

for value in countdown(5):
    print(value)

상세 설명

yield는 값을 하나씩 생성하여 메모리를 절약한다.

예상 결과

5
4
3
2
1

활용·주의점

모든 값을 한꺼번에 저장하지 않는다.

128 실전 제너레이터

제너레이터 표현식

squares = (x ** 2 for x in range(1000000))
print(next(squares))
print(next(squares))

상세 설명

제너레이터 표현식은 필요한 순간에 값을 하나씩 계산한다.

예상 결과

0
1

활용·주의점

대용량 데이터 처리에 적합하다.

129 실전 함수형

map 사용

numbers = [1, 2, 3, 4]
result = list(map(lambda x: x * 10, numbers))
print(result)

상세 설명

map()은 각 항목에 같은 함수를 적용한다.

예상 결과

[10, 20, 30, 40]

활용·주의점

간단한 경우 리스트 컴프리헨션이 더 읽기 쉬울 수 있다.

130 실전 함수형

filter 사용

numbers = [1, 2, 3, 4, 5, 6]
result = list(filter(lambda x: x % 2 == 0, numbers))
print(result)

상세 설명

filter()는 조건을 만족하는 항목만 남긴다.

예상 결과

[2, 4, 6]

활용·주의점

조건 함수는 True 또는 False를 반환해야 한다.

131 실전 함수형

reduce 사용

from functools import reduce
numbers = [1, 2, 3, 4]
product = reduce(lambda a, b: a * b, numbers)
print(product)

상세 설명

reduce()는 여러 값을 차례로 결합하여 하나의 결과를 만든다.

예상 결과

24

활용·주의점

합계는 sum()이 더 명확하다.

132 실전 알고리즘

이진 탐색

def binary_search(data, target):
    left, right = 0, len(data) - 1
    while left <= right:
        mid = (left + right) // 2
        if data[mid] == target:
            return mid
        if data[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1

print(binary_search([1,3,5,7,9], 7))

상세 설명

정렬된 데이터에서 탐색 범위를 절반씩 줄인다.

예상 결과

3

활용·주의점

시간 복잡도는 O(log n)이다.

133 실전 알고리즘

선택 정렬

data = [64, 25, 12, 22, 11]
for i in range(len(data)-1):
    min_index = i
    for j in range(i+1, len(data)):
        if data[j] < data[min_index]:
            min_index = j
    data[i], data[min_index] = data[min_index], data[i]
print(data)

상세 설명

남은 구간에서 최솟값을 찾아 앞쪽에 배치한다.

예상 결과

[11, 12, 22, 25, 64]

활용·주의점

비교 횟수는 많지만 교환 횟수는 적다.

134 실전 알고리즘

삽입 정렬

data = [5, 2, 4, 6, 1, 3]
for i in range(1, len(data)):
    key = data[i]
    j = i - 1
    while j >= 0 and data[j] > key:
        data[j+1] = data[j]
        j -= 1
    data[j+1] = key
print(data)

상세 설명

현재 값을 앞쪽의 정렬된 구간에 알맞게 삽입한다.

예상 결과

[1, 2, 3, 4, 5, 6]

활용·주의점

거의 정렬된 데이터에서 효율적이다.

135 실전 알고리즘

병합 정렬

def merge_sort(data):
    if len(data) <= 1:
        return data
    mid = len(data) // 2
    left = merge_sort(data[:mid])
    right = merge_sort(data[mid:])
    result = []
    while left and right:
        result.append(left.pop(0) if left[0] < right[0] else right.pop(0))
    return result + left + right

print(merge_sort([5, 1, 4, 2, 8]))

상세 설명

데이터를 나누고 정렬된 부분을 합치는 분할 정복 방식이다.

예상 결과

[1, 2, 4, 5, 8]

활용·주의점

실전에서는 pop(0) 대신 인덱스를 쓰면 더 효율적이다.

136 실전 알고리즘

퀵 정렬

def quick_sort(data):
    if len(data) <= 1:
        return data
    pivot = data[0]
    left = [x for x in data[1:] if x <= pivot]
    right = [x for x in data[1:] if x > pivot]
    return quick_sort(left) + [pivot] + quick_sort(right)

print(quick_sort([5, 3, 8, 1, 2]))

상세 설명

기준값을 중심으로 작은 값과 큰 값을 나누어 재귀적으로 정렬한다.

예상 결과

[1, 2, 3, 5, 8]

활용·주의점

기준값 선택에 따라 성능이 달라진다.

137 실전 그래프

인접 리스트 그래프

graph = {
    "A": ["B", "C"],
    "B": ["A", "D"],
    "C": ["A"],
    "D": ["B"]
}
print(graph["A"])

상세 설명

인접 리스트는 각 정점에 연결된 정점 목록을 저장한다.

예상 결과

['B', 'C']

활용·주의점

희소 그래프에 메모리 효율적이다.

138 실전 그래프

너비 우선 탐색

from collections import deque

graph = {"A":["B","C"], "B":["D"], "C":["E"], "D":[], "E":[]}
queue = deque(["A"])
visited = {"A"}
while queue:
    node = queue.popleft()
    print(node, end=" ")
    for nxt in graph[node]:
        if nxt not in visited:
            visited.add(nxt)
            queue.append(nxt)

상세 설명

BFS는 큐를 사용해 가까운 정점부터 탐색한다.

예상 결과

A B C D E

활용·주의점

최단 거리 탐색의 기초가 된다.

139 실전 그래프

깊이 우선 탐색

graph = {"A":["B","C"], "B":["D"], "C":["E"], "D":[], "E":[]}
visited = set()

def dfs(node):
    visited.add(node)
    print(node, end=" ")
    for nxt in graph[node]:
        if nxt not in visited:
            dfs(nxt)

dfs("A")

상세 설명

DFS는 한 경로를 깊게 탐색한 뒤 되돌아온다.

예상 결과

A B D C E

활용·주의점

재귀 깊이가 매우 크면 반복문과 스택을 고려한다.

140 실전 검증

assert 사용

def divide(a, b):
    assert b != 0, "b는 0이 아니어야 합니다."
    return a / b

print(divide(10, 2))

상세 설명

assert는 개발 중 조건이 반드시 참인지 확인한다.

예상 결과

5.0

활용·주의점

운영 환경의 사용자 입력 검증을 assert에만 의존하면 안 된다.

141 실전 테스트

unittest 기초

import unittest

def add(a, b):
    return a + b

class TestAdd(unittest.TestCase):
    def test_add(self):
        self.assertEqual(add(2, 3), 5)

if __name__ == "__main__":
    unittest.main()

상세 설명

unittest는 표준 라이브러리 기반 자동 테스트 도구이다.

예상 결과

테스트 통과 메시지

활용·주의점

테스트 파일은 일반적으로 test_로 시작한다.

142 실전 로깅

logging 사용

import logging
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
logging.info("프로그램 시작")
logging.warning("주의가 필요합니다.")

상세 설명

logging은 print보다 체계적으로 실행 기록을 남긴다.

예상 결과

INFO와 WARNING 메시지

활용·주의점

로그 수준에는 DEBUG, INFO, WARNING, ERROR 등이 있다.

143 실전 명령행

argparse 기본

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--name", default="사용자")
args = parser.parse_args()
print(f"안녕하세요, {args.name}")

상세 설명

argparse는 명령행 인자를 안전하게 처리한다.

예상 결과

실행 인자에 따라 달라짐

활용·주의점

IDLE에서는 기본값으로 실행하고 터미널에서 인자를 전달한다.

144 실전 환경

환경 변수 읽기

import os
value = os.getenv("APP_MODE", "development")
print(value)

상세 설명

환경 변수는 비밀키나 실행 설정을 코드와 분리할 때 사용한다.

예상 결과

설정에 따라 달라짐

활용·주의점

민감한 값을 소스 코드에 직접 작성하지 않는 습관이 중요하다.

145 실전 성능

실행 시간 측정

from time import perf_counter
start = perf_counter()
total = sum(range(1_000_000))
elapsed = perf_counter() - start
print(total)
print(round(elapsed, 6))

상세 설명

perf_counter()는 짧은 코드의 실행 시간을 정밀하게 측정한다.

예상 결과

합계와 실행 시간

활용·주의점

한 번의 측정보다 여러 번 반복해 비교하는 것이 좋다.

146 실전 자료구조

heapq 우선순위 큐

import heapq
heap = []
for value in [5, 1, 3]:
    heapq.heappush(heap, value)
while heap:
    print(heapq.heappop(heap), end=" ")

상세 설명

heapq는 가장 작은 값을 빠르게 꺼내는 최소 힙을 제공한다.

예상 결과

1 3 5

활용·주의점

최대 힙은 음수 값을 이용해 구현할 수 있다.

147 실전 자료구조

bisect로 정렬 상태 유지

import bisect
data = [1, 3, 5, 7]
bisect.insort(data, 4)
print(data)

상세 설명

insort()는 정렬된 리스트의 알맞은 위치에 값을 삽입한다.

예상 결과

[1, 3, 4, 5, 7]

활용·주의점

삽입 자체는 리스트 이동 때문에 O(n)이다.

148 실전 캐시

lru_cache로 재귀 최적화

from functools import lru_cache

@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

print(fib(35))

상세 설명

lru_cache는 이전 계산 결과를 저장해 같은 계산을 반복하지 않는다.

예상 결과

9227465

활용·주의점

동적 계획법의 메모이제이션 구현에 유용하다.

149 실전 직렬화

pickle 저장과 읽기

import pickle
data = {"name": "민수", "score": 95}
with open("data.pkl", "wb") as file:
    pickle.dump(data, file)
with open("data.pkl", "rb") as file:
    loaded = pickle.load(file)
print(loaded)

상세 설명

pickle은 파이썬 객체 구조를 그대로 저장하고 복원한다.

예상 결과

{'name': '민수', 'score': 95}

활용·주의점

신뢰할 수 없는 pickle 파일은 절대 열지 않는다.

150 심화 고급 문법

타입 힌트

def average(values: list[float]) -> float:
    if not values:
        raise ValueError("빈 리스트입니다.")
    return sum(values) / len(values)

print(average([80.0, 90.0, 100.0]))

상세 설명

타입 힌트는 함수가 기대하는 자료형을 문서화하고 정적 분석을 돕는다.

예상 결과

90.0

활용·주의점

파이썬 실행 자체가 타입을 강제하지는 않는다.

151 심화 고급 문법

제네릭 타입 변수

from typing import TypeVar

T = TypeVar("T")

def first(items: list[T]) -> T:
    return items[0]

print(first([10, 20, 30]))

상세 설명

TypeVar를 사용하면 여러 자료형에 재사용 가능한 타입 안전 함수를 표현할 수 있다.

예상 결과

10

활용·주의점

빈 리스트 처리도 함께 고려해야 한다.

152 심화 고급 문법

Protocol 활용

from typing import Protocol

class HasArea(Protocol):
    def area(self) -> float: ...

def print_area(shape: HasArea) -> None:
    print(shape.area())

class Square:
    def area(self) -> float:
        return 16.0

print_area(Square())

상세 설명

Protocol은 특정 메서드를 가진 객체라면 상속 관계 없이 사용할 수 있게 한다.

예상 결과

16.0

활용·주의점

구조적 타이핑을 표현하는 방법이다.

153 심화 고급 문법

match 문

command = ("move", 10, 20)
match command:
    case ("move", x, y):
        print(f"{x}, {y}로 이동")
    case ("stop",):
        print("정지")
    case _:
        print("알 수 없음")

상세 설명

match-case는 데이터 구조의 형태를 비교하는 구조적 패턴 매칭 문법이다.

예상 결과

10, 20로 이동

활용·주의점

파이썬 3.10 이상에서 사용할 수 있다.

154 심화 고급 문법

Walrus 연산자

numbers = [1, 2, 3, 4, 5]
if (count := len(numbers)) > 3:
    print(f"항목 수: {count}")

상세 설명

:= 연산자는 표현식 안에서 값을 변수에 대입한다.

예상 결과

항목 수: 5

활용·주의점

과도하게 사용하면 코드가 읽기 어려워질 수 있다.

155 심화 고급 문법

컨텍스트 관리자 클래스

class Timer:
    def __enter__(self):
        from time import perf_counter
        self.start = perf_counter()
        return self

    def __exit__(self, exc_type, exc, tb):
        from time import perf_counter
        print(round(perf_counter() - self.start, 6))

with Timer():
    sum(range(100000))

상세 설명

__enter__와 __exit__를 구현하면 with 문에서 사용할 수 있는 컨텍스트 관리자가 된다.

예상 결과

실행 시간 출력

활용·주의점

자원 획득과 해제를 한곳에서 관리할 수 있다.

156 심화 고급 문법

contextmanager 데코레이터

from contextlib import contextmanager

@contextmanager
def managed_resource():
    print("자원 열기")
    try:
        yield "데이터"
    finally:
        print("자원 닫기")

with managed_resource() as value:
    print(value)

상세 설명

contextmanager는 제너레이터 형태로 간단한 컨텍스트 관리자를 만든다.

예상 결과

자원 열기
데이터
자원 닫기

활용·주의점

finally에서 반드시 자원을 정리한다.

157 심화 고급 문법

사용자 정의 예외

class InvalidScoreError(Exception):
    pass

def validate_score(score):
    if not 0 <= score <= 100:
        raise InvalidScoreError("점수 범위 오류")
    return score

print(validate_score(95))

상세 설명

도메인에 맞는 예외 클래스를 정의하면 오류 의미가 분명해진다.

예상 결과

95

활용·주의점

기본 Exception을 상속하는 것이 일반적이다.

158 심화 고급 문법

예외 연결

try:
    int("abc")
except ValueError as error:
    raise RuntimeError("데이터 변환 실패") from error

상세 설명

raise ... from ...은 원래 예외와 새 예외의 인과관계를 유지한다.

예상 결과

예외 추적 정보 출력

활용·주의점

디버깅 시 원인을 더 쉽게 파악할 수 있다.

159 심화 함수

부분 함수

from functools import partial

def power(base, exponent):
    return base ** exponent

square = partial(power, exponent=2)
print(square(7))

상세 설명

partial은 일부 인자를 미리 고정한 새 함수를 만든다.

예상 결과

49

활용·주의점

콜백 함수 설정에 유용하다.

160 심화 함수

singledispatch

from functools import singledispatch

@singledispatch
def describe(value):
    return "기타"

@describe.register
def _(value: int):
    return "정수"

@describe.register
def _(value: str):
    return "문자열"

print(describe(10), describe("a"))

상세 설명

singledispatch는 첫 번째 인자의 자료형에 따라 다른 함수를 선택한다.

예상 결과

정수 문자열

활용·주의점

간단한 함수 오버로딩 효과를 낼 수 있다.

161 심화 이터레이터

사용자 정의 이터레이터

class CountDown:
    def __init__(self, start):
        self.current = start

    def __iter__(self):
        return self

    def __next__(self):
        if self.current <= 0:
            raise StopIteration
        value = self.current
        self.current -= 1
        return value

print(list(CountDown(5)))

상세 설명

__iter__와 __next__를 구현하면 반복 가능한 객체가 된다.

예상 결과

[5, 4, 3, 2, 1]

활용·주의점

반복 종료 시 StopIteration을 발생시킨다.

162 심화 메타프로그래밍

속성 동적 접근

class Config:
    debug = True
    port = 8000

config = Config()
for name in ["debug", "port"]:
    print(name, getattr(config, name))

상세 설명

getattr()은 문자열로 속성 이름을 동적으로 읽는다.

예상 결과

debug True
port 8000

활용·주의점

hasattr()으로 속성 존재 여부를 먼저 확인할 수 있다.

163 심화 메타프로그래밍

setattr로 속성 설정

class Settings:
    pass

settings = Settings()
setattr(settings, "theme", "dark")
print(settings.theme)

상세 설명

setattr()은 속성 이름을 문자열로 전달해 값을 설정한다.

예상 결과

dark

활용·주의점

설정 파일을 객체로 변환할 때 활용할 수 있다.

164 심화 메타프로그래밍

함수 데코레이터에 인자 전달

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def hello():
    print("안녕")

hello()

상세 설명

데코레이터를 한 단계 더 감싸면 설정값을 받을 수 있다.

예상 결과

안녕
안녕
안녕

활용·주의점

중첩 함수의 역할을 단계별로 이해해야 한다.

165 심화 성능

timeit 비교

import timeit
list_time = timeit.timeit("[x*x for x in range(1000)]", number=1000)
loop_time = timeit.timeit("result=[]\nfor x in range(1000): result.append(x*x)", number=1000)
print(round(list_time, 4), round(loop_time, 4))

상세 설명

timeit은 코드 조각을 여러 번 실행하여 성능을 비교한다.

예상 결과

환경에 따라 달라짐

활용·주의점

운영체제와 하드웨어에 따라 결과가 달라질 수 있다.

166 심화 성능

메모리 효율적인 슬롯

class Point:
    __slots__ = ("x", "y")

    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(3, 4)
print(p.x, p.y)

상세 설명

__slots__는 허용할 속성을 제한하고 많은 객체의 메모리 사용을 줄일 수 있다.

예상 결과

3 4

활용·주의점

동적 속성 추가가 제한된다.

167 심화 성능

메모리뷰

data = bytearray(b"abcdef")
view = memoryview(data)
view[0] = ord("A")
print(data)

상세 설명

memoryview는 데이터를 복사하지 않고 버퍼를 직접 참조한다.

예상 결과

bytearray(b'Abcdef')

활용·주의점

대용량 바이너리 데이터 처리에 유용하다.

168 심화 병렬

ThreadPoolExecutor

from concurrent.futures import ThreadPoolExecutor

def square(x):
    return x * x

with ThreadPoolExecutor(max_workers=3) as executor:
    print(list(executor.map(square, [1, 2, 3, 4])))

상세 설명

스레드 풀은 여러 I/O 중심 작업을 동시에 처리하는 데 적합하다.

예상 결과

[1, 4, 9, 16]

활용·주의점

CPU 중심 작업은 프로세스 풀이 더 적합할 수 있다.

169 심화 병렬

ProcessPoolExecutor

from concurrent.futures import ProcessPoolExecutor

def square(x):
    return x * x

if __name__ == "__main__":
    with ProcessPoolExecutor() as executor:
        print(list(executor.map(square, [1, 2, 3, 4])))

상세 설명

프로세스 풀은 여러 CPU 코어를 활용할 수 있다.

예상 결과

[1, 4, 9, 16]

활용·주의점

Windows에서는 반드시 __main__ 보호 구문을 사용한다.

170 심화 비동기

asyncio 기본

import asyncio

async def greet():
    await asyncio.sleep(1)
    print("비동기 작업 완료")

asyncio.run(greet())

상세 설명

async def는 코루틴을 정의하고 await는 다른 작업에 실행권을 양보한다.

예상 결과

1초 후 비동기 작업 완료

활용·주의점

IDLE 환경에 따라 이미 실행 중인 이벤트 루프가 있으면 주의한다.

171 심화 비동기

여러 코루틴 동시 실행

import asyncio

async def task(name, delay):
    await asyncio.sleep(delay)
    return name

async def main():
    result = await asyncio.gather(task("A", 1), task("B", 0.5))
    print(result)

asyncio.run(main())

상세 설명

gather()는 여러 코루틴을 동시에 실행하고 결과를 모은다.

예상 결과

['A', 'B']

활용·주의점

반환 순서는 완료 순서가 아니라 전달 순서이다.

172 심화 비동기

비동기 타임아웃

import asyncio

async def slow():
    await asyncio.sleep(2)

async def main():
    try:
        await asyncio.wait_for(slow(), timeout=1)
    except asyncio.TimeoutError:
        print("시간 초과")

asyncio.run(main())

상세 설명

wait_for()는 지정 시간 안에 끝나지 않는 비동기 작업을 취소한다.

예상 결과

시간 초과

활용·주의점

네트워크 작업에는 타임아웃 설정이 중요하다.

173 심화 데이터베이스

SQLite 테이블 생성

import sqlite3

with sqlite3.connect("school.db") as conn:
    conn.execute("CREATE TABLE IF NOT EXISTS students (name TEXT, score INTEGER)")
print("테이블 준비 완료")

상세 설명

sqlite3는 별도 서버 없이 파일 기반 데이터베이스를 사용할 수 있게 한다.

예상 결과

테이블 준비 완료

활용·주의점

with 문을 사용하면 트랜잭션 관리가 편리하다.

174 심화 데이터베이스

SQLite 데이터 삽입

import sqlite3

with sqlite3.connect("school.db") as conn:
    conn.execute("INSERT INTO students VALUES (?, ?)", ("민수", 95))
print("삽입 완료")

상세 설명

물음표 자리표시자를 사용하면 SQL 인젝션 위험을 줄일 수 있다.

예상 결과

삽입 완료

활용·주의점

문자열 연결로 SQL을 만들지 않는다.

175 심화 데이터베이스

SQLite 조회

import sqlite3

with sqlite3.connect("school.db") as conn:
    rows = conn.execute("SELECT name, score FROM students WHERE score >= ?", (90,))
    for row in rows:
        print(row)

상세 설명

조건을 사용해 필요한 데이터만 조회한다.

예상 결과

저장 데이터에 따라 달라짐

활용·주의점

한 개짜리 튜플은 뒤에 쉼표가 필요하다.

176 심화 네트워크

urllib로 웹 문서 요청

from urllib.request import urlopen

with urlopen("https://example.com", timeout=5) as response:
    print(response.status)
    print(response.read(60).decode("utf-8", errors="ignore"))

상세 설명

urllib는 표준 라이브러리만으로 HTTP 요청을 수행한다.

예상 결과

상태 코드 200과 일부 HTML

활용·주의점

인터넷 연결이 필요하며 예외 처리를 추가해야 한다.

177 심화 네트워크

URL 인코딩

from urllib.parse import urlencode
params = {"q": "파이썬 데이터", "page": 1}
print(urlencode(params))

상세 설명

urlencode()는 한글과 특수문자를 URL 쿼리 문자열로 변환한다.

예상 결과

q=%ED%8C%8C...&page=1

활용·주의점

웹 API 요청 주소를 만들 때 사용한다.

178 심화 데이터 구조

트라이 자료구조

class Trie:
    def __init__(self):
        self.root = {}

    def insert(self, word):
        node = self.root
        for ch in word:
            node = node.setdefault(ch, {})
        node["$"] = True

    def contains(self, word):
        node = self.root
        for ch in word:
            if ch not in node:
                return False
            node = node[ch]
        return "$" in node

trie = Trie()
trie.insert("python")
print(trie.contains("python"))

상세 설명

트라이는 문자열의 접두사를 효율적으로 저장하고 검색한다.

예상 결과

True

활용·주의점

자동완성이나 사전 검색에 활용된다.

179 심화 알고리즘

동적 계획법 배낭 문제

weights = [2, 3, 4]
values = [3, 4, 5]
capacity = 5
dp = [0] * (capacity + 1)
for w, v in zip(weights, values):
    for c in range(capacity, w - 1, -1):
        dp[c] = max(dp[c], dp[c-w] + v)
print(dp[capacity])

상세 설명

이전 부분 문제의 결과를 저장해 0-1 배낭 문제를 해결한다.

예상 결과

7

활용·주의점

역순 반복은 같은 물건을 여러 번 사용하는 것을 막는다.

180 심화 알고리즘

최장 증가 부분 수열

data = [10, 20, 10, 30, 20, 50]
dp = [1] * len(data)
for i in range(len(data)):
    for j in range(i):
        if data[j] < data[i]:
            dp[i] = max(dp[i], dp[j] + 1)
print(max(dp))

상세 설명

각 위치에서 끝나는 증가 부분 수열의 최대 길이를 저장한다.

예상 결과

4

활용·주의점

이 구현의 시간 복잡도는 O(n²)이다.

181 심화 알고리즘

다익스트라 최단 경로

import heapq

graph = {
    "A": [("B", 2), ("C", 5)],
    "B": [("C", 1)],
    "C": []
}
dist = {node: float("inf") for node in graph}
dist["A"] = 0
heap = [(0, "A")]
while heap:
    cost, node = heapq.heappop(heap)
    if cost > dist[node]:
        continue
    for nxt, weight in graph[node]:
        new_cost = cost + weight
        if new_cost < dist[nxt]:
            dist[nxt] = new_cost
            heapq.heappush(heap, (new_cost, nxt))
print(dist)

상세 설명

우선순위 큐를 이용해 음수가 없는 가중치 그래프의 최단 거리를 구한다.

예상 결과

{'A': 0, 'B': 2, 'C': 3}

활용·주의점

음수 가중치가 있으면 다른 알고리즘이 필요하다.

182 심화 알고리즘

위상 정렬

from collections import deque

graph = {"A":["C"], "B":["C"], "C":["D"], "D":[]}
indegree = {node: 0 for node in graph}
for node in graph:
    for nxt in graph[node]:
        indegree[nxt] += 1
queue = deque([n for n in graph if indegree[n] == 0])
order = []
while queue:
    node = queue.popleft()
    order.append(node)
    for nxt in graph[node]:
        indegree[nxt] -= 1
        if indegree[nxt] == 0:
            queue.append(nxt)
print(order)

상세 설명

위상 정렬은 선후 관계가 있는 작업을 가능한 순서로 배열한다.

예상 결과

['A', 'B', 'C', 'D'] 또는 A/B 순서 교환

활용·주의점

사이클이 있는 그래프에는 적용할 수 없다.

183 심화 알고리즘

Union-Find

parent = list(range(5))

def find(x):
    if parent[x] != x:
        parent[x] = find(parent[x])
    return parent[x]

def union(a, b):
    ra, rb = find(a), find(b)
    if ra != rb:
        parent[rb] = ra

union(0, 1)
union(1, 2)
print(find(0) == find(2))

상세 설명

Union-Find는 원소들이 같은 집합에 속하는지 빠르게 관리한다.

예상 결과

True

활용·주의점

경로 압축으로 탐색 속도를 높인다.

184 심화 알고리즘

에라토스테네스의 체

n = 50
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, int(n ** 0.5) + 1):
    if is_prime[i]:
        for multiple in range(i*i, n+1, i):
            is_prime[multiple] = False
print([i for i, value in enumerate(is_prime) if value])

상세 설명

여러 소수를 한꺼번에 구할 때 효율적인 알고리즘이다.

예상 결과

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

활용·주의점

i*i부터 지우면 중복 작업을 줄일 수 있다.

185 심화 수치

뉴턴 방법으로 제곱근

def sqrt_newton(value, tolerance=1e-10):
    guess = value / 2
    while abs(guess * guess - value) > tolerance:
        guess = (guess + value / guess) / 2
    return guess

print(sqrt_newton(2))

상세 설명

뉴턴 방법은 반복 계산으로 방정식의 근을 빠르게 근사한다.

예상 결과

약 1.41421356237

활용·주의점

초기값과 종료 조건 선택이 중요하다.

186 심화 수치

사다리꼴 적분

def integrate(f, a, b, n=1000):
    h = (b - a) / n
    total = (f(a) + f(b)) / 2
    for i in range(1, n):
        total += f(a + i * h)
    return total * h

print(integrate(lambda x: x**2, 0, 1))

상세 설명

구간을 작은 사다리꼴로 나누어 정적분을 근사한다.

예상 결과

약 0.3333335

활용·주의점

n을 늘리면 대체로 정확도가 높아진다.

187 심화 수치

오일러 방법 미분방정식

def euler(f, x0, y0, h, steps):
    x, y = x0, y0
    for _ in range(steps):
        y += h * f(x, y)
        x += h
    return x, y

x, y = euler(lambda x, y: y, 0, 1, 0.1, 10)
print(x, y)

상세 설명

오일러 방법은 미분방정식의 해를 작은 시간 간격으로 근사한다.

예상 결과

약 1.0 2.5937

활용·주의점

간격 h가 작을수록 오차가 줄지만 계산량이 늘어난다.

188 심화 수치

행렬 곱셈 직접 구현

A = [[1, 2], [3, 4]]
B = [[5, 6], [7, 8]]
result = [[sum(A[i][k] * B[k][j] for k in range(2)) for j in range(2)] for i in range(2)]
print(result)

상세 설명

행과 열의 대응 원소를 곱해 합산하여 행렬 곱셈을 구현한다.

예상 결과

[[19, 22], [43, 50]]

활용·주의점

대규모 행렬은 NumPy가 훨씬 빠르다.

189 심화 설계

전략 패턴

class Discount:
    def apply(self, price):
        return price

class StudentDiscount:
    def apply(self, price):
        return price * 0.8

class Order:
    def __init__(self, strategy):
        self.strategy = strategy

    def total(self, price):
        return self.strategy.apply(price)

print(Order(StudentDiscount()).total(10000))

상세 설명

전략 패턴은 교체 가능한 알고리즘을 객체로 분리한다.

예상 결과

8000.0

활용·주의점

조건문이 많아지는 계산 규칙에 유용하다.

190 심화 설계

옵저버 패턴

class Subject:
    def __init__(self):
        self.observers = []

    def subscribe(self, observer):
        self.observers.append(observer)

    def notify(self, message):
        for observer in self.observers:
            observer(message)

subject = Subject()
subject.subscribe(lambda m: print("알림:", m))
subject.notify("새 데이터")

상세 설명

옵저버 패턴은 상태 변화가 발생했을 때 여러 구독자에게 알린다.

예상 결과

알림: 새 데이터

활용·주의점

이벤트 기반 프로그램의 기초 구조이다.

191 심화 설계

팩토리 함수

class Dog:
    def speak(self): return "멍멍"

class Cat:
    def speak(self): return "야옹"

def create_animal(kind):
    classes = {"dog": Dog, "cat": Cat}
    return classes[kind]()

print(create_animal("cat").speak())

상세 설명

팩토리 함수는 객체 생성 방법을 호출 코드에서 분리한다.

예상 결과

야옹

활용·주의점

새 클래스 추가 시 생성 규칙을 한곳에서 관리할 수 있다.

192 심화 테스트

mock으로 의존성 대체

from unittest.mock import Mock

service = Mock()
service.get_score.return_value = 95
print(service.get_score("민수"))
service.get_score.assert_called_once_with("민수")

상세 설명

Mock은 실제 외부 서비스 대신 가짜 객체를 사용해 테스트를 단순화한다.

예상 결과

95

활용·주의점

네트워크나 데이터베이스 의존성 테스트에 유용하다.

193 심화 테스트

임시 파일 테스트

from tempfile import NamedTemporaryFile

with NamedTemporaryFile(mode="w+", encoding="utf-8", delete=True) as file:
    file.write("테스트 데이터")
    file.seek(0)
    print(file.read())

상세 설명

tempfile은 테스트 후 자동 정리되는 임시 파일을 제공한다.

예상 결과

테스트 데이터

활용·주의점

실제 사용자 파일을 손상시키지 않고 파일 기능을 시험할 수 있다.

194 심화 프로파일링

cProfile 사용

import cProfile

def work():
    return sum(i*i for i in range(100000))

cProfile.run("work()")

상세 설명

cProfile은 함수별 실행 횟수와 시간을 분석한다.

예상 결과

프로파일링 표 출력

활용·주의점

느린 구간을 찾은 뒤 최적화해야 한다.

195 심화 로깅

파일 로그 저장

import logging
logging.basicConfig(
    filename="app.log",
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(message)s",
    encoding="utf-8"
)
logging.info("프로그램 시작")

상세 설명

로그를 파일에 저장하면 실행 이력을 나중에 분석할 수 있다.

예상 결과

app.log 생성

활용·주의점

개인정보나 비밀키를 로그에 남기지 않는다.

196 심화 설정

configparser 설정 파일

import configparser

config = configparser.ConfigParser()
config["APP"] = {"theme": "dark", "font_size": "14"}
with open("settings.ini", "w", encoding="utf-8") as file:
    config.write(file)
print("설정 저장")

상세 설명

configparser는 INI 형식 설정 파일을 읽고 쓴다.

예상 결과

설정 저장

활용·주의점

숫자와 불리언은 읽을 때 전용 변환 메서드를 사용한다.

197 심화 압축

zip 파일 만들기

from zipfile import ZipFile

with ZipFile("backup.zip", "w") as zip_file:
    zip_file.write("memo.txt")
print("압축 완료")

상세 설명

zipfile 모듈은 표준 ZIP 압축 파일을 만들고 해제한다.

예상 결과

backup.zip 생성

활용·주의점

압축할 파일이 존재하는지 확인해야 한다.

198 심화 암호학 기초

HMAC 무결성 검증

import hmac
import hashlib

key = b"secret-key"
message = b"important data"
signature = hmac.new(key, message, hashlib.sha256).hexdigest()
print(signature)

상세 설명

HMAC은 비밀키와 해시 함수를 이용해 데이터가 변조되지 않았는지 확인한다.

예상 결과

64자리 서명

활용·주의점

키는 코드에 직접 저장하지 않고 안전하게 관리해야 한다.

199 심화 파싱

HTMLParser 사용

from html.parser import HTMLParser

class TitleParser(HTMLParser):
    def handle_starttag(self, tag, attrs):
        if tag == "h1":
            print("제목 태그 발견")

parser = TitleParser()
parser.feed("<h1>파이썬</h1>")

상세 설명

HTMLParser는 HTML 문서를 이벤트 방식으로 분석한다.

예상 결과

제목 태그 발견

활용·주의점

복잡한 문서 분석에는 전용 외부 라이브러리가 편리할 수 있다.

200 심화 문서화

docstring 작성

def area(width: float, height: float) -> float:
    """직사각형의 넓이를 반환한다.

    Args:
        width: 가로 길이
        height: 세로 길이
    """
    return width * height

print(area.__doc__)

상세 설명

docstring은 함수의 목적과 인자, 반환값을 코드 안에 기록한다.

예상 결과

함수 설명 출력

활용·주의점

help(area)로 문서를 확인할 수 있다.