From 88554c3295764bb7aaf9fbb80f2c55ccd8376d67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=81?= Date: Fri, 24 Jul 2020 18:02:50 +0300 Subject: [PATCH] Implemented two versions of the Hash variables and some remarks for the finding variables was made. --- calculate/vars/alt_datavars.py | 80 ++++++++++++++++++++++++++-------- tests/vars/test_alt_vars.py | 11 +++-- 2 files changed, 67 insertions(+), 24 deletions(-) diff --git a/calculate/vars/alt_datavars.py b/calculate/vars/alt_datavars.py index fe3b898..973d337 100644 --- a/calculate/vars/alt_datavars.py +++ b/calculate/vars/alt_datavars.py @@ -6,13 +6,6 @@ from inspect import signature, getsource from types import FunctionType, LambdaType -class VariableType: - '''Базовый класс для типов.''' - @classmethod - def check(self, value: str) -> bool: - return True - - class DependenceError(Exception): pass @@ -38,6 +31,13 @@ class CyclicVariableError(VariableError): self.queue[:-1])) +class VariableType: + '''Базовый класс для типов.''' + @classmethod + def check(self, value: str) -> bool: + return True + + class StringType(VariableType): pass @@ -78,6 +78,14 @@ class ReadonlyType(VariableType): pass +class HashType(VariableType): + pass + + +class TableType(VariableType): + pass + + class DependenceSource: current_namespace = None datavars_root = None @@ -182,6 +190,11 @@ class DependenceSource: return True +class HashSource: + def __init__(self): + pass + + class VariableNode: '''Класс ноды соответствующей переменной в дереве переменных.''' def __init__(self, name, namespace, variable_type=StringType, source=None): @@ -239,6 +252,9 @@ class VariableNode: subscription.subscribers.add(self) def _invalidate(self): + '''Метод для инвалидации данной переменной и всех зависящих от нее + переменных.''' + print('{} is invalidated'.format(self.fullname)) if self.value is not None: self.value = None for subscriber in self.subscribers: @@ -329,6 +345,35 @@ class NamespaceNode: return ''.format(self.fullname) +class HashNode: + def __init__(self, name, namespace, sources, types=dict()): + self.name = name + self.namespace = namespace + self.calculating = False + + self.namespace.add_variable(self) + + self.sources = sources + self.subscribers = dict() + self.values = dict() + self.types = dict() + for key, source in sources: + self.values.update({key: None}) + if key in types: + if issubclass(types[key], VariableType): + self.types.update({key: types[key]}) + else: + raise VariableTypeError('variable_type must be' + ' VariableType, but not {}'.format( + type(types[key]))) + else: + self.types.update({key: StringType}) + + # Источник значения переменной, может быть значением, а может быть + # зависимостью. + self.update_values() + + class DependenceAPI: def __init__(self): self.current_namespace = None @@ -351,24 +396,22 @@ class DependenceAPI: def _find_variable(self, variable_name): '''Метод для поиска переменной в пространстве''' - variable = None name_parts = variable_name.split('.') - if not name_parts[0]: namespace = self.current_namespace - index = 1 - while not name_parts[index]: - namespace = namespace.parent - index += 1 - name_parts = name_parts[index:] + for index in range(1, len(name_parts)): + if not name_parts[index]: + namespace = namespace.parent + else: + name_parts = name_parts[index:] + break else: namespace = self.datavars_root - variable = namespace + search_result = namespace for part in name_parts: - variable = variable[part] - - return variable + search_result = search_result[part] + return search_result class VariableAPI: @@ -454,6 +497,7 @@ class NamespaceAPI: # Устанавливаем текущее пространство имен фабрике зависимостей. self._dependence_fabric.current_namespace = namespace + self._dependence_fabric.datavars_root = self._datavars print('current_namespace in DependenceAPI: {}'.format( namespace.fullname)) try: diff --git a/tests/vars/test_alt_vars.py b/tests/vars/test_alt_vars.py index e0e9f23..beb8efc 100644 --- a/tests/vars/test_alt_vars.py +++ b/tests/vars/test_alt_vars.py @@ -54,7 +54,6 @@ class TestNamespace: def test_find_vars(self): Namespace.reset() datavars = Namespace.datavars - var_1 = Variable('var', source='null') with Namespace('namespace_1'): Variable('var_1', source='val_1') @@ -64,13 +63,13 @@ class TestNamespace: with Namespace('namespace_1_1'): Variable('var_1', source='val_1') - assert Dependence(var_1)._find_variable('.var_1') ==\ + assert Dependence._find_variable('.var_1') ==\ datavars.namespace_1.namespace_1_1['var_1'] - assert Dependence(var_1)._find_variable('..var_3') ==\ + assert Dependence._find_variable('..var_3') ==\ datavars.namespace_1['var_3'] with Namespace('namespace_2'): - assert Dependence(var_1)._find_variable('namespace_1.var_2') ==\ + assert Dependence._find_variable('namespace_1.var_2') ==\ datavars.namespace_1['var_2'] def test_compare_two_dependencies_equal(self): @@ -157,13 +156,13 @@ class TestNamespace: with Namespace('namespace_1'): Variable('var_1', source='val_1') - var_1 = Variable('var_2', source=2) + var_2 = Variable('var_2', source=2) Variable('var_3', source=4) with Namespace('namespace_2'): Variable('var_1', source=Dependence( - var_1, '.var_2', + var_2, '..namespace_1.var_3', depend=lambda arg_1, arg_2: 'greater' if arg_1 > arg_2 else 'less')) with Namespace('namespace_2_1'):