danielutils 1.1.28__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.
- danielutils/__init__.py +50 -0
- danielutils/abstractions/__init__.py +3 -0
- danielutils/abstractions/db/__init__.py +10 -0
- danielutils/abstractions/db/database.py +206 -0
- danielutils/abstractions/db/database_definitions.py +219 -0
- danielutils/abstractions/db/database_exceptions.py +34 -0
- danielutils/abstractions/db/database_factory.py +70 -0
- danielutils/abstractions/db/database_initializer.py +261 -0
- danielutils/abstractions/db/database_models.py +213 -0
- danielutils/abstractions/db/dependencies.py +6 -0
- danielutils/abstractions/db/implementations/__init__.py +4 -0
- danielutils/abstractions/db/implementations/in_memory_database.py +365 -0
- danielutils/abstractions/db/implementations/persistent_in_memory_database.py +174 -0
- danielutils/abstractions/db/implementations/redis_database.py +403 -0
- danielutils/abstractions/db/implementations/sqlite_database.py +491 -0
- danielutils/abstractions/multiprogramming/__init__.py +3 -0
- danielutils/abstractions/multiprogramming/multi_id.py +26 -0
- danielutils/abstractions/multiprogramming/worker.py +104 -0
- danielutils/abstractions/multiprogramming/worker_pool.py +98 -0
- danielutils/abstractions/repl.py +125 -0
- danielutils/aliases.py +174 -0
- danielutils/async_/__init__.py +7 -0
- danielutils/async_/async_cmd.py +28 -0
- danielutils/async_/async_command.py +879 -0
- danielutils/async_/async_layered_command.py +125 -0
- danielutils/async_/async_retry_executor.py +86 -0
- danielutils/async_/async_worker_pool.py +110 -0
- danielutils/async_/time_strategy.py +73 -0
- danielutils/async_/utils.py +57 -0
- danielutils/better_builtins/__init__.py +3 -0
- danielutils/better_builtins/counter.py +48 -0
- danielutils/better_builtins/frange.py +266 -0
- danielutils/better_builtins/typed_builtins/__init__.py +4 -0
- danielutils/better_builtins/typed_builtins/factory.py +126 -0
- danielutils/better_builtins/typed_builtins/tdict.py +36 -0
- danielutils/better_builtins/typed_builtins/tlist.py +223 -0
- danielutils/better_builtins/typed_builtins/tset.py +67 -0
- danielutils/better_builtins/typed_builtins/ttuple.py +15 -0
- danielutils/colors.py +203 -0
- danielutils/context_managers/__init__.py +5 -0
- danielutils/context_managers/attr_context.py +40 -0
- danielutils/context_managers/multi_context.py +34 -0
- danielutils/context_managers/optional_context.py +33 -0
- danielutils/context_managers/state_context.py +25 -0
- danielutils/context_managers/temporary_file.py +108 -0
- danielutils/convenience.py +12 -0
- danielutils/conversions/__init__.py +2 -0
- danielutils/conversions/main_conversions.py +131 -0
- danielutils/conversions/specialized_conversions/__init__.py +2 -0
- danielutils/conversions/specialized_conversions/to_hex.py +25 -0
- danielutils/conversions/specialized_conversions/to_int.py +19 -0
- danielutils/custom_types.py +18 -0
- danielutils/data_structures/__init__.py +8 -0
- danielutils/data_structures/algorithms.py +52 -0
- danielutils/data_structures/comparer.py +47 -0
- danielutils/data_structures/default_dict.py +23 -0
- danielutils/data_structures/functions.py +35 -0
- danielutils/data_structures/graph/__init__.py +4 -0
- danielutils/data_structures/graph/binary_node.py +71 -0
- danielutils/data_structures/graph/graph.py +208 -0
- danielutils/data_structures/graph/multinode.py +101 -0
- danielutils/data_structures/graph/node.py +60 -0
- danielutils/data_structures/heap/__init__.py +3 -0
- danielutils/data_structures/heap/heap.py +119 -0
- danielutils/data_structures/heap/max_heap.py +18 -0
- danielutils/data_structures/heap/min_heap.py +18 -0
- danielutils/data_structures/queue/__init__.py +3 -0
- danielutils/data_structures/queue/atomic_queue.py +15 -0
- danielutils/data_structures/queue/priority_queue.py +110 -0
- danielutils/data_structures/queue/queue.py +92 -0
- danielutils/data_structures/stack.py +102 -0
- danielutils/data_structures/trees/__init__.py +2 -0
- danielutils/data_structures/trees/binary_syntax_tree.py +84 -0
- danielutils/data_structures/trees/binary_tree.py +63 -0
- danielutils/date.py +43 -0
- danielutils/date_time.py +23 -0
- danielutils/decorators/__init__.py +18 -0
- danielutils/decorators/atomic.py +45 -0
- danielutils/decorators/attach.py +61 -0
- danielutils/decorators/chain_decorators.py +39 -0
- danielutils/decorators/decorate_conditionally.py +32 -0
- danielutils/decorators/delay_call.py +47 -0
- danielutils/decorators/deprecate.py +46 -0
- danielutils/decorators/final.py +39 -0
- danielutils/decorators/limit_recursion.py +63 -0
- danielutils/decorators/memo.py +68 -0
- danielutils/decorators/normalize_decorator.py +55 -0
- danielutils/decorators/overload.py +204 -0
- danielutils/decorators/partially_implemented.py +32 -0
- danielutils/decorators/processify.py +74 -0
- danielutils/decorators/property.py +42 -0
- danielutils/decorators/singleton.py +59 -0
- danielutils/decorators/threadify.py +40 -0
- danielutils/decorators/timeout.py +82 -0
- danielutils/decorators/total_ordering.py +82 -0
- danielutils/decorators/validate.py +227 -0
- danielutils/exceptions.py +90 -0
- danielutils/functions/__init__.py +13 -0
- danielutils/functions/areoneof.py +47 -0
- danielutils/functions/check_foreach.py +39 -0
- danielutils/functions/factorial.py +24 -0
- danielutils/functions/flatten.py +33 -0
- danielutils/functions/foreach.py +20 -0
- danielutils/functions/isoftype.py +475 -0
- danielutils/functions/isoneof.py +71 -0
- danielutils/functions/multiloop.py +51 -0
- danielutils/functions/parallel_for.py +47 -0
- danielutils/functions/partition.py +45 -0
- danielutils/functions/powerset.py +31 -0
- danielutils/functions/subseteq.py +25 -0
- danielutils/functions/types_subseteq.py +51 -0
- danielutils/generators/__init__.py +3 -0
- danielutils/generators/conditional_generator.py +59 -0
- danielutils/generators/generator_from_stream.py +31 -0
- danielutils/generators/join_generators.py +109 -0
- danielutils/internet.py +92 -0
- danielutils/io_.py +451 -0
- danielutils/java/__init__.py +18 -0
- danielutils/java/interfaces/__init__.py +1 -0
- danielutils/java/interfaces/comparable.py +31 -0
- danielutils/java/java_interface.py +59 -0
- danielutils/logging_/__init__.py +2 -0
- danielutils/logging_/_impl/__init__.py +4 -0
- danielutils/logging_/_impl/builtin_impls/__init__.py +2 -0
- danielutils/logging_/_impl/builtin_impls/file_logger.py +35 -0
- danielutils/logging_/_impl/builtin_impls/print_logger.py +21 -0
- danielutils/logging_/_impl/log_level.py +13 -0
- danielutils/logging_/_impl/logger.py +109 -0
- danielutils/logging_/_impl/logger_strategy_impl_base.py +37 -0
- danielutils/logging_/utils.py +199 -0
- danielutils/lombok/__init__.py +1 -0
- danielutils/lombok/builder.py +68 -0
- danielutils/math_/__init__.py +2 -0
- danielutils/math_/constants.py +103 -0
- danielutils/math_/functions.py +34 -0
- danielutils/math_/math_print.py +52 -0
- danielutils/math_/math_symbols.py +125 -0
- danielutils/metaclasses/__init__.py +5 -0
- danielutils/metaclasses/atomic_class_meta.py +36 -0
- danielutils/metaclasses/implicit_data_deleter_meta.py +87 -0
- danielutils/metaclasses/instance_cache_meta.py +66 -0
- danielutils/metaclasses/interface.py +328 -0
- danielutils/metaclasses/overload_meta.py +48 -0
- danielutils/mock_/__init__.py +1 -0
- danielutils/mock_/mock_module.py +27 -0
- danielutils/path.py +55 -0
- danielutils/print_.py +123 -0
- danielutils/progress_bar/__init__.py +3 -0
- danielutils/progress_bar/ascii_progress_bar.py +161 -0
- danielutils/progress_bar/progress_bar.py +75 -0
- danielutils/progress_bar/progress_bar_pool.py +72 -0
- danielutils/protocols/__init__.py +3 -0
- danielutils/protocols/dictable.py +38 -0
- danielutils/protocols/evaluable.py +26 -0
- danielutils/protocols/serializable.py +51 -0
- danielutils/py.typed +0 -0
- danielutils/random_.py +47 -0
- danielutils/reflection/__init__.py +6 -0
- danielutils/reflection/declarations.py +288 -0
- danielutils/reflection/file/__init__.py +1 -0
- danielutils/reflection/file/file_reflection.py +85 -0
- danielutils/reflection/function/__init__.py +1 -0
- danielutils/reflection/function/function_reflections.py +152 -0
- danielutils/reflection/info_classes/__init__.py +6 -0
- danielutils/reflection/info_classes/argument_info.py +278 -0
- danielutils/reflection/info_classes/class_info.py +204 -0
- danielutils/reflection/info_classes/decorator_info.py +54 -0
- danielutils/reflection/info_classes/file_info.py +1180 -0
- danielutils/reflection/info_classes/folder_info.py +592 -0
- danielutils/reflection/info_classes/function_info.py +551 -0
- danielutils/reflection/info_classes/import_info.py +207 -0
- danielutils/reflection/interpreter/__init__.py +9 -0
- danielutils/reflection/interpreter/callstack.py +57 -0
- danielutils/reflection/interpreter/get_traceback.py +27 -0
- danielutils/reflection/interpreter/interpreter.py +41 -0
- danielutils/reflection/interpreter/is_debugging.py +13 -0
- danielutils/reflection/interpreter/os_.py +33 -0
- danielutils/reflection/interpreter/packages.py +33 -0
- danielutils/reflection/interpreter/python_version.py +33 -0
- danielutils/reflection/interpreter/signals.py +18 -0
- danielutils/reflection/interpreter/tracer.py +175 -0
- danielutils/reflection/module/__init__.py +3 -0
- danielutils/reflection/module/lazy_module.py +104 -0
- danielutils/reflection/module/module_reflections.py +34 -0
- danielutils/reflection/module/package_reflection.py +161 -0
- danielutils/retry_executor/__init__.py +3 -0
- danielutils/retry_executor/backoff_strategies/__init__.py +6 -0
- danielutils/retry_executor/backoff_strategies/constant_backoff.py +25 -0
- danielutils/retry_executor/backoff_strategies/exponential_backoff.py +26 -0
- danielutils/retry_executor/backoff_strategies/functional_backoff.py +29 -0
- danielutils/retry_executor/backoff_strategies/linear_backoff.py +23 -0
- danielutils/retry_executor/backoff_strategies/multiplicative_backoff.py +23 -0
- danielutils/retry_executor/backoff_strategies/no_backoff.py +17 -0
- danielutils/retry_executor/backoff_strategy.py +28 -0
- danielutils/retry_executor/retry_executor.py +55 -0
- danielutils/snippets/__init__.py +1 -0
- danielutils/snippets/try_get.py +28 -0
- danielutils/system/__init__.py +3 -0
- danielutils/system/independent.py +197 -0
- danielutils/system/layered_command.py +130 -0
- danielutils/system/windows/__init__.py +2 -0
- danielutils/system/windows/utils/__init__.py +1 -0
- danielutils/system/windows/utils/filetime.py +19 -0
- danielutils/system/windows/win32_ctime.py +183 -0
- danielutils/system/windows/windows.py +78 -0
- danielutils/testing/__init__.py +1 -0
- danielutils/testing/unittest_/__init__.py +2 -0
- danielutils/testing/unittest_/always_teardown_testcase.py +75 -0
- danielutils/testing/unittest_/auto_cwd_testcase.py +114 -0
- danielutils/text.py +169 -0
- danielutils/time.py +64 -0
- danielutils/tools/__init__.py +1 -0
- danielutils/tools/unittest_test_runner/__init__.py +9 -0
- danielutils/tools/unittest_test_runner/cli.py +70 -0
- danielutils/tools/unittest_test_runner/core/__init__.py +17 -0
- danielutils/tools/unittest_test_runner/core/discovery.py +322 -0
- danielutils/tools/unittest_test_runner/core/execution.py +244 -0
- danielutils/tools/unittest_test_runner/core/parser.py +163 -0
- danielutils/tools/unittest_test_runner/core/runner.py +561 -0
- danielutils/tools/unittest_test_runner/models.py +82 -0
- danielutils/university/__init__.py +7 -0
- danielutils/university/computability_and_complexity/__init__.py +2 -0
- danielutils/university/computability_and_complexity/discreate_finite_automaton.py +89 -0
- danielutils/university/computability_and_complexity/languages/__init__.py +0 -0
- danielutils/university/computability_and_complexity/languages/language.py +17 -0
- danielutils/university/computability_and_complexity/languages/sat.py +71 -0
- danielutils/university/computability_and_complexity/turing_machine.py +47 -0
- danielutils/university/databases/__init__.py +1 -0
- danielutils/university/databases/all.py +756 -0
- danielutils/university/image_proccesing/__init__.py +1 -0
- danielutils/university/image_proccesing/encoding/__init__.py +3 -0
- danielutils/university/image_proccesing/encoding/encoding.py +35 -0
- danielutils/university/image_proccesing/encoding/lossless/__init__.py +4 -0
- danielutils/university/image_proccesing/encoding/lossless/huffman.py +0 -0
- danielutils/university/image_proccesing/encoding/lossless/lossless_encoding.py +10 -0
- danielutils/university/image_proccesing/encoding/lossless/lzw.py +0 -0
- danielutils/university/image_proccesing/encoding/lossless/run_length.py +22 -0
- danielutils/university/image_proccesing/encoding/lossy/__init__.py +1 -0
- danielutils/university/image_proccesing/encoding/lossy/lossy_encoding.py +10 -0
- danielutils/university/image_proccesing/tansformations/__init__.py +0 -0
- danielutils/university/image_proccesing/tansformations/gaussian.py +0 -0
- danielutils/university/image_proccesing/tansformations/gradient.py +0 -0
- danielutils/university/image_proccesing/tansformations/hough.py +0 -0
- danielutils/university/image_proccesing/tansformations/laplacian.py +0 -0
- danielutils/university/image_proccesing/tansformations/transformation.py +11 -0
- danielutils/university/linear_algebra/__init__.py +1 -0
- danielutils/university/linear_algebra/matrix.py +404 -0
- danielutils/university/machine_learning/__init__.py +0 -0
- danielutils/university/machine_learning/activation_functions/__init__.py +2 -0
- danielutils/university/machine_learning/activation_functions/activation_function.py +11 -0
- danielutils/university/machine_learning/activation_functions/relu.py +11 -0
- danielutils/university/machine_learning/neuron.py +15 -0
- danielutils/university/oop/__init__.py +1 -0
- danielutils/university/oop/observer.py +31 -0
- danielutils/university/oop/strategy.py +9 -0
- danielutils/university/probability/__init__.py +7 -0
- danielutils/university/probability/conditional_variable/__init__.py +3 -0
- danielutils/university/probability/conditional_variable/conditional_variable.py +138 -0
- danielutils/university/probability/conditional_variable/continuous/__init__.py +0 -0
- danielutils/university/probability/conditional_variable/discrete/__init__.py +8 -0
- danielutils/university/probability/conditional_variable/discrete/bernoulli.py +38 -0
- danielutils/university/probability/conditional_variable/discrete/bernoulli_sum.py +31 -0
- danielutils/university/probability/conditional_variable/discrete/binomial.py +40 -0
- danielutils/university/probability/conditional_variable/discrete/conditional_from_discrete_probability_func.py +36 -0
- danielutils/university/probability/conditional_variable/discrete/discrete.py +42 -0
- danielutils/university/probability/conditional_variable/discrete/geometric.py +43 -0
- danielutils/university/probability/conditional_variable/discrete/poisson.py +32 -0
- danielutils/university/probability/conditional_variable/discrete/uniform.py +33 -0
- danielutils/university/probability/distributions.py +35 -0
- danielutils/university/probability/expressions/__init__.py +2 -0
- danielutils/university/probability/expressions/accumulation_expression.py +291 -0
- danielutils/university/probability/expressions/probability_expression.py +110 -0
- danielutils/university/probability/funcs/__init__.py +4 -0
- danielutils/university/probability/funcs/covariance.py +12 -0
- danielutils/university/probability/funcs/expected_value.py +41 -0
- danielutils/university/probability/funcs/probability_function.py +14 -0
- danielutils/university/probability/funcs/variance.py +17 -0
- danielutils/university/probability/operator.py +79 -0
- danielutils/university/probability/protocols.py +32 -0
- danielutils/university/probability/supp.py +101 -0
- danielutils/university/probability/transformation.py +44 -0
- danielutils/versioned_imports.py +31 -0
- danielutils-1.1.28.dist-info/METADATA +390 -0
- danielutils-1.1.28.dist-info/RECORD +287 -0
- danielutils-1.1.28.dist-info/WHEEL +5 -0
- danielutils-1.1.28.dist-info/licenses/LICENSE +21 -0
- danielutils-1.1.28.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .encoding import *
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Iterable, Generator, Union
|
|
4
|
+
|
|
5
|
+
Encodeable = Union[bytes, Iterable[bytes]]
|
|
6
|
+
Decodeable = Encodeable
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Encoding(ABC):
|
|
10
|
+
class EncodingType(Enum):
|
|
11
|
+
LOSSY = "LOSSY"
|
|
12
|
+
LOSSLESS = "LOSSLESS"
|
|
13
|
+
|
|
14
|
+
encoding_type: EncodingType
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
@abstractmethod
|
|
18
|
+
def encode_online(obj: Encodeable) -> Generator[bytes, None, None]: ...
|
|
19
|
+
|
|
20
|
+
@staticmethod
|
|
21
|
+
@abstractmethod
|
|
22
|
+
def encode_offline(obj: Encodeable) -> bytes: ...
|
|
23
|
+
|
|
24
|
+
@staticmethod
|
|
25
|
+
@abstractmethod
|
|
26
|
+
def decode_online(obj: Decodeable) -> Generator[bytes, None, None]: ...
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
@abstractmethod
|
|
30
|
+
def decode_offline(obj: Decodeable) -> bytes: ...
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
'Encoding'
|
|
35
|
+
]
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from typing import Generator, Sequence, List
|
|
2
|
+
from .lossless_encoding import LosslessEncoding
|
|
3
|
+
from ..encoding import Decodeable, Encodeable
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class RunLengthEncoding(LosslessEncoding):
|
|
7
|
+
@staticmethod
|
|
8
|
+
def encode_online(obj: Encodeable) -> Generator[bytes, None, None]:
|
|
9
|
+
buffer: List[int] = []
|
|
10
|
+
for c in obj:
|
|
11
|
+
if len(buffer) > 0:
|
|
12
|
+
if c != buffer[0]:
|
|
13
|
+
yield chr(buffer[0]).encode() + str(len(buffer)).encode()
|
|
14
|
+
buffer.clear()
|
|
15
|
+
buffer.append(c)
|
|
16
|
+
yield chr(buffer[0]).encode() + str(len(buffer)).encode()
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def decode_online(obj: Decodeable) -> Generator[bytes, None, None]:
|
|
20
|
+
raise NotImplementedError("RunLengthEncoding.decode_online() is not implemented")
|
|
21
|
+
|
|
22
|
+
SEPERATOR = b","
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .lossy_encoding import *
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .matrix import *
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import math
|
|
3
|
+
import random
|
|
4
|
+
from fractions import Fraction
|
|
5
|
+
from typing import Tuple, Iterator, Union, Iterable, Protocol, runtime_checkable, Optional, List
|
|
6
|
+
from copy import copy, deepcopy
|
|
7
|
+
from ...logging_.utils import get_logger
|
|
8
|
+
|
|
9
|
+
logger = get_logger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class Multipliable(Protocol):
|
|
14
|
+
def __mul__(self, other): ...
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@runtime_checkable
|
|
18
|
+
class Divisible(Protocol):
|
|
19
|
+
def __truediv__(self, other): ...
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Matrix:
|
|
23
|
+
@staticmethod
|
|
24
|
+
def identity(size: int) -> 'Matrix':
|
|
25
|
+
"""
|
|
26
|
+
Create an identity matrix (1s on the main diagonal) of specified size.
|
|
27
|
+
Args:
|
|
28
|
+
size: size of square matrix
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Matrix
|
|
32
|
+
"""
|
|
33
|
+
res = Matrix(size, size)
|
|
34
|
+
for i in range(size):
|
|
35
|
+
res[i, i] = 1
|
|
36
|
+
return res
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def from_array(cls, arr: List[List[Fraction]]) -> 'Matrix':
|
|
40
|
+
res = Matrix(len(arr), len(arr[0]))
|
|
41
|
+
res._data = deepcopy(arr)
|
|
42
|
+
return res
|
|
43
|
+
|
|
44
|
+
def __init__(self, height: int, width: int, default: Fraction = Fraction(0, 1)) -> None:
|
|
45
|
+
self._height = height
|
|
46
|
+
self._width = width
|
|
47
|
+
self._data = [[default for _ in range(self.width)] for _ in range(self.height)]
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def width(self) -> int:
|
|
51
|
+
return self._width
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def height(self) -> int:
|
|
55
|
+
return self._height
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def is_square(self) -> bool:
|
|
59
|
+
return self.height == self.width
|
|
60
|
+
|
|
61
|
+
def __getitem__(self, tup: Tuple[Union[slice, int], Union[slice, int]]) -> 'Matrix':
|
|
62
|
+
row, col = tup
|
|
63
|
+
if isinstance(row, int) and isinstance(col, int):
|
|
64
|
+
return Matrix(1, 1, self._data[row][col])
|
|
65
|
+
|
|
66
|
+
if isinstance(row, int):
|
|
67
|
+
row = slice(row, row + 1, 1)
|
|
68
|
+
else:
|
|
69
|
+
row = slice(
|
|
70
|
+
row.start if row.start is not None else 0,
|
|
71
|
+
row.stop if row.stop is not None else self.height,
|
|
72
|
+
row.step if row.step is not None else 1
|
|
73
|
+
)
|
|
74
|
+
if isinstance(col, int):
|
|
75
|
+
col = slice(col, col + 1, 1)
|
|
76
|
+
else:
|
|
77
|
+
col = slice(
|
|
78
|
+
col.start if col.start is not None else 0,
|
|
79
|
+
col.stop if col.stop is not None else self.width,
|
|
80
|
+
col.step if col.step is not None else 1
|
|
81
|
+
)
|
|
82
|
+
num_rows = (row.stop - row.start) // row.step
|
|
83
|
+
num_cols = (col.stop - col.start) // col.step
|
|
84
|
+
res = Matrix(num_rows, num_cols)
|
|
85
|
+
for res_i, cur_i in enumerate(range(row.start, row.stop, row.step)):
|
|
86
|
+
for res_j, cur_j in enumerate(range(col.start, col.stop, col.step)):
|
|
87
|
+
res._data[res_i][res_j] = self._data[cur_i][cur_j]
|
|
88
|
+
return res
|
|
89
|
+
|
|
90
|
+
def __setitem__(self, tup: Tuple[Union[slice, int], Union[slice, int]],
|
|
91
|
+
value: Union[int, float, Fraction, complex]) -> None:
|
|
92
|
+
v: Fraction = Fraction(value, 1) if not isinstance(value, Fraction) else value
|
|
93
|
+
row, col = tup
|
|
94
|
+
if isinstance(row, int) and isinstance(col, int):
|
|
95
|
+
self._data[row][col] = v
|
|
96
|
+
return
|
|
97
|
+
|
|
98
|
+
if isinstance(row, int):
|
|
99
|
+
row = slice(row, row + 1, 1)
|
|
100
|
+
else:
|
|
101
|
+
row = slice(
|
|
102
|
+
row.start if row.start is not None else 0,
|
|
103
|
+
row.stop if row.stop is not None else self.height,
|
|
104
|
+
row.step if row.step is not None else 1
|
|
105
|
+
)
|
|
106
|
+
if isinstance(col, int):
|
|
107
|
+
col = slice(col, col + 1, 1)
|
|
108
|
+
else:
|
|
109
|
+
col = slice(
|
|
110
|
+
col.start if col.start is not None else 0,
|
|
111
|
+
col.stop if col.stop is not None else self.width,
|
|
112
|
+
col.step if col.step is not None else 1
|
|
113
|
+
)
|
|
114
|
+
for res_i, cur_i in enumerate(range(row.start, row.stop, row.step)):
|
|
115
|
+
for res_j, cur_j in enumerate(range(col.start, col.stop, col.step)):
|
|
116
|
+
self._data[cur_i][cur_j] = v
|
|
117
|
+
|
|
118
|
+
def __copy__(self) -> 'Matrix':
|
|
119
|
+
return self[:, :]
|
|
120
|
+
|
|
121
|
+
def __mul__(self, other: Union[int, float, Fraction, complex]) -> 'Matrix':
|
|
122
|
+
if isinstance(other, Matrix):
|
|
123
|
+
raise ValueError("For Matrix Multiplication use '@' operator instead of '*' operator")
|
|
124
|
+
res = self.__copy__()
|
|
125
|
+
for i in range(res.height):
|
|
126
|
+
for j in range(res.width):
|
|
127
|
+
res._data[i][j] *= other
|
|
128
|
+
return res
|
|
129
|
+
|
|
130
|
+
def __rmul__(self, other: Union[int, float, Fraction, complex]) -> 'Matrix':
|
|
131
|
+
return self * other
|
|
132
|
+
|
|
133
|
+
def __truediv__(self, value: Union[int, float, Fraction, complex]) -> 'Matrix':
|
|
134
|
+
return self * (Fraction(1, value) if not isinstance(value, Fraction) else 1 / value)
|
|
135
|
+
|
|
136
|
+
def __floordiv__(self, other: Union[int, float, Fraction, complex]) -> 'Matrix':
|
|
137
|
+
return (self / other).__floor__()
|
|
138
|
+
|
|
139
|
+
def __floor__(self) -> 'Matrix':
|
|
140
|
+
res = self[:, :]
|
|
141
|
+
for i in range(self.height):
|
|
142
|
+
for j in range(res.width):
|
|
143
|
+
res._data[i][j] = math.floor(res._data[i][j])
|
|
144
|
+
return res
|
|
145
|
+
|
|
146
|
+
def __ceil__(self):
|
|
147
|
+
res = self[:, :]
|
|
148
|
+
for i in range(self.height):
|
|
149
|
+
for j in range(res.width):
|
|
150
|
+
res._data[i][j] = math.ceil(res._data[i][j])
|
|
151
|
+
return res
|
|
152
|
+
|
|
153
|
+
def __add__(self, other: 'Matrix') -> 'Matrix':
|
|
154
|
+
if not (self.width == other.width or self.height == other.height):
|
|
155
|
+
raise ValueError('Matrix dimensions do not match')
|
|
156
|
+
|
|
157
|
+
res = Matrix(self.width, self.height)
|
|
158
|
+
for i in range(res.height):
|
|
159
|
+
for j in range(res.width):
|
|
160
|
+
res._data[i][j] = self._data[i][j] + other._data[i][j]
|
|
161
|
+
return res
|
|
162
|
+
|
|
163
|
+
def __sub__(self, other: 'Matrix') -> 'Matrix':
|
|
164
|
+
return self + (-1 * other)
|
|
165
|
+
|
|
166
|
+
def __pow__(self, power: int, modulo=None) -> 'Matrix':
|
|
167
|
+
cur: Matrix = self[:, :]
|
|
168
|
+
for _ in range(power - 1):
|
|
169
|
+
cur @= self
|
|
170
|
+
return cur
|
|
171
|
+
|
|
172
|
+
def __matmul__(self, other: 'Matrix') -> 'Matrix':
|
|
173
|
+
if not (self.width == other.height):
|
|
174
|
+
logger.error("Matrix multiplication dimension mismatch: %s != %s", self.width, other.height)
|
|
175
|
+
raise ValueError(
|
|
176
|
+
f"Can't perform Matrix multiplication on A={repr(self)} and B={repr(other)} as A.width != B.height")
|
|
177
|
+
res = Matrix(self.height, other.width, 0)
|
|
178
|
+
for i in range(self.height):
|
|
179
|
+
for j in range(other.width):
|
|
180
|
+
for k in range(self.width):
|
|
181
|
+
res._data[i][j] += self._data[i][k] * other._data[k][j]
|
|
182
|
+
return res
|
|
183
|
+
|
|
184
|
+
def __iter__(self) -> Iterator[Fraction]:
|
|
185
|
+
for row in range(self.height):
|
|
186
|
+
for col in range(self.width):
|
|
187
|
+
yield self._data[row][col]
|
|
188
|
+
|
|
189
|
+
def __neg__(self) -> 'Matrix':
|
|
190
|
+
return -1 * self # type:ignore
|
|
191
|
+
|
|
192
|
+
def __repr__(self) -> str:
|
|
193
|
+
return f'Matrix({self._width}, {self._height})'
|
|
194
|
+
|
|
195
|
+
def __str__(self) -> str:
|
|
196
|
+
rows = []
|
|
197
|
+
for i in range(self.height):
|
|
198
|
+
row = []
|
|
199
|
+
for j in range(self.width):
|
|
200
|
+
row.append(self._data[i][j])
|
|
201
|
+
rows.append("[" + ", ".join(map(str, row)) + "]")
|
|
202
|
+
return "[" + ", ".join(map(str, rows)) + "]"
|
|
203
|
+
|
|
204
|
+
def __len__(self) -> int:
|
|
205
|
+
return self.height * self.width
|
|
206
|
+
|
|
207
|
+
def determinant(self) -> Union[float, 'Polynomial']:
|
|
208
|
+
raise NotImplementedError("Matrix.determinant() is not implemented")
|
|
209
|
+
|
|
210
|
+
def transpose(self) -> 'Matrix':
|
|
211
|
+
res = Matrix(self.width, self.height)
|
|
212
|
+
for i in range(self.height):
|
|
213
|
+
for j in range(self.width):
|
|
214
|
+
res._data[j][i] = self._data[i][j]
|
|
215
|
+
return res
|
|
216
|
+
|
|
217
|
+
def vectorize(self) -> 'Vector':
|
|
218
|
+
size = len(self)
|
|
219
|
+
res = Vector(size)
|
|
220
|
+
for i in range(self.height):
|
|
221
|
+
for j in range(self.width):
|
|
222
|
+
res[i * self.width + j] = self._data[i][j]
|
|
223
|
+
return res
|
|
224
|
+
|
|
225
|
+
def characteristic_polynomial(self) -> 'Polynomial':
|
|
226
|
+
I = Matrix.identity(max(self.width, self.height))
|
|
227
|
+
x = Polynomial([1, 0])
|
|
228
|
+
return (x * I - self).determinant() # type:ignore
|
|
229
|
+
|
|
230
|
+
def eigen_values(self) -> List[Fraction]:
|
|
231
|
+
return self.characteristic_polynomial().roots() # type:ignore
|
|
232
|
+
|
|
233
|
+
@classmethod
|
|
234
|
+
def random(cls, height: int, width: int, a: int = 0, b: int = 100, seed: Optional[int] = None) -> 'Matrix':
|
|
235
|
+
try:
|
|
236
|
+
if seed is not None:
|
|
237
|
+
prev_seed = random.getstate()
|
|
238
|
+
random.seed(seed)
|
|
239
|
+
|
|
240
|
+
res = Matrix(height, width)
|
|
241
|
+
for i in range(height):
|
|
242
|
+
for j in range(width):
|
|
243
|
+
res._data[i][j] = random.randint(a, b)
|
|
244
|
+
return res
|
|
245
|
+
finally:
|
|
246
|
+
if seed is not None:
|
|
247
|
+
random.setstate(prev_seed)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
class Vector(Matrix):
|
|
251
|
+
def __init__(self, size: int, default: Fraction = Fraction(0, 1)) -> None:
|
|
252
|
+
super().__init__(size, 1, default)
|
|
253
|
+
|
|
254
|
+
@property
|
|
255
|
+
def size(self) -> int:
|
|
256
|
+
return self.height
|
|
257
|
+
|
|
258
|
+
def __copy__(self):
|
|
259
|
+
return self[:]
|
|
260
|
+
|
|
261
|
+
def __getitem__(self, index: Union[slice, int]) -> 'Vector': # type:ignore
|
|
262
|
+
m = super().__getitem__((index, 0))
|
|
263
|
+
if isinstance(index, int):
|
|
264
|
+
return Vector(1, m._data[0][0])
|
|
265
|
+
return m.vectorize()
|
|
266
|
+
|
|
267
|
+
def __setitem__(self, index: int, value: float) -> None: # type:ignore
|
|
268
|
+
self._data[index][0] = value
|
|
269
|
+
|
|
270
|
+
def __repr__(self) -> str:
|
|
271
|
+
return f'Vector({self.size})'
|
|
272
|
+
|
|
273
|
+
def __str__(self) -> str:
|
|
274
|
+
vec = []
|
|
275
|
+
for v in self:
|
|
276
|
+
vec.append(v)
|
|
277
|
+
return "[" + ", ".join(map(str, vec)) + "]"
|
|
278
|
+
|
|
279
|
+
def __matmul__(self, other):
|
|
280
|
+
raise ValueError("Can't perform Matrix Multiplication with a vector as the lhs")
|
|
281
|
+
|
|
282
|
+
def __rmatmul__(self, other: 'Matrix') -> 'Vector':
|
|
283
|
+
return other.__matmul__(self).vectorize()
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class Polynomial:
|
|
287
|
+
def __init__(self, coefficients: Iterable[float]) -> None:
|
|
288
|
+
self._coefficients = list(coefficients)
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def coefficients(self) -> List[float]:
|
|
292
|
+
return self._coefficients
|
|
293
|
+
|
|
294
|
+
@property
|
|
295
|
+
def degree(self) -> int:
|
|
296
|
+
return len(self.coefficients) - 1
|
|
297
|
+
|
|
298
|
+
def eval(self, x: float) -> float:
|
|
299
|
+
res = 0.0
|
|
300
|
+
for i, coeff in enumerate(self.coefficients):
|
|
301
|
+
deg = self.degree - i
|
|
302
|
+
res += coeff * x ** deg
|
|
303
|
+
return res
|
|
304
|
+
|
|
305
|
+
def __add__(self, other: Union[float, 'Polynomial']) -> 'Polynomial':
|
|
306
|
+
res = self.__copy__()
|
|
307
|
+
if isinstance(other, (float, int)):
|
|
308
|
+
res.coefficients[-1] += other
|
|
309
|
+
return res
|
|
310
|
+
max_deg = min(self.degree, other.degree)
|
|
311
|
+
for i in range(1, max_deg + 2):
|
|
312
|
+
res.coefficients[-i] += other.coefficients[-i]
|
|
313
|
+
return res
|
|
314
|
+
|
|
315
|
+
def __sub__(self, other: Union[float, 'Polynomial']) -> 'Polynomial':
|
|
316
|
+
return self + (-1 * other)
|
|
317
|
+
|
|
318
|
+
def __copy__(self) -> 'Polynomial':
|
|
319
|
+
return Polynomial(self.coefficients[:])
|
|
320
|
+
|
|
321
|
+
def __mul__(self, other: Union[float, 'Polynomial']) -> Union[Matrix, Vector, 'Polynomial', float]:
|
|
322
|
+
if isinstance(other, (float, int)):
|
|
323
|
+
if other == 0:
|
|
324
|
+
return 0.0
|
|
325
|
+
res = self.__copy__()
|
|
326
|
+
for i in range(self.degree + 1):
|
|
327
|
+
res.coefficients[i] *= other
|
|
328
|
+
return res
|
|
329
|
+
|
|
330
|
+
if isinstance(other, Matrix):
|
|
331
|
+
return other.__mul__(self)
|
|
332
|
+
|
|
333
|
+
res = Polynomial([0 for _ in range(self.degree + other.degree + 1)])
|
|
334
|
+
for deg in range(self.degree + 1):
|
|
335
|
+
coeff = self.coefficients[deg]
|
|
336
|
+
poly = Polynomial(other.coefficients + [0 for _ in range(self.degree - deg)])
|
|
337
|
+
res += coeff * poly
|
|
338
|
+
return res
|
|
339
|
+
|
|
340
|
+
def __pow__(self, power: int, modulo=None) -> 'Polynomial':
|
|
341
|
+
if power == 0:
|
|
342
|
+
return 1
|
|
343
|
+
cur = self.__copy__()
|
|
344
|
+
for _ in range(power - 1):
|
|
345
|
+
cur *= self
|
|
346
|
+
return cur
|
|
347
|
+
|
|
348
|
+
def __rmul__(self, other: Union[float, 'Polynomial']) -> 'Polynomial':
|
|
349
|
+
return self.__mul__(other)
|
|
350
|
+
|
|
351
|
+
def __getitem__(self, index: int) -> float:
|
|
352
|
+
return self.coefficients[index]
|
|
353
|
+
|
|
354
|
+
def roots(self, known_roots: List[int]) -> List[float]:
|
|
355
|
+
cur = self.__copy__()
|
|
356
|
+
for root in known_roots:
|
|
357
|
+
cur /= Polynomial(1) - root
|
|
358
|
+
return []
|
|
359
|
+
|
|
360
|
+
raise NotImplementedError("Polynomial.roots() is not implemented")
|
|
361
|
+
|
|
362
|
+
def __call__(self, x: float) -> float:
|
|
363
|
+
return self.eval(x)
|
|
364
|
+
|
|
365
|
+
def __repr__(self) -> str:
|
|
366
|
+
return f"Polynomial(deg={self.degree})"
|
|
367
|
+
|
|
368
|
+
def __str__(self) -> str:
|
|
369
|
+
parts = []
|
|
370
|
+
for i, v in enumerate(self.coefficients):
|
|
371
|
+
deg = self.degree - i
|
|
372
|
+
if v == 0:
|
|
373
|
+
continue
|
|
374
|
+
if deg == 0:
|
|
375
|
+
if v < 0:
|
|
376
|
+
parts.append(f"\b\b- {abs(v)}")
|
|
377
|
+
else:
|
|
378
|
+
parts.append(f"{v}")
|
|
379
|
+
elif deg == 1:
|
|
380
|
+
if v == 1:
|
|
381
|
+
parts.append("x")
|
|
382
|
+
elif v == -1:
|
|
383
|
+
parts.append("-x")
|
|
384
|
+
elif v < 0:
|
|
385
|
+
parts.append(f"\b\b- {abs(v)}x")
|
|
386
|
+
else:
|
|
387
|
+
parts.append(f"{v}x")
|
|
388
|
+
else:
|
|
389
|
+
if v == 1:
|
|
390
|
+
parts.append(f"x^{deg}")
|
|
391
|
+
elif v == -1:
|
|
392
|
+
parts.append(f"(-x)^{deg}")
|
|
393
|
+
elif v > 0:
|
|
394
|
+
parts.append(f"{v}x^{deg}")
|
|
395
|
+
else:
|
|
396
|
+
parts.append(f"\b\b- {abs(v)}*x^{deg}")
|
|
397
|
+
return " + ".join(parts)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
__all__ = [
|
|
401
|
+
"Matrix",
|
|
402
|
+
"Vector",
|
|
403
|
+
"Polynomial"
|
|
404
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from .activation_functions import ActivationFunction
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Neuron:
|
|
5
|
+
def __init__(self, activation: ActivationFunction, bias):
|
|
6
|
+
self.activation = activation
|
|
7
|
+
self.bias = bias
|
|
8
|
+
|
|
9
|
+
def connect_after(self, successor: 'Neuron') -> None:
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
def connect_before(self, predecessor: 'Neuron') -> None:
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .observer import *
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Generic, TypeVar, Set
|
|
3
|
+
|
|
4
|
+
EventType = TypeVar('EventType')
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Publisher(Generic[EventType]):
|
|
8
|
+
def __init__(self):
|
|
9
|
+
self._subscribers: Set[Subscriber[EventType]] = set()
|
|
10
|
+
|
|
11
|
+
def register(self, subscriber: 'Subscriber') -> None:
|
|
12
|
+
self._subscribers.add(subscriber)
|
|
13
|
+
|
|
14
|
+
def unregister(self, subscriber: 'Subscriber') -> None:
|
|
15
|
+
self._subscribers.remove(subscriber)
|
|
16
|
+
|
|
17
|
+
def notify(self, event: EventType) -> None:
|
|
18
|
+
for subscriber in self._subscribers:
|
|
19
|
+
subscriber.update(self, event)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Subscriber(Generic[EventType], ABC):
|
|
23
|
+
|
|
24
|
+
@abstractmethod
|
|
25
|
+
def update(self, updater: 'Publisher', event: EventType) -> None: ...
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"Publisher",
|
|
30
|
+
"Subscriber",
|
|
31
|
+
]
|