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.
Files changed (287) hide show
  1. danielutils/__init__.py +50 -0
  2. danielutils/abstractions/__init__.py +3 -0
  3. danielutils/abstractions/db/__init__.py +10 -0
  4. danielutils/abstractions/db/database.py +206 -0
  5. danielutils/abstractions/db/database_definitions.py +219 -0
  6. danielutils/abstractions/db/database_exceptions.py +34 -0
  7. danielutils/abstractions/db/database_factory.py +70 -0
  8. danielutils/abstractions/db/database_initializer.py +261 -0
  9. danielutils/abstractions/db/database_models.py +213 -0
  10. danielutils/abstractions/db/dependencies.py +6 -0
  11. danielutils/abstractions/db/implementations/__init__.py +4 -0
  12. danielutils/abstractions/db/implementations/in_memory_database.py +365 -0
  13. danielutils/abstractions/db/implementations/persistent_in_memory_database.py +174 -0
  14. danielutils/abstractions/db/implementations/redis_database.py +403 -0
  15. danielutils/abstractions/db/implementations/sqlite_database.py +491 -0
  16. danielutils/abstractions/multiprogramming/__init__.py +3 -0
  17. danielutils/abstractions/multiprogramming/multi_id.py +26 -0
  18. danielutils/abstractions/multiprogramming/worker.py +104 -0
  19. danielutils/abstractions/multiprogramming/worker_pool.py +98 -0
  20. danielutils/abstractions/repl.py +125 -0
  21. danielutils/aliases.py +174 -0
  22. danielutils/async_/__init__.py +7 -0
  23. danielutils/async_/async_cmd.py +28 -0
  24. danielutils/async_/async_command.py +879 -0
  25. danielutils/async_/async_layered_command.py +125 -0
  26. danielutils/async_/async_retry_executor.py +86 -0
  27. danielutils/async_/async_worker_pool.py +110 -0
  28. danielutils/async_/time_strategy.py +73 -0
  29. danielutils/async_/utils.py +57 -0
  30. danielutils/better_builtins/__init__.py +3 -0
  31. danielutils/better_builtins/counter.py +48 -0
  32. danielutils/better_builtins/frange.py +266 -0
  33. danielutils/better_builtins/typed_builtins/__init__.py +4 -0
  34. danielutils/better_builtins/typed_builtins/factory.py +126 -0
  35. danielutils/better_builtins/typed_builtins/tdict.py +36 -0
  36. danielutils/better_builtins/typed_builtins/tlist.py +223 -0
  37. danielutils/better_builtins/typed_builtins/tset.py +67 -0
  38. danielutils/better_builtins/typed_builtins/ttuple.py +15 -0
  39. danielutils/colors.py +203 -0
  40. danielutils/context_managers/__init__.py +5 -0
  41. danielutils/context_managers/attr_context.py +40 -0
  42. danielutils/context_managers/multi_context.py +34 -0
  43. danielutils/context_managers/optional_context.py +33 -0
  44. danielutils/context_managers/state_context.py +25 -0
  45. danielutils/context_managers/temporary_file.py +108 -0
  46. danielutils/convenience.py +12 -0
  47. danielutils/conversions/__init__.py +2 -0
  48. danielutils/conversions/main_conversions.py +131 -0
  49. danielutils/conversions/specialized_conversions/__init__.py +2 -0
  50. danielutils/conversions/specialized_conversions/to_hex.py +25 -0
  51. danielutils/conversions/specialized_conversions/to_int.py +19 -0
  52. danielutils/custom_types.py +18 -0
  53. danielutils/data_structures/__init__.py +8 -0
  54. danielutils/data_structures/algorithms.py +52 -0
  55. danielutils/data_structures/comparer.py +47 -0
  56. danielutils/data_structures/default_dict.py +23 -0
  57. danielutils/data_structures/functions.py +35 -0
  58. danielutils/data_structures/graph/__init__.py +4 -0
  59. danielutils/data_structures/graph/binary_node.py +71 -0
  60. danielutils/data_structures/graph/graph.py +208 -0
  61. danielutils/data_structures/graph/multinode.py +101 -0
  62. danielutils/data_structures/graph/node.py +60 -0
  63. danielutils/data_structures/heap/__init__.py +3 -0
  64. danielutils/data_structures/heap/heap.py +119 -0
  65. danielutils/data_structures/heap/max_heap.py +18 -0
  66. danielutils/data_structures/heap/min_heap.py +18 -0
  67. danielutils/data_structures/queue/__init__.py +3 -0
  68. danielutils/data_structures/queue/atomic_queue.py +15 -0
  69. danielutils/data_structures/queue/priority_queue.py +110 -0
  70. danielutils/data_structures/queue/queue.py +92 -0
  71. danielutils/data_structures/stack.py +102 -0
  72. danielutils/data_structures/trees/__init__.py +2 -0
  73. danielutils/data_structures/trees/binary_syntax_tree.py +84 -0
  74. danielutils/data_structures/trees/binary_tree.py +63 -0
  75. danielutils/date.py +43 -0
  76. danielutils/date_time.py +23 -0
  77. danielutils/decorators/__init__.py +18 -0
  78. danielutils/decorators/atomic.py +45 -0
  79. danielutils/decorators/attach.py +61 -0
  80. danielutils/decorators/chain_decorators.py +39 -0
  81. danielutils/decorators/decorate_conditionally.py +32 -0
  82. danielutils/decorators/delay_call.py +47 -0
  83. danielutils/decorators/deprecate.py +46 -0
  84. danielutils/decorators/final.py +39 -0
  85. danielutils/decorators/limit_recursion.py +63 -0
  86. danielutils/decorators/memo.py +68 -0
  87. danielutils/decorators/normalize_decorator.py +55 -0
  88. danielutils/decorators/overload.py +204 -0
  89. danielutils/decorators/partially_implemented.py +32 -0
  90. danielutils/decorators/processify.py +74 -0
  91. danielutils/decorators/property.py +42 -0
  92. danielutils/decorators/singleton.py +59 -0
  93. danielutils/decorators/threadify.py +40 -0
  94. danielutils/decorators/timeout.py +82 -0
  95. danielutils/decorators/total_ordering.py +82 -0
  96. danielutils/decorators/validate.py +227 -0
  97. danielutils/exceptions.py +90 -0
  98. danielutils/functions/__init__.py +13 -0
  99. danielutils/functions/areoneof.py +47 -0
  100. danielutils/functions/check_foreach.py +39 -0
  101. danielutils/functions/factorial.py +24 -0
  102. danielutils/functions/flatten.py +33 -0
  103. danielutils/functions/foreach.py +20 -0
  104. danielutils/functions/isoftype.py +475 -0
  105. danielutils/functions/isoneof.py +71 -0
  106. danielutils/functions/multiloop.py +51 -0
  107. danielutils/functions/parallel_for.py +47 -0
  108. danielutils/functions/partition.py +45 -0
  109. danielutils/functions/powerset.py +31 -0
  110. danielutils/functions/subseteq.py +25 -0
  111. danielutils/functions/types_subseteq.py +51 -0
  112. danielutils/generators/__init__.py +3 -0
  113. danielutils/generators/conditional_generator.py +59 -0
  114. danielutils/generators/generator_from_stream.py +31 -0
  115. danielutils/generators/join_generators.py +109 -0
  116. danielutils/internet.py +92 -0
  117. danielutils/io_.py +451 -0
  118. danielutils/java/__init__.py +18 -0
  119. danielutils/java/interfaces/__init__.py +1 -0
  120. danielutils/java/interfaces/comparable.py +31 -0
  121. danielutils/java/java_interface.py +59 -0
  122. danielutils/logging_/__init__.py +2 -0
  123. danielutils/logging_/_impl/__init__.py +4 -0
  124. danielutils/logging_/_impl/builtin_impls/__init__.py +2 -0
  125. danielutils/logging_/_impl/builtin_impls/file_logger.py +35 -0
  126. danielutils/logging_/_impl/builtin_impls/print_logger.py +21 -0
  127. danielutils/logging_/_impl/log_level.py +13 -0
  128. danielutils/logging_/_impl/logger.py +109 -0
  129. danielutils/logging_/_impl/logger_strategy_impl_base.py +37 -0
  130. danielutils/logging_/utils.py +199 -0
  131. danielutils/lombok/__init__.py +1 -0
  132. danielutils/lombok/builder.py +68 -0
  133. danielutils/math_/__init__.py +2 -0
  134. danielutils/math_/constants.py +103 -0
  135. danielutils/math_/functions.py +34 -0
  136. danielutils/math_/math_print.py +52 -0
  137. danielutils/math_/math_symbols.py +125 -0
  138. danielutils/metaclasses/__init__.py +5 -0
  139. danielutils/metaclasses/atomic_class_meta.py +36 -0
  140. danielutils/metaclasses/implicit_data_deleter_meta.py +87 -0
  141. danielutils/metaclasses/instance_cache_meta.py +66 -0
  142. danielutils/metaclasses/interface.py +328 -0
  143. danielutils/metaclasses/overload_meta.py +48 -0
  144. danielutils/mock_/__init__.py +1 -0
  145. danielutils/mock_/mock_module.py +27 -0
  146. danielutils/path.py +55 -0
  147. danielutils/print_.py +123 -0
  148. danielutils/progress_bar/__init__.py +3 -0
  149. danielutils/progress_bar/ascii_progress_bar.py +161 -0
  150. danielutils/progress_bar/progress_bar.py +75 -0
  151. danielutils/progress_bar/progress_bar_pool.py +72 -0
  152. danielutils/protocols/__init__.py +3 -0
  153. danielutils/protocols/dictable.py +38 -0
  154. danielutils/protocols/evaluable.py +26 -0
  155. danielutils/protocols/serializable.py +51 -0
  156. danielutils/py.typed +0 -0
  157. danielutils/random_.py +47 -0
  158. danielutils/reflection/__init__.py +6 -0
  159. danielutils/reflection/declarations.py +288 -0
  160. danielutils/reflection/file/__init__.py +1 -0
  161. danielutils/reflection/file/file_reflection.py +85 -0
  162. danielutils/reflection/function/__init__.py +1 -0
  163. danielutils/reflection/function/function_reflections.py +152 -0
  164. danielutils/reflection/info_classes/__init__.py +6 -0
  165. danielutils/reflection/info_classes/argument_info.py +278 -0
  166. danielutils/reflection/info_classes/class_info.py +204 -0
  167. danielutils/reflection/info_classes/decorator_info.py +54 -0
  168. danielutils/reflection/info_classes/file_info.py +1180 -0
  169. danielutils/reflection/info_classes/folder_info.py +592 -0
  170. danielutils/reflection/info_classes/function_info.py +551 -0
  171. danielutils/reflection/info_classes/import_info.py +207 -0
  172. danielutils/reflection/interpreter/__init__.py +9 -0
  173. danielutils/reflection/interpreter/callstack.py +57 -0
  174. danielutils/reflection/interpreter/get_traceback.py +27 -0
  175. danielutils/reflection/interpreter/interpreter.py +41 -0
  176. danielutils/reflection/interpreter/is_debugging.py +13 -0
  177. danielutils/reflection/interpreter/os_.py +33 -0
  178. danielutils/reflection/interpreter/packages.py +33 -0
  179. danielutils/reflection/interpreter/python_version.py +33 -0
  180. danielutils/reflection/interpreter/signals.py +18 -0
  181. danielutils/reflection/interpreter/tracer.py +175 -0
  182. danielutils/reflection/module/__init__.py +3 -0
  183. danielutils/reflection/module/lazy_module.py +104 -0
  184. danielutils/reflection/module/module_reflections.py +34 -0
  185. danielutils/reflection/module/package_reflection.py +161 -0
  186. danielutils/retry_executor/__init__.py +3 -0
  187. danielutils/retry_executor/backoff_strategies/__init__.py +6 -0
  188. danielutils/retry_executor/backoff_strategies/constant_backoff.py +25 -0
  189. danielutils/retry_executor/backoff_strategies/exponential_backoff.py +26 -0
  190. danielutils/retry_executor/backoff_strategies/functional_backoff.py +29 -0
  191. danielutils/retry_executor/backoff_strategies/linear_backoff.py +23 -0
  192. danielutils/retry_executor/backoff_strategies/multiplicative_backoff.py +23 -0
  193. danielutils/retry_executor/backoff_strategies/no_backoff.py +17 -0
  194. danielutils/retry_executor/backoff_strategy.py +28 -0
  195. danielutils/retry_executor/retry_executor.py +55 -0
  196. danielutils/snippets/__init__.py +1 -0
  197. danielutils/snippets/try_get.py +28 -0
  198. danielutils/system/__init__.py +3 -0
  199. danielutils/system/independent.py +197 -0
  200. danielutils/system/layered_command.py +130 -0
  201. danielutils/system/windows/__init__.py +2 -0
  202. danielutils/system/windows/utils/__init__.py +1 -0
  203. danielutils/system/windows/utils/filetime.py +19 -0
  204. danielutils/system/windows/win32_ctime.py +183 -0
  205. danielutils/system/windows/windows.py +78 -0
  206. danielutils/testing/__init__.py +1 -0
  207. danielutils/testing/unittest_/__init__.py +2 -0
  208. danielutils/testing/unittest_/always_teardown_testcase.py +75 -0
  209. danielutils/testing/unittest_/auto_cwd_testcase.py +114 -0
  210. danielutils/text.py +169 -0
  211. danielutils/time.py +64 -0
  212. danielutils/tools/__init__.py +1 -0
  213. danielutils/tools/unittest_test_runner/__init__.py +9 -0
  214. danielutils/tools/unittest_test_runner/cli.py +70 -0
  215. danielutils/tools/unittest_test_runner/core/__init__.py +17 -0
  216. danielutils/tools/unittest_test_runner/core/discovery.py +322 -0
  217. danielutils/tools/unittest_test_runner/core/execution.py +244 -0
  218. danielutils/tools/unittest_test_runner/core/parser.py +163 -0
  219. danielutils/tools/unittest_test_runner/core/runner.py +561 -0
  220. danielutils/tools/unittest_test_runner/models.py +82 -0
  221. danielutils/university/__init__.py +7 -0
  222. danielutils/university/computability_and_complexity/__init__.py +2 -0
  223. danielutils/university/computability_and_complexity/discreate_finite_automaton.py +89 -0
  224. danielutils/university/computability_and_complexity/languages/__init__.py +0 -0
  225. danielutils/university/computability_and_complexity/languages/language.py +17 -0
  226. danielutils/university/computability_and_complexity/languages/sat.py +71 -0
  227. danielutils/university/computability_and_complexity/turing_machine.py +47 -0
  228. danielutils/university/databases/__init__.py +1 -0
  229. danielutils/university/databases/all.py +756 -0
  230. danielutils/university/image_proccesing/__init__.py +1 -0
  231. danielutils/university/image_proccesing/encoding/__init__.py +3 -0
  232. danielutils/university/image_proccesing/encoding/encoding.py +35 -0
  233. danielutils/university/image_proccesing/encoding/lossless/__init__.py +4 -0
  234. danielutils/university/image_proccesing/encoding/lossless/huffman.py +0 -0
  235. danielutils/university/image_proccesing/encoding/lossless/lossless_encoding.py +10 -0
  236. danielutils/university/image_proccesing/encoding/lossless/lzw.py +0 -0
  237. danielutils/university/image_proccesing/encoding/lossless/run_length.py +22 -0
  238. danielutils/university/image_proccesing/encoding/lossy/__init__.py +1 -0
  239. danielutils/university/image_proccesing/encoding/lossy/lossy_encoding.py +10 -0
  240. danielutils/university/image_proccesing/tansformations/__init__.py +0 -0
  241. danielutils/university/image_proccesing/tansformations/gaussian.py +0 -0
  242. danielutils/university/image_proccesing/tansformations/gradient.py +0 -0
  243. danielutils/university/image_proccesing/tansformations/hough.py +0 -0
  244. danielutils/university/image_proccesing/tansformations/laplacian.py +0 -0
  245. danielutils/university/image_proccesing/tansformations/transformation.py +11 -0
  246. danielutils/university/linear_algebra/__init__.py +1 -0
  247. danielutils/university/linear_algebra/matrix.py +404 -0
  248. danielutils/university/machine_learning/__init__.py +0 -0
  249. danielutils/university/machine_learning/activation_functions/__init__.py +2 -0
  250. danielutils/university/machine_learning/activation_functions/activation_function.py +11 -0
  251. danielutils/university/machine_learning/activation_functions/relu.py +11 -0
  252. danielutils/university/machine_learning/neuron.py +15 -0
  253. danielutils/university/oop/__init__.py +1 -0
  254. danielutils/university/oop/observer.py +31 -0
  255. danielutils/university/oop/strategy.py +9 -0
  256. danielutils/university/probability/__init__.py +7 -0
  257. danielutils/university/probability/conditional_variable/__init__.py +3 -0
  258. danielutils/university/probability/conditional_variable/conditional_variable.py +138 -0
  259. danielutils/university/probability/conditional_variable/continuous/__init__.py +0 -0
  260. danielutils/university/probability/conditional_variable/discrete/__init__.py +8 -0
  261. danielutils/university/probability/conditional_variable/discrete/bernoulli.py +38 -0
  262. danielutils/university/probability/conditional_variable/discrete/bernoulli_sum.py +31 -0
  263. danielutils/university/probability/conditional_variable/discrete/binomial.py +40 -0
  264. danielutils/university/probability/conditional_variable/discrete/conditional_from_discrete_probability_func.py +36 -0
  265. danielutils/university/probability/conditional_variable/discrete/discrete.py +42 -0
  266. danielutils/university/probability/conditional_variable/discrete/geometric.py +43 -0
  267. danielutils/university/probability/conditional_variable/discrete/poisson.py +32 -0
  268. danielutils/university/probability/conditional_variable/discrete/uniform.py +33 -0
  269. danielutils/university/probability/distributions.py +35 -0
  270. danielutils/university/probability/expressions/__init__.py +2 -0
  271. danielutils/university/probability/expressions/accumulation_expression.py +291 -0
  272. danielutils/university/probability/expressions/probability_expression.py +110 -0
  273. danielutils/university/probability/funcs/__init__.py +4 -0
  274. danielutils/university/probability/funcs/covariance.py +12 -0
  275. danielutils/university/probability/funcs/expected_value.py +41 -0
  276. danielutils/university/probability/funcs/probability_function.py +14 -0
  277. danielutils/university/probability/funcs/variance.py +17 -0
  278. danielutils/university/probability/operator.py +79 -0
  279. danielutils/university/probability/protocols.py +32 -0
  280. danielutils/university/probability/supp.py +101 -0
  281. danielutils/university/probability/transformation.py +44 -0
  282. danielutils/versioned_imports.py +31 -0
  283. danielutils-1.1.28.dist-info/METADATA +390 -0
  284. danielutils-1.1.28.dist-info/RECORD +287 -0
  285. danielutils-1.1.28.dist-info/WHEEL +5 -0
  286. danielutils-1.1.28.dist-info/licenses/LICENSE +21 -0
  287. danielutils-1.1.28.dist-info/top_level.txt +1 -0
@@ -0,0 +1,138 @@
1
+ from abc import ABC, abstractmethod
2
+ from fractions import Fraction
3
+ from typing import Callable, Any
4
+ from ..expressions import ProbabilityExpression, AccumulationExpression
5
+ from ..operator import Operator
6
+ from ..supp import Supp
7
+ from ..protocols import Evaluable
8
+
9
+ def _create_operator(op: Operator, reverse: bool = False) -> Callable[['ConditionalVariable', Any], Evaluable]:
10
+ def operator(self, other) -> Evaluable:
11
+ lhs, rhs = self, other
12
+ if reverse:
13
+ lhs, rhs = rhs, lhs
14
+
15
+ if reverse and op == Operator.ADD and other == 0:
16
+ return self
17
+
18
+ if isinstance(other, ConditionalVariable) and op == Operator.ADD:
19
+ combined = _combine_iid_bernoulli_sums(lhs, other)
20
+ if combined is not None:
21
+ return combined
22
+
23
+ if isinstance(other, (int, float, Fraction)):
24
+ return ProbabilityExpression(lhs, op, rhs)
25
+
26
+ if isinstance(rhs, ProbabilityExpression):
27
+ l = ProbabilityExpression(lhs, op, rhs.lhs)
28
+ r = ProbabilityExpression(rhs.rhs, None, None)
29
+ o = other.op
30
+ return AccumulationExpression(l, o, r)
31
+
32
+ raise NotImplementedError("Not Implemented")
33
+
34
+ return operator
35
+
36
+
37
+ def _combine_iid_bernoulli_sums(lhs: 'ConditionalVariable', rhs: 'ConditionalVariable'):
38
+ from .discrete.bernoulli import Bernoulli
39
+ from .discrete.binomial import Binomial
40
+ from .discrete.bernoulli_sum import BernoulliSum
41
+
42
+ def count_and_p(variable: ConditionalVariable):
43
+ if isinstance(variable, Bernoulli):
44
+ return 1, variable.p
45
+ if isinstance(variable, BernoulliSum):
46
+ return variable.n, variable.p
47
+ if isinstance(variable, Binomial):
48
+ return variable.n, variable.p
49
+ return None, None
50
+
51
+ left_n, left_p = count_and_p(lhs)
52
+ right_n, right_p = count_and_p(rhs)
53
+ if left_n is None or right_n is None or left_p != right_p:
54
+ return None
55
+ return BernoulliSum(left_p, left_n + right_n)
56
+
57
+ class ConditionalVariable(ABC):
58
+ OPERATOR_TYPE = Callable[['ConditionalVariable', Any], Evaluable]
59
+
60
+
61
+ __eq__: OPERATOR_TYPE = _create_operator(Operator.EQ) # type:ignore
62
+ __ne__: OPERATOR_TYPE = _create_operator(Operator.NE) # type:ignore
63
+ __gt__: OPERATOR_TYPE = _create_operator(Operator.GT)
64
+ __ge__: OPERATOR_TYPE = _create_operator(Operator.GE)
65
+ __lt__: OPERATOR_TYPE = _create_operator(Operator.LT)
66
+ __le__: OPERATOR_TYPE = _create_operator(Operator.LE)
67
+
68
+ __or__: OPERATOR_TYPE = _create_operator(Operator.GIVEN)
69
+ __ror__: OPERATOR_TYPE = _create_operator(Operator.GIVEN, reverse=True)
70
+ __and__: OPERATOR_TYPE = _create_operator(Operator.AND)
71
+ __rand__: OPERATOR_TYPE = _create_operator(Operator.AND, reverse=True)
72
+
73
+ __mul__: OPERATOR_TYPE = _create_operator(Operator.MUL)
74
+ __truediv__: OPERATOR_TYPE = _create_operator(Operator.DIV)
75
+ __mod__: OPERATOR_TYPE = _create_operator(Operator.MODULUS)
76
+ __pow__: OPERATOR_TYPE = _create_operator(Operator.POW)
77
+ __add__: OPERATOR_TYPE = _create_operator(Operator.ADD)
78
+ __radd__: OPERATOR_TYPE = _create_operator(Operator.ADD, reverse=True)
79
+ __sub__: OPERATOR_TYPE = _create_operator(Operator.SUB)
80
+ __rsub__: OPERATOR_TYPE = _create_operator(Operator.SUB, reverse=True)
81
+
82
+ def __repr__(self) -> str:
83
+ return f"{self.__class__.__name__}"
84
+
85
+ def is_identical(self, other) -> bool:
86
+ if not isinstance(other, ConditionalVariable):
87
+ return False
88
+ return self is other
89
+
90
+ def is_independent(self, other) -> bool:
91
+ if not isinstance(other, ConditionalVariable):
92
+ return False
93
+ if self is other:
94
+ return False
95
+ if not self.supp.is_finite and not other.supp.is_finite:
96
+ raise ValueError("Can't check if two variables are independent if their supp is not finite")
97
+
98
+ if self.supp != other.supp:
99
+ return False
100
+ from ..funcs import probability_function as P
101
+ for k in self.supp:
102
+ if not (P((self == k) & (other == k)) == P(self == k) * P(other == k)):
103
+ return False
104
+ return True
105
+
106
+ def is_dependent(self, other) -> bool:
107
+ return not self.is_independent(other)
108
+
109
+ def is_correlated(self, other) -> bool:
110
+ if not isinstance(other, ConditionalVariable):
111
+ return False
112
+ from ..funcs import covariance as cov
113
+ return cov(self, other) == 0
114
+
115
+ def is_uncorrelated(self, other) -> bool:
116
+ return not self.is_correlated(other)
117
+
118
+ @abstractmethod
119
+ def evaluate(self, other: Any, operator: Operator) -> Fraction:
120
+ ...
121
+
122
+ @abstractmethod
123
+ def between(self, a, b, *args) -> Fraction:
124
+ ...
125
+
126
+ @property
127
+ @abstractmethod
128
+ def supp(self) -> Supp:
129
+ ...
130
+
131
+ @abstractmethod
132
+ def is_equal(self, other) -> bool:
133
+ ...
134
+
135
+
136
+ __all__ = [
137
+ "ConditionalVariable"
138
+ ]
@@ -0,0 +1,8 @@
1
+ from .bernoulli import *
2
+ from .bernoulli_sum import *
3
+ from .binomial import *
4
+ from .conditional_from_discrete_probability_func import *
5
+ from .discrete import *
6
+ from .geometric import *
7
+ from .poisson import *
8
+ from .uniform import *
@@ -0,0 +1,38 @@
1
+ from fractions import Fraction
2
+
3
+ from .discrete import DiscreteConditionalVariable
4
+ from ...supp import FrangeSupp
5
+ from ...operator import Operator
6
+ from ...protocols import ExpectedValueCalculable, VariableCalculable
7
+
8
+
9
+ class Bernoulli(DiscreteConditionalVariable, ExpectedValueCalculable, VariableCalculable):
10
+ def evaluate(self, n: int, op: Operator) -> Fraction:
11
+ if op == Operator.EQ:
12
+ return self.p if n == 1 else 1 - self.p
13
+ if op == Operator.GE:
14
+ if n <= 0:
15
+ return Fraction(1, 1)
16
+ if n == 1:
17
+ return self.p
18
+ return Fraction(0, 1)
19
+ if op == Operator.LE:
20
+ if n >= 1:
21
+ return Fraction(1, 1)
22
+ if n == 0:
23
+ return 1 - self.p
24
+ return Fraction(0, 1)
25
+
26
+ return 1 - self.evaluate(n, op.inverse)
27
+
28
+ def __init__(self, p) -> None:
29
+ super().__init__(p, FrangeSupp(range(0, 2)))
30
+
31
+ def expected_value(self) -> Fraction:
32
+ return self.p
33
+
34
+ def variance(self) -> Fraction:
35
+ return self.p * (1 - self.p)
36
+
37
+
38
+ __all__ = ['Bernoulli']
@@ -0,0 +1,31 @@
1
+ from fractions import Fraction
2
+ from typing import Union
3
+
4
+ from .discrete import DiscreteConditionalVariable
5
+ from .binomial import Binomial
6
+ from ...operator import Operator
7
+ from ...supp import FrangeSupp
8
+ from .....better_builtins import frange
9
+
10
+
11
+ class BernoulliSum(DiscreteConditionalVariable):
12
+ """Sum of iid Bernoulli variables; evaluates via Binomial."""
13
+
14
+ def __init__(self, p: Union[float, Fraction], n: int) -> None:
15
+ super().__init__(p, FrangeSupp(frange(0, n + 1)))
16
+ self._n = n
17
+
18
+ @property
19
+ def n(self) -> int:
20
+ return self._n
21
+
22
+ def evaluate(self, k: int, op: Operator) -> Fraction:
23
+ return Binomial(self._n, self.p).evaluate(k, op)
24
+
25
+ def is_equal(self, other) -> bool:
26
+ if not isinstance(other, BernoulliSum):
27
+ return False
28
+ return self.p == other.p and self._n == other._n
29
+
30
+
31
+ __all__ = ["BernoulliSum"]
@@ -0,0 +1,40 @@
1
+ from fractions import Fraction
2
+ from typing import Union
3
+ from math import factorial
4
+ from .discrete import DiscreteConditionalVariable
5
+ from ...supp import FrangeSupp
6
+ from ...operator import Operator
7
+ from .....better_builtins import frange
8
+ from ...protocols import ExpectedValueCalculable, VariableCalculable
9
+
10
+
11
+ def choose(n: int, k: int) -> Fraction:
12
+ return Fraction(factorial(n), (factorial(k) * factorial(n - k)))
13
+
14
+
15
+ class Binomial(DiscreteConditionalVariable, ExpectedValueCalculable, VariableCalculable):
16
+ def __init__(self, n: int, p: Union[float, Fraction]):
17
+ super().__init__(p, FrangeSupp(frange(0, float("inf"))))
18
+ self._n = n
19
+
20
+ @property
21
+ def n(self) -> int:
22
+ return self._n
23
+
24
+ def evaluate(self, k: int, op: Operator) -> Fraction:
25
+ if not 0 <= k <= self.n:
26
+ return Fraction(0, 1)
27
+
28
+ if op == Operator.EQ:
29
+ return choose(self.n, k) * ((1 - self.p) ** (self.n - k)) * (self.p ** k)
30
+ assert False # TODO
31
+ return 1 - self.evaluate(k, op.inverse)
32
+
33
+ def expected_value(self) -> Fraction:
34
+ return self.n * self.p
35
+
36
+ def variance(self) -> Fraction:
37
+ return self.n * self.p * (1 - self.p)
38
+
39
+
40
+ __all__ = ['Binomial']
@@ -0,0 +1,36 @@
1
+ from typing import Callable
2
+ from fractions import Fraction
3
+ from .discrete import DiscreteConditionalVariable
4
+ from ...supp import FrangeSupp
5
+ from ...operator import Operator
6
+
7
+
8
+ class ConditionalFromDiscreteProbabilityFunc(DiscreteConditionalVariable):
9
+ def evaluate(self, n: int, op: Operator) -> Fraction:
10
+ if op == Operator.EQ:
11
+ return self.f(n)
12
+ if op == Operator.LT:
13
+ res = Fraction(0, 1)
14
+ for k in range(n):
15
+ res += self.evaluate(k, Operator.EQ)
16
+ return res
17
+ if op == Operator.LE:
18
+ return self.evaluate(n, Operator.LT) + self.evaluate(n, Operator.EQ)
19
+
20
+ return 1 - self.evaluate(n, op.inverse)
21
+
22
+ def __init__(self, p: Callable[[int], Fraction], supp: FrangeSupp) -> None:
23
+ super().__init__(None, supp) # type:ignore
24
+ self.f = p
25
+
26
+ @property
27
+ def p(self):
28
+ raise AttributeError(f"{self.__class__.__name__} has no attribute 'p'")
29
+
30
+ def __repr__(self):
31
+ return self.__class__.__name__
32
+
33
+
34
+ __all__ = [
35
+ 'ConditionalFromDiscreteProbabilityFunc',
36
+ ]
@@ -0,0 +1,42 @@
1
+ from fractions import Fraction
2
+ from typing import Union
3
+
4
+ from ..conditional_variable import ConditionalVariable
5
+ from ...supp import FrangeSupp
6
+ from ...operator import Operator
7
+
8
+
9
+ class DiscreteConditionalVariable(ConditionalVariable):
10
+
11
+ def __init__(self, p: Union[float, Fraction], supp: FrangeSupp):
12
+ self._p: Fraction = p if isinstance(p, Fraction) else Fraction.from_float(p)
13
+ self._supp: FrangeSupp = supp
14
+
15
+ def __repr__(self) -> str:
16
+ return f"{self.__class__.__name__}({self.p})"
17
+
18
+ @property
19
+ def supp(self) -> FrangeSupp:
20
+ return self._supp
21
+
22
+ @property
23
+ def p(self) -> Fraction:
24
+ return self._p
25
+
26
+ def between(self, a, b, op1: Operator, op2: Operator) -> Fraction: # type:ignore
27
+ a, b = min(a, b), max(a, b)
28
+ if not (float(a).is_integer() and float(b).is_integer()):
29
+ # a = a - (a % self.supp.step)
30
+ # b = b - (b % self.supp.step)
31
+ raise NotImplementedError("Only integers are currently implemented")
32
+ return 1 - (self.evaluate(a, op1.inverse) + self.evaluate(b, op2.inverse))
33
+
34
+ def is_equal(self, other) -> bool:
35
+ if not isinstance(other, DiscreteConditionalVariable):
36
+ return False
37
+ return self.__class__ == other.__class__ and self.p == other.p
38
+
39
+
40
+ __all__ = [
41
+ "DiscreteConditionalVariable"
42
+ ]
@@ -0,0 +1,43 @@
1
+ from fractions import Fraction
2
+ from typing import Union, Tuple
3
+
4
+ from .discrete import DiscreteConditionalVariable
5
+ from ...operator import Operator
6
+ from .....better_builtins import frange
7
+ from ...supp import FrangeSupp
8
+ from ...protocols import ExpectedValueCalculable, VariableCalculable
9
+ from .....reflection import get_python_version
10
+
11
+
12
+ class Geometric(DiscreteConditionalVariable, ExpectedValueCalculable, VariableCalculable):
13
+ def __init__(self, p: Union[float, Fraction]):
14
+ super().__init__(Fraction(p), FrangeSupp(frange(1, float("inf"), 1)))
15
+
16
+ def _is_edge_case(self, n: int, op: Operator) -> Tuple[bool, Fraction]:
17
+ if n <= 0 and op in Operator.greater_than_inequalities():
18
+ return True, Fraction(1, 1)
19
+ if n <= 0 and op in Operator.less_than_inequalities():
20
+ return True, Fraction(0, 1)
21
+ return False, Fraction(0, 1)
22
+
23
+ def evaluate(self, n: int, op: Operator) -> Fraction:
24
+ if (tup := self._is_edge_case(n, op))[0]:
25
+ return tup[1]
26
+ del tup
27
+
28
+ if op == Operator.EQ:
29
+ return (Fraction(1 - self.p) ** (n - 1)) * self.p
30
+ if op == Operator.GT:
31
+ return Fraction(1 - self.p) ** n
32
+ if op == Operator.GE:
33
+ return self.evaluate(n - 1, Operator.GT)
34
+ return 1 - self.evaluate(n, op.inverse)
35
+
36
+ def expected_value(self) -> Fraction:
37
+ return Fraction(1, self.p)
38
+
39
+ def variance(self) -> Fraction:
40
+ return Fraction(1 - self.p, self.p ** 2)
41
+
42
+
43
+ __all__ = ['Geometric']
@@ -0,0 +1,32 @@
1
+ from fractions import Fraction
2
+ from typing import Union
3
+ from math import e, factorial
4
+
5
+ from .discrete import DiscreteConditionalVariable
6
+ from ...supp import FrangeSupp
7
+ from ...operator import Operator
8
+ from .....better_builtins import frange
9
+ from ...protocols import ExpectedValueCalculable, VariableCalculable
10
+
11
+
12
+ class Poisson(DiscreteConditionalVariable, ExpectedValueCalculable, VariableCalculable):
13
+ def __init__(self, p: Union[float, Fraction]):
14
+ super().__init__(p, FrangeSupp(frange(1, float("inf"))))
15
+
16
+ def evaluate(self, n: int, op: Operator) -> Fraction:
17
+ if n < 0:
18
+ return Fraction(0, 1)
19
+ if op == Operator.EQ:
20
+ return Fraction((e ** (-self.p)) * (self.p ** n), factorial(n)) # type:ignore
21
+
22
+ assert False # TODO
23
+ return 1 - self.evaluate(n, op.inverse) # type:ignore
24
+
25
+ def expected_value(self) -> Fraction:
26
+ return self.p
27
+
28
+ def variance(self) -> Fraction:
29
+ return self.p
30
+
31
+
32
+ __all__ = ['Poisson']
@@ -0,0 +1,33 @@
1
+ from fractions import Fraction
2
+
3
+ from ...supp import FrangeSupp
4
+ from ...operator import Operator
5
+
6
+ from .discrete import DiscreteConditionalVariable
7
+ from ...protocols import ExpectedValueCalculable, VariableCalculable
8
+
9
+
10
+ class Uniform(DiscreteConditionalVariable, ExpectedValueCalculable, VariableCalculable):
11
+ def evaluate(self, n: int, op: Operator) -> Fraction:
12
+ if n not in self.supp:
13
+ return Fraction(0, 1)
14
+
15
+ if op == Operator.EQ:
16
+ return self.p
17
+
18
+ assert False # TODO
19
+ return self.evaluate(n, op.inverse)
20
+
21
+ def __init__(self, size) -> None:
22
+ super().__init__(Fraction(1, size), FrangeSupp(range(1, size + 1)))
23
+
24
+ def expected_value(self) -> Fraction:
25
+ return Fraction(Fraction.from_float(self.supp.minimum + self.supp.maximum), 2)
26
+
27
+ def variance(self) -> Fraction:
28
+ return Fraction(
29
+ Fraction.from_float((self.supp.maximum - self.supp.minimum - 1) ** 2 - 1),
30
+ 12
31
+ )
32
+
33
+ __all__ = ['Uniform']
@@ -0,0 +1,35 @@
1
+ from enum import Enum
2
+ from .conditional_variable import ConditionalVariable
3
+ from .conditional_variable.discrete import Bernoulli, Geometric, Uniform, Binomial, Poisson
4
+
5
+
6
+ class DiscreteDistribution(Enum):
7
+ Ber = Bernoulli
8
+ Geo = Geometric
9
+ Unif = Uniform
10
+ Bin = Binomial
11
+ Pois = Poisson
12
+
13
+ def __call__(self, *args, **kwargs) -> ConditionalVariable:
14
+ return self.value(*args, **kwargs)
15
+
16
+
17
+ class ContinuousDistribution(Enum):
18
+ Unif = None
19
+ Exp = None
20
+ Normal = None
21
+
22
+
23
+ class Distribution:
24
+ Discrete = DiscreteDistribution
25
+ Continuous = ContinuousDistribution
26
+ # def __getattr__(self, item):
27
+ # if item in map(lambda x: x.name, list(self.value)):
28
+ # print("foo")
29
+ # return super().__getattr__(item)
30
+
31
+ __all__ = [
32
+ 'DiscreteDistribution',
33
+ 'ContinuousDistribution',
34
+ 'Distribution'
35
+ ]
@@ -0,0 +1,2 @@
1
+ from .probability_expression import *
2
+ from .accumulation_expression import *