Skip to content

Instantly share code, notes, and snippets.

@gustavz
Last active December 8, 2022 11:43
Show Gist options
  • Save gustavz/f1c615e95f0874c80a66d2f367b2007e to your computer and use it in GitHub Desktop.
Save gustavz/f1c615e95f0874c80a66d2f367b2007e to your computer and use it in GitHub Desktop.
data class with decision log
import trafaret as t
class DecisionLog:
def __init__(self, reason_key=''):
self.init()
self._reason_key = reason_key
self._len_reason_key = len(reason_key)
def init(self):
self.logs = []
def log(self, text):
self.logs.append(text)
def _read_reason_from_value(self, value):
reason = None
if(
isinstance(value, tuple)
and len(value) == 2
and isinstance(value[1], str)
and len(value[1]) > self._len_reason_key
and value[1][:self._len_reason_key] == self._reason_key
):
reason = value[1][self._len_reason_key:]
value = value[0]
return value, reason
def _generate_setattr_text(self, name, value, reason):
text = f'Setting {name} to {value}'
if reason: text += f' because {reason}'
return text
def log_setattr_with_reason(self, name, value):
value, reason = self._read_reason_from_value(value)
text = self._generate_setattr_text(name, value, reason)
self.log(text)
return value
def generate_reason(self, value):
return self._reason_key + value
def to_string(self):
for log in self.logs:
print(log)
return '\n'.join(self.logs)
class BaseDataWithDecisionLog:
_converter = t.Dict()
_logger = DecisionLog(reason_key='r:')
def __init__(self, **kwargs):
self._logger.init()
kwargs = self._converter.check_and_return(kwargs)
self._set_init_kwargs(kwargs)
def _set_init_kwargs(self, kwargs):
for key, value in kwargs.items():
if key in self._keys:
reason = 'initial user input'
if value == self._keys[key].default:
reason = 'default value'
reason = self._logger.generate_reason(reason)
value = value, reason
setattr(self, key, value)
def __setattr__(self, name, value):
value = self._logger.log_setattr_with_reason(name, value)
super().__setattr__(name, value)
@property
def _keys(self):
return {k.name:k for k in self._converter.keys}
@classmethod
def from_dict(cls, data):
return cls(**data)
def to_dict(self):
return {k:getattr(self, k) for k in self._keys}
def get_log(self):
return self._logger.to_string()
class MyDataClass(BaseDataWithDecisionLog):
_converter = t.Dict({
t.Key('var1', optional=True, default=None): t.Or(t.Int, t.Null),
t.Key('var2', optional=True, default=None): t.Or(t.Int, t.Null),
t.Key('var3', optional=True, default=None): t.Or(t.Int, t.Null),
t.Key('var4', optional=True, default=None): t.Or(t.Int, t.Null),
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment