bs-python-utils 0.8.0__tar.gz → 0.8.1__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 (49) hide show
  1. bs_python_utils-0.8.1/LICENSE +21 -0
  2. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/PKG-INFO +9 -2
  3. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/README.md +3 -0
  4. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/__init__.py +14 -6
  5. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bivariate_quantiles.py +12 -5
  6. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_altair.py +36 -18
  7. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_logging.py +10 -5
  8. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_mem.py +6 -3
  9. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_opt.py +25 -12
  10. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_seaborn.py +3 -1
  11. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_sparse_gaussian.py +12 -6
  12. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bsmplutils.py +2 -1
  13. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bsnputils.py +1 -1
  14. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/chebyshev.py +1 -1
  15. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/distance_covariances.py +1 -1
  16. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils.egg-info/PKG-INFO +9 -2
  17. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils.egg-info/SOURCES.txt +1 -0
  18. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils.egg-info/requires.txt +2 -0
  19. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/pyproject.toml +7 -2
  20. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/Timer.py +0 -0
  21. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_mathstr.py +0 -0
  22. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_plots.py +0 -0
  23. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bssputils.py +0 -0
  24. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bsstats.py +0 -0
  25. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bsutils.py +0 -0
  26. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_altair.py +0 -0
  27. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_distance_covariances.py +0 -0
  28. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_mem.py +0 -0
  29. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_mpl.py +0 -0
  30. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_opt.py +0 -0
  31. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_seaborn.py +0 -0
  32. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_sklearn.py +0 -0
  33. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/pandas_utils.py +0 -0
  34. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/sklearn_utils.py +0 -0
  35. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/streamlit_utils.py +0 -0
  36. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils.egg-info/dependency_links.txt +0 -0
  37. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils.egg-info/top_level.txt +0 -0
  38. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/setup.cfg +0 -0
  39. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bivariate_quantiles.py +0 -0
  40. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bs_opt.py +0 -0
  41. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bs_sparse_gaussian.py +0 -0
  42. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bsnputils.py +0 -0
  43. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bssputils.py +0 -0
  44. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bsstats.py +0 -0
  45. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bsutils.py +0 -0
  46. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_chebyshev.py +0 -0
  47. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_nptri.py +0 -0
  48. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_random_draws.py +0 -0
  49. {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_sklearn_utils.py +0 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023, Bernard Salanie
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bs-python-utils
3
- Version: 0.8.0
4
- Summary: Add your description here
3
+ Version: 0.8.1
4
+ Summary: Utilities programs for my Python code
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
7
+ License-File: LICENSE
7
8
  Requires-Dist: altair>=5.5.0
8
9
  Requires-Dist: altair-saver>=0.5.0
9
10
  Requires-Dist: emcee>=3.1.6
@@ -15,12 +16,15 @@ Requires-Dist: numpy>=2.3.3
15
16
  Requires-Dist: pandas>=2.3.2
16
17
  Requires-Dist: pre-commit>=4.3.0
17
18
  Requires-Dist: pytest>=8.4.2
19
+ Requires-Dist: mypy
20
+ Requires-Dist: ruff>=0.14.0
18
21
  Requires-Dist: scikit-learn>=1.7.2
19
22
  Requires-Dist: scipy>=1.16.2
20
23
  Requires-Dist: seaborn>=0.13.2
21
24
  Requires-Dist: statsmodels>=0.14.5
22
25
  Requires-Dist: streamlit>=1.49.1
23
26
  Requires-Dist: vega-datasets>=0.9.0
27
+ Dynamic: license-file
24
28
 
25
29
  # bs-python-utils
26
30
 
@@ -37,6 +41,9 @@ Requires-Dist: vega-datasets>=0.9.0
37
41
 
38
42
  ### Release notes
39
43
 
44
+ #### 0.8.1 (October 18, 2025)
45
+ Deleted extra examples scripts.
46
+
40
47
  #### 0.8 (October 14, 2025)
41
48
  Switched to `uv` for project management. Used Codex to clean up the code and generate more tests. Added the `examples` subdirectory.
42
49
 
@@ -13,6 +13,9 @@
13
13
 
14
14
  ### Release notes
15
15
 
16
+ #### 0.8.1 (October 18, 2025)
17
+ Deleted extra examples scripts.
18
+
16
19
  #### 0.8 (October 14, 2025)
17
20
  Switched to `uv` for project management. Used Codex to clean up the code and generate more tests. Added the `examples` subdirectory.
18
21
 
@@ -1,6 +1,8 @@
1
- """This package contains a number of functions that I have found useful in my programming.
1
+ """This package contains a number of functions that I have found useful in my
2
+ programming.
2
3
 
3
- * `bsutils` has (inter alia) some I/O functions, error reporting, and $C^2$ extensions of log and exp
4
+ * `bsutils` has (inter alia) some I/O functions, error reporting, and $C^2$
5
+ extensions of log and exp
4
6
  * `bs_logging` has customized logging
5
7
  * `bs_mathstr` has Unicode for math strings
6
8
  * `bs_mem` reports memory usage
@@ -9,12 +11,18 @@
9
11
  * `bssputils` has Scipy functions
10
12
  * `sklearn_utils` has Sklearn functions
11
13
  * `pandas_utils` has Pandas functions
12
- * `bsstats` has TSLS code; nonparametric and flexible estimation; and code to draw random samples
14
+ * `bsstats` has TSLS code; nonparametric and flexible estimation; and code to
15
+ draw random samples
13
16
  * `bs_opt` interfaces with `scipy.optimize`
14
- * `bs_sparse_gaussian` uses sparse integration to evaluate $E f(X)$ for $X \\simeq N(0,1)$
17
+ * `bs_sparse_gaussian` uses sparse integration to evaluate $E f(X)$ for
18
+ $X \\simeq N(0,1)$
15
19
  * `chebyshev` has Chebyshev interpolation and integration in dimensions 1 and 2
16
20
  * `distance_covariances` has measures of nonlinear dependence between random variables
17
- * `bivariate_quantiles` computes quantiles and ranks for 2-dimensional random variables à la [Chernozhukov-Galichon-Hallin-Henry (*Ann. Stats.* 2017)](https://projecteuclid.org/journals/annals-of-statistics/volume-45/issue-1/MongeKantorovich-depth-quantiles-ranks-and-signs/10.1214/16-AOS1450.full).
21
+ * `bivariate_quantiles` computes quantiles and ranks for 2-dimensional random
22
+ variables à la [Chernozhukov-Galichon-Hallin-Henry (*Ann. Stats.* 2017)](
23
+ https://projecteuclid.org/journals/annals-of-statistics/volume-45/issue-1/
24
+ MongeKantorovich-depth-quantiles-ranks-and-signs/10.1214/16-AOS1450.full).
18
25
 
19
- * `bs_plots` gathers plotting routines in Matplotlib, Seaborn and Altair from `bsmplutils`, `bs_seaborn`, and `bs_altair`.
26
+ * `bs_plots` gathers plotting routines in Matplotlib, Seaborn and Altair from
27
+ `bsmplutils`, `bs_seaborn`, and `bs_altair`.
20
28
  """
@@ -1,5 +1,8 @@
1
1
  """This takes in observations of a bivariate random variable `y`
2
- and computes vector quantiles and vector ranks à la [Chernozhukov-Galichon-Hallin-Henry (*Ann. Stats.* 2017)](https://projecteuclid.org/journals/annals-of-statistics/volume-45/issue-1/MongeKantorovich-depth-quantiles-ranks-and-signs/10.1214/16-AOS1450.full).
2
+ and computes vector quantiles and vector ranks à la
3
+ [Chernozhukov-Galichon-Hallin-Henry (*Ann. Stats.* 2017)](
4
+ https://projecteuclid.org/journals/annals-of-statistics/volume-45/
5
+ issue-1/MongeKantorovich-depth-quantiles-ranks-and-signs/10.1214/16-AOS1450.full).
3
6
 
4
7
 
5
8
  Note:
@@ -7,10 +10,12 @@ Note:
7
10
 
8
11
  The sequence of steps is as follows:
9
12
 
10
- * choose a number of Chebyshev nodes for numerical integration and optimize the weights: `v = solve_for_v(y, n_nodes)`
13
+ * choose a number of Chebyshev nodes for numerical integration and optimize
14
+ the weights: `v = solve_for_v(y, n_nodes)`
11
15
  * to obtain the $(u_1,u_2)$ quantiles for $(u_1, u_2)\\in [0,1]$, run
12
16
  `qtiles_y = bivariate_quantiles_v(y, v, u1, u2)`
13
- * to compute the vector ranks for all points in the sample (the barycenters of the cells in the power diagram):
17
+ * to compute the vector ranks for all points in the sample (the barycenters
18
+ of the cells in the power diagram):
14
19
  `ranks_y = bivariate_ranks_v(y, v, n_nodes)`
15
20
 
16
21
  Steps 1 and 2 can be combined: `qtiles_y = bivariate_quantiles(y, v, u1, u2, n_nodes)`
@@ -122,7 +127,8 @@ def bivariate_ranks_v(
122
127
  y: Observations with shape ``(n, 2)``.
123
128
  v: Dual weights returned by ``solve_for_v_``.
124
129
  n_nodes: Number of Chebyshev nodes used in the quadrature.
125
- presorted: Set to ``True`` when ``y``/``v`` are pre-sorted by the second coordinate.
130
+ presorted: Set to ``True`` when ``y``/``v`` are pre-sorted by the
131
+ second coordinate.
126
132
 
127
133
  Returns:
128
134
  Array of average ranks (shape ``(n, 2)``) with ``nan`` for zero-mass cells.
@@ -228,7 +234,8 @@ def solve_for_v_(y: np.ndarray, n_nodes: int = 32, verbose: bool = False) -> np.
228
234
  verbose: Print optimisation diagnostics when ``True``.
229
235
 
230
236
  Returns:
231
- Array of length ``n`` containing the optimal weights (including the residual term).
237
+ Array of length ``n`` containing the optimal weights (including the
238
+ residual term).
232
239
  """
233
240
  n, d = y.shape
234
241
 
@@ -2,13 +2,19 @@
2
2
 
3
3
  * `alt_lineplot`, `alt_superposed_lineplot`, `alt_superposed_faceted_lineplot`
4
4
  * `alt_plot_fun`: plots a function
5
- * `alt_density`, `alt_faceted_densities`: plots the density of `x`, or of `x` conditional on a category
6
- * `alt_superposed_faceted_densities`: plots the density of `x` superposed by `f` and faceted by `g`
7
- * `alt_scatterplot`, `alt_scatterplot_with_histo`, `alt-linked_scatterplots`: variants of scatter plots
8
- * `alt_histogram_by`, `alt_histogram_continuous`: histograms of `x` by `y`, and of a continuous `x`
5
+ * `alt_density`, `alt_faceted_densities`: plots the density of `x`, or of `x`
6
+ conditional on a category
7
+ * `alt_superposed_faceted_densities`: plots the density of `x` superposed by
8
+ `f` and faceted by `g`
9
+ * `alt_scatterplot`, `alt_scatterplot_with_histo`, `alt-linked_scatterplots`:
10
+ variants of scatter plots
11
+ * `alt_histogram_by`, `alt_histogram_continuous`: histograms of `x` by `y`,
12
+ and of a continuous `x`
9
13
  * `alt_stacked_area`,`alt_stacked_area_facets`: stacked area plots
10
- * `plot_parameterized_estimates`: plots densities of estimates of coefficients, with the true values, as a function of a parameter
11
- * `plot_true_sim_facets, plot_true_sim2_facets`: plot two simulated values and the true values of statistics as a function of a parameter
14
+ * `plot_parameterized_estimates`: plots densities of estimates of
15
+ coefficients, with the true values, as a function of a parameter
16
+ * `plot_true_sim_facets, plot_true_sim2_facets`: plot two simulated values
17
+ and the true values of statistics as a function of a parameter
12
18
  * `alt_tick_plots`: vertically arranged tick plots of variables
13
19
  * `alt_matrix_heatmap`: plots a heatmap of a matrix.
14
20
  """
@@ -66,7 +72,8 @@ def alt_scatterplot(
66
72
  title: Optional chart title.
67
73
  color: Column used for color encoding.
68
74
  aggreg: Optional aggregation function for ``str_y`` (e.g. ``"mean"``).
69
- selection: When ``True`` and a ``color`` is supplied, enable legend-based multi-selection.
75
+ selection: When ``True`` and a ``color`` is supplied, enable
76
+ legend-based multi-selection.
70
77
 
71
78
  Returns:
72
79
  The Altair ``Chart`` for further composition or rendering.
@@ -134,7 +141,8 @@ def alt_boxes(
134
141
  title: str | None = None,
135
142
  save: str | None = None,
136
143
  ) -> alt.Chart:
137
- """horizontal boxplots of `df[continuous_var]` by `df[discrete_var]` and `df[group_var]`
144
+ """horizontal boxplots of `df[continuous_var]` by `df[discrete_var]` and
145
+ `df[group_var]`
138
146
 
139
147
  Args:
140
148
  df: datframe with the three variables
@@ -143,7 +151,8 @@ def alt_boxes(
143
151
  group_var: name of the grouping variable
144
152
  max_cols: maximum number of columns. Defaults to 3.
145
153
  title: a plot title. Defaults to None.
146
- save: the name of a file to save to (HTML extension will be added). Defaults to None.
154
+ save: the name of a file to save to (HTML extension will be added).
155
+ Defaults to None.
147
156
 
148
157
  Returns:
149
158
  the chart.
@@ -372,8 +381,10 @@ def alt_linked_scatterplots(
372
381
  save: str | None = None,
373
382
  ) -> alt.Chart:
374
383
  """
375
- Creates two scatterplots: of `df[str_x1]` vs `df[str_y]` and of `df[str_x2]` vs `df[str_y]`,
376
- both with color as per `df[str_f]`. Selecting an interval in one shows up in the other.
384
+ Creates two scatterplots: of `df[str_x1]` vs `df[str_y]` and of
385
+ `df[str_x2]` vs `df[str_y]`,
386
+ both with color as per `df[str_f]`. Selecting an interval in one shows up
387
+ in the other.
377
388
 
378
389
  Args:
379
390
  df:
@@ -408,7 +419,8 @@ def alt_scatterplot_with_histo(
408
419
  ) -> alt.Chart:
409
420
  """
410
421
  Scatterplot of `df[str_x]` vs `df[str_y]` with colors as per `df[str_f]`
411
- allows to select an interval and histograns the counts of `df[str_f]` in the interval.
422
+ allows to select an interval and histograns the counts of `df[str_f]` in
423
+ the interval.
412
424
 
413
425
  Args:
414
426
  df: the data with the `str_x` and `str_f` variables
@@ -544,7 +556,8 @@ def alt_superposed_faceted_lineplot(
544
556
  save: str | None = None,
545
557
  ) -> alt.Chart:
546
558
  """
547
- Plots `df[str_x]` vs `df[str_y]` superposed by `df[str_f]` and faceted by `df[str_g]`
559
+ Plots `df[str_x]` vs `df[str_y]` superposed by `df[str_f]` and faceted by
560
+ `df[str_g]`
548
561
 
549
562
  Args:
550
563
  df: the data with the `str_x`, `str_y`, and `str_f` variables
@@ -683,7 +696,8 @@ def alt_stacked_area_facets(
683
696
  save: str | None = None,
684
697
  ) -> alt.Chart:
685
698
  """
686
- Normalized stacked lineplots of `df[str_x]` vs `df[str_y]` by `df[str_f]`, faceted by `df[str_g]`
699
+ Normalized stacked lineplots of `df[str_x]` vs `df[str_y]` by `df[str_f]`,
700
+ faceted by `df[str_g]`
687
701
 
688
702
  Args:
689
703
  df: the data with columns for `str_x`, `str_y`, and `str_f`
@@ -721,7 +735,8 @@ def _stack_estimates(
721
735
  estimate_names: str | list[str], estimates: np.ndarray, df: pd.DataFrame
722
736
  ) -> tuple[pd.DataFrame, list[str]]:
723
737
  """
724
- adds to a dataframe `df` columns with names `estimate_names` for various `estimates of one coefficient
738
+ adds to a dataframe `df` columns with names `estimate_names` for various
739
+ `estimates of one coefficient
725
740
 
726
741
  Args:
727
742
  estimate_names: names of the n estimate columns to be added
@@ -767,7 +782,8 @@ def plot_parameterized_estimates(
767
782
  save: str | None = None,
768
783
  ) -> alt.Chart:
769
784
  """
770
- Plots estimates of coefficients, with the true values, as a function of a parameter; one facet per coefficient
785
+ Plots estimates of coefficients, with the true values, as a function of a
786
+ parameter; one facet per coefficient
771
787
 
772
788
  Args:
773
789
  parameter_name: the name of the parameter
@@ -871,7 +887,8 @@ def plot_true_sim_facets(
871
887
  save: str | None = None,
872
888
  ) -> alt.Chart:
873
889
  """
874
- Plots simulated and true values of statistics as a function of a parameter; one facet per coefficient
890
+ Plots simulated and true values of statistics as a function of a parameter;
891
+ one facet per coefficient
875
892
 
876
893
  Args:
877
894
  parameter_name: the name of the parameter
@@ -972,7 +989,8 @@ def plot_true_sim2_facets(
972
989
  save: str | None = None,
973
990
  ) -> alt.Chart:
974
991
  """
975
- Plots simulated values for two methods and true values of statistics as a function of a parameter;
992
+ Plots simulated values for two methods and true values of statistics as a
993
+ function of a parameter;
976
994
  one facet per coefficient
977
995
 
978
996
  Args:
@@ -21,7 +21,8 @@ def init_logger(
21
21
 
22
22
  Args:
23
23
  logger_name: name for the logger
24
- log_level_for_console: minimum level of messages logged to the console logging
24
+ log_level_for_console: minimum level of messages logged to the
25
+ console logging
25
26
  log_level_for_file:
26
27
  save_dir:
27
28
 
@@ -35,10 +36,13 @@ def init_logger(
35
36
 
36
37
  This will create two logs:
37
38
 
38
- * one printed to console where we run the code (the `StreamHandler`),
39
- * and one that will be saved to file `save_dir/logger_name.txt` (the `FileHandler`).
39
+ * one printed to console where we run the code (the
40
+ `StreamHandler`),
41
+ * and one that will be saved to file `save_dir/logger_name.txt`
42
+ (the `FileHandler`).
40
43
 
41
- `'logger.propagate = False'` makes sure that the logs sent to file will not be printed to console.
44
+ `'logger.propagate = False'` makes sure that the logs sent to file
45
+ will not be printed to console.
42
46
 
43
47
  We use the `Formatter` class to define the format of the logs.
44
48
  Here:
@@ -49,7 +53,8 @@ def init_logger(
49
53
  and the line number, `lineno`.
50
54
  * Lastly, the message itself — `message`.
51
55
 
52
- The default has only `INFO` logs and above (i.e., also `WARNING, ERROR` and `CRITICAL`)
56
+ The default has only `INFO` logs and above (i.e., also
57
+ `WARNING, ERROR` and `CRITICAL`)
53
58
  displayed in the console; the file will also include `DEBUG` logs.
54
59
  """
55
60
  logger = logging.getLogger()
@@ -1,8 +1,10 @@
1
1
  """Reports on memory usage:
2
2
 
3
3
  * `mem_usage`: prints the top `n` largest global items in memory
4
- * `memory_display_top`: prints the top `n` largest memory allocations since tracing started
5
- * `memory_display_top_diffs`: prints the top `n` largest memory allocations since the last snapshot.
4
+ * `memory_display_top`: prints the top `n` largest memory allocations
5
+ since tracing started
6
+ * `memory_display_top_diffs`: prints the top `n` largest memory
7
+ allocations since the last snapshot.
6
8
  """
7
9
 
8
10
  import linecache
@@ -67,7 +69,8 @@ def memory_display_top(
67
69
  snapshot: tracemalloc.Snapshot, key_type: str = "lineno", limit: int | None = 5
68
70
  ) -> None:
69
71
  """
70
- prints out the lines with the top `limit` allocations of memory since `tracemalloc.start()`
72
+ prints out the lines with the top `limit` allocations of memory since
73
+ `tracemalloc.start()`
71
74
 
72
75
  Args:
73
76
  snapshot: obtained from tracemalloc.take_snapshot()
@@ -3,12 +3,17 @@
3
3
  * `ScalarFunctionAndGradient`, `ProximalFunction` type aliases
4
4
  * an `OptimizeParams` class
5
5
  * `check_gradient_scalar_function` checks whether an analytical gradient is correct
6
- * `acc_grad_descent`: accelerated gradient descent for convex, possibly non-smooth functions
7
- * `minimize_some_fixed`: minimizes a function with some parameter values possibly fixed and some possibly within bounds, using L-BFGS-B
8
- * `minimize_free`: minimizes a function with some parameter values possibly within bounds
9
- * `dfp_update, bfgs_update`: compute updates to the inverese Hessian
10
- * `armijo_alpha, barzilai_borwein_alpha`: two ways of computing the step length
11
- * `print_optimization_results`, `print_constrained_optimization_results` format the results.
6
+ * `acc_grad_descent`: accelerated gradient descent for convex, possibly
7
+ non-smooth functions
8
+ * `minimize_some_fixed`: minimizes a function with some parameter values
9
+ possibly fixed and some possibly within bounds, using L-BFGS-B
10
+ * `minimize_free`: minimizes a function with some parameter values possibly
11
+ within bounds
12
+ * `dfp_update, bfgs_update`: compute updates to the inverse Hessian
13
+ * `armijo_alpha, barzilai_borwein_alpha`: two ways of computing the step
14
+ length
15
+ * `print_optimization_results`, `print_constrained_optimization_results`
16
+ format the results.
12
17
  """
13
18
 
14
19
  from dataclasses import dataclass
@@ -27,7 +32,9 @@ from bs_python_utils.Timer import timeit
27
32
  ScalarFunctionAndGradient = Callable[
28
33
  [np.ndarray, Iterable, Optional[bool]], Union[float, tuple[float, np.ndarray]]
29
34
  ]
30
- """Type of `f(v, args, gr)` that returns a scalar value and also a gradient if `gr` is `True`."""
35
+ """Type of `f(v, args, gr)` that returns a scalar value and also a gradient if
36
+ `gr` is `True`.
37
+ """
31
38
 
32
39
 
33
40
  ProximalFunction = Callable[[np.ndarray, float, Iterable], np.ndarray]
@@ -36,7 +43,9 @@ ProximalFunction = Callable[[np.ndarray, float, Iterable], np.ndarray]
36
43
 
37
44
  @dataclass
38
45
  class OptimizeParams:
39
- """used for optimization; combines values, bounds and initial values for a parameter vector"""
46
+ """used for optimization; combines values, bounds and initial values for a
47
+ parameter vector
48
+ """
40
49
 
41
50
  params_values: np.ndarray | None
42
51
  params_bounds: list[tuple] | None
@@ -137,7 +146,8 @@ def armijo_alpha(
137
146
  c1: Armijo sufficient-decrease constant.
138
147
 
139
148
  Returns:
140
- Step size satisfying the Armijo condition; returns ``0.0`` when the supplied direction
149
+ Step size satisfying the Armijo condition; returns ``0.0`` when the
150
+ supplied direction
141
151
  is numerically orthogonal to the gradient.
142
152
  """
143
153
  f0 = f(x, args)
@@ -177,7 +187,8 @@ def barzilai_borwein_alpha(
177
187
  args: Extra arguments passed to the gradient.
178
188
 
179
189
  Returns:
180
- A tuple ``(alpha, gradient)`` where ``alpha`` is the safeguarded BB step size.
190
+ A tuple ``(alpha, gradient)`` where ``alpha`` is the safeguarded BB
191
+ step size.
181
192
  """
182
193
  eps = 1e-12
183
194
  g = grad_f(x, args)
@@ -391,10 +402,12 @@ def minimize_some_fixed(
391
402
  grad_obj: its gradient function
392
403
  fixed_vars: a list if the indices of variables whose values are fixed
393
404
  fixed_vals: their fixed values
394
- x_init: the initial values of all variables (those on fixed variables are not used)
405
+ x_init: the initial values of all variables (those on fixed variables
406
+ are not used)
395
407
  args: other parameters
396
408
  options: any options passed on to `scipy.optimize.minimize`
397
- bounds: the bounds on all variables (those on fixed variables are not used)
409
+ bounds: the bounds on all variables (those on fixed variables are
410
+ not used)
398
411
  time_execution: if `True`, time the execution and print the result
399
412
 
400
413
  Returns:
@@ -4,7 +4,9 @@
4
4
  * `bs_sns_bar_x_byf`: make a bar plot of `x` by `f`
5
5
  * `bs_sns_bar_x_byfg`: make a bar plot of `x` by `f` and `g`
6
6
  * `bs_sns_plot_density`: basic density plot
7
- * `bs_sns_density_estimates`: plots the densities of estimates of several coefficients with several methods, superposed by methods and faceted by coefficients.
7
+ * `bs_sns_density_estimates`: plots the densities of estimates of several
8
+ coefficients with several methods, superposed by methods and faceted by
9
+ coefficients.
8
10
  """
9
11
 
10
12
  from collections.abc import Callable
@@ -1,11 +1,15 @@
1
1
  """
2
- Sets up sparse integration over a Gaussian, given text files that contain rescaled Gauss-Hermite nodes and weights.
2
+ Sets up sparse integration over a Gaussian, given text files that contain
3
+ rescaled Gauss-Hermite nodes and weights.
3
4
 
4
- These files must be named `GHsparseGrid{ndims}prec{iprec}.txt`, where `ndims` is the number of dimensions of integration
5
- and `iprec` is a precision level that must be 9, 13, or (most precise) 17. The file must have `(ndims+1)` columns,
5
+ These files must be named `GHsparseGrid{ndims}prec{iprec}.txt`, where
6
+ `ndims` is the number of dimensions of integration
7
+ and `iprec` is a precision level that must be 9, 13, or (most precise) 17.
8
+ The file must have `(ndims+1)` columns,
6
9
  with the weights in the first column.
7
10
 
8
- The nodes and weights are rescaled so that `f(nodes) @ weights` approximates `Ef(X)` for `X` an `N(0,I)` variable.
11
+ The nodes and weights are rescaled so that `f(nodes) @ weights` approximates
12
+ `Ef(X)` for `X` an `N(0,I)` variable.
9
13
  """
10
14
 
11
15
  from pathlib import Path
@@ -20,7 +24,8 @@ def setup_sparse_gaussian(
20
24
  ndims: int, iprec: int, GHsparsedir: str | None = None
21
25
  ) -> TwoArrays:
22
26
  """
23
- Get nodes and weights for sparse integration Ef(X) with X = N(0,1) in `ndims` dimensions.
27
+ Get nodes and weights for sparse integration Ef(X) with X = N(0,1) in
28
+ `ndims` dimensions.
24
29
 
25
30
  Examples:
26
31
  >>> nodes, weights = setup_sparse_gaussian(mdims, iprec)
@@ -33,7 +38,8 @@ def setup_sparse_gaussian(
33
38
 
34
39
  Returns:
35
40
  a pair of arrays `nodes` and `weights`;
36
- `nodes` has `ndims-1` columns and `weights` is a vector with the same number of rows.
41
+ `nodes` has `ndims-1` columns and `weights` is a vector with the same
42
+ number of rows.
37
43
  """
38
44
  GHdir = (
39
45
  Path.home() / "Dropbox" / "GHsparseGrids"
@@ -2,7 +2,8 @@
2
2
  A Matplotlib utility program:
3
3
 
4
4
  * `ax_text`: annotate an `ax` with text.
5
- * `bs_mpl_plot_dcm_fit`: generates a boxplot of the predicted probas for a discrete choice model
5
+ * `bs_mpl_plot_dcm_fit`: generates a boxplot of the predicted probas for a
6
+ discrete choice model
6
7
  """
7
8
 
8
9
  import matplotlib.axes as axes
@@ -781,7 +781,7 @@ def outer_bivar(pol1: Polynomial, pol2: Polynomial) -> BivariatePolynomial:
781
781
  """
782
782
  p1 = pol1.coef
783
783
  p2 = pol2.coef
784
- prod_coef = np.outer(p1, p2)
784
+ prod_coef = np.outer(p1, p2) # type: ignore
785
785
  return BivariatePolynomial(prod_coef)
786
786
 
787
787
 
@@ -161,7 +161,7 @@ def cheb_get_coefficients_1d(
161
161
  x = cast(np.ndarray, move_from1m1(t, interval))
162
162
  return fun(x)
163
163
 
164
- c = ncheb.chebinterpolate(fun_t, degree)
164
+ c = ncheb.chebinterpolate(fun_t, degree) # type: ignore
165
165
  return cast(np.ndarray, c)
166
166
 
167
167
 
@@ -240,7 +240,7 @@ def _pdcovs_bootstrap(
240
240
  C_YZ = _dcov_prod(Y_ddi, Z_ddi, unbiased)
241
241
  C_ZZ = _dcov_prod(Z_ddi, Z_ddi, unbiased)
242
242
  pdcov_stats_boot[idraw] = C_XY - (C_XZ * C_YZ) / C_ZZ
243
- return n * pdcov_stats_boot
243
+ return cast(np.ndarray, n * pdcov_stats_boot)
244
244
 
245
245
 
246
246
  def pvalue_pdcov(pdcov_results: PdcovResults, ndraws: int = 199) -> float:
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bs-python-utils
3
- Version: 0.8.0
4
- Summary: Add your description here
3
+ Version: 0.8.1
4
+ Summary: Utilities programs for my Python code
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
7
+ License-File: LICENSE
7
8
  Requires-Dist: altair>=5.5.0
8
9
  Requires-Dist: altair-saver>=0.5.0
9
10
  Requires-Dist: emcee>=3.1.6
@@ -15,12 +16,15 @@ Requires-Dist: numpy>=2.3.3
15
16
  Requires-Dist: pandas>=2.3.2
16
17
  Requires-Dist: pre-commit>=4.3.0
17
18
  Requires-Dist: pytest>=8.4.2
19
+ Requires-Dist: mypy
20
+ Requires-Dist: ruff>=0.14.0
18
21
  Requires-Dist: scikit-learn>=1.7.2
19
22
  Requires-Dist: scipy>=1.16.2
20
23
  Requires-Dist: seaborn>=0.13.2
21
24
  Requires-Dist: statsmodels>=0.14.5
22
25
  Requires-Dist: streamlit>=1.49.1
23
26
  Requires-Dist: vega-datasets>=0.9.0
27
+ Dynamic: license-file
24
28
 
25
29
  # bs-python-utils
26
30
 
@@ -37,6 +41,9 @@ Requires-Dist: vega-datasets>=0.9.0
37
41
 
38
42
  ### Release notes
39
43
 
44
+ #### 0.8.1 (October 18, 2025)
45
+ Deleted extra examples scripts.
46
+
40
47
  #### 0.8 (October 14, 2025)
41
48
  Switched to `uv` for project management. Used Codex to clean up the code and generate more tests. Added the `examples` subdirectory.
42
49
 
@@ -1,3 +1,4 @@
1
+ LICENSE
1
2
  README.md
2
3
  pyproject.toml
3
4
  bs_python_utils/Timer.py
@@ -9,6 +9,8 @@ numpy>=2.3.3
9
9
  pandas>=2.3.2
10
10
  pre-commit>=4.3.0
11
11
  pytest>=8.4.2
12
+ mypy
13
+ ruff>=0.14.0
12
14
  scikit-learn>=1.7.2
13
15
  scipy>=1.16.2
14
16
  seaborn>=0.13.2
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "bs-python-utils"
3
- version = "0.8.0"
4
- description = "Add your description here"
3
+ version = "0.8.1"
4
+ description = "Utilities programs for my Python code"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
7
7
  dependencies = [
@@ -16,6 +16,8 @@ dependencies = [
16
16
  "pandas>=2.3.2",
17
17
  "pre-commit>=4.3.0",
18
18
  "pytest>=8.4.2",
19
+ "mypy",
20
+ "ruff>=0.14.0",
19
21
  "scikit-learn>=1.7.2",
20
22
  "scipy>=1.16.2",
21
23
  "seaborn>=0.13.2",
@@ -29,3 +31,6 @@ packages = ["bs_python_utils"]
29
31
 
30
32
  [tool.setuptools.package-data]
31
33
  "bs_python_utils" = ["examples/*", "examples/**/*"]
34
+
35
+ [tool.ruff]
36
+ line-length = 88