From 11cb335e459ad8535b8a87deb1a2e36117869754 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Fri, 15 Dec 2023 06:25:06 +0100 Subject: [PATCH] tut 09 --- Tutorium/tut09/README.md | 514 ++++++++++++++++++ Tutorium/tut09/img/pointdistribution_ex07.png | Bin 0 -> 20885 bytes Tutorium/tut09/img/pointdistribution_ex08.png | Bin 0 -> 18474 bytes Tutorium/tut09/src/classes.py | 31 ++ Tutorium/tut09/src/my_collections.py | 55 ++ 5 files changed, 600 insertions(+) create mode 100644 Tutorium/tut09/img/pointdistribution_ex07.png create mode 100644 Tutorium/tut09/img/pointdistribution_ex08.png create mode 100644 Tutorium/tut09/src/classes.py create mode 100644 Tutorium/tut09/src/my_collections.py diff --git a/Tutorium/tut09/README.md b/Tutorium/tut09/README.md index e69de29..589718e 100644 --- a/Tutorium/tut09/README.md +++ b/Tutorium/tut09/README.md @@ -0,0 +1,514 @@ +--- +marp: true +paginate: true +class: invert +# theme: uncover +footer: Tutorium 09 - 16.12.2023 - Nils Pukropp - https://s.narl.io/s/tutorium-09 +header: +--- + +# Tutorium 09 + +Korrektur 08 - Vererbung, OOP, Datenkapselung + +--- + +# Korrektur 08 + +--- + +# Punkteverteilung + +![](img/pointdistribution_ex08.png) + +--- + +# Häufige Fehler + +* `@dataclass` nicht verwendet +* `__init__` überschrieben, obwohl `@dataclass` das macht und dann `super().__init__()` vergessen +* Kein Polymorphismus verwendet, also Code Duplikate oder auf `self` gematched/`isinstance()` verwendet +* Code nicht getestet, Datei nicht ausführbar => **0 Punkte**! + +--- + +# Musterlösung - Aufgabe 8 a,b) + +```py +import math +from dataclasses import dataclass + + +@dataclass +class Vec2: + x: float + y: float + + def abs(self) -> float: + return math.sqrt(self.x * self.x + self.y * self.y) +``` + +--- + +# Musterlösung - Aufgabe 8 c) + +```py +@dataclass +class GameObject: + position: Vec2 + radius: int + alive: bool + color: tuple[int, int, int] + +@dataclass +class Projectile(GameObject): + speed: float + +@dataclass +class StaticObject(GameObject): + rotation: float +``` + +--- + +# Musterlösung - Aufgabe 8 c) + +```py +class Item(StaticObject): + amount: int + +class Ammunition(Item): + pass + +class Health(Item): + pass + +class Ship(GameObject): + shots: int + hp: int + +class Asteroid(StaticObject): + special: bool +``` + +--- + +# Musterlösung - Aufgabe 8 d) + +```python +class GameObject: + + # ... + + def update(self, width: int, height: int, delta: float): + if not (0 <= self.position.x < width and 0 <= self.position.y < height): + self.alive = False + +class Projectile(GameObject): + speed: float + + def update(self, width: int, height: int, delta: float): + self.position.y -= delta * self.speed + super().update(width, height, delta) +``` + +--- + +# Musterlösung - Aufgabe 8 d) + +```python +class StaticObject(GameObject): + rotation: float + + def update(self, width: int, height: int, delta: float): + self.position.y += delta + self.rotation += delta / self.radius + super().update(width, height, delta) + +class Ship(GameObject): + shots: int + hp: int + + def update(self, width: int, height: int, delta: float): + if self.hp <= 0: + self.hp = 0 + self.alive = False + super().update(width, height, delta) +``` + +--- + +# Musterlösung - Aufgabe 8 e) + +```python +@dataclass +class GameObject: + + # ... + + def is_colliding(self, other: "GameObject") -> bool: + dist = Vec2(self.position.x - other.position.x, self.position.y - other.position.y) + return dist.abs() <= self.radius + other.radius +``` + +--- + +# Musterlösung - Aufgabe 8 f) + +```python +class GameObject: + + # ... + + def on_collision(self, other: "GameObject"): + pass + +class Projectile(GameObject): + + # ... + + def on_collision(self, other: 'GameObject'): + if not isinstance(other, Ship): + self.alive = False +``` + +--- + +# Musterlösung - Aufgabe 8 f) + +```python +class StaticObject(GameObject): + + # ... + + def on_collision(self, other: 'GameObject'): + self.alive = False + +class Ship(GameObject): + # ... + def on_collision(self, other: 'GameObject'): + match other: + case Asteroid(): + self.hp -= other.radius + case Health(): + self.hp += other.amount + case Ammunition(): + self.shots += other.amount +``` + +--- + +# Musterlösung - Aufgabe 8 f) + +```python + +@dataclass +class Asteroid(StaticObject): + special: bool + + def on_collision(self, other: 'GameObject'): + if not isinstance(other, Asteroid): + self.alive = False + +``` + +--- + +# Musterlösung - Aufgabe 8 g) + +```python +@dataclass +class Ship(GameObject): + + # ... + + def shoot(self) -> Projectile: + alive = False + if self.shots: + self.shots -= 1 + alive = True + pos = Vec2(self.position.x, self.position.y) + return Projectile(pos, 5, alive, (255, 0, 0), 3) +``` + +--- + +# Musterlösung - Aufgabe 8 h) + +```python +@dataclass +class GameObject: + + # ... + + def draw(self, screen: pygame.Surface): + pygame.draw.circle(screen, self.color, (self.position.x, self.position.y), self.radius) +``` + +--- + +# Override-Dekorator + +- ist in `typing` +- Wird über Methoden geschrieben, die überschrieben werden +- Pylance zeigt einen Fehler an, wenn die überschriebene Methode in keiner Oberklasse gefunden wird +- Hilft Fehler vorzubeugen - falsche Signatur, Parameter, ... + +--- + +# Override-Dekorator - Beispiel +```python +from typing import override +from dataclasses import dataclass + + +@dataclass +class GameObject: + + def on_collision(self, other: 'GameObject'): + pass + +class StaticObject(GameObject): + + @override + def on_collisoin(self, other: 'GameObject'): # Pylance-Error + self.alive = False +``` +--- + +# Override-Dekorator - Beispiel +```python +from typing import override +from dataclasses import dataclass + + +@dataclass +class GameObject: + + def on_collision(self, other: 'GameObject'): + pass + +class StaticObject(GameObject): + + @override + def on_collision(self): # Pylance-Error + self.alive = False +``` + +--- + +# Datenkapselung + +- Man möchte manche Implementierung verstecken +- Wenn andere deinen Code verwenden, dann möchte man eine Schnittstelle anbieten die intuitiv ist. + +```python +@dataclass +class MyList[T]: + internal_list: list[T] = [] + + def add(self, item: T) -> None: + self.internal_list += [other] +``` +--- +# Datenkapselung - warum ist das schlecht? + +```python +from my_collections import MyList + +xs = MyList() +xs.internal_list # ???? +``` + +- was sollen wir mit `internal_list`? +- andere sollten nur auf `add()` zugreifen können + +--- + +# Private Attribute + +```python +@dataclass +class MyList[T]: + internal_list: InitVar[list[T]] + length: InitVar[int] + + def __init__(self): + self.__internal_list = [] + self.__length = 0 + + def add(self, item: T): + self.__internal_list += [item] + self.__length += 1 + + @property + def length(self) -> int: + return self.__length +``` + +--- + +# Private Attribute + +```python +@dataclass +class MyList[T]: + internal_list: InitVar[list[T]] + length: InitVar[int] + + def __init__(self): + self.__internal_list = [] + self.__length = 0 +``` + +--- + +# Private Attribute + +```python +@dataclass +class MyList[T]: + internal_list: InitVar[list[T]] + length: InitVar[int] + + def __init__(self): + self.__internal_list = [] + self.__length = 0 + + def add(self, item: T): + self.__internal_list += [item] + self.__length += 1 + + @property + def length(self) -> int: + return self.__length +``` +--- + +# Private Attribute - Setter + +- Manchmal wollen wir trotzdem private Attribute setzen +- Aber vielleicht nur wenn bestimmte Bedingungen erfüllt sind + +```python +class GameObject: + position: InitVar[tuple[int, int]] + + def __post__init__(self, position: tuple[int, int]): + assert (0, 0) <= position + self.__position = position + + @property + def position(self) -> tuple[int, int]: + return self.__position +``` + +--- + +# Private Attribute - Setter + +```python +@dataclass +class GameObject: + position: InitVar[tuple[int, int]] + + def __post_init__(self, position: tuple[int, int]): + assert (0, 0) > position + self.__position = position + + @property + def position(self) -> tuple[int, int]: + return self.__position + + @position.setter + def position(self, position: tuple[int, int]): + if (0, 0) > position: + return + self.__position = position +``` + +--- + +# Comprehensive-Guide to `class` + +## `@dataclass` + +- Attribute werden im Klassenrumpf definiert + - können mit einem Standardwert definiert werden +- `__init__`, `__post_init__`, `__repr__`, `__eq__`, `__lt__`, `__le__`, `__gt__`, `__ge__`, ... werden automatisch generiert +- In der Vorlesung benutzen wir nur `dataclass` + +--- + +# Comprehensive-Guide to `class` + +## `@dataclass` + +- Attribute die im Klassenrumpf definiert werden, werden automatisch in die `__init__` generiert, auch wenn es einen Standardwert gibt! + +```python +@dataclass +class A: + x: int + y: int = 0 + + def __init__(self, x: int, y: int = 0): # das macht @dataclass von selber! + self.x = x + self.y = y +``` +--- + +# Comprehensive-Guide to `class` + +## `Enum` + +- Wenn man eine endliche Aufzählung braucht (endliche Menge) +- macht die Fallunterscheidung einfach weil es endliche Elemente gibt +- Versichert auch dass kein quatsch übergeben wird wie zb bei `str` +- **niemals** mit `@dataclass`, sonst geht alles kaputt + +--- + +# Enum - Beispiel + +```python +def eval[T: (int | float)](operator: str, x: T, y: T) -> T: + match operator: + case '+': + return x + y + case '-': + return x - y + case '*': + return x * y + case '/' if y != 0: + return x / y + case _: + return 0 +``` + +--- + +# Enum - Beispiel + +```python +from enum import Enum, auto + +class Op(Enum): + ADD = auto() + SUB = auto() + DIV = auto() + MUL = auto() +``` +Jetzt passen wir die Methodensignatur an +```python +def eval[T: (int | float)](operator: Op, x: T, y: T) -> T: +``` +Jetzt kann nichts beliebiges als `operator` übergeben werden + +--- + +# Blatt 09 - Fragen? + +- Abgabe: 18.12. - 09:00 +- Testet euren Code! +- Es gibt keine dummen Fragen wenns ums Verständnis geht \ No newline at end of file diff --git a/Tutorium/tut09/img/pointdistribution_ex07.png b/Tutorium/tut09/img/pointdistribution_ex07.png new file mode 100644 index 0000000000000000000000000000000000000000..732c3e7b6105bfdd24d18126514174a2931030a4 GIT binary patch literal 20885 zcmeHvcUaU1+U+E6;wDB6Q9-2{Ow>?=1rP+{iV`(qi~=HMB8Z4I>18NMTmwpr8bGBb zVxeQNpzgRy{xf6xB$P5h1Of?Z7fXN&KSL%s(*kNE~1@pfYD zJ>q-P&C}P-#bLF-ledqHr^iMueXR`|tB?Eop7b%$)^`7oH)wf!J8Q2N%~#<=-a7fI zwGV@_>c^YrhpKHN44$?a6js00lxg|+%JKLsb8<}%>hiaq{CUCa%Om>!{EhBc zhmYpJzE(675!JQxz11hrZ(5SucGy|7!I(8R$W40oot`N9Lb*m=J`QO0N7E-*uj3ET zQrj0W7@vOk`|Iyl;D7uIe157UmC@^;0@tM1IH?qQDXe?a9S|%sgD%iwed|9SxcXyMZ%crp;b!UE+y;4h-bwQ-CPvL6N zgh0vsMl;}v^(94SL5~5YYVH==BI94zOdCZ<2Ri#~qiYbqSi8zDd)=ZJgQZ;kwaW`-))ETHFi%vZ@}L z!*_jMlKon(bsTG=k9U=L6~=5l_V8j!-&yqxcgbVT6z$+U9h|_Kp`TlfQK(xub@~Cn z?$NGTrf!)PxnRlGk5_Fv{_f&cnmBbrBSeN*5Seoev$8sN69J_4>DE)|6li;DJ@?luccAUe|%tH%xHHR=d`^2 z3LJ5-Thf&)S1xYxIabPS{1}J0UQI2-H(4weKWJ=h%HG!|81_o zmXn?C#XA~PjnYxr=#C=b&YDPGHOA+dc=c61sH;;Ca7CIdZdifTwnI(*2+fQ_uH5 zz1w})FREvGab+w892u-qa!jmW{YaN`DjUi1nb2h(yvhwJhjn}Y|J-H%uj*HghVlg!UK)_(s{ z9!Hr~g$il^VxAMda_Jjyyx~-g#xP`nYPk9}2W_)en@=pWEAx-33>DQ})N!N)^J?C! z=iXejSV1@1ICQqk#^?hl| zva)okoD`YjrW>;af6fZREK*m z*HrA;8z|s9tIvHR&tQC&QCpXZ8?=0 z`VQmE!Dr6g%TJB|Z4&4ALihJq;GdQeo34Qwwj|VdtjB1To`>Q>#gm_iU+fFd_>qeN z!Eixd;sVxask3e9bj$doJ=)b>r9M1`Ug6GnR&Myf9)J0ETR1|ASG9Cs^tm-=HB@2H z<8*wV{~FjIZ*?MYfWi1AV+D8U|Gb!eP1RD zDa#R#^NL+0e+xy6O`bhlohPq*JP&C~Z!xYZvs#iP&_TVr@LNCIV)?}v?@{yg8*bgP zfB*i|!w)ZQT=(WXD?az&{`B<%$A;uB@uLBAv(tIO(?i~R2>9AfH%H#O>hSd5>HR1b zD3R9uyTdu-ziwZ$BTm^!%{JgaV-*P+{TcO~64e_%$3!hv@r8f1YWqsUJ8R6h6=!YJ zDnXH>Quf9oxvI%V6BXxVubrq!s`jjr!sLQ!k9(C>E|R)UOOE-o%v zOm^ix&e^kP9e}_36Y4MOq(7PwqCOmqS7&Yc7*%$~rsJRc^4oPU_*@IXi2*65*iXC(I1wp zTUNb%dOy9SL?0OAigRPCPU!5Ea6pf}QdV|Pg2tKP>G?6$6YQ`#heua;dHwQXVpX*~ zQ&Ge(*!NkA!Dc~kxTM4254Zq24%!RXes=M8HOIOBav?W=sk#39=K4?neB!b!P;J3v zDnR;Ie>n5|>%Yqts8FOhQVe1&^W#bc z)2*clPL_bbV)KcETW7j_24#F45kX76opM(J*sH0k9xie#t)6bp zu~SGf@H>mPzhcADPs@Rh;&aLfTvP=6l`5c0IaS%m#wR4yVCGVaPzejTB1Q5fa+8NWJ8NXVk2=*azVn{Mn&3mncaRtwo`Vq!8eIq9Rb7qjrXC$;u6N3G?Y zQ-h9eo%(hAcp_W;;a%SsU-XB5|NZw>_f9WL2fAtbcst(f%)@)5S8Y~XyZ7?4B_`sN zn_OEp5;Se(WMv6MT-|jcGLjA#75x1gfF)U3EBhcPMgR6AO_&*l&o1oiL$!>;UC}l- z9JzDYPzJX~3F+)nHc}KBsoxj5rdE@UE5-Z%fccrf!I1a=84LlYQr^7T9iMUppOUZ9 zIb;ATKrJ8~pjOADtK{FgBz!2(BKYRM4;A@`)|MCTWdoO8`@UYNyuM6QF&3)r-y1qZ zBcXUYH$1!g65jPV$3Th2=(cjEKTrR}nqwAG_3T$-;}&s5G-=+8b+Pe)bv zdj4aCWyxN2%VqNNWo-^s;cH|s0U1sGM%g~1%s}+6}nm_Prjjwz|GgPyIWP* zX0I+lMK{PcXGc#8d2w+n;wKBo>pjCZ8qW)P)T2yIAEud@0Px;z8R-q=#R%gh!Z`1` zN>TS%P4B#*_{1e`oYvl3%~pb%7zOzh!+=;EMGZb#0TYC)sVPo{6Fxr}Zh5yG2Ox(t zk3xu>y12YJ78gGMYOqDu8AovW^Bazyzyw}EEoP_Q>|erT&kwWvko4KUW$Cd78T|g_ z#;udmO6C+-k3%x>=N~d!3KW0yeLn+1?AD0~`AckGS<$$%CT?r~y_peB`|^^mxxH2k z^tiW=Y_|=3db%`C0|&b}qd70p$r?nCdy$wIXA*1Y&%Jif-N0|?PIah^it*NUKB$E^ z_xf!R#G1?tBO@`)MIA8T@*xttPFekiLlPgBI38i3u`uU{XjQFjGR-f3nLI<$Ld(Kt^Zdvdv1h2YfY@aD)na+-JGXufc+k18w5Fx;TK~gBO6i-IYEOdRxkGG zs(U{@Ex$9tiSSbO+)S?u-JEnBP#zeR^*CnfovmZeZ}2GXPZ+w4iuOri=7qfCUqFOd z_PZ;Gi^nf+aN123#Y^}!!VDME0fmO3NMvNmM6Eh+s(D}I^g%kUgDD{^2iJnLiMz1R zcuPmIrwTDUxFU&V7DqAGI2~!jP;(rdQt1-+7Z|$|y>R4y_9>P50kt39s5<}Qo<5+~ z82^zD3*j%x%vOwzI6-0sQK}{%ZcKNoOK^(IwJpuxt-S~gmoVVq4acz;H_~Enqz0=6 z&x}^ocT(X7x>_2c=>4gwDIwvc5sX@?rO9h?ZZVn7c~*xGt*}n8a7m)R5f!IGT@YAG z>5?4Yke%5)#w{DKQQ%#P(mET^8>;6l+WPFf?GBQ;nMUqBdd7+EI9@%s_S-_7x#L*H zOe`wDhoJ6P$#`7&<3|taEmkS96$+l^c||wy(@W1==A52L*)=Cvq+Uo8hNf5oRn?v_ z(MZX&^LzRTjRUHgnpUMr#Djs;Emp2U$MD9&8~8Oow}AK60vYM#eEqXa?*W3wL`Jgb zr*plyPKhlOeEPb5__`>qyX(V{-c=y1uIx|W=~TxakMXPmDNx)3P@Aq&9WI#(Pqgs| zbmhc_O{FI{E=QSL+wx+DuW4KIF|zLtccL}hhGV7@dZ%SXUfW*r+O=!_38624UP#fB zTo17KgYM%O?I0VvuK-k1&+>SMAtHTygp5u1{F!yB?QUG7nXU^3uc$aC7|d;G01Yhi zLJ-#A)`Kyoj?BB{oO))m!BG3#B`Wrv#6sTO>^EE6L%~iM1FZ4RUAuMxh_6B2>|1Ce z+-B?j%ZEwXk_T(z+$JmI0CR24>F9T&NV|gK>_WJEy||WGqn=wXy+lL;7>oD^p3dUX zy06a-fEB?<$~fZ=d|oi*%Xfd2=g4{9p2xFn6HP?q;VNFuXsGT%?=Gt!?m2mXaf|*^ z6rgaXpO#>tF^xGo4~Wx;aUl+XXNPGO?yf8d#yD^g9)3)sR*1nw1UuaSc5%P52t(QB zvRyc}$F~jSS(4e|_dH6TeoF-!Y>!bBCi}?9L#5tM$-zUn#tU;p-J?X8K>vme+w`8@ zXEL`5H$q<1rYJhjcy|3|UH4T0HgXu|KS{B?5k7sdJVYPOcEQpHk zzM{coA9F<(KQGU_zxFs#J>fOtB6jpvhVo{Ib8|gD#LpEUXv}Hjb`Ln5eV2 z2H(qE+6)f%rY@q$zWMrIUK@MfFGM`f(Fvay6RR#pRgGjyX4~@Ww94GPI+=4rR!uo} zWs#A>e(ms;)Fd}H=&vyrzr0^EC+Ku_n5Cn;ZqDR(9!<3KKa*<2vUEv8&%ViT#GQx* zL#5HyjN*mB{jJNO8Dvh4v&H?|@y3D}&yY2gtiV_{rTuiBQ7%2aY$%`t@C&F^cBAuX zjE+Bl^Ts&nqbgK~qLLBZ16|RMAz4`(bGJ@EKJd4qr3Y;FHX6*U{ydb&w^dlL`V;Hs z#T~A>)kv(`(L^9e@PTr`7B?SlB`8S972U#eoq-U%8Mq0aU7e)>^7bMP&l9q2nEG#C7Nq-J!+6pA*8zFiarl@yZ|4}Osg!c?3P1|h_vx2{jerZg?VipHK{TSH8nBZD>%W4csQDw zp+?-1w)thUvM6{hy1C#CcbJ+I7_)OG@G)9Cm|&xO^2tvZ4g5}=9?oU5jaze>O#krd zp%z2q{lLQ3xT%-*JncuD^@m$B<%wNDCE5^cJo`M`Ln7$(t0(C@sb$>0U`&2%1Ek}-`}w+g?YuB zj0>HeC1ttwV`V8RKJ3YffF+MDa3q-EO1eAE(~ON`Q7NBymjx(>37^W!jz8SkScR@5 zAC7$BCH0C2{6_+C>!cCbyw9Yf+b8qE^QQDVySHpHXQ2!a_`XB)0zMODZEhf1ha-t2 z#bPx0GbG>ipz!W4u6TYWsxR56;Y?<3WpF`10Pj=(>K;`2l}N^@b!j0Rh~w7G0Z-C- zs4^s|)QLa>ey}VF!#~dk2d#q4L0322vUlJ2rCB-Vk^NtMk(FH1^pL8RDO&5-}5VL@I%HXUDT`{L(k$X%#?$!@*A6P?27~X$`^h3 z;fFdt0}r2fl}^gdNNMM9-dN;-
    N1ew`{s-;%%OcENjoIt>zbb@MQW$M6fgjP+Z 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 Ot{vv4Ie+@{oBsv!;ILZ& literal 0 HcmV?d00001 diff --git a/Tutorium/tut09/img/pointdistribution_ex08.png b/Tutorium/tut09/img/pointdistribution_ex08.png new file mode 100644 index 0000000000000000000000000000000000000000..19227702392f2ba65ca786945e93b6c8e9a4c568 GIT binary patch literal 18474 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 literal 0 HcmV?d00001 diff --git a/Tutorium/tut09/src/classes.py b/Tutorium/tut09/src/classes.py new file mode 100644 index 0000000..b604a35 --- /dev/null +++ b/Tutorium/tut09/src/classes.py @@ -0,0 +1,31 @@ +from dataclasses import dataclass + +@dataclass +class A: + x: int + y: int = 0 + + # die init die von `dataclass` generiert wird, also unnötig + # siehe class B + def __init__(self, x: int, y: int = 0): + self.x = x + self.y = y + +@dataclass +class B: + x: int + y: int = 0 + +if __name__ == '__main__': + my_a = A(1) + assert my_a.x == 1 + assert my_a.y == 0 + my_other_a = A(1, y = 1) + assert my_other_a.x == 1 + assert my_other_a.y == 1 + my_b = B(1) + assert my_b.x == 1 + assert my_b.y == 0 + my_other_b = B(1, y = 1) + assert my_other_b.x == 1 + assert my_other_b.y == 1 \ No newline at end of file diff --git a/Tutorium/tut09/src/my_collections.py b/Tutorium/tut09/src/my_collections.py new file mode 100644 index 0000000..a8986c0 --- /dev/null +++ b/Tutorium/tut09/src/my_collections.py @@ -0,0 +1,55 @@ +from dataclasses import dataclass, InitVar + + +@dataclass +class MyList[T]: + internal_list: InitVar[list[T]] + length: InitVar[int] + + def __init__(self): + self.__internal_list = [] + self.__length = 0 + + def add(self, item: T): + self.__internal_list += [item] + self.__length += 1 + + + @property + def length(self) -> int: + return self.__length + +@dataclass +class GameObject: + position: InitVar[tuple[int, int]] + + def __post_init__(self, position: tuple[int, int]): + assert (0, 0) <= position + self.__position = position + + @property + def position(self) -> tuple[int, int]: + return self.__position + + @position.setter + def position(self, position: tuple[int, int]): + if (0, 0) > position: + return + self.__position = position + +if __name__ == "__main__": + xs: MyList[int] = MyList() + xs.add(100) + assert xs.length == 1 + position = (0, 0) + my_obj = GameObject(position) + assert my_obj.position == (0, 0) + try: + GameObject((0, -1)) + except AssertionError: + pass + else: + raise AssertionError(f"{my_obj} should have thrown a assertation error") + my_obj.position = (-1, 0) + assert my_obj.position == (0, 0) + \ No newline at end of file