파이썬3 바이블 - 제2장 연습문제

프리렉 - FREELEC

http://freelec.co.kr/book/catalogue_view.asp?UID=134

이강성저

1. 주석문에 대해서 정리해 보자.

주석은 사람이 코드를 이해하기 위해서 추가되는 설명으로 실행에는 전혀 영향을 미치지 않는다. 파이썬 주석은 줄 어디에서나 시작할 수 있다. # 으로 시작하는 부분부터 주석으로 취급된다.

In [11]:
# 라인을 주석으로
a = 1 # 주석..

2. 변수 이름과 예약어에 대한 내용이다. 다음 문제를 풀어 보자.

가) 파이썬의 예약어 목록을 확인하는 방법과 어떤 단어가 예약어인지 확인하는 방법은 무엇인가?

In [8]:
import keyword

print (len(keyword.kwlist))             # 예약어 갯수
print (keyword.kwlist)                  # 전체 목록
print('is' in keyword.kwlist)
print('python' in keyword.kwlist)
33
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
True
False

나) 변수의 이름을 지을 때 따라야 하는 규칙을 정리해 보자.

- 유니코드 문자나 _ 로 시작한다
- 이름에 공백이 없어야 한다
- 아스키코드의 특수문자는 사용할 수 없다(예:!@#$)
- 예약어가 아니어야 한다.
In [14]:
변수 = 1
print(변수)

__ = '2013.11.12'
print (__)

그래도_영문_변수를_사용하는_것이_좋습니다 = True
print(그래도_영문_변수를_사용하는_것이_좋습니다)
1
2013.11.12
True

다) 변수의 이름을 지으면서 조심해야 할 점은 무엇인가?

1. 변수의 이름을 일관성 있게 작성하는 것이 좋습니다. 예를 들면 여러 단어를 연결할 때, veryCloseFriends, very_close_friends 등과 같이 할 수 있습니다. 어느 것도 관계 없으나 일관성 있는 것이 좋습니다.

2. 변수의 이름과 함수의 이름, 클래스 이름등 구분되도록 규칙을 정하는게 좋습니다. 클래스 이름은 대문자로 시작하고, 함수나 메쏘드 이름은 소문자로 시작하고, 변수 이름은 단어의 연결을 _으로 하고 하는 등의 규칙을 정하는 것이 좋습니다.

3. 변수의 이름이 기존에 사용되는 이름과 충돌되면 기존의 이름은 사라지거나 보이지 않게됩니다. 이 점을 조심해야 합니다. 다음 예와 같이 이미 존재하는 함수와 혼동될 수 있습니다.
In [23]:
print (abs(-1))   # 내장 함수
abs = 2.0
print(abs * 2.0)
del abs          # 변수 삭제
print (abs(-1))   # 내장 함수
1
4.0
1

3. 치환문에 대한 내용이다. 다음 문제를 풀어 보자.

가) 치환문의 종류를 정리해 보자.

단순 치환문 : =
확장 치환문 : +=, -=, *=, /=, //=, %=, \**=, >>=, <<=, &=, ^=, &=, |=
In [36]:
a = 1
a += 1   # a = a + 1
a *= 2   # a = a * 2
a *= 3+4 # a = a * (3+4)

나) 치환문에서 a = a+1의 의미는 무엇인가?

이전의 a 값에 1을 더하고 그 결과를 다시 a에 저장한다.

다) 1+3 = a가 가능하지 않은 이유는 무엇인가?

좌변은 대입 가능한 변수가, 우변은 식이 와야 한다. 우측의 결과 값이 좌측에 저장되어야 하는데 1+3은 이 것이 가능하지 않다.

라) a = b = 0과 a = (b = 0)의 차이는 무엇인가?

a = b = 0 은 0 객체를 b와 a가 참조하도록 한다.
a = (b = 0)은 (b = 0)를 수행하고 그 결과 값을 a에 전달하라는 의미이다. 하지만 파이썬에서는 이것이 가능하지 않다. b=0은 식이 아니고 문으로 취급되기 때문이다. 아래의 실행 예를 보자.
In [24]:
a = b = 0
In [25]:
a = (b = 0)
  File "<ipython-input-25-031033bd14bf>", line 1
    a = (b = 0)
           ^
SyntaxError: invalid syntax

4. import를 사용하는 의미를 간단히 정리해 보자.

외부 모듈을 가져다 쓰는 기능이다. 외부 모듈을 가져오기 할 때, 해당 모듈의 코드가 실행되면서 함수, 클래스, 변수등이 모듈 이름 공간에 등록된다. 한 번 가져오기 한 모듈은 메모리에 존재하며 중복적으로 가져오기를 하지는 않는다. 사용 방법은 다음과 같다.

In [31]:
import math    # 모듈 이름을 현재의 이름 공간으로 가져온다.
math.sin(math.pi/2)
Out[31]:
1.0
In [30]:
import math    # 이미 앞서 가져오기를 수행했기 때문에 아무런 기능을 하지 않는다.
In [32]:
from math import sin, pi   # 모듈의 특정한 이름들만 가져온다.
sin(pi/2)
Out[32]:
1.0
In [35]:
from math import *  # 모듈에 등록된 전체 이름이 현재의 이름 공간으로 저장된다.

cos(pi/4)
Out[35]:
0.7071067811865476

5. 콘솔 입출력에 대한 내용이다. 다음 문제를 풀어 보자.

가) 키보드로부터 숫자를 입력받고 입력받은 수보다 100이 큰 수를 출력해 보자.

In [39]:
n = int(input('type a number : '))
print(n+100)
type a number : 50
150

나) 화면 출력 함수 print( )로 출력 마지막에 줄 바꾸기를 하지 않는 방법은 무엇인가?

In [41]:
print ('first line', end=' ')    # 줄 바꾸기 대신 공백으로 처리
print ('second line')
print ('third line')
first line second line
third line

다) 복잡한 자료형을 출력할 때 사용하는 pprint 모듈의 실행 예를 보이시오.

In [67]:
import pprint

tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', ('parrot', ('fresh fruit',))))))))

pprint.pprint(tup, indent=2)
pprint.pprint(tup, indent=2, depth=4, width=40)
( 'spam',
  ( 'eggs',
    ( 'lumberjack',
      ('knights', ('ni', ('dead', ('parrot', ('fresh fruit',))))))))
( 'spam',
  ( 'eggs',
    ( 'lumberjack',
      ('knights', (...)))))

6. 자료형의 종류에 대한 내용이다. 다음 문제를 풀어 보자.

가) 각각의 자료형의 특징을 정리해 보자.

2.5절 자료형의 종류 참조

나) 문자열과 리스트, 튜플의 특징을 다음 관점에서 간단히 설명하고 실행 예를 보이시오.

  1. 표현 방법
In [77]:
# string
s1 = "python string"
s2 = "python string" "connected"
s3 = "python  \
string connected"
s4 = '''multi line string
line2
line3'''
print (s1)
print (s2)
print (s3)
print (s4)
python string
python stringconnected
python  string connected
multi line string
line2
line3

In [86]:
# list
l1 = []
l2 = [1,2,3]
l3 = ['python', 'rules', 10000]
print (l1, l2, l3)
[] [1, 2, 3] ['python', 'rules', 10000]

In [84]:
# tuple
t1 = ()
t2 = (1,)
t3 = (1,2,3)
print (t1, t2, t3)
() (1,) (1, 2, 3)

  1. 인덱싱(indexing), 3) 슬라이싱(slicing)
In [91]:
s = "python string"
s[0], s[-1], s[1:], s[1:-2], s[::2], s[::-1]
Out[91]:
('p', 'g', 'ython string', 'ython stri', 'pto tig', 'gnirts nohtyp')
In [93]:
l3 = ['python', 'rules', 10000]
l3[0], l3[:2]
Out[93]:
('python', ['python', 'rules'])
In [94]:
t3 = (1,2,3,4,5)
t3[0], t3[:2]
Out[94]:
(1, (1, 2))
  1. 연결, 5) 반복
In [96]:
s+s, s*2
Out[96]:
('python stringpython string', 'python stringpython string')
In [98]:
l3 + l2, l3 * 3
Out[98]:
(['python', 'rules', 10000, 1, 2, 3],
 ['python',
  'rules',
  10000,
  'python',
  'rules',
  10000,
  'python',
  'rules',
  10000])
In [99]:
t3 + t3, t3 * 2
Out[99]:
((1, 2, 3, 4, 5, 1, 2, 3, 4, 5), (1, 2, 3, 4, 5, 1, 2, 3, 4, 5))
  1. 값의 변경
In [103]:
# 리스트만 가능
l3 = ['python', 'rules', 10000]
l3[0] = 100
print (l3)
l3[1:3] = [4,5]
print (l3)
[100, 'rules', 10000]
[100, 4, 5]

다) 사전은 문자열이나 리스트, 튜플과 어떻게 다른지 간단히 정리해 보자.

문자열, 리스트, 튜플은 순서가 있는 자료형으로 순서에 의한 인덱싱, 슬라이싱등이 가능하다. 사전은 순서가 아닌 키에 의해서 값을 검색하는 자료형이다. 2.5.6절 참조.

7. 문자열 s = 'python'에 대해서 다음 문제를 풀어 보자.

가) s[0][0][0]이 어떤 값이 나오는가 보고 이유를 설명해 보자.

In [105]:
s = 'python'
s[0][0][0]       # 파이썬에는 문자 자료형이 없다. 모두 문자열이다. 따라서 인덱싱이 연속적으로 가능하다.
Out[105]:
'p'

나) s[-100], s[100], s[-100:100] 문들을 실행해 보고 실행되는 것과 실행되지 않는 것을 확인 하시오. 그리고 실행되지 않는 경우에는 어떠한 에러 메시지를 내는지 관찰하시오.

In [108]:
s[-100]   # s[100]도 같은 결과
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-108-4f3d3c7c108a> in <module>()
----> 1 s[-100]   # s[100]도 같은 결과

IndexError: string index out of range
In [109]:
s[-100:100]
Out[109]:
'python'

다) s[1:-1]는 어떤 결과를 내는가?

In [110]:
s[1:-1]
Out[110]:
'ytho'

라) s[3:-3]은 어떤 결과를 내는가?

In [111]:
s[3:-3]
Out[111]:
''

8. 다음과 같이 출력되도록 0도부터 360도까지 10도 간격으로 sin() 표를 만들어보자. math 모듈의 sin( ) 함수는 라디안(Radian)을 입력 단위로 받는 것에 주의하시오.

sin(  0) =  0.000
sin( 10) =  0.174
sin( 20) =  0.342
…
sin( 90) =  1.000
sin(100) =  0.985
…
sin(360) = -0.000

출력 양식을 맞추는 문제는 다음 코드를 변형해서 사용한다. 두 개의 값 10, 20.12345를 형식에 맞게 출력하는 예제이다.

>>> print ('{0:3d} : {1:6.3f}'.format(10, 20.12345))
 10 : 20.123
In [112]:
import math

for deg in range(0, 360+1, 10):
    rad = math.radians(deg)
    print ('sin({0:3d}) = {1:6.3f}'.format(deg, math.sin(rad)))
sin(  0) =  0.000
sin( 10) =  0.174
sin( 20) =  0.342
sin( 30) =  0.500
sin( 40) =  0.643
sin( 50) =  0.766
sin( 60) =  0.866
sin( 70) =  0.940
sin( 80) =  0.985
sin( 90) =  1.000
sin(100) =  0.985
sin(110) =  0.940
sin(120) =  0.866
sin(130) =  0.766
sin(140) =  0.643
sin(150) =  0.500
sin(160) =  0.342
sin(170) =  0.174
sin(180) =  0.000
sin(190) = -0.174
sin(200) = -0.342
sin(210) = -0.500
sin(220) = -0.643
sin(230) = -0.766
sin(240) = -0.866
sin(250) = -0.940
sin(260) = -0.985
sin(270) = -1.000
sin(280) = -0.985
sin(290) = -0.940
sin(300) = -0.866
sin(310) = -0.766
sin(320) = -0.643
sin(330) = -0.500
sin(340) = -0.342
sin(350) = -0.174
sin(360) = -0.000

9. 터틀 그래픽을 이용하여 \(0 \sim 2\pi\)범위에서 사인 그래프를 그려 보자.

# ex09.py
import math
from turtle import *

reset()

yamp = 100
for deg in range(0, 361, 10):
    rad = math.radians(deg)
    y = yamp * math.sin(rad)
    goto(rad*50, y)

done()

10. 터틀 그래픽을 이용하여 \(0 \sim 2\pi\) 범위에서 사인과 코사인 그래프를 함께 그려보자.

# ex10.py
import math
from turtle import *

reset()

t1 = Turtle()  # 거북이1
t2 = Turtle()  # 거북이2

yamp = 100
rad = 0
y1 = yamp * math.sin(rad)
y2 = yamp * math.cos(rad)

# 초기 위치로 이동
t1.up(); t2.up()   # 거북이가 지나가도 흔적이 남지 않도록 위로 올린다.
t1.goto(0, y1)
t2.goto(0, y2)
t1.down(); t2.down()  # 다시 거북이 바닥으로..

# 그래프 그리기
for deg in range(0, 361, 10):
    rad = math.radians(deg)
    y1 = yamp * math.sin(rad)
    y2 = yamp * math.cos(rad)
    t1.goto(rad*50, y1)  # 거북이1
    t2.goto(rad*50, y2)  # 거북이2

done()

11. 터틀 그래픽을 이용하여 \(-6 \sim 6\pi\) 범위에서 다음 그래프를 그려 보자. 참고로 가 0인 경우 함수 값은 1이 된다.

\(sin(x) = \frac{sin(x)}{x}\)

# ex11.py
import math
from turtle import *

reset()

t1 = Turtle()

yamp = 100
xscale = 20
rad = 0

# 초기 위치로 이동
t1.up()
x = math.radians(math.degrees(-6*math.pi))
y = yamp * math.sin(x) / x
t1.goto(x*xscale,y)
t1.down()

# sinc 함수 그리기
for deg in range(int(math.degrees(-6*math.pi)), int(math.degrees(6*math.pi))+1, 10):
    x = math.radians(deg)
    if x == 0:
        y = yamp
    else:
        y = yamp * math.sin(x) / x
    t1.goto(x*xscale, y)

done()

12. 다음과 같은 문자열이 주어져 있다.

s = '''We propose to start by making it possible to teach programming
in Python, an existing scripting language, and to focus on creating a
new development environment and teaching materials for it.'''

s.split( )을 하면 이 문자열이 단어 단위로 분리된 문자열 리스트를 얻게 된다. 이 리스트 에 저장된 단어들을 알파벳 순으로 정렬하고(sort 메서드 이용), 각 단어를 순서대로 하 나씩 출력해 보자. 집합 자료형을 이용한다.

In [122]:
s = '''We propose to start by making it possible to teach programming
in Python, an existing scripting language, and to focus on creating a
new development environment and teaching materials for it.'''

word_list = list(set(s.split()))
word_list.sort()
word_list
Out[122]:
['Python,',
 'We',
 'a',
 'an',
 'and',
 'by',
 'creating',
 'development',
 'environment',
 'existing',
 'focus',
 'for',
 'in',
 'it',
 'it.',
 'language,',
 'making',
 'materials',
 'new',
 'on',
 'possible',
 'programming',
 'propose',
 'scripting',
 'start',
 'teach',
 'teaching',
 'to']

13. while 문을 이용하여 1부터 20까지의 홀수를 출력해 보자.

In [114]:
n = 1
while n < 20:
    print(n, end=' ')
    n += 2
1 3 5 7 9 11 13 15 17 19 

14. while 문을 이용하여 20부터 0까지 짝수를 출력해 보자.

In [115]:
n = 20
while n >= 0:
    print(n, end=' ')
    n -= 2
20 18 16 14 12 10 8 6 4 2 0 

15. while 문을 이용하여 1부터 100까지의 홀수의 합을 계산해 보자.

In [119]:
acc = 0
n = 1
while n < 100:
    acc += n
    n += 2

print(acc)
2500

16. 다음 코드를 시험해 보고 결과를 말해 보자.

>>> for el in range(-10, 260):
exec('x = {0}'.format(el))
exec('y = {0}'.format(el))
print(el, x is y)

참고로 exec( ) 함수는 문자열로 표현된 파이썬 문을 실행한다.

>>> exec('a = 1')
>>> exec('a = a + 1')
>>> a
2
In [121]:
# -5 ~ 256 가지의 수치 객체는 1개가 공유된다.
for el in range(-10, 260):
    exec('x = {0}'.format(el))
    exec('y = {0}'.format(el))
    print(el, x is y)
-10 False
-9 False
-8 False
-7 False
-6 False
-5 True
-4 True
-3 True
-2 True
-1 True
0 True
1 True
2 True
3 True
4 True
5 True
6 True
7 True
8 True
9 True
10 True
11 True
12 True
13 True
14 True
15 True
16 True
17 True
18 True
19 True
20 True
21 True
22 True
23 True
24 True
25 True
26 True
27 True
28 True
29 True
30 True
31 True
32 True
33 True
34 True
35 True
36 True
37 True
38 True
39 True
40 True
41 True
42 True
43 True
44 True
45 True
46 True
47 True
48 True
49 True
50 True
51 True
52 True
53 True
54 True
55 True
56 True
57 True
58 True
59 True
60 True
61 True
62 True
63 True
64 True
65 True
66 True
67 True
68 True
69 True
70 True
71 True
72 True
73 True
74 True
75 True
76 True
77 True
78 True
79 True
80 True
81 True
82 True
83 True
84 True
85 True
86 True
87 True
88 True
89 True
90 True
91 True
92 True
93 True
94 True
95 True
96 True
97 True
98 True
99 True
100 True
101 True
102 True
103 True
104 True
105 True
106 True
107 True
108 True
109 True
110 True
111 True
112 True
113 True
114 True
115 True
116 True
117 True
118 True
119 True
120 True
121 True
122 True
123 True
124 True
125 True
126 True
127 True
128 True
129 True
130 True
131 True
132 True
133 True
134 True
135 True
136 True
137 True
138 True
139 True
140 True
141 True
142 True
143 True
144 True
145 True
146 True
147 True
148 True
149 True
150 True
151 True
152 True
153 True
154 True
155 True
156 True
157 True
158 True
159 True
160 True
161 True
162 True
163 True
164 True
165 True
166 True
167 True
168 True
169 True
170 True
171 True
172 True
173 True
174 True
175 True
176 True
177 True
178 True
179 True
180 True
181 True
182 True
183 True
184 True
185 True
186 True
187 True
188 True
189 True
190 True
191 True
192 True
193 True
194 True
195 True
196 True
197 True
198 True
199 True
200 True
201 True
202 True
203 True
204 True
205 True
206 True
207 True
208 True
209 True
210 True
211 True
212 True
213 True
214 True
215 True
216 True
217 True
218 True
219 True
220 True
221 True
222 True
223 True
224 True
225 True
226 True
227 True
228 True
229 True
230 True
231 True
232 True
233 True
234 True
235 True
236 True
237 True
238 True
239 True
240 True
241 True
242 True
243 True
244 True
245 True
246 True
247 True
248 True
249 True
250 True
251 True
252 True
253 True
254 True
255 True
256 True
257 False
258 False
259 False

In []: