From 571f41c4d8225caaa76c7e5b0f4a5bee956b4423 Mon Sep 17 00:00:00 2001 From: o-murphy Date: Sat, 17 Aug 2024 14:57:12 +0300 Subject: [PATCH] resolved mypy type checks, some pylint checks --- py_ballisticcalc/drag_tables.py | 1 + py_ballisticcalc/interface.py | 2 +- py_ballisticcalc/trajectory_calc.py | 24 +++++++++++++---- py_ballisticcalc/trajectory_data.py | 19 +++++--------- py_ballisticcalc/unit.py | 5 +--- .../py_ballisticcalc_exts/trajectory_calc.pyi | 26 ++++++++++--------- .../py_ballisticcalc_exts/trajectory_calc.pyx | 6 ++++- 7 files changed, 48 insertions(+), 35 deletions(-) diff --git a/py_ballisticcalc/drag_tables.py b/py_ballisticcalc/drag_tables.py index 413c5eb..54c5034 100644 --- a/py_ballisticcalc/drag_tables.py +++ b/py_ballisticcalc/drag_tables.py @@ -670,6 +670,7 @@ def get_drag_tables_names(): + """Return a list of drag table names""" return [f"TableG{n}" for n in (1, 7, 2, 5, 6, 8, 'I', 'S')] diff --git a/py_ballisticcalc/interface.py b/py_ballisticcalc/interface.py index 6c1f34b..4c29445 100644 --- a/py_ballisticcalc/interface.py +++ b/py_ballisticcalc/interface.py @@ -18,7 +18,7 @@ class Calculator: @property def cdm(self): """returns custom drag function based on input data""" - return self._calc._table_data + return self._calc.table_data def barrel_elevation_for_target(self, shot: Shot, target_distance: Union[float, Distance]) -> Angular: """Calculates barrel elevation to hit target at zero_distance. diff --git a/py_ballisticcalc/trajectory_calc.py b/py_ballisticcalc/trajectory_calc.py index 03839eb..11462c1 100644 --- a/py_ballisticcalc/trajectory_calc.py +++ b/py_ballisticcalc/trajectory_calc.py @@ -128,6 +128,11 @@ def __neg__(self) -> 'Vector': class TrajectoryCalc: """All calculations are done in units of feet and fps""" + # the attributes have to be defined before usage + barrel_azimuth: float + barrel_elevation: float + twist: float + def __init__(self, ammo: Ammo): self.ammo: Ammo = ammo self._bc: float = self.ammo.dm.BC @@ -135,6 +140,11 @@ def __init__(self, ammo: Ammo): self._curve = calculate_curve(self._table_data) self.gravity_vector = Vector(.0, cGravityConstant, .0) + @property + def table_data(self) -> List[DragDataPoint]: + """:return: List[DragDataPoint]""" + return self._table_data + @staticmethod def get_calc_step(step: float = 0): """Keep step under max_calc_step_size @@ -187,9 +197,9 @@ def zero_angle(self, shot_info: Shot, distance: Distance) -> Angular: zero_distance = math.cos(self.look_angle) * (distance >> Distance.Foot) height_at_zero = math.sin(self.look_angle) * (distance >> Distance.Foot) maximum_range = zero_distance - 1.5 * self.calc_step - self.barrel_azimuth = 0.0 - self.barrel_elevation = math.atan(height_at_zero / zero_distance) - self.twist = 0 + # self.barrel_azimuth = 0.0 + # self.barrel_elevation = math.atan(height_at_zero / zero_distance) + # self.twist = 0.0 iterations_count = 0 zero_finding_error = cZeroFindingAccuracy * 2 @@ -208,7 +218,7 @@ def zero_angle(self, shot_info: Shot, distance: Distance) -> Angular: if zero_finding_error > cZeroFindingAccuracy: # TODO: Don't raise exception; return a tuple that contains the error so caller can check how close zero is - raise Exception(f'Zero vertical error {zero_finding_error} feet, after {iterations_count} iterations.') + raise RuntimeError(f'Zero vertical error {zero_finding_error} feet, after {iterations_count} iterations.') return Angular.Radian(self.barrel_elevation) def _trajectory(self, shot_info: Shot, maximum_range: float, step: float, @@ -224,6 +234,10 @@ def _trajectory(self, shot_info: Shot, maximum_range: float, step: float, previous_mach: float = .0 drag: float = 0 + # guarantee that mach and density_factor would be referenced before assignment + mach: float = .0 + density_factor: float = .0 + # region Initialize wind-related variables to first wind reading (if any) len_winds = len(shot_info.winds) current_wind = 0 @@ -291,7 +305,7 @@ def _trajectory(self, shot_info: Shot, maximum_range: float, step: float, seen_zero |= TrajFlag.ZERO_DOWN # Mach crossing check - if (velocity / mach <= 1) and (previous_mach > 1): + if previous_mach > 1 >= velocity / mach: # (velocity / mach <= 1) and (previous_mach > 1) _flag |= TrajFlag.MACH # Next range check diff --git a/py_ballisticcalc/trajectory_data.py b/py_ballisticcalc/trajectory_data.py index befc5e1..477867d 100644 --- a/py_ballisticcalc/trajectory_data.py +++ b/py_ballisticcalc/trajectory_data.py @@ -3,26 +3,21 @@ import math from dataclasses import dataclass, field from enum import IntFlag -from typing_extensions import NamedTuple, Optional, Union, Any +from typing_extensions import NamedTuple, Optional, Union from py_ballisticcalc.conditions import Shot from py_ballisticcalc.unit import Angular, Distance, Weight, Velocity, Energy, AbstractUnit, Unit, PreferredUnits -pandas: Any -DataFrame: Any -matplotlib: Any -Polygon: Any -Axes: Any try: - import pandas + import pandas # type: ignore except ImportError as error: logging.warning("Install pandas to convert trajectory to dataframe") pandas = None try: - import matplotlib - from matplotlib.patches import Polygon + import matplotlib # type: ignore + from matplotlib.patches import Polygon # type: ignore except ImportError as error: logging.warning("Install matplotlib to get results as a plot") matplotlib = None @@ -155,7 +150,7 @@ def __str__(self) -> str: + f'ranges from {self.begin.distance << PreferredUnits.distance} ' \ + f'to {self.end.distance << PreferredUnits.distance}' - def overlay(self, ax: 'Axes', label: Optional[str] = None): + def overlay(self, ax: 'Axes', label: Optional[str] = None): # type: ignore """Highlights danger-space region on plot""" if matplotlib is None or not Polygon: raise ImportError("Install matplotlib to get results as a plot") @@ -299,7 +294,7 @@ def find_end_danger(row_num: int) -> TrajectoryData: find_end_danger(index), look_angle) - def dataframe(self, formatted: bool = False) -> 'DataFrame': + def dataframe(self, formatted: bool = False) -> 'DataFrame': # type: ignore """ :param formatted: False for values as floats; True for strings with prefer_units :return: the trajectory table as a DataFrame @@ -313,7 +308,7 @@ def dataframe(self, formatted: bool = False) -> 'DataFrame': trajectory = [p.in_def_units() for p in self] return pandas.DataFrame(trajectory, columns=col_names) - def plot(self, look_angle: Optional[Angular] = None) -> 'Axes': + def plot(self, look_angle: Optional[Angular] = None) -> 'Axes': # type: ignore """:return: graph of the trajectory""" if look_angle is None: look_angle = self.shot.look_angle diff --git a/py_ballisticcalc/unit.py b/py_ballisticcalc/unit.py index e441213..331a029 100644 --- a/py_ballisticcalc/unit.py +++ b/py_ballisticcalc/unit.py @@ -11,22 +11,20 @@ from py_ballisticcalc.logger import logger +# pylint: disable=invalid-name AbstractUnitType = TypeVar('AbstractUnitType', bound='AbstractUnit') class UnitTypeError(TypeError): """Unit type error""" - pass class UnitConversionError(UnitTypeError): """Unit conversion error""" - pass class UnitAliasError(ValueError): """Unit alias error""" - pass # pylint: disable=invalid-name @@ -811,7 +809,6 @@ def create_as_preferred(value_): 'UnitAliasError', 'UnitTypeError', 'UnitConversionError', - # opt '_parse_unit', '_parse_value' ) diff --git a/py_ballisticcalc_exts/py_ballisticcalc_exts/trajectory_calc.pyi b/py_ballisticcalc_exts/py_ballisticcalc_exts/trajectory_calc.pyi index cb3433c..62d08ec 100644 --- a/py_ballisticcalc_exts/py_ballisticcalc_exts/trajectory_calc.pyi +++ b/py_ballisticcalc_exts/py_ballisticcalc_exts/trajectory_calc.pyi @@ -1,16 +1,16 @@ +from dataclasses import dataclass from py_ballisticcalc.conditions import Atmo, Shot +from py_ballisticcalc.drag_model import DragDataPoint from py_ballisticcalc.munition import Ammo from py_ballisticcalc.unit import Angular, Distance -from _typeshed import Incomplete -from dataclasses import dataclass -from typing import NamedTuple +from typing_extensions import NamedTuple, Union __all__ = ['TrajectoryCalc', 'get_global_max_calc_step_size', 'get_global_use_powder_sensitivity', 'set_global_max_calc_step_size', 'set_global_use_powder_sensitivity', 'reset_globals'] def get_global_max_calc_step_size() -> Distance: ... def get_global_use_powder_sensitivity() -> bool: ... def reset_globals() -> None: ... -def set_global_max_calc_step_size(value: float | Distance) -> None: ... +def set_global_max_calc_step_size(value: Union[float, Distance]) -> None: ... def set_global_use_powder_sensitivity(value: bool) -> None: ... class CurvePoint(NamedTuple): @@ -36,22 +36,24 @@ class Vector: def __sub__(self, other: Vector) -> Vector: ... def __rsub__(self, other: Vector) -> Vector: ... def __isub__(self, other: Vector) -> Vector: ... - def __mul__(self, other: int | float | Vector) -> float | Vector: ... - def __rmul__(self, other: int | float | Vector) -> float | Vector: ... - def __imul__(self, other: int | float | Vector) -> float | Vector: ... + def __mul__(self, other: Union[int, float, 'Vector']) -> Union[float, 'Vector']: ... + def __rmul__(self, other: Union[int, float, 'Vector']) -> Union[float, 'Vector']: ... + def __imul__(self, other: Union[int, float, 'Vector']) -> Union[float, 'Vector']: ... def __neg__(self) -> Vector: ... def __init__(self, x, y, z) -> None: ... class TrajectoryCalc: - ammo: Incomplete - gravity_vector: Incomplete + ammo: Ammo + gravity_vector: Vector + barrel_azimuth: float + barrel_elevation: float + twist: float def __init__(self, ammo: Ammo) -> None: ... + @property + def table_data(self) -> list[DragDataPoint]: ... @staticmethod def get_calc_step(step: float = 0): ... def trajectory(self, shot_info: Shot, max_range: Distance, dist_step: Distance, extra_data: bool = False): ... - barrel_azimuth: float - barrel_elevation: Incomplete - twist: int def zero_angle(self, shot_info: Shot, distance: Distance) -> Angular: ... def drag_by_mach(self, mach: float) -> float: ... def spin_drift(self, time) -> float: ... diff --git a/py_ballisticcalc_exts/py_ballisticcalc_exts/trajectory_calc.pyx b/py_ballisticcalc_exts/py_ballisticcalc_exts/trajectory_calc.pyx index b68eb94..c7a9724 100644 --- a/py_ballisticcalc_exts/py_ballisticcalc_exts/trajectory_calc.pyx +++ b/py_ballisticcalc_exts/py_ballisticcalc_exts/trajectory_calc.pyx @@ -158,6 +158,10 @@ cdef class TrajectoryCalc: self._curve = calculate_curve(self._table_data) self.gravity_vector = Vector(.0, cGravityConstant, .0) + @property + def table_data(self) -> list: + return self._table_data + def zero_angle(self, shot_info: Shot, distance: Distance): return self._zero_angle(shot_info, distance) @@ -224,7 +228,7 @@ cdef class TrajectoryCalc: break iterations_count += 1 if zero_finding_error > cZeroFindingAccuracy: - raise Exception(f'Zero vertical error {zero_finding_error} feet, after {iterations_count} iterations.') + raise RuntimeError(f'Zero vertical error {zero_finding_error} feet, after {iterations_count} iterations.') return Angular.Radian(self.barrel_elevation) cdef _trajectory(TrajectoryCalc self, object shot_info,