diff --git a/src/3_Data_Types_Multiple_Dispatch.ipynb b/src/3_Data_Types_Multiple_Dispatch.ipynb index 87d4a2c1e6e7c0bceb35a4a1b433ec6eafa2ea5f..fe5583e0e602b66850dd69608371431efe4e1585 100644 --- a/src/3_Data_Types_Multiple_Dispatch.ipynb +++ b/src/3_Data_Types_Multiple_Dispatch.ipynb @@ -1,5 +1,232 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "24afcfe8-2739-4d92-a592-951071fa9df2", + "metadata": {}, + "source": [ + "## Constructors\n", + "\n", + "Before venturing forward in this notebook, we need a last ingredient from structs: custom constructors.\n", + "A constructor is a special function that is called to create an object. We take as an example a `Date` struct." + ] + }, + { + "cell_type": "markdown", + "id": "f59de749-6cd1-4f77-b89e-57b110d83858", + "metadata": {}, + "source": [ + "## Konstruktoren\n", + "\n", + "Bevor wir in diesem Notebook weitermachen, benötigen wir noch eine letzte Zutat aus Strukturen: benutzerdefinierte Konstruktoren.\n", + "Ein Konstruktor ist eine spezielle Funktion, die aufgerufen wird, um ein Objekt zu erstellen. Wir nehmen als Beispiel eine `Datum` Struktur." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c171ec1a-902b-4211-b250-373953f4c58c", + "metadata": {}, + "outputs": [], + "source": [ + "struct Date\n", + " day::Integer\n", + " month::Integer\n", + " year::Integer\n", + "end" + ] + }, + { + "cell_type": "markdown", + "id": "6857074a-eed4-4e56-9775-89779c37dfce", + "metadata": {}, + "source": [ + "We can instantiate a new date by invoking the default constructor." + ] + }, + { + "cell_type": "markdown", + "id": "c39605b9-2667-4c9d-8b1f-f6505baa0838", + "metadata": {}, + "source": [ + "Wir können ein neues Datum instanziieren, indem wir den Standardkonstruktor aufrufen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "63630a93-6d93-489a-9656-9ac6b5be86f5", + "metadata": {}, + "outputs": [], + "source": [ + "date = Date(1, 11, 2023)\n", + "@show date;" + ] + }, + { + "cell_type": "markdown", + "id": "35369021-8d35-4f65-818f-feb94d3efdf7", + "metadata": {}, + "source": [ + "However, if we are not satisfied by the default behavior of the constructor, we can define our custom constructor which implements custom behavior. For example, we might be interested in a constructor which takes as input a string in the form `DD.MM.YYYY`." + ] + }, + { + "cell_type": "markdown", + "id": "2cad81b4-b9df-42f3-a89b-8340036bbe8e", + "metadata": {}, + "source": [ + "Wenn wir jedoch mit dem Standardverhalten des Konstruktors nicht zufrieden sind, können wir unseren eigenen Konstruktor definieren, der ein benutzerdefiniertes Verhalten implementiert. Zum Beispiel könnten wir an einem Konstruktor interessiert sein, der eine Zeichenkette im Format `TT.MM.JJJJ` als Eingabe akzeptiert.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34e84e19-734a-42c0-b263-2dc25128c0cd", + "metadata": {}, + "outputs": [], + "source": [ + "function Date(str::String)\n", + " parts = split(str, \".\")\n", + " if length(parts) != 3\n", + " throw(ArgumentError(\"Invalid date format. Use DD.MM.YYYY\"))\n", + " end\n", + "\n", + " d = parse(Int, parts[1])\n", + " m = parse(Int, parts[2])\n", + " y = parse(Int, parts[3])\n", + "\n", + " return Date(d, m, y)\n", + "end\n", + "\n", + "date = Date(\"01.11.2023\")\n", + "@show date;" + ] + }, + { + "cell_type": "markdown", + "id": "90876390-1115-4b26-99b9-9221c15a1eb7", + "metadata": {}, + "source": [ + "Alternatively, constructors can be also defined inside the struct. The advantage of this strategy is that we are replacing the default constructor with custom behavior." + ] + }, + { + "cell_type": "markdown", + "id": "915b71b1-c188-4c82-a2ff-810a58f39720", + "metadata": {}, + "source": [ + "Alternativ können Konstruktoren auch innerhalb der Struktur definiert werden. Der Vorteil dieser Strategie ist, dass wir den Standardkonstruktor durch benutzerdefiniertes Verhalten ersetzen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6dda7612-0cd2-471a-93e4-119a4e2f8f93", + "metadata": {}, + "outputs": [], + "source": [ + "struct ValidatedDate\n", + " day::Integer\n", + " month::Integer\n", + " year::Integer\n", + " function ValidatedDate(day, month, year)\n", + " @assert(day > 0, \"day is negative\")\n", + " @assert(month > 0, \"month is negative\")\n", + " @assert(year > 0, \"year is negative\")\n", + " new(day, month, year)\n", + " end\n", + "end\n", + "\n", + "date = ValidatedDate(-1, 10, 2023)" + ] + }, + { + "cell_type": "markdown", + "id": "e676156a-5f36-44b8-b8c1-95bf6d475e07", + "metadata": {}, + "source": [ + "### Exercises\n", + "\n", + " - Write a custom constructor that takes the just the month and the year as input arguments and set the day to 1." + ] + }, + { + "cell_type": "markdown", + "id": "89ab4f63-bd67-4cca-919a-f0d8f2bc88d1", + "metadata": {}, + "source": [ + "### Übungen\n", + "\n", + " - Schreibe einen benutzerdefinierten Konstruktor, der nur den Monat und das Jahr als Eingabeargumente akzeptiert und den Tag auf 1 setzt." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "884e42ed-d340-410c-ad42-950e173807c8", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here.\n" + ] + }, + { + "cell_type": "markdown", + "id": "48ce73e0-a9f2-48b8-974c-85147cce8d5f", + "metadata": {}, + "source": [ + " - Modify the `ValidatedDate` inner constructor in such a way that it checks if the specified day exists in the given month. Assume that February has always 28 days." + ] + }, + { + "cell_type": "markdown", + "id": "459a7d50-1138-4fc1-af46-a0bdb4335287", + "metadata": {}, + "source": [ + " - Passe den `ValidatedDate` inneren Konstruktor so an, dass er überprüft, ob der angegebene Tag im angegebenen Monat existiert. Nehmen Sie an, dass der Februar immer 28 Tage hat." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eeb10ef4-0bb5-46e0-96b4-0fb98e4e1b3d", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here.\n" + ] + }, + { + "cell_type": "markdown", + "id": "063d5208-3297-4df4-8613-4d2c16a2d2c0", + "metadata": {}, + "source": [ + " - Optional: modify the previous result and account also for leap years.\n", + "\n", + " `Every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100, but these centurial years are leap years if they are exactly divisible by 400. For example, the years 1700, 1800, and 1900 are not leap years, but the years 1600 and 2000 are.`" + ] + }, + { + "cell_type": "markdown", + "id": "169512ca-868f-406d-b8c8-8e9174d25b64", + "metadata": {}, + "source": [ + " - Optional: Passe das vorherige Ergebnis an und berücksichtige auch Schaltjahre.\n", + "\n", + " `Jedes Jahr, das genau durch vier teilbar ist, ist ein Schaltjahr, mit Ausnahme von Jahren, die genau durch 100 teilbar sind. Diese Jahrhundertjahre sind jedoch Schaltjahre, wenn sie genau durch 400 teilbar sind. Zum Beispiel sind die Jahre 1700, 1800 und 1900 keine Schaltjahre, aber die Jahre 1600 und 2000 sind es.`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8b1dad51-d7cf-43aa-a2c8-9b3eaa4a1f4d", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: implement your code here.\n" + ] + }, { "cell_type": "markdown", "id": "debc3515-fa08-4577-82bb-9eced849d616", @@ -660,24 +887,7 @@ "metadata": {}, "outputs": [], "source": [ - "# TODO: implement your code\n", - "abstract type Bird <: Animal end # Abstract type\n", - "\n", - "struct Taubeb <: Bird\n", - " name::String\n", - " age::Int\n", - " Beute::String\n", - "end\n", - "\n", - "struct Falke <: Bird\n", - " Beute::String\n", - " MaxSpeed::Float64\n", - "end\n", - "\n", - "print_type_tree(Animal)\n", - "\n", - "a_Taube = Taubeb(\"F\", 2, \"Maus\")\n", - "a_Falke = Falke(\"Wiesel\", 200)\n" + "# TODO: implement your code\n" ] }, { @@ -715,8 +925,7 @@ "metadata": {}, "outputs": [], "source": [ - "# TODO: implement your code\n", - "Float64 <: AbstractFloat" + "# TODO: implement your code\n" ] }, { @@ -1370,20 +1579,6 @@ "Julia ist irgendwie beides." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3ef4e3d0", - "metadata": {}, - "outputs": [], - "source": [ - "x = Dog(\"Buddy\", 4) # x is an Dog\n", - "@show typeof(x)\n", - "\n", - "x = Cat(\"Kitty\", 3) # Now x is a Cat\n", - "@show typeof(x);\n" - ] - }, { "cell_type": "markdown", "id": "a02c0a37", @@ -1499,73 +1694,13 @@ "metadata": {}, "outputs": [], "source": [ - "# TODO: implement your code here.\n", - "abstract type AbstractPolynomial end # Abstract type\n", - "\n", - "struct PolynomialDegree0 <: AbstractPolynomial\n", - " coeff::Dict\n", - "end\n", - "\n", - "struct PolynomialDegree1 <: AbstractPolynomial\n", - " coeff::Dict\n", - "end\n", - "\n", - "struct PolynomialDegree2 <: AbstractPolynomial\n", - " coeff::Dict\n", - "end\n", - "\n", - "struct PolynomialArbitraryDegree <: AbstractPolynomial\n", - " coeff::Dict\n", - "end\n", - "\n", - "function PolynomialDegree0(a0::Real) \n", - " coeff[0] = a0\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f6258d48-096e-4c7f-b9d3-aa1bc1db744e", - "metadata": {}, - "outputs": [], - "source": [ - "print_type_tree(AbstractPolynomial)\n", - "a = PolynomialDegree0(2.0)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c0412892-8a47-4583-a0e1-92d2927f4d0d", - "metadata": {}, - "outputs": [], - "source": [ - "c[1] = 3.2\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "deef05e8-a7c1-4c92-8db0-8c6ab510888d", - "metadata": {}, - "outputs": [], - "source": [ - "c\n" + "# TODO: implement your code here.\n" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "757d616e-4479-4755-ae71-3af310453a00", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { "kernelspec": { - "display_name": "julia 1.9.3", + "display_name": "Julia 1.9.3", "language": "julia", "name": "julia-1.9" },