rgwfuncs 0.0.51__py3-none-any.whl → 0.0.52__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- rgwfuncs/__init__.py +1 -1
- rgwfuncs/algebra_lib.py +148 -2
- {rgwfuncs-0.0.51.dist-info → rgwfuncs-0.0.52.dist-info}/METADATA +40 -1
- rgwfuncs-0.0.52.dist-info/RECORD +12 -0
- rgwfuncs-0.0.51.dist-info/RECORD +0 -12
- {rgwfuncs-0.0.51.dist-info → rgwfuncs-0.0.52.dist-info}/LICENSE +0 -0
- {rgwfuncs-0.0.51.dist-info → rgwfuncs-0.0.52.dist-info}/WHEEL +0 -0
- {rgwfuncs-0.0.51.dist-info → rgwfuncs-0.0.52.dist-info}/entry_points.txt +0 -0
- {rgwfuncs-0.0.51.dist-info → rgwfuncs-0.0.52.dist-info}/top_level.txt +0 -0
rgwfuncs/__init__.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# This file is automatically generated
|
2
2
|
# Dynamically importing functions from modules
|
3
3
|
|
4
|
-
from .algebra_lib import cancel_polynomial_expression, compute_constant_expression, compute_constant_expression_involving_matrices, compute_constant_expression_involving_ordered_series, compute_prime_factors, expand_polynomial_expression, factor_polynomial_expression, python_polynomial_expression_to_latex, simplify_polynomial_expression, solve_homogeneous_polynomial_expression
|
4
|
+
from .algebra_lib import cancel_polynomial_expression, compute_constant_expression, compute_constant_expression_involving_matrices, compute_constant_expression_involving_ordered_series, compute_prime_factors, expand_polynomial_expression, factor_polynomial_expression, plot_polynomial_functions, python_polynomial_expression_to_latex, simplify_polynomial_expression, solve_homogeneous_polynomial_expression
|
5
5
|
from .df_lib import append_columns, append_percentile_classification_column, append_ranged_classification_column, append_ranged_date_classification_column, append_rows, append_xgb_labels, append_xgb_logistic_regression_predictions, append_xgb_regression_predictions, bag_union_join, bottom_n_unique_values, cascade_sort, delete_rows, drop_duplicates, drop_duplicates_retain_first, drop_duplicates_retain_last, filter_dataframe, filter_indian_mobiles, first_n_rows, from_raw_data, insert_dataframe_in_sqlite_database, last_n_rows, left_join, limit_dataframe, load_data_from_path, load_data_from_query, load_data_from_sqlite_path, mask_against_dataframe, mask_against_dataframe_converse, numeric_clean, order_columns, print_correlation, print_dataframe, print_memory_usage, print_n_frequency_cascading, print_n_frequency_linear, rename_columns, retain_columns, right_join, send_data_to_email, send_data_to_slack, send_dataframe_via_telegram, sync_dataframe_to_sqlite_database, top_n_unique_values, union_join, update_rows
|
6
6
|
from .docs_lib import docs
|
7
7
|
from .interactive_shell_lib import interactive_shell
|
rgwfuncs/algebra_lib.py
CHANGED
@@ -8,7 +8,12 @@ from sympy.parsing.sympy_parser import parse_expr
|
|
8
8
|
from sympy import __all__ as sympy_functions
|
9
9
|
from sympy.parsing.sympy_parser import (standard_transformations, implicit_multiplication_application)
|
10
10
|
|
11
|
-
from typing import Tuple, List, Dict, Optional
|
11
|
+
from typing import Tuple, List, Dict, Optional, Any
|
12
|
+
|
13
|
+
|
14
|
+
import numpy as np
|
15
|
+
import matplotlib.pyplot as plt
|
16
|
+
from io import BytesIO
|
12
17
|
|
13
18
|
|
14
19
|
def compute_prime_factors(n: int) -> str:
|
@@ -285,7 +290,6 @@ def python_polynomial_expression_to_latex(
|
|
285
290
|
Raises:
|
286
291
|
ValueError: If the expression cannot be parsed due to syntax errors.
|
287
292
|
"""
|
288
|
-
|
289
293
|
transformations = standard_transformations + (implicit_multiplication_application,)
|
290
294
|
|
291
295
|
def parse_and_convert_expression(expr_str: str, sym_vars: Dict[str, Expr]) -> Expr:
|
@@ -701,3 +705,145 @@ def solve_homogeneous_polynomial_expression(
|
|
701
705
|
|
702
706
|
except Exception as e:
|
703
707
|
raise ValueError(f"Error solving the expression: {e}")
|
708
|
+
|
709
|
+
|
710
|
+
def plot_polynomial_functions(
|
711
|
+
functions: List[Dict[str, Dict[str, Any]]],
|
712
|
+
zoom: float = 10.0,
|
713
|
+
show_legend: bool = True
|
714
|
+
) -> str:
|
715
|
+
"""
|
716
|
+
Plots expressions described by a list of dictionaries of the form:
|
717
|
+
[
|
718
|
+
{ "expression_string": { "x": "*", "a":..., "b":... } },
|
719
|
+
{ "expression_string": { "x": np.linspace(...), "a":..., ... } },
|
720
|
+
...
|
721
|
+
]
|
722
|
+
|
723
|
+
In each top-level dictionary, there is exactly one key (a string
|
724
|
+
representing a Python/NumPy expression) and one value (a dictionary of
|
725
|
+
substitutions). This substitutions dictionary must have an "x" key:
|
726
|
+
• "x": "*" -> Use a default domain from -zoom..+zoom.
|
727
|
+
• "x": np.array(...) -> Use that array as the domain.
|
728
|
+
Other variables (like "a", "b", etc.) may also appear in the same dict.
|
729
|
+
|
730
|
+
Additionally, we use latexify_expression(...) to transform the expression
|
731
|
+
into a nice LaTeX form for the legend, including a special Δ notation for np.diff(...).
|
732
|
+
|
733
|
+
Parameters
|
734
|
+
----------
|
735
|
+
functions : List[Dict[str, Dict[str, Any]]]
|
736
|
+
A list of items. Each item is a dictionary:
|
737
|
+
key = expression string (e.g., "x**2", "np.diff(x,2)", etc.)
|
738
|
+
value = a dictionary of substitutions. Must contain "x",
|
739
|
+
either as "*" or a NumPy array. May contain additional
|
740
|
+
parameters like "a", "b", etc.
|
741
|
+
zoom : float
|
742
|
+
Sets the numeric axis range from -zoom..+zoom in both x and y.
|
743
|
+
show_legend : bool
|
744
|
+
Whether to add a legend to the plot (defaults to True).
|
745
|
+
|
746
|
+
Returns
|
747
|
+
-------
|
748
|
+
str
|
749
|
+
The raw SVG markup of the resulting plot.
|
750
|
+
"""
|
751
|
+
|
752
|
+
def latexify_expression(expr_str: str) -> str:
|
753
|
+
# Regex to locate np.diff(...) with an optional second argument
|
754
|
+
DIFF_PATTERN = r"np\.diff\s*\(\s*([^,\)]+)(?:,\s*(\d+))?\)"
|
755
|
+
|
756
|
+
def diff_replacer(match: re.Match) -> str:
|
757
|
+
inside = match.group(1).strip()
|
758
|
+
exponent = match.group(2)
|
759
|
+
inside_no_np = inside.replace("np.", "")
|
760
|
+
if exponent:
|
761
|
+
return rf"\Delta^{exponent}\left({inside_no_np}\right)"
|
762
|
+
else:
|
763
|
+
return rf"\Delta\left({inside_no_np}\right)"
|
764
|
+
|
765
|
+
expr_tmp = re.sub(DIFF_PATTERN, diff_replacer, expr_str)
|
766
|
+
expr_tmp = expr_tmp.replace("np.", "")
|
767
|
+
try:
|
768
|
+
latex_expr = python_polynomial_expression_to_latex(expr_tmp)
|
769
|
+
return latex_expr
|
770
|
+
except Exception:
|
771
|
+
# Fallback: just do naive **
|
772
|
+
return expr_tmp.replace("**", "^")
|
773
|
+
|
774
|
+
buffer = BytesIO()
|
775
|
+
fig, ax = plt.subplots()
|
776
|
+
|
777
|
+
for entry in functions:
|
778
|
+
if len(entry) != 1:
|
779
|
+
print("Skipping invalid item. Must have exactly 1 expression->substitutions pair.")
|
780
|
+
continue
|
781
|
+
|
782
|
+
expression, sub_dict = list(entry.items())[0]
|
783
|
+
if "x" not in sub_dict:
|
784
|
+
print(f"Skipping '{expression}' because sub-dict lacks 'x' key.")
|
785
|
+
continue
|
786
|
+
|
787
|
+
# If "x" is "*", create a default domain
|
788
|
+
x_val = sub_dict["x"]
|
789
|
+
if isinstance(x_val, str) and x_val == "*":
|
790
|
+
x_values = np.linspace(-zoom, zoom, 1201)
|
791
|
+
sub_dict["x"] = x_values
|
792
|
+
elif isinstance(x_val, np.ndarray):
|
793
|
+
x_values = x_val
|
794
|
+
else:
|
795
|
+
print(f"Skipping '{expression}' because 'x' is neither '*' nor a NumPy array.")
|
796
|
+
continue
|
797
|
+
|
798
|
+
# Evaluate the expression
|
799
|
+
try:
|
800
|
+
eval_context = {"np": np}
|
801
|
+
eval_context.update(sub_dict)
|
802
|
+
y_values = eval(expression, {"np": np}, eval_context)
|
803
|
+
except Exception as e:
|
804
|
+
print(f"Error evaluating expression '{expression}': {e}")
|
805
|
+
continue
|
806
|
+
|
807
|
+
if not isinstance(y_values, np.ndarray):
|
808
|
+
print(f"Skipping '{expression}' because it did not produce a NumPy array.")
|
809
|
+
continue
|
810
|
+
|
811
|
+
# If y_values is shorter than x_values (like np.diff), truncate x
|
812
|
+
if len(y_values) < len(x_values):
|
813
|
+
x_values = x_values[:len(y_values)]
|
814
|
+
|
815
|
+
# Convert expression to a nice LaTeX string
|
816
|
+
label_expr = latexify_expression(expression)
|
817
|
+
ax.plot(x_values, y_values, label=rf"${label_expr}$")
|
818
|
+
|
819
|
+
# Configure axes
|
820
|
+
ax.set_xlim(-zoom, zoom)
|
821
|
+
ax.set_ylim(-zoom, zoom)
|
822
|
+
ax.spines['left'].set_position('zero')
|
823
|
+
ax.spines['bottom'].set_position('zero')
|
824
|
+
ax.spines['right'].set_color('none')
|
825
|
+
ax.spines['top'].set_color('none')
|
826
|
+
ax.set_aspect('equal', 'box')
|
827
|
+
ax.xaxis.set_ticks_position('bottom')
|
828
|
+
ax.yaxis.set_ticks_position('left')
|
829
|
+
ax.grid(True)
|
830
|
+
|
831
|
+
# Show legend
|
832
|
+
if show_legend:
|
833
|
+
leg = ax.legend(
|
834
|
+
loc='upper center',
|
835
|
+
bbox_to_anchor=(0.5, -0.03),
|
836
|
+
fancybox=True,
|
837
|
+
shadow=True,
|
838
|
+
ncol=1
|
839
|
+
)
|
840
|
+
plt.savefig(
|
841
|
+
buffer,
|
842
|
+
format='svg',
|
843
|
+
bbox_inches='tight',
|
844
|
+
bbox_extra_artists=[leg] # ensures the legend is fully captured
|
845
|
+
)
|
846
|
+
else:
|
847
|
+
plt.savefig(buffer, format='svg', bbox_inches='tight')
|
848
|
+
plt.close(fig)
|
849
|
+
return buffer.getvalue().decode('utf-8')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: rgwfuncs
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.52
|
4
4
|
Summary: A functional programming paradigm for mathematical modelling and data science
|
5
5
|
Home-page: https://github.com/ryangerardwilson/rgwfunc
|
6
6
|
Author: Ryan Gerard Wilson
|
@@ -514,6 +514,45 @@ Solves a homogeneous polynomial expression for a specified variable and returns
|
|
514
514
|
|
515
515
|
--------------------------------------------------------------------------------
|
516
516
|
|
517
|
+
### 11. `plot_polynomial_functions`
|
518
|
+
|
519
|
+
This function plots polynomial functions described by a list of expressions and their corresponding substitution dictionaries. It generates SVG markup of the plots, with options for specifying the domain, axis zoom, and legend display.
|
520
|
+
|
521
|
+
• Parameters:
|
522
|
+
- `functions` (`List[Dict[str, Dict[str, Any]]]`): A list of dictionaries, each containing:
|
523
|
+
- A key which is a string representing a Python/NumPy expression (e.g., `"x**2"`, `"np.diff(x,2)"`).
|
524
|
+
- A value which is a dictionary containing substitutions for the expression. Must include an `"x"` key, either as `"*"` for default domain or a NumPy array.
|
525
|
+
- `zoom` (`float`): Determines the numeric axis range from `-zoom` to `+zoom` for both x and y axes (default is `10.0`).
|
526
|
+
- `show_legend` (`bool`): Specifies whether to include a legend in the plot (default is `True`).
|
527
|
+
|
528
|
+
• Returns:
|
529
|
+
- `str`: The raw SVG markup of the resulting plot.
|
530
|
+
|
531
|
+
• Example:
|
532
|
+
|
533
|
+
import subprocess
|
534
|
+
from rgwfuncs import plot_polynomial_functions
|
535
|
+
|
536
|
+
# Generate the SVG
|
537
|
+
plot_svg_string = plot_polynomial_functions(
|
538
|
+
functions=[
|
539
|
+
{"x**2": {"x": "*"}}, # Single expression, "*" means plot all discernable points
|
540
|
+
{"x**2/(2 + a) + a": {"x": np.linspace(-3, 4, 101), "a": 1.23}},
|
541
|
+
{"np.diff(x**3, 2)": {"x": np.linspace(-2, 2, 10)}}
|
542
|
+
],
|
543
|
+
zoom=2
|
544
|
+
)
|
545
|
+
|
546
|
+
# Write the SVG to an actual file
|
547
|
+
with open("plot.svg", "w", encoding="utf-8") as file:
|
548
|
+
file.write(plot_svg_string)
|
549
|
+
|
550
|
+
• Displaying the SVG:
|
551
|
+
|
552
|
+

|
553
|
+
|
554
|
+
--------------------------------------------------------------------------------
|
555
|
+
|
517
556
|
## String Based Functions
|
518
557
|
|
519
558
|
### 1. send_telegram_message
|
@@ -0,0 +1,12 @@
|
|
1
|
+
rgwfuncs/__init__.py,sha256=JjkuVeRV_Bkw8vnqSbJsRcYQRm4iCI3futR86cf3tRI,1637
|
2
|
+
rgwfuncs/algebra_lib.py,sha256=-Q2W63EtRLhwOvGGFuf8KUKVuoLA72ONt-wPhcX6R94,33408
|
3
|
+
rgwfuncs/df_lib.py,sha256=qqRQdakheLy8wMZRBfHwKyIp8DmdZIWfAiLKWgq03QU,68977
|
4
|
+
rgwfuncs/docs_lib.py,sha256=y3wSAOPO3qsA4HZ7xAtW8HimM8w-c8hjcEzMRLJ96ao,1960
|
5
|
+
rgwfuncs/interactive_shell_lib.py,sha256=A7EWsYxAfDev_N0-2GjRvAtp0bAwBPHIczXb8Gu9fzI,1107
|
6
|
+
rgwfuncs/str_lib.py,sha256=rtAdRlnSJIu3JhI-tA_A0wCiPK2m-zn5RoGpBxv_g-4,2228
|
7
|
+
rgwfuncs-0.0.52.dist-info/LICENSE,sha256=7EI8xVBu6h_7_JlVw-yPhhOZlpY9hP8wal7kHtqKT_E,1074
|
8
|
+
rgwfuncs-0.0.52.dist-info/METADATA,sha256=ByUIjumG8zZCcuKbS0d9Ipq5VH0rBfAAumeRHQ5SR90,56826
|
9
|
+
rgwfuncs-0.0.52.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
10
|
+
rgwfuncs-0.0.52.dist-info/entry_points.txt,sha256=j-c5IOPIQ0252EaOV6j6STio56sbXl2C4ym_fQ0lXx0,43
|
11
|
+
rgwfuncs-0.0.52.dist-info/top_level.txt,sha256=aGuVIzWsKiV1f2gCb6mynx0zx5ma0B1EwPGFKVEMTi4,9
|
12
|
+
rgwfuncs-0.0.52.dist-info/RECORD,,
|
rgwfuncs-0.0.51.dist-info/RECORD
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
rgwfuncs/__init__.py,sha256=vs8xv3IVx7KGpPxEXrIePD3gb_QI1XTXpD_n9817foA,1610
|
2
|
-
rgwfuncs/algebra_lib.py,sha256=sLQUxXG4mNNO55XclTgIrwVrg5LbwELOFsiSAm_9G20,28212
|
3
|
-
rgwfuncs/df_lib.py,sha256=qqRQdakheLy8wMZRBfHwKyIp8DmdZIWfAiLKWgq03QU,68977
|
4
|
-
rgwfuncs/docs_lib.py,sha256=y3wSAOPO3qsA4HZ7xAtW8HimM8w-c8hjcEzMRLJ96ao,1960
|
5
|
-
rgwfuncs/interactive_shell_lib.py,sha256=A7EWsYxAfDev_N0-2GjRvAtp0bAwBPHIczXb8Gu9fzI,1107
|
6
|
-
rgwfuncs/str_lib.py,sha256=rtAdRlnSJIu3JhI-tA_A0wCiPK2m-zn5RoGpBxv_g-4,2228
|
7
|
-
rgwfuncs-0.0.51.dist-info/LICENSE,sha256=7EI8xVBu6h_7_JlVw-yPhhOZlpY9hP8wal7kHtqKT_E,1074
|
8
|
-
rgwfuncs-0.0.51.dist-info/METADATA,sha256=Q-t10jPxJYG_orABThvIy6q1-WQvwOYwe_3TNLuLYRw,55152
|
9
|
-
rgwfuncs-0.0.51.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
10
|
-
rgwfuncs-0.0.51.dist-info/entry_points.txt,sha256=j-c5IOPIQ0252EaOV6j6STio56sbXl2C4ym_fQ0lXx0,43
|
11
|
-
rgwfuncs-0.0.51.dist-info/top_level.txt,sha256=aGuVIzWsKiV1f2gCb6mynx0zx5ma0B1EwPGFKVEMTi4,9
|
12
|
-
rgwfuncs-0.0.51.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|