Skip to content
Snippets Groups Projects
Commit 22498cea authored by lukas leufen's avatar lukas leufen
Browse files

first implementation of data store with 2 different designs but same...

first implementation of data store with 2 different designs but same functionality, not decided yet which representation is more suitable
parent ea26f48b
No related branches found
No related tags found
2 merge requests!17update to v0.4.0,!14include data storage
Pipeline #26367 passed
__author__ = 'Lukas Leufen'
__date__ = '2019-11-22'
from typing import Any
from abc import ABC
class NameNotFoundInDataStore(Exception):
pass
class NameNotFoundInScope(Exception):
pass
class AbstractDataStore(ABC):
"""
Data store for all settings for the experiment workflow to save experiment parameters for the proceeding modules
and predefine parameters loaded during the experiment setup phase. The data store is hierarchically structured, so
that global settings can be overwritten by local adjustments.
"""
def __init__(self):
# empty initialise the data-store variables
self._store = {}
def put(self, name: str, obj: Any, scope: str) -> None:
pass
def get(self, name: str, scope: str) -> None:
pass
class DataStoreByVariable(AbstractDataStore):
def put(self, name, obj, scope):
# open new variable related store with `name` as key if not existing
if name not in self._store.keys():
self._store[name] = {}
self._store[name][scope] = obj
def get(self, name, scope, depth=None):
if depth is None:
depth = scope.count(".")
if depth >= 0:
try:
return self._store[name][scope]
except KeyError:
return self.get(name, scope.rsplit(".", maxsplit=depth)[0], depth-1)
else:
if name in self._store.keys():
raise NameNotFoundInScope(f"Couldn't find {name} in scope {scope}. {name} is only defined in "
f"{self.search_name(name)}")
else:
raise NameNotFoundInDataStore(f"Couldn't find {name} in data store")
def search_name(self, name):
return sorted(self._store[name])
class DataStoreByScope(AbstractDataStore):
def put(self, name, obj, scope):
if scope not in self._store.keys():
self._store[scope] = {}
self._store[scope][name] = obj
def get(self, name, scope, depth=None):
if depth is None:
depth = scope.count(".")
if depth >= 0:
try:
return self._store[scope][name]
except KeyError:
return self.get(name, scope.rsplit(".", maxsplit=1)[0], depth-1)
else:
occurrences = self.search_name(name)
if len(occurrences) == 0:
raise NameNotFoundInDataStore(f"Couldn't find {name} in data store")
else:
raise NameNotFoundInScope(f"Couldn't find {name} in scope {scope}. {name} is only defined in "
f"{occurrences}")
def search_name(self, name):
keys = []
for (key, val) in self._store.items():
if name in val.keys():
keys.append(key)
return sorted(keys)
__author__ = 'Lukas Leufen'
__date__ = '2019-11-22'
from src.datastore import AbstractDataStore, DataStoreByVariable, DataStoreByScope
from src.datastore import NameNotFoundInDataStore, NameNotFoundInScope
import pytest
class TestAbstractDataStore:
@pytest.fixture
def ds(self):
return AbstractDataStore()
def test_init(self, ds):
assert ds._store == {}
class TestDataStoreByVariable:
@pytest.fixture
def ds(self):
return DataStoreByVariable()
def test_put(self, ds):
ds.put("number", 3, "general.subscope")
assert ds._store["number"]["general.subscope"] == 3
def test_get(self, ds):
ds.put("number", 3, "general.subscope")
assert ds.get("number", "general.subscope") == 3
def test_get_with_sub_scope(self, ds):
ds.put("number", 3, "general")
ds.put("number", 10, "general.subscope")
assert ds.get("number", "general.subscope") == 10
assert ds.get("number", "general") == 3
def test_get_with_not_existing_sub_scope(self, ds):
ds.put("number", 3, "general")
ds.put("number2", 10, "general.subscope")
ds.put("number2", 1, "general")
assert ds.get("number", "general.subscope") == 3
def test_raise_not_in_data_store(self, ds):
ds.put("number", 22, "general")
with pytest.raises(NameNotFoundInDataStore) as e:
ds.get("number3", "general")
assert "Couldn't find number3 in data store" in e.value.args[0]
def test_search(self, ds):
ds.put("number", 22, "general")
ds.put("number", 22, "general2")
ds.put("number", 22, "general.sub")
assert ds.search_name("number") == ["general", "general.sub", "general2"]
def test_raise_not_in_scope(self, ds):
ds.put("number", 11, "general.sub")
with pytest.raises(NameNotFoundInScope) as e:
ds.get("number", "general")
assert "Couldn't find number in scope general. number is only defined in ['general.sub']" in e.value.args[0]
class TestDataStoreByScope:
@pytest.fixture
def ds(self):
return DataStoreByScope()
def test_put_with_scope(self, ds):
ds.put("number", 3, "general.subscope")
assert ds._store["general.subscope"]["number"] == 3
def test_get(self, ds):
ds.put("number", 3, "general.subscope")
assert ds.get("number", "general.subscope") == 3
def test_get_with_sub_scope(self, ds):
ds.put("number", 3, "general")
ds.put("number", 10, "general.subscope")
assert ds.get("number", "general.subscope") == 10
assert ds.get("number", "general") == 3
def test_get_with_not_existing_sub_scope(self, ds):
ds.put("number", 3, "general")
ds.put("number2", 10, "general.subscope")
ds.put("number2", 1, "general")
assert ds.get("number", "general.subscope") == 3
def test_raise_not_in_data_store(self, ds):
ds.put("number", 22, "general")
with pytest.raises(NameNotFoundInDataStore) as e:
ds.get("number3", "general")
assert "Couldn't find number3 in data store" in e.value.args[0]
def test_search(self, ds):
ds.put("number", 22, "general")
ds.put("number", 22, "general2")
ds.put("number", 22, "general.sub")
assert ds.search_name("number") == ["general", "general.sub", "general2"]
def test_raise_not_in_scope(self, ds):
ds.put("number", 11, "general.sub")
with pytest.raises(NameNotFoundInScope) as e:
ds.get("number", "general")
assert "Couldn't find number in scope general. number is only defined in ['general.sub']" in e.value.args[0]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment