{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.1 개요" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.2 22가지 프로그래밍 지름길" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.1 필요하다면 코드를 여러 줄에 걸쳐서 작성한다" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I am Hen-er-y the Eighth, I am!\n" ] } ], "source": [ "my_str = 'I am Hen-er-y the Eighth,' ' I am!'\n", "print(my_str)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'I am Hen-er-y the Eighth, I am!'" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_str = 'I am Hen-er-y the Eighth,' \\\n", "' I am!'\n", "my_str" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'I am Hen-er-y the Eighth, I am! I am not just any Henry VIII, I really am!'" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_str = ('I am Hen-er-y the Eighth, '\n", "'I am! I am not just any Henry VIII, '\n", "'I really am!')\n", "my_str" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "tuple" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 10, 5\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "side1, side2 = a" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "side1" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "side2" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "11.180339887498949" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "side1, side2 = 10, 5\n", "length_of_hypotenuse = ( (side1 * side1 + side2 * side2)\n", " ** 0.5 )\n", "length_of_hypotenuse" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "11.180339887498949" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "side1, side2 = 10, 5\n", "length_of_hypotenuse = (side1 * side1 + side2 * side2) \\\n", " ** 0.5\n", "length_of_hypotenuse" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.2\t for 루프는 현명하게 사용한다." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "John\n", "Paul\n", "George\n", "Ringo\n" ] } ], "source": [ "beat_list = ['John', 'Paul', 'George', 'Ringo']\n", "for i in range(len(beat_list)):\n", " print(beat_list[i])" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "John\n", "Paul\n", "George\n", "Ringo\n" ] } ], "source": [ "beat_list = ['John', 'Paul', 'George', 'Ringo']\n", "for guy in beat_list:\n", " print(guy)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1. John\n", "2. Paul\n", "3. George\n", "4. Ringo\n" ] } ], "source": [ "beat_list = ['John', 'Paul', 'George', 'Ringo']\n", "for i, name in enumerate(beat_list, 1):\n", " print(i, '. ', name, sep='')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.3 조합 대입 연산자를 이해한다. (예: +=)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](./images_skill_up/4-2.PNG)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "s1: A string....with more stuff!\n", "s2: A string.\n" ] } ], "source": [ "s1 = s2 = 'A string.'\n", "s1 += '...with more stuff!'\n", "print('s1:', s1)\n", "print('s2:', s2)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a_list: [10, 20, 30, 40]\n", "b_list: [10, 20, 30, 40]\n" ] } ], "source": [ "a_list = b_list = [10, 20]\n", "a_list += [30, 40]\n", "print('a_list:', a_list)\n", "print('b_list:', b_list)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'abcdefghijklmnopqrstuvwxyz'" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "str_list = []\n", "n = ord('a')\n", "for i in range(n, n + 26):\n", " str_list += chr(i)\n", "alphabet_str = ''.join(str_list)\n", "alphabet_str" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.4 다중 대입을 사용한다" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "a = b = c = d = e = 0" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a is b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.5 튜플 대입을 사용한다" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "a = 1\n", "b = 0" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "a, b = 1, 0" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(4, 8, 12)" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 4, 8, 12 \t\t# a는 이제 3개 값을 지닌 튜플이다.\n", "a" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "30 10\n" ] } ], "source": [ "a, b = 10, 20\n", "temp = a \t# a 기존 값 보존\n", "a = a + b \t# a에 신규 값 설정\n", "b = temp \t# b에 a 기존 값 저장 \n", "print(a, b)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "30 10\n" ] } ], "source": [ "a, b = 10, 20\n", "a, b = a + b, a\n", "print(a, b)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 1 2 3 5 8 " ] } ], "source": [ "def fibo(n):\n", " a, b = 1, 0\n", "\n", " while a <= n:\n", " print(a, end=' ')\n", " a, b = a + b, a\n", "\n", "fibo(10)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 25\n", "25 1\n" ] } ], "source": [ "x, y = 1, 25\n", "print(x, y) \t# 1 25 출력\n", "x, y = y, x\n", "print(x, y) \t# 25 1 출력" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "a, b, c = [1, 2, 3]" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3\n" ] } ], "source": [ "print(a, b, c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.6 고급 튜플 대입을 사용한다" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10 20 30\n" ] } ], "source": [ "tup = 10, 20, 30 # 패킹 (Packing)\n", "a, b, c = tup # 언패킹 (Unpacking)\n", "print(a, b, c) \t\t# 10, 20, 30 출력" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "too many values to unpack (expected 2)", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mtup\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m30\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtup\u001b[0m \u001b[0;31m# 에러: 언팩 대상 값이 너무 많음\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mValueError\u001b[0m: too many values to unpack (expected 2)" ] } ], "source": [ "tup = 10, 20, 30\n", "a, b = tup \t\t# 에러: 언팩 대상 값이 너무 많음" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "my_list = [3]" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "my_tup = (3)\n", "print(type(my_tup))" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "my_tup = (3,) \t# 한 항목 3을 가진 튜플 만들기\n", "print(type(my_tup))" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 [4, 6, 8]\n" ] } ], "source": [ "a, *b = 2, 4, 6, 8\n", "print(a, b)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10 [20, 30, 40] 50\n" ] } ], "source": [ "a, *b, c = 10, 20, 30, 40, 50\n", "print(a, b, c)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "big, bigger, *many = 100, 200, 300, 400, 500, 600" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "100\n", "200\n", "[300, 400, 500, 600]\n" ] } ], "source": [ "print(big, bigger, many, sep='\\n')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.7 리스트와 문자열 '곱하기'를 사용한다" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10000" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_list = [0] * 10000\n", "len(my_list)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1999" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_list = 1999 * [12]\n", "len(my_list)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "300" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "trip_list = [1, 2, 3] * 100\n", "len(trip_list)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'________________________________________'" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "divider_str = '_' * 40\n", "divider_str" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.8 다중 값을 반환한다" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10\n" ] } ], "source": [ "def double_me(n):\n", " n *= 2\n", "\n", "a = 10\n", "double_me(a)\n", "print(a) \t# a 값이 두배가 되지 않는다!!" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "20\n" ] } ], "source": [ "def double_me(n):\n", " return n * 2\n", "\n", "a = 10\n", "a = double_me(a)\n", "print(a)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "def quad(a, b, c):\n", " determin = (b * b - 4 * a * c) ** .5\n", " x1 = (-b + determin) / (2 * a)\n", " x2 = (-b - determin) / (2 * a)\n", " return x1, x2" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "x1, x2 = quad(1, -1, -1)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1.618033988749895, -0.6180339887498949)" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = quad(1, -1, -1)\n", "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.9 루프와 else 키워드를 사용한다" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "def find_divisor(n, max):\n", " for i in range(2, max + 1):\n", " if n % i == 0:\n", " print(i, 'divides evenly into', n)\n", " break\n", " else: # break를 만나서 일찍 빠져나오지 않는 한 루프 종료시 수행된다.\n", " print('No divisor found')" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "No divisor found\n" ] } ], "source": [ "find_divisor(49, 6)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7 divides evenly into 49\n" ] } ], "source": [ "find_divisor(49, 7)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.10\t 불리언과 'not'의 이점을 활용한다" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "my_str = ''\n", "while True:\n", " if len(my_str) == 0:\n", " break" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [], "source": [ "while True:\n", " if not my_str:\n", " break" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.11\t 문자열은 문자의 나열로 다룬다" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['A', 'B', 'C', 'B', 'A']\n", "True\n" ] } ], "source": [ "test_str = input('Enter test string: ')\n", "a_list = [c.upper() for c in test_str if c.isalnum()]\n", "print(a_list)\n", "print(a_list == a_list[::-1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.12\t replace를 사용하여 문자를 제거한다" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'1/2'" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = '1 / 2'\n", "s = s.replace(' ', '')\n", "s" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'sm dy'" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = 'same day'\n", "a_list = [c for c in s if c not in 'aeiou']\n", "s = ''.join(a_list)\n", "s" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "'sm dy'" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = 'same day'\n", "s = s.replace('a', '').replace('e', '').replace('i', '').replace('o', '').replace('u', '')\n", "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.13\t 필요 없는 루프는 사용하지 않는다" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "55" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def calc_triangle_num(n):\n", " s = 0\n", " for i in range(n + 1):\n", " s += i\n", " return s\n", "\n", "calc_triangle_num(10)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "55" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def calc_triangle_num(n):\n", " return sum(range(n + 1))\n", "\n", "calc_triangle_num(10)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "25.0" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def get_avg(a_list):\n", " s = 0\n", " for i in a_list:\n", " s += i\n", "\n", " return s / len(a_list)\n", "\n", "get_avg([10, 20, 30, 40])" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "25.0" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def get_avg(a_list):\n", " return sum(a_list) / len(a_list)\n", "\n", "get_avg([10, 20, 30, 40])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.14\t 연결된(chained) 비교 연산자를 사용한다" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x is in range.\n" ] } ], "source": [ "x = 55\n", "if 0 < x and x < 100:\n", " print('x is in range.')" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x is in range.\n" ] } ], "source": [ "if 0 < x < 100: \t\t\t# 연결된(chained) 비교 연산자 사용\n", " print('x is in range.')" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All these comparisons are true!\n", "c is equal or greater than all the rest!\n" ] } ], "source": [ "a, b, c = 5, 10, 15\n", "if 0 < a <= c > b > 1:\n", " print('All these comparisons are true!')\n", " print('c is equal or greater than all the rest!')" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All the variables are equal to each other.\n" ] } ], "source": [ "a = b = c = d = e = 100\n", "if a == b == c == d == e:\n", " print('All the variables are equal to each other.')" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All the elements are equal to each other.\n" ] } ], "source": [ "a_list = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ,1 ,1]\n", "if min(a_list) == max(a_list):\n", " print('All the elements are equal to each other.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.15\t 함수 테이블(리스트, 딕셔너리)로 'switch'를 모방한다" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello, insuk\n" ] } ], "source": [ "n = 1\n", "\n", "def test(name='init'):\n", " print('hello,', name)\n", "\n", "do_plot = do_highlow_plot = do_volume_subplot = do_movingavg_plot = test\n", "\n", "stockdf = 'insuk'\n", "\n", "if n == 1:\n", " do_plot(stockdf)\n", "elif n == 2:\n", " do_highlow_plot(stockdf)\n", "elif n == 3:\n", " do_volume_subplot(stockdf)\n", "elif n == 4:\n", " do_movingavg_plot(stockdf)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello, insuk\n" ] } ], "source": [ "n = 1\n", "fn = [do_plot, do_highlow_plot, do_volume_subplot, do_movingavg_plot][n - 1]\n", "fn(stockdf) \t\t# 함수 호출" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello, insuk\n" ] } ], "source": [ "n = 1\n", "f_list = [do_plot, do_highlow_plot, do_volume_subplot, do_movingavg_plot]\n", "fn = f_list[n - 1]\n", "fn(stockdf) \t\t# 함수 호출" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello, init\n" ] } ], "source": [ "load_fn = save_fn = exit_fn = update_fn = test\n", "menu_dict = {'load':load_fn, 'save':save_fn, 'exit':exit_fn, 'update':update_fn}\n", "\n", "selector = 'exit'\n", "(menu_dict[selector])() \t\t\t# 함수 호출" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.16\t is 연산자는 정확하게 사용한다" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 'cat'\n", "b = 'cat'\n", "a == b \t\t# 반드시 True 반환" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s1 = 'I am what I am and that is all that I am.'\n", "s2 = 'I am what I am' + ' and that is all that I am.'\n", "s1 == s2" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s1 is s2" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a_value 함수의 반환값은 None이다.\n" ] } ], "source": [ "def my_function():\n", " return None\n", "\n", "a_value = my_function()\n", "\n", "if a_value is None: # 이곳에 if a_value == None 은 불가!!!\n", " # None이 반환되면 특별한 행동을 취해라.\n", " print('a_value 함수의 반환값은 None이다.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.17\t 단일 행 for 루프를 사용한다" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 2 3 4 5 6 7 8 9 " ] } ], "source": [ "for i in range(10): print(i, end=' ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.18\t 여러 문장을 하나의 행으로 줄인다" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5 7 9 11 13 " ] } ], "source": [ "for i in range(5): n=i*2; m = 5; print(n+m, end=' ')" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] } ], "source": [ "a = 1; b = 2; c = a + b; print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.19\t 단일 행 if/then/else 문을 작성한다" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'O'" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "turn = 0\n", "\n", "if turn % 2:\n", " cell = 'X'\n", "else:\n", " cell = 'O'\n", "\n", "cell" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'O'" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cell = 'X' if turn % 2 else 'O'\n", "cell" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.20\t range와 함께 Enum을 생성한다" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 2 3 4\n" ] } ], "source": [ "red = 0\n", "blue = 1\n", "green = 2\n", "black = 3\n", "white = 4\n", "\n", "print(red, blue, green, black, white)" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 2 3 4\n" ] } ], "source": [ "red, blue, green, black, white = range(5)\n", "print(red, blue, green, black, white)" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3 4 5\n" ] } ], "source": [ "red, blue, green, black, white = range(1, 6)\n", "print(red, blue, green, black, white)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on module enum:\n", "\n", "NAME\n", " enum\n", "\n", "MODULE REFERENCE\n", " https://docs.python.org/3.9/library/enum\n", " \n", " The following documentation is automatically generated from the Python\n", " source files. It may be incomplete, incorrect or include features that\n", " are considered implementation detail and may vary between Python\n", " implementations. When in doubt, consult the module reference at the\n", " location listed above.\n", "\n", "CLASSES\n", " builtins.int(builtins.object)\n", " IntEnum(builtins.int, Enum)\n", " IntFlag(builtins.int, Flag)\n", " builtins.object\n", " Enum\n", " Flag\n", " IntFlag(builtins.int, Flag)\n", " IntEnum(builtins.int, Enum)\n", " auto\n", " builtins.type(builtins.object)\n", " EnumMeta\n", " \n", " class Enum(builtins.object)\n", " | Enum(value, names=None, *, module=None, qualname=None, type=None, start=1)\n", " | \n", " | Generic enumeration.\n", " | \n", " | Derive from this class to define new enumerations.\n", " | \n", " | Data descriptors defined here:\n", " | \n", " | name\n", " | The name of the Enum member.\n", " | \n", " | value\n", " | The value of the Enum member.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Readonly properties inherited from EnumMeta:\n", " | \n", " | __members__\n", " | Returns a mapping of member name->value.\n", " | \n", " | This mapping lists all enum members, including aliases. Note that this\n", " | is a read-only view of the internal mapping.\n", " \n", " class EnumMeta(builtins.type)\n", " | EnumMeta(cls, bases, classdict)\n", " | \n", " | Metaclass for Enum\n", " | \n", " | Method resolution order:\n", " | EnumMeta\n", " | builtins.type\n", " | builtins.object\n", " | \n", " | Methods defined here:\n", " | \n", " | __bool__(self)\n", " | classes/types should always be True.\n", " | \n", " | __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1)\n", " | Either returns an existing member, or creates a new enum class.\n", " | \n", " | This method is used both when an enum class is given a value to match\n", " | to an enumeration member (i.e. Color(3)) and for the functional API\n", " | (i.e. Color = Enum('Color', names='RED GREEN BLUE')).\n", " | \n", " | When used for the functional API:\n", " | \n", " | `value` will be the name of the new class.\n", " | \n", " | `names` should be either a string of white-space/comma delimited names\n", " | (values will start at `start`), or an iterator/mapping of name, value pairs.\n", " | \n", " | `module` should be set to the module this class is being created in;\n", " | if it is not set, an attempt to find that module will be made, but if\n", " | it fails the class will not be picklable.\n", " | \n", " | `qualname` should be set to the actual location this class can be found\n", " | at in its module; by default it is set to the global scope. If this is\n", " | not correct, unpickling will fail in some circumstances.\n", " | \n", " | `type`, if set, will be mixed in as the first base class.\n", " | \n", " | __contains__(cls, member)\n", " | \n", " | __delattr__(cls, attr)\n", " | Implement delattr(self, name).\n", " | \n", " | __dir__(self)\n", " | Specialized __dir__ implementation for types.\n", " | \n", " | __getattr__(cls, name)\n", " | Return the enum member matching `name`\n", " | \n", " | We use __getattr__ instead of descriptors or inserting into the enum\n", " | class' __dict__ in order to support `name` and `value` being both\n", " | properties for enum members (which live in the class' __dict__) and\n", " | enum members themselves.\n", " | \n", " | __getitem__(cls, name)\n", " | \n", " | __iter__(cls)\n", " | \n", " | __len__(cls)\n", " | \n", " | __repr__(cls)\n", " | Return repr(self).\n", " | \n", " | __reversed__(cls)\n", " | \n", " | __setattr__(cls, name, value)\n", " | Block attempts to reassign Enum members.\n", " | \n", " | A simple assignment to the class namespace only changes one of the\n", " | several possible ways to get an Enum member from the Enum class,\n", " | resulting in an inconsistent Enumeration.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Class methods defined here:\n", " | \n", " | __prepare__(cls, bases) from builtins.type\n", " | __prepare__() -> dict\n", " | used to create the namespace for the class statement\n", " | \n", " | ----------------------------------------------------------------------\n", " | Static methods defined here:\n", " | \n", " | __new__(metacls, cls, bases, classdict)\n", " | Create and return a new object. See help(type) for accurate signature.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Readonly properties defined here:\n", " | \n", " | __members__\n", " | Returns a mapping of member name->value.\n", " | \n", " | This mapping lists all enum members, including aliases. Note that this\n", " | is a read-only view of the internal mapping.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Methods inherited from builtins.type:\n", " | \n", " | __getattribute__(self, name, /)\n", " | Return getattr(self, name).\n", " | \n", " | __init__(self, /, *args, **kwargs)\n", " | Initialize self. See help(type(self)) for accurate signature.\n", " | \n", " | __instancecheck__(self, instance, /)\n", " | Check if an object is an instance.\n", " | \n", " | __sizeof__(self, /)\n", " | Return memory consumption of the type object.\n", " | \n", " | __subclasscheck__(self, subclass, /)\n", " | Check if a class is a subclass.\n", " | \n", " | __subclasses__(self, /)\n", " | Return a list of immediate subclasses.\n", " | \n", " | mro(self, /)\n", " | Return a type's method resolution order.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data descriptors inherited from builtins.type:\n", " | \n", " | __abstractmethods__\n", " | \n", " | __dict__\n", " | \n", " | __text_signature__\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data and other attributes inherited from builtins.type:\n", " | \n", " | __base__ = \n", " | type(object_or_name, bases, dict)\n", " | type(object) -> the object's type\n", " | type(name, bases, dict) -> a new type\n", " | \n", " | \n", " | __bases__ = (,)\n", " | \n", " | __basicsize__ = 880\n", " | \n", " | __dictoffset__ = 264\n", " | \n", " | __flags__ = 2148292096\n", " | \n", " | __itemsize__ = 40\n", " | \n", " | __mro__ = (, , )\n", " | \n", " | __weakrefoffset__ = 368\n", " \n", " class Flag(Enum)\n", " | Flag(value, names=None, *, module=None, qualname=None, type=None, start=1)\n", " | \n", " | Support for flags\n", " | \n", " | Method resolution order:\n", " | Flag\n", " | Enum\n", " | builtins.object\n", " | \n", " | Data descriptors inherited from Enum:\n", " | \n", " | name\n", " | The name of the Enum member.\n", " | \n", " | value\n", " | The value of the Enum member.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Readonly properties inherited from EnumMeta:\n", " | \n", " | __members__\n", " | Returns a mapping of member name->value.\n", " | \n", " | This mapping lists all enum members, including aliases. Note that this\n", " | is a read-only view of the internal mapping.\n", " \n", " class IntEnum(builtins.int, Enum)\n", " | IntEnum(value, names=None, *, module=None, qualname=None, type=None, start=1)\n", " | \n", " | Enum where members are also (and must be) ints\n", " | \n", " | Method resolution order:\n", " | IntEnum\n", " | builtins.int\n", " | Enum\n", " | builtins.object\n", " | \n", " | Data descriptors inherited from Enum:\n", " | \n", " | name\n", " | The name of the Enum member.\n", " | \n", " | value\n", " | The value of the Enum member.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Readonly properties inherited from EnumMeta:\n", " | \n", " | __members__\n", " | Returns a mapping of member name->value.\n", " | \n", " | This mapping lists all enum members, including aliases. Note that this\n", " | is a read-only view of the internal mapping.\n", " \n", " class IntFlag(builtins.int, Flag)\n", " | IntFlag(value, names=None, *, module=None, qualname=None, type=None, start=1)\n", " | \n", " | Support for integer-based Flags\n", " | \n", " | Method resolution order:\n", " | IntFlag\n", " | builtins.int\n", " | Flag\n", " | Enum\n", " | builtins.object\n", " | \n", " | Data descriptors inherited from Enum:\n", " | \n", " | name\n", " | The name of the Enum member.\n", " | \n", " | value\n", " | The value of the Enum member.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Readonly properties inherited from EnumMeta:\n", " | \n", " | __members__\n", " | Returns a mapping of member name->value.\n", " | \n", " | This mapping lists all enum members, including aliases. Note that this\n", " | is a read-only view of the internal mapping.\n", " \n", " class auto(builtins.object)\n", " | Instances are replaced with an appropriate value in Enum class suites.\n", " | \n", " | Data descriptors defined here:\n", " | \n", " | __dict__\n", " | dictionary for instance variables (if defined)\n", " | \n", " | __weakref__\n", " | list of weak references to the object (if defined)\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data and other attributes defined here:\n", " | \n", " | value = \n", "\n", "FUNCTIONS\n", " unique(enumeration)\n", " Class decorator for enumerations ensuring unique member values.\n", "\n", "DATA\n", " __all__ = ['EnumMeta', 'Enum', 'IntEnum', 'Flag', 'IntFlag', 'auto', '...\n", "\n", "FILE\n", " /Users/yhhan/anaconda3/envs/minimal_rl/lib/python3.9/enum.py\n", "\n", "\n" ] } ], "source": [ "import enum\n", "help(enum)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from enum import Enum\n", "\n", "class Color(Enum):\n", " red = 1\n", " blue = 2" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Color.red : 1\n" ] } ], "source": [ "a = Color.red\n", "b = Color.blue\n", "\n", "print(a, \":\", a.value)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.21\t IDLE안에서 비효율적인 print 함수 사용을 줄인다" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "- IDLE: Integrated DeveLopment Environment (통합개발환경)\n", " - Jupyter Notebook\n", " - Pycharm\n", " - Visual Studio Code" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n" ] } ], "source": [ "for i in range(20):\n", " for j in range(40):\n", " print('*', end='')\n", " print()" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n" ] } ], "source": [ "row_of_asterisks = '*' * 40\n", "for i in range(20):\n", " print(row_of_asterisks)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "\n" ] } ], "source": [ "row_of_asterisks = '*' * 40\n", "s = ''\n", "for i in range(20):\n", " s += row_of_asterisks + '\\n'\n", "print(s)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n" ] } ], "source": [ "row_of_asterisks = '*' * 40\n", "list_of_str = []\n", "for i in range(20):\n", " list_of_str.append(row_of_asterisks)\n", "print('\\n'.join(list_of_str))" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n", "****************************************\n" ] } ], "source": [ "print('\\n'.join(['*' * 40] * 20))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2.22\t 큰 번호 안에 언드스코어(_)를 넣는다" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [], "source": [ "CEO_salary = 1500000" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1500000" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "CEO_salary = 1_500_000\n", "CEO_salary" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### [추가] 레퍼런스 카운트 이해" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [], "source": [ "x = y = z = 100" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "True\n" ] } ], "source": [ "print(x is y)\n", "print(y is z)" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [], "source": [ "del x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [], "source": [ "y = 200\n", "z = 300" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.3.1 윈도 기반 시스템에서 실행하기" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "python: can't open file '/Users/yhhan/git/supercharged_python/test.py': [Errno 2] No such file or directory\r\n" ] } ], "source": [ "!python test.py" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Python 3.9.0\r\n" ] } ], "source": [ "!python -V" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.3.2 macOS 시스템에서 실행하기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.3.3 pip 혹은 pip3로 패키지 내려받기" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting package metadata (repodata.json): done\r\n", "Solving environment: done\r\n", "\r\n", "\r\n", "==> WARNING: A newer version of conda exists. <==\r\n", " current version: 4.8.0\r\n", " latest version: 4.10.3\r\n", "\r\n", "Please update conda by running\r\n", "\r\n", " $ conda update -n base -c defaults conda\r\n", "\r\n", "\r\n", "\r\n", "## Package Plan ##\r\n", "\r\n", " environment location: /Users/yhhan/anaconda3/envs/minimal_rl\r\n", "\r\n", " added / updated specs:\r\n", " - numpy\r\n", "\r\n", "\r\n", "The following packages will be downloaded:\r\n", "\r\n", " package | build\r\n", " ---------------------------|-----------------\r\n", " ca-certificates-2021.9.30 | hecd8cb5_1 123 KB\r\n", " certifi-2021.10.8 | py39hecd8cb5_0 155 KB\r\n", " numpy-1.21.2 | py39h0fa1045_0 22 KB\r\n", " numpy-base-1.21.2 | py39hbbe2e76_0 5.8 MB\r\n", " ------------------------------------------------------------\r\n", " Total: 6.1 MB\r\n", "\r\n", "The following NEW packages will be INSTALLED:\r\n", "\r\n", " blas pkgs/main/osx-64::blas-1.0-openblas\r\n", " numpy-base pkgs/main/osx-64::numpy-base-1.21.2-py39hbbe2e76_0\r\n", "\r\n", "The following packages will be UPDATED:\r\n", "\r\n", " ca-certificates 2021.7.5-hecd8cb5_1 --> 2021.9.30-hecd8cb5_1\r\n", " certifi 2021.5.30-py39hecd8cb5_0 --> 2021.10.8-py39hecd8cb5_0\r\n", "\r\n", "The following packages will be SUPERSEDED by a higher-priority channel:\r\n", "\r\n", " numpy conda-forge::numpy-1.21.2-py39h7eed0a~ --> pkgs/main::numpy-1.21.2-py39h0fa1045_0\r\n", "\r\n", "\r\n", "Proceed ([y]/n)? ^C\r\n", "\r\n", "CondaSystemExit: \r\n", "Operation aborted. Exiting.\r\n", "\r\n" ] } ], "source": [ "!conda install numpy" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: numpy in /Users/yhhan/anaconda3/envs/minimal_rl/lib/python3.9/site-packages (1.21.2)\r\n" ] } ], "source": [ "!pip install numpy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.4\tDoc Strings 작성하고 사용하기 " ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [], "source": [ "def quad(a, b, c):\n", " '''Quadratic Formula function.\n", " This function applies the Quadratic Formula\n", " to determine the roots of x in a quadratic\n", " equation of the form ax^2 + bx + c = 0.\n", " '''\n", " determin = (b * b - 4 * a * c) ** .5\n", " x1 = (-b + determin) / (2 * a)\n", " x2 = (-b - determin) / (2 * a)\n", " return x1, x2" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function quad in module __main__:\n", "\n", "quad(a, b, c)\n", " Quadratic Formula function.\n", " This function applies the Quadratic Formula\n", " to determine the roots of x in a quadratic\n", " equation of the form ax^2 + bx + c = 0.\n", "\n" ] } ], "source": [ "help(quad)" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "def quad(a, b, c):\n", " '''Quadratic Formula function.\n", "\n", "This function applies the Quadratic Formula\n", "to determine the roots of x in a quadratic\n", "equation of the form ax^2 + bx + c = 0.\n", "'''\n", "\n", " determin = (b * b - 4 * a * c) ** .5\n", " x1 = (-b + determin) / (2 * a)\n", " x2 = (-b - determin) / (2 * a)\n", " return x1, x2" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function quad in module __main__:\n", "\n", "quad(a, b, c)\n", " Quadratic Formula function.\n", " \n", " This function applies the Quadratic Formula\n", " to determine the roots of x in a quadratic\n", " equation of the form ax^2 + bx + c = 0.\n", "\n" ] } ], "source": [ "help(quad)" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "No Python documentation found for 'queens'.\r\n", "Use help() to get the interactive help utility.\r\n", "Use help(str) for help on the str class.\r\n", "\r\n" ] } ], "source": [ "!python -m pydoc queens" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.5 패키지 탑재하기" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on module math:\n", "\n", "NAME\n", " math\n", "\n", "MODULE REFERENCE\n", " https://docs.python.org/3.9/library/math\n", " \n", " The following documentation is automatically generated from the Python\n", " source files. It may be incomplete, incorrect or include features that\n", " are considered implementation detail and may vary between Python\n", " implementations. When in doubt, consult the module reference at the\n", " location listed above.\n", "\n", "DESCRIPTION\n", " This module provides access to the mathematical functions\n", " defined by the C standard.\n", "\n", "FUNCTIONS\n", " acos(x, /)\n", " Return the arc cosine (measured in radians) of x.\n", " \n", " The result is between 0 and pi.\n", " \n", " acosh(x, /)\n", " Return the inverse hyperbolic cosine of x.\n", " \n", " asin(x, /)\n", " Return the arc sine (measured in radians) of x.\n", " \n", " The result is between -pi/2 and pi/2.\n", " \n", " asinh(x, /)\n", " Return the inverse hyperbolic sine of x.\n", " \n", " atan(x, /)\n", " Return the arc tangent (measured in radians) of x.\n", " \n", " The result is between -pi/2 and pi/2.\n", " \n", " atan2(y, x, /)\n", " Return the arc tangent (measured in radians) of y/x.\n", " \n", " Unlike atan(y/x), the signs of both x and y are considered.\n", " \n", " atanh(x, /)\n", " Return the inverse hyperbolic tangent of x.\n", " \n", " ceil(x, /)\n", " Return the ceiling of x as an Integral.\n", " \n", " This is the smallest integer >= x.\n", " \n", " comb(n, k, /)\n", " Number of ways to choose k items from n items without repetition and without order.\n", " \n", " Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates\n", " to zero when k > n.\n", " \n", " Also called the binomial coefficient because it is equivalent\n", " to the coefficient of k-th term in polynomial expansion of the\n", " expression (1 + x)**n.\n", " \n", " Raises TypeError if either of the arguments are not integers.\n", " Raises ValueError if either of the arguments are negative.\n", " \n", " copysign(x, y, /)\n", " Return a float with the magnitude (absolute value) of x but the sign of y.\n", " \n", " On platforms that support signed zeros, copysign(1.0, -0.0)\n", " returns -1.0.\n", " \n", " cos(x, /)\n", " Return the cosine of x (measured in radians).\n", " \n", " cosh(x, /)\n", " Return the hyperbolic cosine of x.\n", " \n", " degrees(x, /)\n", " Convert angle x from radians to degrees.\n", " \n", " dist(p, q, /)\n", " Return the Euclidean distance between two points p and q.\n", " \n", " The points should be specified as sequences (or iterables) of\n", " coordinates. Both inputs must have the same dimension.\n", " \n", " Roughly equivalent to:\n", " sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))\n", " \n", " erf(x, /)\n", " Error function at x.\n", " \n", " erfc(x, /)\n", " Complementary error function at x.\n", " \n", " exp(x, /)\n", " Return e raised to the power of x.\n", " \n", " expm1(x, /)\n", " Return exp(x)-1.\n", " \n", " This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x.\n", " \n", " fabs(x, /)\n", " Return the absolute value of the float x.\n", " \n", " factorial(x, /)\n", " Find x!.\n", " \n", " Raise a ValueError if x is negative or non-integral.\n", " \n", " floor(x, /)\n", " Return the floor of x as an Integral.\n", " \n", " This is the largest integer <= x.\n", " \n", " fmod(x, y, /)\n", " Return fmod(x, y), according to platform C.\n", " \n", " x % y may differ.\n", " \n", " frexp(x, /)\n", " Return the mantissa and exponent of x, as pair (m, e).\n", " \n", " m is a float and e is an int, such that x = m * 2.**e.\n", " If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.\n", " \n", " fsum(seq, /)\n", " Return an accurate floating point sum of values in the iterable seq.\n", " \n", " Assumes IEEE-754 floating point arithmetic.\n", " \n", " gamma(x, /)\n", " Gamma function at x.\n", " \n", " gcd(*integers)\n", " Greatest Common Divisor.\n", " \n", " hypot(...)\n", " hypot(*coordinates) -> value\n", " \n", " Multidimensional Euclidean distance from the origin to a point.\n", " \n", " Roughly equivalent to:\n", " sqrt(sum(x**2 for x in coordinates))\n", " \n", " For a two dimensional point (x, y), gives the hypotenuse\n", " using the Pythagorean theorem: sqrt(x*x + y*y).\n", " \n", " For example, the hypotenuse of a 3/4/5 right triangle is:\n", " \n", " >>> hypot(3.0, 4.0)\n", " 5.0\n", " \n", " isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)\n", " Determine whether two floating point numbers are close in value.\n", " \n", " rel_tol\n", " maximum difference for being considered \"close\", relative to the\n", " magnitude of the input values\n", " abs_tol\n", " maximum difference for being considered \"close\", regardless of the\n", " magnitude of the input values\n", " \n", " Return True if a is close in value to b, and False otherwise.\n", " \n", " For the values to be considered close, the difference between them\n", " must be smaller than at least one of the tolerances.\n", " \n", " -inf, inf and NaN behave similarly to the IEEE 754 Standard. That\n", " is, NaN is not close to anything, even itself. inf and -inf are\n", " only close to themselves.\n", " \n", " isfinite(x, /)\n", " Return True if x is neither an infinity nor a NaN, and False otherwise.\n", " \n", " isinf(x, /)\n", " Return True if x is a positive or negative infinity, and False otherwise.\n", " \n", " isnan(x, /)\n", " Return True if x is a NaN (not a number), and False otherwise.\n", " \n", " isqrt(n, /)\n", " Return the integer part of the square root of the input.\n", " \n", " lcm(*integers)\n", " Least Common Multiple.\n", " \n", " ldexp(x, i, /)\n", " Return x * (2**i).\n", " \n", " This is essentially the inverse of frexp().\n", " \n", " lgamma(x, /)\n", " Natural logarithm of absolute value of Gamma function at x.\n", " \n", " log(...)\n", " log(x, [base=math.e])\n", " Return the logarithm of x to the given base.\n", " \n", " If the base not specified, returns the natural logarithm (base e) of x.\n", " \n", " log10(x, /)\n", " Return the base 10 logarithm of x.\n", " \n", " log1p(x, /)\n", " Return the natural logarithm of 1+x (base e).\n", " \n", " The result is computed in a way which is accurate for x near zero.\n", " \n", " log2(x, /)\n", " Return the base 2 logarithm of x.\n", " \n", " modf(x, /)\n", " Return the fractional and integer parts of x.\n", " \n", " Both results carry the sign of x and are floats.\n", " \n", " nextafter(x, y, /)\n", " Return the next floating-point value after x towards y.\n", " \n", " perm(n, k=None, /)\n", " Number of ways to choose k items from n items without repetition and with order.\n", " \n", " Evaluates to n! / (n - k)! when k <= n and evaluates\n", " to zero when k > n.\n", " \n", " If k is not specified or is None, then k defaults to n\n", " and the function returns n!.\n", " \n", " Raises TypeError if either of the arguments are not integers.\n", " Raises ValueError if either of the arguments are negative.\n", " \n", " pow(x, y, /)\n", " Return x**y (x to the power of y).\n", " \n", " prod(iterable, /, *, start=1)\n", " Calculate the product of all the elements in the input iterable.\n", " \n", " The default start value for the product is 1.\n", " \n", " When the iterable is empty, return the start value. This function is\n", " intended specifically for use with numeric values and may reject\n", " non-numeric types.\n", " \n", " radians(x, /)\n", " Convert angle x from degrees to radians.\n", " \n", " remainder(x, y, /)\n", " Difference between x and the closest integer multiple of y.\n", " \n", " Return x - n*y where n*y is the closest integer multiple of y.\n", " In the case where x is exactly halfway between two multiples of\n", " y, the nearest even value of n is used. The result is always exact.\n", " \n", " sin(x, /)\n", " Return the sine of x (measured in radians).\n", " \n", " sinh(x, /)\n", " Return the hyperbolic sine of x.\n", " \n", " sqrt(x, /)\n", " Return the square root of x.\n", " \n", " tan(x, /)\n", " Return the tangent of x (measured in radians).\n", " \n", " tanh(x, /)\n", " Return the hyperbolic tangent of x.\n", " \n", " trunc(x, /)\n", " Truncates the Real x to the nearest Integral toward 0.\n", " \n", " Uses the __trunc__ magic method.\n", " \n", " ulp(x, /)\n", " Return the value of the least significant bit of the float x.\n", "\n", "DATA\n", " e = 2.718281828459045\n", " inf = inf\n", " nan = nan\n", " pi = 3.141592653589793\n", " tau = 6.283185307179586\n", "\n", "FILE\n", " /Users/yhhan/anaconda3/envs/minimal_rl/lib/python3.9/lib-dynload/math.cpython-39-darwin.so\n", "\n", "\n" ] } ], "source": [ "import math\n", "help(math)" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.4142135623730951" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.sqrt(2)" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.141592653589793" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.atan(1) * 4" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.141592653589793" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.pi" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "- 별칭 (alias)" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.141592653589793\n" ] } ], "source": [ "from math import pi\n", "print(pi)" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.141592653589793\n", "1.4142135623730951\n" ] } ], "source": [ "from math import *\n", "print(pi)\n", "print(sqrt(2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.6 파이썬 패키지의 가이드 투어?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](./tables_skill_up/t0401-1.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](./tables_skill_up/t0401-2.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.7 일급 객체인 함수" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "- 일급 객체는 OOP에서 사용되는 개념 중 하나로 아래의 조건을 만족하는 객체를 의미함\n", "\n", " - 1. 변수 혹은 데이터 구조(자료구조) 안에 담을 수 있어야 한다.\n", " - 2. 매개변수로 전달할 수 있어야 한다.\n", " - 3. 리턴값으로 사용될 수 있어야 한다." ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "- https://tibetsandfox.tistory.com/8" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "def avg(a_list):\n", " '''리스트 항목들의 평균값을 반환한다'''\n", " x = (sum(a_list) / len(a_list))\n", " print('The average is:', x)\n", " return x" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "function" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(avg)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function avg in module __main__:\n", "\n", "avg(a_list)\n", " 리스트 항목들의 평균값을 반환한다\n", "\n" ] } ], "source": [ "help(avg)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def new_func(a_list):\n", " return (sum(a_list) / len(a_list))\n", "\n", "old_avg = avg\n", "avg = new_func" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The average is: 5.0\n" ] }, { "data": { "text/plain": [ "5.0" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "old_avg([4, 6])" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "def func_info(func):\n", " print('Function name:', func.__name__)\n", " print('Function documentation:')\n", " help(func)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Function name: avg\n", "Function documentation:\n", "Help on function avg in module __main__:\n", "\n", "avg(a_list)\n", " 리스트 항목들의 평균값을 반환한다\n", "\n" ] } ], "source": [ "func_info(old_avg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.8\t 가변길이 매개변수\n", "\n", "### 4.8.1\t *args 리스트" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The number of args is 4\n", "The type of args is \n", "10\n", "20\n", "30\n", "40\n" ] } ], "source": [ "def my_var_func(*args):\n", " print('The number of args is', len(args))\n", " print('The type of args is', type(args))\n", " for item in args:\n", " print(item)\n", "\n", "my_var_func(10, 20, 30, 40)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "22.0" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def avg(*args):\n", " return sum(args)/len(args)\n", "\n", "avg(11, 22, 33)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.5" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "avg(1, 2)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "22.0 inches\n" ] } ], "source": [ "def avg(units, *args):\n", " print (sum(args)/len(args), units)\n", "\n", "avg('inches', 11, 22, 33)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3\n" ] } ], "source": [ "ls = [1, 2, 3] # 언팩된 리스트\n", "print(*ls) # 언팩 버전 출력하기" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3]\n" ] } ], "source": [ "print(ls) # 패킹된 버전 출력하기 (일반 리스트)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.8.2\t **kwargs 리스트" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10,20,30." ] } ], "source": [ "print(10, 20, 30, end='.', sep=',')" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "def pr_named_vals(**kwargs):\n", " print(\"The length of kwargs is\", len(kwargs))\n", " print(\"The type of kwargs is\", type(kwargs))\n", " for k in kwargs:\n", " print(k, ':', kwargs[k])" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The length of kwargs is 3\n", "The type of kwargs is \n", "a : 10\n", "b : 20\n", "c : 30\n" ] } ], "source": [ "pr_named_vals(a=10, b=20, c=30)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "def pr_vals_2(*args, **kwargs):\n", "\n", " for i in args:\n", " print(i)\n", "\n", " for k in kwargs:\n", " print(k, ':', kwargs[k])" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n", "-4\n", "a : 100\n", "b : 200\n" ] } ], "source": [ "pr_vals_2(1, 2, 3, -4, a=100, b=200)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.9\t 데코레이터(Decorator)와 함수 프로파일러(Profiler)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "- 데코레이터: 기존 함수가 그대로 동작하면서 추가 문장이 더 실행되는 래퍼 함수(Wrapper Function)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](./images_skill_up/4-3.PNG)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "- 인수처리를 못하는 래퍼 함수 만들기" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [], "source": [ "import time\n", "\n", "def make_timer_wrapper(func):\n", " def wrapper():\n", " t1 = time.time()\n", " ret_val = func()\n", " t2 = time.time()\n", " print('소요 시간 :', t2 - t1)\n", " return ret_val\n", " return wrapper" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "def count_nums():\n", " s = 0\n", " for i in range(10):\n", " for j in range(1000):\n", " s += i * j\n", " return s" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "count_nums = make_timer_wrapper(count_nums)" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "소요 시간 : 0.0006380081176757812\n" ] }, { "data": { "text/plain": [ "22477500" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "count_nums()" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "- 인수처리 가능한 래퍼 함수 만들기" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "import time\n", "\n", "def make_timer_wrapper(func):\n", " def wrapper(*args, **kwargs):\n", " t1 = time.time()\n", " ret_val = func(*args, **kwargs)\n", " t2 = time.time()\n", " print('소요 시간 :', t2 - t1)\n", " return ret_val\n", " return wrapper" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [], "source": [ "def count_nums(n):\n", " s = 0\n", " for i in range(n):\n", " for j in range(1000):\n", " s += i * j\n", " return s" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "count_nums = make_timer_wrapper(count_nums)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "소요 시간 : 0.0006289482116699219\n" ] }, { "data": { "text/plain": [ "22477500" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "count_nums(10)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "- 데코레이터로 위 복잡한 과정을 편리하게 만들기" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "@make_timer_wrapper\n", "def count_nums(n):\n", " s = 0\n", " for i in range(n):\n", " for j in range(1000):\n", " s += i * j\n", " return s" ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "소요 시간 : 0.000682830810546875\n" ] }, { "data": { "text/plain": [ "22477500" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "count_nums(10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 다른 예제" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Start test\n", "Variables : 1 2 345\n", "End test\n" ] } ], "source": [ "def decoratorExample(func):\n", " def wrapFunc(*args, **kargs):\n", " print(\"Start\", func.__name__)\n", " func(*args, **kargs)\n", " print(\"End\", func.__name__)\n", " return wrapFunc\n", "\n", "@decoratorExample\n", "def test(a, b, c):\n", " print(\"Variables :\", a,b,c)\n", "\n", "test(\"1\", 2, c=\"345\")" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "def smart_divide(func):\n", " def inner(a, b):\n", " print(\"I am going to divide\", a, \"and\", b)\n", " if b == 0:\n", " print(\"Whoops! cannot divide\")\n", " return\n", "\n", " return func(a, b)\n", " return inner\n", "\n", "\n", "@smart_divide\n", "def divide(a, b):\n", " print(a / b)" ] }, { "cell_type": "code", "execution_count": 68, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I am going to divide 2 and 5\n", "0.4\n" ] } ], "source": [ "divide(2, 5)" ] }, { "cell_type": "code", "execution_count": 69, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I am going to divide 2 and 0\n", "Whoops! cannot divide\n" ] } ], "source": [ "divide(2, 0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.10\t 제너레이터\n", "\n", "### 4.10.1\t 이터레이터란 무엇인가?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 이터레이터 객체 정의\n", " - 가상의 Sequence 자료를 지니고 있으면서 내부적으로 \\_\\_next\\_\\_(self) 메직 메소드를 지니고 있는 객체\n", " - 내부적으로 지닌 Sequence 자료를 차례로 반환 \n", " - next() 내장 함수에 대응됨 \n", " - next() 내장 함수 호출할 때 마다 각 원소 반환\n", " - next() 내장 함수 호출할 때 더 이상 자료를 념겨줄 수 없다면 StopIteration 예외 발생\n", " - 이터레이터 객체의 메모리 효율성\n", " - 반복자가 원 객체의 원소들을 복사하여 지니고 있지 않음.\n", " - 메모리 효율성!\n", " \n", "- 임의의 객체에 대해 반복자 객체를 얻어오는 방법\n", " - iter(o) 내장 함수\n", " - 객체 o의 반복자 객체를 반환한다.\n", "\n", "- 집합적 객체 A --> iter(A) --> 반복자 객체 B 반환 --> next(B) --> 집합적 자료형 안의 내부 원소를 하나씩 반환\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "I = iter([1, 2, 3])\n", "print(I)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n" ] }, { "ename": "StopIteration", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mI\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 3\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mI\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----> 4\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mI\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\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mStopIteration\u001b[0m: " ] } ], "source": [ "print(next(I))\n", "print(next(I))\n", "print(next(I))\n", "print(next(I))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 리스트 객체에 반복자와 StopIteration 예외를 동시에 활용한 예" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "3\n", "4\n" ] } ], "source": [ "def f(x):\n", " print(x + 1)\n", "\n", "t = iter([1, 2, 3])\n", "while True:\n", " try:\n", " x = next(t)\n", " except StopIteration:\n", " break\n", " f(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 리스트 객체에 대해 일반적인 for ~ in 반복 문 사용예\n", " - for 문이 반복할 때 마다 이터레이터 객체에 next() 내장 함수가 자동으로 호출되어 순차적으로 각 객체에 접근\n", " - StopIteration이 발생하면 for ~ in 구문 자동 정지" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "3\n", "4\n" ] } ], "source": [ "def f(x):\n", " print(x + 1)\n", "\n", "for x in [1, 2, 3]:\n", " f(x)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "iter1 = reversed([1, 2, 3, 4])\n", "print(iter1)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[4, 3, 2, 1]\n" ] } ], "source": [ "print(list(iter1))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4 3 2 1 " ] } ], "source": [ "iter1 = reversed([1, 2, 3, 4])\n", "for i in iter1:\n", " print(i, end=' ')" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "3\n", "4\n" ] } ], "source": [ "def f(x):\n", " print(x + 1)\n", "\n", "t = iter([1, 2, 3])\n", "for x in t:\n", " f(x)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "3\n", "4\n" ] } ], "source": [ "def f(x):\n", " print(x + 1)\n", "\n", "for x in iter([1, 2, 3]):\n", " f(x)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "3\n", "4\n" ] } ], "source": [ "def f(x):\n", " print(x + 1)\n", "\n", "for x in iter((1, 2, 3)):\n", " f(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 사전의 반복자\n", " - 사전에 대해 for ~ in 구문은 키에 대해 반복한다.\n", " - iter(d) 또는 iter(d.keys()) 사용" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one 1\n", "two 2\n", "three 3\n", "four 4\n", "five 5\n" ] } ], "source": [ "d = {'one':1, 'two':2, 'three':3, 'four':4, 'five':5}\n", "\n", "for key in d:\n", " print(key, d[key])" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one 1\n", "two 2\n", "three 3\n", "four 4\n", "five 5\n" ] } ], "source": [ "d = {'one':1, 'two':2, 'three':3, 'four':4, 'five':5}\n", "\n", "for key in iter(d):\n", " print(key, d[key])" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n" ] } ], "source": [ "print(type(d.keys()))\n", "print(type(iter(d.keys())))" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'dict_keys' object is not an iterator", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\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[0m\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mTypeError\u001b[0m: 'dict_keys' object is not an iterator" ] } ], "source": [ "next(d.keys())" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'one'" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(iter(d.keys()))" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one two three four five \n", "one two three four five " ] } ], "source": [ "for key in d.keys(): # 키에 대한 반복자, iter(d.keys()) 가 반환한 반복자에 대해 __next__(self) 함수가 순차적으로 불리워짐\n", " print(key, end=\" \")\n", "\n", "print()\n", "\n", "for key in iter(d.keys()): # 키에 대한 반복자, iter(d.keys()) 가 반환한 반복자에 대해 __next__(self) 함수가 순차적으로 불리워짐\n", " print(key, end=\" \")" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one\n", "two three four five " ] } ], "source": [ "keyset = iter(d)\n", "\n", "print(next(keyset)) # 반복자 객체는 항상 next() 내장 함수에 값을 반환할 수 있음 (내부적으로 __next__(self) 호출)\n", "\n", "for key in keyset: # keyset 반복자에 대해 next() 메소드가 순차적으로 호출됨\n", " print(key, end=\" \")" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n" ] } ], "source": [ "print(type(d.values()))\n", "print(type(iter(d.values())))" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3 4 5 \n", "1 2 3 4 5 " ] } ], "source": [ "for key in d.values(): # 키에 대한 반복자, iter(d.keys()) 가 반환한 반복자에 대해 __next__(self) 함수가 순차적으로 불리워짐\n", " print(key, end=\" \")\n", "\n", "print()\n", "\n", "for key in iter(d.values()): # 키에 대한 반복자, iter(d.keys()) 가 반환한 반복자에 대해 __next__(self) 함수가 순차적으로 불리워짐\n", " print(key, end=\" \")" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n" ] } ], "source": [ "print(type(d.items()))\n", "print(type(iter(d.items())))" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one 1 two 2 three 3 four 4 five 5 \n", "one 1 two 2 three 3 four 4 five 5 " ] } ], "source": [ "for key, value in d.items():\n", " print(key, value, end=\" \")\n", "\n", "print()\n", "\n", "for key, value in iter(d.items()):\n", " print(key, value, end=\" \")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 파일 객체의 반복자\n", " - 파일 객체는 그 자체가 반복자임\n", " - next() 함수에 의해 각 라인이 순차적으로 읽혀짐" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "abc\n", "\n", "def\n", "\n", "ghi\n" ] } ], "source": [ "f = open('readme.txt')\n", "\n", "print(next(f))\n", "\n", "for line in f: # f.next() 가 순차적으로 호출됨\n", " print(line) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.10.2\t제너레이터 소개" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "- 아래 함수 f()는 자신의 인수 및 내부 로컬 변수로서 a, b, c, d를 지니고 있다.\n", " - 이러한 a, b, c, d 변수들은 함수가 종료되고 반환될 때 모두 사라진다.\n", "- 발생자는 f()와 같이 함수가 (임시로) 종료될 때 내부 로컬 변수가 메모리에서 해제되는 것을 막고 다시 함수가 호출 될 때 이전에 수행이 종료되었던 지점 부터 계속 수행이 가능하도록 구현된 함수이다." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 3\n" ] } ], "source": [ "def f(a, b):\n", " c = a * b\n", " d = a + b\n", " return c, d\n", "\n", "x, y = f(1, 2)\n", "print(x, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 발생자(Generator)\n", "- (중단됨 시점부터) 재실행 가능한 함수" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](./images_skill_up/4-4.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- yield 키워드\n", " - return 대신에 yield에 의해 값을 반환하는 함수는 발생자이다.\n", " - yield는 return과 유사하게 임의의 값을 반환하지만 함수의 실행 상태를 보존하면서 함수를 호출한 쪽으로 복귀시켜준다.\n", "\n", "- 발생자는 곧 반복자이다!!!\n", " - 즉, 발생자에게 next() 호출이 가능하다." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 3\n" ] }, { "ename": "StopIteration", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mg\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 13\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mStopIteration\u001b[0m: " ] } ], "source": [ "def f(a, b):\n", " c = a * b\n", " d = a + b\n", " yield c, d\n", "\n", "g = f(1, 2)\n", "\n", "x, y = next(g)\n", "print(x, y)\n", "\n", "x, y = next(g)\n", "print(x, y)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def f(a, b):\n", " for _ in range(2):\n", " c = a * b\n", " d = a + b\n", " yield c, d\n", "\n", "g = f(1, 2)\n", "\n", "x, y = next(g)\n", "print(x, y)\n", "\n", "x, y = next(g)\n", "print(x, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 발생자 함수와 일반 함수의 차이점\n", " - 일반 함수는 함수가 호출되면 그 함수 내부에 정의된 모든 일을 마치고 결과를 반환함\n", " - 발생자 함수는 함수 내에서 수행 중에 중간 결과 값을 반환할 수 있음\n", "\n", "- 발생자가 유용하게 사용되는 경우\n", " - 함수 처리의 중간 결과를 다른 코드에서 사용해야 할 경우\n", " - 즉, 모든 결과를 한꺼번에 반환 받는 것이 아니라 함수 처리 중에 나온 중간 결과를 받아서 사용해야 할 경우\n", " - 시퀀스 자료형을 효율적으로 만들고자 하는 경우" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "4\n", "6\n", "8\n", "10\n" ] } ], "source": [ "def print_evens():\n", " for n in range(2, 11, 2):\n", " print(n)\n", " \n", "print_evens()" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "def make_evens_gen():\n", " for n in range(2, 11, 2):\n", " yield n\n", "\n", "my_gen = make_evens_gen()" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(my_gen)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(my_gen)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(my_gen)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_gen = make_evens_gen() # 다시 시작\n", "next(my_gen)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(my_gen)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(my_gen)" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [], "source": [ "my_gen = make_evens_gen() # 다시 시작" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(my_gen)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(my_gen)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(my_gen)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(make_evens_gen())" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(make_evens_gen())" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(make_evens_gen())" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 4 6 8 10 " ] } ], "source": [ "for i in make_evens_gen():\n", " print(i, end=' ')\n" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 4 6 8 10 " ] } ], "source": [ "my_gen = make_evens_gen()\n", "for i in my_gen:\n", " print(i, end=' ')" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 4, 6, 8, 10]" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_gen = make_evens_gen()\n", "a_list = list(my_gen)\n", "a_list" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a_list = list(my_gen) \t# 앗! 다시 초기화(reset)를 안했군!\n", "a_list" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 4, 6, 8, 10]" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a_list = list(make_evens_gen())\n", "a_list" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [], "source": [ "def make_fibo_gen(n):\n", " a, b = 1, 1\n", " while a <= n:\n", " yield a\n", " a, b = a + b, a" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "[1, 2, 3, 5, 8]\n" ] } ], "source": [ "my_fibo_gen = make_fibo_gen(10)\n", "print(my_fibo_gen)\n", "print(list(my_fibo_gen))" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "number is not a Fibonacci. \n" ] } ], "source": [ "n = int(input('Enter number: '))\n", "if n in make_fibo_gen(n):\n", " print('number is a Fibonacci. ')\n", "else:\n", " print('number is not a Fibonacci. ')" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "number is a Fibonacci. \n" ] } ], "source": [ "n = int(input('Enter number: '))\n", "my_fibo_gen = make_fibo_gen(n)\n", "if n in my_fibo_gen:\n", " print('number is a Fibonacci. ')\n", "else:\n", " print('number is not a Fibonacci. ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 제너레이터의 활용" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [], "source": [ "def generate_ints(N):\n", " for i in range(N):\n", " yield i" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "0\n", "1\n", "2\n" ] }, { "ename": "StopIteration", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgen\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# 발생자 실행 재개. yield에 의해 값 반환 후 다시 중단\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgen\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# 발생자 실행 재개. yield에 의해 값 반환 후 다시 중단\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 13\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgen\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# 발생자 실행 재개. yield에 의해 더 이상 반환할 값이 없다면 StopIteration 예외를 던짐\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 14\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mStopIteration\u001b[0m: " ] } ], "source": [ "gen = generate_ints(3) # 발생자 객체를 얻는다. generate_ints() 함수에 대한 초기 스택 프레임이 만들어지나 실행은 중단되어 있는 상태임\n", "print(gen)\n", "\n", "# print(gen.next()) \n", "# print(gen.next()) \n", "# print(gen.next()) \n", "# print(gen.next()) \n", "\n", "print(next(gen)) # 발생자 객체는 반복자 인터페이스를 가진다. 발생자의 실행이 시작됨. yield에 의해 값 반환 후 실행이 중단됨\n", "print(next(gen)) # 발생자 실행 재개. yield에 의해 값 반환 후 다시 중단\n", "print(next(gen)) # 발생자 실행 재개. yield에 의해 값 반환 후 다시 중단\n", "print(next(gen)) # 발생자 실행 재개. yield에 의해 더 이상 반환할 값이 없다면 StopIteration 예외를 던짐" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 위와 같은 세부 동작 방식을 이용하여, 다음과 같이 for ~ in 구문에 적용할 수 있다." ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 2 3 4 " ] } ], "source": [ "for i in generate_ints(5):\n", " print(i, end=\" \")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 리스트 내포 vs. 발생자\n", " - 리스트 내포는 리스트 객체의 새로운 생성. 즉, 메모리를 실제로 점유하면서 생성됨" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]\n" ] }, { "data": { "text/plain": [ "list" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = [k for k in range(100) if k % 5 == 0]\n", "print(a)\n", "type(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 리스트 내포 구문에 []가 아니라 () 사용\n", " - 리스트 대신에 발생자 생성\n", " - 즉, 처음부터 모든 원소가 생성되지 않고 필요한 시점에 각 원소가 만들어짐\n", " - 메모리를 보다 효율적으로 사용할 수 있음" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " at 0x7f9ac8c15a98>\n" ] }, { "data": { "text/plain": [ "generator" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = (k for k in range(100) if k % 5 == 0)\n", "print(a)\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "5\n", "10\n", "15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 " ] } ], "source": [ "print(next(a))\n", "print(next(a))\n", "print(next(a))\n", "for i in a:\n", " print(i, end=\" \")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 아래 예는 sum 내장 함수에 발생자를 넣어줌\n", " - sum을 호출하는 시점에는 발생자가 아직 호출되기 직전이므로 각 원소들은 아직 존재하지 않는다.\n", " - sum 내부에서 발생자가 지니고 있는 next() 함수를 호출하여 각 원소들을 직접 만들어 활용한다.\n", " - 메모시 사용 효율이 높다." ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "950\n" ] } ], "source": [ "a = (k for k in range(100) if k % 5 == 0)\n", "print(sum(a))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 발생자의 실제 활용 예 1 - 피보나치 수열" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 1 2 3 5 8 13 21 34 55 89 " ] } ], "source": [ "def fibonacci(a = 1, b = 1):\n", " while 1:\n", " yield a\n", " a, b = b, a + b\n", " \n", "for k in fibonacci(): # 발생자를 직접 for ~ in 구문에 활용\n", " if k > 100: \n", " break\n", " print(k, end=\" \")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 발생자의 활용 예 2 - 홀수 집합 만들기" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 \n", "3 \n", "5 \n", "7 \n", "9 \n", "11 \n", "13 \n", "15 \n", "17 \n", "19 \n", "[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]\n" ] } ], "source": [ "def odds(limit=None):\n", " k = 1\n", " while not limit or limit >= k:\n", " yield k\n", " k += 2\n", " \n", "for k in odds(20):\n", " print(k, end=\" \")\n", "\n", " print()\n", "\n", "print(list(odds(20))) # list() 내장 함수가 발생자를 인수로 받으면 해당 발생자의 next()를 매번 호출하여 각 원소를 얻어온다. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.11\t 커맨드-라인 인수 접근하기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](./images_skill_up/4-5.PNG)" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [], "source": [ "import sys" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/Users/yhhan/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py||||-f||||/Users/yhhan/Library/Jupyter/runtime/kernel-47b361ac-2964-463e-afaf-ef9133d4ae86.json||||" ] } ], "source": [ "import sys\n", "for thing in sys.argv:\n", " print(thing, end='||||')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### [추가 내용] copy()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- D.copy()는 Shallow Copy를 수행한다." ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'a': [1, 2, 3], 'b': 4}\n", "{'a': [1, 2, 3], 'b': 4}\n", "\n", "{'a': [1, 2, 3], 'b': 100}\n", "{'a': [1, 2, 3], 'b': 4}\n", "\n", "{'a': [100, 2, 3], 'b': 100}\n", "{'a': [100, 2, 3], 'b': 4}\n" ] } ], "source": [ "phone = {'a': [1,2,3], 'b': 4}\n", "phone2 = phone.copy()\n", "print(phone)\n", "print(phone2)\n", "print()\n", "\n", "phone['b'] = 100\n", "print(phone)\n", "print(phone2)\n", "print()\n", "\n", "phone['a'][0] = 100\n", "print(phone)\n", "print(phone2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.8" } }, "nbformat": 4, "nbformat_minor": 4 }