danielutils 0.9.67__tar.gz → 0.9.69__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.
Files changed (119) hide show
  1. {danielutils-0.9.67 → danielutils-0.9.69}/PKG-INFO +2 -2
  2. {danielutils-0.9.67 → danielutils-0.9.69}/README.md +1 -1
  3. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/__init__.py +2 -1
  4. danielutils-0.9.69/danielutils/data_structures/Comparer.py +40 -0
  5. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/data_structures/Stack.py +10 -8
  6. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/data_structures/__init__.py +0 -1
  7. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/__init__.py +1 -0
  8. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils.egg-info/PKG-INFO +2 -2
  9. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils.egg-info/SOURCES.txt +0 -9
  10. {danielutils-0.9.67 → danielutils-0.9.69}/pyproject.toml +7 -9
  11. {danielutils-0.9.67 → danielutils-0.9.69}/setup.py +2 -1
  12. danielutils-0.9.67/danielutils/data_structures/Comparer.py +0 -37
  13. danielutils-0.9.67/danielutils/data_structures/Graph.py +0 -134
  14. danielutils-0.9.67/danielutils/data_structures/Heap.py +0 -111
  15. danielutils-0.9.67/danielutils/data_structures/Node.py +0 -106
  16. danielutils-0.9.67/danielutils/data_structures/Queue.py +0 -176
  17. {danielutils-0.9.67 → danielutils-0.9.69}/LISENCE +0 -0
  18. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/aliases.py +0 -0
  19. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/Convenience.py +0 -0
  20. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/Counter.py +0 -0
  21. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/Tree.py +0 -0
  22. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/__init__.py +0 -0
  23. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/frange.py +0 -0
  24. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/repl.py +0 -0
  25. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/sorted_builtins/__init__.py +0 -0
  26. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/sorted_builtins/sset.py +0 -0
  27. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/typed_builtins/__init__.py +0 -0
  28. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/typed_builtins/factory.py +0 -0
  29. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/typed_builtins/tdict.py +0 -0
  30. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/typed_builtins/tlist.py +0 -0
  31. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/typed_builtins/tset.py +0 -0
  32. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/classes/typed_builtins/ttuple.py +0 -0
  33. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/colors.py +0 -0
  34. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/conversions/__init__.py +0 -0
  35. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/conversions/main_conversions.py +0 -0
  36. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/conversions/specialized_conversions/__init__.py +0 -0
  37. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/conversions/specialized_conversions/to_hex.py +0 -0
  38. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/conversions/specialized_conversions/to_int.py +0 -0
  39. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/data_structures/default_dict.py +0 -0
  40. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/data_structures/functions.py +0 -0
  41. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/date.py +0 -0
  42. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/date_time.py +0 -0
  43. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/atomic.py +0 -0
  44. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/attach.py +0 -0
  45. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/chain_decorators.py +0 -0
  46. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/decorate_conditionally.py +0 -0
  47. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/delay_call.py +0 -0
  48. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/deprecate.py +0 -0
  49. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/limit_recursion.py +0 -0
  50. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/memo.py +0 -0
  51. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/overload.py +0 -0
  52. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/partially_implemented.py +0 -0
  53. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/processify.py +0 -0
  54. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/property.py +0 -0
  55. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/threadify.py +0 -0
  56. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/timeout.py +0 -0
  57. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/decorators/validate.py +0 -0
  58. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/exceptions.py +0 -0
  59. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/files_and_folders.py +0 -0
  60. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/functions/__init__.py +0 -0
  61. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/functions/areoneof.py +0 -0
  62. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/functions/check_foreach.py +0 -0
  63. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/functions/isoftype.py +0 -0
  64. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/functions/isoneof.py +0 -0
  65. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/functions/powerset.py +0 -0
  66. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/functions/types_subseteq.py +0 -0
  67. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/generators/__init__.py +0 -0
  68. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/generators/conditional_generator.py +0 -0
  69. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/generators/generator_from_stream.py +0 -0
  70. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/generators/join_generators.py +0 -0
  71. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/internet.py +0 -0
  72. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/io.py +0 -0
  73. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/loops.py +0 -0
  74. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/math/__init__.py +0 -0
  75. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/math/constants.py +0 -0
  76. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/math/functions.py +0 -0
  77. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/math/math_print.py +0 -0
  78. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/math/math_symbols.py +0 -0
  79. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/metaclasses/Interface.py +0 -0
  80. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/metaclasses/__init__.py +0 -0
  81. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/metaclasses/atomic_class_meta.py +0 -0
  82. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/metaclasses/implicit_data_deleter_meta.py +0 -0
  83. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/metaclasses/instance_cache_meta.py +0 -0
  84. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/metaclasses/overload_meta.py +0 -0
  85. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/multi_x.py +0 -0
  86. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/my_tqdm.py +0 -0
  87. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/path.py +0 -0
  88. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/print.py +0 -0
  89. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/reflection/__init__.py +0 -0
  90. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/reflection/class_reflection.py +0 -0
  91. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/reflection/file_reflection.py +0 -0
  92. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/reflection/function_reflections.py +0 -0
  93. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/reflection/get_prev_frame.py +0 -0
  94. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/reflection/get_traceback.py +0 -0
  95. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/reflection/module_reflections.py +0 -0
  96. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/reflection/system_reflections.py +0 -0
  97. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/relations.py +0 -0
  98. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/signals.py +0 -0
  99. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/snippets/__init__.py +0 -0
  100. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/snippets/try_get.py +0 -0
  101. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/system/__init__.py +0 -0
  102. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/system/independent.py +0 -0
  103. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/system/windows/__init__.py +0 -0
  104. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/system/windows/utils/__init__.py +0 -0
  105. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/system/windows/utils/filetime.py +0 -0
  106. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/system/windows/win32_ctime.py +0 -0
  107. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/system/windows/windows.py +0 -0
  108. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/text.py +0 -0
  109. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/threads/__init__.py +0 -0
  110. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/threads/worker.py +0 -0
  111. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/threads/worker_pool.py +0 -0
  112. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/time.py +0 -0
  113. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/university/__init__.py +0 -0
  114. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/university/databases/__init__.py +0 -0
  115. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils/university/databases/all.py +0 -0
  116. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils.egg-info/dependency_links.txt +0 -0
  117. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils.egg-info/requires.txt +0 -0
  118. {danielutils-0.9.67 → danielutils-0.9.69}/danielutils.egg-info/top_level.txt +0 -0
  119. {danielutils-0.9.67 → danielutils-0.9.69}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: danielutils
3
- Version: 0.9.67
3
+ Version: 0.9.69
4
4
  Summary: A python utils library for things I find useful
5
5
  Author-email: danielnachumdev <danielnachumdev@gmail.com>
6
6
  License: MIT License
@@ -41,7 +41,7 @@ Requires-Dist: tqdm
41
41
  [![Python 3.10.11](https://img.shields.io/badge/python-3.10.11-blue.svg)](https://www.python.org/downloads/release/python-31011/)
42
42
  [![gitleaks](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
43
43
  [![CodeQL](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql)
44
- # danielutils v=0.9.67
44
+ # danielutils v=0.9.68
45
45
  A utils library for things that I find useful for my coding workflow.\
46
46
  Feel free to use and / or contribute / improve my code :)
47
47
 
@@ -4,7 +4,7 @@
4
4
  [![Python 3.10.11](https://img.shields.io/badge/python-3.10.11-blue.svg)](https://www.python.org/downloads/release/python-31011/)
5
5
  [![gitleaks](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
6
6
  [![CodeQL](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql)
7
- # danielutils v=0.9.67
7
+ # danielutils v=0.9.68
8
8
  A utils library for things that I find useful for my coding workflow.\
9
9
  Feel free to use and / or contribute / improve my code :)
10
10
 
@@ -28,4 +28,5 @@ from .university import *
28
28
  from .my_tqdm import *
29
29
  from .threads import *
30
30
  from .loops import *
31
- from .multi_x import *
31
+ from .multi_x import *
32
+ from .package_utils import *
@@ -0,0 +1,40 @@
1
+ """Comparer class"""
2
+ from typing import Callable, Any, Union, Generic, TypeVar
3
+ from .functions import default_weight_function
4
+
5
+ U = TypeVar("U")
6
+ V = TypeVar("V")
7
+
8
+
9
+ class Comparer(Generic[U, V]):
10
+ """a Comparer class to be used when comparing two objects
11
+ """
12
+
13
+ def __init__(self, func: Callable[[U, V], Union[int, float]]):
14
+ self.func = func
15
+
16
+ def compare(self, v1: U, v2: V) -> Union[int, float]:
17
+ """compares two objects
18
+
19
+ Args:
20
+ v1 (Any): first object
21
+ v2 (Any): second object
22
+
23
+ Returns:
24
+ int: a number specifying the order of the objects
25
+ """
26
+ return self.func(v1, v2)
27
+
28
+ def __call__(self, v1: U, v2: V) -> Union[int, float]:
29
+ return self.compare(v1, v2)
30
+
31
+
32
+ CompareGreater: Comparer[U, V] = Comparer(lambda a, b: default_weight_function(a) -
33
+ default_weight_function(b))
34
+ CompareSmaller: Comparer[U, V] = Comparer(lambda a, b: default_weight_function(b) -
35
+ default_weight_function(a))
36
+ __all__ = [
37
+ "Comparer",
38
+ "CompareGreater",
39
+ "CompareSmaller"
40
+ ]
@@ -1,16 +1,18 @@
1
- from typing import Optional, Generator, Any, cast
2
- from .node import Node
1
+ from typing import Optional, Generator, Any, cast, TypeVar, Generic
2
+ from .graph import Node
3
3
 
4
+ T = TypeVar('T')
4
5
 
5
- class Stack:
6
+
7
+ class Stack(Generic[T]):
6
8
  """A classic Stack class
7
9
  """
8
10
 
9
11
  def __init__(self) -> None:
10
- self.head: Optional[Node] = None
12
+ self.head: Optional[Node[T]] = None
11
13
  self.size = 0
12
14
 
13
- def push(self, value: Any):
15
+ def push(self, value: Node[T]):
14
16
  """push an item to the stack
15
17
 
16
18
  Args:
@@ -23,7 +25,7 @@ class Stack:
23
25
  self.head = new_head
24
26
  self.size += 1
25
27
 
26
- def pop(self) -> Any:
28
+ def pop(self) -> Node[T]:
27
29
  """pop an item from the stack
28
30
 
29
31
  Returns:
@@ -39,7 +41,7 @@ class Stack:
39
41
  def __len__(self) -> int:
40
42
  return self.size
41
43
 
42
- def __iter__(self) -> Generator:
44
+ def __iter__(self) -> Generator[Node[T], None, None]:
43
45
  while self:
44
46
  yield self.pop()
45
47
 
@@ -51,7 +53,7 @@ class Stack:
51
53
  def __bool__(self) -> bool:
52
54
  return not self.is_empty()
53
55
 
54
- def __contains__(self, value) -> bool:
56
+ def __contains__(self, value: T) -> bool:
55
57
  curr = self.head
56
58
  while curr is not None:
57
59
  if curr.data == value:
@@ -1,7 +1,6 @@
1
1
  from .queue import *
2
2
  from .heap import *
3
3
  from .comparer import *
4
- from .node import *
5
4
  from .graph import *
6
5
  from .stack import *
7
6
  from .default_dict import *
@@ -12,3 +12,4 @@ from .threadify import *
12
12
  from .delay_call import *
13
13
  from .deprecate import *
14
14
  from .processify import *
15
+ from .singleton import *
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: danielutils
3
- Version: 0.9.67
3
+ Version: 0.9.69
4
4
  Summary: A python utils library for things I find useful
5
5
  Author-email: danielnachumdev <danielnachumdev@gmail.com>
6
6
  License: MIT License
@@ -41,7 +41,7 @@ Requires-Dist: tqdm
41
41
  [![Python 3.10.11](https://img.shields.io/badge/python-3.10.11-blue.svg)](https://www.python.org/downloads/release/python-31011/)
42
42
  [![gitleaks](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/gitleaks.yml)
43
43
  [![CodeQL](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/danielnachumdev/danielutils/actions/workflows/github-code-scanning/codeql)
44
- # danielutils v=0.9.67
44
+ # danielutils v=0.9.68
45
45
  A utils library for things that I find useful for my coding workflow.\
46
46
  Feel free to use and / or contribute / improve my code :)
47
47
 
@@ -1,7 +1,6 @@
1
1
  LISENCE
2
2
  README.md
3
3
  pyproject.toml
4
- setup.cfg
5
4
  setup.py
6
5
  danielutils/__init__.py
7
6
  danielutils/aliases.py
@@ -49,19 +48,11 @@ danielutils/conversions/specialized_conversions/__init__.py
49
48
  danielutils/conversions/specialized_conversions/to_hex.py
50
49
  danielutils/conversions/specialized_conversions/to_int.py
51
50
  danielutils/data_structures/Comparer.py
52
- danielutils/data_structures/Graph.py
53
- danielutils/data_structures/Heap.py
54
- danielutils/data_structures/Node.py
55
- danielutils/data_structures/Queue.py
56
51
  danielutils/data_structures/Stack.py
57
52
  danielutils/data_structures/__init__.py
58
53
  danielutils/data_structures/comparer.py
59
54
  danielutils/data_structures/default_dict.py
60
55
  danielutils/data_structures/functions.py
61
- danielutils/data_structures/graph.py
62
- danielutils/data_structures/heap.py
63
- danielutils/data_structures/node.py
64
- danielutils/data_structures/queue.py
65
56
  danielutils/data_structures/stack.py
66
57
  danielutils/decorators/__init__.py
67
58
  danielutils/decorators/atomic.py
@@ -4,23 +4,21 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "danielutils"
7
- version = "0.9.67"
7
+ version = "0.9.69"
8
8
  authors = [
9
9
  { name = "danielnachumdev", email = "danielnachumdev@gmail.com" },
10
10
  ]
11
- dependencies = ["tqdm"]
11
+ dependencies = ['tqdm']
12
12
  keywords = ['functions', 'decorators', 'methods', 'classes', 'metaclasses']
13
13
  license = { "file" = "LISENCE" }
14
14
  description = "A python utils library for things I find useful"
15
15
  readme = "README.md"
16
16
  requires-python = ">=3.8.17"
17
17
  classifiers = [
18
- "Development Status :: 3 - Alpha",
19
- "Intended Audience :: Developers",
20
- "Programming Language :: Python :: 3",
21
- # "Operating system :: Unix",
22
- # "Operating system :: MacOS :: MacOS X",
23
- "Operating System :: Microsoft :: Windows",
18
+ "Development Status :: 3 - Alpha",
19
+ "Intended Audience :: Developers",
20
+ "Programming Language :: Python :: 3",
21
+ "Operating System :: Microsoft :: Windows"
24
22
  ]
25
23
 
26
24
  [tool.setuptools]
@@ -28,4 +26,4 @@ packages = ["danielutils"]
28
26
 
29
27
  [project.urls]
30
28
  "Homepage" = "https://github.com/danielnachumdev/danielutils"
31
- "Bug Tracker" = "https://github.com/danielnachumdev/danielutils/issues"
29
+ "Bug Tracker" = "https://github.com/danielnachumdev/danielutils/issues"
@@ -1,2 +1,3 @@
1
1
  from setuptools import setup
2
- setup()
2
+
3
+ setup()
@@ -1,37 +0,0 @@
1
- """Comparer class"""
2
- from typing import Callable, Any, Union
3
- from .functions import default_weight_function
4
-
5
-
6
- class Comparer():
7
- """a Comparer class to be used when comparing two objects
8
- """
9
-
10
- def __init__(self, func: Callable[[Any, Any], Union[int, float]]):
11
- self.func = func
12
-
13
- def compare(self, v1: Any, v2: Any) -> Union[int, float]:
14
- """compares two objects
15
-
16
- Args:
17
- v1 (Any): first object
18
- v2 (Any): second object
19
-
20
- Returns:
21
- int: a number specifying the order of the objects
22
- """
23
- return self.func(v1, v2)
24
-
25
- def __call__(self, v1: Any, v2: Any) -> Union[int, float]:
26
- return self.compare(v1, v2)
27
-
28
-
29
- CompareGreater = Comparer(lambda a, b: default_weight_function(a) -
30
- default_weight_function(b))
31
- CompareSmaller = Comparer(lambda a, b: default_weight_function(b) -
32
- default_weight_function(a))
33
- __all__ = [
34
- "Comparer",
35
- "CompareGreater",
36
- "CompareSmaller"
37
- ]
@@ -1,134 +0,0 @@
1
- from typing import Optional, Generator, List as t_list, Set as t_set
2
- from .queue import Queue
3
- from .node import MultiNode
4
- from ..reflection import get_python_version
5
- if get_python_version() >= (3, 9):
6
- from builtins import list as t_list, set as t_set
7
-
8
-
9
- class Graph:
10
- """A general-purpose Graph class.
11
-
12
- This class represents a directed graph, where nodes can be connected through edges.
13
-
14
- Attributes:
15
- nodes (Optional[t_list[MultiNode]]): A list of MultiNode instances representing the nodes in the graph.
16
- Default is an empty list.
17
-
18
- Methods:
19
- __init__(self, nodes: Optional[t_list[MultiNode]] = None): Initialize the Graph with given nodes.
20
- add_node(self, node): Add a node to the graph.
21
- _extended_dfs(self) -> Generator: Perform an extended depth-first search on the graph.
22
- dfs(self) -> Generator: Perform a depth-first search on the graph.
23
- topological_sort(self) -> list: Get a topological sort of the graph nodes.
24
- bfs(self) -> Generator: Perform a breadth-first search on the graph.
25
- __str__(self) -> str: Get a string representation of the graph.
26
-
27
- """
28
-
29
- def __init__(self, nodes: Optional[t_list[MultiNode]] = None):
30
- self.nodes: t_list[MultiNode] = nodes if nodes is not None else []
31
-
32
- def add_node(self, node):
33
- """Add a node to the graph.
34
-
35
- Args:
36
- node: The MultiNode instance to add to the graph.
37
- """
38
- self.nodes.append(node)
39
-
40
- def _extended_dfs(self) -> Generator:
41
- """Perform an extended depth-first search on the graph.
42
-
43
- This private method performs an extended depth-first search (DFS) on the graph,
44
- keeping track of enter and exit times for each node, and returns a generator that yields
45
- nodes in the order of DFS traversal.
46
-
47
- Yields:
48
- Generator: The MultiNode instances in the order of depth-first traversal.
49
- """
50
- seen: set = set()
51
- enter_times: dict = {}
52
- exit_times: dict = {}
53
- travel_index: int = 1
54
- all_nodes: list = []
55
-
56
- def handle_node(node: MultiNode):
57
- nonlocal travel_index
58
- seen.add(node)
59
- all_nodes.append(node)
60
- yield node
61
- for subnode in node._children: # pylint: disable=protected-access
62
- if subnode not in seen:
63
- travel_index += 1
64
- enter_times[subnode] = travel_index
65
- if subnode is not None:
66
- yield from handle_node(subnode)
67
- travel_index += 1
68
- exit_times[subnode] = travel_index
69
-
70
- for node in self.nodes:
71
- if node not in seen:
72
- enter_times[node] = travel_index
73
- travel_index += 1
74
- yield from handle_node(node)
75
- travel_index += 1
76
- exit_times[node] = travel_index
77
- topological_order = sorted(
78
- all_nodes, key=lambda v: exit_times[v], reverse=True)
79
- return topological_order
80
-
81
- def dfs(self) -> Generator:
82
- """Perform a depth-first search on the graph.
83
-
84
- This method performs a depth-first search (DFS) on the graph using the private _extended_dfs method.
85
-
86
- Yields:
87
- Generator: The MultiNode instances in the order of depth-first traversal.
88
- """
89
- yield from self._extended_dfs()
90
-
91
- def topological_sort(self) -> list:
92
- """Get a topological sort of the graph nodes.
93
-
94
- This method performs a topological sort on the graph using the private _extended_dfs method.
95
-
96
- Returns:
97
- list: A list containing the MultiNode instances in topological order.
98
- """
99
- g = self._extended_dfs()
100
- try:
101
- while True:
102
- next(g)
103
- except StopIteration as e:
104
- return e.value
105
-
106
- def bfs(self) -> Generator:
107
- """Perform a breadth-first search on the graph.
108
-
109
- This method performs a breadth-first search (BFS) on the graph using a queue.
110
-
111
- Yields:
112
- Generator: The MultiNode instances in the order of breadth-first traversal.
113
- """
114
- q = Queue()
115
- for node in self.nodes:
116
- q.push(node)
117
- seen: t_set[MultiNode] = set()
118
- for node in q:
119
- if node not in seen:
120
- seen.add(node)
121
- yield node
122
- for child in node._children: # pylint: disable=protected-access
123
- q.push(child)
124
-
125
- def __str__(self) -> str:
126
- tmp = []
127
- for n in self.dfs():
128
- tmp.append(f"\t{str(n)}")
129
- return "Graph(\n"+",\n".join(tmp)+"\n)"
130
-
131
-
132
- __all__ = [
133
- "Graph"
134
- ]
@@ -1,111 +0,0 @@
1
- from typing import Any, Union
2
- from .comparer import Comparer, CompareGreater, CompareSmaller
3
-
4
-
5
- class Heap:
6
- """a Heap class which will do the sorting according to the supplied comparer object
7
- """
8
-
9
- def __init__(self, comparer: Comparer) -> None:
10
- self.arr: list = []
11
- self.comparer = comparer
12
-
13
- def push(self, val: Any) -> None:
14
- """will add a new object to the heap
15
-
16
- Args:
17
- val (Any): the object to add to the heap
18
- """
19
- res: Union[int, float] = -1
20
- curr_index = len(self)
21
- self.arr.append(val)
22
- parent_index = curr_index//2 - (1 - curr_index % 2)
23
- while res < 0 and parent_index >= 0:
24
- res = self.comparer.compare(
25
- self[parent_index], self[curr_index])
26
- if res < 0:
27
- self.arr[parent_index], self.arr[curr_index] = self[curr_index], self[parent_index]
28
- curr_index = parent_index
29
- parent_index = curr_index//2 - (1 - curr_index % 2)
30
-
31
- def __len__(self):
32
- return len(self.arr)
33
-
34
- def __getitem__(self, index: int):
35
- return self.arr[index]
36
-
37
- def is_empty(self) -> bool:
38
- """return whether the heap is empty
39
-
40
- Returns:
41
- bool: result
42
- """
43
- return len(self) == 0
44
-
45
- def pop(self) -> Any:
46
- """return the value at the top of the heap while removing it
47
-
48
- Returns:
49
- Any: the result
50
- """
51
- res = self[0]
52
- self.arr[0], self.arr[-1] = self[-1], self[0]
53
- self.arr.pop()
54
- flag = True
55
- curr_index = 0
56
- while flag:
57
- child1_index = curr_index*2+1
58
- child2_index = curr_index*2+2
59
- if len(self) > child2_index:
60
- if self.comparer.compare(self[child1_index], self[child2_index]) < 0:
61
- self.arr[curr_index], self.arr[child2_index] = self[child2_index], self[curr_index]
62
- curr_index = child2_index
63
- elif self.comparer.compare(self[child1_index], self[child2_index]) > 0:
64
- self.arr[curr_index], self.arr[child1_index] = self[child1_index], self[curr_index]
65
- curr_index = child1_index
66
- else:
67
- flag = False
68
- else:
69
- if len(self) > child1_index:
70
- if self.comparer.compare(self[child1_index], self[curr_index]) > 0:
71
- self.arr[curr_index], self.arr[child1_index] = self[child1_index], self[curr_index]
72
- curr_index = child1_index
73
- else:
74
- flag = False
75
- else:
76
- flag = False
77
- return res
78
-
79
- def __str__(self):
80
- return str(self.arr)
81
-
82
- def peek(self) -> Any:
83
- """return the value at the top of the Heap without removing it
84
-
85
- Returns:
86
- Any: the result
87
- """
88
- return self[0]
89
-
90
-
91
- class MaxHeap(Heap):
92
- """classic MaxHeap implementation
93
- """
94
-
95
- def __init__(self):
96
- super().__init__(CompareGreater)
97
-
98
-
99
- class MinHeap(Heap):
100
- """classic MinHeap implementation
101
- """
102
-
103
- def __init__(self) -> None:
104
- super().__init__(CompareSmaller)
105
-
106
-
107
- __all__ = [
108
- "Heap",
109
- "MaxHeap",
110
- "MinHeap",
111
- ]
@@ -1,106 +0,0 @@
1
- from __future__ import annotations
2
- from typing import Any, Optional, Generator
3
- from ..metaclasses import ImplicitDataDeleterMeta
4
-
5
-
6
- class MultiNode:
7
- """A node class with no limit to children amount
8
- """
9
-
10
- def __init__(self, data: Any, children: Optional[list[Optional[MultiNode]]] = None):
11
- self.data = data
12
- self._children = children if children is not None else []
13
-
14
- def __getitem__(self, index) -> Any:
15
- return self._children[index]
16
-
17
- def __setitem__(self, value, index) -> None:
18
- self._children[index] = value
19
-
20
- def __len__(self) -> int:
21
- return len(self._children)
22
-
23
- def __iter__(self) -> Generator:
24
- yield from self._children
25
-
26
- def __str__(self) -> str:
27
- res = ""
28
- seen = set()
29
-
30
- def handle_node(node: MultiNode):
31
- nonlocal res
32
- # res += f"MultiNode({node.data}, ["
33
- seen.add(node)
34
- tmp = []
35
- for child in node._children: # pylint: disable=protected-access
36
- if child in seen:
37
- tmp.append("...")
38
- else:
39
- if child is not None:
40
- tmp.append(handle_node(child))
41
- return f"{node.__class__.__name__}({node.data}, ["+", ".join(tmp)+"])"
42
-
43
- return handle_node(self)
44
-
45
- def __repr__(self):
46
- return str(self)
47
-
48
- def add_child(self, child):
49
- """adds a child to current node
50
- """
51
- self._children.append(child)
52
-
53
-
54
- class Node(MultiNode, metaclass=ImplicitDataDeleterMeta):
55
- """A 'classic' node class with only one child
56
- """
57
-
58
- def __init__(self, data, next: Optional[Node] = None): # pylint: disable=redefined-builtin
59
- super().__init__(data, [next])
60
-
61
- @property
62
- def next(self):
63
- """return the next node after self
64
- """
65
- return self._children[0]
66
-
67
- @next.setter
68
- def next(self, value):
69
- self._children[0] = value
70
-
71
- def __str__(self):
72
- # res = ""
73
- # seen = set()
74
-
75
- # def handle_node(node: Node):
76
- # nonlocal res
77
- # if node in seen:
78
- # res += "..."
79
- # else:
80
- # seen.add(node)
81
- # res += f"Node({node.data}, "
82
- # if node.next is None:
83
- # res += "None)"
84
- # elif node.next in seen:
85
- # res += "...)"
86
-
87
- # curr = self
88
- # while curr is not None:
89
- # handle_node(curr)
90
- # curr = curr.next
91
- # if curr in seen:
92
- # break
93
- # return res+")"
94
- return MultiNode.__str__(self).replace(
95
- self.__class__.__mro__[1].__name__,
96
- self.__class__.__name__
97
- ).replace("[", "").replace("]", "")
98
-
99
- def __repr__(self):
100
- return str(self)
101
-
102
-
103
- __all__ = [
104
- "MultiNode",
105
- "Node"
106
- ]
@@ -1,176 +0,0 @@
1
- from typing import Callable, Any, Union
2
- from .heap import Heap
3
- from .comparer import Comparer, CompareGreater
4
- from .functions import default_weight_function
5
- from ..metaclasses import AtomicClassMeta
6
-
7
-
8
- class Queue:
9
- """classic Queue data structure"""
10
-
11
- def __init__(self) -> None:
12
- self.data: list = []
13
-
14
- def pop(self) -> Any:
15
- """return the oldest element while removing it from the queue
16
-
17
- Returns:
18
- Any: result
19
- """
20
- return self.data.pop()
21
-
22
- def push(self, value: Any) -> None:
23
- """adds a new element to the queue
24
-
25
- Args:
26
- value (Any): the value to add
27
- """
28
- self.data.insert(0, value)
29
-
30
- def peek(self) -> Any:
31
- """returns the oldest element in the queue
32
- without removing it from the queue
33
-
34
- Returns:
35
- Any: result
36
- """
37
- return self.data[-1]
38
-
39
- def __len__(self) -> int:
40
- return len(self.data)
41
-
42
- def is_empty(self) -> bool:
43
- """returns whether the queue is empty
44
-
45
- Returns:
46
- bool: result
47
- """
48
- return len(self) == 0
49
-
50
- def __str__(self) -> str:
51
- return repr(self)
52
-
53
- def __repr__(self) -> str:
54
- return str(self.data)
55
-
56
- def __iter__(self):
57
- return iter(self.data)
58
-
59
- def push_many(self, arr: list):
60
- """will push many objects to the Queue
61
-
62
- Args:
63
- arr (list): the objects to push
64
- """
65
- for v in arr:
66
- self.push(v)
67
-
68
-
69
- class AtomicQueue(Queue, metaclass=AtomicClassMeta):
70
- """Same as Queue but atomic
71
- """
72
-
73
-
74
- class PriorityQueue(Queue):
75
- """
76
- A priority queue implementation based on a binary heap.
77
-
78
- Args:
79
- weight_func (Callable[[T], Union[int, float]], optional): A function to calculate the weight of items added
80
- to the queue. Defaults to default_weight_function.
81
- comparer (Comparer, optional): The comparer to use when comparing weights of items in the queue.
82
- Defaults to Comparer.GREATER.
83
-
84
- Raises:
85
- ValueError: Raised if an item with the same weight value is added more than once.
86
-
87
- Methods:
88
- pop() -> T:
89
- Removes and returns the item with the highest priority (i.e., the lowest weight value) from the queue.
90
- push(value: T):
91
- Adds a new item to the queue with the specified value and weight.
92
- peek() -> T:
93
- Returns the item with the highest priority
94
- (i.e., the lowest weight value) from the queue without removing it.
95
- __str__() -> str:
96
- Returns a string representation of the queue.
97
-
98
- Example:
99
- >>> pq = PriorityQueue()
100
- >>> pq.push(5)
101
- >>> pq.push(10)
102
- >>> pq.push(3)
103
- >>> pq.pop()
104
- 10
105
- """
106
-
107
- def __init__(self, weight_func: Callable[[Any], Union[int, float]] = default_weight_function):
108
- super().__init__()
109
- comparer = CompareGreater if weight_func is default_weight_function else Comparer(
110
- lambda a, b: weight_func(a)-weight_func(b))
111
- self.data: Heap = Heap(comparer) # type:ignore
112
- self.weight_func = weight_func
113
- self.dct: dict = {}
114
-
115
- def pop(self) -> Any:
116
- """
117
- Removes and returns the item with the highest priority (i.e., the lowest weight value) from the queue.
118
-
119
- Returns:
120
- T: The item with the highest priority in the queue.
121
-
122
- Raises:
123
- KeyError: Raised if the queue is empty.
124
- """
125
- item_weight = self.data.pop()
126
- res = self.dct[item_weight]
127
- del self.dct[item_weight]
128
- return res
129
-
130
- def push(self, value: Any):
131
- """
132
- Adds a new item to the queue with the specified value and weight.
133
-
134
- Args:
135
- value (T): The value of the item to add to the queue.
136
-
137
- Returns:
138
- None
139
-
140
- Raises:
141
- ValueError: Raised if an item with the same weight value is added more than once.
142
- """
143
- item_weight = self.weight_func(value)
144
- if item_weight in self.dct:
145
- raise ValueError(
146
- "Can't have same weight value more than once in current implementation")
147
- self.data.push(item_weight)
148
- self.dct[item_weight] = value
149
-
150
- def peek(self) -> Any:
151
- """
152
- Returns the item with the highest priority (i.e., the lowest weight value) from the queue without removing it.
153
-
154
- Returns:
155
- T: The item with the highest priority in the queue.
156
-
157
- Raises:
158
- KeyError: Raised if the queue is empty.
159
- """
160
- return self.dct[self.data.peek()]
161
-
162
- def __str__(self) -> str:
163
- """
164
- Returns a string representation of the queue.
165
-
166
- Returns:
167
- str: A string representation of the queue.
168
- """
169
- return str([str(self.dct[w]) for w in [self.data[i] for i in range(len(self.data))]])
170
-
171
-
172
- __all__ = [
173
- "Queue",
174
- "AtomicQueue",
175
- "PriorityQueue"
176
- ]
File without changes
File without changes