mergeron_extra 2024.739099.2__tar.gz → 2024.739099.6__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mergeron_extra
3
- Version: 2024.739099.2
3
+ Version: 2024.739099.6
4
4
  Summary: Tools for users of the mergeron package.
5
5
  License: MIT
6
6
  Author: Murthy Kambhampaty
@@ -4,7 +4,7 @@ description = "Tools for users of the mergeron package."
4
4
  authors = ["Murthy Kambhampaty <smk@capeconomics.com>"]
5
5
  license = "MIT"
6
6
  readme = "README.rst"
7
- version = "2024.739099.2"
7
+ version = "2024.739099.6"
8
8
 
9
9
  classifiers = [
10
10
  "Development Status :: 4 - Beta",
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  from pathlib import Path
4
4
 
5
5
  import numpy as np
6
+ from numpy.typing import NDArray
6
7
 
7
8
  _PKG_NAME: str = Path(__file__).parent.stem
8
9
 
@@ -19,5 +20,11 @@ If the subdirectory doesn't exist, it is created on package invocation.
19
20
  if not DATA_DIR.is_dir():
20
21
  DATA_DIR.mkdir(parents=False)
21
22
 
23
+ np.set_printoptions(precision=24, floatmode="fixed")
22
24
 
23
- np.set_printoptions(precision=18)
25
+ type ArrayBoolean = NDArray[np.bool_]
26
+ type ArrayFloat = NDArray[np.half | np.single | np.double]
27
+ type ArrayINT = NDArray[np.intp]
28
+
29
+ type ArrayDouble = NDArray[np.double]
30
+ type ArrayBIGINT = NDArray[np.int64]
@@ -9,23 +9,20 @@ from __future__ import annotations
9
9
 
10
10
  from collections.abc import Sequence
11
11
  from dataclasses import dataclass
12
- from typing import Literal, TypeVar
12
+ from typing import Literal
13
13
 
14
14
  import numpy as np
15
- from numpy.typing import NBitBase, NDArray
16
15
  from scipy.optimize import OptimizeResult, root # type: ignore
17
16
  from scipy.stats import beta, chi2, norm # type: ignore
18
17
 
19
- from . import TI, VERSION, ArrayDouble, ArrayINT
18
+ from . import VERSION, ArrayDouble, ArrayINT
20
19
 
21
20
  __version__ = VERSION
22
21
 
23
- TI = TypeVar("TI", bound=NBitBase)
24
-
25
22
 
26
23
  def propn_ci(
27
- _npos: ArrayINT[TI] | int = 4,
28
- _nobs: ArrayINT[TI] | int = 10,
24
+ _npos: ArrayINT | int = 4,
25
+ _nobs: ArrayINT | int = 10,
29
26
  /,
30
27
  *,
31
28
  alpha: float = 0.05,
@@ -127,7 +124,7 @@ def propn_ci(
127
124
 
128
125
 
129
126
  def propn_ci_multinomial(
130
- _counts: NDArray[np.integer[TI]],
127
+ _counts: ArrayINT,
131
128
  /,
132
129
  *,
133
130
  alpha: float = 0.05,
@@ -438,7 +435,7 @@ def _propn_diff_chisq_mn(
438
435
 
439
436
 
440
437
  def propn_diff_ci_multinomial(
441
- _counts: NDArray[np.integer[TI]], /, *, alpha: float = 0.05
438
+ _counts: ArrayINT, /, *, alpha: float = 0.05
442
439
  ) -> ArrayDouble:
443
440
  """Estimate confidence intervals of pair-wise differences in multinomial proportions
444
441
 
@@ -480,7 +477,7 @@ class MultinomialPropnsTest:
480
477
 
481
478
 
482
479
  def propn_test_multinomial(
483
- _counts: NDArray[np.integer[TI]], /, *, alpha: float = 0.05
480
+ _counts: ArrayINT, /, *, alpha: float = 0.05
484
481
  ) -> MultinomialPropnsTest:
485
482
  """Chi-square test for homogeneity of differences in multinomial proportions.
486
483
 
@@ -27,15 +27,16 @@ from collections.abc import Sequence
27
27
  from typing import Any, ClassVar, Literal, TypeAlias, TypedDict
28
28
 
29
29
  import numpy as np
30
- import xlsxwriter # type: ignore
31
30
  from aenum import Enum, extend_enum, unique # type: ignore
32
31
  from numpy.typing import NDArray
32
+ from xlsxwriter.format import Format
33
+ from xlsxwriter.workbook import Workbook
34
+ from xlsxwriter.worksheet import Worksheet
33
35
 
34
36
  from . import VERSION
35
37
 
36
38
  __version__ = VERSION
37
39
 
38
- Workbook = xlsxwriter.Workbook
39
40
 
40
41
  XLBorderType: TypeAlias = Literal[
41
42
  "none",
@@ -132,7 +133,7 @@ class CFmtVal(TypedDict, total=False):
132
133
 
133
134
 
134
135
  @unique
135
- class CFmt(dict, Enum): # type: ignore
136
+ class CFmt(Enum): # type: ignore
136
137
  """
137
138
  Cell format enums for xlsxwriter Format objects.
138
139
 
@@ -194,7 +195,7 @@ class CFmt(dict, Enum): # type: ignore
194
195
  HDR_BORDER: ClassVar = TOP_BORDER | BOTTOM_BORDER
195
196
 
196
197
  @classmethod
197
- def add_new(self, _fmt_name: str, _xlsx_fmt_dict: CFmtVal, /) -> CFmt:
198
+ def add_new(cls, _fmt_name: str, _xlsx_fmt_dict: CFmtVal, /) -> CFmt:
198
199
  """
199
200
  Add new :class:`CFmt` object to instance.
200
201
 
@@ -204,9 +205,9 @@ class CFmt(dict, Enum): # type: ignore
204
205
  Name of new member to be added to :class:`CFmt`
205
206
  _xlsx_fmt_dict
206
207
  Any valid argument to :code:`xlsxwriter.Workbook.add_format()`, or union of
207
- same with one or more :class:`CFmt` objects, e.g.,
208
- :code:`CFmt.HDR_BORDER | CFmt.HDR_FILL` or
209
- :code:`CFmt.HDR_BORDER | {"pattern": 1, "bg_color": "f2f2f2"}`
208
+ same with the value of one or more :class:`CFmt` objects, e.g.,
209
+ :code:`CFmt.HDR_BORDER.value | CFmt.HDR_FILL.value` or
210
+ :code:`CFmt.HDR_BORDER.value | {"pattern": 1, "bg_color": "f2f2f2"}`
210
211
 
211
212
  Returns
212
213
  -------
@@ -214,11 +215,11 @@ class CFmt(dict, Enum): # type: ignore
214
215
 
215
216
  """
216
217
 
217
- return extend_enum(self, _fmt_name, _xlsx_fmt_dict) # type: ignore
218
+ return extend_enum(cls, _fmt_name, _xlsx_fmt_dict) # type: ignore
218
219
 
219
220
  @classmethod
220
221
  def ensure_cell_format_spec_tuple(
221
- self, _cell_format: Sequence[CFmt | Sequence[CFmt]], /
222
+ cls, _cell_format: Sequence[CFmt | Sequence[CFmt]], /
222
223
  ) -> bool:
223
224
  """
224
225
  Test that a given format specification is a tuple of :class:`CFmt` enums
@@ -242,7 +243,7 @@ class CFmt(dict, Enum): # type: ignore
242
243
 
243
244
  for _cf in _cell_format:
244
245
  if isinstance(_cf, tuple):
245
- self.ensure_cell_format_spec_tuple(_cf)
246
+ cls.ensure_cell_format_spec_tuple(_cf)
246
247
 
247
248
  if not (isinstance(_cf, CFmt),):
248
249
  raise ValueError(
@@ -254,11 +255,11 @@ class CFmt(dict, Enum): # type: ignore
254
255
 
255
256
  @classmethod
256
257
  def xl_fmt(
257
- self,
258
- _xl_book: xlsxwriter.Workbook,
258
+ cls,
259
+ _xl_book: Workbook,
259
260
  _cell_fmt: Sequence[CFmt | Sequence[CFmt]] | CFmt | None,
260
261
  /,
261
- ) -> xlsxwriter.format.Format:
262
+ ) -> Format:
262
263
  """
263
264
  Return :code:`xlsxwriter` :code:`Format` object given a :class:`CFmt` enum, or tuple thereof.
264
265
 
@@ -274,7 +275,7 @@ class CFmt(dict, Enum): # type: ignore
274
275
  ------
275
276
  ValueError
276
277
  If format specification is not one of None, a :class:`CFmt` enum, or
277
- a :code:`xlsxwriter.format.Format` object
278
+ a :code:`Format` object
278
279
 
279
280
  Returns
280
281
  -------
@@ -282,20 +283,20 @@ class CFmt(dict, Enum): # type: ignore
282
283
 
283
284
  """
284
285
 
285
- if isinstance(_cell_fmt, xlsxwriter.format.Format):
286
+ if isinstance(_cell_fmt, Format):
286
287
  return _cell_fmt
287
288
  elif _cell_fmt is None:
288
289
  return _xl_book.add_format(CFmt.XL_DEFAULT.value)
289
290
 
290
291
  _cell_fmt_dict: CFmtVal = {}
291
292
  if isinstance(_cell_fmt, Sequence):
292
- self.ensure_cell_format_spec_tuple(_cell_fmt)
293
+ cls.ensure_cell_format_spec_tuple(_cell_fmt)
293
294
  for _cf in _cell_fmt:
294
- _cell_fmt_dict = (
295
- (_cell_fmt_dict | _cfi.value for _cfi in _cf)
296
- if isinstance(_cf, Sequence)
297
- else _cell_fmt_dict | _cf.value
298
- )
295
+ if isinstance(_cf, Sequence):
296
+ for _cfi in _cf:
297
+ _cell_fmt_dict |= _cfi.value
298
+ else:
299
+ _cell_fmt_dict |= _cf.value
299
300
  elif isinstance(_cell_fmt, CFmt):
300
301
  _cell_fmt_dict = _cell_fmt.value
301
302
  else:
@@ -305,7 +306,7 @@ class CFmt(dict, Enum): # type: ignore
305
306
 
306
307
 
307
308
  def write_header(
308
- _xl_sheet: xlsxwriter.worksheet.Worksheet,
309
+ _xl_sheet: Worksheet,
309
310
  /,
310
311
  *,
311
312
  center_header: str | None = None,
@@ -348,7 +349,7 @@ def write_header(
348
349
 
349
350
 
350
351
  def write_footer(
351
- _xl_sheet: xlsxwriter.worksheet.Worksheet,
352
+ _xl_sheet: Worksheet,
352
353
  /,
353
354
  *,
354
355
  center_footer: str | None = None,
@@ -392,8 +393,8 @@ def write_footer(
392
393
 
393
394
 
394
395
  def array_to_sheet(
395
- _xl_book: xlsxwriter.workbook.Workbook,
396
- _xl_sheet: xlsxwriter.worksheet.Worksheet,
396
+ _xl_book: Workbook,
397
+ _xl_sheet: Worksheet,
397
398
  _data_table: Sequence[Any] | NDArray[Any],
398
399
  _row_id: int,
399
400
  _col_id: int = 0,
@@ -498,6 +499,7 @@ def array_to_sheet(
498
499
  _num_cols = len(_data_table[0])
499
500
  _right_column_id = _col_id + _num_cols
500
501
 
502
+ _cell_format: Sequence[CFmt | Sequence[CFmt]]
501
503
  if isinstance(cell_format, Sequence):
502
504
  if _num_rows > 1 and ragged_flag:
503
505
  raise ValueError(
@@ -512,10 +514,11 @@ def array_to_sheet(
512
514
  elif isinstance(cell_format, CFmt):
513
515
  _cell_format = (cell_format,) * len(_data_table[0])
514
516
  else:
515
- _cell_format = (CFmt.XL_DEFAULT,) * len(_data_table[0])
517
+ _cell_format = (CFmt.XL_DEFAULT,) * len(_data_table[0]) # pyright: ignore
516
518
 
517
519
  # construct vector of xlslwrter.format.Format objects
518
520
  _wbk_formats = tuple(CFmt.xl_fmt(_xl_book, _cf) for _cf in _cell_format)
521
+ _wbk_formats_greened = _wbk_formats
519
522
  if _num_rows > 1:
520
523
  _wbk_formats_greened = (
521
524
  tuple(
@@ -536,6 +539,7 @@ def array_to_sheet(
536
539
  for _ci, _cv in enumerate(_rv):
537
540
  _cf = _wbk_fmt_tuple[_ci]
538
541
  scalar_to_sheet(
542
+ _xl_book,
539
543
  _xl_sheet,
540
544
  _row_id + _ri,
541
545
  _col_id + _ci,
@@ -550,7 +554,8 @@ def array_to_sheet(
550
554
 
551
555
 
552
556
  def scalar_to_sheet(
553
- _xl_sheet: xlsxwriter.worksheet.Worksheet,
557
+ _xl_book: Workbook,
558
+ _xl_sheet: Worksheet,
554
559
  _cell_addr_0: str | int = "A1",
555
560
  /,
556
561
  *_s2s_args: Any,
@@ -591,9 +596,9 @@ def scalar_to_sheet(
591
596
 
592
597
  """
593
598
 
594
- _cell_addr: tuple[int | str, ...] = ()
595
- _cell_val: Any = None
596
- _cell_fmt: xlsxwriter.format.Format = CFmt.XL_DEFAULT
599
+ _cell_addr: tuple[str] | tuple[int, int]
600
+ _cell_val: Any
601
+ _cell_fmt: CFmt | Sequence[CFmt] | None
597
602
 
598
603
  if isinstance(_cell_addr_0, str):
599
604
  if len(_s2s_args) not in (1, 2):
@@ -603,6 +608,7 @@ def scalar_to_sheet(
603
608
  _cell_fmt = _s2s_args[1] if len(_s2s_args) == 2 else None
604
609
  elif isinstance(_cell_addr_0, int):
605
610
  if len(_s2s_args) not in (2, 3) or not isinstance(_s2s_args[0], int):
611
+ print(repr(_s2s_args))
606
612
  raise ValueError("Incorrect/incomplete specification for Excel cell data.")
607
613
  _cell_addr = (_cell_addr_0, _s2s_args[0])
608
614
  _cell_val = _s2s_args[1]
@@ -615,7 +621,9 @@ def scalar_to_sheet(
615
621
  if np.ndim(_cell_val) or _cell_val in (np.inf, -np.inf, np.nan)
616
622
  else (*_cell_addr, _cell_val)
617
623
  )
618
- _write_args = (*_write_args, _cell_fmt) if _cell_fmt else _write_args
624
+ _write_args = (
625
+ (*_write_args, CFmt.xl_fmt(_xl_book, _cell_fmt)) if _cell_fmt else _write_args
626
+ )
619
627
 
620
628
  if empty_as_blank and (_cell_val is None or _cell_val == ""):
621
629
  _xl_sheet.write_blank(*_write_args)