Compare commits

..

7 Commits

Author SHA1 Message Date
ilia
e6a2f6eac7 fill methods 2023-10-26 17:28:48 +03:00
ilia
b0e095e2e7 trait and action descriptors 2023-10-24 10:35:32 +03:00
ilia
2ed1f00421 fix get_doc 2023-10-24 10:34:02 +03:00
ilia
593ad6b45c rewrite get_descriptors to use __dict__ 2023-10-24 10:28:38 +03:00
ilia
08cbcec767 add get_descriptors with using "return" and "set" 2023-10-24 10:13:31 +03:00
ilia
9cf90c7f18 add execute 2023-10-24 10:11:30 +03:00
ilia
48b18048c8 start doing turtle task 2023-10-23 13:44:07 +03:00
9 changed files with 99 additions and 16 deletions

View File

@ -1,8 +0,0 @@
from turtle import Turtle
from controls.device import SynchronyDevice
class TurtleDevice(SynchronyDevice):
pass # TODO(Homework #3)

1
turtle/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
test.ipynb

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 ABC, abstractmethod, abstractproperty
from enum import Enum
class DeviceLifecycleState:
pass # TODO(Homework #3)
class DevaceError(Exception): class DeviceLifecycleState(Enum):
INIT = 0
OPEN = 1
CLOSE = 2
class DeviceError(Exception):
pass pass
@ -33,8 +37,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 +47,11 @@ class Device:
def close(self): def close(self):
self._state = DeviceLifecycleState.CLOSE self._state = DeviceLifecycleState.CLOSE
@abstractproperty
def trait_descriptors(self) -> Collection[TraitDescriptor]: def trait_descriptors(self) -> Collection[TraitDescriptor]:
pass pass
@abstractproperty
def action_descriptors(self) -> Collection[ActionDescriptor]: def action_descriptors(self) -> Collection[ActionDescriptor]:
pass pass
@ -79,4 +84,4 @@ class SynchronyDevice(Device):
@abstractmethod @abstractmethod
def invalidate(self, trait_name: str): def invalidate(self, trait_name: str):
"""Invalidate logical state of trait `trait_name`""" """Invalidate logical state of trait `trait_name`"""
pass pass

View File

@ -0,0 +1,85 @@
from turtle import Turtle
from typing import Optional, Collection, Any
from controls.device import SynchronyDevice
from controls.device import TraitDescriptor
from controls.device import ActionDescriptor
from controls.device import DeviceError
import inspect
class TurtleDevice(SynchronyDevice):
def open(self):
self.turtle = Turtle()
self.descriptors = dict(traits=dict(), actions=dict())
super().open()
def close(self):
self.turtle.clear()
super().close()
def trait_descriptors(self) -> Collection[TraitDescriptor]:
return self.get_descriptors()["traits"]
def action_descriptors(self) -> Collection[ActionDescriptor]:
return self.get_descriptors()["actions"]
def __getitem__(self, trait_name: str) -> Optional[Any]:
"""Return logical state of trait `trait_name`."""
return self.descriptors[trait_name]
def read_descriptors(self, arg):
self.descriptors = self.get_descriptors()
return self.descriptors
def read(self, trait_name: str) -> Any:
"""Read physical state of trait `trait_name` from device."""
self.read_descriptors()
return self.descriptors[trait_name]
def write(self, trait_name: str, value: Any) -> bool:
"""Turtle traits are not writable"""
# trait_desc = self.trait_descriptors.get(trait_name)
# if trait_desc.writable:
# return getattr(self.turtle, trait_name)(value)
super().write()
def execute(self, action_name: str, *args, **kwargs):
"""Execute action `action_name`, using `args` and `kwargs` as action argument."""
action = self.get_descriptors()["actions"].get(action_name)
if action:
return getattr(self.turtle, action_name)(*args, **kwargs)
super().execute()
def invalidate(self, trait_name: str):
"""Invalidate logical state of trait `trait_name`"""
if self.trait_descriptors.get(trait_name):
self.trait_descriptors[trait_name] = None
raise DeviceError()
def get_descriptors(self):
descriptors = dict(actions=dict(), traits=dict())
for k, v in self.turtle.__dict__.items():
if not k.startswith("_"):
descriptors["traits"][k] = TraitDescriptor(k,
inspect.getdoc(v),
readable=True,
writable=False)
for m_name, member in inspect.getmembers(Turtle):
if m_name.startswith("_"): continue
if m_name.lower() != m_name: continue
doc = inspect.getdoc(member)
if doc is None: continue
if not inspect.isfunction(member):
descriptors["traits"][m_name] = TraitDescriptor(m_name,
doc,
readable=True,
writable=False)
else:
sig = inspect.signature(member)
params_dict = dict(sig.parameters)
descriptors["actions"][m_name] = ActionDescriptor(m_name,
arguments=params_dict,
info=doc)
return descriptors