kevin-toolbox-dev 1.2.8__py3-none-any.whl → 1.3.0__py3-none-any.whl

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.
kevin_toolbox/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "1.2.8"
1
+ __version__ = "1.3.0"
2
2
 
3
3
 
4
4
  import os
@@ -12,5 +12,5 @@ os.system(
12
12
  os.system(
13
13
  f'python {os.path.split(__file__)[0]}/env_info/check_validity_and_uninstall.py '
14
14
  f'--package_name kevin-toolbox-dev '
15
- f'--expiration_timestamp 1715414856 --verbose 0'
15
+ f'--expiration_timestamp 1718018144 --verbose 0'
16
16
  )
@@ -4,6 +4,8 @@ import inspect
4
4
  import pkgutil
5
5
  import weakref
6
6
  import kevin_toolbox.nested_dict_list as ndl
7
+ from kevin_toolbox.patches import for_os
8
+ from kevin_toolbox.patches.for_os import Path_Ignorer, Ignore_Scope
7
9
 
8
10
 
9
11
  class Registry:
@@ -218,14 +220,22 @@ class Registry:
218
220
 
219
221
  # -------------------- 通过路径添加 --------------------- #
220
222
 
221
- def collect_from_paths(self, path_ls=None, path_ls_to_exclude=None, b_execute_now=False):
223
+ def collect_from_paths(self, path_ls=None, ignore_s=None, b_execute_now=False):
222
224
  """
223
225
  遍历 path_ls 下的所有模块,并自动导入其中主要被注册的部分
224
226
  比如被 register() 装饰器包裹或者通过 add() 添加的部分
225
227
 
226
228
  参数:
227
229
  path_ls: <list of paths> 需要搜索的目录
228
- path_ls_to_exclude: <list of paths> 需要排除的目录
230
+ ignore_s: <list/tuple of dict> 在搜索遍历目录时候要执行的排除规则
231
+ 具体设置方式参考 patches.for_os.walk() 中的 ignore_s 参数。
232
+ 比如使用下面的规则就可以排除待搜索目录下的所有 temp/ 和 test/ 文件夹:
233
+ [
234
+ {
235
+ "func": lambda _, __, path: os.path.basename(path) in ["temp", "test"],
236
+ "scope": ["root", "dirs"]
237
+ },
238
+ ]
229
239
  b_execute_now: <boolean> 现在就执行导入
230
240
  默认为 False,将等到第一次执行 get() 函数时才会真正尝试导入
231
241
 
@@ -243,10 +253,13 @@ class Registry:
243
253
  f'calling Registry.collect_from_paths() in __init__.py is forbidden, file: {caller_frame.filename}.\n' \
244
254
  f'you can call it in other files, and then import the result of the call in __init__.py'
245
255
 
256
+ # 根据 ignore_s 构建 Path_Ignorer
257
+ path_ignorer = ignore_s if isinstance(ignore_s, (Path_Ignorer,)) else Path_Ignorer(ignore_s=ignore_s)
258
+
246
259
  #
247
260
  if not b_execute_now:
248
261
  self._path_to_collect.append(
249
- dict(path_ls=path_ls, path_ls_to_exclude=path_ls_to_exclude, b_execute_now=True))
262
+ dict(path_ls=path_ls, ignore_s=path_ignorer, b_execute_now=True))
250
263
  return
251
264
 
252
265
  #
@@ -254,27 +267,38 @@ class Registry:
254
267
  temp = []
255
268
  for path in filter(lambda x: os.path.isdir(x), path_ls):
256
269
  temp.append(path)
257
- for root, dirs, _ in os.walk(path, topdown=False):
270
+ for root, dirs, _ in for_os.walk(path, topdown=False, ignore_s=path_ignorer, followlinks=True):
258
271
  temp.extend([os.path.join(root, i) for i in dirs])
259
- if path_ls_to_exclude is not None:
260
- for path_ex in path_ls_to_exclude:
261
- if not os.path.exists(path_ex):
262
- continue
263
- for i in reversed(range(len(temp))):
264
- if os.path.samefile(os.path.commonpath([path_ex, temp[i]]), path_ex):
265
- temp.pop(i)
266
272
  # 从深到浅导入,可以避免继承引起的 TypeError: super(type, obj) 类型错误
267
273
  path_ls = list(set(temp))
268
274
  path_ls.sort(reverse=True)
275
+ path_set = set(path_ls)
269
276
 
270
277
  temp = None
271
278
  for loader, module_name, is_pkg in pkgutil.walk_packages(path_ls):
279
+ # 判断该模块是否需要导入
280
+ # (快速判断)判断该模块所在目录是否在 path_set 中
281
+ if loader.path not in path_set:
282
+ continue
283
+ if is_pkg:
284
+ # 若不是 package,判断是否满足 Path_Ignorer 中的 dirs 对应的规则
285
+ path = os.path.dirname(loader.find_module(module_name).path)
286
+ if path_ignorer(Ignore_Scope.DIRS, True, os.path.islink(path), path):
287
+ continue
288
+ else:
289
+ # 若该模块是 package,判断该模块的文件路径是否满足 Path_Ignorer 中的 files 对应的规则
290
+ path = loader.find_module(module_name).path
291
+ if path_ignorer(Ignore_Scope.FILES, False, os.path.islink(path), path):
292
+ continue
293
+ # 加载模块
272
294
  module = loader.find_module(module_name).load_module(module_name)
295
+ # 选择遍历过程中第一次找到的 Registry 实例
273
296
  if temp is None:
274
297
  for name, obj in inspect.getmembers(module):
275
298
  if getattr(obj, "name", None) == Registry.name and getattr(obj, "uid", None) == self.uid:
276
299
  temp = obj
277
300
  break
301
+
278
302
  if temp is not None:
279
303
  self.database = temp.database
280
304
 
@@ -1,2 +1,3 @@
1
1
  from .write import write
2
2
  from .read import read
3
+ from .enum_variable import Strictness_Level
@@ -0,0 +1,12 @@
1
+ from enum import Enum
2
+
3
+
4
+ class Strictness_Level(Enum):
5
+ """
6
+ 对于正确性与完整性的要求的严格程度
7
+ """
8
+ COMPLETE = "high" # 所有节点均有一个或者多个匹配上的 backend,且第一个匹配上的 backend 就成功写入。
9
+ COMPATIBLE = "normal" # 所有节点均有一个或者多个匹配上的 backend,但是首先匹配到的 backend 写入出错,使用其后再次匹配到的其他 backend 能够成功写入
10
+ # (这种情况更多应归咎于 backend 的 writable() 方法无法拒绝所有错误输入或者 backend 本身没有按照预期工作。一般而言这对最终写入内容的正确不会有太大影响。)
11
+ # 这个等级是默认等级
12
+ IGNORE_FAILURE = "low" # 匹配不完整,或者某些节点尝试过所有匹配到的 backend 之后仍然无法写入
@@ -3,7 +3,6 @@ import time
3
3
  from kevin_toolbox.patches import for_os
4
4
  from kevin_toolbox.data_flow.file import json_
5
5
  import kevin_toolbox.nested_dict_list as ndl
6
- from kevin_toolbox.nested_dict_list.serializer.variable import SERIALIZER_BACKEND
7
6
 
8
7
 
9
8
  def read(input_path, **kwargs):
@@ -13,6 +12,8 @@ def read(input_path, **kwargs):
13
12
  参数:
14
13
  input_path: <path> 文件夹或者 .tar 文件,具体结构参考 write()
15
14
  """
15
+ from kevin_toolbox.nested_dict_list.serializer.variable import SERIALIZER_BACKEND
16
+
16
17
  assert os.path.exists(input_path)
17
18
 
18
19
  # 解压
@@ -1,5 +1,4 @@
1
1
  import os
2
- from enum import Enum
3
2
  from kevin_toolbox.computer_science.algorithm.registration import Registry
4
3
 
5
4
  SERIALIZER_BACKEND = Registry(uid="SERIALIZER_BACKEND")
@@ -7,14 +6,3 @@ SERIALIZER_BACKEND = Registry(uid="SERIALIZER_BACKEND")
7
6
  # 从 kevin_toolbox/nested_dict_list/serializer/backends 下收集被注册的 backend
8
7
  SERIALIZER_BACKEND.collect_from_paths(path_ls=[os.path.join(os.path.dirname(__file__), "backends"), ],
9
8
  b_execute_now=False)
10
-
11
-
12
- class Strictness_Level(Enum):
13
- """
14
- 对于正确性与完整性的要求的严格程度
15
- """
16
- COMPLETE = "high" # 所有节点均有一个或者多个匹配上的 backend,且第一个匹配上的 backend 就成功写入。
17
- COMPATIBLE = "normal" # 所有节点均有一个或者多个匹配上的 backend,但是首先匹配到的 backend 写入出错,使用其后再次匹配到的其他 backend 能够成功写入
18
- # (这种情况更多应归咎于 backend 的 writable() 方法无法拒绝所有错误输入或者 backend 本身没有按照预期工作。一般而言这对最终写入内容的正确不会有太大影响。)
19
- # 这个等级是默认等级
20
- IGNORE_FAILURE = "low" # 匹配不完整,或者某些节点尝试过所有匹配到的 backend 之后仍然无法写入
@@ -6,7 +6,7 @@ from kevin_toolbox.data_flow.file import json_
6
6
  from kevin_toolbox.patches import for_os
7
7
  import kevin_toolbox.nested_dict_list as ndl
8
8
  from kevin_toolbox.nested_dict_list.traverse import Traversal_Mode
9
- from kevin_toolbox.nested_dict_list.serializer.variable import SERIALIZER_BACKEND, Strictness_Level
9
+ from .enum_variable import Strictness_Level
10
10
 
11
11
 
12
12
  def write(var, output_dir, settings=None, traversal_mode=Traversal_Mode.BFS, b_pack_into_tar=True,
@@ -83,6 +83,7 @@ def write(var, output_dir, settings=None, traversal_mode=Traversal_Mode.BFS, b_p
83
83
  的 backend 之后仍然无法写入
84
84
  默认是 "normal"
85
85
  """
86
+ from kevin_toolbox.nested_dict_list.serializer.variable import SERIALIZER_BACKEND
86
87
 
87
88
  #
88
89
  traversal_mode = Traversal_Mode(traversal_mode)
@@ -52,11 +52,17 @@ def set_value(var, name, value, b_force=False):
52
52
  raise ValueError(f'The location pointed to by name {name} does not exist in var')
53
53
  else:
54
54
  if method_ls[-1] in "|:":
55
+ # 对于字符串默认使用 dict 构建
55
56
  value = {raw_key: value}
56
57
  else:
58
+ # 对于需要eval的情况
57
59
  key = eval(raw_key)
58
- assert isinstance(key, (int,)) and key >= 0
59
- value = [None] * key + [value]
60
+ if isinstance(key, (int,)) and key >= 0:
61
+ # 只有当 key 为非负整数时,才会使用 list 构建
62
+ value = [None] * key + [value]
63
+ else:
64
+ # 其他,比如当 key 为元组、浮点数等等时,则使用 dict 构建
65
+ value = {key: value}
60
66
  var = set_value(var=var, name=name[:-1 - len(node_ls[-1])], value=value, b_force=b_force)
61
67
 
62
68
  return var
@@ -2,14 +2,14 @@ import optuna
2
2
  import kevin_toolbox.nested_dict_list as ndl
3
3
 
4
4
 
5
- def sample_from_feasible_domain(var, trial: optuna.trial.BaseTrial, pre_name=""):
5
+ def sample_from_feasible_domain(var, trial: optuna.trial.BaseTrial, f_p_name_builder=None, b_use_name_as_idx=True):
6
6
  """
7
7
  使用试验 trial 基于输入中的定义域 feasible_domain 部分进行参数采样和替换。
8
8
  遍历输入中的所有元素,找出符合 <feasible_domain> 格式要求的记录了参数定义域的元素,
9
9
  然后使用输入的试验实例 trial 结合参数定义域采样出对应的参数,最后用采样出来的参数替换掉原来的定义域。
10
10
 
11
11
  参数:
12
- inputs: <list/dict> 当其中的元素满足 <feasible_domain> 格式要求,将进行采样与替换。
12
+ var: <list/dict> 当其中的元素满足 <feasible_domain> 格式要求,将进行采样与替换。
13
13
  <feasible_domain> 格式要求:
14
14
  1. 是一个 dictionary
15
15
  2. 包含 "p_type" 字段
@@ -20,15 +20,26 @@ def sample_from_feasible_domain(var, trial: optuna.trial.BaseTrial, pre_name="")
20
20
  更多参见 https://optuna.readthedocs.io/zh_CN/latest/reference/generated/optuna.trial.Trial.html#optuna.trial.Trial
21
21
  中的 suggest_xxx() 函数。
22
22
  trial: <optuna.trial.BaseTrial> 试验
23
- pre_name: <string> 采样出的参数在试验 trial 中注册的名称的前缀
23
+ f_p_name_builder: <callable> 对于采样出的参数,使用该函数构建其在试验 trial 中注册的名称。
24
+ 函数类型为 def(idx, p_type): ...
25
+ 其中:
26
+ idx 被采样的节点在 var 中的位置
27
+ 当 b_use_name_as_idx=False 时,
28
+ 对于列表是 index,对于字典是 key
29
+ 当为 True 时,传入的是元素在整体结构中的 name 位置,name的格式和含义参考
30
+ name_handler.parse_name() 中的介绍
31
+ p_type 被采样的节点中的 "p_type" 字段
32
+ 默认为:
33
+ lambda idx, p_type: idx
34
+ b_use_name_as_idx: <boolean> 决定传入 f_p_name_builder 中的参数 idx 的形式。
24
35
 
25
36
  返回:
26
- var, name_ls
37
+ var, node_vs_paras_s
27
38
  var 是采样后的结果
28
- name_ls 是被采样的节点名称,注意并不带 pre_name 前缀
39
+ node_vs_paras_s 是一个<dict>,以被采样的节点在 var 中位置的名称作为键,以对应节点在 trial 中注册的参数名为值。
29
40
 
30
41
  实例:
31
- 对于输入 inputs={
42
+ 对于输入 var={
32
43
  "thr":[
33
44
  "interval_thr": {
34
45
  "p_type": "categorical",
@@ -56,19 +67,33 @@ def sample_from_feasible_domain(var, trial: optuna.trial.BaseTrial, pre_name="")
56
67
  ]
57
68
  }
58
69
  可能返回的采样结果是 res={"thr":[{"interval_thr":1000}, {"iou_thr":0.6}, {"connection":lambda x:x} ], }。
59
- pre_name="my" 时,这些参数在 trial 中注册的名称分别是 "my:thr@0:interval_thr","my:thr@1:iou_thr" 和 "my:thr@1:connection"。
70
+ f_p_name_builder=lambda idx, p_type: f'my{idx}' 时,
71
+ 这些参数在 trial 中注册的名称分别是 "my:thr@0:interval_thr","my:thr@1:iou_thr" 和 "my:thr@1:connection"。
60
72
  特别地,
61
73
  - 对于字典形式的 choices,其中保存在 trial 中的取值是其键 key 而非 value。
62
74
  - 对于list形式,但含有非支持类型的 choices,其中保存在 trial 中的取值是元素的 index。
63
75
  这些名称的含义详见 get_value()。
64
76
  """
77
+ if f_p_name_builder is None:
78
+ f_p_name_builder = lambda idx, p_type: idx
79
+ if not b_use_name_as_idx:
80
+ p_name_builder = lambda idx, p_type: f_p_name_builder(ndl.name_handler.parse_name(idx)[-1][-1], p_type)
81
+ else:
82
+ p_name_builder = f_p_name_builder
65
83
 
66
- name_ls=[]
84
+ node_vs_paras_s = dict()
85
+ p_name_set = set()
67
86
 
68
87
  def func(idx, v):
69
- nonlocal name_ls
88
+ nonlocal node_vs_paras_s, p_name_builder
89
+
70
90
  p_type = v.pop("p_type")
91
+ p_name = v.pop("p_name") if "p_name" in v else f'{p_name_builder(idx, p_type)}'
92
+ assert p_name not in p_name_set, \
93
+ f"p_name={p_name} is duplicated!"
94
+ p_name_set.add(p_name)
71
95
  kwargs = v
96
+ #
72
97
  choice_values = None
73
98
  if p_type == "categorical":
74
99
  # optuna 目前的类别元素仅支持 None, bool, int, float 和 str 类型
@@ -83,14 +108,15 @@ def sample_from_feasible_domain(var, trial: optuna.trial.BaseTrial, pre_name="")
83
108
  choice_values = kwargs["choices"]
84
109
  kwargs["choices"] = list(kwargs["choices"].keys())
85
110
 
86
- v = eval(f'trial.suggest_{p_type}(name=name, **kwargs)',
87
- {"trial": trial, "name": f'{pre_name}{idx}', "kwargs": kwargs})
111
+ v = eval(f'trial.suggest_{p_type}(name=name, **kwargs)', {"trial": trial, "name": p_name, "kwargs": kwargs})
88
112
  if choice_values is not None:
89
113
  v = choice_values[v]
90
- name_ls.append(idx)
114
+
115
+ #
116
+ node_vs_paras_s[idx] = p_name
91
117
  return v
92
118
 
93
119
  var = ndl.traverse(var=var, match_cond=lambda _, __, v: isinstance(v, (dict,)) and "p_type" in v,
94
120
  action_mode="replace", converter=func, b_use_name_as_idx=True)
95
121
 
96
- return var, name_ls
122
+ return var, node_vs_paras_s
@@ -1,3 +1,4 @@
1
1
  from .remove import remove
2
2
  from .pack import pack
3
3
  from .unpack import unpack
4
+ from .walk import walk, Path_Ignorer, Ignore_Scope
@@ -4,13 +4,15 @@ import shutil
4
4
 
5
5
  def remove(path, ignore_errors=False):
6
6
  """
7
- 移除文件/文件夹
7
+ 移除文件/文件夹/软连接
8
8
 
9
9
  返回:
10
10
  boolean 是否成功
11
11
  """
12
12
  try:
13
- if os.path.isfile(path): # 移除文件
13
+ if os.path.islink(path): # 移除软连接
14
+ os.unlink(path)
15
+ elif os.path.isfile(path): # 移除文件
14
16
  os.remove(path)
15
17
  elif os.path.isdir(path): # 移除文件夹
16
18
  shutil.rmtree(path=path, ignore_errors=False)
@@ -0,0 +1,167 @@
1
+ import os
2
+ from collections import defaultdict
3
+ from enum import Enum
4
+
5
+
6
+ class Ignore_Scope(Enum):
7
+ ROOT = "root"
8
+ DIRS = "dirs"
9
+ FILES = "files"
10
+
11
+
12
+ class Path_Ignorer:
13
+ def __init__(self, ignore_s=None):
14
+ self.ignore_s = defaultdict(list)
15
+ try:
16
+ if isinstance(ignore_s, (list, tuple)):
17
+ for it in ignore_s:
18
+ for scope in it["scope"]:
19
+ scope = Ignore_Scope(scope)
20
+ self.ignore_s[scope].append(it["func"])
21
+ elif isinstance(ignore_s, (dict,)):
22
+ for k, v in ignore_s.items():
23
+ self.ignore_s[Ignore_Scope(k)].extend(v)
24
+ except:
25
+ raise ValueError(f'invalid ignore_s, got a {ignore_s}')
26
+
27
+ def __call__(self, scope, *args, **kwargs):
28
+ for func in self.ignore_s[scope]:
29
+ if func(*args, **kwargs):
30
+ return True
31
+ return False
32
+
33
+ def __len__(self):
34
+ return len(self.ignore_s)
35
+
36
+
37
+ def walk(top, topdown=True, onerror=None, followlinks=False, ignore_s=None):
38
+ """
39
+ 在 os.walk() 的基础上增加了以下功能
40
+ - 可以通过 ignore_s 参数来排除特定的目录和文件
41
+
42
+ 参数:
43
+ (对于参数 top,topdown,onerror,followlinks,其用法与 os.walk() 完全相同)
44
+ top: <path> 要遍历的目录
45
+ topdown: <boolean> 是否从浅到深遍历
46
+ 默认为 True,优先遍历完浅层目录
47
+ onerror: <callable> 当遇到异常时,会调用该函数
48
+ followlinks: <boolean> 是否遍历软链接目录
49
+ 默认为 False,不对软链接进行进一步遍历
50
+ ignore_s: <list/tuple of dict or dict> 排除规则
51
+ 有两种输入方式:
52
+
53
+ 方式 1 <list/tuple of dict>:
54
+ 列表中每个字典需要具有以下键值对:
55
+ "scope": <list/tuple of str> 该规则的作用范围
56
+ 可选值,及(满足规则时)对应效果:
57
+ "root": 不遍历满足规则的目录
58
+ "dirs": 将返回的三元组中第二个 dirs 部分中满足规则的部分移除
59
+ "files": 将返回的三元组中第三个 files 部分中满足规则的部分移除
60
+ "func": <callable> 排除规则
61
+ 当调用该函数的返回值为 True 时,执行排除。
62
+ 函数类型为 def(b_is_dir, b_is_symlink, path): ...
63
+ 其中:
64
+ b_is_dir 是否是目录
65
+ b_is_symlink 是否是软链接
66
+ path 输入是对于作用范围 "root",输入的直接就是 root,
67
+ 对于作用范围 "dirs",输入是 dirs 中的每个元素和 root 组成的绝对路径,
68
+ 对于作用范围 "files",输入是 files 中的每个元素和 root 组成的绝对路径。
69
+ 注意:
70
+ - 当有多个规则时,只要满足其一即会进行排除。
71
+ - 任何规则都不会对 top 目录进行过滤,亦即对 top 的遍历是必然的。不能通过设定某个 top 满足的规则来停止对 top 的遍历。
72
+ 比如,通过下面的规则就可以实现不对 basename 为 "test" 和 "temp" 的目录进行遍历和输出,
73
+ 同时只保留非软连接的 .png 和 .jpg 文件:
74
+ [
75
+ {
76
+ "func": lambda _, __, path: os.path.basename(path) in ["temp", "test"],
77
+ "scope": ["root", "dirs"]
78
+ },
79
+ {
80
+ "func": lambda _, b_is_symlink, path: b_is_symlink or not path.endswith((".png",".jpg")),
81
+ "scope": ["files", ]
82
+ }
83
+ ]
84
+
85
+ 方式 2 <dict>:
86
+ 一个以 scope 为键,func 为值的字典。
87
+ 延续上面的例子,其另一种等效形式为:
88
+ {
89
+ "root": [
90
+ lambda _, __, path: os.path.basename(path) in ["temp", "test"],
91
+ ],
92
+ "dirs": [
93
+ lambda _, __, path: os.path.basename(path) in ["temp", "test"],
94
+ ],
95
+ "files": [
96
+ lambda _, b_is_symlink, path: b_is_symlink or not path.endswith((".png",".jpg")),
97
+ ]
98
+ }
99
+
100
+ 方式 3 <Path_Ignorer>:
101
+ 根据 ignore_s 构建的 Path_Ignorer
102
+
103
+ """
104
+ # 根据 ignore_s 构建 Path_Ignorer
105
+ path_ignorer = ignore_s if isinstance(ignore_s, (Path_Ignorer,)) else Path_Ignorer(ignore_s=ignore_s)
106
+
107
+ #
108
+ yield from __walk(top, topdown, onerror, followlinks, path_ignorer)
109
+
110
+
111
+ def __walk(top, topdown, onerror, followlinks, path_ignorer):
112
+ #
113
+ top = os.fspath(top)
114
+ dirs, files = [], []
115
+ walk_dirs = []
116
+
117
+ try:
118
+ scandir_it = os.scandir(top)
119
+ except OSError as error:
120
+ if onerror is not None:
121
+ onerror(error)
122
+ return
123
+
124
+ with scandir_it:
125
+ while True:
126
+ try:
127
+ try:
128
+ entry = next(scandir_it)
129
+ except StopIteration:
130
+ break
131
+ except OSError as error:
132
+ if onerror is not None:
133
+ onerror(error)
134
+ return
135
+
136
+ try:
137
+ is_dir = entry.is_dir()
138
+ except OSError:
139
+ is_dir = False
140
+
141
+ if is_dir:
142
+ dirs.append(entry.name)
143
+ walk_dirs.append(os.path.join(top, entry.name))
144
+ else:
145
+ files.append(entry.name)
146
+
147
+ # 过滤
148
+ if len(path_ignorer) > 0:
149
+ for it_ls, scope in zip([walk_dirs, dirs, files], [Ignore_Scope.ROOT, Ignore_Scope.DIRS, Ignore_Scope.FILES]):
150
+ for i in reversed(range(len(it_ls))):
151
+ path = os.path.join(top, it_ls[i]) if scope != Ignore_Scope.ROOT else it_ls[i]
152
+ if path_ignorer(scope, scope != Ignore_Scope.FILES, os.path.islink(path), path):
153
+ it_ls.pop(i)
154
+
155
+ #
156
+ if topdown:
157
+ yield top, dirs, files
158
+ #
159
+ for new_path in walk_dirs:
160
+ if followlinks or not os.path.islink(new_path):
161
+ yield from __walk(new_path, topdown, onerror, followlinks, path_ignorer)
162
+ else:
163
+ for new_path in walk_dirs:
164
+ if followlinks or not os.path.islink(new_path):
165
+ yield from __walk(new_path, topdown, onerror, followlinks, path_ignorer)
166
+ #
167
+ yield top, dirs, files
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.1
2
+ Name: kevin-toolbox-dev
3
+ Version: 1.3.0
4
+ Summary: 一个常用的工具代码包集合
5
+ Home-page: https://github.com/cantbeblank96/kevin_toolbox
6
+ Download-URL: https://github.com/username/your-package/archive/refs/tags/v1.0.0.tar.gz
7
+ Author: kevin hsu
8
+ Author-email: xukaiming1996@163.com
9
+ License: MIT
10
+ Keywords: mathematics,pytorch,numpy,machine-learning,algorithm
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: >=3.6
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: torch (>=1.2.0)
17
+ Requires-Dist: numpy (>=1.19.0)
18
+ Provides-Extra: plot
19
+ Requires-Dist: matplotlib (>=3.0) ; extra == 'plot'
20
+ Provides-Extra: rest
21
+ Requires-Dist: pytest (>=6.2.5) ; extra == 'rest'
22
+ Requires-Dist: line-profiler (>=3.5) ; extra == 'rest'
23
+
24
+ # kevin_toolbox
25
+
26
+ 一个通用的工具代码包集合
27
+
28
+
29
+
30
+ 环境要求
31
+
32
+ ```shell
33
+ numpy>=1.19
34
+ pytorch>=1.2
35
+ ```
36
+
37
+ 安装方法:
38
+
39
+ ```shell
40
+ pip install kevin-toolbox --no-dependencies
41
+ ```
42
+
43
+
44
+
45
+ [项目地址 Repo](https://github.com/cantbeblank96/kevin_toolbox)
46
+
47
+ [使用指南 User_Guide](./notes/User_Guide.md)
48
+
49
+ [免责声明 Disclaimer](./notes/Disclaimer.md)
50
+
51
+ [版本更新记录](./notes/Release_Record.md):
52
+
53
+ - v 1.3.0 (2023-12-13)【bug fix】【new feature】【incompatible change】
54
+ - nested_dict_list
55
+ - serializer
56
+ - 【bug fix】fix bug in read() and write(),解除这两个函数中出现的 nested_dict_list 和 kevin_toolbox.computer_science.algorithm.registration.Registry 模块之间的交叉引用。
57
+ - 【bug fix】fix bug in set_value(),对于使用method=@,但是node不为正整数的name进行强制写入的情况,未修复前表现为错误地尝试使用list进行构建并报错,现修复为使用 dict 进行构建。在新的策略下,对于强制写入,只有 method=@ 且 node 为非负正整数的情况下才会使用 list 进行构建,其他一律用 dict。
58
+ - 添加了对应的测试用例。
59
+ - patches.for_os
60
+ - 【new feature】add walk(),该方法在 os.walk() 的基础上增加了 ignore_s 参数,用于设定规则排除特定的目录和文件。相较于先使用 os.walk() 递归遍历这个目录,再对内容进行逐个过滤筛选的这种方式,本方法在遍历过程中就可以使用规则进行过滤并决定是否要继续深入遍历,更加高效。
61
+ - 补充了对应的测试用例。
62
+ - 【new feature】add Path_Ignorer,该类用于解释 ignore_s 参数,并进行基于规则的判断。
63
+ - 【new feature】modify remove(),支持对软连接的删除。
64
+ - computer_science.algorithm.registration
65
+ - 【new feature】【incompatible change】modify Registry.collect_from_paths(),将原有的通过目录前缀匹配来排除目录的 path_ls_to_exclude 参数,替换成通过规则匹配待排除目录的 ignore_s 参数,更加自由灵活。ignore_s 参数的设定方式与 for_os.walk() 中的 ignore_s 参数相同。
66
+ - 添加了对应的测试用例。
67
+ - patches.for_optuna
68
+ - 【new feature】【incompatible change】modify sample_from_feasible_domain(),进行了以下改变:
69
+ - 允许在 <feasible_domain> 中通过 "p_name" 字段来强制指定该参数在 trial 中的注册名称。
70
+ - 支持通过 f_p_name_builder 和 b_use_name_as_idx 决定如何从 <feasible_domain> 的位置生成参数的注册名称。
71
+ - 删去了 pre_name 参数,如果要实现原 pre_name 的效果,可以等效使用:
72
+ - `f_p_name_builder =lambda idx, p_type: f'{pre_name}{idx}'`
73
+ - 原来返回 var, node_name_ls 改为返回 var, node_vs_paras_s,其中 node_vs_paras_s 是一个`<dict>`,以被采样的节点在 var 中位置的名称作为键,以对应节点在 trial 中注册的参数名为值。
@@ -1,4 +1,4 @@
1
- kevin_toolbox/__init__.py,sha256=M-w-yHT9mHLIjAywLvjob-ZQ6UEVlrQwqccucr30ews,410
1
+ kevin_toolbox/__init__.py,sha256=W_CLt--CjnjEw_hvNoQ6sNjhKqIx6otWbRWTAdprkh0,410
2
2
  kevin_toolbox/computer_science/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  kevin_toolbox/computer_science/algorithm/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
4
4
  kevin_toolbox/computer_science/algorithm/combinatorial_optimization/__init__.py,sha256=fBMX0_WiV8kfHLWZNfVe2uL67gsN_oHfpbuHaHUOiys,142
@@ -25,7 +25,7 @@ kevin_toolbox/computer_science/algorithm/parallel_and_concurrent/multi_thread_ex
25
25
  kevin_toolbox/computer_science/algorithm/pareto_front/__init__.py,sha256=LbeaSzG0hkx8NHAlzvEalrGi2WufaXguVfeBRzaw-MA,57
26
26
  kevin_toolbox/computer_science/algorithm/pareto_front/get_pareto_points_idx.py,sha256=a-8Js-dpkuVu9MsImW9hwHp9OTC278xo9oJP96oX0Io,2712
27
27
  kevin_toolbox/computer_science/algorithm/registration/__init__.py,sha256=teEd9HkrB6baLpwNwae5c4wn0QRwV3KtBv-2V9-Z7cc,49
28
- kevin_toolbox/computer_science/algorithm/registration/registry.py,sha256=_4s3u3hpg0jPmOv9UldzHe2Oa_XGQErjl9xTEwSCTwk,13842
28
+ kevin_toolbox/computer_science/algorithm/registration/registry.py,sha256=rAs7kG_f6P9AL264TuUin_8-jgYnQNo7EB8axgtCxkk,15383
29
29
  kevin_toolbox/computer_science/algorithm/scheduler/__init__.py,sha256=ENzZsNaMu6ISilTxeE3_EP_L0dNi8SI7IYdTdxic2nw,76
30
30
  kevin_toolbox/computer_science/algorithm/scheduler/strategy_manager.py,sha256=yLh2GBEsedJhqvB90zEmAOdZ8IF7nn1r9lSE95BbnEQ,12194
31
31
  kevin_toolbox/computer_science/algorithm/scheduler/trigger.py,sha256=YlqTX2TE44BwcQI0jfvcBCJhouhdAYuhwu2QJhuBWP0,4470
@@ -202,16 +202,17 @@ kevin_toolbox/nested_dict_list/count_leaf_node_nums.py,sha256=l67u47EvO1inoGinUq
202
202
  kevin_toolbox/nested_dict_list/get_hash.py,sha256=Ygadnn5dnvIeE-9t39p2EwNKNRLzomL37ZsRD5daXxo,1286
203
203
  kevin_toolbox/nested_dict_list/get_nodes.py,sha256=MrWc08K_-hdaoaFRrUP_y2to3afUclf39BCfKnRCOGs,3457
204
204
  kevin_toolbox/nested_dict_list/get_value.py,sha256=isvUhqSQyUNHBXgNuZX6_o2c84UV_SpjNjAYm2M3gd4,2083
205
- kevin_toolbox/nested_dict_list/set_value.py,sha256=PaNQNsfz0_2evJmKHdF4saqIUPOYScAfC8wQJKwe3w4,3122
205
+ kevin_toolbox/nested_dict_list/set_value.py,sha256=pmSWzC0y0jBxk7yritsjKU2Q-PPMar0X3A9bF6uWvoQ,3470
206
206
  kevin_toolbox/nested_dict_list/traverse.py,sha256=5_EirnYVy34JLfXxuTvb-mMjDeO1veyfLOcaVYcuGF8,6846
207
207
  kevin_toolbox/nested_dict_list/name_handler/__init__.py,sha256=P_pWq78oN6NdvWg2h6AduW_sUqbeaaVyoWWbW9kbgmU,107
208
208
  kevin_toolbox/nested_dict_list/name_handler/build_name.py,sha256=Hj8Bz-90DBezfQgbzThR1-C206dqY13KmEguFECQWMY,1020
209
209
  kevin_toolbox/nested_dict_list/name_handler/escape_node.py,sha256=niT9MxmsyrSZYhKXlWzdoKXVYhWRCR-kmQBkZopznpA,1163
210
210
  kevin_toolbox/nested_dict_list/name_handler/parse_name.py,sha256=QpF8y7OuI4G6pS6sH_EXAV2TzJXYRu45bcIGJpVjiZc,2311
211
- kevin_toolbox/nested_dict_list/serializer/__init__.py,sha256=Fn38vJkHXdcvMc83VzCZBqVIyjFblmR7T5d49o7RvC0,48
212
- kevin_toolbox/nested_dict_list/serializer/read.py,sha256=2tT0yn3qq_cXxC5380el-RpY3ONM4QhZ0RrcHcmfcLk,2572
213
- kevin_toolbox/nested_dict_list/serializer/variable.py,sha256=K4xGehjnRoLbb5321-QXQkSH5UnPo9dExrVtPmt6xE4,1239
214
- kevin_toolbox/nested_dict_list/serializer/write.py,sha256=KdMq3QocIoGEKSQcG09GxPuieU4pvRGv0TeQk21mGtw,18115
211
+ kevin_toolbox/nested_dict_list/serializer/__init__.py,sha256=xLDfzSZIDNBssHArUEK84gF6WZFR64qJy0iOpM8LbP8,92
212
+ kevin_toolbox/nested_dict_list/serializer/enum_variable.py,sha256=RWPydtXI4adOJYGo_k5CWHSL0Odzj_bsahb24p1ranY,847
213
+ kevin_toolbox/nested_dict_list/serializer/read.py,sha256=8196AZW3y1eZNguw5fDi5gQmOtpJ0MdqhRNHZ5EWYHI,2577
214
+ kevin_toolbox/nested_dict_list/serializer/variable.py,sha256=ZywG6obipRBCGY1cY42gdvsuWk8GLZXr6eCYcW7ZJ9c,392
215
+ kevin_toolbox/nested_dict_list/serializer/write.py,sha256=sQtryi7NbVWynOMWpKKkqxoTf9dxSGE4yC4ReIAxT8U,18145
215
216
  kevin_toolbox/nested_dict_list/serializer/backends/__init__.py,sha256=8g7y-L3cmctxao616dVkGiot00FJzKNmNl_69V2bSmE,39
216
217
  kevin_toolbox/nested_dict_list/serializer/backends/_json_.py,sha256=oJXIc28yjxsD9ZJuw120pVHTVsTzCdaXEhVUSQeydq4,2145
217
218
  kevin_toolbox/nested_dict_list/serializer/backends/_ndl.py,sha256=QMF4DFAnt1sp35atds6t44nfCYuIOeGgW1-SPfJq6KM,1652
@@ -239,11 +240,12 @@ kevin_toolbox/patches/for_numpy/linalg/cos_similar.py,sha256=bFkfDwrW3maXq5i9ZAB
239
240
  kevin_toolbox/patches/for_numpy/linalg/normalize.py,sha256=7qstt__rwUkk3jRJOQoneBp9YdfhYQtWfh6PZoWbvaA,625
240
241
  kevin_toolbox/patches/for_numpy/linalg/softmax.py,sha256=5ukhay9SvQoOch6czEXuJXqXg47Q1fokrv_zZTDHRjI,2035
241
242
  kevin_toolbox/patches/for_optuna/__init__.py,sha256=w7FuRlbX4rqVlpwOSAGQ2Y3ZhCglW81n2_4usHzIyJU,69
242
- kevin_toolbox/patches/for_optuna/sample_from_feasible_domain.py,sha256=zZcM7v1kAgEQGtN8oXVe0V2GiyGPUV16SujczF7ruxM,5325
243
- kevin_toolbox/patches/for_os/__init__.py,sha256=Gt9psQWmC5zt8DazalHnWk9IAy9CFdCRn9FV0m2dgu4,77
243
+ kevin_toolbox/patches/for_optuna/sample_from_feasible_domain.py,sha256=-Ckwo2N4vhWr08F7ROLfwLWIx4ERwdwn4Q5Ft2JRm7g,7071
244
+ kevin_toolbox/patches/for_os/__init__.py,sha256=Q6GzEPWggV4EovJdrertlL2l__W7k0zUEpuQIQDcA7A,128
244
245
  kevin_toolbox/patches/for_os/pack.py,sha256=A6u4g3dfwXPtlU4gBcThNrktz6dO4DVi2wmQXytqfDI,656
245
- kevin_toolbox/patches/for_os/remove.py,sha256=ji71D3BQA8g-xZr7IMRD9ANXfdsszS9QXDopAfVHfnw,658
246
+ kevin_toolbox/patches/for_os/remove.py,sha256=PmwqzVJbyfdqwXn_T1F9d4Oar8CwQ2YFaqcZQkfnrnI,750
246
247
  kevin_toolbox/patches/for_os/unpack.py,sha256=d_fO7nPmExy1VIg7ADIMayCzjBBeFxvJLhIsulIRlzI,1047
248
+ kevin_toolbox/patches/for_os/walk.py,sha256=LrtEeRUDwzZgu_zGZ-kPsFJd4D-8R8ECHW6WNdEsDSw,8376
247
249
  kevin_toolbox/patches/for_test/__init__.py,sha256=sFr2VZD1zk8Vtjq2_F8uE4xNovJF6yDY8j1YND5XAw0,49
248
250
  kevin_toolbox/patches/for_test/check_consistency.py,sha256=5zwjHc0M3A-RTYcgZpIugm6-L-m2pDSG496dCkg8Q4Q,5038
249
251
  kevin_toolbox/patches/for_torch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -261,7 +263,7 @@ kevin_toolbox/patches/for_torch/math/get_y_at_x.py,sha256=bfoVcasZ_tMdhR_1Me0Jli
261
263
  kevin_toolbox/patches/for_torch/math/my_around.py,sha256=ptpU3ids50gwf663EpHbw7raj9tNrDGBFZ5t_uMNH14,1378
262
264
  kevin_toolbox/patches/for_torch/nn/__init__.py,sha256=aJs3RMqRzQmd8KKDmQW9FxwCqS5yfPqEdg-m0PwlQro,39
263
265
  kevin_toolbox/patches/for_torch/nn/lambda_layer.py,sha256=KUuLiX_Dr4bvRmpAaCW5QTDWDcnMPRnw0jg4NNXTFhM,223
264
- kevin_toolbox_dev-1.2.8.dist-info/METADATA,sha256=KVN0HrBDUFlCBIxWi1MWDwkakK34V9vHz5iXM8JEO2Q,3469
265
- kevin_toolbox_dev-1.2.8.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
266
- kevin_toolbox_dev-1.2.8.dist-info/top_level.txt,sha256=S5TeRGF-PwlhsaUEPTI-f2vWrpLmh3axpyI6v-Fi75o,14
267
- kevin_toolbox_dev-1.2.8.dist-info/RECORD,,
266
+ kevin_toolbox_dev-1.3.0.dist-info/METADATA,sha256=Lv7LGBtCfRboHibUCT2EhwceSzrBneAbK7vwo5IJFss,3843
267
+ kevin_toolbox_dev-1.3.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
268
+ kevin_toolbox_dev-1.3.0.dist-info/top_level.txt,sha256=S5TeRGF-PwlhsaUEPTI-f2vWrpLmh3axpyI6v-Fi75o,14
269
+ kevin_toolbox_dev-1.3.0.dist-info/RECORD,,
@@ -1,80 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: kevin-toolbox-dev
3
- Version: 1.2.8
4
- Summary: 一个常用的工具代码包集合
5
- Home-page: https://github.com/cantbeblank96/kevin_toolbox
6
- Download-URL: https://github.com/username/your-package/archive/refs/tags/v1.0.0.tar.gz
7
- Author: kevin hsu
8
- Author-email: xukaiming1996@163.com
9
- License: MIT
10
- Keywords: mathematics,pytorch,numpy,machine-learning,algorithm
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Programming Language :: Python
13
- Classifier: Programming Language :: Python :: 3
14
- Requires-Python: >=3.6
15
- Description-Content-Type: text/markdown
16
- Requires-Dist: torch (>=1.2.0)
17
- Requires-Dist: numpy (>=1.19.0)
18
- Provides-Extra: plot
19
- Requires-Dist: matplotlib (>=3.0) ; extra == 'plot'
20
- Provides-Extra: rest
21
- Requires-Dist: pytest (>=6.2.5) ; extra == 'rest'
22
- Requires-Dist: line-profiler (>=3.5) ; extra == 'rest'
23
-
24
- # kevin_toolbox
25
-
26
- 一个通用的工具代码包集合
27
-
28
-
29
-
30
- 环境要求
31
-
32
- ```shell
33
- numpy>=1.19
34
- pytorch>=1.2
35
- ```
36
-
37
- 安装方法:
38
-
39
- ```shell
40
- pip install kevin-toolbox --no-dependencies
41
- ```
42
-
43
-
44
-
45
- [项目地址 Repo](https://github.com/cantbeblank96/kevin_toolbox)
46
-
47
- [使用指南 User_Guide](./notes/User_Guide.md)
48
-
49
- [免责声明 Disclaimer](./notes/Disclaimer.md)
50
-
51
- [版本更新记录](./notes/Release_Record.md):
52
-
53
- - v 1.2.8 (2023-11-13)【new feature】
54
- - data_flow.file.markdown
55
- - 【new feature】modify generate_table()
56
- - 支持两种输入模式(新增了第二种模式)
57
- 1. 简易模式:
58
- ` content_s = {<title>: <list of value>, ...}`
59
- 此时键作为标题,值作为标题下的一系列值。
60
- 由于字典的无序性,此时标题的顺序是不能保证的,若要额外指定顺序,请使用下面的 完整模式。
61
- 2. 完整模式:
62
- `content_s = {<index>: {"title": <title>,"values":<list of value>}, ...}`
63
- 此时将取第 `<index>` 个 "title" 的值来作为第 `<index>` 个标题的值。values 同理。
64
- 该模式允许缺省某些 `<index>`,此时这些 `<index>` 对应的行/列将全部置空。
65
- - 部分兼容旧版的输入(对应于上面的简易模式),但是不再支持通过 ordered_keys 来指定简易模式下的标题顺序。若要实现类似功能,请直接使用 collections.OrderedDict 作为输入。
66
- - 支持通过 chunk_nums 和 chunk_size 参数实现表格的分割并列显示。
67
- - 支持通过 b_allow_misaligned_values 参数来允许不对齐的 values。
68
- - 支持通过 f_gen_order_of_values 来指定 values 的排序顺序。
69
- - 添加了对应的测试用例。
70
- - patches.for_numpy.linalg
71
- - 【new feature】modify softmax()
72
- - 新增了 temperature 参数,该参数起到对输入中的相对小/大值的抑制/增强作用。
73
- - 新增了 b_use_log_over_x 参数,用于简化 softmax(log(x)) 计算。
74
- - 添加了对应的测试用例。
75
- - nested_dict_list
76
- - 改造模块加载方式,不再支持通过x.y间接加载子模块,比如 nested_dict_list.serializer 等(相当于回退到1.2.6)
77
- - computer_science.algorithm.statistician
78
- - 进行重构,从 Average_Accumulator 和 Exponential_Moving_Average 中抽象出基类 Accumulator_Base。
79
- - 【new feature】在 Accumulator_Base 中增加了 load_state_dict() 和 state_dict() 接口用于加载和获取实例状态。
80
- - 增加了对应的测试用例。