added type annotation to zusammenfassung

This commit is contained in:
2025-01-23 22:21:46 +01:00
parent ccc8fe8be4
commit 55c62ffc5a

View File

@ -1,7 +1,7 @@
#import "../../templates/template.typ": * #import "../../templates/template.typ": *
#show: project.with( #show: project.with(
title: "Type Annotations", title: "Zusammenfassung",
subtitle: "Einführung in die Programmierung", subtitle: "Einführung in die Programmierung",
logo: "unifreiburglogo.png", logo: "unifreiburglogo.png",
authors: ( 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` - Ä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 als: `a > b`, `a < b`
- Kleiner/Größer-Gleich als: `a >= b`, `a <= b` - 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
```