{ "cells": [ { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e15757ea0cf743dc9af162093423cb6e", "version_major": 2, "version_minor": 0 }, "text/plain": [ "VBox(children=(HBox(children=(Dropdown(description='Regel:', options=('Kombination', 'Permutation', 'Fakultät'…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import ipywidgets as widgets\n", "from IPython.display import display, Math, clear_output\n", "\n", "# Interaktives Lern-Tool für Kombinatorik-Regeln\n", "# Dies ist ein Jupyter-Notebook-Style Code für interaktive Widgets.\n", "# Bitte in einer Umgebung ausführen, die Widgets unterstützt (z.B. JupyterLab/Notebook).\n", "\n", "# Funktionen zur Berechnung\n", "def combination(n, k):\n", " from math import comb\n", " return comb(n, k)\n", "\n", "def permutation(n, k):\n", " from math import perm\n", " return perm(n, k)\n", "\n", "def factorial(n):\n", " from math import factorial\n", " return factorial(n)\n", "\n", "def binomial_coefficient(n, k):\n", " from math import comb\n", " return comb(n, k)\n", "\n", "def variation(n, k):\n", " from math import perm\n", " return perm(n, k)\n", "\n", "def multiset_combination(n, k):\n", " from math import comb\n", " return comb(n + k - 1, k)\n", "\n", "# Funktion, um den Entscheidungsbaum zu zeichnen (nur für Kombinationen und Permutationen)\n", "def draw_tree(n, k, is_perm):\n", " plt.figure(figsize=(8, 6))\n", " ax = plt.gca()\n", " ax.clear()\n", " ax.set_title(\"Entscheidungsbaum\", fontsize=14)\n", " ax.axis('off')\n", "\n", " if k == 1:\n", " x_start = 0.5\n", " y_start = 0.9\n", " plt.text(x_start, y_start, f\"Start\\n(n={n})\", ha='center', va='center')\n", " for i in range(n):\n", " x = 0.1 + i*(0.8/(n-1)) if n > 1 else 0.5\n", " y = 0.6\n", " plt.plot([x_start, x], [y_start-0.05, y], 'k-')\n", " plt.text(x, y, f\"Wahl {i+1}\", ha='center', va='center')\n", "\n", " elif k == 2:\n", " x_start = 0.5\n", " y_start = 0.9\n", " plt.text(x_start, y_start, f\"Start\\n(n={n})\", ha='center', va='center')\n", " child_coords = []\n", " for i in range(n):\n", " x = 0.1 + i*(0.8/(n-1)) if n > 1 else 0.5\n", " y = 0.7\n", " plt.plot([x_start, x], [y_start-0.05, y], 'k-')\n", " plt.text(x, y, f\"W1={i+1}\", ha='center', va='center')\n", " child_coords.append((x, y))\n", " for (ix, iy) in child_coords:\n", " branch_count = (n-1) if is_perm else (n)\n", " for j in range(branch_count):\n", " x2 = ix - 0.08 + j*(0.16/(branch_count-1)) if branch_count > 1 else ix\n", " y2 = 0.45\n", " plt.plot([ix, x2], [iy-0.05, y2], 'k-')\n", " plt.text(x2, y2, f\"W2={j+1}\", ha='center', va='center', fontsize=8)\n", " elif k == 3:\n", " x_start = 0.5\n", " y_start = 0.95\n", " plt.text(x_start, y_start, f\"Start\\n(n={n})\", ha='center', va='center')\n", " layer1 = []\n", " for i in range(n):\n", " x = 0.1 + i*(0.8/(n-1)) if n > 1 else 0.5\n", " y = 0.8\n", " plt.plot([x_start, x], [y_start-0.03, y], 'k-')\n", " plt.text(x, y, f\"W1={i+1}\", ha='center', va='center', fontsize=9)\n", " layer1.append((x, y))\n", " layer2 = []\n", " for (ix, iy) in layer1:\n", " branch_count = (n-1) if is_perm else n\n", " for j in range(branch_count):\n", " x2 = ix - 0.05 + j*(0.1/(branch_count-1)) if branch_count > 1 else ix\n", " y2 = 0.6\n", " plt.plot([ix, x2], [iy-0.03, y2], 'k-')\n", " plt.text(x2, y2, f\"W2={j+1}\", ha='center', va='center', fontsize=7)\n", " layer2.append((x2, y2))\n", " for (ix2, iy2) in layer2:\n", " branch_count = (n-2) if is_perm else n\n", " for j in range(branch_count):\n", " x3 = ix2 - 0.02 + j*(0.04/(branch_count-1)) if branch_count > 1 else ix2\n", " y3 = 0.4\n", " plt.plot([ix2, x3], [iy2-0.03, y3], 'k-')\n", " plt.text(x3, y3, f\"W3={j+1}\", ha='center', va='center', fontsize=6)\n", " else:\n", " plt.text(0.5, 0.5, \"Baumdiagramm für k>3 ist zu groß.\\nBitte k <= 3 für Baum\", ha='center', va='center', fontsize=12)\n", "\n", " plt.tight_layout()\n", " plt.show()\n", "\n", "# Widgets erstellen\n", "dropdown_rule = widgets.Dropdown(\n", " options=['Kombination', 'Permutation', 'Fakultät', 'Binomialkoeffizient', 'Variation', 'Mehrfachkombination'],\n", " value='Kombination',\n", " description='Regel:',\n", " style={'description_width': 'initial'}\n", ")\n", "\n", "input_n = widgets.IntText(value=5, description='n:', style={'description_width': 'initial'})\n", "input_k = widgets.IntText(value=2, description='k:', style={'description_width': 'initial'})\n", "input_k.layout.visibility = 'visible' # Standardmäßig sichtbar\n", "\n", "output_area = widgets.Output()\n", "\n", "# Button zum Berechnen\n", "button = widgets.Button(description='Berechnen & Visualisieren')\n", "\n", "# Callback-Funktion\n", "def on_button_click(b):\n", " with output_area:\n", " clear_output()\n", " rule = dropdown_rule.value\n", " n = input_n.value\n", " k = input_k.value if rule in ['Kombination', 'Permutation', 'Binomialkoeffizient', 'Variation', 'Mehrfachkombination'] else None\n", "\n", " try:\n", " if rule == 'Kombination':\n", " if k > n:\n", " print(\"k darf nicht größer als n sein.\")\n", " return\n", " res = combination(n, k)\n", " display(Math(r\"C(n,k) = \\binom{{{}}}{{{}}} = {}\".format(n, k, res)))\n", " draw_tree(n, k, is_perm=False)\n", " elif rule == 'Permutation':\n", " if k > n:\n", " print(\"k darf nicht größer als n sein.\")\n", " return\n", " res = permutation(n, k)\n", " display(Math(r\"P(n,k) = {} = {}\".format(res, res)))\n", " draw_tree(n, k, is_perm=True)\n", " elif rule == 'Fakultät':\n", " res = factorial(n)\n", " display(Math(r\"n! = {} = {}\".format(res, res)))\n", " elif rule == 'Binomialkoeffizient':\n", " if k > n:\n", " print(\"k darf nicht größer als n sein.\")\n", " return\n", " res = binomial_coefficient(n, k)\n", " display(Math(r\"\\binom{{{}}}{{{}}} = {}\".format(n, k, res)))\n", " elif rule == 'Variation':\n", " if k > n:\n", " print(\"k darf nicht größer als n sein.\")\n", " return\n", " res = variation(n, k)\n", " display(Math(r\"V(n,k) = P(n,k) = {} = {}\".format(res, res)))\n", " elif rule == 'Mehrfachkombination':\n", " res = multiset_combination(n, k)\n", " display(Math(r\"\\binom{{n+k-1}}{{k}} = {} = {}\".format(res, res)))\n", " else:\n", " print(\"Unbekannte Regel.\")\n", " except Exception as e:\n", " print(f\"Fehler: {e}\")\n", "\n", "# Event verknüpfen\n", "button.on_click(on_button_click)\n", "\n", "# Anpassung der sichtbaren Eingabefelder basierend auf der gewählten Regel\n", "def on_rule_change(change):\n", " rule = change['new']\n", " if rule in ['Kombination', 'Permutation', 'Binomialkoeffizient', 'Variation', 'Mehrfachkombination']:\n", " input_k.layout.visibility = 'visible'\n", " else:\n", " input_k.layout.visibility = 'hidden'\n", "\n", "dropdown_rule.observe(on_rule_change, names='value')\n", "\n", "# Anzeige\n", "controls = widgets.VBox([\n", " widgets.HBox([dropdown_rule]),\n", " widgets.HBox([input_n, input_k]),\n", " button,\n", " output_area\n", "])\n", "display(controls)\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7" } }, "nbformat": 4, "nbformat_minor": 2 }