mergeron_extra 2024.739148.6__py3-none-any.whl → 2025.739411.0__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.
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import numpy as np
4
4
  from numpy.typing import NDArray
5
5
 
6
- VERSION = "2024.739148.6"
6
+ VERSION = "2025.739411.0"
7
7
 
8
8
  __version__ = VERSION
9
9
 
@@ -9,13 +9,15 @@ from __future__ import annotations
9
9
 
10
10
  from collections.abc import Sequence
11
11
  from dataclasses import dataclass
12
+ from itertools import starmap
12
13
  from typing import Literal
13
14
 
14
15
  import numpy as np
16
+ from mergeron import ArrayDouble, ArrayINT
15
17
  from scipy.optimize import OptimizeResult, root # type: ignore
16
18
  from scipy.stats import beta, chi2, norm # type: ignore
17
19
 
18
- from . import VERSION, ArrayDouble, ArrayINT
20
+ from . import VERSION
19
21
 
20
22
  __version__ = VERSION
21
23
 
@@ -29,12 +31,11 @@ def propn_ci(
29
31
  method: Literal[
30
32
  "Agresti-Coull", "Clopper-Pearson", "Exact", "Wilson", "Score"
31
33
  ] = "Wilson",
32
- ) -> tuple[
33
- ArrayDouble | float, ArrayDouble | float, ArrayDouble | float, ArrayDouble | float
34
- ]:
35
- """Returns point estimates and confidence interval for a proportion
34
+ ) -> ArrayDouble:
35
+ """
36
+ Point estimates and confidence interval for a proportion.
36
37
 
37
- Methods "Clopper-Pearson" and "Exact" are synoymous [3]_. Similarly,
38
+ Methods "Clopper-Pearson" and "Exact" are synonymous [3]_. Similarly,
38
39
  "Wilson" and "Score" are synonyms here.
39
40
 
40
41
  Parameters
@@ -65,37 +66,37 @@ def propn_ci(
65
66
  https://doi.org/10.1080/00031305.1998.10480550
66
67
 
67
68
  """
68
-
69
- for _f in _npos, _nobs:
70
- if not isinstance(_f, int | np.integer):
71
- raise ValueError(
72
- f"Count, {_f!r} must have type that is a subtype of np.integer."
73
- )
74
-
75
- if not _nobs:
76
- return (np.nan, np.nan, np.nan, np.nan)
77
-
78
- _raw_phat: ArrayDouble | float = _npos / _nobs
69
+ if any((
70
+ isinstance(_nobs, float) and not _nobs,
71
+ isinstance(_nobs, np.ndarray) and not _nobs.any(),
72
+ isinstance(_npos, float) and not _npos,
73
+ isinstance(_npos, np.ndarray) and not _npos.any(),
74
+ )):
75
+ return ArrayDouble([np.nan, np.nan, np.nan, np.nan])
76
+
77
+ _raw_phat = (
78
+ ArrayDouble(_npos / _nobs) if isinstance(_npos, np.ndarray) else _npos / _nobs
79
+ )
79
80
  _est_phat: ArrayDouble | float
80
81
  _est_ci_l: ArrayDouble | float
81
82
  _est_ci_u: ArrayDouble | float
82
83
 
83
84
  match method:
84
85
  case "Clopper-Pearson" | "Exact":
85
- _est_ci_l, _est_ci_u = (
86
- beta.ppf(*_f)
87
- for _f in (
86
+ _est_ci_l, _est_ci_u = starmap(
87
+ beta.ppf,
88
+ (
88
89
  (alpha / 2, _npos, _nobs - _npos + 1),
89
90
  (1 - alpha / 2, _npos + 1, _nobs - _npos),
90
- )
91
+ ),
91
92
  )
92
- _est_phat = 1 / 2 * (_est_ci_l + _est_ci_u)
93
+ _est_phat = 1 / 2 * (_est_ci_l + _est_ci_u) # type: ignore
93
94
 
94
95
  case "Agresti-Coull":
95
96
  _zsc = norm.ppf(1 - alpha / 2)
96
97
  _zscsq = _zsc * _zsc
97
98
  _adjmt = 4 if alpha == 0.05 else _zscsq
98
- _est_phat = (_npos + _adjmt / 2) / (_nobs + _adjmt)
99
+ _est_phat = (_npos + _adjmt / 2) / (_nobs + _adjmt) # type: ignore
99
100
  _est_ci_l, _est_ci_u = (
100
101
  _est_phat + _g
101
102
  for _g in [
@@ -120,7 +121,8 @@ def propn_ci(
120
121
  case _:
121
122
  raise ValueError(f"Method, {f'"{method}"'} not yet implemented.")
122
123
 
123
- return _raw_phat, _est_phat, _est_ci_l, _est_ci_u
124
+ retlist = [_raw_phat, _est_phat, _est_ci_l, _est_ci_u]
125
+ return ArrayDouble(retlist if isinstance(_npos, int) else np.hstack(retlist)) # type: ignore
124
126
 
125
127
 
126
128
  def propn_ci_multinomial(
@@ -165,18 +167,22 @@ def propn_ci_multinomial(
165
167
 
166
168
  if alternative == "default":
167
169
  _ci_len_half = np.sqrt(_chi2_cr * (_chi2_cr + 4 * _n * _prob * (1 - _prob)))
168
- return np.column_stack([
169
- (_chi2_cr + 2 * _counts + _f * _ci_len_half) / (2 * (_n + _chi2_cr))
170
- for _f in (-1, 1)
171
- ])
170
+ return ArrayDouble(
171
+ np.column_stack([
172
+ (_chi2_cr + 2 * _counts + _f * _ci_len_half) / (2 * (_n + _chi2_cr))
173
+ for _f in (-1, 1)
174
+ ])
175
+ )
172
176
 
173
177
  elif alternative == "simplified":
174
178
  _ci_len_half = np.sqrt(_chi2_cr * _prob * (1 - _prob) / _n)
175
- return np.column_stack([_prob + _f * _ci_len_half for _f in (-1, 1)])
179
+ return ArrayDouble(
180
+ np.column_stack([_prob + _f * _ci_len_half for _f in (-1, 1)])
181
+ )
176
182
 
177
183
  else:
178
184
  raise ValueError(
179
- f"Invalid value, {f'"{alternative}"'} for, \"alternative\". "
185
+ f'Invalid value, {f'"{alternative}"'} for, "alternative". '
180
186
  f"Must be one of '{'("default", "simplified")'}'."
181
187
  )
182
188
 
@@ -190,7 +196,7 @@ def propn_diff_ci(
190
196
  *,
191
197
  alpha: float = 0.05,
192
198
  method: Literal["Agresti-Caffo", "Mee", "M-N", "Newcombe", "Score"] = "M-N",
193
- ) -> tuple[float, float, float, float]:
199
+ ) -> ArrayDouble:
194
200
  R"""Confidence intervals for differences in binomial proportions.
195
201
 
196
202
  Methods available are Agresti-Caffo [4]_, Mee [5]_, Meitinen-Nurminen [5]_ [6]_
@@ -239,7 +245,7 @@ def propn_diff_ci(
239
245
  )
240
246
 
241
247
  if not min(_nobs1, _nobs2):
242
- return (np.nan, np.nan, np.nan, np.nan)
248
+ return ArrayDouble((np.nan, np.nan, np.nan, np.nan))
243
249
 
244
250
  match method:
245
251
  case "Agresti-Caffo":
@@ -260,7 +266,7 @@ def propn_diff_ci(
260
266
  case _:
261
267
  raise ValueError(f"Method, {f'"{method}"'} not implemented.")
262
268
 
263
- return _res
269
+ return ArrayDouble(_res)
264
270
 
265
271
 
266
272
  def _propn_diff_ci_agresti_caffo(
@@ -276,7 +282,6 @@ def _propn_diff_ci_agresti_caffo(
276
282
  Estimate Agresti-Caffo confidence intervals for differences of
277
283
  multiple proportions.
278
284
  """
279
-
280
285
  _diff_hat = _npos1 / _nobs1 - _npos2 / _nobs2
281
286
 
282
287
  _zsc = norm.ppf(1 - alpha / 2)
@@ -327,16 +332,18 @@ def _propn_diff_ci_newcombe_score(
327
332
 
328
333
 
329
334
  def _propn_diff_ci_mn(
330
- _npos1: int = 4,
331
- _nobs1: int = 10,
332
- _npos2: int = 4,
333
- _nobs2: int = 10,
335
+ _npos1: int | np.integer = 4,
336
+ _nobs1: int | np.integer = 10,
337
+ _npos2: int | np.integer = 4,
338
+ _nobs2: int | np.integer = 10,
334
339
  /,
335
340
  *,
336
341
  alpha: float = 0.05,
337
342
  method: Literal["M-N", "Mee"] = "M-N",
338
343
  ) -> tuple[float, float, float, float]:
339
344
  """
345
+ Meittinen-Nurminen (1985; Newcombe (1998)).
346
+
340
347
  See Miettinen and Nurminen (1985; Newcombe (1998);
341
348
  and StasAndCIs.r -> BinomDiffCi -> "mn".
342
349
 
@@ -354,7 +361,7 @@ def _propn_diff_ci_mn(
354
361
 
355
362
  _ci_est_start = np.array([(_diff_hat + _s) / 2 for _s in (-1, 1)])
356
363
  # Avoid potential corner cases
357
- _ci_est_offset = (1 - 1.055e-2, 1)
364
+ _ci_est_offset = (1 - 1.025e-2, 1)
358
365
  if _diff_hat == 1.0:
359
366
  _ci_est_start += _ci_est_offset
360
367
  elif _diff_hat == -1.0:
@@ -384,8 +391,12 @@ def _propn_diff_chisq_mn(
384
391
  *,
385
392
  method: Literal["M-N", "Mee"] = "M-N",
386
393
  ) -> float:
387
- R"""Estimate the :math:`\chi^2` statistic for the Meittinen-Nurminen (1985),
388
- and Newcombe (1998) confidence intervals for a difference in binomial proportions.
394
+ R"""
395
+ Estimate :math:`\chi^2` statistic for a difference in binomial proportions.
396
+
397
+ This :math:`\chi^2` statistic is used in the methods of Meittinen-Nurminen (1985),
398
+ and Newcombe (1998) for estimating confidence intervals for a difference in
399
+ binomial proportions.
389
400
 
390
401
  Parameters
391
402
  ----------
@@ -454,7 +465,6 @@ def propn_diff_ci_multinomial(
454
465
  Array of confidence intervals
455
466
 
456
467
  """
457
-
458
468
  if len(_counts.shape) > 2:
459
469
  raise ValueError(
460
470
  "This implementation is only valid for estimating confidence intervals "
@@ -465,7 +475,9 @@ def propn_diff_ci_multinomial(
465
475
  _var = np.einsum("jk->j", _prob * (1 - _prob) / _counts)[:, None]
466
476
 
467
477
  _d, _d_cr = np.diff(_prob, axis=1), norm.ppf(1 - (alpha / len(_counts)))
468
- return np.column_stack([_d + _f * _d_cr * np.sqrt(_var) for _f in (-1, 1)])
478
+ return ArrayDouble(
479
+ np.column_stack([_d + _f * _d_cr * np.sqrt(_var) for _f in (-1, 1)])
480
+ )
469
481
 
470
482
 
471
483
  @dataclass(slots=True, frozen=True)
@@ -496,7 +508,6 @@ def propn_test_multinomial(
496
508
  Estimated statistic, degrees of freedom, critical value, p-value
497
509
 
498
510
  """
499
-
500
511
  _n = np.einsum("jk->", _counts).astype(np.int64)
501
512
  _n_k = np.einsum("jk->k", _counts).astype(np.int64)
502
513
  _prob = _counts / _n_k
@@ -16,6 +16,7 @@ from collections.abc import Callable, Sequence
16
16
  from typing import Final, Literal, TypeAlias
17
17
 
18
18
  import numpy as np
19
+ from matplotlib import pyplot as plt
19
20
  from matplotlib.colors import LinearSegmentedColormap, to_rgba_array
20
21
 
21
22
 
@@ -670,18 +671,55 @@ TCName: TypeAlias = Literal[
670
671
  "bright", "high-contrast", "vibrant", "muted", "medium-contrast", "light"
671
672
  ]
672
673
  TCNameList: TypeAlias = tuple[TCName, ...]
673
- Bcset = namedtuple("Bcset", "blue red green yellow cyan purple grey black")
674
- Hcset = namedtuple("Hcset", "blue yellow red black")
675
- Vcset = namedtuple("Vcset", "orange blue cyan magenta red teal grey black")
674
+ Bcset = namedtuple(
675
+ "Bcset", ["blue", "red", "green", "yellow", "cyan", "purple", "grey", "black"]
676
+ )
677
+ Hcset = namedtuple("Hcset", ["blue", "yellow", "red", "black"])
678
+ Vcset = namedtuple(
679
+ "Vcset", ["orange", "blue", "cyan", "magenta", "red", "teal", "grey", "black"]
680
+ )
676
681
  Muset = namedtuple(
677
- "Muset", "rose indigo sand green cyan wine teal olive purple pale_grey black"
682
+ "Muset",
683
+ [
684
+ "rose",
685
+ "indigo",
686
+ "sand",
687
+ "green",
688
+ "cyan",
689
+ "wine",
690
+ "teal",
691
+ "olive",
692
+ "purple",
693
+ "pale_grey",
694
+ "black",
695
+ ],
678
696
  )
679
697
  Mcset = namedtuple(
680
- "Mcset", "light_blue dark_blue light_yellow dark_red dark_yellow light_red black"
698
+ "Mcset",
699
+ [
700
+ "light_blue",
701
+ "dark_blue",
702
+ "light_yellow",
703
+ "dark_red",
704
+ "dark_yellow",
705
+ "light_red",
706
+ "black",
707
+ ],
681
708
  )
682
709
  Lcset = namedtuple(
683
710
  "Lcset",
684
- "light_blue orange light_yellow pink light_cyan mint pear olive pale_grey black",
711
+ [
712
+ "light_blue",
713
+ "orange",
714
+ "light_yellow",
715
+ "pink",
716
+ "light_cyan",
717
+ "mint",
718
+ "pear",
719
+ "olive",
720
+ "pale_grey",
721
+ "black",
722
+ ],
685
723
  )
686
724
 
687
725
 
@@ -781,7 +819,6 @@ def tol_cset( # noqa: PLR0911
781
819
 
782
820
 
783
821
  def main() -> None:
784
- from matplotlib import pyplot as plt
785
822
 
786
823
  # Change default colorset (for lines) and colormap (for maps).
787
824
  # plt.rc('axes', prop_cycle=plt.cycler('color', list(tol_cset('bright'))))
@@ -25,7 +25,7 @@ from __future__ import annotations
25
25
 
26
26
  from collections.abc import Sequence
27
27
  from types import MappingProxyType
28
- from typing import Any, ClassVar, Literal, TypeAlias, TypedDict
28
+ from typing import Any, ClassVar, Literal, TypedDict, overload
29
29
 
30
30
  import numpy as np
31
31
  from aenum import Enum, extend_enum, unique # type: ignore
@@ -39,38 +39,39 @@ from . import VERSION
39
39
  __version__ = VERSION
40
40
 
41
41
 
42
- XLBorderType: TypeAlias = Literal[
43
- "none",
44
- "thin",
45
- "medium",
46
- "dashed",
47
- "dotted",
48
- "thick",
49
- "double",
50
- "hair",
51
- "medium_dashed",
52
- "dash_dot",
53
- "medium_dash_dot",
54
- "dash_dot_dot",
55
- "medium_dash_dot_dot",
56
- "slant_dash_dot",
57
- True,
58
- False,
59
- 0,
60
- 1,
61
- 2,
62
- 3,
63
- 4,
64
- 5,
65
- 6,
66
- 7,
67
- 8,
68
- 9,
69
- 10,
70
- 11,
71
- 12,
72
- 13,
73
- ]
42
+ type XLBorderType = (
43
+ Literal[
44
+ "none",
45
+ "thin",
46
+ "medium",
47
+ "dashed",
48
+ "dotted",
49
+ "thick",
50
+ "double",
51
+ "hair",
52
+ "medium_dashed",
53
+ "dash_dot",
54
+ "medium_dash_dot",
55
+ "dash_dot_dot",
56
+ "medium_dash_dot_dot",
57
+ "slant_dash_dot",
58
+ 0,
59
+ 1,
60
+ 2,
61
+ 3,
62
+ 4,
63
+ 5,
64
+ 6,
65
+ 7,
66
+ 8,
67
+ 9,
68
+ 10,
69
+ 11,
70
+ 12,
71
+ 13,
72
+ ]
73
+ | bool
74
+ )
74
75
 
75
76
 
76
77
  class CFmtVal(TypedDict, total=False):
@@ -91,18 +92,12 @@ class CFmtVal(TypedDict, total=False):
91
92
  shrink: bool
92
93
  bold: bool
93
94
  italic: bool
94
- underline: Literal[
95
- True,
96
- False,
97
- 1,
98
- 2,
99
- 33,
100
- 34,
101
- "single",
102
- "double",
103
- "accountingSingle",
104
- "accountingDouble",
105
- ]
95
+ underline: (
96
+ bool
97
+ | Literal[
98
+ 1, 2, 33, 34, "single", "double", "accountingSingle", "accountingDouble"
99
+ ]
100
+ )
106
101
  font_strikeout: bool
107
102
  font_script: Literal[1, 2]
108
103
 
@@ -261,7 +256,14 @@ class CFmt(Enum): # type: ignore
261
256
  def xl_fmt(
262
257
  cls,
263
258
  _xl_book: Workbook,
264
- _cell_fmt: Sequence[CFmt | Sequence[CFmt]] | CFmt | None,
259
+ _cell_format: CFmt
260
+ | MappingProxyType[CFmtVal, Any]
261
+ | Sequence[
262
+ CFmt
263
+ | MappingProxyType[CFmtVal, Any]
264
+ | Sequence[CFmt | MappingProxyType[CFmtVal, Any]]
265
+ ]
266
+ | None,
265
267
  /,
266
268
  ) -> Format:
267
269
  """
@@ -272,7 +274,7 @@ class CFmt(Enum): # type: ignore
272
274
  _xl_book
273
275
  :code:`xlsxwriter.Workbook` object
274
276
 
275
- _cell_fmt
277
+ _cell_format
276
278
  :class:`CFmt` enum object, or tuple thereof
277
279
 
278
280
  Raises
@@ -287,26 +289,26 @@ class CFmt(Enum): # type: ignore
287
289
 
288
290
  """
289
291
 
290
- if isinstance(_cell_fmt, Format):
291
- return _cell_fmt
292
- elif _cell_fmt is None:
293
- return _xl_book.add_format(CFmt.XL_DEFAULT.value)
292
+ if isinstance(_cell_format, Format):
293
+ return _cell_format
294
+ elif _cell_format is None:
295
+ return _xl_book.add_format(CFmt.XL_DEFAULT.value) # type: ignore
294
296
 
295
- _cell_fmt_dict: CFmtVal = {}
296
- if isinstance(_cell_fmt, Sequence):
297
- cls.ensure_cell_format_spec_tuple(_cell_fmt)
298
- for _cf in _cell_fmt:
297
+ _cell_format_dict: CFmtVal = {}
298
+ if isinstance(_cell_format, Sequence):
299
+ cls.ensure_cell_format_spec_tuple(_cell_format) # type: ignore
300
+ for _cf in _cell_format:
299
301
  if isinstance(_cf, Sequence):
300
302
  for _cfi in _cf:
301
- _cell_fmt_dict |= _cfi.value
303
+ _cell_format_dict |= _cfi.value # type: ignore
302
304
  else:
303
- _cell_fmt_dict |= _cf.value
304
- elif isinstance(_cell_fmt, CFmt):
305
- _cell_fmt_dict = _cell_fmt.value
305
+ _cell_format_dict |= _cf.value # type: ignore
306
+ elif isinstance(_cell_format, CFmt):
307
+ _cell_format_dict = _cell_format.value
306
308
  else:
307
309
  raise ValueError("Improperly specified format specification.")
308
310
 
309
- return _xl_book.add_format(_cell_fmt_dict)
311
+ return _xl_book.add_format(_cell_format_dict)
310
312
 
311
313
 
312
314
  def write_header(
@@ -502,7 +504,11 @@ def array_to_sheet(
502
504
  _num_cols = len(_data_table[0])
503
505
  _right_column_id = _col_id + _num_cols
504
506
 
505
- _cell_format: Sequence[CFmt | Sequence[CFmt]]
507
+ _cell_format: Sequence[
508
+ CFmt
509
+ | MappingProxyType[CFmtVal, Any]
510
+ | Sequence[CFmt | MappingProxyType[CFmtVal, Any]]
511
+ ]
506
512
  if isinstance(cell_format, Sequence):
507
513
  if _num_rows > 1 and ragged_flag:
508
514
  raise ValueError(
@@ -517,7 +523,7 @@ def array_to_sheet(
517
523
  elif isinstance(cell_format, CFmt):
518
524
  _cell_format = (cell_format,) * len(_data_table[0])
519
525
  else:
520
- _cell_format = (CFmt.XL_DEFAULT,) * len(_data_table[0])
526
+ _cell_format = (CFmt.XL_DEFAULT,) * len(_data_table[0]) # type: ignore
521
527
 
522
528
  # construct vector of xlslwrter.format.Format objects
523
529
  _wbk_formats = tuple(CFmt.xl_fmt(_xl_book, _cf) for _cf in _cell_format)
@@ -527,7 +533,7 @@ def array_to_sheet(
527
533
  tuple(
528
534
  CFmt.xl_fmt(
529
535
  _xl_book,
530
- (*_cf, CFmt.BAR_FILL)
536
+ (*_cf, CFmt.BAR_FILL) # type: ignore
531
537
  if isinstance(_cf, Sequence)
532
538
  else (_cf, CFmt.BAR_FILL),
533
539
  )
@@ -550,29 +556,57 @@ def array_to_sheet(
550
556
  return _bottom_row_id, _right_column_id
551
557
 
552
558
 
559
+ @overload
560
+ def scalar_to_sheet(
561
+ _xl_book: Workbook,
562
+ _xl_sheet: Worksheet,
563
+ _address0: str,
564
+ _value: Any,
565
+ _format: CFmt | Sequence[CFmt | Sequence[CFmt]] | None,
566
+ /,
567
+ ) -> None: ...
568
+
569
+
570
+ @overload
553
571
  def scalar_to_sheet(
554
572
  _xl_book: Workbook,
555
573
  _xl_sheet: Worksheet,
574
+ _address0: int,
575
+ _address1: int,
576
+ _value: Any,
577
+ _format: CFmt | Sequence[CFmt | Sequence[CFmt]] | None,
556
578
  /,
557
- *_s2s_args: tuple[str, Any, CFmt | Sequence[CFmt | Sequence[CFmt]] | None]
558
- | tuple[int, int, Any, CFmt | Sequence[CFmt | Sequence[CFmt]] | None],
579
+ ) -> None: ...
580
+
581
+
582
+ def scalar_to_sheet(
583
+ _xl_book: Workbook, _xl_sheet: Worksheet, /, *_s2s_args: Any
559
584
  ) -> None:
560
585
  """
561
586
  Write to a single cell in a worksheet.
562
587
 
563
588
  Parameters
564
589
  ----------
590
+ _xl_book
591
+ Workbook object for defining formats, and writing data
592
+
565
593
  _xl_sheet
566
- Worksheet object to which to write the give array
594
+ Worksheet object to which to write the given scalar
595
+
596
+ _cell_addr
597
+ An Excel cell address string in 'A1' format
598
+
599
+ _address0
600
+ Index-0 row number of destintaion cell
601
+
602
+ _address1
603
+ Index-0 column number of destintaion cell
567
604
 
568
- _cell_addr_0
569
- First element of a cell address, which may be the entire address
570
- in 'A1' format or the row-part in 'Row-column' format
605
+ _value
606
+ Value to write
571
607
 
572
- _s2s_args
573
- Other arguments, which may be just the cell value to be written and the
574
- cell format, or the column-part of the 'Row-column' address along with
575
- cell value and cell format.
608
+ _format
609
+ Member of :class:`CFmt`, or tuple thereof
576
610
 
577
611
  Raises
578
612
  ------
@@ -592,39 +626,42 @@ def scalar_to_sheet(
592
626
 
593
627
  """
594
628
 
595
- _cell_addr: tuple[str] | tuple[int, int]
596
- _cell_val: Any
597
- _cell_fmt: CFmt | Sequence[CFmt | Sequence[CFmt]] | None
629
+ _address: tuple[str] | tuple[int, int]
630
+ _value: Any
631
+ _format: CFmt | Sequence[CFmt | Sequence[CFmt]] | None
598
632
 
599
633
  if isinstance(_s2s_args[0], str):
600
634
  if len(_s2s_args) not in (2, 3):
601
635
  raise ValueError("Incorrect number of arguments.")
602
- _cell_addr = (_s2s_args[0],)
603
- _cell_val = _s2s_args[0]
604
- _cell_fmt = _s2s_args[1] if len(_s2s_args) == 2 else None
636
+ _address = (_s2s_args[0],)
637
+ _value = _s2s_args[1]
638
+ _format = _s2s_args[2] if len(_s2s_args) == 3 else None
605
639
  elif isinstance(_s2s_args[0], int):
606
640
  if not isinstance(_s2s_args[1], int) or len(_s2s_args) not in (3, 4):
607
641
  print(repr(_s2s_args))
608
642
  raise ValueError("Incorrect/incomplete specification for Excel cell data.")
609
- _cell_addr = _s2s_args[:2]
610
- _cell_val = _s2s_args[2]
611
- _cell_fmt = _s2s_args[3] if len(_s2s_args) == 3 else None
643
+ _address = _s2s_args[:2]
644
+ _value = _s2s_args[2]
645
+ _format = _s2s_args[3] if len(_s2s_args) == 4 else None
612
646
  else:
613
647
  raise ValueError("Incorrect/incomplete specification for Excel cell data.")
614
648
 
615
649
  _write_args = (
616
- (*_cell_addr, repr(_cell_val))
617
- if np.ndim(_cell_val) or _cell_val in (np.inf, -np.inf, np.nan)
618
- else (*_cell_addr, _cell_val)
650
+ *_address,
651
+ (
652
+ repr(_value)
653
+ if np.ndim(_value) or _value in (np.inf, -np.inf, np.nan)
654
+ else _value
655
+ ),
619
656
  )
620
- _write_args += (CFmt.xl_fmt(_xl_book, _cell_fmt),) if _cell_fmt else ()
657
+ _write_args += (CFmt.xl_fmt(_xl_book, _format),) if _format else ()
621
658
 
622
- if _cell_val is None or _cell_val == "":
659
+ if _value is None or _value == "":
623
660
  _xl_sheet.write_blank(*_write_args)
624
661
  elif (
625
- isinstance(_cell_val, str)
626
- or np.ndim(_cell_val)
627
- or _cell_val in (np.inf, -np.inf, np.nan)
662
+ isinstance(_value, str)
663
+ or np.ndim(_value)
664
+ or _value in (np.inf, -np.inf, np.nan)
628
665
  ):
629
666
  _xl_sheet.write_string(*_write_args)
630
667
  else:
@@ -1,8 +1,8 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: mergeron_extra
3
- Version: 2024.739148.6
3
+ Version: 2025.739411.0
4
4
  Summary: Tools for users of the mergeron package.
5
- License: MIT
5
+ License-Expression: MIT
6
6
  Author: Murthy Kambhampaty
7
7
  Author-email: smk@capeconomics.com
8
8
  Requires-Python: >=3.12,<4.0
@@ -14,13 +14,14 @@ Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Operating System :: OS Independent
15
15
  Classifier: Programming Language :: Python
16
16
  Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.12
18
- Classifier: Programming Language :: Python :: 3.13
19
17
  Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.12
20
19
  Classifier: Programming Language :: Python :: Implementation :: CPython
21
- Requires-Dist: aenum (>=3.1.15,<4.0.0)
20
+ Requires-Dist: aenum (>=3.1.15)
22
21
  Requires-Dist: certifi (>=2023.11.17)
22
+ Requires-Dist: frozendict (>=2.4.7)
23
23
  Requires-Dist: matplotlib (>=3.8)
24
+ Requires-Dist: mergeron (>=2026.739636.0)
24
25
  Requires-Dist: numpy (>=2.0)
25
26
  Requires-Dist: scipy (>=1.12)
26
27
  Requires-Dist: xlsxwriter (>=3.1)
@@ -0,0 +1,8 @@
1
+ mergeron_extra/__init__.py,sha256=61h1CNdWbUvuNLO2i8hEFL3CcIeh5lnlWis5qO_w4cU,399
2
+ mergeron_extra/proportions_tests.py,sha256=GWQ6rMhphe1XL55m8tuccGwshN9Tms9wmrfEZjpeaRw,15524
3
+ mergeron_extra/py.types,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ mergeron_extra/tol_colors.py,sha256=9x83ymz5xcmHAVmDzifLe_GZWvL03c7hxbKQW6XPLek,22626
5
+ mergeron_extra/xlsxw_helper.py,sha256=WW8sSqPSChlVsi60r2W4HSRB52ZWlEp35d1StHJa1HQ,19358
6
+ mergeron_extra-2025.739411.0.dist-info/METADATA,sha256=YxJQUGeKpl7gdrIVJmmfSTo3N2zfdZZhbxO_vzEBOWk,3773
7
+ mergeron_extra-2025.739411.0.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
8
+ mergeron_extra-2025.739411.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.1
2
+ Generator: poetry-core 2.3.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,8 +0,0 @@
1
- mergeron_extra/__init__.py,sha256=YPeb33DBYedoQAwmhXCenycYZPJ3XeDLOu691SvzeaI,399
2
- mergeron_extra/proportions_tests.py,sha256=3mctgM09M8Aee3l1zAlsYW1t962Ndzvb6bZkd7NHp7c,15019
3
- mergeron_extra/py.types,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- mergeron_extra/tol_colors.py,sha256=EgajNpN-BAlsD__E_-CgzGDRGy7j0rO97KpCTDdbZSc,22225
5
- mergeron_extra/xlsxw_helper.py,sha256=4mEGhmNG3aVHBHVWcaqI6qCvRLr_pogSGumxNubq_k8,18635
6
- mergeron_extra-2024.739148.6.dist-info/METADATA,sha256=Y5cIaeq-35dxs5cmRe0FhFVKFThTU3o2SldQr-R8kZw,3742
7
- mergeron_extra-2024.739148.6.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
8
- mergeron_extra-2024.739148.6.dist-info/RECORD,,