You are on page 1of 237

초보자를 위한 파이썬 200제

본 PPT 문서는 정보문화사에서 출판한


<초보자를 위한 파이썬 200제>에 관련된 자료입니다.
001 대화식 모드로 프로그래밍하기
>>> print('안녕하세요') 대화식 모드로 파이썬 프로그래밍을 하는 방법
안녕하세요 • 윈도우 명령 프롬프트를 열고 파이썬을 실행한다.

• IDLE을 실행한다.

> > > : 파이썬 인터프리터의 프롬프트

IDLE을 실행하려면 윈도우 명령프롬프트나 윈도우 하단 작업표시


줄 왼쪽에 있는 윈도우검색창에서 IDLE을 입력

‘> > >’ 부분에 파이썬 코드를 한 라인 작성하고 Enter를 누르면 파이


썬 인터프리터는 곧바로 이를 해석하여 결과를 보여줍니다.

‘> > >’가 표시된 부분은 모두 대화식 모드로 프로그래밍하는 것으


로 생각하면 됩니다.
002 텍스트 에디터로 프로그래밍하기
1. print('안녕하세요') IDLE을 실행하고 상단 메뉴에서 [File] – [New File]을 클릭
2. a=1
텍스트 에디터에 코드 입력 후 Ctrl + C 를 누르고 ‘002.py’로 저장
3. b=1
4. print(a+b) F5를 눌러 저장된 코드를 실행

이 방법은 파일에 작성된 파이썬 코드를 한번에 일괄적으로실행하


는 배치 형식으로 동작으로, 프로그래머가 일반적으로 코딩하는
방식
003 변수명 만들기
>>> _myname = 'samsjang' 변수명 첫 문자는 밑줄 문자 ‘_’ 또는 영문자로 시작해야 함
>>> my_name = '홍길동
>>> MyName2 = 'Hong gil-dong'
변수명의 두 번째 문자부터는 알파벳, 숫자 그리고 밑줄 문자를 사용.
>>> counter = 1
변수명은 대소문자를 구분하므로 counter와 Counter는 다른 변수가
>>> Counter = 2 됨.

* 파이썬 예약어

파이썬에서 이미 사용하고 있는 일부 단어는 변수명으로 사용할 수


없음.

제어문으로 사용되는 if, elif, while, for

함수를 정의할 때 사용되는 def

클래스를 나타내는 class 등


004 변수에 값 대입하기
1. number1 = 1 1~2번째 줄 : 변수 number1에 정수 1을 대입했으므로 number1은
2. pi = 3.14 정수 자료가 되며 변수 pi에는 3.14를 대입해서 실수 자료가 됨.
3. flag = True
3번째 줄 : flag에 True를 대입하여 참 또는 거짓을 나타내는 불린
4. char = 'x'
(boolean) 자료로 활용.
5. chars = 'I love Python'
4~5번째 줄 : 한 개의 문자를 변수에 대입하거나 여러 개의 문자로
구성된 문자열을 변수에 대입하여 한 문자 또는 문자열을 정의.
005 주석 처리하기 (#)
1. # 주석 처리 예시임 파이썬 코드 한 라인을 주석처리하기 위해서 문자 ‘#’으로 시작.
2. # 만든 날짜: 2016. 5. 30 ‘#’ 이전의 문자들은 주석 처리가 되지 않음
3. a = 1 # a에 1을 대입함
4. b = 5 # b에 5를 대입함
5. print(a+b) # a+b의 결과를 출력함
특정 영역을 주석 처리하고자 하는 경우

# 삼중 따옴표로 특정 영역 주석 처리 예시
"""a = 1
b=5
print(a+b)"""
a=2
b=6
print(a+b)
006 자료형 개념 배우기
1. int _data = 1 # 정수 선언 1. 수치형 자료 (1~3번째 줄)
2. float _data = 3.14 # 실수 선언
• 정수형 상수: -1, 0, 1 과 같은 경우
3. complex_data = 1+5j # 복소수 선언 • 실수형 상수: -0.7, 2.1 등과 같이 분수로 표현할 수 있는 유리수
와 π(원주율), 2 와 같은 무리수를 포함하는 실수
4. str _data1 = 'I love Python' # 문자열 선언 (영문) • 복소수형 상수: 실수부 + 허수부로 되어 있는 복소수
5. str _data2 = "반갑습니다." # 문자열 선언 (한글)
각 변수에 정수형 상수 1, 실수형 상수 3.14, 복소수형 상수 1+5j를 대입한
6. list _data = [1, 2, 3] # 리스트 선언 예. 파이썬에서 허수부는 j로 표현함
7. tuple _data = (1, 2, 3) # 튜플 선언
2. 문자열 자료 (4~5번째 줄)
8. dict _data = {0:'False', 1:'True'} # 사전 선언
문자열 자료의 선언 방법으로는 4라인처럼 ‘ ’로 둘러싸인 문자열을 변수
에 대입하는 방법과, 5라인과 같이 “ ”로 둘러싸인 문자열을 변수에 대입
하는 방법이 있음

3. 리스트 자료 (6번째 줄) list_data의 요소는 1, 2, 3 숫자로만 되어 있지


만 리스트의 각 요소는 임의의 자료형이나 객체가 될 수 있음

4. 튜플 자료 (7번째 줄) 리스트와 비슷하나 요소 값을 변경할 수 없음

5. 사전 자료 (8번째 줄)

‘{ }’ 안에 ‘키:값’으로 된 쌍이 요소로 구성된 순서가 없는 자료형. 각 요소


는 콤마로 구분하여 나열합니다. 사전 자료는 순서가 없으므로 인덱스로
값을 접근할 수 없고 키를 이용해 대응되는 값을 접근
007 자료형 출력 개념 배우기
1. a = 200 1~4번째 줄 : 변수에 수치형 자료, 문자열, 리스트, 사전 자료를 정의
해서 대입
2. msg = 'I love Python'
3. list _data = ['a', 'b', 'c'] 5번째 줄 : 변수 a의 값을 화면에 출력. 변수 a에는 숫자 200이 대입
되어 있으므로 200이 출력됨.
4. dict _data = {'a':97, 'b':98}
6번째 줄 : 변수 msg의 값을 화면에 출력. 분수 msg에는 ‘ I love
5. print(a) Python’이라는 문자열이 대입되어 있으므로 ‘ I love Python’을 출력
6. print(msg)
7~8번째 줄 : 리스트 자료인 list_data와 list_data의 첫 번째 요소를
7. print(list_data) 출력
8. print(list_data[0]) 9~10번째 줄 : 사전 자료인 dict_data와 dict_data에서 키가 a인 값을
출력
9. print(dict_data)
10. print(dict_data['a'])
결과

200
I love Python
['a', 'b', 'c']
a
{'b': 98, 'a': 97}
97
008 들여쓰기 개념 배우기
1. listdata = ['a', 'b', 'c'] 파이썬은 들여쓰기(indentation)로 괄호 { }를 대신함.

2. if 'a' in listdata: Space bar / Tab으로 들여쓰기를 할 수 있음.


3. print('a가 listdata에 있습니다.') 제어문이나 함수이름, 클래스 이름 뒤에 콜론(‘:’)으로 제어문, 함수
4. print(listdata) 이름, 클래스 이름의 끝을 표시하며 ‘:’ 다음에 실행 코드를 작성

5. else:
6. print('a가 listdata에 존재하지 않습니다.') 실행 코드가 한 라인일 경우
if 'a' in listdata: print('a가 listdata에 있습니다.')

1. 가장 바깥쪽의 실행 코드는 들여쓰기 없이 시작해야 함


(공백)listdata = ['a', 'b', 'c']
if 'a' in listdata:

2. 콜론(‘ : ’) 다음 라인부터 시작하는 실행 코드는 들여쓰기 간격이


모두 동일해야 함
listdata = ['a', 'b', 'c']
if 'a' in listdata:
print('a가 listdata에 있습니다.')
print(listdata) # 오류가 발생하는 지점
else:
print('a가 listdata에 존재하지 않습니다.')
009 if문 개념 배우기 ① (if~else)
1. x=1 if 조건:
실행 코드 1
2. y=2 else:
실행 코드 2
3. if x >= y:
4. print('x가 y보다 크거나 같습니다.') if문은 조건이 참인지 아닌지 판단하여 코드를 수행할 때 사용하는
조건문
5. else:
if 뒤의 조건이 참이면 실행 코드 1을 수행하고, 조건이 거짓이면 실
6. print('x가 y보다 작습니다.') 행 코드 2를 수행함.

1~2번째 줄 : 변수 x, y에 각각 1, 2를 대입

3~4번째 줄 : x가 y보다 크거나 같으면 ‘x가 y보다 크거나 같습니다.’


를 출력

5~6번째 줄 : x가 y보다 작으면 ‘x가 y보다 작습니다.’를 출력


010 if문 개념 배우기 ② (if~elif)
1. x=1 If ~ elif문의 기본적인 사용
2. y=2 if 조건 1:
실행 코드 1
3. if x > y: elif 조건 2
실행 코드 2
4. print('x가 y보다 큽니다.') else:
실행 코드 3
5. elif x < y:
6. print('x가 y보다 작습니다.')
7. else: 3~8번째 줄 : x가 y보다 큰지 확인하고 조건이 거짓이면 x가 y보다

8. print('x와 y가 같습니다.) 작은지 확인. 이 결과도 거짓이면 x와 y는 값이 같으므로 ‘x와 y가 같


습니다.’를 출력함.
011 for문 개념 배우기 ① (for)
1. scope = [1, 2, 3, 4, 5] for문의 기본적인 사용
2. for x in scope: for 변수 in 범위:
반복으로 실행할 코드
3. print(x)
for문의 범위로 사용되는 것은 시퀀스 자료형 또는 반복 가능한 자료
여야 함.

for문의 범위로 사용되는 객체

• 문자열
• 리스트나 튜플
• 사전
• range( )
• 그 외 반복 가능한 객체
012 for문 개념 배우기 ② (for~continue~break)
1. scope = [1, 2, 3, 4, 5] for 반복문 안에서 continue를 만나면 이후 코드는 수행하지 않고 다
2. for x in scope: 음 반복문을 수행하게 되며, break를 만나면 for 반복문을 탈출하게
3. print(x) 됨.
4. if x < 3:
for 변수 in 범위:
5. continue …
continue # 다음 반복문 수행
6. else: …
break # for 반복문 탈출
7. break

예제는 1~5까지 정수에 대해 코드를 반복하는데, 화면에 해당 정수


를 출력한 후 그 수가 3보다 작으면 그 다음 숫자를 출력하고 3보다
크거나 같으면 for 반복문을 탈출하여 종료함.

scope = [1, 2, 3, 4, 5]
for x in scope:
print(x)
if x >= 3:
break
013 for문 개념 배우기 ③ (for~else)
1. scope = [1, 2, 3,] for 반복문이 break에 의해 중단됨이 없이 정상적으로 모두 실행되
2. for x in scope: 어야만 특정 코드를 실행하게 할 경우 for ~ else를 사용함.
3. print(x)
for 변수 in 범위:
4. break 반복 실행 코드
else:
5. else: for 구문이 모두 실행되었을 때 실행할 코드
6. print('Perfect')
else:로의 진입은 for 반복문에서 break 등에 의해 중간에 중단됨이
없이 정상적으로 실행이 다 되었을 경우

1
2
3
Perfect
014 while문 개념 배우기 (while~continue~break)
1. x=0 기본 while 구문
2. while x < 10:
while 조건:
3. x = x+1 반복 실행 코드
continue # while 구문 처음으로 이동하여 반복문 계속
4. if x < 3: …
break # while 구문을 탈출함
5. continue
6. print(x)
7. if x > 7: 1~2번째 줄 : x의 초기값을 0으로 설정하고, 변수 x의 값이 10보다 작
8. break 으면 while 반복문을 계속 수행함. x의 초기값이 0이므로 while의 조
건이 참이 되며 while 구문으로 진입하게 됨.

3~8번째 줄 : x의 값을 1 증가시키고 x가 3보다 작으면 continue를 통


해 while 반복문 처음으로 돌아가게 함.

만약 x가 3보다 크거나 같으면 x값을 출력하고 x가 7보다 큰 값인지


체크한 후, 7보다 크면 while 반복문을 탈출함.
015 None 개념 배우기
1. val = None 파이썬 문서에서 설명하는 None
2. condition = 1
None은 Types.NoneType의 유일한 값으로, 값이 존재하지 않는 변수에
3. if condition == 1: 대입하여 이 변수에 아무런 값이 없다는 것을 나타내기 위해 주로 활용
4. val = [1, 2, 3] 된다.

5. else:
6. val = 'I love Python'
Val = None으로 선언한 경우, val은 아무런 값도 가지지 않는 변수이
므로 이 변수로는 아무것도 할 수 없음.

하지만 None으로 지정된 변수에 값이 있는 임의의 자료형을 대입하


여 활용 가능.

예제는 condition의 값에 따라 val에 리스트 또는 문자열을 대입하는


예로, condition의 값이 1이면 val에 리스트 [1, 2, 3]을 대입하고
condition의 값이 1이 아니면 변수 val에 문자열 ‘I love Python’을 대
입함.
016 정수형 자료 이해하기
1. int _data = 10 2~5번째 줄 : 파이썬의 정수형 상수의 최소값, 최대값은 존재하지 않
2. bin_data = 0b10 고, 메모리가 허용하는 범위에서 지원 가능한 수를 사용 가능
3. oct _data = 0o10
6~10번째 줄 : 정수형 상수를 대입한 변수 출력 – 모두 10진수
4. hex_data = 0x10
5. long_data = 1234567890123456789
6. print(int_data)
결과
7. print(bin_data)
10
8. print(oct _data) 2
9. print(hex _data) 8
16
10. print(long_data) 1234567890123456789
017 실수형 자료 이해하기
1. f1 = 1.0 1~2번째 줄 : 변수에 소수로 표현한 값을 대입하면 실수형 자료 취급.
2. f2 = 3.14 f1, f2 모두 실수형 자료
3. f3 = 1.56e3
3~4번째 줄 : 실수형 상수를 표현하는 또 다른 방법은 e(10의 거듭
4. f4 = -0.7e-4 제곱)를 사용하는 것.
5. print(f1) e2는 102, e-3은 10-3을 나타냄.
6. print(f2)
7. print(f3)
결과
8. print(f4)
1.0
3.14
1560.0
-7e-05
018 복소수형 자료 이해하기
1. c1 = 1+7j 복소수형 상수 : 실수부 + 허수부로 되어 있는 수
2. print(c1.real); print(c1.imag)
3. c2 = complex(2, -3)
1번째 줄 : 변수 c1에 복소수형 상수 1 + 7j를 대입
4. print(c2)
2~3번째 줄 : 복소수형 자료에서 실수부만 취하려면 real 이용.

복소수형 자료에서 허수부만 취하려면 imag 이용.

c1.real과 c1.imag는 각각 1.0, 7.0

4~6번째 줄 : complex( )를 이용해 복소수형 상수 구성.

complex(2, 3)은 실수부가 2, 허수부가 3인 복소수.

변수 c2에 대입 → c2의 값은 2 + 3j

결과
1.0
7.0
(2+3j)
019 대입 연산자 이해하기(=)
1. a=1 =(등호) : 변수에 값을 대입하는데 사용되는 기호
2. b=2 파이썬을 포함한 컴퓨터 프로그래밍 언어에서 =는
3. ret = a+b
= 왼쪽의 변수에 = 오른쪽의 값을 대입한다는 의미
4. print('a와 b를 더한 값은 ', end='')
5. print(ret, end='')
1~2번째 줄 : 변수 a와 b에 각각 정수형 상수 1과 2를 대입
6. print('입니다.')
3번째 줄 : 변수 ret에 a와 b를 더한 값을 대입.

변수 a와 b의 값이 각각 1과 2이므로 ret은 3

4~6번째 줄 : ‘a와 b를 더한 값은 ’을 줄바꿈 문자 \n을 생략하고

출력하고, ret의 값을 출력한 후, ‘입니다.’를 출력

결과
a와 b를 더한 값은 3입니다.
020 사칙 연산자 이해하기
1. a=2 1~2번째 줄 : 변수 a와 b에 각각 정수형 상수 2와 4를 대입
2. b=4 3번째 줄 : 정수형 자료 a와 b를 더한 값을 변수 ret1에 대입
3. ret1 = a+b # ret1 = 2+4 = 6
4번째 줄 : 정수형 자료 a에서 b를 뺀 값을 변수 ret2에 대입
4. ret2 = a–b # ret2 = 2–4 = -2
5번째 줄 : 정수형 자료 a와 b를 곱한 값을 변수 ret3에 대입
5. ret3 = a*b # ret3 = 2*4 = 8
6번째 줄 : 정수형 자료 a에서 b를 나눈 값을 변수 ret4에 대입
6. ret4 = a/b # ret4 = 2/4 = 0.5
7. ret5 = a**b # ret5 = 2**4 = 16 파이썬 3은 나눗셈의 경우 실수형으로 결과를 리턴

8. ret6 = a+a*b/a # ret6 = 2+2*4/2 = 6 7번째 줄 : 정수형 자료 a를 b번 거듭제곱하여 변수 ret5에 대입

9. ret7 = (a+b)*(a–b) # ret7 = (2+4)*(2-4) = -12 8번째 줄 : a+a*b/a는 a*b/a를 먼저 계산하고 이 값을 a와 더함


10. ret8 = a*b**a # ret8 = 2*4**2 = 32 9번째 줄 : 괄호( )로 묶여 있는 부분을 먼저 계산한 후 사칙 연산을

수행. (a+b)*(a-b)는 (a+b)와 (a-b)를 먼저 계산하고

두 값을 곱함

10번째 줄 : 거듭제곱이 우선 순위.

a*b**a는 b**a를 먼저 계산하고 a와 곱함


021 연산자 축약 이해하기
1. a=0 변수 a에 1을 더하고 그 결과를 다시 변수 a에 대입할 때
2. a += 1 # a = a+1, a의 값은 1 a = a+1

3. a -= 5 # a = a-5, a의 값은 -4
4. a *= 2 # a = a*2, a의 값은 -8
어떤변수와어떤값을사칙연산한결과를다시동일한변수에대입할때
5. a /= 4 # a = a/4, a의 값은 -2.0
a += 1

1~4번째 줄 : a에 정수형 상수 0을 대입하고,

a에 1을 더한 결과를 다시 a에 대입.

a에 5를 뺀 결과를 다시 a에 대입하고,

a에 2를 곱한 값을 a에 대입

5번째 줄 : a를 정수형 상수 4로 나누고 그 결과를 a에 대입.

a의 최종값은 -2.0
022 True와 False 이해하기
1. a = True 파이썬에서 참과 거짓을 나타내는 상수 :
2. b = False True와 False True는 1, False는 0
3. print(a == 1) # True가 출력됨
4. print(b != 0) # False가 출력됨
1~2번째 줄 : a에 True, b에 False를 대입

3번째 줄 : True 값이 대입된 a가 1과 같은 값인지 체크

4번째 줄 : False 값이 대입된 b가 0과 다른 값인지 체크

while 코드 : 코드에 무한 루프 로직을 구현할 때

while True:
(무한 반복 실행 코드)

if 조건 == True: # 조건이 만족하면 무한루프를 탈출함
break
023 관계 연산자 이해하기
1. x = 1; y = 2 파이썬에서 사용 가능한 관계 연산자
2. str1 = 'abc'; str2 = 'python' A == B A와 B가 같으면 참
3. print(x == y) # False가 출력됨 A != B A와 B가 다르면 참
A<B A가 B보다 작으면 참
4. print(x != y) # True가 출력됨
A <= B A가 B보다 작거나 같으면 참
5. print(str1 == str2) # False가 출력됨
A>B A가 B보다 크면 참
6. print(str2 == 'python') # True가 출력됨 A >= B A가 B보다 크거나 같으면 참
7. print(str1 < str2) # True가 출력됨
1~2번째 줄 : x, y에 각각 정수형 상수1과 2를 대입하고,

str1과 str2에는 문자열 ‘abc’와 ‘python’을 각각 대입

3번째 줄 : x와 y가 같은 값인지 검사하고 결과를 출력

4번째 줄 : x와 y가 다른 값인지 검사하고 결과를 출력

5번째 줄 : str1과 str2가 서로 같은지 비교하고 결과를 출력

6번째 줄 : str2와 ‘python’이 서로 같은지 비교하고 결과를 출력

7번째 줄 : str1이 str2보다 작은지 비교하고 결과를 출력

문자열의 크기 비교는 문자열의 사전 순서


024 논리 연산자 이해하기
1. bool1 = True; bool2 = False; bool3 = True; bool4 = False 1번째 줄 : boo1과 boo3은 True, bool2와 bool4는 False를 각각 대입
2. print(bool1 and bool2) # False가 출력됨 2번째 줄 : bool1과 bool2의 and 연산 결과를 출력
3. print(bool1 and bool3) # True가 출력됨
3번째 줄 : bool1과 bool3의 and 연산 결과를 출력
4. print(bool2 or bool3) # True가 출력됨
4번째 줄 : bool2와 bool3의 or 연산 결과를 출력
5. print(bool2 or bool4) # False가 출력됨
5번째 줄 : bool2와 bool4의 or 연산 결과를 출력
6. print(not bool1) # False가 출력됨
7. print(not bool2) # True가 출력됨 6~7번째 줄 : bool1 반대 논리값을 출력

파이썬에서 사용 가능한 논리 연산자

A and B A와 B가 모두 참이면 참
A or B A, B 중 하나 이상이 참이면 참
not A A 논리값의 반대
025 비트 연산자 이해하기
1비트 : 0또는 1로만 표현될 수 있는 데이터 단위. 1비트는 두 개의 값만 표시 가능하므로 1비트로 나타낼 수 있는 경우의 수는 두 가지

Ex. 문자 ‘a’와 문자 ‘b’의 비트간 연산 : ‘a’의 각 비트들과 ‘b’의 각 비트들을 자릿수에 맞게 비트별로 연산을 독립적으로 수행한다는 의미

1바이트를 2진수로 표현하면 8자리 숫자가 되기 때문에 편의상 1바이트를 표현할 때 두 자리 16진수로 표현함.

상위 4비트 : 1바이트를 이루는 8비트에서 왼쪽 4비트 / 하위 4비트 : 오른쪽 4비트 => 각각 16진수로 대응시켜 나타냄.
025 비트 연산자 이해하기
1. bit1 = 0x61 1~2번째 줄 : bit1과 bit2에 각각 16진수 61, 62를 대입
2. bit2 = 0x62 3번째 줄 : 0110 0001 & 0110 0010을 연산하면 0110 0000 (16진
3. print(hex(bit1 & bit2)) # 0x60이 출력됨 수로 60)

4. print(hex(bit1 | bit2)) # 0x63이 출력됨 4번째 줄 : 0110 0001 | 0110 0010을 연산하면 0110 0011 (16진
수로 63)
5. print(hex(bit1 ^ bit2)) # 0x3 이 출력됨
5번째 줄 : 0110 0001 ^ 0110 0010을 연산하면 0000 0011 (16진
6. print(hex(bit1 >> 1)) # 0x30이 출력됨
수로 3, 배타적 논리합 XOR은 두 개의 비트값이 다른 경우에는 1, 같
7. print(hex(bit1 << 2)) # 0x184가 출력됨 은 경우에는 0)

6번째 줄 : 0110 0001을 오른쪽으로 1만큼 시프트. 결과는 0011


0000 (16진수 값으로 30)

7번째 줄 : 0110 0001을 왼쪽으로 2만큼 시프트. 결과는 0001


1000 0100 (16진수값으로 184)
026 시퀀스 자료형 이해하기
1. strdata = 'abcde‘ # 문자열은 시퀀스 자료형임 시퀀스 자료형 : 어떤 객체가 순서를 가지고 나열되어 있는 것
2. listdata = [1, [2, 3], '안녕'] # 리스트는 시퀀스 자료형임 • 문자열
• 리스트
3. tupledata = (100, 200, 300) # 튜플은 시퀀스 자료형임
• 튜플

1번째 줄 : strdata는 알파벳 ‘a’, ‘b’, ‘c’, ‘d’, ‘e’가 순서대로 나열되어
있는 문자열을 담고 있는 변수

2번째 줄 : listdata는 1, [2, 3], ‘안녕’이 순서대로 나열되어 있는 리


스트를 담은 변수

3번째 줄 : 튜플은 리스트와 마찬가지로 값을 변경할 수 없는 임의의


객체가 나열되어 있는 시퀀스 자료형

시퀀스 자료형의 특성

인덱싱 인덱스를 통해 해당값에 접근


슬라이싱 특정 구간의 값을 취할 수 있음
연결 + 연산자를 이용해 두 시퀀스를 연결
반복 * 연산자를 이용해 시퀀스 자료를 여러 번 반복
In 키워드를 사용해 특정값이 자료 요소로 속해 있
멤버체크
는지 확인
크기정보 Len( )을 이용해 시퀀스 자료의 크기를 알 수 있음
027 시퀀스 자료 인덱싱 이해하기
1. strdata = 'Time is money!!' 인덱싱(indexing) : 시퀀스 자료형에서 인덱스를 통해 해당하는 값
을 얻는 방법
2. listdata = [1, 2, [1, 2, 3]]
3. print(strdata[5]) # 'i'가 출력됨 strdata 각 요소에 대해 표시한 인덱스

4. print(strdata[-2]) # '!'가 출력됨


5. print(listdata[0]) # 1이 출력됨
6. print(listdata[-1]) # [1, 2, 3]이 출력됨
7. print(listdata[2][-1]) # 3이 출력됨
3번째 줄 : strdata에서 인덱스가 5인 요소를 출력

4번째 줄 : strdata의 끝에서 두 번째 요소를 출력

5번째 줄 : listdata에서 인덱스가 0인 요소를 출력

6번째 줄 : listdata의 끝에서 첫 번째 요소, 즉 마지막 요소를 출력

7번째 줄 : listdata에서 인덱스가 2인 요소는 [1, 2, 3].

listdata[2] = [1, 2, 3]이므로 listdata[2][-1]은

listdata[2]의 마지막 요소를 나타내므로,

[1, 2, 3]의 마지막 요소는 3


028 시퀀스 자료 슬라이싱 이해하기
1. strdata = 'Time is money!!' [시작 인덱스:끝 인덱스:스텝(생략가능)]

2. print(strdata[1:5]) # 'ime'가 출력됨 • 시작 인덱스: 슬라이싱 범위의 시작

3. print(strdata[:7]) # 'Time is'가 출력됨 • 끝 인덱스: 슬라이싱 범위의 끝

4. print(strdata[9:]) # 'oney!!'가 출력됨 • 스텝: 자료를 취하는 간격

5. print(strdata[:-3]) # 'Time is mone'이 출력됨


시작 인덱스 ≤ [시작 인덱스 : 끝 인덱스] < 끝 인덱스
6. print(strdata[-3:]) # 'y!!'이 출력됨
7. print(strdata[:]) # 'Time is money!!'가 출력됨 2번째 줄 : strdata[1:5]는 인덱스가 1 이상이고 5 미만인 부분 슬라이싱
8. print(strdata[::2]) # 'Tm smny!'가 출력됨 3번째줄 : strdata[:7]은 처음부터 인덱스가 7 미만인 부분을 슬라이싱

4번째 줄 : strdata[9:]은 인덱스가 9 이상인 모든 요소를 슬라이싱

5번째 줄 : strdata[:-3]은 처음부터 끝에서 3번째 미만인 요소까지 슬라


이싱

6번째 줄 : strdata[-3:]은 끝에서 3번째 이상인 모든 요소를 슬라이싱

7번째 줄 : strdata[:]은 처음부터 끝까지 슬라이싱

8번째 줄 : strdata[::2]는 처음부터 끝까지 스텝을 2로 해서 슬라이싱


029 시퀀스 자료 연결 이해하기
1. strdata1 = 'I love '; strdata2 = 'Python'; strdata3 = 'you' 자료형이 동일한 두 개의 시퀀스 자료는 + 연산자로 순서있게 연결
2. listdata1 = [1, 2, 3]; listdata2 = [4, 5, 6] 하여 새로운 시퀀스 자료로 만들 수 있음.
3. print(strdata1 + strdata2) # 'I love Python'이 출력됨
문자열 + 문자열, 리스트 + 리스트, 튜플 + 튜플과 같이 두 개의 동일
4. print(strdata1 + strdata3) # 'I love you'가 출력됨
한 시퀀스 자료형에 대해 ‘+’ 연산자로 연결 가능. 문자열과 리스트
5. print(listdata1 + listdata2) # [1, 2, 3, 4, 5, 6]이 출력됨
를 ‘+’로 연결할 수는 없음.

1~2번째 줄 : 세 개의 문자열 strdata1, strdata2, strdata3을 정의하


고, 두 개의 리스트 listdata1, listdata2를 정의

3~4번째 줄 : 문자열 strdata1과 strdata2를 ‘+’로 연결한 새로운 문


자열과 strdata1과 strdata3을 ‘+’로 연결한 새로운 문자열을 출력

5번째 줄 : 리스트인 listdata1과 listdata2를 ‘+’로 연결한 새로운 리


스트를 만들고 출력
030 시퀀스 자료 반복 이해하기
1. artist = '빅뱅' ‘*’ 연산자 : 동일한 시퀀스 자료를 반복하여 새로운 시퀀스 자료를
2. sing = '뱅~' 만들고자 할 때 사용함
3. dispdata = artist + '이 부르는 ' + sing*3
시퀀스 자료 seqdata를 n번 반복하여 새로운 자료로
4. print(dispdata) # '빅뱅이 부르는 뱅~뱅~뱅~'이 출력됨
만들려면 seqdata*n이 됨

3번째 줄 : dispdata는 artist + '이 부르는 ' + sing*3이 연결된 문자


열.

sing*3은 ‘뱅~’*3이므로 ‘뱅~’을 3번 반복한 ‘뱅~뱅~뱅~’


031 시퀀스 자료 크기 이해하기
1. strdata1 = 'I love python' 모든 시퀀스 자료는 고정된 길이 또는 크기를 가지고 있음.
2. strdata2 = '나는 파이썬을 사랑합니다' 시퀀스 자료의 크기는 시퀀스 자료를 구성하는 요소의 개수.
3. listdata = ['a', 'b', 'c', strdata1, strdata2]
4. print(len(strdata1)) # 13이 출력됨
4~5번째 줄 : strdata1은 공백을 포함하여 모두 13자로 구성된
5. print(len(strdata2)) # 13이 출력됨
문자열 ‘I love python’을 담은 변수.
6. print(len(listdata)) # 5가 출력됨
7. print(len(listdata[3])) # 13이 출력됨 따라서 len(strdata1)은 13.

6번째 줄 : listdata는 5개의 요소를 가진 리스트

['a', 'b', 'c', strdata1, strdata2]를 담은 변수

7번째 줄 : listdata[3]의 값은 strdata1


032 멤버체크 이해하기(in)
1. listdata =[1, 2, 3, 4] in : 자료에 어떤 값이 있는지 없는지 확인할 때 사용하는 키워드
2. ret1 = 5 in listdata # False 값이 자료에 있으면 결과는 True, 없으면 False
3. ret2 = 4 in listdata # True
<값> in <자료>
4. print(ret1); print(ret2)
5. strdata = 'abcde'
1~4번째 줄 : listdata에 5가 있는지 체크하고 결과를 ret1에 대입
6. ret3 = 'c' in strdata # True
7. ret4 = '1' in strdata # False listdata에 4가 있는지 체크하고 결과를 ret2에 대입

8. print(ret3); print(ret4) 5~8번째 줄 : strdata에 문자 ‘c’가 있는지 체크하고 결과를 ret3에

대입. strdata에 문자 ‘1’이 있는지 체크하고 결과를

ret4에 대입
033 문자열 이해하기
1. strdata1 = '나는 파이썬 프로그래머다' # 문자열 선언 방법 1 문자열 : 문자나 기호가 순서로 나열되어 있는 시퀀스 자료
2. strdata2 = "You are a programmer" # 문자열 선언 방법 2
3. strdata3 = """I love # 문자열 선언 방법 3
1번째 줄 : ' '를 이용해 '나는 파이썬 프로그래머다' 문자열 정의
4. python. You love
2번째 줄 : " "를 이용해 "You are a programmer"라는 문자열 정의
5. python too!
4~6번째 줄 : """ """를 이용해 문자열 정의.
6. """
7. strdata4 = "My son's name is John" # " " 안에서 ' 사용하기 7번째 줄 : 문자열에 '이 포함되어 있으면 " "를 이용해 선언

8. strdata5 = '문자열 "abc"의 길이는 3입니다.' # ' ' 안에서 " 사용 8번째 줄 : 문자열에 "이 포함되어 있으면 ' '를 이용해 선언
하기
034 문자열 포맷팅 이해하기
1. txt1 = '자바'; txt2 = '파이썬' 3번째 줄 : 두 개의 포맷 문자열 %s 부분에 실제적인 값을 대입하려
2. num1 = 5; num2 = 10 면 %(첫 번째 %s에 대입할 문자열, 두 번째 %에 대입할
3. print('나는 %s보다 %s에 더 익숙합니다.' %(txt1, txt2)) 문자열)을 뒤에 추가
4. print('%s은 %s보다 %d배 더 쉽습니다.' %(txt2, txt1, num1))
4번째 줄 : 포맷 문자열 %s %s %d에 각각 txt2, txt1, num1이 대입
5. print('%d + %d = %d' %(num1, num2, num1+num2))
6. print('작년 세계 경제 성장률은 전년에 비해 %d%% 포인트 증가 5번째 줄 : 포맷 문자열 %d %d %d에 각각 num1, num2,
했다.' %num1)
num1+num2가 대입

6번째 줄 : 포맷 문자열 %d%%에서 %%는 기호 ‘%’ 자체를 의미

자주 사용하는 포맷 문자열

%s 문자열에 대응됨

%c 문자나 기호 한 개에 대응됨

%f 실수에 대응됨

%d 정수에 대응됨

%% ‘%’라는 기호 자체를 표시함


035 이스케이프 문자 이해하기
1. print('나는 파이썬을 사랑합니다.\n파이썬은 자바보다 훨씬 쉽습 이스케이프 문자 : 키보드로 입력하기 어려운 기호를 나타내기 위해
니다.')
역슬래쉬 ‘\’로 시작하는 문자입니다. 인용부호(' ' 또는 " ") 안에 동
2. print('Name: John Smith\tSex: Male\tAge: 22')
일한 인용부호를 입력하는 경우에도 이스케이프 문자 사용
3. print('이 문장은 화면폭에 비해 너무 길어 보기가 힘듭니다. \
4. 그래서 \\Enter키를 이용해 문장을 다음줄과 연속되도록 했습니 결과
다.') 나는 파이썬을 사랑합니다.
파이썬은 자바보다 훨씬 쉽습니다.
5. print('작은따옴표(\')와 큰 따옴표(")는 문자열을 정의할 때 사용
Name: John Smith Sex: Male Age: 22
합니다.') 이 문장은 화면폭에 비해 너무 길어 보기가 힘듭니다. 그래서
\Enter키를 이용해 문장을 다음줄과
연속되도록 했습니다.
작은따옴표(')와 큰 따옴표(")는 문자열을 정의할 때 사용합니다.

자주 사용되는 이스케이프 문자

\n 문자열에 대응됨

\t 문자나 기호 한 개에 대응됨

\ Enter 실수에 대응됨

\\ 정수에 대응됨

\’ 또는 \” ‘%’라는 기호 자체를 표시함


036 리스트 이해하기([ ])
1. list1 = [1, 2, 3, 4, 5] 1번째 줄 : list1은 정수 1에서 5까지 5개의 요소를 가지는 리스트
2. list2 = ['a', 'b', 'c'] 2번째 줄 : list2는 문자 ‘a’, ‘b’, ‘c’ 3개의 요소를 가지는 리스트
3. list3 = [1, 'a', 'abc', [1, 2, 3, 4, 5], ['a', 'b', 'c']]
3번째 줄 : list3은 정수 1, 문자 ‘a’, 문자열 ‘abc’, 리스트 [1, 2, 3, 4,
4. list1[0] = 6 5],

5. print(list1) # [6, 2, 3, 4, 5]가 출력됨 리스트 ['a', 'b', 'c'] 5개의 요소를 가지는 리스트
6. def myfunc( ): 4~5번째 줄 : list1[0]에 6을 대입하고 list1을 출력하면 list1의
7. print('안녕하세요')
첫 번째 요소가 6으로 변경되어 [6, 2, 3, 4, 5]가 표시됨
8. list4 = [1, 2, myfunc]
6~9번째 줄 : myfunc( )라는 함수를 정의.
9. list4[2]( ) # '안녕하세요' 가 출력됨
list4는 정수 1, 2, 함수 myfunc를 요소로 가지는 리스트
037 튜플 이해하기(( ))
1. tuple1 = (1, 2, 3, 4, 5) 1~3번째 줄 : 튜플은 리스트와 마찬가지로 임의의 객체를 요소로
2. tuple2 = ('a', 'b', 'c') 가질 수 있는 시퀀스 자료형
3. tuple3 = (1, 'a', 'abc', [1, 2, 3, 4, 5], ['a', 'b', 'c'])
4번째 줄 : tuple1[0]의 값을 6으로 대입하여 변경하고자 하면
4. tuple1[0] = 6
다음과 같은 오류가 발생(튜플 요소 값 변경 불가)
5.

6. def myfunc( ): TypeError: 'tuple' object does not support item assignment

7. print('안녕하세요')
8. 9~10번째 줄 : 오류가 발생한 4라인을 삭제하거나 주석 처리하고

9. tuple4 = (1, 2, myfunc) 코드를 실행


10. tuple4[2]( ) # '안녕하세요' 가 출력됨
038 사전 이해하기({ })
1. dict1 = {'a':1, 'b':2, 'c':3} 사전 : 키와 값을 하나의 요소로 하는 순서가 없는 집합
2. print(dict1['a']) # 1이 출력됨 키:값

3. dict1['d'] = 4
4. print(dict1) # {'a':1, 'b':2', 'c':3, 'd':4}가 출력되
나 순서가 틀릴 수 있음 1번째 줄 : 요소가 'a':1, 'b':2, 'c':3인 사전 dict1을 선언

5. dict1['b'] = 7 2번째 줄 : 사전은 시퀀스 자료가 아니므로 dict1[0]와 같이 인덱싱


6. print(dict1) # {'a':1, 'b':7', 'c':3, 'd':4}가 출력되 으로 값을 얻을 수 없고, 키로 접근해야 함.
나 순서가 틀릴 수 있음
dict1['a']는 dict1의 요소 중 키가 ‘a’인 값을 의미
7. print(len(dict1)) # 4가 출력됨
3~4번째 줄 : dict1에 새로운 키:값을 추가하는 방법

5~6번째 줄 : 동일한 키가 있다면 키에 대응하는 값을 변경

7번째 줄 : 사전의 크기를 구할 때는 시퀀스 자료형의 크기를 구할 때

사용했던 len( )을 사용
039 함수이해하기(def)
함수 :특정 목적을 가진 코드의 집합이며 독립적으로 호출될 수 있는 것

인자와 리턴값이 있는 함수 선언 방법 인자와 리턴값이 있는 함수 호출 방법


def 함수이름(인자1, 인자2, …):
코드들 변수 = 함수이름(값1, 값2, …)
return 결과값

리턴값은 있지만 인자가 없는 함수 선언 방법 리턴값이 없는 함수 호출 방법


def 함수이름( ):
코드들 함수이름(값1, 값2, …)
return 결과값

인자와 리턴값이 없는 함수 선언 방법 인자와 리턴값이 없는 함수 호출 방법

def 함수이름( ):
코드들 함수이름( )
return (또는 생략)
039 함수 이해하기(def)
1. def add_number(n1, n2): 1~3번째 줄 : 인자 n1, n2를 더한 값을 리턴
2. ret = n1+n2 5~6번째 줄 : 인자 t1, t2를 더한 값을 출력하며, 리턴값은 없음
3. return ret
8~9번째 줄 : add_number 함수는 인자로 입력된 10과 15를 더하고
4.
이 값을 리턴하며, 리턴값을 ans로 둠
5. def add_txt(t1, t2):
10~12번째 줄 : 인자 자리에 text1, text2를 대입
6. print(t1+t2)
7.
add_txt 함수는 이 두 문자열을 연결한 결과를 출력

8. ans = add_number(10, 15)


9. print(ans) # 25가 출력됨
10. text1 = '대한민국~'
11. text2 ='만세!!'
12. add_txt(text1, text2) # '대한민국~만세!!'가 출력됨
040 함수 인자 이해하기
1. def add_txt(t1, t2='파이썬'): 7~8번째 줄 : 가변 인자는 *args와 같이 인자 이름 앞에 *를 붙임.
2. print(t1+' : ' +t2)
args는 함수 내부에서 튜플로 처리됩니다. func1은 가변 인자인
3.
args를 출력하는 함수
4. add_txt('베스트') # '베스트 : 파이썬'이 출력됨
5. add_txt(t2='대한민국', t1='1등') # '1등 : 대한민국'이 출력됨 10~11번째 줄 : kwargs는 함수 내부에서 사전으로 처리

6.
func2는 미정 키워드 인자 kwargs를 출력하는 함수
7. def func1(*args):
8. print(args) 13~14번째 줄 : 3, 5, 1, 5와 같이 네 개의 값을 인자로 함수에 전달하
9. 면 args에 이 값들을 (3, 5, 1, 5)와 같이 튜플로 담아 함수 내부에서
10. def func2(width, height, **kwargs):
처리
11. print(kwargs)
12. 15~16번째 줄 : func2에 width, height외에 키워드 인자로
13. func1( ) # 빈 튜플 ( )이 출력됨 depth=50, color='blue' 를 추가하여 호출하면 **kwargs는
14. func1(3, 5, 1, 5) # (3, 5, 1, 5)가 출력됨 depth=50, color='blue'를 전달받고, func2 함수 내부에서 kwargs
15. func2(10, 20) # 빈 사전 { }이 출력됨 는 {'depth':50, 'color':'blue'}와 같은 사전 자료가 됨
16. func2(10, 20, depth=50, color='blue') # {'depth':50,
'color':'blue'} 이 출력됨
041 지역변수와 전역변수 이해하기(global)
1. param = 10
지역변수 : 함수 내에서만 유효한 변수, 함수 내부에서 선언
2. strdata = '전역변수'
3.
전역변수 : 코드 전반에 걸쳐 유효한 변수, 함수 바깥에서 선언
4. def func1( ):
5. strdata = '지역변수'
6. print(strdata) 1~2번째 줄 : param과 strdata를 각각 10, ‘전역변수’로 선언
7.
4~6번째 줄 : func1( ) 내에서 strdata에 ‘지역변수’ 문자열을 대입
8. def func2(param):
9. param = 1 8~9번째 줄 : 인자이름 param은 전역변수와 이름이 같지만
10.
func2( ) 내에서만 유효한 지역변수로 취급, 처리
11. def func3( ):
12. global param 11~13번째 줄 : func3( ) 내부에서 global param으로 전역변수로
13. param = 50 선언된 param을 사용할 것임을 명시
14.

15. func1( ) # '지역변수'가 출력됨 15~16번째 줄 : func1( )을 호출하면 func1( ) 내에서 선언된
16. print(strdata) # '전역변수'가 출력됨 지역변수 strdata의 값인 ‘지역변수’를 출력
17. print(param) # 10이 출력됨
18. func2(param) 17~19번째 줄 : func2( )의 인자로 전역변수 param을 대입하여
19. print(param) # 10이 출력됨 호출하면 func2( )는 이를 자신의 인자인 param에 대입
20. func3( )
21. print(param) # 50이 출력됨 20~21번째 줄 : 전역변수 param의 값을 50으로 변경하는 함수
042 함수 리턴값 이해하기(return)
1. def reverse(x, y, z): 1~2번째 줄 : reverse( )는 3개의 인자를 가지고 있으며,
2. return z, y, x 이 함수는 인자의 순서를 바꾸어 리턴
3.
4~5번째 줄 : 숫자 1, 2, 3을 reverse( )의 인자로 전달하여 호출하고
4. ret = reverse(1, 2, 3)
그 결과값을 ret으로 둠
5. print(ret) # (3, 2, 1)이 출력됨
7~8번째 줄 : r1, r2, r3에 각각 'c', 'b', 'a'가 리턴값으로 대입됨
6.

7. r1, r2, r3 = reverse('a', 'b', 'c')


8. print(r1); print(r2); print(r3) # 'c', 'b', 'a' 순으로 출력

043 파이썬 모듈 이해하기
1. import time 모듈 : 이미 만들어져 있고 안정성이 검증된 함수들을 성격에 맞게
2. 하나의 파이썬 파일에 묶어 만들어 놓은 것
3. print('5초간 프로그램을 정지합니다.')
모듈을 임포트(import)한다 : 외부 모듈에 있는 함수들을
4. time.sleep(5)
활용하기 위해 모듈을 코드로 가져오는 것
5. print('5초가 지나갔습니다.')

1번째 줄 : 파이썬 내장 모듈인 time 모듈을 import 키워드를 통해

우리 코드로 임포트함

4번째 줄 : time 모듈이 제공하는 sleep( )을 호출하려면

time.sleep( )과 같이 함수이름 앞에 모듈이름을 명시


044 파이썬 패키지 이해하기
1. import mypackage 파이썬 패키지 : 파이썬 모듈을 계층적인 디렉터리 형태로 구성한 것
2.

3. ret1 = mypackage.mylib.add_txt('대한민국', '1등')


실제 패키지를 만드는 방법
4. ret2 = mypackage.mylib.reverse(1, 2, 3)
1. mypackage라는 이름의 디렉터리를 생성
2. mypackage 디렉터리로 이동
3. 예제 043에서 구성한 mylib.py를 mypackage 디렉터리로 복사
4. mypackage 폴더에 version=1.0 이 내용인 __init__.py 파일을 생성
5. 서브 디렉터리를 생성한 후 서브 디렉터리에 하위 패키지를 구성하려면
1~4 과정을 동일하게 반복

1번째 줄 : mypackage를 임포트

3~4번째 줄 : mypackage에 있는 mylib 모듈의 add_txt( )를 호출

마찬가지로 mypackage에 있는 mylib 모듈의

reverse( )를 호출
045 파이썬 모듈 임포트 이해하기 ① (import)
1. import time # 파이썬 내장 모듈인 time을 임포트함 모듈을 임포트하는 방법
2. import mylib # 내가 작성한 mylib 모듈을 임포트함 import 모듈이름
3. import mypackage.mylib # mypackage에 있는 mylib 모듈을 Import 패키지이름.모듈이름
임포트함
4. 존재하지 않는 모듈을 임포트했을 경우

5. time.sleep(1) # time 모듈의 sleep 함수를 이용해 1초간 정지 ImportError: No module named '모듈이름'

6. mylib.add_txt('나는', '파이썬이다') # mylib 모듈의


add_txt 함수를 호출
1번째 줄 : 파이썬에 내장되어 있는 time 모듈을 임포트
7. mypackage.mylib.reverse(1, 2, 3) # mypackage.mylib 모
듈의 reverse 함수 호출 2번째 줄 : mylib.py를 임포트

3번째 줄 : mypackage에 있는 mylib 모듈을 임포트


046 파이썬 모듈 임포트 이해하기 ② (from~import)
1. from time import sleep 계층 경로 모두를 표시하지 않고 간단하게 임포트하는 방법
2. from mypackage import mylib from 모듈이름 import 함수이름
from 패키지이름 import 모듈이름
3. from mypackage.mylib import reverse
4.

5. sleep(1) # time 모듈의 sleep 함수 호출


1번째 줄 : time 모듈의 sleep( ) 함수만 임포트
6. mylib.add_txt('나는', '파이썬이다') # mypackage.mylib 모듈의
add_txt 함수 호출 2번째 줄 : mypackage의 mylib 모듈만 임포트
7. reverse(1, 2, 3) # mypackage.mylib 모듈의
3번째 줄 : mypackage.mylib 모듈의 reverse( ) 함수만 임포트
reverse 함수 호출
047 파이썬 모듈 임포트 이해하기 ③ (import~as)
1. import mypackage as mp 모듈에 별명을 붙여 간단하게 호출하는 방법
2. import mypackage.mylib as ml import 이름이 긴 모듈명 as 별명

3.

4. ret1 = mp.mylib.add_txt('대한민국', '1등')


5. ret2 = ml.reverse(1, 2, 3)
1번째 줄 : mypackage를 mp로 축약하여 별명 생성

2번째 줄 : mypackage.mylib을 ml로 축약하여 별명 생성

3번째 줄 : mp.mylib.add_txt( )는 곧 mypackage.mylib.add_txt( )와

동일하게 취급됨. 마찬가지로 ml.reverse( )는

mypackage.mylib.reverse( )와 동일하게 취급
048 파일 열고 닫기(open, close)
1. f1 = open('text.txt', 'r') open(파일이름, 모드)

2. f2 = open('d:/myimages/mypicture1.jpg', 'rb') 1번째 줄 : 프로그램이 구동되는 디렉터리에서 text.txt 파일을 찾아


3.
텍스트 읽기 모드로 오픈하고 파일 객체를 f1로 둠
4. #----------------------------------------------
2번째 줄 : d:/myimages/mypicture1.jpg를 바이너리 읽기 모드로
5. # 오픈한 파일을 처리하는 코드를 작성함
오픈하고 파일 객체를 f2로 둠
6. #----------------------------------------------
7.
4~6번째 줄 : 파일 객체를 이용해 파일을 읽거나 쓰는 행위를

8. f1.close( ) 수행하는 코드를 작성

9. f2.close( ) 8~9번째 줄 : 파일 객체의 close( )를 이용해 오픈한 파일을 닫음

r 또는 rt 텍스트 모드로 읽기
w 또는 wt 텍스트 모드로 쓰기
a 또는 at 텍스트 모드로 파일 마지막에 추가하기
rb 바이너리 모드로 읽기
wb 바이너리 모드로 쓰기
ab 바이너리 모드로 파일 마지막에 추가하기
049 클래스 이해하기(class)
1. class MyClass: class 클래스 이름:
클래스 멤버 정의
2. var = '안녕하세요' 클래스 메소드 정의
3. def sayHello(self):
4. print(self.var)
2번째 줄 : 클래스 멤버는 클래스 메소드 밖에서 정의되는 변수
5.
3~4번째 줄 : 클래스 메소드는 클래스 내에서 정의되는 함수.
6. obj = MyClass( ) # MyClass 인스턴스 객체 생성
7. print(obj.var) # '안녕하세요'가 출력됨 첫 번째 인자가 반드시 self로 시작

8. obj.sayHello( ) # '안녕하세요'가 출력됨 6번째 줄 : MyClass를 인스턴스 객체로 만들기 위해서는 MyClass( )

로 호출. MyClass의 인스턴스 객체를 obj에 지정

7번째 줄 : MyClass의 인스턴스 객체 obj의 멤버 또는 메소드를 호출

obj.클래스 멤버 # MyClass의 클래스 멤버


obj.클래스 메소드 # MyClass의 클래스 메소드

8번째 줄 : obj.sayHello( )는 MyClass의 sayHello( )를 호출함.

MyClass 선언부 내에서 클래스 멤버를 지시할 때는

self.클래스 멤버 이용
050 클래스 멤버와 인스턴스 멤버 이해하기
1. class MyClass: 클래스에서 선언되는 변수는 ‘클래스 멤버’와 ‘인스턴스 멤버’
2. var = '안녕하세요!!' self.var # 클래스 메소드 내에서 var를 참조할 경우
3. def sayHello(self): MyClass.var # 클래스 밖에서 클래스 이름만으로 참조할 경우
obj.var # MyClass의 인스턴스 객체 obj에서 var를 참조할 경우
4. param1 = '안녕'
5. self.param2 = '하이'
2번째 줄 : MyClass 내에서 var라는 이름의 변수를 선언
6. print(param1) # '안녕'이 출력됨
7. print(self.var) # '안녕하세요'가 출력됨 3~7번째 줄 : sayHello( )는 param1의 값과 클래스 멤버인 var의

8. 값을 출력. sayHello( )를 호출하기 전에 self.param2를

9. obj = MyClass( ) 참조할 경우 오류 발생


10. print(obj.var) # '안녕하세요'가 출력됨 AttributeError: 'MyClass' object has no attribute 'param2'
11. obj.sayHello( )
9~12번째 줄 : MyClass의 인스턴스 객체를 만들고 클래스 멤버 var
12. #obj.param1
를 출력. MyClass의 sayHello( )를 호출하면 sayHello( )의

지역변수 param1과 MyClass의 클래스 멤버 var의 값을

화면에 출력. 12번째 줄 주석을 풀고 실행하면 오류 발생


AttributeError: 'MyClass' object has no attribute 'param1'
051 클래스 메소드 이해하기
1. class MyClass: 클래스 내에서 정의되는 함수인 클래스 메소드는
2. def sayHello(self): 첫 번째 인자가 반드시 self여야 함
3. print('안녕하세요')
4.

5. def sayBye(self, name):


2~3번째 줄 : MyClass의 클래스 메소드 sayHello( )를 정의
6. print('%s! 다음에 보자!' %name)
7.
5~6번째 줄 : MyClass의 클래스 메소드 sayBye(self, name)의

8. obj = MyClass( ) 인자는 name

9. obj.sayHello( ) # '안녕하세요'가 출력됨 8~9번째 줄 : MyClass의 인스턴스 객체를 생성하고 obj로 지정


10. obj.sayBye('철수') # '철수! 다음에 보자!'가 출력됨
052 클래스 생성자 이해하기
1. class MyClass: 클래스 생성자
2. def _ _init _ _(self): def _ _init _ _(self, *args)
3. self.var = '안녕하세요!'
4. print('MyClass 인스턴스 객체가 생성되었습니다')
2~4번째 줄 : MyClass의 클래스 생성자를 정의
5.
6번째 줄 : MyClass의 생성자에 인자가 없으므로
6. obj = MyClass( ) # 'MyClass 인스턴스 객체가 생성
되었습니다'가 출력됨 MyClass( )와 같이 인스턴스 객체를 생성.
7. print(obj.var) # '안녕하세요'가 출력됨
인스턴스 객체가 생성될 때 self.var가 초기화되고

화면에 메시지를 출력

7번째 줄 : MyClass의 생성자에서 초기화한 self.var의 값을 출력


053 클래스 소멸자 이해하기
1. class MyClass: 클래스 소멸자
2. def _ _del _ _(self): _ _del _ _(self):
3. print('MyClass 인스턴스 객체가 메모리에서 제거됩니다')
인스턴스 객체 제거
4.
del <인스턴스 객체>
5. obj = MyClass( )
6. del obj # 'MyClass 인스턴스 객체가 메모리에서 제거
됩니다'가 출력됨 2~3번째 줄 : 클래스 소멸자에서 print( )를 호출하여 메시지를 출력

6번째 줄 : 생성된 MyClass 인스턴스 객체 obj를 del 키워드로

메모리에서 제거. 이때 클래스 소멸자가 자동으로 호출

되므로 3라인에서 작성된 메시지가 화면에 출력됨


054 클래스 상속 이해하기
1. class Add: 부모(슈퍼)클래스 : 상속을 해주는 클래스
2. def add(self, n1, n2): 자식(서브)클래스 : 상속을 받는 클래스
3. return n1+n2
4. 부모클래스로부터 상속을 받아 자식클래스를 정의하는 방법

5. class Calculator(Add): class 자식클래스(부모클래스):

6. def sub(self, n1, n2):


7. return n1-n2
1~3번째 줄 : Add라는 이름의 클래스를 정의
8.
5~7번째 줄 : Calculator 클래스에서 두 수를 뺀 값을 리턴하는
9. obj = Calculator( )
sub( )라는 클래스 메소드를 정의
10. print(obj.add(1, 2)) # 3이 출력됨
11. print(obj.sub(1, 2)) # -1이 출력됨 9~11번째 줄 : Calculator 클래스의 인스턴스 객체를 생성하고

이 객체의 add(1, 2)를 호출.

Calculator에서 정의한 sub( ) 메소드를 호출

다중상속 클래스를 정의하는 방법


class 자식클래스(부모클래스1, 부모클래스2, ..)
055 예외처리 이해하기 ① (try~except)
1. try: 예외(Exception) : 프로그램이 실행되는 동안 오류가 발생하여 프로
2. print('안녕하세요.') 그램이 더 이상 진행될 수 없는 상태
3. print(param)
try~except : 프로그램에 예외가 발생하더라도 프로그램을 중단시
4. except:
키지 않고 예외에 대한 적절한 처리를 하여 프로그램을 계속 진행시
5. print('예외가 발생했습니다!')
킬 수 있도록 하는 구문

3번째 줄 : 정의되지 않은 변수 param을 화면에 출력하는 코드는

예외를 발생시키고 프로그램을 중단함

NameError: name 'param' is not defined


056 예외처리 이해하기 ② (try~except~else)
1. try: try~except~else : 어떤 로직을 수행했을 때 오류 상황이 아닐 경우
2. print('안녕하세요.') 에만 어떤 작업을 수행하는 코드를 작성해야 할 때 활용하는 구문
3. print(param)
4. except:
5. print('예외가 발생했습니다!') 3번째 줄 : param은 정의되지 않은 변수이므로 이 부분에서 예외가
발생.
6. else:
7. print('예외가 발생하지 않았습니다.') 안녕하세요.
예외가 발생했습니다!

3라인을 주석 처리하고 다시 실행하면 예외 부분이 없어졌기 때문에


except 부분은 실행되지 않고 else 부분이 실행.
안녕하세요.
예외가 발생하지 않았습니다.
057 예외처리 이해하기 ③ (try~except~finally)
1. try: try~except~finally : 오류 발생 유무와 상관없이 어떤 코드를 무조
2. print('안녕하세요.') 건 실행시킬 경우에 사용하는 구문
3. print(param)
4. except:
5. print('예외가 발생했습니다!') 3번째 줄 : 정의되지 않은 변수인 param을 화면에 출력하려고

6. finally: 했으므로 예외가 발생되어 except 부분이 실행.


7. print('무조건 실행하는 코드') finally는 예외가 발생하든 발생하지 않든 무조건

실행되는 부분

안녕하세요.
예외가 발생했습니다!
무조건 실행하는 코드
058 예외처리 이해하기 ④ (try~except Exception as e)
1. try: 파이썬은 발생 가능한 예외에 대해 exception 객체로 미리 정의해둠
2. print(param) https://docs.python.org/3/library/exceptions.html #bltin-
3. except Exception as e: exceptions

4. print(e) # name 'param' is not defined가 출력됨

2~3번째 줄 : param이라는 정의되지 않은 변수를 코드에서 사용

이는 파이썬에서 NameError 예외를 발생시키고

except Exception as e는 NameError 객체를 e라는

이름으로 접근할 수 있게 해줌

4번째 줄 : NameError 객체를 출력

name 'param' is not defined


059 예외처리 이해하기 ⑤ (try~except 특정 예외)
1. import time 1번째 줄 : sleep( ) 함수를 이용하기 위해 time 모듈을 임포트
2. count = 1 2번째 줄 : count의 초기값을 1로 설정
3. try:
3~7번째 줄 : count 값을 출력하고 count를 1 증가함.
4. while True:
0.5초 동안 멈추고 다시 count 값을 출력하고
5. print(count)
1 증가시키는 로직을 무한 반복.
6. count += 1
7. time.sleep(0.5) Ctrl + C 가 입력되면 try 내부에 있는 로직에서

8. except KeyboardInterrupt: # Ctrl+C가 입력되면 발생하는 오류 KeyboardInterrupt 예외가 발생.

9. print('사용자에 의해 프로그램이 중단되었습니다.') except KeyboardInterrupt 부분으로 제어가 넘어감.


060 사용자 입력받기(input)
1. k = input('<값>을 입력하세요: ') 1번째 줄 : 화면에 ' < 값 > 을 입력하세요: '를 출력하고 사용자 입력
2. print('당신이 입력한 값은 <' + k + '>입니다.') 을 기다린 후 사용자가 키보드로 값을 입력하고 를 누르면 input( )은
사용자가 입력한 값을 문자열로 리턴하며, 변수 k에 대입

2번째 줄 : 사용자가 ‘안녕하세요 파이썬’이라는 문장을 입력

결과
당신이 입력한 값은 <안녕하세요 파이썬>입니다.
061 자료형 확인하기(type)
1. numdata = 57 - 파이썬의 자료형은 하나의 클래스로 취급됨
2. strdata = '파이썬' - 코드를 작성하다가 변수이름만 보고 어떤 자료형인지 확인해야 할
3. listdata = [1, 2, 3]
경우 파이썬 내장함수인 type( )을 활용
4. dictdata = {'a':1, 'b':2}
5.
결과
6. def func( ):
<class 'int'>
7. print('안녕하세요.')
<class 'str'>
8. <class 'list'>
<class 'dict'>
9. print(type(numdata)) <class 'function'>

10. print(type(strdata))
11. print(type(listdata))
12. print(type(dictdata))
13. print(type(func))
062 나눗셈에서 나머지만 구하기(%)
1. a = 11113 나누기 연산
2. 2: b = 23 수학식 파이썬 코드

3. 3: ret = a%b 12 mod 3 = 0 12 % 3 = 0


12 mod 5 =2 12 % 5 = 2
4. 4: print('<%d>를 <%d>로 나누면 <%d>가 나머지로 남습니
다.' %(a, b, ret))
결과

<11113>를 <23>로 나누면 <4>가 나머지로 남습니다.


063 몫과 나머지 구하기(divmod)
1. a = 11113 3~4번째 줄 : divmod( )는 두 개의 정수를 인자로 받음.
2. b = 23 첫 번째 인자를 두 번째 인자로 나눈 결과를 (몫, 나머
3. ret1, ret2 = divmod(a, b)
지)와 같이 튜플로 리턴
4. print('<%d/ %d>는 몫이 <%d>, 나머지가 <%d>입니다.' %(a, b,
ret1, ret2))

결과
<11113/23>는 몫이 <483>, 나머지가 <4>입니다.
064 10진수를 16진수로 변환하기(hex)
1. h1 = hex(97) # h1은 문자열 '0x61' 파이썬 내장함수 hex( ) : 인자로 입력된 10진수 정수를 16진수로 변
환해서 문자열로 리턴
2. h2 = hex(98) # h2는 문자열 '0x62'
3. ret1 = h1 +h2 1~2번째 줄 : 파이썬 내장함수 hex( )는 10진수 97과 98을 16진수로

4. print(ret1) # '0x610x62' 가 출력됨 변환하고 이를 문자열로 리턴

5. a = int(h1, 16) 3~4번째 줄 : h1과 h2를 더한 결과는 ‘0x610x62’


6. b = int(h2, 16) 5~6번째 줄 : int('0x61', 16)과 같이 int( )의 두 번째 인자에 정수로
7. ret2 = a + b # ret2는 10진수 195가 됨
변환할 수가 16진수임을 지정. 두 번째 인자가 없으면
8. print(hex(ret2)) # '0xc3' 가 출력됨
정수로 변환할 수를 10진수로 처리

7~8번째 줄 : a와 b를 더하면 10진수로 195가 됨

195를 hex( )로 16진수로 변환하면 문자열 ‘0xc3’이 됨


065 10진수를 2진수로 변환하기(bin)
1. b1 = bin(97) # b1은 문자열 '0b11000001' bin( ) : 인자로 입력된 숫자를 2진수로 변환하여 그 값을 문자열로
리턴
2. b2 = bin(98) # b2는 문자열 '0b11000010'
3. ret1 = b1 + b2
4. print(ret1) # '0b110000010b11000010'가 출력됨 1~2번째 줄 : bin( )은 10진수 97과 98을 2진수로 변환하고 이를 문
자열로 리턴
5. a = int(b1, 2)
3~4번째 줄 : b1과 b2를 더하면 ‘0b110000010b11000010’
6. b = int(b2, 2)
7. ret2 = a + b 5~6번째 줄 : bin( )으로 변환한 값은 int( )으로 숫자 변환 가능

8. print(bin(ret2)) # '0b11000011' 이 출력됨


066 2진수, 16진수를 10진수로 변환하기(int)
1. bnum = 0b11110000; bstr = '0b11110000' int( ) : 2진수, 8진수, 16진수 정수를 10진수 정수로 변환
2. onum = 0o360; ostr = '0o360'
3. hnum = 0xf0; hstr = '0xf0'
4. b1 = int(bnum); b2 = int(bstr, 2) # b2 = int(bstr, 0)로도 가능 1~3번째 줄 : 2진수로 된 숫자와 문자열, 8진수로 된 숫자와 문자열

5. o1 = int(onum); o2 = int(ostr, 8) # o2 = int(ostr, 0)로도 가능 그리고 16진수로 된 숫자와 문자열을 선언하고 int( )를 이용해 10진
수로 변환하는 코드
6. h1 = int(hnum); h2 = int(hstr, 16) # h2 = int(hstr, 0)로도 가능
7. print(b1); print(b2) 4~6번째 줄 : int( )의 두 번째 인자로 0을 지정하면 첫 번째 인자의
8. print(o1); print(o2) 문자열 그대로 숫자로 변환하고 10진수로 변환한 결과를 리턴
9. print(h1); print(h2)
7~9번째 줄 : 모든 결과는 240
067 절대값 구하기(abs)
1. abs1 = abs(-3) # 정수의 절대값 파이썬 내장함수 abs( )는 인자로 입력된 값의 절대값을 리턴.
2. abs2 = abs(-5.72) # 실수의 절대값 만약 복소수가 인자로 입력되면 복소수의 크기를 리턴.
3. abs3 = abs(3+4j) # 복소수의 절대값
복소수 a+bi의 크기는 a2+b2
4. print(abs1) # 3이 출력됨
5. print(abs2) # 5.72가 출력됨
1~6번째 줄 : 정수 -3, 실수 -5.72, 복소수 3+4j의 절대값을 구함.
6. print(abs3) # 5.0이 출력됨
각각의 절대값들은 3, 5.72, 5.0
068 반올림수 구하기(round)
1. ret1 = round(1118) # 소수점 첫째자리에서 반올림해줌 round( ) : 인자로 입력된 수치형 자료를 지정된 자리수에서
2. ret2 = round(16.554) # 소수점 첫째자리에서 반올림해줌 반올림한 결과를 리턴
3. ret3 = round(1118, -1) # 1자리에서 반올림해줌
4. ret4 = round(16.554, 2) # 소수점 셋째자리에서 반올림해줌
1번째 줄 : 디폴트로 round( )는 입력된 숫자의 소수점 첫째자리에
5. print(ret1) # 1118
서 반올림한 수를 리턴
6. print(ret2) # 17
7. print(ret3) # 1120 2번째 줄 : 16.554를 소수점 첫째자리에서 반올림

8. print(ret4) # 16.55 3번째 줄 : round(1118, -1)은 1118의 1자리인 8에서 반올림

4번째 줄 : round(16.554, 2)는 소수점 셋째자리에서 반올림


069 실수형 자료를 정수형 자료로 변환하기(int)
1. idata1 = int(-5.4) int( ) : 인자로 입력된 실수형 자료를 정수형 자료로 변환.
2. idata2 = int(1.78e1) 입력된 실수형 자료의 소수부분은 버리고 정수부분만
3. idata3 = int(171.56)
취하여 정수값으로 리턴
4. print(idata1) # -5가 출력됨
5. print(idata2) # 17이 출력됨
6. print(idata3) # 171이 출력됨
1번째 줄 : -5.4를 int( )로 정수형 자료로 변환하면 -5

2번째 줄 : 1.78e1은 17.8이므로 int( )로 정수형 자료로 변환하면

17이 됨

3번째 줄 : 171.56을 int( )로 정수형 자료로 변환하면 171


070 정수형 자료를 실수형 자료로 변환하기(float)
1. fdata = float(10) float( ) : 인자로 입력된 정수형 자료를 실수형 자료로 변환
2. print(fdata) # 10.0으로 출력됨

1~2번째 줄 : 정수형 자료 10을 float( )을 이용해 실수형으로 변환.

이 값을 출력해보면 10.0으로 표시되어 실수형 자료로

변환되었음을 알 수 있음
071 정수 리스트에서 소수만 걸러내기(filter)
1. def getPrime(x): filter( ) : 리스트와 같이 반복 가능한 자료에서 특정 조건을 만족하
2. for i in range(2, x-1): 는 값만을 편리하게 추출할 수 있는 방법을 제공
3. if x%i == 0:
filter( )의 첫 번째 인자는 특정조건의 값을 추출하는 함수가 입력되
4. break
며, 두 번째 인자는 리스트와 같은 반복 가능한 자료가 입력됨
5. else:
6. return x
7. 1~6번째 줄 : getPrime( ) 함수는 인자로 입력된 x의 값이 소수인지
체크하고 소수일 경우에만 값을 리턴. 여기서 사용된 range( )는 순
8. listdata = [117, 119, 1113, 11113, 11119] 차적인 정수 리스트를 만드는 함수
9. ret = filter(getPrime, listdata)
8번째 줄 : 5개의 정수를 요소로 가지는 리스트를 정의
10. print(list(ret)) # [11113, 11119]가 출력됨
9~10번째 줄 : filter( )의 첫 번째 인자는 소수를 추출하는 함수인
getPrime을, 두 번째 인자는 반복 가능한 자료인 리스트를 입력.

filter( )의 리턴값은 결과가 담긴 filter 객체입니다. list( )를 이용해


filter 객체에 담긴 내용을 리스트로 변환하여 출력

결과

[11113, 11119]
072 최대값, 최소값 구하기(max, min)
1. listdata = [9.96, 1.27, 5.07, 6.45, 8.38, 9.29, 4.93, 7.73, 3.71, max( ), min( ) : 인자로 입력된 자료에서 최대, 최소값을 구해주는
0.93]
함수
2. maxval = max(listdata)
3. minval = min(listdata)
4. print(maxval) # 9.96이 출력됨 1번째 줄 : 숫자가 요소인 리스트 자료 listdata를 정의
5. print(minval) # 0.93이 출력됨
2~5번째 줄 : listdata의 요소 중 최대값을 maxval,
6.
최소값을 minval에 지정하고 이 값들을 출력
7. txt = 'Alotofthingsoccureachday'
8. maxval = max(txt) 7번째 줄 : 문자열 txt를 정의

9. minval = min(txt) 8~11번째 줄 : txt의 최대값, 최소값을 maxval, minval로 둠


10. print(maxval); # 'y'가 출력됨 13~16번째 줄 : 개별 숫자나 문자, 문자열을 비교하여
11. print(minval) # 'A'가 출력됨
최대값 또는 최소값을 구할 수 있음
12.

13. maxval = max(2+3, 2*3, 2**3, 3**2)


14. minval = min('abz', 'a12')
15. print(maxval) # 9가 출력됨
16. print(minval) # 'a12'가 출력됨
073 1바이트에서 하위 4비트 추출하기
1. a = 107 # 16진수로 0x6b 비트는 0과 1로 표현되는 2진수로 나타낼 수 있음.
2. b = a & 0x0f 8비트 = 1바이트(일반적으로 컴퓨터가 처리하는 데이터의 최소 단
3. print(b) # 11이 출력됨. 11은 16진수로 b임 위)

1번째 줄 : 숫자 107을 1바이트 단위의 2진수로 표현하면 01101101,

16진수로 표현하면 6b

2번째 줄 : 숫자 107(16진수 0x6b)의 하위 4비트값만 추출하려면

이 값을 0x0f와 비트단위 AND 연산을 수행.


074 1바이트에서 상위 4비트 추출하기
1. a = 107 1바이트에서 상위 4비트를 추출하려면 모든 비트를 오른쪽으로 시
2. b = (a>>4) & 0x0f 프트하는 연산자인 >>를 이용해 오른쪽으로 4만큼 시프트하고 하
3. print(b) # 6이 출력됨 위 4비트를 추출하는 방법을 적용

숫자 107을 오른쪽으로 4만큼 시프트했을 때의 비트값

0x6b 0 1 1 0 1 1 0 1
0x0b>>4 0 0 0 0 0 1 1 0
075 문자열에서 특정 위치의 문자 얻기
1. txt1 = 'A tale that was not right' 1번째 줄 : 영문으로 된 문자열 txt1을 정의
2. txt2 = '이 또한 지나가리라.' 2번째 줄 : 한글로 된 문자열 txt2를 정의
3. print(txt1[5]) # 'e'가 출력됨
3번째 줄 : 영문으로 된 문자열 txt1의 6번째 문자를 출력
4. print(txt2[-2]) # '라'가 출력됨
4번째 줄 : 한글로 된 문자열 txt2의 끝에서 2번째 문자를 출력
076 문자열에서 지정한 구간의 문자열 얻기
1. txt1 = 'A tale that was not right' 3번째 줄 : 영문으로 된 문자열 txt1의 3번째부터 7번째 미만까지
2. txt2 = '이 또한 지나가리라.' 문자열을 화면에 출력
3. print(txt1[3:7]) # 'ale '이 출력됨
4번째 줄 : txt1의 처음부터 6번째 미만까지 문자열을 출력
4. print(txt1[:6]) # 'A tale'이 출력됨
5번째 줄 : 한글로 된 문자열 txt2에서 끝에서 4번째부터 마지막
5. print(txt2[-4:]) # '가리라.'가 출력됨
문자까지 문자열을 출력

응용 코드 구현

txt = 'python'
for i in range(len(text)):
print(txt[:i+1])

결과
p
py
pyt
pyth
pytho
python
077 문자열에서 홀수 번째 문자만 출력하기
1. txt = 'aAbBcCdDeEfFgGhHiIjJkK' 2번째 줄 : txt[::2]는 문자열 txt의 처음부터 끝까지 스텝 2로
2. ret = txt[::2] 슬라이싱하라는 의미.
3. print(ret) # 'abcdefghijk' 가 출력됨
txt의 첫 번째 문자인 a를 추출하고 두 번째 문자인 A를

건너뛰고 세 번째 문자인 b를 추출하는 방식으로 문자열

txt의 끝까지 수행.

문자열 txt의 짝수 번째 문자만 추출하고자 할 경우(2라인 수정)

ret = txt[1::2]
078 문자열을 거꾸로 만들기
1. txt = 'abcdefghijk' 2번째 줄 : 문자열 txt의 처음부터 끝까지 스텝 -1로 슬라이싱
2. ret = txt[::-1]
3. print(ret) # 'kjihgfedcba' 가 출력됨
역순으로 홀수 번째 문자만 추출하여 문자열을 만들 경우

ret = txt[::-2]

역순으로 짝수 번째 문자만 추출하여 문자열을 만들 경우

ret = txt[-2::-2]
079 두 개의 문자열 합치기(+)
1. filename = input('저장할 파일이름을 입력하세요: ') 1번째 줄 : input( ) 함수를 이용해 사용자로부터 저장할 파일이름을
2. filename = filename + '.jpg' 입력받아 filename에 지정
3. display_msg = '당신이 저장한 파일은 <' + filename + '>입니다.'
2번째 줄 : 사용자가 입력한 문자열 뒤에 ‘.jpg’를 연결
4. print(display_msg)
3번째 줄 : 사용자에게 피드백을 주기 위한 메시지를 생성

코드를 실행하고 ‘mypics’를 입력한 결과

당신이 저장한 파일은 <mypics.jpg>입니다.


080 문자열을 반복해서 새로운 문자열로 만들기(*)
1. msg1 = '여러분' 3번째 줄 : display_msg는 msg1과 ', ', msg2를 세 번 반복한 문자열,
2. msg2 = '파이팅!' '~!'를 차례로 합친 문자열
3. display_msg = msg1 + ', ' + msg2*3 + '~!'
4. print(display_msg)

결과

여러분, 파이팅!파이팅!파이팅!~!
081 문자열에서 특정 문자가 있는지 확인하기(in)
1. msg = input('임의의 문장을 입력하세요: ') 1번째 줄 : 임의의 문장을 사용자로부터 입력받음
2. if 'a' in msg: 2번째 줄 : 문자 ‘a’가 사용자가 입력한 문장에 있는지 체크.
3. print('당신이 입력한 문장에는 a가 있습니다.')
'a' in msg는 msg에 문자 ‘a’가 한 개라도 있으면 참이고
4. else:
한 개도 없으면 거짓
5. print('당신이 입력한 문장에는 a가 없습니다.')

코드를 실행하고 사용자 입력 부분이 나타나면 ‘Ok, you are right.’


를 입력한 결과

당신이 입력한 문장에는 a가 있습니다.


082 문자열에서 특정 문자열이 있는지 확인하기(in)
1. msg = input('임의의 문장을 입력하세요: ') 1번째 줄 : 사용자로부터 임의의 문장을 사용자로부터 입력받음
2. if 'is' in msg: 2번째 줄 : 문자열 ‘is’가 사용자가 입력한 문장에 있는지 없는지 체크
3. print('당신이 입력한 문장에는 is가 있습니다.')
4. else:
5. print('당신이 입력한 문장에는 is가 없습니다.')
083 문자열 길이 구하기(len)
1. msg = input('임의의 문장을 입력하세요: ') 1번째 줄 : 사용자로부터 임의의 문장을 입력받음
2. msglen = len(msg) 2번째 줄 : 사용자로부터 입력받은 문장의 길이를 len( ) 함수로 구함
3. print('당신이 입력한 문장의 길이는 <%d>입니다.' %msglen)
코드를 실행하고 사용자 입력 부분에 ‘python’을 입력

알파벳으로 된 ‘python’과 한글 ‘안녕하세요.’는 문자열의 길이는

6으로 같지만 컴퓨터 내부에서 처리되는 바이트 크기는 다르므로

2라인을 아래와 같이 수정함

msglen = len(msg.encode( ))

결과를 통해 ‘python’과 ‘안녕하세요.’의 문자열의 길이는 같지만

컴퓨터에서 처리되는 실제 바이트 객체 크기는 다르다는 것을

알 수 있음
084 문자열이 알파벳인지 검사하기(isalpha)
1. txt1 = 'A' isalpha( ) : 주어진 문자열이 사람의 언어 문자로만 구성되어 있
2. txt2 = '안녕' 는지를 확인. 문자열의 모든 요소가 사람의 언어 문자
3. txt3 = 'Warcraft Three'
로만 구성되어 있으면 True를 리턴하고 아니면 False를
4. txt4 = '3PO'
리턴
5. ret1 = txt1.isalpha( )
6. ret2 = txt2.isalpha( )
7. ret3 = txt3.isalpha( ) 5번째 줄 : txt1은 알파벳 한글자로 된 ‘A’이므로 ret1의 값은 True

8. ret4 = txt4.isalpha( ) 6번째 줄 : 언어 문자로만 구성되어 있으므로 ret2의 값은 True

9. print(ret1) # True가 출력됨 7번째 줄 : 사이에 띄어쓰기 기호인 공백(space)이 들어가 있으므로
10. print(ret2) # True가 출력됨 ret3은 False
11. print(ret3) # False가 출력됨
8번째 줄 : txt4에는 숫자 3이 포함되어 있으므로 ret4는 False
12. print(ret4) # False가 출력됨
085 문자열이 숫자인지 검사하기(isdigit)
1. txt1 = '010-1234-5678' isdigit( ) 메소드 : 문자열을 구성하는 요소가 모두 숫자인지 체크하
고 True 또는 False를 리턴
2. txt2 = 'R2D2'
3. txt3 = '1212'
4. ret1 = txt1.isdigit( ) 4번째 줄 : txt1에는 숫자 이외에 하이픈 ‘-’이 포함되어 있으므로

5. ret2 = txt2.isdigit( ) ret1의 값은 False입니다.


6. ret3 = txt3.isdigit( ) 5번째 줄 : txt2에는 알파벳이 포함되어 있으므로 ret2의 값은
7. print(ret1) # False가 출력됨
False
8. print(ret2) # False가 출력됨
6번째 줄 : 모두 숫자로 되어 있는 문자열이므로 ret3의 값은 True
9. print(ret3) # True가 출력됨
086 문자열이 알파벳 또는 숫자인지 검사하기(isalnum)
1. txt1 = '안녕하세요?' isalnum( ) 메소드 : 문자열을 구성하는 요소가 모두 언어 문자 또는
숫자인지 체크하고 True 또는 False를 리턴
2. txt2 = '1. Title-제목을 넣으세요'
3. txt3 = '3피오R2D2'
4. ret1 = txt1.isalnum( ) 4번째 줄 : txt1에는 물음표 ‘?’가 들어가 있으므로 ret1의 값은 False

5. ret2 = txt2.isalnum ( ) 5번째 줄 : txt2에는 마침표 ‘.’와 하이픈 ‘-’이 들어가 있으므로 ret2의
값은 False
6. ret3 = txt3.isalnum ( )
7. print(ret1) # False가 출력됨 6번째 줄 : txt3은 모두 문자와 숫자로만 구성되어 있으므로 ret3의
값은 True
8. print(ret2) # False가 출력됨
9. print(ret3) # True가 출력됨
087 문자열에서 대소문자 변환하기(upper, lower)
1. txt = 'A lot of Things occur each day.' upper( ) 메소드 : 문자열에 있는 모든 알파벳을 대문자로 변환한
2. ret1 = txt.upper( ) 결과를 리턴
3. ret2 = txt.lower( )
lower( ) 메소드 : 문자열에 있는 모든 알파벳을 소문자로 변환한
4. print(ret1)
결과를 리턴
5. print(ret2)
upper( )와 lower( )는 원본 문자열을 변경시키지 않음

2번째 줄 : txt에 존재하는 모든 알파벳을 대문자로 변환하고

결과를 ret1로 둠. 원본 문자열 txt는 변경시키지 않음

3번째 줄 : txt에 존재하는 모든 알파벳을 소문자로 변환하고

결과를 ret2에 대입. 원본 문자열 txt는 변경시키지 않음

결과
A LOT OF THINGS OCCUR EACH DAY.
a lot of things occur each day.
088 문자열에서 좌우 공백 제거하기(istrip, rstrip, strip)
1. txt = ' 양쪽에 공백이 있는 문자열입니다. ' 2번째 줄 : 문자열 객체의 lstrip( ) 메소드는 문자열에 존재하는
2. ret1 = txt.lstrip( ) 왼쪽 공백을 제거한 후 결과를 리턴
3. ret2 = txt.rstrip( )
3번째 줄 : 문자열 객체의 rstrip( ) 메소드는 문자열에 존재하는
4. ret3 = txt.strip( )
오른쪽 공백을 제거한 후 결과를 리턴
5. print('<'+txt+'>')
4번째 줄 : 문자열 객체의 strip( ) 메소드는 문자열에 존재하는
6. print('<'+ret1+'>')
7. print('<'+ret2+'>') 왼쪽, 오른쪽 공백을 모두 제거한 후 결과를 리턴

8. print('<'+ret3+'>')

결과
< 양쪽에 공백이 있는 문자열입니다. >
<양쪽에 공백이 있는 문자열입니다. >
< 양쪽에 공백이 있는 문자열입니다.>
<양쪽에 공백이 있는 문자열입니다.>
089 문자열을 수치형 자료로 변환하기(int, float)
1. numstr = input('숫자를 입력하세요: ') - 파일에 기록되어 있는 숫자나 사용자로부터 입력받은 숫자는 문자
열로 처리됨
2. try:
3. num = int(numstr) - 파이썬 내장함수 int( )와 float( )를 사용하면 문자열로 된 숫자를

4. print('당신이 입력한 숫자는 정수 <%d>입니다.' %num) 정수형 또는 실수형 자료로 변환 가능


5. except:
6. try: 1번째 줄 : 사용자로부터 숫자를 입력받고 그 값을 numstr으로 지정
7. num = float(numstr)
2~5번째 줄 : numstr의 값은 문자열.
8. print('당신이 입력한 숫자는 실수 <%f>입니다.' %num)
numstr의 값을 int( )를 이용해 정수형 자료로 변환
9. except:
int( )는인자로 정수 형식으로 된 문자열만 정수형 자료
10. print('+++ 숫자를 입력하세요~ +++')
로 변환. 실수 형식의 문자열이나 숫자만으로 구성되지

않은 문자열이 입력되면 오류 발생

6~10번째 줄 : numstr이 int( )로 변환되지 않아 오류가 발생하면

입력한 문자열이 실수 형식인 것으로 가정하고

float( )를 이용해 실수로 변환. float( )는 숫자만으로

구성되지 않은 문자열이 입력되면 오류 발생


090 수치형 자료를 문자열로 변환하기(str)
1. num1 = 1234 str( ) : 인자로 입력된 수치형 자료를 문자열로 변환
2. num2 = 3.14
3.

4. numstr1 = str(num1)
1~2번째 줄 : num1은 정수형 자료 1234,
5. numstr2 = str(num2)
num2는 실수형 자료 3.14로 정의
6. print('num1을 문자열로 변환한 값은 "%s"입니다.' %numstr1)
7. print('num2를 문자열로 변환한 값은 "%s"입니다.' %numstr2) 4~5번째 줄 : 파이썬 내장함수 str( )을 이용해 num1과 num2를

문자열로 변환하여 numstr1, numstr2로 각각 지정

6~7번째 줄 : numstr1과 numstr2는 문자열이므로 화면 출력 메시지

를 위한 포맷 문자열에 문자열을 표시하는 %s를 사용

결과
num1을 문자열로 변환한 값은 "1234"입니다.
num2를 문자열로 변환한 값은 "3.14"입니다.
091 문자열에 있는 문자(열) 개수 구하기(count)
1. txt = 'A lot of things occur each day, every day.' count( ) 메소드 : 문자열에서 특정 문자의 개수를 리턴
2. word_count1 = txt.count('o')
3. word_count2 = txt.count('day')
4. word_count3 = txt.count(' ')
2번째 줄 : txt에 존재하는 알파벳 ‘o’의 개수를 구함
5. print(word_count1) # 3이 출력됨
3번째 줄 : txt에 존재하는 단어 ‘day’의 개수를 구함
6. print(word_count2) # 2가 출력됨
7. print(word_count3) # 8이 출력됨 4번째 줄 : txt에 존재하는 공백의 개수를 구함.

공백개수 +1은 문자열에 존재하는 단어의 개수

5~7번째 줄 : word_count1, word_count2, word_count3은 각각 3, 2, 8


092 문자열에서 특정 문자(열) 위치 찾기(find)
1. txt = 'A lot of things occur each day, every day.' find( ) : 문자열에서 특정 문자나 문자열이 위치하는 인덱스를 리턴
2. offset1 = txt.find('e') find( )에는 찾고자 하는 문자 또는 문자만을 입력하면 해당
3. offset2 = txt.find('day')
문자나 문자열이 최초로 나타나는 위치에 대한 인덱스 리턴
4. offset3 = txt.find('day', 30)
5. print(offset1) # 22가 출력됨
2번째 줄 : txt에서 알파벳 ‘e’가 최초로 나타나는 위치의 인덱스를
6. print(offset2) # 27이 출력됨
7. print(offset3) # 38이 출력됨 offset1로 둠

3번째 줄 : txt에서 ‘day’가 최초로 나타나는 위치의 인덱스를

offset2로 둠

4번째 줄 : find( )의 두 번째 인자는 문자열에서 특정 문자열을 찾기

시작할 시작점을 지정. txt.find(‘day’, 30)은 txt에서 인덱스

30번 이후에 나타나는 ‘day’는 every day의 ‘day’

find( )는 해당 문자나 문자열을 찾을 수 없으면 -1을 리턴


093 문자열을 특정 문자(열)로 분리하기(split)
1. url = 'http://www.naver.com/news/today=20160831' split( ) : 구분자를 기준으로 문자열을 쉽게 분리하여 파싱 가능
2. log = 'name:홍길동 age:17 sex:남자 nation:조선'
3.
1번째 줄 : url에 일반적인 URL 형식의 문자열을 정의
4. ret1 = url.split('/')
2번째 줄 : log에 공백과 콜론(:)으로 구분되어 있는 문자열을 정의
5. print(ret1)
4~5번째 줄 : url을 슬래쉬(‘/’)를 구분자로 문자열을 분리하고
6.

7. ret2 = log.split( ) 그 결과를 화면에 출력


['http:', '', 'www.naver.com', 'news', 'today=20160831']
8. for data in ret2:
9. d1, d2 = data.split(':') 7번째 줄 : split( )에 인자가 없으면 디폴트로 공백을 구분자로
10. print('%s -> %s' %(d1, d2)) 문자열을 분리

['name:홍길동', 'age:17', 'sex:남자', 'nation:조선']

8~10번째 줄 : ret2의 모든 요소를 콜론(‘:’)을 구분자로 분리하고

그 결과를 d1, d2로 두고 이를 화면에 출력

name -> 홍길동


age -> 17
sex -> 남자
nation -> 조선
094 문자열을 특정 문자(열)로 결합하기(join)
1. loglist = ['2016/08/26 10:12:11', '200', 'OK', '이 또한 지나가리 join( ) 메소드 : split( )과는 반대로 문자열이 요소인 리스트를 인자
라'] 로 받아 리스트 모든 요소를 특정 문자열로 연결하여 새로운 문자열
로 만들어 리턴
2. bond = ';'
3. log = bond.join(loglist)
4. print(log) 1번째 줄 : loglist는 4개의 문자열이 요소인 리스트로 정의

2번째 줄 : 리스트 요소를 연결할 문자를 세미콜론(‘;’)으로 하고,

세미콜론을 변수 bond로 둠

3~4번째 줄 : bond.join(loglist)는 loglist의 모든 요소를 bond로

연결하여 하나의 문자열로만듦

2016/08/26 10:12:11;200;ok;이 또한 지나가리라


095 문자열에서 특정 문자를 다른 문자로 바꾸기(replace)
1. txt = 'My password is 1234' 2번째 줄 : txt.replace('1', '0')은 txt에서 ‘1’을 모두 찾아 ‘0’으로
2. ret1 = txt.replace('1', '0') 변경한 문자열을 리턴
3. ret2 = txt.replace('1', 'python')
3번째 줄 : txt.replace('1', 'python')은 txt에서 ‘1’을 모두 찾아
4. print(ret1) # 'My Password is 0234'가 출력됨
‘python’으로 변경한 문자열을 리턴
5. print(ret2) # 'My Password is python234'가 출력됨
7번째 줄 : txt에 한글로 된 새로운 문자열을 정의
6.

7. txt = '매일 많은 일들이 일어납니다.' 8번째 줄 : txt.replace('매일', '항상')은 txt에서 ‘매일’을 모두 찾아

8. ret3 = txt.replace('매일', '항상') ‘항상’으로 변경한 문자열을 리턴

9. ret4 = ret3.replace('일', '사건') 9번째 줄 : ret3.replace('일', '사건')은 ret3에서 ‘일’을 모두 찾아


10. print(ret3) # '항상 많은 일들이 일어납니다.'가 출력됨 ‘사건’으로 변경한 문자열을 리턴
11. print(ret4) # '항상 많은 사건들이 사건어납니다.'가 출력됨
096 문자열을 바이트 객체로 바꾸기(encode)
1. u_txt = 'I love python' 1번째 줄 : u_txt에 문자열 ‘I love python’을 정의
2. b_txt = u _txt.encode( ) 2번째 줄 : u_txt.encode( )는 문자열 u_txt를 UTF-8로 인코딩한
3. print(u _txt)
바이트 객체로 변환
4. print(b _txt)
b'I love python‘
5.

6. ret1 = 'I' == u_txt[0] 73 32 108 111 118 101 32 112 121 116 104 111 110

7. ret2 = 'I' == b_txt[0]


8. print(ret1) # True가 출력됨 6번째 줄 : 'I' == u_txt[0]의 값을 ret1로 둠.

9. print(ret2) # False가 출력됨 u_txt[0]은 문자 ‘I ’이므로 이 값은 True

7번째 줄 : 'I' == b_txt[0]의 값을 ret2로 둠.

b_txt[0]은 정수 73이므로 문자 ‘I ’와는 다른 값이므로

ret2는 False
097 바이트 객체를 문자열로 바꾸기(decode)
1. b_txt = b'A lot of things occur each day.' decode( ) 메소드 : 바이트 객체를 유니코드 문자열로 변환
2. u_txt = b _txt.decode( )
3. print(u _txt)
1번째 줄 : b_txt를 바이트 객체 문자열로 정의합니다.

2번째 줄 : b_txt.decode( )는 바이트 객체 b_txt를 유니코드 문자열로

변환

A lot of things occur each day.


098 문자열을 정렬하기(sorted, join)
1. strdata = input('정렬할 문자열을 입력하세요: ') sorted( ) : 인자로 입력되는 문자열의 모든 문자를 a, b, c,.. 오름차순
으로 정렬하고, 정렬된 각 문자를 요소로 하는 리스트로 리턴
2. ret1 = sorted(strdata)
3. ret2 = sorted(strdata, reverse=True)
4. print(ret1) 1번째 줄 : 정렬할 문자열을 입력받아 변수 strdata로 둠

5. print(ret2) 2번째 줄 : sorted( )를 이용해 strdata를 오름차순으로 정렬한


6. ret1 = ''.join(ret1) 결과가 담긴 리스트를 ret1로 둠
7. ret2 = ''.join(ret2)
3번째 줄 : sorted( )의 두 번째 인자를 reverse=True로 설정하면
8. print('오름차순으로 정렬된 문자열은 <' + ret1 + '>입니다.')
strdata를 c, b, a와 같은 순서인 내림차순으로 정렬
9. print('내림차순으로 정렬된 문자열은 <' + ret2 + '>입니다.')
4~5번째 줄 : ret1과 ret2를 출력 → strdata를 오름차순으로 정렬한

리스트와 내림차순으로 정렬한 리스트

6~7번째 줄 : 정렬한 결과인 리스트를 문자열로 생성하려면

문자열 객체의 join( )을 이용

['a', 'b', 'c', '가', '나', '다']


['다', '나', '가', 'c', 'b', 'a']
오름차순으로 정렬된 문자열은 <abc가나다>입니다.
내림차순으로 정렬된 문자열은 <다나가cba>입니다.
099 순차적인 정수 리스트 만들기(range)
1. range1 = range(10) 1번째 줄 : range(10)은 0 이상 10 미만까지 순차적인 정수를 구성하
고 반복 가능한 자료형인 range 객체를 리턴
2. range2 = range(10, 20)
3. print(list(range1)) # [0 ,1, 2, 3, 4, 5, 6, 7, 8, 9]가 출력됨 2번째 줄 : range(10, 20)은 10 이상 20 미만까지 순차적인 정수를 구
성하고 range 객체를 리턴
4. print(list(range2)) # [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]가 출
력됨 3~4번째 줄 : range( )가 리턴한 range 객체의 실제값들을 출력하려
면 반복 가능한 자료형을 리스트로 변환해주는 파이썬 내장함수
list( )를 이용

1부터 10까지 정수를 모두 더하는 코드(for문)

ret = 0
for i in range(10):
ret += (i+1)
100 리스트에서 특정 위치의 요소 얻기
1. listdata = [1, 2, 'a', 'b', 'c', [4, 5, 6]] 1번째 줄 : 다양한 요소로 구성되어 있는 리스트를 listdata에 정의
2. val1 = listdata[1] 2번째 줄 : listdata[1]은 listdata의 2번째 요소, val1의 값은 2
3. val2 = listdata[3]
3번째 줄 : listdata[3]은 listdata의 4번째 요소, val2의 값은 ‘b’
4. val3 = listdata[5][1]
4번째 줄 : listdata[5]는 listdata의 6번째 요소,
5. print(val1) # 2가 출력됨
listdata의 6번째 요소는 [4, 5, 6]인 리스트
6. print(val2) # 'b'가 출력됨
7. print(val3) # 5가 출력됨
101 리스트에서 특정 요소의 위치 구하기(index)
1. solarsys = ['태양', '수성', '금성', '지구', '화성', '목성', '토성', '천왕 index( ) 메소드 : 리스트에서 요소의 값을 알고 있을 때
성', '해왕성', '지구']
그 요소가 최초로 나타나는위치의 인덱스를 리턴
2. planet = '지구'
3. pos = solarsys.index(planet)
4. print('%s은(는) 태양계에서 %d번째에 위치하고 있습니 1번째 줄 : solarsys를 태양계 구성 천체를 요소로 하는 리스트로
다.' %(planet, pos))
정의. 리스트에서 ‘지구’를 ‘해왕성’ 다음에 삽입
5. pos = solarsys.index(planet, 5)
2~3번째 줄 : solarsys 요소 중 ‘지구’가 위치하는 인덱스를 구함.
6. print('%s은(는) 태양계에서 %d번째에 위치하고 있습니
다.' %(planet, pos)) index( )는 리스트의 처음부터 찾기 시작하여 찾고자

하는 대상이 최초로 나타나는 인덱스를 리턴

결과 지구은(는) 태양계에서 3번째에 위치하고 있습니다.

5~6번째 줄 : solarsys에서 인덱스가 5 이상인 요소부터 검색하여

planet 과 동일한 요소가 등장하는 인덱스를 리턴

결과 지구는(은) 태양계에서 9번째에 위치하고 있습니다.


102 리스트에서 특정 위치의 요소를 변경하기
1. solarsys = ['태양', '수성', '금성', '지구', '화성', '목성', '토성', '천왕 1번째 줄 : solarsys를 태양계 구성 천체를 요소로 하는 리스트로 정
성', '해왕성'] 의
2. planet = '화성' 2~3번째 줄 : solarsys에서 ‘화성’의 인덱스를 구하고 pos로 둠
3. pos = solarsys.index(planet)
4번째 줄 : solarsys[pos]를 ‘Mars’로 변경
4. solarsys [pos] = 'Mars'
5. print(solarsys)
결과

['태양', '수성', '금성', '지구', 'Mars', '목성', '토성', '천왕성', '해왕성']


103 리스트에서 특정 구간에 있는 요소 추출하기
1. solarsys = ['태양', '수성', '금성', '지구', '화성', '목성', '토성', '천왕 1번째 줄 : solarsys를 태양계 구성 천체를 요소로 하는 리스트로 정
성', '해왕성'] 의
2. rock_planets = solarsys[1:4] 2번째 줄 : solarsys의 첫 번째 요소부터 3번째 요소까지 슬라이싱하
3. gas_planets = solarsys[4:] 여 만든 새로운 리스트를 rock_planets으로 둠

4. print('태양계의 암석형 행성: ', end='');print(rock_planets) 3번째 줄 : solarsys의 4번째 요소부터 끝까지 슬라이싱하여 만든 새
로운 리스트를 gas_planets으로 둠
5. print('태양계의 가스형 행성: ', end='');print(gas_planets)
4~5번째 줄 : rock_planets과 gas_planets을 출력

결과
태양계의 암석형 행성: ['수성', '금성', '지구']
태양계의 가스형 행성: ['화성', '토성', '목성', '천왕성', '해왕성']
104 리스트에서 짝수 번째 요소만 추출하기
1. listdata = list(range(1, 21)) 1번째 줄 : 1에서 20까지 순차적인 정수 리스트를 생성하고 변수
listdata로 지정
2. evenlist = listdata[1::2]
3. print(evenlist) 2번째 줄 : listdata의 두 번째 요소부터 끝까지 스텝 2로 슬라이싱

결과

[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

홀수 번째 요소만 추출하여 새로운 리스트를 만들고 싶을 경우


oddlist = listdata[::2]
print(oddlist)
105 리스트 요소 순서를 역순으로 만들기 ① (reverse)
1. listdata = list(range(5)) reverse( ) 메소드 : 리스트의 모든 요소 순서를 거꾸로 만듦
2. listdata.reverse( )
3. print(listdata) # [4, 3, 2, 1, 0]이 출력됨

1번째 줄 : listdata를 0에서 4까지 순차적인 정수 리스트로 정의

2번째 줄 : listdata.reverse( )로 listdata의 요소가 역순으로 변경됨

결과

[4, 3, 2, 1, 0]
106 리스트 요소 순서를 역순으로 만들기 ② (reversed)
1. listdata = list(range(5)) reversed( ) : 인자로 입력된 시퀀스 자료형의 요소 순서를 역순으로
새로운 시퀀스 자료형을 만들어 리턴
2. ret1 = reversed(listdata)
3. print('원본 리스트 ', end='');print(listdata);
4. print('역순 리스트 ', end='');print(list(ret1)) 1번째 줄 : listdata를 0에서 4까지 순차적인 정수 리스트로 정의

5. 2번째 줄 : listdata의 요소 순서를 역순으로 새로운 리스트를 만들고


6. ret2 = listdata[::-1] ret1으로 둠
7. print('슬라이싱 이용 ', end='');print(ret2)
3~4번째 줄 : 원본 리스트와 reversed( )로 새로 생성한 리스트를

화면에 출력

6~7번째 줄 : 리스트의 처음부터 끝까지 스텝이 -1인 슬라이싱을

이용하면 리스트의 요소 순서가 역순으로 된

새로운 리스트를 만듦

결과
원본 리스트 [0, 1, 2, 3, 4]
역순 리스트 [4, 3, 2, 1, 0]
슬라이싱 이용 [4, 3, 2, 1, 0]
107 리스트 합치기(+)
1. listdata1 = ['a', 'b', 'c', 'd', 'e'] 1~2번째 줄 : 두 개의 리스트 ['a', 'b', 'c', 'd', 'e']와 ['f ', 'g', 'h', 'i', 'j']를
2. listdata2 = ['f', 'g', 'h', 'i', 'j'] 변수 listdata1, listdata2에 각각 대입
3. listdata3 = listdata1 + listdata2
3번째 줄 : listdata1와 listdata2를 연결하여 만들어지는 리스트를
4. listdata4 = listdata2 + listdata1
listdata3으로 둠
5. print(listdata3) # ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']가 출력됨
4번째 줄 : listdata2와 listdata1을 연결하여 만들어지는 리스트를
6. print(listdata4) # ['f', 'g', 'h', 'i', 'j', 'a', 'b', 'c', 'd', 'e']가 출력됨
listdata4로 둠

결과
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
['f', 'g', 'h', 'i', 'j', 'a', 'b', 'c', 'd', 'e']
108 리스트 반복하기(*)
1. listdata = list(range(3)) list*2 = list + list
2. ret = listdata*3
3. print(ret) # [0, 1, 2, 0, 1, 2, 0, 1, 2]가 출력됨
1번째 줄 : listdata를 [0, 1, 2]로 정의

2번째 줄 : listdata*3은 listdata를 3번 반복한 리스트

listdata*3은 listdata + listdata + listdata와 동일

결과

[0, 1, 2, 0, 1, 2, 0, 1, 2]
109 리스트에 요소 추가하기(append)
1. listdata = [ ] append( ) : 인자로 입력된 값을 리스트의 맨 마지막 요소로 추가
2. for i in range(3):
3. txt = input('리스트에 추가할 값을 입력하세요[%d/3]:
1번째 줄 : 빈 리스트를 listdata로 정의
' %(i+1))
4. listdata.append(txt) 2~3번째 줄 : 사용자로부터 값을 3번 입력받기 위해

5. print(listdata) for문과 input( )을 이용

4~5번째 줄 : listdata에 사용자가 입력한 값을 추가하고

listdata를 화면에 출력

결과(12, 14, 18 입력 시)
리스트에 추가할 값을 입력하세요[1/3]: 12
['12']
리스트에 추가할 값을 입력하세요[2/3]: 14
['12', '14']
리스트에 추가할 값을 입력하세요[3/3]: 18
['12', '14', '18']
110 리스트의 특정 위치에 요소 삽입하기(insert)
1. solarsys = ['태양', '수성', '금성', '지구', '화성', '목성', '토성', '천왕 insert( ) : 리스트의 특정 위치에 새로운 요소를 삽입
성', '해왕성']
2. pos = solarsys.index('목성')
1번째 줄 : 태양계 구성 천체를 리스트 solarsys로 정의
3. solarsys.insert(pos, '소행성')
4. print(solarsys) 2번째 줄 : solarsys에서 ‘목성’의 인덱스를 구하여 pos로 둠

3번째 줄 : solarsys.insert(pos, '소행성')은 solarsys에서 인덱스가

pos인 부분에 새로운 요소 ‘소행성’을 삽입

결과

['태양', '수성', '금성', '지구', '화성', '소행성', '목성', '토성', '천왕성', '해왕성']
111 리스트의 특정 위치의 요소 제거하기(del)
1. solarsys = ['태양', '수성', '금성', '지구', '화성', '목성', '토성', '천왕 1번째 줄 : 태양계 구성 천체를 리스트 solarsys로 정의
성', '해왕성']
2~3번째 줄 : solarsys의 인덱스가 0인 첫 번째 요소인 ‘태양’을
2. del solarsys[0]
solarsys로부터 제거
3. print(solarsys)
4. del solarsys[-2] ['수성', '금성', '지구', '화성', '목성', '토성', '천왕성', '해왕성']

5. print(solarsys)

4~5번째 줄 : solarsys의 끝에서 2번째 요소를 제거

['수성', '금성', '지구', '화성', '목성', '토성', '해왕성']


112 리스트에서 특정 요소 제거하기(remove)
1. solarsys = ['태양', '수성', '금성', '지구', '화성', '목성', '토성', '천왕 remove( ) : 리스트에서 특정 요소의 값을 알고 있을 때 해당
성', '해왕성']
요소를 제거
2. solarsys.remove('태양')
3. print(solarsys)
1번째 줄 : 태양계 구성 천체를 리스트 solarsys로 정의

2번째 줄 : solarsys에서 ‘태양’이라는 요소를 제거 → solarsys에

존재하지 않는 요소를 제거하려고 하면 오류가 발생

ValueError: list.remove(x): x not in list

결과

['수성', '금성', '지구', '화성', '목성', '토성', '천왕성', '해왕성']


113 리스트에서 특정 구간에 있는 모든 요소 제거하기
1. solarsys = ['태양', '수성', '금성', '지구', '화성', '목성', '토성', '천왕 list의 인덱스 2번 요소부터 인덱스 5번 요소까지 삭제할 경우
성', '해왕성']
del list[2:6]
2. del solarsys[1:3]
3. print(solarsys)
1번째 줄 : 태양계 구성 천체를 리스트 solarsys로 정의

2번째 줄 : solarsys[1:3]을 제거

solarsys[1:3]은 solarsys의 인덱스 1번 요소부터

3번 요소 미만까지를 의미

결과

['태양', '지구', '화성', '목성', '토성', '천왕성', '해왕성']


114 리스트에 있는 요소 개수 구하기(len)
1. listdata = [2, 2, 1, 3, 8, 5, 7, 6, 3, 6, 2, 3, 9, 4, 4] len( ) : 시퀀스 자료형의 크기를 구하는 함수
2. listsize = len(listdata) 리스트에 적용하면 리스트의 모든 요소의 개수를 리턴
3. print(listsize) # 15가 출력됨

1번째 줄 : 정수를 요소로 하는 리스트를 listdata로 정의

2~3번째 줄 : len(listdata)는 listdata의 요소 개수를 리턴

listdata의 요소 개수는 15개이므로 listsize는 15


115 리스트에서 특정 요소 개수 구하기(count)
1. listdata = [2, 2, 1, 3, 8, 5, 7, 6, 3, 6, 2, 3, 9, 4, 4] count( ) 메소드 : 리스트에 존재하는 특정 요소의 개수를 리턴
2. c1 = listdata.count(2)
3. c2 = listdata.count(7)
1번째 줄 : 정수를 요소로 하는 리스트를 listdata로 정의
4. print(c1) # 3이 출력됨
2번째 줄 : listdata에서 값이 2인 요소 개수를 구해서 c1로 둠
5. print(c2) # 1이 출력됨
3번째 줄 : listdata에서 값이 7인 요소 개수를 구해서 c2로 둠

4~5번째 줄 : listdata에서 값이 2인 요소의 개수와 값이 7인 요소의

개수는 각각 3과 1
116 리스트 제거하기(del)
1. listdata = [2, 2, 1, 3, 8, 5, 7, 6, 3, 6, 2, 3, 9, 4, 4] 1번째 줄 : 정수를 요소로 하는 리스트를 listdata로 정의
2. del listdata 2번째 줄 : del listdata는 listdata를 메모리에서 제거함
3. print(listdata)
3번째 줄 : listdata 자체가 메모리에서 제거 → listdata는 코드에서

존재하지 않는 변수

listdata의 값을 출력하려고 할 경우 오류가 발생

NameError: name 'listdata' is not defined


117 리스트 요소 정렬하기 ① (sort)
1. namelist = ['Mary', 'Sams', 'Aimy', 'Tom', 'Michale', 'Bob', 'Kelly'] 1번째 줄 : 영문 이름이 요소인 리스트 namelist를 정의
2. namelist.sort( ) 2번째 줄 : namelist.sort( )로 namelist의 모든 요소를 오름차순으로
3. print(namelist)
정렬. 내림차순으로 정렬하려면 2라인을 수정

namelist.sort(reverse=True)

3번째 줄 : 리스트 객체의 sort( )로 listdata를 정렬

['Aimy', 'Bob', 'Kelly', 'Mary', 'Michale', 'Sams', 'Tom']

결과(listdata.sort(reverse=True))

['Tom', 'Sams', 'Michale', 'Mary', 'Kelly', 'Bob', 'Aimy']


118 리스트 요소 정렬하기 ② (sorted)
1. namelist = ['Mary', 'Sams', 'Aimy', 'Tom', "Michale', 'Bob', 'Kelly'] sorted( ) : 원본 리스트는 그대로 두고 정렬한 결과 리스트를 리턴
2. ret1 = sorted(namelist)
3. ret2 = sorted(namelist, reverse=True)
1번째 줄 : sorted( )를 이용해 namelist의 모든 요소를 오름차순으로
4. print(namelist)
정렬한 결과를 ret1로 둠
5. print(ret1)
2번째 줄 : sorted( )를 이용해 namelist의 모든 요소를 내림차순으로
6. print(ret2)
정렬한 결과를 ret2로 둠

3번째 줄 : namelist 원본 리스트와 namelist를 오름차순으로 정렬한

결과인 ret1, namelist를 내림차순으로 정렬한 결과인

ret2를 출력

결과
['Mary', 'Sams', 'Aimy', 'Tom', "Michale', 'Bob', 'Kelly']
['Aimy', 'Bob', 'Kelly', 'Mary', 'Michale', 'Sams', 'Tom']
['Tom', 'Sams', 'Michale', 'Mary', 'Kelly', 'Bob', 'Aimy']
119 리스트 요소 무작위로 섞기(shuffle)
1. from random import shuffle 1번째 줄 : random 모듈의 shuffle( )을 임포트
2. 3번째 줄 : 1부터 10까지 순차적인 정수 리스트를 listdata로 정의
3. listdata = list(range(1, 11))
4~6번째 줄 : for문을 이용하여 listdata를 shuffle( )로 무작위로 섞은
4. for i in range(3):
결과를 3번 출력
5. shuffle(listdata)
6. print(listdata) # 출력 결과는 실행할 때마다 달라짐
결과

[3, 9, 6, 8, 4, 10, 1, 2, 5, 7]
[7, 5, 4, 2, 3, 10, 9, 6, 8, 1]
[9, 8, 4, 7, 1, 2, 3, 10, 6, 5]
120 리스트의 모든 요소를 인덱스와 쌍으로 추출하기(enumerate)
1. solarsys = ['태양', '수성', '금성', '지구', '화성', '목성', '토성', '천왕 enumerate( ) : 시퀀스 자료형을 인자로 받아 각 요소를 인덱스와
성', '해왕성']
함께 쌍으로 추출할 수 있는 반복 가능 자료 enumerate 객체를 리턴
2. ret = list(enumerate(solarsys))
3. print(ret)
4. 1번째 줄 : 태양계 구성 천체를 리스트 solarsys로 정의

5. for i, body in enumerate(solarsys): 2번째 줄 : solarsys의 enumerate 객체를 생성하고 list( )를 이용해
6. print('태양계의 %d번째 천체: %s' %(i, body)) 리스트로 변환

결과 [(0, '태양'), (1, '수성'), (2, '금성'), (3, '지구'), (4, '화성'), (5, '목성'), (6,
'토성'), (7, '천왕성'), (8, '해왕성')]

5~6번째 줄 : solarsys의 enumerate 객체와 for문을 활용한 예

태양계의 0번째 천체: 태양


태양계의 1번째 천체: 수성
태양계의 2번째 천체: 금성
태양계의 3번째 천체: 지구
태양계의 4번째 천체: 화성
태양계의 5번째 천체: 목성
태양계의 6번째 천체: 토성
태양계의 7번째 천체: 천왕성
태양계의 8번째 천체: 해왕성
121 리스트의 모든 요소의 합 구하기(sum)
1. listdata = [2, 2, 1, 3, 8, 5, 7, 6, 3, 6, 2, 3, 9, 4, 4] 1번째 줄 : 임의의 정수가 요소인 리스트를 listdata로 정의
2. ret = sum(listdata) 2번째 줄 : 내장함수 sum( )을 이용해 listdata의 모든 요소의 합을
3. print(ret) # 65가 출력됨
ret으로 둠

3번째 줄 : ret을 출력하면 listdata의 모든 요소의 합 65가 출력

숫자가 아닌 요소가 섞여 있는 리스트를 sum( )을 이용해

합을 구하려고 할 경우 TypeError 오류 발생
122 리스트 요소가 모두 참인지 확인하기(all, any)
1. listdata1 = [0, 1, 2, 3, 4] - 리스트의 모든 요소가 참인지 또는 모든 요소가 거짓인지 판단해야 하는
경우 사용
2. listdata2 = [True, True, True]
3. listdata3 = ['', [ ], ( ), { }, None, False] all( ) : 인자로 입력되는 리스트의 모든 요소가 참인 경우에만

4. print(all(listdata1)) # False가 출력됨 True를 리턴

5. print(any(listdata1)) # True가 출력됨 any( ) : 인자로 입력되는 리스트의 모든 요소가 거짓인 경우에만
6. print(all(listdata2)) # True가 출력됨 False를 리턴
7. print(any(listdata2)) # True가 출력됨
모두 거짓을 의미하는 값
8. print(all(listdata3)) # False가 출력됨
• 숫자 0
9. print(any(listdata3)) # False가 출력됨
• 빈 문자열 ‘’, “”
• 빈 리스트 [ ]
• 빈 튜플 ( )
• 빈 사전 { }
• None

1~3번째 줄 : 리스트 자료 listdata1, listdata2, listdata3을 정의

4번째 줄 : 0은 거짓인 값이므로 all(listdata1)은 False

5번째 줄 : listdata1은 0을 제외한 모든 값이 참인 값

6~7번째 줄 : listdata2는 요소가 모두 True

8~9번째 줄 : listdata3은 모든 요소가 거짓


123 사전에 요소 추가하기
1. solar1=['태양', '수성', '금성', '지구', '화성', '목성', '토성', '천왕성', 사전에 새로운 요소를 추가하는 방법
'해왕성']
dict[k2] = val2
2. solar2=['Sun','Mercury','Venus','Earth','Mars','Jupiter','Saturn','
Uranus', 'Neptune']
3. solardict = { } 1~2번째 줄 : solar1, solar2를 태양계를 구성하는 천체의 한글이름
4. for i, k in enumerate(solar1): 과 영문이름을 순서에 맞게 각각 리스트로 정의

5. val = solar2[i] 3번째 줄 : 빈 사전을 solardict라는 이름으로 정의


6. solardict[k] = val 4~5번째 줄 : solar1의 값을 추출한 후 변수 i, k로 두고, 추출한 인덱
7.
스에 해당하는 solar2의 값을 val에 대입

8. print(solardict) 6번째 줄 :사전 solardict에 k:val을 요소로 추가

7번째 줄 : for 구문을 모두 반복한 후 solardict를 출력

결과
{'수성': 'Mercury', '지구': 'Earth', '천왕성': 'Uranus', '목성': 'Jupiter', '해왕성':
'Neptune', '토성':
'Saturn', '화성': 'Mars', '태양': 'Sun', '금성': 'Venus'}
124 사전의 특정 요소값 변경하기
1. names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245, val의 값을 val2로 변경하는 방법
2. 'Michale':27115, 'Bob':5887, 'Kelly':7855} dict[k] = val2
3. names['Aimy'] = 10000
4. print(names)
1~2번째 줄 : 사전 자료 names를 정의

3번째 줄 : names의 요소 중 키가 ‘Aimy’인 출생아 수를 10000으로


변경

4번째 줄 : names를 출력 → 키가 ‘Aimy’의 값이 10000으로 변경

{'Aimy': 10000, 'Michale': 27115, 'Tom': 20245, 'Bob': 5887, 'Mary': 10999,
'Sams': 2111,
'Kelly': 7855}
125 사전의 특정 요소 제거하기(del)
1. names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245, 사전 dict에서 특정 요소 k:val을 제거하는 방법
2. 'Michale':27115, 'Bob':5887, 'Kelly':7855} del dict[k]
3. del names['Sams']
4. print(names)
1~2번째 줄 : 사전 자료 names를 정의

3번째 줄 : names의 요소 중 키가 ‘Sams’인 요소를 사전에서 제거

4번째 줄 : names를 출력

결과

{'Aimy': 9778, 'Michale': 27115, 'Tom': 20245, 'Bob': 5887, 'Mary': 10999,
'Kelly': 7855}
126 사전의 모든 요소 제거하기(clear)
1. names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245, clear( ) : 사전의 모든 요소를 제거하여 빈 사전으로 만들 때 사용
2. 'Michale':27115, 'Bob':5887, 'Kelly':7855}
3. names.clear( )
1~2번째 줄 : 이름이 키이고 출생아 수가 값인 사전 자료 names를
4. print(names)
정의

3번째 줄 : names의 모든 요소를 제거하여 names를 빈 사전 { }로

만듦

4번째 줄 : names를 출력하면 빈 사전 { }이 출력됨


127 사전에서 키만 추출하기(keys)
1. names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245, 1~2번째 줄 : 사전 자료 names를 정의
2. 'Michale':27115, 'Bob':5887, 'Kelly':7855} 3~4번째 줄 : names.keys( )는 names의 모든 키를 추출하여
3. ks = names.keys( )
dict_keys 사전 뷰 객체로 리턴
4. print(ks)
dict_keys 객체를 ks에 대입하고 출력
5.

6. for k in ks: dict_keys(['Aimy', 'Michale', 'Tom', 'Bob', 'Mary', 'Sams', 'Kelly'])

7. print('Key:%s \tValue:%d' %(k, names[k]))


dict_keys 객체

key_list = list(names.keys( ))

결과 6~7번째 줄 : names의 dict_keys 사전 뷰 객체 ks의 모든 요소를

Key:Aimy Value:9778 하나씩 추출하여 변수 k에 대입하고 k의 값과 names[k]


Key:Michale Value:27115
Key:Tom Value:20245 의 값을 화면에 출력
Key:Bob Value:5887
Key:Mary Value:10999
Key:Sams Value:2111
Key:Kelly Value:7855
128 사전에서 값만 추출하기(values)
1. names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245, 1~2번째 줄 : 사전 자료 names를 정의
2. 'Michale':27115, 'Bob':5887, 'Kelly':7855} 3~4번째 줄 : names.values( )는 names의 모든 값을 추출하여
3. vals = names.values( )
dict_values 사전 뷰 객체로 리턴
4. print(vals)
dict_values 객체를 vals에 대입하고 출력
5.

6. vals _list = list(vals) dict_values([9778, 27115, 20245, 5887, 10999, 2111, 7855])

7. ret = sum(vals _list)


8. print('출생아 수 총계: %d' %ret) 6번째 줄 : dict_values 객체는 list( ) 함수의 인자로 입력되어

리스트로 변환

7~8번째 줄 : sum( )을 이용해 val_list의 모든 요소를 더함

결과
출생아 수 총계: 83990
129 사전 요소를 모두 추출하기(items)
1. names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245, 1~2번째 줄 : 이름이 키이고 출생아 수가 값인 사전 자료 names를
2. 'Michale':27115, 'Bob':5887, 'Kelly':7855} 정의
3. items = names.items( )
3~4번째 줄 : names.items( )는 names의 모든 요소를 추출하여
4. print(items)
dict_items 사전 뷰 객체로 리턴
5.
dict_items 객체를 items에 대입하고 출력
6. for item in items:
7. print(item) 결과

dict _items([('Mary', 10999), ('Michale', 27115), ('Bob', 5887), ('Sams',


2111), ('Kelly', 7855),
('Tom', 20245), ('Aimy', 9778)])

6~7번째 줄 : for문을 이용해 items의 모든 요소를 출력

결과

('Mary', 10999)
('Michale', 27115)
('Bob', 5887)
('Sams', 2111)
('Kelly', 7855)
('Tom', 20245)
('Aimy', 9778)
130 사전에 특정 키가 존재하는지 확인하기(in)
1. names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245, 사전 dict에 k가 키로 있는지 확인하는 방법
2. 'Michale':27115, 'Bob':5887, 'Kelly':7855} k in dict
3. k = input('이름을 입력하세요: ')
4. if k in names:
1~2번째 줄 : 이름이 키이고 출생아 수가 값인 사전 자료 names를
5. print('이름이 <%s>인 출생아 수는 <%d>명입니다.' %(k,
names[k])) 정의
6. else: 3번째 줄 : 사용자로부터 이름을 입력받고 그 값을 변수 k에 대입
7. print('자료에 <%s>인 이름이 존재하지 않습니다.' %k)
4~5번째 줄 : k가 사전 자료 names의 키로 존재하면,

키와 이 키에 대응하는 값을 출력

6~7번째 줄 : k가 사전 자료 names의 키로 존재하지 않으면

그에 대한 메시지를 출력

결과
이름이 <Michale>인 출생아 수는 <27115>명입니다.
131 사전 정렬하기(sorted)
1. names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245, sorted( ) : 사전 자료를 인자로 입력받아 정렬
2. 'Michale':27115, 'Bob':5887, 'Kelly':7855} 사전을 인자로 입력하면 기본적으로 사전의 키를
3. ret1 = sorted(names)
오름차 순으로 정렬한 결과를 리스트로 리턴
4. print(ret1)
5.
3~4번째 줄 : sorted(names)는 names의 키를 오름차순으로
6. def f1(x):
7. return x[0] 정렬하여 리스트로 리턴. ret1을 출력

8. ['Aimy', 'Bob', 'Kelly', 'Mary', 'Michale', 'Sams', 'Tom']


9. def f2(x):
10. return x[1] 6~7번째 줄 : sorted( )의 key 인자로 사용할 함수 f1을 정의

f1은 인자로 입력된 x의 첫 번째 요소인 x[0]를 리턴

정렬할 데이터의 첫 번째 요소를 기준으로 정렬

9~10번째 줄 : sorted( )의 key 인자로 사용할 함수 f2를 정의

f2는 인자로 입력된 x의 두 번째 요소인 x[1]를 리턴

정렬할 데이터의 두 번째 요소를 기준으로 정렬


131 사전 정렬하기(sorted)
11. 12~13번째 줄 : f1이 리턴하는 값은 첫 번째 요소
12. ret2 = sorted(names.items( ), key=f1) names.items( ) 요소의 첫 번째 값은 names의 키
13. print(ret2)
ret2는 오름차순 정렬, 리스트 리턴
14.
[('Aimy', 9778), ('Bob', 5887), ('Kelly', 7855), ('Mary', 10999), ('Michale',
15. ret3 = sorted(names.items( ), key=f2) 27115), ('Sams',
2111), ('Tom', 20245)]
16. print(ret3)
17.
15~16번째 줄 : f2가 리턴하는 값은 두 번째 요소

18. ret4 = sorted(names.items( ), key=f2, reverse=True) names.items( ) 요소의 두 번째 값은 키에 대응

19. print(ret4) ret3은 오름차순으로 정렬, 리스트로 리턴

[('Sams', 2111), ('Bob', 5887), ('Kelly', 7855), ('Aimy', 9778), ('Mary', 10999),
('Tom', 20245),
('Michale', 27115)]

18~19번째 줄 : 15라인과 동일한 기준으로 내림차순 정렬

[('Michale', 27115), ('Tom', 20245), ('Mary', 10999), ('Aimy', 9778), ('Kelly',


7855), ('Bob', 5887),
('Sams', 2111)]
132 문자 코드값 구하기(ord)
1. ch = input('문자를 1개 입력하세요: ') ord( ) : 문자를 컴퓨터가 인식하는 코드값으로 변환
2. if len(ch) != 0:
3. ch = ch[0]
1번째 줄 : 사용자로부터 문자를 입력받아 변수 ch에 대입
4. chv = ord(ch)
2번째 줄 : ch의 길이가 0이 아닌지 체크
5. print('문자: %s \t코드값: %d [%s]' %(ch, chv, hex(chv)))
3번째 줄 : ch의 첫 번째 문자를 ch로 재정의

4번째 줄 : ch의 코드값인 ord(ch)의 값을 chv에 대입

5번째 줄 : ch, chv와 chv의 16진수 값을 화면에 출력

코드를 실행하고 ‘a’를 입력

결과

문자: a 코드값: 97 [0x61]

결과(‘가’를 입력했을 때)

문자: 가 코드값: 44032 [0xac00]


133 코드값에 대응하는 문자 얻기(chr)
1. val = input('문자 코드값을 입력하세요: ') chr( ) : 정수값을 입력하면 이 정수값에 해당하는 문자를 리턴
2. val = int(val)
3. try:
1~2번째 줄 : 사용자로부터 숫자를 입력받아 변수 val에 대입하고
4. ch = chr(val)
int( )를 이용해 정수형 자료로 변환
5. print('코드값: %d [%s], 문자: %s' %(val, hex(val), ch))
3~5번째 줄 : 사용자가 입력한 숫자에 해당하는 문자를 ch에 대입
6. except ValueError:
7. print('입력한 <%d>에 대한 문자가 존재하지 않습니 화면에 val, val의 16진수 값, ch를 각각 출력
다!' %val)
6~7번째 줄 : 사용자가 입력한 숫자에 해당하는 문자가 없으면

ValueError를 발생

결과(정수 114입력)

코드값: 114 [0x72], 문자: r


134 문자열로 된 식을 실행하기(eval)
1. expr1 = '2+3' eval( ) : 파이썬 코드로 실행 가능한 문자열을 인자로 받아
2. expr2 = 'round(3.7)' 실행하는 함수
3. ret1 = eval(expr1)
4. ret2 = eval(expr2)
1~2번째 줄 : 문자열을 변수 expr1, expr2에 각각 대입
5. print('<%s>를 eval( )로 실행한 결과: ' %expr1, end='');
print(ret1) 3~4번째 줄 : expr1과 expr2를 eval( )로 실행한 결과를
6. print('<%s>를 eval( )로 실행한 결과: ' %expr2, end=''); 각각 ret1, ret2로 둠. 파이썬 코드로 실행 불가능한
print(ret2)
문자열이면 SyntaxError가 발생

SyntaxError: unexpected EOF while parsing

결과

<2+3>를 eval( )로 실행한 결과: 5


<round(3.7)>를 eval( )로 실행한 결과: 4
135 이름없는 한줄짜리 함수 만들기(lambda)
1. add = lambda x, y: x+y lambda 함수 정의 방법
2. ret = add(1, 3) lambda 인자, 인자, … : 실행 코드

3. print(ret) # 4가 출력됨
2개의 인자를 받고 이를 더한 결과를 리턴하는 lambda 함수
4.
lambda x, y: x+y
5. funcs = [lambda x: x+'.pptx', lambda x: x+'.docx']
1~3번째 줄 : 2개의 인자 x, y를 더하는 lambda 함수를 add로 정의
6. ret1 = funcs[0]('Intro')
7. ret2 = funcs[1]('Report') add(1, 3)은 1과 3을 더한 결과를 리턴. ret에 대입하고 화면에 출력

8. print(ret1) # intro.pptx가 출력됨 5번째 줄 : lambda 함수 2개를 정의하고 이를 요소로 하는

9. print(ret2) # Report.docx가 출력됨 리스트를 funcs로 정의


10. 6~9번째 줄 : funcs[0]('intro')와 funcs[1]('Report')의 값을 출력
11. names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245,
11~14번째 줄 : sorted( )의 key인자에 대입되는 함수를
'Michale':27115,
12. 'Bob':5887, 'Kelly':7855} lambda 함수로 정의

13. ret3 = sorted(names.items( ), key=lambda x: x[0]) 결과


14. print(ret3) [('Aimy', 9778), ('Bob', 5887), ('Kelly', 7855), ('Mary', 10999), ('Michale',
27115), ('Sams',
2111), ('Tom', 20245)]
136 인자를 바꾸어 함수를 반복 호출하여 결과값 얻기(map)
1. f = lambda x: x*x map( ) : 집합 A와 함수 f가 주어지면 집합 B를 쉽게 구해주는 함수와
동일한 역할
2. args = [1, 2, 3, 4, 5]
3. ret = map(f, args)
4. print(list(ret)) 1번째 줄 : lambda 함수 lambda x: x*x를 f로 둠

2번째 줄 : 함수의 인자로 입력될 리스트를 정의하고 args로 둠

3~4번째 줄 : map(f, args)는 args의 모든 요소를 f에 대입하여

결과를 얻은 후 map 객체로 리턴

map 객체는 list( )를 이용해 리스트로 변환 가능

결과

[1, 4, 9, 16, 25]


137 텍스트 파일을 읽고 출력하기(read)
1. f = open('stockcode.txt', 'r') 1번째 줄 : stockcode.txt 파일을 텍스트 읽기 모드 ‘r’로 오픈하고,
2. data = f.read( ) 오픈한 파일 객체를 f로 둠
3. print(data)
2~3번째 줄 : f.read( )는 stockcode.txt의 모든 내용을 한꺼번에 읽음
4. f.close( )
data는 stockcode.txt 파일의 모든 내용을 담고 있음

결과
000020 동화약품
000040 S&T모터스
000050 경방
000060 메리츠화재
000070 삼양사
000071 삼양사우
000100 유한양행
000101 유한양행우

104110 신성ENG
104120 신성FA
104700 한국철강
105560 KB금융
107590 미원에스씨
138 텍스트 파일을 한줄씩 읽고 출력하기 ① (readline)
1. f = open('stockcode.txt', 'r') 1번째 줄 : 파일을 텍스트 읽기 모드로 오픈하고 파일 객체를 f로 둠
2. line _num = 1 2번째 줄 : 라인 넘버를 표시하기 위해 line_num 변수를 이용
3. line = f.readline( )
3번째 줄 : stockcode.txt의 첫 한 줄을 읽고 변수 line에 대입
4. while line:
4번째 줄 : line의 값이 빈 문자열일 때까지 while 루프를 반복
5. print('%d %s' %(line_num, line), end='')
5번째 줄 : 읽은 한 줄을 라인 넘버와 함께 화면에 출력
6. line = f.readline( )
7. line _num += 1 6~7번째 줄 : readline( )으로 그 다음줄을 읽어 line에 대입하고 라인
넘버를 1 증가. line이 빈 문자열일 때까지 5~7라인을 반복
8. f.close( )
결과
0 000020 동화약품
1 000040 S&T모터스
2 000050 경방
3 000060 메리츠화재
4 000070 삼양사
5 000071 삼양사우
6 000100 유한양행
7 000101 유한양행우

922 104110 신성ENG
923 104120 신성FA
924 104700 한국철강
925 105560 KB금융
926 107590 미원에스씨
139 텍스트 파일을 한줄씩 읽고 출력하기 ② (readlines)
1. f = open('stockcode.txt', 'r') readlines( ) : 텍스트 파일의 끝까지 한 줄씩 읽어 각 줄을 요소로
2. lines = f.readlines( ) 하는 리스트로 리턴
3. for line _num, line in enumerate(lines):
4. print('%d %s' %(line_num+1, line), end='')
1번째 줄 : 파일을 텍스트 읽기 모드로 오픈하고 객체를 f에 대입
5. f.close( )
2번째 줄 : 텍스트 파일의 모든 내용을 한 줄씩 한꺼번에 읽고

각 줄을 요소로 하는 리스트를 lines로 둠

['000020 동화약품\n', '000040 S&T모터스\n', …, '107590 미원에스씨']

3번째 줄 : lines의 모든 요소에 대해 인덱스와 요소 추출

4번째 줄 : 인덱스+1을 라인 넘버로 하고 lines 요소 출력


140 화면에서 사용자 입력을 받고 파일로 쓰기(write)
1. text = input('파일에 저장할 내용을 입력하세요: ') 1번째 줄 : 사용자로부터 파일에 저장할 내용을 입력받기 위해
2. f = open('mydata.txt', 'w') input( )을 이용하고 입력받은 텍스트를 text로 둠
3. f.write(text)
2번째 줄 : 텍스트 파일을 텍스트 쓰기 모드로 오픈
4. f.close( )
3~4번째 줄 : 파일 객체의 write( )를 이용해 text를

mydata.txt 파일에 기록하고 닫음


141 텍스트 파일에 한 줄씩 쓰기(writelines)
1. count = 1 1번째 줄 : 사용자의 입력 회수를 나타내기 위한 변수 count를
2. data = [ ] 1로 정의
3. print('파일에 내용을 저장하려면 내용을 입력하지 말고 [Enter]를
2번째 줄 : data는 사용자가 입력한 문자열을 요소로 담을 리스트
누르세요')
4. while True: 4~7번째 줄 : 사용자가 빈 문자열을 입력할 때까지 사용자로부터

5. text = input('[%d] 파일에 저장할 내용을 입력하세요: 문자열을 입력받음


' %count)
8~9번째 줄 : 줄바꿈 기호인 ‘\n’을 추가한 문자열을 리스트 자료
6. if text == '':
data에 추가 후 count를 1 증가
7. break
8. data.append(text+'\n') 11~13번째 줄 : mydata.txt 파일을 텍스트 쓰기 모드로 오픈하고

9. count += 1 writelines( )를 이용해 data의 모든 요소를 파일에

10. 기록
11. f = open('mydata.txt', 'w')
12. f.writelines(data)
13. f.close( )
142 텍스트 파일 복사하기(read, write)
1. f = open('stockcode.txt', 'r') 1~2번째 줄 : 원본 파일을 텍스트 읽기 모드로 오픈하고 파일 객체를
2. h = open('stockcode_copy.txt', 'w') f로 둠. 원본 파일의 복사본이 될 파일을 텍스트 쓰기
3.
모드로 오픈하고 파일 객체를 h로 둠
4. data = f.read( )
4~5번째 줄 : f.read( )로 stockcode.txt의 모든 내용을 읽고 그 내용을
5. h.write(data)
data로 둠. h.write( )로 data를 기록
6.

7. f.close( ) 7~8번째 줄 : 2개의 파일을 모두 닫음

8. h.close( )
143 바이너리 파일 복사하기(read, write)
1. bufsize = 1024 1번째 줄 : bufsize를 1024로 정의
2. f = open('img_sample.jpg', 'rb') 2~3번째 줄 : img_sample.jpg를 바이너리 읽기 모드로 오픈하고
3. h = open('img_sample_copy.jpg', 'wb')
파일 객체를 f로 둠. img_sample.jpg의 복사본이 될
4.
img_sample_copy.jpg를 바이너리 쓰기 모드로 오픈하고
5. data = f.read(bufsize)
파일 객체를 h로 둠
6. while data:
7. h.write(data) 5번째 줄 : img_sample.jpg 파일의 내용을 bufsize인 1024바이트만큼

8. data = f.read(bufsize) 읽어 data로 둠

9. 6번째 줄 : data가 빈 문자열이 될 때까지 while 루프를 반복


10. f.close( ) 7~8번째 줄 : data를 img_sample_copy.jpg에 기록하고 원본 이미지
11. h.close( )
파일인 img_sample.jpg에서 다음 1024바이트를 읽어

data로 둠
144 파일을 열고 자동으로 닫기(with~as)
1. with open('stockcode.txt', 'r') as f: 파일 열고 닫기의 기본적인 방법
2. for line_num, line in enumerate(f.readlines( )): f = open('stockcode.txt', 'r')
… 파일 처리 코드 …
3. print('%d %s' %(line _num+1, line), end='') f.close( )

with open( ) as

with open('stockcode.txt', 'r') as f:


… 파일 처리 코드 …
145 파일의 특정 부분만 복사하기(seek, read, write)
1. spos = 105 # 파일을 읽는 위치 지정 1~2번째 줄 : spos와 size는 파일을 읽는 위치와 읽을 크기를 지정한
2. size = 500 # 읽을 크기를 지정 변수
3.
4~5번째 줄 : 각각 텍스트 읽기 모드, 텍스트 쓰기 모드로 오픈
4. f = open('stockcode.txt', 'r')
7번째 줄 : stockcode.txt에서 파일을 읽을 위치를 seek( )으로
5. h = open('stockcode_part.txt', 'w')
spos만큼 이동
6.

7. f.seek(spos) 8~9번째 줄 : stockcode.txt를 spos부터 size만큼 읽어 data로 두고

8. data = f.read(size) stockcode_part.txt에 기록

9. h.write(data) 11~12번째 줄 : 파일을 모두 닫음


10. 코드를 실행하고 stockcode_part.txt가 생성되었는지 확인
11. h.close( ) 유한양행
000101 유한양행우
12. f.close( )
000120 대한통운
000140 하이트홀딩스
000141 하이트홀딩스우

000541 흥국쌍용화재우
000542 흥국쌍용화재2우B
000590 조선선재
00061
146 파일 크기 구하기
1. from os.path import getsize 파일의 크기를 확인하려면 os.path 모듈의 getsize( )를 이용
2. getsize( )는 인자로 입력된 파일의 크기를 바이트 크기로 리턴
3. file1 = 'stockcode.txt'
4. file2 = 'd:/devlab/py200/img_sample.jpg'
1번째 줄 : os.path 모듈의 getsize( )를 임포트
5. file _size1 = getsize(file1)
3~4번째 줄 : file1에는 stockcode.txt 파일이름만, file2에는
6. file _size2 = getsize(file2)
7.
img_sample.jpg 파일의 절대경로로 각각 정의

8. print('File Name: %s \tFile Size: %d' %(file1, file_size1)) 5번째 줄 : getsize(file1)은 프로그램이 구동되는 디렉터리에 있는

9. print('File Name: %s \tFile Size: %d' %(file2, file_size2)) stockcode.txt의 파일크기를 리턴

6번째 줄 : getsize(file2)는 getsize( )의 인자로 절대경로를 입력하여

해당 파일의 크기를 얻음

8~9번째 줄 :결과를 화면에 출력

결과
File Name: stockcode.txt File Size: 16339
File Name: d:/devlab/py200/img_sample.jpg File Size: 170005
147 파일 삭제하기(os.remove)
1. from os import remove 존재하는 파일을 삭제하려면 os 모듈의 remove( )를 이용

삭제하려고 하는 파일의 상대경로나 절대경로를 인자로 입력받음


2. target _file = 'stockcode_copy.txt'
3. k = input('[%s] 파일을 삭제하겠습니까? (y/n)' %target_file)
1번째 줄 : os 모듈의 remove( )를 임포트
4. if k == 'y':
3번째 줄 : 삭제하려고 하는 파일을 지정
5. remove(target_file)
6. print('[%s]를 삭제했습니다.' %target_file) 5~7번째 줄 : 파일 삭제 여부를 사용자에게 한 번 더 확인하고

사용자가 ‘y’를 입력하면 remove( )로 대상 파일을 삭제


148 파일이름 바꾸기(os.rename)
1. from os import rename os 모듈이 rename( )은 파일이름을 변경.

rename( )은 이름을 변경하고자 하는 대상 파일의 상대경로 또는


2. target _file = 'stockcode.txt'
절대경로를 인자로 입력받음
3. newname = input('[%s]에 대한 새로운 파일이름을 입력하세요:
' %target_file)
4. rename(target_file, newname) 1번째 줄 : os 모듈의 rename( )을 임포트
5. print('[%s] -> [%s] 로 파일이름이 변경되었습니 3번째 줄 : 이름을 변경하고자 하는 대상 파일을 지정
다.' %(target_file, newname))
4번째 줄 : input( )을 이용해 사용자로부터 새로운 파일이름을 입력

받음

5~6번째 줄 : rename( )으로 대상 파일의 이름을 변경

이미 존재하는 파일이름으로 변경하려고 할 경우

FileExistsError가 발생

FileExistsError: [WinError 183] 파일이 이미 있으므로 만들 수 없습니다


149 파일을 다른 디렉터리로 이동하기(os.rename)
1. from os import rename 1번째 줄 : os 모듈의 rename( )을 임포트
2. 3번째 줄 : 이동할 대상 파일을 지정
3. target _file = 'stockcode.txt'
4번째 줄 : 사용자로부터 이동할 디렉터리의 절대경로를 입력받고
4. newpath = input('[%s]를 이동할 디렉터리의 절대경로를 입력하
세요: ' %target_file) newpath로 둠

5. 6~9번째 줄 : 사용자로부터 입력받은 절대경로의 뒤에 대상


6. if newpath[-1] == '/': 파일이름을 추가
7. newname = newpath + target_file
11~15번째 줄 : try~except 구문을 활용
8. else:
[stockcode.txt]를 이동할 디렉터리의 절대경로를 입력하세요:
9. newname = newpath + '/' + target_file d:/devlab/py200
[stockcode.txt] -> [d:/devlab/py200/stockcode.txt]로 이동되었습니다.
10.
rename( )에서 FileNotFoundError가 발생할 경우
11. try:
[stockcode.txt]를 이동할 디렉터리의 절대경로를 입력하세요: d:/data
12. rename(target_file, newname)
[WinError 3] 지정된 경로를 찾을 수 없습니다: 'stockcode.txt' ->
13. print('[%s] -> [%s]로 이동되었습니다.' %(target_file, 'd:/data/stockcode.txt'
newname))
14. except FileNotFoundError as e:
15. print(e)
150 디렉터리에 있는 파일목록 얻기(os.listdir, glob.glob)
1. import os, glob - os 모듈의 listdir( )은 인자로 입력된 경로에 존재하는 모든 파일과
2. 디렉터리를 리스트로 리턴
3. folder = 'd:/devlab/py200'
- glob 모듈의 glob( )은 인자로 입력된 조건이나 경로에 해당하는
4. file _list = os.listdir(folder)
파일들을 리스트로 리턴
5. print(file_list)
6.

7. files = '*.txt' 1~2번째 줄 : os 모듈과 glob 모듈을 임포트

8. file_list = glob.glob(files) 4~6번째 줄 : 대상 디렉터리를 변수 folder로 정의

9. print(file_list) ['137.py', '138.py', '146.py', '147.py', '148.py', '149.py', '150.py', 'data',


'img_sample.jpg',
'stockcode.txt', 'stockcode2.txt']

8~10번째 줄 : 확장자가 .txt인 텍스트 파일 목록만 얻기 위해 와일드

카드 *를 이용해 ‘*.txt’를 files로 둠

glob(files)는 현재 디렉터리에서 확장자가 .txt인 파일

목록을 리스트로 리턴

['stockcode.txt', 'stockcode2.txt']
151 현재 디렉터리 확인하고 바꾸기(os.getcwd, os.chdir)
1. import os 1번째 줄 : os 모듈을 임포트
2. 3번째 줄 : os.getcwd( )로 현재 디렉터리를 얻고 이를 pdir로 두고
3. pdir = os.getcwd( ); print(pdir)
화면에 경로를 출력
4. os.chdir('..'); print(os.getcwd( ))
4번째 줄 : os.chdir('..')은 현재 작업 디렉터리의 부모 디렉터리로
5. os.chdir(pdir); print(os.getcwd( ))
이동

5번째 줄 : os.chdir(pdir)로 다시 이전 작업 디렉터리로 현재 작업

디렉터리를 변경

결과

D:\devlab\py200
D:\devlab
D:\devlab\py200
152 디렉터리 생성하기(os.mkdir)
1. import os 1번째 줄 : os 모듈을 임포트
2. 2번째 줄 : 사용자로부터 생성할 디렉터리 이름을 입력받음
3. newfolder = input('새로 생성할 디렉터리 이름을 입력하세요: ')
4~8번째 줄 : 사용자가 입력한 디렉터리가 이미 존재하거나
4. try:
경로 이름이 잘못된 경우에는 ok.mkdir( )이 오류를
5. os.mkdir(newfolder)
발생하므로 오류 내용을 출력
6. print('[%s] 디렉터리를 새로 생성했습니다.' %newfolder)
7. except Exception as e: 유효한 디렉터리 이름을 입력하면 디렉터리를 생성

8. print(e) 하고 메시지를 출력
153 디렉터리 제거하기(os.rmdir)
1. import os 1번째 줄 : os 모듈을 임포트
2. 3~4번째 줄 : 삭제할 디렉터리 이름을 지정하고 사용자에게 삭제할
3. target _folder = 'tmp' 것인지 확인

4. k = input('[%s] 디렉터리를 삭제하겠습니까? 5~10번째 줄 : 사용자가 ‘y’를 입력하면 지정된 디렉터리를


(y/n)' %target_folder) os.rmdir( )을 이용해 삭제

5. if k == 'y':
6. try: 만약 디렉터리가 존재하지 않거나 디렉터리가 비어있지 않는
7. os.rmdir(target_folder)
오류가 발생하면 try~except를 이용해 오류 내용을 출력하고
8. print('[%s] 디렉터리를 삭제했습니다.' %target_folder)
프로그램을 정상 종료함
9. except Exception as e:
10. print(e)
154 하위 디렉터리 및 파일 전체 삭제하기(shutil.rmtree)
1. import shutil shutil 모듈의 rmtree( ) : 인자로 입력된 경로에 해당하는 디렉터리
2. import os 와 하위 디렉터리 및 모든 파일들을 일괄적으로 삭제
3.

4. target _folder = 'd:/devlab/py200/tmp'


1~2번째 줄 : shutil 모듈과 os 모듈을 임포트
5. print('[%s] 하위 모든 디렉터리 및 파일들을 삭제합니
다.' %target_folder) 4~8번째 줄 : 삭제할 디렉터리를 지정하고 삭제할 디렉터리에 있는
6. for file in os.listdir(target_folder): 파일 리스트를 출력한 후 사용자에게 삭제할 것인지 확인
7. print(file)
9~14번째 줄 : 사용자가 ‘y’를 입력하면 지정된 디렉터리와
8. k = input('[%s]를 삭제하겠습니까? (y/n) ' %target_folder)
하위 디렉터리 및 모든 파일들을 삭제
9. if k == 'y':
오류가 발생하면 오류 내용을 출력하고 프로그램을
10. try:
정상 종료
11. shutil.rmtree(target_folder)
12. print('[%s]의 모든 하위 디렉터리와 파일들을 삭제했습
니다.' %target_folder)
13. except Exception as e:
14. print(e)
155 파일이 존재하는지 체크하기(os.path.exists)
1. import os os.path 모듈의 exists( )는 인자에 해당하는 파일이나 디렉터리가 존
재하면 True를 존재하지 않으면 False를 리턴
2. from os.path import exists
3.

4. dir _name = input('새로 생성할 디렉터리 이름을 입력하세요: ') 1~2번째 줄 : os 모듈과 os.path 모듈의 exists( )를 임포트

5. if not exists(dir_name): 4번째 줄 : 사용자로부터 생성할 디렉터리 이름을 입력받음


6. os.mkdir(dir_name) 5~9번째 줄 : 사용자로부터 입력받은 디렉터리 이름이 존재하지
7. print('[%s] 디렉터리를 생성했습니다.' %dir _name)
않으면 디렉터리를 생성. 디렉터리 이름이 존재하면
8. else:
메시지를 출력하고 종료
9. print('[%s]은(는) 이미 존재합니다.' %dir _name)
156 파일인지 디렉터리인지 확인하기(os.path.isfile, os.path.isdir)
1. import os - os.path 모듈의 isfile( )은 인자로 입력된 경로가 파일이면 True,
2. from os.path import exists, isdir, isfile 파일이 아니면 False를 리턴
3.
- os.path 모듈의 isdir( )은 인자로 입력된 경로가 디렉터리면 True,
4. files = os.listdir( )
디렉터리가 아니면 False를 리턴
5. for file in files:
6. if isdir(file):
7. print('DIR: %s' %file) 1~2번째 줄 : os 모듈과 os.path 모듈의 exists( ), isdir( ), isfile( )을 임
포트
8.
4번째 줄 : 현재 디렉터리의 파일 목록을 files로 둠
9. for file in files:
5~7번째 줄 : 현재 디렉터리의 파일 목록 중 디렉터리만 화면에 출력
10. if isfile(file):
11. print('FILE: %s' %file) 9~11번째 줄 : 현재 디렉터리의 파일 목록 중 파일만 화면에 출력
157 현재 시간을 년-월-일 시:분:초로 출력하기(localtime, strftime)
1. from time import localtime, strftime 1번째 줄 : time 모듈의 localtime( )과 strftime( )을 임포트
2. 3번째 줄 : logfile을 ‘test.log’로 설정
3. logfile = 'test.log'
4번째 줄 : logfile에 타임스탬프를 추가하여 log를 로깅
4. def writelog(logfile, log):
5~6번째 줄 : strftime(‘%Y-%m-%d %X\t’, localtime( ))의 결과를
5. time_stamp = strftime('%Y-%m-%d %X\t', localtime( ))
time_stamp에 지정 log 앞부분에 time_stamp를 추가하고 줄바꿈
6. log = time_stamp + log + '\n'
7.
기호를 끝에 추가하여 log에 재지정

8. with open(logfile, 'a') as f: 8~9번째 줄 : test.log 파일을 텍스트 추가 모드로 열고 log를 파일의

9. f.writelines(log) 마지막에 추가
10. 11번째 줄 : writelog( )를 이용하여 문자열을 로그파일에 로깅
11. writelog(logfile, '첫 번째 로깅 문장입니다.')
생성된 test.log 파일을 텍스트 에디터로 열기

2017-09-27 23:20:32 첫 번째 로깅 문장입니다.


158 올해 경과된 날짜수 계산하기(localtime)
1. from time import localtime 1번째 줄 : time 모듈의 localtime( )을 임포트
2. 3번째 줄 : 현재 시간을 localtime( )으로 구하고 이 값을 변수 t로 둠
3. t = localtime( )
4번째 줄 : 해당 년도 1월 1일을 표시하기 위해 문자열 생성
4. start _day = '%d-01-01' %t.tm_year
5번째 줄 : t.tm_yday는 해당 년도의 1월 1일부터 현재 날짜까지
5. elapsed_day = t.tm_yday
경과된 날짜수
6.

7. print('오늘은 [%s]이후 [%d]일째 되는 날입니다.' %(start_day,


elapsed _day))
결과

오늘은 [2017-01-01]이후 [56]일째 되는 날입니다.


159 오늘의 요일 계산하기(localtime)
1. from time import localtime 1번째 줄: time 모듈의 localtime( )을 임포트
2. 3번째 줄 : weekdays를 ‘월요일’~‘일요일’까지 문자열을 요소로 하
3. weekdays = ['월요일', '화요일', '수요일', '목요일', '금요일', '토요
는 리스트로 정의
일', '일요일']
4. 5~6번째 줄 : localtime( )으로 현재 시간을 struct_time 형식으로

5. t = localtime( ) 구하고 이를 t에 대입
6. today = '%d-%d-%d' %(t.tm_year, t.tm _mon, t.tm _mday) 오늘 날짜를 t.tm_year, t.tm_mon, t.tm_mday 값을
7. week = weekdays[t.tm_wday]
이용해 문자열로 구성
8.
7번째 줄 : t.tm_wday가 weekdays의 인덱스로 입력
9. print('[%s] 오늘은 [%s]입니다.' %(today, week))

결과

[2017-2-15] 오늘은 [수요일]입니다.


160 프로그램 실행 시간 계산하기(datetime.now)
1. from datetime import datetime datetime 객체는 date 객체와 time 객체의 기능들을 모두 제공
2. datetime 객체의 now( )는 현재 시간을 1/1000000초 단위까지 계산
3. start = datetime.now( )
4. print('1에서 백만까지 더합니다.')
1번째 줄 : datetime 모듈의 datetime 객체를 임포트
5. ret = 0
3번째 줄 : 코드의 시작부분에 datetime.now( )를 호출
6. for i in range(1000000):
7. ret += i 5번째 줄 : ret은 1부터 백만까지 더한 결과를 담을 변수

8. print('1에서 백만까지 더한 결과: %d' %ret) 6~7번째 줄 : 1에서 백만까지 더하는 루틴을 for 구문을 이용해 구현

9. end = datetime.now( ) 8번째 줄 : 1에서 백만까지 더한 결과를 화면에 출력


10. elapsed = end – start 9번째 줄 : 코드의 끝부분에 datetime.now( )를 호출
11. print('총 계산 시간: ', end='');print(elapsed)
10번째 줄 : end – start를 elapsed로 둠
12. elapsed_ms = int(elapsed.total_seconds( )*1000)
11번째 줄 : 이 값을 화면에 출력
13. print('총 계산 시간: %dms' %elapsed_ms)
12~13번째 줄 : 값에 1000을 곱하고 정수 부분만 추출

1에서 백만까지 더합니다.


1에서 백만까지 더한 결과: 499999500000
총 계산 시간: 0:00:00.219141
총 계산 시간: 219ms
161 주어진 숫자를 천 단위로 구분하기
1. num = input('아무 숫자를 입력하세요: ') 1번째 줄 : 사용자로부터 숫자를 입력받아 변수 num으로 둠
2. 3번째 줄 : 입력한 문자열이 숫자로만 구성되어 있는지 확인
3. if num.isdigit( ):
4~5번째 줄 : 숫자로만 구성된 문자열이면 사용자가 입력한 숫자를
4. num = num[::-1]
거꾸로 배열하여 변수 num에 재지정
5. ret = ''
6~9번째 줄 : num에서 인덱스i와 요소를 하나씩 추출 → 인덱스 i에
6. for i, c in enumerate(num):
7. i += 1 1을 더함

8. if i != len(num) and i%3 == 0: 10~11번째 줄 : 추출한 요소가 마지막에 위치하거나 3의 배수가

9. ret += (c + ',') 아니면 추출한 요소를 ret에 추가


10. else: 12~13번째 줄 : ret을 거꾸로 배열하고 화면에 출력
11. ret += c
14~15번째 줄 : 사용자가 입력한 문자열이 숫자로만 이루어져
12. ret = ret[::-1]
있지 않으면 입력한 내용이 숫자가 아니라는
13. print(ret)
메시지를 출력
14. else:
15. print('입력한 내용 [%s]: 숫자가 아닙니다.' %num)
162 문자열의 각 문자를 그 다음 문자로 변경하기
1. text = input('문장을 입력하세요: ') 1번째 줄 : 사용자로부터 임의의 문자열을 입력받고 text로 둠
2. 3번쨰 줄 : 결과는 ret에 담을 예정
3. ret = ''
4~8번째 줄 : text의 각 문자의 인덱스 i에 대해 i가 text의 맨 마지막
4. for i in range(len(text)):
문자의 인덱스가 아니면 ret에 text[i+1]을 추가
5. if i != len(text)-1:
마지막 문자의 인덱스라면 ret에 text[0]을 추가
6. ret += text[i+1]
7. else: 10번째 줄 : ret을 화면에 출력

8. ret += text[0]
9. 결과 (‘안녕하세요. 내 이름은 홍길동입니다.’를 입력)
10. print(ret)
녕하세요. 내 이름은 홍길동입니다.안
163 URL에서 호스트 도메인 추출하기
1. url = 1번째 줄 : 인터넷 주소창에 입력하는 형식의 URL을 url로 둠
'http://news.naver.com/main/read.nhn?mode=LSD&mid=sh
m&sid1= 4번째 줄 : url.split( )으로 url을 ‘/’로 구분한 결과를 tmp로 둠

2. 105&oid=028&aid=0002334601' tmp는 url을 ‘/’로 구분한 문자열이 요소인 리스트


3. 5~6번째 줄 : url을 ‘/’로 구분하면 3번째 위치(인덱스는 2)하는
4. tmp = url.split('/')
요소가 추출할 호스트 도메인
5. domain = tmp[2]
6. print(domain)
결과
news.naver.com
164 URL에서 쿼리 문자열 추출하기
1. url = 쿼리 문자열 : URL에서 ‘?’ 뒤에 표시되는 문자열
'http://news.naver.com/main/read.nhn?mode=LSD&mid=sh
m&sid1= 변수=값 쌍이 &로 구분되어 나열됨

2. 105&oid=028&aid=0002334601'
3. 1번째 줄 : 인터넷 주소창에 입력하는 형식의 URL을 url로 둠
4. tmp = url.split('?')
4번째 줄 : url.split( )으로 url을 ‘?’로 구분한 결과를 tmp로 둠
5. queries = tmp[1].split('&')
5번째 줄 : tmp[1]은 url의 ‘?’ 다음의 문자열
6. for query in queries:
tmp[1]을 ‘&’로 구분한 결과를 queries로 둠
7. print(query)
6~7번째 줄 : queries의 모든 요소를 화면에 출력

결과
mode=LSD
mid=shm
sid1=105
oid=028
aid=0002334601
165 스택 구현하기(append, pop)
1. mystack = [ ]
스택(stack) : 나중에 저장된 자료가 먼저 추출될 수 있도록 되어 있
2.
는 나열 구조
3. def putdata(data):

4. global mystack

5. mystack.append(data)
1번째 줄 : 빈 리스트를 mystack으로 둠
6.

7. def popdata( ): 3~5번째 줄 : mystack에 data를 저장하는 함수를 putdata(data)로


8. global mystack

9. if len(mystack) == 0: 구현. global 키워드로전역변수 mystack 사용을 명시


10. return None
7~11번째 줄 : mystack으로부터 데이터를 하나 추출하는 함수를
11. return mystack.pop( )

12.
popdata( )로 구현
13. putdata('데이터1')

14. putdata([3, 4, 5, 6]) 13~15번째 줄 : putdata( )를 호출하여 mystack에 ‘데이터1’,


15. putdata(12345)
[3, 4, 5, 6], 12345를 차례로 저장
16.

17. print('<스택상태>: ', end=''); print(mystack) 19~23번째 줄 : popdata( )를 호출. while문을 이용해 ret이 None일
18.

19. ret = popdata( ) 때까지 popdata( )를 호출하여 mystack으로부터


20. while ret != None:
데이터를 추출, 화면에 추출한 데이터를 출력하고
21. print('스택에서 데이터 추출:', end=''); print(ret)

22. print('<스택상태>: ', end=''); print(mystack) mystack의 상태도 출력


23. ret = popdata( )
166 문장에 나타나는 문자 빈도수 계산하기
1. def getTextFreq(filename): 1번째 줄 : 파일이름을 인자로 받아 각 문자들이 나타나는 빈도수를
2. with open(filename, 'r') as f:
문자별로 계산하여 그 결과를 사전으로 리턴
3. text = f.read( )
2~3번째 줄 : filename을 텍스트 읽기 모드로 엶
4. fa = { }
5. for c in text: 4번째 줄 : 빈 사전을 fa로 둠

6. if c in fa: 5~7번째 줄 : text의 모든 문자에 대해 문자를 하나씩 추출 →


7. fa[c] += 1 문자가 fa의 키로 존재하면 해당 값을 1 증가
8. else:
8~9번째 줄 : 추출한 문자가 새로운 요소 c:1을 fa의 요소로 추가
9. fa[c] = 1
12번째 줄 : ‘mydata.txt’ 파일을 인자로 getTextFreq( )를 호출한
10. return fa
11. 결과를 ret으로 둠

12. ret = getTextFreq('mydata.txt') 13번째 줄 : ret을 내림차순으로 정렬하여 ret에 재지정


13. ret = sorted(ret.items( ), key=lambda x:x[1], reverse=True)
14~17번째 줄 : 문자, 빈도수를 ret으로부터 하나씩 추출하여
14. for c, freq in ret:
화면에 출력
15. if c == '\n':
16. continue
17. print('[%c] -> [%d]회 나타남' %(c, freq))
167 텍스트 파일에 있는 단어 개수 계산하기
1. with open('mydata.txt', 'r') as f: 1번째 줄 : ‘mydata.txt’를 텍스트 읽기 모드로 오픈
2. data = f.read( ) 2~3번째 줄 : 파일의 내용을 모두 읽어 data로 두고
3. tmp = data.split( )
data를 공백으로 분리한 결과를 tmp로 둠
4. print('단어수: [%d]' %len(tmp))
4번째 줄 : 리스트 자료의 크기 = 요소의 개수

→ 구하고자 하는 단어 개수 = tmp의 크기

결과
단어수: [213]
168 파일에서 특정 단어 개수 계산하기
1. def countWord(filename, word): 2~4번째 줄 : 파일을 텍스트 읽기 모드로 열고 내용을 읽어 text로
2. with open(filename, 'r') as f: 두고 text를 모두 소문자로 변환
3. text = f.read( )
5번째 줄 : text.find(word)로 text에서 word가 최초로 나타나는
4. text = text.lower( )
위치를 구하여 pos에 대입
5. pos = text.find(word)
6~10번째 줄 : while 문의 조건을 만족하면 count를 1 증가
6. count = 0
7. while pos != -1: text.find(word, pos+1)로 찾은 word의 위치 다음부터

8. count += 1 다시 word를 text에서 찾음

9. pos = text.find(word, pos+1) while 구문을 벗어나면 count를 리턴


10. return count 12번째 줄 : ‘mydata.txt’에서 개수를 구할 단어를 입력받고 word로
11. 둠

12. word = input('mydata.txt에서 개수를 구할 단어를 입력하세요: ') 13번째 줄 : word를 소문자로 변환
13. word = word.lower( ) 14~15번째 줄 : countWord( )를 호출하고 결과를 화면에 출력
14. ret = countWord('mydata.txt', word)
[how]의 개수: 2
15. print('[%s]의 개수: %d' %(word, ret))
169 파일에서 특정 문자열 교체하기
1. t1 = input('찾을 단어를 입력하세요: ') 1~2번째 줄 : ‘mydata.txt’ 파일에서 찾아서 변경할 단어를 각각
2. t2 = input('변경할 단어를 입력하세요: ') 입력받아 t1, t2로둠
3.
4~5번째 줄 : ‘mydata.txt’를 텍스트 읽기 모드, ‘mydata2.txt’를
4. with open('mydata.txt', 'r') as f:
쓰기 모드로 오픈, 각각 파일 핸들을 f, h로 둠
5. with open('mydata2.txt', 'w') as h:
6~8번째 줄 : ‘mydata.txt’ 파일의 내용을 모두 읽어 text로 두고,
6. text = f.read( )
7. text = text.replace(t1, t2) text.replace(t1, t2)로 text에 등장하는 t1을 t2로 모두

8. h.write(text) 변경 → text를 ‘mydata2.txt’에 저장

9.

10. print('[%s]를 [%s]로 변경하였습니다.' %(t1, t2))


170 URL에 접속하여 HTML 페이지 화면에 출력하기
1. from urllib.request import urlopen 1번째 줄 : urllib.request 모듈의 urlopen( )을 임포트
2. 2번째 줄 : URL을 url변수에 정의
3. url = 'https://www.python.org'
4번째 줄 : urlopen(url)로 url에 접속하여 오픈하고 그 핸들을 f로 둠
4. with urlopen(url) as f:
5번째 줄 : f.read( )는 url로부터 해당 리소스 데이터를 바이트
5. doc = f.read( ).decode( )
스트림으로 읽어옴
6. print(doc)
f.read( ).decode( )로 바이트 스트림을 텍스트로 변환

결과
<!doctype html>
<!--[if lt IE 7]> <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7 lt-ie8 lt-ie9"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 lt-ie9"> <![endif]-->
<!--[if gt IE 8]> <!--><html class="no-js" lang="en" dir="ltr"> <!--<![endif]--
>
(생략)
<script type="text/javascript" src="/static/js/plugins/getComputedStyle-
min.js"
charset="utf-8"></script>
<![endif]-->
</body>
</html>
171 URL에 접속하여 HTML 페이지를 파일로 저장하기
1. from urllib.request import urlopen 1번째 줄 : urllib.request 모듈의 urlopen( )을 임포트
2. 3번째 줄 : 파이썬 공식 홈페이지 URL을 url 변수에 정의
3. url = 'https://www.python.org/'
4번째 줄 : urlopen(url)로 오픈하고 핸들을 f로 둠
4. with urlopen(url) as f:
5번째 줄 : f.read( )는 url로부터 해당 리소스 데이터를 바이트
5. doc = f.read( ).decode( )
스트림으로 읽어옴. f.read( ).decode( )로 바이트 스트림을
6. with open('pythonhome.html', 'w') as h:
7. h.writelines(doc) 텍스트로 변환하고 doc으로 둠

6~7번째 줄 : ‘pythonhom.html’을 텍스트 쓰기 모드로 오픈하고

write(doc)으로 doc을 파일에 저장

‘pythonhome.html’을 바이너리 쓰기 모드로 오프닝하여

바이트 스트림을 저장하는 방법(5~6라인)

doc = f.read( )
with open('pythonhome.html', 'wb') as h:
h.write(doc)
172 인터넷에 있는 이미지를 내 PC로 저장하기
1. from urllib.request import urlopen 1번째 줄 : urllib.request 모듈의 urlopen( )을 임포트
2. 3번째 줄 : 이미지 파일의 URL을 imgurl로 둠
3. imgurl = 'http://www.epaiai.com/img_sample.jpg'
4번째 줄 : 이미지 이름을 imgurl로부터 분리하고 imgname으로 둠
4. imgname = imgurl.split('/')[-1]
5번째 줄 : URL이 잘못된 경우 프로그램이 비정상적으로 종료되지
5. try:
않도록 try~except로 감싸줌
6. with urlopen(imgurl) as f:
7. with open(imgname, 'wb') as h: 6~9번째 줄 : imgurl을 오픈하고 imgname을 바이너리 쓰기 모드로

8. img = f.read( ) 오픈하여 각 핸들을 f, h로 둠

9. h.write(img) f.read( )로 이미지 파일을 imgname으로 지정된 파일


10. except Exception as e: 에 저장
11. print(e)
10~11번째 줄 : 6~9라인에서 오류가 발생하면 오류를 화면에 출력

하고 프로그램을 정상 종료
173 인터넷에 있는 대용량 파일을 내 PC로 저장하기
1. from urllib.request import urlopen 1번째 줄 : urllib.request 모듈의 urlopen( )을 임포트
2. 3번째 줄 : BUFSIZE를 256KB로 설정
3. BUFSIZE = 256*1024
5번째 줄 : URL을 fileurl로 지정
4.
6번째 줄 : fileurl에서 파일이름 부분만 추출하여 filename으로 둠
5. fileurl = 'https://www.python.org/ftp/python/3.5.2/python-
3.5.2.exe' 8~9번째 줄 : fileurl을 오픈, filename을 바이너리 쓰기 모드로 오픈
6. filename = fileurl.split('/')[-1] 각 파일 핸들을 f, h로 둠
7. try:
10~13번째 줄 : fileurl을 BUFSIZE만큼 읽어 buf로 지정하고
8. with urlopen(fileurl) as f:
while문으로 진입. filename에 buf로 지정된 데이터
9. with open(filename, 'wb') as h:
저장, fileurl에서 다시 BUFSIZE만큼 읽고 buf로 두는
10. buf = f.read(BUFSIZE)
반복 수행. while 구문을 벗어나면 fileurl의 모든
11. while buf:
12. h.write(buf) 데이터가 로컬 파일로 저장

13. buf = f.read(BUFSIZE) 14~15번째 줄 : 8~13라인에서 오류가 발생하면 오류 내용을


14. except Exception as e: 화면에 출력하고 프로그램을 종료
15. print(e)
174 10MB 파일을 1MB 파일 10개로 분리하기
1. filename = 'python-3.5.2.exe' 1번째 줄 : 작은 파일로 분리하려는 파일을 지정
2. subsize = 1024*1024*3 # 3MB 2번째 줄 : 서브파일의 크기를 3MB로 설정하고 subsize로 둠
3. suffix = 0
3번째 줄 : suffix는 파일이름 뒤에 추가할 숫자를 나타냄
4.
5~11번째 줄 : 원본 파일을 바이너리 읽기 모드로 오픈하고
5. with open(filename, 'rb') as f:
subsize만큼 읽은 데이터를 buf로 두고 while문으로
6. buf = f.read(subsize)
7. while buf: 진입. 저장할 서브파일 이름을 생성하고 이 파일을

8. subfilename = filename + '_' + str(suffix) 바이너리 쓰기 모드로 오픈한 후 buf를 파일에 저장

9. with open(subfilename, 'wb') as h: 13~14번째 줄 : 원본 파일에서 다시 subsize만큼 읽어 buf에


10. h.write(buf) 저장하고 suffix를 1 증가하는 반복을 실행
11. print('[%s] 완료' %subfilename)
12.

13. buf = f.read(subsize)


14. suffix += 1
175 1MB 파일 10개를 합쳐서 10MB 파일로 만들기
1. BUFSIZE = 256*1024 1번째 줄 : 버퍼사이즈를 256KB로 설정하고 BUFSIZE로 둠
2. merge_filename = 'ret.exe' 2번째 줄 : 합친 결과 파일의 이름을 ret.exe로 설정하고
3. filelist = ['python-3.5.2.exe_' + str(x) for x in range(10)]
merge_filename으로 둠
4.
3번째 줄 : 서브파일 이름을 리스트로 구성
5. with open(merge_filename, 'wb') as f:
['python-3.5.2.exe_0', 'python-3.5.2.exe _1', … , 'python-3.5.2.exe _9']
6. for filename in filelist:
7. print('[%s] 합치는 중..' %filename) 5번째 줄 : merge_filename을 바이너리 쓰기 모드로 오픈

8. with open(filename, 'rb') as h: 6~12번째 줄 : filelist에 있는 모든 서브파일 이름에 대해 순서대로

9. buf = h.read(BUFSIZE) 바이너리 읽기 모드로 오픈


10. while buf: 서브파일을 BUFSIZE만큼 읽어 buf에 대입하고 while
11. f.write(buf)
문으로 진입. buf를 지정한 파일에 저장하고 다시
12. buf = h.read(BUFSIZE)
BUFSIZE만큼 읽는 것을 반복
13.
while 구문 반복 종료, for 구문이 모두 마무리되면
14. print('파일 합치기가 완료되었습니다.')
모든 서브파일의 내용을 merge_filename에 저장
176 파일을 ZIP 압축 파일로 만들기
1. from zipfile import * 1번째 줄 : zipfile 모듈의 모든 것을 임포트
2. 3번째 줄 : filename으로 지정된 파일을 ZIP으로 압축하여 zipname
3. def compressZip(zipname, filename):
으로 지정된 파일로 저장
4. print('[%s] -> [%s] 압축...' %(filename, zipname))
5번째 줄 : ZipFile 객체를 생성하고 이에 대한 핸들을 ziph로 둠
5. with ZipFile(zipname, 'w') as ziph:
6번째 줄 : ZIP 파일에 filename의 데이터를 ZIP으로 압축하여 기록
6. ziph.write(filename)
7.
10~12번째 줄 : 압축할 파일을 filename으로 두고 ZIP 파일이름을

8. print('압축이 끝났습니다.') zipname으로 둠. compressZip(zipname,filename)

9. 을 호출하여 ZIP 파일을 생성


10. filename = 'mydata.txt'
11. zipname = filename + '.zip'
12. compressZip(zipname, filename)
177 디렉터리를 하나의 ZIP 압축파일로 만들기
1. from zipfile import * 1~2번째 줄 : zipfile 모듈의 모든 것과 os 모듈을 임포트
2. import os 4번째 줄 : folder로 지정된 디렉터리에 포함된 모든 하위 디렉터리
3.
및 파일들을 ZIP으로 압축하여 zipname 파일에 저장
4. def compressAll(zipname, folder):
6번째 줄 : ZipFile 객체를 쓰기 모드로 생성
5. print('[%s] -> [%s] 압축...' %( folder, zipname))
7번째 줄 : os.walk(folder)는 folder의 모든 하위 디렉터리 및
6. with ZipFile(zipname, 'w') as ziph:
7. for dirname, subdirs, files in os.walk(folder): 파일들을 탐색하여 위에서 설명한 리스트로 리턴

8. for file in files: 8~9번째 줄 : os.path.join(dirname, file)은 dirname과 file을 합쳐

9. ziph.write(os.path.join(dirname, file)) tmp 기준으로 file의 상대경로를 구성.


10. 경로가 구성된 파일명을 이용해 해당 파일을 압축하여
11. folder = 'tmp'
ZIP 파일에 기록
12. zipname = folder + '.zip'
13. compressAll(zipname, folder)
178 ZIP 파일 압축 풀기
1. from zipfile import * 1번째 줄 : zipfile 모듈의 모든 것을 임포트
2. 3번째 줄 : zipname으로 지정된 ZIP 파일의 모든 내용을 압축 해제
3. def extractZip(zipname):
4번째 줄 : ZipFile 객체를 읽기 모드로 생성. 객체의 핸들을 ziph로 둠
4. with ZipFile(zipname, 'r') as ziph:
5번째 줄 : ZIP 파일의 모든 내용을 압축 해제
5. ziph.extractall( )
6. print('[%s]가 성공적으로 추출되었습니다.' %zipname)
7.

8. extractZip('files.zip')
179 로또 번호 추출기 만들기
1. from random import shuffle 1~2번째 줄 : random 모듈의shuffle( )과time 모듈의sleep( )을임포트
2. from time import sleep 4번째 줄 : 사용자로부터 로또 게임수를 입력받고 gamenum에 지정
3.
6번째 줄 : 입력한 게임 횟수만큼 for 구문을 반복
4. gamenum = input('로또 게임 횟수를 입력하세요: ')
7~8번째 줄 : balls는 1에서 45까지 정수를요소로하는 리스트로정의
5.
9번째 줄 : 6번 반복하여 숫자를 추출
6. for i in range(int(gamenum)):
7. balls = [x+1 for x in range(45)] 10~12번째 줄 : shuffle( )로 balls를 무작위로 섞고 pop( )으로

8. ret = [ ] balls의 제일 마지막 숫자를 추출, 추출된 숫자를

9. for j in range(6): 제거. 추출된 숫자는 ret에 추가


10. shuffle(balls) 13~16번째 줄 : ret.sort( )로 ret을 오름차순 정렬
11. number = balls.pop( )
ret을 화면에 출력하고 1초 후 다음 번호를 추출
12. ret.append(number)
13. ret.sort( )
결과(게임수3 입력)
14. print('로또번호[%d]: ' %(i+1), end='')
로또번호[1]: [2, 14, 23, 28, 30, 41]
15. print(ret)
로또번호[2]: [6, 9, 18, 31, 35, 39]
16. sleep(1) 로또번호[3]: [1, 3, 4, 13, 28, 31]
180 남녀 파트너 정해주기 프로그램 만들기(zip)
1. from random import shuffle zip( ) : 동일한 요소 개수를 가진 두 개 이상의 리스트를 인자로 받고,
2. 각 리스트의 같은 인덱스의 요소들끼리 묶은 튜플을 요소로 하는
3. male = ['슈퍼맨', '심봉사', '로미오', '이몽룡', '마루치']
리스트로 만들어 리턴
4. female = ['원더우먼', '뺑덕', '줄리엣', '성춘향', '아라치']
5. shuffle(male)
1번째 줄 : random 모듈의 shuffle( )을 임포트
6. shuffle(female)
7. couples = zip(male, female) 3~4번째 줄 : 남자 5명, 여자 5명의 이름을 요소로 하는

8. 리스트를 구성하고 각각 male, female로 둠

9. for i, couple in enumerate(couples): 5~6번째 줄 : male과 female을 shuffle( )을 이용해 무작위로 섞음


10. print('커플%d: [%s]-[%s]' %(i+1, couple[0], couple[1])) 7번째 줄 : male과 female의 동일한 인덱스의 요소끼리 묶고

그 결과를 couples로 둡니다.

9~10번째 줄 : 정해진 남녀 파트너 결과 출력

커플1: [로미오]-[원더우먼]
커플2: [심봉사]-[아라치]
커플3: [마루치]-[줄리엣]
커플4: [이몽룡]-[뺑덕]
커플5: [슈퍼맨]-[성춘향]
181 데이터 처리 ❶ 연도별 출생아 수 계산하기
1. def countBirths( ): 데이터 다운링크 https://catalog.data.gov/dataset/baby-names-
from-social-security-card-applications-national-level-data
2. ret = [ ]
3. for y in range(1880, 2015): 1번째 줄 : 연도별로 저장된 출생아 이름과 출생아 수 데이터 파일을
모두 읽고 연도별로 출생아 수만 더한 결과를 csv 파일로 저장하는
4. count = 0 함수
5. filename = 'names/yob%d.txt' %y 2번째 줄 : 튜플이 요소인 리스트로 구성될 변수
6. with open(filename, 'r') as f:
3~5번째 줄 : for문을 이용해 순차적으로 파일이름을 구성.
7. data = f.readlines( )
count는 연도별 출생아 수를 위한 변수
8. for d in data:
6~13번째 줄 : 연도별 데이터 파일을 텍스트 읽기 모드로 오픈하고
9. if d[-1] == '\n':
10. d = d[:-1] readlines( )로 모든 데이터를 읽어 data로 둠

11. data를 d에 지정. birth를 정수형으로 변환한 후 count

12. birth = d.split(',')[2] 에 더해줌


13. count += int(birth) 14번째 줄 : data의 모든 요소에 대해 9~13라인을 수행
14. ret.append((y, count))
15번째 줄 : 1880부터 2015까지 for 구문을 반복
15. return ret
countBirths( )는 ret을 리턴하고 마무리
181 데이터 처리 ❶ 연도별 출생아 수 계산하기
16. 17번째 줄 : countBirths( )의 호출 결과를 result로 둠
17. result = countBirths( ) 18~22번째 줄 : birth_by_year.csv라는 이름의 파일을 텍스트 쓰기
18. with open('birth_by_year.csv', 'w') as f:
모드로 오픈하고 result의 각 요소를 문자열로 구성
19. for year, birth in result:
birth_by_year.csv에 한 줄씩 기록
20. data = '%s,%s\n' %(year, birth)
21. print(data)
22. f.write(data)
182 데이터 처리 ❷ 연도별 성별 출생아 수 계산하기
1. def countBirthsBySex( ): 1번째 줄 : 연도별 데이터 파일을 모두 읽어 여자아기, 남자아기
2. ret = [ ]
출생아 수를 연도별로 따로 계산하고 그 결과를 리스트로
3. for y in range(1880, 2015):
4. count_f = 0 # 여자아기 출생아 수 만들어 리턴
5. count_m = 0 # 남자아기 출생아 수
2번째 줄 : 튜플이 요소인 리스트로 구성될 변수
6. filename = 'names/yob%d.txt' %y
7. with open(filename, 'r') as f: 3~6번째 줄 : for문을 이용해 순차적으로 파일이름을 구성
8. data = f.readlines( )
7~20번째 줄 : 14라인에서 d의 두 번째 데이터는 ‘F’ 또는 ‘M’으로
9. for d in data:
10. if d[-1] == '\n': 표시되는 성별이므로 이 값을 sex에 대입
11. d = d[:-1] sex의 값이 ‘F’이면 count_f에 birth의 정수형 값을
12.

13. tmp = d.split(',')


더하고 sex의 값이 ‘F’가 아니면 count_m에 birth의

14. sex = tmp[1] 정수형 값을 더함


15. birth = tmp[2]
16.

17. if sex == 'F':


18. count_f += int(birth)
19. else:
20. count_m += int(birth)
182 데이터 처리 ❷ 연도별 성별 출생아 수 계산하기
21. ret.append((y, count _f, count _m)) 21번째 줄 : 연도별 데이터 파일 하나에 대한 처리가 마무리
22. return ret ret에 (y, count_f, count_m)을 추가
23.
22번째 줄 : countBirthsBySex( )는 ret을 리턴
24. result = countBirthsBySex( )
24번째 줄 : countBirthsBySex( )의 호출 결과를 result로 둠
25. with open('birth_by_sex.csv', 'w') as f:
25~29번째 줄 : 파일을 텍스트 쓰기 모드로 오픈하고 result의
26. for y, bf, bm in result:
27. data = '%s,%s,%s\n' %(y, bf, bm) 각 요소를 문자열로 구성하고 birth_by_sex.csv에

28. print(data) 한 줄씩 기록

29. f.write(data)
183 데이터 처리 ❸ 연도별 인기있는 상위 10개 성별 출생아 이름 구하기
1. from os.path import exists
2.
3. def getTop10BabyName(year):
4. nameF = { }
5. nameM = { }
6.
7. filename = 'names/yob%s.txt' %year
8. if not exists(filename):
9. print('[%s] 파일이 존재하지 않습니다.' %filename)
10. return None
11.
12. with open(filename, 'r') as f:
13. data = f.readlines( )
14. for d in data:
15. if d[-1] == '\n':
16. d = d[:-1]
17.
18. tmp = d.split(',')
19. name = tmp[0]
20. sex = tmp[1]
21. birth = tmp[2]
22.
183 데이터 처리 ❸ 연도별 인기있는 상위 10개 성별 출생아 이름 구하기
23. if sex == 'F':
24. ret = nameF
25. else:
26. ret = nameM
27.
28. if name in ret:
29. ret[name] += int(birth)
30. else:
31. ret[name] = int(birth)
32.
33. retF = sorted(nameF.items( ), key=lambda x:x[1], reverse=True)
34. retM = sorted(nameM.items( ), key=lambda x:x[1], reverse=True)
35.
36. for i, name in enumerate(retF):
37. if i > 9:
38. break
39. print('TOP _%d 여자아기이름: %s' %(i+1, name))
40.
41. for i, name in enumerate(retM):
42. if i > 9:
43. break
44. print('TOP_%d 남자아기이름: %s' %(i+1, name))
45.
46. y = input('인기순 상위10개 이름을 알고 싶은 출생년도를 입력하세요(예:2001): ')
47. getTop10BabyName(y)
183 데이터 처리 ❸ 연도별 인기있는 상위 10개 성별 출생아 이름 구하기
1번째 줄 : os.path 모듈의 exists( )를 임포트

3번째 줄 : year에 해당하는 연도에 태어난 1위에서 10위까지 각 출생아 수와 함께 화면에 출력하는 코드

4~5번째 줄 : 각각 여자아기이름:출생아 수와 남자아기이름:출생아 수를 요소로 가지는 사전 자료

7~10번째 줄 : 함수 인자로 전달받은 year에 해당하는 데이터 파일이름을 구성. 해당 파일이 존재하는지 확인

19번째 줄 : d의 첫 번째 요소인 아기이름을 name에 대입

23~26번째 줄 : sex의 값이 ‘F’이면 사전 nameF를 ret으로 두고, sex의 값이 ‘F’가 아니면 사전 nameM을 ret으로 둠

28~31번째 줄 : name이 ret의 키로 존재하면 ret[name]의 값에 birth의 정수형 값을 더하고 존재하지 않으면 name:int(birth)를 추가

33~34번째 줄 : data의 모든 요소 d에 대한 처리가 끝나면 내림차순 정렬하고 그 결과를 각각 retF, retM으로 둠

46~47번째 줄 : 사용자로부터 연도를 입력받아 getTop10BabyName( )의 인자로 입력하고 호출

TOP_1 여자아기이름: ('Emma', 20355) TOP_1 남자아기이름: ('Noah', 19511)


TOP_2 여자아기이름: ('Olivia', 19553) TOP_2 남자아기이름: ('Liam', 18281)
TOP_3 여자아기이름: ('Sophia', 17327) TOP_3 남자아기이름: ('Mason', 16535)
TOP_4 여자아기이름: ('Ava', 16286) TOP_4 남자아기이름: ('Jacob', 15816)
TOP_5 여자아기이름: ('Isabella', 15504) TOP_5 남자아기이름: ('William', 15809)
TOP_6 여자아기이름: ('Mia', 14820) TOP_6 남자아기이름: ('Ethan', 14991)
TOP_7 여자아기이름: ('Abigail', 12311) TOP_7 남자아기이름: ('James', 14705)
TOP_8 여자아기이름: ('Emily', 11727) TOP_8 남자아기이름: ('Alexander', 14460)
TOP_9 여자아기이름: ('Charlotte', 11332) TOP_9 남자아기이름: ('Michael', 14321)
TOP_10 여자아기이름: ('Harper', 10241) TOP_10 남자아기이름: ('Benjamin', 13608)
184 웹서버 로그 처리 ❶ 총 페이지뷰 수 계산하기
1. pageviews = 0 아파치가 기록하는 접근로그 파일의 일반적 로그 형식
2. 127.0.0.1 웹서버로 요청한 클라이언트 IP

3. with open('access_log', 'r') as f: - 무시해도 됨

4. logs = f.readlines( ) - HTTP 인증에 따른 요청 사용자의 ID. 무시해도 됨

[01/Oct/2016 :13 :55 :36 웹서버가 응답한 시간. +0900은 협정 세계시(UTC) 기준 +9시
5. for log in logs: +0900] 간을 의미함
“GET /apache_pb.gif
6. log = log.split( ) HTTP/1.0”
클라이언트의 요청줄(Request Line)

7. status = log[8] 200 HTTP 상태코드

8. if status == '200': 2326 웹서버가 제공한 콘텐츠 크기(바이트)

9. pageviews += 1 1번째 줄 : 총 페이지 수를 담을 변수


10. 3번째 줄 : 텍스트 읽기 모드로 오픈하고 파일 핸들을 f로 둠
11. print('총 페이지뷰: [%d]' %pageviews)
4번째 줄 : f.readlines( )로 logs 변수에 지정

5~7번째 줄 : log.split( )으로 logs의 각 요소를 공백으로 분리한 결과

결과 리스트를 변수 log에 재지정. log[8]은 status로 둠

11번째 줄 : for 구문을 모두 반복하면 access_log에서 status가 200인


총 페이지뷰: [327]
라인수가 모두 계산됨
185 웹서버 로그 처리 ❷ 고유 방문자 수 계산하기
1. visit _ip = [ ] 1번째 줄 : 고유한 IP를 저장할 빈 리스트
2. 3~4번째 줄 : access_log를 텍스트 읽기 모드로 오픈하고
3. with open('access_log', 'r') as f:
readlines( )로 로그파일의 모든 내용을 리스트로 저장
4. logs = f.readlines( )
5~7번째 줄 : 각 log에 대해 log.split( )으로 공백을 분리한 리스트를
5. for log in logs:
log에 재지정. log[0]은 클라이언트 IP
6. log = log.split( )
7. ip = log[0] 8~9번째 줄 : visit_ip의 요소로 ip가 존재하지 않으면 visit_ip에 ip를

8. if ip not in visit_ip: 추가. for 구문을 모두 반복하면 visit_ip에 서로 다른 IP

9. visit _ip.append(ip) 가 요소인 리스트가 만들어짐


10.

11. print('고유 방문자 수: [%d]' %len(visit_ip))


결과
고유 방문자 수: [99]
186 웹서버 로그 처리 ❸ 총 서비스 용량 계산하기
1. KB = 1024 1번째 줄 : 서비스 용량 단위를 KB로 표시, 계산된 서비스 용량에
2. total _service = 0 이 값을 나누면 KB 단위가 됨
3.
2번째 줄 : 총 서비스 용량은 total_service에 저장
4. with open('access_log', 'r') as f:
4~5번째 줄 : access_log를 텍스트 읽기 모드로 오픈하고 로그파일의
5. logs = f.readlines( )
모든 내용을 라인 단위로 읽어 리스트로 저장
6. for log in logs:
7. log = log.split( ) 8~10번째 줄 : 공백으로 분리한 10번째 요소가 웹서버가 제공한

8. servicebyte = log[9] 콘텐츠 크기이므로 이 값을 servicebyte로 둠.

9. if servicebyte.isdigit( ): servicebyte가 숫자로 구성되었는지 확인하고


10. total _service += int(servicebyte) total_service에int(servicebyte)를 더함
11.
12~13번째 줄 : for 구문을 모두 반복하면 total_service에 웹서버가
12. total _service /= KB
제공한 총 서비스 용량이 저장.
13. print('총 서비스 용량: %dKB' %total_service)
값을 KB 단위로 변환하고 화면에 결과를 출력

총 서비스 용량: 29289KB


187 웹서버 로그 처리 ❹ 사용자별 서비스 용량 계산하기
1. services = { }
2.
3. with open('access_log', 'r') as f:
4. logs = f.readlines( )
5. for log in logs:
6. log = log.split( )
7. ip = log[0]
8. servicebyte = log[9]
9. if servicebyte.isdigit( ):
10. servicebyte = int(servicebyte)
11. else:
12. servicebyte = 0
13.
14. if ip not in services:
15. services[ip] = servicebyte
16. else:
17. services[ip] += servicebyte
18.
19. ret = sorted(services.items( ), key=lambda x: x[1], reverse=True)
20.
21. print('사용자IP – 서비스 용량')
22. for ip, b in ret:
23. print('[%s] – [%d]' %(ip, b))
187 웹서버 로그 처리 ❹ 사용자별 서비스 용량 계산하기
1번째 줄 : IP:서비스 용량이 요소로 저장될 사전

3~4번째 줄 : access_log를 텍스트 읽기 모드로 오픈하고 readlines( )로 로그파일의 모든 내용을 라인 단위로 읽어 리스트로 저장

5~8번째 줄 : 공백으로분리한첫번째요소와10번째요소는클라이언트IP와웹서버가제공한콘텐츠크기이며, 각각변수ip와servicebyte에지정

9~12번째 줄 : servicebyte가 숫자로 구성되었는지 확인하고 servicebyte를 정수형으로 변환한 후 변수 servicebyte에 재지정

14~17번째 줄 : ip가 사전 services의 키로 존재하지 않으면 services에 ip:servicebyte를 새로운 요소로 추가.

존재하면 해당 키에 대응하는 값에 servicebyte를 더함

19번째 줄 : for 구문을 모두 반복하면 services는 IP가 키, 해당 IP에 제공한 서비스 용량이 값인 사전으로 구성.

services를 서비스 용량 기준으로 내림차순 정렬하고 결과를 ret으로 둠

22~23번째 줄 : 정렬된 ret의 각 요소를 적절한 문자열로 구성하여 화면에 출력

사용자IP - 서비스 용량 [180.76.15.151] - [20436]


[223.62.67.5] - [26540048] …
[223.62.67.194] - [2062270] [54.81.168.187] - [0]
[64.79.100.43] - [444448] [203.67.9.74] - [0]
[222.186.21.90] - [149616]
[180.76.15.144] - [34060]
[180.76.15.145] - [27248]
[180.76.15.158] - [20436]
188 간단한 슈팅게임 만들기 ❶ 게임화면 구성하기
1. import pygame
2. 2:
3. 3: # 게임에 사용되는 전역변수 정의
4. 4: BLACK = (0, 0, 0)
5. 5: pad_width = 480
6. 6: pad_height = 640
7. 7:
8. 8: # 게임 실행 메인 함수
9. 9: def runGame( ):
10. 10: global gamepad, clock
11. 11:
12. 12: doneFlag = False
13. 13: while not doneFlag:
14. 14: for event in pygame.event.get( ):
15. 15: if event.type == pygame.QUIT:
16. 16: doneFlag = True
17. 17:
18. 18: # 게임 화면을 검은색으로 채우고 화면을 업데이트 함
19. 19: gamepad.fill(BLACK)
20. 20: pygame.display.update( )
188 간단한 슈팅게임 만들기 ❶ 게임화면 구성하기
21. 21: clock.tick(60)
22. 22:
23. 23: pygame.quit( )
24. 24:
25. 25: # 게임 초기화 함수
26. 26: def initGame( ):
27. 27: global gamepad, clock
28. 28:
29. 29: pygame.init( )
30. 30: gamepad = pygame.display.set_mode((pad_width, pad_height))
31. 31: pygame.display.set _caption('MyGalaga')
32. 32: clock = pygame.time.Clock( )
33. 33:
34. 34: initGame( )
35. 35: runGame( )
188 간단한 슈팅게임 만들기 ❶ 게임화면 구성하기
4~6번째 줄 : 게임에 사용되는 전역변수를 정의 27번째 줄 : gamepad와 clock을 전역변수로 선언

9번째 줄 : 게임 실행 메인 로직을 담을 함수 29번째 줄 : pygame.init( )은 pygame 라이브러리를 초기화

10번째 줄 : initGame( )에서 초기화 된 전역변수 30번째 줄 : 게임 화면의 가로 크기를 pad_width, 세로 크기를

12번째 줄 : 게임 화면을 닫을 때 False로 설정하여 pad_height로 설정

while 루프를 빠져나올 수 있도록 해주는 플래그 31번째 줄 : 게임 화면의 타이틀 바에 ‘MyGalaga’라는 이름을 표시

13번째 줄 : ongame이 False가 될 때까지 while 루프를 반복 32번째 줄 : pygame.time.Clock( )은 초당 프레임 수를 설정할 수 있는

14~16번째 줄 : pygame.event.get( )은 게임 화면에서 발생하는 Clock 객체를 생성

다양한 이벤트를 리턴 34~35번째 줄 : 구현한 initGame( )과 runGame( )을 순서대로 호출

19번째 줄 : 게임 화면 전체를 BLACK으로 설정된 값에 해당하는

색상으로 채움

20번째 줄 : 게임 화면을 다시 그림

21번째 줄 : 게임 화면의 초당 프레임 수를 60으로 설정

23번째 줄 : 초기화한 pygame을 종료

26번째 줄 :게임을 초기화하는 로직을 구현한 함수


189 간단한 슈팅게임 만들기 ❷ 전투기 배치하기
1. import pygame
2.
3. # 게임에 사용되는 전역변수 정의
4. BLACK = (0, 0, 0)
5. pad_width = 480
6. pad_height = 640
7. fighter _width = 36
8. fighter _height = 38
9.
10. # 게임에 등장하는 객체를 드로잉
11. def drawObject(obj, x, y):
12. global gamepad
13. gamepad.blit(obj, (x,y))
14.
15. # 게임 실행 메인 함수
16. def runGame( ):
17. global gamepad, clock, fighter
18.
19. # 전투기 초기 위치 (x, y) 설정
20. x = pad _width*0.45
21. y = pad _height*0.9
22. x_change = 0
23.
24. ongame = False
25. while not ongame:
26. for event in pygame.event.get( ):
27. if event.type == pygame.QUIT:
28. ongame = True
189 간단한 슈팅게임 만들기 ❷ 전투기 배치하기
30. if event.type == pygame.KEYDOWN:
31. if event.key == pygame.K_LEFT:
32. x_change -= 5
33.
34. elif event.key == pygame.K_RIGHT:
35. x_change += 5
36.
37. if event.type == pygame.KEYUP:
38. if event.key == pygame.K _LEFT or event.key == pygame.K_RIGHT:
39. x_change = 0
40.
41. gamepad.fill(BLACK)
42.
43. # 전투기의 위치를 재조정
44. x += x _change
45. if x < 0:
46. x=0
47. elif x > pad _width - fighter_width:
48. x = pad _width - fighter _width
49.
50. drawObject(fighter, x, y)
51. pygame.display.update( )
52. clock.tick(60)
189 간단한 슈팅게임 만들기 ❷ 전투기 배치하기
53.
54. pygame.quit( )
55.
56. # 게임 초기화 함수
57. def initGame( ):
58. global gamepad, clock, fighter
59.
60. pygame.init( )
61. gamepad = pygame.display.set_mode((pad_width, pad_height))
62. pygame.display.set _caption('MyGalaga')
63. fighter = pygame.image.load('fighter.png')
64. clock = pygame.time.Clock( )
65.
66. initGame( )
67. runGame( )
189 간단한 슈팅게임 만들기 ❷ 전투기 배치하기
7~8번째 줄 : 전투기 이미지의 가로, 세로 크기를 지정

11~13번째 줄 : obj를 게임 화면의 (x, y) 좌표에 그려주는 함수

17번째 줄 : runGame( ) 함수에서 새로운 전역변수 fighter를 선언

20~21번째 줄 : 전투기의 위치 x, y값

22번째 줄 : 전투기를 좌우로 이동시키기 위한 변수

30번째 줄 : 이벤트 타입이 키보드를 누르는 이벤트인지 체크

31~32번째 줄 : 누른 키보드 키가 왼쪽 화살표키이면 x_change의 값을 5 감소

34~35번째 줄 : 오른쪽 화살표키이면 x_change의 값을 5 증가

37~39번째 줄 : 키보드를 눌렀다가 떼는 이벤트 타입인지 체크

44번째 줄 : while 루프를 한 번 반복할 때마다 전투기의 x 좌표에 x_change를 더함

45~48번째 줄 : x값이 0보다 작아지게 되면 0으로 고정시켜서 전투기가 게임 화면 왼쪽 바깥으로 나가지 않게 하고,

반대로 x값이 게임화면의 오른쪽 끝에서 전투기 이미지의 가로 크기를 뺀 값보다 커지지 않도록 함

50번째 줄 : fighter를 게임 화면의 (x, y) 좌표에 그림

58번째 줄 : initGame( )에서 fighter를 전역변수로 선언

63번째 줄 : 이미지 파일을 읽고 이 이미지 객체를 변수 fighter에 지정. 인자로 지정된 이미지 파일을 읽어 이를 처리할 수 있는 핸들러 객체를 리턴
190 간단한 슈팅게임 만들기 ❸ 적 날아오게 하기
1. import pygame
2. import random
3.
4. # 게임에 사용되는 전역변수 정의
5. BLACK = (0, 0, 0)
6. pad_width = 480
7. pad_height = 640
8. fight _width = 36
9. fight _height = 38
10. enemy_width = 26
11. enemy_height = 20
12.
13. # 게임에 등장하는 객체를 드로잉
14. def drawObject(obj, x, y):
15. global gamepad
16. gamepad.blit(obj, (x,y))
17.
18. # 게임 실행 메인 함수
19. def runGame( ):
20. global gamepad, clock, fighter, enemy
21.
22. # 전투기 초기 위치 설정
23. x = pad _width*0.45
24. y = pad _height*0.9
25. x_change = 0
26.
27. # 적 초기 위치 설정
28. enemy_x = random.randrange(0, pad_width-enemy_width)
29. enemy_y = 0
190 간단한 슈팅게임 만들기 ❸ 적 날아오게 하기
30. enemy_speed = 3
31.
32. ongame = False
33. while not ongame:
34. for event in pygame.event.get( ):
35. if event.type == pygame.QUIT:
36. ongame = True
37.
38. if event.type == pygame.KEYDOWN:
39. if event.key == pygame.K_LEFT:
40. x_change -= 5
41.
42. elif event.key == pygame.K_RIGHT:
43. x_change += 5
44.
45. if event.type == pygame.KEYUP:
46. if event.key == pygame.K _LEFT or event.key == pygame.K_RIGHT:
47. x_change = 0
48.
49. gamepad.fill(BLACK)
50.
51. # 전투기의 위치 재조정
52. x += x _change
53. if x < 0:
54. x=0
55. elif x > pad _width - fight_width:
56. x = pad _width - fight_width
57.
58. drawObject(fighter, x, y)
190 간단한 슈팅게임 만들기 ❸ 적 날아오게 하기
60. # 적을 아래로 움직임
61. enemy_y += enemy_speed
62. if enemy_y > pad_height:
63. enemy_y = 0
64. enemy_x = random.randrange(0, pad_width-enemy_width)
65.
66. drawObject(enemy, enemy_x, enemy_y)
67.
68. pygame.display.update( )
69. clock.tick(60)
70.
71. pygame.quit( )
72.
73. # 게임 초기화 함수
74. def initGame( ):
75. global gamepad, clock, fighter, enemy
76.
77. pygame.init( )
78. gamepad = pygame.display.set_mode((pad_width, pad_height))
79. pygame.display.set _caption('MyGalaga')
80. fighter = pygame.image.load('fighter.png')
81. enemy = pygame.image.load('enemy.png')
82. clock = pygame.time.Clock( )
83.
84. initGame( )
85. runGame( )
190 간단한 슈팅게임 만들기 ❸ 적 날아오게 하기
10~11번째 줄 : 적 이미지의 가로, 세로 크기를 각각 지정

20번째 줄 : runGame( )에서 전역변수 enemy를 추가

28~29번째 줄 : enemy_x와 enemy_y는 게임 화면에서 적 이미지가 위치할 좌표

30번째 줄 : enemy_speed는 적이 화면 상단에서 하단으로 떨어지는 속도를 지정해주는 변수

61번째 줄 : while 루프를 반복할 때마다 enemy_y의 값에 enemy_speed의 값을 더해줌

62~64번째 줄 : enemy_y의 값이 게임 화면의 세로 크기를 벗어나면 enemy_y의 값을 다시 0으로 초기화하고

enemy_x의 값을 28라인과 같이 0과 pad_width-enemy_width 사이의 무작위 값으로 설정

66번째 줄 : enemy를 게임 화면의 (enemy_x, enemy_y) 좌표에 그림

75번째 줄 : initGame( )에서 전역변수 enemy를 추가

81번째 줄 : 이미지 파일을 읽고 이 이미지 객체를 변수 enemy에 지정


191 간단한 슈팅게임 만들기 ❹ 무기 발사하기
1. import pygame
2. import random
3.
4. # 게임에 사용되는 전역변수 정의
5. BLACK = (0, 0, 0)
6. pad_width = 480
7. pad_height = 640
8. fight _width = 36
9. fight _height = 38
10. enemy_width = 26
11. enemy_height = 20
12.
13. # 게임에 등장하는 객체를 드로잉
14. def drawObject(obj, x, y):
15. global gamepad
16. gamepad.blit(obj, (x,y))
17.
18. # 게임 실행 메인 함수
19. def runGame( ):
20. global gamepad, clock, fighter, enemy, bullet
21.
22. # 무기 좌표를 위한 리스트 자료
23. bullet _xy = [ ]
24.
25. # 전투기 초기 위치 설정
26. x = pad _width*0.45
27. y = pad _height*0.9
28. x_change = 0
191 간단한 슈팅게임 만들기 ❹ 무기 발사하기
30. # 적 초기 위치 설정
31. enemy_x = random.randrange(0, pad_width-enemy_width)
32. enemy_y = 0
33. enemy_speed = 3
34.
35. doneFlag = False
36. while not doneFlag:
37. for event in pygame.event.get( ):
38. if event.type == pygame.QUIT:
39. doneFlag = True
40.
41. if event.type == pygame.KEYDOWN:
42. if event.key == pygame.K_LEFT:
43. x_change -= 5
44.
45. elif event.key == pygame.K_RIGHT:
46. x_change += 5
47.
48. # 왼쪽 컨트롤 키를 누르면 무기 발사. 무기는 한 번에 2발만 발사됨
49. elif event.key == pygame.K_LCTRL:
50. if len(bullet_xy) < 2:
51. bullet _x = x + fight_width/2
52. bullet _y = y - fight_height
53. bullet _xy.append([bullet_x, bullet_y])
54.
55. if event.type == pygame.KEYUP:
56. if event.key == pygame.K _LEFT or event.key == pygame.K_RIGHT:
57. x_change = 0
58.
191 간단한 슈팅게임 만들기 ❹ 무기 발사하기
59. gamepad.fill(BLACK)
60.
61. # 전투기의 위치 재조정
62. x += x _change
63. if x < 0:
64. x=0
65. elif x > pad _width - fight_width:
66. x = pad _width - fight_width
67.
68. drawObject(fighter, x, y)
69.
70. # 전투기 무기 발사 화면에 그리기
71. if len(bullet_xy) != 0:
72. for i, bxy in enumerate(bullet_xy):
73. bxy[1] -= 10
74. bullet_xy[i][1] = bxy[1]
75.
76. if bxy[1] <= 0:
77. try:
78. bullet _xy.remove(bxy)
79. except:
80. pass
81.
82. if len(bullet_xy) != 0:
83. for bx, by in bullet_xy:
84. drawObject(bullet, bx, by)
85.
86. # 적을 아래로 움직임
87. enemy_y += enemy_speed
191 간단한 슈팅게임 만들기 ❹ 무기 발사하기
88. if enemy_y > pad_height:
89. enemy_y = 0
90. enemy_x = random.randrange(0, pad_width-enemy_width)
91.
92. drawObject(enemy, enemy_x, enemy_y)
93.
94. pygame.display.update( )
95. clock.tick(60)
96.
97. pygame.quit( )
98.
99. # 게임 초기화 함수
100.def initGame( ):
101. global gamepad, clock, fighter, enemy, bullet
102.
103. pygame.init( )
104. gamepad = pygame.display.set_mode((pad_width, pad_height))
105. pygame.display.set _caption('MyGalaga')
106. fighter = pygame.image.load('fighter.png')
107. enemy = pygame.image.load('enemy.png')
108. bullet = pygame.image.load('bullet.png')
109. clock = pygame.time.Clock( )
110.
111.initGame( )
112.runGame( )
191 간단한 슈팅게임 만들기 ❹ 무기 발사하기
20번째 줄 : bullet은 initGame( )에서 무기를 나타내는 이미지를 로딩하여 이에 대한 이미지 객체를 지정한 변수

23번째 줄 : bullet_xy는 전투기에서 발사된 무기의 좌표를 저장하는 리스트 변수

49번째 줄 : 키보드의 왼쪽 컨트롤 키를 누르면 무기 발사 - 이벤트가 발생한 키가 왼쪽 컨트롤 키인지 확인

50~53번째 줄 : 전투기에서 한 번에 발사되는 무기는 2발로 제한

71~74번째 줄 : bullet_xy에 요소가 존재하면 bullet_xy의 각 요소의 y 좌표의 값을 10만큼 감소

76~80번째 줄 : 무기가 게임 화면 밖으로 나가면 bullet_xy로부터 해당 좌표를 제거

82~84번째 줄 : 발사된 무기를 화면에 그림

101번째 줄 : initGame( )에서 전역변수 bullet을 선언

108번째 줄 : bullet.png 이미지 파일을 읽고 이 이미지 객체를 변수 bullet에 지정


192 간단한 슈팅게임 만들기 ❺ 게임규칙 적용하기
1: import pygame
2: import random
3: from time import sleep
4:
5: # 게임에 사용되는 전역변수 정의
6: BLACK = (0, 0, 0)
7: RED = (255, 0, 0)
8: pad_width = 480
9: pad_height = 640
10: fight _width = 36
11: fight _height = 38
12: enemy_width = 26
13: enemy_height = 20
14:
15: # 적을 맞춘 개수 계산
16: def drawScore(count):
17: global gamepad
18: font = pygame.font.SysFont(None, 20)
19: text = font.render('Enemy Kills: ' + str(count), True, WHITE)
20: gamepad.blit(text, (0, 0))
21:
22: # 적이 화면 아래로 통과한 개수
23: def drawPassed(count):
24: global gamepad
25: font = pygame.font.SysFont(None, 20)
26: text = font.render('Enemy Passed: ' + str(count), True, RED)
27: gamepad.blit(text, (360, 0))
28:
29: # 화면에 글씨 보이게 하기
192 간단한 슈팅게임 만들기 ❺ 게임규칙 적용하기
30: def dispMessage(text):
31: global gamepad
32: textfont = pygame.font.Font('freesansbold.ttf', 80)
33: text = textfont.render(text, True, RED)
34: textpos = text.get_rect( )
35: textpos.center = (pad_width/2, pad _height/2)
36: gamepad.blit(text, textpos)
37: pygame.display.update( )
38: sleep(2)
39: runGame( )
40:
41: # 전투기가 적과 충돌했을 때 메시지 출력
42: def crash( ):
43: global gamepad
44: dispMessage('Crashed!')
45:
46: # 게임 오버 메시지 보이기
47: def gameover( ):
48: global gamepad
49: dispMessage('Game Over')
50:
51: # 게임에 등장하는 객체를 드로잉
52: def drawObject(obj, x, y):
53: global gamepad
54: gamepad.blit(obj, (x,y))
55:
56: # 게임 실행 메인 함수
57: def runGame( ):
58: global gamepad, clock, fighter, enemy, bullet
192 간단한 슈팅게임 만들기 ❺ 게임규칙 적용하기
60: # 전투기 무기에 적이 맞았을 경우 True로 설정되는 플래그
61: isShot = False
62: shotcount = 0
63: enemypassed = 0
64:
65: # 무기 좌표를 위한 리스트 자료
66: bullet_xy = [ ]
67:
68: # 전투기 초기 위치 설정
69: x = pad _width*0.45
70: y = pad _height*0.9
71: x_change = 0
72:
73: # 적 초기 위치 설정
74: enemy_x = random.randrange(0, pad_width-enemy_width)
75: enemy_y = 0
76: enemy_speed = 3
77:
78: ongame = False
79: while not ongame:
80: for event in pygame.event.get( ):
81: if event.type == pygame.QUIT:
82: ongame = True
83:
84: if event.type == pygame.KEYDOWN:
85: if event.key == pygame.K_LEFT:
86: x_change -= 5
87:
88: elif event.key == pygame.K_RIGHT:
89: x_change += 5
192 간단한 슈팅게임 만들기 ❺ 게임규칙 적용하기
91: # 왼쪽 컨트롤키를 누르면 총알이 발사. 총알은 한 번에 2발만 발사
92: elif event.key == pygame.K_LCTRL:
93: if len(bullet_xy) < 2:
94: bullet _x = x + fight_width/2
95: bullet _y = y - fight_height
96: bullet _xy.append([bullet_x, bullet_y])
97:
98: if event.type == pygame.KEYUP:
99: if event.key == pygame.K _LEFT or event.key == pygame.K_RIGHT:
100: x_change = 0
101:
102: gamepad.fill(BLACK)
103:
104: # 전투기의 위치 재조정
105: x += x _change
106: if x < 0:
107: x=0
108: elif x > pad _width - fight_width:
109: x = pad _width - fight_width
110:
111: # 게이머 전투기가 적과 충돌했는지 체크
112: if y < enemy _y + enemy_height:
113: if (enemy _x > x and enemy_x < x + fight _width) or \
114: (enemy_x + enemy_width > x and enemy_x+ enemy_width < x +
115: fight _width):
116: crash( )
117:
118: drawObject(fighter, x, y)
192 간단한 슈팅게임 만들기 ❺ 게임규칙 적용하기
120: # 전투기 총알 발사 구현
121: if len(bullet_xy) != 0:
122: for i, bxy in enumerate(bullet_xy):
123: bxy[1] -= 10
124: bullet_xy[i][1] = bxy[1]
125:
126: # 전투기 무기가 적을 격추했을 경우
127: if bxy[1] < enemy _y:
128: if bxy[0] > enemy_x and bxy[0] < enemy_x + enemy_width:
129: bullet _xy.remove(bxy)
130: isShot = True
131: shotcount += 1
132:
133: if bxy[1] <= 0:
134: try:
135: bullet _xy.remove(bxy)
136: except:
137: pass
138:
139: if len(bullet_xy) != 0:
140: for bx, by in bullet_xy:
141: drawObject(bullet, bx, by)
142:
143: drawScore(shotcount)
144:
145: # 적을 아래로 움직임
146: enemy_y += enemy_speed
147:
148: if enemy_y > pad_height:
149: enemy_y = 0
192 간단한 슈팅게임 만들기 ❺ 게임규칙 적용하기
150: enemy_x = random.randrange(0, pad_width-enemy_width)
151: enemypassed += 1
152:
153: if enemypassed == 3:
154: gameover( )
155:
156: drawPassed(enemypassed)
157:
158: # 적이 무기에 맞았는지 체크하고 맞았으면 스피드업
159: if isShot:
160: enemy_speed += 1
161: if enemy_speed >= 10:
162: enemy_speed = 10
163:
164: enemy_x = random.randrange(0, pad_width-enemy_width)
165: enemy_y = 0
166: isShot = False
167:
168: drawObject(enemy, enemy_x, enemy_y)
169:
170: pygame.display.update( )
171: clock.tick(60)
172:
173: pygame.quit( )
174:
175: # 게임 초기화 함수
176: def initGame( ):
177: global gamepad, clock, fighter, enemy, bullet
192 간단한 슈팅게임 만들기 ❺ 게임규칙 적용하기
178:

179: pygame.init( )

180: gamepad = pygame.display.set_mode((pad_width, pad_height))

181: pygame.display.set_caption('MyGalaga')

182: fighter = pygame.image.load('fighter.png')

183: enemy = pygame.image.load('enemy.png')

184: bullet = pygame.image.load('bullet.png')

185: clock = pygame.time.Clock( )

186:

187: initGame( )

188: runGame( )
192 간단한 슈팅게임 만들기 ❺ 게임규칙 적용하기
3번째 줄 : time 모듈의 sleep( )을 임포트

7번째 줄 : 빨간색을 나타내는 값으로 RED를 정의

16~20번째 줄 : count에 해당하는 숫자를 게임 화면의 왼쪽 상단에 폰트 크기 20의 흰색 글씨로 나타내는 함수

23~27번째 줄 : count에 해당하는 숫자를 게임 화면의 오른쪽 상단에 폰트 크기 20의 빨간색 글씨로 나타내는 함수

30~38번째 줄 : text를 폰트 크기 80의 빨간색 글씨로 게임화면 정중앙에 표시하고 2초 이후 runGame( )을 호출하여 게임을 재시작하는 함수

42~44번째 줄 : 전투기가 적과 충돌했을 때 호출되는 함수

61~63번째 줄 : 전투기가 발사한 무기가 적을 격추했을 때 True로 설정되는 플래그

112~116번째 줄 : 전투기가 적과 충돌했으면 crash( )를 호출

127~131번째 줄 : 전투기 무기가 적을 격추했으면 bullet_xy에서 격추한 무기 좌표를 제거하여 화면에서 무기가 사라지게 함

143번째 줄 : drawScore(shotcount)를 호출하여 shotcount에 해당하는 숫자를 게임 화면 왼쪽 상단에 표시

151번째 줄 : 적이 격추되지 않고 화면을 통과하면 enemypassed의 값을 1 증가

153~154번째 줄 : enemypassed의 값이 3이면 gameover( )를 호출

156번째 줄 : drawPassed(enemypassed)를 호출하여 enemypassed에 해당하는 숫자를 게임 화면 오른쪽 상단에 표시

159~166번째 줄 : isShot이 True이면 enemy_speed의 값을 1 증가. enemy_speed의 값이 10 이상이면 10으로 고정.

새로운 적을 게임 화면에 표시하기 위해 적의 좌표를 초기화하고 isShot의 값을 False로 변경


193 에코 서버 만들기 ❶

네트워크 소켓의 종류

• TCP 소켓: TCP를 활용하는 네트워크 소켓


• UDP 소켓: UDP를 활용하는 네트워크 소켓
• Raw 소켓: 라우터나 네트워크 장비에 활용되는 소켓
193 에코 서버 만들기 ❶
1. import socket 1번째 줄 : socket 모듈을 임포트
2.
3. HOST = '' 3~4번째 줄 : 서버의 IP와 포트번호를각각 HOST와 PORT에 지정
4. PORT = 9009 4번째 줄 : 에코 서버를 구현한 메인 함수
5.
6. def runServer( ): 7번째 줄 : TCP 소켓을 생성하고 socket 객체를 리턴
7. with socket.socket(socket.AF _INET, socket.SOCK_STREAM)
as sock: 8번째 줄 : 소켓을 지정된 IP와 포트번호로 바인딩
8. sock.bind((HOST, PORT)) 9번째 줄 : 서버가 한 번에 처리 가능한 연결 수를 1로 설정하고 대기
9. sock.listen(1)
10. print('클라이언트 연결을 기다리는 중..') 11번째 줄 : 클라이언트로부터 연결 요청이 오면 accept( )는 클라이
11. conn, addr = sock.accept( ) 언트와 연결된 TCP 소켓과 클라이언트 주소를 리턴
12. with conn:
14~15번째 줄 : 클라이언트로부터 1024바이트를 수신
13. print('[%s]와 연결됨' %addr[0])
14. while True: 16~17번째 줄 : 수신한 데이터가 없으면 서버를 종료
15. data = conn.recv(1024)
16. if not data: 18~19번째 줄 : 수신한 데이터가 있으면 data를 화면에 출력
17. break
data.decode( )로 알아볼 수 있는 문자열로 변환하여 화면에 출력
18. print('메시지 수신 [%s]' %data.decode( ))
19. conn.sendall(data) conn.sendall(data)는 data를 클라이언트 소켓인 conn을 통해 data를
20. 모두 전송.
21. runServer( )
20번째 줄 : runServer( )를 호출하여 서버를 구동
194 에코 클라이언트 만들기 ❶
194 에코 클라이언트 만들기 ❶
1. import socket 3~4번째 줄 : 서버의 IP주소, 서버의 포트번호를 각각 지정
2. 6번째 줄 : TCP 소켓을 생성하고 sock으로 둠
3. HOST = 'localhost'
7번째 줄 : (HOST, PORT)에 해당하는 원격 호스트로 연결을 시도
4. PORT = 9009
8번째 줄 : 사용자로부터 메시지를 입력받고 msg로 둠
5.
9번째 줄 : msg를 msg.encode( )로 바이트 스트림으로 인코딩하고
6. with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as
sock: 소켓의 sendall( )을 이용해 서버로 전송
7. sock.connect((HOST, PORT))
10번째 줄 : sock.recv(1024)로 서버가 전송하는 데이터를 수신
8. msg = input('메시지 입력: ')
12번째 줄 : 수신한 데이터를 화면에 출력
9. sock.sendall(msg.encode( ))
10. data = sock.recv(1024)
11.

12. print('에코 서버로부터 받은 데이터 [%s]' %data.decode( ))


195 에코 서버 만들기 ❷
1: import socketserver 27:
2: 28: try:
3: HOST = '' 29: server = socketserver.TCPServer((HOST, PORT), MyTcpHandler)
4: PORT = 9009 30: server.serve _forever( )
5: 31: except KeyboardInterrupt:
6: class MyTcpHandler(socketserver.BaseRequestHandler): 32: print('--- 에코 서버를 종료합니다.')
7: # 이 클래스는 서버 하나당 단 한 번 초기화됩니다. 33:
8: # handle( ) 메소드에 클라이언트 연결 처리를 위한 로직을 구현합니다. 34: runServer( )
9: def handle(self):
10: print('[%s] 연결됨' %self.client_address[0])
11:
12: try:
13: while True:
14: self.data = self.request.recv(1024)
15: if self.data.decode( ) == '/quit':
16: print('[%s] 사용자에 의해 중단' %self.client_address[0])
17: return
18:
19: print('[%s]' %self.data.decode( ))
20: self.request.sendall(self.data)
21: except Exception as e:
22: print(e)
23:
24: def runServer( ):
25: print('+++ 에코 서버를 시작합니다.')
26: print('+++ 에코 서버를 끝내려면 Ctrl+C를 누르세요.')
195 에코 서버 만들기 ❷
많이 사용하는 socketserver

socketserver.TCPServer 클래스
TCP 프로토콜을 사용하는 서버를 구현할 때 활용하는 socketserver의 클래스입니다.
socketserver.UDPServer 클래스
UDP 프로토콜을 사용하는 서버를 구현할 때 활용하는 socketserver의 클래스입니다.

3~4번째 줄 : HOST에는 빈 문자열, PORT에는 9009를 설정

6번째 줄 : socketserver.BaseRequestHandler 클래스를 상속받은 클래스이며, socketserver. TCPServer 객체를 생성할 때 인자로 입력됨

9번째 줄 : 클라이언트의 연결과 요청 작업은 handle( )에서 처리

10번째 줄 : client_address는 클라이언트의 IP주소를 담고 있음

14번째 줄 : request는 클라이언트 소켓과 연결된 서버의 TCP 소켓

15~17번째 줄 : 클라이언트로부터 수신한 메시지가 ‘/quit’이면 해당 클라이언트에 대한 연결을 종료

19~20번째 줄 : 수신한 메시지가 ‘/quit’이 아니면 해당 메시지를 클라이언트로 재전송

24번째 줄 : 에코 서버를 구동하는 함수

28~32번째 줄 : PORT 번호로 HOST와 바인딩하여 socketserver.TCPServer 객체를 생성하고 server로 둠

사용자가 Ctrl + C 를 누르면 메시지를 화면에 출력하고 서버를 종료


196 에코 클라이언트 만들기 ❷
1. import socket 9번째 줄 : 사용자가 ‘/quit’을 입력할 때까지 무한 루프
2.
3. HOST = 'localhost' 10~13번째 줄 : 사용자로부터 입력받은 메시지를 msg에 대입
4. PORT = 9009
5.
6. with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as
sock:
7. sock.connect((HOST, PORT))
8.
9. while True:
10. msg = input('메시지 입력: ')
11. if msg == '/quit':
12. sock.sendall(msg.encode( ))
13. break
14.
15. sock.sendall(msg.encode( ))
16. data = sock.recv(1024)
17. print('에코 서버로부터 받은 데이터
[%s]' %data.decode( ))
18.
19. print('클라이언트 종료')
197 파일 송신 프로그램 만들기
1: import socketserver 27: print('전송완료[%s], 전송량[%d]' %(filename, data_transferred))
2: from os.path import exists 28:
3: 29: def runServer( ):
4: HOST = '' 30: print('+++ 파일 서버를 시작합니다.')
5: PORT = 9009 31: print('+++ 파일 서버를 끝내려면 Ctrl+C를 누르세요.')
6: 32:
7: class MyTcpHandler(socketserver.BaseRequestHandler): 33: try:
8: def handle(self): 34: server = socketserver.TCPServer((HOST, PORT), MyTcpHandler)
9: data_transferred = 0 35: server.serve _forever( )
10: print('[%s] 연결됨' %self.client_address[0]) 36: except KeyboardInterrupt:
11: filename = self.request.recv(1024) 37: print('--- 파일 서버를 종료합니다.')
12: filename = filename.decode( ) 38:
13: 39: runServer( )
14: if not exists(filename):
15: return
16:
17: print('파일 [%s] 전송 시작...' %filename)
18: with open(filename, 'rb') as f:
19: try:
20: data = f.read(1024)
21: while data:
22: data_transferred += self.request.send(data)
23: data = f.read(1024)
24: except Exception as e:
25: print(e)
26:
197 파일 송신 프로그램 만들기
8번째 줄 : handle( )을 클라이언트가 요청하는 파일 데이터를 읽어 소켓을 통해 클라이언트로 전송해주는 로직으로 수정

9~12번째 줄 : data_tranferred는 서버가 전송한 데이터 양을 저장하는 변수

네트워크를 통해 전달받은 데이터는 filename.decode( )로 일반 문자열로 변환

14~15번째 줄 : 클라이언트가 요청한 파일이 서버가 구동되는 디렉터리에 존재하지 않으면 handle( )을 빠져나옴

17~25번째 줄 : 전송을 시작한다는 메시지를 출력하고 해당 파일을 오픈한 후 1024바이트씩 읽어 클라이언트로 데이터를 전송

send( )는 전송한 데이터의 크기를 리턴하므로 이 값을 data_transferred에 누적하여 더함

data가 빈 문자열이므로 while 구문을 빠져나오게 되고 전송해 준 용량을 출력하고 마무리


198 파일 수신 프로그램 만들기
1: import socket 26:
2: 27: print('파일 [%s] 전송종료. 전송량 [%d]' %(filename, data_transferred))
3: HOST = 'localhost' 28:
4: PORT = 9009 29: filename = input('다운로드 받을 파일이름을 입력하세요: ')
5: 30: getFileFromServer(filename)
6: def getFileFromServer(filename):
7: data_transferred = 0
8:
9: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
10: sock.connect((HOST, PORT))
11: sock.sendall(filename.encode( ))
12:
13: data = sock.recv(1024)
14: if not data:
15: print('파일[%s]: 서버에 존재하지 않거나 전송중 오류발생
' %filename)
16: return
17:
18: with open('download/'+filename, 'wb') as f:
19: try:
20: while data:
21: f.write(data)
22: data_transferred += len(data)
23: data = sock.recv(1024)
24: except Exception as e:
25: print(e)
198 파일 수신 프로그램 만들기
3~4번째 줄 : 클라이언트가 연결하려는 서버의 IP와 포트번호를 HOST와 PORT에 설정

6번째 줄 : filename에 해당하는 파일을 서버에 접속하여 다운로드를 수행하는 함수

7번째 줄 : 클라이언트가 서버로부터 전송받은 데이터 양을 저장하는 변수

9~11번째 줄 : TCP 소켓을 생성하고 서버로 연결한 후 사용자가 입력한 파일이름을 전송

13~16번째 줄 : 서버로부터 1024바이트만큼 수신한 데이터를 data로 둠. 수신되는 데이터가 없으면 오류 메시지를 출력하고 리턴

18~25번째 줄 : download 디렉터리에 filename으로 지정된 파일을 바이너리 쓰기 모드로 오픈하고 파일 핸들러를 f로 둠

data가 빈 문자열이 아니면 파일에 data를 기록하고 서버로부터다시 데이터를 수신

27번째 줄 : 파일을 모두 다운로드 받으면 전송량을 출력

29~30번째 줄 : 사용자로부터 다운로드 받을 파일이름을 입력받고 getFileFromServer( )를 호출


199 채팅 서버 만들기
1: import socketserver 27: def removeUser(self, username):
2: import threading 28: if username not in self.users:
3: 29: return
4: HOST = '' 30:
5: PORT = 9009 31: lock.acquire( )
6: lock = threading.Lock( ) 32: del self.users[username]
7: 33: lock.release( )
8: class UserManager: 34:
9: def _ _init _ _(self): 35: self.sendMessageToAll('[%s]님이 퇴장했습니다.' %username)
10: self.users = { } 36: print('--- 대화 참여자 수 [%d]' %len(self.users))
11: 37:
12: def addUser(self, username, conn, addr): 38: def messageHandler(self, username, msg):
13: if username in self.users: 39: if msg[0] != '/':
14: conn.send('이미 등록된 사용자입니다.\n'.encode( )) 40: self.sendMessageToAll('[%s] %s' %(username, msg))
15: return None 41: return
16: 42:
17: # 새로운 사용자를 등록함 43: if msg.strip( ) == '/quit':
18: lock.acquire( ) 44: self.removeUser(username)
19: self.users[username] = (conn, addr) 45: return -1
20: lock.release( )
21:
22: self.sendMessageToAll('[%s]님이 입장했습니다.' %username)
23: print('+++ 대화 참여자 수 [%d]' %len(self.users))
24:
25: return username
26:
199 채팅 서버 만들기
47: def sendMessageToAll(self, msg): 75: while True:
48: for conn, addr in self.users.values( ): 76: self.request.send('로그인ID:'.encode( ))
49: conn.send(msg.encode( )) 77: username = self.request.recv(1024)
50: 78: username = username.decode( ).strip( )
51: 79: if self.userman.addUser(username, self.request, self.client
52: class MyTcpHandler(socketserver.BaseRequestHandler): _address):
53: userman = UserManager( ) 80: return username
54: 81:
55: def handle(self): 82: class ChatingServer(socketserver.ThreadingMixIn,
56: print('[%s] 연결됨' %self.client_address[0]) socketserver.TCPServer):
57: 83: pass
58: try: 84:
59: username = self.registerUsername( ) 85: def runServer( ):
60: msg = self.request.recv(1024) 86: print('+++ 채팅 서버를 시작합니다.')
61: while msg: 87: print('+++ 채텅 서버를 끝내려면 Ctrl+C를 누르세요.')
62: print(msg.decode( )) 88:
63: if self.userman.messageHandler(username, msg.decode( )) 89: try:
== -1: 90: server = ChatingServer((HOST, PORT), MyTcpHandler)
64: self.request.close( ) 91: server.serve _forever( )
65: break 92: except KeyboardInterrupt:
66: msg = self.request.recv(1024) 93: print('--- 채팅 서버를 종료합니다.')
67: 94: server.shutdown( )
68: except Exception as e: 95: server.server _close( )
69: print(e) 96:
70: 97: runServer( )
71: print('[%s] 접속종료' %self.client_address[0])
72: self.userman.removeUser(username)
73:
74: def registerUsername(self):
199 채팅 서버 만들기
1~2번째 줄 : socketserver 모듈과 threading 모듈을 임포트

4~5번째 줄 : 채팅 서버에서 사용할 HOST와 PORT를 설정

6번째 줄 : threading.Lock( ) 객체를 생성하고 변수 lock으로 둠

8번째 줄 : UserManager 클래스를 구현

9~10번째 줄 : UserManager 클래스의 생성자에서 사용자 등록 정보를 담을 사전인 self.users를 초기화

12번째 줄 : addUser(self, username, conn, addr)는 사용자 ID를 self.users에 추가하는 함수

13~15번째 줄 : self.users의 키로 username이 존재하면 이미 등록된 사용자라는 메시지를 클라이언트로 전송하고 None을 리턴

18~20번째 줄 : self.users에 username을 키로, (conn, addr)를 값으로 하는 요소를 추가

self.users를 업데이트 하면 lock.release( )를 호출하여 락을 해제

22~25번째 줄 : 채팅 서버에 접속한 모든 클라이언트에 새로운 사용자가 입장하였다는 메시지를 전송하고 사용자 수를 출력

27~29번째 줄 : removeUser(self, username)은 username을 self.users에서 제거하는 함수

31~33번째 줄 : 락을 건 후 self.users에서 키가 username인 요소를 제거하고 락을 해제

35~36번째 줄 : 해당 사용자가 퇴장했다는 메시지를 접속 중인 모든 클라이언트에 전송하고 서버 화면에 현재 접속한 사용자 수를 출력

38번째 줄 : username이 전송한 메시지인 msg를 처리하는 함수


199 채팅 서버 만들기
47~49번째 줄 : sendMessageToAll(self, msg)는 채팅 서버에 접속한 모든 클라이언트에 msg를 전송

53~54번째 줄 : UserManager 클래스의 객체를 생성하고 이를 userman으로 둠

56번째 줄 : 클라이언트가 접속하면 클라이언트 주소를 출력

59번째 줄 : registerUsername( )을 호출하여 사용자 ID를 클라이언트로 요청하여 전달받고 사용자를 채팅 서버에 등록하는 과정을 수행

60~66번째 줄 : 클라이언트로부터 메시지를 수신하여 msg로 지정. msg에 내용이 있으면 서버 화면에 메시지를 출력.

messageHandler(username, msg.decode( ))를 호출하여 메시지를 처리

71~72번째 줄 : while 구문을 빠져나오면 해당 클라이언트가 접속 종료되었다는 메시지를 서버 화면에 출력하고 사용자 ID를 제거

74번째 줄 : registerUsername(self)는 사용자 ID를 클라이언트로 요청하여 전달받고 사용자를 등록하는 함수

75~80번째 줄 : 클라이언트가 최초 접속하면 로그인 ID를 요청하는 메시지를 클라이언트로 전송. 좌우 공백을 username.strip( )

으로 제거. addUser(username, self.request, self.client_address)를 호출하여 사용자 등록을 수행

82번째 줄 : socketserver.ThreadingMixIn 클래스와 socketserver.TCPServer 클래스로부터 상속받은 ChatingServer 클래스를 정의

85번째 줄 : 이후의 runServer( )는 채팅 서버를 구동하고 종료하는 역할을 수행하는 함수

89~95번째 줄 : ChatingServer 클래스를 이용해 서버 객체를 생성. 사용자가 Ctrl+ C 를 누르면 서버를 셧다운하고 종료

97번째 줄 : runServer( )를 호출하여 채팅 서버를 실행


200 채팅 클라이언트 만들기
1: import socket 27: sock.send(msg.encode( ))
2: from threading import Thread 28: break
3: 29:
4: HOST = 'localhost' 30: sock.send(msg.encode( ))
5: PORT = 9009 31:
6: 32: runChat( )
7: def rcvMsg(sock):
8: while True:
9: try:
10: data = sock.recv(1024)
11: if not data:
12: break
13: print(data.decode( ))
14: except:
15: pass
16:
17: def runChat( ):
18: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
19: sock.connect((HOST, PORT))
20: t = Thread(target=rcvMsg, args=(sock,))
21: t.daemon = True
22: t.start( )
23:
24: while True:
25: msg = input( )
26: if msg == '/quit':
200 채팅 클라이언트 만들기
1~2번째 줄 : socket 모듈과 threading 모듈의 Thread( )를 임포트

4~5번째 줄 : 채팅 서버의 HOST와 PORT를 설정

7번째 줄 : rcvMsg(sock)은 runChat( )에서 스레드로 구동되며 채팅 서버로부터 메시지를 수신받아 출력. sock은 채팅 서버와 연결된 TCP 소켓

8번째 줄 : 무한 루프

10~13번째 줄 : 채팅 서버로부터 메시지를 수신

17번째 줄 : runChat( )은 소켓을 생성하고 채팅 서버에 연결한 후 rcvMsg( )를 스레드로 구동하고 사용자로부터 메시지를 입력받아

채팅 서버로 전송하는 함수

18~19번째 줄 : TCP 소켓을 생성하고 채팅 서버에 연결

20번째 줄 : rcvMsg( ) 함수를 독립적으로 실행 가능한 스레드로 만들고, 함수 인자로 sock을 넘겨줌

21~22번째 줄 : t.daemon = True로 설정하면 스레드 t는 t를 생성한 메인 스레드가 종료하면 자동적으로 종료

t.start( )는 생성한 스레드 t를 구동

24~28번쨰 줄 : 사용자가 ‘/quit’을 입력할 때까지 메시지를 입력받아 채팅 서버로 전송

32번째 줄 : runChat( )을 호출하여 채팅 클라이언트를 구동

You might also like