Skip to content

Commit

Permalink
Merge pull request #18 from bis-med-it/flatten_hierarchy
Browse files Browse the repository at this point in the history
Flatten hierarchy
  • Loading branch information
sosna committed Feb 23, 2024
2 parents 2a0bb09 + bad9281 commit 864f008
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 9 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pysdmx"
version = "1.0.0-beta-7"
version = "1.0.0-beta-8"
description = "Your opinionated Python SDMX library"
authors = [
"Xavier Sosnovsky <xavier.sosnovsky@bis.org>",
Expand Down
2 changes: 1 addition & 1 deletion src/pysdmx/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Your opinionated Python SDMX library."""

__version__ = "1.0.0-beta-7"
__version__ = "1.0.0-beta-8"
28 changes: 28 additions & 0 deletions src/pysdmx/model/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,34 @@ def by_id(self, id: str) -> Sequence[HierarchicalCode]:
"""
return self.__by_id(id, self.codes)

def __get_codes(
self, codes: Sequence[HierarchicalCode]
) -> Sequence[HierarchicalCode]:
out = []
for code in codes:
out.append(code)
if code.codes:
out.extend(self.__get_codes(code.codes))
return out

def all_codes(self) -> Sequence[HierarchicalCode]:
"""Get all the codes in the hierarchy as a flat list.
This is useful for validation purposes. The sequence behaves
as a set, i.e. even if a code is attached to multiple nodes,
it will be available only once in the returned sequence.
Returns:
A flat list of the codes present in the hierarchy.
"""
out = []
# We need to do this below because a hierarchical code is not
# (yet?) hashable.
for c in self.__get_codes(self.codes):
if c not in out:
out.append(c)
return out


class HierarchyAssociation(Struct, frozen=True, omit_defaults=True):
"""Links a hierarchy to a component withing the context of a dataflow."""
Expand Down
12 changes: 5 additions & 7 deletions src/pysdmx/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

from pysdmx.errors import NotFound

NF = "Not found"


class Reference(Struct, frozen=True):
"""The coordinates of an SDMX maintainable artefact.
Expand Down Expand Up @@ -58,9 +60,7 @@ def parse_urn(urn: str) -> Reference:
)
else:
raise NotFound(
404,
"Not found",
f"{urn} does not match {maintainable_urn_pattern}",
404, NF, f"{urn} does not match {maintainable_urn_pattern}"
)


Expand All @@ -76,9 +76,7 @@ def parse_item_urn(urn: str) -> ItemReference:
item_id=m.group(5),
)
else:
raise NotFound(
404, "Not found", f"{urn} does not match {item_urn_pattern}."
)
raise NotFound(404, NF, f"{urn} does not match {item_urn_pattern}.")


def find_by_urn(artefacts: Sequence[Any], urn: str) -> Any:
Expand All @@ -95,7 +93,7 @@ def find_by_urn(artefacts: Sequence[Any], urn: str) -> Any:
urns = [f"{a.agency}:{a.id}({a.version})" for a in artefacts]
raise NotFound(
404,
"Not found",
NF,
(
f"Could not find an artefact matching the following URN: "
f"{urn}. The artefacts received were: {urns}."
Expand Down
23 changes: 23 additions & 0 deletions tests/model/test_hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,26 @@ def test_codes_by_id_diff_names(id, name, agency):
m = list(m)
assert grandchild1 in m
assert grandchild3 in m


def test_all_codes(id, name, agency):
grandchild1 = HierarchicalCode("grandchild1", "grandchild 1")
grandchild2 = HierarchicalCode("grandchild2", "grandchild 2")
grandchild3 = HierarchicalCode("grandchild3", "grandchild 3")
child1 = HierarchicalCode(
"child1", "child 1", codes=[grandchild1, grandchild2]
)
child2 = HierarchicalCode(
"child2", "child 2", codes=[grandchild1, grandchild2, grandchild3]
)
parent1 = HierarchicalCode("parent1", "parent 1")
parent2 = HierarchicalCode(
"parent2",
"parent 2",
codes=[child1, child2],
)

h = Hierarchy(id, name, agency, codes=[parent1, parent2])

m = h.all_codes()
assert len(m) == 7

0 comments on commit 864f008

Please sign in to comment.