From 8536a1ec885f997e62ee3f5e6ad7c0f195bf859a Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Tue, 6 Feb 2024 17:12:47 +0100 Subject: [PATCH] added unteschiede-note --- Notes/Unterschiede.md | 140 ++++++++++++++++++++++++++++++++++++++ Notes/src/unterschiede.py | 68 ++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 Notes/Unterschiede.md create mode 100644 Notes/src/unterschiede.py diff --git a/Notes/Unterschiede.md b/Notes/Unterschiede.md new file mode 100644 index 0000000..c59c318 --- /dev/null +++ b/Notes/Unterschiede.md @@ -0,0 +1,140 @@ +# Unterschiede zu Vorjahren + +## Typalias + +Manchmal braucht man eine Kombination aus Datentypen + +### Vorher + +Erstellen von Typaliasen mit `Union` + +```python +from typing import Union + +# `RealNumber` ist also eine `int` oder eine `float` +RealNumber = Union[int, float] + +# also geht hier +# `add(1, 1) -> 2` +# `add(1.0, 1.0) -> 2.0` +# aber auch +# `add(1, 1.0) -> 2.0` +def add(x: RealNumber, y: RealNumber) -> RealNumber: + return x + y +``` + +### In Python3.12 + +Wir haben jetzt das `type`-Keyword für das wir nichts importieren müssen und können einfach Datentypen mit `|` *odern* + +```python +# `type` statt `Union` +type NewRealNumber = int | float + +# sonst sieht alles gleich aus +def new_add(x: NewRealNumber, y: NewRealNumber) -> NewRealNumber: + return x + y +``` + +## Generiche Typ-Parameter (Generics, Typvariabeln, ...) + +### Vorher + +Erstellen von generischen Typvariabeln/Typ-Parametern mit `TypeVar` aus `typing`: + +```python +from typing import Generic, TypeVar, Optional +from dataclasses import dataclass, field + +# T ist unser Platzhalten für einen beliebigen Datentyp +T = TypeVar('T') + +# jetzt können wir `T` einfach als Platzhalter für einen beliebigen Datentyp verwenden +# praktisch weil wir so wissen dass `x`, `y` und der `return` zumindest den **selben** Datentyp verwenden +# aber welcher genau wissen wir nicht bis jemand die Funktion mit z.b. `int` oder `float`! +# Zum Beispiel bedeutet dass +# `add(1, 2) == 3` => `T == int` +# `add(1.0, 2.0) == 3.0` => `T == float` +# ... +def add(x: T, y: T) -> T: + return x + y + +# Ebenso können wir `T` auch für Klassen verwenden +@dataclass +# wir müssen hier festlegen dass T in der Klasse verwendet wird +# indem `MyList` von `Generic[UnsereGenerischeVariabel]` erbt +class MyList(Generic[T]): + + def __post_init__(self, ): + # wir haben intern eine `internal_list` die von außen nicht sichtbar ist + self.__internal_list: list[T] = field(default_factory=list) + # hier speichern wir uns die aktuelle Länge unserer Liste + self.__length: int = 0 + + def append(self, value: T): + """fügt ein element mit dem Typ `T` hinzu""" + self.__internal_list += [value] + self.__length += 1 + + def remove(self, value: T): + """entfert das element `value`, wenn es in unserer Liste ist""" + if value in self.__internal_list: + self.__internal_list.remove(value) + + def get(self, i: int) -> Optional[T]: + """gibt das element an `i` Stelle zurück. Wenn Liste kleiner als `i` ist, dann `None`""" + if i < len(self): + return self[i] + return None + + def __len__(self) -> int: + return self.__length + + def __getitem__(self, i: int) -> T: + return self.__internal_list[i] +``` + +### In Python3.12 + +Deklaration der Typvariabel direkt im Funktionskopf/Klassenkopf mit `[]`. +Sprich wir brauchen `TypeVar` nicht mehr + +```python +from typing import Optional +from dataclasses import dataclass, field + + +# hier wird `V` durch `[V]` deklariert und kann in der Funktion benutzt werden +def new_add[V](x: V, y: V) -> V: + return x + y + + +# hier wird `T` für die Klasse `NewMyList` deklariert durch `[T]` und kann überall in der Klasse genutzt werden +# der Rest ist genau gleich, das einzige was sich eben geändert hat ist dass man dieses `TypeVar` nicht mehr braucht +# sondern direkt in der Deklaration von Klassen/Funktionen/Methoden die generischen Typvariabeln mit deklariert +@dataclass +class NewMyList[T]: + + def __post_init__(self, ): + self.__internal_list: list[T] = field(default_factory=list) + self.__length: int = 0 + + def append(self, value: T): + self.__internal_list += [value] + self.__length += 1 + + def remove(self, value: T): + if value in self.__internal_list: + self.__internal_list.remove(value) + + def get(self, i: int) -> Optional[T]: + if i < len(self): + return self[i] + return None + + def __len__(self) -> int: + return self.__length + + def __getitem__(self, i: int) -> T: + return self.__internal_list[i] +``` \ No newline at end of file diff --git a/Notes/src/unterschiede.py b/Notes/src/unterschiede.py new file mode 100644 index 0000000..c567d99 --- /dev/null +++ b/Notes/src/unterschiede.py @@ -0,0 +1,68 @@ +from typing import Generic, TypeVar, Optional, Union +from dataclasses import dataclass, field + +T = TypeVar('T') + +@dataclass +class MyList(Generic[T]): + + def __post_init__(self, ): + self.__internal_list: list[T] = field(default_factory=list) + self.__length: int = 0 + + def append(self, value: T): + self.__internal_list += [value] + self.__length += 1 + + def remove(self, value: T): + if value in self.__internal_list: + self.__internal_list.remove(value) + + def get(self, i: int) -> Optional[T]: + if i < len(self): + return self[i] + return None + + def __len__(self) -> int: + return self.__length + + def __getitem__(self, i: int) -> T: + return self.__internal_list[i] + +@dataclass +class MyListNew[T]: + + def __post_init__(self, ): + self.__internal_list: list[T] = field(default_factory=list) + self.__length: int = 0 + + def append(self, value: T): + self.__internal_list += [value] + self.__length += 1 + + def remove(self, value: T): + if value in self.__internal_list: + self.__internal_list.remove(value) + + def get(self, i: int) -> Optional[T]: + if i < len(self): + return self[i] + return None + + def __len__(self) -> int: + return self.__length + + def __getitem__(self, i: int) -> T: + return self.__internal_list[i] + + +RealNumber = Union[int, float] + +def add(x: RealNumber, y: RealNumber) -> RealNumber: + return x + y + +type NewRealNumber = int | float + +# sonst sieht alles gleich aus +def new_add(x: NewRealNumber, y: NewRealNumber) -> NewRealNumber: + return x + y \ No newline at end of file