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

View File

@ -1,8 +1,85 @@
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):
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
def test_enum(self):
self.assertEqual(DeviceLifecycleStateTest["INIT"], DeviceLifecycleStateTest.INIT)
# NOTE: это имеется в виду?
# self.assertEqual(DeviceLifecycleStateTest["INIT"], DeviceLifecycleStateTest.INIT)
self.assertEqual(DeviceLifecycleState["INIT"], DeviceLifecycleState.INIT)