bivarcontours.bivarcontours-99

function-contour-dimensioning-diagram.py

Crate a dimensioning diagram for the dependent variable z of an arbitrary function with two independent variables x and y.

MIT License Permissions of this strong copyleft license are conditioned on making available complete source code of licensed works and modifications, which include larger works using a licensed work, under the same license. Copyright and license notices must be preserved. Contributors provide an express grant of patent rights. Contributor: Uwe Schweinsberg december 2023

ToDo: * Parameters without input validation: The initializer accepts quite a few parameters but does not verify if they are in the correct form/type. Depending on the rest of the program it could lead to potential errors if incorrect data types are passed.

  • click expects x_start to be a float. If the user passes a string that cannot be converted to a float, click will

    raise an error. This is a simple form of type-checking that works very well at the boundaries of your systems (where your function interacts with the user).

  • However, keep in mind that click type checking does not substitute good practices inside your code. It aids in

    making sure inputs are of correct type but proper error handling, input checking, and type checking inside your functions and methods are still very important.

  • Moreover, since Python is a dynamically typed language, the type of a variable can change during program execution.

    Therefore, having type checks at critical points in your code (not just at the entry points) can help prevent type-related bugs.

  • Potential division by zero: In the compute_values function, if self.arr_step_1 or self.arr_step_2 is zero, it would

    lead to ValueError.

  • Closeness of values: If the min_1 and max_1 values are too close, it could lead to problems

    with the np.arange function. The same goes for min_2 and max_2.

Module Contents

Classes

Contour

This class represents a Contour object for generating contour plots.

Functions

result_unit(parsed_formula, x_sym, y_sym, x_base, y_base)

runtime_calculate_z(formula_, x_, y_, x_base, y_base, ...)

Use evaluate(), NumExpr() from the numexpr library to compile the arithmetic expression at runtime.

calculate_z(formula_, x_, y_, z_dim)

using eval() in unsafe environments, e.g. Webserver is evil.

unit_validation(dims)

Check if the given dimensions are valid units using the pint module.

_convert_units_to_dimensionless_and_get_interval(...)

Converts units to dimensionless and returns the start, base unit, stop, and interval.

_set_correct_units_for_dimension(dimension, min_value, ...)

param dimension:

The dimension of the values being set. This should be a valid dimension recognized by the

cplot(title, x_label, y_label, formula, z_dim, ...)

param title:

The title of the contour plot

Attributes

ureg

Q_

color

FIGURE_SIZE

TITLE_FONTSIZE

TITLE_FONTWEIGHT

MAX_DISPLAY_DIGITS

SCALING_EXPONENT

SCALING_FACTOR

bivarcontours.bivarcontours-99.ureg
bivarcontours.bivarcontours-99.Q_
bivarcontours.bivarcontours-99.color
bivarcontours.bivarcontours-99.FIGURE_SIZE = 10
bivarcontours.bivarcontours-99.TITLE_FONTSIZE = 14
bivarcontours.bivarcontours-99.TITLE_FONTWEIGHT = 'bold'
bivarcontours.bivarcontours-99.MAX_DISPLAY_DIGITS = 4
bivarcontours.bivarcontours-99.SCALING_EXPONENT = 3
bivarcontours.bivarcontours-99.SCALING_FACTOR
bivarcontours.bivarcontours-99.result_unit(parsed_formula, x_sym, y_sym, x_base, y_base)
bivarcontours.bivarcontours-99.runtime_calculate_z(formula_, x_, y_, x_base, y_base, z_dim)

Use evaluate(), NumExpr() from the numexpr library to compile the arithmetic expression at runtime. Using numexpr.evaluate() or any similar function with untrusted input (like user-supplied formulas) can have security implications. Like eval(), numexpr.evaluate() parses the input and evaluates it. This parsing and evaluation is done with C and not Python, which might limit the possible malicious code that could be run, but it doesn’t guarantee that no harm can be done. While it’s less likely than with Python’s eval(), it is theoretically possible for a user to craft an input string that causes numexpr.evaluate() to execute arbitrary code or perform operations that consume excessive resources. For example, a user could potentially input a formula that results in an infinite loop or a formula that attempts to allocate massive amounts of memory, effectively conducting a Denial-of-Service (DoS) attack on your machine or program. Therefore, as a general rule, never trust user input. Always sanitize/validate any input before using it. If you must use formulas from an unknown source, it might be safer to parse the formula yourself and validate that it contains only allowed symbols (variables and safe functions) in a valid structure. You want to ensure that the formula doesn’t contain any unrecognized or potentially harmful elements. If you plan to accept user input of arbitrary formulas, you should make sure to validate the input carefully to make sure it doesn’t contain any unexpected or harmful content. This can include: - Checking the formula against a list of safe-to-use functions and/or symbols. - Putting limits on formula size, complexity, and computational cost. - Using try/except blocks to catch and handle any resulting exceptions. - Putting a timeout limit on calculations to prevent your service from hanging on extremely complex inputs. In any case, without further protections, it’s better to not allow untrusted users to supply arbitrary formulas. Especially in crucial or sensitive applications, it’s ideal to have a passlist of allowed operations and strictly parse the user input.

Parameters:
  • formula – f(x,y): string

  • x – numpy x array

  • y – numpy y array

  • x_base – base unit for x

  • y_base – base unit for y

  • z_dim – unit for the calculation result: string

Returns:

result_quant : numpy z array with ureg.Quantity

bivarcontours.bivarcontours-99.calculate_z(formula_, x_, y_, z_dim)

using eval() in unsafe environments, e.g. Webserver is evil. Using SymPy’s parse_expr is generally safe when considering injecting malicious code, as parse_expr will only interpret mathematical expressions and not arbitrary Python code. This makes it inherently safer than functions like eval() which can execute arbitrary Python code.

However, there are potential concerns to be aware of, including: * Denial-of-Service (DoS) Attacks: While parse_expr doesn’t execute arbitrary Python code, a user could, in theory, input an extremely complicated mathematical expression that takes a lot of server resources to compute, leading to a denial-of-service attack where your server becomes unresponsive.

  • Input validation: You should always properly validate and sanitize any user input to prevent any potential

injection attacks or unexpected crashes due to faulty input.

Therefore, while SymPy’s parse_expr is safer than eval(), it’s still important to treat all user-supplied data with suspicion and ensure you have proper error handling and resource management in place to prevent potential attacks or crashes. The primary rule of accepting user input is: “Always validate user input thoroughly”. Meaning, you should put limits on input size, check for possible invalid characters or character sequences, etc. You could also put a timeout limit on calculations to prevent your service from hanging on extremely complex inputs. Always remember that when it comes to security, there’s more to consider than just whether a single function is safe or not. A secure application/system requires an overall well-thought-out design.

process a function with two variables x and y with sympy. Consider that the values x and y are pint-derived values with magnitude and units. In special cases, the units could be dimensionless. Sympy internally could handle base units. Pint has a larger pool of dimensions but could convert these arbitrary dimensions to base units. It is important to consider the correct factors to adjust the magnitudes of the values according to the base unit conversion. In a first step, convert the values x and y to base units and pass them with a formula (e.g. “x/y”) to sympy to be processed. the result should be returned from sympy and converted back to pint-derived values with magnitude and units. The dimension result should be compared with the expected dimension result e.g.: dimensionless in the case of x/y or m² in the case of x*y (with m as base unit). If the comparison result passes, the result will be processed further. Otherwise, an exception “invalidFormula” will be raised.

Parameters:
  • z_dim – unit fo the calculation result: string

  • formula – f(x,y): string

  • x

  • y

Returns:

z

exception bivarcontours.bivarcontours-99.UnitError(message='Invalid unit')

Bases: Exception

Exception raised for errors in the input unit.

bivarcontours.bivarcontours-99.unit_validation(dims)

Check if the given dimensions are valid units using the pint module.

Parameters:

dims (list) – A list of dimensions to be validated

Raises:

UnitError – If a dimension is not defined in the pint module

bivarcontours.bivarcontours-99._convert_units_to_dimensionless_and_get_interval(min_value, max_value, step_value)

Converts units to dimensionless and returns the start, base unit, stop, and interval.

Parameters:
  • min_value – The minimum value with units.

  • max_value – The maximum value with units.

  • step_value – The step value with units.

Returns:

A tuple containing the start (dimensionless), base unit (dimensionless), stop (dimensionless), and interval (dimensionless).

bivarcontours.bivarcontours-99._set_correct_units_for_dimension(dimension, min_value, max_value, step_value)
Parameters:

dimension – The dimension of the values being set. This should be a valid dimension recognized by the

Quantity class. :param min_value: The minimum value allowed for the dimension. :param max_value: The maximum value allowed for the dimension. :param step_value: The step value by which the dimension values should be incremented.

Returns:

A tuple containing the minimum value, maximum value, and step value, all with the appropriate units

based on the dimension provided.

class bivarcontours.bivarcontours-99.Contour(title, label_1, label_2, formula, dim_res, min_1, max_1, step_1, dim_1, min_2, max_2, step_2, dim_2, swap_axes, verbose=False)

This class represents a Contour object for generating contour plots.

Attributes: - title (str): The title of the contour plot - label_1 (str): The label for the first dimension - label_2 (str): The label for the second dimension - formula (str): The formula used to calculate the contour values - dim_res (str): The dimensional resolution of the contour plot - min_1 (float): The minimum value for the first dimension - max_1 (float): The maximum value for the first dimension - step_1 (float): The step size for the first dimension - dim_1 (str): The dimension unit for the first dimension - min_2 (float): The minimum value for the second dimension - max_2 (float): The maximum value for the second dimension - step_2 (float): The step size for the second dimension - dim_2 (str): The dimension unit for the second dimension - swap_axes (bool): Indicates whether to swap the axes of the contour plot - verbose (bool): Indicates whether to include verbose output during computation

Methods: - __init__(self, title, label_1, label_2, formula, dim_res, min_1, max_1, step_1, dim_1, min_2, max_2, step_2, dim_2, swap_axes, verbose=False): Initializes a Contour object with the * given parameters. - initialize_swapping_axes(self, dim_1, dim_2): Initializes the values for swapping the axes if necessary. - initialize_values(self): Initializes all necessary values for generating the contour plot. - initialize_dimension_one_values(self): Initializes the values for the first dimension. - initialize_dimension_two_values(self): Initializes the values for the second dimension. - _set_correct_units_for_dimension(self, dimension, min_value, max_value, step_value): Sets the correct units for a given dimension. - _convert_units_to_dimensionless_and_get_interval(self, min_value, max_value, step_value): Converts the units to dimensionless and returns the interval. - initialize_diagram_labels(self): Initializes the labels for the contour plot diagram. - set_values_for_contour_calc_with_scalars_scaled_to_base_units(self): Sets the values for calculating the contour with scaled base units. - filename_for_saved_contour_figure(self): Generates the filename for saving the contour figure. - compute_values(self): Computes the contour values based on the given formula and dimension values. - check_ticks_in_range(self, ax): Checks if the ticks are within the range of the contour plot.

initialize_swapping_axes(label_1, label_2, min_1, max_1, step_1, dim_1, min_2, max_2, step_2, dim_2)

This method initializes the swapping of axes.

Parameters:
  • dim_1 – The first dimension to be swapped.

  • dim_2 – The second dimension to be swapped.

Returns:

None

initialize_values()

Initializes the values required for the calculation and plotting of contours.

Returns:

None

initialize_dimension_one_values()

Initializes the values related to dimension one.

Returns:

None

initialize_dimension_two_values()

Initializes dimension two values.

Returns:

None

initialize_diagram_labels()

Initializes the labels for the x and y axes of the diagram.

Returns:

None

set_values_for_contour_calc_with_scalars_scaled_to_base_units()

Sets the values for the X and Y coordinates to be used in contour calculation. The X values are generated using the given start_1, stop_1, and step_1_interval parameters. The Y values are generated using the given start_2, stop_2, and step_2_interval parameters.

Returns:

None

filename_for_saved_contour_figure()

Generate a filename for saving a contour figure.

Returns:

The generated filename for saving the contour figure.

Return type:

str

compute_values()

Compute the values for the x and y axes, as well as the contour values and labels.

Returns:

None

check_ticks_in_range(ax, tick_x_values, tick_y_values)
Parameters:
  • ax – A matplotlib Axes object representing the plot on which to check the tick values.

  • tick_y_values

  • tick_x_values

Returns:

None

Checks if the tick values on the x-axis and y-axis of the given Axes object are within the data range of the plot. If any tick value is outside the data range, a ValueError is raised.

Example usage:

fig, ax = plt.subplots() # Assume some plot is created on ax obj = SomeClass() obj.check_ticks_in_range(ax)

create_diagram()

Creates a diagram using matplotlib and saves it as an image file.

Returns:

None

run()

This method runs the main process of the software.

Returns:

None

bivarcontours.bivarcontours-99.cplot(title, x_label, y_label, formula, z_dim, x_start, x_stop, x_step, x_dim, y_min, y_max, y_step, y_dim, swap_axes, verbose)
Parameters:
  • title – The title of the contour plot

  • x_label – The label of the x-axis

  • y_label – The label of the y-axis

  • formula – The mathematical formula used to generate the contour plot

  • z_dim – The dimension of the z-axis

  • x_start – The starting value of the x-axis

  • x_stop – The stopping value of the x-axis

  • x_step – The step size of the x-axis

  • x_dim – The dimension of the x-axis values

  • y_min – The minimum value of the y-axis

  • y_max – The maximum value of the y-axis

  • y_step – The step size of the y-axis

  • y_dim – The dimension of the y-axis values

  • swap_axes – The flag indicating whether to swap the x and y axes

  • verbose – The flag indicating whether to print verbose information on the screen

Returns:

None