diff --git a/forgebox/__init__.py b/forgebox/__init__.py index 68cdeee..382021f 100644 --- a/forgebox/__init__.py +++ b/forgebox/__init__.py @@ -1 +1 @@ -__version__ = "1.0.5" +__version__ = "1.0.6" diff --git a/forgebox/imports.py b/forgebox/imports.py index 1f5a9cb..e553d4a 100644 --- a/forgebox/imports.py +++ b/forgebox/imports.py @@ -4,7 +4,7 @@ # Cell -__all__ = ["pd", "np", "partial", "Path", "json", "Counter", +__all__ = ["pd", "np", "partial", "Path", "json", "Counter", "Unpack", "plt", "os", "sys", "glob", "Image", ] # import enhanced version of pandas @@ -14,6 +14,7 @@ import json from functools import partial from collections import Counter +from .unpack import Unpack import os diff --git a/forgebox/unpack.py b/forgebox/unpack.py new file mode 100644 index 0000000..a91c21b --- /dev/null +++ b/forgebox/unpack.py @@ -0,0 +1,62 @@ +from typing import Tuple, Any + + +class Unpack: + """ + Simmulat js unpacking variables + Assume you have very convoluted data structure + data = { + "info":{ + "name": "Lisa", "age":12, + }, + "grad":{ + "math":{ + "mid":98, "final":99 + }, + "history":{"mid":90, "final":95}, + }, + "date":"2022-01-01", + } + student = Unpack(data) + name, final_math_score, date = student(["info","name"],['grad','math','final'],'date') + """ + + def __init__(self, obj, raise_error: bool = False): + self.obj = obj + self.raise_error = raise_error + + def indexing(self, key: str) -> Any: + try: + return self.obj[key] + except (KeyError, IndexError) as e: + if self.raise_error: + raise e + else: + return None + + def __call__(self, *args) -> Tuple[Any]: + rt = [] + for arg in args: + if type(arg) in [list, tuple]: # arg is iterable + if len(arg) > 1: + answer = self.indexing(arg[0]) + if type(answer) in [dict, list, tuple]: + # answer has further indexing possibilities + rt.append(Unpack(answer)(arg[1:])) + else: + # still remaining keychains, but no tree branch to go on + rt.append(answer) + elif len(arg) == 1: + rt.append(self.indexing(arg[0])) + else: + if self.raise_error: + raise ValueError(f"list length can not equal to zero") + else: + rt.append(None) + else: # arg is just one key + rt.append(self.indexing(arg)) + + if len(rt) == 1: + return rt[0] + else: + return tuple(rt) diff --git a/settings.ini b/settings.ini index 1b7dd74..3eed568 100644 --- a/settings.ini +++ b/settings.ini @@ -7,7 +7,7 @@ author = xiaochen(ray) zhang author_email = b2ray2c@gmail.com copyright = xiaochen(ray) zhang branch = master -version = 1.0.5 +version = 1.0.6 min_python = 3.6 host = github audience = Developers diff --git a/test/pipeline_test.py b/test/pipeline_test.py index 4dcd419..98be604 100644 --- a/test/pipeline_test.py +++ b/test/pipeline_test.py @@ -86,3 +86,23 @@ def test_cosine_search(): assert (cos(vec) == [2, 1, 0]).all() assert (cos(vec2) == [0, 1, 2]).all() assert (cos.search(vec) == [2, 1 ,0]).all() + + +def test_unpack(): + from forgebox.imports import Unpack + data = { + "info":{ + "name": "Lisa", "age":12, + }, + "grad":{ + "math":{ + "mid":98, "final":99 + }, + "history":{"mid":90, "final":95}, + }, + "date":"2022-01-01", + } + name, math_final, date = Unpack(data, False)(["info","name"],['grad','math','final'],'date') + assert name == "Lisa" + assert math_final == 99 + assert date == "2022-01-01" \ No newline at end of file