├── .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 | --------------------------------------------------------------------------------