├── .gitignore
├── 02장.ipynb
├── 03장.ipynb
├── 04장.ipynb
├── 05장.ipynb
├── 06장.ipynb
├── 07장.ipynb
├── 08장.ipynb
├── 09장.ipynb
├── 10장.ipynb
├── 11장.ipynb
├── 12장.ipynb
├── 13장.ipynb
├── 14장.ipynb
├── 15장.ipynb
├── 16장.ipynb
├── 17장.ipynb
├── 18장.ipynb
├── 19장.ipynb
├── 20장.ipynb
├── 21장.ipynb
├── 22장.ipynb
├── 23장.ipynb
├── 24장.ipynb
├── 25장.ipynb
├── 26장.ipynb
├── LICENSE
├── README.md
├── TitanicPassengers.csv
├── US_temperatures.csv
├── bm_results2012.csv
├── circle.py
├── dentalFormulas.csv
├── diet.csv
├── figure_13-19.png
├── global-fossil-fuel-consumption.csv
├── launcherData.csv
├── midWestHousingPrices.csv
├── quiz1grades.txt
├── springData.csv
└── wwc2019_q-f.csv
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
--------------------------------------------------------------------------------
/03장.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "GBYWNrldlqeG"
7 | },
8 | "source": [
9 | "
\n",
10 | " \n",
11 | " |
"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "metadata": {
17 | "id": "gRbvYbZtlu47"
18 | },
19 | "source": [
20 | "# 3장 간단한 수치 프로그램"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {
26 | "id": "sGsS514Sm94L"
27 | },
28 | "source": [
29 | "## 3.1 완전 열거"
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {
35 | "id": "TZc6RCl3U24D"
36 | },
37 | "source": [
38 | "예제 3-1 완전 열거 방식으로 세제곱근 구하기"
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": null,
44 | "metadata": {
45 | "colab": {
46 | "base_uri": "https://localhost:8080/"
47 | },
48 | "id": "rETHAcZWlj5t",
49 | "outputId": "def7d44b-fe29-4a8b-dcfb-3435e2846ae0"
50 | },
51 | "outputs": [
52 | {
53 | "name": "stdout",
54 | "output_type": "stream",
55 | "text": [
56 | "정수를 입력하세요: 7406961012236344616\n",
57 | "7406961012236344616 의 세제곱근은 1949306 입니다\n"
58 | ]
59 | }
60 | ],
61 | "source": [
62 | "#정수 세제곱근을 찾습니다\n",
63 | "x = int(input('정수를 입력하세요: '))\n",
64 | "ans = 0\n",
65 | "while ans**3 < abs(x):\n",
66 | " ans = ans + 1\n",
67 | "if ans**3 != abs(x):\n",
68 | " print(x, '는 완전한 세제곱수가 아닙니다')\n",
69 | "else:\n",
70 | " if x < 0:\n",
71 | " ans = -ans\n",
72 | " print(x,'의 세제곱근은', ans, '입니다')"
73 | ]
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": null,
78 | "metadata": {
79 | "colab": {
80 | "base_uri": "https://localhost:8080/"
81 | },
82 | "id": "W1HOkNc4qz5p",
83 | "outputId": "9d81d4a8-8833-4931-ac59-8ac2e81af184"
84 | },
85 | "outputs": [
86 | {
87 | "name": "stdout",
88 | "output_type": "stream",
89 | "text": [
90 | "양의 정수를 입력하세요: 10000000\n",
91 | "10000000\n"
92 | ]
93 | }
94 | ],
95 | "source": [
96 | "max_val = int(input('양의 정수를 입력하세요: '))\n",
97 | "i = 0\n",
98 | "while i < max_val:\n",
99 | " i = i + 1\n",
100 | "print(i)"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {
106 | "id": "6jmLOYRpVFxd"
107 | },
108 | "source": [
109 | "예제 3-2 완전 열거 방식을 사용한 소수 테스트"
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": null,
115 | "metadata": {
116 | "colab": {
117 | "base_uri": "https://localhost:8080/"
118 | },
119 | "id": "Fi8_VgtB8J2r",
120 | "outputId": "37131042-64ac-4b98-f1c9-1dc0279e70dd"
121 | },
122 | "outputs": [
123 | {
124 | "name": "stdout",
125 | "output_type": "stream",
126 | "text": [
127 | "2보다 큰 정수를 입력하세요: 111119\n",
128 | "111119 는 소수입니다\n"
129 | ]
130 | }
131 | ],
132 | "source": [
133 | "# 2보다 큰 정수가 소수인지 테스트합니다. 소수가 아니면 가장 작은 제수를 출력합니다.\n",
134 | "x = int(input('2보다 큰 정수를 입력하세요: '))\n",
135 | "smallest_divisor = None\n",
136 | "for guess in range(2, x):\n",
137 | " if x%guess == 0:\n",
138 | " smallest_divisor = guess\n",
139 | " break\n",
140 | "if smallest_divisor != None:\n",
141 | " print(x, '의 가장 작은 제수는', smallest_divisor, '입니다')\n",
142 | "else:\n",
143 | " print(x, '는 소수입니다')"
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "metadata": {
149 | "id": "Qqa4Zs8PAVtT"
150 | },
151 | "source": [
152 | "**뇌풀기 문제**"
153 | ]
154 | },
155 | {
156 | "cell_type": "code",
157 | "execution_count": null,
158 | "metadata": {
159 | "colab": {
160 | "base_uri": "https://localhost:8080/"
161 | },
162 | "id": "VbRkQ72JA7-d",
163 | "outputId": "09fe7bfc-69de-4f89-b871-63a399bdd3c5"
164 | },
165 | "outputs": [
166 | {
167 | "name": "stdout",
168 | "output_type": "stream",
169 | "text": [
170 | "2보다 큰 정수를 입력하세요: 100\n",
171 | "100 의 가장 큰 제수는 50 입니다\n"
172 | ]
173 | }
174 | ],
175 | "source": [
176 | "# 2보다 큰 정수가 소수인지 테스트합니다. 소수가 아니면 가장 작은 제수를 출력합니다.\n",
177 | "x = int(input('2보다 큰 정수를 입력하세요: '))\n",
178 | "largest_divisor = None\n",
179 | "for guess in range(2, x):\n",
180 | " if x%guess == 0:\n",
181 | " largest_divisor = int(x/guess)\n",
182 | " break\n",
183 | "if largest_divisor != None:\n",
184 | " print(x, '의 가장 큰 제수는', largest_divisor, '입니다')\n",
185 | "else:\n",
186 | " print(x, '는 소수입니다')"
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {
192 | "id": "hhUd0KE0VKoQ"
193 | },
194 | "source": [
195 | "예제 3-3 더 효율적인 소수 테스트"
196 | ]
197 | },
198 | {
199 | "cell_type": "code",
200 | "execution_count": null,
201 | "metadata": {
202 | "colab": {
203 | "base_uri": "https://localhost:8080/"
204 | },
205 | "id": "KpSQO-J2A2_o",
206 | "outputId": "6b197313-2d85-4c20-a281-42f0422a5b40"
207 | },
208 | "outputs": [
209 | {
210 | "name": "stdout",
211 | "output_type": "stream",
212 | "text": [
213 | "2보다 큰 정수를 입력하세요: 111119\n",
214 | "111119 는 소수입니다\n"
215 | ]
216 | }
217 | ],
218 | "source": [
219 | "# 2보다 큰 정수가 소수인지 테스트합니다. 소수가 아니면 가장 작은 제수를 출력합니다.\n",
220 | "x = int(input('2보다 큰 정수를 입력하세요: '))\n",
221 | "smallest_divisor = None\n",
222 | "if x%2 == 0:\n",
223 | " smallest_divisor = 2\n",
224 | "else:\n",
225 | " for guess in range(3, x, 2):\n",
226 | " if x%guess == 0:\n",
227 | " smallest_divisor = guess\n",
228 | " break\n",
229 | "if smallest_divisor != None:\n",
230 | " print(x, '의 가장 작은 제수는', smallest_divisor, '입니다')\n",
231 | "else:\n",
232 | " print(x, '는 소수입니다')"
233 | ]
234 | },
235 | {
236 | "cell_type": "markdown",
237 | "metadata": {
238 | "id": "oPcI0MrMy4AD"
239 | },
240 | "source": [
241 | "**뇌풀기 문제**"
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": null,
247 | "metadata": {
248 | "colab": {
249 | "base_uri": "https://localhost:8080/"
250 | },
251 | "id": "MTvDd_pMy3Hd",
252 | "outputId": "b689d48b-5224-41f1-dc12-43f479bc13b2"
253 | },
254 | "outputs": [
255 | {
256 | "name": "stdout",
257 | "output_type": "stream",
258 | "text": [
259 | "정수를 입력하세요: 4\n",
260 | "1 < pwr < 6 사이에서 4 == root**pwr을 만족하는 정수 root와 pwr은\n",
261 | "root: -2 pwr: 2\n",
262 | "root: 2 pwr: 2\n",
263 | "입니다\n"
264 | ]
265 | }
266 | ],
267 | "source": [
268 | "x = int(input('정수를 입력하세요: '))\n",
269 | "print('1 < pwr < 6 사이에서 ', x, '== root**pwr을 만족하는 정수 root와 pwr은')\n",
270 | "ans_flag = 0\n",
271 | "for pwr in range(2, 6):\n",
272 | " root = 2\n",
273 | " while root**pwr < abs(x):\n",
274 | " root = root + 1\n",
275 | " if (-root)**pwr == x:\n",
276 | " ans_flag = 1\n",
277 | " print('root:', -root, 'pwr:', pwr)\n",
278 | " if root**pwr == x:\n",
279 | " ans_flag = 1\n",
280 | " print('root:', root, 'pwr:', pwr)\n",
281 | "if ans_flag == 1:\n",
282 | " print('입니다')\n",
283 | "else:\n",
284 | " print('없습니다')"
285 | ]
286 | },
287 | {
288 | "cell_type": "markdown",
289 | "metadata": {
290 | "id": "WDYHJPkXzEDp"
291 | },
292 | "source": [
293 | "**뇌풀기 문제**"
294 | ]
295 | },
296 | {
297 | "cell_type": "code",
298 | "execution_count": null,
299 | "metadata": {
300 | "colab": {
301 | "base_uri": "https://localhost:8080/"
302 | },
303 | "id": "3sIUPcC7sr_x",
304 | "outputId": "efd86002-b415-46fb-933d-8f15f58de68b"
305 | },
306 | "outputs": [
307 | {
308 | "name": "stdout",
309 | "output_type": "stream",
310 | "text": [
311 | "76125\n"
312 | ]
313 | }
314 | ],
315 | "source": [
316 | "sum = 0\n",
317 | "# 3~1000 사이의 홀수를 반복합니다.\n",
318 | "for odd in range(3, 1000, 2):\n",
319 | " sum = sum + odd\n",
320 | " for n in range(3, odd, 2):\n",
321 | " if odd%n == 0: # 다른 홀수로 나누어 떨어지면 소수가 아닙니다.\n",
322 | " sum = sum - odd\n",
323 | " break\n",
324 | "print(sum)"
325 | ]
326 | },
327 | {
328 | "cell_type": "markdown",
329 | "metadata": {
330 | "id": "AUZwjLdmdQc9"
331 | },
332 | "source": [
333 | "## 2.2 근사 해법과 이분 검색"
334 | ]
335 | },
336 | {
337 | "cell_type": "markdown",
338 | "metadata": {
339 | "id": "Xi966CfHVO1k"
340 | },
341 | "source": [
342 | "예제 3-4 완전 열거를 사용한 제곱근의 근삿값 구하기"
343 | ]
344 | },
345 | {
346 | "cell_type": "code",
347 | "execution_count": null,
348 | "metadata": {
349 | "colab": {
350 | "base_uri": "https://localhost:8080/"
351 | },
352 | "id": "IZ1hnPWBdUqv",
353 | "outputId": "5befe030-c945-49de-cbf1-956e6035b1f3"
354 | },
355 | "outputs": [
356 | {
357 | "name": "stdout",
358 | "output_type": "stream",
359 | "text": [
360 | "추측 횟수 = 49990\n",
361 | "4.999000000001688 (은)는 25 의 제곱근에 가깝습니다\n"
362 | ]
363 | }
364 | ],
365 | "source": [
366 | "x = 25\n",
367 | "epsilon = 0.01\n",
368 | "step = epsilon**2\n",
369 | "num_guesses = 0\n",
370 | "ans = 0.0\n",
371 | "while abs(ans**2 - x) >= epsilon and ans <= x:\n",
372 | " ans += step\n",
373 | " num_guesses += 1\n",
374 | "print('추측 횟수 =', num_guesses)\n",
375 | "if abs(ans**2 - x) >= epsilon:\n",
376 | " print(x, '의 제곱근을 찾지 못했습니다')\n",
377 | "else:\n",
378 | " print(ans, '(은)는', x, '의 제곱근에 가깝습니다')"
379 | ]
380 | },
381 | {
382 | "cell_type": "code",
383 | "execution_count": null,
384 | "metadata": {
385 | "colab": {
386 | "base_uri": "https://localhost:8080/"
387 | },
388 | "id": "f7GDfmPUn9aZ",
389 | "outputId": "563d7574-7026-4f56-96de-b67fb2f644c9"
390 | },
391 | "outputs": [
392 | {
393 | "name": "stdout",
394 | "output_type": "stream",
395 | "text": [
396 | "추측 횟수 = 2501\n",
397 | "0.25 의 제곱근을 찾지 못했습니다\n"
398 | ]
399 | }
400 | ],
401 | "source": [
402 | "x = 0.25\n",
403 | "epsilon = 0.01\n",
404 | "step = epsilon**2\n",
405 | "num_guesses = 0\n",
406 | "ans = 0.0\n",
407 | "while abs(ans**2 - x) >= epsilon and ans <= x:\n",
408 | " ans += step\n",
409 | " num_guesses += 1\n",
410 | "print('추측 횟수 =', num_guesses)\n",
411 | "if abs(ans**2 - x) >= epsilon:\n",
412 | " print(x, '의 제곱근을 찾지 못했습니다')\n",
413 | "else:\n",
414 | " print(ans, '(은)는', x, '의 제곱근에 가깝습니다')"
415 | ]
416 | },
417 | {
418 | "cell_type": "code",
419 | "execution_count": null,
420 | "metadata": {
421 | "colab": {
422 | "base_uri": "https://localhost:8080/"
423 | },
424 | "id": "sVuRI6PHq9lX",
425 | "outputId": "787dbc7e-b35b-4dd9-c984-bc41b0704f7e"
426 | },
427 | "outputs": [
428 | {
429 | "name": "stdout",
430 | "output_type": "stream",
431 | "text": [
432 | "추측 횟수 = 4899\n",
433 | "0.48989999999996237 (은)는 0.25 의 제곱근에 가깝습니다\n"
434 | ]
435 | }
436 | ],
437 | "source": [
438 | "x = 0.25\n",
439 | "epsilon = 0.01\n",
440 | "step = epsilon**2\n",
441 | "num_guesses = 0\n",
442 | "ans = 0.0\n",
443 | "while abs(ans**2 - x) >= epsilon and ans*ans <= x:\n",
444 | " ans += step\n",
445 | " num_guesses += 1\n",
446 | "print('추측 횟수 =', num_guesses)\n",
447 | "if abs(ans**2 - x) >= epsilon:\n",
448 | " print(x, '의 제곱근을 찾지 못했습니다')\n",
449 | "else:\n",
450 | " print(ans, '(은)는', x, '의 제곱근에 가깝습니다')"
451 | ]
452 | },
453 | {
454 | "cell_type": "code",
455 | "execution_count": null,
456 | "metadata": {
457 | "colab": {
458 | "base_uri": "https://localhost:8080/"
459 | },
460 | "id": "iZ0PPr9jsYYS",
461 | "outputId": "12b103ed-6a8c-4554-cdd3-2170201fa863"
462 | },
463 | "outputs": [
464 | {
465 | "name": "stdout",
466 | "output_type": "stream",
467 | "text": [
468 | "추측 횟수 = 3513631\n",
469 | "123456 의 제곱근을 찾지 못했습니다\n"
470 | ]
471 | }
472 | ],
473 | "source": [
474 | "x = 123456\n",
475 | "epsilon = 0.01\n",
476 | "step = epsilon**2\n",
477 | "num_guesses = 0\n",
478 | "ans = 0.0\n",
479 | "while abs(ans**2 - x) >= epsilon and ans*ans <= x:\n",
480 | " ans += step\n",
481 | " num_guesses += 1\n",
482 | "print('추측 횟수 =', num_guesses)\n",
483 | "if abs(ans**2 - x) >= epsilon:\n",
484 | " print(x, '의 제곱근을 찾지 못했습니다')\n",
485 | "else:\n",
486 | " print(ans, '(은)는', x, '의 제곱근에 가깝습니다')"
487 | ]
488 | },
489 | {
490 | "cell_type": "code",
491 | "execution_count": null,
492 | "metadata": {
493 | "colab": {
494 | "base_uri": "https://localhost:8080/"
495 | },
496 | "id": "Dn4p-J-csZjh",
497 | "outputId": "956019f6-600c-4d78-f99b-9c6374992930"
498 | },
499 | "outputs": [
500 | {
501 | "name": "stdout",
502 | "output_type": "stream",
503 | "text": [
504 | "추측 횟수 = 351363047\n",
505 | "351.36304620491023 (은)는 123456 의 제곱근에 가깝습니다\n"
506 | ]
507 | }
508 | ],
509 | "source": [
510 | "x = 123456\n",
511 | "epsilon = 0.01\n",
512 | "step = epsilon**3\n",
513 | "num_guesses = 0\n",
514 | "ans = 0.0\n",
515 | "while abs(ans**2 - x) >= epsilon and ans*ans <= x:\n",
516 | " ans += step\n",
517 | " num_guesses += 1\n",
518 | "print('추측 횟수 =', num_guesses)\n",
519 | "if abs(ans**2 - x) >= epsilon:\n",
520 | " print(x, '의 제곱근을 찾지 못했습니다')\n",
521 | "else:\n",
522 | " print(ans, '(은)는', x, '의 제곱근에 가깝습니다')"
523 | ]
524 | },
525 | {
526 | "cell_type": "markdown",
527 | "metadata": {
528 | "id": "UXHJwIJ2UhRf"
529 | },
530 | "source": [
531 | "예제 3-5 이분 검색을 사용한 제곱근의 근삿값 찾기"
532 | ]
533 | },
534 | {
535 | "cell_type": "code",
536 | "execution_count": null,
537 | "metadata": {
538 | "colab": {
539 | "base_uri": "https://localhost:8080/"
540 | },
541 | "id": "R-UBZnE1uvz1",
542 | "outputId": "60bbffbb-2fc6-4d0d-c340-6dd3654d5230"
543 | },
544 | "outputs": [
545 | {
546 | "name": "stdout",
547 | "output_type": "stream",
548 | "text": [
549 | "low = 0 high = 25 ans = 12.5\n",
550 | "low = 0 high = 12.5 ans = 6.25\n",
551 | "low = 0 high = 6.25 ans = 3.125\n",
552 | "low = 3.125 high = 6.25 ans = 4.6875\n",
553 | "low = 4.6875 high = 6.25 ans = 5.46875\n",
554 | "low = 4.6875 high = 5.46875 ans = 5.078125\n",
555 | "low = 4.6875 high = 5.078125 ans = 4.8828125\n",
556 | "low = 4.8828125 high = 5.078125 ans = 4.98046875\n",
557 | "low = 4.98046875 high = 5.078125 ans = 5.029296875\n",
558 | "low = 4.98046875 high = 5.029296875 ans = 5.0048828125\n",
559 | "low = 4.98046875 high = 5.0048828125 ans = 4.99267578125\n",
560 | "low = 4.99267578125 high = 5.0048828125 ans = 4.998779296875\n",
561 | "low = 4.998779296875 high = 5.0048828125 ans = 5.0018310546875\n",
562 | "추측 횟수 = 13\n",
563 | "5.00030517578125 (은)는 25 의 제곱근에 가깝습니다\n"
564 | ]
565 | }
566 | ],
567 | "source": [
568 | "x = 25\n",
569 | "epsilon = 0.01\n",
570 | "num_guesses, low = 0, 0\n",
571 | "high = max(1, x)\n",
572 | "ans = (high + low)/2\n",
573 | "while abs(ans**2 - x) >= epsilon:\n",
574 | " print('low =', low, 'high =', high, 'ans =', ans)\n",
575 | " num_guesses += 1\n",
576 | " if ans**2 < x:\n",
577 | " low = ans\n",
578 | " else:\n",
579 | " high = ans\n",
580 | " ans = (high + low)/2\n",
581 | "print('추측 횟수 =', num_guesses)\n",
582 | "print(ans, '(은)는', x, '의 제곱근에 가깝습니다')"
583 | ]
584 | },
585 | {
586 | "cell_type": "code",
587 | "execution_count": null,
588 | "metadata": {
589 | "colab": {
590 | "base_uri": "https://localhost:8080/"
591 | },
592 | "id": "0ft_68vnLHzz",
593 | "outputId": "1c08d5de-bba0-4933-cf87-507a4631c772"
594 | },
595 | "outputs": [
596 | {
597 | "name": "stdout",
598 | "output_type": "stream",
599 | "text": [
600 | "low = 0 high = 123456 ans = 61728.0\n",
601 | "low = 0 high = 61728.0 ans = 30864.0\n",
602 | "low = 0 high = 30864.0 ans = 15432.0\n",
603 | "low = 0 high = 15432.0 ans = 7716.0\n",
604 | "low = 0 high = 7716.0 ans = 3858.0\n",
605 | "low = 0 high = 3858.0 ans = 1929.0\n",
606 | "low = 0 high = 1929.0 ans = 964.5\n",
607 | "low = 0 high = 964.5 ans = 482.25\n",
608 | "low = 0 high = 482.25 ans = 241.125\n",
609 | "low = 241.125 high = 482.25 ans = 361.6875\n",
610 | "low = 241.125 high = 361.6875 ans = 301.40625\n",
611 | "low = 301.40625 high = 361.6875 ans = 331.546875\n",
612 | "low = 331.546875 high = 361.6875 ans = 346.6171875\n",
613 | "low = 346.6171875 high = 361.6875 ans = 354.15234375\n",
614 | "low = 346.6171875 high = 354.15234375 ans = 350.384765625\n",
615 | "low = 350.384765625 high = 354.15234375 ans = 352.2685546875\n",
616 | "low = 350.384765625 high = 352.2685546875 ans = 351.32666015625\n",
617 | "low = 351.32666015625 high = 352.2685546875 ans = 351.797607421875\n",
618 | "low = 351.32666015625 high = 351.797607421875 ans = 351.5621337890625\n",
619 | "low = 351.32666015625 high = 351.5621337890625 ans = 351.44439697265625\n",
620 | "low = 351.32666015625 high = 351.44439697265625 ans = 351.3855285644531\n",
621 | "low = 351.32666015625 high = 351.3855285644531 ans = 351.35609436035156\n",
622 | "low = 351.35609436035156 high = 351.3855285644531 ans = 351.37081146240234\n",
623 | "low = 351.35609436035156 high = 351.37081146240234 ans = 351.36345291137695\n",
624 | "low = 351.35609436035156 high = 351.36345291137695 ans = 351.35977363586426\n",
625 | "low = 351.35977363586426 high = 351.36345291137695 ans = 351.3616132736206\n",
626 | "low = 351.3616132736206 high = 351.36345291137695 ans = 351.3625330924988\n",
627 | "low = 351.3625330924988 high = 351.36345291137695 ans = 351.36299300193787\n",
628 | "low = 351.36299300193787 high = 351.36345291137695 ans = 351.3632229566574\n",
629 | "low = 351.36299300193787 high = 351.3632229566574 ans = 351.36310797929764\n",
630 | "추측 횟수 = 30\n",
631 | "351.36305049061775 (은)는 123456 의 제곱근에 가깝습니다\n"
632 | ]
633 | }
634 | ],
635 | "source": [
636 | "x = 123456\n",
637 | "epsilon = 0.01\n",
638 | "num_guesses, low = 0, 0\n",
639 | "high = max(1, x)\n",
640 | "ans = (high + low)/2\n",
641 | "while abs(ans**2 - x) >= epsilon:\n",
642 | " print('low =', low, 'high =', high, 'ans =', ans)\n",
643 | " num_guesses += 1\n",
644 | " if ans**2 < x:\n",
645 | " low = ans\n",
646 | " else:\n",
647 | " high = ans\n",
648 | " ans = (high + low)/2\n",
649 | "print('추측 횟수 =', num_guesses)\n",
650 | "print(ans, '(은)는', x, '의 제곱근에 가깝습니다')"
651 | ]
652 | },
653 | {
654 | "cell_type": "code",
655 | "execution_count": null,
656 | "metadata": {
657 | "colab": {
658 | "base_uri": "https://localhost:8080/"
659 | },
660 | "id": "LHbTCxyhN23d",
661 | "outputId": "43a30fde-6e10-47f0-90a1-f21cfd532198"
662 | },
663 | "outputs": [
664 | {
665 | "name": "stdout",
666 | "output_type": "stream",
667 | "text": [
668 | "low = 0 high = 123456789 ans = 61728394.5\n",
669 | "low = 0 high = 61728394.5 ans = 30864197.25\n",
670 | "low = 0 high = 30864197.25 ans = 15432098.625\n",
671 | "low = 0 high = 15432098.625 ans = 7716049.3125\n",
672 | "low = 0 high = 7716049.3125 ans = 3858024.65625\n",
673 | "low = 0 high = 3858024.65625 ans = 1929012.328125\n",
674 | "low = 0 high = 1929012.328125 ans = 964506.1640625\n",
675 | "low = 0 high = 964506.1640625 ans = 482253.08203125\n",
676 | "low = 0 high = 482253.08203125 ans = 241126.541015625\n",
677 | "low = 0 high = 241126.541015625 ans = 120563.2705078125\n",
678 | "low = 0 high = 120563.2705078125 ans = 60281.63525390625\n",
679 | "low = 0 high = 60281.63525390625 ans = 30140.817626953125\n",
680 | "low = 0 high = 30140.817626953125 ans = 15070.408813476562\n",
681 | "low = 0 high = 15070.408813476562 ans = 7535.204406738281\n",
682 | "low = 7535.204406738281 high = 15070.408813476562 ans = 11302.806610107422\n",
683 | "low = 7535.204406738281 high = 11302.806610107422 ans = 9419.005508422852\n",
684 | "low = 9419.005508422852 high = 11302.806610107422 ans = 10360.906059265137\n",
685 | "low = 10360.906059265137 high = 11302.806610107422 ans = 10831.85633468628\n",
686 | "low = 10831.85633468628 high = 11302.806610107422 ans = 11067.33147239685\n",
687 | "low = 11067.33147239685 high = 11302.806610107422 ans = 11185.069041252136\n",
688 | "low = 11067.33147239685 high = 11185.069041252136 ans = 11126.200256824493\n",
689 | "low = 11067.33147239685 high = 11126.200256824493 ans = 11096.765864610672\n",
690 | "low = 11096.765864610672 high = 11126.200256824493 ans = 11111.483060717583\n",
691 | "low = 11096.765864610672 high = 11111.483060717583 ans = 11104.124462664127\n",
692 | "low = 11104.124462664127 high = 11111.483060717583 ans = 11107.803761690855\n",
693 | "low = 11107.803761690855 high = 11111.483060717583 ans = 11109.643411204219\n",
694 | "low = 11109.643411204219 high = 11111.483060717583 ans = 11110.5632359609\n",
695 | "low = 11110.5632359609 high = 11111.483060717583 ans = 11111.023148339242\n",
696 | "low = 11111.023148339242 high = 11111.483060717583 ans = 11111.253104528412\n",
697 | "low = 11111.023148339242 high = 11111.253104528412 ans = 11111.138126433827\n",
698 | "low = 11111.023148339242 high = 11111.138126433827 ans = 11111.080637386534\n",
699 | "low = 11111.080637386534 high = 11111.138126433827 ans = 11111.10938191018\n",
700 | "low = 11111.10938191018 high = 11111.138126433827 ans = 11111.123754172004\n",
701 | "low = 11111.10938191018 high = 11111.123754172004 ans = 11111.116568041092\n",
702 | "low = 11111.10938191018 high = 11111.116568041092 ans = 11111.112974975636\n",
703 | "low = 11111.10938191018 high = 11111.112974975636 ans = 11111.111178442909\n",
704 | "low = 11111.10938191018 high = 11111.111178442909 ans = 11111.110280176545\n",
705 | "low = 11111.110280176545 high = 11111.111178442909 ans = 11111.110729309727\n",
706 | "low = 11111.110729309727 high = 11111.111178442909 ans = 11111.110953876318\n",
707 | "low = 11111.110953876318 high = 11111.111178442909 ans = 11111.111066159614\n",
708 | "low = 11111.110953876318 high = 11111.111066159614 ans = 11111.111010017965\n",
709 | "low = 11111.111010017965 high = 11111.111066159614 ans = 11111.11103808879\n",
710 | "low = 11111.11103808879 high = 11111.111066159614 ans = 11111.1110521242\n",
711 | "low = 11111.1110521242 high = 11111.111066159614 ans = 11111.111059141907\n",
712 | "low = 11111.111059141907 high = 11111.111066159614 ans = 11111.111062650762\n",
713 | "추측 횟수 = 45\n",
714 | "11111.111060896335 (은)는 123456789 의 제곱근에 가깝습니다\n"
715 | ]
716 | }
717 | ],
718 | "source": [
719 | "x = 123456789\n",
720 | "epsilon = 0.01\n",
721 | "num_guesses, low = 0, 0\n",
722 | "high = max(1, x)\n",
723 | "ans = (high + low)/2\n",
724 | "while abs(ans**2 - x) >= epsilon:\n",
725 | " print('low =', low, 'high =', high, 'ans =', ans)\n",
726 | " num_guesses += 1\n",
727 | " if ans**2 < x:\n",
728 | " low = ans\n",
729 | " else:\n",
730 | " high = ans\n",
731 | " ans = (high + low)/2\n",
732 | "print('추측 횟수 =', num_guesses)\n",
733 | "print(ans, '(은)는', x, '의 제곱근에 가깝습니다')"
734 | ]
735 | },
736 | {
737 | "cell_type": "markdown",
738 | "metadata": {
739 | "id": "rzlNJZKAUTFJ"
740 | },
741 | "source": [
742 | "이분 검색을 사용한 세제곱근의 근삿값 찾기"
743 | ]
744 | },
745 | {
746 | "cell_type": "code",
747 | "execution_count": null,
748 | "metadata": {
749 | "colab": {
750 | "base_uri": "https://localhost:8080/"
751 | },
752 | "id": "5xd10pkuUEuc",
753 | "outputId": "a0f823f3-e088-46da-90e4-611eeb91f00c"
754 | },
755 | "outputs": [
756 | {
757 | "name": "stdout",
758 | "output_type": "stream",
759 | "text": [
760 | "low = 0 high = 27 ans = 13.5\n",
761 | "low = 0 high = 13.5 ans = 6.75\n",
762 | "low = 0 high = 6.75 ans = 3.375\n",
763 | "low = 0 high = 3.375 ans = 1.6875\n",
764 | "low = 1.6875 high = 3.375 ans = 2.53125\n",
765 | "low = 2.53125 high = 3.375 ans = 2.953125\n",
766 | "low = 2.953125 high = 3.375 ans = 3.1640625\n",
767 | "low = 2.953125 high = 3.1640625 ans = 3.05859375\n",
768 | "low = 2.953125 high = 3.05859375 ans = 3.005859375\n",
769 | "low = 2.953125 high = 3.005859375 ans = 2.9794921875\n",
770 | "low = 2.9794921875 high = 3.005859375 ans = 2.99267578125\n",
771 | "low = 2.99267578125 high = 3.005859375 ans = 2.999267578125\n",
772 | "low = 2.999267578125 high = 3.005859375 ans = 3.0025634765625\n",
773 | "low = 2.999267578125 high = 3.0025634765625 ans = 3.00091552734375\n",
774 | "추측 횟수 = 14\n",
775 | "3.000091552734375 (은)는 27 의 세제곱근에 가깝습니다\n"
776 | ]
777 | }
778 | ],
779 | "source": [
780 | "x = 27\n",
781 | "epsilon = 0.01\n",
782 | "num_guesses, low = 0, 0\n",
783 | "high = max(1, x)\n",
784 | "ans = (high + low)/2\n",
785 | "while abs(ans**3 - x) >= epsilon:\n",
786 | " print('low =', low, 'high =', high, 'ans =', ans)\n",
787 | " num_guesses += 1\n",
788 | " if ans**3 < x:\n",
789 | " low = ans\n",
790 | " else:\n",
791 | " high = ans\n",
792 | " ans = (high + low)/2\n",
793 | "print('추측 횟수 =', num_guesses)\n",
794 | "print(ans, '(은)는', x, '의 세제곱근에 가깝습니다')"
795 | ]
796 | },
797 | {
798 | "cell_type": "markdown",
799 | "metadata": {
800 | "id": "ihmdt9kHUPyG"
801 | },
802 | "source": [
803 | "예제 3-6 이분 검색을 사용하여 밑이 2인 로그의 근삿값 찾기"
804 | ]
805 | },
806 | {
807 | "cell_type": "code",
808 | "execution_count": null,
809 | "metadata": {
810 | "colab": {
811 | "base_uri": "https://localhost:8080/"
812 | },
813 | "id": "gx5C4WFbN5nO",
814 | "outputId": "dde13b66-3b58-4125-95c6-20d6cef71759"
815 | },
816 | "outputs": [
817 | {
818 | "name": "stdout",
819 | "output_type": "stream",
820 | "text": [
821 | "3.0 (은)는 8 의 밑이 2인 로그에 가깝습니다\n"
822 | ]
823 | }
824 | ],
825 | "source": [
826 | "x = 8\n",
827 | "# ans의 하한값을 찾습니다\n",
828 | "lower_bound = 0\n",
829 | "while 2**lower_bound < x:\n",
830 | " lower_bound += 1\n",
831 | "low = lower_bound -1\n",
832 | "high = lower_bound + 1\n",
833 | "# 이분 검색을 수행합니다\n",
834 | "ans = (high + low)/2\n",
835 | "while abs(2**ans -x) >= epsilon:\n",
836 | " if 2**ans < x:\n",
837 | " low = ans\n",
838 | " else:\n",
839 | " high = ans\n",
840 | " ans = (high + low)/2\n",
841 | "print(ans, '(은)는', x, '의 밑이 2인 로그에 가깝습니다')"
842 | ]
843 | },
844 | {
845 | "cell_type": "markdown",
846 | "metadata": {
847 | "id": "DclfAYxxTheU"
848 | },
849 | "source": [
850 | "**뇌풀기 문제**"
851 | ]
852 | },
853 | {
854 | "cell_type": "code",
855 | "execution_count": null,
856 | "metadata": {
857 | "colab": {
858 | "base_uri": "https://localhost:8080/"
859 | },
860 | "id": "mDHkJLIaTZzA",
861 | "outputId": "5df74114-8482-48fb-e773-1cdb7de67db6"
862 | },
863 | "outputs": [
864 | {
865 | "name": "stdout",
866 | "output_type": "stream",
867 | "text": [
868 | "low = -27 high = 1 ans = -13.0\n",
869 | "low = -13.0 high = 1 ans = -6.0\n",
870 | "low = -6.0 high = 1 ans = -2.5\n",
871 | "low = -6.0 high = -2.5 ans = -4.25\n",
872 | "low = -4.25 high = -2.5 ans = -3.375\n",
873 | "low = -3.375 high = -2.5 ans = -2.9375\n",
874 | "low = -3.375 high = -2.9375 ans = -3.15625\n",
875 | "low = -3.15625 high = -2.9375 ans = -3.046875\n",
876 | "low = -3.046875 high = -2.9375 ans = -2.9921875\n",
877 | "low = -3.046875 high = -2.9921875 ans = -3.01953125\n",
878 | "low = -3.01953125 high = -2.9921875 ans = -3.005859375\n",
879 | "low = -3.005859375 high = -2.9921875 ans = -2.9990234375\n",
880 | "low = -3.005859375 high = -2.9990234375 ans = -3.00244140625\n",
881 | "low = -3.00244140625 high = -2.9990234375 ans = -3.000732421875\n",
882 | "추측 횟수 = 14\n",
883 | "-2.9998779296875 (은)는 -27 의 세제곱근에 가깝습니다\n"
884 | ]
885 | }
886 | ],
887 | "source": [
888 | "x = -27\n",
889 | "epsilon = 0.01\n",
890 | "num_guesses = 0\n",
891 | "low = min(0, x)\n",
892 | "high = max(1, x)\n",
893 | "ans = (high + low)/2\n",
894 | "n_iter = 0\n",
895 | "while abs(ans**3 - x) >= epsilon:\n",
896 | " print('low =', low, 'high =', high, 'ans =', ans)\n",
897 | " num_guesses += 1\n",
898 | " if ans**3 < x:\n",
899 | " low = ans\n",
900 | " else:\n",
901 | " high = ans\n",
902 | " ans = (high + low)/2\n",
903 | " if n_iter > 100:\n",
904 | " break\n",
905 | " n_iter += 1\n",
906 | "print('추측 횟수 =', num_guesses)\n",
907 | "print(ans, '(은)는', x, '의 세제곱근에 가깝습니다')"
908 | ]
909 | },
910 | {
911 | "cell_type": "markdown",
912 | "metadata": {
913 | "id": "Py5cDunqYgs2"
914 | },
915 | "source": [
916 | "**뇌풀기 문제**"
917 | ]
918 | },
919 | {
920 | "cell_type": "code",
921 | "execution_count": null,
922 | "metadata": {
923 | "colab": {
924 | "base_uri": "https://localhost:8080/"
925 | },
926 | "id": "FEHW0S4vYc6P",
927 | "outputId": "0c610418-b5ad-4eec-cca8-f7c8fcbc04cd"
928 | },
929 | "outputs": [
930 | {
931 | "name": "stdout",
932 | "output_type": "stream",
933 | "text": [
934 | "사용한 달걀 갯수 = 7\n",
935 | "102 층은 달걀이 깨지지 않는 가장 높은 층입니다\n"
936 | ]
937 | }
938 | ],
939 | "source": [
940 | "max_floor = 102 #정답\n",
941 | "epsilon = 0.5\n",
942 | "num_eggs = 0\n",
943 | "low = 1\n",
944 | "high = 102\n",
945 | "ans = (high + low)/2\n",
946 | "while abs(ans - max_floor) >= epsilon:\n",
947 | " num_eggs += 1\n",
948 | " if ans < max_floor:\n",
949 | " low = ans\n",
950 | " else:\n",
951 | " high = ans\n",
952 | " ans = (high + low)/2\n",
953 | "ans = int(ans+0.5)\n",
954 | "print('사용한 달걀 갯수 =', num_eggs)\n",
955 | "print(ans, '층은 달걀이 깨지지 않는 가장 높은 층입니다')"
956 | ]
957 | },
958 | {
959 | "cell_type": "markdown",
960 | "metadata": {
961 | "id": "GnNNVp2e8xc5"
962 | },
963 | "source": [
964 | "## 3.3 부동소수점 사용에 대하여"
965 | ]
966 | },
967 | {
968 | "cell_type": "code",
969 | "execution_count": null,
970 | "metadata": {
971 | "colab": {
972 | "base_uri": "https://localhost:8080/"
973 | },
974 | "id": "nObKXUKMYirG",
975 | "outputId": "a7558161-fb6b-47e3-e8a9-ad2818764eb8"
976 | },
977 | "outputs": [
978 | {
979 | "name": "stdout",
980 | "output_type": "stream",
981 | "text": [
982 | "0.9999999999999999 는 1.0이 아닙니다\n"
983 | ]
984 | }
985 | ],
986 | "source": [
987 | "x = 0.0\n",
988 | "for i in range(10):\n",
989 | " x = x + 0.1\n",
990 | "if x == 1.0:\n",
991 | " print(x, '= 1.0')\n",
992 | "else:\n",
993 | " print(x, '는 1.0이 아닙니다')"
994 | ]
995 | },
996 | {
997 | "cell_type": "markdown",
998 | "metadata": {
999 | "id": "21sxP1jzXq7S"
1000 | },
1001 | "source": [
1002 | "**뇌풀기 문제**"
1003 | ]
1004 | },
1005 | {
1006 | "cell_type": "code",
1007 | "execution_count": null,
1008 | "metadata": {
1009 | "colab": {
1010 | "base_uri": "https://localhost:8080/"
1011 | },
1012 | "id": "yNYiZ5Uj97SM",
1013 | "outputId": "eb8e6b88-afa7-47ac-dd46-3ece5b5751fe"
1014 | },
1015 | "outputs": [
1016 | {
1017 | "data": {
1018 | "text/plain": [
1019 | "19"
1020 | ]
1021 | },
1022 | "execution_count": 21,
1023 | "metadata": {},
1024 | "output_type": "execute_result"
1025 | }
1026 | ],
1027 | "source": [
1028 | "1*16+0*8+0*4+1*2+1*1"
1029 | ]
1030 | },
1031 | {
1032 | "cell_type": "markdown",
1033 | "metadata": {
1034 | "id": "j_qy2IZm9Z76"
1035 | },
1036 | "source": [
1037 | "## 3.4 뉴턴-랍슨 방법"
1038 | ]
1039 | },
1040 | {
1041 | "cell_type": "markdown",
1042 | "metadata": {
1043 | "id": "mj0oM8U8-e81"
1044 | },
1045 | "source": [
1046 | "예제 3-7 뉴턴-랍슨 방법 구현"
1047 | ]
1048 | },
1049 | {
1050 | "cell_type": "code",
1051 | "execution_count": null,
1052 | "metadata": {
1053 | "colab": {
1054 | "base_uri": "https://localhost:8080/"
1055 | },
1056 | "id": "i-Ao2rqC9emu",
1057 | "outputId": "c568b894-4171-4952-a38d-317c323f85f7"
1058 | },
1059 | "outputs": [
1060 | {
1061 | "name": "stdout",
1062 | "output_type": "stream",
1063 | "text": [
1064 | "24 의 제곱근은 약 4.8989887432139305 입니다\n"
1065 | ]
1066 | }
1067 | ],
1068 | "source": [
1069 | "k = 24\n",
1070 | "# 제곱근을 위한 뉴턴-랍슨 방법\n",
1071 | "# Find x such that x**2 - 24이 epsilon 이내에서 0이 되는 x를 찾습니다\n",
1072 | "epsilon = 0.01\n",
1073 | "guess = k/2\n",
1074 | "while abs(guess**2 - k) >= epsilon:\n",
1075 | " guess = guess - (((guess**2) - k)/(2*guess))\n",
1076 | "print(k, '의 제곱근은 약', guess, '입니다')"
1077 | ]
1078 | },
1079 | {
1080 | "cell_type": "markdown",
1081 | "metadata": {
1082 | "id": "4hd6WdDC9hd4"
1083 | },
1084 | "source": [
1085 | "**뇌풀기 문제**"
1086 | ]
1087 | },
1088 | {
1089 | "cell_type": "code",
1090 | "execution_count": null,
1091 | "metadata": {
1092 | "colab": {
1093 | "base_uri": "https://localhost:8080/"
1094 | },
1095 | "id": "dnDVVRSn9uJR",
1096 | "outputId": "0011bf74-0c76-43c1-c9c6-ed9adfbe8b24"
1097 | },
1098 | "outputs": [
1099 | {
1100 | "name": "stdout",
1101 | "output_type": "stream",
1102 | "text": [
1103 | "추측 횟수 = 4\n",
1104 | "25 의 제곱근은 약 5.000012953048684 입니다\n"
1105 | ]
1106 | }
1107 | ],
1108 | "source": [
1109 | "k = 25\n",
1110 | "# 제곱근을 위한 뉴턴-랍슨 방법\n",
1111 | "epsilon = 0.01\n",
1112 | "guess = k/2\n",
1113 | "num_guesses = 0\n",
1114 | "while abs(guess**2 - k) >= epsilon:\n",
1115 | " num_guesses += 1\n",
1116 | " guess = guess - (((guess**2) - k)/(2*guess))\n",
1117 | "print('추측 횟수 =', num_guesses)\n",
1118 | "print(k, '의 제곱근은 약', guess, '입니다')"
1119 | ]
1120 | }
1121 | ],
1122 | "metadata": {
1123 | "colab": {
1124 | "provenance": []
1125 | },
1126 | "kernelspec": {
1127 | "display_name": "Python 3 (ipykernel)",
1128 | "language": "python",
1129 | "name": "python3"
1130 | },
1131 | "language_info": {
1132 | "codemirror_mode": {
1133 | "name": "ipython",
1134 | "version": 3
1135 | },
1136 | "file_extension": ".py",
1137 | "mimetype": "text/x-python",
1138 | "name": "python",
1139 | "nbconvert_exporter": "python",
1140 | "pygments_lexer": "ipython3",
1141 | "version": "3.8.2"
1142 | }
1143 | },
1144 | "nbformat": 4,
1145 | "nbformat_minor": 0
1146 | }
--------------------------------------------------------------------------------
/04장.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "USsQzQUpwch-"
7 | },
8 | "source": [
9 | "\n",
10 | " \n",
11 | " |
"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "metadata": {
17 | "id": "RRDDAOnjwcey"
18 | },
19 | "source": [
20 | "# 4장 함수, 유효범위, 추상화"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {
26 | "id": "Gmzr_AZfwcSV"
27 | },
28 | "source": [
29 | "예제 4-1 이분 검색을 사용한 x의 제곱근에 대한 근삿값 찾기"
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": 1,
35 | "metadata": {
36 | "colab": {
37 | "base_uri": "https://localhost:8080/"
38 | },
39 | "id": "lrbgtp87j_f3",
40 | "outputId": "c1707176-ce9b-4e82-e607-bd5cefd1f7d4"
41 | },
42 | "outputs": [
43 | {
44 | "name": "stdout",
45 | "output_type": "stream",
46 | "text": [
47 | "5.00030517578125 는 25 의 제곱근에 가깝습니다\n"
48 | ]
49 | }
50 | ],
51 | "source": [
52 | "x = 25\n",
53 | "epsilon = 0.01\n",
54 | "\n",
55 | "# x 제곱근의 근삿값 찾기\n",
56 | "if x < 0:\n",
57 | " print('제곱근이 존재하지 않습니다')\n",
58 | "else:\n",
59 | " low = 0\n",
60 | " high = max(1, x)\n",
61 | " ans = (high + low)/2\n",
62 | " while abs(ans**2 - x) >= epsilon:\n",
63 | " if ans**2 < x:\n",
64 | " low = ans\n",
65 | " else:\n",
66 | " high = ans\n",
67 | " ans = (high + low)/2\n",
68 | " print(ans, '는', x, '의 제곱근에 가깝습니다')"
69 | ]
70 | },
71 | {
72 | "cell_type": "markdown",
73 | "metadata": {
74 | "id": "dWd9WEQT6vcR"
75 | },
76 | "source": [
77 | "예제 4-2 제곱근과 세제곱근 더하기"
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": 2,
83 | "metadata": {
84 | "colab": {
85 | "base_uri": "https://localhost:8080/"
86 | },
87 | "id": "ZljtLPXP6wKJ",
88 | "outputId": "6175ac7a-56af-4092-d99a-a2449307371e"
89 | },
90 | "outputs": [
91 | {
92 | "name": "stdout",
93 | "output_type": "stream",
94 | "text": [
95 | "25 의 제곱근과 -8 의 세제곱근의 합은 3.00030517578125 입니다\n"
96 | ]
97 | }
98 | ],
99 | "source": [
100 | "x1 = 25\n",
101 | "epsilon = 0.01\n",
102 | "\n",
103 | "# x1의 제곱근을 찾습니다\n",
104 | "if x1 < 0:\n",
105 | " print('Does not exist')\n",
106 | "else:\n",
107 | " low = 0\n",
108 | " high = max(1, x1)\n",
109 | " ans = (high + low)/2\n",
110 | " while abs(ans**2 - x1) >= epsilon:\n",
111 | " if ans**2 < x1:\n",
112 | " low = ans\n",
113 | " else:\n",
114 | " high = ans\n",
115 | " ans = (high + low)/2\n",
116 | "x1_root = ans\n",
117 | "x2 = -8\n",
118 | "# x2의 세제곱근을 찾습니다\n",
119 | "if x2 < 0:\n",
120 | " is_pos = False\n",
121 | " x2 = -x2\n",
122 | "else:\n",
123 | " is_pos = True\n",
124 | "low = 0\n",
125 | "high = max(1, x2)\n",
126 | "ans = (high + low)/2\n",
127 | "while abs(ans**3 - x2) >= epsilon:\n",
128 | " if ans**3 < x2:\n",
129 | " low = ans\n",
130 | " else:\n",
131 | " high = ans\n",
132 | " ans = (high + low)/2\n",
133 | "if is_pos:\n",
134 | " x2_root = ans\n",
135 | "else:\n",
136 | " x2_root = -ans\n",
137 | " x2 = -x2\n",
138 | "print(x1, '의 제곱근과', x2, '의 세제곱근의 합은',\n",
139 | " x1_root + x2_root, '입니다')"
140 | ]
141 | },
142 | {
143 | "cell_type": "markdown",
144 | "metadata": {
145 | "id": "maDoRdZ_Et5d"
146 | },
147 | "source": [
148 | "## 4.1 함수와 유효범위"
149 | ]
150 | },
151 | {
152 | "cell_type": "markdown",
153 | "metadata": {
154 | "id": "kt9-sNPTO-lo"
155 | },
156 | "source": [
157 | "### 4.1.1 함수 정의"
158 | ]
159 | },
160 | {
161 | "cell_type": "code",
162 | "execution_count": 3,
163 | "metadata": {
164 | "id": "X17Zu_yv7B8f"
165 | },
166 | "outputs": [],
167 | "source": [
168 | "def max_val(x, y):\n",
169 | " if x > y:\n",
170 | " return x\n",
171 | " else:\n",
172 | " return y"
173 | ]
174 | },
175 | {
176 | "cell_type": "code",
177 | "execution_count": 4,
178 | "metadata": {
179 | "colab": {
180 | "base_uri": "https://localhost:8080/"
181 | },
182 | "id": "iq-vOTLrE_cE",
183 | "outputId": "5d4faf39-ccf9-490a-aa3d-66e47ee014d9"
184 | },
185 | "outputs": [
186 | {
187 | "data": {
188 | "text/plain": [
189 | "4"
190 | ]
191 | },
192 | "execution_count": 4,
193 | "metadata": {},
194 | "output_type": "execute_result"
195 | }
196 | ],
197 | "source": [
198 | "max_val(3, 4)"
199 | ]
200 | },
201 | {
202 | "cell_type": "markdown",
203 | "metadata": {
204 | "id": "Fg2wlunkXgd2"
205 | },
206 | "source": [
207 | "예제 4-3 근 찾기 함수"
208 | ]
209 | },
210 | {
211 | "cell_type": "code",
212 | "execution_count": 5,
213 | "metadata": {
214 | "id": "10KqWPF1FCMj"
215 | },
216 | "outputs": [],
217 | "source": [
218 | "def find_root(x, power, epsilon):\n",
219 | " # 답이 포함된 범위를 찾습니다\n",
220 | " if x < 0 and power%2 == 0:\n",
221 | " return None #음수는 짝수 제곱근이 없습니다.\n",
222 | " low = min(-1, x)\n",
223 | " high = max(1, x)\n",
224 | " # 이분 검색을 사용합니다\n",
225 | " ans = (high + low)/2\n",
226 | " while abs(ans**power - x) >= epsilon:\n",
227 | " if ans**power < x:\n",
228 | " low = ans\n",
229 | " else:\n",
230 | " high = ans\n",
231 | " ans = (high + low)/2\n",
232 | " return ans"
233 | ]
234 | },
235 | {
236 | "cell_type": "markdown",
237 | "metadata": {
238 | "id": "IXnEIjRqXqoB"
239 | },
240 | "source": [
241 | "예제 4-4 `find_root` 테스트 코드"
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": 6,
247 | "metadata": {
248 | "colab": {
249 | "base_uri": "https://localhost:8080/"
250 | },
251 | "id": "OE42ktirUdkT",
252 | "outputId": "73a66086-e3c2-4f94-ad51-19415273a093"
253 | },
254 | "outputs": [
255 | {
256 | "name": "stdout",
257 | "output_type": "stream",
258 | "text": [
259 | "x = 0.25, power = 1, epsilon = 0.1: 통과\n",
260 | "x = 0.25, power = 1, epsilon = 0.001: 통과\n",
261 | "x = 0.25, power = 1, epsilon = 1: 통과\n",
262 | "x = 0.25, power = 2, epsilon = 0.1: 통과\n",
263 | "x = 0.25, power = 2, epsilon = 0.001: 통과\n",
264 | "x = 0.25, power = 2, epsilon = 1: 통과\n",
265 | "x = 0.25, power = 3, epsilon = 0.1: 통과\n",
266 | "x = 0.25, power = 3, epsilon = 0.001: 통과\n",
267 | "x = 0.25, power = 3, epsilon = 1: 통과\n",
268 | "x = 8, power = 1, epsilon = 0.1: 통과\n",
269 | "x = 8, power = 1, epsilon = 0.001: 통과\n",
270 | "x = 8, power = 1, epsilon = 1: 통과\n",
271 | "x = 8, power = 2, epsilon = 0.1: 통과\n",
272 | "x = 8, power = 2, epsilon = 0.001: 통과\n",
273 | "x = 8, power = 2, epsilon = 1: 통과\n",
274 | "x = 8, power = 3, epsilon = 0.1: 통과\n",
275 | "x = 8, power = 3, epsilon = 0.001: 통과\n",
276 | "x = 8, power = 3, epsilon = 1: 통과\n",
277 | "x = -8, power = 1, epsilon = 0.1: 통과\n",
278 | "x = -8, power = 1, epsilon = 0.001: 통과\n",
279 | "x = -8, power = 1, epsilon = 1: 통과\n",
280 | "x = -8, power = 2, epsilon = 0.1: 근이 존재하지 않습니다\n",
281 | "x = -8, power = 2, epsilon = 0.001: 근이 존재하지 않습니다\n",
282 | "x = -8, power = 2, epsilon = 1: 근이 존재하지 않습니다\n",
283 | "x = -8, power = 3, epsilon = 0.1: 통과\n",
284 | "x = -8, power = 3, epsilon = 0.001: 통과\n",
285 | "x = -8, power = 3, epsilon = 1: 통과\n"
286 | ]
287 | }
288 | ],
289 | "source": [
290 | "def test_find_root(x_vals, powers, epsilons):\n",
291 | " for x in x_vals:\n",
292 | " for p in powers:\n",
293 | " for e in epsilons:\n",
294 | " result = find_root(x, p, e)\n",
295 | " if result == None:\n",
296 | " val = '근이 존재하지 않습니다'\n",
297 | " else:\n",
298 | " val = '통과'\n",
299 | " if abs(result**p - x) > e:\n",
300 | " val = '실패'\n",
301 | " print(f'x = {x}, power = {p}, epsilon = {e}: {val}')\n",
302 | "\n",
303 | "x_vals = (0.25, 8, -8)\n",
304 | "powers = (1, 2, 3)\n",
305 | "epsilons = (0.1, 0.001, 1)\n",
306 | "test_find_root(x_vals, powers, epsilons)"
307 | ]
308 | },
309 | {
310 | "cell_type": "markdown",
311 | "metadata": {
312 | "id": "ZurBuaVvYwiZ"
313 | },
314 | "source": [
315 | "**뇌풀기 문제**"
316 | ]
317 | },
318 | {
319 | "cell_type": "code",
320 | "execution_count": 7,
321 | "metadata": {
322 | "colab": {
323 | "base_uri": "https://localhost:8080/"
324 | },
325 | "id": "UfKyDTHOYydE",
326 | "outputId": "a4dcab8e-c64b-4c1c-cf42-ffe0af8c630a"
327 | },
328 | "outputs": [
329 | {
330 | "name": "stdout",
331 | "output_type": "stream",
332 | "text": [
333 | "4.999988555908203\n"
334 | ]
335 | }
336 | ],
337 | "source": [
338 | "sum = 0.\n",
339 | "epsilon = 0.001\n",
340 | "sum += find_root(25, 2, epsilon)\n",
341 | "sum += find_root(-8, 3, epsilon)\n",
342 | "sum += find_root(16, 4, epsilon)\n",
343 | "print(sum)"
344 | ]
345 | },
346 | {
347 | "cell_type": "markdown",
348 | "metadata": {
349 | "id": "AGFJzoYpIDIE"
350 | },
351 | "source": [
352 | "**뇌풀기 문제**"
353 | ]
354 | },
355 | {
356 | "cell_type": "code",
357 | "execution_count": 8,
358 | "metadata": {
359 | "colab": {
360 | "base_uri": "https://localhost:8080/"
361 | },
362 | "id": "AgrdWl4HIEVy",
363 | "outputId": "3255a17f-5a21-48a5-f9bf-9cde11dd8062"
364 | },
365 | "outputs": [
366 | {
367 | "data": {
368 | "text/plain": [
369 | "True"
370 | ]
371 | },
372 | "execution_count": 8,
373 | "metadata": {},
374 | "output_type": "execute_result"
375 | }
376 | ],
377 | "source": [
378 | "def is_in(s1, s2):\n",
379 | " if s1 in s2 or s2 in s1:\n",
380 | " return True\n",
381 | " else:\n",
382 | " return False\n",
383 | "\n",
384 | "is_in('abcde', 'abc')"
385 | ]
386 | },
387 | {
388 | "cell_type": "markdown",
389 | "metadata": {
390 | "id": "RciWQeB3Ilci"
391 | },
392 | "source": [
393 | "**뇌풀기 문제**"
394 | ]
395 | },
396 | {
397 | "cell_type": "code",
398 | "execution_count": 9,
399 | "metadata": {
400 | "colab": {
401 | "base_uri": "https://localhost:8080/"
402 | },
403 | "id": "yJwNidZIIjtW",
404 | "outputId": "d8e5cdd8-f69b-4230-ea6b-5778a810edb3"
405 | },
406 | "outputs": [
407 | {
408 | "name": "stdout",
409 | "output_type": "stream",
410 | "text": [
411 | "s1 = abcde, s2 = bcd: 통과\n",
412 | "s1 = abcde, s2 = bd: 통과\n",
413 | "s1 = python, s2 = ytho: 통과\n",
414 | "s1 = python, s2 = yh: 통과\n"
415 | ]
416 | }
417 | ],
418 | "source": [
419 | "def test_is_in(ss):\n",
420 | " for s in ss:\n",
421 | " s1 = s\n",
422 | " s2 = s[1:len(s)-1]\n",
423 | " if is_in(s1, s2) == True and is_in(s2, s1) == True:\n",
424 | " val = '통과'\n",
425 | " else:\n",
426 | " val = '실패'\n",
427 | " print(f's1 = {s1}, s2 = {s2}: {val}')\n",
428 | " s2 = s[1:len(s)-1:2]\n",
429 | " if is_in(s1, s2) == False and is_in(s2, s1) == False:\n",
430 | " val = '통과'\n",
431 | " else:\n",
432 | " val = '실패'\n",
433 | " print(f's1 = {s1}, s2 = {s2}: {val}')\n",
434 | "\n",
435 | "test_is_in(('abcde', 'python'))"
436 | ]
437 | },
438 | {
439 | "cell_type": "markdown",
440 | "metadata": {
441 | "id": "4zzJdj74OxPI"
442 | },
443 | "source": [
444 | "### 4.1.2 키워드 인수와 기본값"
445 | ]
446 | },
447 | {
448 | "cell_type": "code",
449 | "execution_count": 10,
450 | "metadata": {
451 | "id": "A82wdvLXYJew"
452 | },
453 | "outputs": [],
454 | "source": [
455 | "def print_name(first_name, last_name, reverse):\n",
456 | " if reverse:\n",
457 | " print(last_name + ', ' + first_name)\n",
458 | " else:\n",
459 | " print(first_name, last_name)"
460 | ]
461 | },
462 | {
463 | "cell_type": "code",
464 | "execution_count": 12,
465 | "metadata": {
466 | "colab": {
467 | "base_uri": "https://localhost:8080/"
468 | },
469 | "id": "9yQqGPfzOyj1",
470 | "outputId": "bb6f238d-6b83-4785-aa0c-16540bd396e7"
471 | },
472 | "outputs": [
473 | {
474 | "name": "stdout",
475 | "output_type": "stream",
476 | "text": [
477 | "길동 홍\n",
478 | "길동 홍\n",
479 | "길동 홍\n",
480 | "길동 홍\n"
481 | ]
482 | }
483 | ],
484 | "source": [
485 | "print_name('길동', '홍', False)\n",
486 | "print_name('길동', '홍', reverse = False)\n",
487 | "print_name('길동', last_name = '홍', reverse = False)\n",
488 | "print_name(last_name = '홍', first_name = '길동', reverse = False)"
489 | ]
490 | },
491 | {
492 | "cell_type": "code",
493 | "execution_count": 13,
494 | "metadata": {
495 | "colab": {
496 | "base_uri": "https://localhost:8080/",
497 | "height": 147
498 | },
499 | "id": "aB_saDb4Q-wv",
500 | "outputId": "ab0c33f5-1729-4eb0-b445-152ebd26056b"
501 | },
502 | "outputs": [
503 | {
504 | "ename": "SyntaxError",
505 | "evalue": "ignored",
506 | "output_type": "error",
507 | "traceback": [
508 | "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print_name('길동', last_name = '홍', False)\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m positional argument follows keyword argument\n"
509 | ]
510 | }
511 | ],
512 | "source": [
513 | "print_name('길동', last_name = '홍', False)"
514 | ]
515 | },
516 | {
517 | "cell_type": "code",
518 | "execution_count": 14,
519 | "metadata": {
520 | "id": "WFQaBC94Scqc"
521 | },
522 | "outputs": [],
523 | "source": [
524 | "def print_name(first_name, last_name, reverse = False):\n",
525 | " if reverse:\n",
526 | " print(last_name + ', ' + first_name)\n",
527 | " else:\n",
528 | " print(first_name, last_name)"
529 | ]
530 | },
531 | {
532 | "cell_type": "code",
533 | "execution_count": 15,
534 | "metadata": {
535 | "colab": {
536 | "base_uri": "https://localhost:8080/"
537 | },
538 | "id": "rtwXf_SxS1E3",
539 | "outputId": "d0d4c08e-988c-4f1c-c510-44a7c679f5fe"
540 | },
541 | "outputs": [
542 | {
543 | "name": "stdout",
544 | "output_type": "stream",
545 | "text": [
546 | "길동 홍\n",
547 | "홍, 길동\n",
548 | "홍, 길동\n"
549 | ]
550 | }
551 | ],
552 | "source": [
553 | "print_name('길동', '홍')\n",
554 | "print_name('길동', '홍', True)\n",
555 | "print_name('길동', '홍', reverse = True)"
556 | ]
557 | },
558 | {
559 | "cell_type": "code",
560 | "execution_count": 16,
561 | "metadata": {
562 | "colab": {
563 | "base_uri": "https://localhost:8080/"
564 | },
565 | "id": "0D4WJEVJTHXs",
566 | "outputId": "18fec304-357d-4ba3-eb2e-82afa6e31b19"
567 | },
568 | "outputs": [
569 | {
570 | "name": "stdout",
571 | "output_type": "stream",
572 | "text": [
573 | "길동 홍\n"
574 | ]
575 | }
576 | ],
577 | "source": [
578 | "print_name(last_name = '홍', first_name = '길동')"
579 | ]
580 | },
581 | {
582 | "cell_type": "markdown",
583 | "metadata": {
584 | "id": "mXfbQftyVHLC"
585 | },
586 | "source": [
587 | "**뇌풀기 문제**"
588 | ]
589 | },
590 | {
591 | "cell_type": "code",
592 | "execution_count": 17,
593 | "metadata": {
594 | "colab": {
595 | "base_uri": "https://localhost:8080/"
596 | },
597 | "id": "PaxEr1LcT7-Q",
598 | "outputId": "bb662d25-ca4d-4f38-825d-b47aa8158566"
599 | },
600 | "outputs": [
601 | {
602 | "name": "stdout",
603 | "output_type": "stream",
604 | "text": [
605 | "6\n",
606 | "2\n",
607 | "3\n"
608 | ]
609 | }
610 | ],
611 | "source": [
612 | "def mult(i1=None, i2=None):\n",
613 | " if i1 != None and i2 != None:\n",
614 | " print(i1 * i2)\n",
615 | " elif i1 != None:\n",
616 | " print(i1)\n",
617 | " elif i2 != None:\n",
618 | " print(i2)\n",
619 | "\n",
620 | "mult(2, 3)\n",
621 | "mult(2)\n",
622 | "mult(i2=3)"
623 | ]
624 | },
625 | {
626 | "cell_type": "markdown",
627 | "metadata": {
628 | "id": "_MppuwQ3VJPD"
629 | },
630 | "source": [
631 | "### 4.1.3 가변 길이 인수"
632 | ]
633 | },
634 | {
635 | "cell_type": "code",
636 | "execution_count": 18,
637 | "metadata": {
638 | "colab": {
639 | "base_uri": "https://localhost:8080/"
640 | },
641 | "id": "nhePJq39VR6g",
642 | "outputId": "592ba02e-de99-487b-ffed-020dedb0c5c8"
643 | },
644 | "outputs": [
645 | {
646 | "data": {
647 | "text/plain": [
648 | "1"
649 | ]
650 | },
651 | "execution_count": 18,
652 | "metadata": {},
653 | "output_type": "execute_result"
654 | }
655 | ],
656 | "source": [
657 | "min(6,4)\n",
658 | "min(3,4,1,6)"
659 | ]
660 | },
661 | {
662 | "cell_type": "code",
663 | "execution_count": 19,
664 | "metadata": {
665 | "colab": {
666 | "base_uri": "https://localhost:8080/"
667 | },
668 | "id": "61EL6EPUmVyy",
669 | "outputId": "7d58773f-a56d-4f9c-b584-8a31b892eecf"
670 | },
671 | "outputs": [
672 | {
673 | "name": "stdout",
674 | "output_type": "stream",
675 | "text": [
676 | "1.5\n",
677 | "-1.0\n"
678 | ]
679 | }
680 | ],
681 | "source": [
682 | "def mean(*args):\n",
683 | " # 적어도 한 개의 인수가 있고 모든 인수를 숫자로 가정합니다\n",
684 | " # 인수의 평균을 반환합니다\n",
685 | " tot = 0\n",
686 | " for a in args:\n",
687 | " tot += a\n",
688 | " return tot/len(args)\n",
689 | "\n",
690 | "print(mean(1, 2))\n",
691 | "print(mean(-4, 0, 1))"
692 | ]
693 | },
694 | {
695 | "cell_type": "markdown",
696 | "metadata": {
697 | "id": "MLvEe-jIqCIS"
698 | },
699 | "source": [
700 | "### 4.1.4 유효범위"
701 | ]
702 | },
703 | {
704 | "cell_type": "code",
705 | "execution_count": 20,
706 | "metadata": {
707 | "colab": {
708 | "base_uri": "https://localhost:8080/"
709 | },
710 | "id": "isqBwGvypI-C",
711 | "outputId": "2484d547-c428-4770-aced-da5add049771"
712 | },
713 | "outputs": [
714 | {
715 | "name": "stdout",
716 | "output_type": "stream",
717 | "text": [
718 | "x = 4\n",
719 | "z = 4\n",
720 | "x = 3\n",
721 | "y = 2\n"
722 | ]
723 | }
724 | ],
725 | "source": [
726 | "def f(x): #이름 x를 형식 매개변수로 사용합니다\n",
727 | " y = 1\n",
728 | " x = x + y\n",
729 | " print('x =', x)\n",
730 | " return x\n",
731 | "\n",
732 | "x = 3\n",
733 | "y = 2\n",
734 | "z = f(x) #x의 값을 실 매개변수로 사용합니다\n",
735 | "print('z =', z)\n",
736 | "print('x =', x)\n",
737 | "print('y =', y)"
738 | ]
739 | },
740 | {
741 | "cell_type": "markdown",
742 | "metadata": {
743 | "id": "YX_vzeoNVqrQ"
744 | },
745 | "source": [
746 | "예제 4-5 중첩된 유효범위"
747 | ]
748 | },
749 | {
750 | "cell_type": "code",
751 | "execution_count": 21,
752 | "metadata": {
753 | "colab": {
754 | "base_uri": "https://localhost:8080/"
755 | },
756 | "id": "4XZq_Jf4qdgq",
757 | "outputId": "9bf4890e-e032-4055-f905-613064372784"
758 | },
759 | "outputs": [
760 | {
761 | "name": "stdout",
762 | "output_type": "stream",
763 | "text": [
764 | "x = 4\n",
765 | "z = 4\n",
766 | "x = abc\n",
767 | "x = 4\n",
768 | "x = 3\n",
769 | "z = .g at 0x7e9df90dd2d0>\n",
770 | "x = abc\n"
771 | ]
772 | }
773 | ],
774 | "source": [
775 | "def f(x):\n",
776 | " def g():\n",
777 | " x = 'abc'\n",
778 | " print('x =', x)\n",
779 | " def h():\n",
780 | " z = x\n",
781 | " print('z =', z)\n",
782 | " x = x + 1\n",
783 | " print('x =', x)\n",
784 | " h()\n",
785 | " g()\n",
786 | " print('x =', x)\n",
787 | " return g\n",
788 | "\n",
789 | "x = 3\n",
790 | "z = f(x)\n",
791 | "print('x =', x)\n",
792 | "print('z =', z)\n",
793 | "z()"
794 | ]
795 | },
796 | {
797 | "cell_type": "code",
798 | "execution_count": 22,
799 | "metadata": {
800 | "colab": {
801 | "base_uri": "https://localhost:8080/",
802 | "height": 361
803 | },
804 | "id": "oWP5-ncRtLvn",
805 | "outputId": "4f059c50-54e3-4edc-ddc0-4180f0f4f822"
806 | },
807 | "outputs": [
808 | {
809 | "name": "stdout",
810 | "output_type": "stream",
811 | "text": [
812 | "3\n"
813 | ]
814 | },
815 | {
816 | "ename": "UnboundLocalError",
817 | "evalue": "ignored",
818 | "output_type": "error",
819 | "traceback": [
820 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
821 | "\u001b[0;31mUnboundLocalError\u001b[0m Traceback (most recent call last)",
822 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
823 | "\u001b[0;32m\u001b[0m in \u001b[0;36mg\u001b[0;34m()\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
824 | "\u001b[0;31mUnboundLocalError\u001b[0m: local variable 'x' referenced before assignment"
825 | ]
826 | }
827 | ],
828 | "source": [
829 | "def f():\n",
830 | " print(x)\n",
831 | "\n",
832 | "def g():\n",
833 | " print(x)\n",
834 | " x = 1\n",
835 | "\n",
836 | "x = 3\n",
837 | "f()\n",
838 | "x = 3\n",
839 | "g()"
840 | ]
841 | },
842 | {
843 | "cell_type": "markdown",
844 | "metadata": {
845 | "id": "HhjkSxyKvq5B"
846 | },
847 | "source": [
848 | "## 4.2 사양"
849 | ]
850 | },
851 | {
852 | "cell_type": "markdown",
853 | "metadata": {
854 | "id": "g9S6EKLXbidr"
855 | },
856 | "source": [
857 | "예제 4-6 사양을 포함한 함수 정의"
858 | ]
859 | },
860 | {
861 | "cell_type": "code",
862 | "execution_count": 23,
863 | "metadata": {
864 | "id": "I-FOTEDOr3qS"
865 | },
866 | "outputs": [],
867 | "source": [
868 | "def find_root(x, power, epsilon):\n",
869 | " \"\"\"x와 epsilon은 int 또는 float이고, power는 정수이며,\n",
870 | " epsilon > 0 & power >= 1 라고 가정합니다\n",
871 | " x에서 epsilon 이내에 y**power가 있다면 y를 반환합니다.\n",
872 | " 이런 float가 없다면 None을 반환합니다\"\"\"\n",
873 | " # 답이 포함된 범위를 찾습니다\n",
874 | " if x < 0 and power%2 == 0:\n",
875 | " return None\n",
876 | " low = min(-1, x)\n",
877 | " high = max(1, x)\n",
878 | " # 이분 검색을 사용합니다\n",
879 | " ans = (high + low)/2\n",
880 | " while abs(ans**power - x) >= epsilon:\n",
881 | " if ans**power < x:\n",
882 | " low = ans\n",
883 | " else:\n",
884 | " high = ans\n",
885 | " ans = (high + low)/2\n",
886 | " return ans"
887 | ]
888 | },
889 | {
890 | "cell_type": "code",
891 | "execution_count": 24,
892 | "metadata": {
893 | "colab": {
894 | "base_uri": "https://localhost:8080/"
895 | },
896 | "id": "gPYbD_E2CmEz",
897 | "outputId": "3db98088-984a-4db6-8ec6-6fa6c300ebc4"
898 | },
899 | "outputs": [
900 | {
901 | "name": "stdout",
902 | "output_type": "stream",
903 | "text": [
904 | "Help on built-in function abs in module builtins:\n",
905 | "\n",
906 | "abs(x, /)\n",
907 | " Return the absolute value of the argument.\n",
908 | "\n"
909 | ]
910 | }
911 | ],
912 | "source": [
913 | "help(abs)"
914 | ]
915 | },
916 | {
917 | "cell_type": "code",
918 | "execution_count": 34,
919 | "metadata": {
920 | "colab": {
921 | "base_uri": "https://localhost:8080/"
922 | },
923 | "id": "GquRS88WCnQD",
924 | "outputId": "0eb253b6-6270-40ce-b151-b730a5644e4b"
925 | },
926 | "outputs": [
927 | {
928 | "name": "stdout",
929 | "output_type": "stream",
930 | "text": [
931 | "\n",
932 | "Welcome to Python 3.10's help utility!\n",
933 | "\n",
934 | "If this is your first time using Python, you should definitely check out\n",
935 | "the tutorial on the internet at https://docs.python.org/3.10/tutorial/.\n",
936 | "\n",
937 | "Enter the name of any module, keyword, or topic to get help on writing\n",
938 | "Python programs and using Python modules. To quit this help utility and\n",
939 | "return to the interpreter, just type \"quit\".\n",
940 | "\n",
941 | "To get a list of available modules, keywords, symbols, or topics, type\n",
942 | "\"modules\", \"keywords\", \"symbols\", or \"topics\". Each module also comes\n",
943 | "with a one-line summary of what it does; to list the modules whose name\n",
944 | "or summary contain a given string such as \"spam\", type \"modules spam\".\n",
945 | "\n",
946 | "help> quit\n",
947 | "\n",
948 | "You are now leaving help and returning to the Python interpreter.\n",
949 | "If you want to ask for help on a particular object directly from the\n",
950 | "interpreter, you can type \"help(object)\". Executing \"help('string')\"\n",
951 | "has the same effect as typing a particular string at the help> prompt.\n"
952 | ]
953 | }
954 | ],
955 | "source": [
956 | "help()"
957 | ]
958 | },
959 | {
960 | "cell_type": "code",
961 | "execution_count": 35,
962 | "metadata": {
963 | "colab": {
964 | "base_uri": "https://localhost:8080/"
965 | },
966 | "id": "BniDjKwxCzGD",
967 | "outputId": "9c6831ee-4a48-4769-a1b6-50f25a9ca290"
968 | },
969 | "outputs": [
970 | {
971 | "name": "stdout",
972 | "output_type": "stream",
973 | "text": [
974 | "Help on function find_root in module __main__:\n",
975 | "\n",
976 | "find_root(x, power, epsilon)\n",
977 | " x와 epsilon은 int 또는 float, power는 int, \n",
978 | " epsilon > 0 & power >= 1라고 가정합니다.\n",
979 | " x에서 epsilon 이내에 y**power가 있다면 y를 반환합니다.\n",
980 | " 이런 float 값이 존재하지 않으면 None을 반환합니다\n",
981 | "\n"
982 | ]
983 | }
984 | ],
985 | "source": [
986 | "help(find_root)"
987 | ]
988 | },
989 | {
990 | "cell_type": "markdown",
991 | "metadata": {
992 | "id": "c6niUT3yN10Q"
993 | },
994 | "source": [
995 | "**뇌풀기 문제**"
996 | ]
997 | },
998 | {
999 | "cell_type": "code",
1000 | "execution_count": 36,
1001 | "metadata": {
1002 | "colab": {
1003 | "base_uri": "https://localhost:8080/"
1004 | },
1005 | "id": "ZK1AX8RaDJ7S",
1006 | "outputId": "f213648a-c994-43b1-ede9-3e9ea3dbbb34"
1007 | },
1008 | "outputs": [
1009 | {
1010 | "data": {
1011 | "text/plain": [
1012 | "3.0"
1013 | ]
1014 | },
1015 | "execution_count": 36,
1016 | "metadata": {},
1017 | "output_type": "execute_result"
1018 | }
1019 | ],
1020 | "source": [
1021 | "def log(x, base, epsilon):\n",
1022 | " \"\"\"x와 epsilon은 int 또는 float, base는 int,\n",
1023 | " x > 1, epsilon > 0 & power >= 1라고 가정합니다.\n",
1024 | " x에서 epsilon 이내에 base**y를 만족시키는 y를 반환합니다.\"\"\"\n",
1025 | " # y의 하한값을 찾습니다\n",
1026 | " lower_bound = 0\n",
1027 | " while base**lower_bound < x:\n",
1028 | " lower_bound += 1\n",
1029 | " low = lower_bound -1\n",
1030 | " high = lower_bound + 1\n",
1031 | " # 이분 검색을 수행합니다\n",
1032 | " y = (high + low)/2\n",
1033 | " while abs(base**y -x) >= epsilon:\n",
1034 | " if base**y < x:\n",
1035 | " low = ans\n",
1036 | " else:\n",
1037 | " high = ans\n",
1038 | " y = (high + low)/2\n",
1039 | " return y\n",
1040 | "\n",
1041 | "log(8, 2, 0.01)"
1042 | ]
1043 | },
1044 | {
1045 | "cell_type": "markdown",
1046 | "metadata": {
1047 | "id": "IHgDO3ITPXby"
1048 | },
1049 | "source": [
1050 | "## 4.3 함수를 사용해 코드를 모듈화하기"
1051 | ]
1052 | },
1053 | {
1054 | "cell_type": "markdown",
1055 | "metadata": {
1056 | "id": "axwU5t67dDIK"
1057 | },
1058 | "source": [
1059 | "예제 4-7 `find_root`를 여러 개의 함수로 분할하기"
1060 | ]
1061 | },
1062 | {
1063 | "cell_type": "code",
1064 | "execution_count": 37,
1065 | "metadata": {
1066 | "id": "E_qBabyOOcVI"
1067 | },
1068 | "outputs": [],
1069 | "source": [
1070 | "def find_root_bounds(x, power):\n",
1071 | " \"\"\"x는 float, power는 양의 정수입니다.\n",
1072 | " low**power <=x 이고 high**power >= x인 low, high를 반환합니다.\n",
1073 | " \"\"\"\n",
1074 | " low = min(-1, x)\n",
1075 | " high = max(1, x)\n",
1076 | " return low, high\n",
1077 | "\n",
1078 | "def bisection_solve(x, power, epsilon, low, high):\n",
1079 | " \"\"\"x, epsilon, low, high는 float, epsilon > 0, low <= high이고\n",
1080 | " x에서 epsilon 이내에 ans**power를 만족시키는\n",
1081 | " low와 high 사이의 값 ans가 있습니다.\n",
1082 | " x에서 epsilon 이내에 ans**power를 만족시키는 ans를 반환합니다\"\"\"\n",
1083 | " ans = (high + low)/2\n",
1084 | " while abs(ans**power - x) >= epsilon:\n",
1085 | " if ans**power < x:\n",
1086 | " low = ans\n",
1087 | " else:\n",
1088 | " high = ans\n",
1089 | " ans = (high + low)/2\n",
1090 | " return ans\n",
1091 | "\n",
1092 | "def find_root(x, power, epsilon):\n",
1093 | " \"\"\"x와 epsilon은 int 또는 float, power는 int,\n",
1094 | " epsilon > 0 & power >= 1라고 가정합니다.\n",
1095 | " x에서 epsilon 이내에 y**power가 있다면 y를 반환합니다.\n",
1096 | " 이런 float 값이 존재하지 않으면 None을 반환합니다\"\"\"\n",
1097 | " if x < 0 and power%2 == 0:\n",
1098 | " return None #음수는 짝수 제곱근이 없습니다.\n",
1099 | " low, high = find_root_bounds(x, power)\n",
1100 | " return bisection_solve(x, power, epsilon, low, high)"
1101 | ]
1102 | },
1103 | {
1104 | "cell_type": "markdown",
1105 | "metadata": {
1106 | "id": "unkWKcT9dGCe"
1107 | },
1108 | "source": [
1109 | "## 4.4 객체로서의 함수"
1110 | ]
1111 | },
1112 | {
1113 | "cell_type": "markdown",
1114 | "metadata": {
1115 | "id": "GIvlouCQfy2-"
1116 | },
1117 | "source": [
1118 | "예제 4-8 `bisection_solve` 일반화하기"
1119 | ]
1120 | },
1121 | {
1122 | "cell_type": "code",
1123 | "execution_count": 38,
1124 | "metadata": {
1125 | "id": "1_16xw61hN99"
1126 | },
1127 | "outputs": [],
1128 | "source": [
1129 | "def bisection_solve(x, eval_ans, epsilon, low, high):\n",
1130 | " \"\"\"x, epsilon, low, high는 float, epsilon > 0,\n",
1131 | " eval_ans는 float를 float로 매핑하는 함수, low <= high이고,\n",
1132 | " x에서 epsilon 이내에 eval(ans)를 만족시키는\n",
1133 | " low와 high 사이의 값 ans가 있습니다.\n",
1134 | " x에서 epsilon 이내에 eval(ans)를 만족시키는 ans를 반환합니다\"\"\"\n",
1135 | " ans = (high + low)/2\n",
1136 | " while abs(eval_ans(ans) - x) >= epsilon:\n",
1137 | " if eval_ans(ans) < x:\n",
1138 | " low = ans\n",
1139 | " else:\n",
1140 | " high = ans\n",
1141 | " ans = (high + low)/2\n",
1142 | " return ans"
1143 | ]
1144 | },
1145 | {
1146 | "cell_type": "code",
1147 | "execution_count": 39,
1148 | "metadata": {
1149 | "colab": {
1150 | "base_uri": "https://localhost:8080/"
1151 | },
1152 | "id": "k40bDCyChOcN",
1153 | "outputId": "db34067b-a292-416f-c1a2-0e84e35f7715"
1154 | },
1155 | "outputs": [
1156 | {
1157 | "name": "stdout",
1158 | "output_type": "stream",
1159 | "text": [
1160 | "9.94970703125\n"
1161 | ]
1162 | }
1163 | ],
1164 | "source": [
1165 | "def square(ans):\n",
1166 | " return ans**2\n",
1167 | "\n",
1168 | "low, high = find_root_bounds(99, 2)\n",
1169 | "print(bisection_solve(99, square, 0.01, low, high))"
1170 | ]
1171 | },
1172 | {
1173 | "cell_type": "markdown",
1174 | "metadata": {
1175 | "id": "j7gdc3knrVUT"
1176 | },
1177 | "source": [
1178 | "**뇌풀기 문제**"
1179 | ]
1180 | },
1181 | {
1182 | "cell_type": "code",
1183 | "execution_count": 40,
1184 | "metadata": {
1185 | "colab": {
1186 | "base_uri": "https://localhost:8080/"
1187 | },
1188 | "id": "TKEdvo03mQsw",
1189 | "outputId": "6ab8fdc1-df35-4abc-de2f-94bded4abefe"
1190 | },
1191 | "outputs": [
1192 | {
1193 | "data": {
1194 | "text/plain": [
1195 | "(None, 2.0)"
1196 | ]
1197 | },
1198 | "execution_count": 40,
1199 | "metadata": {},
1200 | "output_type": "execute_result"
1201 | }
1202 | ],
1203 | "source": [
1204 | "f = lambda i, j: None if j == 0 else i/j\n",
1205 | "\n",
1206 | "f(4, 0), f(4, 2)"
1207 | ]
1208 | },
1209 | {
1210 | "cell_type": "code",
1211 | "execution_count": 41,
1212 | "metadata": {
1213 | "id": "09OSxAgMrmDr"
1214 | },
1215 | "outputs": [],
1216 | "source": [
1217 | "def create_eval_ans():\n",
1218 | " power = input('양의 정수를 입력하세요: ')\n",
1219 | " return lambda ans: ans**int(power)"
1220 | ]
1221 | },
1222 | {
1223 | "cell_type": "code",
1224 | "execution_count": 42,
1225 | "metadata": {
1226 | "colab": {
1227 | "base_uri": "https://localhost:8080/"
1228 | },
1229 | "id": "UaczoX3hsNdv",
1230 | "outputId": "6f847c38-437a-4966-f7d8-a05882b225fb"
1231 | },
1232 | "outputs": [
1233 | {
1234 | "name": "stdout",
1235 | "output_type": "stream",
1236 | "text": [
1237 | "양의 정수를 입력하세요: 2\n",
1238 | "9.94970703125\n"
1239 | ]
1240 | }
1241 | ],
1242 | "source": [
1243 | "eval_ans = create_eval_ans()\n",
1244 | "print(bisection_solve(99, eval_ans, 0.01, low, high))"
1245 | ]
1246 | },
1247 | {
1248 | "cell_type": "markdown",
1249 | "metadata": {
1250 | "id": "YFkBTFeptgXP"
1251 | },
1252 | "source": [
1253 | "예제 4-9 `bisection_solve`를 사용하여 로그의 근삿값 구하기"
1254 | ]
1255 | },
1256 | {
1257 | "cell_type": "code",
1258 | "execution_count": 43,
1259 | "metadata": {
1260 | "id": "deOLaadJsSkI"
1261 | },
1262 | "outputs": [],
1263 | "source": [
1264 | "def log(x, base, epsilon):\n",
1265 | " \"\"\"x와 epsilon은 int 또는 float, base는 int,\n",
1266 | " x > 1, epsilon > 0 & power >= 1이라 가정합니다.\n",
1267 | " x에서 epsilon 이내에 base**y를 만족시키는 float y를 반환합니다.\"\"\"\n",
1268 | " def find_log_bounds(x, base):\n",
1269 | " upper_bound = 0\n",
1270 | " while base**upper_bound < x:\n",
1271 | " upper_bound += 1\n",
1272 | " return upper_bound -1, upper_bound\n",
1273 | " low, high = find_log_bounds(x, base)\n",
1274 | " return bisection_solve(x, lambda ans: base**ans, epsilon, low, high)"
1275 | ]
1276 | },
1277 | {
1278 | "cell_type": "markdown",
1279 | "metadata": {
1280 | "id": "WGBvd74rvk-u"
1281 | },
1282 | "source": [
1283 | "## 4.5 메서드"
1284 | ]
1285 | },
1286 | {
1287 | "cell_type": "code",
1288 | "execution_count": 44,
1289 | "metadata": {
1290 | "colab": {
1291 | "base_uri": "https://localhost:8080/"
1292 | },
1293 | "id": "jPZRaYixtX0r",
1294 | "outputId": "3b90181b-d126-4241-c01a-15a61e266816"
1295 | },
1296 | "outputs": [
1297 | {
1298 | "data": {
1299 | "text/plain": [
1300 | "1"
1301 | ]
1302 | },
1303 | "execution_count": 44,
1304 | "metadata": {},
1305 | "output_type": "execute_result"
1306 | }
1307 | ],
1308 | "source": [
1309 | "s = 'abcbc'\n",
1310 | "s.find('bc')"
1311 | ]
1312 | },
1313 | {
1314 | "cell_type": "code",
1315 | "execution_count": 45,
1316 | "metadata": {
1317 | "colab": {
1318 | "base_uri": "https://localhost:8080/",
1319 | "height": 183
1320 | },
1321 | "id": "tigy0joH1rw9",
1322 | "outputId": "b59e1a19-a777-46ff-8f8f-2b57618d5cc2"
1323 | },
1324 | "outputs": [
1325 | {
1326 | "ename": "NameError",
1327 | "evalue": "ignored",
1328 | "output_type": "error",
1329 | "traceback": [
1330 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
1331 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
1332 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfind\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'bc'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
1333 | "\u001b[0;31mNameError\u001b[0m: name 'find' is not defined"
1334 | ]
1335 | }
1336 | ],
1337 | "source": [
1338 | "find(s, 'bc')"
1339 | ]
1340 | },
1341 | {
1342 | "cell_type": "markdown",
1343 | "metadata": {
1344 | "id": "7Z6ggwz41sw8"
1345 | },
1346 | "source": [
1347 | "**뇌풀기 문제**"
1348 | ]
1349 | },
1350 | {
1351 | "cell_type": "code",
1352 | "execution_count": 46,
1353 | "metadata": {
1354 | "colab": {
1355 | "base_uri": "https://localhost:8080/"
1356 | },
1357 | "id": "-WHBZe541x6i",
1358 | "outputId": "054e8f84-3beb-4750-b9de-ab914f16d157"
1359 | },
1360 | "outputs": [
1361 | {
1362 | "data": {
1363 | "text/plain": [
1364 | "-1"
1365 | ]
1366 | },
1367 | "execution_count": 46,
1368 | "metadata": {},
1369 | "output_type": "execute_result"
1370 | }
1371 | ],
1372 | "source": [
1373 | "s.find('cd')"
1374 | ]
1375 | },
1376 | {
1377 | "cell_type": "markdown",
1378 | "metadata": {
1379 | "id": "jFnDg7pW2DIJ"
1380 | },
1381 | "source": [
1382 | "**뇌풀기 문제**"
1383 | ]
1384 | },
1385 | {
1386 | "cell_type": "code",
1387 | "execution_count": 47,
1388 | "metadata": {
1389 | "colab": {
1390 | "base_uri": "https://localhost:8080/"
1391 | },
1392 | "id": "IS8DJe3u2caP",
1393 | "outputId": "585279c8-200c-4702-df67-61b68d9e188d"
1394 | },
1395 | "outputs": [
1396 | {
1397 | "data": {
1398 | "text/plain": [
1399 | "3"
1400 | ]
1401 | },
1402 | "execution_count": 47,
1403 | "metadata": {},
1404 | "output_type": "execute_result"
1405 | }
1406 | ],
1407 | "source": [
1408 | "def find_last(s, sub):\n",
1409 | " \"\"\"s와 sub는 빈 문자열이 아닙니다.\n",
1410 | " s에서 sub이 마지막으로 등장하는 인덱스를 반환하세요.\n",
1411 | " s에 sub이 등장하지 않으면 None을 반환합니다\"\"\"\n",
1412 | " if s.find(sub) < 0:\n",
1413 | " return None\n",
1414 | " return len(s) - (s[::-1].find(sub[::-1]) + len(sub))\n",
1415 | "\n",
1416 | "find_last('abcbc', 'bc')"
1417 | ]
1418 | }
1419 | ],
1420 | "metadata": {
1421 | "colab": {
1422 | "provenance": []
1423 | },
1424 | "kernelspec": {
1425 | "display_name": "Python 3 (ipykernel)",
1426 | "language": "python",
1427 | "name": "python3"
1428 | },
1429 | "language_info": {
1430 | "codemirror_mode": {
1431 | "name": "ipython",
1432 | "version": 3
1433 | },
1434 | "file_extension": ".py",
1435 | "mimetype": "text/x-python",
1436 | "name": "python",
1437 | "nbconvert_exporter": "python",
1438 | "pygments_lexer": "ipython3",
1439 | "version": "3.8.2"
1440 | }
1441 | },
1442 | "nbformat": 4,
1443 | "nbformat_minor": 1
1444 | }
1445 |
--------------------------------------------------------------------------------
/06장.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "x_DA7MhnPJMn"
7 | },
8 | "source": [
9 | "\n",
10 | " \n",
11 | " | "
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "metadata": {
17 | "id": "GojwnblnPOn7"
18 | },
19 | "source": [
20 | "# 6장 재귀와 전역 변수"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {
26 | "id": "owatuASEruyt"
27 | },
28 | "source": [
29 | "예제 6-1 팩토리얼의 반복 구현과 재귀 구현"
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": null,
35 | "metadata": {
36 | "id": "KfRbgwesO-ym"
37 | },
38 | "outputs": [],
39 | "source": [
40 | "def fact_iter(n):\n",
41 | " \"\"\"n은 0보다 큰 정수로 가정합니다\n",
42 | " n!을 반환합니다\"\"\"\n",
43 | " result = 1\n",
44 | " for i in range(1, n+1):\n",
45 | " result *= i\n",
46 | " return result\n",
47 | "\n",
48 | "def fact_rec(n):\n",
49 | " \"\"\"n은 0보다 큰 정수로 가정합니다\n",
50 | " n!을 반환합니다\"\"\"\n",
51 | " if n == 1:\n",
52 | " return n\n",
53 | " else:\n",
54 | " return n*fact_rec(n - 1)"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": null,
60 | "metadata": {
61 | "colab": {
62 | "base_uri": "https://localhost:8080/"
63 | },
64 | "id": "TnBefYE1PYA7",
65 | "outputId": "eacb48d3-b7f4-4a79-e94f-8910770e93df"
66 | },
67 | "outputs": [
68 | {
69 | "data": {
70 | "text/plain": [
71 | "120"
72 | ]
73 | },
74 | "execution_count": 2,
75 | "metadata": {},
76 | "output_type": "execute_result"
77 | }
78 | ],
79 | "source": [
80 | "fact_iter(5)"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": null,
86 | "metadata": {
87 | "colab": {
88 | "base_uri": "https://localhost:8080/"
89 | },
90 | "id": "Y0qqKreUPaOC",
91 | "outputId": "f9fbecfe-0696-49f2-e424-8f7642914b9d"
92 | },
93 | "outputs": [
94 | {
95 | "data": {
96 | "text/plain": [
97 | "120"
98 | ]
99 | },
100 | "execution_count": 3,
101 | "metadata": {},
102 | "output_type": "execute_result"
103 | }
104 | ],
105 | "source": [
106 | "fact_rec(5)"
107 | ]
108 | },
109 | {
110 | "cell_type": "markdown",
111 | "metadata": {
112 | "id": "3WXM9T5gfdBs"
113 | },
114 | "source": [
115 | "**뇌풀기 문제**"
116 | ]
117 | },
118 | {
119 | "cell_type": "code",
120 | "execution_count": null,
121 | "metadata": {
122 | "colab": {
123 | "base_uri": "https://localhost:8080/"
124 | },
125 | "id": "KxkpwRfJfeud",
126 | "outputId": "636b3710-f064-42d9-b299-85e18f57078a"
127 | },
128 | "outputs": [
129 | {
130 | "data": {
131 | "text/plain": [
132 | "2.9289682539682538"
133 | ]
134 | },
135 | "execution_count": 4,
136 | "metadata": {},
137 | "output_type": "execute_result"
138 | }
139 | ],
140 | "source": [
141 | "def harmonic_sum(n):\n",
142 | " if n == 1:\n",
143 | " return n\n",
144 | " else:\n",
145 | " return 1/n + harmonic_sum(n - 1)\n",
146 | "\n",
147 | "harmonic_sum(10)"
148 | ]
149 | },
150 | {
151 | "cell_type": "markdown",
152 | "metadata": {
153 | "id": "Dc5W5ZqLPdY7"
154 | },
155 | "source": [
156 | "## 6.1 피보나치 수열"
157 | ]
158 | },
159 | {
160 | "cell_type": "markdown",
161 | "metadata": {
162 | "id": "00c_y2_Lrz8H"
163 | },
164 | "source": [
165 | "예제 6-3 피보나치 수열의 재귀 구현"
166 | ]
167 | },
168 | {
169 | "cell_type": "code",
170 | "execution_count": null,
171 | "metadata": {
172 | "id": "lzXseW7UPf6p"
173 | },
174 | "outputs": [],
175 | "source": [
176 | "def fib(n):\n",
177 | " \"\"\"n은 정수이고 n >= 0이라고 가정합니다.\n",
178 | " n의 피보나치 수열 값을 반환합니다\"\"\"\n",
179 | " if n == 0 or n == 1:\n",
180 | " return 1\n",
181 | " else:\n",
182 | " return fib(n-1) + fib(n-2)\n",
183 | "\n",
184 | "def test_fib(n):\n",
185 | " for i in range(n+1):\n",
186 | " print(f'fib({i}) =', fib(i))"
187 | ]
188 | },
189 | {
190 | "cell_type": "code",
191 | "execution_count": null,
192 | "metadata": {
193 | "colab": {
194 | "base_uri": "https://localhost:8080/"
195 | },
196 | "id": "x0DKD1xvur2W",
197 | "outputId": "b283bdf5-da37-4248-b200-e556f831d4c1"
198 | },
199 | "outputs": [
200 | {
201 | "name": "stdout",
202 | "output_type": "stream",
203 | "text": [
204 | "fib(0) = 1\n",
205 | "fib(1) = 1\n",
206 | "fib(2) = 2\n",
207 | "fib(3) = 3\n",
208 | "fib(4) = 5\n",
209 | "fib(5) = 8\n"
210 | ]
211 | }
212 | ],
213 | "source": [
214 | "test_fib(5)"
215 | ]
216 | },
217 | {
218 | "cell_type": "code",
219 | "execution_count": null,
220 | "metadata": {
221 | "id": "0lSLUL4dux_u"
222 | },
223 | "outputs": [],
224 | "source": [
225 | "def fib2(n):\n",
226 | " \"\"\"n은 정수이고 n >= 0이라고 가정합니다.\n",
227 | " n의 피보나치 수열을 반환합니다\"\"\"\n",
228 | " fs = [1, 1]\n",
229 | " if n < 2:\n",
230 | " return fs[n]\n",
231 | " for i in range(1, n):\n",
232 | " fs.append(fs[i-1] + fs[i])\n",
233 | " return fs"
234 | ]
235 | },
236 | {
237 | "cell_type": "code",
238 | "execution_count": null,
239 | "metadata": {
240 | "colab": {
241 | "base_uri": "https://localhost:8080/"
242 | },
243 | "id": "F0w2eIHpwfS-",
244 | "outputId": "59f150a9-fe8a-4f29-8245-f56b2dd39fb8"
245 | },
246 | "outputs": [
247 | {
248 | "data": {
249 | "text/plain": [
250 | "[1, 1, 2, 3, 5, 8]"
251 | ]
252 | },
253 | "execution_count": 8,
254 | "metadata": {},
255 | "output_type": "execute_result"
256 | }
257 | ],
258 | "source": [
259 | "fib2(5)"
260 | ]
261 | },
262 | {
263 | "cell_type": "markdown",
264 | "metadata": {
265 | "id": "s6jNSE91_9ue"
266 | },
267 | "source": [
268 | "**뇌풀기 문제**"
269 | ]
270 | },
271 | {
272 | "cell_type": "code",
273 | "execution_count": null,
274 | "metadata": {
275 | "colab": {
276 | "base_uri": "https://localhost:8080/"
277 | },
278 | "id": "jhzft9xU__Tj",
279 | "outputId": "8aa74a1b-fdc1-4449-a5dc-c266cbb618e8"
280 | },
281 | "outputs": [
282 | {
283 | "name": "stdout",
284 | "output_type": "stream",
285 | "text": [
286 | "fib(2) 계산\n",
287 | "fib(2) 계산\n",
288 | "fib(2) 계산\n"
289 | ]
290 | },
291 | {
292 | "data": {
293 | "text/plain": [
294 | "8"
295 | ]
296 | },
297 | "execution_count": 9,
298 | "metadata": {},
299 | "output_type": "execute_result"
300 | }
301 | ],
302 | "source": [
303 | "def fib3(n):\n",
304 | " \"\"\"n은 정수이고 n >= 0이라고 가정합니다.\n",
305 | " n의 피보나치 수열 값을 반환합니다\"\"\"\n",
306 | " if n == 2:\n",
307 | " print('fib(2) 계산')\n",
308 | " if n == 0 or n == 1:\n",
309 | " return 1\n",
310 | " else:\n",
311 | " return fib3(n-1) + fib3(n-2)\n",
312 | "\n",
313 | "fib3(5)"
314 | ]
315 | },
316 | {
317 | "cell_type": "markdown",
318 | "metadata": {
319 | "id": "4Kn5TbBsALOt"
320 | },
321 | "source": [
322 | "## 6.2 팰린드롬"
323 | ]
324 | },
325 | {
326 | "cell_type": "markdown",
327 | "metadata": {
328 | "id": "22XGDZl5r7rV"
329 | },
330 | "source": [
331 | "예제 6-3 팰린드롬 테스트"
332 | ]
333 | },
334 | {
335 | "cell_type": "code",
336 | "execution_count": null,
337 | "metadata": {
338 | "id": "It2zBDpHHmo_"
339 | },
340 | "outputs": [],
341 | "source": [
342 | "def is_palindrome(s):\n",
343 | " \"\"\"s는 문자열이라 가정합니다.\n",
344 | " s에 있는 문자가 팰린드롬이면 True, 그렇지 않으면 False를 반환합니다.\n",
345 | " 알파벳 이외의 문자와 대소문자는 무시합니다\"\"\"\n",
346 | "\n",
347 | " def to_chars(s):\n",
348 | " s = s.lower()\n",
349 | " letters = ''\n",
350 | " for c in s:\n",
351 | " if c in 'abcdefghijklmnopqrstuvwxyz':\n",
352 | " letters = letters + c\n",
353 | " return letters\n",
354 | "\n",
355 | " def is_pal(s):\n",
356 | " if len(s) <= 1:\n",
357 | " return True\n",
358 | " else:\n",
359 | " return s[0] == s[-1] and is_pal(s[1:-1])\n",
360 | "\n",
361 | " return is_pal(to_chars(s))"
362 | ]
363 | },
364 | {
365 | "cell_type": "code",
366 | "execution_count": null,
367 | "metadata": {
368 | "colab": {
369 | "base_uri": "https://localhost:8080/"
370 | },
371 | "id": "229cCfqEH-yj",
372 | "outputId": "7c79decd-da60-4942-b34f-af11a90c24a3"
373 | },
374 | "outputs": [
375 | {
376 | "data": {
377 | "text/plain": [
378 | "True"
379 | ]
380 | },
381 | "execution_count": 11,
382 | "metadata": {},
383 | "output_type": "execute_result"
384 | }
385 | ],
386 | "source": [
387 | "is_palindrome('abccba')"
388 | ]
389 | },
390 | {
391 | "cell_type": "markdown",
392 | "metadata": {
393 | "id": "n95gzqRuOcrH"
394 | },
395 | "source": [
396 | "예제 6-4 팰린드롬 테스트 시각화 코드"
397 | ]
398 | },
399 | {
400 | "cell_type": "code",
401 | "execution_count": null,
402 | "metadata": {
403 | "id": "NXl_ah5dICCn"
404 | },
405 | "outputs": [],
406 | "source": [
407 | "def is_palindrome(s):\n",
408 | " \"\"\"s는 문자열이라 가정합니다.\n",
409 | " s에 있는 문자가 팰린드롬이면 True, 그렇지 않으면 False를 반환합니다.\n",
410 | " 알파벳 이외의 문자와 대소문자는 무시합니다\"\"\"\n",
411 | "\n",
412 | " def to_chars(s):\n",
413 | " s = s.lower()\n",
414 | " letters = ''\n",
415 | " for c in s:\n",
416 | " if c in 'abcdefghijklmnopqrstuvwxyz':\n",
417 | " letters = letters + c\n",
418 | " return letters\n",
419 | "\n",
420 | " def is_pal(s):\n",
421 | " print(' is_pal 호출:', s)\n",
422 | " if len(s) <= 1:\n",
423 | " print(' True 반환: 베이스 케이스')\n",
424 | " return True\n",
425 | " else:\n",
426 | " answer = s[0] == s[-1] and is_pal(s[1:-1])\n",
427 | " print('', answer, '반환:', s)\n",
428 | " return answer\n",
429 | "\n",
430 | " return is_pal(to_chars(s))"
431 | ]
432 | },
433 | {
434 | "cell_type": "code",
435 | "execution_count": null,
436 | "metadata": {
437 | "colab": {
438 | "base_uri": "https://localhost:8080/"
439 | },
440 | "id": "DA9VyvcCOBZe",
441 | "outputId": "e242ed1b-e410-4d86-c8c4-8d116b163aa4"
442 | },
443 | "outputs": [
444 | {
445 | "name": "stdout",
446 | "output_type": "stream",
447 | "text": [
448 | "dogGod 시도\n",
449 | " is_pal 호출: doggod\n",
450 | " is_pal 호출: oggo\n",
451 | " is_pal 호출: gg\n",
452 | " is_pal 호출: \n",
453 | " True 반환: 베이스 케이스\n",
454 | " True 반환: gg\n",
455 | " True 반환: oggo\n",
456 | " True 반환: doggod\n",
457 | "True\n",
458 | "doGood 시도\n",
459 | " is_pal 호출: dogood\n",
460 | " is_pal 호출: ogoo\n",
461 | " is_pal 호출: go\n",
462 | " False 반환: go\n",
463 | " False 반환: ogoo\n",
464 | " False 반환: dogood\n",
465 | "False\n"
466 | ]
467 | }
468 | ],
469 | "source": [
470 | "print('dogGod 시도')\n",
471 | "print(is_palindrome('dogGod'))\n",
472 | "print('doGood 시도')\n",
473 | "print(is_palindrome('doGood'))"
474 | ]
475 | },
476 | {
477 | "cell_type": "markdown",
478 | "metadata": {
479 | "id": "wmtumeSLOv7E"
480 | },
481 | "source": [
482 | "## 6.3 전역 변수"
483 | ]
484 | },
485 | {
486 | "cell_type": "markdown",
487 | "metadata": {
488 | "id": "ewJSRtZEsCaA"
489 | },
490 | "source": [
491 | "예제 6-5 전역 변수 사용하기"
492 | ]
493 | },
494 | {
495 | "cell_type": "code",
496 | "execution_count": null,
497 | "metadata": {
498 | "id": "dDZp8LYvOMvr"
499 | },
500 | "outputs": [],
501 | "source": [
502 | "def fib(x):\n",
503 | " \"\"\"x는 정수이고 x >= 0이라고 가정합니다.\n",
504 | " x의 피보나치 수열 값을 반환합니다\"\"\"\n",
505 | " global num_fib_calls\n",
506 | " num_fib_calls += 1\n",
507 | " if x == 0 or x == 1:\n",
508 | " return 1\n",
509 | " else:\n",
510 | " return fib(x-1) + fib(x-2)\n",
511 | "\n",
512 | "def test_fib(n):\n",
513 | " for i in range(n+1):\n",
514 | " global num_fib_calls\n",
515 | " num_fib_calls = 0\n",
516 | " print(f'fib({i})', '=', fib(i))\n",
517 | " print('fib 호출 횟수:', num_fib_calls, '번')"
518 | ]
519 | },
520 | {
521 | "cell_type": "code",
522 | "execution_count": null,
523 | "metadata": {
524 | "colab": {
525 | "base_uri": "https://localhost:8080/"
526 | },
527 | "id": "IQMt-N9RoBL9",
528 | "outputId": "3c12a43a-a410-4e5d-c854-dc1abe4aeb40"
529 | },
530 | "outputs": [
531 | {
532 | "name": "stdout",
533 | "output_type": "stream",
534 | "text": [
535 | "fib(0) = 1\n",
536 | "fib 호출 횟수: 1 번\n",
537 | "fib(1) = 1\n",
538 | "fib 호출 횟수: 1 번\n",
539 | "fib(2) = 2\n",
540 | "fib 호출 횟수: 3 번\n",
541 | "fib(3) = 3\n",
542 | "fib 호출 횟수: 5 번\n",
543 | "fib(4) = 5\n",
544 | "fib 호출 횟수: 9 번\n",
545 | "fib(5) = 8\n",
546 | "fib 호출 횟수: 15 번\n",
547 | "fib(6) = 13\n",
548 | "fib 호출 횟수: 25 번\n"
549 | ]
550 | }
551 | ],
552 | "source": [
553 | "test_fib(6)"
554 | ]
555 | }
556 | ],
557 | "metadata": {
558 | "colab": {
559 | "provenance": []
560 | },
561 | "kernelspec": {
562 | "display_name": "Python 3 (ipykernel)",
563 | "language": "python",
564 | "name": "python3"
565 | },
566 | "language_info": {
567 | "codemirror_mode": {
568 | "name": "ipython",
569 | "version": 3
570 | },
571 | "file_extension": ".py",
572 | "mimetype": "text/x-python",
573 | "name": "python",
574 | "nbconvert_exporter": "python",
575 | "pygments_lexer": "ipython3",
576 | "version": "3.8.2"
577 | }
578 | },
579 | "nbformat": 4,
580 | "nbformat_minor": 1
581 | }
582 |
--------------------------------------------------------------------------------
/07장.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "provenance": []
7 | },
8 | "kernelspec": {
9 | "name": "python3",
10 | "display_name": "Python 3"
11 | },
12 | "language_info": {
13 | "name": "python"
14 | }
15 | },
16 | "cells": [
17 | {
18 | "cell_type": "markdown",
19 | "source": [
20 | "\n",
21 | " \n",
22 | " | "
23 | ],
24 | "metadata": {
25 | "id": "fD-Q_EYixRZe"
26 | }
27 | },
28 | {
29 | "cell_type": "markdown",
30 | "source": [
31 | "# 7장 모듈과 파일"
32 | ],
33 | "metadata": {
34 | "id": "42c5y2qExVZX"
35 | }
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "source": [
40 | "그림 7-1 원과 구(sphere)에 관련된 코드"
41 | ],
42 | "metadata": {
43 | "id": "DPbImybVrGrh"
44 | }
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": null,
49 | "metadata": {
50 | "id": "9QgPoHd9xN52"
51 | },
52 | "outputs": [],
53 | "source": [
54 | "pi = 3.14159\n",
55 | "\n",
56 | "def area(radius):\n",
57 | " return pi*(radius**2)\n",
58 | "\n",
59 | "def circumference(radius):\n",
60 | " return 2*pi*radius\n",
61 | "\n",
62 | "def sphere_surface(radius):\n",
63 | " return 4.0*area(radius)\n",
64 | "\n",
65 | "def sphere_volume(radius):\n",
66 | " return (4.0/3.0)*pi*(radius**3)"
67 | ]
68 | },
69 | {
70 | "cell_type": "code",
71 | "source": [
72 | "# 코랩에서 실행하는 경우 깃허브에 있는 circle.py 파일을 다운로드합니다.\n",
73 | "!wget https://raw.githubusercontent.com/rickiepark/python4daml/main/circle.py"
74 | ],
75 | "metadata": {
76 | "colab": {
77 | "base_uri": "https://localhost:8080/"
78 | },
79 | "id": "5Zx8vNYSvCwq",
80 | "outputId": "ef8da76f-d913-4c4b-8dbd-2194447ce78f"
81 | },
82 | "execution_count": null,
83 | "outputs": [
84 | {
85 | "output_type": "stream",
86 | "name": "stdout",
87 | "text": [
88 | "--2023-04-03 14:22:11-- https://raw.githubusercontent.com/rickiepark/python4daml/main/circle.py\n",
89 | "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n",
90 | "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n",
91 | "HTTP request sent, awaiting response... 200 OK\n",
92 | "Length: 230 [text/plain]\n",
93 | "Saving to: ‘circle.py’\n",
94 | "\n",
95 | "\rcircle.py 0%[ ] 0 --.-KB/s \rcircle.py 100%[===================>] 230 --.-KB/s in 0s \n",
96 | "\n",
97 | "2023-04-03 14:22:12 (14.0 MB/s) - ‘circle.py’ saved [230/230]\n",
98 | "\n"
99 | ]
100 | }
101 | ]
102 | },
103 | {
104 | "cell_type": "code",
105 | "source": [
106 | "import circle\n",
107 | "pi = 3\n",
108 | "print(pi)\n",
109 | "print(circle.pi)\n",
110 | "print(circle.area(3))\n",
111 | "print(circle.circumference(3))\n",
112 | "print(circle.sphere_surface(3))"
113 | ],
114 | "metadata": {
115 | "colab": {
116 | "base_uri": "https://localhost:8080/"
117 | },
118 | "id": "3YymmHNjrFmn",
119 | "outputId": "c060d542-827e-42b4-c5b0-addb7a53ef2f"
120 | },
121 | "execution_count": null,
122 | "outputs": [
123 | {
124 | "output_type": "stream",
125 | "name": "stdout",
126 | "text": [
127 | "3\n",
128 | "3.14159\n",
129 | "28.27431\n",
130 | "18.849539999999998\n",
131 | "113.09724\n"
132 | ]
133 | }
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "source": [
139 | "# circle 모듈을 다시 로드하기 위해\n",
140 | "del circle"
141 | ],
142 | "metadata": {
143 | "id": "3WEgG_RFtZsT"
144 | },
145 | "execution_count": null,
146 | "outputs": []
147 | },
148 | {
149 | "cell_type": "code",
150 | "source": [
151 | "from circle import *\n",
152 | "print(pi)\n",
153 | "print(circle.pi)"
154 | ],
155 | "metadata": {
156 | "colab": {
157 | "base_uri": "https://localhost:8080/",
158 | "height": 221
159 | },
160 | "id": "nYabW5V1u78a",
161 | "outputId": "2be8bc32-d30f-4cb2-866e-20f877b5eb76"
162 | },
163 | "execution_count": null,
164 | "outputs": [
165 | {
166 | "output_type": "stream",
167 | "name": "stdout",
168 | "text": [
169 | "3.14159\n"
170 | ]
171 | },
172 | {
173 | "output_type": "error",
174 | "ename": "NameError",
175 | "evalue": "ignored",
176 | "traceback": [
177 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
178 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
179 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mcircle\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcircle\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
180 | "\u001b[0;31mNameError\u001b[0m: name 'circle' is not defined"
181 | ]
182 | }
183 | ]
184 | },
185 | {
186 | "cell_type": "markdown",
187 | "source": [
188 | "## 7.2 사전에 정의된 패키지 사용하기"
189 | ],
190 | "metadata": {
191 | "id": "m5FxbAEQ4h9f"
192 | }
193 | },
194 | {
195 | "cell_type": "code",
196 | "source": [
197 | "import math\n",
198 | "\n",
199 | "x = 4\n",
200 | "print(math.log(x, 2))"
201 | ],
202 | "metadata": {
203 | "id": "_ozsR7EAfmA9",
204 | "outputId": "97d644df-53c8-43b4-874c-e81c8582f901",
205 | "colab": {
206 | "base_uri": "https://localhost:8080/"
207 | }
208 | },
209 | "execution_count": null,
210 | "outputs": [
211 | {
212 | "output_type": "stream",
213 | "name": "stdout",
214 | "text": [
215 | "2.0\n"
216 | ]
217 | }
218 | ]
219 | },
220 | {
221 | "cell_type": "code",
222 | "source": [
223 | "import calendar as cal\n",
224 | "cal_english = cal.TextCalendar()\n",
225 | "print(cal_english.formatmonth(1949, 3))"
226 | ],
227 | "metadata": {
228 | "id": "Tc824MjUs6I5",
229 | "colab": {
230 | "base_uri": "https://localhost:8080/"
231 | },
232 | "outputId": "b12425e9-1930-46dc-f65d-6f314949b4c8"
233 | },
234 | "execution_count": null,
235 | "outputs": [
236 | {
237 | "output_type": "stream",
238 | "name": "stdout",
239 | "text": [
240 | " March 1949\n",
241 | "Mo Tu We Th Fr Sa Su\n",
242 | " 1 2 3 4 5 6\n",
243 | " 7 8 9 10 11 12 13\n",
244 | "14 15 16 17 18 19 20\n",
245 | "21 22 23 24 25 26 27\n",
246 | "28 29 30 31\n",
247 | "\n"
248 | ]
249 | }
250 | ]
251 | },
252 | {
253 | "cell_type": "markdown",
254 | "source": [
255 | "코랩의 경우 다른 언어로 달력을 출력하려면 로케일을 추가한 후 런타임을 다시 실행해야 합니다."
256 | ],
257 | "metadata": {
258 | "id": "ssZGJvhce9La"
259 | }
260 | },
261 | {
262 | "cell_type": "code",
263 | "source": [
264 | "!/usr/share/locales/install-language-pack fr_FR\n",
265 | "!/usr/share/locales/install-language-pack pl_PL\n",
266 | "!/usr/share/locales/install-language-pack da_DK\n",
267 | "!dpkg-reconfigure locales\n",
268 | "\n",
269 | "# 런타임을 다시 시작합니다.\n",
270 | "import os\n",
271 | "os.kill(os.getpid(), 9)"
272 | ],
273 | "metadata": {
274 | "colab": {
275 | "base_uri": "https://localhost:8080/"
276 | },
277 | "id": "l0rv7H7ldP06",
278 | "outputId": "175486dc-deed-4709-bb14-49c9cc0806b7"
279 | },
280 | "execution_count": null,
281 | "outputs": [
282 | {
283 | "output_type": "stream",
284 | "name": "stdout",
285 | "text": [
286 | "Generating locales (this might take a while)...\n",
287 | " fr_FR.ISO-8859-1... done\n",
288 | "Generation complete.\n",
289 | "\u001b[1mdpkg-trigger:\u001b[0m \u001b[1;31merror:\u001b[0m must be called from a maintainer script (or with a --by-package option)\n",
290 | "\n",
291 | "Type dpkg-trigger --help for help about this utility.\n",
292 | "Generating locales (this might take a while)...\n",
293 | " pl_PL.ISO-8859-2... done\n",
294 | "Generation complete.\n",
295 | "\u001b[1mdpkg-trigger:\u001b[0m \u001b[1;31merror:\u001b[0m must be called from a maintainer script (or with a --by-package option)\n",
296 | "\n",
297 | "Type dpkg-trigger --help for help about this utility.\n",
298 | "Generating locales (this might take a while)...\n",
299 | " da_DK.ISO-8859-1... done\n",
300 | "Generation complete.\n",
301 | "\u001b[1mdpkg-trigger:\u001b[0m \u001b[1;31merror:\u001b[0m must be called from a maintainer script (or with a --by-package option)\n",
302 | "\n",
303 | "Type dpkg-trigger --help for help about this utility.\n",
304 | "Generating locales (this might take a while)...\n",
305 | " da_DK.ISO-8859-1... done\n",
306 | " en_US.UTF-8... done\n",
307 | " fr_FR.ISO-8859-1... done\n",
308 | " pl_PL.ISO-8859-2..."
309 | ]
310 | }
311 | ]
312 | },
313 | {
314 | "cell_type": "code",
315 | "source": [
316 | "import calendar as cal\n",
317 | "\n",
318 | "print(cal.LocaleTextCalendar(locale='fr_FR').formatmonth(2049, 3))\n",
319 | "print(cal.LocaleTextCalendar(locale='pl_PL').formatmonth(2049, 3))\n",
320 | "print(cal.LocaleTextCalendar(locale='da_DK').formatmonth(2049, 3))"
321 | ],
322 | "metadata": {
323 | "colab": {
324 | "base_uri": "https://localhost:8080/"
325 | },
326 | "id": "qWlEOqoGbnwy",
327 | "outputId": "7839d6c1-3bc7-4b4e-cdce-a55056af47a8"
328 | },
329 | "execution_count": null,
330 | "outputs": [
331 | {
332 | "output_type": "stream",
333 | "name": "stdout",
334 | "text": [
335 | " mars 2049\n",
336 | "lu ma me je ve sa di\n",
337 | " 1 2 3 4 5 6 7\n",
338 | " 8 9 10 11 12 13 14\n",
339 | "15 16 17 18 19 20 21\n",
340 | "22 23 24 25 26 27 28\n",
341 | "29 30 31\n",
342 | "\n",
343 | " marca 2049\n",
344 | "po wt śr cz pi so ni\n",
345 | " 1 2 3 4 5 6 7\n",
346 | " 8 9 10 11 12 13 14\n",
347 | "15 16 17 18 19 20 21\n",
348 | "22 23 24 25 26 27 28\n",
349 | "29 30 31\n",
350 | "\n",
351 | " marts 2049\n",
352 | "ma ti on to fr lø sø\n",
353 | " 1 2 3 4 5 6 7\n",
354 | " 8 9 10 11 12 13 14\n",
355 | "15 16 17 18 19 20 21\n",
356 | "22 23 24 25 26 27 28\n",
357 | "29 30 31\n",
358 | "\n"
359 | ]
360 | }
361 | ]
362 | },
363 | {
364 | "cell_type": "code",
365 | "source": [
366 | "print(cal.day_name[cal.weekday(2033, 12, 25)])"
367 | ],
368 | "metadata": {
369 | "colab": {
370 | "base_uri": "https://localhost:8080/"
371 | },
372 | "id": "Ov5AB9U7bxXe",
373 | "outputId": "2915d278-0222-4594-b523-6ebdde02e22b"
374 | },
375 | "execution_count": null,
376 | "outputs": [
377 | {
378 | "output_type": "stream",
379 | "name": "stdout",
380 | "text": [
381 | "Sunday\n"
382 | ]
383 | }
384 | ]
385 | },
386 | {
387 | "cell_type": "code",
388 | "source": [
389 | "def find_thanksgiving(year):\n",
390 | " month = cal.monthcalendar(year, 11)\n",
391 | " if month[0][cal.THURSDAY] != 0:\n",
392 | " thanksgiving = month[3][cal.THURSDAY]\n",
393 | " else:\n",
394 | " thanksgiving = month[4][cal.THURSDAY]\n",
395 | " return thanksgiving\n",
396 | "\n",
397 | "print('2011년 미국 추수감사절은 11월',\n",
398 | " find_thanksgiving(2011), '일 입니다')"
399 | ],
400 | "metadata": {
401 | "colab": {
402 | "base_uri": "https://localhost:8080/"
403 | },
404 | "id": "dme_l7lwgdtK",
405 | "outputId": "c2a2f8be-d8cf-4bf6-9b94-5bfd0297601e"
406 | },
407 | "execution_count": null,
408 | "outputs": [
409 | {
410 | "output_type": "stream",
411 | "name": "stdout",
412 | "text": [
413 | "2011년 미국 추수감사절은 11월 24 일 입니다\n"
414 | ]
415 | }
416 | ]
417 | },
418 | {
419 | "cell_type": "markdown",
420 | "source": [
421 | "**뇌풀기 문제**"
422 | ],
423 | "metadata": {
424 | "id": "wO_Pa9fywFaK"
425 | }
426 | },
427 | {
428 | "cell_type": "code",
429 | "source": [
430 | "def shopping_days(year):\n",
431 | " \"\"\"year >= 1941 입니다.\n",
432 | " 미국 추수감사절과 크리스마스 사이의 일수를 반환합니다\"\"\"\n",
433 | " thanksgiving_day = find_thanksgiving(year)\n",
434 | " return 30-thanksgiving_day+25-1\n",
435 | "\n",
436 | "shopping_days(2022)"
437 | ],
438 | "metadata": {
439 | "colab": {
440 | "base_uri": "https://localhost:8080/"
441 | },
442 | "id": "7wixGPX-wf6U",
443 | "outputId": "666b81b4-b493-4ed0-917d-07956bdf5425"
444 | },
445 | "execution_count": null,
446 | "outputs": [
447 | {
448 | "output_type": "execute_result",
449 | "data": {
450 | "text/plain": [
451 | "30"
452 | ]
453 | },
454 | "metadata": {},
455 | "execution_count": 4
456 | }
457 | ]
458 | },
459 | {
460 | "cell_type": "markdown",
461 | "source": [
462 | "**뇌풀기 문제**"
463 | ],
464 | "metadata": {
465 | "id": "8xNEy5TBxvOq"
466 | }
467 | },
468 | {
469 | "cell_type": "code",
470 | "source": [
471 | "def canadian_shopping_days(year):\n",
472 | " month = cal.monthcalendar(year, 10)\n",
473 | " if month[0][cal.MONDAY] != 0:\n",
474 | " thanksgiving_day = month[1][cal.MONDAY]\n",
475 | " else:\n",
476 | " thanksgiving_day = month[2][cal.MONDAY]\n",
477 | " return 31-thanksgiving_day+30+25-1\n",
478 | "\n",
479 | "canadian_shopping_days(2022)"
480 | ],
481 | "metadata": {
482 | "colab": {
483 | "base_uri": "https://localhost:8080/"
484 | },
485 | "id": "JQnc77rT0O7Y",
486 | "outputId": "c176740c-bcfe-43bf-b0da-1bbb73768d8a"
487 | },
488 | "execution_count": null,
489 | "outputs": [
490 | {
491 | "output_type": "execute_result",
492 | "data": {
493 | "text/plain": [
494 | "75"
495 | ]
496 | },
497 | "metadata": {},
498 | "execution_count": 5
499 | }
500 | ]
501 | },
502 | {
503 | "cell_type": "markdown",
504 | "source": [
505 | "## 7.3 파일"
506 | ],
507 | "metadata": {
508 | "id": "nRYUSpn55nUZ"
509 | }
510 | },
511 | {
512 | "cell_type": "code",
513 | "source": [
514 | "name_handle = open('kids', 'w')"
515 | ],
516 | "metadata": {
517 | "id": "1_Flp9Zt5sL-"
518 | },
519 | "execution_count": null,
520 | "outputs": []
521 | },
522 | {
523 | "cell_type": "code",
524 | "source": [
525 | "name_handle = open('kids', 'w')\n",
526 | "for i in range(2):\n",
527 | " name = input('이름을 입력하세요: ')\n",
528 | " name_handle.write(name + '\\n')\n",
529 | "name_handle.close()"
530 | ],
531 | "metadata": {
532 | "colab": {
533 | "base_uri": "https://localhost:8080/"
534 | },
535 | "id": "DVjHD4Ge0jD-",
536 | "outputId": "7873f86c-0f2b-4e2c-aaf0-4a0cdd342c13"
537 | },
538 | "execution_count": null,
539 | "outputs": [
540 | {
541 | "name": "stdout",
542 | "output_type": "stream",
543 | "text": [
544 | "이름을 입력하세요: David\n",
545 | "이름을 입력하세요: Andrea\n"
546 | ]
547 | }
548 | ]
549 | },
550 | {
551 | "cell_type": "code",
552 | "source": [
553 | "with open('kids', 'r') as name_handle:\n",
554 | " for line in name_handle:\n",
555 | " print(line)"
556 | ],
557 | "metadata": {
558 | "colab": {
559 | "base_uri": "https://localhost:8080/"
560 | },
561 | "id": "EB1JudTR55IX",
562 | "outputId": "8ceae904-e139-4509-bd72-df29c3195776"
563 | },
564 | "execution_count": null,
565 | "outputs": [
566 | {
567 | "output_type": "stream",
568 | "name": "stdout",
569 | "text": [
570 | "David\n",
571 | "\n",
572 | "Andrea\n",
573 | "\n"
574 | ]
575 | }
576 | ]
577 | },
578 | {
579 | "cell_type": "code",
580 | "source": [
581 | "name_handle = open('kids', 'w')\n",
582 | "name_handle.write('Michael')\n",
583 | "name_handle.write('Mark')\n",
584 | "name_handle.close()\n",
585 | "name_handle = open('kids', 'r')\n",
586 | "for line in name_handle:\n",
587 | " print(line)"
588 | ],
589 | "metadata": {
590 | "colab": {
591 | "base_uri": "https://localhost:8080/"
592 | },
593 | "id": "ZTbeZuhz60RO",
594 | "outputId": "a138f6a1-c462-4f45-f2ca-88bd92ed4079"
595 | },
596 | "execution_count": null,
597 | "outputs": [
598 | {
599 | "output_type": "stream",
600 | "name": "stdout",
601 | "text": [
602 | "MichaelMark\n"
603 | ]
604 | }
605 | ]
606 | },
607 | {
608 | "cell_type": "code",
609 | "source": [
610 | "name_handle = open('kids', 'a')\n",
611 | "name_handle = open('kids', 'a')\n",
612 | "name_handle.write('David')\n",
613 | "name_handle.write('Andrea')\n",
614 | "name_handle.close()\n",
615 | "name_handle = open('kids', 'r')\n",
616 | "for line in name_handle:\n",
617 | " print(line)"
618 | ],
619 | "metadata": {
620 | "colab": {
621 | "base_uri": "https://localhost:8080/"
622 | },
623 | "id": "l21bTBPE7sBA",
624 | "outputId": "11ff5fb1-4fd0-4811-9710-ba5de3ce1b18"
625 | },
626 | "execution_count": null,
627 | "outputs": [
628 | {
629 | "output_type": "stream",
630 | "name": "stdout",
631 | "text": [
632 | "MichaelMarkDavidAndrea\n"
633 | ]
634 | }
635 | ]
636 | },
637 | {
638 | "cell_type": "markdown",
639 | "source": [
640 | "**뇌풀기 문제**"
641 | ],
642 | "metadata": {
643 | "id": "pX69QPV-_fat"
644 | }
645 | },
646 | {
647 | "cell_type": "code",
648 | "source": [
649 | "def fib2(n):\n",
650 | " \"\"\"n은 정수이고 n >= 0이라고 가정합니다.\n",
651 | " n의 피보나치 수열을 반환합니다\"\"\"\n",
652 | " fs = [1, 1]\n",
653 | " if n < 2:\n",
654 | " return fs[n]\n",
655 | " for i in range(1, n):\n",
656 | " fs.append(fs[i-1] + fs[i])\n",
657 | " return fs\n",
658 | "\n",
659 | "with open('fib_file', 'w') as f:\n",
660 | " for i in fib2(9):\n",
661 | " f.write(f'{i}\\n')\n",
662 | "\n",
663 | "with open('fib_file', 'r') as f:\n",
664 | " for line in f:\n",
665 | " print(line[:-1])"
666 | ],
667 | "metadata": {
668 | "colab": {
669 | "base_uri": "https://localhost:8080/"
670 | },
671 | "id": "vUZGp5mR_gcj",
672 | "outputId": "2fcfd438-009c-47b4-81f0-4bc7c1cae42a"
673 | },
674 | "execution_count": null,
675 | "outputs": [
676 | {
677 | "output_type": "stream",
678 | "name": "stdout",
679 | "text": [
680 | "1\n",
681 | "1\n",
682 | "2\n",
683 | "3\n",
684 | "5\n",
685 | "8\n",
686 | "13\n",
687 | "21\n",
688 | "34\n",
689 | "55\n"
690 | ]
691 | }
692 | ]
693 | }
694 | ]
695 | }
--------------------------------------------------------------------------------
/08장.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "g3tfDi-PFUv3"
7 | },
8 | "source": [
9 | "\n",
10 | " \n",
11 | " | "
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "metadata": {
17 | "id": "l2u9Z2AOFOXR"
18 | },
19 | "source": [
20 | "# 8장 테스트와 디버깅"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {
26 | "id": "81zhK0iJPKeq"
27 | },
28 | "source": [
29 | "## 8.1 테스트"
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {
35 | "id": "0_1bi-DQFMmu"
36 | },
37 | "source": [
38 | "### 8.1.1 블랙 박스 테스트"
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": 1,
44 | "metadata": {
45 | "id": "CmLXz_PHvx8G"
46 | },
47 | "outputs": [],
48 | "source": [
49 | "def copy(L1, L2): \n",
50 | " \"\"\"L1, L2는 리스트라고 가정합니다.\n",
51 | " L2를 L1의 복사본으로 만듭니다\"\"\" \n",
52 | " while len(L2) > 0: #L2의 모든 원소를 삭제합니다\n",
53 | " L2.pop() #L2의 마지막 원소를 삭제합니다\n",
54 | " for e in L1: #L1의 원소를 L2에 추가합니다\n",
55 | " L2.append(e) "
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {
61 | "id": "PnA4UR9cfqXy"
62 | },
63 | "source": [
64 | "### 8.1.2 글라스 박스 테스트"
65 | ]
66 | },
67 | {
68 | "cell_type": "code",
69 | "execution_count": 2,
70 | "metadata": {
71 | "id": "dPDUMenFZIX0"
72 | },
73 | "outputs": [],
74 | "source": [
75 | "def is_prime(x): \n",
76 | " \"\"\"x는 음수가 아닌 정수로 가정합니다. \n",
77 | " x가 소수이면 True, 그렇지 않으면 False를 반환합니다\"\"\" \n",
78 | " if x <= 2: \n",
79 | " return False \n",
80 | " for i in range(2, x): \n",
81 | " if x%i == 0: \n",
82 | " return False \n",
83 | " return True "
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": 3,
89 | "metadata": {
90 | "id": "YvpT3f7SfnXg"
91 | },
92 | "outputs": [],
93 | "source": [
94 | "def abs(x): \n",
95 | " \"\"\"x는 int라고 가정합니다.\n",
96 | " x>=0이면 x를, 그렇지 않으면 –x를 반환합니다\"\"\" \n",
97 | " if x < -1: \n",
98 | " return -x \n",
99 | " else: \n",
100 | " return x"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {
106 | "id": "CSWVu-IsAP6R"
107 | },
108 | "source": [
109 | "### 8.1.3 테스트 수행하기"
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {
115 | "id": "nc5z5I0uw7Ok"
116 | },
117 | "source": [
118 | "## 8.2 디버깅"
119 | ]
120 | },
121 | {
122 | "cell_type": "markdown",
123 | "metadata": {
124 | "id": "VGuHpkxQw1lA"
125 | },
126 | "source": [
127 | "### 8.2.1 디버깅 배우기"
128 | ]
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "metadata": {
133 | "id": "GA21gAaHJqCr"
134 | },
135 | "source": [
136 | "### 8.2.2 실험 설계하기"
137 | ]
138 | },
139 | {
140 | "cell_type": "markdown",
141 | "metadata": {
142 | "id": "L8Wb2Wk9Ju_F"
143 | },
144 | "source": [
145 | "예제 8-1 버그가 있는 프로그램"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": 4,
151 | "metadata": {
152 | "id": "H0rRt0t1GR3E"
153 | },
154 | "outputs": [],
155 | "source": [
156 | "def is_pal(x):\n",
157 | " \"\"\"x는 리스트로 가정합니다.\n",
158 | " 리스트가 팰린드롬이면 True, 그렇지 않으면 False를 반환합니다\"\"\"\n",
159 | " temp = x\n",
160 | " temp.reverse\n",
161 | " return temp == x\n",
162 | "\n",
163 | "def silly(n):\n",
164 | " \"\"\"n은 정수이고 n > 0이라고 가정합니다.\n",
165 | " 사용자에게 n 개의 입력을 받고, 입력 시퀀스가 팰린드롬이면 'Yes',\n",
166 | " 그렇지 않으면 'No'를 출력합니다.\"\"\"\n",
167 | " for i in range(n):\n",
168 | " result = []\n",
169 | " elem = input('문자를 입력하세요: ')\n",
170 | " result.append(elem)\n",
171 | " if is_pal(result):\n",
172 | " print('Yes')\n",
173 | " else:\n",
174 | " print('No')"
175 | ]
176 | },
177 | {
178 | "cell_type": "code",
179 | "execution_count": 5,
180 | "metadata": {
181 | "colab": {
182 | "base_uri": "https://localhost:8080/"
183 | },
184 | "id": "Cl10RM5PJx56",
185 | "outputId": "9b9450e4-abc4-4750-f493-04a028f8bf1e"
186 | },
187 | "outputs": [
188 | {
189 | "name": "stdout",
190 | "output_type": "stream",
191 | "text": [
192 | "문자를 입력하세요: a\n",
193 | "문자를 입력하세요: b\n",
194 | "Yes\n"
195 | ]
196 | }
197 | ],
198 | "source": [
199 | "silly(2)"
200 | ]
201 | },
202 | {
203 | "cell_type": "code",
204 | "execution_count": 6,
205 | "metadata": {
206 | "id": "MTo2c1aqN0f8"
207 | },
208 | "outputs": [],
209 | "source": [
210 | "def is_pal(x):\n",
211 | " \"\"\"x는 리스트로 가정합니다.\n",
212 | " 리스트가 팰린드롬이면 True, 그렇지 않으면 False를 반환합니다\"\"\"\n",
213 | " temp = x\n",
214 | " temp.reverse\n",
215 | " return temp == x\n",
216 | "\n",
217 | "def silly(n):\n",
218 | " \"\"\"n은 정수이고 n > 0이라고 가정합니다.\n",
219 | " 사용자에게 n 개의 입력을 받고, 입력 시퀀스가 팰린드롬이면 'Yes',\n",
220 | " 그렇지 않으면 'No'를 출력합니다.\"\"\"\n",
221 | " result = []\n",
222 | " for i in range(n):\n",
223 | " elem = input('문자를 입력하세요: ')\n",
224 | " result.append(elem)\n",
225 | " print(result)\n",
226 | " if is_pal(result):\n",
227 | " print('Yes')\n",
228 | " else:\n",
229 | " print('No')"
230 | ]
231 | },
232 | {
233 | "cell_type": "code",
234 | "execution_count": 7,
235 | "metadata": {
236 | "colab": {
237 | "base_uri": "https://localhost:8080/"
238 | },
239 | "id": "-TtwobaPUOzY",
240 | "outputId": "d74623cb-ae91-43a3-bc97-504cc9352936"
241 | },
242 | "outputs": [
243 | {
244 | "name": "stdout",
245 | "output_type": "stream",
246 | "text": [
247 | "문자를 입력하세요: a\n",
248 | "문자를 입력하세요: b\n",
249 | "['a', 'b']\n",
250 | "Yes\n"
251 | ]
252 | }
253 | ],
254 | "source": [
255 | "silly(2)"
256 | ]
257 | },
258 | {
259 | "cell_type": "code",
260 | "execution_count": 8,
261 | "metadata": {
262 | "id": "h8f7Ssk_Wrzs"
263 | },
264 | "outputs": [],
265 | "source": [
266 | "def is_pal(x):\n",
267 | " \"\"\"x는 리스트로 가정합니다.\n",
268 | " 리스트가 팰린드롬이면 True, 그렇지 않으면 False를 반환합니다\"\"\"\n",
269 | " temp = x\n",
270 | " temp.reverse\n",
271 | " print(temp, x) \n",
272 | " return temp == x\n",
273 | "\n",
274 | "def silly(n):\n",
275 | " \"\"\"n은 정수이고 n > 0이라고 가정합니다.\n",
276 | " 사용자에게 n 개의 입력을 받고, 입력 시퀀스가 팰린드롬이면 'Yes',\n",
277 | " 그렇지 않으면 'No'를 출력합니다.\"\"\"\n",
278 | " result = []\n",
279 | " for i in range(n):\n",
280 | " elem = input('문자를 입력하세요: ')\n",
281 | " result.append(elem)\n",
282 | " if is_pal(result):\n",
283 | " print('Yes')\n",
284 | " else:\n",
285 | " print('No')"
286 | ]
287 | },
288 | {
289 | "cell_type": "code",
290 | "execution_count": 9,
291 | "metadata": {
292 | "colab": {
293 | "base_uri": "https://localhost:8080/"
294 | },
295 | "id": "rS3HJj7QXAZG",
296 | "outputId": "6423c509-1be0-4e42-87df-bdbd62953f87"
297 | },
298 | "outputs": [
299 | {
300 | "name": "stdout",
301 | "output_type": "stream",
302 | "text": [
303 | "문자를 입력하세요: a\n",
304 | "문자를 입력하세요: b\n",
305 | "['a', 'b'] ['a', 'b']\n",
306 | "Yes\n"
307 | ]
308 | }
309 | ],
310 | "source": [
311 | "silly(2)"
312 | ]
313 | },
314 | {
315 | "cell_type": "code",
316 | "execution_count": 10,
317 | "metadata": {
318 | "id": "rBTxChgPXCGN"
319 | },
320 | "outputs": [],
321 | "source": [
322 | "def is_pal(x):\n",
323 | " \"\"\"x는 리스트로 가정합니다.\n",
324 | " 리스트가 팰린드롬이면 True, 그렇지 않으면 False를 반환합니다\"\"\"\n",
325 | " temp = x\n",
326 | " temp.reverse()\n",
327 | " print(temp, x)\n",
328 | " return temp == x\n",
329 | "\n",
330 | "def silly(n):\n",
331 | " \"\"\"n은 정수이고 n > 0이라고 가정합니다.\n",
332 | " 사용자에게 n 개의 입력을 받고, 입력 시퀀스가 팰린드롬이면 'Yes',\n",
333 | " 그렇지 않으면 'No'를 출력합니다.\"\"\"\n",
334 | " result = []\n",
335 | " for i in range(n):\n",
336 | " elem = input('문자를 입력하세요: ')\n",
337 | " result.append(elem)\n",
338 | " if is_pal(result):\n",
339 | " print('Yes')\n",
340 | " else:\n",
341 | " print('No')"
342 | ]
343 | },
344 | {
345 | "cell_type": "code",
346 | "execution_count": 11,
347 | "metadata": {
348 | "colab": {
349 | "base_uri": "https://localhost:8080/"
350 | },
351 | "id": "sqa7cGkukQ3b",
352 | "outputId": "56afd576-0f19-474e-badd-7cf6980075fa"
353 | },
354 | "outputs": [
355 | {
356 | "name": "stdout",
357 | "output_type": "stream",
358 | "text": [
359 | "문자를 입력하세요: a\n",
360 | "문자를 입력하세요: b\n",
361 | "['b', 'a'] ['b', 'a']\n",
362 | "Yes\n"
363 | ]
364 | }
365 | ],
366 | "source": [
367 | "silly(2)"
368 | ]
369 | },
370 | {
371 | "cell_type": "code",
372 | "execution_count": 12,
373 | "metadata": {
374 | "id": "THK9ZBZ2kmKc"
375 | },
376 | "outputs": [],
377 | "source": [
378 | "def is_pal(x):\n",
379 | " \"\"\"x는 리스트로 가정합니다.\n",
380 | " 리스트가 팰린드롬이면 True, 그렇지 않으면 False를 반환합니다\"\"\"\n",
381 | " temp = x[:]\n",
382 | " temp.reverse()\n",
383 | " print(temp, x)\n",
384 | " return temp == x\n",
385 | "\n",
386 | "def silly(n):\n",
387 | " \"\"\"n은 정수이고 n > 0이라고 가정합니다.\n",
388 | " 사용자에게 n 개의 입력을 받고, 입력 시퀀스가 팰린드롬이면 'Yes',\n",
389 | " 그렇지 않으면 'No'를 출력합니다.\"\"\"\n",
390 | " result = []\n",
391 | " for i in range(n):\n",
392 | " elem = input('문자를 입력하세요: ')\n",
393 | " result.append(elem)\n",
394 | " if is_pal(result):\n",
395 | " print('Yes')\n",
396 | " else:\n",
397 | " print('No')"
398 | ]
399 | },
400 | {
401 | "cell_type": "code",
402 | "execution_count": 13,
403 | "metadata": {
404 | "colab": {
405 | "base_uri": "https://localhost:8080/"
406 | },
407 | "id": "aBksbZrskn5W",
408 | "outputId": "3f6f9df2-c96a-4f4d-fc63-1f6f1573132c"
409 | },
410 | "outputs": [
411 | {
412 | "name": "stdout",
413 | "output_type": "stream",
414 | "text": [
415 | "문자를 입력하세요: a\n",
416 | "문자를 입력하세요: b\n",
417 | "['b', 'a'] ['a', 'b']\n",
418 | "No\n"
419 | ]
420 | }
421 | ],
422 | "source": [
423 | "silly(2)"
424 | ]
425 | }
426 | ],
427 | "metadata": {
428 | "colab": {
429 | "authorship_tag": "ABX9TyMg/+pT/PZyS8GsTrMlNEl5",
430 | "collapsed_sections": [],
431 | "provenance": []
432 | },
433 | "kernelspec": {
434 | "display_name": "Python 3 (ipykernel)",
435 | "language": "python",
436 | "name": "python3"
437 | },
438 | "language_info": {
439 | "codemirror_mode": {
440 | "name": "ipython",
441 | "version": 3
442 | },
443 | "file_extension": ".py",
444 | "mimetype": "text/x-python",
445 | "name": "python",
446 | "nbconvert_exporter": "python",
447 | "pygments_lexer": "ipython3",
448 | "version": "3.8.2"
449 | }
450 | },
451 | "nbformat": 4,
452 | "nbformat_minor": 1
453 | }
454 |
--------------------------------------------------------------------------------
/09장.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "3b02jyTMFO0q"
7 | },
8 | "source": [
9 | "\n",
10 | " \n",
11 | " | "
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "metadata": {
17 | "id": "ojlcxZz3FOo0"
18 | },
19 | "source": [
20 | "# 9장 예외와 어서션"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {
26 | "id": "7XoXjX0Hv2Lf"
27 | },
28 | "source": [
29 | "## 9.1 예외 처리하기"
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {
35 | "id": "83v_8TEqXC00"
36 | },
37 | "source": [
38 | "**뇌풀기 문제**"
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": 16,
44 | "metadata": {
45 | "colab": {
46 | "base_uri": "https://localhost:8080/"
47 | },
48 | "id": "trBgADCtFM1G",
49 | "outputId": "9d480e9e-9c51-4651-9ec8-90b7e5fc014c"
50 | },
51 | "outputs": [
52 | {
53 | "data": {
54 | "text/plain": [
55 | "5"
56 | ]
57 | },
58 | "execution_count": 16,
59 | "metadata": {},
60 | "output_type": "execute_result"
61 | }
62 | ],
63 | "source": [
64 | "def sum_digits(s): \n",
65 | " \"\"\"s는 문자열이라고 가정합니다.\n",
66 | " s에 있는 숫자의 합을 반환합니다.\n",
67 | " 예를 들어 s가 'a2b3c'라면 5를 반환합니다\"\"\" \n",
68 | " sum = 0\n",
69 | " for i in s:\n",
70 | " try:\n",
71 | " sum += int(i)\n",
72 | " except ValueError:\n",
73 | " continue\n",
74 | " return sum\n",
75 | "\n",
76 | "sum_digits('a2b3c') "
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {
82 | "id": "jqI7FwqFCQ6R"
83 | },
84 | "source": [
85 | "예제 9-1 제어 흐름을 위해 예외 사용하기"
86 | ]
87 | },
88 | {
89 | "cell_type": "code",
90 | "execution_count": 17,
91 | "metadata": {
92 | "id": "tQz0RhsWYF5t"
93 | },
94 | "outputs": [],
95 | "source": [
96 | "def get_ratios(vect1, vect2): \n",
97 | " \"\"\"가정: vect1와 vect2은 동일 길이의 숫자 리스트입니다.\n",
98 | " 반환: vect1[i]/vect2[i]의 값을 담은 리스트\"\"\" \n",
99 | " ratios = [] \n",
100 | " for index in range(len(vect1)): \n",
101 | " try: \n",
102 | " ratios.append(vect1[index]/vect2[index]) \n",
103 | " except ZeroDivisionError: \n",
104 | " ratios.append(float('nan')) #nan = Not a Number \n",
105 | " except: \n",
106 | " raise ValueError('잘못된 인수로 get_ratios가 호출되었습니다') \n",
107 | " return ratios "
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": 18,
113 | "metadata": {
114 | "colab": {
115 | "base_uri": "https://localhost:8080/"
116 | },
117 | "id": "JaA8u1RECKct",
118 | "outputId": "6d485075-cb54-410c-83e3-658c9cf6a363"
119 | },
120 | "outputs": [
121 | {
122 | "name": "stdout",
123 | "output_type": "stream",
124 | "text": [
125 | "[1.0, 1.0, nan, 2.0]\n",
126 | "[]\n",
127 | "잘못된 인수로 get_ratios가 호출되었습니다\n"
128 | ]
129 | }
130 | ],
131 | "source": [
132 | "try: \n",
133 | " print(get_ratios([1, 2, 7, 6], [1, 2, 0, 3])) \n",
134 | " print(get_ratios([], [])) \n",
135 | " print(get_ratios([1, 2], [3])) \n",
136 | "except ValueError as msg:\n",
137 | " print(msg) "
138 | ]
139 | },
140 | {
141 | "cell_type": "markdown",
142 | "metadata": {
143 | "id": "eu7ZC6YuCN20"
144 | },
145 | "source": [
146 | "그림 9-2 try-except를 사용하지 않은 제어 흐름"
147 | ]
148 | },
149 | {
150 | "cell_type": "code",
151 | "execution_count": 19,
152 | "metadata": {
153 | "id": "CM39RKseJILV"
154 | },
155 | "outputs": [],
156 | "source": [
157 | "def get_ratios(vect1, vect2): \n",
158 | " \"\"\"가정: vect1와 vect2은 동일 길이의 숫자 리스트입니다.\n",
159 | " 반환: vect1[i]/vect2[i]의 값을 담은 리스트\"\"\" \n",
160 | " ratios = [] \n",
161 | " if len(vect1) != len(vect2): \n",
162 | " raise ValueError('잘못된 인수로 get_ratios가 호출되었습니다') \n",
163 | " for index in range(len(vect1)): \n",
164 | " vect1_elem = vect1[index] \n",
165 | " vect2_elem = vect2[index] \n",
166 | " if (type(vect1_elem) not in (int, float)) \\\n",
167 | " or (type(vect2_elem) not in (int, float)): \n",
168 | " raise ValueError('잘못된 인수로 get_ratios가 호출되었습니다') \n",
169 | " if vect2_elem == 0: \n",
170 | " ratios.append(float('NaN')) #NaN = Not a Number \n",
171 | " else: \n",
172 | " ratios.append(vect1_elem/vect2_elem) \n",
173 | " return ratios "
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": 21,
179 | "metadata": {
180 | "colab": {
181 | "base_uri": "https://localhost:8080/"
182 | },
183 | "id": "_Ryx-jz-kzAX",
184 | "outputId": "7822b8d7-75c2-47d5-f36d-2c01f19d6af1"
185 | },
186 | "outputs": [
187 | {
188 | "name": "stdout",
189 | "output_type": "stream",
190 | "text": [
191 | "정수를 입력하세요: 3\n",
192 | "입력한 정수의 제곱: 9\n"
193 | ]
194 | }
195 | ],
196 | "source": [
197 | "val = int(input('정수를 입력하세요: ')) \n",
198 | "print('입력한 정수의 제곱:', val**2)"
199 | ]
200 | },
201 | {
202 | "cell_type": "code",
203 | "execution_count": 22,
204 | "metadata": {
205 | "colab": {
206 | "base_uri": "https://localhost:8080/"
207 | },
208 | "id": "N4vz3kWBmzLW",
209 | "outputId": "20e5b7ae-ee03-4875-ec99-4e1259738f9f"
210 | },
211 | "outputs": [
212 | {
213 | "name": "stdout",
214 | "output_type": "stream",
215 | "text": [
216 | "정수를 입력하세요: abc\n",
217 | "abc (은)는 정수가 아닙니다\n",
218 | "정수를 입력하세요: 3\n",
219 | "입력한 정수의 제곱: 9\n"
220 | ]
221 | }
222 | ],
223 | "source": [
224 | "while True: \n",
225 | " val = input('정수를 입력하세요: ') \n",
226 | " try: \n",
227 | " val = int(val) \n",
228 | " print('입력한 정수의 제곱:', val**2) \n",
229 | " break #while 루프를 벗어나기 위해\n",
230 | " except ValueError: \n",
231 | " print(val, '(은)는 정수가 아닙니다') "
232 | ]
233 | },
234 | {
235 | "cell_type": "code",
236 | "execution_count": 23,
237 | "metadata": {
238 | "id": "twepJgxxzjKT"
239 | },
240 | "outputs": [],
241 | "source": [
242 | "def read_int(): \n",
243 | " while True: \n",
244 | " val = input('정수를 입력하세요: ') \n",
245 | " try: \n",
246 | " return(int(val)) #반환하기 전에 str을 int로 바꿉니다.\n",
247 | " except ValueError: \n",
248 | " print(val, '(은)는 정수가 아닙니다') "
249 | ]
250 | },
251 | {
252 | "cell_type": "code",
253 | "execution_count": 24,
254 | "metadata": {
255 | "id": "r29OEgTP3kxr"
256 | },
257 | "outputs": [],
258 | "source": [
259 | "def read_val(val_type, request_msg, error_msg): \n",
260 | " while True: \n",
261 | " val = input(request_msg + ' ') \n",
262 | " try: \n",
263 | " return(val_type(val)) #str을 val_type으로 바꿉니다.\n",
264 | " except ValueError: \n",
265 | " print(val, error_msg) "
266 | ]
267 | },
268 | {
269 | "cell_type": "code",
270 | "execution_count": 25,
271 | "metadata": {
272 | "colab": {
273 | "base_uri": "https://localhost:8080/"
274 | },
275 | "id": "9mwE-jQ25FIz",
276 | "outputId": "cd51ddd8-0b93-4fa1-92a7-f1c006853af0"
277 | },
278 | "outputs": [
279 | {
280 | "name": "stdout",
281 | "output_type": "stream",
282 | "text": [
283 | "정수를 입력하세요: abc\n",
284 | "abc (은)는 정수가 아닙니다\n",
285 | "정수를 입력하세요: 3\n"
286 | ]
287 | }
288 | ],
289 | "source": [
290 | "val = read_val(int, '정수를 입력하세요:', '(은)는 정수가 아닙니다') "
291 | ]
292 | },
293 | {
294 | "cell_type": "markdown",
295 | "metadata": {
296 | "id": "9Ybc03Tj5Fmw"
297 | },
298 | "source": [
299 | "## 9.2 제어 흐름 메커니즘으로 예외 사용하기"
300 | ]
301 | },
302 | {
303 | "cell_type": "markdown",
304 | "metadata": {
305 | "id": "HCjjMagh9Fgl"
306 | },
307 | "source": [
308 | "**뇌풀기 문제**"
309 | ]
310 | },
311 | {
312 | "cell_type": "code",
313 | "execution_count": 26,
314 | "metadata": {
315 | "id": "Q9ZexoOZA16p"
316 | },
317 | "outputs": [],
318 | "source": [
319 | "def find_an_even(L): \n",
320 | " \"\"\"L은 정수 리스트로 가정합니다. \n",
321 | " L에 있는 첫 번째 짝수를 반환합니다.\n",
322 | " L에 짝수가 없으면 ValueError 예외를 발생시킵니다\"\"\"\n",
323 | " for i in L:\n",
324 | " if i%2 == 0:\n",
325 | " return i\n",
326 | " raise ValueError('L에 짝수가 없습니다')"
327 | ]
328 | },
329 | {
330 | "cell_type": "code",
331 | "execution_count": 27,
332 | "metadata": {
333 | "colab": {
334 | "base_uri": "https://localhost:8080/"
335 | },
336 | "id": "n-CRkhfdBxEp",
337 | "outputId": "35921f61-9536-4b0e-bd7c-e1d3600216bc"
338 | },
339 | "outputs": [
340 | {
341 | "data": {
342 | "text/plain": [
343 | "2"
344 | ]
345 | },
346 | "execution_count": 27,
347 | "metadata": {},
348 | "output_type": "execute_result"
349 | }
350 | ],
351 | "source": [
352 | "find_an_even([1,2,3])"
353 | ]
354 | },
355 | {
356 | "cell_type": "code",
357 | "execution_count": 28,
358 | "metadata": {
359 | "colab": {
360 | "base_uri": "https://localhost:8080/",
361 | "height": 277
362 | },
363 | "id": "JhvhgKTBB15H",
364 | "outputId": "4a916864-9e53-4572-e77c-0c68c8d4b5ce"
365 | },
366 | "outputs": [
367 | {
368 | "ename": "ValueError",
369 | "evalue": "ignored",
370 | "output_type": "error",
371 | "traceback": [
372 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
373 | "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
374 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfind_an_even\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
375 | "\u001b[0;32m\u001b[0m in \u001b[0;36mfind_an_even\u001b[0;34m(L)\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mi\u001b[0m\u001b[0;34m%\u001b[0m\u001b[0;36m2\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mi\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'L에 짝수가 없습니다'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
376 | "\u001b[0;31mValueError\u001b[0m: L에 짝수가 없습니다"
377 | ]
378 | }
379 | ],
380 | "source": [
381 | "find_an_even([1,3,5])"
382 | ]
383 | },
384 | {
385 | "cell_type": "code",
386 | "execution_count": 30,
387 | "metadata": {
388 | "colab": {
389 | "base_uri": "https://localhost:8080/"
390 | },
391 | "id": "OhjpfmbfMk5c",
392 | "outputId": "29d1d14e-770d-435c-edd6-4a69c405f4eb"
393 | },
394 | "outputs": [
395 | {
396 | "name": "stdout",
397 | "output_type": "stream",
398 | "text": [
399 | "--2022-10-28 06:06:05-- https://raw.githubusercontent.com/rickiepark/python4daml/main/quiz1grades.txt\n",
400 | "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.109.133, ...\n",
401 | "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected.\n",
402 | "HTTP request sent, awaiting response... 200 OK\n",
403 | "Length: 302 [text/plain]\n",
404 | "Saving to: ‘quiz1grades.txt’\n",
405 | "\n",
406 | "\r",
407 | "quiz1grades.txt 0%[ ] 0 --.-KB/s \r",
408 | "quiz1grades.txt 100%[===================>] 302 --.-KB/s in 0s \n",
409 | "\n",
410 | "2022-10-28 06:06:05 (15.0 MB/s) - ‘quiz1grades.txt’ saved [302/302]\n",
411 | "\n"
412 | ]
413 | }
414 | ],
415 | "source": [
416 | "# 코랩의 경우 이 셀을 실행하여 깃허브에서 예제 텍스트 파일을 다운로드합니다.\n",
417 | "!wget https://raw.githubusercontent.com/rickiepark/python4daml/main/quiz1grades.txt"
418 | ]
419 | },
420 | {
421 | "cell_type": "markdown",
422 | "metadata": {},
423 | "source": [
424 | "예제 9-3 점수 얻기"
425 | ]
426 | },
427 | {
428 | "cell_type": "code",
429 | "execution_count": 31,
430 | "metadata": {
431 | "colab": {
432 | "base_uri": "https://localhost:8080/"
433 | },
434 | "id": "3WaiAahxB7hd",
435 | "outputId": "302073fe-82de-4490-e967-ce3656f790f4"
436 | },
437 | "outputs": [
438 | {
439 | "name": "stdout",
440 | "output_type": "stream",
441 | "text": [
442 | "점수의 중앙값: 83.0\n"
443 | ]
444 | }
445 | ],
446 | "source": [
447 | "def get_grades(fname):\n",
448 | " grades = []\n",
449 | " try:\n",
450 | " with open(fname, 'r') as grades_file:\n",
451 | " for line in grades_file:\n",
452 | " try:\n",
453 | " grades.append(float(line))\n",
454 | " except:\n",
455 | " raise ValueError('읽어들인 라인을 float로 바꿀 수 없습니다')\n",
456 | " except IOError:\n",
457 | " raise ValueError('get_grades가 다음 파일을 열 수 없습니다: ' + fname)\n",
458 | " return grades\n",
459 | "\n",
460 | "try:\n",
461 | " grades = get_grades('quiz1grades.txt')\n",
462 | " grades.sort()\n",
463 | " median = grades[len(grades)//2]\n",
464 | " print('점수의 중앙값:', median)\n",
465 | "except ValueError as error_msg:\n",
466 | " print('에러:', error_msg)"
467 | ]
468 | }
469 | ],
470 | "metadata": {
471 | "colab": {
472 | "authorship_tag": "ABX9TyORBEoq2on8h/+M538devJa",
473 | "collapsed_sections": [],
474 | "provenance": []
475 | },
476 | "kernelspec": {
477 | "display_name": "Python 3 (ipykernel)",
478 | "language": "python",
479 | "name": "python3"
480 | },
481 | "language_info": {
482 | "codemirror_mode": {
483 | "name": "ipython",
484 | "version": 3
485 | },
486 | "file_extension": ".py",
487 | "mimetype": "text/x-python",
488 | "name": "python",
489 | "nbconvert_exporter": "python",
490 | "pygments_lexer": "ipython3",
491 | "version": "3.8.2"
492 | }
493 | },
494 | "nbformat": 4,
495 | "nbformat_minor": 1
496 | }
497 |
--------------------------------------------------------------------------------
/12장.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "mfQbJKnNOAJb"
7 | },
8 | "source": [
9 | "\n",
10 | " \n",
11 | " | "
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "metadata": {
17 | "id": "KtiOf8SbN57J"
18 | },
19 | "source": [
20 | "# 12장 몇 가지 간단한 알고리즘과 데이터 구조"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {
26 | "id": "3YyhkPMi4xhD"
27 | },
28 | "source": [
29 | "## 12.1 검색 알고리즘"
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {
35 | "id": "jHK45qNo4ywI"
36 | },
37 | "source": [
38 | "### 12.1.1 선형 검색과 간접 참조로 원소에 접근하기"
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {
44 | "id": "rWx7pSgn4uYA"
45 | },
46 | "source": [
47 | "### 12.1.2 이진 검색과 가정 활용"
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {
53 | "id": "ZXVgIB7UN5Jb"
54 | },
55 | "source": [
56 | "예제 12.1 정렬된 리스트의 선형 검색"
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": 1,
62 | "metadata": {
63 | "id": "Yt0LQjxDIYQL"
64 | },
65 | "outputs": [],
66 | "source": [
67 | "def search(L, e):\n",
68 | " \"\"\"L이 리스트이고 원소가 오름차순으로 정렬되어 있다고 가정합니다.\n",
69 | " L에 e가 포함되어 있으면 True, 그렇지 않으면 False를 반환합니다\"\"\"\n",
70 | " for i in range(len(L)):\n",
71 | " if L[i] == e:\n",
72 | " return True\n",
73 | " if L[i] > e:\n",
74 | " return False\n",
75 | " return False"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {
81 | "id": "yjTyh1crYz4y"
82 | },
83 | "source": [
84 | "예제 12-2 재귀를 사용한 이진 검색 구현"
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": 2,
90 | "metadata": {
91 | "id": "tW4PyfDGRmGw"
92 | },
93 | "outputs": [],
94 | "source": [
95 | "def search(L, e):\n",
96 | " \"\"\"L이 리스트이고 원소가 오름차순으로 정렬되어 있다고 가정합니다.\n",
97 | " L에 e가 포함되어 있으면 True, 그렇지 않으면 False를 반환합니다\"\"\"\n",
98 | "\n",
99 | " def bin_search(L, e, low, high):\n",
100 | " #high - low를 줄입니다\n",
101 | " if high == low:\n",
102 | " return L[low] == e\n",
103 | " mid = (low + high)//2\n",
104 | " if L[mid] == e:\n",
105 | " return True\n",
106 | " elif L[mid] > e:\n",
107 | " if low == mid: #nothing left to search\n",
108 | " return False\n",
109 | " else:\n",
110 | " return bin_search(L, e, low, mid -1)\n",
111 | " else:\n",
112 | " return bin_search(L, e, mid + 1, high)\n",
113 | "\n",
114 | " if len(L) == 0:\n",
115 | " return False\n",
116 | " else:\n",
117 | " return bin_search(L, e, 0, len(L) -1)"
118 | ]
119 | },
120 | {
121 | "cell_type": "markdown",
122 | "metadata": {
123 | "id": "PkmDPh34Yt1e"
124 | },
125 | "source": [
126 | "## 12.2 정렬 알고리즘"
127 | ]
128 | },
129 | {
130 | "cell_type": "markdown",
131 | "metadata": {
132 | "id": "8BPB7qJKYvMN"
133 | },
134 | "source": [
135 | "예제 12-3 선택 정렬"
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": 3,
141 | "metadata": {
142 | "id": "flk97XyvYuPQ"
143 | },
144 | "outputs": [],
145 | "source": [
146 | "def sel_sort(L):\n",
147 | " \"\"\"L은 >을 사용해 비교할 수 있는 원소로 구성된 리스트라 가정합니다.\n",
148 | " L은 오름차순으로 정렬합니다\"\"\"\n",
149 | " suffix_start = 0\n",
150 | " while suffix_start != len(L):\n",
151 | " #뒷부분에 있는 모든 원소를 반복합니다\n",
152 | " for i in range(suffix_start, len(L)):\n",
153 | " if L[i] < L[suffix_start]:\n",
154 | " #원소의 위치를 바꿉니다\n",
155 | " L[suffix_start], L[i] = L[i], L[suffix_start]\n",
156 | " suffix_start += 1"
157 | ]
158 | },
159 | {
160 | "cell_type": "markdown",
161 | "metadata": {
162 | "id": "dMvSiLH4ZXfy"
163 | },
164 | "source": [
165 | "### 12.2.1 합병 정렬"
166 | ]
167 | },
168 | {
169 | "cell_type": "markdown",
170 | "metadata": {
171 | "id": "fX4XDml2knPh"
172 | },
173 | "source": [
174 | "예제 12-4 합병 정렬"
175 | ]
176 | },
177 | {
178 | "cell_type": "code",
179 | "execution_count": 4,
180 | "metadata": {
181 | "id": "5L3U8xPzZXOU"
182 | },
183 | "outputs": [],
184 | "source": [
185 | "def merge(left, right, compare):\n",
186 | " \"\"\"left와 right는 정렬된 리스트이고 compare는 원소의 순서를 정의합니다.\n",
187 | " (left + right)의 결과와 같은 원소를 담은 새로운 정렬된 리스트를 반환합니다.\"\"\"\n",
188 | "\n",
189 | " result = []\n",
190 | " i,j = 0, 0\n",
191 | " while i < len(left) and j < len(right):\n",
192 | " if compare(left[i], right[j]):\n",
193 | " result.append(left[i])\n",
194 | " i += 1\n",
195 | " else:\n",
196 | " result.append(right[j])\n",
197 | " j += 1\n",
198 | " while (i < len(left)):\n",
199 | " result.append(left[i])\n",
200 | " i += 1\n",
201 | " while (j < len(right)):\n",
202 | " result.append(right[j])\n",
203 | " j += 1\n",
204 | " return result\n",
205 | "\n",
206 | "def merge_sort(L, compare = lambda x, y: x < y):\n",
207 | " \"\"\"L은 리스트이고 compare는 L 원소의 순서를 정의합니다.\n",
208 | " L와 동일한 원소를 가진 새로운 정렬된 리스트를 반환합니다\"\"\"\n",
209 | " if len(L) < 2:\n",
210 | " return L[:]\n",
211 | " else:\n",
212 | " middle = len(L)//2\n",
213 | " left = merge_sort(L[:middle], compare)\n",
214 | " right = merge_sort(L[middle:], compare)\n",
215 | " return merge(left, right, compare)"
216 | ]
217 | },
218 | {
219 | "cell_type": "code",
220 | "execution_count": 5,
221 | "metadata": {
222 | "colab": {
223 | "base_uri": "https://localhost:8080/"
224 | },
225 | "id": "QEdachTVmUYU",
226 | "outputId": "2396ac1b-622d-4a7e-a9c0-5933a906d912"
227 | },
228 | "outputs": [
229 | {
230 | "name": "stdout",
231 | "output_type": "stream",
232 | "text": [
233 | "[1, 2, 3, 4, 5] [5, 4, 3, 2, 1]\n"
234 | ]
235 | }
236 | ],
237 | "source": [
238 | "L = [2,1,4,5,3]\n",
239 | "print(merge_sort(L), merge_sort(L, lambda x, y: x > y))"
240 | ]
241 | },
242 | {
243 | "cell_type": "markdown",
244 | "metadata": {
245 | "id": "k0fAvyAUWCO3"
246 | },
247 | "source": [
248 | "**뇌풀기 문제**"
249 | ]
250 | },
251 | {
252 | "cell_type": "code",
253 | "execution_count": 6,
254 | "metadata": {
255 | "colab": {
256 | "base_uri": "https://localhost:8080/"
257 | },
258 | "id": "9Ch0bwdhWFgC",
259 | "outputId": "71c22ff0-9355-43e1-bf6e-08a0064a78c7"
260 | },
261 | "outputs": [
262 | {
263 | "data": {
264 | "text/plain": [
265 | "[(1, 2, 3), (5, 2), (1, 8)]"
266 | ]
267 | },
268 | "execution_count": 6,
269 | "metadata": {},
270 | "output_type": "execute_result"
271 | }
272 | ],
273 | "source": [
274 | "L = [(1, 8), (5, 2), (1, 2, 3)]\n",
275 | "merge_sort(L, lambda x, y: sum(x) < sum(y))"
276 | ]
277 | },
278 | {
279 | "cell_type": "markdown",
280 | "metadata": {
281 | "id": "ZK9_HGN4DI2D"
282 | },
283 | "source": [
284 | "### 12.2.2 파이썬의 정렬 기능"
285 | ]
286 | },
287 | {
288 | "cell_type": "markdown",
289 | "metadata": {
290 | "id": "ltpq_S7JS1Ua"
291 | },
292 | "source": [
293 | "예제 12-5 이름 리스트 정렬하기"
294 | ]
295 | },
296 | {
297 | "cell_type": "code",
298 | "execution_count": 7,
299 | "metadata": {
300 | "colab": {
301 | "base_uri": "https://localhost:8080/"
302 | },
303 | "id": "L0EiO3-JI2D0",
304 | "outputId": "c4eda630-9185-41cc-c488-868066c7d181"
305 | },
306 | "outputs": [
307 | {
308 | "name": "stdout",
309 | "output_type": "stream",
310 | "text": [
311 | "성으로 정렬하기 = ['Tom Brady', 'Gisele Bundchen', 'Eric Grimson']\n",
312 | "이름으로 정렬하기 = ['Eric Grimson', 'Gisele Bundchen', 'Tom Brady']\n"
313 | ]
314 | }
315 | ],
316 | "source": [
317 | "def last_name_first_name(name1, name2):\n",
318 | " arg1 = name1.split(' ')\n",
319 | " arg2 = name2.split(' ')\n",
320 | " if arg1[1] != arg2[1]:\n",
321 | " return arg1[1] < arg2[1]\n",
322 | " else: #성이 같은 경우 이름으로 정렬합니다\n",
323 | " return arg1[0] < arg2[0]\n",
324 | "def first_name_last_name(name1, name2):\n",
325 | " arg1 = name1.split(' ')\n",
326 | " arg2 = name2.split(' ')\n",
327 | " if arg1[0] != arg2[0]:\n",
328 | " return arg1[0] < arg2[0]\n",
329 | " else: #이름이 같은 경우 성으로 정렬합니다\n",
330 | " return arg1[1] < arg2[1]\n",
331 | "\n",
332 | "L = ['Tom Brady', 'Eric Grimson', 'Gisele Bundchen']\n",
333 | "newL = merge_sort(L, last_name_first_name)\n",
334 | "print('성으로 정렬하기 =', newL)\n",
335 | "newL = merge_sort(L, first_name_last_name)\n",
336 | "print('이름으로 정렬하기 =', newL)"
337 | ]
338 | },
339 | {
340 | "cell_type": "code",
341 | "execution_count": 8,
342 | "metadata": {
343 | "colab": {
344 | "base_uri": "https://localhost:8080/",
345 | "height": 274
346 | },
347 | "id": "w6gC4AA2Sf7S",
348 | "outputId": "331f9eeb-87ae-43b3-a14e-a1552eb8a8ad"
349 | },
350 | "outputs": [
351 | {
352 | "name": "stdout",
353 | "output_type": "stream",
354 | "text": [
355 | "[2, 3, 5]\n",
356 | "[3, 5, 2]\n",
357 | "[2, 3, 5]\n",
358 | "['a', 'b', 'c']\n"
359 | ]
360 | },
361 | {
362 | "ename": "AttributeError",
363 | "evalue": "ignored",
364 | "output_type": "error",
365 | "traceback": [
366 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
367 | "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
368 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mL\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msorted\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mD\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mD\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msort\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
369 | "\u001b[0;31mAttributeError\u001b[0m: 'dict' object has no attribute 'sort'"
370 | ]
371 | }
372 | ],
373 | "source": [
374 | "L = [3,5,2]\n",
375 | "D = {'a':12, 'c':5, 'b':'dog'}\n",
376 | "print(sorted(L))\n",
377 | "print(L)\n",
378 | "L.sort()\n",
379 | "print(L)\n",
380 | "print(sorted(D))\n",
381 | "D.sort()"
382 | ]
383 | },
384 | {
385 | "cell_type": "code",
386 | "execution_count": 9,
387 | "metadata": {
388 | "colab": {
389 | "base_uri": "https://localhost:8080/"
390 | },
391 | "id": "oFsNeD-JvuWR",
392 | "outputId": "10cb032e-bb4d-4999-bc70-88d62171fb60"
393 | },
394 | "outputs": [
395 | {
396 | "name": "stdout",
397 | "output_type": "stream",
398 | "text": [
399 | "[(3, 2, 1, 0), [1, 2, 3], 'abc']\n"
400 | ]
401 | }
402 | ],
403 | "source": [
404 | "L = [[1,2,3], (3,2,1,0), 'abc']\n",
405 | "print(sorted(L, key = len, reverse = True))"
406 | ]
407 | },
408 | {
409 | "cell_type": "markdown",
410 | "metadata": {
411 | "id": "WCeDtEw89lLS"
412 | },
413 | "source": [
414 | "**뇌풀기 문제**"
415 | ]
416 | },
417 | {
418 | "cell_type": "code",
419 | "execution_count": 10,
420 | "metadata": {
421 | "colab": {
422 | "base_uri": "https://localhost:8080/"
423 | },
424 | "id": "7myhricvxJ-i",
425 | "outputId": "a55fee42-efbe-4c79-9802-db7128ed0c17"
426 | },
427 | "outputs": [
428 | {
429 | "data": {
430 | "text/plain": [
431 | "['abc', (3, 2, 1), [1, 2, 3]]"
432 | ]
433 | },
434 | "execution_count": 10,
435 | "metadata": {},
436 | "output_type": "execute_result"
437 | }
438 | ],
439 | "source": [
440 | "L = [[1,2,3], (3,2,1), 'abc']\n",
441 | "merge_sort(L, compare=lambda x, y: len(x) < len(y))"
442 | ]
443 | },
444 | {
445 | "cell_type": "markdown",
446 | "metadata": {
447 | "id": "qBfqfOYl-Ml8"
448 | },
449 | "source": [
450 | "## 12.3 해시 테이블"
451 | ]
452 | },
453 | {
454 | "cell_type": "markdown",
455 | "metadata": {
456 | "id": "CK-S_L-5vJh5"
457 | },
458 | "source": [
459 | "예제 12-6 해싱을 사용한 딕셔너리 구현"
460 | ]
461 | },
462 | {
463 | "cell_type": "code",
464 | "execution_count": 11,
465 | "metadata": {
466 | "id": "tpKKfBuu94Xw"
467 | },
468 | "outputs": [],
469 | "source": [
470 | "class Int_dict(object):\n",
471 | " \"\"\"정수 키를 사용한 딕셔너리\"\"\"\n",
472 | "\n",
473 | " def __init__(self, num_buckets):\n",
474 | " \"\"\"빈 딕셔너리를 만듭니다\"\"\"\n",
475 | " self.buckets = []\n",
476 | " self.num_buckets = num_buckets\n",
477 | " for i in range(num_buckets):\n",
478 | " self.buckets.append([])\n",
479 | "\n",
480 | " def add_entry(self, key, dict_val):\n",
481 | " \"\"\"key는 int라고 가정합니다. 항목을 추가합니다.\"\"\"\n",
482 | " hash_bucket = self.buckets[key%self.num_buckets]\n",
483 | " for i in range(len(hash_bucket)):\n",
484 | " if hash_bucket[i][0] == key:\n",
485 | " hash_bucket[i] = (key, dict_val)\n",
486 | " return\n",
487 | " hash_bucket.append((key, dict_val))\n",
488 | "\n",
489 | " def get_value(self, key):\n",
490 | " \"\"\"key는 int라고 가정합니다.\n",
491 | " key에 연관된 값을 반환합니다\"\"\"\n",
492 | " hash_bucket = self.buckets[key%self.num_buckets]\n",
493 | " for e in hash_bucket:\n",
494 | " if e[0] == key:\n",
495 | " return e[1]\n",
496 | " return None\n",
497 | "\n",
498 | " def __str__(self):\n",
499 | " result = '{'\n",
500 | " for b in self.buckets:\n",
501 | " for e in b:\n",
502 | " result += f'{e[0]}:{e[1]},'\n",
503 | " return result[:-1] + '}' #result[:-1]로 마지막 콤마를 제외합니다"
504 | ]
505 | },
506 | {
507 | "cell_type": "code",
508 | "execution_count": 12,
509 | "metadata": {
510 | "colab": {
511 | "base_uri": "https://localhost:8080/"
512 | },
513 | "id": "lJVnok62x83L",
514 | "outputId": "a8279cbf-5fba-4eae-c64c-d6bc6f242c5c"
515 | },
516 | "outputs": [
517 | {
518 | "name": "stdout",
519 | "output_type": "stream",
520 | "text": [
521 | "Int_dict 객체의 값:\n",
522 | "{5441:5,43334:7,77895:16,13518:0,86295:2,74565:11,76452:18,8640:6,99539:10,70946:8,6534:1,39396:3,2252:12,35829:17,61993:15,45572:4,29626:13,13714:14,64358:9,83841:19}\n"
523 | ]
524 | }
525 | ],
526 | "source": [
527 | "import random\n",
528 | "D = Int_dict(17)\n",
529 | "for i in range(20):\n",
530 | " #0 ~ 10**5 - 1 사이에서 랜덤하게 정수를 선택합니다\n",
531 | " key = random.choice(range(10**5))\n",
532 | " D.add_entry(key, i)\n",
533 | "print('Int_dict 객체의 값:')\n",
534 | "print(D)"
535 | ]
536 | },
537 | {
538 | "cell_type": "code",
539 | "execution_count": 13,
540 | "metadata": {
541 | "colab": {
542 | "base_uri": "https://localhost:8080/"
543 | },
544 | "id": "D5aGmGWhyHTH",
545 | "outputId": "6243230e-a686-4c8b-dc5f-f34cabbb30ca"
546 | },
547 | "outputs": [
548 | {
549 | "name": "stdout",
550 | "output_type": "stream",
551 | "text": [
552 | "버킷 내용:\n",
553 | " []\n",
554 | " [(5441, 5), (43334, 7), (77895, 16)]\n",
555 | " []\n",
556 | " [(13518, 0), (86295, 2), (74565, 11), (76452, 18)]\n",
557 | " [(8640, 6), (99539, 10)]\n",
558 | " [(70946, 8)]\n",
559 | " [(6534, 1)]\n",
560 | " [(39396, 3)]\n",
561 | " [(2252, 12)]\n",
562 | " []\n",
563 | " [(35829, 17)]\n",
564 | " [(61993, 15)]\n",
565 | " [(45572, 4), (29626, 13), (13714, 14)]\n",
566 | " [(64358, 9)]\n",
567 | " [(83841, 19)]\n",
568 | " []\n",
569 | " []\n"
570 | ]
571 | }
572 | ],
573 | "source": [
574 | "print('버킷 내용:')\n",
575 | "for hash_bucket in D.buckets: #추상 장벽을 위배합니다\n",
576 | " print(' ', hash_bucket)"
577 | ]
578 | }
579 | ],
580 | "metadata": {
581 | "colab": {
582 | "authorship_tag": "ABX9TyPEi5asdf/dorjxEAofuN28",
583 | "provenance": []
584 | },
585 | "kernelspec": {
586 | "display_name": "Python 3 (ipykernel)",
587 | "language": "python",
588 | "name": "python3"
589 | },
590 | "language_info": {
591 | "codemirror_mode": {
592 | "name": "ipython",
593 | "version": 3
594 | },
595 | "file_extension": ".py",
596 | "mimetype": "text/x-python",
597 | "name": "python",
598 | "nbconvert_exporter": "python",
599 | "pygments_lexer": "ipython3",
600 | "version": "3.8.2"
601 | }
602 | },
603 | "nbformat": 4,
604 | "nbformat_minor": 1
605 | }
606 |
--------------------------------------------------------------------------------
/14장.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "KpWRJro7RwFv"
7 | },
8 | "source": [
9 | "# 14장 배낭 문제와 그래프 최적화 문제"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {
15 | "id": "_p7-IIT-SKh7"
16 | },
17 | "source": [
18 | "\n",
19 | " \n",
20 | " | "
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {
26 | "id": "7CqBxIQeiWP_"
27 | },
28 | "source": [
29 | "## 14.1 배낭 문제"
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {
35 | "id": "ULPmwtWricF-"
36 | },
37 | "source": [
38 | "### 14.1.1 탐욕 알고리즘"
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {
44 | "id": "vzrpqVSQiqEi"
45 | },
46 | "source": [
47 | "예제 14-1 Item 클래스"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": 1,
53 | "metadata": {
54 | "id": "AGC_Y-8vSOMa"
55 | },
56 | "outputs": [],
57 | "source": [
58 | "class Item(object): \n",
59 | " def __init__(self, n, v, w): \n",
60 | " self._name = n \n",
61 | " self._value = v \n",
62 | " self._weight = w \n",
63 | " def get_name(self): \n",
64 | " return self._name \n",
65 | " def get_value(self): \n",
66 | " return self._value \n",
67 | " def get_weight(self): \n",
68 | " return self._weight \n",
69 | " def __str__(self): \n",
70 | " return f'<{self._name}, {self._value}, {self._weight}>' \n",
71 | "\n",
72 | "def value(item): \n",
73 | " return item.get_value() \n",
74 | "\n",
75 | "def weight_inverse(item): \n",
76 | " return 1.0/item.get_weight() \n",
77 | "\n",
78 | "def density(item): \n",
79 | " return item.get_value()/item.get_weight() "
80 | ]
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "metadata": {
85 | "id": "gy5wmV47jqDu"
86 | },
87 | "source": [
88 | "예제 14-2 탐욕 알고리즘 구현"
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": 2,
94 | "metadata": {
95 | "id": "ICR1t0aijqZK"
96 | },
97 | "outputs": [],
98 | "source": [
99 | "def greedy(items, max_weight, key_function): \n",
100 | " \"\"\"items는 리스트, max_weight >= 0, \n",
101 | " key_function는 items의 원소를 숫자에 매핑한다고 가정합니다\"\"\" \n",
102 | " items_copy = sorted(items, key=key_function, reverse = True) \n",
103 | " result = [] \n",
104 | " total_value, total_weight = 0.0, 0.0 \n",
105 | " for i in range(len(items_copy)): \n",
106 | " if (total_weight + items_copy[i].get_weight()) <= max_weight: \n",
107 | " result.append(items_copy[i]) \n",
108 | " total_weight += items_copy[i].get_weight() \n",
109 | " total_value += items_copy[i].get_value() \n",
110 | " return (result, total_value) "
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {
116 | "id": "RsDg1d5dnlcm"
117 | },
118 | "source": [
119 | "예제 14-3 탐욕 알고리즘으로 물건 선택하기"
120 | ]
121 | },
122 | {
123 | "cell_type": "code",
124 | "execution_count": 3,
125 | "metadata": {
126 | "id": "sF8YGtmrnlwH"
127 | },
128 | "outputs": [],
129 | "source": [
130 | "def build_items(): \n",
131 | " names = ['시계','그림','라디오','꽃병','책','컴퓨터'] \n",
132 | " values = [175,90,20,50,10,200] \n",
133 | " weights = [10,9,4,2,1,20] \n",
134 | " Items = [] \n",
135 | " for i in range(len(values)): \n",
136 | " Items.append(Item(names[i], values[i], weights[i])) \n",
137 | " return Items \n",
138 | "\n",
139 | "def test_greedy(items, max_weight, key_function): \n",
140 | " taken, val = greedy(items, max_weight, key_function) \n",
141 | " print('선택한 물건의 총 가치:', val) \n",
142 | " for item in taken: \n",
143 | " print(' ', item) \n",
144 | "\n",
145 | "def test_greedys(max_weight = 20): \n",
146 | " items = build_items() \n",
147 | " print('가치 기준 탐욕 알고리즘을 사용해', max_weight, '크기의 배낭을 채우기') \n",
148 | " test_greedy(items, max_weight, value) \n",
149 | " print('\\n무게 기준 탐욕 알고리즘을 사용해', max_weight, '크기의 배낭을 채우기') \n",
150 | " test_greedy(items, max_weight, weight_inverse) \n",
151 | " print('\\n밀도 기준 탐욕 알고리즘을 사용해', max_weight, '크기의 배낭을 채우기') \n",
152 | " test_greedy(items, max_weight, density) "
153 | ]
154 | },
155 | {
156 | "cell_type": "code",
157 | "execution_count": 4,
158 | "metadata": {
159 | "colab": {
160 | "base_uri": "https://localhost:8080/"
161 | },
162 | "id": "ejp5O1eModji",
163 | "outputId": "3db43ad6-34ef-4ac6-848c-4aaff57245fd"
164 | },
165 | "outputs": [
166 | {
167 | "name": "stdout",
168 | "output_type": "stream",
169 | "text": [
170 | "가치 기준 탐욕 알고리즘을 사용해 20 크기의 배낭을 채우기\n",
171 | "선택한 물건의 총 가치: 200.0\n",
172 | " <컴퓨터, 200, 20>\n",
173 | "\n",
174 | "무게 기준 탐욕 알고리즘을 사용해 20 크기의 배낭을 채우기\n",
175 | "선택한 물건의 총 가치: 170.0\n",
176 | " <책, 10, 1>\n",
177 | " <꽃병, 50, 2>\n",
178 | " <라디오, 20, 4>\n",
179 | " <그림, 90, 9>\n",
180 | "\n",
181 | "밀도 기준 탐욕 알고리즘을 사용해 20 크기의 배낭을 채우기\n",
182 | "선택한 물건의 총 가치: 255.0\n",
183 | " <꽃병, 50, 2>\n",
184 | " <시계, 175, 10>\n",
185 | " <책, 10, 1>\n",
186 | " <라디오, 20, 4>\n"
187 | ]
188 | }
189 | ],
190 | "source": [
191 | "test_greedys()"
192 | ]
193 | },
194 | {
195 | "cell_type": "markdown",
196 | "metadata": {
197 | "id": "ms6RDhpfonM8"
198 | },
199 | "source": [
200 | "### 14.1.2 0/1 배낭 문제의 최적 솔루션"
201 | ]
202 | },
203 | {
204 | "cell_type": "code",
205 | "execution_count": 5,
206 | "metadata": {
207 | "id": "p6By3x3CqmXs"
208 | },
209 | "outputs": [],
210 | "source": [
211 | "def get_binary_rep(n, num_digits): \n",
212 | " \"\"\"n과 num_digits은 음수가 아닌 정수로 가정합니다. \n",
213 | " n의 이진 표현을 num_digits 길이의 문자열로 반환합니다\"\"\" \n",
214 | " result = '' \n",
215 | " while n > 0: \n",
216 | " result = str(n%2) + result \n",
217 | " n = n//2 \n",
218 | " if len(result) > num_digits: \n",
219 | " raise ValueError('num_digits가 부족합니다') \n",
220 | " for i in range(num_digits - len(result)): \n",
221 | " result = '0' + result \n",
222 | " return result \n",
223 | "\n",
224 | "def gen_powerset(L): \n",
225 | " \"\"\"L은 리스트로 가정합니다. \n",
226 | " L에 있는 원소로 가능한 모든 조합을 담은 리스트의 리스트를 반환합니다.\n",
227 | " 예를 들어 L이 [1, 2]이면 [], [1], [2], [1, 2]를 원소로 가진 리스트를 반환합니다\"\"\" \n",
228 | " powerset = [] \n",
229 | " for i in range(0, 2**len(L)): \n",
230 | " bin_str = get_binary_rep(i, len(L)) \n",
231 | " subset = [] \n",
232 | " for j in range(len(L)): \n",
233 | " if bin_str[j] == '1': \n",
234 | " subset.append(L[j]) \n",
235 | " powerset.append(subset) \n",
236 | " return powerset "
237 | ]
238 | },
239 | {
240 | "cell_type": "markdown",
241 | "metadata": {},
242 | "source": [
243 | "예제 14-4 0/1 배낭 문제의 단순하지만 최적인 솔루션"
244 | ]
245 | },
246 | {
247 | "cell_type": "code",
248 | "execution_count": 6,
249 | "metadata": {
250 | "id": "mhsGe4PDpEG0"
251 | },
252 | "outputs": [],
253 | "source": [
254 | "def choose_best(pset, max_weight, get_val, get_weight): \n",
255 | " best_val = 0.0 \n",
256 | " best_set = None \n",
257 | " for items in pset: \n",
258 | " items_val = 0.0 \n",
259 | " items_weight = 0.0 \n",
260 | " for item in items: \n",
261 | " items_val += get_val(item) \n",
262 | " items_weight += get_weight(item) \n",
263 | " if items_weight <= max_weight and items_val > best_val: \n",
264 | " best_val = items_val \n",
265 | " best_set = items \n",
266 | " return (best_set, best_val) \n",
267 | "\n",
268 | "def test_best(max_weight = 20): \n",
269 | " items = build_items() \n",
270 | " pset = gen_powerset(items) \n",
271 | " taken, val = choose_best(pset, max_weight, Item.get_value, \n",
272 | " Item.get_weight) \n",
273 | " print('선택한 물건의 총 가치:', val) \n",
274 | " for item in taken: \n",
275 | " print(item) "
276 | ]
277 | },
278 | {
279 | "cell_type": "code",
280 | "execution_count": 7,
281 | "metadata": {
282 | "colab": {
283 | "base_uri": "https://localhost:8080/"
284 | },
285 | "id": "ZWYpG6p5q8Py",
286 | "outputId": "4c26e8b7-b441-463f-d080-02b65df3c9a9"
287 | },
288 | "outputs": [
289 | {
290 | "name": "stdout",
291 | "output_type": "stream",
292 | "text": [
293 | "선택한 물건의 총 가치: 275.0\n",
294 | "<시계, 175, 10>\n",
295 | "<그림, 90, 9>\n",
296 | "<책, 10, 1>\n"
297 | ]
298 | }
299 | ],
300 | "source": [
301 | "test_best()"
302 | ]
303 | },
304 | {
305 | "cell_type": "markdown",
306 | "metadata": {
307 | "id": "KBcJG7ISwCRG"
308 | },
309 | "source": [
310 | "## 14.2 그래프 최적화 문제"
311 | ]
312 | },
313 | {
314 | "cell_type": "markdown",
315 | "metadata": {
316 | "id": "V9fmRj_xx0m8"
317 | },
318 | "source": [
319 | "예제 14-5 노드와 에지"
320 | ]
321 | },
322 | {
323 | "cell_type": "code",
324 | "execution_count": 8,
325 | "metadata": {
326 | "id": "r-i1Cg68rb4d"
327 | },
328 | "outputs": [],
329 | "source": [
330 | "class Node(object): \n",
331 | " def __init__(self, name): \n",
332 | " \"\"\"name은 문자열이라고 가정합니다\"\"\" \n",
333 | " self._name = name \n",
334 | " def get_name(self): \n",
335 | " return self._name \n",
336 | " def __str__(self): \n",
337 | " return self._name \n",
338 | "\n",
339 | "class Edge(object): \n",
340 | " def __init__(self, src, dest): \n",
341 | " \"\"\"src와 dest는 노드라고 가정합니다\"\"\" \n",
342 | " self._src = src \n",
343 | " self._dest = dest \n",
344 | " def get_source(self): \n",
345 | " return self._src \n",
346 | " def get_destination(self): \n",
347 | " return self._dest \n",
348 | " def __str__(self): \n",
349 | " return self._src.get_name() + '->' + self._dest.get_name() \n",
350 | "\n",
351 | "class Weighted_edge(Edge): \n",
352 | " def __init__(self, src, dest, weight = 1.0): \n",
353 | " \"\"\"src와 dest는 노드이고, weight는 숫자라고 가정합니다\"\"\" \n",
354 | " self._src = src \n",
355 | " self._dest = dest \n",
356 | " self._weight = weight \n",
357 | " def get_weight(self): \n",
358 | " return self._weight \n",
359 | " def __str__(self): \n",
360 | " return (f'{self._src.get_name()}->({self._weight})' + \n",
361 | " f'{self._dest.get_name()}') "
362 | ]
363 | },
364 | {
365 | "cell_type": "markdown",
366 | "metadata": {
367 | "id": "uSNDSYYQ0hWx"
368 | },
369 | "source": [
370 | "예제 14-6 `Graph`와 `Digraph` 클래스"
371 | ]
372 | },
373 | {
374 | "cell_type": "code",
375 | "execution_count": 9,
376 | "metadata": {
377 | "id": "4QvnkaTH0hx2"
378 | },
379 | "outputs": [],
380 | "source": [
381 | "class Digraph(object): \n",
382 | " #_nodes는 그래프에 있는 노드의 리스트입니다.\n",
383 | " #_edges는 각 노드를 자식 노드 리스트에 매핑한 딕셔너리입니다.\n",
384 | " def __init__(self): \n",
385 | " self._nodes = [] \n",
386 | " self._edges = {} \n",
387 | " def add_node(self, node): \n",
388 | " if node in self._nodes: \n",
389 | " raise ValueError('Duplicate node') \n",
390 | " else: \n",
391 | " self._nodes.append(node) \n",
392 | " self._edges[node] = [] \n",
393 | " def add_edge(self, edge): \n",
394 | " src = edge.get_source() \n",
395 | " dest = edge.get_destination() \n",
396 | " if not (src in self._nodes and dest in self._nodes): \n",
397 | " raise ValueError('Node not in graph') \n",
398 | " self._edges[src].append(dest) \n",
399 | " def children_of(self, node): \n",
400 | " return self._edges[node] \n",
401 | " def has_node(self, node): \n",
402 | " return node in self._nodes \n",
403 | " def __str__(self): \n",
404 | " result = '' \n",
405 | " for src in self._nodes: \n",
406 | " for dest in self._edges[src]: \n",
407 | " result = (result + src.get_name() + '->' \n",
408 | " + dest.get_name() + '\\n') \n",
409 | " return result[:-1] #마지막 줄바꿈을 제외합니다\n",
410 | "\n",
411 | "class Graph(Digraph): \n",
412 | " def add_edge(self, edge): \n",
413 | " Digraph.add_edge(self, edge) \n",
414 | " rev = Edge(edge.get_destination(), edge.get_source()) \n",
415 | " Digraph.add_edge(self, rev) "
416 | ]
417 | },
418 | {
419 | "cell_type": "markdown",
420 | "metadata": {
421 | "id": "YxA-s0of-OES"
422 | },
423 | "source": [
424 | "### 14.2.1 고전 그래프 문제"
425 | ]
426 | },
427 | {
428 | "cell_type": "markdown",
429 | "metadata": {
430 | "id": "YRZVFUmSDSzP"
431 | },
432 | "source": [
433 | "### 14.2.2 최단 경로: 깊이 우선 탐색과 너비 우선 탐색"
434 | ]
435 | },
436 | {
437 | "cell_type": "markdown",
438 | "metadata": {
439 | "id": "krhLQ_F9kOpW"
440 | },
441 | "source": [
442 | "예제 14-7 깊이 우선 탐색 최단 경로 알고리즘"
443 | ]
444 | },
445 | {
446 | "cell_type": "code",
447 | "execution_count": 10,
448 | "metadata": {
449 | "id": "fmFNL4JK-Pi9"
450 | },
451 | "outputs": [],
452 | "source": [
453 | "def print_path(path): \n",
454 | " \"\"\"path는 노드의 리스트라고 가정합니다\"\"\" \n",
455 | " result = '' \n",
456 | " for i in range(len(path)): \n",
457 | " result = result + str(path[i]) \n",
458 | " if i != len(path) - 1: \n",
459 | " result = result + '->' \n",
460 | " return result \n",
461 | "\n",
462 | "def DFS(graph, start, end, path, shortest, to_print = False): \n",
463 | " \"\"\"Assumes graph는 Digraph, start와 end는 노드, \n",
464 | " path와 shortest는 노드의 리스트로 가정합니다.\n",
465 | " graph에서 start부터 end까지 최단 경로를 반환합니다\"\"\" \n",
466 | " path = path + [start] \n",
467 | " if to_print: \n",
468 | " print('현재 DFS 경로:', print_path(path)) \n",
469 | " if start == end: \n",
470 | " return path \n",
471 | " for node in graph.children_of(start): \n",
472 | " if node not in path: #순환을 피합니다\n",
473 | " if shortest == None or len(path) < len(shortest): \n",
474 | " new_path = DFS(graph, node, end, path, shortest, to_print) \n",
475 | " if new_path != None: \n",
476 | " shortest = new_path \n",
477 | " return shortest \n",
478 | "\n",
479 | "def shortest_path(graph, start, end, to_print = False): \n",
480 | " \"\"\"graph는 Digraph, start와 end는 노드라고 가정합니다.\n",
481 | " 그래프에서 start부터 end까지 최단 경로를 반환합니다\"\"\" \n",
482 | " return DFS(graph, start, end, [], None, to_print) "
483 | ]
484 | },
485 | {
486 | "cell_type": "markdown",
487 | "metadata": {
488 | "id": "ovwTMZKNCYNE"
489 | },
490 | "source": [
491 | "예제 14-8 깊이 우선 탐색 코드 테스트"
492 | ]
493 | },
494 | {
495 | "cell_type": "code",
496 | "execution_count": 11,
497 | "metadata": {
498 | "id": "GerAdpCNCJpK"
499 | },
500 | "outputs": [],
501 | "source": [
502 | "def test_SP(): \n",
503 | " nodes = [] \n",
504 | " for name in range(6): #6개 노드를 만듭니다\n",
505 | " nodes.append(Node(str(name))) \n",
506 | " g = Digraph() \n",
507 | " for n in nodes: \n",
508 | " g.add_node(n) \n",
509 | " g.add_edge(Edge(nodes[0],nodes[1])) \n",
510 | " g.add_edge(Edge(nodes[1],nodes[2])) \n",
511 | " g.add_edge(Edge(nodes[2],nodes[3])) \n",
512 | " g.add_edge(Edge(nodes[2],nodes[4])) \n",
513 | " g.add_edge(Edge(nodes[3],nodes[4])) \n",
514 | " g.add_edge(Edge(nodes[3],nodes[5])) \n",
515 | " g.add_edge(Edge(nodes[0],nodes[2])) \n",
516 | " g.add_edge(Edge(nodes[1],nodes[0])) \n",
517 | " g.add_edge(Edge(nodes[3],nodes[1])) \n",
518 | " g.add_edge(Edge(nodes[4],nodes[0])) \n",
519 | " sp = shortest_path(g, nodes[0], nodes[5], to_print = True) \n",
520 | " print('DFS가 찾은 최단 경로:', print_path(sp))"
521 | ]
522 | },
523 | {
524 | "cell_type": "code",
525 | "execution_count": 12,
526 | "metadata": {
527 | "colab": {
528 | "base_uri": "https://localhost:8080/"
529 | },
530 | "id": "wHHO0D6eCZcL",
531 | "outputId": "d142f744-6fe3-4529-94b6-91006b61aaaa"
532 | },
533 | "outputs": [
534 | {
535 | "name": "stdout",
536 | "output_type": "stream",
537 | "text": [
538 | "현재 DFS 경로: 0\n",
539 | "현재 DFS 경로: 0->1\n",
540 | "현재 DFS 경로: 0->1->2\n",
541 | "현재 DFS 경로: 0->1->2->3\n",
542 | "현재 DFS 경로: 0->1->2->3->4\n",
543 | "현재 DFS 경로: 0->1->2->3->5\n",
544 | "현재 DFS 경로: 0->1->2->4\n",
545 | "현재 DFS 경로: 0->2\n",
546 | "현재 DFS 경로: 0->2->3\n",
547 | "현재 DFS 경로: 0->2->3->4\n",
548 | "현재 DFS 경로: 0->2->3->5\n",
549 | "현재 DFS 경로: 0->2->3->1\n",
550 | "현재 DFS 경로: 0->2->4\n",
551 | "DFS가 찾은 최단 경로: 0->2->3->5\n"
552 | ]
553 | }
554 | ],
555 | "source": [
556 | "test_SP()"
557 | ]
558 | },
559 | {
560 | "cell_type": "markdown",
561 | "metadata": {
562 | "id": "M-GfzCh5Ep-L"
563 | },
564 | "source": [
565 | "**뇌풀기 문제**"
566 | ]
567 | },
568 | {
569 | "cell_type": "code",
570 | "execution_count": 13,
571 | "metadata": {
572 | "colab": {
573 | "base_uri": "https://localhost:8080/"
574 | },
575 | "id": "5a8bOpk3FoEl",
576 | "outputId": "90b18b17-0698-4b79-999a-6ee4fc641e82"
577 | },
578 | "outputs": [
579 | {
580 | "name": "stdout",
581 | "output_type": "stream",
582 | "text": [
583 | "현재 DFS 경로: 0 \t 가중치 합: 0\n",
584 | "현재 DFS 경로: 0->1 \t 가중치 합: 1\n",
585 | "현재 DFS 경로: 0->1->2 \t 가중치 합: 3\n",
586 | "현재 DFS 경로: 0->1->2->3 \t 가중치 합: 4\n",
587 | "현재 DFS 경로: 0->1->2->3->4 \t 가중치 합: 5\n",
588 | "현재 DFS 경로: 0->1->2->3->5 \t 가중치 합: 6\n",
589 | "현재 DFS 경로: 0->1->2->4 \t 가중치 합: 4\n",
590 | "현재 DFS 경로: 0->2 \t 가중치 합: 4\n",
591 | "현재 DFS 경로: 0->2->3 \t 가중치 합: 5\n",
592 | "현재 DFS 경로: 0->2->3->4 \t 가중치 합: 6\n",
593 | "현재 DFS 경로: 0->2->3->5 \t 가중치 합: 7\n",
594 | "현재 DFS 경로: 0->2->3->1 \t 가중치 합: 6\n",
595 | "현재 DFS 경로: 0->2->4 \t 가중치 합: 5\n",
596 | "DFS가 찾은 최단 경로: 0->1->2->3->5\n"
597 | ]
598 | }
599 | ],
600 | "source": [
601 | "class Wgraph(Digraph): \n",
602 | " def __init__(self): \n",
603 | " super().__init__()\n",
604 | " self._weighted_edges = [] \n",
605 | " def add_edges(self, edges):\n",
606 | " self._weighted_edges = edges\n",
607 | " for edge in edges:\n",
608 | " self.add_edge(edge)\n",
609 | " def get_weights(self, path):\n",
610 | " weight_sum = 0\n",
611 | " parent_node = path[0]\n",
612 | " for child_node in path[1:]:\n",
613 | " for edge in self._weighted_edges:\n",
614 | " if edge._src == parent_node and edge._dest == child_node:\n",
615 | " weight_sum += edge.get_weight()\n",
616 | " break\n",
617 | " parent_node = child_node\n",
618 | " return weight_sum\n",
619 | "\n",
620 | "def WDFS(graph, start, end, path, shortest, to_print = False): \n",
621 | " \"\"\"Assumes graph는 Digraph, start와 end는 노드, \n",
622 | " path와 shortest는 노드의 리스트로 가정합니다.\n",
623 | " graph에서 start부터 end까지 최단 경로를 반환합니다\"\"\" \n",
624 | " path = path + [start] \n",
625 | " if to_print: \n",
626 | " print('현재 DFS 경로:', print_path(path), '\\t', \n",
627 | " '가중치 합:', graph.get_weights(path)) \n",
628 | " if start == end:\n",
629 | " return path \n",
630 | " for node in graph.children_of(start):\n",
631 | " if node in path: #순환을 피합니다\n",
632 | " continue\n",
633 | " new_path = WDFS(graph, node, end, path, shortest, to_print) \n",
634 | " if shortest == None or (new_path != None and \\\n",
635 | " graph.get_weights(new_path) < graph.get_weights(shortest)): \n",
636 | " shortest = new_path \n",
637 | " return shortest \n",
638 | "\n",
639 | "def test_WSP(): \n",
640 | " nodes = [] \n",
641 | " for name in range(6): #6개 노드를 만듭니다\n",
642 | " nodes.append(Node(str(name))) \n",
643 | " g = Wgraph() \n",
644 | " for n in nodes: \n",
645 | " g.add_node(n)\n",
646 | " edges = [Weighted_edge(nodes[0],nodes[1],1),\n",
647 | " Weighted_edge(nodes[1],nodes[2],2),\n",
648 | " Weighted_edge(nodes[2],nodes[3],1),\n",
649 | " Weighted_edge(nodes[2],nodes[4],1),\n",
650 | " Weighted_edge(nodes[3],nodes[4],1),\n",
651 | " Weighted_edge(nodes[3],nodes[5],2),\n",
652 | " Weighted_edge(nodes[0],nodes[2],4),\n",
653 | " Weighted_edge(nodes[1],nodes[0],1),\n",
654 | " Weighted_edge(nodes[3],nodes[1],1),\n",
655 | " Weighted_edge(nodes[4],nodes[0],1)\n",
656 | " ]\n",
657 | " g.add_edges(edges) \n",
658 | " sp = WDFS(g, nodes[0], nodes[5], [], None, to_print = True) \n",
659 | " print('DFS가 찾은 최단 경로:', print_path(sp))\n",
660 | "\n",
661 | "test_WSP()"
662 | ]
663 | },
664 | {
665 | "cell_type": "markdown",
666 | "metadata": {
667 | "id": "R0aljjiJ03Vh"
668 | },
669 | "source": [
670 | "예제 14-9 너비 우선 탐색 최단 경로 알고리즘"
671 | ]
672 | },
673 | {
674 | "cell_type": "code",
675 | "execution_count": 14,
676 | "metadata": {
677 | "id": "tkLDp2-ovry3"
678 | },
679 | "outputs": [],
680 | "source": [
681 | "def BFS(graph, start, end, to_print = False): \n",
682 | " \"\"\"graph는 Digraph, start와 end는 노드라고 가정합니다.\n",
683 | " graph에서 start부터 end까지 최단 경로를 반환합니다\"\"\" \n",
684 | " init_path = [start] \n",
685 | " path_queue = [init_path] \n",
686 | " while len(path_queue) != 0: \n",
687 | " #path_queue의 첫 번째 원소를 추출합니다\n",
688 | " tmp_path = path_queue.pop(0) \n",
689 | " if to_print: \n",
690 | " print('현재 BFS 경로:', print_path(tmp_path)) \n",
691 | " last_node = tmp_path[-1] \n",
692 | " if last_node == end: \n",
693 | " return tmp_path \n",
694 | " for next_node in graph.children_of(last_node): \n",
695 | " if next_node not in tmp_path: \n",
696 | " new_path = tmp_path + [next_node] \n",
697 | " path_queue.append(new_path) \n",
698 | " return None "
699 | ]
700 | },
701 | {
702 | "cell_type": "code",
703 | "execution_count": 15,
704 | "metadata": {
705 | "colab": {
706 | "base_uri": "https://localhost:8080/"
707 | },
708 | "id": "-4I5f-IzxfJS",
709 | "outputId": "e7b21f6d-7dbf-4c77-c51d-a8e13800f06c"
710 | },
711 | "outputs": [
712 | {
713 | "name": "stdout",
714 | "output_type": "stream",
715 | "text": [
716 | "현재 BFS 경로: 0\n",
717 | "현재 BFS 경로: 0->1\n",
718 | "현재 BFS 경로: 0->2\n",
719 | "현재 BFS 경로: 0->1->2\n",
720 | "현재 BFS 경로: 0->2->3\n",
721 | "현재 BFS 경로: 0->2->4\n",
722 | "현재 BFS 경로: 0->1->2->3\n",
723 | "현재 BFS 경로: 0->1->2->4\n",
724 | "현재 BFS 경로: 0->2->3->4\n",
725 | "현재 BFS 경로: 0->2->3->5\n",
726 | "BFS가 찾은 최단 경로: 0->2->3->5\n"
727 | ]
728 | }
729 | ],
730 | "source": [
731 | "def test_SP(): \n",
732 | " nodes = [] \n",
733 | " for name in range(6): #6개 노드를 만듭니다\n",
734 | " nodes.append(Node(str(name))) \n",
735 | " g = Digraph() \n",
736 | " for n in nodes: \n",
737 | " g.add_node(n) \n",
738 | " g.add_edge(Edge(nodes[0],nodes[1])) \n",
739 | " g.add_edge(Edge(nodes[1],nodes[2])) \n",
740 | " g.add_edge(Edge(nodes[2],nodes[3])) \n",
741 | " g.add_edge(Edge(nodes[2],nodes[4])) \n",
742 | " g.add_edge(Edge(nodes[3],nodes[4])) \n",
743 | " g.add_edge(Edge(nodes[3],nodes[5])) \n",
744 | " g.add_edge(Edge(nodes[0],nodes[2])) \n",
745 | " g.add_edge(Edge(nodes[1],nodes[0])) \n",
746 | " g.add_edge(Edge(nodes[3],nodes[1])) \n",
747 | " g.add_edge(Edge(nodes[4],nodes[0])) \n",
748 | " sp = BFS(g, nodes[0], nodes[5], to_print=True) \n",
749 | " print('BFS가 찾은 최단 경로:', print_path(sp)) \n",
750 | "\n",
751 | "test_SP()"
752 | ]
753 | }
754 | ],
755 | "metadata": {
756 | "colab": {
757 | "authorship_tag": "ABX9TyO1lJCK+2igtve74iIneRUi",
758 | "provenance": []
759 | },
760 | "kernelspec": {
761 | "display_name": "Python 3 (ipykernel)",
762 | "language": "python",
763 | "name": "python3"
764 | },
765 | "language_info": {
766 | "codemirror_mode": {
767 | "name": "ipython",
768 | "version": 3
769 | },
770 | "file_extension": ".py",
771 | "mimetype": "text/x-python",
772 | "name": "python",
773 | "nbconvert_exporter": "python",
774 | "pygments_lexer": "ipython3",
775 | "version": "3.8.2"
776 | }
777 | },
778 | "nbformat": 4,
779 | "nbformat_minor": 1
780 | }
781 |
--------------------------------------------------------------------------------
/15장.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "duwpRtdcHaee"
7 | },
8 | "source": [
9 | "# 15장 동적 계획법"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {
15 | "id": "GCdh4-5yHkzJ"
16 | },
17 | "source": [
18 | "\n",
19 | " \n",
20 | " | "
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {
26 | "id": "Vqi1KR1OAA6u"
27 | },
28 | "source": [
29 | "## 15.1 피보나치 수열 다시 살펴 보기"
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": null,
35 | "metadata": {
36 | "id": "YXWb6PazACVa"
37 | },
38 | "outputs": [],
39 | "source": [
40 | "def fib(n): \n",
41 | " \"\"\"n은 0보다 크거나 같은 정수라고 가정합니다.\n",
42 | " n의 피보나치 수열 값을 반환합니다\"\"\" \n",
43 | " if n == 0 or n == 1: \n",
44 | " return 1 \n",
45 | " else: \n",
46 | " return fib(n-1) + fib(n-2) "
47 | ]
48 | },
49 | {
50 | "cell_type": "markdown",
51 | "metadata": {
52 | "id": "TINeJzU5UVBd"
53 | },
54 | "source": [
55 | "예제 15-1 동적 계획법을 사용한 피보나치 구현"
56 | ]
57 | },
58 | {
59 | "cell_type": "code",
60 | "execution_count": null,
61 | "metadata": {
62 | "id": "LfGeUrYTB0-3"
63 | },
64 | "outputs": [],
65 | "source": [
66 | "def fib_memo(n, memo = None): \n",
67 | " \"\"\"n은 0보다 크거나 같은 정수라고 가정하며, memo는 재귀 호출에서만 사용됩니다.\n",
68 | " n의 피보나치 수열 값을 반환합니다\"\"\"\n",
69 | " if memo == None: \n",
70 | " memo = {} \n",
71 | " if n == 0 or n == 1: \n",
72 | " return 1 \n",
73 | " try: \n",
74 | " return memo[n] \n",
75 | " except KeyError: \n",
76 | " result = fib_memo(n-1, memo) + fib_memo(n-2, memo) \n",
77 | " memo[n] = result \n",
78 | " return result \n",
79 | "\n",
80 | "def fib_tab(n): \n",
81 | " \"\"\"n은 0보다 크거나 같은 정수라고 가정합니다.\n",
82 | " n의 피보나치 수열 값을 반환합니다\"\"\" \n",
83 | " tab = [1]*(n+1) #처음 두 값만 맞습니다\n",
84 | " for i in range(2, n + 1): \n",
85 | " tab[i] = tab[i-1] + tab[i-2] \n",
86 | " return tab[n] "
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": null,
92 | "metadata": {
93 | "colab": {
94 | "base_uri": "https://localhost:8080/"
95 | },
96 | "id": "c4gXGmJwaEJW",
97 | "outputId": "ecf523d4-d739-43b2-f2d2-895c3fb8a75b"
98 | },
99 | "outputs": [
100 | {
101 | "data": {
102 | "text/plain": [
103 | "8670007398507948658051921"
104 | ]
105 | },
106 | "execution_count": 3,
107 | "metadata": {},
108 | "output_type": "execute_result"
109 | }
110 | ],
111 | "source": [
112 | "fib_memo(120)"
113 | ]
114 | },
115 | {
116 | "cell_type": "code",
117 | "execution_count": null,
118 | "metadata": {
119 | "colab": {
120 | "base_uri": "https://localhost:8080/"
121 | },
122 | "id": "XytkxyMKaG8y",
123 | "outputId": "4271ee01-d7e8-484c-ff6e-99586e814b41"
124 | },
125 | "outputs": [
126 | {
127 | "data": {
128 | "text/plain": [
129 | "8670007398507948658051921"
130 | ]
131 | },
132 | "execution_count": 4,
133 | "metadata": {},
134 | "output_type": "execute_result"
135 | }
136 | ],
137 | "source": [
138 | "fib_tab(120)"
139 | ]
140 | },
141 | {
142 | "cell_type": "markdown",
143 | "metadata": {
144 | "id": "DNb0ZA1waIP3"
145 | },
146 | "source": [
147 | "**뇌풀기 문제**"
148 | ]
149 | },
150 | {
151 | "cell_type": "code",
152 | "execution_count": null,
153 | "metadata": {
154 | "id": "yX_Cc8rNbZ4D"
155 | },
156 | "outputs": [],
157 | "source": [
158 | "def make_change(coin_vals, change): \n",
159 | " \"\"\"coin_vals는 양수 리스트이고 coin_vals[0] = 1입니다.\n",
160 | " change는 양수입니다.\n",
161 | " 동전의 합이 change가 되기 위해 필요한 최소 동전 개수를 반환합니다.\n",
162 | " 동전은 한 번 이상 사용할 수 있습니다.\n",
163 | " 예를 들어 make_change([1, 5, 8], 11)은 3을 반환해야 합니다.\"\"\""
164 | ]
165 | },
166 | {
167 | "cell_type": "markdown",
168 | "metadata": {
169 | "id": "z0u9sq7cihNu"
170 | },
171 | "source": [
172 | "## 15.2 동적 계획법과 0/1 배낭 문제"
173 | ]
174 | },
175 | {
176 | "cell_type": "markdown",
177 | "metadata": {
178 | "id": "Oi-7tgUZ1IDD"
179 | },
180 | "source": [
181 | "예제 15-2 결정 트리를 사용해 배낭 문제 해결하기"
182 | ]
183 | },
184 | {
185 | "cell_type": "code",
186 | "execution_count": null,
187 | "metadata": {
188 | "id": "5vBNMOOYTxRB"
189 | },
190 | "outputs": [],
191 | "source": [
192 | "def max_val(to_consider, avail): \n",
193 | " \"\"\"to_consider는 물건의 리스트이고 avail은 무게라고 가정합니다.\n",
194 | " 0/1 배낭 문제의 해에 대한 총 가치와 물건을 튜플로 반환합니다\"\"\"\n",
195 | " if to_consider == [] or avail == 0: \n",
196 | " result = (0, ()) \n",
197 | " elif to_consider[0].get_weight() > avail: \n",
198 | " #오른쪽 가지만 탐색합니다\n",
199 | " result = max_val(to_consider[1:], avail) \n",
200 | " else: \n",
201 | " next_item = to_consider[0] \n",
202 | " #왼쪽 가지를 탐색합니다\n",
203 | " with_val, with_to_take = max_val(to_consider[1:], \n",
204 | " avail - next_item.get_weight()) \n",
205 | " with_val += next_item.get_value() \n",
206 | " #오른쪽 가지를 탐색합니다\n",
207 | " without_val, without_to_take = max_val(to_consider[1:], avail) \n",
208 | " #더 나은 가지를 선택합니다\n",
209 | " if with_val > without_val: \n",
210 | " result = (with_val, with_to_take + (next_item,)) \n",
211 | " else: \n",
212 | " result = (without_val, without_to_take) \n",
213 | " return result"
214 | ]
215 | },
216 | {
217 | "cell_type": "code",
218 | "execution_count": null,
219 | "metadata": {
220 | "id": "Md9HwscC9DXi"
221 | },
222 | "outputs": [],
223 | "source": [
224 | "class Item(object): \n",
225 | " def __init__(self, n, v, w): \n",
226 | " self._name = n \n",
227 | " self._value = v \n",
228 | " self._weight = w \n",
229 | " def get_name(self): \n",
230 | " return self._name \n",
231 | " def get_value(self): \n",
232 | " return self._value \n",
233 | " def get_weight(self): \n",
234 | " return self._weight \n",
235 | " def __str__(self): \n",
236 | " return f'<{self._name}, {self._value}, {self._weight}>' "
237 | ]
238 | },
239 | {
240 | "cell_type": "markdown",
241 | "metadata": {
242 | "id": "sK0LmoVv8oB0"
243 | },
244 | "source": [
245 | "예제 15-3 결정 트리 기반 구현 테스트하기"
246 | ]
247 | },
248 | {
249 | "cell_type": "code",
250 | "execution_count": null,
251 | "metadata": {
252 | "id": "Bni9JPyL8aOA"
253 | },
254 | "outputs": [],
255 | "source": [
256 | "import random\n",
257 | "\n",
258 | "def small_test(): \n",
259 | " names = ['a', 'b', 'c', 'd'] \n",
260 | " vals = [6, 7, 8, 9] \n",
261 | " weights = [3, 3, 2, 5] \n",
262 | " Items = [] \n",
263 | " for i in range(len(vals)): \n",
264 | " Items.append(Item(names[i], vals[i], weights[i])) \n",
265 | " val, taken = max_val(Items, 5) \n",
266 | " for item in taken: \n",
267 | " print(item) \n",
268 | " print('선택한 물건의 총 가치 =', val) \n",
269 | "\n",
270 | "def build_many_items(num_items, max_val, max_weight): \n",
271 | " items = [] \n",
272 | " for i in range(num_items): \n",
273 | " items.append(Item(str(i), \n",
274 | " random.randint(1, max_val), \n",
275 | " random.randint(1, max_weight))) \n",
276 | " return items \n",
277 | "\n",
278 | "def big_test(num_items, avail_weight): \n",
279 | " items = build_many_items(num_items, 10, 10) \n",
280 | " val, taken = max_val(items, avail_weight) \n",
281 | " print('선택한 물건') \n",
282 | " for item in taken: \n",
283 | " print(item) \n",
284 | " print('선택한 물건의 총 가치 =', val) "
285 | ]
286 | },
287 | {
288 | "cell_type": "code",
289 | "execution_count": null,
290 | "metadata": {
291 | "colab": {
292 | "base_uri": "https://localhost:8080/"
293 | },
294 | "id": "n9-Rrsv09EX4",
295 | "outputId": "48bb4330-7e11-4cf4-93e7-5005b0010cb7"
296 | },
297 | "outputs": [
298 | {
299 | "name": "stdout",
300 | "output_type": "stream",
301 | "text": [
302 | "\n",
303 | "\n",
304 | "선택한 물건의 총 가치 = 15\n"
305 | ]
306 | }
307 | ],
308 | "source": [
309 | "small_test()"
310 | ]
311 | },
312 | {
313 | "cell_type": "code",
314 | "execution_count": null,
315 | "metadata": {
316 | "colab": {
317 | "base_uri": "https://localhost:8080/"
318 | },
319 | "id": "-t7ATos09GYi",
320 | "outputId": "99b7cb7b-2976-4677-9929-b616f013ba21"
321 | },
322 | "outputs": [
323 | {
324 | "name": "stdout",
325 | "output_type": "stream",
326 | "text": [
327 | "선택한 물건\n",
328 | "<8, 5, 1>\n",
329 | "<6, 9, 3>\n",
330 | "<5, 10, 3>\n",
331 | "<4, 6, 6>\n",
332 | "<3, 9, 7>\n",
333 | "<2, 5, 10>\n",
334 | "<1, 8, 1>\n",
335 | "<0, 7, 9>\n",
336 | "선택한 물건의 총 가치 = 59\n"
337 | ]
338 | }
339 | ],
340 | "source": [
341 | "big_test(10, 40)"
342 | ]
343 | },
344 | {
345 | "cell_type": "markdown",
346 | "metadata": {
347 | "id": "0NqKrCIyLT-p"
348 | },
349 | "source": [
350 | "예제 15-4 배낭 문제에 대한 동적 계획법 솔루션"
351 | ]
352 | },
353 | {
354 | "cell_type": "code",
355 | "execution_count": null,
356 | "metadata": {
357 | "id": "0bajQ1Dr_PNP"
358 | },
359 | "outputs": [],
360 | "source": [
361 | "def fast_max_val(to_consider, avail, memo = {}): \n",
362 | " \"\"\"to_consider는 물건의 리스트이고 avail은 무게라고 가정합니다.\n",
363 | " memo는 재귀 호출에 의해 제공됩니다.\n",
364 | " 0/1 배낭 문제의 해에 대한 총 가치와 물건을 튜플로 반환합니다\"\"\" \n",
365 | " if (len(to_consider), avail) in memo: \n",
366 | " result = memo[(len(to_consider), avail)] \n",
367 | " elif to_consider == [] or avail == 0: \n",
368 | " result = (0, ()) \n",
369 | " elif to_consider[0].get_weight() > avail: \n",
370 | " #오른쪽 가지만 탐색합니다\n",
371 | " result = fast_max_val(to_consider[1:], avail, memo) \n",
372 | " else: \n",
373 | " next_item = to_consider[0] \n",
374 | " #왼쪽 가지를 탐색합니다\n",
375 | " with_val, with_to_take = \\\n",
376 | " fast_max_val(to_consider[1:], \n",
377 | " avail - next_item.get_weight(), memo) \n",
378 | " with_val += next_item.get_value() \n",
379 | " #오른쪽 가지를 탐색합니다\n",
380 | " without_val, without_to_take = fast_max_val(to_consider[1:], \n",
381 | " avail, memo) \n",
382 | " #더 나은 가지를 선택합니다\n",
383 | " if with_val > without_val: \n",
384 | " result = (with_val, with_to_take + (next_item,)) \n",
385 | " else: \n",
386 | " result = (without_val, without_to_take) \n",
387 | " memo[(len(to_consider), avail)] = result \n",
388 | " return result "
389 | ]
390 | },
391 | {
392 | "cell_type": "code",
393 | "execution_count": null,
394 | "metadata": {
395 | "colab": {
396 | "base_uri": "https://localhost:8080/"
397 | },
398 | "id": "yH8ViV3cNvgE",
399 | "outputId": "6c19d44d-530e-4d91-ad2a-fdff65cf9562"
400 | },
401 | "outputs": [
402 | {
403 | "name": "stdout",
404 | "output_type": "stream",
405 | "text": [
406 | "선택한 물건\n",
407 | "<39, 10, 8>\n",
408 | "<37, 9, 5>\n",
409 | "<36, 8, 8>\n",
410 | "<35, 3, 1>\n",
411 | "<33, 7, 1>\n",
412 | "<32, 7, 4>\n",
413 | "<31, 5, 2>\n",
414 | "<28, 5, 1>\n",
415 | "<27, 6, 8>\n",
416 | "<26, 8, 1>\n",
417 | "<25, 10, 4>\n",
418 | "<24, 4, 3>\n",
419 | "<23, 8, 9>\n",
420 | "<22, 7, 1>\n",
421 | "<21, 9, 5>\n",
422 | "<18, 10, 3>\n",
423 | "<14, 7, 6>\n",
424 | "<11, 3, 1>\n",
425 | "<9, 8, 5>\n",
426 | "<6, 6, 1>\n",
427 | "<4, 9, 4>\n",
428 | "<3, 3, 1>\n",
429 | "<2, 7, 6>\n",
430 | "<1, 8, 6>\n",
431 | "<0, 5, 6>\n",
432 | "선택한 물건의 총 가치 = 172\n"
433 | ]
434 | }
435 | ],
436 | "source": [
437 | "def big_test(num_items, avail_weight): \n",
438 | " items = build_many_items(num_items, 10, 10) \n",
439 | " val, taken = fast_max_val(items, avail_weight) \n",
440 | " print('선택한 물건') \n",
441 | " for item in taken: \n",
442 | " print(item) \n",
443 | " print('선택한 물건의 총 가치 =', val) \n",
444 | "\n",
445 | "big_test(40, 100)"
446 | ]
447 | }
448 | ],
449 | "metadata": {
450 | "colab": {
451 | "authorship_tag": "ABX9TyO8Z8AbKN9k39F9Q/98PMAR",
452 | "provenance": []
453 | },
454 | "kernelspec": {
455 | "display_name": "Python 3 (ipykernel)",
456 | "language": "python",
457 | "name": "python3"
458 | },
459 | "language_info": {
460 | "codemirror_mode": {
461 | "name": "ipython",
462 | "version": 3
463 | },
464 | "file_extension": ".py",
465 | "mimetype": "text/x-python",
466 | "name": "python",
467 | "nbconvert_exporter": "python",
468 | "pygments_lexer": "ipython3",
469 | "version": "3.8.2"
470 | }
471 | },
472 | "nbformat": 4,
473 | "nbformat_minor": 1
474 | }
475 |
--------------------------------------------------------------------------------
/18장.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "LZ9iezv3C7zV"
7 | },
8 | "source": [
9 | "# 18장 몬테 카를로 시뮬레이션"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {
15 | "id": "KPGY-MC0CsoF"
16 | },
17 | "source": [
18 | "\n",
19 | " \n",
20 | " | "
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {
26 | "id": "pmScby1UHfZZ"
27 | },
28 | "source": [
29 | "## 18.1 파스칼의 문제"
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": 1,
35 | "metadata": {
36 | "id": "rJkLQZZPbpXp"
37 | },
38 | "outputs": [],
39 | "source": [
40 | "import random \n",
41 | "import numpy as np "
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "metadata": {},
47 | "source": [
48 | "예제 18-1 파스칼의 답 확인하기"
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": 2,
54 | "metadata": {
55 | "id": "VgLdm648WreF"
56 | },
57 | "outputs": [],
58 | "source": [
59 | "def roll_die(): \n",
60 | " return random.choice([1,2,3,4,5,6]) \n",
61 | "\n",
62 | "def check_pascal(num_trials): \n",
63 | " \"\"\"num_trials은 int > 0라고 가정합니다.\n",
64 | " 이길 확률을 출력합니다\"\"\" \n",
65 | " num_wins = 0 \n",
66 | " for i in range(num_trials): \n",
67 | " for j in range(24): \n",
68 | " d1 = roll_die() \n",
69 | " d2 = roll_die() \n",
70 | " if d1 == 6 and d2 == 6: \n",
71 | " num_wins += 1 \n",
72 | " break \n",
73 | " print('이길 확률 =', num_wins/num_trials) "
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": 3,
79 | "metadata": {
80 | "colab": {
81 | "base_uri": "https://localhost:8080/"
82 | },
83 | "id": "TWnerjeebodu",
84 | "outputId": "fb0cf5ab-6800-48c6-aa5d-52832bf32d2a"
85 | },
86 | "outputs": [
87 | {
88 | "name": "stdout",
89 | "output_type": "stream",
90 | "text": [
91 | "이길 확률 = 0.491858\n"
92 | ]
93 | }
94 | ],
95 | "source": [
96 | "check_pascal(1000000)"
97 | ]
98 | },
99 | {
100 | "cell_type": "markdown",
101 | "metadata": {
102 | "id": "orqaE-UdbuGO"
103 | },
104 | "source": [
105 | "## 18.2 Pass 또는 Don’t pass?"
106 | ]
107 | },
108 | {
109 | "cell_type": "markdown",
110 | "metadata": {
111 | "id": "oi9PPoUnQ6SJ"
112 | },
113 | "source": [
114 | "예제 18-2 `Craps_game` 클래스"
115 | ]
116 | },
117 | {
118 | "cell_type": "code",
119 | "execution_count": 4,
120 | "metadata": {
121 | "id": "0LIM0DijQ5c5"
122 | },
123 | "outputs": [],
124 | "source": [
125 | "class Craps_game(object): \n",
126 | " def __init__(self): \n",
127 | " self.pass_wins, self.pass_losses = 0, 0 \n",
128 | " self.dp_wins, self.dp_losses, self.dp_pushes = 0, 0, 0 \n",
129 | "\n",
130 | " def play_hand(self): \n",
131 | " throw = roll_die() + roll_die() \n",
132 | " if throw == 7 or throw == 11: \n",
133 | " self.pass_wins += 1 \n",
134 | " self.dp_losses += 1 \n",
135 | " elif throw == 2 or throw == 3 or throw == 12: \n",
136 | " self.pass_losses += 1 \n",
137 | " if throw == 12: \n",
138 | " self.dp_pushes += 1 \n",
139 | " else: \n",
140 | " self.dp_wins += 1 \n",
141 | " else: \n",
142 | " point = throw \n",
143 | " while True: \n",
144 | " throw = roll_die() + roll_die() \n",
145 | " if throw == point: \n",
146 | " self.pass_wins += 1 \n",
147 | " self.dp_losses += 1 \n",
148 | " break \n",
149 | " elif throw == 7: \n",
150 | " self.pass_losses += 1 \n",
151 | " self.dp_wins += 1 \n",
152 | " break \n",
153 | "\n",
154 | " def pass_results(self): \n",
155 | " return (self.pass_wins, self.pass_losses) \n",
156 | "\n",
157 | " def dp_results(self): \n",
158 | " return (self.dp_wins, self.dp_losses, self.dp_pushes) "
159 | ]
160 | },
161 | {
162 | "cell_type": "markdown",
163 | "metadata": {
164 | "id": "FQIhZL-2WGB_"
165 | },
166 | "source": [
167 | "예제 18-3 크랩스 게임 시뮬레이션하기"
168 | ]
169 | },
170 | {
171 | "cell_type": "code",
172 | "execution_count": 5,
173 | "metadata": {
174 | "id": "7HVwJ3bRWGsu"
175 | },
176 | "outputs": [],
177 | "source": [
178 | "def craps_sim(hands_per_game, num_games): \n",
179 | " \"\"\"hands_per_game과 num_games는 ints > 0이라고 가정합니다.\n",
180 | " hands_per_game번 핸드를 반복하는 num_games번 게임을 플레이하고 결과를 출력합니다\"\"\"\n",
181 | " games = [] \n",
182 | "\n",
183 | " #num_games번 게임을 플레이합니다\n",
184 | " for t in range(num_games): \n",
185 | " c = Craps_game() \n",
186 | " for i in range(hands_per_game): \n",
187 | " c.play_hand() \n",
188 | " games.append(c) \n",
189 | "\n",
190 | " #각 게임에 대한 통계를 생성합니다\n",
191 | " p_ROI_per_game, dp_ROI_per_game = [], [] \n",
192 | " for g in games: \n",
193 | " wins, losses = g.pass_results() \n",
194 | " p_ROI_per_game.append((wins - losses)/float(hands_per_game)) \n",
195 | " wins, losses, pushes = g.dp_results() \n",
196 | " dp_ROI_per_game.append((wins - losses)/float(hands_per_game)) \n",
197 | "\n",
198 | " #요약 통계를 만들어 출력합니다\n",
199 | " mean_ROI = str(round((100*sum(p_ROI_per_game)/num_games), 4)) + '%' \n",
200 | " sigma = str(round(100*np.std(p_ROI_per_game), 4)) + '%' \n",
201 | " print('패스:', '평균 ROI =', mean_ROI, '표준 편차 =', sigma) \n",
202 | " mean_ROI = str(round((100*sum(dp_ROI_per_game)/num_games), 4)) +'%' \n",
203 | " sigma = str(round(100*np.std(dp_ROI_per_game), 4)) + '%' \n",
204 | " print('돈 패스:','평균 ROI =', mean_ROI, '표준 편차 =', sigma) "
205 | ]
206 | },
207 | {
208 | "cell_type": "code",
209 | "execution_count": 6,
210 | "metadata": {
211 | "colab": {
212 | "base_uri": "https://localhost:8080/"
213 | },
214 | "id": "RE-paU7-XDkx",
215 | "outputId": "722cde5b-7978-4d77-fa58-8b86a03a42df"
216 | },
217 | "outputs": [
218 | {
219 | "name": "stdout",
220 | "output_type": "stream",
221 | "text": [
222 | "패스: 평균 ROI = -1.0% 표준 편차 = 18.1384%\n",
223 | "돈 패스: 평균 ROI = -1.5% 표준 편차 = 17.7553%\n"
224 | ]
225 | }
226 | ],
227 | "source": [
228 | "craps_sim(20, 10)"
229 | ]
230 | },
231 | {
232 | "cell_type": "code",
233 | "execution_count": 7,
234 | "metadata": {
235 | "id": "v_NGzXwWc2O0"
236 | },
237 | "outputs": [
238 | {
239 | "name": "stdout",
240 | "output_type": "stream",
241 | "text": [
242 | "패스: 평균 ROI = -1.3754% 표준 편차 = 0.0769%\n",
243 | "돈 패스: 평균 ROI = -1.3994% 표준 편차 = 0.0667%\n"
244 | ]
245 | }
246 | ],
247 | "source": [
248 | "craps_sim(1000000, 10)"
249 | ]
250 | },
251 | {
252 | "cell_type": "code",
253 | "execution_count": 8,
254 | "metadata": {},
255 | "outputs": [
256 | {
257 | "name": "stdout",
258 | "output_type": "stream",
259 | "text": [
260 | "패스: 평균 ROI = -1.4054% 표준 편차 = 22.3624%\n",
261 | "돈 패스: 평균 ROI = -1.3775% 표준 편차 = 22.0482%\n"
262 | ]
263 | }
264 | ],
265 | "source": [
266 | "craps_sim(20, 1000000)"
267 | ]
268 | },
269 | {
270 | "cell_type": "code",
271 | "execution_count": 9,
272 | "metadata": {},
273 | "outputs": [],
274 | "source": [
275 | "def roll_die(): \n",
276 | " return random.choice([1,1,2,3,3,4,4,5,5,5,6,6]) "
277 | ]
278 | },
279 | {
280 | "cell_type": "code",
281 | "execution_count": 10,
282 | "metadata": {},
283 | "outputs": [
284 | {
285 | "name": "stdout",
286 | "output_type": "stream",
287 | "text": [
288 | "패스: 평균 ROI = 6.664% 표준 편차 = 0.0772%\n",
289 | "돈 패스: 평균 ROI = -9.4545% 표준 편차 = 0.0713%\n"
290 | ]
291 | }
292 | ],
293 | "source": [
294 | "craps_sim(1000000, 10)"
295 | ]
296 | },
297 | {
298 | "cell_type": "markdown",
299 | "metadata": {},
300 | "source": [
301 | "**뇌풀기 문제**"
302 | ]
303 | },
304 | {
305 | "cell_type": "code",
306 | "execution_count": 11,
307 | "metadata": {},
308 | "outputs": [
309 | {
310 | "name": "stdout",
311 | "output_type": "stream",
312 | "text": [
313 | "빅 6: 시간당 평균 비용 = -15.3525달러 표준 편차 = 0.0901달러\n"
314 | ]
315 | }
316 | ],
317 | "source": [
318 | "def roll_die(): \n",
319 | " return random.choice([1,2,3,4,5,6]) \n",
320 | "\n",
321 | "class Craps_game_big6(object): \n",
322 | " def __init__(self): \n",
323 | " self.b6_wins, self.b6_losses = 0, 0\n",
324 | "\n",
325 | " def play_hand(self): \n",
326 | " throw = roll_die() + roll_die() \n",
327 | " if throw == 6:\n",
328 | " self.b6_wins += 1\n",
329 | " elif throw == 7:\n",
330 | " self.b6_losses += 1\n",
331 | " else: \n",
332 | " point = throw \n",
333 | " while True: \n",
334 | " throw = roll_die() + roll_die() \n",
335 | " if throw == 6:\n",
336 | " self.b6_wins += 1\n",
337 | " elif throw == point: \n",
338 | " break \n",
339 | " elif throw == 7: \n",
340 | " self.b6_losses += 1\n",
341 | " break \n",
342 | "\n",
343 | " def b6_results(self):\n",
344 | " return (self.b6_wins, self.b6_losses)\n",
345 | "\n",
346 | "def craps_sim_b6(hands_per_game, num_games): \n",
347 | " \"\"\"hands_per_game과 num_games는 ints > 0이라고 가정합니다.\n",
348 | " hands_per_game번 핸드를 반복하는 num_games번 게임을 플레이하고 결과를 출력합니다\"\"\"\n",
349 | " games = [] \n",
350 | "\n",
351 | " #num_games번 게임을 플레이합니다\n",
352 | " for t in range(num_games): \n",
353 | " c = Craps_game_big6() \n",
354 | " for i in range(hands_per_game): \n",
355 | " c.play_hand() \n",
356 | " games.append(c) \n",
357 | "\n",
358 | " #각 게임에 대한 통계를 생성합니다\n",
359 | " b6_cost_per_hour = [] \n",
360 | " for g in games: \n",
361 | " wins, losses = g.b6_results() \n",
362 | " b6_cost_per_hour.append((wins - losses)*5/(float(hands_per_game)/30)) \n",
363 | "\n",
364 | " #요약 통계를 만들어 출력합니다\n",
365 | " mean_cost = str(round(sum(b6_cost_per_hour)/num_games, 4)) + '달러' \n",
366 | " sigma = str(round(np.std(b6_cost_per_hour), 4)) + '달러' \n",
367 | " print('빅 6:', '시간당 평균 비용 =', mean_cost, '표준 편차 =', sigma) \n",
368 | "\n",
369 | "craps_sim_b6(1000000, 10)"
370 | ]
371 | },
372 | {
373 | "cell_type": "markdown",
374 | "metadata": {},
375 | "source": [
376 | "예제 18-4 테이블 룩업을 사용해 성능 향상하기"
377 | ]
378 | },
379 | {
380 | "cell_type": "code",
381 | "execution_count": 12,
382 | "metadata": {},
383 | "outputs": [],
384 | "source": [
385 | "def play_hand(self): \n",
386 | " #빠른 버전의 play_hand 구현\n",
387 | " points_dict = {4:1/3, 5:2/5, 6:5/11, 8:5/11, 9:2/5, 10:1/3} \n",
388 | " throw = roll_die() + roll_die() \n",
389 | " if throw == 7 or throw == 11: \n",
390 | " self.pass_wins += 1 \n",
391 | " self.dp_losses += 1 \n",
392 | " elif throw == 2 or throw == 3 or throw == 12: \n",
393 | " self.pass_losses += 1 \n",
394 | " if throw == 12: \n",
395 | " self.dp_pushes += 1 \n",
396 | " else: \n",
397 | " self.dp_wins += 1 \n",
398 | " else: \n",
399 | " if random.random() <= points_dict[throw]: # 7전에 포인트가 나옴\n",
400 | " self.pass_wins += 1 \n",
401 | " self.dp_losses += 1 \n",
402 | " else: # 포인트 전에 7이 나옴\n",
403 | " self.pass_losses += 1 \n",
404 | " self.dp_wins += 1 "
405 | ]
406 | },
407 | {
408 | "cell_type": "markdown",
409 | "metadata": {},
410 | "source": [
411 | "## 18.4 𝜋 찾기"
412 | ]
413 | },
414 | {
415 | "cell_type": "markdown",
416 | "metadata": {},
417 | "source": [
418 | "예제 18-5 𝜋 추정하기"
419 | ]
420 | },
421 | {
422 | "cell_type": "code",
423 | "execution_count": 13,
424 | "metadata": {},
425 | "outputs": [],
426 | "source": [
427 | "def throw_needles(num_needles): \n",
428 | " in_circle = 0 \n",
429 | " for Needles in range(1, num_needles + 1): \n",
430 | " x = random.random() \n",
431 | " y = random.random() \n",
432 | " if (x*x + y*y)**0.5 <= 1: \n",
433 | " in_circle += 1 \n",
434 | " #1사분면 안에 있는 바늘만 세므로 4를 곱합니다\n",
435 | " return 4*(in_circle/num_needles) \n",
436 | "\n",
437 | "def get_est(num_needles, num_trials): \n",
438 | " estimates = [] \n",
439 | " for t in range(num_trials): \n",
440 | " pi_guess = throw_needles(num_needles) \n",
441 | " estimates.append(pi_guess) \n",
442 | " std_dev = np.std(estimates) \n",
443 | " cur_est = sum(estimates)/len(estimates) \n",
444 | " print('𝜋 =', str(round(cur_est, 5)) + ',', \n",
445 | " '표준 편차 =', str(round(std_dev, 5)) + ',', \n",
446 | " '바늘 개수 =', num_needles) \n",
447 | " return (cur_est, std_dev) \n",
448 | "\n",
449 | "def est_pi(precision, num_trials): \n",
450 | " num_needles = 1000 \n",
451 | " std_dev = precision \n",
452 | " while std_dev > precision/1.96: \n",
453 | " cur_est, std_dev = get_est(num_needles, num_trials) \n",
454 | " num_needles *= 2 \n",
455 | " return cur_est "
456 | ]
457 | },
458 | {
459 | "cell_type": "code",
460 | "execution_count": 14,
461 | "metadata": {},
462 | "outputs": [
463 | {
464 | "name": "stdout",
465 | "output_type": "stream",
466 | "text": [
467 | "𝜋 = 3.13596, 표준 편차 = 0.05301, 바늘 개수 = 1000\n",
468 | "𝜋 = 3.14062, 표준 편차 = 0.03621, 바늘 개수 = 2000\n",
469 | "𝜋 = 3.14338, 표준 편차 = 0.02382, 바늘 개수 = 4000\n",
470 | "𝜋 = 3.14186, 표준 편차 = 0.01979, 바늘 개수 = 8000\n",
471 | "𝜋 = 3.1404, 표준 편차 = 0.01274, 바늘 개수 = 16000\n",
472 | "𝜋 = 3.14246, 표준 편차 = 0.00977, 바늘 개수 = 32000\n",
473 | "𝜋 = 3.14203, 표준 편차 = 0.00601, 바늘 개수 = 64000\n",
474 | "𝜋 = 3.14213, 표준 편차 = 0.0037, 바늘 개수 = 128000\n"
475 | ]
476 | },
477 | {
478 | "data": {
479 | "text/plain": [
480 | "3.1421275000000013"
481 | ]
482 | },
483 | "execution_count": 14,
484 | "metadata": {},
485 | "output_type": "execute_result"
486 | }
487 | ],
488 | "source": [
489 | "est_pi(0.01, 100)"
490 | ]
491 | },
492 | {
493 | "cell_type": "code",
494 | "execution_count": 15,
495 | "metadata": {},
496 | "outputs": [
497 | {
498 | "name": "stdout",
499 | "output_type": "stream",
500 | "text": [
501 | "𝜋 = 1.57422, 표준 편차 = 0.02394, 바늘 개수 = 1000\n",
502 | "𝜋 = 1.56959, 표준 편차 = 0.01775, 바늘 개수 = 2000\n",
503 | "𝜋 = 1.57054, 표준 편차 = 0.01356, 바늘 개수 = 4000\n",
504 | "𝜋 = 1.57072, 표준 편차 = 0.0084, 바늘 개수 = 8000\n",
505 | "𝜋 = 1.57068, 표준 편차 = 0.00685, 바늘 개수 = 16000\n",
506 | "𝜋 = 1.57066, 표준 편차 = 0.00424, 바늘 개수 = 32000\n"
507 | ]
508 | },
509 | {
510 | "data": {
511 | "text/plain": [
512 | "1.5706568750000003"
513 | ]
514 | },
515 | "execution_count": 15,
516 | "metadata": {},
517 | "output_type": "execute_result"
518 | }
519 | ],
520 | "source": [
521 | "def throw_needles(num_needles): \n",
522 | " in_circle = 0 \n",
523 | " for Needles in range(1, num_needles + 1): \n",
524 | " x = random.random() \n",
525 | " y = random.random() \n",
526 | " if (x*x + y*y)**0.5 <= 1: \n",
527 | " in_circle += 1 \n",
528 | " #1사분면 안에 있는 바늘만 세므로 4를 곱합니다\n",
529 | " return 2*(in_circle/num_needles) \n",
530 | "\n",
531 | "random.seed(0)\n",
532 | "est_pi(0.01, 100)"
533 | ]
534 | }
535 | ],
536 | "metadata": {
537 | "colab": {
538 | "authorship_tag": "ABX9TyNWhSsZ1N10qve8sOsSoLIt",
539 | "provenance": []
540 | },
541 | "environment": {
542 | "kernel": "python3",
543 | "name": "common-cpu.m102",
544 | "type": "gcloud",
545 | "uri": "gcr.io/deeplearning-platform-release/base-cpu:m102"
546 | },
547 | "kernelspec": {
548 | "display_name": "Python 3 (ipykernel)",
549 | "language": "python",
550 | "name": "python3"
551 | },
552 | "language_info": {
553 | "codemirror_mode": {
554 | "name": "ipython",
555 | "version": 3
556 | },
557 | "file_extension": ".py",
558 | "mimetype": "text/x-python",
559 | "name": "python",
560 | "nbconvert_exporter": "python",
561 | "pygments_lexer": "ipython3",
562 | "version": "3.8.2"
563 | }
564 | },
565 | "nbformat": 4,
566 | "nbformat_minor": 4
567 | }
568 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Haesun Park
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 코딩 뇌를 깨우는 파이썬
2 |
3 | 구매처: [Yes24](https://www.yes24.com/Product/Goods/121961550), [교보문고](https://product.kyobobook.co.kr/detail/S000208693477), [알라딘](https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=323348640), [한빛미디어](https://www.hanbit.co.kr/media/books/book_view.html?p_code=B6171497304)
4 |
5 |
6 |
7 | 이 저장소는 <코딩 뇌를 깨우는 파이썬>(한빛미디어, 2023)의 코드를 담고 있습니다.
8 |
9 | 각 장의 코드는 독립된 하나의 노트북으로 제공됩니다. 모든 노트북은 구글 코랩을 사용해 실행해 볼 수 있습니다. 노트북을 클릭하면 구글 코랩으로 열 수 있는 링크를 볼 수 있습니다.
10 |
--------------------------------------------------------------------------------
/circle.py:
--------------------------------------------------------------------------------
1 | pi = 3.14159
2 |
3 | def area(radius):
4 | return pi*(radius**2)
5 |
6 | def circumference(radius):
7 | return 2*pi*radius
8 |
9 | def sphere_surface(radius):
10 | return 4.0*area(radius)
11 |
12 | def sphere_volume(radius):
13 | return (4.0/3.0)*pi*(radius**3)
14 |
--------------------------------------------------------------------------------
/dentalFormulas.csv:
--------------------------------------------------------------------------------
1 | #다음 라인은 열 이름 설명입니다
2 | #이름,위 앞니,위 송곳니,위 작은 어금니,위 큰 어금니,아래 앞니,아래 송곳니,아래 작은 어금니,아래 큰 어금니,무게
3 | Name,ti,tc,tpm,tm,bi,bc,bpm,bm,weight
4 | 오소리,3,1,3,1,3,1,3,2,10
5 | 곰,3,1,4,2,3,1,4,3,278
6 | 퓨마,3,1,3,1,3,1,2,1,63
7 | 소,0,0,3,3,3,1,2,1,400
8 | 사슴,0,0,3,3,4,0,3,3,200
9 | 개,3,1,4,2,3,1,4,3,20
10 | 엘크,0,1,3,3,3,1,3,3,500
11 | 여우,3,1,4,2,3,1,4,3,5
12 | 물개,3,1,4,1,2,1,4,1,200
13 | 회색물범,3,1,3,2,2,1,3,2,268
14 | 기니피그,1,0,1,3,1,0,1,3,1
15 | 사람,2,1,2,3,2,1,2,3,150
16 | 재규어,3,1,3,1,3,1,2,1,81
17 | 캥커루,3,1,2,4,1,0,2,4,55
18 | 사자,3,1,3,1,3,1,2,1,175
19 | 밍크,3,1,3,1,3,1,3,2,1
20 | 두더지,3,1,4,3,3,1,4,3,0.75
21 | 무스,0,0,3,3,4,0,3,3,900
22 | 생쥐,1,0,0,3,1,0,0,3,0.3
23 | 돼지,3,1,4,3,3,1,4,3,50
24 | 호저,1,0,1,3,1,0,1,3,3
25 | 토끼,2,0,3,3,1,0,2,3,1
26 | 너구리,3,1,4,2,3,1,4,2,40
27 | 쥐,1,0,0,3,1,0,0,3,.75
28 | 붉은나무박쥐,1,1,2,3,3,1,2,3,1
29 | 바다사자,3,1,4,1,2,1,4,1,415
30 | 스컹크,3,1,3,1,3,1,3,2,2
31 | 다람쥐,1,0,2,3,1,0,1,3,2
32 | 늑대,3,1,4,2,3,1,4,3,27
33 | 그라운드호그,1,0,2,3,1,0,1,3,4
--------------------------------------------------------------------------------
/diet.csv:
--------------------------------------------------------------------------------
1 | #식습관: 0=초식, 1=육식, 2=잡식
2 | Name,Diet
3 | 오소리,1
4 | 곰,2
5 | 퓨마,1
6 | 소,0
7 | 사슴,0
8 | 개,1
9 | 엘크,0
10 | 여우,1
11 | 물개,1
12 | 회색물범,1
13 | 기니피그,0
14 | 사람,2
15 | 재규어,1
16 | 캥거루,0
17 | 사자,1
18 | 밍크,1
19 | 두더지,1
20 | 무스,0
21 | 생쥐,2
22 | 돼지,2
23 | 호저,0
24 | 토끼,0
25 | 너구리,2
26 | 쥐,2
27 | 붉은나무박쥐,1
28 | 바다사자,1
29 | 스컹크,2
30 | 다람쥐,2
31 | 늑대,1
32 | 그라운드호그,2
--------------------------------------------------------------------------------
/figure_13-19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rickiepark/python4daml/01881350f6cb8b40587f09342272d025bc379cbc/figure_13-19.png
--------------------------------------------------------------------------------
/global-fossil-fuel-consumption.csv:
--------------------------------------------------------------------------------
1 | Year,Coal,Crude Oil,Natural Gas
2 | 1965,16151.96017,18054.69004,6306.370076
3 | 1966,16332.01679,19442.23715,6871.686791
4 | 1967,16071.18119,20830.13575,7377.525476
5 | 1968,16312.60576,22613.21746,8046.478672
6 | 1969,16825.99292,24534.98916,8835.591838
7 | 1970,17065.27113,26649.8116,9614.414364
8 | 1971,16971.04648,28233.71612,10289.89468
9 | 1972,17161.86462,30399.20981,10858.55694
10 | 1973,17673.14043,32775.00958,11374.03922
11 | 1974,17687.80045,32299.54837,11652.60482
12 | 1975,18031.66073,31973.18489,11657.59717
13 | 1976,18688.42129,34064.96456,12350.85663
14 | 1977,19241.4531,35224.40759,12756.89778
15 | 1978,19456.78595,36354.28057,13291.68232
16 | 1979,20359.51044,36953.1491,14121.9509
17 | 1980,20856.53098,35506.32689,14238.31962
18 | 1981,21148.79702,34228.87205,14395.89609
19 | 1982,21384.22049,33177.85701,14473.22634
20 | 1983,22040.19421,32981.31709,14706.11331
21 | 1984,22997.47253,33746.54047,15912.38739
22 | 1985,23906.3229,33792.84203,16263.14014
23 | 1986,24182.95534,34819.31693,16421.36448
24 | 1987,25145.10228,35532.11408,17289.17958
25 | 1988,25889.97449,36735.8996,18083.52241
26 | 1989,26152.07667,37343.11239,18902.85595
27 | 1990,25845.88485,37736.94729,19486.64542
28 | 1991,25561.41954,37763.14824,19984.58677
29 | 1992,25478.81089,38422.53103,20076.92098
30 | 1993,25580.92144,38179.42324,20275.09431
31 | 1994,25729.64169,39021.80173,20405.36342
32 | 1995,25867.8533,39555.43054,21121.78818
33 | 1996,26516.28457,40480.1731,22143.41796
34 | 1997,26549.71899,41544.67299,22082.05319
35 | 1998,26351.79429,41768.48384,22485.93806
36 | 1999,26492.77461,42510.09274,23107.57158
37 | 2000,27403.94562,43038.62001,24019.89227
38 | 2001,27851.05371,43421.10755,24367.11133
39 | 2002,28936.6423,43796.55068,25108.12839
40 | 2003,31475.58334,44803.21017,25769.17552
41 | 2004,33656.31109,46503.96733,26752.16794
42 | 2005,36118.94545,47115.72728,27537.09099
43 | 2006,37979.81684,47732.19992,28347.57835
44 | 2007,40143.91171,48471.73162,29580.25097
45 | 2008,40712.5427,48250.64229,30321.37836
46 | 2009,40088.33994,47422.36853,29477.9263
47 | 2010,41932.74507,48949.72046,31759.12422
48 | 2011,43948.96889,49455.27172,32410.44868
49 | 2012,44129.62497,50065.86499,33270.53388
50 | 2013,44953.01385,50698.38455,33714.94785
51 | 2014,44916.83781,51109.97172,33986.84723
52 | 2015,43786.8458,52053.27008,34741.88349
53 | 2016,43101.23216,53001.86598,35741.82987
54 | 2017,43397.13549,53752.27638,36703.96587
--------------------------------------------------------------------------------
/launcherData.csv:
--------------------------------------------------------------------------------
1 | Distance,Trial1,Trial2,Trial3,Trial4
2 | 1080,0.0,0.0,0.0,0.0
3 | 1044,2.25,3.25,4.5,6.5
4 | 1008,5.25,6.5,6.5,8.75
5 | 972,7.5,7.75,8.25,9.25
6 | 936,8.75,9.25,9.5,10.5
7 | 900,12.0,12.25,12.5,14.75
8 | 864,13.75,16.0,16.0,16.5
9 | 828,14.75,15.25,15.5,17.5
10 | 792,15.5,16.0,16.6,16.75
11 | 756,17.0,17.0,17.5,19.25
12 | 720,17.5,18.5,18.5,19.0
13 | 540,19.5,20.0,20.25,20.5
14 | 360,18.5,18.5,19.0,19.0
15 | 180,13.0,13.0,13.0,13.0
16 | 0,0.0,0.0,0.0,0.0
17 |
--------------------------------------------------------------------------------
/midWestHousingPrices.csv:
--------------------------------------------------------------------------------
1 | 2006,01,210700
2 | 2006,02,203100
3 | 2006,03,216800
4 | 2006,04,216200
5 | 2007,01,212800
6 | 2007,02,203200
7 | 2007,03,209600
8 | 2007,04,197400
9 | 2008,01,219200
10 | 2008,02,198500
11 | 2008,03,184700
12 | 2008,04,202500
13 | 2009,01,187100
14 | 2009,02,193200
15 | 2009,03,184900
16 | 2009,04,196000
17 |
--------------------------------------------------------------------------------
/quiz1grades.txt:
--------------------------------------------------------------------------------
1 | 83
2 | 76
3 | 94
4 | 85
5 | 82
6 | 85
7 | 74
8 | 84
9 | 92
10 | 95
11 | 99
12 | 93
13 | 79
14 | 77
15 | 93
16 | 76
17 | 94
18 | 74
19 | 99
20 | 70
21 | 84
22 | 97
23 | 82
24 | 85
25 | 77
26 | 95
27 | 97
28 | 100
29 | 83
30 | 87
31 | 75
32 | 84
33 | 82
34 | 80
35 | 100
36 | 91
37 | 74
38 | 93
39 | 73
40 | 98
41 | 81
42 | 80
43 | 79
44 | 76
45 | 80
46 | 86
47 | 94
48 | 73
49 | 74
50 | 78
51 | 74
52 | 89
53 | 93
54 | 86
55 | 78
56 | 84
57 | 94
58 | 82
59 | 89
60 | 85
61 | 72
62 | 78
63 | 92
64 | 75
65 | 81
66 | 83
67 | 85
68 | 81
69 | 73
70 | 86
71 | 80
72 | 80
73 | 74
74 | 88
75 | 78
76 | 76
77 | 94
78 | 84
79 | 71
80 | 70
81 | 91
82 | 93
83 | 80
84 | 80
85 | 86
86 | 78
87 | 70
88 | 90
89 | 80
90 | 90
91 | 86
92 | 74
93 | 78
94 | 91
95 | 94
96 | 76
97 | 70
98 | 85
99 | 89
100 | 72
101 |
--------------------------------------------------------------------------------
/springData.csv:
--------------------------------------------------------------------------------
1 | Distance (m),Mass (kg)
2 | 0.0865,0.1
3 | 0.1015,0.15
4 | 0.1106,0.2
5 | 0.1279,0.25
6 | 0.1892,0.3
7 | 0.2695,0.35
8 | 0.2888,0.4
9 | 0.2425,0.45
10 | 0.3465,0.5
11 | 0.3225,0.55
12 | 0.3764,0.6
13 | 0.4263,0.65
14 | 0.4562,0.7
15 | 0.4502,0.75
16 | 0.4499,0.8
17 | 0.4534,0.85
18 | 0.4416,0.9
19 | 0.4304,0.95
20 | 0.437,1.0
21 |
--------------------------------------------------------------------------------
/wwc2019_q-f.csv:
--------------------------------------------------------------------------------
1 | Round,Winner,W Goals,Loser,L Goals
2 | Quarters,England,3,Norway,0
3 | Quarters,USA,2,France,1
4 | Quarters,Netherlands,2,Italy,0
5 | Quarters,Sweden,2,Germany,1
6 | Semis,USA,2,England,1
7 | Semis,Netherlands,1,Sweden,0
8 | 3rd Place,Sweden,2,England,1
9 | Championship,USA,2,Netherlands,0
10 |
--------------------------------------------------------------------------------
| | |