{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "80fd796e-f42e-4940-89ae-e7359be4d10a",
   "metadata": {},
   "source": [
    "# 4 Vorlesung"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb2fcdfe-257a-4736-b9c2-5fa17d63fd1b",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "## Generatoren\n",
    "```python\n",
    "def <funktion-name>(<parameterliste>):\n",
    "    # do something\n",
    "    yield <ergebnis>\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0ea7c66c-439c-4a3b-a154-3449c2a799a1",
   "metadata": {},
   "source": [
    "### Endliche Generatoren"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "d5465edd-a13d-4fa0-a805-30c35a384d54",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Matrikelnummer generator\n",
    "import random \n",
    "def mat_nr_gen(anzahl: int) -> float:\n",
    "    for _ in range(anzahl):\n",
    "        yield random.randint(500_000, 700_000) # Generator weil yield"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "48109f19-47d2-45a1-bd03-9eccb4d25372",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<generator object mat_nr_gen at 0x10838f060>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sem_3 = mat_nr_gen(5) # generator erstellen\n",
    "sem_3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "413bbbf6-87c8-41ff-8680-a70e8456d865",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "559540"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "next(sem_3) # Nächsten Wert des Generators"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "14a1220d-ae0c-428b-bd51-564e66e55854",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "606586"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "next(sem_3) # ..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "af75146c-e727-41e8-b496-695b93a68a56",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "503048\n",
      "648312\n",
      "629536\n",
      "556597\n",
      "512158\n"
     ]
    }
   ],
   "source": [
    "for _ in range(5):\n",
    "    print(next(sem_3)) # 5 mal den generator aufrufen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "4691aa5c-0e3d-4dff-93c1-835a805e20e9",
   "metadata": {},
   "outputs": [
    {
     "ename": "StopIteration",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mStopIteration\u001b[0m                             Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[19], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43msem_3\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[0;31mStopIteration\u001b[0m: "
     ]
    }
   ],
   "source": [
    "next(sem_3) # Generator hat keine Werte mehr -> Fehler"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "6790f776-4201-403f-b95d-d789a4fe3a6f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "591325\n",
      "582340\n",
      "622867\n",
      "653166\n",
      "531169\n",
      "538806\n",
      "571659\n"
     ]
    }
   ],
   "source": [
    "for mat_nr in mat_nr_gen(7): # For loop übernimmt die komplette Arbeit\n",
    "    print(mat_nr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4cfbb732-c412-4ded-8f33-75a9917b0df1",
   "metadata": {},
   "source": [
    "### Unendliche Generatoren"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "b2b3c678-a775-4213-9a73-4d3aa48eff5e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Seriennummer generator\n",
    "def serial_nr_gen() -> int:\n",
    "    while True: # \"Führe unendlich of aus\"\n",
    "        yield random.randint(1000, 2000) # Generator weil yield"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "e6ba3c92-465c-487d-a936-a155ad713784",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1940\n",
      "1748\n",
      "1342\n",
      "1463\n",
      "1100\n",
      "1748\n",
      "1158\n",
      "1577\n",
      "1321\n",
      "1949\n"
     ]
    }
   ],
   "source": [
    "ser_gen = serial_nr_gen() # Generator erstellen\n",
    "for _ in range(10):\n",
    "    print(next(ser_gen)) # 10 mal den generator abfragen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "c015d2c3-238b-454a-b75e-f81a19f89a79",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1281"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "next(ser_gen) # Diesmal kein Fehler da Generator kein Ende hat"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd8ed607-c0e0-481c-aaa7-cf07e8c97051",
   "metadata": {},
   "source": [
    "## Type Hints"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "9f564549-70d7-4538-a3fd-7158514fa0d4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{2.0: 2.0, 'HI': 'HI', 9: 9, True: True}\n",
      "0.0 <class 'float'>\n"
     ]
    }
   ],
   "source": [
    "# Beispielfunktion\n",
    "\n",
    "# Type hints zeigen dem Programmierer welche Datentypen erwartet werden\n",
    "def useless(p1: int, p2: float, p3: bool, p4: str) -> dict: \n",
    "    return {p1: p1, p2: p2, p3: p3, p4: p4}\n",
    "\n",
    "print(useless(2.0, \"HI\", 9, True)) # Aufruf mit \"Falschen\" Datentypen\n",
    "\n",
    "# Beispielvariablen:\n",
    "zahl: int = 0.0 # Zahl ist ein Float\n",
    "print(zahl, type(zahl))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2572fb15-de4f-4be7-809b-955d26895d84",
   "metadata": {},
   "source": [
    "## Dataclasses\n",
    "\n",
    "Auto Dataclass\n",
    "\n",
    "|Attribut|Wert|\n",
    "|-|-|\n",
    "|Marke|VW|\n",
    "|Fahrzeugtyp|Limousine|\n",
    "|Seriennummer|<Zufällig generiert>|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "feb80166-b58a-46bf-94b0-f26142d6131f",
   "metadata": {},
   "outputs": [],
   "source": [
    "from dataclasses import dataclass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "b9c6ba77-1d59-4058-b18c-601989d9b8db",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<function dataclasses.dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False)>"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataclass # Decorator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "81e41f92-8ce6-40de-9319-629cb69c73e9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Auto(marke='VW', model='Limousine', serial_nr=1146)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ser_gen = serial_nr_gen()\n",
    "\n",
    "# Diese Syntax einfach merken\n",
    "@dataclass\n",
    "class Auto:\n",
    "    marke: str # 1 Attribut\n",
    "    model: str # 2 Attribut\n",
    "    serial_nr: int = next(ser_gen) # 3 Attribut mit Standardwert\n",
    "\n",
    "Auto(\"VW\", \"Limousine\") # Erstellt eine Auto Dataclass "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "f2e0e50e-f1f9-4ead-8530-0aeb40989581",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Auto(marke='Porsche', model='SUV', serial_nr=1146)"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Auto(model=\"SUV\", marke=\"Porsche\") # Attribute können explizit definiert werden"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "e5cb5618-50a9-4e38-a0b4-7e3e5e4c2295",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Auto(marke='Porsche', model='SUV', serial_nr=5678)"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Auto(model=\"SUV\", serial_nr=5678, marke=\"Porsche\") # Standardwerte lassen sich überschreiben "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "655cbee0-88c0-4f60-97c5-4ef475d59f0b",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "Auto.__init__() got an unexpected keyword argument 'reifenzahl'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[37], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mAuto\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mSUV\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mserial_nr\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m5678\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmarke\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mPorsche\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreifenzahl\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m5\u001b[39;49m\u001b[43m)\u001b[49m\n",
      "\u001b[0;31mTypeError\u001b[0m: Auto.__init__() got an unexpected keyword argument 'reifenzahl'"
     ]
    }
   ],
   "source": [
    "Auto(model=\"SUV\", serial_nr=5678, marke=\"Porsche\", reifenzahl=5) # Nicht bekanntes Attribut wirft Fehler"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "22c0625c-4e7d-46aa-a711-5cc2bb759427",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'marke': 'Porsche', 'model': 'SUV', 'serial_nr': 12766}"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Beispiel als Dict\n",
    "vw = {\n",
    "    \"marke\": \"Porsche\",\n",
    "    \"model\": \"SUV\",\n",
    "    \"serial_nr\": 12766\n",
    "}\n",
    "\n",
    "vw"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "77668ca0-719d-48b8-954f-b2f7becdb318",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'marke': 'Porsche', 'model': 'SUV', 'serial_nr': 12766, 'reifenzahl': 7}"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Dict wirft keinen Fehler\n",
    "vw[\"reifenzahl\"] = 7\n",
    "vw"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "deb76203-f99c-45d1-b1f6-8395dc22ccab",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Porsche'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vw[\"marke\"] # Zugriff auf Wert im dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "b3397bbe-0925-4189-b079-bef46a3dff95",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Auto(marke='Porsche', model='SUV', serial_nr=5678)"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "porsche = Auto(model=\"SUV\", serial_nr=5678, marke=\"Porsche\")\n",
    "porsche"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "4a244554-957a-423d-8561-765aad99475a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'SUV'"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "porsche.model # Zugriff auf Attribut in der Dataclass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "3c02985e-e7b7-4dd6-aad5-02a3bd3e5312",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5678"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "porsche.serial_nr # same"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "57ccfffc-e89b-4c51-bc6d-7bf2ca16720f",
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'mark'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[44], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mvw\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmark\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\n",
      "\u001b[0;31mKeyError\u001b[0m: 'mark'"
     ]
    }
   ],
   "source": [
    "vw[\"mark\"] # KeyError wenn schlüssel nicht vorhanden im dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "8e508117-c1b3-4bf1-b9ae-a73b7bafd801",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Auto(marke=True, model=2.14, serial_nr=1146)"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Type Hints sind Type Hints und hindern nicht daran \"Falsche\" Datentypen an die Dataclasss zu vergeben \n",
    "Auto(model=2.14, marke=True) "
   ]
  }
 ],
 "metadata": {
  "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.12.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
