{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Chapter 19 Introduction to Classes\n",
    "<img align=\"left\" src=\"https://i.imgur.com/lnc0qMV.png\" />"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I'm a yellow lemon and I taste sour.\n",
      "Yep! I'm edible.\n"
     ]
    }
   ],
   "source": [
    "# 01 왜 클래스(Class)를 사용하나요?\n",
    "\n",
    "class Fruit(object):\n",
    "    \"\"\"A class that makes various tasty fruits.\"\"\"\n",
    "    def __init__(self, name, color, flavor, poisonous):\n",
    "        self.name = name\n",
    "        self.color = color\n",
    "        self.flavor = flavor\n",
    "        self.poisonous = poisonous\n",
    "\n",
    "    def description(self):\n",
    "        print (\"I'm a %s %s and I taste %s.\" % (self.color, self.name, self.flavor))\n",
    "    \n",
    "    def is_edible(self):\n",
    "        if not self.poisonous:\n",
    "            print (\"Yep! I'm edible.\")\n",
    "        else:\n",
    "            print (\"Don't eat me! I am super poisonous.\")\n",
    "\n",
    "lemon = Fruit(\"lemon\", \"yellow\", \"sour\", False)\n",
    "\n",
    "lemon.description()\n",
    "lemon.is_edible()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# 02 클래스(Classes) 문법\n",
    "\n",
    "class Animal(object):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# 03 클래스(Classes)다운 클래스\n",
    "\n",
    "class Animal(object):\n",
    "    def __init__(self):\n",
    "        pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# 04 두 번째 매개변수 추가하기\n",
    "\n",
    "class Animal(object):\n",
    "    def __init__(self, name):\n",
    "        self.name = name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Jeffrey\n"
     ]
    }
   ],
   "source": [
    "# 05 첫번째 객체(Object) 인스턴스화\n",
    "\n",
    "class Animal(object):\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "\n",
    "zebra = Animal(\"Jeffrey\")\n",
    "print (zebra.name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Jeffrey 2 True\n",
      "Bruce 1 False\n",
      "Chad 7 True\n"
     ]
    }
   ],
   "source": [
    "# 06 함수 __init__()과 self 더 알아보기\n",
    "\n",
    "# Class definition\n",
    "class Animal(object):\n",
    "    \"\"\"Makes cute animals.\"\"\"\n",
    "    # For initializing our instance objects\n",
    "    def __init__(self, name, age, is_hungry):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "        self.is_hungry = is_hungry\n",
    "\n",
    "# Note that self is only used in the __init__()\n",
    "# function definition; we don't need to pass it\n",
    "# to our instance objects.\n",
    "\n",
    "zebra = Animal(\"Jeffrey\", 2, True)\n",
    "giraffe = Animal(\"Bruce\", 1, False)\n",
    "panda = Animal(\"Chad\", 7, True)\n",
    "\n",
    "print (zebra.name, zebra.age, zebra.is_hungry)\n",
    "print (giraffe.name, giraffe.age, giraffe.is_hungry)\n",
    "print (panda.name, panda.age, panda.is_hungry)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Jeffrey 2 True\n",
      "Bruce 1 True\n",
      "Chad 7 True\n"
     ]
    }
   ],
   "source": [
    "# 07 클래스 범위(Class Scope)\n",
    "\n",
    "class Animal(object):\n",
    "    \"\"\"Makes cute animals.\"\"\"\n",
    "    is_alive = True\n",
    "    def __init__(self, name, age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "\n",
    "zebra = Animal(\"Jeffrey\", 2)\n",
    "giraffe = Animal(\"Bruce\", 1)\n",
    "panda = Animal(\"Chad\", 7)\n",
    "\n",
    "print (zebra.name, zebra.age, zebra.is_alive)\n",
    "print (giraffe.name, giraffe.age, giraffe.is_alive)\n",
    "print (panda.name, panda.age, panda.is_alive)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "fanfank\n",
      "22\n"
     ]
    }
   ],
   "source": [
    "# 08 메소드(method)\n",
    "\n",
    "class Animal(object):\n",
    "    \"\"\"Makes cute animals.\"\"\"\n",
    "    is_alive = True\n",
    "    def __init__(self, name, age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "        # Add your method here!\n",
    "    def description(self):\n",
    "        print (self.name)\n",
    "        print (self.age)\n",
    "\n",
    "hippo = Animal(\"fanfank\", 22)\n",
    "hippo.description()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "good\n",
      "good\n",
      "good\n"
     ]
    }
   ],
   "source": [
    "# 09 멤버 변수(member variables) 추가하기\n",
    "\n",
    "class Animal(object):\n",
    "    \"\"\"Makes cute animals.\"\"\"\n",
    "    is_alive = True\n",
    "    health = \"good\"\n",
    "    def __init__(self, name, age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "    # Add your method here!\n",
    "    def description(self):\n",
    "        print (self.name)\n",
    "        print (self.age)\n",
    "\n",
    "hippo = Animal(\"CHN\", 5000)\n",
    "sloth = Animal(\"JPN\", 3000)\n",
    "ocelot = Animal(\"USA\", 300)\n",
    "\n",
    "print (hippo.health)\n",
    "print (sloth.health)\n",
    "print (ocelot.health)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BaiduTieba added.\n",
      "BaiduTieba removed.\n"
     ]
    }
   ],
   "source": [
    "# 10 보다 현실적인 클래스와 객체\n",
    "\n",
    "class ShoppingCart(object):\n",
    "    \"\"\"Creates shopping cart objects\n",
    "        for users of our fine website.\"\"\"\n",
    "    items_in_cart = {}\n",
    "    def __init__(self, customer_name):\n",
    "        self.customer_name = customer_name\n",
    "    \n",
    "    def add_item(self, product, price):\n",
    "        \"\"\"Add product to the cart.\"\"\"\n",
    "        if not product in self.items_in_cart:\n",
    "            self.items_in_cart[product] = price\n",
    "            print (product + \" added.\")\n",
    "        else:\n",
    "            print (product + \" is already in the cart.\")\n",
    "    \n",
    "    def remove_item(self, product):\n",
    "        \"\"\"Remove product from the cart.\"\"\"\n",
    "        if product in self.items_in_cart:\n",
    "            del self.items_in_cart[product]\n",
    "            print (product + \" removed.\")\n",
    "        else:\n",
    "            print (product + \" is not in the cart.\")\n",
    "\n",
    "#\n",
    "my_cart = ShoppingCart(\"fanfank\")\n",
    "my_cart.add_item(\"BaiduTieba\", 1)\n",
    "my_cart.remove_item(\"BaiduTieba\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I'm a string that stands in for the contents of your shopping cart!\n",
      "I'm a string that stands in for your order history!\n"
     ]
    }
   ],
   "source": [
    "# 11 경고: 상속(Inheritance)의 주의 사항\n",
    "\n",
    "class Customer(object):\n",
    "    \"\"\"Produces objects that represent customers.\"\"\"\n",
    "    def __init__(self, customer_id):\n",
    "        self.customer_id = customer_id\n",
    "    \n",
    "    def display_cart(self):\n",
    "        print (\"I'm a string that stands in for the contents of your shopping cart!\")\n",
    "\n",
    "class ReturningCustomer(Customer):\n",
    "    \"\"\"For customers of the repeat variety.\"\"\"\n",
    "    def display_order_history(self):\n",
    "        print (\"I'm a string that stands in for your order history!\")\n",
    "\n",
    "#\n",
    "monty_python = ReturningCustomer(\"ID: 12345\")\n",
    "monty_python.display_cart()\n",
    "monty_python.display_order_history()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 12 상속(Inheritance) 문법\n",
    "\n",
    "class Shape(object):\n",
    "    \"\"\"Makes shapes!\"\"\"\n",
    "    def __init__(self, number_of_sides):\n",
    "        self.number_of_sides = number_of_sides\n",
    "\n",
    "# Add your Triangle class below!\n",
    "class Triangle(Shape):\n",
    "    def __init__(self, side1, side2, side3):\n",
    "        self.side1 = side1\n",
    "        self.side2 = side2\n",
    "        self.side3 = side3\n",
    "        \n",
    "#\n",
    "tri = Triangle(2,3,4)\n",
    "tri.side1\n",
    "\n",
    "tri = Shape(5)\n",
    "tri.number_of_sides\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "200.0\n",
      "120.0\n"
     ]
    }
   ],
   "source": [
    "# 13 오버라이드(Override)!\n",
    "\n",
    "class Employee(object):\n",
    "    \"\"\"Models real-life employees!\"\"\"\n",
    "    def __init__(self, employee_name):\n",
    "        self.employee_name = employee_name\n",
    "    \n",
    "    def calculate_wage(self, hours):\n",
    "        self.hours = hours\n",
    "        return hours * 20.00\n",
    "\n",
    "# Add your code below!\n",
    "class PartTimeEmployee(Employee):\n",
    "    def calculate_wage(self, hours):\n",
    "        self.hours = hours\n",
    "        return hours * 12.00\n",
    "\n",
    "\n",
    "#\n",
    "emp = Employee('John')\n",
    "tmp = PartTimeEmployee('Tom')\n",
    "\n",
    "print (emp.calculate_wage(10))\n",
    "print (tmp.calculate_wage(10))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "200.0\n"
     ]
    }
   ],
   "source": [
    "# 14 This Looks Like a Job For\n",
    "\n",
    "class Employee(object):\n",
    "    \"\"\"Models real-life employees!\"\"\"\n",
    "    def __init__(self, employee_name):\n",
    "        self.employee_name = employee_name\n",
    "    \n",
    "    def calculate_wage(self, hours):\n",
    "        self.hours = hours\n",
    "        return hours * 20.00\n",
    "\n",
    "# Add your code below!\n",
    "class PartTimeEmployee(Employee):\n",
    "    def calculate_wage(self, hours):\n",
    "        self.hours = hours\n",
    "        return hours * 12.00\n",
    "    \n",
    "    def full_time_wage(self, hours):\n",
    "        return super(PartTimeEmployee, self).calculate_wage(hours)\n",
    "\n",
    "milton = PartTimeEmployee(\"milton\")\n",
    "print (milton.full_time_wage(10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 15 클래스(Class)의 기초\n",
    "\n",
    "class Triangle(object):\n",
    "    def __init__(self, angle1, angle2, angle3):\n",
    "        self.angle1 = angle1\n",
    "        self.angle2 = angle2\n",
    "        self.angle3 = angle3\n",
    "        \n",
    "#\n",
    "t = Triangle(1,2,3)\n",
    "t.angle1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "# 16 속성(attribute)과 메소드(method) 추가하기\n",
    "\n",
    "class Triangle(object):\n",
    "    number_of_sides = 3\n",
    "    \n",
    "    def __init__(self, angle1, angle2, angle3):\n",
    "        self.angle1 = angle1\n",
    "        self.angle2 = angle2\n",
    "        self.angle3 = angle3\n",
    "    \n",
    "    def check_angles(self):\n",
    "        return (self.angle1 + self.angle2 + self.angle3) == 180\n",
    "    \n",
    "\n",
    "#\n",
    "t = Triangle(3,4,5)\n",
    "print (t.number_of_sides)\n",
    "print (t.check_angles())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "# 17 객체(Object) 인스턴스화(Instantiatie) 시키기\n",
    "\n",
    "class Triangle(object):\n",
    "    number_of_sides = 3\n",
    "    \n",
    "    def __init__(self, angle1, angle2, angle3):\n",
    "        self.angle1 = angle1\n",
    "        self.angle2 = angle2\n",
    "        self.angle3 = angle3\n",
    "    \n",
    "    def check_angles(self):\n",
    "        return (self.angle1 + self.angle2 + self.angle3) == 180\n",
    "\n",
    "my_triangle = Triangle(60, 60, 60)\n",
    "print (my_triangle.number_of_sides)\n",
    "print (my_triangle.check_angles())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "# 18 상속\n",
    "\n",
    "class Triangle(object):\n",
    "    number_of_sides = 3\n",
    "    \n",
    "    def __init__(self, angle1, angle2, angle3):\n",
    "        self.angle1 = angle1\n",
    "        self.angle2 = angle2\n",
    "        self.angle3 = angle3\n",
    "    \n",
    "    def check_angles(self):\n",
    "        return (self.angle1 + self.angle2 + self.angle3) == 180\n",
    "\n",
    "class Equilateral(Triangle):\n",
    "    angle = 60\n",
    "    def __init__(self):\n",
    "        self.angle1 = self.angle2 = self.angle3 = self.angle\n",
    "\n",
    "\n",
    "my_triangle = Equilateral()\n",
    "print (my_triangle.number_of_sides)\n",
    "print (my_triangle.check_angles())"
   ]
  }
 ],
 "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.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}