commit b0f1a49375aea6e8e4934e67050a0db32f434ec1 Author: Alexander Kimmig Date: Mon Jun 2 21:35:39 2025 +0000 Anfang diff --git a/01 Einführung/.ipynb_checkpoints/Untitled-checkpoint.ipynb b/01 Einführung/.ipynb_checkpoints/Untitled-checkpoint.ipynb new file mode 100644 index 0000000..061f18e --- /dev/null +++ b/01 Einführung/.ipynb_checkpoints/Untitled-checkpoint.ipynb @@ -0,0 +1,592 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 5, + "id": "e47a5d17-b891-49bd-9326-67a7d55b848b", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import { assertEquals } from \"jsr:@std/assert\";" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "cea43bc6-51c7-4e2a-9772-026925624173", + "metadata": {}, + "outputs": [], + "source": [ + "const x = 1 + 2;" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "95652cce-ec3b-441d-99d1-9916574648bd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "simple test ... \u001b[0m\u001b[32mok\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[32mok\u001b[0m | 1 passed | 0 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"simple test\", () => {\n", + " assertEquals(x, 3);\n", + "});" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "3566a6a9-3fdb-44af-ab02-f85d9cad7790", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import pl from \"npm:nodejs-polars\";\n", + "import { display } from \"https://deno.land/x/display@v0.1.1/mod.ts\";" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "4208a600-9873-49b6-b4ca-a3ecbdca6093", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.dataresource+json": { + "data": [ + { + "ActualExpenses": 270, + "ActualIncome": 340, + "BudgetExpenses": 264, + "BudgetIncome": 332, + "Consulting": 2, + "Date": "2022-06-18", + "DiffExpenses": -6, + "DiffIncome": -8, + "Equipment": 44, + "Expenses": 270, + "Hardware": 9, + "Income": 340, + "Marketing": 47, + "NetIncome": 70, + "Office Supplies": 6, + "R&D": 44, + "Rent": 33, + "Salaries": 39, + "Software": 8, + "Utilities": 38 + }, + { + "ActualExpenses": 265, + "ActualIncome": 401, + "BudgetExpenses": 266, + "BudgetIncome": 403, + "Consulting": 3, + "Date": "2022-03-16", + "DiffExpenses": 1, + "DiffIncome": 2, + "Equipment": 41, + "Expenses": 265, + "Hardware": 7, + "Income": 401, + "Marketing": 40, + "NetIncome": 136, + "Office Supplies": 5, + "R&D": 32, + "Rent": 48, + "Salaries": 42, + "Software": 3, + "Utilities": 44 + }, + { + "ActualExpenses": 213, + "ActualIncome": 192, + "BudgetExpenses": 210, + "BudgetIncome": 189, + "Consulting": 7, + "Date": "2022-05-07", + "DiffExpenses": -3, + "DiffIncome": -3, + "Equipment": 25, + "Expenses": 213, + "Hardware": 3, + "Income": 192, + "Marketing": 26, + "NetIncome": -21, + "Office Supplies": 5, + "R&D": 28, + "Rent": 38, + "Salaries": 46, + "Software": 4, + "Utilities": 31 + }, + { + "ActualExpenses": 238, + "ActualIncome": 291, + "BudgetExpenses": 233, + "BudgetIncome": 296, + "Consulting": 4, + "Date": "2022-07-09", + "DiffExpenses": -5, + "DiffIncome": 5, + "Equipment": 22, + "Expenses": 238, + "Hardware": 9, + "Income": 291, + "Marketing": 32, + "NetIncome": 53, + "Office Supplies": 2, + "R&D": 37, + "Rent": 48, + "Salaries": 34, + "Software": 4, + "Utilities": 46 + }, + { + "ActualExpenses": 239, + "ActualIncome": 262, + "BudgetExpenses": 242, + "BudgetIncome": 268, + "Consulting": 9, + "Date": "2022-06-22", + "DiffExpenses": 3, + "DiffIncome": 6, + "Equipment": 30, + "Expenses": 239, + "Hardware": 4, + "Income": 262, + "Marketing": 36, + "NetIncome": 23, + "Office Supplies": 8, + "R&D": 24, + "Rent": 40, + "Salaries": 48, + "Software": 3, + "Utilities": 37 + }, + { + "ActualExpenses": 237, + "ActualIncome": 299, + "BudgetExpenses": 242, + "BudgetIncome": 292, + "Consulting": 8, + "Date": "2022-03-31", + "DiffExpenses": 5, + "DiffIncome": -7, + "Equipment": 48, + "Expenses": 237, + "Hardware": 7, + "Income": 299, + "Marketing": 33, + "NetIncome": 62, + "Office Supplies": 6, + "R&D": 20, + "Rent": 48, + "Salaries": 30, + "Software": 8, + "Utilities": 29 + }, + { + "ActualExpenses": 237, + "ActualIncome": 284, + "BudgetExpenses": 245, + "BudgetIncome": 293, + "Consulting": 7, + "Date": "2022-02-24", + "DiffExpenses": 8, + "DiffIncome": 9, + "Equipment": 37, + "Expenses": 237, + "Hardware": 3, + "Income": 284, + "Marketing": 41, + "NetIncome": 47, + "Office Supplies": 9, + "R&D": 38, + "Rent": 41, + "Salaries": 24, + "Software": 1, + "Utilities": 36 + }, + { + "ActualExpenses": 200, + "ActualIncome": 269, + "BudgetExpenses": 200, + "BudgetIncome": 270, + "Consulting": 8, + "Date": "2022-05-30", + "DiffExpenses": 0, + "DiffIncome": 1, + "Equipment": 26, + "Expenses": 200, + "Hardware": 7, + "Income": 269, + "Marketing": 32, + "NetIncome": 69, + "Office Supplies": 8, + "R&D": 25, + "Rent": 21, + "Salaries": 49, + "Software": 2, + "Utilities": 22 + }, + { + "ActualExpenses": 250, + "ActualIncome": 304, + "BudgetExpenses": 248, + "BudgetIncome": 316, + "Consulting": 1, + "Date": "2022-03-23", + "DiffExpenses": -2, + "DiffIncome": 12, + "Equipment": 42, + "Expenses": 250, + "Hardware": 7, + "Income": 304, + "Marketing": 30, + "NetIncome": 54, + "Office Supplies": 2, + "R&D": 49, + "Rent": 48, + "Salaries": 39, + "Software": 2, + "Utilities": 30 + }, + { + "ActualExpenses": 214, + "ActualIncome": 182, + "BudgetExpenses": 213, + "BudgetIncome": 185, + "Consulting": 8, + "Date": "2022-05-28", + "DiffExpenses": -1, + "DiffIncome": 3, + "Equipment": 38, + "Expenses": 214, + "Hardware": 2, + "Income": 182, + "Marketing": 32, + "NetIncome": -32, + "Office Supplies": 2, + "R&D": 27, + "Rent": 36, + "Salaries": 21, + "Software": 5, + "Utilities": 43 + } + ], + "schema": { + "fields": [ + { + "name": "Date", + "type": "string" + }, + { + "name": "Income", + "type": "integer" + }, + { + "name": "Expenses", + "type": "integer" + }, + { + "name": "NetIncome", + "type": "integer" + }, + { + "name": "BudgetIncome", + "type": "integer" + }, + { + "name": "ActualIncome", + "type": "integer" + }, + { + "name": "BudgetExpenses", + "type": "integer" + }, + { + "name": "ActualExpenses", + "type": "integer" + }, + { + "name": "Salaries", + "type": "integer" + }, + { + "name": "R&D", + "type": "integer" + }, + { + "name": "Marketing", + "type": "integer" + }, + { + "name": "Utilities", + "type": "integer" + }, + { + "name": "Rent", + "type": "integer" + }, + { + "name": "Equipment", + "type": "integer" + }, + { + "name": "Software", + "type": "integer" + }, + { + "name": "Hardware", + "type": "integer" + }, + { + "name": "Consulting", + "type": "integer" + }, + { + "name": "Office Supplies", + "type": "integer" + }, + { + "name": "DiffIncome", + "type": "integer" + }, + { + "name": "DiffExpenses", + "type": "integer" + } + ] + } + }, + "text/html": [ + "
DateIncomeExpensesNetIncomeBudgetIncomeActualIncomeBudgetExpensesActualExpensesSalariesR&DMarketingUtilitiesRentEquipmentSoftwareHardwareConsultingOffice SuppliesDiffIncomeDiffExpenses
2022-06-18340270703323402642703944473833448926-8-6
2022-03-16401265136403401266265423240444841373521
2022-05-07192213-211891922102134628263138254375-3-3
2022-07-092912385329629123323834373246482249425-5
2022-06-2226223923268262242239482436374030349863
2022-03-31299237622922992422373020332948488786-75
2022-02-2428423747293284245237243841364137137998
2022-05-3026920069270269200200492532222126278810
2022-03-2330425054316304248250394930304842271212-2
2022-05-28182214-3218518221321421273243363852823-1
" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let response = await fetch(\n", + " \"https://gist.githubusercontent.com/agustinustheo/195f32a4a6c68c493056c883d959ca35/raw/c7363d8b916ab00a2d1747adb89fca120da29f42/mock_financial_data.csv\",\n", + ");\n", + "\n", + "let data = await response.text();\n", + "\n", + "let df = pl.readCSV(data, { sep: \",\" });\n", + "\n", + "await display(df.sample(10));" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "e5132db2-735b-4f81-9511-8e9c868bbcb2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32mDownloading\u001b[39m https://github.com/DjDeveloperr/skia_canvas/releases/download/0.5.8/libnative_canvas.so\n" + ] + } + ], + "source": [ + "import * as d3 from \"npm:d3\";\n", + "import { createCanvas } from \"https://deno.land/x/skia_canvas/mod.ts\";" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "3f54f383-1e48-431d-926b-897c54d38601", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " Date: \"2022-07-19\",\n", + " Income: 316,\n", + " Expenses: 211,\n", + " NetIncome: 105,\n", + " BudgetIncome: 317,\n", + " ActualIncome: 316,\n", + " BudgetExpenses: 212,\n", + " ActualExpenses: 211,\n", + " Salaries: 29,\n", + " \"R&D\": 48,\n", + " Marketing: 20,\n", + " Utilities: 35,\n", + " Rent: 22,\n", + " Equipment: 39,\n", + " Software: 3,\n", + " Hardware: 3,\n", + " Consulting: 6,\n", + " \"Office Supplies\": 6,\n", + " DiffIncome: 1,\n", + " DiffExpenses: 1\n", + "}\n" + ] + } + ], + "source": [ + "const lastDataPoint = df.tail(1).toRecords()[0];\n", + "console.log(lastDataPoint);" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "be1d2f7c-5537-4428-ab94-3410d9b07cc1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[33m10\u001b[39m" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let categories = ['Salaries', 'R&D', 'Marketing', 'Utilities', 'Rent', 'Equipment', 'Software', 'Hardware', 'Consulting', 'Office Supplies'];\n", + "\n", + "// Sample data\n", + "const sampleData1 = [];\n", + "for(let i = 0; i < categories.length; i++) {\n", + " const category = categories[i];\n", + " sampleData1.push({\n", + " category,\n", + " amount: lastDataPoint[category],\n", + " });\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "9e6414d0-3b56-438c-be30-74080dbd706a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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" + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "const width = 500;\n", + "const height = 500;\n", + "const radius = Math.min(width, height) / 2;\n", + "\n", + "// Create a pie function\n", + "const pie = d3.pie().value(d => d.amount);\n", + "\n", + "// Create an arc generator for the slices\n", + "const arc = d3.arc()\n", + " .innerRadius(0)\n", + " .outerRadius(radius);\n", + "\n", + "// Create an arc generator for the labels\n", + "const labelArc = d3.arc()\n", + " .innerRadius(radius - 40) // Adjust to position the labels\n", + " .outerRadius(radius - 40);\n", + "\n", + "// Create the canvas\n", + "const canvas = createCanvas(width, height);\n", + "const ctx = canvas.getContext(\"2d\");\n", + "\n", + "// Translate to center the pie chart\n", + "ctx.translate(width / 2, height / 2);\n", + "\n", + "// Draw the pie chart\n", + "pie(sampleData1).forEach((d, i) => {\n", + " // Draw the slice\n", + " ctx.beginPath();\n", + " arc.context(ctx)(d);\n", + " ctx.fillStyle = d3.schemeCategory10[i % 10];\n", + " ctx.fill();\n", + "\n", + " // Draw the label\n", + " ctx.fillStyle = \"#000\"; // Label color\n", + " ctx.textAlign = \"center\";\n", + " ctx.textBaseline = \"middle\";\n", + "\n", + " const centroid = labelArc.centroid(d);\n", + " ctx.fillText(d.data.category, centroid[0], centroid[1]);\n", + "});\n", + "\n", + "// Display the canvas\n", + "await display(canvas);" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e511a773-aab3-4525-a63e-a2ba90b3f85e", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + }, + "toc": { + "base_numbering": 1 + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/.ipynb_checkpoints/Untitled1-checkpoint.ipynb b/01 Einführung/.ipynb_checkpoints/Untitled1-checkpoint.ipynb new file mode 100644 index 0000000..363fcab --- /dev/null +++ b/01 Einführung/.ipynb_checkpoints/Untitled1-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/01 Variablen/.ipynb_checkpoints/01 Einführung-checkpoint.ipynb b/01 Einführung/01 Variablen/.ipynb_checkpoints/01 Einführung-checkpoint.ipynb new file mode 100644 index 0000000..fe364a5 --- /dev/null +++ b/01 Einführung/01 Variablen/.ipynb_checkpoints/01 Einführung-checkpoint.ipynb @@ -0,0 +1,233 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d5c00cd0-b48b-467e-9276-0356d2ccffdb", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Variablen\n", + "Anders als bei Java müssen Datentypen in TypeScript nicht explizit angegeben werden. Besserer Programmierstil ist jedoch, wenn wir die Typen trotzdem mit angeben. Die Schreibweise hierzu ist jedoch an der UML-Schreibweise angelegt:\n", + "\n", + "Wir kennen von Java bereits:\n", + "`int a = 5`\n", + "\n", + "Demgegenüber bei TypeScript:\n", + "`let a: number = 5`\n", + "\n", + "Wie in der Einführung bereits geschrieben, wird TypeScript immer in JavaScript übersetzt und dann erst ausgeführt. Dadurch, dass JavaScript jedoch keine statische Typisierung von Variablen kennt, können wir den Datentyp prinzipiell auch weglassen.\n", + "\n", + "Programmiert jedoch ein größeres Projekt in einer richtigen Entwicklungsumgebung, so helfen Typen dabei, Fehler frühzeitig zu erkennen! Wir werden in aller Regel deshalb auch hier den Datentyp mit dazu schreiben!" + ] + }, + { + "cell_type": "markdown", + "id": "c96b5908-744c-49e8-b705-02fae696b6fe", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Variablentypen\n", + "neben `let` gibt es auch noch die Schlüsselwörter `const` sowie `var`. Der Unterschiede bestehen darin:\n", + "* `var`: ähnlich wie `let`, jedoch ist der Geltungsbereich etwas \"gewöhnungsbedürftig\". So kann innerhalb eines Blocks eine Variable, die außerhalb mit `var` angelegt wurde nicht neu angelegt werden.\n", + "* `let`: Verahlten, wie man es z.B. von Java gewohnt ist. Wird eine Variable mit `let` in einem Block neu definiert, so wird eine neue Variable angelegt. Will man stattdessen den Wert der außerhalb definierten Variable ändern, so lässt man das Schlüsselwort `let` weg.\n", + "* `const`: Wie `let`, jedoch kann der Wert der \"Variablen\" nicht mehr geändert werden." + ] + }, + { + "cell_type": "markdown", + "id": "1406f526-923c-40a6-bb87-422e50a5899b", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel für `var`:\n", + "Hier wird außerhalb des `if`-Blocks eine Variable `hallo` angelegt. Innerhalb des Blocks wird die `hallo`-Variable neu zugewiesen. In der Ausgabe wird deshalb zunächst `Hallo` und anschließend zwei mal `Tschüss` ausgegeben.\n", + "\n", + "Bei der Variablen `greeter` wird trotz Angabe des Schlüsselwortes `var` innerhalb des `if`-Blocks keine neue Variable angelegt sondern ebenfalls der Wert der äußeren Variablen `greeter` verändert. Die Ausgabe ist deshalb ebenfalls zunächst `Hello`, anschließend beide male `Goodbye`." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "4dd26396-d818-4ea4-829a-92c193012890", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hallo Hello\n", + "Tschüss Goodbye\n", + "Tschüss Goodbye\n" + ] + } + ], + "source": [ + "var hallo = \"Hallo\";\n", + "var greeter = \"Hello\";\n", + "console.log(hallo, greeter); // Ausgabe: \"Hallo Hello\"\n", + "var times = 4;\n", + "\n", + "if (times > 3) {\n", + " hallo = \"Tschüss\";\n", + " var greeter = \"Goodbye\";\n", + " console.log(hallo, greeter); // Ausgabe: \"Tschüss Goodbye\"\n", + "}\n", + "\n", + "console.log(hallo, greeter); // Ausgabe: \"Tschüss Goodbye\"" + ] + }, + { + "cell_type": "markdown", + "id": "4343607c-7165-4236-b2b3-bd03526a6b3b", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel für `let`:\n", + "Hier wird außerhalb des `if`-Blocks eine Variable `hallo2` angelegt. Innerhalb des Blocks wird die `hallo2`-Variable neu zugewiesen. In der Ausgabe wird deshalb zunächst `Hallo` und anschließend zwei mal `Tschüss` ausgegeben.\n", + "\n", + "Bei der Variablen `greeter2` wird durch die Angabe des Schlüsselwortes `let` innerhalb des `if`-Blocks eine neue Variable angelegt. Die Ausgabe ist deshalb ebenfalls zunächst `Hello`, anschließend `Goodbye`. Da die Variable `greeter2` in dem `if`-Block neu angelegt wurde und nur dort gültig ist, wird nach dem Block wieder auf die ursprüngliche Variable zugegriffen und wieder `Hello` ausgegeben." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "d1fad4da-b713-4ca5-a7b8-34401b078883", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hallo Hello\n", + "Tschüss Goodbye\n", + "Tschüss Hello\n" + ] + } + ], + "source": [ + "let hallo2 = \"Hallo\";\n", + "let greeter2 = \"Hello\";\n", + "console.log(hallo2, greeter2); // Ausgabe: \"Hallo Hello\"\n", + "let times2 = 4;\n", + "\n", + "if (times > 3) {\n", + " hallo2 = \"Tschüss\";\n", + " let greeter2 = \"Goodbye\";\n", + " console.log(hallo2, greeter2); // Ausgabe: \"Tschüss Goodbye\"\n", + "}\n", + "\n", + "console.log(hallo2, greeter2); // Ausgabe: \"Tschüss Goodbye\"" + ] + }, + { + "cell_type": "markdown", + "id": "51652a7d-dc22-4244-8823-3babfc29a1c8", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel für `const`:\n", + "Wird eine \"Variable\" mit `const` angelegt, so verhält sie sich bzgl. dem Geltungsbereich wie `let`. Jedoch lässt sich der direkt Inhalt nicht mehr ändern.\n", + "\n", + "*Anmerkung: ist der Inhalt dieser Variablen ein Array oder ein Objekt, so lassen sich die Inhalte davon weiterhin ändern. Dazu später mehr.*" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "39b662d7-ab11-4628-865d-abe4cdc6e6cd", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "Assignment to constant variable.", + "output_type": "error", + "traceback": [ + "Stack trace:", + "TypeError: Assignment to constant variable.", + " at :2:8" + ] + } + ], + "source": [ + "const hallo3 = \"Hallo\";\n", + "hallo3 = \"Tschüss\"; // funktioniert nicht, da \"hallo3\" konstant!" + ] + }, + { + "cell_type": "markdown", + "id": "ff6bd7f3-5020-4358-a66b-5836ed36dae5", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Regel für den Unterricht:\n", + "**Wir werden kein `var` verwenden! Wir verwenden in aller Regel `let` oder alternativ, wenn sich nichts direkt ändern soll `const`**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/01 Variablen/.ipynb_checkpoints/02 Übungen-checkpoint.ipynb b/01 Einführung/01 Variablen/.ipynb_checkpoints/02 Übungen-checkpoint.ipynb new file mode 100644 index 0000000..b10f85f --- /dev/null +++ b/01 Einführung/01 Variablen/.ipynb_checkpoints/02 Übungen-checkpoint.ipynb @@ -0,0 +1,197 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "636d4527-50fc-4836-ae08-00c12844da8d", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import { assertEquals } from \"jsr:@std/assert\"" + ] + }, + { + "cell_type": "markdown", + "id": "d90b7734-c902-4300-80ef-d8bf55a64813", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.01.1\n", + "Deklariere eine Variable `vorname` und initialisiere sie mit dem Wert `'Franz'`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "594735d3-e90e-443e-9eff-e4600c331bc2", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "245aec76-71a6-478e-9301-08ca4e14ff71", + "metadata": { + "collapsed": true, + "editable": false, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "Test" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A1: vorname ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "A1: vorname \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: vorname is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m16\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "A1: vorname \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 1 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"A1: vorname\", () => {\n", + " assertEquals(vorname, 'Franz')\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "9eb66210-476a-499e-8965-9c63da2de3e7", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.01.2\n", + "Deklariere eine Variable `blume` und weise ihr den Wert `'Rose'` zu.\n", + "\n", + "Deklariere eine zweite Variable `tier` und weise ihr den Wert `'Käfer'` zu." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7daea9ea-3417-48d9-9416-3462cc38f8bc", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "4f710df6-8465-4da1-a997-4e34ea80d6ed", + "metadata": { + "collapsed": true, + "editable": false, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "Test" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A2: blume ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "A2: tier ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "A2: blume \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: blume is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m16\u001b[0m\n", + "\n", + "A2: tier \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: tier is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m16\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "A2: blume \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "A2: tier \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 2 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"A2: blume\", () => {\n", + " assertEquals(blume, 'Rose')\n", + "})\n", + "Deno.test(\"A2: tier\", () => {\n", + " assertEquals(tier, 'Käfer')\n", + "})" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/01 Variablen/01 Einführung.ipynb b/01 Einführung/01 Variablen/01 Einführung.ipynb new file mode 100644 index 0000000..2e29d66 --- /dev/null +++ b/01 Einführung/01 Variablen/01 Einführung.ipynb @@ -0,0 +1,263 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d5c00cd0-b48b-467e-9276-0356d2ccffdb", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Variablen\n", + "Anders als bei Java müssen Datentypen in TypeScript nicht explizit angegeben werden. Besserer Programmierstil ist jedoch, wenn wir die Typen trotzdem mit angeben. Die Schreibweise hierzu ist jedoch an der UML-Schreibweise angelegt:\n", + "\n", + "Wir kennen von Java bereits:\n", + "`int a = 5`\n", + "\n", + "Demgegenüber bei TypeScript:\n", + "`let a: number = 5`\n", + "\n", + "Wie in der Einführung bereits geschrieben, wird TypeScript immer in JavaScript übersetzt und dann erst ausgeführt. Dadurch, dass JavaScript jedoch keine statische Typisierung von Variablen kennt, können wir den Datentyp prinzipiell auch weglassen.\n", + "\n", + "Programmiert jedoch ein größeres Projekt in einer richtigen Entwicklungsumgebung, so helfen Typen dabei, Fehler frühzeitig zu erkennen! Wir werden in aller Regel deshalb auch hier den Datentyp mit dazu schreiben!" + ] + }, + { + "cell_type": "markdown", + "id": "67bb7709-852f-480b-80ab-a6b5b0194037", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Datentypen in TypeScript\n", + "Bei TypeScript gibt es im Wesentlichen folgende Datentypen:\n", + "* `string`: Entspricht dem Java-Datentyp `String`, dieser kann Zeichenketten aufnehmen\n", + "* `number`: Im Gegensatz zu Java unterscheidet TypeScript z.B. nicht, um welche Zahltypen (ganze Zahlen/Kommazahlen) es sich handelt. `number` steht allgemein für eine Zahl\n", + "* `boolean`: Wahrheitswerte `true` bzw `false`\n", + "\n", + "Wird eine Variable gleichzeitig deklariert (= angelegt) als auch initialisiert (= Wert zugewiesen) so kann hier auf eine Angabe des Datentyps verzichtet werden, da TypeScript dann automatisch den Datentyp ableitet.\n", + "\n", + "Soll beispielsweise bei einem Funktions-Parameter der Datentyp variabel sein bzw alle möglichen Werte angenommen werden können, so kann als Datentyp `any` genutzt werden.\n", + "\n", + "### Beispiel:\n", + "\n", + "```\n", + "let x = \"Hallo\";\n", + "```\n", + "\n", + "`x` hat hier automatisch den Datentyp `string`." + ] + }, + { + "cell_type": "markdown", + "id": "c96b5908-744c-49e8-b705-02fae696b6fe", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Variablentypen\n", + "neben `let` gibt es auch noch die Schlüsselwörter `const` sowie `var`. Der Unterschiede bestehen darin:\n", + "* `var`: ähnlich wie `let`, jedoch ist der Geltungsbereich etwas \"gewöhnungsbedürftig\". So kann innerhalb eines Blocks eine Variable, die außerhalb mit `var` angelegt wurde nicht neu angelegt werden.\n", + "* `let`: Verahlten, wie man es z.B. von Java gewohnt ist. Wird eine Variable mit `let` in einem Block neu definiert, so wird eine neue Variable angelegt. Will man stattdessen den Wert der außerhalb definierten Variable ändern, so lässt man das Schlüsselwort `let` weg.\n", + "* `const`: Wie `let`, jedoch kann der Wert der \"Variablen\" nicht mehr geändert werden." + ] + }, + { + "cell_type": "markdown", + "id": "1406f526-923c-40a6-bb87-422e50a5899b", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel für `var`:\n", + "Hier wird außerhalb des `if`-Blocks eine Variable `hallo` angelegt. Innerhalb des Blocks wird die `hallo`-Variable neu zugewiesen. In der Ausgabe wird deshalb zunächst `Hallo` und anschließend zwei mal `Tschüss` ausgegeben.\n", + "\n", + "Bei der Variablen `greeter` wird trotz Angabe des Schlüsselwortes `var` innerhalb des `if`-Blocks keine neue Variable angelegt sondern ebenfalls der Wert der äußeren Variablen `greeter` verändert. Die Ausgabe ist deshalb ebenfalls zunächst `Hello`, anschließend beide male `Goodbye`." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "4dd26396-d818-4ea4-829a-92c193012890", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hallo Hello\n", + "Tschüss Goodbye\n", + "Tschüss Goodbye\n" + ] + } + ], + "source": [ + "var hallo = \"Hallo\";\n", + "var greeter = \"Hello\";\n", + "console.log(hallo, greeter); // Ausgabe: \"Hallo Hello\"\n", + "var times = 4;\n", + "\n", + "if (times > 3) {\n", + " hallo = \"Tschüss\";\n", + " var greeter = \"Goodbye\";\n", + " console.log(hallo, greeter); // Ausgabe: \"Tschüss Goodbye\"\n", + "}\n", + "\n", + "console.log(hallo, greeter); // Ausgabe: \"Tschüss Goodbye\"" + ] + }, + { + "cell_type": "markdown", + "id": "4343607c-7165-4236-b2b3-bd03526a6b3b", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel für `let`:\n", + "Hier wird außerhalb des `if`-Blocks eine Variable `hallo2` angelegt. Innerhalb des Blocks wird die `hallo2`-Variable neu zugewiesen. In der Ausgabe wird deshalb zunächst `Hallo` und anschließend zwei mal `Tschüss` ausgegeben.\n", + "\n", + "Bei der Variablen `greeter2` wird durch die Angabe des Schlüsselwortes `let` innerhalb des `if`-Blocks eine neue Variable angelegt. Die Ausgabe ist deshalb ebenfalls zunächst `Hello`, anschließend `Goodbye`. Da die Variable `greeter2` in dem `if`-Block neu angelegt wurde und nur dort gültig ist, wird nach dem Block wieder auf die ursprüngliche Variable zugegriffen und wieder `Hello` ausgegeben." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "d1fad4da-b713-4ca5-a7b8-34401b078883", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hallo Hello\n", + "Tschüss Goodbye\n", + "Tschüss Hello\n" + ] + } + ], + "source": [ + "let hallo2 = \"Hallo\";\n", + "let greeter2 = \"Hello\";\n", + "console.log(hallo2, greeter2); // Ausgabe: \"Hallo Hello\"\n", + "let times2 = 4;\n", + "\n", + "if (times > 3) {\n", + " hallo2 = \"Tschüss\";\n", + " let greeter2 = \"Goodbye\";\n", + " console.log(hallo2, greeter2); // Ausgabe: \"Tschüss Goodbye\"\n", + "}\n", + "\n", + "console.log(hallo2, greeter2); // Ausgabe: \"Tschüss Goodbye\"" + ] + }, + { + "cell_type": "markdown", + "id": "51652a7d-dc22-4244-8823-3babfc29a1c8", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel für `const`:\n", + "Wird eine \"Variable\" mit `const` angelegt, so verhält sie sich bzgl. dem Geltungsbereich wie `let`. Jedoch lässt sich der direkt Inhalt nicht mehr ändern.\n", + "\n", + "*Anmerkung: ist der Inhalt dieser Variablen ein Array oder ein Objekt, so lassen sich die Inhalte davon weiterhin ändern. Dazu später mehr.*" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "39b662d7-ab11-4628-865d-abe4cdc6e6cd", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "Assignment to constant variable.", + "output_type": "error", + "traceback": [ + "Stack trace:", + "TypeError: Assignment to constant variable.", + " at :2:8" + ] + } + ], + "source": [ + "const hallo3 = \"Hallo\";\n", + "hallo3 = \"Tschüss\"; // funktioniert nicht, da \"hallo3\" konstant!" + ] + }, + { + "cell_type": "markdown", + "id": "ff6bd7f3-5020-4358-a66b-5836ed36dae5", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Regel für den Unterricht:\n", + "**Wir werden kein `var` verwenden! Wir verwenden in aller Regel `let` oder alternativ, wenn sich nichts direkt ändern soll `const`**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/01 Variablen/02 Übungen.ipynb b/01 Einführung/01 Variablen/02 Übungen.ipynb new file mode 100644 index 0000000..b10f85f --- /dev/null +++ b/01 Einführung/01 Variablen/02 Übungen.ipynb @@ -0,0 +1,197 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "636d4527-50fc-4836-ae08-00c12844da8d", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import { assertEquals } from \"jsr:@std/assert\"" + ] + }, + { + "cell_type": "markdown", + "id": "d90b7734-c902-4300-80ef-d8bf55a64813", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.01.1\n", + "Deklariere eine Variable `vorname` und initialisiere sie mit dem Wert `'Franz'`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "594735d3-e90e-443e-9eff-e4600c331bc2", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "245aec76-71a6-478e-9301-08ca4e14ff71", + "metadata": { + "collapsed": true, + "editable": false, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "Test" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A1: vorname ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "A1: vorname \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: vorname is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m16\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "A1: vorname \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 1 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"A1: vorname\", () => {\n", + " assertEquals(vorname, 'Franz')\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "9eb66210-476a-499e-8965-9c63da2de3e7", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.01.2\n", + "Deklariere eine Variable `blume` und weise ihr den Wert `'Rose'` zu.\n", + "\n", + "Deklariere eine zweite Variable `tier` und weise ihr den Wert `'Käfer'` zu." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7daea9ea-3417-48d9-9416-3462cc38f8bc", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "4f710df6-8465-4da1-a997-4e34ea80d6ed", + "metadata": { + "collapsed": true, + "editable": false, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "Test" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A2: blume ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "A2: tier ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "A2: blume \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: blume is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m16\u001b[0m\n", + "\n", + "A2: tier \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: tier is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m16\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "A2: blume \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "A2: tier \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 2 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"A2: blume\", () => {\n", + " assertEquals(blume, 'Rose')\n", + "})\n", + "Deno.test(\"A2: tier\", () => {\n", + " assertEquals(tier, 'Käfer')\n", + "})" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/02 Funktionen/.ipynb_checkpoints/01 Einführung-checkpoint.ipynb b/01 Einführung/02 Funktionen/.ipynb_checkpoints/01 Einführung-checkpoint.ipynb new file mode 100644 index 0000000..d895829 --- /dev/null +++ b/01 Einführung/02 Funktionen/.ipynb_checkpoints/01 Einführung-checkpoint.ipynb @@ -0,0 +1,163 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e61302c1-61b9-43e6-9faf-340c6f63eeb5", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Funktionen" + ] + }, + { + "cell_type": "markdown", + "id": "91c5bfe0-c800-425e-95a5-3ba858172eac", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Grundlegendes\n", + "Eine Funktion ist ein Block von Anweisungen, der beliebig oft ausgeführt werden kann." + ] + }, + { + "cell_type": "markdown", + "id": "1d2ca0b1-ee23-4835-9a19-d1e0ca566475", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel 1: einfache Funktion\n", + "Hier wird eine einfache Funktion `hallo` definiert und anschließend zwei Mal ausgeführt." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "5cbd4fea-aa4c-4132-b6a5-600477bbe9aa", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hallo Welt!\n", + "Hallo Welt!\n" + ] + } + ], + "source": [ + "function hallo() {\n", + " console.log(\"Hallo Welt!\");\n", + "}\n", + "\n", + "hallo(); // Aufruf der Funktion\n", + "hallo(); // zweiter Aufruf" + ] + }, + { + "cell_type": "markdown", + "id": "8199e2d4-a3ec-4c9e-9c33-f0562de760d8", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Rückgabe\n", + "Eine Funktion kann nicht nur dafür verwendet werden, bestimmte Befehlsabfolgen auszuführen, sie kann auch ein Ergebnis zurückliefern. Dieses Ergebnis kann anschließend z.B. in einer Variablen gespeichert und weiterverwendet werden.\n", + "\n", + "Bei einer Funktion mit Rückgabe sollte der Rückgabe-Datentyp bei der Funktionsdefinition mit angegeben werden.\n", + "\n", + "Das Schlüsselwort `return` gibt den nachfolgenden Wert zurück und bricht gleichzeitig auch die Funktion ab!" + ] + }, + { + "cell_type": "markdown", + "id": "c3014407-d02c-41c7-bfe6-30177d95d71b", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel 2: Funktion mit Rückgabewert\n", + "Hier wird die Funktion `hallo` definiert, die einen `string` zurückgibt.\n", + "\n", + "Mit `return \"Hallo Welt!\";` wird dann dieser String zurückgegeben." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "7ea0e464-e3b7-43fb-807b-90f8232d4feb", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hallo Welt!\n" + ] + } + ], + "source": [ + "function hallo(): string {\n", + " return \"Hallo Welt!\"; // hier wird \"Hallo Welt!\" zurückgegeben und die Funktion abgebrochen\n", + "\n", + " console.log(\"Keine Ausgabe\"); // diese Ausgabe findet nie statt, da zuvor bereits mit `return` abgebrochen wird\n", + "}\n", + "\n", + "let s: string = hallo(); // Funktion `hallo` wird aufgerufen und das Ergebnis in der Variablen s gespeichert\n", + "console.log(s); // Inhalt der Variablen `s` ausgeben" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/02 Funktionen/.ipynb_checkpoints/02 Übungen-checkpoint.ipynb b/01 Einführung/02 Funktionen/.ipynb_checkpoints/02 Übungen-checkpoint.ipynb new file mode 100644 index 0000000..5fc9da4 --- /dev/null +++ b/01 Einführung/02 Funktionen/.ipynb_checkpoints/02 Übungen-checkpoint.ipynb @@ -0,0 +1,273 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "4fbccfbc-2e07-4214-a665-4b13afb2723e", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import { assertEquals } from \"jsr:@std/assert\";" + ] + }, + { + "cell_type": "markdown", + "id": "86eb640a-2c5b-4498-90d7-774984742f45", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.02.1\n", + "Definiere eine Funktion `hallo`, die `'Hallo Welt!'` zurückgibt." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "90e1aef5-ac02-45a6-9f98-3c812ed506f0", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "a6e2ef7a-6785-44b4-be55-55ef733320bd", + "metadata": { + "collapsed": true, + "editable": true, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.02.1: hallo ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.02.1: hallo \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: hallo is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.02.1: hallo \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 1 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.02.1: hallo\", () => {\n", + " assertEquals(hallo(), 'Hallo Welt!')\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "7b17b7b9-9337-43f9-904b-3d8e11d1d9c3", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.02.2\n", + "Definiere zwei Funktionen. Die erste Funktion `a` soll `'Hallo a!'` zurückgeben. Die zweite Funktion `b` soll `'Hallo b!'` zurückgeben." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "89bda355-b2d5-4e47-9c7e-e711a5663f72", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f084bd1d-cd11-49f7-a0aa-ee33fd7886d3", + "metadata": { + "collapsed": true, + "editable": true, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.02.2: a ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.02.2: b ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.02.2: a \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: a is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.02.2: b \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: b is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.02.2: a \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "01.02.2: b \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 2 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.02.2: a\", () => {\n", + " assertEquals(a(), 'Hallo a!')\n", + "})\n", + "Deno.test(\"01.02.2: b\", () => {\n", + " assertEquals(b(), 'Hallo b!')\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "302df880-f486-4cd5-b0e4-987a122d2b17", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.02.3\n", + "1. Definiere eine Funktion `begruesse`, die den Wert `'Moin!'` zurückgibt.\n", + "2. Deklariere eine Variable `begruessung`. Rufe die Funktion `begruesse` auf und weise der Variablen `begruessung` die Rückgabe dieses Aufrufs zu." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "956109e0-0e4a-416b-94a3-4a6f6c88caf9", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d013cd3d-eb31-4a4f-a679-990fb77243c7", + "metadata": { + "collapsed": true, + "editable": true, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.02.3: begruesse ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.02.3: begruessung ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.02.3: begruesse \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: begruesse is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.02.3: begruessung \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: begruessung is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m16\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.02.3: begruesse \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "01.02.3: begruessung \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 2 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.02.3: begruesse\", () => {\n", + " assertEquals(begruesse(), 'Moin!')\n", + "})\n", + "Deno.test(\"01.02.3: begruessung\", () => {\n", + " assertEquals(begruessung, 'Moin!')\n", + "})" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/02 Funktionen/.ipynb_checkpoints/03 Parameter-checkpoint.ipynb b/01 Einführung/02 Funktionen/.ipynb_checkpoints/03 Parameter-checkpoint.ipynb new file mode 100644 index 0000000..13bc8b2 --- /dev/null +++ b/01 Einführung/02 Funktionen/.ipynb_checkpoints/03 Parameter-checkpoint.ipynb @@ -0,0 +1,162 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7871315d-8e48-467f-b664-6666282b0122", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Parameter\n", + "Eine Funktion kann auch einen oder mehrere Parameter entgegennehmen. Diese stehen bei der Definition als Variablen in der Klammer, beim Aufruf werden die Werte ebenfalls in der Klammer mit übergeben." + ] + }, + { + "cell_type": "markdown", + "id": "a05503b8-9275-4a9b-8362-610689c2c8fa", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel 3: Funktion mit Parameter\n", + "Hier wird eine Funktion `quadrat` definiert, die einen Parameter vom Typ `number` entgegennimmt." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "5234f737-4fbd-42ca-8481-81f878cc65d3", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "25\n", + "49\n" + ] + } + ], + "source": [ + "function quadrat(a: number) {\n", + " console.log( a * a );\n", + "}\n", + "\n", + "quadrat(5); // Ausgabe: 25\n", + "quadrat(7); // Ausgabe: 49" + ] + }, + { + "cell_type": "markdown", + "id": "1be106e1-3fe0-48fe-98c3-7e031e7beb57", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel 4: Funktion mit mehreren Parametern und Rückgabe\n", + "Wir definieren hier eine Funktion `sum`, die zwei Parameter (jeweils vom Typ `number`) entgegennimmt und ebenfalls einen Wert vom Typ `number` zurückgibt.\n", + "\n", + "Als Test wird die Funktion mit den beiden Werten 45 und 17 aufgerufen und das Ergebnis in `a` gespeichert. Achtung: die Variable `a` hat nichts mit dem Parameter `a` zu tun und ist völlig unabhängig von diesem!\n", + "\n", + "Außerdem kann man auch das Ergebnis einer Funktion direkt als Wert für einen Parameter einer weiteren Funktion (hier `console.log`) verwenden." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "fcdea9e8-640f-47e5-8f39-ba64d62107b4", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "62\n", + "13\n" + ] + } + ], + "source": [ + "function sum(a: number, b: number): number {\n", + " return a + b;\n", + "}\n", + "\n", + "let a: number = sum(45, 17);\n", + "console.log(a); // Ausgabe: 62\n", + "console.log( sum(5, 8) ); // Ausgabe: 13" + ] + }, + { + "cell_type": "markdown", + "id": "22568774-001a-4ae5-ba93-032a4d278cd6", + "metadata": { + "editable": false, + "raw_mimetype": "", + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Anmerkung\n", + "Auch `console.log` ist eine Funktion, die auch mehrere Parameter (unterschiedlichen Typs) entgegennehmen kann und alle Parameterwerte nacheinander ausgibt." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "596221c0-294c-4db6-ba7f-1176fc4c0560", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/02 Funktionen/.ipynb_checkpoints/04 Übungen-checkpoint.ipynb b/01 Einführung/02 Funktionen/.ipynb_checkpoints/04 Übungen-checkpoint.ipynb new file mode 100644 index 0000000..363fcab --- /dev/null +++ b/01 Einführung/02 Funktionen/.ipynb_checkpoints/04 Übungen-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/02 Funktionen/01 Einführung.ipynb b/01 Einführung/02 Funktionen/01 Einführung.ipynb new file mode 100644 index 0000000..d895829 --- /dev/null +++ b/01 Einführung/02 Funktionen/01 Einführung.ipynb @@ -0,0 +1,163 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e61302c1-61b9-43e6-9faf-340c6f63eeb5", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Funktionen" + ] + }, + { + "cell_type": "markdown", + "id": "91c5bfe0-c800-425e-95a5-3ba858172eac", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Grundlegendes\n", + "Eine Funktion ist ein Block von Anweisungen, der beliebig oft ausgeführt werden kann." + ] + }, + { + "cell_type": "markdown", + "id": "1d2ca0b1-ee23-4835-9a19-d1e0ca566475", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel 1: einfache Funktion\n", + "Hier wird eine einfache Funktion `hallo` definiert und anschließend zwei Mal ausgeführt." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "5cbd4fea-aa4c-4132-b6a5-600477bbe9aa", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hallo Welt!\n", + "Hallo Welt!\n" + ] + } + ], + "source": [ + "function hallo() {\n", + " console.log(\"Hallo Welt!\");\n", + "}\n", + "\n", + "hallo(); // Aufruf der Funktion\n", + "hallo(); // zweiter Aufruf" + ] + }, + { + "cell_type": "markdown", + "id": "8199e2d4-a3ec-4c9e-9c33-f0562de760d8", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Rückgabe\n", + "Eine Funktion kann nicht nur dafür verwendet werden, bestimmte Befehlsabfolgen auszuführen, sie kann auch ein Ergebnis zurückliefern. Dieses Ergebnis kann anschließend z.B. in einer Variablen gespeichert und weiterverwendet werden.\n", + "\n", + "Bei einer Funktion mit Rückgabe sollte der Rückgabe-Datentyp bei der Funktionsdefinition mit angegeben werden.\n", + "\n", + "Das Schlüsselwort `return` gibt den nachfolgenden Wert zurück und bricht gleichzeitig auch die Funktion ab!" + ] + }, + { + "cell_type": "markdown", + "id": "c3014407-d02c-41c7-bfe6-30177d95d71b", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel 2: Funktion mit Rückgabewert\n", + "Hier wird die Funktion `hallo` definiert, die einen `string` zurückgibt.\n", + "\n", + "Mit `return \"Hallo Welt!\";` wird dann dieser String zurückgegeben." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "7ea0e464-e3b7-43fb-807b-90f8232d4feb", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hallo Welt!\n" + ] + } + ], + "source": [ + "function hallo(): string {\n", + " return \"Hallo Welt!\"; // hier wird \"Hallo Welt!\" zurückgegeben und die Funktion abgebrochen\n", + "\n", + " console.log(\"Keine Ausgabe\"); // diese Ausgabe findet nie statt, da zuvor bereits mit `return` abgebrochen wird\n", + "}\n", + "\n", + "let s: string = hallo(); // Funktion `hallo` wird aufgerufen und das Ergebnis in der Variablen s gespeichert\n", + "console.log(s); // Inhalt der Variablen `s` ausgeben" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/02 Funktionen/02 Übungen.ipynb b/01 Einführung/02 Funktionen/02 Übungen.ipynb new file mode 100644 index 0000000..1e75398 --- /dev/null +++ b/01 Einführung/02 Funktionen/02 Übungen.ipynb @@ -0,0 +1,288 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "4fbccfbc-2e07-4214-a665-4b13afb2723e", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import { assertEquals } from \"jsr:@std/assert\";" + ] + }, + { + "cell_type": "markdown", + "id": "86eb640a-2c5b-4498-90d7-774984742f45", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.02.1\n", + "Definiere eine Funktion `hallo`, die `'Hallo Welt!'` zurückgibt." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "90e1aef5-ac02-45a6-9f98-3c812ed506f0", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "a6e2ef7a-6785-44b4-be55-55ef733320bd", + "metadata": { + "collapsed": true, + "editable": false, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.02.1: hallo ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.02.1: hallo \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: hallo is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.02.1: hallo \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 1 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.02.1: hallo\", () => {\n", + " assertEquals(typeof hallo, 'function')\n", + "})\n", + "Deno.test(\"01.02.1: hallo\", () => {\n", + " assertEquals(hallo(), 'Hallo Welt!')\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "7b17b7b9-9337-43f9-904b-3d8e11d1d9c3", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.02.2\n", + "Definiere zwei Funktionen. Die erste Funktion `a` soll `'Hallo a!'` zurückgeben. Die zweite Funktion `b` soll `'Hallo b!'` zurückgeben." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "89bda355-b2d5-4e47-9c7e-e711a5663f72", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f084bd1d-cd11-49f7-a0aa-ee33fd7886d3", + "metadata": { + "collapsed": true, + "editable": false, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.02.2: a ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.02.2: b ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.02.2: a \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: a is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.02.2: b \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: b is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.02.2: a \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "01.02.2: b \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 2 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.02.2: a\", () => {\n", + " assertEquals(typeof a, 'function')\n", + "})\n", + "Deno.test(\"01.02.2: b\", () => {\n", + " assertEquals(typeof b, 'function')\n", + "})\n", + "Deno.test(\"01.02.2: a\", () => {\n", + " assertEquals(a(), 'Hallo a!')\n", + "})\n", + "Deno.test(\"01.02.2: b\", () => {\n", + " assertEquals(b(), 'Hallo b!')\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "302df880-f486-4cd5-b0e4-987a122d2b17", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.02.3\n", + "1. Definiere eine Funktion `begruesse`, die den Wert `'Moin!'` zurückgibt.\n", + "2. Deklariere eine Variable `begruessung`. Rufe die Funktion `begruesse` auf und weise der Variablen `begruessung` die Rückgabe dieses Aufrufs zu." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "956109e0-0e4a-416b-94a3-4a6f6c88caf9", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d013cd3d-eb31-4a4f-a679-990fb77243c7", + "metadata": { + "collapsed": true, + "editable": false, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.02.3: begruesse ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.02.3: begruessung ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.02.3: begruesse \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: begruesse is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.02.3: begruessung \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: begruessung is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m16\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.02.3: begruesse \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "01.02.3: begruessung \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 2 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.02.3: begruesse\", () => {\n", + " assertEquals(typeof begruesse, 'function')\n", + "})\n", + "Deno.test(\"01.02.3: begruesse\", () => {\n", + " assertEquals(begruesse(), 'Moin!')\n", + "})\n", + "Deno.test(\"01.02.3: begruessung\", () => {\n", + " assertEquals(typeof begruessung, 'string')\n", + "})\n", + "Deno.test(\"01.02.3: begruessung\", () => {\n", + " assertEquals(begruessung, 'Moin!')\n", + "})" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/02 Funktionen/03 Parameter.ipynb b/01 Einführung/02 Funktionen/03 Parameter.ipynb new file mode 100644 index 0000000..13bc8b2 --- /dev/null +++ b/01 Einführung/02 Funktionen/03 Parameter.ipynb @@ -0,0 +1,162 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7871315d-8e48-467f-b664-6666282b0122", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Parameter\n", + "Eine Funktion kann auch einen oder mehrere Parameter entgegennehmen. Diese stehen bei der Definition als Variablen in der Klammer, beim Aufruf werden die Werte ebenfalls in der Klammer mit übergeben." + ] + }, + { + "cell_type": "markdown", + "id": "a05503b8-9275-4a9b-8362-610689c2c8fa", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel 3: Funktion mit Parameter\n", + "Hier wird eine Funktion `quadrat` definiert, die einen Parameter vom Typ `number` entgegennimmt." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "5234f737-4fbd-42ca-8481-81f878cc65d3", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "25\n", + "49\n" + ] + } + ], + "source": [ + "function quadrat(a: number) {\n", + " console.log( a * a );\n", + "}\n", + "\n", + "quadrat(5); // Ausgabe: 25\n", + "quadrat(7); // Ausgabe: 49" + ] + }, + { + "cell_type": "markdown", + "id": "1be106e1-3fe0-48fe-98c3-7e031e7beb57", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Beispiel 4: Funktion mit mehreren Parametern und Rückgabe\n", + "Wir definieren hier eine Funktion `sum`, die zwei Parameter (jeweils vom Typ `number`) entgegennimmt und ebenfalls einen Wert vom Typ `number` zurückgibt.\n", + "\n", + "Als Test wird die Funktion mit den beiden Werten 45 und 17 aufgerufen und das Ergebnis in `a` gespeichert. Achtung: die Variable `a` hat nichts mit dem Parameter `a` zu tun und ist völlig unabhängig von diesem!\n", + "\n", + "Außerdem kann man auch das Ergebnis einer Funktion direkt als Wert für einen Parameter einer weiteren Funktion (hier `console.log`) verwenden." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "fcdea9e8-640f-47e5-8f39-ba64d62107b4", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "62\n", + "13\n" + ] + } + ], + "source": [ + "function sum(a: number, b: number): number {\n", + " return a + b;\n", + "}\n", + "\n", + "let a: number = sum(45, 17);\n", + "console.log(a); // Ausgabe: 62\n", + "console.log( sum(5, 8) ); // Ausgabe: 13" + ] + }, + { + "cell_type": "markdown", + "id": "22568774-001a-4ae5-ba93-032a4d278cd6", + "metadata": { + "editable": false, + "raw_mimetype": "", + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Anmerkung\n", + "Auch `console.log` ist eine Funktion, die auch mehrere Parameter (unterschiedlichen Typs) entgegennehmen kann und alle Parameterwerte nacheinander ausgibt." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "596221c0-294c-4db6-ba7f-1176fc4c0560", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/02 Funktionen/04 Übungen.ipynb b/01 Einführung/02 Funktionen/04 Übungen.ipynb new file mode 100644 index 0000000..ab11698 --- /dev/null +++ b/01 Einführung/02 Funktionen/04 Übungen.ipynb @@ -0,0 +1,272 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "13e0b4fc-3ea3-4fc8-9293-7d9f58eb82fb", + "metadata": { + "editable": true, + "jupyter": { + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import { assertEquals } from \"jsr:@std/assert\"" + ] + }, + { + "cell_type": "markdown", + "id": "12998cb3-fe6b-4be9-83de-4d725210c5b1", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.02.4\n", + "Schreibe eine Funktion `echo`, die ebenfalls den übergebenen Parameter wieder zurückgibt." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3bc621d3-8101-4588-9a9a-73480f296a5d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "288a67d3-1aab-4f24-ac41-ab24c2d098eb", + "metadata": { + "collapsed": true, + "editable": true, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.02.4: echo ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(2ms)\u001b[0m\n", + "01.02.4: Parameter ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.02.4: Greta ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.02.4: CO2 ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.02.4: echo \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: AssertionError: Values are not equal.\n", + "\n", + "\n", + " \u001b[90m\u001b[1m[Diff]\u001b[22m\u001b[39m \u001b[31m\u001b[1mActual\u001b[22m\u001b[39m / \u001b[32m\u001b[1mExpected\u001b[22m\u001b[39m\n", + "\n", + "\n", + "\u001b[31m\u001b[1m- \u001b[41m\u001b[37mundefined\u001b[31m\u001b[49m\n", + "\u001b[22m\u001b[39m\u001b[32m\u001b[1m+ \u001b[42m\u001b[37mfunction\u001b[32m\u001b[49m\n", + "\u001b[22m\u001b[39m\n", + "\n", + " throw new AssertionError(message);\n", + "\u001b[0m\u001b[31m ^\u001b[0m\n", + " at \u001b[0m\u001b[1m\u001b[3massertEquals\u001b[0m (\u001b[0m\u001b[36mhttps://jsr.io/@std/assert/1.0.13/equals.ts\u001b[0m:\u001b[0m\u001b[33m64\u001b[0m:\u001b[0m\u001b[33m9\u001b[0m)\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.02.4: Parameter \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: echo is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m16\u001b[0m\n", + "\n", + "01.02.4: Greta \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: echo is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m8\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.02.4: CO2 \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: echo is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m11\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.02.4: echo \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "01.02.4: Parameter \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "01.02.4: Greta \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "01.02.4: CO2 \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 4 failed \u001b[0m\u001b[38;5;245m(3ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.02.4: echo\", () => {\n", + " assertEquals(typeof echo, 'function')\n", + "})\n", + "Deno.test(\"01.02.4: Parameter\", () => {\n", + " assertEquals(echo.length, 1)\n", + "})\n", + "Deno.test(\"01.02.4: Greta\", () => {\n", + " assertEquals(echo('Greta'), 'Greta')\n", + "})\n", + "Deno.test(\"01.02.4: CO2\", () => {\n", + " assertEquals(echo('CO2'), 'CO2')\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "f80f8e2f-f8e0-48d4-9ffb-21a17b14b473", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.02.5\n", + "Schreibe eine Funktion `welcome`, die einen Parameter entgegennimmt und die `'Hallo !'` zurückgibt.\n", + "\n", + "Beispiel: Übergibt man der Funktion `welcome` den Wert `'Ada'`, so sollte die Funktion `'Hallo Ada!'` zurückgeben." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8fd18a65-713b-48af-a6ad-ade656a3f7dd", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "21b1f649-6e1f-4c1a-a8f3-f3653dd4eb89", + "metadata": { + "editable": true, + "jupyter": { + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.02.5: welcome ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.02.5: Parameter ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.02.5: Ada ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.02.5: Marianne ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(16ms)\u001b[0m\n", + "01.02.5: Mitchell ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.02.5: welcome \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: AssertionError: Values are not equal.\n", + "\n", + "\n", + " \u001b[90m\u001b[1m[Diff]\u001b[22m\u001b[39m \u001b[31m\u001b[1mActual\u001b[22m\u001b[39m / \u001b[32m\u001b[1mExpected\u001b[22m\u001b[39m\n", + "\n", + "\n", + "\u001b[31m\u001b[1m- \u001b[41m\u001b[37mundefined\u001b[31m\u001b[49m\n", + "\u001b[22m\u001b[39m\u001b[32m\u001b[1m+ \u001b[42m\u001b[37mfunction\u001b[32m\u001b[49m\n", + "\u001b[22m\u001b[39m\n", + "\n", + " throw new AssertionError(message);\n", + "\u001b[0m\u001b[31m ^\u001b[0m\n", + " at \u001b[0m\u001b[1m\u001b[3massertEquals\u001b[0m (\u001b[0m\u001b[36mhttps://jsr.io/@std/assert/1.0.13/equals.ts\u001b[0m:\u001b[0m\u001b[33m64\u001b[0m:\u001b[0m\u001b[33m9\u001b[0m)\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.02.5: Parameter \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: welcome is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m16\u001b[0m\n", + "\n", + "01.02.5: Ada \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: welcome is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m8\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.02.5: Marianne \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: welcome is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m11\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.02.5: Mitchell \u001b[0m\u001b[38;5;245m=> :13:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: welcome is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m14\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.02.5: welcome \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "01.02.5: Parameter \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "01.02.5: Ada \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "01.02.5: Marianne \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "01.02.5: Mitchell \u001b[0m\u001b[38;5;245m=> :13:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 5 failed \u001b[0m\u001b[38;5;245m(18ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.02.5: welcome\", () => {\n", + " assertEquals(typeof welcome, 'function')\n", + "})\n", + "Deno.test(\"01.02.5: Parameter\", () => {\n", + " assertEquals(welcome.length, 1)\n", + "})\n", + "Deno.test(\"01.02.5: Ada\", () => {\n", + " assertEquals(welcome('Ada'), 'Hallo Ada!')\n", + "})\n", + "Deno.test(\"01.02.5: Marianne\", () => {\n", + " assertEquals(welcome('Marianne'), 'Hallo Marianne!')\n", + "})\n", + "Deno.test(\"01.02.5: Mitchell\", () => {\n", + " assertEquals(welcome('Mitchell'), 'Hallo Mitchell!')\n", + "})" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/03 Bedingungen/.ipynb_checkpoints/01 Wahrheitswerte-checkpoint.ipynb b/01 Einführung/03 Bedingungen/.ipynb_checkpoints/01 Wahrheitswerte-checkpoint.ipynb new file mode 100644 index 0000000..fa7f7f5 --- /dev/null +++ b/01 Einführung/03 Bedingungen/.ipynb_checkpoints/01 Wahrheitswerte-checkpoint.ipynb @@ -0,0 +1,160 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f005ac12-f7b6-44ed-99bd-def52028b315", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Wahrheitswerte\n", + "Der dritte wichtige Datentyp neben `string` und `number` sind Wahrheitswerte. Sie werden auch boolesche Werte genannt. Boolesche Werte kennen nur zwei Zustände: `true` und `false`.\n", + "\n", + "Mit booleschen Werten kann man ähnlich \"rechnen\" wie mit Zahlen. JavaScript kennt drei boolesche Operatoren:\n", + "* `&&` (und)\n", + " * `&&` verknüpft zwei boolesche Werte. Sind beide Werte `true`, ist das Ergebnis auch `true`. In allen anderen Fällen ist es `false`.\n", + "* `||` (oder)\n", + " * Bei `||` ist das Ergebnis `false`, wenn beide Eingangswerte auch `false` sind. In allen anderen Fällen ist das Ergebnis `true`.\n", + "* `!` (nicht)\n", + " * `!` wird nur auf einen booleschen Wert angewendet und invertiert diesen Wert: aus `true` wird `false` und aus `false` wird `true`.\n", + " \n", + "```\n", + "let x1 = true && false;\n", + "let x2 = !x1;\n", + "let x3 = x1 || x2;\n", + "```\n", + "\n", + "* `x1` ist `false`\n", + "* `x2` ist `true`\n", + "* `x3` ist `true`\n", + "\n", + "*Anmerkung: `x1`, `x2` und `x3` sind damit automatisch vom Datentyp `boolean`, ohne dass dies explizit angegeben werden muss.*" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "8c60bf4a-7f20-46d3-be56-96228d5dd0c6", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "false\n", + "false\n", + "true\n" + ] + } + ], + "source": [ + "console.log( true && false ); // Ausgabe: false\n", + "console.log( !true ); // Ausgabe: false\n", + "console.log( true || false ); // Ausgabe: true" + ] + }, + { + "cell_type": "markdown", + "id": "d8a82694-693a-44a3-9c0d-383531b19036", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Vergleiche\n", + "Zahlen kann man mit den aus der Mathematik bekannten Zeichen `>`, `>=`, `<` und `<=` auf größer, größer gleich, kleiner und kleiner gleich vergleichen. Im folgenden Beispiel liefern alle Ausdrücke den Wert `true`:\n", + "```\n", + "let v1 = 5 > 4;\n", + "let v2 = 5 >= 5;\n", + "let v3 = 5 < 6;\n", + "let v4 = 5 <= 5;\n", + "```\n", + "\n", + "Zwei Werte kann man auch auf strikte Gleichheit überprüfen. Das Ergebnis eines solchen Vergleichs ist entweder `true`, die beiden Werte sind gleich, oder `false`, die beiden Werte sind ungleich. Der Operator für strikte Gleichheit ist `===`.\n", + "\n", + "Im Gegensatz dazu gibt es auch den aus anderen Programmiersprachen bekannten Operator `==`. Dieser liefert ebenfalls `true` z.B. wenn die Datentypen unterschiedlich sind, jedoch der Inhalt gleich ist:\n", + "```\n", + "let v5 = 1 === 1; // liefert `true`\n", + "let v6 = 1 === '1'; // liefert `false`, da die Datentypen unterschiedlich sind\n", + "let v7 = 1 == '1'; // liefert `true`, da bei Typumwandlung der Inhalt gleich ist\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "972f23b8-0a4d-4b70-953a-883949688896", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "true\n", + "true\n", + "false\n", + "true\n" + ] + } + ], + "source": [ + "console.log( 5 > 4 ) // Ausgabe: true\n", + "console.log( 5 >= 5 ) // Ausgabe: true\n", + "console.log( 1 === '1' ) // Ausgabe: false\n", + "console.log( 1 == '1' ) // Ausgabe: true" + ] + }, + { + "cell_type": "markdown", + "id": "bb9081df-6937-4709-b477-4c7fbbb6512c", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Regel für den Unterricht\n", + "**In aller Regel verwenden wir im Unterricht die strikte Gleichheit `===`**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/03 Bedingungen/.ipynb_checkpoints/02 Übungen-checkpoint.ipynb b/01 Einführung/03 Bedingungen/.ipynb_checkpoints/02 Übungen-checkpoint.ipynb new file mode 100644 index 0000000..967f44f --- /dev/null +++ b/01 Einführung/03 Bedingungen/.ipynb_checkpoints/02 Übungen-checkpoint.ipynb @@ -0,0 +1,400 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "0a476912-ee13-42d8-b705-b711433d149a", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import { assertEquals } from \"jsr:@std/assert\";" + ] + }, + { + "cell_type": "markdown", + "id": "d31a7ba1-13af-40a1-bb9d-4733096cc531", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.03.1\n", + "Schreibe eine Funktion `nand`, die zwei boolesche Werte als Parameter entgegennimmt. Die Rückgabe der Funktion soll `false` sein, wenn beide Paramter `true` sind. In den anderen Fällen soll die Rückgabe `true` sein.\n", + "\n", + "D.h.:\n", + "* `nand(true, true)` soll `false` liefern\n", + "* `nand(true, false)`, `nand(false, true)` und `nand(false, false)` sollen `true` zurückgeben." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "9a0582d4-9acb-4dd1-86c5-3b9d4d2bd4fb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b0deac5e-d859-47d0-a220-80d4cdcb98d4", + "metadata": { + "collapsed": true, + "editable": false, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.03.1: function ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.1: nand(1,1) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.1: nand(1,0) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.1: nand(0,1) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.1: nand(0,0) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.03.1: function \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.1: nand(1,1) \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.1: nand(1,0) \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m8\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.1: nand(0,1) \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m11\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.1: nand(0,0) \u001b[0m\u001b[38;5;245m=> :13:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m14\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.03.1: function \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "01.03.1: nand(1,1) \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "01.03.1: nand(1,0) \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "01.03.1: nand(0,1) \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "01.03.1: nand(0,0) \u001b[0m\u001b[38;5;245m=> :13:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 5 failed \u001b[0m\u001b[38;5;245m(1ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.03.1: function\", () => {\n", + " assertEquals(typeof nand, 'function')\n", + "})\n", + "Deno.test(\"01.03.1: nand(1,1)\", () => {\n", + " assertEquals(nand(true, true), false)\n", + "})\n", + "Deno.test(\"01.03.1: nand(1,0)\", () => {\n", + " assertEquals(nand(true, false), true)\n", + "})\n", + "Deno.test(\"01.03.1: nand(0,1)\", () => {\n", + " assertEquals(nand(false, true), true)\n", + "})\n", + "Deno.test(\"01.03.1: nand(0,0)\", () => {\n", + " assertEquals(nand(false, false), true)\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "57c3c062-b29e-40dc-add0-97b5c5a999c1", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.03.2\n", + "Schreibe eine Funktion `nor`, die zwei boolesche Werte als Parameter entgegennimmt. Die Rückgabe der Funktion soll genau dann `true` sein, wenn beide Paramter `false` sind. In den anderen Fällen soll die Rückgabe `false` sein.\n", + "\n", + "D.h.:\n", + "* `nor(false, false)` soll `true` liefern\n", + "* `nor(false, true)`, `nor(true, false)` und `nor(true, true)` sollen `false` zurückgeben." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7e1929b1-033a-4b9c-ba66-f67d2b0dab89", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "82ff9541-bb28-4520-9c93-57185f3ea9bf", + "metadata": { + "collapsed": true, + "editable": false, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.03.2: function ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.2: nor(1,1) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.2: nor(1,0) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.2: nor(0,1) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.2: nor(0,0) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.03.2: function \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.2: nor(1,1) \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.2: nor(1,0) \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m8\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.2: nor(0,1) \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m11\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.2: nor(0,0) \u001b[0m\u001b[38;5;245m=> :13:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m14\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.03.2: function \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "01.03.2: nor(1,1) \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "01.03.2: nor(1,0) \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "01.03.2: nor(0,1) \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "01.03.2: nor(0,0) \u001b[0m\u001b[38;5;245m=> :13:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 5 failed \u001b[0m\u001b[38;5;245m(1ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.03.2: function\", () => {\n", + " assertEquals(typeof nor, 'function')\n", + "})\n", + "Deno.test(\"01.03.2: nor(1,1)\", () => {\n", + " assertEquals(nor(true, true), false)\n", + "})\n", + "Deno.test(\"01.03.2: nor(1,0)\", () => {\n", + " assertEquals(nor(true, false), false)\n", + "})\n", + "Deno.test(\"01.03.2: nor(0,1)\", () => {\n", + " assertEquals(nor(false, true), false)\n", + "})\n", + "Deno.test(\"01.03.2: nor(0,0)\", () => {\n", + " assertEquals(nor(false, false), true)\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "340a44a5-5010-4b46-8c4c-2d7c459750eb", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.03.3\n", + "Schreibe eine Funktion `xor`, die zwei boolesche Werte als Parameter entgegennimmt. Die Rückgabe der Funktion soll `true` sein, wenn beide Paramter verschieden sind. In den anderen Fällen soll die Rückgabe `false` sein.\n", + "\n", + "D.h.:\n", + "* `xor(true, false)` und `xor(false, true)` sollen `true` liefern\n", + "* `xor(true, true)` und `xor(false, false)` sollen `false` zurückgeben." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c80d2fe9-4d8b-445a-8d1c-5803776b3d74", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d76d78ff-6a02-42d4-93bc-eb9e19be39ce", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "Deno.test(\"01.03.3: function\", () => {\n", + " assertEquals(typeof xor, 'function')\n", + "})\n", + "Deno.test(\"01.03.3: xor(1,1)\", () => {\n", + " assertEquals(xor(true, true), false)\n", + "})\n", + "Deno.test(\"01.03.3: xor(1,0)\", () => {\n", + " assertEquals(xor(true, false), true)\n", + "})\n", + "Deno.test(\"01.03.3: xor(0,1)\", () => {\n", + " assertEquals(xor(false, true), true)\n", + "})\n", + "Deno.test(\"01.03.3: xor(0,0)\", () => {\n", + " assertEquals(xor(false, false), false)\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "e15e95e4-89e5-4cea-be8f-d95ea68eb9a7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.03.4\n", + "Schreibe eine Funktion `gleich`, die zwei Werte auf strikte Gleichheit überprüft.\n", + "\n", + "Beispiel: `gleich(1, 1)` soll `true` und `gleich(1, 2)` soll `false` ergeben.\n", + "\n", + "*Hinweis: sollen bei einem Parameter unterschiedliche Datentypen übergeben werden können, so kann als Datentyp `any` genutzt werden!*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a98dce86-57ee-41d7-bf1b-f8648430bee5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1af5c359-2df3-49af-82a2-0d6cc8324746", + "metadata": { + "editable": false, + "jupyter": { + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "Deno.test(\"01.03.4: function\", () => {\n", + " assertEquals(typeof gleich, 'function')\n", + "})\n", + "Deno.test(\"01.03.4: Parameter\", () => {\n", + " assertEquals(gleich.length, 2)\n", + "})\n", + "Deno.test(\"01.03.4: gleich(1,1)\", () => {\n", + " assertEquals(gleich(1, 1), true)\n", + "})\n", + "Deno.test(\"01.03.4: gleich(1,0)\", () => {\n", + " assertEquals(gleich(1, 0), false)\n", + "})\n", + "Deno.test(\"01.03.4: gleich(1,'1')\", () => {\n", + " assertEquals(gleich(1, '1'), false)\n", + "})\n", + "Deno.test(\"01.03.4: gleich(1,2)\", () => {\n", + " assertEquals(gleich(1, 2), false)\n", + "})\n", + "Deno.test(\"01.03.4: gleich('klein','klein')\", () => {\n", + " assertEquals(gleich('klein', 'klein'), false)\n", + "})\n", + "Deno.test(\"01.03.4: gleich('Links','Rechts')\", () => {\n", + " assertEquals(gleich('Links', 'Rechts'), false)\n", + "})\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/03 Bedingungen/.ipynb_checkpoints/03 if-checkpoint.ipynb b/01 Einführung/03 Bedingungen/.ipynb_checkpoints/03 if-checkpoint.ipynb new file mode 100644 index 0000000..2dea35d --- /dev/null +++ b/01 Einführung/03 Bedingungen/.ipynb_checkpoints/03 if-checkpoint.ipynb @@ -0,0 +1,73 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "076931c8-a182-4790-a031-9759dc063e0a", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Bedingungen\n", + "Häufig soll Code nur dann ausgeführt werden, wenn eine bestimmte Bedingung erfüllt ist. Dazu verwendet man die `if`-Anweisung.\n", + "```\n", + "let gewinn = 0;\n", + "if (wuerfelzahl === 6) {\n", + " gewinn = 100;\n", + "}\n", + "```\n", + "Diese Anweisung besteht aus dem Schlüsselwort `if` (engl: wenn) gefolgt von runden Klammern. In den runden Klammern steht die Bedingung. Ergibt die Bedingung `true`, werden alle Anweisungen in dem durch die geschweiften Klammern begrenzten Block ausgeführt. Ergibt die Bedingung `false`, wird der durch die geschweiften Klammern begrenzte Block übersprungen. Hat in unserem Beispiel die Variable `wuerfelzahl` den Wert 6, so wird `gewinn` auf 100 gesetzt. Hat `wuerfelzahl` nicht den Wert 6, bleibt gewinn bei 0." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "80a31a45-95ee-4375-8b26-ec8f2e0f87d3", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n" + ] + } + ], + "source": [ + "let wuerfelzahl = Math.round(Math.random()*5.49) + 1; // generiere Zufallszahl zwischen 1 und 6\n", + "console.log(wuerfelzahl); // Ausgabe der Würfelzahl\n", + "\n", + "if (wuerfelzahl === 6) {\n", + " console.log(\"Gewonnen!\");\n", + "}" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/03 Bedingungen/.ipynb_checkpoints/04 Übungen-checkpoint.ipynb b/01 Einführung/03 Bedingungen/.ipynb_checkpoints/04 Übungen-checkpoint.ipynb new file mode 100644 index 0000000..363fcab --- /dev/null +++ b/01 Einführung/03 Bedingungen/.ipynb_checkpoints/04 Übungen-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/03 Bedingungen/01 Wahrheitswerte.ipynb b/01 Einführung/03 Bedingungen/01 Wahrheitswerte.ipynb new file mode 100644 index 0000000..fa7f7f5 --- /dev/null +++ b/01 Einführung/03 Bedingungen/01 Wahrheitswerte.ipynb @@ -0,0 +1,160 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f005ac12-f7b6-44ed-99bd-def52028b315", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Wahrheitswerte\n", + "Der dritte wichtige Datentyp neben `string` und `number` sind Wahrheitswerte. Sie werden auch boolesche Werte genannt. Boolesche Werte kennen nur zwei Zustände: `true` und `false`.\n", + "\n", + "Mit booleschen Werten kann man ähnlich \"rechnen\" wie mit Zahlen. JavaScript kennt drei boolesche Operatoren:\n", + "* `&&` (und)\n", + " * `&&` verknüpft zwei boolesche Werte. Sind beide Werte `true`, ist das Ergebnis auch `true`. In allen anderen Fällen ist es `false`.\n", + "* `||` (oder)\n", + " * Bei `||` ist das Ergebnis `false`, wenn beide Eingangswerte auch `false` sind. In allen anderen Fällen ist das Ergebnis `true`.\n", + "* `!` (nicht)\n", + " * `!` wird nur auf einen booleschen Wert angewendet und invertiert diesen Wert: aus `true` wird `false` und aus `false` wird `true`.\n", + " \n", + "```\n", + "let x1 = true && false;\n", + "let x2 = !x1;\n", + "let x3 = x1 || x2;\n", + "```\n", + "\n", + "* `x1` ist `false`\n", + "* `x2` ist `true`\n", + "* `x3` ist `true`\n", + "\n", + "*Anmerkung: `x1`, `x2` und `x3` sind damit automatisch vom Datentyp `boolean`, ohne dass dies explizit angegeben werden muss.*" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "8c60bf4a-7f20-46d3-be56-96228d5dd0c6", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "false\n", + "false\n", + "true\n" + ] + } + ], + "source": [ + "console.log( true && false ); // Ausgabe: false\n", + "console.log( !true ); // Ausgabe: false\n", + "console.log( true || false ); // Ausgabe: true" + ] + }, + { + "cell_type": "markdown", + "id": "d8a82694-693a-44a3-9c0d-383531b19036", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Vergleiche\n", + "Zahlen kann man mit den aus der Mathematik bekannten Zeichen `>`, `>=`, `<` und `<=` auf größer, größer gleich, kleiner und kleiner gleich vergleichen. Im folgenden Beispiel liefern alle Ausdrücke den Wert `true`:\n", + "```\n", + "let v1 = 5 > 4;\n", + "let v2 = 5 >= 5;\n", + "let v3 = 5 < 6;\n", + "let v4 = 5 <= 5;\n", + "```\n", + "\n", + "Zwei Werte kann man auch auf strikte Gleichheit überprüfen. Das Ergebnis eines solchen Vergleichs ist entweder `true`, die beiden Werte sind gleich, oder `false`, die beiden Werte sind ungleich. Der Operator für strikte Gleichheit ist `===`.\n", + "\n", + "Im Gegensatz dazu gibt es auch den aus anderen Programmiersprachen bekannten Operator `==`. Dieser liefert ebenfalls `true` z.B. wenn die Datentypen unterschiedlich sind, jedoch der Inhalt gleich ist:\n", + "```\n", + "let v5 = 1 === 1; // liefert `true`\n", + "let v6 = 1 === '1'; // liefert `false`, da die Datentypen unterschiedlich sind\n", + "let v7 = 1 == '1'; // liefert `true`, da bei Typumwandlung der Inhalt gleich ist\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "972f23b8-0a4d-4b70-953a-883949688896", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "true\n", + "true\n", + "false\n", + "true\n" + ] + } + ], + "source": [ + "console.log( 5 > 4 ) // Ausgabe: true\n", + "console.log( 5 >= 5 ) // Ausgabe: true\n", + "console.log( 1 === '1' ) // Ausgabe: false\n", + "console.log( 1 == '1' ) // Ausgabe: true" + ] + }, + { + "cell_type": "markdown", + "id": "bb9081df-6937-4709-b477-4c7fbbb6512c", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Regel für den Unterricht\n", + "**In aller Regel verwenden wir im Unterricht die strikte Gleichheit `===`**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/03 Bedingungen/02 Übungen.ipynb b/01 Einführung/03 Bedingungen/02 Übungen.ipynb new file mode 100644 index 0000000..3f739fd --- /dev/null +++ b/01 Einführung/03 Bedingungen/02 Übungen.ipynb @@ -0,0 +1,396 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "0a476912-ee13-42d8-b705-b711433d149a", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import { assertEquals } from \"jsr:@std/assert\";" + ] + }, + { + "cell_type": "markdown", + "id": "d31a7ba1-13af-40a1-bb9d-4733096cc531", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.03.1\n", + "Schreibe eine Funktion `nand`, die zwei boolesche Werte als Parameter entgegennimmt. Die Rückgabe der Funktion soll `false` sein, wenn beide Paramter `true` sind. In den anderen Fällen soll die Rückgabe `true` sein.\n", + "\n", + "D.h.:\n", + "* `nand(true, true)` soll `false` liefern\n", + "* `nand(true, false)`, `nand(false, true)` und `nand(false, false)` sollen `true` zurückgeben." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "9a0582d4-9acb-4dd1-86c5-3b9d4d2bd4fb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b0deac5e-d859-47d0-a220-80d4cdcb98d4", + "metadata": { + "collapsed": true, + "editable": false, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.03.1: function ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.1: nand(1,1) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.1: nand(1,0) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.1: nand(0,1) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.1: nand(0,0) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.03.1: function \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.1: nand(1,1) \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.1: nand(1,0) \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m8\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.1: nand(0,1) \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m11\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.1: nand(0,0) \u001b[0m\u001b[38;5;245m=> :13:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m14\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.03.1: function \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "01.03.1: nand(1,1) \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "01.03.1: nand(1,0) \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "01.03.1: nand(0,1) \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "01.03.1: nand(0,0) \u001b[0m\u001b[38;5;245m=> :13:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 5 failed \u001b[0m\u001b[38;5;245m(1ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.03.1: function\", () => {\n", + " assertEquals(typeof nand, 'function')\n", + "})\n", + "Deno.test(\"01.03.1: nand(1,1)\", () => {\n", + " assertEquals(nand(true, true), false)\n", + "})\n", + "Deno.test(\"01.03.1: nand(1,0)\", () => {\n", + " assertEquals(nand(true, false), true)\n", + "})\n", + "Deno.test(\"01.03.1: nand(0,1)\", () => {\n", + " assertEquals(nand(false, true), true)\n", + "})\n", + "Deno.test(\"01.03.1: nand(0,0)\", () => {\n", + " assertEquals(nand(false, false), true)\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "57c3c062-b29e-40dc-add0-97b5c5a999c1", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.03.2\n", + "Schreibe eine Funktion `nor`, die zwei boolesche Werte als Parameter entgegennimmt. Die Rückgabe der Funktion soll genau dann `true` sein, wenn beide Paramter `false` sind. In den anderen Fällen soll die Rückgabe `false` sein.\n", + "\n", + "D.h.:\n", + "* `nor(false, false)` soll `true` liefern\n", + "* `nor(false, true)`, `nor(true, false)` und `nor(true, true)` sollen `false` zurückgeben." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7e1929b1-033a-4b9c-ba66-f67d2b0dab89", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "82ff9541-bb28-4520-9c93-57185f3ea9bf", + "metadata": { + "collapsed": true, + "editable": false, + "jupyter": { + "outputs_hidden": true, + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "01.03.2: function ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.2: nor(1,1) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.2: nor(1,0) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.2: nor(0,1) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "01.03.2: nor(0,0) ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "01.03.2: function \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m2\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.2: nor(1,1) \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m5\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.2: nor(1,0) \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m8\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.2: nor(0,1) \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m11\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "01.03.2: nor(0,0) \u001b[0m\u001b[38;5;245m=> :13:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: ReferenceError: assertEquals is not defined\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m14\u001b[0m:\u001b[0m\u001b[33m3\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "01.03.2: function \u001b[0m\u001b[38;5;245m=> :1:27\u001b[0m\n", + "01.03.2: nor(1,1) \u001b[0m\u001b[38;5;245m=> :4:6\u001b[0m\n", + "01.03.2: nor(1,0) \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "01.03.2: nor(0,1) \u001b[0m\u001b[38;5;245m=> :10:6\u001b[0m\n", + "01.03.2: nor(0,0) \u001b[0m\u001b[38;5;245m=> :13:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 0 passed | 5 failed \u001b[0m\u001b[38;5;245m(1ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"01.03.2: function\", () => {\n", + " assertEquals(typeof nor, 'function')\n", + "})\n", + "Deno.test(\"01.03.2: nor(1,1)\", () => {\n", + " assertEquals(nor(true, true), false)\n", + "})\n", + "Deno.test(\"01.03.2: nor(1,0)\", () => {\n", + " assertEquals(nor(true, false), false)\n", + "})\n", + "Deno.test(\"01.03.2: nor(0,1)\", () => {\n", + " assertEquals(nor(false, true), false)\n", + "})\n", + "Deno.test(\"01.03.2: nor(0,0)\", () => {\n", + " assertEquals(nor(false, false), true)\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "340a44a5-5010-4b46-8c4c-2d7c459750eb", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.03.3\n", + "Schreibe eine Funktion `xor`, die zwei boolesche Werte als Parameter entgegennimmt. Die Rückgabe der Funktion soll `true` sein, wenn beide Paramter verschieden sind. In den anderen Fällen soll die Rückgabe `false` sein.\n", + "\n", + "D.h.:\n", + "* `xor(true, false)` und `xor(false, true)` sollen `true` liefern\n", + "* `xor(true, true)` und `xor(false, false)` sollen `false` zurückgeben." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c80d2fe9-4d8b-445a-8d1c-5803776b3d74", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d76d78ff-6a02-42d4-93bc-eb9e19be39ce", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "Deno.test(\"01.03.3: function\", () => {\n", + " assertEquals(typeof xor, 'function')\n", + "})\n", + "Deno.test(\"01.03.3: xor(1,1)\", () => {\n", + " assertEquals(xor(true, true), false)\n", + "})\n", + "Deno.test(\"01.03.3: xor(1,0)\", () => {\n", + " assertEquals(xor(true, false), true)\n", + "})\n", + "Deno.test(\"01.03.3: xor(0,1)\", () => {\n", + " assertEquals(xor(false, true), true)\n", + "})\n", + "Deno.test(\"01.03.3: xor(0,0)\", () => {\n", + " assertEquals(xor(false, false), false)\n", + "})" + ] + }, + { + "cell_type": "markdown", + "id": "e15e95e4-89e5-4cea-be8f-d95ea68eb9a7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.03.4\n", + "Schreibe eine Funktion `gleich`, die zwei Werte auf strikte Gleichheit überprüft.\n", + "\n", + "Beispiel: `gleich(1, 1)` soll `true` und `gleich(1, 2)` soll `false` ergeben.\n", + "\n", + "*Hinweis: sollen bei einem Parameter unterschiedliche Datentypen übergeben werden können, so kann als Datentyp `any` genutzt werden!*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a98dce86-57ee-41d7-bf1b-f8648430bee5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1af5c359-2df3-49af-82a2-0d6cc8324746", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "Deno.test(\"01.03.4: function\", () => {\n", + " assertEquals(typeof gleich, 'function')\n", + "})\n", + "Deno.test(\"01.03.4: Parameter\", () => {\n", + " assertEquals(gleich.length, 2)\n", + "})\n", + "Deno.test(\"01.03.4: gleich(1,1)\", () => {\n", + " assertEquals(gleich(1, 1), true)\n", + "})\n", + "Deno.test(\"01.03.4: gleich(1,0)\", () => {\n", + " assertEquals(gleich(1, 0), false)\n", + "})\n", + "Deno.test(\"01.03.4: gleich(1,'1')\", () => {\n", + " assertEquals(gleich(1, '1'), false)\n", + "})\n", + "Deno.test(\"01.03.4: gleich(1,2)\", () => {\n", + " assertEquals(gleich(1, 2), false)\n", + "})\n", + "Deno.test(\"01.03.4: gleich('klein','klein')\", () => {\n", + " assertEquals(gleich('klein', 'klein'), false)\n", + "})\n", + "Deno.test(\"01.03.4: gleich('Links','Rechts')\", () => {\n", + " assertEquals(gleich('Links', 'Rechts'), false)\n", + "})\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/03 Bedingungen/03 if.ipynb b/01 Einführung/03 Bedingungen/03 if.ipynb new file mode 100644 index 0000000..e6d7749 --- /dev/null +++ b/01 Einführung/03 Bedingungen/03 if.ipynb @@ -0,0 +1,129 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "076931c8-a182-4790-a031-9759dc063e0a", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Bedingungen\n", + "Häufig soll Code nur dann ausgeführt werden, wenn eine bestimmte Bedingung erfüllt ist. Dazu verwendet man die `if`-Anweisung.\n", + "```\n", + "let gewinn = 0;\n", + "if (wuerfelzahl === 6) {\n", + " gewinn = 100;\n", + "}\n", + "```\n", + "Diese Anweisung besteht aus dem Schlüsselwort `if` (engl: wenn) gefolgt von runden Klammern. In den runden Klammern steht die Bedingung. Ergibt die Bedingung `true`, werden alle Anweisungen in dem durch die geschweiften Klammern begrenzten Block ausgeführt. Ergibt die Bedingung `false`, wird der durch die geschweiften Klammern begrenzte Block übersprungen. Hat in unserem Beispiel die Variable `wuerfelzahl` den Wert 6, so wird `gewinn` auf 100 gesetzt. Hat `wuerfelzahl` nicht den Wert 6, bleibt gewinn bei 0." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "80a31a45-95ee-4375-8b26-ec8f2e0f87d3", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "6\n", + "Gewonnen!\n" + ] + } + ], + "source": [ + "let wuerfelzahl = Math.round(Math.random()*5.49) + 1; // generiere Zufallszahl zwischen 1 und 6\n", + "console.log(wuerfelzahl); // Ausgabe der Würfelzahl\n", + "\n", + "if (wuerfelzahl === 6) {\n", + " console.log(\"Gewonnen!\");\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "9d07e555-9477-4459-8f64-bb34293070a9", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## `if ... else`\n", + "Soll ein Codeblock nur dann ausgeführt werden, wenn eine `if`-Bedingung nicht erfüllt ist, verwendet man zusätzlich zum `if` ein `else` (engl.: sonst).\n", + "```\n", + "let mitteilung;\n", + "if (betrag > 1000) {\n", + " mitteilung = \"Keine Auszahlung möglich!\";\n", + "} else {\n", + " mitteilung = \"Der Betrag wird ausgezahlt!\";\n", + "}\n", + "```\n", + "Je nachdem, ob `betrag` größer oder kleiner 1000 ist, wird entweder der `if`-Zweig oder der `else`-Zweig ausgeführt." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "c7476e8b-1781-4d8a-8c10-5b58feb3b5a3", + "metadata": { + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.1452680265049231\n", + "abrunden!\n" + ] + } + ], + "source": [ + "let betrag = Math.random(); // Zufallszah zwischen 0 und 1\n", + "console.log(betrag);\n", + "\n", + "if (betrag >= 0.5) {\n", + " console.log('aufrunden!');\n", + "} else {\n", + " console.log('abrunden!');\n", + "}" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/03 Bedingungen/04 Übungen.ipynb b/01 Einführung/03 Bedingungen/04 Übungen.ipynb new file mode 100644 index 0000000..67fe00d --- /dev/null +++ b/01 Einführung/03 Bedingungen/04 Übungen.ipynb @@ -0,0 +1,123 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "a474ad60-bfa2-4e43-9d97-88c553bfdc53", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import { assertEquals } from \"jsr:@std/assert\";" + ] + }, + { + "cell_type": "markdown", + "id": "a36a9ffd-a123-434a-9148-b8c7c75c30d4", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Aufgabe 01.03.5\n", + "Schreibe eine Funktion `gleich`, die 2 Werte auf strikte Gleichheit überprüft. Sind die beiden Werte gleich, so soll der String `'GLEICH'` zurückgegeben werden. Sind sie ungleich, so soll man `'UNGLEICH'` erhalten." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f21bb2d9-d623-4083-a0ee-d4219678c93c", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6985fdb-5098-40f9-a1e8-48a6d763cfb5", + "metadata": { + "editable": false, + "jupyter": { + "source_hidden": true + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "Deno.test(\"01.03.5: function\", () => {\n", + " assertEquals(typeof gleich, 'function')\n", + "})\n", + "Deno.test(\"01.03.5: Parameter\", () => {\n", + " assertEquals(gleich.length, 2)\n", + "})\n", + "Deno.test(\"01.03.5: gleich(1,1)\", () => {\n", + " assertEquals(gleich(1, 1), 'GLEICH')\n", + "})\n", + "Deno.test(\"01.03.5: gleich(1,0)\", () => {\n", + " assertEquals(gleich(1, 0), 'UNGLEICH')\n", + "})\n", + "Deno.test(\"01.03.5: gleich(1,'1')\", () => {\n", + " assertEquals(gleich(1, '1'), 'UNGLEICH')\n", + "})\n", + "Deno.test(\"01.03.5: gleich(1,2)\", () => {\n", + " assertEquals(gleich(1, 2), 'UNGLEICH')\n", + "})\n", + "Deno.test(\"01.03.5: gleich('klein','klein')\", () => {\n", + " assertEquals(gleich('klein', 'klein'), 'UNGLEICH')\n", + "})\n", + "Deno.test(\"01.03.5: gleich('Links','Rechts')\", () => {\n", + " assertEquals(gleich('Links', 'Rechts'), 'UNGLEICH')\n", + "})\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "58f0c4ee-8ef3-4682-8dd7-53a24afb85a6", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/Untitled.ipynb b/01 Einführung/Untitled.ipynb new file mode 100644 index 0000000..8d3976e --- /dev/null +++ b/01 Einführung/Untitled.ipynb @@ -0,0 +1,592 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "e47a5d17-b891-49bd-9326-67a7d55b848b", + "metadata": { + "editable": false, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import { assertEquals } from \"jsr:@std/assert\";" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cea43bc6-51c7-4e2a-9772-026925624173", + "metadata": {}, + "outputs": [], + "source": [ + "const x = 1 + 2;" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "95652cce-ec3b-441d-99d1-9916574648bd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "simple test ... \u001b[0m\u001b[32mok\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[32mok\u001b[0m | 1 passed | 0 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"simple test\", () => {\n", + " assertEquals(x, 3);\n", + "});" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "3566a6a9-3fdb-44af-ab02-f85d9cad7790", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import pl from \"npm:nodejs-polars\";\n", + "import { display } from \"https://deno.land/x/display@v0.1.1/mod.ts\";" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "4208a600-9873-49b6-b4ca-a3ecbdca6093", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.dataresource+json": { + "data": [ + { + "ActualExpenses": 270, + "ActualIncome": 340, + "BudgetExpenses": 264, + "BudgetIncome": 332, + "Consulting": 2, + "Date": "2022-06-18", + "DiffExpenses": -6, + "DiffIncome": -8, + "Equipment": 44, + "Expenses": 270, + "Hardware": 9, + "Income": 340, + "Marketing": 47, + "NetIncome": 70, + "Office Supplies": 6, + "R&D": 44, + "Rent": 33, + "Salaries": 39, + "Software": 8, + "Utilities": 38 + }, + { + "ActualExpenses": 265, + "ActualIncome": 401, + "BudgetExpenses": 266, + "BudgetIncome": 403, + "Consulting": 3, + "Date": "2022-03-16", + "DiffExpenses": 1, + "DiffIncome": 2, + "Equipment": 41, + "Expenses": 265, + "Hardware": 7, + "Income": 401, + "Marketing": 40, + "NetIncome": 136, + "Office Supplies": 5, + "R&D": 32, + "Rent": 48, + "Salaries": 42, + "Software": 3, + "Utilities": 44 + }, + { + "ActualExpenses": 213, + "ActualIncome": 192, + "BudgetExpenses": 210, + "BudgetIncome": 189, + "Consulting": 7, + "Date": "2022-05-07", + "DiffExpenses": -3, + "DiffIncome": -3, + "Equipment": 25, + "Expenses": 213, + "Hardware": 3, + "Income": 192, + "Marketing": 26, + "NetIncome": -21, + "Office Supplies": 5, + "R&D": 28, + "Rent": 38, + "Salaries": 46, + "Software": 4, + "Utilities": 31 + }, + { + "ActualExpenses": 238, + "ActualIncome": 291, + "BudgetExpenses": 233, + "BudgetIncome": 296, + "Consulting": 4, + "Date": "2022-07-09", + "DiffExpenses": -5, + "DiffIncome": 5, + "Equipment": 22, + "Expenses": 238, + "Hardware": 9, + "Income": 291, + "Marketing": 32, + "NetIncome": 53, + "Office Supplies": 2, + "R&D": 37, + "Rent": 48, + "Salaries": 34, + "Software": 4, + "Utilities": 46 + }, + { + "ActualExpenses": 239, + "ActualIncome": 262, + "BudgetExpenses": 242, + "BudgetIncome": 268, + "Consulting": 9, + "Date": "2022-06-22", + "DiffExpenses": 3, + "DiffIncome": 6, + "Equipment": 30, + "Expenses": 239, + "Hardware": 4, + "Income": 262, + "Marketing": 36, + "NetIncome": 23, + "Office Supplies": 8, + "R&D": 24, + "Rent": 40, + "Salaries": 48, + "Software": 3, + "Utilities": 37 + }, + { + "ActualExpenses": 237, + "ActualIncome": 299, + "BudgetExpenses": 242, + "BudgetIncome": 292, + "Consulting": 8, + "Date": "2022-03-31", + "DiffExpenses": 5, + "DiffIncome": -7, + "Equipment": 48, + "Expenses": 237, + "Hardware": 7, + "Income": 299, + "Marketing": 33, + "NetIncome": 62, + "Office Supplies": 6, + "R&D": 20, + "Rent": 48, + "Salaries": 30, + "Software": 8, + "Utilities": 29 + }, + { + "ActualExpenses": 237, + "ActualIncome": 284, + "BudgetExpenses": 245, + "BudgetIncome": 293, + "Consulting": 7, + "Date": "2022-02-24", + "DiffExpenses": 8, + "DiffIncome": 9, + "Equipment": 37, + "Expenses": 237, + "Hardware": 3, + "Income": 284, + "Marketing": 41, + "NetIncome": 47, + "Office Supplies": 9, + "R&D": 38, + "Rent": 41, + "Salaries": 24, + "Software": 1, + "Utilities": 36 + }, + { + "ActualExpenses": 200, + "ActualIncome": 269, + "BudgetExpenses": 200, + "BudgetIncome": 270, + "Consulting": 8, + "Date": "2022-05-30", + "DiffExpenses": 0, + "DiffIncome": 1, + "Equipment": 26, + "Expenses": 200, + "Hardware": 7, + "Income": 269, + "Marketing": 32, + "NetIncome": 69, + "Office Supplies": 8, + "R&D": 25, + "Rent": 21, + "Salaries": 49, + "Software": 2, + "Utilities": 22 + }, + { + "ActualExpenses": 250, + "ActualIncome": 304, + "BudgetExpenses": 248, + "BudgetIncome": 316, + "Consulting": 1, + "Date": "2022-03-23", + "DiffExpenses": -2, + "DiffIncome": 12, + "Equipment": 42, + "Expenses": 250, + "Hardware": 7, + "Income": 304, + "Marketing": 30, + "NetIncome": 54, + "Office Supplies": 2, + "R&D": 49, + "Rent": 48, + "Salaries": 39, + "Software": 2, + "Utilities": 30 + }, + { + "ActualExpenses": 214, + "ActualIncome": 182, + "BudgetExpenses": 213, + "BudgetIncome": 185, + "Consulting": 8, + "Date": "2022-05-28", + "DiffExpenses": -1, + "DiffIncome": 3, + "Equipment": 38, + "Expenses": 214, + "Hardware": 2, + "Income": 182, + "Marketing": 32, + "NetIncome": -32, + "Office Supplies": 2, + "R&D": 27, + "Rent": 36, + "Salaries": 21, + "Software": 5, + "Utilities": 43 + } + ], + "schema": { + "fields": [ + { + "name": "Date", + "type": "string" + }, + { + "name": "Income", + "type": "integer" + }, + { + "name": "Expenses", + "type": "integer" + }, + { + "name": "NetIncome", + "type": "integer" + }, + { + "name": "BudgetIncome", + "type": "integer" + }, + { + "name": "ActualIncome", + "type": "integer" + }, + { + "name": "BudgetExpenses", + "type": "integer" + }, + { + "name": "ActualExpenses", + "type": "integer" + }, + { + "name": "Salaries", + "type": "integer" + }, + { + "name": "R&D", + "type": "integer" + }, + { + "name": "Marketing", + "type": "integer" + }, + { + "name": "Utilities", + "type": "integer" + }, + { + "name": "Rent", + "type": "integer" + }, + { + "name": "Equipment", + "type": "integer" + }, + { + "name": "Software", + "type": "integer" + }, + { + "name": "Hardware", + "type": "integer" + }, + { + "name": "Consulting", + "type": "integer" + }, + { + "name": "Office Supplies", + "type": "integer" + }, + { + "name": "DiffIncome", + "type": "integer" + }, + { + "name": "DiffExpenses", + "type": "integer" + } + ] + } + }, + "text/html": [ + "
DateIncomeExpensesNetIncomeBudgetIncomeActualIncomeBudgetExpensesActualExpensesSalariesR&DMarketingUtilitiesRentEquipmentSoftwareHardwareConsultingOffice SuppliesDiffIncomeDiffExpenses
2022-06-18340270703323402642703944473833448926-8-6
2022-03-16401265136403401266265423240444841373521
2022-05-07192213-211891922102134628263138254375-3-3
2022-07-092912385329629123323834373246482249425-5
2022-06-2226223923268262242239482436374030349863
2022-03-31299237622922992422373020332948488786-75
2022-02-2428423747293284245237243841364137137998
2022-05-3026920069270269200200492532222126278810
2022-03-2330425054316304248250394930304842271212-2
2022-05-28182214-3218518221321421273243363852823-1
" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let response = await fetch(\n", + " \"https://gist.githubusercontent.com/agustinustheo/195f32a4a6c68c493056c883d959ca35/raw/c7363d8b916ab00a2d1747adb89fca120da29f42/mock_financial_data.csv\",\n", + ");\n", + "\n", + "let data = await response.text();\n", + "\n", + "let df = pl.readCSV(data, { sep: \",\" });\n", + "\n", + "await display(df.sample(10));" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "e5132db2-735b-4f81-9511-8e9c868bbcb2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32mDownloading\u001b[39m https://github.com/DjDeveloperr/skia_canvas/releases/download/0.5.8/libnative_canvas.so\n" + ] + } + ], + "source": [ + "import * as d3 from \"npm:d3\";\n", + "import { createCanvas } from \"https://deno.land/x/skia_canvas/mod.ts\";" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "3f54f383-1e48-431d-926b-897c54d38601", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " Date: \"2022-07-19\",\n", + " Income: 316,\n", + " Expenses: 211,\n", + " NetIncome: 105,\n", + " BudgetIncome: 317,\n", + " ActualIncome: 316,\n", + " BudgetExpenses: 212,\n", + " ActualExpenses: 211,\n", + " Salaries: 29,\n", + " \"R&D\": 48,\n", + " Marketing: 20,\n", + " Utilities: 35,\n", + " Rent: 22,\n", + " Equipment: 39,\n", + " Software: 3,\n", + " Hardware: 3,\n", + " Consulting: 6,\n", + " \"Office Supplies\": 6,\n", + " DiffIncome: 1,\n", + " DiffExpenses: 1\n", + "}\n" + ] + } + ], + "source": [ + "const lastDataPoint = df.tail(1).toRecords()[0];\n", + "console.log(lastDataPoint);" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "be1d2f7c-5537-4428-ab94-3410d9b07cc1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[33m10\u001b[39m" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let categories = ['Salaries', 'R&D', 'Marketing', 'Utilities', 'Rent', 'Equipment', 'Software', 'Hardware', 'Consulting', 'Office Supplies'];\n", + "\n", + "// Sample data\n", + "const sampleData1 = [];\n", + "for(let i = 0; i < categories.length; i++) {\n", + " const category = categories[i];\n", + " sampleData1.push({\n", + " category,\n", + " amount: lastDataPoint[category],\n", + " });\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "9e6414d0-3b56-438c-be30-74080dbd706a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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" + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "const width = 500;\n", + "const height = 500;\n", + "const radius = Math.min(width, height) / 2;\n", + "\n", + "// Create a pie function\n", + "const pie = d3.pie().value(d => d.amount);\n", + "\n", + "// Create an arc generator for the slices\n", + "const arc = d3.arc()\n", + " .innerRadius(0)\n", + " .outerRadius(radius);\n", + "\n", + "// Create an arc generator for the labels\n", + "const labelArc = d3.arc()\n", + " .innerRadius(radius - 40) // Adjust to position the labels\n", + " .outerRadius(radius - 40);\n", + "\n", + "// Create the canvas\n", + "const canvas = createCanvas(width, height);\n", + "const ctx = canvas.getContext(\"2d\");\n", + "\n", + "// Translate to center the pie chart\n", + "ctx.translate(width / 2, height / 2);\n", + "\n", + "// Draw the pie chart\n", + "pie(sampleData1).forEach((d, i) => {\n", + " // Draw the slice\n", + " ctx.beginPath();\n", + " arc.context(ctx)(d);\n", + " ctx.fillStyle = d3.schemeCategory10[i % 10];\n", + " ctx.fill();\n", + "\n", + " // Draw the label\n", + " ctx.fillStyle = \"#000\"; // Label color\n", + " ctx.textAlign = \"center\";\n", + " ctx.textBaseline = \"middle\";\n", + "\n", + " const centroid = labelArc.centroid(d);\n", + " ctx.fillText(d.data.category, centroid[0], centroid[1]);\n", + "});\n", + "\n", + "// Display the canvas\n", + "await display(canvas);" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e511a773-aab3-4525-a63e-a2ba90b3f85e", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + }, + "toc": { + "base_numbering": 1 + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/01 Einführung/Untitled1.ipynb b/01 Einführung/Untitled1.ipynb new file mode 100644 index 0000000..f1765b9 --- /dev/null +++ b/01 Einführung/Untitled1.ipynb @@ -0,0 +1,413 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "da1f2271-09ca-4665-9c88-d0e19defb876", + "metadata": {}, + "outputs": [], + "source": [ + "import pl from \"npm:nodejs-polars\";\n", + "import { display } from \"https://deno.land/x/display@v0.1.1/mod.ts\";" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "20c60624-0371-463e-98cf-42bc77377f5f", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.dataresource+json": { + "data": [ + { + "ActualExpenses": 216, + "ActualIncome": 255, + "BudgetExpenses": 217, + "BudgetIncome": 256, + "Consulting": 3, + "Date": "2022-03-22", + "DiffExpenses": 1, + "DiffIncome": 1, + "Equipment": 47, + "Expenses": 216, + "Hardware": 3, + "Income": 255, + "Marketing": 27, + "NetIncome": 39, + "Office Supplies": 3, + "R&D": 39, + "Rent": 41, + "Salaries": 20, + "Software": 3, + "Utilities": 30 + }, + { + "ActualExpenses": 225, + "ActualIncome": 317, + "BudgetExpenses": 226, + "BudgetIncome": 301, + "Consulting": 2, + "Date": "2022-01-24", + "DiffExpenses": 1, + "DiffIncome": -16, + "Equipment": 27, + "Expenses": 225, + "Hardware": 4, + "Income": 317, + "Marketing": 39, + "NetIncome": 92, + "Office Supplies": 3, + "R&D": 46, + "Rent": 34, + "Salaries": 32, + "Software": 4, + "Utilities": 34 + }, + { + "ActualExpenses": 239, + "ActualIncome": 287, + "BudgetExpenses": 237, + "BudgetIncome": 281, + "Consulting": 6, + "Date": "2022-07-17", + "DiffExpenses": -2, + "DiffIncome": -6, + "Equipment": 37, + "Expenses": 239, + "Hardware": 2, + "Income": 287, + "Marketing": 36, + "NetIncome": 48, + "Office Supplies": 5, + "R&D": 39, + "Rent": 46, + "Salaries": 38, + "Software": 6, + "Utilities": 24 + }, + { + "ActualExpenses": 227, + "ActualIncome": 264, + "BudgetExpenses": 229, + "BudgetIncome": 268, + "Consulting": 7, + "Date": "2022-03-06", + "DiffExpenses": 2, + "DiffIncome": 4, + "Equipment": 22, + "Expenses": 227, + "Hardware": 5, + "Income": 264, + "Marketing": 27, + "NetIncome": 37, + "Office Supplies": 2, + "R&D": 47, + "Rent": 32, + "Salaries": 45, + "Software": 3, + "Utilities": 37 + }, + { + "ActualExpenses": 212, + "ActualIncome": 276, + "BudgetExpenses": 206, + "BudgetIncome": 283, + "Consulting": 8, + "Date": "2022-03-18", + "DiffExpenses": -6, + "DiffIncome": 7, + "Equipment": 43, + "Expenses": 212, + "Hardware": 2, + "Income": 276, + "Marketing": 28, + "NetIncome": 64, + "Office Supplies": 2, + "R&D": 29, + "Rent": 27, + "Salaries": 29, + "Software": 2, + "Utilities": 42 + }, + { + "ActualExpenses": 259, + "ActualIncome": 294, + "BudgetExpenses": 257, + "BudgetIncome": 281, + "Consulting": 8, + "Date": "2022-06-10", + "DiffExpenses": -2, + "DiffIncome": -13, + "Equipment": 47, + "Expenses": 259, + "Hardware": 8, + "Income": 294, + "Marketing": 24, + "NetIncome": 35, + "Office Supplies": 6, + "R&D": 49, + "Rent": 48, + "Salaries": 40, + "Software": 4, + "Utilities": 25 + }, + { + "ActualExpenses": 216, + "ActualIncome": 317, + "BudgetExpenses": 210, + "BudgetIncome": 312, + "Consulting": 3, + "Date": "2022-02-04", + "DiffExpenses": -6, + "DiffIncome": -5, + "Equipment": 26, + "Expenses": 216, + "Hardware": 6, + "Income": 317, + "Marketing": 21, + "NetIncome": 101, + "Office Supplies": 6, + "R&D": 34, + "Rent": 27, + "Salaries": 44, + "Software": 7, + "Utilities": 42 + }, + { + "ActualExpenses": 213, + "ActualIncome": 233, + "BudgetExpenses": 212, + "BudgetIncome": 221, + "Consulting": 3, + "Date": "2022-06-13", + "DiffExpenses": -1, + "DiffIncome": -12, + "Equipment": 41, + "Expenses": 213, + "Hardware": 1, + "Income": 233, + "Marketing": 46, + "NetIncome": 20, + "Office Supplies": 1, + "R&D": 25, + "Rent": 44, + "Salaries": 20, + "Software": 9, + "Utilities": 23 + }, + { + "ActualExpenses": 242, + "ActualIncome": 305, + "BudgetExpenses": 240, + "BudgetIncome": 310, + "Consulting": 3, + "Date": "2022-03-11", + "DiffExpenses": -2, + "DiffIncome": 5, + "Equipment": 26, + "Expenses": 242, + "Hardware": 3, + "Income": 305, + "Marketing": 23, + "NetIncome": 63, + "Office Supplies": 9, + "R&D": 48, + "Rent": 34, + "Salaries": 39, + "Software": 8, + "Utilities": 49 + }, + { + "ActualExpenses": 205, + "ActualIncome": 248, + "BudgetExpenses": 199, + "BudgetIncome": 248, + "Consulting": 4, + "Date": "2022-01-28", + "DiffExpenses": -6, + "DiffIncome": 0, + "Equipment": 30, + "Expenses": 205, + "Hardware": 8, + "Income": 248, + "Marketing": 37, + "NetIncome": 43, + "Office Supplies": 5, + "R&D": 42, + "Rent": 25, + "Salaries": 26, + "Software": 4, + "Utilities": 24 + } + ], + "schema": { + "fields": [ + { + "name": "Date", + "type": "string" + }, + { + "name": "Income", + "type": "integer" + }, + { + "name": "Expenses", + "type": "integer" + }, + { + "name": "NetIncome", + "type": "integer" + }, + { + "name": "BudgetIncome", + "type": "integer" + }, + { + "name": "ActualIncome", + "type": "integer" + }, + { + "name": "BudgetExpenses", + "type": "integer" + }, + { + "name": "ActualExpenses", + "type": "integer" + }, + { + "name": "Salaries", + "type": "integer" + }, + { + "name": "R&D", + "type": "integer" + }, + { + "name": "Marketing", + "type": "integer" + }, + { + "name": "Utilities", + "type": "integer" + }, + { + "name": "Rent", + "type": "integer" + }, + { + "name": "Equipment", + "type": "integer" + }, + { + "name": "Software", + "type": "integer" + }, + { + "name": "Hardware", + "type": "integer" + }, + { + "name": "Consulting", + "type": "integer" + }, + { + "name": "Office Supplies", + "type": "integer" + }, + { + "name": "DiffIncome", + "type": "integer" + }, + { + "name": "DiffExpenses", + "type": "integer" + } + ] + } + }, + "text/html": [ + "
DateIncomeExpensesNetIncomeBudgetIncomeActualIncomeBudgetExpensesActualExpensesSalariesR&DMarketingUtilitiesRentEquipmentSoftwareHardwareConsultingOffice SuppliesDiffIncomeDiffExpenses
2022-03-2225521639256255217216203927304147333311
2022-01-24317225923013172262253246393434274423-161
2022-07-17287239482812872372393839362446376265-6-2
2022-03-0626422737268264229227454727373222357242
2022-03-182762126428327620621229292842274322827-6
2022-06-10294259352812942572594049242548474886-13-2
2022-02-043172161013123172102164434214227267636-5-6
2022-06-13233213202212332122132025462344419131-12-1
2022-03-113052426331030524024239482349342683395-2
2022-01-282482054324824819920526423724253048450-6
" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let response = await fetch(\n", + " \"https://gist.githubusercontent.com/agustinustheo/195f32a4a6c68c493056c883d959ca35/raw/c7363d8b916ab00a2d1747adb89fca120da29f42/mock_financial_data.csv\",\n", + ");\n", + "\n", + "let data = await response.text();\n", + "\n", + "let df = pl.readCSV(data, { sep: \",\" });\n", + "\n", + "await display(df.sample(10));" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "18396e24-7e98-40d8-8a2b-9ed9e2dd7e67", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n" + ] + } + ], + "source": [ + "for (let i = 0; i < 10; i++) {\n", + " console.log(i)\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c5fd29b9-3704-4b9f-b26a-00a09c43dd27", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}