From 55c62ffc5ac443fb88f89eac8df11f62db40dce6 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Thu, 23 Jan 2025 22:21:46 +0100 Subject: [PATCH] added type annotation to zusammenfassung --- .../type-annotations/type-annotations.typ | 118 +++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/Zusammenfassungen/type-annotations/type-annotations.typ b/Zusammenfassungen/type-annotations/type-annotations.typ index ac55686..bdf2060 100644 --- a/Zusammenfassungen/type-annotations/type-annotations.typ +++ b/Zusammenfassungen/type-annotations/type-annotations.typ @@ -1,7 +1,7 @@ #import "../../templates/template.typ": * #show: project.with( - title: "Type Annotations", + title: "Zusammenfassung", subtitle: "Einführung in die Programmierung", logo: "unifreiburglogo.png", authors: ( @@ -67,4 +67,118 @@ Neben den typischen arithmetischen Operatoren aus der Mathematik brauchen wir au - Äquivalenz ist etwas schwieriger, denn diese unterscheidet sich manchmal von Paradigmen zu Paradigmen. Aber für den Anfang sagen wir einfach wenn etwas gleich ist, dann ist es äquivalent: `a == b` - Kleiner/Größer als: `a > b`, `a < b` -- Kleiner/Größer-Gleich als: `a >= b`, `a <= b` \ No newline at end of file +- Kleiner/Größer-Gleich als: `a >= b`, `a <= b` + +=== Datentypen + +Um Daten zu beschreiben müssen wir diesen auch gewisse Typen zuordnen, welche deren Verhalten/Zustände beschreiben. + +Nehmen wir hierfür die bekannten Mengendefinitionen der Zahlen in der Mathematik. Also z.B. die natürlichen Zahlen $NN$ und die rationalen Zahlen $RR$. Wir wissen dass die natürlichen Zahlen $NN$ in die rationalen Zahlen $RR$ _reinpassen_. + +In Python stellen wir die natürlichen Zahlen $NN$ als `int` da. Die ratinoalen Zahlen $RR$ als `float`. Für uns ist `1 + 1 = 2` ziemlich eindeutig und uns ist egal ob jetzt mit `1` oder `2` eine rationale oder natürliche Zahl gemeint ist. Bei Programmiersprachen müssen wir aber genauer sein. Also ist `1` ein `int` und `1.0` eine `float`. + +Deswegen muss man jetzt aufpassen was passiert welche Datentypen man zusammenrechnet. + +$ + underbrace(underbrace(underbrace(6, "int") * underbrace("round(2.1, 1)", "float"), "float") " // " underbrace(2, "int"), "float, also 6.0") +$ + +Hier wandelt Python einen `int` direkt um zu einem `float`, da wir ja wissen dass $NN subset RR$ ist. Genauso hat aber alles einen Datentypen. Auch die Funktionen die wir schreiben. + +=== Typannotationen + +Um beim Schreiben von Python-Skripten die Datentypen zu veranschaulichen und besser lesbar zu machen, schreiben wir Typannotation. Hierbei ist nicht alles verpflichtend, sondern nur an den Stellen, an welchen der Datentyp nicht direkt offensichtlich ist. + +==== Variabeln + +Variabeln können eine Typannotation haben, ist aber eher offensichtlich und daher unnötig + +```py +x: int = 1 +``` + +==== Funktionen + +Funktionen, oder genauer der Funktionskopf/Funktionssignatur benötigt eine Typannotation. Woher sollte man sonst wissen welche Parameter man verwendet oder was einem diese Funktion zurückgibt? + +```py +def add(a: int, b: int) -> int: + return a + b +``` + +==== Klassen + +Datenklassen benötigen sowieso Typannotation da der Code sonst gar nicht funktioniert. + +```py +from dataclasses import dataclass + + +@dataclass +class Vec2D: + x: float + y: float +``` + +Mit einer Klasse erstellen wir einen neuen Bauplan, sprich `Vec2D` ist jetzt auch ein Datentyp den wir verwenden können. + +==== Methoden + +Methoden sind die Funktionen der Objekte, es heißt Methode weil das Verhalten von einem Objekt modelliert wird. Genau wie Funktionen brauchen wir eine Typannotation. Mit dem kleinen Unterschied dass `self` keine braucht, da wir ja wissen was `self` ist. + +```py +from dataclasses import dataclass +from math import sqrt + + +@dataclass +class Vec2D: + x: float + y: float + + def abs(self) -> float: + return sqrt(self.x ** 2 + self.y ** 2) + + def __eq__(self, other: 'Vec2D') -> bool: + if not isinstance(other, Vec2D): + return False + return self.x == other.x and self.y == other.y +``` + +==== Listen, Dictionary, Tuple + +Listen sind, wer hätte es gedacht, Listen aus Objekten die auch wieder Datentypen haben. Das müssen wir bei der Typannotation berücksichtigen. + +```py +my_list: list[str] = ["hello", "world"] +``` + +Dictionary bestehen immer aus Keys mit Datentypen und Values mit Datentypen. Deswegen müssen wir auch beides bei der Definition angeben. + +```py +my_dict: dict[int, str] = { 1: "hello", 2: "world" } +``` +Tupel beschreiben eine endliche Aufzählung von Dingen, also kann nicht größer oder kleiner werden. Deshalb müssen wir jedes einzelne Element einen Datentypen zuordnen. + +```py +my_tuple: tuple[str, str, int, float] = ("hello", "world", 69, 420.0) +``` + +==== Lambda + +Von Lambda würde ich eher abraten wenn man nicht genau weiß was man tut, aber auch Funktionen haben einen Datentyp und muss verwendet werden. + +```py +add: Callable[[int, int], int] = lambda a, b: a + b +``` + +Genauso haben aber Funktionen die mit `def` geschrieben wurden denselben Datentyp. + +```py + +def add(a: int, b: int) -> int: + return a + b + +add_2: Callable[[int, int], int] = add + +``` \ No newline at end of file