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.
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/PKG-INFO +1 -1
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/pyproject.toml +2 -2
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_math.py +14 -16
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_polars.py +49 -39
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/math.py +5 -1
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/polars.py +106 -63
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/.gitignore +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/LICENSE +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/README.md +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/__init__.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/conftest.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/__init__.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_missing/__init__.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_missing/module.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/__init__.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/outer_1.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/outer_2.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/subpackage/__init__.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/subpackage/inner_1.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/subpackage/inner_2.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/subpackage/inner_3.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_without/__init__.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_without/module_1.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_without/module_2.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/standalone.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/with_imports.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__obj.json +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestMultipleRegressionFixtures__test_main__series.json +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_int.json +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__false.json +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_literal__true.json +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestOrjsonRegressionFixture__test_dataclass_nested.json +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_dataframe.json +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/regressions/test_pytest_regressions/TestPolarsRegressionFixture__test_series.json +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_altair.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_asyncio.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_atomicwrites.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_atools.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_cachetools.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_click.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_concurrent.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_contextlib.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_contextvars.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_cryptography.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_cvxpy.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_dataclasses.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_enum.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_errors.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_eventkit.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_fastapi.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_fpdf2.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_functions.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_functools.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_getpass.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_gzip.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_hashlib.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_http.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_hypothesis.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_importlib.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_inflect.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_ipython.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_iterables.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_json.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_jupyter.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_libcst.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_lightweight_charts.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_logging.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_memory_profiler.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_modules.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_more_itertools.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_numpy.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_objects/__init__.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_objects/objects.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_operator.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_optuna.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_orjson.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_os.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_parse.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pathlib.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pickle.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_platform.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_polars_ols.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_postgres.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pottery.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pqdm.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_psutil.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pyinstrument.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pytest.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pytest_randomly.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_pytest_regressions.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_random.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_re.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_redis.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_reprlib.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_scipy.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_sentinel.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_shelve.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_slack_sdk.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_socket.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_sqlalchemy.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_statsmodels.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_string.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_tempfile.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_text.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_threading.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_timer.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_traceback.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_typed_settings.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_types.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_typing.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_typing_funcs/__init__.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_typing_funcs/no_future.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_typing_funcs/with_future.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_tzdata.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_tzlocal.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_uuid.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_version.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_warnings.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_whenever.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_zipfile.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/test_zoneinfo.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/click.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/eventkit.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/gzip.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/http.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/inflect.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/json.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/os.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/postgres.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pottery.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pytest_plugins/__init__.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/random.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/re.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/string.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/text.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/typed_settings.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/types.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/version.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/utilities/zoneinfo.py +0 -0
@@ -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.
|
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.
|
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
|
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
|
-
("
|
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, *,
|
1574
|
-
|
1575
|
-
result = first_true_horizontal(
|
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
|
-
|
2445
|
-
result = round_to_float(
|
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]]]] = [
|
@@ -641,7 +641,10 @@ def _is_close(
|
|
641
641
|
##
|
642
642
|
|
643
643
|
|
644
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
1331
|
-
|
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:
|
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
|
-
|
2392
|
-
|
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",
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_missing/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_missing/module.py
RENAMED
File without changes
|
{dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_with/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_without/__init__.py
RENAMED
File without changes
|
{dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_without/module_1.py
RENAMED
File without changes
|
{dycw_utilities-0.159.3 → dycw_utilities-0.159.5}/src/tests/modules/package_without/module_2.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|