{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Wprowadzenie do Pythona: Klasy\n",
    "\n",
    "## Tomasz Dwojak\n",
    "\n",
    "### 3 grudnia 2017"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Plan na dziś:\n",
    " * klasy,\n",
    " * wyjątki."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Python jest językiem obiektowym \n",
    " * Wszystko jest obiektem: liczby, napisy, None, funkcje, moduły (biblioteki)..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "Python da się lubić !\n"
     ]
    }
   ],
   "source": [
    "print((2017).imag)\n",
    "print(' '.join(['Python', 'da', 'się', 'lubić', '!']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Konstrukcja"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class '__main__.NajprostszaKlasa'>\n"
     ]
    }
   ],
   "source": [
    "class NajprostszaKlasa:\n",
    "    pass\n",
    "\n",
    "nasza_klasa = NajprostszaKlasa() # Uwaga na nawiasy na końcu!\n",
    "print(type(nasza_klasa))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## (Pseudo) Konstruktor \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n"
     ]
    }
   ],
   "source": [
    "class Punkt:\n",
    "    def __init__(self, x, y):\n",
    "        self.x = x\n",
    "        self.y = y\n",
    "\n",
    "punkt = Punkt(2, 3)\n",
    "print(punkt.x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "class Figura:\n",
    "    def __init__(self, vertexes):\n",
    "        self.vertexes = vertexes\n",
    "    \n",
    "    def liczba_wierzcholkow(self):\n",
    "        return len(self.vertexes)\n",
    "    \n",
    "    def dodaj_wierzcholek(self, x):\n",
    "        self.vertexes.append(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "class Prostokat(Figura):\n",
    "    def __init__(self, vertexes):\n",
    "        super().__init__(vertexes)\n",
    "        \n",
    "    def czy_jestem_kwadratem(self):\n",
    "        pass\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Figura:\n",
    "    def __init__(self, vertexes):\n",
    "        self.vertexes = vertexes\n",
    "    \n",
    "    def liczba_wierzcholkow(self):\n",
    "        return len(self.vertexes)\n",
    "    \n",
    "    def __len__(self):\n",
    "        return self.liczba_wierzcholkow()\n",
    "    \n",
    "len(Figura([Punkt(2,3), Punkt(3,4), Punkt(0, 0)]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Dobre praktyki: komentarze"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "class Punkt(object):\n",
    "    \"\"\"Klasa reprezentująca punkt w 2D.\"\"\"\n",
    "    def __init__(self, x, y):\n",
    "        \"\"\"opis argumentów x i y.\"\"\"\n",
    "        self.x = x\n",
    "        self.y = y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on class Punkt in module __main__:\n",
      "\n",
      "class Punkt(builtins.object)\n",
      " |  Klasa reprezentująca punkt w 2D.\n",
      " |  \n",
      " |  Methods defined here:\n",
      " |  \n",
      " |  __init__(self, x, y)\n",
      " |      opis argumentów x i y.\n",
      " |  \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"
     ]
    }
   ],
   "source": [
    "help(Punkt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Enkapsulacja: publiczne czy prywatne?\n",
    " * Prywatne zaczynają się od dwóch podkreśleń: ``__``, np. ``def __policz(self)``\n",
    " * chronione tylko w konwencji, zaczynają się od '\\_', np. ``def _parse(self)``\n",
    " * publiczne jest wszystko co nie zaczyna się od '\\_'."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'Parser' object has no attribute '__parse'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-6-80ee186598d3>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0mparser\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mParser\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0mparser\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mparser\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__parse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m: 'Parser' object has no attribute '__parse'"
     ]
    }
   ],
   "source": [
    "class Parser(object):\n",
    "    def __parse(self): pass\n",
    "    def _get(self): pass\n",
    "parser = Parser()\n",
    "parser._get()\n",
    "parser.__parse()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Iteratory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<__main__.Punkt object at 0x7f728015b358>\n",
      "<__main__.Punkt object at 0x7f728015b4a8>\n",
      "<__main__.Punkt object at 0x7f728015b438>\n"
     ]
    }
   ],
   "source": [
    "class Figura:\n",
    "    def __init__(self, vertexes):\n",
    "        self.vertexes = vertexes  \n",
    "        \n",
    "    def __iter__(self):\n",
    "        self.index = -1\n",
    "        return self\n",
    "    \n",
    "    def __next__(self):\n",
    "        self.index += 1\n",
    "        if self.index == len(self.vertexes):\n",
    "            raise StopIteration\n",
    "        return self.vertexes[self.index]\n",
    "        \n",
    "for v in Figura([Punkt(2,3), Punkt(3,4), Punkt(0, 0)]):\n",
    "    print(v)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Atrybuty i metody statyczne"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "0\n"
     ]
    }
   ],
   "source": [
    "class Klasa:\n",
    "    atrybut = 0\n",
    "\n",
    "klasa = Klasa()\n",
    "print(Klasa.atrybut)\n",
    "print(klasa.atrybut)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Jestem statyczna!\n"
     ]
    }
   ],
   "source": [
    "class Klasa:\n",
    "    def __init__(self):\n",
    "        self.t = 0\n",
    "    def metoda():\n",
    "        print(\"Jestem statyczna!\")\n",
    "\n",
    "Klasa.metoda()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Wyjątki"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "ename": "FileNotFoundError",
     "evalue": "[Errno 2] No such file or directory: 'nieistniejący_plik.txt'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mFileNotFoundError\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-20-41928d542bef>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"nieistniejący_plik.txt\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mplik\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m     \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mplik\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\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;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'nieistniejący_plik.txt'"
     ]
    }
   ],
   "source": [
    "with open(\"nieistniejący_plik.txt\") as plik:\n",
    "    content = plik.read()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    with open(\"nieistniejący_plik.txt\") as plik:\n",
    "        content = plik.read()\n",
    "except FileNotFoundError:\n",
    "    contenct = \"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Warning [Errno 2] No such file or directory: 'nieistniejący_plik.txt'\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    with open(\"nieistniejący_plik.txt\") as plik:\n",
    "        content = plik.read()\n",
    "except FileNotFoundError as e:\n",
    "    print(\"Warning {}\".format(e))\n",
    "    contenct = \"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Warning [Errno 2] No such file or directory: 'nieistniejący_plik.txt'\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    with open(\"nieistniejący_plik.txt\") as plik:\n",
    "        content = plik.read()\n",
    "except Exception as e:\n",
    "    print(\"Warning {}\".format(e))\n",
    "    contenct = \"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    with open(\"nieistniejący_plik.txt\") as plik:\n",
    "        content = plik.read()\n",
    "except:\n",
    "    contenct = \"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "class Figura:\n",
    "    def __init__(self, vertexes):\n",
    "        if len(vertexes) == 0:\n",
    "            raise Exception(\"Empty list of vertexes\")\n",
    "        self.vertexes = vertexes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "class MyError(Exception):\n",
    "    def __init__(self, text):\n",
    "        self.text = text\n",
    "    def __str__(self):\n",
    "        return self.text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "ename": "MyError",
     "evalue": "Coś poszło nie tak!",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mMyError\u001b[0m                                   Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-36-4fb306b42ebc>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mMyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Coś poszło nie tak!\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mMyError\u001b[0m: Coś poszło nie tak!"
     ]
    }
   ],
   "source": [
    "raise MyError(\"Coś poszło nie tak!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "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.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}