{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# [X-Village] Lesson03 - Class\n", "---\n", "speaker: amber(吳思嬋)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 有系統內建函式(ex. print),我們可以使用 keyword def 來建立自定義的函式。\n", "\n", "## 同理,有系統內建的type(ex. number, string, ...),我們也可以使用某一個keyword 來建立我們自定義的type。" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 使用 keyword class 就能建立自己的 type object,將這個type object 指派給我們我們自由定義的名字(Name)\n", "---\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 在 class 的內部 assign name, name 為變數(variable) 或 函式(def statement)\n", "---\n", "* class 的變數(variable) 我們稱為屬性(attribute)\n", "* class 的變數 函式(function),我們稱為方法(method)\n", "* 當 class object 建立時,class object 擁有自己的scope, 存放 attribute 和 method\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Instance Objects (實例物件)\n", "* 當我們使用 class object 的時候,就會產生 instance object\n", "* 產生 instance object 時,instance object 會擁有自己的 local scope。\n", "* 產生 instance object 時,它會繼承 class object 的 attribute(屬性) 與 method(方法),位於 instance object 的 local scope" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### 建立 instance object (實例物件) 時,instance object 就擁有自己獨立的scope 和 繼承 class的 attribute 與 method,attribute 與 method 屬於 instance object 的 local scope。\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### 在instance object 中,assign attribute 或 reassgin attribute 都不會影響原本的 class object\n", "" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is my own attribute\n" ] } ], "source": [ "class Animal:\n", " name = 'default_name'\n", " age = 'default_age'\n", " \n", "my_pet = Animal() # Make instances object\n", "my_pet.name = 'dog'\n", "my_pet.age = '7'\n", "\n", "my_pet.new = 'This is my own attribute'\n", "print(my_pet.new)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 在 class 中可以使用 keyword def 來產生 function,我們稱為method。\n", "## Method 宣告時的第一個 argument 非常重要!!!一定要寫。 代表 instance object 可以取用 attribute。\n", "---\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 使用 instance.method 的表達時,可以呼叫 method" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "球體體積 523.3333333333334\n", "球體表面積 314.0\n" ] } ], "source": [ "class Ball: \n", " def set_radius(self, radius_arg):\n", " self.radius = radius_arg\n", " \n", " def calculate_volume(self): # 計算球體體積\n", " volume = 4/3 * 3.14 * (self.radius*self.radius*self.radius)\n", " return volume\n", "\n", " def calculate_surface_area(self): # 計算球體表面積\n", " self.surface_area = 4 * 3.14 * (self.radius*self.radius)\n", " \n", "x = Ball() # 建立 instance object\n", "x.set_radius(5)\n", "\n", "volume = x.calculate_volume() # 呼叫計算體積method\n", "print('球體體積', volume) # \n", "\n", "x.calculate_surface_area() # 呼叫計算表面積method\n", "print('球體表面積', x.surface_area) " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Recap Scope - 當我們 assign name 的時候,name所在的位置就決定了它的scope\n", "---\n", "* 在 function 中 assign name,name 屬於 function 的 local scope\n", "* 在 function 外 assign name,name 屬於 global scope" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "## class object 和 instance object 的 Scope\n", "---\n", "* class object 建立的時候,擁有自己的 scope,存放attribute 和 method\n", "* instance object 建立的時候,也擁有自己的scope,存放attribute 和 method" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 課堂練習 - 判斷 name 所屬的 scope (不列入課堂成績)\n", "---\n", "1. 請根據我們教的 scope 概念,圈出 global scope 和 local scope \n", "2. 請判斷下列的name 所屬的 scope,若為 local scope, 則需列出是誰的local scope 。\n", " * Ball, set_radius, calculate_volume, calculate_surface_area, radius_arg, volume1, volume2, x ,\n", " * 屬性 color, radius, surface_area" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "球體體積 523.3333333333334\n", "球體表面積 314.0\n" ] } ], "source": [ "class Ball: \n", " color = 'BLACK'\n", " def set_radius(self, radius_arg):\n", " self.radius = radius_arg\n", " \n", " def calculate_volume(self): # 計算球體體積\n", " volume1 = 4/3 * 3.14 * (self.radius*self.radius*self.radius)\n", " return volume1\n", "\n", " def calculate_surface_area(self): # 計算球體表面積\n", " self.surface_area = 4 * 3.14 * (self.radius*self.radius)\n", " \n", "x = Ball() # 建立 instance object\n", "x.set_radius(5)\n", "\n", "volume2 = x.calculate_volume() # 呼叫計算體積method\n", "print('球體體積', volume) # \n", "\n", "x.calculate_surface_area() # 呼叫計算表面積method\n", "print('球體表面積', x.surface_area) " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 課堂練習1 - 判斷 name 所屬的 scope (列入課堂成績)\n", "---\n", "1. 請根據我們教的 scope 概念,圈出 global scope 和 local scope,判斷 name 的 scope。 \n", "2. 請找助教講解下列程式的流程,以及每一個name所屬的scope及其緣由(為什麼會print出這樣的結果)。" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Name: Keven result: 過輕\n" ] } ], "source": [ "class BMI: \n", " name = 'default_name' \n", " def set_name(self, name_arg):\n", " self.name = name_arg\n", " name = 'John'\n", " \n", " def judge(self, height, weight):\n", " calculate = weight / (height*height)\n", " if calculate < 18.5:\n", " self.result = '過輕'\n", " elif 18.5 < calculate and calculate < 24:\n", " self.result = '正常'\n", " else:\n", " self.result ='過重'\n", " def display(self): # 展示結果\n", " print('Name:', self.name, 'result:',self.result)\n", " \n", "man = BMI()\n", "man.set_name('Keven')\n", "man.judge(1.82, 50)\n", "man.display()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 課堂練習2 - 建立 class Life(列入課堂成績)\n", "* 程式要求:\n", " * 需使用 list 儲存nxn地圖 \n", " * 2x2 map:\n", " [[*, *],\n", " [*, *]]\n", " * 建立 set_map method,傳入參數 n, 建立 nxn 地圖\n", " * 建立 set_pattern method, 傳入參數 p, 如果 p=1, 在 nxn 地圖中的中央設置 Glider圖案(如下列範例)\n", " * 建立 display method,展示地圖\n", " * 可以自由建立任何你需要的 attribute, method\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "* 範例\n", " * my_map = Map() #建立 instance object\n", " * my_map.set_map(5) # n=5, 代表地圖為 5x5 大小\n", " * my_map.display() #印出 5x5 地圖\n", "\n", " * my_map.set_pattern(1) # p=1, 設置 Glider 圖案在地圖中央\n", " * my_map.display() # 展示有 Glider 圖案的地圖\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "* 範例(接續)\n", " * my_map.set_map(7) # n=7, 代表地圖為 7x7 大小。\n", " * my_map.display() #印出 7x7 地圖\n", "\n", "\n", " * my_map.set_pattern(1) # p=1, 設置 Glider 圖案在地圖中央\n", " * my_map.display() # 展示有 Glider 圖案的地圖\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Constructors Method: _init_\n", "----\n", "* **語法: init前後都需要雙底線 **,init的名字不能更改,一定要叫做init。\n", "* 如果我們有設置 _init_ method,當 instance object 被建立的時候,就會自動執行。\n", "* 因此,我們常透過 _init_ method 來做初始化的動作。" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "![](https://i.imgur.com/jAbemHW.png)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "John 35\n" ] } ], "source": [ "# __init__ is run when a new instance object is created\n", "class People:\n", " def __init__(self, name, age):\n", " self.name = name\n", " self.age = age\n", " \n", "x = People('John', '35')\n", "print(x.name, x.age)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## 課堂練習3 - 建立 class Life(列入課堂成績)\n", "* 程式要求:\n", " * 需使用 list 儲存nxn地圖 \n", " * 2x2 map:\n", " [[*, *],\n", " [*, *]]\n", " * 建立 _init_ method,傳入參數 n, p, 初始化 nxn 地圖。如果 p=1, 在 nxn 地圖中的中央設置 Glider圖案(如下列範例)\n", " * 建立 display method,展示地圖\n", " * 可以自由建立任何你需要的 attribute, method" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "* 範例\n", " * my_map = Map(5, 1) #建立 instance object\n", " * my_map.display() #印出有 Glider 圖案的 5x5 地圖\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## [X-Village Python Programming - 作業1](https://github.com/x-village/X-Village-Homework1)(列入作業成績)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## [X-Village Python Programming - 自我挑戰題](https://hackmd.io/Oy66r5PkSNC7xoHbhZkwug)(不列入作業和課堂成績)" ] } ], "metadata": { "celltoolbar": "Slideshow", "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.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }