dycw-utilities 0.153.2__py3-none-any.whl → 0.153.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.153.2
3
+ Version: 0.153.3
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=BOz9C-obZ9rIhyLSCVDsOVjnOeSdkl-YhkX0PSDH0-A,60
1
+ utilities/__init__.py,sha256=1GHQrcKaEUZf3pfIY7NBsyrMxgkxqFe8199dJVber6A,60
2
2
  utilities/altair.py,sha256=92E2lCdyHY4Zb-vCw6rEJIsWdKipuu-Tu2ab1ufUfAk,9079
3
3
  utilities/asyncio.py,sha256=QXkTtugXkqtYt7Do23zgYErqzdp6jwzPpV_SP9fJ1gI,16780
4
4
  utilities/atomicwrites.py,sha256=tPo6r-Rypd9u99u66B9z86YBPpnLrlHtwox_8Z7T34Y,5790
@@ -45,7 +45,7 @@ utilities/parse.py,sha256=JcJn5yXKhIWXBCwgBdPsyu7Hvcuw6kyEdqvaebCaI9k,17951
45
45
  utilities/pathlib.py,sha256=qGuU8XPmdgGpy8tOMUgelfXx3kxI8h9IaV3TI_06QGE,8428
46
46
  utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
47
47
  utilities/platform.py,sha256=pTn7gw6N4T6LdKrf0virwarof_mze9WtoQlrGMzhGVI,2798
48
- utilities/polars.py,sha256=uxV4liIQoCO92aERDO-AMfa8Es_-xCKgwZoyTO3PazQ,74410
48
+ utilities/polars.py,sha256=Ba1XxJZ3Q8i_mHkcNxjo4aGuMKwRsCdh0mIDI-V_HXw,76581
49
49
  utilities/polars_ols.py,sha256=Uc9V5kvlWZ5cU93lKZ-cfAKdVFFw81tqwLW9PxtUvMs,5618
50
50
  utilities/postgres.py,sha256=70BPcb_Na0LqDXJfqu0JwkHkGrwyuKpIVooSm6NlRn8,12467
51
51
  utilities/pottery.py,sha256=HJ96oLRarTP37Vhg0WTyB3yAu2hETeg6HgRmpDIqyUs,6581
@@ -87,8 +87,8 @@ utilities/zoneinfo.py,sha256=FBMcUQ4662Aq8SsuCL1OAhDQiyANmVjtb-C30DRrWoE,1966
87
87
  utilities/pytest_plugins/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
88
88
  utilities/pytest_plugins/pytest_randomly.py,sha256=B1qYVlExGOxTywq2r1SMi5o7btHLk2PNdY_b1p98dkE,409
89
89
  utilities/pytest_plugins/pytest_regressions.py,sha256=9v8kAXDM2ycIXJBimoiF4EgrwbUvxTycFWJiGR_GHhM,1466
90
- dycw_utilities-0.153.2.dist-info/METADATA,sha256=ZoTBo07vfu7uVKDOazdKRsN6QUwefZDYSLO15V1AAD4,1696
91
- dycw_utilities-0.153.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
- dycw_utilities-0.153.2.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
93
- dycw_utilities-0.153.2.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
- dycw_utilities-0.153.2.dist-info/RECORD,,
90
+ dycw_utilities-0.153.3.dist-info/METADATA,sha256=xSL1sIennAtafYoihcSuowIbjg7Wywuh9l5u3kLM7qg,1696
91
+ dycw_utilities-0.153.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
+ dycw_utilities-0.153.3.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
93
+ dycw_utilities-0.153.3.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
+ dycw_utilities-0.153.3.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.153.2"
3
+ __version__ = "0.153.3"
utilities/polars.py CHANGED
@@ -33,6 +33,7 @@ from polars import (
33
33
  any_horizontal,
34
34
  col,
35
35
  concat,
36
+ datetime_range,
36
37
  int_range,
37
38
  lit,
38
39
  struct,
@@ -49,6 +50,7 @@ from polars.exceptions import (
49
50
  )
50
51
  from polars.schema import Schema
51
52
  from polars.testing import assert_frame_equal, assert_series_equal
53
+ from whenever import ZonedDateTime
52
54
 
53
55
  from utilities.dataclasses import _YieldFieldsInstance, yield_fields
54
56
  from utilities.errors import ImpossibleCaseError
@@ -129,6 +131,7 @@ DatetimeUSEastern = Datetime(time_zone="US/Eastern")
129
131
  DatetimeUTC = Datetime(time_zone="UTC")
130
132
  _FINITE_EWM_MIN_WEIGHT = 0.9999
131
133
 
134
+
132
135
  ##
133
136
 
134
137
 
@@ -2021,6 +2024,19 @@ def normal(
2021
2024
  ##
2022
2025
 
2023
2026
 
2027
+ def offset_datetime(
2028
+ datetime: ZonedDateTime, offset: str, /, *, n: int = 1
2029
+ ) -> ZonedDateTime:
2030
+ """Offset a datetime as `polars` would."""
2031
+ sr = Series(values=[datetime.py_datetime()])
2032
+ for _ in range(n):
2033
+ sr = sr.dt.offset_by(offset)
2034
+ return ZonedDateTime.from_py_datetime(sr.item())
2035
+
2036
+
2037
+ ##
2038
+
2039
+
2024
2040
  @overload
2025
2041
  def order_of_magnitude(column: ExprLike, /, *, round_: bool = False) -> Expr: ...
2026
2042
  @overload
@@ -2041,6 +2057,75 @@ def order_of_magnitude(
2041
2057
  ##
2042
2058
 
2043
2059
 
2060
+ @overload
2061
+ def period_range(
2062
+ start: ZonedDateTime,
2063
+ end_or_length: ZonedDateTime | int,
2064
+ /,
2065
+ *,
2066
+ interval: str = "1d",
2067
+ time_unit: TimeUnit | None = None,
2068
+ time_zone: TimeZoneLike | None = None,
2069
+ eager: Literal[True],
2070
+ ) -> Series: ...
2071
+ @overload
2072
+ def period_range(
2073
+ start: ZonedDateTime,
2074
+ end_or_length: ZonedDateTime | int,
2075
+ /,
2076
+ *,
2077
+ interval: str = "1d",
2078
+ time_unit: TimeUnit | None = None,
2079
+ time_zone: TimeZoneLike | None = None,
2080
+ eager: Literal[False] = False,
2081
+ ) -> Expr: ...
2082
+ @overload
2083
+ def period_range(
2084
+ start: ZonedDateTime,
2085
+ end_or_length: ZonedDateTime | int,
2086
+ /,
2087
+ *,
2088
+ interval: str = "1d",
2089
+ time_unit: TimeUnit | None = None,
2090
+ time_zone: TimeZoneLike | None = None,
2091
+ eager: bool = False,
2092
+ ) -> Series | Expr: ...
2093
+ def period_range(
2094
+ start: ZonedDateTime,
2095
+ end_or_length: ZonedDateTime | int,
2096
+ /,
2097
+ *,
2098
+ interval: str = "1d",
2099
+ time_unit: TimeUnit | None = None,
2100
+ time_zone: TimeZoneLike | None = None,
2101
+ eager: bool = False,
2102
+ ) -> Series | Expr:
2103
+ """Construct a period range."""
2104
+ time_zone_use = None if time_zone is None else ensure_time_zone(time_zone).key
2105
+ match end_or_length:
2106
+ case ZonedDateTime() as end:
2107
+ ...
2108
+ case int() as length:
2109
+ end = offset_datetime(start, interval, n=length)
2110
+ case never:
2111
+ assert_never(never)
2112
+ starts = datetime_range(
2113
+ start.py_datetime(),
2114
+ end.py_datetime(),
2115
+ interval,
2116
+ closed="left",
2117
+ time_unit=time_unit,
2118
+ time_zone=time_zone_use,
2119
+ eager=eager,
2120
+ ).alias("start")
2121
+ ends = (starts.dt.offset_by(interval)).alias("end")
2122
+ period = struct(starts, ends)
2123
+ return try_reify_expr(period, starts, ends)
2124
+
2125
+
2126
+ ##
2127
+
2128
+
2044
2129
  def reify_exprs(
2045
2130
  *exprs: IntoExprColumn, **named_exprs: IntoExprColumn
2046
2131
  ) -> Expr | Series | DataFrame:
@@ -2529,7 +2614,9 @@ __all__ = [
2529
2614
  "nan_sum_agg",
2530
2615
  "nan_sum_cols",
2531
2616
  "normal",
2617
+ "offset_datetime",
2532
2618
  "order_of_magnitude",
2619
+ "period_range",
2533
2620
  "read_dataframe",
2534
2621
  "read_series",
2535
2622
  "replace_time_zone",