tensorneko-util 0.3.18__tar.gz → 0.3.20__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/PKG-INFO +1 -1
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/README.md +1 -1
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/image/image_reader.py +4 -1
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/json/json_writer.py +3 -3
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/pickle/pickle_reader.py +3 -3
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/__init__.py +3 -1
- tensorneko_util-0.3.20/src/tensorneko_util/util/multi_layer_indexer.py +113 -0
- tensorneko_util-0.3.20/src/tensorneko_util/version.txt +1 -0
- tensorneko_util-0.3.18/src/tensorneko_util/visualization/watcher/web/dist/assets/index.3222e532.js → tensorneko_util-0.3.20/src/tensorneko_util/visualization/watcher/web/dist/assets/index.7498e230.js +7 -7
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/watcher/web/dist/index.html +1 -1
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util.egg-info/PKG-INFO +1 -1
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util.egg-info/SOURCES.txt +2 -1
- tensorneko_util-0.3.18/src/tensorneko_util/version.txt +0 -1
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/setup.cfg +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/setup.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/setup_util.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/_rich.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/backend/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/backend/audio_lib.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/backend/blocking.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/backend/parallel.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/backend/tqdm.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/backend/visual_lib.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/debug/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/debug/logger.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/debug/parser.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/_default_backends.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/_path_conversion.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/audio/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/audio/audio_data.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/audio/audio_reader.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/audio/audio_writer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/hdf5/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/hdf5/hdf5_reader.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/hdf5/hdf5_writer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/image/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/image/image_writer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/json/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/json/json_data.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/json/json_reader.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/matlab/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/matlab/mat_reader.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/matlab/mat_writer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/npy/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/npy/npy_reader.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/npy/npy_writer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/pickle/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/pickle/pickle_writer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/reader.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/text/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/text/text_reader.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/text/text_writer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/toml/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/toml/toml_reader.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/toml/toml_writer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/video/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/video/video_data.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/video/video_reader.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/video/video_writer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/writer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/yaml/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/yaml/yaml_reader.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/yaml/yaml_writer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/msg/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/msg/gotify.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/notebook/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/notebook/animation.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/notebook/display.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/preprocess/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/preprocess/crop.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/preprocess/face_detector/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/preprocess/face_detector/_utils.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/preprocess/face_detector/abstract_face_detector.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/preprocess/face_detector/anime_face_detector.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/preprocess/face_detector/facexzoo_face_detector.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/preprocess/face_detector/opencv_face_detector.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/preprocess/ffmpeg.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/preprocess/image.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/preprocess/video.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/average_meter.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/bimap.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/dispatched_misc.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/dispatcher.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/downloader.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/eventbus/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/eventbus/bus.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/eventbus/decorator.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/eventbus/event.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/args.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/array/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/array/abstract_seq.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/array/seq.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/array/stream.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/func.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/monad/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/monad/eval.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/monad/monad.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/monad/option.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/fp/underscore.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/misc.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/ref.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/registry.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/server.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/singleton.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/timer.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/type.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/util/window_merger.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/color.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/image_browser/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/image_browser/server.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/image_browser/web/index.html +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/matplotlib.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/multi_plots.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/seaborn.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/tensorboard.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/watcher/__init__.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/watcher/component.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/watcher/server.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/watcher/view.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/visualization/watcher/web/dist/assets/index.cf95019d.css +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util.egg-info/dependency_links.txt +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util.egg-info/requires.txt +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util.egg-info/top_level.txt +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/test/test_library_info.py +0 -0
- {tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/test/test_version.py +0 -0
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<div align="center">
|
|
13
13
|
<a href="https://www.python.org/"><img src="https://img.shields.io/pypi/pyversions/tensorneko?style=flat-square"></a>
|
|
14
14
|
<a href="https://pytorch.org/"><img src="https://img.shields.io/badge/PyTorch-%3E%3D1.9.0-EE4C2C?style=flat-square&logo=pytorch"></a>
|
|
15
|
-
<a href="https://www.pytorchlightning.ai/"><img src="https://img.shields.io/badge/Lightning-2
|
|
15
|
+
<a href="https://www.pytorchlightning.ai/"><img src="https://img.shields.io/badge/Lightning-2.*-792EE5?style=flat-square&logo=lightning"></a>
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
<div align="center">
|
{tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/image/image_reader.py
RENAMED
|
@@ -35,7 +35,10 @@ class ImageReader:
|
|
|
35
35
|
if not VisualLib.opencv_available():
|
|
36
36
|
raise ValueError("OpenCV is not installed.")
|
|
37
37
|
import cv2
|
|
38
|
-
img = cv2.imread(path)
|
|
38
|
+
img = cv2.imread(path)
|
|
39
|
+
if img is None:
|
|
40
|
+
raise ValueError("Invalid image path: {}".format(path))
|
|
41
|
+
img = img.astype(np.float32) / 255.0
|
|
39
42
|
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
|
40
43
|
elif backend == VisualLib.MATPLOTLIB:
|
|
41
44
|
if not VisualLib.matplotlib_available():
|
{tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/json/json_writer.py
RENAMED
|
@@ -9,7 +9,7 @@ from .._path_conversion import _path2str
|
|
|
9
9
|
class JsonWriter:
|
|
10
10
|
|
|
11
11
|
@staticmethod
|
|
12
|
-
def _write_json(path: str, obj: Union[dict, list], encoding: str = "UTF-8", indent: int =
|
|
12
|
+
def _write_json(path: str, obj: Union[dict, list], encoding: str = "UTF-8", indent: int = 2,
|
|
13
13
|
ensure_ascii: bool = False, fast: bool = True
|
|
14
14
|
) -> None:
|
|
15
15
|
if not fast:
|
|
@@ -28,7 +28,7 @@ class JsonWriter:
|
|
|
28
28
|
file.write(orjson.dumps(obj, option=option))
|
|
29
29
|
|
|
30
30
|
@classmethod
|
|
31
|
-
def to(cls, path: Union[str, Path], obj: Union[dict, list, object], encoding: str = "UTF-8", indent: int =
|
|
31
|
+
def to(cls, path: Union[str, Path], obj: Union[dict, list, object], encoding: str = "UTF-8", indent: int = 2,
|
|
32
32
|
ensure_ascii: bool = False, fast: bool = True
|
|
33
33
|
) -> None:
|
|
34
34
|
"""
|
|
@@ -68,7 +68,7 @@ class JsonWriter:
|
|
|
68
68
|
else:
|
|
69
69
|
raise TypeError("Not implemented type. Only support dict, list, json_data.")
|
|
70
70
|
|
|
71
|
-
def __new__(cls, path: Union[str, Path], obj: Union[dict, list, object], encoding: str = "UTF-8", indent: int =
|
|
71
|
+
def __new__(cls, path: Union[str, Path], obj: Union[dict, list, object], encoding: str = "UTF-8", indent: int = 2,
|
|
72
72
|
ensure_ascii: bool = False, fast: bool = True
|
|
73
73
|
) -> None:
|
|
74
74
|
"""Alias of :meth:`~tensorneko.io.json.json_writer.JsonWriter.to`."""
|
{tensorneko_util-0.3.18 → tensorneko_util-0.3.20}/src/tensorneko_util/io/pickle/pickle_reader.py
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import pickle
|
|
2
|
-
from typing import Union
|
|
2
|
+
from typing import Union, Any
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
5
|
from .._path_conversion import _path2str
|
|
@@ -8,7 +8,7 @@ from .._path_conversion import _path2str
|
|
|
8
8
|
class PickleReader:
|
|
9
9
|
|
|
10
10
|
@classmethod
|
|
11
|
-
def of(cls, path: Union[str, Path]) ->
|
|
11
|
+
def of(cls, path: Union[str, Path]) -> Any:
|
|
12
12
|
"""
|
|
13
13
|
Save the object to a file.
|
|
14
14
|
|
|
@@ -19,7 +19,7 @@ class PickleReader:
|
|
|
19
19
|
with open(path, 'rb') as f:
|
|
20
20
|
return pickle.load(f)
|
|
21
21
|
|
|
22
|
-
def __new__(cls, path: Union[str, Path]) ->
|
|
22
|
+
def __new__(cls, path: Union[str, Path]) -> Any:
|
|
23
23
|
"""Alias to :meth:`~tensorneko_util.io.pickle.PickleReader.of`."""
|
|
24
24
|
path = _path2str(path)
|
|
25
25
|
return cls.of(path)
|
|
@@ -12,6 +12,7 @@ from .eventbus import Event, EventBus, EventHandler, subscribe
|
|
|
12
12
|
from .singleton import Singleton
|
|
13
13
|
from .downloader import download_file, download_file_thread, download_files_thread
|
|
14
14
|
from .window_merger import WindowMerger
|
|
15
|
+
from .multi_layer_indexer import MultiLayerIndexer
|
|
15
16
|
|
|
16
17
|
tensorneko_util_path = get_tensorneko_util_path()
|
|
17
18
|
|
|
@@ -56,5 +57,6 @@ __all__ = [
|
|
|
56
57
|
"download_file_thread",
|
|
57
58
|
"download_files_thread",
|
|
58
59
|
"WindowMerger",
|
|
59
|
-
"Registry"
|
|
60
|
+
"Registry",
|
|
61
|
+
"MultiLayerIndexer"
|
|
60
62
|
]
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
from typing import Union, List
|
|
2
|
+
|
|
3
|
+
T_Counts = Union[int, List["Counts"]]
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MultiLayerIndexer:
|
|
7
|
+
"""
|
|
8
|
+
Multi-layer indexer for hierarchical indexing structures.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
counts (``int`` | ``List[int | List]``): A nested structure representing the counts at each layer.
|
|
12
|
+
It can be an integer or a list of counts (which can themselves be lists).
|
|
13
|
+
|
|
14
|
+
Examples::
|
|
15
|
+
|
|
16
|
+
# Test Case 1
|
|
17
|
+
counts = [5, 10, 15]
|
|
18
|
+
indexer = MultiLayerIndexer(counts)
|
|
19
|
+
print(len(indexer), indexer(12)) # Output: 30 [1, 7]
|
|
20
|
+
|
|
21
|
+
# Test Case 2
|
|
22
|
+
counts = [[3, 2], 4, [1, 1, 1]]
|
|
23
|
+
indexer = MultiLayerIndexer(counts)
|
|
24
|
+
print(len(indexer), indexer(8)) # Output: 12 [1, 3]
|
|
25
|
+
|
|
26
|
+
# Test Case 3 (Error Handling)
|
|
27
|
+
try:
|
|
28
|
+
counts = [2, [3, [4, 5]]]
|
|
29
|
+
indexer = MultiLayerIndexer(counts)
|
|
30
|
+
print(len(indexer), indexer(20)) # Should raise IndexError
|
|
31
|
+
except IndexError as e:
|
|
32
|
+
print(e) # Output: Index out of bounds
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(self, counts: T_Counts):
|
|
37
|
+
self._counts = counts
|
|
38
|
+
self._total = self._total_counts(counts)
|
|
39
|
+
|
|
40
|
+
def __call__(self, index: int) -> List[int]:
|
|
41
|
+
"""
|
|
42
|
+
Given a global index, return the indices at each layer.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
index (``int``): The global index.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
``List[int]``: A list of indices at each layer corresponding to the global index.
|
|
49
|
+
|
|
50
|
+
Raises:
|
|
51
|
+
``IndexError``: If the provided global index is out of bounds.
|
|
52
|
+
"""
|
|
53
|
+
return self._multi_layer_index(self._counts, index)
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def _multi_layer_index(cls, counts: T_Counts, index: int) -> List[int]:
|
|
57
|
+
"""
|
|
58
|
+
A recursive helper function to compute the indices at each layer.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
counts (``int`` | ``List[int | List]``): The counts at the current layer.
|
|
62
|
+
index (``int``): The index at the current layer.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
``list``: A list of indices at each layer.
|
|
66
|
+
|
|
67
|
+
Raises:
|
|
68
|
+
``IndexError``: If the provided index exceeds the available counts.
|
|
69
|
+
"""
|
|
70
|
+
if isinstance(counts, int):
|
|
71
|
+
if index < counts:
|
|
72
|
+
return [index]
|
|
73
|
+
else:
|
|
74
|
+
raise IndexError("Index out of bounds")
|
|
75
|
+
elif isinstance(counts, list):
|
|
76
|
+
cumulative_counts = [0]
|
|
77
|
+
for c in counts:
|
|
78
|
+
total_c = cls._total_counts(c)
|
|
79
|
+
cumulative_counts.append(cumulative_counts[-1] + total_c)
|
|
80
|
+
for i in range(len(cumulative_counts) - 1):
|
|
81
|
+
if cumulative_counts[i] <= index < cumulative_counts[i + 1]:
|
|
82
|
+
sub_idx = index - cumulative_counts[i]
|
|
83
|
+
sub_indices = cls._multi_layer_index(counts[i], sub_idx)
|
|
84
|
+
return [i] + sub_indices
|
|
85
|
+
raise IndexError("Index out of bounds")
|
|
86
|
+
else:
|
|
87
|
+
raise ValueError("Invalid counts structure")
|
|
88
|
+
|
|
89
|
+
@classmethod
|
|
90
|
+
def _total_counts(cls, counts: T_Counts) -> int:
|
|
91
|
+
"""
|
|
92
|
+
Compute the total counts of items under the given counts structure.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
counts (``int`` | ``List[int | List]``): The counts structure.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
``int``: The total count of items.
|
|
99
|
+
|
|
100
|
+
Raises:
|
|
101
|
+
``ValueError``: If the counts structure is invalid.
|
|
102
|
+
"""
|
|
103
|
+
if isinstance(counts, int):
|
|
104
|
+
if counts < 0:
|
|
105
|
+
raise ValueError("Counts cannot be negative")
|
|
106
|
+
return counts
|
|
107
|
+
elif isinstance(counts, list):
|
|
108
|
+
return sum(cls._total_counts(c) for c in counts)
|
|
109
|
+
else:
|
|
110
|
+
raise ValueError("Invalid counts structure")
|
|
111
|
+
|
|
112
|
+
def __len__(self) -> int:
|
|
113
|
+
return self._total
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.3.20
|