From 8040ea170a06bd784bc4002192557e036905e794 Mon Sep 17 00:00:00 2001 From: Gui-FernandesBR Date: Mon, 16 Jun 2025 22:57:16 -0300 Subject: [PATCH 1/6] ENH: refactor motor prints classes to inherit from _MotorPrints --- rocketpy/prints/hybrid_motor_prints.py | 27 ++++--------------------- rocketpy/prints/liquid_motor_prints.py | 28 +++++--------------------- rocketpy/prints/solid_motor_prints.py | 28 +++++--------------------- 3 files changed, 14 insertions(+), 69 deletions(-) diff --git a/rocketpy/prints/hybrid_motor_prints.py b/rocketpy/prints/hybrid_motor_prints.py index d527042a3..6f086a162 100644 --- a/rocketpy/prints/hybrid_motor_prints.py +++ b/rocketpy/prints/hybrid_motor_prints.py @@ -1,7 +1,9 @@ import numpy as np +from .motor_prints import _MotorPrints -class _HybridMotorPrints: + +class _HybridMotorPrints(_MotorPrints): """Class that holds prints methods for HybridMotor class. Attributes @@ -26,6 +28,7 @@ def __init__( ------- None """ + super().__init__(hybrid_motor) self.hybrid_motor = hybrid_motor def nozzle_details(self): @@ -63,28 +66,6 @@ def grain_details(self): print(f"Grain Volume: {self.hybrid_motor.solid.grain_initial_volume:.3f} m3") print(f"Grain Mass: {self.hybrid_motor.solid.grain_initial_mass:.3f} kg\n") - def motor_details(self): - """Prints out all data available about the HybridMotor. - - Returns - ------- - None - """ - print("Motor Details") - print(f"Total Burning Time: {self.hybrid_motor.burn_duration} s") - print( - f"Total Propellant Mass: {self.hybrid_motor.propellant_initial_mass:.3f} kg" - ) - print(f"Structural Mass Ratio: {self.hybrid_motor.structural_mass_ratio:.3f}") - avg = self.hybrid_motor.exhaust_velocity.average(*self.hybrid_motor.burn_time) - print(f"Average Propellant Exhaust Velocity: {avg:.3f} m/s") - print(f"Average Thrust: {self.hybrid_motor.average_thrust:.3f} N") - print( - f"Maximum Thrust: {self.hybrid_motor.max_thrust} N at " - f"{self.hybrid_motor.max_thrust_time} s after ignition." - ) - print(f"Total Impulse: {self.hybrid_motor.total_impulse:.3f} Ns\n") - def all(self): """Prints out all data available about the HybridMotor. diff --git a/rocketpy/prints/liquid_motor_prints.py b/rocketpy/prints/liquid_motor_prints.py index 4c80326ab..7411ca59a 100644 --- a/rocketpy/prints/liquid_motor_prints.py +++ b/rocketpy/prints/liquid_motor_prints.py @@ -1,4 +1,7 @@ -class _LiquidMotorPrints: +from .motor_prints import _MotorPrints + + +class _LiquidMotorPrints(_MotorPrints): """Class that holds prints methods for LiquidMotor class. Attributes @@ -23,6 +26,7 @@ def __init__( ------- None """ + super().__init__(liquid_motor) self.liquid_motor = liquid_motor def nozzle_details(self): @@ -35,28 +39,6 @@ def nozzle_details(self): print("Nozzle Details") print("Nozzle Radius: " + str(self.liquid_motor.nozzle_radius) + " m\n") - def motor_details(self): - """Prints out all data available about the motor. - - Returns - ------- - None - """ - print("Motor Details") - print(f"Total Burning Time: {self.liquid_motor.burn_duration} s") - print( - f"Total Propellant Mass: {self.liquid_motor.propellant_initial_mass:.3f} kg" - ) - print(f"Structural Mass Ratio: {self.liquid_motor.structural_mass_ratio:.3f}") - avg = self.liquid_motor.exhaust_velocity.average(*self.liquid_motor.burn_time) - print(f"Average Propellant Exhaust Velocity: {avg:.3f} m/s") - print(f"Average Thrust: {self.liquid_motor.average_thrust:.3f} N") - print( - f"Maximum Thrust: {self.liquid_motor.max_thrust} N at " - f"{self.liquid_motor.max_thrust_time} s after ignition." - ) - print(f"Total Impulse: {self.liquid_motor.total_impulse:.3f} Ns\n") - def all(self): """Prints out all data available about the LiquidMotor. diff --git a/rocketpy/prints/solid_motor_prints.py b/rocketpy/prints/solid_motor_prints.py index 6f4c28d5b..16ef5dc38 100644 --- a/rocketpy/prints/solid_motor_prints.py +++ b/rocketpy/prints/solid_motor_prints.py @@ -1,4 +1,7 @@ -class _SolidMotorPrints: +from .motor_prints import _MotorPrints + + +class _SolidMotorPrints(_MotorPrints): """Class that holds prints methods for SolidMotor class. Attributes @@ -23,6 +26,7 @@ def __init__( ------- None """ + super().__init__(solid_motor) self.solid_motor = solid_motor def nozzle_details(self): @@ -53,28 +57,6 @@ def grain_details(self): print(f"Grain Volume: {self.solid_motor.grain_initial_volume:.3f} m3") print(f"Grain Mass: {self.solid_motor.grain_initial_mass:.3f} kg\n") - def motor_details(self): - """Prints out all data available about the SolidMotor. - - Returns - ------- - None - """ - print("Motor Details") - print("Total Burning Time: " + str(self.solid_motor.burn_duration) + " s") - print( - f"Total Propellant Mass: {self.solid_motor.propellant_initial_mass:.3f} kg" - ) - print(f"Structural Mass Ratio: {self.solid_motor.structural_mass_ratio:.3f}") - average = self.solid_motor.exhaust_velocity.average(*self.solid_motor.burn_time) - print(f"Average Propellant Exhaust Velocity: {average:.3f} m/s") - print(f"Average Thrust: {self.solid_motor.average_thrust:.3f} N") - print( - f"Maximum Thrust: {self.solid_motor.max_thrust} N " - f"at {self.solid_motor.max_thrust_time} s after ignition." - ) - print(f"Total Impulse: {self.solid_motor.total_impulse:.3f} Ns\n") - def all(self): """Prints out all data available about the SolidMotor. From a8aef597a676a5cf3c54e3251602607327ac4aa6 Mon Sep 17 00:00:00 2001 From: Gui-FernandesBR Date: Mon, 16 Jun 2025 22:57:30 -0300 Subject: [PATCH 2/6] STY: make format --- rocketpy/mathutils/function.py | 2 +- tests/integration/test_environment_analysis.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rocketpy/mathutils/function.py b/rocketpy/mathutils/function.py index e60b39286..221974ca8 100644 --- a/rocketpy/mathutils/function.py +++ b/rocketpy/mathutils/function.py @@ -10,10 +10,10 @@ from bisect import bisect_left from collections.abc import Iterable from copy import deepcopy +from enum import Enum from functools import cached_property from inspect import signature from pathlib import Path -from enum import Enum import matplotlib.pyplot as plt import numpy as np diff --git a/tests/integration/test_environment_analysis.py b/tests/integration/test_environment_analysis.py index e6043c85a..2b12a2057 100644 --- a/tests/integration/test_environment_analysis.py +++ b/tests/integration/test_environment_analysis.py @@ -4,6 +4,7 @@ import matplotlib as plt import pytest + from rocketpy import Environment plt.rcParams.update({"figure.max_open_warning": 0}) From 1a6f8d9d51aed6811df218ad3a40f444c8109b75 Mon Sep 17 00:00:00 2001 From: Gui-FernandesBR Date: Mon, 16 Jun 2025 23:16:00 -0300 Subject: [PATCH 3/6] MNT: update code and remove deprecated functions --- rocketpy/environment/environment.py | 95 +--------------------- rocketpy/motors/motor.py | 2 +- rocketpy/plots/monte_carlo_plots.py | 4 +- rocketpy/rocket/aero_surface/air_brakes.py | 3 +- rocketpy/simulation/flight.py | 32 ++------ rocketpy/utilities.py | 90 -------------------- tests/acceptance/test_bella_lui_rocket.py | 1 - tests/unit/test_environment.py | 5 +- 8 files changed, 16 insertions(+), 216 deletions(-) diff --git a/rocketpy/environment/environment.py b/rocketpy/environment/environment.py index a0a8c4238..97d79d988 100644 --- a/rocketpy/environment/environment.py +++ b/rocketpy/environment/environment.py @@ -451,7 +451,7 @@ def __initialize_utm_coordinates(self): self.initial_utm_letter, self.initial_hemisphere, self.initial_ew, - ) = self.geodesic_to_utm( + ) = geodesic_to_utm_tools( lat=self.latitude, lon=self.longitude, flattening=self.ellipsoid.flattening, @@ -2523,98 +2523,7 @@ def set_earth_geometry(self, datum): f"the following recognized datum: {available_datums}" ) from e - # Auxiliary functions - Geodesic Coordinates - - @staticmethod - def geodesic_to_utm( - lat, lon, semi_major_axis=6378137.0, flattening=1 / 298.257223563 - ): - """Function which converts geodetic coordinates, i.e. lat/lon, to UTM - projection coordinates. Can be used only for latitudes between -80.00° - and 84.00° - - Parameters - ---------- - lat : float - The latitude coordinates of the point of analysis, must be contained - between -80.00° and 84.00° - lon : float - The longitude coordinates of the point of analysis, must be - contained between -180.00° and 180.00° - semi_major_axis : float - The semi-major axis of the ellipsoid used to represent the Earth, - must be given in meters (default is 6,378,137.0 m, which corresponds - to the WGS84 ellipsoid) - flattening : float - The flattening of the ellipsoid used to represent the Earth, usually - between 1/250 and 1/150 (default is 1/298.257223563, which - corresponds to the WGS84 ellipsoid) - - Returns - ------- - x : float - East coordinate, always positive - y : float - North coordinate, always positive - utm_zone : int - The number of the UTM zone of the point of analysis, can vary - between 1 and 60 - utm_letter : string - The letter of the UTM zone of the point of analysis, can vary - between C and X, omitting the letters "I" and "O" - hemis : string - Returns "S" for southern hemisphere and "N" for Northern hemisphere - EW : string - Returns "W" for western hemisphere and "E" for eastern hemisphere - """ - warnings.warn( - "This function is deprecated and will be removed in v1.10.0. " - "Please use the new method `tools.geodesic_to_utm` instead.", - DeprecationWarning, - ) - return geodesic_to_utm_tools(lat, lon, semi_major_axis, flattening) - - @staticmethod - def utm_to_geodesic( - x, y, utm_zone, hemis, semi_major_axis=6378137.0, flattening=1 / 298.257223563 - ): - """Function to convert UTM coordinates to geodesic coordinates - (i.e. latitude and longitude). - - Parameters - ---------- - x : float - East UTM coordinate in meters - y : float - North UTM coordinate in meters - utm_zone : int - The number of the UTM zone of the point of analysis, can vary - between 1 and 60 - hemis : string - Equals to "S" for southern hemisphere and "N" for Northern - hemisphere - semi_major_axis : float - The semi-major axis of the ellipsoid used to represent the Earth, - must be given in meters (default is 6,378,137.0 m, which corresponds - to the WGS84 ellipsoid) - flattening : float - The flattening of the ellipsoid used to represent the Earth, usually - between 1/250 and 1/150 (default is 1/298.257223563, which - corresponds to the WGS84 ellipsoid) - - Returns - ------- - lat : float - latitude of the analyzed point - lon : float - latitude of the analyzed point - """ - warnings.warn( - "This function is deprecated and will be removed in v1.10.0. " - "Please use the new method `tools.utm_to_geodesic` instead.", - DeprecationWarning, - ) - return utm_to_geodesic_tools(x, y, utm_zone, hemis, semi_major_axis, flattening) + # Auxiliary functions @staticmethod def calculate_earth_radius( diff --git a/rocketpy/motors/motor.py b/rocketpy/motors/motor.py index 7178cdcf5..1cb659d4f 100644 --- a/rocketpy/motors/motor.py +++ b/rocketpy/motors/motor.py @@ -1151,7 +1151,7 @@ def vacuum_thrust(self): Returns ------- vacuum_thrust : Function - The rocket's thrust in a vaccum. + The rocket's thrust in a vacuum. """ if self.reference_pressure is None: warnings.warn( diff --git a/rocketpy/plots/monte_carlo_plots.py b/rocketpy/plots/monte_carlo_plots.py index cfb865c5f..a2af1f5db 100644 --- a/rocketpy/plots/monte_carlo_plots.py +++ b/rocketpy/plots/monte_carlo_plots.py @@ -183,7 +183,7 @@ def all(self, keys=None): ax2 = fig.add_subplot(gs[1]) # Plot boxplot - ax1.boxplot(self.monte_carlo.results[key], vert=False) + ax1.boxplot(self.monte_carlo.results[key], orientation="horizontal") ax1.set_title(f"Box Plot of {key}") ax1.set_yticks([]) @@ -226,7 +226,7 @@ def plot_comparison(self, other_monte_carlo): # Plot boxplot bp = ax1.boxplot( [other_monte_carlo.results[key], self.monte_carlo.results[key]], - vert=False, + orientation="horizontal", tick_labels=["Other", "Original"], patch_artist=True, ) diff --git a/rocketpy/rocket/aero_surface/air_brakes.py b/rocketpy/rocket/aero_surface/air_brakes.py index ee4830808..d0eb733d5 100644 --- a/rocketpy/rocket/aero_surface/air_brakes.py +++ b/rocketpy/rocket/aero_surface/air_brakes.py @@ -131,7 +131,8 @@ def deployment_level(self, value): warnings.warn( f"Deployment level of {self.name} is smaller than 0 or " + "larger than 1. Extrapolation for the drag coefficient " - + "curve will be used." + + "curve will be used.", + UserWarning, ) self._deployment_level = value diff --git a/rocketpy/simulation/flight.py b/rocketpy/simulation/flight.py index ce728dafe..914300a1d 100644 --- a/rocketpy/simulation/flight.py +++ b/rocketpy/simulation/flight.py @@ -3055,14 +3055,16 @@ def __calculate_rail_button_forces(self): # TODO: complex method. null_force = Function(0) if self.out_of_rail_time_index == 0: # No rail phase, no rail button forces warnings.warn( - "Trying to calculate rail button forces without a rail phase defined." - + "The rail button forces will be set to zero." + "Trying to calculate rail button forces without a rail phase defined. " + + "The rail button forces will be set to zero.", + UserWarning, ) return null_force, null_force, null_force, null_force if len(self.rocket.rail_buttons) == 0: warnings.warn( - "Trying to calculate rail button forces without rail buttons defined." - + "The rail button forces will be set to zero." + "Trying to calculate rail button forces without rail buttons defined. " + + "The rail button forces will be set to zero.", + UserWarning, ) return null_force, null_force, null_force, null_force @@ -3174,28 +3176,6 @@ def __evaluate_post_process(self): return np.array(self.__post_processed_variables) - def post_process(self, interpolation="spline", extrapolation="natural"): - """This method is **deprecated** and is only kept here for backwards - compatibility. All attributes that need to be post processed are - computed just in time. - - Post-process all Flight information produced during - simulation. Includes the calculation of maximum values, - calculation of secondary values such as energy and conversion - of lists to Function objects to facilitate plotting. - - Returns - ------- - None - """ - # pylint: disable=unused-argument - warnings.warn( - "The method post_process is deprecated and will be removed in v1.10. " - "All attributes that need to be post processed are computed just in time.", - DeprecationWarning, - ) - self.post_processed = True - def calculate_stall_wind_velocity(self, stall_angle): # TODO: move to utilities """Function to calculate the maximum wind velocity before the angle of attack exceeds a desired angle, at the instant of departing rail launch. diff --git a/rocketpy/utilities.py b/rocketpy/utilities.py index 3ed81df41..c8d32e6af 100644 --- a/rocketpy/utilities.py +++ b/rocketpy/utilities.py @@ -444,96 +444,6 @@ def _flutter_prints( print(f"Altitude of minimum Safety Factor: {altitude_min_sf:.3f} m (AGL)\n") -def create_dispersion_dictionary(filename): # pragma: no cover - """Creates a dictionary with the rocket data provided by a .csv file. - File should be organized in four columns: attribute_class, parameter_name, - mean_value, standard_deviation. The first row should be the header. - It is advised to use ";" as separator, but "," should work on most of cases. - The "," separator might cause problems if the data set contains lists where - the items are separated by commas. - - Parameters - ---------- - filename : string - String with the path to the .csv file. The file should follow the - following structure: - - .. code-block:: - - attribute_class; parameter_name; mean_value; standard_deviation; - - environment; ensemble_member; [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];; - - motor; impulse; 1415.15; 35.3; - - motor; burn_time; 5.274; 1; - - motor; nozzle_radius; 0.021642; 0.0005; - - motor; throat_radius; 0.008; 0.0005; - - motor; grain_separation; 0.006; 0.001; - - motor; grain_density; 1707; 50; - - Returns - ------- - dictionary - Dictionary with all rocket data to be used in dispersion analysis. The - dictionary will follow the following structure: - - .. code-block:: python - - analysis_parameters = { - 'environment': { - 'ensemble_member': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - }, - 'motor': { - 'impulse': (1415.15, 35.3), - 'burn_time': (5.274, 1), - 'nozzle_radius': (0.021642, 0.0005), - 'throat_radius': (0.008, 0.0005), - 'grain_separation': (0.006, 0.001), - 'grain_density': (1707, 50), - } - } - """ - warnings.warn( - "This function is deprecated and will be removed in v1.10.0.", - DeprecationWarning, - ) - try: - file = np.genfromtxt( - filename, usecols=(1, 2, 3), skip_header=1, delimiter=";", dtype=str - ) - except ValueError: - warnings.warn( - "Error caught: the recommended delimiter is ';'. If using ',' " - "instead, be aware that some resources might not work as " - "expected if your data set contains lists where the items are " - "separated by commas. Please consider changing the delimiter to " - "';' if that is the case." - ) - warnings.warn(traceback.format_exc()) - file = np.genfromtxt( - filename, usecols=(1, 2, 3), skip_header=1, delimiter=",", dtype=str - ) - analysis_parameters = {} - for row in file: - if row[0] != "": - if row[2] == "": - try: - analysis_parameters[row[0].strip()] = float(row[1]) - except ValueError: - analysis_parameters[row[0].strip()] = ast.literal_eval(row[1]) - else: - try: - analysis_parameters[row[0].strip()] = (float(row[1]), float(row[2])) - except ValueError: - analysis_parameters[row[0].strip()] = "" - return analysis_parameters - - def apogee_by_mass(flight, min_mass, max_mass, points=10, plot=True): """Returns a Function object that estimates the apogee of a rocket given its mass (no motor). The function will use the rocket's mass as the diff --git a/tests/acceptance/test_bella_lui_rocket.py b/tests/acceptance/test_bella_lui_rocket.py index 76f2b4fde..a67547780 100644 --- a/tests/acceptance/test_bella_lui_rocket.py +++ b/tests/acceptance/test_bella_lui_rocket.py @@ -182,7 +182,6 @@ def drogue_trigger(p, h, y): inclination=parameters.get("inclination")[0], heading=parameters.get("heading")[0], ) - test_flight.post_process() # Comparison with Real Data flight_data = np.loadtxt( diff --git a/tests/unit/test_environment.py b/tests/unit/test_environment.py index 714470a40..6ad3e51db 100644 --- a/tests/unit/test_environment.py +++ b/tests/unit/test_environment.py @@ -6,6 +6,7 @@ import pytz from rocketpy import Environment +from rocketpy.environment.tools import geodesic_to_utm, utm_to_geodesic @pytest.mark.parametrize( @@ -78,7 +79,7 @@ def test_geodesic_coordinate_geodesic_to_utm_converts_coordinate(): utm_letter, north_south_hemis, east_west_hemis, - ) = Environment.geodesic_to_utm( + ) = geodesic_to_utm( lat=32.990254, lon=-106.974998, semi_major_axis=6378137.0, # WGS84 @@ -98,7 +99,7 @@ class and checks the conversion results from UTM to geodesic coordinates. """ - lat, lon = Environment.utm_to_geodesic( + lat, lon = utm_to_geodesic( x=315468.64, y=3651938.65, utm_zone=13, From dd7604de1200697dd4d31a0ca1032ec35ddbf7e9 Mon Sep 17 00:00:00 2001 From: Gui-FernandesBR Date: Mon, 16 Jun 2025 23:26:55 -0300 Subject: [PATCH 4/6] ENH: add deprecation decorator and update deprecated methods --- rocketpy/mathutils/function.py | 24 ++++++------- rocketpy/rocket/rocket.py | 12 +++---- rocketpy/tools.py | 61 ++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 19 deletions(-) diff --git a/rocketpy/mathutils/function.py b/rocketpy/mathutils/function.py index 221974ca8..a034ba6f8 100644 --- a/rocketpy/mathutils/function.py +++ b/rocketpy/mathutils/function.py @@ -24,7 +24,7 @@ RBFInterpolator, ) -from rocketpy.tools import from_hex_decode, to_hex_encode +from rocketpy.tools import deprecated, from_hex_decode, to_hex_encode from ..plots.plot_helpers import show_or_save_plot @@ -1459,14 +1459,13 @@ def plot(self, *args, **kwargs): else: print("Error: Only functions with 1D or 2D domains can be plotted.") + @deprecated( + reason="The `Function.plot1D` method is set to be deprecated and fully " + "removed in rocketpy v2.0.0", + alternative="Function.plot_1d", + ) def plot1D(self, *args, **kwargs): # pragma: no cover """Deprecated method, use Function.plot_1d instead.""" - warnings.warn( - "The `Function.plot1D` method is set to be deprecated and fully " - + "removed in rocketpy v2.0.0, use `Function.plot_1d` instead. " - + "This method is calling `Function.plot_1d`.", - DeprecationWarning, - ) return self.plot_1d(*args, **kwargs) def plot_1d( # pylint: disable=too-many-statements @@ -1559,14 +1558,13 @@ def plot_1d( # pylint: disable=too-many-statements if return_object: return fig, ax + @deprecated( + reason="The `Function.plot2D` method is set to be deprecated and fully " + "removed in rocketpy v2.0.0", + alternative="Function.plot_2d", + ) def plot2D(self, *args, **kwargs): # pragma: no cover """Deprecated method, use Function.plot_2d instead.""" - warnings.warn( - "The `Function.plot2D` method is set to be deprecated and fully " - + "removed in rocketpy v2.0.0, use `Function.plot_2d` instead. " - + "This method is calling `Function.plot_2d`.", - DeprecationWarning, - ) return self.plot_2d(*args, **kwargs) def plot_2d( # pylint: disable=too-many-statements diff --git a/rocketpy/rocket/rocket.py b/rocketpy/rocket/rocket.py index bf938d4be..1d6e1e7e5 100644 --- a/rocketpy/rocket/rocket.py +++ b/rocketpy/rocket/rocket.py @@ -22,7 +22,7 @@ from rocketpy.rocket.aero_surface.generic_surface import GenericSurface from rocketpy.rocket.components import Components from rocketpy.rocket.parachute import Parachute -from rocketpy.tools import parallel_axis_theorem_from_com +from rocketpy.tools import deprecated, parallel_axis_theorem_from_com # pylint: disable=too-many-instance-attributes, too-many-public-methods, too-many-instance-attributes @@ -1173,16 +1173,16 @@ def add_nose( self.add_surfaces(nose, position) return nose + @deprecated( + reason="This method is set to be deprecated in version 1.0.0 and fully " + "removed by version 2.0.0", + alternative="Rocket.add_trapezoidal_fins", + ) def add_fins(self, *args, **kwargs): # pragma: no cover """See Rocket.add_trapezoidal_fins for documentation. This method is set to be deprecated in version 1.0.0 and fully removed by version 2.0.0. Use Rocket.add_trapezoidal_fins instead. It keeps the same arguments and signature.""" - warnings.warn( - "This method is set to be deprecated in version 1.0.0 and fully " - "removed by version 2.0.0. Use Rocket.add_trapezoidal_fins instead", - DeprecationWarning, - ) return self.add_trapezoidal_fins(*args, **kwargs) def add_trapezoidal_fins( diff --git a/rocketpy/tools.py b/rocketpy/tools.py index 692d5e224..a5ffb1b50 100644 --- a/rocketpy/tools.py +++ b/rocketpy/tools.py @@ -14,6 +14,7 @@ import math import re import time +import warnings from bisect import bisect_left import dill @@ -28,6 +29,66 @@ INSTALL_MAPPING = {"IPython": "ipython"} +def deprecated(reason=None, version=None, alternative=None): + """ + Decorator to mark functions or methods as deprecated. + + This decorator issues a DeprecationWarning when the decorated function + is called, indicating that it will be removed in future versions. + + Parameters + ---------- + reason : str, optional + Custom deprecation message. If not provided, a default message will be used. + version : str, optional + Version when the function will be removed. If provided, it will be + included in the warning message. + alternative : str, optional + Name of the alternative function/method that should be used instead. + If provided, it will be included in the warning message. + + Returns + ------- + callable + The decorated function with deprecation warning functionality. + + Examples + -------- + >>> @deprecated(reason="This function is obsolete", version="v2.0.0", + ... alternative="new_function") + ... def old_function(): + ... return "old result" + + >>> @deprecated() + ... def another_old_function(): + ... return "result" + """ + + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + # Build the deprecation message + if reason: + message = reason + else: + message = f"The function `{func.__name__}` is deprecated" + + if version: + message += f" and will be removed in {version}" + + if alternative: + message += f". Use `{alternative}` instead" + + message += "." + + warnings.warn(message, DeprecationWarning, stacklevel=2) + return func(*args, **kwargs) + + return wrapper + + return decorator + + def tuple_handler(value): """Transforms the input value into a tuple that represents a range. If the input is an int or float, the output is a tuple from zero to the input From efc0c81a1a7c8efad859e5a325d48702e747faf2 Mon Sep 17 00:00:00 2001 From: Gui-FernandesBR Date: Mon, 16 Jun 2025 23:27:15 -0300 Subject: [PATCH 5/6] make format --- rocketpy/environment/environment.py | 1 - rocketpy/rocket/rocket.py | 1 - rocketpy/utilities.py | 2 -- 3 files changed, 4 deletions(-) diff --git a/rocketpy/environment/environment.py b/rocketpy/environment/environment.py index 97d79d988..3731ccb18 100644 --- a/rocketpy/environment/environment.py +++ b/rocketpy/environment/environment.py @@ -35,7 +35,6 @@ mask_and_clean_dataset, ) from rocketpy.environment.tools import geodesic_to_utm as geodesic_to_utm_tools -from rocketpy.environment.tools import utm_to_geodesic as utm_to_geodesic_tools from rocketpy.environment.weather_model_mapping import WeatherModelMapping from rocketpy.mathutils.function import NUMERICAL_TYPES, Function, funcify_method from rocketpy.plots.environment_plots import _EnvironmentPlots diff --git a/rocketpy/rocket/rocket.py b/rocketpy/rocket/rocket.py index 1d6e1e7e5..31ef9dd3f 100644 --- a/rocketpy/rocket/rocket.py +++ b/rocketpy/rocket/rocket.py @@ -1,5 +1,4 @@ import math -import warnings import numpy as np diff --git a/rocketpy/utilities.py b/rocketpy/utilities.py index c8d32e6af..9ec707ffe 100644 --- a/rocketpy/utilities.py +++ b/rocketpy/utilities.py @@ -1,8 +1,6 @@ -import ast import inspect import json import os -import traceback import warnings from datetime import date from importlib.metadata import version From 496cf0d52e4013df070ea97d4e280f53a481af84 Mon Sep 17 00:00:00 2001 From: Gui-FernandesBR <63590233+Gui-FernandesBR@users.noreply.github.com> Date: Sat, 21 Jun 2025 22:54:14 -0300 Subject: [PATCH 6/6] fix warnings --- rocketpy/plots/monte_carlo_plots.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocketpy/plots/monte_carlo_plots.py b/rocketpy/plots/monte_carlo_plots.py index 556ffe6f1..114858252 100644 --- a/rocketpy/plots/monte_carlo_plots.py +++ b/rocketpy/plots/monte_carlo_plots.py @@ -227,7 +227,7 @@ def plot_comparison(self, other_monte_carlo): # Plot boxplot bp = ax1.boxplot( [other_monte_carlo.results[key], self.monte_carlo.results[key]], - orientation="horizontal", + vert=False, tick_labels=["Other", "Original"], patch_artist=True, )