HW3 complete #2

Merged
zugzvangg merged 8 commits from hw3 into main 2023-10-27 11:32:46 +03:00
3 changed files with 103 additions and 10 deletions
Showing only changes of commit 4363ac2dfd - Show all commits

View File

@ -1,12 +1,16 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import Optional, Collection, Any from typing import Optional, Collection, Any
from abc import abstractmethod from abc import abstractmethod, ABC
import enum
class DeviceLifecycleState:
pass # TODO(Homework #3)
class DevaceError(Exception): class DeviceLifecycleState(enum.Enum):
INIT = "INIT"
OPEN = "OPEN"
CLOSE = "CLOSE"
class DeviceError(Exception):
pass pass
@ -18,6 +22,12 @@ class NonWritableTrait(Exception):
pass pass
class NoSuchTrait(Exception):
pass
class NoSuchAction(Exception):
pass
@dataclass @dataclass
class TraitDescriptor: class TraitDescriptor:
name: str name: str
@ -33,8 +43,7 @@ class ActionDescriptor:
info: Optional[str] = None info: Optional[str] = None
class Device: class Device(ABC):
# TODO(Homework #3)
_state = DeviceLifecycleState.INIT _state = DeviceLifecycleState.INIT
@property @property
@ -44,9 +53,14 @@ class Device:
def close(self): def close(self):
self._state = DeviceLifecycleState.CLOSE self._state = DeviceLifecycleState.CLOSE
@property
@abstractmethod
def trait_descriptors(self) -> Collection[TraitDescriptor]: def trait_descriptors(self) -> Collection[TraitDescriptor]:
pass pass
@property
@abstractmethod
def action_descriptors(self) -> Collection[ActionDescriptor]: def action_descriptors(self) -> Collection[ActionDescriptor]:
pass pass

View File

@ -1,8 +1,85 @@
from turtle import Turtle from turtle import Turtle
from controls.device import SynchronyDevice from controls.device import (
SynchronyDevice,
TraitDescriptor,
ActionDescriptor,
NoSuchTrait,
NoSuchAction,
)
from typing import Collection, Optional, Any
import inspect
class TurtleDevice(SynchronyDevice): class TurtleDevice(SynchronyDevice):
pass # TODO(Homework #3) def __init__(self) -> None:
super().__init__()
self.open()
def open(self):
self.turtle = Turtle()
def close(self):
del self.turtle
def execute(self, action_name: str, *args, **kwargs):
pass
def read(self, trait_name: str) -> Any:
traits = self.trait_descriptors
for trait in traits:
if trait.name == trait_name:
return self.turtle.__getattribute__(trait_name)
raise NoSuchTrait
def write(self, trait_name: str, value: Any) -> bool:
traits = self.trait_descriptors
for trait in traits:
if trait.name == trait_name:
attribute_type = type(self.turtle.__getattribute__(trait_name))
assert (
type(value) == attribute_type
), f"Wrong value type. Type should be {attribute_type}, but you pass {type(value)}"
self.turtle.__setattr__(trait_name, value)
return True
raise NoSuchTrait
def invalidate(self, trait_name: str):
pass
def __getitem__(self, trait_name: str) -> Optional[Any]:
pass
@property
def trait_descriptors(self) -> Collection[TraitDescriptor]:
return [
TraitDescriptor(name=attr, info=getattr(self.turtle, attr).__doc__)
for attr in dir(self.turtle)
if attr[0] != "_"
and attr[-1] != "_"
and not callable(getattr(self.turtle, attr))
]
@property
def action_descriptors(self) -> Collection[ActionDescriptor]:
methods = [
attr
for attr in dir(self.turtle)
if attr[0] != "_"
and attr[-1] != "_"
and callable(getattr(self.turtle, attr))
]
result = []
for method_name in methods:
method = getattr(self.turtle, method_name)
args = inspect.signature(method).parameters
arg_types = {}
for arg_name, arg in args.items():
arg_types[arg_name] = arg.annotation
result.append(
ActionDescriptor(
name=method_name, info=method.__doc__, arguments=arg_types
)
)
return result

View File

@ -9,4 +9,6 @@ class DeviceLifecycleStateTest(TestCase):
pass pass
def test_enum(self): def test_enum(self):
self.assertEqual(DeviceLifecycleStateTest["INIT"], DeviceLifecycleStateTest.INIT) # NOTE: это имеется в виду?
# self.assertEqual(DeviceLifecycleStateTest["INIT"], DeviceLifecycleStateTest.INIT)
self.assertEqual(DeviceLifecycleState["INIT"], DeviceLifecycleState.INIT)