added some stuff

This commit is contained in:
2023-12-16 10:52:49 +01:00
parent 17c32ba50d
commit c02f514871
8 changed files with 277 additions and 15 deletions

Binary file not shown.

View File

@ -3,27 +3,27 @@ from dataclasses import dataclass, InitVar
@dataclass
class MyList[T]:
internal_list: InitVar[list[T]]
length: InitVar[int]
def __init__(self):
self.__internal_list = []
_internal_list: InitVar[list[T]]
_length: InitVar[int]
def __init__(self) -> None:
self.__internal_list: list[T] = []
self.__length = 0
def add(self, item: T):
def add(self, item: T) -> None:
self.__internal_list += [item]
self.__length += 1
@property
def length(self) -> int:
return self.__length
@dataclass
class GameObject:
position: InitVar[tuple[int, int]]
_position: InitVar[tuple[int, int]]
def __post_init__(self, position: tuple[int, int]):
def __post_init__(self, position: tuple[int, int]) -> None:
assert (0, 0) <= position
self.__position = position
@ -32,16 +32,17 @@ class GameObject:
return self.__position
@position.setter
def position(self, position: tuple[int, int]):
def position(self, position: tuple[int, int]) -> None:
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)
position: tuple[int, int] = (0, 0)
my_obj = GameObject(position)
assert my_obj.position == (0, 0)
try:
@ -49,7 +50,7 @@ if __name__ == "__main__":
except AssertionError:
pass
else:
raise AssertionError(f"{my_obj} should have thrown a assertation error")
raise AssertionError(
f"{my_obj} should have thrown a assertation error")
my_obj.position = (-1, 0)
assert my_obj.position == (0, 0)

View File

@ -0,0 +1,17 @@
---
marp: true
paginate: true
class: invert
# theme: uncover
footer: Tutorium 10 - 22.12.2023 - Nils Pukropp - https://s.narl.io/s/tutorium-10
header:
---
# Tutorium 10 - 22.12.2023
Weihnachtsaufgabe :)
---
# Aufgabe - SpaceArena

View File

@ -0,0 +1,26 @@
from result import Err, Ok, Panick, Result
from ui import run_command, Color
from spacearena import Difficulty, SpaceArena
if __name__ == '__main__':
if __name__ == '__main__':
difficulty: Difficulty | None = None
while not difficulty:
difficulty = Difficulty.get_difficulty(
input(f"Choose your difficulty {[e.name.lower() for e in list(Difficulty)]}\n> ").upper())
print(f"Difficulty: {difficulty} selected!")
game = SpaceArena(difficulty)
print("Starting game!")
while game.is_running:
Err("error value hehe").unwrap_or("yay still works")
match run_command(input("> "), game):
case Ok(value):
print(f"{Color.OK}{value}{Color.ENDC}")
case Err(value):
print(f"{Color.BOLD}{Color.FAIL}Error:{Color.ENDC} {Color.WARNING}{value}{Color.ENDC}")

View File

@ -0,0 +1,92 @@
from abc import ABC
from dataclasses import dataclass
from typing import Callable, overload
class Panick(Exception):
def __init__(self, msg_res: 'Err | str') -> None:
match msg_res:
case str(msg):
super().__init__(msg)
case _:
super().__init__(f"thread `__main__` panicked:\ncalled `Result::unwrap()` on an `Err` value: \"{msg_res.value}\"")
@dataclass
class Result[V, E](ABC):
def unwrap(self) -> V:
match self:
case Ok(value):
return value
raise Panick(self) # type: ignore
def expect(self, msg: str) -> V:
match self:
case Ok(value):
return value
raise Panick(msg)
def is_ok(self) -> bool:
return isinstance(self, Ok)
def is_err(self) -> bool:
return isinstance(self, Err)
def unwrap_or(self, value: V) -> V:
match self:
case Ok(val):
return val
return value
def and_[O](self, other: 'Result[O, E]') -> 'Result[O, E]':
match self, other:
case Err(value), _:
return Err(value)
return other
def and_then[O](self, func: Callable[[V], 'Result[O, E]']) -> 'Result[O, E]':
match self:
case Ok(value):
return func(value)
return Err(self.value) # type: ignore
@dataclass
class Ok[V, E](Result[V, E]):
value: V
@dataclass
class Err[V, E](Result[V, E]):
value: E
def __sqrt(num: float) -> Result[float, str]:
if num < 0:
return Err('negative sqrt')
return Ok(num ** 0.5)
def test_result() -> None:
assert Ok(4.0).and_then(__sqrt) == Ok(2.0)
assert Ok(-5.0).and_then(__sqrt) == Err('negative sqrt')
assert Err("haha error").and_then(__sqrt) == Err("haha error")
assert Ok("test").unwrap() == "test"
try:
Err("haha error").unwrap()
except Panick:
pass
else:
assert False, 'didn\'t throw Panick'
assert Err('haha error').unwrap_or("doch nicht") == 'doch nicht'
result = Ok('test result')
match result:
case Ok(res):
assert res == 'test result'
case Err():
pass
result = Err('test result')
match result:
case Ok():
pass
case Err(res):
assert res == 'test result'

View File

@ -0,0 +1,44 @@
from dataclasses import dataclass, InitVar
from enum import Enum
from typing import Optional
class Difficulty(Enum):
EASY = 0.5
NORMAL = 1.0
HARD = 2.0
@staticmethod
def get_difficulty(input: str) -> Optional['Difficulty']:
for e in list(Difficulty):
if e.name == input:
return e
def __str__(self):
return self.name
@dataclass
class SpaceArena:
_difficulty: InitVar[Difficulty] = Difficulty.NORMAL
def __post_init__(self, difficulty: Difficulty = Difficulty.NORMAL) -> None:
self.__difficulty = difficulty
self.__is_running = True
@property
def difficulty(self) -> Difficulty:
return self.__difficulty
@difficulty.setter
def difficulty(self, new_diff: Difficulty):
self.__difficulty = new_diff
@property
def is_running(self) -> bool:
return self.__is_running
def stop(self):
self.__is_running = False

79
Tutorium/tut10/src/ui.py Normal file
View File

@ -0,0 +1,79 @@
from abc import ABC, abstractmethod
from enum import Enum
import re
from typing import override
from result import Ok, Err, Result
from spacearena import Difficulty, SpaceArena
class Color(Enum):
OK = '\033[92m'
FAIL = '\033[91m'
WARNING = '\033[93m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def __str__(self) -> str:
return self.value
class AbstractCommand(ABC):
def matches(self, inp: str) -> Result[re.Match[str], None]:
if m := re.match(self.pattern(), inp):
return Ok(m)
return Err(None)
@abstractmethod
def pattern(self) -> str:
pass
@abstractmethod
def run(self, game: SpaceArena, args: list[str]) -> Result[str, str]:
pass
class QuitCommand(AbstractCommand):
@override
def pattern(self) -> str:
return r"(quit)"
@override
def run(self, game: SpaceArena, _: list[str]) -> Result[str, str]:
game.stop()
return Ok('quitting game!')
class DifficultyCommand(AbstractCommand):
@override
def pattern(self) -> str:
return r"(difficulty|diff)\s+(increase|decrease)"
@override
def run(self, game: SpaceArena, args: list[str]) -> Result[str, str]:
diffs = list(Difficulty)
curr = diffs.index(game.difficulty)
match args[0]:
case 'increase' if curr + 1 < len(diffs):
game.difficulty = diffs[curr + 1]
return Ok(f"Increasing difficulty to {game.difficulty}")
case 'increase':
return Err("maximum difficulty")
case 'decrease' if curr - 1 >= 0:
game.difficulty = diffs[curr - 1]
return Ok(f"Decreasing difficulty to {game.difficulty}")
case 'decrease':
return Err("minimum difficulty")
return Err("invalid input")
ALL_COMMANDS: list[AbstractCommand] = [QuitCommand(), DifficultyCommand()]
def run_command(inp: str, game: SpaceArena, commands: list[AbstractCommand] = ALL_COMMANDS) -> Result[str, str]:
for command in commands:
match command.matches(inp):
case Ok(value):
args = [str(s) for s in value.groups()]
return command.run(game, args[1:])
return Err("command not found")