dycw-utilities 0.159.3__tar.gz → 0.159.5__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 (209) hide show
  1. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/PKG-INFO +1 -1
  2. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/pyproject.toml +2 -2
  3. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_math.py +14 -16
  4. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_polars.py +49 -39
  5. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/__init__.py +1 -1
  6. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/math.py +5 -1
  7. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/polars.py +106 -63
  8. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/.gitignore +0 -0
  9. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/LICENSE +0 -0
  10. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/README.md +0 -0
  11. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/__init__.py +0 -0
  12. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/conftest.py +0 -0
  13. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/__init__.py +0 -0
  14. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_missing/__init__.py +0 -0
  15. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_missing/module.py +0 -0
  16. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/__init__.py +0 -0
  17. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/outer_1.py +0 -0
  18. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/outer_2.py +0 -0
  19. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
  20. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
  21. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
  22. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
  23. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_without/__init__.py +0 -0
  24. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_without/module_1.py +0 -0
  25. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_without/module_2.py +0 -0
  26. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/standalone.py +0 -0
  27. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/with_imports.py +0 -0
  28. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
  29. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
  30. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
  31. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
  32. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
  33. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
  34. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
  35. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
  36. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_altair.py +0 -0
  37. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_asyncio.py +0 -0
  38. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_atomicwrites.py +0 -0
  39. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_atools.py +0 -0
  40. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_cachetools.py +0 -0
  41. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_click.py +0 -0
  42. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_concurrent.py +0 -0
  43. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_contextlib.py +0 -0
  44. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_contextvars.py +0 -0
  45. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_cryptography.py +0 -0
  46. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_cvxpy.py +0 -0
  47. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_dataclasses.py +0 -0
  48. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_enum.py +0 -0
  49. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_errors.py +0 -0
  50. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_eventkit.py +0 -0
  51. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_fastapi.py +0 -0
  52. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_fpdf2.py +0 -0
  53. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_functions.py +0 -0
  54. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_functools.py +0 -0
  55. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_getpass.py +0 -0
  56. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_gzip.py +0 -0
  57. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_hashlib.py +0 -0
  58. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_http.py +0 -0
  59. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_hypothesis.py +0 -0
  60. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_importlib.py +0 -0
  61. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_inflect.py +0 -0
  62. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_ipython.py +0 -0
  63. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_iterables.py +0 -0
  64. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_json.py +0 -0
  65. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_jupyter.py +0 -0
  66. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_libcst.py +0 -0
  67. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_lightweight_charts.py +0 -0
  68. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_logging.py +0 -0
  69. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_memory_profiler.py +0 -0
  70. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_modules.py +0 -0
  71. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_more_itertools.py +0 -0
  72. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_numpy.py +0 -0
  73. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_objects/__init__.py +0 -0
  74. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_objects/objects.py +0 -0
  75. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_operator.py +0 -0
  76. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_optuna.py +0 -0
  77. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_orjson.py +0 -0
  78. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_os.py +0 -0
  79. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_parse.py +0 -0
  80. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pathlib.py +0 -0
  81. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pickle.py +0 -0
  82. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_platform.py +0 -0
  83. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_polars_ols.py +0 -0
  84. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_postgres.py +0 -0
  85. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pottery.py +0 -0
  86. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pqdm.py +0 -0
  87. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_psutil.py +0 -0
  88. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pyinstrument.py +0 -0
  89. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pytest.py +0 -0
  90. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pytest_randomly.py +0 -0
  91. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pytest_regressions.py +0 -0
  92. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_random.py +0 -0
  93. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_re.py +0 -0
  94. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_redis.py +0 -0
  95. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_reprlib.py +0 -0
  96. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_scipy.py +0 -0
  97. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_sentinel.py +0 -0
  98. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_shelve.py +0 -0
  99. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_slack_sdk.py +0 -0
  100. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_socket.py +0 -0
  101. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_sqlalchemy.py +0 -0
  102. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_sqlalchemy_polars.py +0 -0
  103. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_statsmodels.py +0 -0
  104. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_string.py +0 -0
  105. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_tempfile.py +0 -0
  106. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_text.py +0 -0
  107. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_threading.py +0 -0
  108. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_timer.py +0 -0
  109. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_traceback.py +0 -0
  110. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_typed_settings.py +0 -0
  111. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_types.py +0 -0
  112. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_typing.py +0 -0
  113. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_typing_funcs/__init__.py +0 -0
  114. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_typing_funcs/no_future.py +0 -0
  115. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_typing_funcs/with_future.py +0 -0
  116. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_tzdata.py +0 -0
  117. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_tzlocal.py +0 -0
  118. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_uuid.py +0 -0
  119. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_version.py +0 -0
  120. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_warnings.py +0 -0
  121. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_whenever.py +0 -0
  122. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_zipfile.py +0 -0
  123. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_zoneinfo.py +0 -0
  124. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/altair.py +0 -0
  125. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/asyncio.py +0 -0
  126. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/atomicwrites.py +0 -0
  127. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/atools.py +0 -0
  128. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/cachetools.py +0 -0
  129. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/click.py +0 -0
  130. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/concurrent.py +0 -0
  131. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/contextlib.py +0 -0
  132. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/contextvars.py +0 -0
  133. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/cryptography.py +0 -0
  134. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/cvxpy.py +0 -0
  135. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/dataclasses.py +0 -0
  136. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/enum.py +0 -0
  137. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/errors.py +0 -0
  138. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/eventkit.py +0 -0
  139. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/fastapi.py +0 -0
  140. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/fpdf2.py +0 -0
  141. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/functions.py +0 -0
  142. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/functools.py +0 -0
  143. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/getpass.py +0 -0
  144. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/gzip.py +0 -0
  145. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/hashlib.py +0 -0
  146. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/http.py +0 -0
  147. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/hypothesis.py +0 -0
  148. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/importlib.py +0 -0
  149. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/inflect.py +0 -0
  150. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/ipython.py +0 -0
  151. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/iterables.py +0 -0
  152. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/json.py +0 -0
  153. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/jupyter.py +0 -0
  154. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/libcst.py +0 -0
  155. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/lightweight_charts.py +0 -0
  156. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/logging.py +0 -0
  157. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/memory_profiler.py +0 -0
  158. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/modules.py +0 -0
  159. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/more_itertools.py +0 -0
  160. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/numpy.py +0 -0
  161. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/operator.py +0 -0
  162. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/optuna.py +0 -0
  163. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/orjson.py +0 -0
  164. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/os.py +0 -0
  165. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/parse.py +0 -0
  166. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pathlib.py +0 -0
  167. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pickle.py +0 -0
  168. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/platform.py +0 -0
  169. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/polars_ols.py +0 -0
  170. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/postgres.py +0 -0
  171. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pottery.py +0 -0
  172. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pqdm.py +0 -0
  173. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/psutil.py +0 -0
  174. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/py.typed +0 -0
  175. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pyinstrument.py +0 -0
  176. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pytest.py +0 -0
  177. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pytest_plugins/__init__.py +0 -0
  178. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
  179. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
  180. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pytest_regressions.py +0 -0
  181. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/random.py +0 -0
  182. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/re.py +0 -0
  183. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/redis.py +0 -0
  184. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/reprlib.py +0 -0
  185. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/scipy.py +0 -0
  186. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/sentinel.py +0 -0
  187. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/shelve.py +0 -0
  188. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/slack_sdk.py +0 -0
  189. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/socket.py +0 -0
  190. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/sqlalchemy.py +0 -0
  191. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/sqlalchemy_polars.py +0 -0
  192. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/statsmodels.py +0 -0
  193. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/string.py +0 -0
  194. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/tempfile.py +0 -0
  195. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/text.py +0 -0
  196. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/threading.py +0 -0
  197. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/timer.py +0 -0
  198. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/traceback.py +0 -0
  199. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/typed_settings.py +0 -0
  200. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/types.py +0 -0
  201. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/typing.py +0 -0
  202. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/tzdata.py +0 -0
  203. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/tzlocal.py +0 -0
  204. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/uuid.py +0 -0
  205. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/version.py +0 -0
  206. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/warnings.py +0 -0
  207. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/whenever.py +0 -0
  208. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/zipfile.py +0 -0
  209. {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.159.3
3
+ Version: 0.159.5
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -227,7 +227,7 @@ dependencies = [
227
227
  name = "dycw-utilities"
228
228
  readme = "README.md"
229
229
  requires-python = ">= 3.12"
230
- version = "0.159.3"
230
+ version = "0.159.5"
231
231
 
232
232
  [project.entry-points.pytest11]
233
233
  pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
@@ -259,7 +259,7 @@ test = [
259
259
  # bump-my-version
260
260
  [tool.bumpversion]
261
261
  allow_dirty = true
262
- current_version = "0.159.3"
262
+ current_version = "0.159.5"
263
263
 
264
264
  [[tool.bumpversion.files]]
265
265
  filename = "src/utilities/__init__.py"
@@ -843,22 +843,20 @@ class TestMaxLongAndDouble:
843
843
 
844
844
  class TestNumberOfDecimals:
845
845
  max_int: ClassVar[int] = int(1e6)
846
+ cases: ClassVar[list[tuple[float, int]]] = [
847
+ (0.0, 0),
848
+ (0.1, 1),
849
+ (0.12, 2),
850
+ (0.123, 3),
851
+ (0.1234, 4),
852
+ (0.12345, 5),
853
+ (0.123456, 6),
854
+ (0.1234567, 7),
855
+ (0.12345678, 8),
856
+ (0.123456789, 9),
857
+ ]
846
858
 
847
- @given(
848
- integer=integers(-max_int, max_int),
849
- case=sampled_from([
850
- (0.0, 0),
851
- (0.1, 1),
852
- (0.12, 2),
853
- (0.123, 3),
854
- (0.1234, 4),
855
- (0.12345, 5),
856
- (0.123456, 6),
857
- (0.1234567, 7),
858
- (0.12345678, 8),
859
- (0.123456789, 9),
860
- ]),
861
- )
859
+ @given(integer=integers(-max_int, max_int), case=sampled_from(cases))
862
860
  def test_main(self, *, integer: int, case: tuple[float, int]) -> None:
863
861
  frac, expected = case
864
862
  x = integer + frac
@@ -870,7 +868,7 @@ class TestNumberOfDecimals:
870
868
  with raises(
871
869
  NumberOfDecimalsError,
872
870
  match=escape(
873
- "Could not determine number of decimals of 1.401298464324817e-45 (up to 20)"
871
+ "Could not determine number of decimals of 1.401298464324817e-45 (up to 10)"
874
872
  ),
875
873
  ):
876
874
  _ = number_of_decimals(x)
@@ -9,7 +9,7 @@ from enum import auto
9
9
  from itertools import chain, repeat
10
10
  from math import isfinite, nan
11
11
  from random import Random
12
- from typing import TYPE_CHECKING, Any, ClassVar, Literal, assert_never
12
+ from typing import TYPE_CHECKING, Any, ClassVar, Literal, assert_never, cast
13
13
  from uuid import UUID, uuid4
14
14
 
15
15
  import hypothesis.strategies
@@ -60,6 +60,7 @@ from pytest import mark, param, raises
60
60
  from whenever import DateDelta, DateTimeDelta, PlainDateTime, TimeDelta, ZonedDateTime
61
61
 
62
62
  import tests.test_math
63
+ import utilities.math
63
64
  import utilities.polars
64
65
  from utilities.hypothesis import (
65
66
  date_deltas,
@@ -78,7 +79,6 @@ from utilities.hypothesis import (
78
79
  zoned_date_time_periods,
79
80
  zoned_date_times,
80
81
  )
81
- from utilities.math import number_of_decimals
82
82
  from utilities.numpy import DEFAULT_RNG
83
83
  from utilities.pathlib import PWD
84
84
  from utilities.polars import (
@@ -97,6 +97,7 @@ from utilities.polars import (
97
97
  InsertBeforeError,
98
98
  OneColumnEmptyError,
99
99
  OneColumnNonUniqueError,
100
+ RoundToFloatError,
100
101
  SetFirstRowAsColumnsError,
101
102
  TimePeriodDType,
102
103
  _check_polars_dataframe_predicates,
@@ -123,8 +124,6 @@ from utilities.polars import (
123
124
  _GetDataTypeOrSeriesTimeZoneNotDateTimeError,
124
125
  _GetDataTypeOrSeriesTimeZoneNotZonedError,
125
126
  _GetDataTypeOrSeriesTimeZoneStructNonUniqueError,
126
- _GetSeriesNumberOfDecimalsAllNullError,
127
- _GetSeriesNumberOfDecimalsNotFloatError,
128
127
  _InsertBetweenMissingColumnsError,
129
128
  _InsertBetweenNonConsecutiveError,
130
129
  _IsNearEventAfterError,
@@ -169,7 +168,6 @@ from utilities.polars import (
169
168
  get_data_type_or_series_time_zone,
170
169
  get_expr_name,
171
170
  get_frequency_spectrum,
172
- get_series_number_of_decimals,
173
171
  increasing_horizontal,
174
172
  insert_after,
175
173
  insert_before,
@@ -183,6 +181,7 @@ from utilities.polars import (
183
181
  nan_sum_agg,
184
182
  nan_sum_cols,
185
183
  normal,
184
+ number_of_decimals,
186
185
  offset_datetime,
187
186
  one_column,
188
187
  order_of_magnitude,
@@ -1562,7 +1561,7 @@ class TestFiniteEWMWeights:
1562
1561
 
1563
1562
  class TestFirstTrueHorizontal:
1564
1563
  @mark.parametrize(
1565
- ("row", "expected"),
1564
+ ("values", "expected"),
1566
1565
  [
1567
1566
  param([True, True, True], 0),
1568
1567
  param([False, True, True], 1),
@@ -1570,9 +1569,9 @@ class TestFirstTrueHorizontal:
1570
1569
  param([False, False, False], None),
1571
1570
  ],
1572
1571
  )
1573
- def test_main(self, *, row: list[bool], expected: int | None) -> None:
1574
- df = DataFrame([row], schema={str(i): Boolean for i in range(3)}, orient="row")
1575
- result = first_true_horizontal(df)
1572
+ def test_main(self, *, values: list[bool], expected: int | None) -> None:
1573
+ series = [Series(values=[v], dtype=Boolean) for v in values]
1574
+ result = first_true_horizontal(*series)
1576
1575
  assert result.item() == expected
1577
1576
 
1578
1577
 
@@ -1660,34 +1659,6 @@ class TestGetFrequencySpectrum:
1660
1659
  assert allclose(result.filter(col("frequency").abs() > 0.02)["amplitude"], 0.0)
1661
1660
 
1662
1661
 
1663
- class TestGetSeriesNumberOfDecimals:
1664
- @given(data=data(), n=hypothesis.strategies.integers(1, 10), nullable=booleans())
1665
- def test_main(self, *, data: DataObject, n: int, nullable: bool) -> None:
1666
- strategy = int64s() | none() if nullable else int64s()
1667
- ints_or_none = data.draw(lists(strategy, min_size=1, max_size=10))
1668
- values = [None if i is None else i / 10**n for i in ints_or_none]
1669
- series = Series(values=values, dtype=Float64)
1670
- result = get_series_number_of_decimals(series, nullable=nullable)
1671
- if not nullable:
1672
- assert result is not None
1673
- expected = max(number_of_decimals(v) for v in values if v is not None)
1674
- assert result == expected
1675
-
1676
- def test_error_not_float(self) -> None:
1677
- with raises(
1678
- _GetSeriesNumberOfDecimalsNotFloatError,
1679
- match="Data type must be Float64; got Boolean",
1680
- ):
1681
- _ = get_series_number_of_decimals(Series(dtype=Boolean))
1682
-
1683
- def test_error_not_zoned(self) -> None:
1684
- with raises(
1685
- _GetSeriesNumberOfDecimalsAllNullError,
1686
- match="Series must not be all-null; got .*",
1687
- ):
1688
- _ = get_series_number_of_decimals(Series(dtype=Float64))
1689
-
1690
-
1691
1662
  class TestIncreasingAndDecreasingHorizontal:
1692
1663
  def test_main(self) -> None:
1693
1664
  df = DataFrame(
@@ -2261,6 +2232,22 @@ class TestNormal:
2261
2232
  assert series.is_finite().all()
2262
2233
 
2263
2234
 
2235
+ class TestNumberOfDecimals:
2236
+ @given(
2237
+ integer=hypothesis.strategies.integers(
2238
+ -tests.test_math.TestNumberOfDecimals.max_int,
2239
+ tests.test_math.TestNumberOfDecimals.max_int,
2240
+ ),
2241
+ case=sampled_from(tests.test_math.TestNumberOfDecimals.cases),
2242
+ )
2243
+ def test_main(self, *, integer: int, case: tuple[float, int]) -> None:
2244
+ frac, expected = case
2245
+ x = integer + frac
2246
+ series = Series(name="x", values=[x], dtype=Float64)
2247
+ result = number_of_decimals(series)
2248
+ assert result.item() == expected
2249
+
2250
+
2264
2251
  class TestOffsetDateTime:
2265
2252
  @mark.parametrize(
2266
2253
  ("n", "time"), [param(1, whenever.Time(13, 30)), param(2, whenever.Time(15))]
@@ -2441,8 +2428,8 @@ class TestReplaceTimeZone:
2441
2428
  class TestRoundToFloat:
2442
2429
  @mark.parametrize(("x", "y", "exp_value"), tests.test_math.TestRoundToFloat.cases)
2443
2430
  def test_main(self, *, x: float, y: float, exp_value: float) -> None:
2444
- series = Series(name="x", values=[x], dtype=Float64)
2445
- result = round_to_float(series, y)
2431
+ x_sr = Series(name="x", values=[x], dtype=Float64)
2432
+ result = round_to_float(x_sr, y)
2446
2433
  expected = Series(name="x", values=[exp_value], dtype=Float64)
2447
2434
  assert_series_equal(result, expected, check_exact=True)
2448
2435
 
@@ -2455,6 +2442,29 @@ class TestRoundToFloat:
2455
2442
  expected = Series(name="x", values=[1.2], dtype=Float64).to_frame()
2456
2443
  assert_frame_equal(df, expected)
2457
2444
 
2445
+ def test_series_and_expr(self) -> None:
2446
+ x = Series(name="x", values=[1.234], dtype=Float64)
2447
+ y = lit(0.1, dtype=Float64).alias("y")
2448
+ result = round_to_float(x, y)
2449
+ assert result.item() == 1.2
2450
+
2451
+ def test_expr_and_expr(self) -> None:
2452
+ x = lit(1.234, dtype=Float64).alias("x")
2453
+ y = Series(name="y", values=[0.1], dtype=Float64)
2454
+ result = round_to_float(x, y)
2455
+ assert result.item() == 1.2
2456
+
2457
+ @mark.parametrize(
2458
+ ("x", "y"),
2459
+ [param("x", "y"), param(col.x, "y"), param("x", col.y), param(col.x, col.y)],
2460
+ )
2461
+ def test_error(self, *, x: IntoExprColumn, y: IntoExprColumn) -> None:
2462
+ with raises(
2463
+ RoundToFloatError,
2464
+ match="At least 1 of the dividend and/or divisor must be a Series; got .* and .*",
2465
+ ):
2466
+ _ = round_to_float(cast("Any", x), cast("Any", y))
2467
+
2458
2468
 
2459
2469
  class TestSerializeAndDeserializeDataFrame:
2460
2470
  cases: ClassVar[list[tuple[PolarsDataType, SearchStrategy[Any]]]] = [
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.159.3"
3
+ __version__ = "0.159.5"
@@ -641,7 +641,10 @@ def _is_close(
641
641
  ##
642
642
 
643
643
 
644
- def number_of_decimals(x: float, /, *, max_decimals: int = 20) -> int:
644
+ MAX_DECIMALS = 10
645
+
646
+
647
+ def number_of_decimals(x: float, /, *, max_decimals: int = MAX_DECIMALS) -> int:
645
648
  """Get the number of decimals."""
646
649
  _, frac = divmod(x, 1)
647
650
  results = (
@@ -889,6 +892,7 @@ def significant_figures(x: float, /, *, n: int = 2) -> str:
889
892
 
890
893
 
891
894
  __all__ = [
895
+ "MAX_DECIMALS",
892
896
  "MAX_FLOAT32",
893
897
  "MAX_FLOAT64",
894
898
  "MAX_INT8",
@@ -53,11 +53,11 @@ from polars.schema import Schema
53
53
  from polars.testing import assert_frame_equal, assert_series_equal
54
54
  from whenever import DateDelta, DateTimeDelta, PlainDateTime, TimeDelta, ZonedDateTime
55
55
 
56
+ import utilities.math
56
57
  from utilities.dataclasses import yield_fields
57
58
  from utilities.errors import ImpossibleCaseError
58
59
  from utilities.functions import (
59
- EnsureIntError,
60
- ensure_int,
60
+ get_class_name,
61
61
  is_dataclass_class,
62
62
  is_dataclass_instance,
63
63
  make_isinstance,
@@ -80,12 +80,12 @@ from utilities.iterables import (
80
80
  )
81
81
  from utilities.json import write_formatted_json
82
82
  from utilities.math import (
83
+ MAX_DECIMALS,
83
84
  CheckIntegerError,
84
85
  check_integer,
85
86
  ewm_parameters,
86
87
  is_less_than,
87
88
  is_non_negative,
88
- number_of_decimals,
89
89
  )
90
90
  from utilities.reprlib import get_repr
91
91
  from utilities.types import MaybeStr, Number, PathLike, WeekDay
@@ -1325,10 +1325,27 @@ class _FiniteEWMWeightsError(Exception):
1325
1325
  ##
1326
1326
 
1327
1327
 
1328
- def first_true_horizontal(df: DataFrame, /) -> Series:
1328
+ @overload
1329
+ def first_true_horizontal(column: Series, /) -> Series: ...
1330
+ @overload
1331
+ def first_true_horizontal(column1: Series, column2: Series, /) -> Series: ...
1332
+ @overload
1333
+ def first_true_horizontal(
1334
+ column1: Series, column2: Series, column3: Series, /
1335
+ ) -> Series: ...
1336
+ @overload
1337
+ def first_true_horizontal(
1338
+ column1: Series, column2: Series, column3: Series, column4: Series, /
1339
+ ) -> Series: ...
1340
+ @overload
1341
+ def first_true_horizontal(*columns: Series) -> Series: ...
1342
+ @overload
1343
+ def first_true_horizontal(*columns: IntoExprColumn) -> ExprOrSeries: ...
1344
+ def first_true_horizontal(*columns: IntoExprColumn) -> ExprOrSeries:
1329
1345
  """Get the index of the first true in each row."""
1330
- expr = when(any_horizontal(pl.all())).then(concat_list(pl.all()).list.arg_max())
1331
- return one_column(df.select(expr))
1346
+ columns2 = ensure_expr_or_series_many(*columns)
1347
+ expr = when(any_horizontal(*columns2)).then(concat_list(*columns2).list.arg_max())
1348
+ return try_reify_expr(expr, *columns2)
1332
1349
 
1333
1350
 
1334
1351
  ##
@@ -1427,56 +1444,6 @@ def get_frequency_spectrum(series: Series, /, *, d: int = 1) -> DataFrame:
1427
1444
  ##
1428
1445
 
1429
1446
 
1430
- @overload
1431
- def get_series_number_of_decimals(
1432
- series: Series, /, *, nullable: Literal[True]
1433
- ) -> int | None: ...
1434
- @overload
1435
- def get_series_number_of_decimals(
1436
- series: Series, /, *, nullable: Literal[False] = False
1437
- ) -> int: ...
1438
- @overload
1439
- def get_series_number_of_decimals(
1440
- series: Series, /, *, nullable: bool = False
1441
- ) -> int | None: ...
1442
- def get_series_number_of_decimals(
1443
- series: Series, /, *, nullable: bool = False
1444
- ) -> int | None:
1445
- """Get the number of decimals of a series."""
1446
- if not isinstance(dtype := series.dtype, Float64):
1447
- raise _GetSeriesNumberOfDecimalsNotFloatError(dtype=dtype)
1448
- decimals = series.map_elements(number_of_decimals, return_dtype=Int64).max()
1449
- try:
1450
- return ensure_int(decimals, nullable=nullable)
1451
- except EnsureIntError:
1452
- raise _GetSeriesNumberOfDecimalsAllNullError(series=series) from None
1453
-
1454
-
1455
- @dataclass(kw_only=True, slots=True)
1456
- class GetSeriesNumberOfDecimalsError(Exception): ...
1457
-
1458
-
1459
- @dataclass(kw_only=True, slots=True)
1460
- class _GetSeriesNumberOfDecimalsNotFloatError(GetSeriesNumberOfDecimalsError):
1461
- dtype: DataType
1462
-
1463
- @override
1464
- def __str__(self) -> str:
1465
- return f"Data type must be Float64; got {self.dtype}"
1466
-
1467
-
1468
- @dataclass(kw_only=True, slots=True)
1469
- class _GetSeriesNumberOfDecimalsAllNullError(GetSeriesNumberOfDecimalsError):
1470
- series: Series
1471
-
1472
- @override
1473
- def __str__(self) -> str:
1474
- return f"Series must not be all-null; got {self.series}"
1475
-
1476
-
1477
- ##
1478
-
1479
-
1480
1447
  @overload
1481
1448
  def increasing_horizontal(*columns: ExprLike) -> Expr: ...
1482
1449
  @overload
@@ -2023,6 +1990,38 @@ def normal(
2023
1990
  ##
2024
1991
 
2025
1992
 
1993
+ @overload
1994
+ def number_of_decimals(
1995
+ series: ExprLike, /, *, max_decimals: int = MAX_DECIMALS
1996
+ ) -> Expr: ...
1997
+ @overload
1998
+ def number_of_decimals(
1999
+ series: Series, /, *, max_decimals: int = MAX_DECIMALS
2000
+ ) -> Series: ...
2001
+ @overload
2002
+ def number_of_decimals(
2003
+ series: IntoExprColumn, /, *, max_decimals: int = MAX_DECIMALS
2004
+ ) -> ExprOrSeries: ...
2005
+ def number_of_decimals(
2006
+ series: IntoExprColumn, /, *, max_decimals: int = MAX_DECIMALS
2007
+ ) -> ExprOrSeries:
2008
+ """Get the number of decimals."""
2009
+ series = ensure_expr_or_series(series)
2010
+ frac = series - series.floor()
2011
+ results = (
2012
+ _number_of_decimals_check_scale(frac, s) for s in range(max_decimals + 1)
2013
+ )
2014
+ return first_true_horizontal(*results)
2015
+
2016
+
2017
+ def _number_of_decimals_check_scale(frac: ExprOrSeries, scale: int, /) -> ExprOrSeries:
2018
+ scaled = 10**scale * frac
2019
+ return is_close(scaled, scaled.round()).alias(str(scale))
2020
+
2021
+
2022
+ ##
2023
+
2024
+
2026
2025
  def offset_datetime(
2027
2026
  datetime: ZonedDateTime, offset: str, /, *, n: int = 1
2028
2027
  ) -> ZonedDateTime:
@@ -2377,19 +2376,63 @@ def round_to_float(
2377
2376
  ) -> Expr: ...
2378
2377
  @overload
2379
2378
  def round_to_float(
2380
- x: Series, y: float, /, *, mode: RoundMode = "half_to_even"
2379
+ x: Series, y: float | ExprOrSeries, /, *, mode: RoundMode = "half_to_even"
2381
2380
  ) -> Series: ...
2382
2381
  @overload
2383
2382
  def round_to_float(
2384
- x: IntoExprColumn, y: float, /, *, mode: RoundMode = "half_to_even"
2383
+ x: ExprLike, y: Series, /, *, mode: RoundMode = "half_to_even"
2384
+ ) -> Series: ...
2385
+ @overload
2386
+ def round_to_float(
2387
+ x: ExprLike, y: Expr, /, *, mode: RoundMode = "half_to_even"
2388
+ ) -> Expr: ...
2389
+ @overload
2390
+ def round_to_float(
2391
+ x: IntoExprColumn, y: float | Series, /, *, mode: RoundMode = "half_to_even"
2385
2392
  ) -> ExprOrSeries: ...
2386
2393
  def round_to_float(
2387
- x: IntoExprColumn, y: float, /, *, mode: RoundMode = "half_to_even"
2394
+ x: IntoExprColumn, y: float | IntoExprColumn, /, *, mode: RoundMode = "half_to_even"
2388
2395
  ) -> ExprOrSeries:
2389
2396
  """Round a column to the nearest multiple of another float."""
2390
2397
  x = ensure_expr_or_series(x)
2391
- z = (x / y).round(mode=mode) * y
2392
- return z.round(decimals=number_of_decimals(y) + 1)
2398
+ y = y if isinstance(y, int | float) else ensure_expr_or_series(y)
2399
+ match x, y:
2400
+ case Expr() | Series(), int() | float():
2401
+ z = (x / y).round(mode=mode) * y
2402
+ return z.round(decimals=utilities.math.number_of_decimals(y) + 1)
2403
+ case Series(), Expr() | Series():
2404
+ df = (
2405
+ x.to_frame()
2406
+ .with_columns(y)
2407
+ .with_columns(number_of_decimals(y).alias("_decimals"))
2408
+ .with_row_index(name="_index")
2409
+ .group_by("_decimals")
2410
+ .map_groups(_round_to_float_one)
2411
+ .sort("_index")
2412
+ )
2413
+ return df[df.columns[1]]
2414
+ case Expr(), Series():
2415
+ df = y.to_frame().with_columns(x)
2416
+ return round_to_float(df[df.columns[1]], df[df.columns[0]], mode=mode)
2417
+ case Expr(), Expr() | str():
2418
+ raise RoundToFloatError(x=x, y=y)
2419
+ case never:
2420
+ assert_never(never)
2421
+
2422
+
2423
+ def _round_to_float_one(df: DataFrame, /) -> DataFrame:
2424
+ decimals: int = df["_decimals"].unique().item()
2425
+ return df.with_columns(col(df.columns[1]).round(decimals=decimals))
2426
+
2427
+
2428
+ @dataclass(kw_only=True, slots=True)
2429
+ class RoundToFloatError(Exception):
2430
+ x: IntoExprColumn
2431
+ y: IntoExprColumn
2432
+
2433
+ @override
2434
+ def __str__(self) -> str:
2435
+ return f"At least 1 of the dividend and/or divisor must be a Series; got {get_class_name(self.x)!r} and {get_class_name(self.y)!r}"
2393
2436
 
2394
2437
 
2395
2438
  ##
@@ -2595,7 +2638,6 @@ __all__ = [
2595
2638
  "ExprOrSeries",
2596
2639
  "FiniteEWMMeanError",
2597
2640
  "GetDataTypeOrSeriesTimeZoneError",
2598
- "GetSeriesNumberOfDecimalsError",
2599
2641
  "InsertAfterError",
2600
2642
  "InsertBeforeError",
2601
2643
  "InsertBetweenError",
@@ -2603,6 +2645,7 @@ __all__ = [
2603
2645
  "OneColumnEmptyError",
2604
2646
  "OneColumnError",
2605
2647
  "OneColumnNonUniqueError",
2648
+ "RoundToFloatError",
2606
2649
  "SetFirstRowAsColumnsError",
2607
2650
  "TimePeriodDType",
2608
2651
  "acf",
@@ -2634,7 +2677,6 @@ __all__ = [
2634
2677
  "get_data_type_or_series_time_zone",
2635
2678
  "get_expr_name",
2636
2679
  "get_frequency_spectrum",
2637
- "get_series_number_of_decimals",
2638
2680
  "increasing_horizontal",
2639
2681
  "insert_after",
2640
2682
  "insert_before",
@@ -2650,6 +2692,7 @@ __all__ = [
2650
2692
  "nan_sum_agg",
2651
2693
  "nan_sum_cols",
2652
2694
  "normal",
2695
+ "number_of_decimals",
2653
2696
  "offset_datetime",
2654
2697
  "one_column",
2655
2698
  "order_of_magnitude",