{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Software Entwicklung \n",
    "\n",
    "## Kapitel 5: Module und Pakete"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 5.4 Eigene Module\n",
    "\n",
    "Natürlich ist es auch mögliche, selbst Module zu entwickeln und diese zu importieren. Genau genommen\n",
    "ist jede Python-Quellcodedatei ein eigenes Modul. Die darin enthaltenen globalen Objekte\n",
    "(insbesondere Funktionen) können mittels <code>import</code> in anderen Quellcodedateien\n",
    "zugänglich gemacht werden.\n",
    "\n",
    "![Import eigener Module](../img/import.png \"Import eigener Module\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Der Name des Moduls beim Import entspricht dem Dateinamen der Python-Quellcodedatei. Gefunden\n",
    "werden auf diese Weise Quellcodedateien, die im gleichen Verzeichnis liegen oder in einem der\n",
    "beim Python-Interpreter hinterlegten Modulverzeichnisse.\n",
    "\n",
    "Vorsicht: Sollte das eigene Modul den gleichen Namen beitzen wie ein Standardmodul, so wird\n",
    "das Standardmodul gefunden und importiert!\n",
    "\n",
    "\n",
    "Der Name eines Moduls kann im übrigen mit der *Special Variable* <code>\\_\\_name\\_\\_</code> ermittelt\n",
    "werden."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "print(__name__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Mit Hilfe der Variable <code>\\_\\_name\\_\\_</code> kann festgestellt werden, ob die Quellcodedatei \n",
    "gerade ausgeführt wird, \n",
    "\n",
    "* weil sie direkt gestartet wurde und das Top-Level-Modul ist - in diesem Fall enthält die\n",
    "  Variable den String <code>\"\\_\\_main\\_\\_\"</code>\n",
    "* weil sie in ein anderes Modul importiert wird - in diesem Fall enthält die Variable \n",
    "  den Modulnamen, wie er beim Importstatement angegeben ist"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Durch diese Unterscheidung ist es möglich, Module mit Test- oder Beispielcode zu versehen, der\n",
    "nicht ausgeführt wird, wenn die Quellcodedatei importiert wird. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# Definition einer Funktion, die von anderen importiert werden soll\n",
    "def f():\n",
    "    return 17\n",
    "\n",
    "# Testcode, der nur ausgeführt werden soll, wenn das Modul direkt ausgeführt wird\n",
    "if __name__ == \"__main__\":\n",
    "    if f() != 17:\n",
    "        print(\"Fehler!\")\n",
    "    else:\n",
    "        print(\"Alles ok!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 5.5 Packages\n",
    "\n",
    "*Packages* dienen dazu, mehrere Module zusammenzufassen und in strukturierter Form\n",
    "importieren zu können. Python enthält z.B. bereits im Standard das Package <code>http</code>\n",
    "mit den darin enthaltenen Standardmodulen <code>http.client</code>, <code>http.server</code>\n",
    "und weiteren. Auf die enthaltenen Teilmodule kann beim Import mit der *Dot-Notation* zugegriffen\n",
    "werden kann, z.B.:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "import http.client\n",
    "\n",
    "connection = http.client.HTTPConnection('www.th-nuernberg.de')\n",
    "connection.request(\"GET\", \"/\")\n",
    "response = connection.getresponse()\n",
    "print(response.status, response.reason)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Ein Package ist ein Dateisystem-Verzeichnis mit folgendem Inhalt:\n",
    "\n",
    "* die Python-Dateien der beinhalteten Module\n",
    "* eine optionale Initialisierungsdatei <code>__init__.py</code>,\n",
    "  die beim Importieren des Packages geladen und ausgeführt wird"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
