{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Software Entwicklung \n",
    "\n",
    "## Kapitel 6: Mengen und Dictionaries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### 6.1 Mengen\n",
    "\n",
    "*Listen* sind keine *Mengen* im mathematischen Sinne, weil\n",
    "\n",
    "* die Elemente eine Reihenfolge besitzen (was bei Mengen im Allgeinen nicht der Fall ist)\n",
    "* Elemente mehrfach in der Liste vorkommen können (was bei Mengen nicht möglich ist)\n",
    "\n",
    "Eine Liste kann mit Hilfe der Built-In-Funktion\n",
    "<code>set</code> in eine Menge umgewandelt werden."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "menge = set([1, 2, 3])\n",
    "print(type(menge))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Duplikate werden bereinigt, d.h. identische Werte sind anschließend nur einmal enthalten."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "menge = set([1, 1, 3])\n",
    "print(len(menge))\n",
    "print(menge)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Da die Elemente in einer Menge keine Reihenfolge besitzen, ist der Zugriff mit Hilfe\n",
    "eines Index nicht möglich."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "menge = set([1, 2, 3])\n",
    "print(menge[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Allerdings kann in der bekannten Form über eine Menge iteriert werden. Die Reihenfolge ist\n",
    "nicht festgelegt und kann sich ggf. von Rechner zu Rechner unterscheiden."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "menge = set([1, 2, 3])\n",
    "for zahl in menge:\n",
    "    print(zahl)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Die Elemente in einem Set müssen einen unveränderlichen Datentyp besitzen, d.h. Listen\n",
    "sind z.B. keine zulässigen Elemente eines Sets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "liste1 = [1, 2]\n",
    "liste2 = [3, 4]\n",
    "\n",
    "liste_der_listen = [liste1, liste2]\n",
    "\n",
    "menge = set(liste_der_listen)\n",
    "print(len(menge))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Bei Mengen in Python unterscheiden sich Gleichheit und Identität, d.h.\n",
    "Mengen sind selbst auch veränderliche Datentypen."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "menge1 = set([])\n",
    "menge2 = set([])\n",
    "\n",
    "if menge1 == menge2:\n",
    "    print(\"Gleich!\")\n",
    "\n",
    "if menge1 is menge2:\n",
    "    print(\"Identisch!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Elemente können mit <code>add</code> hinzugefügt und mit <code>remove</code> entfernt werden."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "menge = set([1, 2, 3])\n",
    "menge.add(2)\n",
    "menge.remove(3)\n",
    "for zahl in menge:\n",
    "    print(zahl)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Die Überprüfung, ob ein Element in einer Menge ist, erfolgt wieder mit dem Operator <code>in</code>."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "menge = set([1, 2, 3])\n",
    "if 4 in menge:\n",
    "    print(\"Enthalten!\")\n",
    "liste = [1, 2, 3]\n",
    "if 3 in liste:\n",
    "    print(\"E\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Aufgrund der Einschränkungen, die mit einer Menge verbunden sind (keine Reihenfolge,\n",
    "jedes Element max. einmal enthalten), kann Python einige Operationen performanter ausführen\n",
    "als bei einer Liste.\n",
    "\n",
    "Im nachfolgenden Beispiel erwartet <code>timeit</code> als erstes Argument eine\n",
    "Funktion, die dann <code>number</code>-mal ausgeführt wird. Zurückgegeben wird die\n",
    "Ausführungszeit.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "import timeit\n",
    "\n",
    "liste = list(range(100000))\n",
    "menge = set(liste)\n",
    "\n",
    "dauer_bei_liste = timeit.timeit(lambda:50000 in liste, number=10000)\n",
    "print(f\"Liste {dauer_bei_liste}\")\n",
    "\n",
    "dauer_bei_menge = timeit.timeit(lambda:50000 in menge, number=10000)\n",
    "print(f\"Menge {dauer_bei_menge}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Darüber hinaus bietet eine Menge einige Mengenoperationen mittels Infix-Operator:\n",
    "\n",
    "* <code>&</code> liefert die Schnittmenge zweier Mengen\n",
    "* <code>|</code> liefert die Vereinigungsmenge zweier Mengen\n",
    "* <code>-</code> liefert die Differnzmenge, d.h. die erste Menge ohne die Elemente der zweiten Menge"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "menge1 = set([1, 2, 3])\n",
    "menge2 = set([2, 4, 6])\n",
    "\n",
    "schnittmenge = menge1 & menge2\n",
    "vereinigungsmenge = menge1 | menge2\n",
    "differenzmenge = menge1 - menge2\n",
    "\n",
    "print(f\"Schnittmenge {schnittmenge}\")\n",
    "print(f\"Vereinigungsmenge {vereinigungsmenge}\")\n",
    "print(f\"Differenzmenge {differenzmenge}\")\n",
    "print(f\"dd{1+2}dd\")\n",
    "\n",
    "text = \"dd{1+2}dd\"\n",
    "print(len(text))\n"
   ]
  }
 ],
 "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
}
