From adc0e3f958b3c7534af4379302daa7f8984831a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Konrad=20V=C3=B6lkel?= <konrad.voelkel@hhu.de>
Date: Tue, 4 Feb 2025 16:50:55 +0100
Subject: [PATCH] Experiment mit Widgets

---
 stochastik-programmieren.ipynb | 122 +++++++++++++++++++++++++++++----
 1 file changed, 110 insertions(+), 12 deletions(-)

diff --git a/stochastik-programmieren.ipynb b/stochastik-programmieren.ipynb
index 7ba713d..2750357 100644
--- a/stochastik-programmieren.ipynb
+++ b/stochastik-programmieren.ipynb
@@ -13,7 +13,9 @@
    "id": "9b4163a3-d84b-42ec-b927-6888e3bc159b",
    "metadata": {},
    "source": [
-    "Wir wollen uns nun kurz damit beschäftigen, wie sich mit Python Stichproben von Zufallsexperimenten simulieren lassen.\n",
+    "Wir wollen uns nun kurz damit beschäftigen, wie sich mit Python Stichproben (en. Samples) von Zufallsexperimenten simulieren lassen.\n",
+    "\n",
+    "Verwendete Python-Konstrukte: [Module/import](https://docs.python.org/3/tutorial/modules.html), [Methoden/def](https://docs.python.org/3/tutorial/controlflow.html#defining-functions), [Länge/len](https://docs.python.org/3/library/functions.html#len), [Mengen/set](https://docs.python.org/3/tutorial/datastructures.html#sets), [Generator-Ausdruck](https://docs.python.org/3/tutorial/classes.html#generator-expressions), [Range](https://docs.python.org/3/tutorial/controlflow.html#the-range-function), [Assertion/assert](https://docs.python.org/3/reference/simple_stmts.html#the-assert-statement)\n",
     "\n",
     "## Wahrscheinlichkeitsmaß implementieren"
    ]
@@ -30,7 +32,7 @@
     "def P(A, Omega):\n",
     "    \"\"\"Die Wahrscheinlichkeit für das Ereignis A,\n",
     "       gegeben gleich wahrscheinliche Ergebnisse aus einem Ergebnisraum Ω.\"\"\"\n",
-    "    return Fraction(len(A & Omega), len(Omega))"
+    "    return Fraction(len(A and Omega), len(Omega))"
    ]
   },
   {
@@ -73,7 +75,7 @@
     "\n",
     "## Zufall importieren\n",
     "\n",
-    "Python bietet mit dem `random`-Modul eine Schnittstelle zu Pseudozufallszahlen. Die Methode `random.random` ist ein direkt in C implementierter Mersenne Twister. Wenn man \"echte\" Zufallszahlen braucht, etwa für kryptografische Zwecke, gibt es dazu das `secrets`-Modul. Den Seed für den Mersenne Twister kann man angeben, und sollte man auch, um Zufallssimulationen reproduzierbar zu machen."
+    "Python bietet mit dem `random`-Modul eine Schnittstelle zu Pseudozufallszahlen. Die Methode `random.random` ist ein direkt in C implementierter [Mersenne Twister](https://de.wikipedia.org/wiki/Mersenne-Twister). Wenn man \"echte\" Zufallszahlen braucht, etwa für kryptografische Zwecke, gibt es dazu das `secrets`-Modul. Den Seed für den Mersenne Twister kann man angeben, und sollte man auch, um Zufallssimulationen reproduzierbar zu machen."
    ]
   },
   {
@@ -91,7 +93,7 @@
       "random() method of random.Random instance\n",
       "    random() -> x in the interval [0, 1).\n",
       "\n",
-      "0.7803255204450154\n",
+      "0.5311158584902383\n",
       "0.13436424411240122\n"
      ]
     }
@@ -122,15 +124,15 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
-   "id": "c453b1a1-9693-401c-ab9e-fb39a13c81a2",
+   "execution_count": 18,
+   "id": "62096c2f-6911-4c7a-b243-b8661e83ddb3",
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[6, 5, 2, 3, 3, 4, 5, 1, 1, 6, 3, 5, 1, 3, 5, 2, 6, 6, 1, 1, 4, 6, 3, 2, 3, 1, 2, 3, 3, 2, 2, 2, 3, 2, 1, 6, 4, 4, 2, 6, 6, 1, 2, 5, 5, 6, 3, 5, 5, 2, 4, 6, 6, 4, 4, 1, 2, 5, 3, 2, 4, 5, 5, 3, 3, 4, 5, 4, 3, 3, 1, 1, 5, 6, 4, 3, 2, 4, 6, 5, 4, 6, 2, 4, 6, 4, 3, 2, 4, 6, 1, 5, 5, 6, 5, 5, 4, 4, 3, 1]\n"
+      "[1, 1, 4, 2, 2, 5, 3, 2, 3, 1, 3, 3, 2, 1, 6, 4, 2, 4, 5, 1, 1, 1, 5, 1, 5, 5, 4, 2, 6, 5, 4, 2, 4, 3, 4, 2, 4, 1, 2, 6, 6, 2, 6, 2, 6, 5, 3, 2, 1, 6, 1, 5, 6, 4, 2, 6, 6, 5, 4, 3, 3, 2, 5, 3, 2, 1, 4, 2, 3, 2, 6, 6, 1, 2, 2, 6, 5, 3, 2, 5, 6, 6, 3, 6, 5, 3, 6, 2, 5, 1, 2, 6, 2, 5, 4, 6, 3, 3, 2, 6]\n"
      ]
     }
    ],
@@ -142,8 +144,104 @@
     "assert list(range(1,7)) == [transform_unit_to_dice((x-1)/6)\n",
     "                            for x in range(1,7)]\n",
     "\n",
-    "print([transform_unit_to_dice(r()) for n in range(100)])\n",
-    "    "
+    "N = 100\n",
+    "würfe = [transform_unit_to_dice(r()) for n in range(N)]\n",
+    "print(würfe)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "id": "4e0195f2-cb57-4256-bc2a-18eb44c2f83b",
+   "metadata": {
+    "jupyter": {
+     "source_hidden": true
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "2e4e538749bd4a5ebcc6ec634762fd23",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "IntSlider(value=10)"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "90473d7109de424cb9f8daf466690c9c",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Button(description='Würfel werfen', icon='dice', style=ButtonStyle(), tooltip='Anklicken um Würfelwürfe zu sim…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "8152dfae48c3489686a6bd7fc0cb4eea",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Button(description='Seed reset auf 1', icon='dice-one', style=ButtonStyle(), tooltip='Anklicken um Random Seed…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "3d388dc7c06b41888b852c0e707cd1d7",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "Label(value='')"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Interaktiv: Benutzen Sie den Schieberegler und die Buttons!\n",
+    "# Der folgende Code ist nur zur interaktiven Interaktion da,\n",
+    "# wir lernen und üben in dieser Vorlesung nicht, wie man interaktive Elemente in Notebooks gestaltet.\n",
+    "import ipywidgets as widgets\n",
+    "from IPython.display import display\n",
+    "slider = widgets.IntSlider(value=10, max=100)\n",
+    "text = widgets.Label(value='')\n",
+    "wurfbutton = widgets.Button(\n",
+    "    description='Würfel werfen',\n",
+    "    tooltip='Anklicken um Würfelwürfe zu simulieren',\n",
+    "    icon='dice'\n",
+    ")\n",
+    "seedbutton = widgets.Button(\n",
+    "    description='Seed reset auf 1',\n",
+    "    tooltip='Anklicken um Random Seed wieder auf 1 zu setzen',\n",
+    "    icon='dice-one'\n",
+    ")\n",
+    "def roll_dice(_):\n",
+    "    text.value = \" \".join([str(transform_unit_to_dice(r())) for _ in range(slider.value)])\n",
+    "wurfbutton.on_click(roll_dice)\n",
+    "def seed_reset(_):\n",
+    "    random.seed(1)\n",
+    "seedbutton.on_click(seed_reset)\n",
+    "seed_reset(None)\n",
+    "display(slider, wurfbutton, seedbutton, text)"
    ]
   },
   {
@@ -153,9 +251,9 @@
    "source": [
     "Damit man solche Transformationen nicht andauernd programmieren muss, kann man hier auch auf `random.randint(1,6)` oder auch auf `random.choice(range(1,7))` oder `random.randrange(1,7)` zurückgreifen. Dabei ist `randint` ein Kürzel für das entsprechende `randrange` und `choice` ist etwas allgemeiner.\n",
     "\n",
-    "Wir wollen aber festhalten: gegeben eine gleichverteilte \"Zufallsvariable\" $X=$`random.random` mit Werten in $[0,1)$ haben wir eine Abbildung $t =$`transform_unit_to_dice` konstruiert und implementiert, die Werte in $\\{1,2,3,4,5,6\\}$ hat und $t(X)$ ist gleichverteilt. Die mathematische Abbildung $t$ ist eine Zufallsvariable, wir behandeln die Verknüpfung $t \\circ X$ als Zufallsvariable, die den Würfel modelliert.\n",
+    "Wir wollen aber festhalten: gegeben eine gleichverteilte \"Zufallsvariable\" $X=$`random.random` mit Werten in $[0,1)$ haben wir eine Abbildung $t =$`transform_unit_to_dice` konstruiert und implementiert, die Werte in $\\Omega := \\{1,2,3,4,5,6\\}$ hat und $t(X)$ ist gleichverteilt. Die mathematische Abbildung $t \\colon [0,1) \\to \\Omega$ ist eine Zufallsvariable, wir behandeln die [Verknüpfung](https://de.wikipedia.org/wiki/Komposition_(Mathematik)) $t \\circ X$ als Zufallsvariable, die den Würfel modelliert.\n",
     "\n",
-    "Nun könnte man sich beschweren: `random.random()` nimmt gar keinen Parameter, ist also keine mathematische Abbildung von einem Definitionsbereich in die Menge $[0,1)$. Tatsächlich müssen wir uns vorstellen, dass es eine Abbildung $X \\colon \\Omega \\to [0,1)$ ist, und auf $\\Omega$ ein irgendwie geartetes Wahrscheinlichkeitsmaß definiert ist, sodass durch $X$ auf $[0,1)$ die Gleichverteilung induziert wird. Die Menge $\\Omega$ spielt für uns keine konkrete Rolle - da \"kommt der Zufall her\" und in der Notation `random.random()` sehen wir schon, dass wir eben kein konkretes Element von $\\Omega$ einsetzen, sondern pseudozufällig eins ziehen und das in $X$ einsetzen."
+    "Nun könnte man sich beschweren: `random.random()` nimmt gar keinen Parameter, ist also keine mathematische Abbildung von einem Definitionsbereich in die Menge $[0,1)$. Tatsächlich müssen wir uns vorstellen, dass es eine Abbildung $X \\colon \\Omega' \\to [0,1)$ ist, und auf $\\Omega'$ ein irgendwie geartetes Wahrscheinlichkeitsmaß definiert ist, sodass durch $X$ auf $[0,1)$ die Gleichverteilung induziert wird. Die Menge $\\Omega'$ spielt für uns keine konkrete Rolle - da \"kommt der Zufall her\" und in der Notation `random.random()` sehen wir schon, dass wir eben kein konkretes Element von $\\Omega'$ einsetzen, sondern pseudozufällig eins ziehen und das in $X$ einsetzen."
    ]
   },
   {
@@ -192,7 +290,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.12"
+   "version": "3.11.2"
   }
  },
  "nbformat": 4,
-- 
GitLab