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