Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
9f26eb4
removed UUIDS from Graph in borg
damskii9992 Jun 12, 2024
5bb1f7f
replace convert_id calls with .name
damskii9992 Jun 13, 2024
7779d58
NameConverter class removed, move name assignment
damskii9992 Jun 13, 2024
0d59e9a
remove get_key
damskii9992 Jun 13, 2024
74dcb28
Add check if object name is already taken
damskii9992 Jun 13, 2024
3bedcee
add default name generation to BasedBase and Descriptor
damskii9992 Jun 13, 2024
048fdb7
borg _clear method
damskii9992 Jun 18, 2024
62b06a6
change id from name to unique_name
damskii9992 Jun 18, 2024
b57a136
more .name changes
damskii9992 Jun 18, 2024
ece545e
reorder name and value
damskii9992 Jun 18, 2024
982b3ca
more .name replacements and test fixes
damskii9992 Jun 18, 2024
3d5a65b
Fix tests
damskii9992 Jun 18, 2024
09ac66b
Ruff
damskii9992 Jun 18, 2024
2305785
tox fix
damskii9992 Jun 18, 2024
c6a7224
fix tox errors
damskii9992 Jun 18, 2024
473a844
Update map on unique_name change + code cleanup
damskii9992 Jul 1, 2024
0453369
Clear graph unittest
damskii9992 Jul 1, 2024
9b8f7f3
test_add_vertex
damskii9992 Jul 2, 2024
8d39a97
Rename borg to global_object
damskii9992 Jul 2, 2024
0be9d52
Restructure sourcecode tree
damskii9992 Jul 2, 2024
0e13ac2
restructure test folder
damskii9992 Jul 3, 2024
9073e49
more tests
damskii9992 Jul 3, 2024
64f0d39
test for identical unique names
damskii9992 Jul 4, 2024
f2fa102
removed UUIDS from Graph in borg
damskii9992 Jun 12, 2024
287c6de
replace convert_id calls with .name
damskii9992 Jun 13, 2024
34d609d
NameConverter class removed, move name assignment
damskii9992 Jun 13, 2024
b7617f3
remove get_key
damskii9992 Jun 13, 2024
7575d19
Add check if object name is already taken
damskii9992 Jun 13, 2024
c3e917d
add default name generation to BasedBase and Descriptor
damskii9992 Jun 13, 2024
82c75e7
borg _clear method
damskii9992 Jun 18, 2024
2edab45
change id from name to unique_name
damskii9992 Jun 18, 2024
4c18ded
more .name changes
damskii9992 Jun 18, 2024
e170e88
reorder name and value
damskii9992 Jun 18, 2024
d56a111
more .name replacements and test fixes
damskii9992 Jun 18, 2024
b4766a2
Fix tests
damskii9992 Jun 18, 2024
77131e6
Ruff
damskii9992 Jun 18, 2024
c24f40a
tox fix
damskii9992 Jun 18, 2024
1b5230d
Update map on unique_name change + code cleanup
damskii9992 Jul 1, 2024
d2e7edf
Clear graph unittest
damskii9992 Jul 1, 2024
d84cb52
test_add_vertex
damskii9992 Jul 2, 2024
f0a94cf
Rename borg to global_object
damskii9992 Jul 2, 2024
3d5e8c3
Restructure sourcecode tree
damskii9992 Jul 2, 2024
3b35911
restructure test folder
damskii9992 Jul 3, 2024
d68fc7c
more tests
damskii9992 Jul 3, 2024
7c64c6f
test for identical unique names
damskii9992 Jul 4, 2024
0b625a6
more tests
damskii9992 Jul 5, 2024
ed6ec28
Merge branch 'replace_UUIDS' of https://github.com/EasyScience/EasySc…
damskii9992 Jul 5, 2024
663c08e
Rebase on develop
damskii9992 Jul 8, 2024
574a654
fix dict tests
damskii9992 Jul 8, 2024
eff8f4b
fix __copy__ method
damskii9992 Jul 8, 2024
ad53055
fix tests
damskii9992 Jul 8, 2024
93964d0
fix remaining tests
damskii9992 Jul 8, 2024
80305db
ruff & test syntax
damskii9992 Jul 8, 2024
501230b
add final unique_name tests
damskii9992 Jul 8, 2024
3ff376b
add borg alias for global_object for backwards compatibility
damskii9992 Jul 8, 2024
da3dc61
According to PR
damskii9992 Jul 15, 2024
50791c2
fix mistake
damskii9992 Jul 15, 2024
0021efe
possible fix of test_star
damskii9992 Jul 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions examples_old/dataset_examples.ipynb

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions examples_old/example4.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import numpy as np

from easyscience import borg
from easyscience import global_object
from easyscience.Fitting import Fitter
from easyscience.Objects.core import ComponentSerializer
from easyscience.Objects.ObjectClasses import BaseObj
Expand Down Expand Up @@ -84,7 +84,7 @@ class InterfaceTemplate(ComponentSerializer, metaclass=ABCMeta):
"""

_interfaces = []
_borg = borg
_global_object = global_object

def __init_subclass__(cls, is_abstract: bool = False, **kwargs):
"""
Expand Down Expand Up @@ -171,7 +171,7 @@ def set_value(self, value_label: str, value: float):
:return: None
:rtype: noneType
"""
if self._borg.debug:
if self._global_object.debug:
print(f"Interface1: Value of {value_label} set to {value}")
setattr(self.calculator, value_label, value)

Expand Down Expand Up @@ -224,7 +224,7 @@ def set_value(self, value_label: str, value: float):
:return: None
:rtype: noneType
"""
if self._borg.debug:
if self._global_object.debug:
print(f"Interface2: Value of {value_label} set to {value}")
self._data = json.loads(self.calculator.export_data())
if value_label in self._data.keys():
Expand Down
10 changes: 5 additions & 5 deletions examples_old/example5_broken.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import numpy as np

from easyscience import borg
from easyscience import global_object
from easyscience.Fitting import Fitter
from easyscience.Objects.Base import BaseObj
from easyscience.Objects.Base import Parameter
Expand Down Expand Up @@ -86,7 +86,7 @@ class InterfaceTemplate(ComponentSerializer, metaclass=ABCMeta):
"""

_interfaces = []
_borg = borg
_global_object = global_object

def __init_subclass__(cls, is_abstract: bool = False, **kwargs):
"""
Expand Down Expand Up @@ -173,7 +173,7 @@ def set_value(self, value_label: str, value: float):
:return: None
:rtype: noneType
"""
if self._borg.debug:
if self._global_object.debug:
print(f"Interface1: Value of {value_label} set to {value}")
setattr(self.calculator, value_label, value)

Expand Down Expand Up @@ -226,7 +226,7 @@ def set_value(self, value_label: str, value: float):
:return: None
:rtype: noneType
"""
if self._borg.debug:
if self._global_object.debug:
print(f"Interface2: Value of {value_label} set to {value}")
self._data = json.loads(self.calculator.export_data())
if value_label in self._data.keys():
Expand Down Expand Up @@ -338,7 +338,7 @@ def __repr__(self):
return f"Line: m={self.m}, c={self.c}"


borg.debug = True
global_object.debug = True

interface = InterfaceFactory()
line = Line(interface_factory=interface)
Expand Down
14 changes: 7 additions & 7 deletions examples_old/example6_broken.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

import numpy as np

from easyscience import borg
from easyscience.Fitting import Fitter
from easyscience.Objects.Base import BaseObj
from easyscience.Objects.Base import Parameter
from easyscience import global_object
from easyscience.fitting import Fitter
from easyscience.Objects.ObjectClasses import BaseObj
from easyscience.Objects.Variable import Parameter
from easyscience.Objects.core import ComponentSerializer
from easyscience.Objects.Inferface import InterfaceFactoryTemplate

Expand Down Expand Up @@ -92,7 +92,7 @@ class InterfaceTemplate(ComponentSerializer, metaclass=ABCMeta):
"""

_interfaces = []
_borg = borg
_global_object = global_object

def __init_subclass__(cls, is_abstract: bool = False, **kwargs):
"""
Expand Down Expand Up @@ -183,7 +183,7 @@ def set_value(self, value_label: str, value: float):
:return: None
:rtype: noneType
"""
if self._borg.debug:
if self._global_object.debug:
print(f"Interface1: Value of {value_label} set to {value}")
setattr(self.calculator, value_label, value)

Expand Down Expand Up @@ -264,7 +264,7 @@ def set_value(self, value_label: str, value: float):
:return: None
:rtype: noneType
"""
if self._borg.debug:
if self._global_object.debug:
print(f"Interface2: Value of {value_label} set to {value}")
self._data = json.loads(self.calculator.export_data())
if value_label in self._data.keys():
Expand Down
4 changes: 2 additions & 2 deletions resources/images/ec_logo_wfont.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 12 additions & 13 deletions src/easyscience/Objects/Groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
from typing import Tuple
from typing import Union

from easyscience import borg
from easyscience.global_object.undo_redo import NotarizedDict
from easyscience.Objects.ObjectClasses import BasedBase
from easyscience.Objects.ObjectClasses import Descriptor
from easyscience.Utils.UndoRedo import NotarizedDict

if TYPE_CHECKING:
from easyscience.Utils.typing import B
Expand Down Expand Up @@ -75,17 +74,17 @@ def __init__(
for key, item in kwargs.items():
_kwargs[key] = item
for arg in args:
kwargs[str(borg.map.convert_id_to_key(arg))] = arg
_kwargs[str(borg.map.convert_id_to_key(arg))] = arg
kwargs[arg.unique_name] = arg
_kwargs[arg.unique_name] = arg

# Set kwargs, also useful for serialization
self._kwargs = NotarizedDict(**_kwargs)

for key in kwargs.keys():
if key in self.__dict__.keys() or key in self.__slots__:
raise AttributeError(f'Given kwarg: `{key}`, is an internal attribute. Please rename.')
self._borg.map.add_edge(self, kwargs[key])
self._borg.map.reset_type(kwargs[key], 'created_internal')
self._global_object.map.add_edge(self, kwargs[key])
self._global_object.map.reset_type(kwargs[key], 'created_internal')
if interface is not None:
kwargs[key].interface = interface
# TODO wrap getter and setter in Logger
Expand All @@ -109,13 +108,13 @@ def insert(self, index: int, value: Union[V, B]) -> None:
update_key = list(self._kwargs.keys())
values = list(self._kwargs.values())
# Update the internal dict
new_key = str(borg.map.convert_id_to_key(value))
new_key = value.unique_name
update_key.insert(index, new_key)
values.insert(index, value)
self._kwargs.reorder(**{k: v for k, v in zip(update_key, values)})
# ADD EDGE
self._borg.map.add_edge(self, value)
self._borg.map.reset_type(value, 'created_internal')
self._global_object.map.add_edge(self, value)
self._global_object.map.reset_type(value, 'created_internal')
value.interface = self.interface
else:
raise AttributeError('Only EasyScience objects can be put into an EasyScience group')
Expand Down Expand Up @@ -174,11 +173,11 @@ def __setitem__(self, key: int, value: Union[B, V]) -> None:
update_dict = {update_key[key]: value}
self._kwargs.update(update_dict)
# ADD EDGE
self._borg.map.add_edge(self, value)
self._borg.map.reset_type(value, 'created_internal')
self._global_object.map.add_edge(self, value)
self._global_object.map.reset_type(value, 'created_internal')
value.interface = self.interface
# REMOVE EDGE
self._borg.map.prune_vertex_from_edge(self, old_item)
self._global_object.map.prune_vertex_from_edge(self, old_item)
else:
raise NotImplementedError('At the moment only numerical values or EasyScience objects can be set.')

Expand All @@ -193,7 +192,7 @@ def __delitem__(self, key: int) -> None:
"""
keys = list(self._kwargs.keys())
item = self._kwargs[keys[key]]
self._borg.map.prune_vertex_from_edge(self, item)
self._global_object.map.prune_vertex_from_edge(self, item)
del self._kwargs[keys[key]]

def __len__(self) -> int:
Expand Down
64 changes: 47 additions & 17 deletions src/easyscience/Objects/ObjectClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from typing import TypeVar
from typing import Union

from easyscience import borg
from easyscience import global_object
from easyscience.Utils.classTools import addLoggedProp

from .core import ComponentSerializer
Expand All @@ -34,16 +34,19 @@


class BasedBase(ComponentSerializer):
__slots__ = ['_name', '_borg', 'user_data', '_kwargs']
__slots__ = ['_name', '_global_object', 'user_data', '_kwargs']

_REDIRECT = {}

def __init__(self, name: str, interface: Optional[iF] = None):
self._borg = borg
self._borg.map.add_vertex(self, obj_type='created')
def __init__(self, name: str, interface: Optional[iF] = None, unique_name: Optional[str] = None):
self._global_object = global_object
if unique_name is None:
unique_name = self._unique_name_generator()
self._unique_name = unique_name
self._name = name
self._global_object.map.add_vertex(self, obj_type="created")
self.interface = interface
self.user_data: dict = {}
self._name: str = name

@property
def _arg_spec(self) -> Set[str]:
Expand All @@ -64,6 +67,21 @@ def __reduce__(self):
cls = getattr(self, '__old_class__', self.__class__)
return cls.from_dict, (state,)

@property
def unique_name(self) -> str:
""" Get the unique name of the object."""
return self._unique_name

@unique_name.setter
def unique_name(self, new_unique_name: str):
""" Set a new unique name for the object. The old name is still kept in the map.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we are not able to reuse the unique names then?
why not delete (prune) the vertex? Leaving old mapping seems wasteful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are, but only once the old object using the unique_name has been deleted and garbage collection has run and thus removed its entries from the map.
Alternatively the user can manually prune the old unique_name from the map. The prune method is not "hidden".
We want to encourage users to not reuse unique_names, as that makes them not really "unique".
But maybe this discussion belongs in the ADR Suggestion #16.

:param new_unique_name: New unique name for the object"""
if not isinstance(new_unique_name, str):
raise TypeError("Unique name has to be a string.")
self._unique_name = new_unique_name
self._global_object.map.add_vertex(self)

@property
def name(self) -> str:
"""
Expand Down Expand Up @@ -114,10 +132,12 @@ def generate_bindings(self):
if self.interface is None:
raise AttributeError('Interface error for generating bindings. `interface` has to be set.')
interfaceable_children = [
key for key in self._borg.map.get_edges(self) if issubclass(type(self._borg.map.get_item_by_key(key)), BasedBase)
key
for key in self._global_object.map.get_edges(self)
if issubclass(type(self._global_object.map.get_item_by_key(key)), BasedBase)
]
for child_key in interfaceable_children:
child = self._borg.map.get_item_by_key(child_key)
child = self._global_object.map.get_item_by_key(child_key)
child.interface = self.interface
self.interface.generate_bindings(self)

Expand Down Expand Up @@ -186,6 +206,14 @@ def get_fit_parameters(self) -> Union[List[Parameter], List[new_Parameter]]:
fit_list.append(item)
return fit_list

def _unique_name_generator(self) -> str:
"""
Generate a generic unique name for the object using the class name and a global iterator.
"""
class_name = self.__class__.__name__
iterator_string = str(self._global_object.map._get_name_iterator(class_name))
return class_name + "_" + iterator_string

def __dir__(self) -> Iterable[str]:
"""
This creates auto-completion and helps out in iPython notebooks.
Expand All @@ -194,6 +222,7 @@ def __dir__(self) -> Iterable[str]:
"""
new_class_objs = list(k for k in dir(self.__class__) if not k.startswith('_'))
return sorted(new_class_objs)



if TYPE_CHECKING:
Expand All @@ -213,6 +242,7 @@ class BaseObj(BasedBase):
def __init__(
self,
name: str,
unique_name: Optional[str] = None,
*args: Optional[BV],
**kwargs: Optional[BV],
):
Expand All @@ -223,7 +253,7 @@ def __init__(
:param args: Any arguments?
:param kwargs: Fields which this class should contain
"""
super(BaseObj, self).__init__(name)
super(BaseObj, self).__init__(name=name, unique_name=unique_name)
# If Parameter or Descriptor is given as arguments...
for arg in args:
if issubclass(type(arg), (BaseObj, Descriptor, DescriptorBase)):
Expand All @@ -233,12 +263,12 @@ def __init__(
self._kwargs = kwargs
for key in kwargs.keys():
if key in known_keys:
raise AttributeError
raise AttributeError("Kwargs cannot overwrite class attributes in BaseObj.")
if issubclass(type(kwargs[key]), (BasedBase, Descriptor, DescriptorBase)) or 'BaseCollection' in [
c.__name__ for c in type(kwargs[key]).__bases__
]:
self._borg.map.add_edge(self, kwargs[key])
self._borg.map.reset_type(kwargs[key], 'created_internal')
self._global_object.map.add_edge(self, kwargs[key])
self._global_object.map.reset_type(kwargs[key], 'created_internal')
addLoggedProp(
self,
key,
Expand Down Expand Up @@ -271,8 +301,8 @@ def __init__(self, foo: Parameter, bar: Parameter):
:return: None
"""
self._kwargs[key] = component
self._borg.map.add_edge(self, component)
self._borg.map.reset_type(component, 'created_internal')
self._global_object.map.add_edge(self, component)
self._global_object.map.reset_type(component, 'created_internal')
addLoggedProp(
self,
key,
Expand All @@ -298,13 +328,13 @@ def __setattr__(self, key: str, value: BV) -> None:
):
if issubclass(type(getattr(self, key, None)), (BasedBase, Descriptor, DescriptorBase)):
old_obj = self.__getattribute__(key)
self._borg.map.prune_vertex_from_edge(self, old_obj)
self._global_object.map.prune_vertex_from_edge(self, old_obj)
self._add_component(key, value)
else:
if hasattr(self, key) and issubclass(type(value), (BasedBase, Descriptor, DescriptorBase)):
old_obj = self.__getattribute__(key)
self._borg.map.prune_vertex_from_edge(self, old_obj)
self._borg.map.add_edge(self, value)
self._global_object.map.prune_vertex_from_edge(self, old_obj)
self._global_object.map.add_edge(self, value)
super(BaseObj, self).__setattr__(key, value)
# Update the interface bindings if something changed (BasedBase and Descriptor)
if old_obj is not None:
Expand Down
Loading