From 525bff0b4bc7fd53e805fd9a620dedb15b811fa3 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sun, 8 Oct 2023 19:52:13 +0200 Subject: [PATCH 01/33] DOC: update README and add badges --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 66b90e3..681378a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,11 @@ -A python package for mechanical transmission analysis +# Mechanical Transmission Analysis + +[![PyPi](https://img.shields.io/pypi/v/gearpy)](https://pypi.org/project/gearpy/) +[![PyPi](https://img.shields.io/pypi/pyversions/gearpy.svg)](https://pypi.org/project/gearpy/) +[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://github.com/AndreaBlengino/gearpy/blob/v0.1.0/LICENSE) [![Tests](https://github.com/AndreaBlengino/gearpy/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/AndreaBlengino/gearpy/actions/workflows/tests.yml) +[![Documentation Status](https://readthedocs.org/projects/gearpy/badge/?version=latest)](https://gearpy.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/gh/AndreaBlengino/gearpy/graph/badge.svg?token=4JHzii1LrK)](https://codecov.io/gh/AndreaBlengino/gearpy) + +**gearpy** is a python package for mechanical transmission analysis. From 0284a04eeb95cfb9ebd4dbb6ad2bbb2a76070603 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sun, 8 Oct 2023 19:57:29 +0200 Subject: [PATCH 02/33] DOC: add CONTRIBUTING file, pull request, bug report and feature request templates --- .github/CONTRIBUTING.md | 49 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/bug_report.md | 50 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 +++++++++ .github/PULL_REQUEST_TEMPLATE.md | 28 +++++++++++++ 4 files changed, 147 insertions(+) create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..0675901 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,49 @@ +# Contributing to gearpy + +## Reporting issues + +When reporting issues please include as much detail as possible about +your operating system, python version, dependencies version and geapy +version. +Whenever possible, please also include a brief, self-contained code +example that demonstrates the problem. + +## Contributing code + +Thanks for your interest in contributing code to gearpy! + +Please be sure to follow the convention for commit messages, similar to +the [numpy commit message convention](https://numpy.org/devdocs/dev/development_workflow.html#writing-the-commit-message). +Commit messages should be clear and follow a few basic rules. Example: + +``` +ENH: add functionality X gearpy.. + +The first line of the commit message starts with a capitalized acronym +(options listed below) indicating what type of commit this is. Then a +blank line, then more text if needed. Lines shouldn't be longer than 72 +characters. If the commit is related to a ticket, indicate that with +"See #3456", "See ticket 3456", "Closes #3456" or similar. +``` + +Describing the motivation for a change, the nature of a bug for bug +fixes or some details on what an enhancement does are also good to +include in a commit message. Messages should be understandable without +looking at the code changes. A commit message like +`MNT: fixed another one` is an example of what not to do; the reader has +to go look for context elsewhere. +Standard acronyms to start the commit message with are: + +``` +BUG: bug fix +DEP: deprecate something or remove a deprecated object +DEV: development tool or utility +DOC: documentation +ENH: enhancement +MNT: maintenance commit (refactoring, typos, etc.) +REV: revert an earlier commit +STY: style fix (whitespace, PEP8) +TST: addition or modification of tests +REL: related to releasing gearpy +MRG: merging commit +``` diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..9681c74 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,50 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +Your issue may already be reported! +Please search on the [issue tracker](../) before creating one. + +## Bug Description + + +## Expected Behavior + + + +## Current Behavior + + + +## Possible Solution + + + +## Steps to Reproduce + + +1. +2. +3. +4. + +## Context + + + +## Your Environment + +* Operating System and version: +* Python version: +* Package version: +* Dependencies version: +* gearpy installation type: + - [ ] `pip install gearpy` + - [ ] from source (.tar.gz) + - [ ] `git clone` + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..74088cd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +## Is your feature request related to a problem? + + +## Describe the solution you'd like + + +## Describe alternatives you've considered + + +## Teachability, Documentation, Adoption + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..908978d --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,28 @@ + + +## Description + + +## Motivation and Context + + + +## How has this been tested? + + + + +## Types of changes + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) + +## Checklist: + + +- [ ] My code follows the code style of this project +- [ ] My change requires a change to the documentation +- [ ] I have updated the documentation accordingly +- [ ] I have added tests to cover my changes +- [ ] All new and existing tests passed From 3627169a087bf33d5128c41ae78611ee43b3f595 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Mon, 9 Oct 2023 23:11:55 +0200 Subject: [PATCH 03/33] MNT: fix typo in 'driven_by' error message --- gearpy/gear/gear.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gearpy/gear/gear.py b/gearpy/gear/gear.py index 3f67c3a..8ca08c5 100644 --- a/gearpy/gear/gear.py +++ b/gearpy/gear/gear.py @@ -36,7 +36,7 @@ def driven_by(self) -> RotatingObject: @abstractmethod def driven_by(self, driven_by: RotatingObject): if not isinstance(driven_by, RotatingObject): - raise TypeError("Parameter 'drives' must be a RotatingObject") + raise TypeError("Parameter 'driven_by' must be a RotatingObject") self.__driven_by = driven_by From e8d7a3d3e23080abb4b1a7696c1591e1299e0736 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Mon, 9 Oct 2023 23:17:35 +0200 Subject: [PATCH 04/33] DEV: add RotatingObject abstract properties to MotorBase and GearBase --- gearpy/gear/gear.py | 60 +++++++++++++++++++++++++++++++++++++++++++ gearpy/motor/motor.py | 60 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/gearpy/gear/gear.py b/gearpy/gear/gear.py index 8ca08c5..b09f764 100644 --- a/gearpy/gear/gear.py +++ b/gearpy/gear/gear.py @@ -53,6 +53,66 @@ def drives(self, drives: RotatingObject): self.__drives = drives + @property + @abstractmethod + def angle(self) -> Union[float, int]: + return super().angle + + @angle.setter + @abstractmethod + def angle(self, angle: Union[float, int]): + super(GearBase, type(self)).angle.fset(self, angle) + + @property + @abstractmethod + def speed(self) -> Union[float, int]: + return super().speed + + @speed.setter + @abstractmethod + def speed(self, speed: Union[float, int]): + super(GearBase, type(self)).speed.fset(self, speed) + + @property + @abstractmethod + def acceleration(self) -> Union[float, int]: + return super().acceleration + + @acceleration.setter + @abstractmethod + def acceleration(self, acceleration: Union[float, int]): + super(GearBase, type(self)).acceleration.fset(self, acceleration) + + @property + @abstractmethod + def torque(self) -> Union[float, int]: + return super().torque + + @torque.setter + @abstractmethod + def torque(self, torque: Union[float, int]): + super(GearBase, type(self)).torque.fset(self, torque) + + @property + @abstractmethod + def driving_torque(self) -> Union[float, int]: + return super().driving_torque + + @driving_torque.setter + @abstractmethod + def driving_torque(self, driving_torque: Union[float, int]): + super(GearBase, type(self)).driving_torque.fset(self, driving_torque) + + @property + @abstractmethod + def load_torque(self) -> Union[float, int]: + return super().load_torque + + @load_torque.setter + @abstractmethod + def load_torque(self, load_torque: Union[float, int]): + super(GearBase, type(self)).load_torque.fset(self, load_torque) + @property @abstractmethod def master_gear_ratio(self) -> float: diff --git a/gearpy/motor/motor.py b/gearpy/motor/motor.py index 6ee7907..1c7330f 100644 --- a/gearpy/motor/motor.py +++ b/gearpy/motor/motor.py @@ -23,5 +23,65 @@ def drives(self, drives: RotatingObject): self.__drives = drives + @property + @abstractmethod + def angle(self) -> Union[float, int]: + return super().angle + + @angle.setter + @abstractmethod + def angle(self, angle: Union[float, int]): + super(MotorBase, type(self)).angle.fset(self, angle) + + @property + @abstractmethod + def speed(self) -> Union[float, int]: + return super().speed + + @speed.setter + @abstractmethod + def speed(self, speed: Union[float, int]): + super(MotorBase, type(self)).speed.fset(self, speed) + + @property + @abstractmethod + def acceleration(self) -> Union[float, int]: + return super().acceleration + + @acceleration.setter + @abstractmethod + def acceleration(self, acceleration: Union[float, int]): + super(MotorBase, type(self)).acceleration.fset(self, acceleration) + + @property + @abstractmethod + def torque(self) -> Union[float, int]: + return super().torque + + @torque.setter + @abstractmethod + def torque(self, torque: Union[float, int]): + super(MotorBase, type(self)).torque.fset(self, torque) + + @property + @abstractmethod + def driving_torque(self) -> Union[float, int]: + return super().driving_torque + + @driving_torque.setter + @abstractmethod + def driving_torque(self, driving_torque: Union[float, int]): + super(MotorBase, type(self)).driving_torque.fset(self, driving_torque) + + @property + @abstractmethod + def load_torque(self) -> Union[float, int]: + return super().load_torque + + @load_torque.setter + @abstractmethod + def load_torque(self, load_torque: Union[float, int]): + super(MotorBase, type(self)).load_torque.fset(self, load_torque) + @abstractmethod def compute_torque(self): ... From e21e029bd346fa287d06930336bba3f57b438e19 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Tue, 10 Oct 2023 01:01:04 +0200 Subject: [PATCH 05/33] DEV: improve import strategy --- gearpy/__init__.py | 11 ++++++----- gearpy/gear/__init__.py | 2 ++ gearpy/gear/{gear.py => gear_base.py} | 2 +- gearpy/gear/spur_gear.py | 4 ++-- gearpy/mechanical_object/__init__.py | 2 ++ gearpy/motor/__init__.py | 2 ++ gearpy/motor/dc_motor.py | 4 ++-- gearpy/motor/{motor.py => motor_base.py} | 2 +- gearpy/solver/__init__.py | 1 + gearpy/solver/solver.py | 6 +++--- gearpy/transmission/__init__.py | 1 + gearpy/transmission/transmission.py | 2 +- gearpy/utils/__init__.py | 2 ++ gearpy/{utils.py => utils/relations.py} | 4 ++-- tests/conftest.py | 9 +++++---- tests/test_dc_motor.py | 3 ++- tests/test_solver.py | 2 +- tests/test_spur_gear.py | 3 ++- tests/test_transmission.py | 4 +++- tests/test_utils.py | 3 ++- 20 files changed, 43 insertions(+), 26 deletions(-) rename gearpy/gear/{gear.py => gear_base.py} (98%) rename gearpy/motor/{motor.py => motor_base.py} (97%) create mode 100644 gearpy/utils/__init__.py rename gearpy/{utils.py => utils/relations.py} (94%) diff --git a/gearpy/__init__.py b/gearpy/__init__.py index 9b484e4..e9106c1 100644 --- a/gearpy/__init__.py +++ b/gearpy/__init__.py @@ -1,5 +1,6 @@ -from .gear.spur_gear import SpurGear -from .utils import add_fixed_joint, add_gear_mating -from .motor.dc_motor import DCMotor -from .solver.solver import Solver -from .transmission.transmission import Transmission +from gearpy import gear +from gearpy import mechanical_object +from gearpy import motor +from gearpy import solver +from gearpy import transmission +from gearpy import utils diff --git a/gearpy/gear/__init__.py b/gearpy/gear/__init__.py index e69de29..b499520 100644 --- a/gearpy/gear/__init__.py +++ b/gearpy/gear/__init__.py @@ -0,0 +1,2 @@ +from .gear_base import GearBase +from .spur_gear import SpurGear diff --git a/gearpy/gear/gear.py b/gearpy/gear/gear_base.py similarity index 98% rename from gearpy/gear/gear.py rename to gearpy/gear/gear_base.py index b09f764..15dfe12 100644 --- a/gearpy/gear/gear.py +++ b/gearpy/gear/gear_base.py @@ -1,5 +1,5 @@ from abc import abstractmethod -from gearpy.mechanical_object.rotating_object import RotatingObject +from gearpy.mechanical_object import RotatingObject from typing import Callable, Union diff --git a/gearpy/gear/spur_gear.py b/gearpy/gear/spur_gear.py index 37abf1b..c197e19 100644 --- a/gearpy/gear/spur_gear.py +++ b/gearpy/gear/spur_gear.py @@ -1,5 +1,5 @@ -from .gear import GearBase -from gearpy.mechanical_object.rotating_object import RotatingObject +from gearpy.gear import GearBase +from gearpy.mechanical_object import RotatingObject from typing import Callable, Union diff --git a/gearpy/mechanical_object/__init__.py b/gearpy/mechanical_object/__init__.py index e69de29..de526a2 100644 --- a/gearpy/mechanical_object/__init__.py +++ b/gearpy/mechanical_object/__init__.py @@ -0,0 +1,2 @@ +from .mechanical_object import MechanicalObject +from .rotating_object import RotatingObject diff --git a/gearpy/motor/__init__.py b/gearpy/motor/__init__.py index e69de29..0731c80 100644 --- a/gearpy/motor/__init__.py +++ b/gearpy/motor/__init__.py @@ -0,0 +1,2 @@ +from .motor_base import MotorBase +from .dc_motor import DCMotor diff --git a/gearpy/motor/dc_motor.py b/gearpy/motor/dc_motor.py index 0e9cffe..baec22d 100644 --- a/gearpy/motor/dc_motor.py +++ b/gearpy/motor/dc_motor.py @@ -1,5 +1,5 @@ -from gearpy.mechanical_object.rotating_object import RotatingObject -from .motor import MotorBase +from gearpy.mechanical_object import RotatingObject +from gearpy.motor import MotorBase from typing import Union diff --git a/gearpy/motor/motor.py b/gearpy/motor/motor_base.py similarity index 97% rename from gearpy/motor/motor.py rename to gearpy/motor/motor_base.py index 1c7330f..f1fef19 100644 --- a/gearpy/motor/motor.py +++ b/gearpy/motor/motor_base.py @@ -1,5 +1,5 @@ from abc import abstractmethod -from gearpy.mechanical_object.rotating_object import RotatingObject +from gearpy.mechanical_object import RotatingObject from typing import Union diff --git a/gearpy/solver/__init__.py b/gearpy/solver/__init__.py index e69de29..70089f3 100644 --- a/gearpy/solver/__init__.py +++ b/gearpy/solver/__init__.py @@ -0,0 +1 @@ +from .solver import Solver diff --git a/gearpy/solver/solver.py b/gearpy/solver/solver.py index ad1b56e..be7a652 100644 --- a/gearpy/solver/solver.py +++ b/gearpy/solver/solver.py @@ -1,6 +1,6 @@ -from gearpy.mechanical_object.rotating_object import RotatingObject -from gearpy.motor.motor import MotorBase -from gearpy.transmission.transmission import Transmission +from gearpy.mechanical_object import RotatingObject +from gearpy.motor import MotorBase +from gearpy.transmission import Transmission import numpy as np from typing import Union diff --git a/gearpy/transmission/__init__.py b/gearpy/transmission/__init__.py index e69de29..80f9f9e 100644 --- a/gearpy/transmission/__init__.py +++ b/gearpy/transmission/__init__.py @@ -0,0 +1 @@ +from .transmission import Transmission diff --git a/gearpy/transmission/transmission.py b/gearpy/transmission/transmission.py index 3e2eccc..609e7b0 100644 --- a/gearpy/transmission/transmission.py +++ b/gearpy/transmission/transmission.py @@ -1,4 +1,4 @@ -from gearpy.motor.motor import MotorBase +from gearpy.motor import MotorBase class Transmission: diff --git a/gearpy/utils/__init__.py b/gearpy/utils/__init__.py new file mode 100644 index 0000000..e1b5455 --- /dev/null +++ b/gearpy/utils/__init__.py @@ -0,0 +1,2 @@ +from .relations import add_fixed_joint +from .relations import add_gear_mating diff --git a/gearpy/utils.py b/gearpy/utils/relations.py similarity index 94% rename from gearpy/utils.py rename to gearpy/utils/relations.py index 682566b..f33d821 100644 --- a/gearpy/utils.py +++ b/gearpy/utils/relations.py @@ -1,5 +1,5 @@ -from gearpy.gear.gear import GearBase -from gearpy.motor.motor import MotorBase +from gearpy.gear import GearBase +from gearpy.motor import MotorBase from typing import Union diff --git a/tests/conftest.py b/tests/conftest.py index 5e4c8c5..82b6a66 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,8 @@ -from gearpy import DCMotor, SpurGear, Transmission, add_fixed_joint, add_gear_mating -from gearpy.gear.gear import GearBase -from gearpy.motor.motor import MotorBase -from gearpy.mechanical_object.rotating_object import RotatingObject +from gearpy.gear import GearBase, SpurGear +from gearpy.mechanical_object import RotatingObject +from gearpy.motor import MotorBase, DCMotor +from gearpy.transmission import Transmission +from gearpy.utils import add_fixed_joint, add_gear_mating from hypothesis.strategies import composite, text, integers, floats, lists import numpy as np from pytest import fixture diff --git a/tests/test_dc_motor.py b/tests/test_dc_motor.py index 9fbdb20..6978aa4 100644 --- a/tests/test_dc_motor.py +++ b/tests/test_dc_motor.py @@ -1,4 +1,5 @@ -from gearpy import DCMotor, SpurGear +from gearpy.gear import SpurGear +from gearpy.motor import DCMotor from hypothesis import given, settings from hypothesis.strategies import text, floats from pytest import mark, raises diff --git a/tests/test_solver.py b/tests/test_solver.py index 57c9026..f6f5ab2 100644 --- a/tests/test_solver.py +++ b/tests/test_solver.py @@ -1,4 +1,4 @@ -from gearpy import Solver +from gearpy.solver import Solver from hypothesis import given, settings from hypothesis.strategies import floats, integers import numpy as np diff --git a/tests/test_spur_gear.py b/tests/test_spur_gear.py index e8ab3f9..a041e1b 100644 --- a/tests/test_spur_gear.py +++ b/tests/test_spur_gear.py @@ -1,4 +1,5 @@ -from gearpy import DCMotor, SpurGear +from gearpy.gear import SpurGear +from gearpy.motor import DCMotor from hypothesis import given, settings from hypothesis.strategies import text, floats, integers, functions from pytest import mark, raises diff --git a/tests/test_transmission.py b/tests/test_transmission.py index 2c9ed88..64ed95f 100644 --- a/tests/test_transmission.py +++ b/tests/test_transmission.py @@ -1,4 +1,6 @@ -from gearpy import DCMotor, Transmission, add_gear_mating, add_fixed_joint +from gearpy.motor import DCMotor +from gearpy.transmission import Transmission +from gearpy.utils import add_gear_mating, add_fixed_joint from hypothesis import given, settings from hypothesis.strategies import lists from pytest import mark, raises diff --git a/tests/test_utils.py b/tests/test_utils.py index 86d057c..df89689 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,4 +1,5 @@ -from gearpy import SpurGear, add_gear_mating, add_fixed_joint +from gearpy.gear import SpurGear +from gearpy.utils import add_gear_mating, add_fixed_joint from hypothesis import given, settings from hypothesis.strategies import floats from pytest import mark, raises From 02415a1c57e66be1505f7490b30413984019b7a4 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Tue, 10 Oct 2023 23:18:57 +0200 Subject: [PATCH 06/33] DOC: create documentation structure --- docs/source/conf.py | 9 ++++++++- docs/source/gear/SpurGear/index.rst | 14 +++++++++++++ docs/source/gear/index.rst | 16 +++++++++++++++ docs/source/index.rst | 20 ++++++++++++++----- docs/source/motor/DCMotor/index.rst | 14 +++++++++++++ docs/source/motor/index.rst | 16 +++++++++++++++ docs/source/requirements.txt | 1 + docs/source/solver/Solver/index.rst | 14 +++++++++++++ docs/source/solver/index.rst | 16 +++++++++++++++ .../transmission/Transmission/index.rst | 14 +++++++++++++ docs/source/transmission/index.rst | 16 +++++++++++++++ docs/source/utils/index.rst | 14 +++++++++++++ setup.py | 1 + 13 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 docs/source/gear/SpurGear/index.rst create mode 100644 docs/source/gear/index.rst create mode 100644 docs/source/motor/DCMotor/index.rst create mode 100644 docs/source/motor/index.rst create mode 100644 docs/source/solver/Solver/index.rst create mode 100644 docs/source/solver/index.rst create mode 100644 docs/source/transmission/Transmission/index.rst create mode 100644 docs/source/transmission/index.rst create mode 100644 docs/source/utils/index.rst diff --git a/docs/source/conf.py b/docs/source/conf.py index b7538bb..7521a61 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -3,6 +3,11 @@ # For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html +import os +import sys + +sys.path.insert(0, os.path.abspath('../..')) + # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information @@ -14,7 +19,7 @@ # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration -extensions = [] +extensions = ['sphinx.ext.autodoc', 'm2r2'] templates_path = ['_templates'] exclude_patterns = [] @@ -26,3 +31,5 @@ html_theme = 'alabaster' html_static_path = ['_static'] +add_module_names = False +html_title = 'gearpy' diff --git a/docs/source/gear/SpurGear/index.rst b/docs/source/gear/SpurGear/index.rst new file mode 100644 index 0000000..f45c8a8 --- /dev/null +++ b/docs/source/gear/SpurGear/index.rst @@ -0,0 +1,14 @@ +SpurGear +======== + + +.. currentmodule:: gearpy.gear +.. autoclass:: gearpy.gear.spur_gear.SpurGear + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: diff --git a/docs/source/gear/index.rst b/docs/source/gear/index.rst new file mode 100644 index 0000000..8c6fa18 --- /dev/null +++ b/docs/source/gear/index.rst @@ -0,0 +1,16 @@ +gear +==== + + +.. currentmodule:: gearpy.gear +.. autoclass:: gearpy.gear.spur_gear.SpurGear + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: + + SpurGear/index diff --git a/docs/source/index.rst b/docs/source/index.rst index d16ecce..e8d66cc 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,15 +1,25 @@ -Welcome to gearpy's documentation! -================================== +******************** +gearpy documentation +******************** + + +**Date**: |today| + +**Version**: |version| + .. toctree:: - :maxdepth: 2 - :caption: Contents: + :hidden: + :caption: Module + + gearpy + +.. mdinclude:: ../../README.md Indices and tables ================== -* :ref:`genindex` * :ref:`modindex` * :ref:`search` diff --git a/docs/source/motor/DCMotor/index.rst b/docs/source/motor/DCMotor/index.rst new file mode 100644 index 0000000..584671b --- /dev/null +++ b/docs/source/motor/DCMotor/index.rst @@ -0,0 +1,14 @@ +DCMotor +======= + + +.. currentmodule:: gearpy.motor +.. autoclass:: gearpy.motor.dc_motor.DCMotor + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: diff --git a/docs/source/motor/index.rst b/docs/source/motor/index.rst new file mode 100644 index 0000000..508de91 --- /dev/null +++ b/docs/source/motor/index.rst @@ -0,0 +1,16 @@ +motor +===== + + +.. currentmodule:: gearpy.motor +.. autoclass:: gearpy.motor.dc_motor.DCMotor + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: + + DCMotor/index diff --git a/docs/source/requirements.txt b/docs/source/requirements.txt index f3d691e..df8b94e 100644 --- a/docs/source/requirements.txt +++ b/docs/source/requirements.txt @@ -1 +1,2 @@ sphinx==7.2.6 +m2r2==0.3.3.post2 diff --git a/docs/source/solver/Solver/index.rst b/docs/source/solver/Solver/index.rst new file mode 100644 index 0000000..2aad9bc --- /dev/null +++ b/docs/source/solver/Solver/index.rst @@ -0,0 +1,14 @@ +Solver +====== + + +.. currentmodule:: gearpy.solver +.. autoclass:: gearpy.solver.solver.Solver + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: diff --git a/docs/source/solver/index.rst b/docs/source/solver/index.rst new file mode 100644 index 0000000..e624ed4 --- /dev/null +++ b/docs/source/solver/index.rst @@ -0,0 +1,16 @@ +solver +====== + + +.. currentmodule:: gearpy.solver +.. autoclass:: gearpy.solver.solver.Solver + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: + + Solver/index diff --git a/docs/source/transmission/Transmission/index.rst b/docs/source/transmission/Transmission/index.rst new file mode 100644 index 0000000..416dc6c --- /dev/null +++ b/docs/source/transmission/Transmission/index.rst @@ -0,0 +1,14 @@ +Transmission +============ + + +.. currentmodule:: gearpy.transmission +.. autoclass:: gearpy.transmission.transmission.Transmission + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: diff --git a/docs/source/transmission/index.rst b/docs/source/transmission/index.rst new file mode 100644 index 0000000..4115342 --- /dev/null +++ b/docs/source/transmission/index.rst @@ -0,0 +1,16 @@ +transmission +============ + + +.. currentmodule:: gearpy.transmission +.. autoclass:: gearpy.transmission.transmission.Transmission + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: + + Transmission/index diff --git a/docs/source/utils/index.rst b/docs/source/utils/index.rst new file mode 100644 index 0000000..f600723 --- /dev/null +++ b/docs/source/utils/index.rst @@ -0,0 +1,14 @@ +utils +===== + + +.. automodule:: gearpy.utils + :members: + :undoc-members: + :show-inheritance: + + +.. toctree:: + :hidden: + + diff --git a/setup.py b/setup.py index 7f2a5c3..9f0e176 100644 --- a/setup.py +++ b/setup.py @@ -30,6 +30,7 @@ 'Topic :: Scientific/Engineering'], install_requires = ['numpy >= 1.26.0'], extras_require = {'dev': ['sphinx >= 7.2.6', + 'm2r2 >= 0.3.3.post2', 'tox >= 4.11.3', 'hypothesis >= 6.87.1', 'twine >= 4.0.2']}, From 4ebf38221bb9d4ece4961a6a939b89c906f7cd72 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Tue, 10 Oct 2023 23:21:11 +0200 Subject: [PATCH 07/33] DOC: change documentation theme --- docs/source/conf.py | 2 +- docs/source/requirements.txt | 1 + setup.py | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 7521a61..8fe2004 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -29,7 +29,7 @@ # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = 'alabaster' +html_theme = 'furo' html_static_path = ['_static'] add_module_names = False html_title = 'gearpy' diff --git a/docs/source/requirements.txt b/docs/source/requirements.txt index df8b94e..ced87c5 100644 --- a/docs/source/requirements.txt +++ b/docs/source/requirements.txt @@ -1,2 +1,3 @@ sphinx==7.2.6 m2r2==0.3.3.post2 +furo==2023.9.10 diff --git a/setup.py b/setup.py index 9f0e176..e6cde99 100644 --- a/setup.py +++ b/setup.py @@ -31,6 +31,7 @@ install_requires = ['numpy >= 1.26.0'], extras_require = {'dev': ['sphinx >= 7.2.6', 'm2r2 >= 0.3.3.post2', + 'furo >= 2023.9.10', 'tox >= 4.11.3', 'hypothesis >= 6.87.1', 'twine >= 4.0.2']}, From a907abeae61d8a01a91c1f20defc06ce1dffd5a3 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Tue, 10 Oct 2023 23:22:38 +0200 Subject: [PATCH 08/33] DOC: add version into documentation --- docs/source/conf.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 8fe2004..bd686e0 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -5,16 +5,19 @@ import os import sys +import subprocess sys.path.insert(0, os.path.abspath('../..')) + # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information project = 'gearpy' copyright = '2023, Andrea Blengino' author = 'Andrea Blengino' -release = '0.0.1' +version = subprocess.run(['git', 'describe', '--tags'], stdout = subprocess.PIPE).stdout.decode('utf-8').split('-')[0] + # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration @@ -25,7 +28,6 @@ exclude_patterns = [] - # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output From cbe6e2b3ee984e62a4ad3bc76e37004c8f750064 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Tue, 10 Oct 2023 23:26:06 +0200 Subject: [PATCH 09/33] DOC: add documentation references --- docs/source/gearpy.rst | 12 ++++++++++++ docs/source/index.rst | 10 ++++++++++ docs/source/license.rst | 10 ++++++++++ 3 files changed, 32 insertions(+) create mode 100644 docs/source/gearpy.rst create mode 100644 docs/source/license.rst diff --git a/docs/source/gearpy.rst b/docs/source/gearpy.rst new file mode 100644 index 0000000..103f5fa --- /dev/null +++ b/docs/source/gearpy.rst @@ -0,0 +1,12 @@ +gearpy +====== + + +.. toctree:: + :hidden: + + gear/index + motor/index + solver/index + transmission/index + utils/index \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index e8d66cc..207a199 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -15,6 +15,16 @@ gearpy documentation gearpy +.. toctree:: + :hidden: + :caption: References + + Source Code + PyPI + Issue Tracker + license + + .. mdinclude:: ../../README.md diff --git a/docs/source/license.rst b/docs/source/license.rst new file mode 100644 index 0000000..d363ed4 --- /dev/null +++ b/docs/source/license.rst @@ -0,0 +1,10 @@ +License +======= + + +GNU General Public License v3.0 +------------------------------- + + +.. include:: ../../LICENSE + :literal: From 3147a19409ed34d5c1bc8dad9bcb1b62a03e5af1 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Wed, 11 Oct 2023 23:58:55 +0200 Subject: [PATCH 10/33] DEV: create UnitBase --- gearpy/__init__.py | 1 + gearpy/units/__init__.py | 1 + gearpy/units/unit_base.py | 31 +++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 gearpy/units/__init__.py create mode 100644 gearpy/units/unit_base.py diff --git a/gearpy/__init__.py b/gearpy/__init__.py index e9106c1..e5c5d0d 100644 --- a/gearpy/__init__.py +++ b/gearpy/__init__.py @@ -3,4 +3,5 @@ from gearpy import motor from gearpy import solver from gearpy import transmission +from gearpy import units from gearpy import utils diff --git a/gearpy/units/__init__.py b/gearpy/units/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/gearpy/units/__init__.py @@ -0,0 +1 @@ + diff --git a/gearpy/units/unit_base.py b/gearpy/units/unit_base.py new file mode 100644 index 0000000..3c9ba53 --- /dev/null +++ b/gearpy/units/unit_base.py @@ -0,0 +1,31 @@ +from abc import ABC, abstractmethod +from typing import Union + + +class UnitBase(ABC): + + __UNITS = {} + + @abstractmethod + def __init__(self, value: Union[float, int], unit: str): + if not isinstance(value, float) and not isinstance(value, int): + raise TypeError("Parameter 'value' must be a float or an integer.") + + if not isinstance(unit, str): + raise TypeError("Parameter 'unit' must be a string.") + + @abstractmethod + def __repr__(self): ... + + @property + @abstractmethod + def value(self) -> None: ... + + @property + @abstractmethod + def unit(self) -> None: ... + + @abstractmethod + def to(self, target_unit: str) -> None: + if not isinstance(target_unit, str): + raise TypeError("Parameter 'target_unit' must be a string.") From b2deb7f1767cbe73949fc797e9de08de4d74acd1 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Thu, 12 Oct 2023 00:02:20 +0200 Subject: [PATCH 11/33] DEV: create concrete unit classes Create Angle, Speed, Acceleration, Inertia, Torque and Time --- gearpy/units/__init__.py | 7 +++++- gearpy/units/acceleration.py | 42 +++++++++++++++++++++++++++++++ gearpy/units/angle.py | 44 ++++++++++++++++++++++++++++++++ gearpy/units/inertia.py | 45 +++++++++++++++++++++++++++++++++ gearpy/units/speed.py | 49 ++++++++++++++++++++++++++++++++++++ gearpy/units/time.py | 42 +++++++++++++++++++++++++++++++ gearpy/units/torque.py | 44 ++++++++++++++++++++++++++++++++ 7 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 gearpy/units/acceleration.py create mode 100644 gearpy/units/angle.py create mode 100644 gearpy/units/inertia.py create mode 100644 gearpy/units/speed.py create mode 100644 gearpy/units/time.py create mode 100644 gearpy/units/torque.py diff --git a/gearpy/units/__init__.py b/gearpy/units/__init__.py index 8b13789..e804fd5 100644 --- a/gearpy/units/__init__.py +++ b/gearpy/units/__init__.py @@ -1 +1,6 @@ - +from .acceleration import Acceleration +from .angle import Angle +from .inertia import Inertia +from .speed import Speed +from .time import Time +from .torque import Torque diff --git a/gearpy/units/acceleration.py b/gearpy/units/acceleration.py new file mode 100644 index 0000000..f6641d1 --- /dev/null +++ b/gearpy/units/acceleration.py @@ -0,0 +1,42 @@ +from math import pi +from typing import Union +from .unit_base import UnitBase + + +class Acceleration(UnitBase): + + __UNITS = {'rad/s^2': 1, + 'deg/s^2': pi/180} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"Acceleration unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str) -> 'Acceleration': + super().to(target_unit = target_unit) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"Acceleration unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + self.__unit = target_unit + + return self diff --git a/gearpy/units/angle.py b/gearpy/units/angle.py new file mode 100644 index 0000000..5008261 --- /dev/null +++ b/gearpy/units/angle.py @@ -0,0 +1,44 @@ +from math import pi +from typing import Union +from .unit_base import UnitBase + + +class Angle(UnitBase): + + __UNITS = {'rad': 1, + 'deg': pi/180, + 'arcmin': pi/180/60, + 'arcsec': pi/180/60/60} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"Angle unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str) -> 'Angle': + super().to(target_unit = target_unit) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"Angle unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + self.__unit = target_unit + + return self diff --git a/gearpy/units/inertia.py b/gearpy/units/inertia.py new file mode 100644 index 0000000..bb1b89f --- /dev/null +++ b/gearpy/units/inertia.py @@ -0,0 +1,45 @@ +from typing import Union +from .unit_base import UnitBase + + +class Inertia(UnitBase): + + __UNITS = {'kgm^2': 1, + 'gm^2': 1e-3, + 'gcm^2': 1e-7} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"Inertia unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + if value <= 0: + raise ValueError("Parameter 'value' must be positive.") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str) -> 'Inertia': + super().to(target_unit = target_unit) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"Inertia unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + self.__unit = target_unit + + return self diff --git a/gearpy/units/speed.py b/gearpy/units/speed.py new file mode 100644 index 0000000..e0a92af --- /dev/null +++ b/gearpy/units/speed.py @@ -0,0 +1,49 @@ +from math import pi +from typing import Union +from .unit_base import UnitBase + + +class Speed(UnitBase): + + __UNITS = {'rad/s': 1, + 'rad/min': 1/60, + 'rad/h': 1/60/60, + 'deg/s': pi/180, + 'deg/min': pi/180/60, + 'deg/h': pi/180/60/60, + 'rps': 2*pi, + 'rpm': 2*pi/60, + 'rph': 2*pi/60/60} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"Speed unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str) -> 'Speed': + super().to(target_unit = target_unit) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"Speed unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + self.__unit = target_unit + + return self diff --git a/gearpy/units/time.py b/gearpy/units/time.py new file mode 100644 index 0000000..0f80328 --- /dev/null +++ b/gearpy/units/time.py @@ -0,0 +1,42 @@ +from typing import Union +from .unit_base import UnitBase + + +class Time(UnitBase): + + __UNITS = {'sec': 1, + 'min': 60, + 'hour': 60*60} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"Time unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str) -> 'Time': + super().to(target_unit = target_unit) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"Time unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + self.__unit = target_unit + + return self diff --git a/gearpy/units/torque.py b/gearpy/units/torque.py new file mode 100644 index 0000000..cd93fb8 --- /dev/null +++ b/gearpy/units/torque.py @@ -0,0 +1,44 @@ +from typing import Union +from .unit_base import UnitBase + + +class Torque(UnitBase): + + __UNITS = {'Nm': 1, + 'mNm': 1e-3, + 'kNm': 1e3, + 'kgfm': 9.80665, + 'kgfcm': 9.80665e-2} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"Torque unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str) -> 'Torque': + super().to(target_unit = target_unit) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"Torque unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + self.__unit = target_unit + + return self From 9b5dff32c38219df2c0ede26853b18aead02fedb Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Thu, 12 Oct 2023 00:04:48 +0200 Subject: [PATCH 12/33] DEV: add unit operators to perform computations Add addition, subtraction, multiplication and division --- gearpy/units/acceleration.py | 57 ++++++++++++++++++++++++++++++++++++ gearpy/units/angle.py | 45 ++++++++++++++++++++++++++++ gearpy/units/inertia.py | 54 ++++++++++++++++++++++++++++++++++ gearpy/units/speed.py | 57 ++++++++++++++++++++++++++++++++++++ gearpy/units/time.py | 45 ++++++++++++++++++++++++++++ gearpy/units/torque.py | 53 +++++++++++++++++++++++++++++++++ gearpy/units/unit_base.py | 24 +++++++++++++++ 7 files changed, 335 insertions(+) diff --git a/gearpy/units/acceleration.py b/gearpy/units/acceleration.py index f6641d1..11e53bb 100644 --- a/gearpy/units/acceleration.py +++ b/gearpy/units/acceleration.py @@ -1,4 +1,6 @@ from math import pi +from .speed import Speed +from .time import Time from typing import Union from .unit_base import UnitBase @@ -21,6 +23,61 @@ def __init__(self, value: Union[float, int], unit: str): def __repr__(self) -> str: return f'{self.__value} {self.__unit}' + def __add__(self, other: 'Acceleration') -> 'Acceleration': + super().__add__(other = other) + + if not isinstance(other, Acceleration): + raise TypeError(f'It is not allowed to sum an Acceleration and a {other.__class__.__name__}.') + + return Acceleration(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __sub__(self, other: 'Acceleration') -> 'Acceleration': + super().__sub__(other = other) + + if not isinstance(other, Acceleration): + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an Acceleration.') + + return Acceleration(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __mul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration']: + super().__mul__(other = other) + + if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply an Acceleration by a {other.__class__.__name__}.') + + if isinstance(other, Time): + time = Time(value = other.value, unit = other.unit) + time.to('sec') + return Speed(value = self.__value*self.__UNITS[self.__unit]/self.__UNITS['rad/s^2']*time.value, + unit = 'rad/s') + return Acceleration(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration']: + super().__rmul__(other = other) + + if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an Acceleration.') + + if isinstance(other, Time): + time = Time(value = other.value, unit = other.unit) + time.to('sec') + return Speed(value = self.__value*self.__UNITS[self.__unit]/self.__UNITS['rad/s^2']*time.value, + unit = 'rad/s') + return Acceleration(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['Acceleration', float, int]) -> Union['Acceleration', float]: + super().__truediv__(other = other) + + if not isinstance(other, Acceleration) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to divide an Acceleration by a {other.__class__.__name__}.') + + if isinstance(other, Acceleration): + return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) + else: + return Acceleration(value = self.__value/other, unit = self.__unit) + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/angle.py b/gearpy/units/angle.py index 5008261..8ffdf6f 100644 --- a/gearpy/units/angle.py +++ b/gearpy/units/angle.py @@ -23,6 +23,51 @@ def __init__(self, value: Union[float, int], unit: str): def __repr__(self) -> str: return f'{self.__value} {self.__unit}' + def __add__(self, other: 'Angle') -> 'Angle': + super().__add__(other = other) + + if not isinstance(other, Angle): + raise TypeError(f'It is not allowed to sum an Angle and a {other.__class__.__name__}.') + + return Angle(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __sub__(self, other: 'Angle') -> 'Angle': + super().__sub__(other = other) + + if not isinstance(other, Angle): + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an Angle.') + + return Angle(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __mul__(self, other: Union[float, int]) -> 'Angle': + super().__mul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply an Angle by a {other.__class__.__name__}.') + + return Angle(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[float, int]) -> 'Angle': + super().__rmul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an Angle.') + + return Angle(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['Angle', float, int]) -> Union['Angle', float]: + super().__truediv__(other = other) + + if not isinstance(other, Angle) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to divide an Angle by a {other.__class__.__name__}.') + + if isinstance(other, Angle): + return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) + else: + return Angle(value = self.__value/other, unit = self.__unit) + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/inertia.py b/gearpy/units/inertia.py index bb1b89f..b7ca5cb 100644 --- a/gearpy/units/inertia.py +++ b/gearpy/units/inertia.py @@ -24,6 +24,60 @@ def __init__(self, value: Union[float, int], unit: str): def __repr__(self) -> str: return f'{self.__value} {self.__unit}' + def __add__(self, other: 'Inertia') -> 'Inertia': + super().__add__(other = other) + + if not isinstance(other, Inertia): + raise TypeError(f'It is not allowed to sum an Inertia and a {other.__class__.__name__}.') + + return Inertia(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __sub__(self, other: 'Inertia') -> 'Inertia': + super().__sub__(other = other) + + if not isinstance(other, Inertia): + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an Inertia.') + + if self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit] <= 0: + raise ValueError('Cannot perform the subtraction because the result is not positive.') + + return Inertia(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __mul__(self, other: Union[float, int]) -> 'Inertia': + super().__mul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply an Inertia by a {other.__class__.__name__}.') + + if other <= 0: + raise ValueError('Cannot perform a multiplication by a non-positive number.') + + return Inertia(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[float, int]) -> 'Inertia': + super().__rmul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an Inertia.') + + if other <= 0: + raise ValueError('Cannot perform a multiplication by a non-positive number.') + + return Inertia(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['Inertia', float, int]) -> Union['Inertia', float]: + super().__truediv__(other = other) + + if not isinstance(other, Inertia) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to divide an Inertia by a {other.__class__.__name__}.') + + if isinstance(other, Inertia): + return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) + else: + return Inertia(value = self.__value/other, unit = self.__unit) + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/speed.py b/gearpy/units/speed.py index e0a92af..1d1f2f0 100644 --- a/gearpy/units/speed.py +++ b/gearpy/units/speed.py @@ -1,4 +1,6 @@ +from .angle import Angle from math import pi +from .time import Time from typing import Union from .unit_base import UnitBase @@ -28,6 +30,61 @@ def __init__(self, value: Union[float, int], unit: str): def __repr__(self) -> str: return f'{self.__value} {self.__unit}' + def __add__(self, other: 'Speed') -> 'Speed': + super().__add__(other = other) + + if not isinstance(other, Speed): + raise TypeError(f'It is not allowed to sum a Speed and a {other.__class__.__name__}.') + + return Speed(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __sub__(self, other: 'Speed') -> 'Speed': + super().__sub__(other = other) + + if not isinstance(other, Speed): + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from a Speed.') + + return Speed(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __mul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: + super().__mul__(other = other) + + if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a Speed by a {other.__class__.__name__}.') + + if isinstance(other, Time): + time = Time(value = other.value, unit = other.unit) + time.to('sec') + return Angle(value = self.__value*self.__UNITS[self.__unit]/self.__UNITS['rad/s']*time.value, + unit = 'rad') + return Speed(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: + super().__rmul__(other = other) + + if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a Speed.') + + if isinstance(other, Time): + time = Time(value = other.value, unit = other.unit) + time.to('sec') + return Angle(value = self.__value*self.__UNITS[self.__unit]/self.__UNITS['rad/s']*time.value, + unit = 'rad') + return Speed(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['Speed', float, int]) -> Union['Speed', float]: + super().__truediv__(other = other) + + if not isinstance(other, Speed) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to divide a Speed by a {other.__class__.__name__}.') + + if isinstance(other, Speed): + return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) + else: + return Speed(value = self.__value/other, unit = self.__unit) + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/time.py b/gearpy/units/time.py index 0f80328..9839ab1 100644 --- a/gearpy/units/time.py +++ b/gearpy/units/time.py @@ -21,6 +21,51 @@ def __init__(self, value: Union[float, int], unit: str): def __repr__(self) -> str: return f'{self.__value} {self.__unit}' + def __add__(self, other: 'Time') -> 'Time': + super().__add__(other = other) + + if not isinstance(other, Time): + raise TypeError(f'It is not allowed to sum a Time and a {other.__class__.__name__}.') + + return Time(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __sub__(self, other: 'Time') -> 'Time': + super().__sub__(other = other) + + if not isinstance(other, Time): + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an Time.') + + return Time(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __mul__(self, other: Union[float, int]) -> 'Time': + super().__mul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a Time by a {other.__class__.__name__}.') + + return Time(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[float, int]) -> 'Time': + super().__rmul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a Time.') + + return Time(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: + super().__truediv__(other = other) + + if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to divide a Time by a {other.__class__.__name__}.') + + if isinstance(other, Time): + return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) + else: + return Time(value = self.__value/other, unit = self.__unit) + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/torque.py b/gearpy/units/torque.py index cd93fb8..29bd135 100644 --- a/gearpy/units/torque.py +++ b/gearpy/units/torque.py @@ -1,3 +1,5 @@ +from .acceleration import Acceleration +from .inertia import Inertia from typing import Union from .unit_base import UnitBase @@ -23,6 +25,57 @@ def __init__(self, value: Union[float, int], unit: str): def __repr__(self) -> str: return f'{self.__value} {self.__unit}' + def __add__(self, other: 'Torque') -> 'Torque': + super().__add__(other = other) + + if not isinstance(other, Torque): + raise TypeError(f'It is not allowed to sum a Torque and a {other.__class__.__name__}.') + + return Torque(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __sub__(self, other: 'Torque') -> 'Torque': + super().__sub__(other = other) + + if not isinstance(other, Torque): + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from a Torque.') + + return Torque(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], + unit = self.__unit) + + def __mul__(self, other: Union[float, int]) -> 'Torque': + super().__mul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a Torque by a {other.__class__.__name__}.') + + return Torque(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[float, int]) -> 'Torque': + super().__rmul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a Torque.') + + return Torque(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['Torque', float, int]) -> Union['Torque', 'Acceleration', float]: + super().__truediv__(other = other) + + if not isinstance(other, Torque) and not isinstance(other, float) and not isinstance(other, int) \ + and not isinstance(other, Inertia): + raise TypeError(f'It is not allowed to divide a Torque by a {other.__class__.__name__}.') + + if isinstance(other, Torque): + return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) + if isinstance(other, Inertia): + inertia = Inertia(value = other.value, unit = other.unit) + inertia.to('kgm^2') + return Acceleration(value = self.__value*self.__UNITS[self.__unit]/self.__UNITS['Nm']/inertia.value, + unit = 'rad/s^2') + else: + return Torque(value = self.__value/other, unit = self.__unit) + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/unit_base.py b/gearpy/units/unit_base.py index 3c9ba53..d160eaf 100644 --- a/gearpy/units/unit_base.py +++ b/gearpy/units/unit_base.py @@ -17,6 +17,30 @@ def __init__(self, value: Union[float, int], unit: str): @abstractmethod def __repr__(self): ... + @abstractmethod + def __add__(self, other: 'UnitBase') -> None: ... + + @abstractmethod + def __sub__(self, other: 'UnitBase') -> None: ... + + @abstractmethod + def __mul__(self, other: Union[float, int]) -> None: ... + + @abstractmethod + def __rmul__(self, other: Union[float, int]) -> None: ... + + @abstractmethod + def __truediv__(self, other: Union['UnitBase', float, int]) -> None: + if not isinstance(other, UnitBase) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to divide a Unit by a {other.__class__.__name__}.') + + if isinstance(other, UnitBase): + if other.value == 0: + raise ZeroDivisionError('It is not allowed to divide a Unit by zero.') + + if other == 0: + raise ZeroDivisionError('It is not allowed to divide a Unit by zero.') + @property @abstractmethod def value(self) -> None: ... From 22ff37f321ea2a04d8674ab10981e78b6a386f56 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Thu, 12 Oct 2023 00:08:49 +0200 Subject: [PATCH 13/33] DEV: edit RotatingObject and derivatives to accept UnitBase as input --- gearpy/gear/gear_base.py | 27 ++++----- gearpy/gear/spur_gear.py | 29 +++++----- gearpy/mechanical_object/rotating_object.py | 61 ++++++++++----------- gearpy/motor/dc_motor.py | 53 +++++++++--------- gearpy/motor/motor_base.py | 28 +++++----- 5 files changed, 99 insertions(+), 99 deletions(-) diff --git a/gearpy/gear/gear_base.py b/gearpy/gear/gear_base.py index 15dfe12..8064407 100644 --- a/gearpy/gear/gear_base.py +++ b/gearpy/gear/gear_base.py @@ -1,12 +1,13 @@ from abc import abstractmethod from gearpy.mechanical_object import RotatingObject +from gearpy.units import Acceleration, Angle, Inertia, Speed, Torque from typing import Callable, Union class GearBase(RotatingObject): @abstractmethod - def __init__(self, name: str, n_teeth: int, inertia: float): + def __init__(self, name: str, n_teeth: int, inertia: Inertia): super().__init__(name = name, inertia = inertia) if not isinstance(n_teeth, int): @@ -55,62 +56,62 @@ def drives(self, drives: RotatingObject): @property @abstractmethod - def angle(self) -> Union[float, int]: + def angle(self) -> Angle: return super().angle @angle.setter @abstractmethod - def angle(self, angle: Union[float, int]): + def angle(self, angle: Angle): super(GearBase, type(self)).angle.fset(self, angle) @property @abstractmethod - def speed(self) -> Union[float, int]: + def speed(self) -> Speed: return super().speed @speed.setter @abstractmethod - def speed(self, speed: Union[float, int]): + def speed(self, speed: Speed): super(GearBase, type(self)).speed.fset(self, speed) @property @abstractmethod - def acceleration(self) -> Union[float, int]: + def acceleration(self) -> Acceleration: return super().acceleration @acceleration.setter @abstractmethod - def acceleration(self, acceleration: Union[float, int]): + def acceleration(self, acceleration: Acceleration): super(GearBase, type(self)).acceleration.fset(self, acceleration) @property @abstractmethod - def torque(self) -> Union[float, int]: + def torque(self) -> Torque: return super().torque @torque.setter @abstractmethod - def torque(self, torque: Union[float, int]): + def torque(self, torque: Torque): super(GearBase, type(self)).torque.fset(self, torque) @property @abstractmethod - def driving_torque(self) -> Union[float, int]: + def driving_torque(self) -> Torque: return super().driving_torque @driving_torque.setter @abstractmethod - def driving_torque(self, driving_torque: Union[float, int]): + def driving_torque(self, driving_torque: Torque): super(GearBase, type(self)).driving_torque.fset(self, driving_torque) @property @abstractmethod - def load_torque(self) -> Union[float, int]: + def load_torque(self) -> Torque: return super().load_torque @load_torque.setter @abstractmethod - def load_torque(self, load_torque: Union[float, int]): + def load_torque(self, load_torque: Torque): super(GearBase, type(self)).load_torque.fset(self, load_torque) @property diff --git a/gearpy/gear/spur_gear.py b/gearpy/gear/spur_gear.py index c197e19..bdc9f42 100644 --- a/gearpy/gear/spur_gear.py +++ b/gearpy/gear/spur_gear.py @@ -1,11 +1,12 @@ from gearpy.gear import GearBase from gearpy.mechanical_object import RotatingObject +from gearpy.units import Acceleration, Angle, Inertia, Speed, Torque from typing import Callable, Union class SpurGear(GearBase): - def __init__(self, name: str, n_teeth: int, inertia: float): + def __init__(self, name: str, n_teeth: int, inertia: Inertia): super().__init__(name = name, n_teeth = n_teeth, inertia = inertia) @property @@ -49,55 +50,55 @@ def master_gear_efficiency(self, master_gear_efficiency: Union[float, int]): super(SpurGear, type(self)).master_gear_efficiency.fset(self, master_gear_efficiency) @property - def angle(self) -> Union[float, int]: + def angle(self) -> Angle: return super().angle @angle.setter - def angle(self, angle: Union[float, int]): + def angle(self, angle: Angle): super(SpurGear, type(self)).angle.fset(self, angle) @property - def speed(self) -> Union[float, int]: + def speed(self) -> Speed: return super().speed @speed.setter - def speed(self, speed: Union[float, int]): + def speed(self, speed: Speed): super(SpurGear, type(self)).speed.fset(self, speed) @property - def acceleration(self) -> Union[float, int]: + def acceleration(self) -> Acceleration: return super().acceleration @acceleration.setter - def acceleration(self, acceleration: Union[float, int]): + def acceleration(self, acceleration: Acceleration): super(SpurGear, type(self)).acceleration.fset(self, acceleration) @property - def torque(self) -> Union[float, int]: + def torque(self) -> Torque: return super().torque @torque.setter - def torque(self, torque: Union[float, int]): + def torque(self, torque: Torque): super(SpurGear, type(self)).torque.fset(self, torque) @property - def driving_torque(self) -> Union[float, int]: + def driving_torque(self) -> Torque: return super().driving_torque @driving_torque.setter - def driving_torque(self, driving_torque: Union[float, int]): + def driving_torque(self, driving_torque: Torque): super(SpurGear, type(self)).driving_torque.fset(self, driving_torque) @property - def load_torque(self) -> Union[float, int]: + def load_torque(self) -> Torque: return super().load_torque @load_torque.setter - def load_torque(self, load_torque: Union[float, int]): + def load_torque(self, load_torque: Torque): super(SpurGear, type(self)).load_torque.fset(self, load_torque) @property - def inertia(self) -> Union[float, int]: + def inertia(self) -> Inertia: return super().inertia @property diff --git a/gearpy/mechanical_object/rotating_object.py b/gearpy/mechanical_object/rotating_object.py index ab1c752..634a4ec 100644 --- a/gearpy/mechanical_object/rotating_object.py +++ b/gearpy/mechanical_object/rotating_object.py @@ -1,19 +1,16 @@ from abc import abstractmethod +from gearpy.units import Acceleration, Angle, Inertia, Speed, Torque from .mechanical_object import MechanicalObject -from typing import Union class RotatingObject(MechanicalObject): @abstractmethod - def __init__(self, name: str, inertia: Union[float, int]): + def __init__(self, name: str, inertia: Inertia): super().__init__(name = name) - if not isinstance(inertia, float) and not isinstance(inertia, int): - raise TypeError("Parameter 'inertia' must be a float or an integer.") - - if inertia <= 0: - raise ValueError("Parameter 'inertia' must be positive.") + if not isinstance(inertia, Inertia): + raise TypeError("Parameter 'inertia' must be an instance of Inertia.") self.__angle = None self.__speed = None @@ -31,85 +28,85 @@ def __init__(self, name: str, inertia: Union[float, int]): @property @abstractmethod - def angle(self) -> Union[float, int]: + def angle(self) -> Angle: return self.__angle @angle.setter @abstractmethod - def angle(self, angle: Union[float, int]): - if not isinstance(angle, float) and not isinstance(angle, int): - raise TypeError("Parameter 'angle' must be a float or an integer.") + def angle(self, angle: Angle): + if not isinstance(angle, Angle): + raise TypeError("Parameter 'angle' must be an instance of Angle.") self.__angle = angle @property @abstractmethod - def speed(self) -> Union[float, int]: + def speed(self) -> Speed: return self.__speed @speed.setter @abstractmethod - def speed(self, speed: Union[float, int]): - if not isinstance(speed, float) and not isinstance(speed, int): - raise TypeError("Parameter 'speed' must be a float or an integer.") + def speed(self, speed: Speed): + if not isinstance(speed, Speed): + raise TypeError("Parameter 'speed' must be an instance of Speed.") self.__speed = speed @property @abstractmethod - def acceleration(self) -> Union[float, int]: + def acceleration(self) -> Acceleration: return self.__acceleration @acceleration.setter @abstractmethod - def acceleration(self, acceleration: Union[float, int]): - if not isinstance(acceleration, float) and not isinstance(acceleration, int): - raise TypeError("Parameter 'acceleration' must be a float or an integer.") + def acceleration(self, acceleration: Acceleration): + if not isinstance(acceleration, Acceleration): + raise TypeError("Parameter 'acceleration' must be an instance of Acceleration.") self.__acceleration = acceleration @property @abstractmethod - def torque(self) -> Union[float, int]: + def torque(self) -> Torque: return self.__torque @torque.setter @abstractmethod - def torque(self, torque: Union[float, int]): - if not isinstance(torque, float) and not isinstance(torque, int): - raise TypeError("Parameter 'torque' must be a float or an integer.") + def torque(self, torque: Torque): + if not isinstance(torque, Torque): + raise TypeError("Parameter 'torque' must be an instance of Torque.") self.__torque = torque @property @abstractmethod - def driving_torque(self) -> Union[float, int]: + def driving_torque(self) -> Torque: return self.__driving_torque @driving_torque.setter @abstractmethod - def driving_torque(self, driving_torque: Union[float, int]): - if not isinstance(driving_torque, float) and not isinstance(driving_torque, int): - raise TypeError("Parameter 'driving_torque' must be a float or an integer.") + def driving_torque(self, driving_torque: Torque): + if not isinstance(driving_torque, Torque): + raise TypeError("Parameter 'driving_torque' must be an instance of Torque.") self.__driving_torque = driving_torque @property @abstractmethod - def load_torque(self) -> Union[float, int]: + def load_torque(self) -> Torque: return self.__load_torque @load_torque.setter @abstractmethod - def load_torque(self, load_torque: Union[float, int]): - if not isinstance(load_torque, float) and not isinstance(load_torque, int): - raise TypeError("Parameter 'load_torque' must be a float or an integer.") + def load_torque(self, load_torque: Torque): + if not isinstance(load_torque, Torque): + raise TypeError("Parameter 'load_torque' must be an instance of Torque.") self.__load_torque = load_torque @property @abstractmethod - def inertia(self) -> Union[float, int]: + def inertia(self) -> Inertia: return self.__inertia @property diff --git a/gearpy/motor/dc_motor.py b/gearpy/motor/dc_motor.py index baec22d..11642a6 100644 --- a/gearpy/motor/dc_motor.py +++ b/gearpy/motor/dc_motor.py @@ -1,24 +1,23 @@ from gearpy.mechanical_object import RotatingObject from gearpy.motor import MotorBase -from typing import Union +from gearpy.units import Acceleration, Angle, Inertia, Speed, Torque class DCMotor(MotorBase): - def __init__(self, name: str, inertia: Union[float, int], no_load_speed: Union[float, int], - maximum_torque: Union[float, int]): + def __init__(self, name: str, inertia: Inertia, no_load_speed: Speed, maximum_torque: Torque): super().__init__(name = name, inertia = inertia) - if not isinstance(no_load_speed, float) and not isinstance(no_load_speed, int): - raise TypeError("Parameter 'no_load_speed' must be a float or an integer.") + if not isinstance(no_load_speed, Speed): + raise TypeError("Parameter 'no_load_speed' must be an instance of Speed") - if not isinstance(maximum_torque, float) and not isinstance(maximum_torque, int): - raise TypeError("Parameter 'maximum_torque' must be a float or an integer.") + if not isinstance(maximum_torque, Torque): + raise TypeError("Parameter 'maximum_torque' must be an instance of Torque.") - if no_load_speed <= 0: + if no_load_speed.value <= 0: raise ValueError("Parameter 'no_load_speed' must be positive.") - if maximum_torque <= 0: + if maximum_torque.value <= 0: raise ValueError("Parameter 'maximum_torque' must be positive.") self.__no_load_speed = no_load_speed @@ -37,67 +36,69 @@ def drives(self, drives: RotatingObject): super(DCMotor, type(self)).drives.fset(self, drives) @property - def angle(self) -> Union[float, int]: + def angle(self) -> Angle: return super().angle @angle.setter - def angle(self, angle: Union[float, int]): + def angle(self, angle: Angle): super(DCMotor, type(self)).angle.fset(self, angle) @property - def speed(self) -> Union[float, int]: + def speed(self) -> Speed: return super().speed @speed.setter - def speed(self, speed: Union[float, int]): + def speed(self, speed: Speed): super(DCMotor, type(self)).speed.fset(self, speed) @property - def acceleration(self) -> Union[float, int]: + def acceleration(self) -> Acceleration: return super().acceleration @acceleration.setter - def acceleration(self, acceleration: Union[float, int]): + def acceleration(self, acceleration: Acceleration): super(DCMotor, type(self)).acceleration.fset(self, acceleration) @property - def no_load_speed(self) -> Union[float, int]: + def no_load_speed(self) -> Speed: return self.__no_load_speed @property - def maximum_torque(self) -> Union[float, int]: + def maximum_torque(self) -> Torque: return self.__maximum_torque @property - def torque(self) -> Union[float, int]: + def torque(self) -> Torque: return super().torque @torque.setter - def torque(self, torque: Union[float, int]): + def torque(self, torque: Torque): super(DCMotor, type(self)).torque.fset(self, torque) @property - def driving_torque(self) -> Union[float, int]: + def driving_torque(self) -> Torque: return super().driving_torque @driving_torque.setter - def driving_torque(self, driving_torque: Union[float, int]): + def driving_torque(self, driving_torque: Torque): super(DCMotor, type(self)).driving_torque.fset(self, driving_torque) @property - def load_torque(self) -> Union[float, int]: + def load_torque(self) -> Torque: return super().load_torque @load_torque.setter - def load_torque(self, load_torque: Union[float, int]): + def load_torque(self, load_torque: Torque): super(DCMotor, type(self)).load_torque.fset(self, load_torque) @property - def inertia(self) -> Union[float, int]: + def inertia(self) -> Inertia: return super().inertia - def compute_torque(self) -> Union[float, int]: - return (1 - self.speed/self.__no_load_speed)*self.__maximum_torque + def compute_torque(self) -> Torque: + return Torque(value = (1 - self.speed.to('rad/s').value/self.__no_load_speed.to('rad/s').value)* + self.__maximum_torque.value, + unit = self.__maximum_torque.unit) @property def time_variables(self) -> dict: diff --git a/gearpy/motor/motor_base.py b/gearpy/motor/motor_base.py index f1fef19..734dc3f 100644 --- a/gearpy/motor/motor_base.py +++ b/gearpy/motor/motor_base.py @@ -1,12 +1,12 @@ from abc import abstractmethod from gearpy.mechanical_object import RotatingObject -from typing import Union +from gearpy.units import Acceleration, Angle, Inertia, Speed, Torque class MotorBase(RotatingObject): @abstractmethod - def __init__(self, name: str, inertia: Union[float, int]): + def __init__(self, name: str, inertia: Inertia): super().__init__(name = name, inertia = inertia) self.__drives = None @@ -25,62 +25,62 @@ def drives(self, drives: RotatingObject): @property @abstractmethod - def angle(self) -> Union[float, int]: + def angle(self) -> Angle: return super().angle @angle.setter @abstractmethod - def angle(self, angle: Union[float, int]): + def angle(self, angle: Angle): super(MotorBase, type(self)).angle.fset(self, angle) @property @abstractmethod - def speed(self) -> Union[float, int]: + def speed(self) -> Speed: return super().speed @speed.setter @abstractmethod - def speed(self, speed: Union[float, int]): + def speed(self, speed: Speed): super(MotorBase, type(self)).speed.fset(self, speed) @property @abstractmethod - def acceleration(self) -> Union[float, int]: + def acceleration(self) -> Acceleration: return super().acceleration @acceleration.setter @abstractmethod - def acceleration(self, acceleration: Union[float, int]): + def acceleration(self, acceleration: Acceleration): super(MotorBase, type(self)).acceleration.fset(self, acceleration) @property @abstractmethod - def torque(self) -> Union[float, int]: + def torque(self) -> Torque: return super().torque @torque.setter @abstractmethod - def torque(self, torque: Union[float, int]): + def torque(self, torque: Torque): super(MotorBase, type(self)).torque.fset(self, torque) @property @abstractmethod - def driving_torque(self) -> Union[float, int]: + def driving_torque(self) -> Torque: return super().driving_torque @driving_torque.setter @abstractmethod - def driving_torque(self, driving_torque: Union[float, int]): + def driving_torque(self, driving_torque: Torque): super(MotorBase, type(self)).driving_torque.fset(self, driving_torque) @property @abstractmethod - def load_torque(self) -> Union[float, int]: + def load_torque(self) -> Torque: return super().load_torque @load_torque.setter @abstractmethod - def load_torque(self, load_torque: Union[float, int]): + def load_torque(self, load_torque: Torque): super(MotorBase, type(self)).load_torque.fset(self, load_torque) @abstractmethod From 17a0d87b73677a50e497536c4d4f1aba94d93eb9 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Thu, 12 Oct 2023 00:52:55 +0200 Subject: [PATCH 14/33] DEV: add comparison operator dunder methods --- gearpy/units/acceleration.py | 60 +++++++++++++++++++++++++++++++++++ gearpy/units/angle.py | 60 +++++++++++++++++++++++++++++++++++ gearpy/units/inertia.py | 60 +++++++++++++++++++++++++++++++++++ gearpy/units/speed.py | 60 +++++++++++++++++++++++++++++++++++ gearpy/units/time.py | 61 ++++++++++++++++++++++++++++++++++++ gearpy/units/torque.py | 60 +++++++++++++++++++++++++++++++++++ gearpy/units/unit_base.py | 22 +++++++++++-- 7 files changed, 381 insertions(+), 2 deletions(-) diff --git a/gearpy/units/acceleration.py b/gearpy/units/acceleration.py index 11e53bb..48ca947 100644 --- a/gearpy/units/acceleration.py +++ b/gearpy/units/acceleration.py @@ -78,6 +78,66 @@ def __truediv__(self, other: Union['Acceleration', float, int]) -> Union['Accele else: return Acceleration(value = self.__value/other, unit = self.__unit) + def __eq__(self, other: 'Acceleration') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Acceleration): + raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + + angle = Acceleration(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value == angle.value + + def __ne__(self, other: 'Acceleration') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Acceleration): + raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + + angle = Acceleration(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value != angle.value + + def __gt__(self, other: 'Acceleration') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Acceleration): + raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + + angle = Acceleration(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value > angle.value + + def __ge__(self, other: 'Acceleration') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Acceleration): + raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + + angle = Acceleration(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value >= angle.value + + def __lt__(self, other: 'Acceleration') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Acceleration): + raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + + angle = Acceleration(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value < angle.value + + def __le__(self, other: 'Acceleration') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Acceleration): + raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + + angle = Acceleration(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value <= angle.value + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/angle.py b/gearpy/units/angle.py index 8ffdf6f..b8f5c23 100644 --- a/gearpy/units/angle.py +++ b/gearpy/units/angle.py @@ -68,6 +68,66 @@ def __truediv__(self, other: Union['Angle', float, int]) -> Union['Angle', float else: return Angle(value = self.__value/other, unit = self.__unit) + def __eq__(self, other: 'Angle') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Angle): + raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + + angle = Angle(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value == angle.value + + def __ne__(self, other: 'Angle') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Angle): + raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + + angle = Angle(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value != angle.value + + def __gt__(self, other: 'Angle') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Angle): + raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + + angle = Angle(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value > angle.value + + def __ge__(self, other: 'Angle') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Angle): + raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + + angle = Angle(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value >= angle.value + + def __lt__(self, other: 'Angle') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Angle): + raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + + angle = Angle(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value < angle.value + + def __le__(self, other: 'Angle') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Angle): + raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + + angle = Angle(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value <= angle.value + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/inertia.py b/gearpy/units/inertia.py index b7ca5cb..b80d093 100644 --- a/gearpy/units/inertia.py +++ b/gearpy/units/inertia.py @@ -78,6 +78,66 @@ def __truediv__(self, other: Union['Inertia', float, int]) -> Union['Inertia', f else: return Inertia(value = self.__value/other, unit = self.__unit) + def __eq__(self, other: 'Inertia') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Inertia): + raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + + angle = Inertia(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value == angle.value + + def __ne__(self, other: 'Inertia') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Inertia): + raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + + angle = Inertia(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value != angle.value + + def __gt__(self, other: 'Inertia') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Inertia): + raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + + angle = Inertia(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value > angle.value + + def __ge__(self, other: 'Inertia') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Inertia): + raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + + angle = Inertia(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value >= angle.value + + def __lt__(self, other: 'Inertia') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Inertia): + raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + + angle = Inertia(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value < angle.value + + def __le__(self, other: 'Inertia') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Inertia): + raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + + angle = Inertia(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value <= angle.value + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/speed.py b/gearpy/units/speed.py index 1d1f2f0..73a89eb 100644 --- a/gearpy/units/speed.py +++ b/gearpy/units/speed.py @@ -85,6 +85,66 @@ def __truediv__(self, other: Union['Speed', float, int]) -> Union['Speed', float else: return Speed(value = self.__value/other, unit = self.__unit) + def __eq__(self, other: 'Speed') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Speed): + raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + + angle = Speed(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value == angle.value + + def __ne__(self, other: 'Speed') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Speed): + raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + + angle = Speed(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value != angle.value + + def __gt__(self, other: 'Speed') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Speed): + raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + + angle = Speed(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value > angle.value + + def __ge__(self, other: 'Speed') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Speed): + raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + + angle = Speed(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value >= angle.value + + def __lt__(self, other: 'Speed') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Speed): + raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + + angle = Speed(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value < angle.value + + def __le__(self, other: 'Speed') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Speed): + raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + + angle = Speed(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value <= angle.value + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/time.py b/gearpy/units/time.py index 9839ab1..73c7fc5 100644 --- a/gearpy/units/time.py +++ b/gearpy/units/time.py @@ -66,6 +66,67 @@ def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: else: return Time(value = self.__value/other, unit = self.__unit) + def __eq__(self, other: 'Time') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Time): + raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + + angle = Time(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value == angle.value + + def __ne__(self, other: 'Time') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Time): + raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + + + angle = Time(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value != angle.value + + def __gt__(self, other: 'Time') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Time): + raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + + angle = Time(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value > angle.value + + def __ge__(self, other: 'Time') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Time): + raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + + angle = Time(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value >= angle.value + + def __lt__(self, other: 'Time') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Time): + raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + + angle = Time(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value < angle.value + + def __le__(self, other: 'Time') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Time): + raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + + angle = Time(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value <= angle.value + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/torque.py b/gearpy/units/torque.py index 29bd135..3938d71 100644 --- a/gearpy/units/torque.py +++ b/gearpy/units/torque.py @@ -76,6 +76,66 @@ def __truediv__(self, other: Union['Torque', float, int]) -> Union['Torque', 'Ac else: return Torque(value = self.__value/other, unit = self.__unit) + def __eq__(self, other: 'Torque') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Torque): + raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + + angle = Torque(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value == angle.value + + def __ne__(self, other: 'Torque') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Torque): + raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + + angle = Torque(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value != angle.value + + def __gt__(self, other: 'Torque') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Torque): + raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + + angle = Torque(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value > angle.value + + def __ge__(self, other: 'Torque') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Torque): + raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + + angle = Torque(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value >= angle.value + + def __lt__(self, other: 'Torque') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Torque): + raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + + angle = Torque(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value < angle.value + + def __le__(self, other: 'Torque') -> bool: + super().__eq__(other = other) + + if not isinstance(other, Torque): + raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + + angle = Torque(value = other.value, unit = other.unit) + angle.to(self.__unit) + return self.__value <= angle.value + @property def value(self) -> Union[float, int]: return self.__value diff --git a/gearpy/units/unit_base.py b/gearpy/units/unit_base.py index d160eaf..2da7f3a 100644 --- a/gearpy/units/unit_base.py +++ b/gearpy/units/unit_base.py @@ -37,9 +37,27 @@ def __truediv__(self, other: Union['UnitBase', float, int]) -> None: if isinstance(other, UnitBase): if other.value == 0: raise ZeroDivisionError('It is not allowed to divide a Unit by zero.') + else: + if other == 0: + raise ZeroDivisionError('It is not allowed to divide a Unit by zero.') + + @abstractmethod + def __eq__(self, other: 'UnitBase') -> None: ... + + @abstractmethod + def __ne__(self, other: 'UnitBase') -> None: ... + + @abstractmethod + def __gt__(self, other: 'UnitBase') -> None: ... + + @abstractmethod + def __ge__(self, other: 'UnitBase') -> None: ... - if other == 0: - raise ZeroDivisionError('It is not allowed to divide a Unit by zero.') + @abstractmethod + def __lt__(self, other: 'UnitBase') -> None: ... + + @abstractmethod + def __le__(self, other: 'UnitBase') -> None: ... @property @abstractmethod From f5435d23742b8d683a1a9c925a1b6c0d93c050fa Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Thu, 12 Oct 2023 00:53:45 +0200 Subject: [PATCH 15/33] DEV: edit Solver to accept UnitBase as input --- gearpy/solver/solver.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/gearpy/solver/solver.py b/gearpy/solver/solver.py index be7a652..e955bd1 100644 --- a/gearpy/solver/solver.py +++ b/gearpy/solver/solver.py @@ -1,28 +1,26 @@ from gearpy.mechanical_object import RotatingObject from gearpy.motor import MotorBase from gearpy.transmission import Transmission +from gearpy.units import Time import numpy as np -from typing import Union class Solver: - def __init__(self, time_discretization: Union[float, int], - simulation_time: Union[float, int], - transmission: Transmission): - if not isinstance(time_discretization, float) and not isinstance(time_discretization, int): - raise TypeError("Parameter 'time_discretization' must be a float or an integer.") + def __init__(self, time_discretization: Time, simulation_time: Time, transmission: Transmission): + if not isinstance(time_discretization, Time): + raise TypeError("Parameter 'time_discretization' must be an instance of Time.") - if not isinstance(simulation_time, float) and not isinstance(simulation_time, int): - raise TypeError("Parameter 'simulation_time' must be a float or an integer.") + if not isinstance(simulation_time, Time): + raise TypeError("Parameter 'simulation_time' must be an instance of Time.") if not isinstance(transmission, Transmission): raise TypeError("Parameter 'transmission' must be an instance of Transmission.") - if time_discretization <= 0: + if time_discretization.value <= 0: raise ValueError("Parameter 'time_discretization' must be positive.") - if simulation_time <= 0: + if simulation_time.value <= 0: raise ValueError("Parameter 'time_simulation' must be positive.") if time_discretization >= simulation_time: @@ -40,7 +38,7 @@ def __init__(self, time_discretization: Union[float, int], self.time_discretization = time_discretization self.simulation_time = simulation_time self.transmission_chain = transmission.chain - self.time = [0] + self.time = [Time(value = 0, unit = time_discretization.unit)] def run(self): @@ -48,9 +46,9 @@ def run(self): self._compute_transmission_initial_state() self._update_time_variables() - for k in np.arange(self.time_discretization, self.simulation_time, self.time_discretization): + for k in np.arange(self.time_discretization.value, self.simulation_time.value, self.time_discretization.value): - self.time.append(k) + self.time.append(Time(value = float(k), unit = self.time_discretization.unit)) self._compute_kinematic_variables() self._compute_driving_torque() From 249af9b3e3d16a785bced927aa4a06b5997423d1 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Thu, 12 Oct 2023 23:40:10 +0200 Subject: [PATCH 16/33] ENH: improve error message f-strings --- gearpy/units/acceleration.py | 30 +++++++++++++++++------------- gearpy/units/angle.py | 30 +++++++++++++++++------------- gearpy/units/inertia.py | 30 +++++++++++++++++------------- gearpy/units/speed.py | 29 ++++++++++++++++------------- gearpy/units/time.py | 29 ++++++++++++++++------------- gearpy/units/torque.py | 29 ++++++++++++++++------------- 6 files changed, 99 insertions(+), 78 deletions(-) diff --git a/gearpy/units/acceleration.py b/gearpy/units/acceleration.py index 48ca947..de5c833 100644 --- a/gearpy/units/acceleration.py +++ b/gearpy/units/acceleration.py @@ -14,7 +14,7 @@ def __init__(self, value: Union[float, int], unit: str): super().__init__(value = value, unit = unit) if unit not in self.__UNITS.keys(): - raise KeyError(f"Acceleration unit '{unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") self.__value = value @@ -27,7 +27,7 @@ def __add__(self, other: 'Acceleration') -> 'Acceleration': super().__add__(other = other) if not isinstance(other, Acceleration): - raise TypeError(f'It is not allowed to sum an Acceleration and a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to sum an {self.__class__.__name__} and a {other.__class__.__name__}.') return Acceleration(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], unit = self.__unit) @@ -36,7 +36,8 @@ def __sub__(self, other: 'Acceleration') -> 'Acceleration': super().__sub__(other = other) if not isinstance(other, Acceleration): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an Acceleration.') + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' + f'{self.__class__.__name__}.') return Acceleration(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], unit = self.__unit) @@ -45,7 +46,8 @@ def __mul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration' super().__mul__(other = other) if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply an Acceleration by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to multiply an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') if isinstance(other, Time): time = Time(value = other.value, unit = other.unit) @@ -58,7 +60,8 @@ def __rmul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration super().__rmul__(other = other) if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an Acceleration.') + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an ' + f'{self.__class__.__name__}.') if isinstance(other, Time): time = Time(value = other.value, unit = other.unit) @@ -71,7 +74,8 @@ def __truediv__(self, other: Union['Acceleration', float, int]) -> Union['Accele super().__truediv__(other = other) if not isinstance(other, Acceleration) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to divide an Acceleration by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') if isinstance(other, Acceleration): return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) @@ -82,7 +86,7 @@ def __eq__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Acceleration(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -92,7 +96,7 @@ def __ne__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Acceleration(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -102,7 +106,7 @@ def __gt__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Acceleration(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -112,7 +116,7 @@ def __ge__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Acceleration(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -122,7 +126,7 @@ def __lt__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Acceleration(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -132,7 +136,7 @@ def __le__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare Acceleration and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Acceleration(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -150,7 +154,7 @@ def to(self, target_unit: str) -> 'Acceleration': super().to(target_unit = target_unit) if target_unit not in self.__UNITS.keys(): - raise KeyError(f"Acceleration unit '{target_unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] diff --git a/gearpy/units/angle.py b/gearpy/units/angle.py index b8f5c23..f580a4f 100644 --- a/gearpy/units/angle.py +++ b/gearpy/units/angle.py @@ -14,7 +14,7 @@ def __init__(self, value: Union[float, int], unit: str): super().__init__(value = value, unit = unit) if unit not in self.__UNITS.keys(): - raise KeyError(f"Angle unit '{unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") self.__value = value @@ -27,7 +27,7 @@ def __add__(self, other: 'Angle') -> 'Angle': super().__add__(other = other) if not isinstance(other, Angle): - raise TypeError(f'It is not allowed to sum an Angle and a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to sum an {self.__class__.__name__} and a {other.__class__.__name__}.') return Angle(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], unit = self.__unit) @@ -36,7 +36,8 @@ def __sub__(self, other: 'Angle') -> 'Angle': super().__sub__(other = other) if not isinstance(other, Angle): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an Angle.') + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' + f'{self.__class__.__name__}.') return Angle(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], unit = self.__unit) @@ -45,7 +46,8 @@ def __mul__(self, other: Union[float, int]) -> 'Angle': super().__mul__(other = other) if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply an Angle by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to multiply an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') return Angle(value = self.__value*other, unit = self.__unit) @@ -53,7 +55,8 @@ def __rmul__(self, other: Union[float, int]) -> 'Angle': super().__rmul__(other = other) if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an Angle.') + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an ' + f'{self.__class__.__name__}.') return Angle(value = self.__value*other, unit = self.__unit) @@ -61,7 +64,8 @@ def __truediv__(self, other: Union['Angle', float, int]) -> Union['Angle', float super().__truediv__(other = other) if not isinstance(other, Angle) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to divide an Angle by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') if isinstance(other, Angle): return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) @@ -72,7 +76,7 @@ def __eq__(self, other: 'Angle') -> bool: super().__eq__(other = other) if not isinstance(other, Angle): - raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Angle(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -82,7 +86,7 @@ def __ne__(self, other: 'Angle') -> bool: super().__eq__(other = other) if not isinstance(other, Angle): - raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Angle(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -92,7 +96,7 @@ def __gt__(self, other: 'Angle') -> bool: super().__eq__(other = other) if not isinstance(other, Angle): - raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Angle(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -102,7 +106,7 @@ def __ge__(self, other: 'Angle') -> bool: super().__eq__(other = other) if not isinstance(other, Angle): - raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Angle(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -112,7 +116,7 @@ def __lt__(self, other: 'Angle') -> bool: super().__eq__(other = other) if not isinstance(other, Angle): - raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Angle(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -122,7 +126,7 @@ def __le__(self, other: 'Angle') -> bool: super().__eq__(other = other) if not isinstance(other, Angle): - raise TypeError(f'Cannot compare Angle and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Angle(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -140,7 +144,7 @@ def to(self, target_unit: str) -> 'Angle': super().to(target_unit = target_unit) if target_unit not in self.__UNITS.keys(): - raise KeyError(f"Angle unit '{target_unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] diff --git a/gearpy/units/inertia.py b/gearpy/units/inertia.py index b80d093..e3e9815 100644 --- a/gearpy/units/inertia.py +++ b/gearpy/units/inertia.py @@ -12,7 +12,7 @@ def __init__(self, value: Union[float, int], unit: str): super().__init__(value = value, unit = unit) if unit not in self.__UNITS.keys(): - raise KeyError(f"Inertia unit '{unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") if value <= 0: @@ -28,7 +28,7 @@ def __add__(self, other: 'Inertia') -> 'Inertia': super().__add__(other = other) if not isinstance(other, Inertia): - raise TypeError(f'It is not allowed to sum an Inertia and a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to sum an {self.__class__.__name__} and a {other.__class__.__name__}.') return Inertia(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], unit = self.__unit) @@ -37,7 +37,8 @@ def __sub__(self, other: 'Inertia') -> 'Inertia': super().__sub__(other = other) if not isinstance(other, Inertia): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an Inertia.') + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' + f'{self.__class__.__name__}.') if self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit] <= 0: raise ValueError('Cannot perform the subtraction because the result is not positive.') @@ -49,7 +50,8 @@ def __mul__(self, other: Union[float, int]) -> 'Inertia': super().__mul__(other = other) if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply an Inertia by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to multiply an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') if other <= 0: raise ValueError('Cannot perform a multiplication by a non-positive number.') @@ -60,7 +62,8 @@ def __rmul__(self, other: Union[float, int]) -> 'Inertia': super().__rmul__(other = other) if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an Inertia.') + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an ' + f'{self.__class__.__name__}.') if other <= 0: raise ValueError('Cannot perform a multiplication by a non-positive number.') @@ -71,7 +74,8 @@ def __truediv__(self, other: Union['Inertia', float, int]) -> Union['Inertia', f super().__truediv__(other = other) if not isinstance(other, Inertia) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to divide an Inertia by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') if isinstance(other, Inertia): return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) @@ -82,7 +86,7 @@ def __eq__(self, other: 'Inertia') -> bool: super().__eq__(other = other) if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Inertia(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -92,7 +96,7 @@ def __ne__(self, other: 'Inertia') -> bool: super().__eq__(other = other) if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Inertia(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -102,7 +106,7 @@ def __gt__(self, other: 'Inertia') -> bool: super().__eq__(other = other) if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Inertia(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -112,7 +116,7 @@ def __ge__(self, other: 'Inertia') -> bool: super().__eq__(other = other) if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Inertia(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -122,7 +126,7 @@ def __lt__(self, other: 'Inertia') -> bool: super().__eq__(other = other) if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Inertia(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -132,7 +136,7 @@ def __le__(self, other: 'Inertia') -> bool: super().__eq__(other = other) if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare Inertia and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Inertia(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -150,7 +154,7 @@ def to(self, target_unit: str) -> 'Inertia': super().to(target_unit = target_unit) if target_unit not in self.__UNITS.keys(): - raise KeyError(f"Inertia unit '{target_unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] diff --git a/gearpy/units/speed.py b/gearpy/units/speed.py index 73a89eb..9b772ca 100644 --- a/gearpy/units/speed.py +++ b/gearpy/units/speed.py @@ -21,7 +21,7 @@ def __init__(self, value: Union[float, int], unit: str): super().__init__(value = value, unit = unit) if unit not in self.__UNITS.keys(): - raise KeyError(f"Speed unit '{unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") self.__value = value @@ -34,7 +34,7 @@ def __add__(self, other: 'Speed') -> 'Speed': super().__add__(other = other) if not isinstance(other, Speed): - raise TypeError(f'It is not allowed to sum a Speed and a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to sum a {self.__class__.__name__} and a {other.__class__.__name__}.') return Speed(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], unit = self.__unit) @@ -43,7 +43,8 @@ def __sub__(self, other: 'Speed') -> 'Speed': super().__sub__(other = other) if not isinstance(other, Speed): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from a Speed.') + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from a ' + f'{self.__class__.__name__}.') return Speed(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], unit = self.__unit) @@ -52,7 +53,8 @@ def __mul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: super().__mul__(other = other) if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a Speed by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to multiply a {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') if isinstance(other, Time): time = Time(value = other.value, unit = other.unit) @@ -65,7 +67,8 @@ def __rmul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: super().__rmul__(other = other) if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a Speed.') + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a ' + f'{self.__class__.__name__}.') if isinstance(other, Time): time = Time(value = other.value, unit = other.unit) @@ -78,7 +81,7 @@ def __truediv__(self, other: Union['Speed', float, int]) -> Union['Speed', float super().__truediv__(other = other) if not isinstance(other, Speed) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to divide a Speed by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') if isinstance(other, Speed): return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) @@ -89,7 +92,7 @@ def __eq__(self, other: 'Speed') -> bool: super().__eq__(other = other) if not isinstance(other, Speed): - raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Speed(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -99,7 +102,7 @@ def __ne__(self, other: 'Speed') -> bool: super().__eq__(other = other) if not isinstance(other, Speed): - raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Speed(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -109,7 +112,7 @@ def __gt__(self, other: 'Speed') -> bool: super().__eq__(other = other) if not isinstance(other, Speed): - raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Speed(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -119,7 +122,7 @@ def __ge__(self, other: 'Speed') -> bool: super().__eq__(other = other) if not isinstance(other, Speed): - raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Speed(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -129,7 +132,7 @@ def __lt__(self, other: 'Speed') -> bool: super().__eq__(other = other) if not isinstance(other, Speed): - raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Speed(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -139,7 +142,7 @@ def __le__(self, other: 'Speed') -> bool: super().__eq__(other = other) if not isinstance(other, Speed): - raise TypeError(f'Cannot compare Speed and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Speed(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -157,7 +160,7 @@ def to(self, target_unit: str) -> 'Speed': super().to(target_unit = target_unit) if target_unit not in self.__UNITS.keys(): - raise KeyError(f"Speed unit '{target_unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] diff --git a/gearpy/units/time.py b/gearpy/units/time.py index 73c7fc5..2ce6d8f 100644 --- a/gearpy/units/time.py +++ b/gearpy/units/time.py @@ -12,7 +12,7 @@ def __init__(self, value: Union[float, int], unit: str): super().__init__(value = value, unit = unit) if unit not in self.__UNITS.keys(): - raise KeyError(f"Time unit '{unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") self.__value = value @@ -25,7 +25,7 @@ def __add__(self, other: 'Time') -> 'Time': super().__add__(other = other) if not isinstance(other, Time): - raise TypeError(f'It is not allowed to sum a Time and a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to sum a {self.__class__.__name__} and a {other.__class__.__name__}.') return Time(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], unit = self.__unit) @@ -34,7 +34,8 @@ def __sub__(self, other: 'Time') -> 'Time': super().__sub__(other = other) if not isinstance(other, Time): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an Time.') + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' + f'{self.__class__.__name__}.') return Time(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], unit = self.__unit) @@ -43,7 +44,8 @@ def __mul__(self, other: Union[float, int]) -> 'Time': super().__mul__(other = other) if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a Time by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to multiply a {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') return Time(value = self.__value*other, unit = self.__unit) @@ -51,7 +53,8 @@ def __rmul__(self, other: Union[float, int]) -> 'Time': super().__rmul__(other = other) if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a Time.') + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a ' + f'{self.__class__.__name__}.') return Time(value = self.__value*other, unit = self.__unit) @@ -59,7 +62,7 @@ def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: super().__truediv__(other = other) if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to divide a Time by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') if isinstance(other, Time): return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) @@ -70,7 +73,7 @@ def __eq__(self, other: 'Time') -> bool: super().__eq__(other = other) if not isinstance(other, Time): - raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Time(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -80,7 +83,7 @@ def __ne__(self, other: 'Time') -> bool: super().__eq__(other = other) if not isinstance(other, Time): - raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Time(value = other.value, unit = other.unit) @@ -91,7 +94,7 @@ def __gt__(self, other: 'Time') -> bool: super().__eq__(other = other) if not isinstance(other, Time): - raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Time(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -101,7 +104,7 @@ def __ge__(self, other: 'Time') -> bool: super().__eq__(other = other) if not isinstance(other, Time): - raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Time(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -111,7 +114,7 @@ def __lt__(self, other: 'Time') -> bool: super().__eq__(other = other) if not isinstance(other, Time): - raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Time(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -121,7 +124,7 @@ def __le__(self, other: 'Time') -> bool: super().__eq__(other = other) if not isinstance(other, Time): - raise TypeError(f'Cannot compare Time and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Time(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -139,7 +142,7 @@ def to(self, target_unit: str) -> 'Time': super().to(target_unit = target_unit) if target_unit not in self.__UNITS.keys(): - raise KeyError(f"Time unit '{target_unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] diff --git a/gearpy/units/torque.py b/gearpy/units/torque.py index 3938d71..676882a 100644 --- a/gearpy/units/torque.py +++ b/gearpy/units/torque.py @@ -16,7 +16,7 @@ def __init__(self, value: Union[float, int], unit: str): super().__init__(value = value, unit = unit) if unit not in self.__UNITS.keys(): - raise KeyError(f"Torque unit '{unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") self.__value = value @@ -29,7 +29,7 @@ def __add__(self, other: 'Torque') -> 'Torque': super().__add__(other = other) if not isinstance(other, Torque): - raise TypeError(f'It is not allowed to sum a Torque and a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to sum a {self.__class__.__name__} and a {other.__class__.__name__}.') return Torque(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], unit = self.__unit) @@ -38,7 +38,8 @@ def __sub__(self, other: 'Torque') -> 'Torque': super().__sub__(other = other) if not isinstance(other, Torque): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from a Torque.') + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from a ' + f'{self.__class__.__name__}.') return Torque(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], unit = self.__unit) @@ -47,7 +48,8 @@ def __mul__(self, other: Union[float, int]) -> 'Torque': super().__mul__(other = other) if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a Torque by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to multiply a {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') return Torque(value = self.__value*other, unit = self.__unit) @@ -55,7 +57,8 @@ def __rmul__(self, other: Union[float, int]) -> 'Torque': super().__rmul__(other = other) if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a Torque.') + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a ' + f'{self.__class__.__name__}.') return Torque(value = self.__value*other, unit = self.__unit) @@ -64,7 +67,7 @@ def __truediv__(self, other: Union['Torque', float, int]) -> Union['Torque', 'Ac if not isinstance(other, Torque) and not isinstance(other, float) and not isinstance(other, int) \ and not isinstance(other, Inertia): - raise TypeError(f'It is not allowed to divide a Torque by a {other.__class__.__name__}.') + raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') if isinstance(other, Torque): return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) @@ -80,7 +83,7 @@ def __eq__(self, other: 'Torque') -> bool: super().__eq__(other = other) if not isinstance(other, Torque): - raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Torque(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -90,7 +93,7 @@ def __ne__(self, other: 'Torque') -> bool: super().__eq__(other = other) if not isinstance(other, Torque): - raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Torque(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -100,7 +103,7 @@ def __gt__(self, other: 'Torque') -> bool: super().__eq__(other = other) if not isinstance(other, Torque): - raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Torque(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -110,7 +113,7 @@ def __ge__(self, other: 'Torque') -> bool: super().__eq__(other = other) if not isinstance(other, Torque): - raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Torque(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -120,7 +123,7 @@ def __lt__(self, other: 'Torque') -> bool: super().__eq__(other = other) if not isinstance(other, Torque): - raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Torque(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -130,7 +133,7 @@ def __le__(self, other: 'Torque') -> bool: super().__eq__(other = other) if not isinstance(other, Torque): - raise TypeError(f'Cannot compare Torque and {other.__class__.__name__}') + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') angle = Torque(value = other.value, unit = other.unit) angle.to(self.__unit) @@ -148,7 +151,7 @@ def to(self, target_unit: str) -> 'Torque': super().to(target_unit = target_unit) if target_unit not in self.__UNITS.keys(): - raise KeyError(f"Torque unit '{target_unit}' not available. " + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] From 8d476903f95238ea1c505122c2f26eafa39ddfdc Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Fri, 13 Oct 2023 00:34:16 +0200 Subject: [PATCH 17/33] DEV: add 'inplace' parameter to '.to' method If 'inplace' is True, the method overwrite the instance value and unit, otherwise returns another instance with converted value and unit --- gearpy/units/acceleration.py | 62 ++++++++++++++---------------------- gearpy/units/angle.py | 46 +++++++++++--------------- gearpy/units/inertia.py | 48 +++++++++++----------------- gearpy/units/speed.py | 62 ++++++++++++++---------------------- gearpy/units/time.py | 47 +++++++++++---------------- gearpy/units/torque.py | 53 ++++++++++++------------------ gearpy/units/unit_base.py | 5 ++- 7 files changed, 127 insertions(+), 196 deletions(-) diff --git a/gearpy/units/acceleration.py b/gearpy/units/acceleration.py index de5c833..02c3b57 100644 --- a/gearpy/units/acceleration.py +++ b/gearpy/units/acceleration.py @@ -29,8 +29,7 @@ def __add__(self, other: 'Acceleration') -> 'Acceleration': if not isinstance(other, Acceleration): raise TypeError(f'It is not allowed to sum an {self.__class__.__name__} and a {other.__class__.__name__}.') - return Acceleration(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Acceleration(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Acceleration') -> 'Acceleration': super().__sub__(other = other) @@ -39,8 +38,7 @@ def __sub__(self, other: 'Acceleration') -> 'Acceleration': raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' f'{self.__class__.__name__}.') - return Acceleration(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Acceleration(value = self.__value - other.to(self.__unit).value, unit = self.__unit) def __mul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration']: super().__mul__(other = other) @@ -50,11 +48,9 @@ def __mul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration' f'{other.__class__.__name__}.') if isinstance(other, Time): - time = Time(value = other.value, unit = other.unit) - time.to('sec') - return Speed(value = self.__value*self.__UNITS[self.__unit]/self.__UNITS['rad/s^2']*time.value, - unit = 'rad/s') - return Acceleration(value = self.__value*other, unit = self.__unit) + return Speed(value = self.to('rad/s^2').value*other.to('sec').value, unit = 'rad/s') + else: + return Acceleration(value = self.__value*other, unit = self.__unit) def __rmul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration']: super().__rmul__(other = other) @@ -64,11 +60,9 @@ def __rmul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration f'{self.__class__.__name__}.') if isinstance(other, Time): - time = Time(value = other.value, unit = other.unit) - time.to('sec') - return Speed(value = self.__value*self.__UNITS[self.__unit]/self.__UNITS['rad/s^2']*time.value, - unit = 'rad/s') - return Acceleration(value = self.__value*other, unit = self.__unit) + return Speed(value = self.to('rad/s^2').value*other.to('sec').value, unit = 'rad/s') + else: + return Acceleration(value = self.__value*other, unit = self.__unit) def __truediv__(self, other: Union['Acceleration', float, int]) -> Union['Acceleration', float]: super().__truediv__(other = other) @@ -78,7 +72,7 @@ def __truediv__(self, other: Union['Acceleration', float, int]) -> Union['Accele f'{other.__class__.__name__}.') if isinstance(other, Acceleration): - return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) + return self.__value/other.to(self.__unit).value else: return Acceleration(value = self.__value/other, unit = self.__unit) @@ -88,9 +82,7 @@ def __eq__(self, other: 'Acceleration') -> bool: if not isinstance(other, Acceleration): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Acceleration(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value == angle.value + return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) @@ -98,9 +90,7 @@ def __ne__(self, other: 'Acceleration') -> bool: if not isinstance(other, Acceleration): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Acceleration(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value != angle.value + return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) @@ -108,9 +98,7 @@ def __gt__(self, other: 'Acceleration') -> bool: if not isinstance(other, Acceleration): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Acceleration(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value > angle.value + return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) @@ -118,9 +106,7 @@ def __ge__(self, other: 'Acceleration') -> bool: if not isinstance(other, Acceleration): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Acceleration(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value >= angle.value + return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) @@ -128,9 +114,7 @@ def __lt__(self, other: 'Acceleration') -> bool: if not isinstance(other, Acceleration): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Acceleration(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value < angle.value + return self.__value < other.to(self.__unit).value def __le__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) @@ -138,9 +122,7 @@ def __le__(self, other: 'Acceleration') -> bool: if not isinstance(other, Acceleration): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Acceleration(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value <= angle.value + return self.__value <= other.to(self.__unit).value @property def value(self) -> Union[float, int]: @@ -150,14 +132,18 @@ def value(self) -> Union[float, int]: def unit(self) -> str: return self.__unit - def to(self, target_unit: str) -> 'Acceleration': - super().to(target_unit = target_unit) + def to(self, target_unit: str, inplace: bool = False) -> 'Acceleration': + super().to(target_unit = target_unit, inplace = inplace) if target_unit not in self.__UNITS.keys(): raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - self.__unit = target_unit + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - return self + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return Acceleration(value = target_value, unit = target_unit) diff --git a/gearpy/units/angle.py b/gearpy/units/angle.py index f580a4f..c68fbdb 100644 --- a/gearpy/units/angle.py +++ b/gearpy/units/angle.py @@ -29,8 +29,7 @@ def __add__(self, other: 'Angle') -> 'Angle': if not isinstance(other, Angle): raise TypeError(f'It is not allowed to sum an {self.__class__.__name__} and a {other.__class__.__name__}.') - return Angle(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Angle(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Angle') -> 'Angle': super().__sub__(other = other) @@ -39,8 +38,7 @@ def __sub__(self, other: 'Angle') -> 'Angle': raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' f'{self.__class__.__name__}.') - return Angle(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Angle(value = self.__value - other.to(self.__unit).value, unit = self.__unit) def __mul__(self, other: Union[float, int]) -> 'Angle': super().__mul__(other = other) @@ -68,7 +66,7 @@ def __truediv__(self, other: Union['Angle', float, int]) -> Union['Angle', float f'{other.__class__.__name__}.') if isinstance(other, Angle): - return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) + return self.__value/other.to(self.__unit).value else: return Angle(value = self.__value/other, unit = self.__unit) @@ -78,9 +76,7 @@ def __eq__(self, other: 'Angle') -> bool: if not isinstance(other, Angle): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Angle(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value == angle.value + return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Angle') -> bool: super().__eq__(other = other) @@ -88,9 +84,7 @@ def __ne__(self, other: 'Angle') -> bool: if not isinstance(other, Angle): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Angle(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value != angle.value + return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Angle') -> bool: super().__eq__(other = other) @@ -98,9 +92,7 @@ def __gt__(self, other: 'Angle') -> bool: if not isinstance(other, Angle): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Angle(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value > angle.value + return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Angle') -> bool: super().__eq__(other = other) @@ -108,9 +100,7 @@ def __ge__(self, other: 'Angle') -> bool: if not isinstance(other, Angle): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Angle(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value >= angle.value + return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Angle') -> bool: super().__eq__(other = other) @@ -118,9 +108,7 @@ def __lt__(self, other: 'Angle') -> bool: if not isinstance(other, Angle): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Angle(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value < angle.value + return self.__value < other.to(self.__unit).value def __le__(self, other: 'Angle') -> bool: super().__eq__(other = other) @@ -128,9 +116,7 @@ def __le__(self, other: 'Angle') -> bool: if not isinstance(other, Angle): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Angle(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value <= angle.value + return self.__value <= other.to(self.__unit).value @property def value(self) -> Union[float, int]: @@ -140,14 +126,18 @@ def value(self) -> Union[float, int]: def unit(self) -> str: return self.__unit - def to(self, target_unit: str) -> 'Angle': - super().to(target_unit = target_unit) + def to(self, target_unit: str, inplace: bool = False) -> 'Angle': + super().to(target_unit = target_unit, inplace = inplace) if target_unit not in self.__UNITS.keys(): raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - self.__unit = target_unit + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - return self + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return Angle(value = target_value, unit = target_unit) diff --git a/gearpy/units/inertia.py b/gearpy/units/inertia.py index e3e9815..e3f8110 100644 --- a/gearpy/units/inertia.py +++ b/gearpy/units/inertia.py @@ -30,8 +30,7 @@ def __add__(self, other: 'Inertia') -> 'Inertia': if not isinstance(other, Inertia): raise TypeError(f'It is not allowed to sum an {self.__class__.__name__} and a {other.__class__.__name__}.') - return Inertia(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Inertia(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Inertia') -> 'Inertia': super().__sub__(other = other) @@ -40,11 +39,10 @@ def __sub__(self, other: 'Inertia') -> 'Inertia': raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' f'{self.__class__.__name__}.') - if self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit] <= 0: + if self.__value - other.to(self.__unit).value <= 0: raise ValueError('Cannot perform the subtraction because the result is not positive.') - return Inertia(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Inertia(value = self.__value - other.to(self.__unit).value, unit = self.__unit) def __mul__(self, other: Union[float, int]) -> 'Inertia': super().__mul__(other = other) @@ -78,7 +76,7 @@ def __truediv__(self, other: Union['Inertia', float, int]) -> Union['Inertia', f f'{other.__class__.__name__}.') if isinstance(other, Inertia): - return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) + return self.__value/other.to(self.__unit).value else: return Inertia(value = self.__value/other, unit = self.__unit) @@ -88,9 +86,7 @@ def __eq__(self, other: 'Inertia') -> bool: if not isinstance(other, Inertia): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Inertia(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value == angle.value + return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Inertia') -> bool: super().__eq__(other = other) @@ -98,9 +94,7 @@ def __ne__(self, other: 'Inertia') -> bool: if not isinstance(other, Inertia): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Inertia(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value != angle.value + return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Inertia') -> bool: super().__eq__(other = other) @@ -108,9 +102,7 @@ def __gt__(self, other: 'Inertia') -> bool: if not isinstance(other, Inertia): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Inertia(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value > angle.value + return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Inertia') -> bool: super().__eq__(other = other) @@ -118,9 +110,7 @@ def __ge__(self, other: 'Inertia') -> bool: if not isinstance(other, Inertia): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Inertia(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value >= angle.value + return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Inertia') -> bool: super().__eq__(other = other) @@ -128,9 +118,7 @@ def __lt__(self, other: 'Inertia') -> bool: if not isinstance(other, Inertia): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Inertia(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value < angle.value + return self.__value < other.to(self.__unit).value def __le__(self, other: 'Inertia') -> bool: super().__eq__(other = other) @@ -138,9 +126,7 @@ def __le__(self, other: 'Inertia') -> bool: if not isinstance(other, Inertia): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Inertia(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value <= angle.value + return self.__value <= other.to(self.__unit).value @property def value(self) -> Union[float, int]: @@ -150,14 +136,18 @@ def value(self) -> Union[float, int]: def unit(self) -> str: return self.__unit - def to(self, target_unit: str) -> 'Inertia': - super().to(target_unit = target_unit) + def to(self, target_unit: str, inplace: bool = False) -> 'Inertia': + super().to(target_unit = target_unit, inplace = inplace) if target_unit not in self.__UNITS.keys(): raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - self.__unit = target_unit + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - return self + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return Inertia(value = target_value, unit = target_unit) diff --git a/gearpy/units/speed.py b/gearpy/units/speed.py index 9b772ca..4922278 100644 --- a/gearpy/units/speed.py +++ b/gearpy/units/speed.py @@ -36,8 +36,7 @@ def __add__(self, other: 'Speed') -> 'Speed': if not isinstance(other, Speed): raise TypeError(f'It is not allowed to sum a {self.__class__.__name__} and a {other.__class__.__name__}.') - return Speed(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Speed(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Speed') -> 'Speed': super().__sub__(other = other) @@ -46,8 +45,7 @@ def __sub__(self, other: 'Speed') -> 'Speed': raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from a ' f'{self.__class__.__name__}.') - return Speed(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Speed(value = self.__value - other.to(self.__unit).value, unit = self.__unit) def __mul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: super().__mul__(other = other) @@ -57,11 +55,9 @@ def __mul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: f'{other.__class__.__name__}.') if isinstance(other, Time): - time = Time(value = other.value, unit = other.unit) - time.to('sec') - return Angle(value = self.__value*self.__UNITS[self.__unit]/self.__UNITS['rad/s']*time.value, - unit = 'rad') - return Speed(value = self.__value*other, unit = self.__unit) + return Angle(value = self.to('rad/s').value*other.to('sec').value, unit = 'rad') + else: + return Speed(value = self.__value*other, unit = self.__unit) def __rmul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: super().__rmul__(other = other) @@ -71,11 +67,9 @@ def __rmul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: f'{self.__class__.__name__}.') if isinstance(other, Time): - time = Time(value = other.value, unit = other.unit) - time.to('sec') - return Angle(value = self.__value*self.__UNITS[self.__unit]/self.__UNITS['rad/s']*time.value, - unit = 'rad') - return Speed(value = self.__value*other, unit = self.__unit) + return Angle(value = self.to('rad/s').value*other.to('sec').value, unit = 'rad') + else: + return Speed(value = self.__value*other, unit = self.__unit) def __truediv__(self, other: Union['Speed', float, int]) -> Union['Speed', float]: super().__truediv__(other = other) @@ -84,7 +78,7 @@ def __truediv__(self, other: Union['Speed', float, int]) -> Union['Speed', float raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') if isinstance(other, Speed): - return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) + return self.__value/other.to(self.__unit).value else: return Speed(value = self.__value/other, unit = self.__unit) @@ -94,9 +88,7 @@ def __eq__(self, other: 'Speed') -> bool: if not isinstance(other, Speed): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Speed(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value == angle.value + return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Speed') -> bool: super().__eq__(other = other) @@ -104,9 +96,7 @@ def __ne__(self, other: 'Speed') -> bool: if not isinstance(other, Speed): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Speed(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value != angle.value + return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Speed') -> bool: super().__eq__(other = other) @@ -114,9 +104,7 @@ def __gt__(self, other: 'Speed') -> bool: if not isinstance(other, Speed): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Speed(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value > angle.value + return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Speed') -> bool: super().__eq__(other = other) @@ -124,9 +112,7 @@ def __ge__(self, other: 'Speed') -> bool: if not isinstance(other, Speed): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Speed(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value >= angle.value + return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Speed') -> bool: super().__eq__(other = other) @@ -134,9 +120,7 @@ def __lt__(self, other: 'Speed') -> bool: if not isinstance(other, Speed): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Speed(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value < angle.value + return self.__value < other.to(self.__unit).value def __le__(self, other: 'Speed') -> bool: super().__eq__(other = other) @@ -144,9 +128,7 @@ def __le__(self, other: 'Speed') -> bool: if not isinstance(other, Speed): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Speed(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value <= angle.value + return self.__value <= other.to(self.__unit).value @property def value(self) -> Union[float, int]: @@ -156,14 +138,18 @@ def value(self) -> Union[float, int]: def unit(self) -> str: return self.__unit - def to(self, target_unit: str) -> 'Speed': - super().to(target_unit = target_unit) + def to(self, target_unit: str, inplace: bool = False) -> 'Speed': + super().to(target_unit = target_unit, inplace = inplace) if target_unit not in self.__UNITS.keys(): raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - self.__unit = target_unit + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - return self + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return Speed(value = target_value, unit = target_unit) diff --git a/gearpy/units/time.py b/gearpy/units/time.py index 2ce6d8f..b2b1b91 100644 --- a/gearpy/units/time.py +++ b/gearpy/units/time.py @@ -27,8 +27,7 @@ def __add__(self, other: 'Time') -> 'Time': if not isinstance(other, Time): raise TypeError(f'It is not allowed to sum a {self.__class__.__name__} and a {other.__class__.__name__}.') - return Time(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Time(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Time') -> 'Time': super().__sub__(other = other) @@ -37,8 +36,7 @@ def __sub__(self, other: 'Time') -> 'Time': raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' f'{self.__class__.__name__}.') - return Time(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Time(value = self.__value - other.to(self.__unit).value, unit = self.__unit) def __mul__(self, other: Union[float, int]) -> 'Time': super().__mul__(other = other) @@ -65,7 +63,7 @@ def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') if isinstance(other, Time): - return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) + return self.__value/other.to(self.__unit).value else: return Time(value = self.__value/other, unit = self.__unit) @@ -75,9 +73,7 @@ def __eq__(self, other: 'Time') -> bool: if not isinstance(other, Time): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Time(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value == angle.value + return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Time') -> bool: super().__eq__(other = other) @@ -85,10 +81,7 @@ def __ne__(self, other: 'Time') -> bool: if not isinstance(other, Time): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - - angle = Time(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value != angle.value + return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Time') -> bool: super().__eq__(other = other) @@ -96,9 +89,7 @@ def __gt__(self, other: 'Time') -> bool: if not isinstance(other, Time): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Time(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value > angle.value + return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Time') -> bool: super().__eq__(other = other) @@ -106,9 +97,7 @@ def __ge__(self, other: 'Time') -> bool: if not isinstance(other, Time): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Time(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value >= angle.value + return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Time') -> bool: super().__eq__(other = other) @@ -116,9 +105,7 @@ def __lt__(self, other: 'Time') -> bool: if not isinstance(other, Time): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Time(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value < angle.value + return self.__value < other.to(self.__unit).value def __le__(self, other: 'Time') -> bool: super().__eq__(other = other) @@ -126,9 +113,7 @@ def __le__(self, other: 'Time') -> bool: if not isinstance(other, Time): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Time(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value <= angle.value + return self.__value <= other.to(self.__unit).value @property def value(self) -> Union[float, int]: @@ -138,14 +123,18 @@ def value(self) -> Union[float, int]: def unit(self) -> str: return self.__unit - def to(self, target_unit: str) -> 'Time': - super().to(target_unit = target_unit) + def to(self, target_unit: str, inplace: bool = False) -> 'Time': + super().to(target_unit = target_unit, inplace = inplace) if target_unit not in self.__UNITS.keys(): raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - self.__unit = target_unit + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - return self + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return Time(value = target_value, unit = target_unit) diff --git a/gearpy/units/torque.py b/gearpy/units/torque.py index 676882a..571a9b5 100644 --- a/gearpy/units/torque.py +++ b/gearpy/units/torque.py @@ -31,8 +31,7 @@ def __add__(self, other: 'Torque') -> 'Torque': if not isinstance(other, Torque): raise TypeError(f'It is not allowed to sum a {self.__class__.__name__} and a {other.__class__.__name__}.') - return Torque(value = self.__value + other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Torque(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Torque') -> 'Torque': super().__sub__(other = other) @@ -41,8 +40,7 @@ def __sub__(self, other: 'Torque') -> 'Torque': raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from a ' f'{self.__class__.__name__}.') - return Torque(value = self.__value - other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit], - unit = self.__unit) + return Torque(value = self.__value - other.to(self.__unit).value, unit = self.__unit) def __mul__(self, other: Union[float, int]) -> 'Torque': super().__mul__(other = other) @@ -70,12 +68,9 @@ def __truediv__(self, other: Union['Torque', float, int]) -> Union['Torque', 'Ac raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') if isinstance(other, Torque): - return self.__value/(other.value*self.__UNITS[other.unit]/self.__UNITS[self.__unit]) - if isinstance(other, Inertia): - inertia = Inertia(value = other.value, unit = other.unit) - inertia.to('kgm^2') - return Acceleration(value = self.__value*self.__UNITS[self.__unit]/self.__UNITS['Nm']/inertia.value, - unit = 'rad/s^2') + return self.__value/other.to(self.__unit).value + elif isinstance(other, Inertia): + return Acceleration(value = self.to('Nm').value/other.to('kgm^2').value, unit = 'rad/s^2') else: return Torque(value = self.__value/other, unit = self.__unit) @@ -85,9 +80,7 @@ def __eq__(self, other: 'Torque') -> bool: if not isinstance(other, Torque): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Torque(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value == angle.value + return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Torque') -> bool: super().__eq__(other = other) @@ -95,9 +88,7 @@ def __ne__(self, other: 'Torque') -> bool: if not isinstance(other, Torque): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Torque(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value != angle.value + return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Torque') -> bool: super().__eq__(other = other) @@ -105,9 +96,7 @@ def __gt__(self, other: 'Torque') -> bool: if not isinstance(other, Torque): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Torque(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value > angle.value + return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Torque') -> bool: super().__eq__(other = other) @@ -115,9 +104,7 @@ def __ge__(self, other: 'Torque') -> bool: if not isinstance(other, Torque): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Torque(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value >= angle.value + return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Torque') -> bool: super().__eq__(other = other) @@ -125,9 +112,7 @@ def __lt__(self, other: 'Torque') -> bool: if not isinstance(other, Torque): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Torque(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value < angle.value + return self.__value < other.to(self.__unit).value def __le__(self, other: 'Torque') -> bool: super().__eq__(other = other) @@ -135,9 +120,7 @@ def __le__(self, other: 'Torque') -> bool: if not isinstance(other, Torque): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - angle = Torque(value = other.value, unit = other.unit) - angle.to(self.__unit) - return self.__value <= angle.value + return self.__value <= other.to(self.__unit).value @property def value(self) -> Union[float, int]: @@ -147,14 +130,18 @@ def value(self) -> Union[float, int]: def unit(self) -> str: return self.__unit - def to(self, target_unit: str) -> 'Torque': - super().to(target_unit = target_unit) + def to(self, target_unit: str, inplace: bool = False) -> 'Torque': + super().to(target_unit = target_unit, inplace = inplace) if target_unit not in self.__UNITS.keys(): raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - self.__value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - self.__unit = target_unit + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - return self + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return Torque(value = target_value, unit = target_unit) diff --git a/gearpy/units/unit_base.py b/gearpy/units/unit_base.py index 2da7f3a..bbf0d31 100644 --- a/gearpy/units/unit_base.py +++ b/gearpy/units/unit_base.py @@ -68,6 +68,9 @@ def value(self) -> None: ... def unit(self) -> None: ... @abstractmethod - def to(self, target_unit: str) -> None: + def to(self, target_unit: str, inplace: bool) -> None: if not isinstance(target_unit, str): raise TypeError("Parameter 'target_unit' must be a string.") + + if not isinstance(inplace, bool): + raise TypeError("Parameter 'inplace' must be a bool.") From 58aead661b900d0930851f80002de4c323af453a Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Fri, 13 Oct 2023 00:54:31 +0200 Subject: [PATCH 18/33] DEV: move comparison operators error message to abstract methods --- gearpy/units/acceleration.py | 28 +++++----------------------- gearpy/units/angle.py | 28 +++++----------------------- gearpy/units/inertia.py | 28 +++++----------------------- gearpy/units/speed.py | 28 +++++----------------------- gearpy/units/time.py | 28 +++++----------------------- gearpy/units/torque.py | 28 +++++----------------------- gearpy/units/unit_base.py | 24 ++++++++++++++++++------ 7 files changed, 48 insertions(+), 144 deletions(-) diff --git a/gearpy/units/acceleration.py b/gearpy/units/acceleration.py index 02c3b57..8514868 100644 --- a/gearpy/units/acceleration.py +++ b/gearpy/units/acceleration.py @@ -79,48 +79,30 @@ def __truediv__(self, other: Union['Acceleration', float, int]) -> Union['Accele def __eq__(self, other: 'Acceleration') -> bool: super().__eq__(other = other) - if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Acceleration') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ne__(other = other) return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Acceleration') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__gt__(other = other) return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Acceleration') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ge__(other = other) return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Acceleration') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__lt__(other = other) return self.__value < other.to(self.__unit).value def __le__(self, other: 'Acceleration') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Acceleration): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__le__(other = other) return self.__value <= other.to(self.__unit).value diff --git a/gearpy/units/angle.py b/gearpy/units/angle.py index c68fbdb..3f07e4c 100644 --- a/gearpy/units/angle.py +++ b/gearpy/units/angle.py @@ -73,48 +73,30 @@ def __truediv__(self, other: Union['Angle', float, int]) -> Union['Angle', float def __eq__(self, other: 'Angle') -> bool: super().__eq__(other = other) - if not isinstance(other, Angle): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Angle') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Angle): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ne__(other = other) return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Angle') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Angle): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__gt__(other = other) return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Angle') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Angle): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ge__(other = other) return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Angle') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Angle): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__lt__(other = other) return self.__value < other.to(self.__unit).value def __le__(self, other: 'Angle') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Angle): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__le__(other = other) return self.__value <= other.to(self.__unit).value diff --git a/gearpy/units/inertia.py b/gearpy/units/inertia.py index e3f8110..f069c4f 100644 --- a/gearpy/units/inertia.py +++ b/gearpy/units/inertia.py @@ -83,48 +83,30 @@ def __truediv__(self, other: Union['Inertia', float, int]) -> Union['Inertia', f def __eq__(self, other: 'Inertia') -> bool: super().__eq__(other = other) - if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Inertia') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ne__(other = other) return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Inertia') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__gt__(other = other) return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Inertia') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ge__(other = other) return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Inertia') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__lt__(other = other) return self.__value < other.to(self.__unit).value def __le__(self, other: 'Inertia') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Inertia): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__le__(other = other) return self.__value <= other.to(self.__unit).value diff --git a/gearpy/units/speed.py b/gearpy/units/speed.py index 4922278..8105cba 100644 --- a/gearpy/units/speed.py +++ b/gearpy/units/speed.py @@ -85,48 +85,30 @@ def __truediv__(self, other: Union['Speed', float, int]) -> Union['Speed', float def __eq__(self, other: 'Speed') -> bool: super().__eq__(other = other) - if not isinstance(other, Speed): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Speed') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Speed): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ne__(other = other) return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Speed') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Speed): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__gt__(other = other) return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Speed') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Speed): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ge__(other = other) return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Speed') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Speed): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__lt__(other = other) return self.__value < other.to(self.__unit).value def __le__(self, other: 'Speed') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Speed): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__le__(other = other) return self.__value <= other.to(self.__unit).value diff --git a/gearpy/units/time.py b/gearpy/units/time.py index b2b1b91..f6259f0 100644 --- a/gearpy/units/time.py +++ b/gearpy/units/time.py @@ -70,48 +70,30 @@ def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: def __eq__(self, other: 'Time') -> bool: super().__eq__(other = other) - if not isinstance(other, Time): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Time') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Time): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ne__(other = other) return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Time') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Time): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__gt__(other = other) return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Time') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Time): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ge__(other = other) return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Time') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Time): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__lt__(other = other) return self.__value < other.to(self.__unit).value def __le__(self, other: 'Time') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Time): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__le__(other = other) return self.__value <= other.to(self.__unit).value diff --git a/gearpy/units/torque.py b/gearpy/units/torque.py index 571a9b5..5bec8f2 100644 --- a/gearpy/units/torque.py +++ b/gearpy/units/torque.py @@ -77,48 +77,30 @@ def __truediv__(self, other: Union['Torque', float, int]) -> Union['Torque', 'Ac def __eq__(self, other: 'Torque') -> bool: super().__eq__(other = other) - if not isinstance(other, Torque): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') - return self.__value == other.to(self.__unit).value def __ne__(self, other: 'Torque') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Torque): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ne__(other = other) return self.__value != other.to(self.__unit).value def __gt__(self, other: 'Torque') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Torque): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__gt__(other = other) return self.__value > other.to(self.__unit).value def __ge__(self, other: 'Torque') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Torque): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__ge__(other = other) return self.__value >= other.to(self.__unit).value def __lt__(self, other: 'Torque') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Torque): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__lt__(other = other) return self.__value < other.to(self.__unit).value def __le__(self, other: 'Torque') -> bool: - super().__eq__(other = other) - - if not isinstance(other, Torque): - raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') + super().__le__(other = other) return self.__value <= other.to(self.__unit).value diff --git a/gearpy/units/unit_base.py b/gearpy/units/unit_base.py index bbf0d31..3357ea3 100644 --- a/gearpy/units/unit_base.py +++ b/gearpy/units/unit_base.py @@ -42,22 +42,34 @@ def __truediv__(self, other: Union['UnitBase', float, int]) -> None: raise ZeroDivisionError('It is not allowed to divide a Unit by zero.') @abstractmethod - def __eq__(self, other: 'UnitBase') -> None: ... + def __eq__(self, other: 'UnitBase') -> None: + if not isinstance(other, self.__class__): + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @abstractmethod - def __ne__(self, other: 'UnitBase') -> None: ... + def __ne__(self, other: 'UnitBase') -> None: + if not isinstance(other, self.__class__): + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @abstractmethod - def __gt__(self, other: 'UnitBase') -> None: ... + def __gt__(self, other: 'UnitBase') -> None: + if not isinstance(other, self.__class__): + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @abstractmethod - def __ge__(self, other: 'UnitBase') -> None: ... + def __ge__(self, other: 'UnitBase') -> None: + if not isinstance(other, self.__class__): + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @abstractmethod - def __lt__(self, other: 'UnitBase') -> None: ... + def __lt__(self, other: 'UnitBase') -> None: + if not isinstance(other, self.__class__): + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @abstractmethod - def __le__(self, other: 'UnitBase') -> None: ... + def __le__(self, other: 'UnitBase') -> None: + if not isinstance(other, self.__class__): + raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @property @abstractmethod From a369f77436e5b2d50c44d298c5933a1bc76388bb Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Fri, 13 Oct 2023 15:01:47 +0200 Subject: [PATCH 19/33] DEV: move TypeError from concrete class to abstract one --- gearpy/units/acceleration.py | 7 ------- gearpy/units/angle.py | 7 ------- gearpy/units/inertia.py | 7 ------- gearpy/units/speed.py | 7 ------- gearpy/units/time.py | 7 ------- gearpy/units/torque.py | 9 +-------- gearpy/units/unit_base.py | 9 +++++++-- 7 files changed, 8 insertions(+), 45 deletions(-) diff --git a/gearpy/units/acceleration.py b/gearpy/units/acceleration.py index 8514868..56d5eae 100644 --- a/gearpy/units/acceleration.py +++ b/gearpy/units/acceleration.py @@ -26,18 +26,11 @@ def __repr__(self) -> str: def __add__(self, other: 'Acceleration') -> 'Acceleration': super().__add__(other = other) - if not isinstance(other, Acceleration): - raise TypeError(f'It is not allowed to sum an {self.__class__.__name__} and a {other.__class__.__name__}.') - return Acceleration(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Acceleration') -> 'Acceleration': super().__sub__(other = other) - if not isinstance(other, Acceleration): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' - f'{self.__class__.__name__}.') - return Acceleration(value = self.__value - other.to(self.__unit).value, unit = self.__unit) def __mul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration']: diff --git a/gearpy/units/angle.py b/gearpy/units/angle.py index 3f07e4c..353a73a 100644 --- a/gearpy/units/angle.py +++ b/gearpy/units/angle.py @@ -26,18 +26,11 @@ def __repr__(self) -> str: def __add__(self, other: 'Angle') -> 'Angle': super().__add__(other = other) - if not isinstance(other, Angle): - raise TypeError(f'It is not allowed to sum an {self.__class__.__name__} and a {other.__class__.__name__}.') - return Angle(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Angle') -> 'Angle': super().__sub__(other = other) - if not isinstance(other, Angle): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' - f'{self.__class__.__name__}.') - return Angle(value = self.__value - other.to(self.__unit).value, unit = self.__unit) def __mul__(self, other: Union[float, int]) -> 'Angle': diff --git a/gearpy/units/inertia.py b/gearpy/units/inertia.py index f069c4f..73e573a 100644 --- a/gearpy/units/inertia.py +++ b/gearpy/units/inertia.py @@ -27,18 +27,11 @@ def __repr__(self) -> str: def __add__(self, other: 'Inertia') -> 'Inertia': super().__add__(other = other) - if not isinstance(other, Inertia): - raise TypeError(f'It is not allowed to sum an {self.__class__.__name__} and a {other.__class__.__name__}.') - return Inertia(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Inertia') -> 'Inertia': super().__sub__(other = other) - if not isinstance(other, Inertia): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' - f'{self.__class__.__name__}.') - if self.__value - other.to(self.__unit).value <= 0: raise ValueError('Cannot perform the subtraction because the result is not positive.') diff --git a/gearpy/units/speed.py b/gearpy/units/speed.py index 8105cba..0d50dd3 100644 --- a/gearpy/units/speed.py +++ b/gearpy/units/speed.py @@ -33,18 +33,11 @@ def __repr__(self) -> str: def __add__(self, other: 'Speed') -> 'Speed': super().__add__(other = other) - if not isinstance(other, Speed): - raise TypeError(f'It is not allowed to sum a {self.__class__.__name__} and a {other.__class__.__name__}.') - return Speed(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Speed') -> 'Speed': super().__sub__(other = other) - if not isinstance(other, Speed): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from a ' - f'{self.__class__.__name__}.') - return Speed(value = self.__value - other.to(self.__unit).value, unit = self.__unit) def __mul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: diff --git a/gearpy/units/time.py b/gearpy/units/time.py index f6259f0..c591b10 100644 --- a/gearpy/units/time.py +++ b/gearpy/units/time.py @@ -24,18 +24,11 @@ def __repr__(self) -> str: def __add__(self, other: 'Time') -> 'Time': super().__add__(other = other) - if not isinstance(other, Time): - raise TypeError(f'It is not allowed to sum a {self.__class__.__name__} and a {other.__class__.__name__}.') - return Time(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Time') -> 'Time': super().__sub__(other = other) - if not isinstance(other, Time): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from an ' - f'{self.__class__.__name__}.') - return Time(value = self.__value - other.to(self.__unit).value, unit = self.__unit) def __mul__(self, other: Union[float, int]) -> 'Time': diff --git a/gearpy/units/torque.py b/gearpy/units/torque.py index 5bec8f2..663af43 100644 --- a/gearpy/units/torque.py +++ b/gearpy/units/torque.py @@ -28,18 +28,11 @@ def __repr__(self) -> str: def __add__(self, other: 'Torque') -> 'Torque': super().__add__(other = other) - if not isinstance(other, Torque): - raise TypeError(f'It is not allowed to sum a {self.__class__.__name__} and a {other.__class__.__name__}.') - return Torque(value = self.__value + other.to(self.__unit).value, unit = self.__unit) def __sub__(self, other: 'Torque') -> 'Torque': super().__sub__(other = other) - if not isinstance(other, Torque): - raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} from a ' - f'{self.__class__.__name__}.') - return Torque(value = self.__value - other.to(self.__unit).value, unit = self.__unit) def __mul__(self, other: Union[float, int]) -> 'Torque': @@ -60,7 +53,7 @@ def __rmul__(self, other: Union[float, int]) -> 'Torque': return Torque(value = self.__value*other, unit = self.__unit) - def __truediv__(self, other: Union['Torque', float, int]) -> Union['Torque', 'Acceleration', float]: + def __truediv__(self, other: Union['Torque', 'Inertia', float, int]) -> Union['Torque', 'Acceleration', float]: super().__truediv__(other = other) if not isinstance(other, Torque) and not isinstance(other, float) and not isinstance(other, int) \ diff --git a/gearpy/units/unit_base.py b/gearpy/units/unit_base.py index 3357ea3..8cdb032 100644 --- a/gearpy/units/unit_base.py +++ b/gearpy/units/unit_base.py @@ -18,10 +18,15 @@ def __init__(self, value: Union[float, int], unit: str): def __repr__(self): ... @abstractmethod - def __add__(self, other: 'UnitBase') -> None: ... + def __add__(self, other: 'UnitBase') -> None: + if not isinstance(other, self.__class__): + raise TypeError(f'It is not allowed to sum a {self.__class__.__name__} and a {other.__class__.__name__}.') @abstractmethod - def __sub__(self, other: 'UnitBase') -> None: ... + def __sub__(self, other: 'UnitBase') -> None: + if not isinstance(other, self.__class__): + raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} ' + f'from a {self.__class__.__name__}.') @abstractmethod def __mul__(self, other: Union[float, int]) -> None: ... From 6dedf772b89f3a1d1286f8fbac5f31c639ec7512 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Fri, 13 Oct 2023 17:02:14 +0200 Subject: [PATCH 20/33] DEV: create TimeInterval --- gearpy/units/__init__.py | 1 + gearpy/units/time_interval.py | 67 +++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 gearpy/units/time_interval.py diff --git a/gearpy/units/__init__.py b/gearpy/units/__init__.py index e804fd5..9f5dcd1 100644 --- a/gearpy/units/__init__.py +++ b/gearpy/units/__init__.py @@ -3,4 +3,5 @@ from .inertia import Inertia from .speed import Speed from .time import Time +from .time_interval import TimeInterval from .torque import Torque diff --git a/gearpy/units/time_interval.py b/gearpy/units/time_interval.py new file mode 100644 index 0000000..7c9271c --- /dev/null +++ b/gearpy/units/time_interval.py @@ -0,0 +1,67 @@ +from .time import Time +from typing import Union + + +class TimeInterval(Time): + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if value <= 0: + raise ValueError("Parameter 'value' must be positive.") + + self.__value = value + self.__unit = unit + + def __add__(self, other: Union['TimeInterval', 'Time']) -> Union['TimeInterval', 'Time']: + super().__add__(other = other) + + if isinstance(other, TimeInterval): + return TimeInterval(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + else: + return Time(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + + def __sub__(self, other: Union['TimeInterval', 'Time']) -> Union['TimeInterval', 'Time']: + super().__sub__(other = other) + + if self.__value - other.to(self.__unit).value <= 0: + raise ValueError('Cannot perform the subtraction because the result is not positive.') + + if isinstance(other, TimeInterval): + return TimeInterval(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + else: + return Time(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + + def __mul__(self, other: Union[float, int]) -> 'TimeInterval': + super().__mul__(other = other) + + if other <= 0: + raise ValueError('Cannot perform a multiplication by a non-positive number.') + + return TimeInterval(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[float, int]) -> 'TimeInterval': + super().__rmul__(other = other) + + if other <= 0: + raise ValueError('Cannot perform a multiplication by a non-positive number.') + + return TimeInterval(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: + super().__truediv__(other = other) + + if isinstance(other, Time): + return self.__value/other.to(self.__unit).value + else: + return TimeInterval(value = self.__value/other, unit = self.__unit) + + def to(self, target_unit: str, inplace: bool = False) -> 'TimeInterval': + converted = super().to(target_unit = target_unit, inplace = inplace) + + if inplace: + self.__value = converted.value + self.__unit = converted.unit + return self + else: + return TimeInterval(value = converted.value, unit = converted.unit) From 7b111da45b0a625ffae9108b4f20116ee5f2b9ab Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Fri, 13 Oct 2023 17:02:46 +0200 Subject: [PATCH 21/33] DEV: edit Solver to get TimeInterval as input in place of Time --- gearpy/solver/solver.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/gearpy/solver/solver.py b/gearpy/solver/solver.py index e955bd1..af808a7 100644 --- a/gearpy/solver/solver.py +++ b/gearpy/solver/solver.py @@ -1,28 +1,22 @@ from gearpy.mechanical_object import RotatingObject from gearpy.motor import MotorBase from gearpy.transmission import Transmission -from gearpy.units import Time +from gearpy.units import Time, TimeInterval import numpy as np class Solver: - def __init__(self, time_discretization: Time, simulation_time: Time, transmission: Transmission): - if not isinstance(time_discretization, Time): - raise TypeError("Parameter 'time_discretization' must be an instance of Time.") + def __init__(self, time_discretization: TimeInterval, simulation_time: TimeInterval, transmission: Transmission): + if not isinstance(time_discretization, TimeInterval): + raise TypeError("Parameter 'time_discretization' must be an instance of TimeInterval.") - if not isinstance(simulation_time, Time): - raise TypeError("Parameter 'simulation_time' must be an instance of Time.") + if not isinstance(simulation_time, TimeInterval): + raise TypeError("Parameter 'simulation_time' must be an instance of TimeInterval.") if not isinstance(transmission, Transmission): raise TypeError("Parameter 'transmission' must be an instance of Transmission.") - if time_discretization.value <= 0: - raise ValueError("Parameter 'time_discretization' must be positive.") - - if simulation_time.value <= 0: - raise ValueError("Parameter 'time_simulation' must be positive.") - if time_discretization >= simulation_time: raise ValueError("Parameter 'time_discretization' cannot be greater or equal to 'simulation_time'.") From 23a4aab2fbe1175018375255ddceeb665513d690 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Fri, 13 Oct 2023 17:50:23 +0200 Subject: [PATCH 22/33] ENH: convert TypeError messages in f-strings --- gearpy/gear/gear_base.py | 4 ++-- gearpy/mechanical_object/rotating_object.py | 14 +++++++------- gearpy/motor/dc_motor.py | 4 ++-- gearpy/motor/motor_base.py | 2 +- gearpy/solver/solver.py | 10 +++++----- gearpy/transmission/transmission.py | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/gearpy/gear/gear_base.py b/gearpy/gear/gear_base.py index 8064407..6b8c73a 100644 --- a/gearpy/gear/gear_base.py +++ b/gearpy/gear/gear_base.py @@ -37,7 +37,7 @@ def driven_by(self) -> RotatingObject: @abstractmethod def driven_by(self, driven_by: RotatingObject): if not isinstance(driven_by, RotatingObject): - raise TypeError("Parameter 'driven_by' must be a RotatingObject") + raise TypeError(f"Parameter 'driven_by' must be a {RotatingObject.__name__!r}") self.__driven_by = driven_by @@ -50,7 +50,7 @@ def drives(self) -> RotatingObject: @abstractmethod def drives(self, drives: RotatingObject): if not isinstance(drives, RotatingObject): - raise TypeError("Parameter 'drives' must be a RotatingObject") + raise TypeError(f"Parameter 'drives' must be a {RotatingObject.__name__!r}") self.__drives = drives diff --git a/gearpy/mechanical_object/rotating_object.py b/gearpy/mechanical_object/rotating_object.py index 634a4ec..b56bfdd 100644 --- a/gearpy/mechanical_object/rotating_object.py +++ b/gearpy/mechanical_object/rotating_object.py @@ -10,7 +10,7 @@ def __init__(self, name: str, inertia: Inertia): super().__init__(name = name) if not isinstance(inertia, Inertia): - raise TypeError("Parameter 'inertia' must be an instance of Inertia.") + raise TypeError(f"Parameter 'inertia' must be an instance of {Inertia.__name__!r}.") self.__angle = None self.__speed = None @@ -35,7 +35,7 @@ def angle(self) -> Angle: @abstractmethod def angle(self, angle: Angle): if not isinstance(angle, Angle): - raise TypeError("Parameter 'angle' must be an instance of Angle.") + raise TypeError(f"Parameter 'angle' must be an instance of {Angle.__name__!r}.") self.__angle = angle @@ -48,7 +48,7 @@ def speed(self) -> Speed: @abstractmethod def speed(self, speed: Speed): if not isinstance(speed, Speed): - raise TypeError("Parameter 'speed' must be an instance of Speed.") + raise TypeError(f"Parameter 'speed' must be an instance of {Speed.__name__!r}.") self.__speed = speed @@ -61,7 +61,7 @@ def acceleration(self) -> Acceleration: @abstractmethod def acceleration(self, acceleration: Acceleration): if not isinstance(acceleration, Acceleration): - raise TypeError("Parameter 'acceleration' must be an instance of Acceleration.") + raise TypeError(f"Parameter 'acceleration' must be an instance of {Acceleration.__name__!r}.") self.__acceleration = acceleration @@ -74,7 +74,7 @@ def torque(self) -> Torque: @abstractmethod def torque(self, torque: Torque): if not isinstance(torque, Torque): - raise TypeError("Parameter 'torque' must be an instance of Torque.") + raise TypeError(f"Parameter 'torque' must be an instance of {Torque.__name__!r}.") self.__torque = torque @@ -87,7 +87,7 @@ def driving_torque(self) -> Torque: @abstractmethod def driving_torque(self, driving_torque: Torque): if not isinstance(driving_torque, Torque): - raise TypeError("Parameter 'driving_torque' must be an instance of Torque.") + raise TypeError(f"Parameter 'driving_torque' must be an instance of {Torque.__name__!r}.") self.__driving_torque = driving_torque @@ -100,7 +100,7 @@ def load_torque(self) -> Torque: @abstractmethod def load_torque(self, load_torque: Torque): if not isinstance(load_torque, Torque): - raise TypeError("Parameter 'load_torque' must be an instance of Torque.") + raise TypeError(f"Parameter 'load_torque' must be an instance of {Torque.__name__!r}.") self.__load_torque = load_torque diff --git a/gearpy/motor/dc_motor.py b/gearpy/motor/dc_motor.py index 11642a6..5268aca 100644 --- a/gearpy/motor/dc_motor.py +++ b/gearpy/motor/dc_motor.py @@ -9,10 +9,10 @@ def __init__(self, name: str, inertia: Inertia, no_load_speed: Speed, maximum_to super().__init__(name = name, inertia = inertia) if not isinstance(no_load_speed, Speed): - raise TypeError("Parameter 'no_load_speed' must be an instance of Speed") + raise TypeError(f"Parameter 'no_load_speed' must be an instance of {Speed.__name__!r}") if not isinstance(maximum_torque, Torque): - raise TypeError("Parameter 'maximum_torque' must be an instance of Torque.") + raise TypeError(f"Parameter 'maximum_torque' must be an instance of {Torque.__name__!r}.") if no_load_speed.value <= 0: raise ValueError("Parameter 'no_load_speed' must be positive.") diff --git a/gearpy/motor/motor_base.py b/gearpy/motor/motor_base.py index 734dc3f..30906fc 100644 --- a/gearpy/motor/motor_base.py +++ b/gearpy/motor/motor_base.py @@ -19,7 +19,7 @@ def drives(self) -> RotatingObject: @abstractmethod def drives(self, drives: RotatingObject): if not isinstance(drives, RotatingObject): - raise TypeError("Parameter 'drives' must be a RotatingObject") + raise TypeError(f"Parameter 'drives' must be a {RotatingObject.__name__!r}") self.__drives = drives diff --git a/gearpy/solver/solver.py b/gearpy/solver/solver.py index af808a7..e42c955 100644 --- a/gearpy/solver/solver.py +++ b/gearpy/solver/solver.py @@ -9,13 +9,13 @@ class Solver: def __init__(self, time_discretization: TimeInterval, simulation_time: TimeInterval, transmission: Transmission): if not isinstance(time_discretization, TimeInterval): - raise TypeError("Parameter 'time_discretization' must be an instance of TimeInterval.") + raise TypeError(f"Parameter 'time_discretization' must be an instance of {TimeInterval.__name__!r}.") if not isinstance(simulation_time, TimeInterval): - raise TypeError("Parameter 'simulation_time' must be an instance of TimeInterval.") + raise TypeError(f"Parameter 'simulation_time' must be an instance of {TimeInterval.__name__!r}.") if not isinstance(transmission, Transmission): - raise TypeError("Parameter 'transmission' must be an instance of Transmission.") + raise TypeError(f"Parameter 'transmission' must be an instance of {Transmission.__name__!r}.") if time_discretization >= simulation_time: raise ValueError("Parameter 'time_discretization' cannot be greater or equal to 'simulation_time'.") @@ -24,10 +24,10 @@ def __init__(self, time_discretization: TimeInterval, simulation_time: TimeInter raise ValueError("Parameter 'transmission.chain' cannot be an empty list.") if not isinstance(transmission.chain[0], MotorBase): - raise TypeError("First element in 'transmission' must be an instance of MotorBase.") + raise TypeError(f"First element in 'transmission' must be an instance of {MotorBase.__name__!r}.") if not all([isinstance(item, RotatingObject) for item in transmission.chain]): - raise TypeError("All elements of 'transmission' must be instances of RotatingObject.") + raise TypeError(f"All elements of 'transmission' must be instances of {RotatingObject.__name__!r}.") self.time_discretization = time_discretization self.simulation_time = simulation_time diff --git a/gearpy/transmission/transmission.py b/gearpy/transmission/transmission.py index 609e7b0..bfc2ed4 100644 --- a/gearpy/transmission/transmission.py +++ b/gearpy/transmission/transmission.py @@ -5,7 +5,7 @@ class Transmission: def __init__(self, motor: MotorBase): if not isinstance(motor, MotorBase): - raise TypeError("Parameter 'motor' must be an instance of MotorBase.") + raise TypeError(f"Parameter 'motor' must be an instance of {MotorBase.__name__!r}.") if motor.drives is None: raise ValueError("Parameter 'motor' is not connected to any other element. Call 'add_fixed_joint' " From 59fcacaf5bbcb72f7b797f6e1bf3fb821c97121e Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Fri, 13 Oct 2023 18:41:30 +0200 Subject: [PATCH 23/33] ENH: rename RotatingObject properties --- gearpy/gear/gear_base.py | 36 ++++----- gearpy/gear/spur_gear.py | 40 +++++----- gearpy/mechanical_object/rotating_object.py | 75 ++++++++++--------- gearpy/motor/dc_motor.py | 48 ++++++------ gearpy/motor/motor_base.py | 36 ++++----- gearpy/solver/solver.py | 49 ++++++------ gearpy/units/__init__.py | 11 +-- ...cceleration.py => angular_acceleration.py} | 48 ++++++------ .../units/{angle.py => angular_position.py} | 42 +++++------ gearpy/units/{speed.py => angular_speed.py} | 48 ++++++------ .../units/{inertia.py => inertia_moment.py} | 42 +++++------ gearpy/units/torque.py | 12 +-- 12 files changed, 247 insertions(+), 240 deletions(-) rename gearpy/units/{acceleration.py => angular_acceleration.py} (61%) rename gearpy/units/{angle.py => angular_position.py} (66%) rename gearpy/units/{speed.py => angular_speed.py} (66%) rename gearpy/units/{inertia.py => inertia_moment.py} (70%) diff --git a/gearpy/gear/gear_base.py b/gearpy/gear/gear_base.py index 6b8c73a..9a87bd6 100644 --- a/gearpy/gear/gear_base.py +++ b/gearpy/gear/gear_base.py @@ -1,14 +1,14 @@ from abc import abstractmethod from gearpy.mechanical_object import RotatingObject -from gearpy.units import Acceleration, Angle, Inertia, Speed, Torque +from gearpy.units import AngularPosition, AngularSpeed, AngularAcceleration, InertiaMoment, Torque from typing import Callable, Union class GearBase(RotatingObject): @abstractmethod - def __init__(self, name: str, n_teeth: int, inertia: Inertia): - super().__init__(name = name, inertia = inertia) + def __init__(self, name: str, n_teeth: int, inertia_moment: InertiaMoment): + super().__init__(name = name, inertia_moment = inertia_moment) if not isinstance(n_teeth, int): raise TypeError("Parameter 'n_teeth' must be an integer.") @@ -56,33 +56,33 @@ def drives(self, drives: RotatingObject): @property @abstractmethod - def angle(self) -> Angle: - return super().angle + def angular_position(self) -> AngularPosition: + return super().angular_position - @angle.setter + @angular_position.setter @abstractmethod - def angle(self, angle: Angle): - super(GearBase, type(self)).angle.fset(self, angle) + def angular_position(self, angular_position: AngularPosition): + super(GearBase, type(self)).angular_position.fset(self, angular_position) @property @abstractmethod - def speed(self) -> Speed: - return super().speed + def angular_speed(self) -> AngularSpeed: + return super().angular_speed - @speed.setter + @angular_speed.setter @abstractmethod - def speed(self, speed: Speed): - super(GearBase, type(self)).speed.fset(self, speed) + def angular_speed(self, angular_speed: AngularSpeed): + super(GearBase, type(self)).angular_speed.fset(self, angular_speed) @property @abstractmethod - def acceleration(self) -> Acceleration: - return super().acceleration + def angular_acceleration(self) -> AngularAcceleration: + return super().angular_acceleration - @acceleration.setter + @angular_acceleration.setter @abstractmethod - def acceleration(self, acceleration: Acceleration): - super(GearBase, type(self)).acceleration.fset(self, acceleration) + def angular_acceleration(self, angular_acceleration: AngularAcceleration): + super(GearBase, type(self)).angular_acceleration.fset(self, angular_acceleration) @property @abstractmethod diff --git a/gearpy/gear/spur_gear.py b/gearpy/gear/spur_gear.py index bdc9f42..f987838 100644 --- a/gearpy/gear/spur_gear.py +++ b/gearpy/gear/spur_gear.py @@ -1,13 +1,13 @@ from gearpy.gear import GearBase from gearpy.mechanical_object import RotatingObject -from gearpy.units import Acceleration, Angle, Inertia, Speed, Torque +from gearpy.units import AngularPosition, AngularSpeed, AngularAcceleration, InertiaMoment, Torque from typing import Callable, Union class SpurGear(GearBase): - def __init__(self, name: str, n_teeth: int, inertia: Inertia): - super().__init__(name = name, n_teeth = n_teeth, inertia = inertia) + def __init__(self, name: str, n_teeth: int, inertia_moment: InertiaMoment): + super().__init__(name = name, n_teeth = n_teeth, inertia_moment = inertia_moment) @property def name(self) -> str: @@ -50,28 +50,28 @@ def master_gear_efficiency(self, master_gear_efficiency: Union[float, int]): super(SpurGear, type(self)).master_gear_efficiency.fset(self, master_gear_efficiency) @property - def angle(self) -> Angle: - return super().angle + def angular_position(self) -> AngularPosition: + return super().angular_position - @angle.setter - def angle(self, angle: Angle): - super(SpurGear, type(self)).angle.fset(self, angle) + @angular_position.setter + def angular_position(self, angular_position: AngularPosition): + super(SpurGear, type(self)).angular_position.fset(self, angular_position) @property - def speed(self) -> Speed: - return super().speed + def angular_speed(self) -> AngularSpeed: + return super().angular_speed - @speed.setter - def speed(self, speed: Speed): - super(SpurGear, type(self)).speed.fset(self, speed) + @angular_speed.setter + def angular_speed(self, angular_speed: AngularSpeed): + super(SpurGear, type(self)).angular_speed.fset(self, angular_speed) @property - def acceleration(self) -> Acceleration: - return super().acceleration + def angular_acceleration(self) -> AngularAcceleration: + return super().angular_acceleration - @acceleration.setter - def acceleration(self, acceleration: Acceleration): - super(SpurGear, type(self)).acceleration.fset(self, acceleration) + @angular_acceleration.setter + def angular_acceleration(self, angular_acceleration: AngularAcceleration): + super(SpurGear, type(self)).angular_acceleration.fset(self, angular_acceleration) @property def torque(self) -> Torque: @@ -98,8 +98,8 @@ def load_torque(self, load_torque: Torque): super(SpurGear, type(self)).load_torque.fset(self, load_torque) @property - def inertia(self) -> Inertia: - return super().inertia + def inertia_moment(self) -> InertiaMoment: + return super().inertia_moment @property def external_torque(self) -> Callable: diff --git a/gearpy/mechanical_object/rotating_object.py b/gearpy/mechanical_object/rotating_object.py index b56bfdd..7734eeb 100644 --- a/gearpy/mechanical_object/rotating_object.py +++ b/gearpy/mechanical_object/rotating_object.py @@ -1,69 +1,70 @@ from abc import abstractmethod -from gearpy.units import Acceleration, Angle, Inertia, Speed, Torque +from gearpy.units import AngularPosition, AngularSpeed, AngularAcceleration, InertiaMoment, Torque from .mechanical_object import MechanicalObject class RotatingObject(MechanicalObject): @abstractmethod - def __init__(self, name: str, inertia: Inertia): + def __init__(self, name: str, inertia_moment: InertiaMoment): super().__init__(name = name) - if not isinstance(inertia, Inertia): - raise TypeError(f"Parameter 'inertia' must be an instance of {Inertia.__name__!r}.") + if not isinstance(inertia_moment, InertiaMoment): + raise TypeError(f"Parameter 'inertia_moment' must be an instance of {InertiaMoment.__name__!r}.") - self.__angle = None - self.__speed = None - self.__acceleration = None + self.__angular_position = None + self.__angular_speed = None + self.__angular_acceleration = None self.__torque = None self.__driving_torque = None self.__load_torque = None - self.__inertia = inertia - self.__time_variables = {'angle': [], - 'speed': [], - 'acceleration': [], + self.__inertia_moment = inertia_moment + self.__time_variables = {'angular position': [], + 'angular speed': [], + 'angular acceleration': [], 'torque': [], 'driving torque': [], 'load torque': []} @property @abstractmethod - def angle(self) -> Angle: - return self.__angle + def angular_position(self) -> AngularPosition: + return self.__angular_position - @angle.setter + @angular_position.setter @abstractmethod - def angle(self, angle: Angle): - if not isinstance(angle, Angle): - raise TypeError(f"Parameter 'angle' must be an instance of {Angle.__name__!r}.") + def angular_position(self, angular_position: AngularPosition): + if not isinstance(angular_position, AngularPosition): + raise TypeError(f"Parameter 'angular_position' must be an instance of {AngularPosition.__name__!r}.") - self.__angle = angle + self.__angular_position = angular_position @property @abstractmethod - def speed(self) -> Speed: - return self.__speed + def angular_speed(self) -> AngularSpeed: + return self.__angular_speed - @speed.setter + @angular_speed.setter @abstractmethod - def speed(self, speed: Speed): - if not isinstance(speed, Speed): - raise TypeError(f"Parameter 'speed' must be an instance of {Speed.__name__!r}.") + def angular_speed(self, angular_speed: AngularSpeed): + if not isinstance(angular_speed, AngularSpeed): + raise TypeError(f"Parameter 'angular_speed' must be an instance of {AngularSpeed.__name__!r}.") - self.__speed = speed + self.__angular_speed = angular_speed @property @abstractmethod - def acceleration(self) -> Acceleration: - return self.__acceleration + def angular_acceleration(self) -> AngularAcceleration: + return self.__angular_acceleration - @acceleration.setter + @angular_acceleration.setter @abstractmethod - def acceleration(self, acceleration: Acceleration): - if not isinstance(acceleration, Acceleration): - raise TypeError(f"Parameter 'acceleration' must be an instance of {Acceleration.__name__!r}.") + def angular_acceleration(self, angular_acceleration: AngularAcceleration): + if not isinstance(angular_acceleration, AngularAcceleration): + raise TypeError(f"Parameter 'angular_acceleration' must be an instance of " + f"{AngularAcceleration.__name__!r}.") - self.__acceleration = acceleration + self.__angular_acceleration = angular_acceleration @property @abstractmethod @@ -106,8 +107,8 @@ def load_torque(self, load_torque: Torque): @property @abstractmethod - def inertia(self) -> Inertia: - return self.__inertia + def inertia_moment(self) -> InertiaMoment: + return self.__inertia_moment @property @abstractmethod @@ -116,9 +117,9 @@ def time_variables(self) -> dict: @abstractmethod def update_time_variables(self): - self.__time_variables['angle'].append(self.__angle) - self.__time_variables['speed'].append(self.__speed) - self.__time_variables['acceleration'].append(self.__acceleration) + self.__time_variables['angular position'].append(self.__angular_position) + self.__time_variables['angular speed'].append(self.__angular_speed) + self.__time_variables['angular acceleration'].append(self.__angular_acceleration) self.__time_variables['torque'].append(self.__torque) self.__time_variables['driving torque'].append(self.__driving_torque) self.__time_variables['load torque'].append(self.__load_torque) diff --git a/gearpy/motor/dc_motor.py b/gearpy/motor/dc_motor.py index 5268aca..f93fc6b 100644 --- a/gearpy/motor/dc_motor.py +++ b/gearpy/motor/dc_motor.py @@ -1,15 +1,15 @@ from gearpy.mechanical_object import RotatingObject from gearpy.motor import MotorBase -from gearpy.units import Acceleration, Angle, Inertia, Speed, Torque +from gearpy.units import AngularPosition, AngularSpeed, AngularAcceleration, InertiaMoment, Torque class DCMotor(MotorBase): - def __init__(self, name: str, inertia: Inertia, no_load_speed: Speed, maximum_torque: Torque): - super().__init__(name = name, inertia = inertia) + def __init__(self, name: str, inertia_moment: InertiaMoment, no_load_speed: AngularSpeed, maximum_torque: Torque): + super().__init__(name = name, inertia_moment = inertia_moment) - if not isinstance(no_load_speed, Speed): - raise TypeError(f"Parameter 'no_load_speed' must be an instance of {Speed.__name__!r}") + if not isinstance(no_load_speed, AngularSpeed): + raise TypeError(f"Parameter 'no_load_speed' must be an instance of {AngularSpeed.__name__!r}") if not isinstance(maximum_torque, Torque): raise TypeError(f"Parameter 'maximum_torque' must be an instance of {Torque.__name__!r}.") @@ -36,31 +36,31 @@ def drives(self, drives: RotatingObject): super(DCMotor, type(self)).drives.fset(self, drives) @property - def angle(self) -> Angle: - return super().angle + def angular_position(self) -> AngularPosition: + return super().angular_position - @angle.setter - def angle(self, angle: Angle): - super(DCMotor, type(self)).angle.fset(self, angle) + @angular_position.setter + def angular_position(self, angular_position: AngularPosition): + super(DCMotor, type(self)).angular_position.fset(self, angular_position) @property - def speed(self) -> Speed: - return super().speed + def angular_speed(self) -> AngularSpeed: + return super().angular_speed - @speed.setter - def speed(self, speed: Speed): - super(DCMotor, type(self)).speed.fset(self, speed) + @angular_speed.setter + def angular_speed(self, angular_speed: AngularSpeed): + super(DCMotor, type(self)).angular_speed.fset(self, angular_speed) @property - def acceleration(self) -> Acceleration: - return super().acceleration + def angular_acceleration(self) -> AngularAcceleration: + return super().angular_acceleration - @acceleration.setter - def acceleration(self, acceleration: Acceleration): - super(DCMotor, type(self)).acceleration.fset(self, acceleration) + @angular_acceleration.setter + def angular_acceleration(self, angular_acceleration: AngularAcceleration): + super(DCMotor, type(self)).angular_acceleration.fset(self, angular_acceleration) @property - def no_load_speed(self) -> Speed: + def no_load_speed(self) -> AngularSpeed: return self.__no_load_speed @property @@ -92,11 +92,11 @@ def load_torque(self, load_torque: Torque): super(DCMotor, type(self)).load_torque.fset(self, load_torque) @property - def inertia(self) -> Inertia: - return super().inertia + def inertia_moment(self) -> InertiaMoment: + return super().inertia_moment def compute_torque(self) -> Torque: - return Torque(value = (1 - self.speed.to('rad/s').value/self.__no_load_speed.to('rad/s').value)* + return Torque(value = (1 - self.angular_speed.to('rad/s').value/self.__no_load_speed.to('rad/s').value)* self.__maximum_torque.value, unit = self.__maximum_torque.unit) diff --git a/gearpy/motor/motor_base.py b/gearpy/motor/motor_base.py index 30906fc..8295ce5 100644 --- a/gearpy/motor/motor_base.py +++ b/gearpy/motor/motor_base.py @@ -1,13 +1,13 @@ from abc import abstractmethod from gearpy.mechanical_object import RotatingObject -from gearpy.units import Acceleration, Angle, Inertia, Speed, Torque +from gearpy.units import AngularPosition, AngularSpeed, AngularAcceleration, InertiaMoment, Torque class MotorBase(RotatingObject): @abstractmethod - def __init__(self, name: str, inertia: Inertia): - super().__init__(name = name, inertia = inertia) + def __init__(self, name: str, inertia_moment: InertiaMoment): + super().__init__(name = name, inertia_moment = inertia_moment) self.__drives = None @property @@ -25,33 +25,33 @@ def drives(self, drives: RotatingObject): @property @abstractmethod - def angle(self) -> Angle: - return super().angle + def angular_position(self) -> AngularPosition: + return super().angular_position - @angle.setter + @angular_position.setter @abstractmethod - def angle(self, angle: Angle): - super(MotorBase, type(self)).angle.fset(self, angle) + def angular_position(self, angular_position: AngularPosition): + super(MotorBase, type(self)).angular_position.fset(self, angular_position) @property @abstractmethod - def speed(self) -> Speed: - return super().speed + def angular_speed(self) -> AngularSpeed: + return super().angular_speed - @speed.setter + @angular_speed.setter @abstractmethod - def speed(self, speed: Speed): - super(MotorBase, type(self)).speed.fset(self, speed) + def angular_speed(self, angular_speed: AngularSpeed): + super(MotorBase, type(self)).angular_speed.fset(self, angular_speed) @property @abstractmethod - def acceleration(self) -> Acceleration: - return super().acceleration + def angular_acceleration(self) -> AngularAcceleration: + return super().angular_acceleration - @acceleration.setter + @angular_acceleration.setter @abstractmethod - def acceleration(self, acceleration: Acceleration): - super(MotorBase, type(self)).acceleration.fset(self, acceleration) + def angular_acceleration(self, angular_acceleration: AngularAcceleration): + super(MotorBase, type(self)).angular_acceleration.fset(self, angular_acceleration) @property @abstractmethod diff --git a/gearpy/solver/solver.py b/gearpy/solver/solver.py index e42c955..b697ce5 100644 --- a/gearpy/solver/solver.py +++ b/gearpy/solver/solver.py @@ -53,27 +53,28 @@ def run(self): def _compute_transmission_inertia(self): - self.transmission_inertia = self.transmission_chain[0].inertia + self.transmission_inertia_moment = self.transmission_chain[0].inertia_moment for item in self.transmission_chain[1:]: - self.transmission_inertia *= item.master_gear_ratio - self.transmission_inertia += item.inertia + self.transmission_inertia_moment *= item.master_gear_ratio + self.transmission_inertia_moment += item.inertia_moment def _compute_transmission_initial_state(self): for i in range(len(self.transmission_chain) - 2, -1, -1): gear_ratio = self.transmission_chain[i + 1].master_gear_ratio - self._compute_angle(gear_ratio = gear_ratio, i = i) - self._compute_speed(gear_ratio = gear_ratio, i = i) + self._compute_angular_position(gear_ratio = gear_ratio, i = i) + self._compute_angular_speed(gear_ratio = gear_ratio, i = i) self._compute_driving_torque() self._compute_load_torque() self._compute_torque() - self.transmission_chain[-1].acceleration = self.transmission_chain[-1].torque/self.transmission_inertia + self.transmission_chain[-1].angular_acceleration = self.transmission_chain[-1].torque/\ + self.transmission_inertia_moment for i in range(len(self.transmission_chain) - 2, -1, -1): gear_ratio = self.transmission_chain[i + 1].master_gear_ratio - self._compute_acceleration(gear_ratio = gear_ratio, i = i) + self._compute_angular_acceleration(gear_ratio = gear_ratio, i = i) def _update_time_variables(self): @@ -84,21 +85,21 @@ def _compute_kinematic_variables(self): for i in range(len(self.transmission_chain) - 2, -1, -1): gear_ratio = self.transmission_chain[i + 1].master_gear_ratio - self._compute_angle(gear_ratio = gear_ratio, i = i) - self._compute_speed(gear_ratio = gear_ratio, i = i) - self._compute_acceleration(gear_ratio = gear_ratio, i = i) + self._compute_angular_position(gear_ratio = gear_ratio, i = i) + self._compute_angular_speed(gear_ratio = gear_ratio, i = i) + self._compute_angular_acceleration(gear_ratio = gear_ratio, i = i) - def _compute_angle(self, gear_ratio, i): + def _compute_angular_position(self, gear_ratio, i): - self.transmission_chain[i].angle = gear_ratio*self.transmission_chain[i + 1].angle + self.transmission_chain[i].angular_position = gear_ratio*self.transmission_chain[i + 1].angular_position - def _compute_speed(self, gear_ratio, i): + def _compute_angular_speed(self, gear_ratio, i): - self.transmission_chain[i].speed = gear_ratio*self.transmission_chain[i + 1].speed + self.transmission_chain[i].angular_speed = gear_ratio*self.transmission_chain[i + 1].angular_speed - def _compute_acceleration(self, gear_ratio, i): + def _compute_angular_acceleration(self, gear_ratio, i): - self.transmission_chain[i].acceleration = gear_ratio*self.transmission_chain[i + 1].acceleration + self.transmission_chain[i].angular_acceleration = gear_ratio*self.transmission_chain[i + 1].angular_acceleration def _compute_driving_torque(self): @@ -114,9 +115,10 @@ def _compute_load_torque(self): for i in range(len(self.transmission_chain) - 1, 0, -1): if self.transmission_chain[i].external_torque is not None: self.transmission_chain[i].load_torque = \ - self.transmission_chain[i].external_torque(time = self.time[-1], - angle = self.transmission_chain[i].angle, - speed = self.transmission_chain[i].speed) + self.transmission_chain[i]. \ + external_torque(time = self.time[-1], + angular_position = self.transmission_chain[i].angular_position, + angular_speed = self.transmission_chain[i].angular_speed) gear_ratio = self.transmission_chain[i].master_gear_ratio self.transmission_chain[i - 1].load_torque = self.transmission_chain[i].load_torque/gear_ratio @@ -127,6 +129,9 @@ def _compute_torque(self): def _time_integration(self): - self.transmission_chain[-1].acceleration = self.transmission_chain[-1].torque/self.transmission_inertia - self.transmission_chain[-1].speed += self.transmission_chain[-1].acceleration*self.time_discretization - self.transmission_chain[-1].angle += self.transmission_chain[-1].speed*self.time_discretization + self.transmission_chain[-1].angular_acceleration = self.transmission_chain[-1].torque/\ + self.transmission_inertia_moment + self.transmission_chain[-1].angular_speed += self.transmission_chain[-1].angular_acceleration*\ + self.time_discretization + self.transmission_chain[-1].angular_position += self.transmission_chain[-1].angular_speed*\ + self.time_discretization diff --git a/gearpy/units/__init__.py b/gearpy/units/__init__.py index 9f5dcd1..d23071c 100644 --- a/gearpy/units/__init__.py +++ b/gearpy/units/__init__.py @@ -1,7 +1,8 @@ -from .acceleration import Acceleration -from .angle import Angle -from .inertia import Inertia -from .speed import Speed +from .angular_position import AngularPosition +from .angular_speed import AngularSpeed +from .angular_acceleration import AngularAcceleration +from .inertia_moment import InertiaMoment +from .torque import Torque from .time import Time from .time_interval import TimeInterval -from .torque import Torque + diff --git a/gearpy/units/acceleration.py b/gearpy/units/angular_acceleration.py similarity index 61% rename from gearpy/units/acceleration.py rename to gearpy/units/angular_acceleration.py index 56d5eae..3a0e7cb 100644 --- a/gearpy/units/acceleration.py +++ b/gearpy/units/angular_acceleration.py @@ -1,11 +1,11 @@ from math import pi -from .speed import Speed +from .angular_speed import AngularSpeed from .time import Time from typing import Union from .unit_base import UnitBase -class Acceleration(UnitBase): +class AngularAcceleration(UnitBase): __UNITS = {'rad/s^2': 1, 'deg/s^2': pi/180} @@ -23,17 +23,17 @@ def __init__(self, value: Union[float, int], unit: str): def __repr__(self) -> str: return f'{self.__value} {self.__unit}' - def __add__(self, other: 'Acceleration') -> 'Acceleration': + def __add__(self, other: 'AngularAcceleration') -> 'AngularAcceleration': super().__add__(other = other) - return Acceleration(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + return AngularAcceleration(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - def __sub__(self, other: 'Acceleration') -> 'Acceleration': + def __sub__(self, other: 'AngularAcceleration') -> 'AngularAcceleration': super().__sub__(other = other) - return Acceleration(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + return AngularAcceleration(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - def __mul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration']: + def __mul__(self, other: Union[Time, float, int]) -> Union[AngularSpeed, 'AngularAcceleration']: super().__mul__(other = other) if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): @@ -41,11 +41,11 @@ def __mul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration' f'{other.__class__.__name__}.') if isinstance(other, Time): - return Speed(value = self.to('rad/s^2').value*other.to('sec').value, unit = 'rad/s') + return AngularSpeed(value = self.to('rad/s^2').value*other.to('sec').value, unit = 'rad/s') else: - return Acceleration(value = self.__value*other, unit = self.__unit) + return AngularAcceleration(value = self.__value*other, unit = self.__unit) - def __rmul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration']: + def __rmul__(self, other: Union[Time, float, int]) -> Union[AngularSpeed, 'AngularAcceleration']: super().__rmul__(other = other) if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): @@ -53,48 +53,48 @@ def __rmul__(self, other: Union[Time, float, int]) -> Union[Speed, 'Acceleration f'{self.__class__.__name__}.') if isinstance(other, Time): - return Speed(value = self.to('rad/s^2').value*other.to('sec').value, unit = 'rad/s') + return AngularSpeed(value = self.to('rad/s^2').value*other.to('sec').value, unit = 'rad/s') else: - return Acceleration(value = self.__value*other, unit = self.__unit) + return AngularAcceleration(value = self.__value*other, unit = self.__unit) - def __truediv__(self, other: Union['Acceleration', float, int]) -> Union['Acceleration', float]: + def __truediv__(self, other: Union['AngularAcceleration', float, int]) -> Union['AngularAcceleration', float]: super().__truediv__(other = other) - if not isinstance(other, Acceleration) and not isinstance(other, float) and not isinstance(other, int): + if not isinstance(other, AngularAcceleration) and not isinstance(other, float) and not isinstance(other, int): raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' f'{other.__class__.__name__}.') - if isinstance(other, Acceleration): + if isinstance(other, AngularAcceleration): return self.__value/other.to(self.__unit).value else: - return Acceleration(value = self.__value/other, unit = self.__unit) + return AngularAcceleration(value = self.__value/other, unit = self.__unit) - def __eq__(self, other: 'Acceleration') -> bool: + def __eq__(self, other: 'AngularAcceleration') -> bool: super().__eq__(other = other) return self.__value == other.to(self.__unit).value - def __ne__(self, other: 'Acceleration') -> bool: + def __ne__(self, other: 'AngularAcceleration') -> bool: super().__ne__(other = other) return self.__value != other.to(self.__unit).value - def __gt__(self, other: 'Acceleration') -> bool: + def __gt__(self, other: 'AngularAcceleration') -> bool: super().__gt__(other = other) return self.__value > other.to(self.__unit).value - def __ge__(self, other: 'Acceleration') -> bool: + def __ge__(self, other: 'AngularAcceleration') -> bool: super().__ge__(other = other) return self.__value >= other.to(self.__unit).value - def __lt__(self, other: 'Acceleration') -> bool: + def __lt__(self, other: 'AngularAcceleration') -> bool: super().__lt__(other = other) return self.__value < other.to(self.__unit).value - def __le__(self, other: 'Acceleration') -> bool: + def __le__(self, other: 'AngularAcceleration') -> bool: super().__le__(other = other) return self.__value <= other.to(self.__unit).value @@ -107,7 +107,7 @@ def value(self) -> Union[float, int]: def unit(self) -> str: return self.__unit - def to(self, target_unit: str, inplace: bool = False) -> 'Acceleration': + def to(self, target_unit: str, inplace: bool = False) -> 'AngularAcceleration': super().to(target_unit = target_unit, inplace = inplace) if target_unit not in self.__UNITS.keys(): @@ -121,4 +121,4 @@ def to(self, target_unit: str, inplace: bool = False) -> 'Acceleration': self.__unit = target_unit return self else: - return Acceleration(value = target_value, unit = target_unit) + return AngularAcceleration(value = target_value, unit = target_unit) diff --git a/gearpy/units/angle.py b/gearpy/units/angular_position.py similarity index 66% rename from gearpy/units/angle.py rename to gearpy/units/angular_position.py index 353a73a..db698e7 100644 --- a/gearpy/units/angle.py +++ b/gearpy/units/angular_position.py @@ -3,7 +3,7 @@ from .unit_base import UnitBase -class Angle(UnitBase): +class AngularPosition(UnitBase): __UNITS = {'rad': 1, 'deg': pi/180, @@ -23,72 +23,72 @@ def __init__(self, value: Union[float, int], unit: str): def __repr__(self) -> str: return f'{self.__value} {self.__unit}' - def __add__(self, other: 'Angle') -> 'Angle': + def __add__(self, other: 'AngularPosition') -> 'AngularPosition': super().__add__(other = other) - return Angle(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + return AngularPosition(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - def __sub__(self, other: 'Angle') -> 'Angle': + def __sub__(self, other: 'AngularPosition') -> 'AngularPosition': super().__sub__(other = other) - return Angle(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + return AngularPosition(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - def __mul__(self, other: Union[float, int]) -> 'Angle': + def __mul__(self, other: Union[float, int]) -> 'AngularPosition': super().__mul__(other = other) if not isinstance(other, float) and not isinstance(other, int): raise TypeError(f'It is not allowed to multiply an {self.__class__.__name__} by a ' f'{other.__class__.__name__}.') - return Angle(value = self.__value*other, unit = self.__unit) + return AngularPosition(value = self.__value*other, unit = self.__unit) - def __rmul__(self, other: Union[float, int]) -> 'Angle': + def __rmul__(self, other: Union[float, int]) -> 'AngularPosition': super().__rmul__(other = other) if not isinstance(other, float) and not isinstance(other, int): raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an ' f'{self.__class__.__name__}.') - return Angle(value = self.__value*other, unit = self.__unit) + return AngularPosition(value = self.__value*other, unit = self.__unit) - def __truediv__(self, other: Union['Angle', float, int]) -> Union['Angle', float]: + def __truediv__(self, other: Union['AngularPosition', float, int]) -> Union['AngularPosition', float]: super().__truediv__(other = other) - if not isinstance(other, Angle) and not isinstance(other, float) and not isinstance(other, int): + if not isinstance(other, AngularPosition) and not isinstance(other, float) and not isinstance(other, int): raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' f'{other.__class__.__name__}.') - if isinstance(other, Angle): + if isinstance(other, AngularPosition): return self.__value/other.to(self.__unit).value else: - return Angle(value = self.__value/other, unit = self.__unit) + return AngularPosition(value = self.__value/other, unit = self.__unit) - def __eq__(self, other: 'Angle') -> bool: + def __eq__(self, other: 'AngularPosition') -> bool: super().__eq__(other = other) return self.__value == other.to(self.__unit).value - def __ne__(self, other: 'Angle') -> bool: + def __ne__(self, other: 'AngularPosition') -> bool: super().__ne__(other = other) return self.__value != other.to(self.__unit).value - def __gt__(self, other: 'Angle') -> bool: + def __gt__(self, other: 'AngularPosition') -> bool: super().__gt__(other = other) return self.__value > other.to(self.__unit).value - def __ge__(self, other: 'Angle') -> bool: + def __ge__(self, other: 'AngularPosition') -> bool: super().__ge__(other = other) return self.__value >= other.to(self.__unit).value - def __lt__(self, other: 'Angle') -> bool: + def __lt__(self, other: 'AngularPosition') -> bool: super().__lt__(other = other) return self.__value < other.to(self.__unit).value - def __le__(self, other: 'Angle') -> bool: + def __le__(self, other: 'AngularPosition') -> bool: super().__le__(other = other) return self.__value <= other.to(self.__unit).value @@ -101,7 +101,7 @@ def value(self) -> Union[float, int]: def unit(self) -> str: return self.__unit - def to(self, target_unit: str, inplace: bool = False) -> 'Angle': + def to(self, target_unit: str, inplace: bool = False) -> 'AngularPosition': super().to(target_unit = target_unit, inplace = inplace) if target_unit not in self.__UNITS.keys(): @@ -115,4 +115,4 @@ def to(self, target_unit: str, inplace: bool = False) -> 'Angle': self.__unit = target_unit return self else: - return Angle(value = target_value, unit = target_unit) + return AngularPosition(value = target_value, unit = target_unit) diff --git a/gearpy/units/speed.py b/gearpy/units/angular_speed.py similarity index 66% rename from gearpy/units/speed.py rename to gearpy/units/angular_speed.py index 0d50dd3..fd5bed9 100644 --- a/gearpy/units/speed.py +++ b/gearpy/units/angular_speed.py @@ -1,11 +1,11 @@ -from .angle import Angle +from .angular_position import AngularPosition from math import pi from .time import Time from typing import Union from .unit_base import UnitBase -class Speed(UnitBase): +class AngularSpeed(UnitBase): __UNITS = {'rad/s': 1, 'rad/min': 1/60, @@ -30,17 +30,17 @@ def __init__(self, value: Union[float, int], unit: str): def __repr__(self) -> str: return f'{self.__value} {self.__unit}' - def __add__(self, other: 'Speed') -> 'Speed': + def __add__(self, other: 'AngularSpeed') -> 'AngularSpeed': super().__add__(other = other) - return Speed(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + return AngularSpeed(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - def __sub__(self, other: 'Speed') -> 'Speed': + def __sub__(self, other: 'AngularSpeed') -> 'AngularSpeed': super().__sub__(other = other) - return Speed(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + return AngularSpeed(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - def __mul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: + def __mul__(self, other: Union[Time, float, int]) -> Union[AngularPosition, 'AngularSpeed']: super().__mul__(other = other) if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): @@ -48,11 +48,11 @@ def __mul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: f'{other.__class__.__name__}.') if isinstance(other, Time): - return Angle(value = self.to('rad/s').value*other.to('sec').value, unit = 'rad') + return AngularPosition(value = self.to('rad/s').value*other.to('sec').value, unit = 'rad') else: - return Speed(value = self.__value*other, unit = self.__unit) + return AngularSpeed(value = self.__value*other, unit = self.__unit) - def __rmul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: + def __rmul__(self, other: Union[Time, float, int]) -> Union[AngularPosition, 'AngularSpeed']: super().__rmul__(other = other) if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): @@ -60,47 +60,47 @@ def __rmul__(self, other: Union[Time, float, int]) -> Union[Angle, 'Speed']: f'{self.__class__.__name__}.') if isinstance(other, Time): - return Angle(value = self.to('rad/s').value*other.to('sec').value, unit = 'rad') + return AngularPosition(value = self.to('rad/s').value*other.to('sec').value, unit = 'rad') else: - return Speed(value = self.__value*other, unit = self.__unit) + return AngularSpeed(value = self.__value*other, unit = self.__unit) - def __truediv__(self, other: Union['Speed', float, int]) -> Union['Speed', float]: + def __truediv__(self, other: Union['AngularSpeed', float, int]) -> Union['AngularSpeed', float]: super().__truediv__(other = other) - if not isinstance(other, Speed) and not isinstance(other, float) and not isinstance(other, int): + if not isinstance(other, AngularSpeed) and not isinstance(other, float) and not isinstance(other, int): raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') - if isinstance(other, Speed): + if isinstance(other, AngularSpeed): return self.__value/other.to(self.__unit).value else: - return Speed(value = self.__value/other, unit = self.__unit) + return AngularSpeed(value = self.__value/other, unit = self.__unit) - def __eq__(self, other: 'Speed') -> bool: + def __eq__(self, other: 'AngularSpeed') -> bool: super().__eq__(other = other) return self.__value == other.to(self.__unit).value - def __ne__(self, other: 'Speed') -> bool: + def __ne__(self, other: 'AngularSpeed') -> bool: super().__ne__(other = other) return self.__value != other.to(self.__unit).value - def __gt__(self, other: 'Speed') -> bool: + def __gt__(self, other: 'AngularSpeed') -> bool: super().__gt__(other = other) return self.__value > other.to(self.__unit).value - def __ge__(self, other: 'Speed') -> bool: + def __ge__(self, other: 'AngularSpeed') -> bool: super().__ge__(other = other) return self.__value >= other.to(self.__unit).value - def __lt__(self, other: 'Speed') -> bool: + def __lt__(self, other: 'AngularSpeed') -> bool: super().__lt__(other = other) return self.__value < other.to(self.__unit).value - def __le__(self, other: 'Speed') -> bool: + def __le__(self, other: 'AngularSpeed') -> bool: super().__le__(other = other) return self.__value <= other.to(self.__unit).value @@ -113,7 +113,7 @@ def value(self) -> Union[float, int]: def unit(self) -> str: return self.__unit - def to(self, target_unit: str, inplace: bool = False) -> 'Speed': + def to(self, target_unit: str, inplace: bool = False) -> 'AngularSpeed': super().to(target_unit = target_unit, inplace = inplace) if target_unit not in self.__UNITS.keys(): @@ -127,4 +127,4 @@ def to(self, target_unit: str, inplace: bool = False) -> 'Speed': self.__unit = target_unit return self else: - return Speed(value = target_value, unit = target_unit) + return AngularSpeed(value = target_value, unit = target_unit) diff --git a/gearpy/units/inertia.py b/gearpy/units/inertia_moment.py similarity index 70% rename from gearpy/units/inertia.py rename to gearpy/units/inertia_moment.py index 73e573a..bad397f 100644 --- a/gearpy/units/inertia.py +++ b/gearpy/units/inertia_moment.py @@ -2,7 +2,7 @@ from .unit_base import UnitBase -class Inertia(UnitBase): +class InertiaMoment(UnitBase): __UNITS = {'kgm^2': 1, 'gm^2': 1e-3, @@ -24,20 +24,20 @@ def __init__(self, value: Union[float, int], unit: str): def __repr__(self) -> str: return f'{self.__value} {self.__unit}' - def __add__(self, other: 'Inertia') -> 'Inertia': + def __add__(self, other: 'InertiaMoment') -> 'InertiaMoment': super().__add__(other = other) - return Inertia(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + return InertiaMoment(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - def __sub__(self, other: 'Inertia') -> 'Inertia': + def __sub__(self, other: 'InertiaMoment') -> 'InertiaMoment': super().__sub__(other = other) if self.__value - other.to(self.__unit).value <= 0: raise ValueError('Cannot perform the subtraction because the result is not positive.') - return Inertia(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + return InertiaMoment(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - def __mul__(self, other: Union[float, int]) -> 'Inertia': + def __mul__(self, other: Union[float, int]) -> 'InertiaMoment': super().__mul__(other = other) if not isinstance(other, float) and not isinstance(other, int): @@ -47,9 +47,9 @@ def __mul__(self, other: Union[float, int]) -> 'Inertia': if other <= 0: raise ValueError('Cannot perform a multiplication by a non-positive number.') - return Inertia(value = self.__value*other, unit = self.__unit) + return InertiaMoment(value = self.__value*other, unit = self.__unit) - def __rmul__(self, other: Union[float, int]) -> 'Inertia': + def __rmul__(self, other: Union[float, int]) -> 'InertiaMoment': super().__rmul__(other = other) if not isinstance(other, float) and not isinstance(other, int): @@ -59,46 +59,46 @@ def __rmul__(self, other: Union[float, int]) -> 'Inertia': if other <= 0: raise ValueError('Cannot perform a multiplication by a non-positive number.') - return Inertia(value = self.__value*other, unit = self.__unit) + return InertiaMoment(value = self.__value*other, unit = self.__unit) - def __truediv__(self, other: Union['Inertia', float, int]) -> Union['Inertia', float]: + def __truediv__(self, other: Union['InertiaMoment', float, int]) -> Union['InertiaMoment', float]: super().__truediv__(other = other) - if not isinstance(other, Inertia) and not isinstance(other, float) and not isinstance(other, int): + if not isinstance(other, InertiaMoment) and not isinstance(other, float) and not isinstance(other, int): raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' f'{other.__class__.__name__}.') - if isinstance(other, Inertia): + if isinstance(other, InertiaMoment): return self.__value/other.to(self.__unit).value else: - return Inertia(value = self.__value/other, unit = self.__unit) + return InertiaMoment(value = self.__value/other, unit = self.__unit) - def __eq__(self, other: 'Inertia') -> bool: + def __eq__(self, other: 'InertiaMoment') -> bool: super().__eq__(other = other) return self.__value == other.to(self.__unit).value - def __ne__(self, other: 'Inertia') -> bool: + def __ne__(self, other: 'InertiaMoment') -> bool: super().__ne__(other = other) return self.__value != other.to(self.__unit).value - def __gt__(self, other: 'Inertia') -> bool: + def __gt__(self, other: 'InertiaMoment') -> bool: super().__gt__(other = other) return self.__value > other.to(self.__unit).value - def __ge__(self, other: 'Inertia') -> bool: + def __ge__(self, other: 'InertiaMoment') -> bool: super().__ge__(other = other) return self.__value >= other.to(self.__unit).value - def __lt__(self, other: 'Inertia') -> bool: + def __lt__(self, other: 'InertiaMoment') -> bool: super().__lt__(other = other) return self.__value < other.to(self.__unit).value - def __le__(self, other: 'Inertia') -> bool: + def __le__(self, other: 'InertiaMoment') -> bool: super().__le__(other = other) return self.__value <= other.to(self.__unit).value @@ -111,7 +111,7 @@ def value(self) -> Union[float, int]: def unit(self) -> str: return self.__unit - def to(self, target_unit: str, inplace: bool = False) -> 'Inertia': + def to(self, target_unit: str, inplace: bool = False) -> 'InertiaMoment': super().to(target_unit = target_unit, inplace = inplace) if target_unit not in self.__UNITS.keys(): @@ -125,4 +125,4 @@ def to(self, target_unit: str, inplace: bool = False) -> 'Inertia': self.__unit = target_unit return self else: - return Inertia(value = target_value, unit = target_unit) + return InertiaMoment(value = target_value, unit = target_unit) diff --git a/gearpy/units/torque.py b/gearpy/units/torque.py index 663af43..cf99e42 100644 --- a/gearpy/units/torque.py +++ b/gearpy/units/torque.py @@ -1,5 +1,5 @@ -from .acceleration import Acceleration -from .inertia import Inertia +from .angular_acceleration import AngularAcceleration +from .inertia_moment import InertiaMoment from typing import Union from .unit_base import UnitBase @@ -53,17 +53,17 @@ def __rmul__(self, other: Union[float, int]) -> 'Torque': return Torque(value = self.__value*other, unit = self.__unit) - def __truediv__(self, other: Union['Torque', 'Inertia', float, int]) -> Union['Torque', 'Acceleration', float]: + def __truediv__(self, other: Union['Torque', 'InertiaMoment', float, int]) -> Union['Torque', 'AngularAcceleration', float]: super().__truediv__(other = other) if not isinstance(other, Torque) and not isinstance(other, float) and not isinstance(other, int) \ - and not isinstance(other, Inertia): + and not isinstance(other, InertiaMoment): raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') if isinstance(other, Torque): return self.__value/other.to(self.__unit).value - elif isinstance(other, Inertia): - return Acceleration(value = self.to('Nm').value/other.to('kgm^2').value, unit = 'rad/s^2') + elif isinstance(other, InertiaMoment): + return AngularAcceleration(value = self.to('Nm').value/other.to('kgm^2').value, unit = 'rad/s^2') else: return Torque(value = self.__value/other, unit = self.__unit) From 7fe62a1ade0a85c09c8b4881999003cb015b5969 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sat, 14 Oct 2023 00:45:46 +0200 Subject: [PATCH 24/33] DEV: add computation tolerance to deal with floating point rounding --- gearpy/units/angular_acceleration.py | 38 ++++++++++++++++++++++------ gearpy/units/angular_position.py | 38 ++++++++++++++++++++++------ gearpy/units/angular_speed.py | 38 ++++++++++++++++++++++------ gearpy/units/inertia_moment.py | 37 ++++++++++++++++++++++----- gearpy/units/settings.py | 1 + gearpy/units/time.py | 37 ++++++++++++++++++++++----- gearpy/units/torque.py | 37 ++++++++++++++++++++++----- 7 files changed, 181 insertions(+), 45 deletions(-) create mode 100644 gearpy/units/settings.py diff --git a/gearpy/units/angular_acceleration.py b/gearpy/units/angular_acceleration.py index 3a0e7cb..2bc6de3 100644 --- a/gearpy/units/angular_acceleration.py +++ b/gearpy/units/angular_acceleration.py @@ -1,5 +1,6 @@ -from math import pi from .angular_speed import AngularSpeed +from math import pi, fabs +from .settings import COMPARISON_TOLERANCE from .time import Time from typing import Union from .unit_base import UnitBase @@ -72,32 +73,50 @@ def __truediv__(self, other: Union['AngularAcceleration', float, int]) -> Union[ def __eq__(self, other: 'AngularAcceleration') -> bool: super().__eq__(other = other) - return self.__value == other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE def __ne__(self, other: 'AngularAcceleration') -> bool: super().__ne__(other = other) - return self.__value != other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE def __gt__(self, other: 'AngularAcceleration') -> bool: super().__gt__(other = other) - return self.__value > other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE def __ge__(self, other: 'AngularAcceleration') -> bool: super().__ge__(other = other) - return self.__value >= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE def __lt__(self, other: 'AngularAcceleration') -> bool: super().__lt__(other = other) - return self.__value < other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE def __le__(self, other: 'AngularAcceleration') -> bool: super().__le__(other = other) - return self.__value <= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE @property def value(self) -> Union[float, int]: @@ -114,7 +133,10 @@ def to(self, target_unit: str, inplace: bool = False) -> 'AngularAcceleration': raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value if inplace: self.__value = target_value diff --git a/gearpy/units/angular_position.py b/gearpy/units/angular_position.py index db698e7..c193c5d 100644 --- a/gearpy/units/angular_position.py +++ b/gearpy/units/angular_position.py @@ -1,4 +1,5 @@ -from math import pi +from math import pi, fabs +from .settings import COMPARISON_TOLERANCE from typing import Union from .unit_base import UnitBase @@ -66,32 +67,50 @@ def __truediv__(self, other: Union['AngularPosition', float, int]) -> Union['Ang def __eq__(self, other: 'AngularPosition') -> bool: super().__eq__(other = other) - return self.__value == other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE def __ne__(self, other: 'AngularPosition') -> bool: super().__ne__(other = other) - return self.__value != other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE def __gt__(self, other: 'AngularPosition') -> bool: super().__gt__(other = other) - return self.__value > other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE def __ge__(self, other: 'AngularPosition') -> bool: super().__ge__(other = other) - return self.__value >= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE def __lt__(self, other: 'AngularPosition') -> bool: super().__lt__(other = other) - return self.__value < other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE def __le__(self, other: 'AngularPosition') -> bool: super().__le__(other = other) - return self.__value <= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE @property def value(self) -> Union[float, int]: @@ -108,7 +127,10 @@ def to(self, target_unit: str, inplace: bool = False) -> 'AngularPosition': raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value if inplace: self.__value = target_value diff --git a/gearpy/units/angular_speed.py b/gearpy/units/angular_speed.py index fd5bed9..78f1bb2 100644 --- a/gearpy/units/angular_speed.py +++ b/gearpy/units/angular_speed.py @@ -1,5 +1,6 @@ from .angular_position import AngularPosition -from math import pi +from math import pi, fabs +from .settings import COMPARISON_TOLERANCE from .time import Time from typing import Union from .unit_base import UnitBase @@ -78,32 +79,50 @@ def __truediv__(self, other: Union['AngularSpeed', float, int]) -> Union['Angula def __eq__(self, other: 'AngularSpeed') -> bool: super().__eq__(other = other) - return self.__value == other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE def __ne__(self, other: 'AngularSpeed') -> bool: super().__ne__(other = other) - return self.__value != other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE def __gt__(self, other: 'AngularSpeed') -> bool: super().__gt__(other = other) - return self.__value > other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE def __ge__(self, other: 'AngularSpeed') -> bool: super().__ge__(other = other) - return self.__value >= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE def __lt__(self, other: 'AngularSpeed') -> bool: super().__lt__(other = other) - return self.__value < other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE def __le__(self, other: 'AngularSpeed') -> bool: super().__le__(other = other) - return self.__value <= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE @property def value(self) -> Union[float, int]: @@ -120,7 +139,10 @@ def to(self, target_unit: str, inplace: bool = False) -> 'AngularSpeed': raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value if inplace: self.__value = target_value diff --git a/gearpy/units/inertia_moment.py b/gearpy/units/inertia_moment.py index bad397f..1eb7547 100644 --- a/gearpy/units/inertia_moment.py +++ b/gearpy/units/inertia_moment.py @@ -1,3 +1,5 @@ +from math import fabs +from .settings import COMPARISON_TOLERANCE from typing import Union from .unit_base import UnitBase @@ -76,32 +78,50 @@ def __truediv__(self, other: Union['InertiaMoment', float, int]) -> Union['Inert def __eq__(self, other: 'InertiaMoment') -> bool: super().__eq__(other = other) - return self.__value == other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE def __ne__(self, other: 'InertiaMoment') -> bool: super().__ne__(other = other) - return self.__value != other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE def __gt__(self, other: 'InertiaMoment') -> bool: super().__gt__(other = other) - return self.__value > other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE def __ge__(self, other: 'InertiaMoment') -> bool: super().__ge__(other = other) - return self.__value >= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE def __lt__(self, other: 'InertiaMoment') -> bool: super().__lt__(other = other) - return self.__value < other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE def __le__(self, other: 'InertiaMoment') -> bool: super().__le__(other = other) - return self.__value <= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE @property def value(self) -> Union[float, int]: @@ -118,7 +138,10 @@ def to(self, target_unit: str, inplace: bool = False) -> 'InertiaMoment': raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value if inplace: self.__value = target_value diff --git a/gearpy/units/settings.py b/gearpy/units/settings.py new file mode 100644 index 0000000..b37738e --- /dev/null +++ b/gearpy/units/settings.py @@ -0,0 +1 @@ +COMPARISON_TOLERANCE = 1e-12 diff --git a/gearpy/units/time.py b/gearpy/units/time.py index c591b10..15260f1 100644 --- a/gearpy/units/time.py +++ b/gearpy/units/time.py @@ -1,3 +1,5 @@ +from math import fabs +from .settings import COMPARISON_TOLERANCE from typing import Union from .unit_base import UnitBase @@ -63,32 +65,50 @@ def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: def __eq__(self, other: 'Time') -> bool: super().__eq__(other = other) - return self.__value == other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE def __ne__(self, other: 'Time') -> bool: super().__ne__(other = other) - return self.__value != other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE def __gt__(self, other: 'Time') -> bool: super().__gt__(other = other) - return self.__value > other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE def __ge__(self, other: 'Time') -> bool: super().__ge__(other = other) - return self.__value >= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE def __lt__(self, other: 'Time') -> bool: super().__lt__(other = other) - return self.__value < other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE def __le__(self, other: 'Time') -> bool: super().__le__(other = other) - return self.__value <= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE @property def value(self) -> Union[float, int]: @@ -105,7 +125,10 @@ def to(self, target_unit: str, inplace: bool = False) -> 'Time': raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value if inplace: self.__value = target_value diff --git a/gearpy/units/torque.py b/gearpy/units/torque.py index cf99e42..da4c7e6 100644 --- a/gearpy/units/torque.py +++ b/gearpy/units/torque.py @@ -1,5 +1,7 @@ from .angular_acceleration import AngularAcceleration from .inertia_moment import InertiaMoment +from math import fabs +from .settings import COMPARISON_TOLERANCE from typing import Union from .unit_base import UnitBase @@ -70,32 +72,50 @@ def __truediv__(self, other: Union['Torque', 'InertiaMoment', float, int]) -> Un def __eq__(self, other: 'Torque') -> bool: super().__eq__(other = other) - return self.__value == other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE def __ne__(self, other: 'Torque') -> bool: super().__ne__(other = other) - return self.__value != other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE def __gt__(self, other: 'Torque') -> bool: super().__gt__(other = other) - return self.__value > other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE def __ge__(self, other: 'Torque') -> bool: super().__ge__(other = other) - return self.__value >= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE def __lt__(self, other: 'Torque') -> bool: super().__lt__(other = other) - return self.__value < other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE def __le__(self, other: 'Torque') -> bool: super().__le__(other = other) - return self.__value <= other.to(self.__unit).value + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE @property def value(self) -> Union[float, int]: @@ -112,7 +132,10 @@ def to(self, target_unit: str, inplace: bool = False) -> 'Torque': raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " f"Available units are: {list(self.__UNITS.keys())}") - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value if inplace: self.__value = target_value From d769c8da15960f831ffdedd7fb275586dbe24e02 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sat, 14 Oct 2023 01:28:33 +0200 Subject: [PATCH 25/33] DEV: move concrete unit classes in a single file In order to avoid circular import, all concrete unit classes are moved to a single file --- gearpy/units/__init__.py | 15 +- gearpy/units/angular_acceleration.py | 146 ----- gearpy/units/angular_position.py | 140 ---- gearpy/units/angular_speed.py | 152 ----- gearpy/units/concrete_units.py | 913 +++++++++++++++++++++++++++ gearpy/units/inertia_moment.py | 151 ----- gearpy/units/settings.py | 1 - gearpy/units/time.py | 138 ---- gearpy/units/time_interval.py | 67 -- gearpy/units/torque.py | 145 ----- 10 files changed, 920 insertions(+), 948 deletions(-) delete mode 100644 gearpy/units/angular_acceleration.py delete mode 100644 gearpy/units/angular_position.py delete mode 100644 gearpy/units/angular_speed.py create mode 100644 gearpy/units/concrete_units.py delete mode 100644 gearpy/units/inertia_moment.py delete mode 100644 gearpy/units/settings.py delete mode 100644 gearpy/units/time.py delete mode 100644 gearpy/units/time_interval.py delete mode 100644 gearpy/units/torque.py diff --git a/gearpy/units/__init__.py b/gearpy/units/__init__.py index d23071c..0b93ab6 100644 --- a/gearpy/units/__init__.py +++ b/gearpy/units/__init__.py @@ -1,8 +1,7 @@ -from .angular_position import AngularPosition -from .angular_speed import AngularSpeed -from .angular_acceleration import AngularAcceleration -from .inertia_moment import InertiaMoment -from .torque import Torque -from .time import Time -from .time_interval import TimeInterval - +from .concrete_units import AngularPosition, \ + AngularSpeed, \ + AngularAcceleration, \ + InertiaMoment, \ + Torque, \ + Time, \ + TimeInterval diff --git a/gearpy/units/angular_acceleration.py b/gearpy/units/angular_acceleration.py deleted file mode 100644 index 2bc6de3..0000000 --- a/gearpy/units/angular_acceleration.py +++ /dev/null @@ -1,146 +0,0 @@ -from .angular_speed import AngularSpeed -from math import pi, fabs -from .settings import COMPARISON_TOLERANCE -from .time import Time -from typing import Union -from .unit_base import UnitBase - - -class AngularAcceleration(UnitBase): - - __UNITS = {'rad/s^2': 1, - 'deg/s^2': pi/180} - - def __init__(self, value: Union[float, int], unit: str): - super().__init__(value = value, unit = unit) - - if unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - self.__value = value - self.__unit = unit - - def __repr__(self) -> str: - return f'{self.__value} {self.__unit}' - - def __add__(self, other: 'AngularAcceleration') -> 'AngularAcceleration': - super().__add__(other = other) - - return AngularAcceleration(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - - def __sub__(self, other: 'AngularAcceleration') -> 'AngularAcceleration': - super().__sub__(other = other) - - return AngularAcceleration(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - - def __mul__(self, other: Union[Time, float, int]) -> Union[AngularSpeed, 'AngularAcceleration']: - super().__mul__(other = other) - - if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply an {self.__class__.__name__} by a ' - f'{other.__class__.__name__}.') - - if isinstance(other, Time): - return AngularSpeed(value = self.to('rad/s^2').value*other.to('sec').value, unit = 'rad/s') - else: - return AngularAcceleration(value = self.__value*other, unit = self.__unit) - - def __rmul__(self, other: Union[Time, float, int]) -> Union[AngularSpeed, 'AngularAcceleration']: - super().__rmul__(other = other) - - if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an ' - f'{self.__class__.__name__}.') - - if isinstance(other, Time): - return AngularSpeed(value = self.to('rad/s^2').value*other.to('sec').value, unit = 'rad/s') - else: - return AngularAcceleration(value = self.__value*other, unit = self.__unit) - - def __truediv__(self, other: Union['AngularAcceleration', float, int]) -> Union['AngularAcceleration', float]: - super().__truediv__(other = other) - - if not isinstance(other, AngularAcceleration) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' - f'{other.__class__.__name__}.') - - if isinstance(other, AngularAcceleration): - return self.__value/other.to(self.__unit).value - else: - return AngularAcceleration(value = self.__value/other, unit = self.__unit) - - def __eq__(self, other: 'AngularAcceleration') -> bool: - super().__eq__(other = other) - - if self.__unit == other.unit: - return self.__value == other.value - else: - return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE - - def __ne__(self, other: 'AngularAcceleration') -> bool: - super().__ne__(other = other) - - if self.__unit == other.unit: - return self.__value != other.value - else: - return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE - - def __gt__(self, other: 'AngularAcceleration') -> bool: - super().__gt__(other = other) - - if self.__unit == other.unit: - return self.__value > other.value - else: - return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE - - def __ge__(self, other: 'AngularAcceleration') -> bool: - super().__ge__(other = other) - - if self.__unit == other.unit: - return self.__value >= other.value - else: - return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE - - def __lt__(self, other: 'AngularAcceleration') -> bool: - super().__lt__(other = other) - - if self.__unit == other.unit: - return self.__value < other.value - else: - return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE - - def __le__(self, other: 'AngularAcceleration') -> bool: - super().__le__(other = other) - - if self.__unit == other.unit: - return self.__value <= other.value - else: - return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE - - @property - def value(self) -> Union[float, int]: - return self.__value - - @property - def unit(self) -> str: - return self.__unit - - def to(self, target_unit: str, inplace: bool = False) -> 'AngularAcceleration': - super().to(target_unit = target_unit, inplace = inplace) - - if target_unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - if target_unit != self.__unit: - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - else: - target_value = self.__value - - if inplace: - self.__value = target_value - self.__unit = target_unit - return self - else: - return AngularAcceleration(value = target_value, unit = target_unit) diff --git a/gearpy/units/angular_position.py b/gearpy/units/angular_position.py deleted file mode 100644 index c193c5d..0000000 --- a/gearpy/units/angular_position.py +++ /dev/null @@ -1,140 +0,0 @@ -from math import pi, fabs -from .settings import COMPARISON_TOLERANCE -from typing import Union -from .unit_base import UnitBase - - -class AngularPosition(UnitBase): - - __UNITS = {'rad': 1, - 'deg': pi/180, - 'arcmin': pi/180/60, - 'arcsec': pi/180/60/60} - - def __init__(self, value: Union[float, int], unit: str): - super().__init__(value = value, unit = unit) - - if unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - self.__value = value - self.__unit = unit - - def __repr__(self) -> str: - return f'{self.__value} {self.__unit}' - - def __add__(self, other: 'AngularPosition') -> 'AngularPosition': - super().__add__(other = other) - - return AngularPosition(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - - def __sub__(self, other: 'AngularPosition') -> 'AngularPosition': - super().__sub__(other = other) - - return AngularPosition(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - - def __mul__(self, other: Union[float, int]) -> 'AngularPosition': - super().__mul__(other = other) - - if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply an {self.__class__.__name__} by a ' - f'{other.__class__.__name__}.') - - return AngularPosition(value = self.__value*other, unit = self.__unit) - - def __rmul__(self, other: Union[float, int]) -> 'AngularPosition': - super().__rmul__(other = other) - - if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an ' - f'{self.__class__.__name__}.') - - return AngularPosition(value = self.__value*other, unit = self.__unit) - - def __truediv__(self, other: Union['AngularPosition', float, int]) -> Union['AngularPosition', float]: - super().__truediv__(other = other) - - if not isinstance(other, AngularPosition) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' - f'{other.__class__.__name__}.') - - if isinstance(other, AngularPosition): - return self.__value/other.to(self.__unit).value - else: - return AngularPosition(value = self.__value/other, unit = self.__unit) - - def __eq__(self, other: 'AngularPosition') -> bool: - super().__eq__(other = other) - - if self.__unit == other.unit: - return self.__value == other.value - else: - return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE - - def __ne__(self, other: 'AngularPosition') -> bool: - super().__ne__(other = other) - - if self.__unit == other.unit: - return self.__value != other.value - else: - return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE - - def __gt__(self, other: 'AngularPosition') -> bool: - super().__gt__(other = other) - - if self.__unit == other.unit: - return self.__value > other.value - else: - return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE - - def __ge__(self, other: 'AngularPosition') -> bool: - super().__ge__(other = other) - - if self.__unit == other.unit: - return self.__value >= other.value - else: - return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE - - def __lt__(self, other: 'AngularPosition') -> bool: - super().__lt__(other = other) - - if self.__unit == other.unit: - return self.__value < other.value - else: - return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE - - def __le__(self, other: 'AngularPosition') -> bool: - super().__le__(other = other) - - if self.__unit == other.unit: - return self.__value <= other.value - else: - return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE - - @property - def value(self) -> Union[float, int]: - return self.__value - - @property - def unit(self) -> str: - return self.__unit - - def to(self, target_unit: str, inplace: bool = False) -> 'AngularPosition': - super().to(target_unit = target_unit, inplace = inplace) - - if target_unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - if target_unit != self.__unit: - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - else: - target_value = self.__value - - if inplace: - self.__value = target_value - self.__unit = target_unit - return self - else: - return AngularPosition(value = target_value, unit = target_unit) diff --git a/gearpy/units/angular_speed.py b/gearpy/units/angular_speed.py deleted file mode 100644 index 78f1bb2..0000000 --- a/gearpy/units/angular_speed.py +++ /dev/null @@ -1,152 +0,0 @@ -from .angular_position import AngularPosition -from math import pi, fabs -from .settings import COMPARISON_TOLERANCE -from .time import Time -from typing import Union -from .unit_base import UnitBase - - -class AngularSpeed(UnitBase): - - __UNITS = {'rad/s': 1, - 'rad/min': 1/60, - 'rad/h': 1/60/60, - 'deg/s': pi/180, - 'deg/min': pi/180/60, - 'deg/h': pi/180/60/60, - 'rps': 2*pi, - 'rpm': 2*pi/60, - 'rph': 2*pi/60/60} - - def __init__(self, value: Union[float, int], unit: str): - super().__init__(value = value, unit = unit) - - if unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - self.__value = value - self.__unit = unit - - def __repr__(self) -> str: - return f'{self.__value} {self.__unit}' - - def __add__(self, other: 'AngularSpeed') -> 'AngularSpeed': - super().__add__(other = other) - - return AngularSpeed(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - - def __sub__(self, other: 'AngularSpeed') -> 'AngularSpeed': - super().__sub__(other = other) - - return AngularSpeed(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - - def __mul__(self, other: Union[Time, float, int]) -> Union[AngularPosition, 'AngularSpeed']: - super().__mul__(other = other) - - if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {self.__class__.__name__} by a ' - f'{other.__class__.__name__}.') - - if isinstance(other, Time): - return AngularPosition(value = self.to('rad/s').value*other.to('sec').value, unit = 'rad') - else: - return AngularSpeed(value = self.__value*other, unit = self.__unit) - - def __rmul__(self, other: Union[Time, float, int]) -> Union[AngularPosition, 'AngularSpeed']: - super().__rmul__(other = other) - - if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a ' - f'{self.__class__.__name__}.') - - if isinstance(other, Time): - return AngularPosition(value = self.to('rad/s').value*other.to('sec').value, unit = 'rad') - else: - return AngularSpeed(value = self.__value*other, unit = self.__unit) - - def __truediv__(self, other: Union['AngularSpeed', float, int]) -> Union['AngularSpeed', float]: - super().__truediv__(other = other) - - if not isinstance(other, AngularSpeed) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') - - if isinstance(other, AngularSpeed): - return self.__value/other.to(self.__unit).value - else: - return AngularSpeed(value = self.__value/other, unit = self.__unit) - - def __eq__(self, other: 'AngularSpeed') -> bool: - super().__eq__(other = other) - - if self.__unit == other.unit: - return self.__value == other.value - else: - return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE - - def __ne__(self, other: 'AngularSpeed') -> bool: - super().__ne__(other = other) - - if self.__unit == other.unit: - return self.__value != other.value - else: - return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE - - def __gt__(self, other: 'AngularSpeed') -> bool: - super().__gt__(other = other) - - if self.__unit == other.unit: - return self.__value > other.value - else: - return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE - - def __ge__(self, other: 'AngularSpeed') -> bool: - super().__ge__(other = other) - - if self.__unit == other.unit: - return self.__value >= other.value - else: - return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE - - def __lt__(self, other: 'AngularSpeed') -> bool: - super().__lt__(other = other) - - if self.__unit == other.unit: - return self.__value < other.value - else: - return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE - - def __le__(self, other: 'AngularSpeed') -> bool: - super().__le__(other = other) - - if self.__unit == other.unit: - return self.__value <= other.value - else: - return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE - - @property - def value(self) -> Union[float, int]: - return self.__value - - @property - def unit(self) -> str: - return self.__unit - - def to(self, target_unit: str, inplace: bool = False) -> 'AngularSpeed': - super().to(target_unit = target_unit, inplace = inplace) - - if target_unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - if target_unit != self.__unit: - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - else: - target_value = self.__value - - if inplace: - self.__value = target_value - self.__unit = target_unit - return self - else: - return AngularSpeed(value = target_value, unit = target_unit) diff --git a/gearpy/units/concrete_units.py b/gearpy/units/concrete_units.py new file mode 100644 index 0000000..35863bb --- /dev/null +++ b/gearpy/units/concrete_units.py @@ -0,0 +1,913 @@ +from math import pi, fabs +from typing import Union +from .unit_base import UnitBase + + +COMPARISON_TOLERANCE = 1e-12 + + +class AngularPosition(UnitBase): + + __UNITS = {'rad': 1, + 'deg': pi/180, + 'arcmin': pi/180/60, + 'arcsec': pi/180/60/60} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + def __add__(self, other: 'AngularPosition') -> 'AngularPosition': + super().__add__(other = other) + + return AngularPosition(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + + def __sub__(self, other: 'AngularPosition') -> 'AngularPosition': + super().__sub__(other = other) + + return AngularPosition(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + + def __mul__(self, other: Union[float, int]) -> 'AngularPosition': + super().__mul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') + + return AngularPosition(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[float, int]) -> 'AngularPosition': + super().__rmul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an ' + f'{self.__class__.__name__}.') + + return AngularPosition(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['AngularPosition', float, int]) -> Union['AngularPosition', float]: + super().__truediv__(other = other) + + if not isinstance(other, AngularPosition) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') + + if isinstance(other, AngularPosition): + return self.__value/other.to(self.__unit).value + else: + return AngularPosition(value = self.__value/other, unit = self.__unit) + + def __eq__(self, other: 'AngularPosition') -> bool: + super().__eq__(other = other) + + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE + + def __ne__(self, other: 'AngularPosition') -> bool: + super().__ne__(other = other) + + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE + + def __gt__(self, other: 'AngularPosition') -> bool: + super().__gt__(other = other) + + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE + + def __ge__(self, other: 'AngularPosition') -> bool: + super().__ge__(other = other) + + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE + + def __lt__(self, other: 'AngularPosition') -> bool: + super().__lt__(other = other) + + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE + + def __le__(self, other: 'AngularPosition') -> bool: + super().__le__(other = other) + + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str, inplace: bool = False) -> 'AngularPosition': + super().to(target_unit = target_unit, inplace = inplace) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value + + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return AngularPosition(value = target_value, unit = target_unit) + + +class AngularSpeed(UnitBase): + + __UNITS = {'rad/s': 1, + 'rad/min': 1/60, + 'rad/h': 1/60/60, + 'deg/s': pi/180, + 'deg/min': pi/180/60, + 'deg/h': pi/180/60/60, + 'rps': 2*pi, + 'rpm': 2*pi/60, + 'rph': 2*pi/60/60} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + def __add__(self, other: 'AngularSpeed') -> 'AngularSpeed': + super().__add__(other = other) + + return AngularSpeed(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + + def __sub__(self, other: 'AngularSpeed') -> 'AngularSpeed': + super().__sub__(other = other) + + return AngularSpeed(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + + def __mul__(self, other: Union['Time', float, int]) -> Union['AngularPosition', 'AngularSpeed']: + super().__mul__(other = other) + + if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') + + if isinstance(other, Time): + return AngularPosition(value = self.to('rad/s').value*other.to('sec').value, unit = 'rad') + else: + return AngularSpeed(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union['Time', float, int]) -> Union['AngularPosition', 'AngularSpeed']: + super().__rmul__(other = other) + + if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a ' + f'{self.__class__.__name__}.') + + if isinstance(other, Time): + return AngularPosition(value = self.to('rad/s').value*other.to('sec').value, unit = 'rad') + else: + return AngularSpeed(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['AngularSpeed', float, int]) -> Union['AngularSpeed', float]: + super().__truediv__(other = other) + + if not isinstance(other, AngularSpeed) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') + + if isinstance(other, AngularSpeed): + return self.__value/other.to(self.__unit).value + else: + return AngularSpeed(value = self.__value/other, unit = self.__unit) + + def __eq__(self, other: 'AngularSpeed') -> bool: + super().__eq__(other = other) + + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE + + def __ne__(self, other: 'AngularSpeed') -> bool: + super().__ne__(other = other) + + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE + + def __gt__(self, other: 'AngularSpeed') -> bool: + super().__gt__(other = other) + + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE + + def __ge__(self, other: 'AngularSpeed') -> bool: + super().__ge__(other = other) + + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE + + def __lt__(self, other: 'AngularSpeed') -> bool: + super().__lt__(other = other) + + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE + + def __le__(self, other: 'AngularSpeed') -> bool: + super().__le__(other = other) + + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str, inplace: bool = False) -> 'AngularSpeed': + super().to(target_unit = target_unit, inplace = inplace) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value + + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return AngularSpeed(value = target_value, unit = target_unit) + + +class AngularAcceleration(UnitBase): + + __UNITS = {'rad/s^2': 1, + 'deg/s^2': pi/180} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + def __add__(self, other: 'AngularAcceleration') -> 'AngularAcceleration': + super().__add__(other = other) + + return AngularAcceleration(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + + def __sub__(self, other: 'AngularAcceleration') -> 'AngularAcceleration': + super().__sub__(other = other) + + return AngularAcceleration(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + + def __mul__(self, other: Union['Time', float, int]) -> Union['AngularAcceleration', 'AngularSpeed']: + super().__mul__(other = other) + + if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') + + if isinstance(other, Time): + return AngularSpeed(value = self.to('rad/s^2').value*other.to('sec').value, unit = 'rad/s') + else: + return AngularAcceleration(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union['Time', float, int]) -> Union['AngularAcceleration', 'AngularSpeed']: + super().__rmul__(other = other) + + if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an ' + f'{self.__class__.__name__}.') + + if isinstance(other, Time): + return AngularSpeed(value = self.to('rad/s^2').value*other.to('sec').value, unit = 'rad/s') + else: + return AngularAcceleration(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['AngularAcceleration', float, int]) -> Union['AngularAcceleration', float]: + super().__truediv__(other = other) + + if not isinstance(other, AngularAcceleration) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') + + if isinstance(other, AngularAcceleration): + return self.__value/other.to(self.__unit).value + else: + return AngularAcceleration(value = self.__value/other, unit = self.__unit) + + def __eq__(self, other: 'AngularAcceleration') -> bool: + super().__eq__(other = other) + + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE + + def __ne__(self, other: 'AngularAcceleration') -> bool: + super().__ne__(other = other) + + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE + + def __gt__(self, other: 'AngularAcceleration') -> bool: + super().__gt__(other = other) + + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE + + def __ge__(self, other: 'AngularAcceleration') -> bool: + super().__ge__(other = other) + + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE + + def __lt__(self, other: 'AngularAcceleration') -> bool: + super().__lt__(other = other) + + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE + + def __le__(self, other: 'AngularAcceleration') -> bool: + super().__le__(other = other) + + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str, inplace: bool = False) -> 'AngularAcceleration': + super().to(target_unit = target_unit, inplace = inplace) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value + + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return AngularAcceleration(value = target_value, unit = target_unit) + + +class InertiaMoment(UnitBase): + + __UNITS = {'kgm^2': 1, + 'gm^2': 1e-3, + 'gcm^2': 1e-7} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + if value <= 0: + raise ValueError("Parameter 'value' must be positive.") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + def __add__(self, other: 'InertiaMoment') -> 'InertiaMoment': + super().__add__(other = other) + + return InertiaMoment(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + + def __sub__(self, other: 'InertiaMoment') -> 'InertiaMoment': + super().__sub__(other = other) + + if self.__value - other.to(self.__unit).value <= 0: + raise ValueError('Cannot perform the subtraction because the result is not positive.') + + return InertiaMoment(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + + def __mul__(self, other: Union[float, int]) -> 'InertiaMoment': + super().__mul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') + + if other <= 0: + raise ValueError('Cannot perform a multiplication by a non-positive number.') + + return InertiaMoment(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[float, int]) -> 'InertiaMoment': + super().__rmul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an ' + f'{self.__class__.__name__}.') + + if other <= 0: + raise ValueError('Cannot perform a multiplication by a non-positive number.') + + return InertiaMoment(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['InertiaMoment', float, int]) -> Union['InertiaMoment', float]: + super().__truediv__(other = other) + + if not isinstance(other, InertiaMoment) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') + + if isinstance(other, InertiaMoment): + return self.__value/other.to(self.__unit).value + else: + return InertiaMoment(value = self.__value/other, unit = self.__unit) + + def __eq__(self, other: 'InertiaMoment') -> bool: + super().__eq__(other = other) + + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE + + def __ne__(self, other: 'InertiaMoment') -> bool: + super().__ne__(other = other) + + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE + + def __gt__(self, other: 'InertiaMoment') -> bool: + super().__gt__(other = other) + + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE + + def __ge__(self, other: 'InertiaMoment') -> bool: + super().__ge__(other = other) + + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE + + def __lt__(self, other: 'InertiaMoment') -> bool: + super().__lt__(other = other) + + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE + + def __le__(self, other: 'InertiaMoment') -> bool: + super().__le__(other = other) + + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str, inplace: bool = False) -> 'InertiaMoment': + super().to(target_unit = target_unit, inplace = inplace) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value + + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return InertiaMoment(value = target_value, unit = target_unit) + + +class Torque(UnitBase): + + __UNITS = {'Nm': 1, + 'mNm': 1e-3, + 'kNm': 1e3, + 'kgfm': 9.80665, + 'kgfcm': 9.80665e-2} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + def __add__(self, other: 'Torque') -> 'Torque': + super().__add__(other = other) + + return Torque(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + + def __sub__(self, other: 'Torque') -> 'Torque': + super().__sub__(other = other) + + return Torque(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + + def __mul__(self, other: Union[float, int]) -> 'Torque': + super().__mul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') + + return Torque(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[float, int]) -> 'Torque': + super().__rmul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a ' + f'{self.__class__.__name__}.') + + return Torque(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['InertiaMoment', 'Torque', float, int]) -> Union['AngularAcceleration', 'Torque', float]: + super().__truediv__(other = other) + + if not isinstance(other, Torque) and not isinstance(other, float) and not isinstance(other, int) \ + and not isinstance(other, InertiaMoment): + raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') + + if isinstance(other, Torque): + return self.__value/other.to(self.__unit).value + elif isinstance(other, InertiaMoment): + return AngularAcceleration(value = self.to('Nm').value/other.to('kgm^2').value, unit = 'rad/s^2') + else: + return Torque(value = self.__value/other, unit = self.__unit) + + def __eq__(self, other: 'Torque') -> bool: + super().__eq__(other = other) + + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE + + def __ne__(self, other: 'Torque') -> bool: + super().__ne__(other = other) + + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE + + def __gt__(self, other: 'Torque') -> bool: + super().__gt__(other = other) + + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE + + def __ge__(self, other: 'Torque') -> bool: + super().__ge__(other = other) + + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE + + def __lt__(self, other: 'Torque') -> bool: + super().__lt__(other = other) + + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE + + def __le__(self, other: 'Torque') -> bool: + super().__le__(other = other) + + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str, inplace: bool = False) -> 'Torque': + super().to(target_unit = target_unit, inplace = inplace) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value + + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return Torque(value = target_value, unit = target_unit) + + +class Time(UnitBase): + + __UNITS = {'sec': 1, + 'min': 60, + 'hour': 60*60} + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + self.__value = value + self.__unit = unit + + def __repr__(self) -> str: + return f'{self.__value} {self.__unit}' + + def __add__(self, other: 'Time') -> 'Time': + super().__add__(other = other) + + return Time(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + + def __sub__(self, other: 'Time') -> 'Time': + super().__sub__(other = other) + + return Time(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + + def __mul__(self, other: Union[float, int]) -> 'Time': + super().__mul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {self.__class__.__name__} by a ' + f'{other.__class__.__name__}.') + + return Time(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[float, int]) -> 'Time': + super().__rmul__(other = other) + + if not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a ' + f'{self.__class__.__name__}.') + + return Time(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: + super().__truediv__(other = other) + + if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): + raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') + + if isinstance(other, Time): + return self.__value/other.to(self.__unit).value + else: + return Time(value = self.__value/other, unit = self.__unit) + + def __eq__(self, other: 'Time') -> bool: + super().__eq__(other = other) + + if self.__unit == other.unit: + return self.__value == other.value + else: + return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE + + def __ne__(self, other: 'Time') -> bool: + super().__ne__(other = other) + + if self.__unit == other.unit: + return self.__value != other.value + else: + return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE + + def __gt__(self, other: 'Time') -> bool: + super().__gt__(other = other) + + if self.__unit == other.unit: + return self.__value > other.value + else: + return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE + + def __ge__(self, other: 'Time') -> bool: + super().__ge__(other = other) + + if self.__unit == other.unit: + return self.__value >= other.value + else: + return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE + + def __lt__(self, other: 'Time') -> bool: + super().__lt__(other = other) + + if self.__unit == other.unit: + return self.__value < other.value + else: + return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE + + def __le__(self, other: 'Time') -> bool: + super().__le__(other = other) + + if self.__unit == other.unit: + return self.__value <= other.value + else: + return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE + + @property + def value(self) -> Union[float, int]: + return self.__value + + @property + def unit(self) -> str: + return self.__unit + + def to(self, target_unit: str, inplace: bool = False) -> 'Time': + super().to(target_unit = target_unit, inplace = inplace) + + if target_unit not in self.__UNITS.keys(): + raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " + f"Available units are: {list(self.__UNITS.keys())}") + + if target_unit != self.__unit: + target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] + else: + target_value = self.__value + + if inplace: + self.__value = target_value + self.__unit = target_unit + return self + else: + return Time(value = target_value, unit = target_unit) + + +class TimeInterval(Time): + + def __init__(self, value: Union[float, int], unit: str): + super().__init__(value = value, unit = unit) + + if value <= 0: + raise ValueError("Parameter 'value' must be positive.") + + self.__value = value + self.__unit = unit + + def __add__(self, other: Union['Time', 'TimeInterval']) -> Union['Time', 'TimeInterval']: + super().__add__(other = other) + + if isinstance(other, TimeInterval): + return TimeInterval(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + else: + return Time(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + + def __sub__(self, other: Union['Time', 'TimeInterval']) -> Union['Time', 'TimeInterval']: + super().__sub__(other = other) + + if self.__value - other.to(self.__unit).value <= 0: + raise ValueError('Cannot perform the subtraction because the result is not positive.') + + if isinstance(other, TimeInterval): + return TimeInterval(value = self.__value - other.to(self.__unit).value, unit = self.__unit) + else: + return Time(value = self.__value + other.to(self.__unit).value, unit = self.__unit) + + def __mul__(self, other: Union[float, int]) -> 'TimeInterval': + super().__mul__(other = other) + + if other <= 0: + raise ValueError('Cannot perform a multiplication by a non-positive number.') + + return TimeInterval(value = self.__value*other, unit = self.__unit) + + def __rmul__(self, other: Union[float, int]) -> 'TimeInterval': + super().__rmul__(other = other) + + if other <= 0: + raise ValueError('Cannot perform a multiplication by a non-positive number.') + + return TimeInterval(value = self.__value*other, unit = self.__unit) + + def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: + super().__truediv__(other = other) + + if isinstance(other, Time): + return self.__value/other.to(self.__unit).value + else: + return TimeInterval(value = self.__value/other, unit = self.__unit) + + def to(self, target_unit: str, inplace: bool = False) -> 'TimeInterval': + converted = super().to(target_unit = target_unit, inplace = inplace) + + if inplace: + self.__value = converted.value + self.__unit = converted.unit + return self + else: + return TimeInterval(value = converted.value, unit = converted.unit) diff --git a/gearpy/units/inertia_moment.py b/gearpy/units/inertia_moment.py deleted file mode 100644 index 1eb7547..0000000 --- a/gearpy/units/inertia_moment.py +++ /dev/null @@ -1,151 +0,0 @@ -from math import fabs -from .settings import COMPARISON_TOLERANCE -from typing import Union -from .unit_base import UnitBase - - -class InertiaMoment(UnitBase): - - __UNITS = {'kgm^2': 1, - 'gm^2': 1e-3, - 'gcm^2': 1e-7} - - def __init__(self, value: Union[float, int], unit: str): - super().__init__(value = value, unit = unit) - - if unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - if value <= 0: - raise ValueError("Parameter 'value' must be positive.") - - self.__value = value - self.__unit = unit - - def __repr__(self) -> str: - return f'{self.__value} {self.__unit}' - - def __add__(self, other: 'InertiaMoment') -> 'InertiaMoment': - super().__add__(other = other) - - return InertiaMoment(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - - def __sub__(self, other: 'InertiaMoment') -> 'InertiaMoment': - super().__sub__(other = other) - - if self.__value - other.to(self.__unit).value <= 0: - raise ValueError('Cannot perform the subtraction because the result is not positive.') - - return InertiaMoment(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - - def __mul__(self, other: Union[float, int]) -> 'InertiaMoment': - super().__mul__(other = other) - - if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply an {self.__class__.__name__} by a ' - f'{other.__class__.__name__}.') - - if other <= 0: - raise ValueError('Cannot perform a multiplication by a non-positive number.') - - return InertiaMoment(value = self.__value*other, unit = self.__unit) - - def __rmul__(self, other: Union[float, int]) -> 'InertiaMoment': - super().__rmul__(other = other) - - if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by an ' - f'{self.__class__.__name__}.') - - if other <= 0: - raise ValueError('Cannot perform a multiplication by a non-positive number.') - - return InertiaMoment(value = self.__value*other, unit = self.__unit) - - def __truediv__(self, other: Union['InertiaMoment', float, int]) -> Union['InertiaMoment', float]: - super().__truediv__(other = other) - - if not isinstance(other, InertiaMoment) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to divide an {self.__class__.__name__} by a ' - f'{other.__class__.__name__}.') - - if isinstance(other, InertiaMoment): - return self.__value/other.to(self.__unit).value - else: - return InertiaMoment(value = self.__value/other, unit = self.__unit) - - def __eq__(self, other: 'InertiaMoment') -> bool: - super().__eq__(other = other) - - if self.__unit == other.unit: - return self.__value == other.value - else: - return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE - - def __ne__(self, other: 'InertiaMoment') -> bool: - super().__ne__(other = other) - - if self.__unit == other.unit: - return self.__value != other.value - else: - return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE - - def __gt__(self, other: 'InertiaMoment') -> bool: - super().__gt__(other = other) - - if self.__unit == other.unit: - return self.__value > other.value - else: - return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE - - def __ge__(self, other: 'InertiaMoment') -> bool: - super().__ge__(other = other) - - if self.__unit == other.unit: - return self.__value >= other.value - else: - return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE - - def __lt__(self, other: 'InertiaMoment') -> bool: - super().__lt__(other = other) - - if self.__unit == other.unit: - return self.__value < other.value - else: - return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE - - def __le__(self, other: 'InertiaMoment') -> bool: - super().__le__(other = other) - - if self.__unit == other.unit: - return self.__value <= other.value - else: - return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE - - @property - def value(self) -> Union[float, int]: - return self.__value - - @property - def unit(self) -> str: - return self.__unit - - def to(self, target_unit: str, inplace: bool = False) -> 'InertiaMoment': - super().to(target_unit = target_unit, inplace = inplace) - - if target_unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - if target_unit != self.__unit: - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - else: - target_value = self.__value - - if inplace: - self.__value = target_value - self.__unit = target_unit - return self - else: - return InertiaMoment(value = target_value, unit = target_unit) diff --git a/gearpy/units/settings.py b/gearpy/units/settings.py deleted file mode 100644 index b37738e..0000000 --- a/gearpy/units/settings.py +++ /dev/null @@ -1 +0,0 @@ -COMPARISON_TOLERANCE = 1e-12 diff --git a/gearpy/units/time.py b/gearpy/units/time.py deleted file mode 100644 index 15260f1..0000000 --- a/gearpy/units/time.py +++ /dev/null @@ -1,138 +0,0 @@ -from math import fabs -from .settings import COMPARISON_TOLERANCE -from typing import Union -from .unit_base import UnitBase - - -class Time(UnitBase): - - __UNITS = {'sec': 1, - 'min': 60, - 'hour': 60*60} - - def __init__(self, value: Union[float, int], unit: str): - super().__init__(value = value, unit = unit) - - if unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - self.__value = value - self.__unit = unit - - def __repr__(self) -> str: - return f'{self.__value} {self.__unit}' - - def __add__(self, other: 'Time') -> 'Time': - super().__add__(other = other) - - return Time(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - - def __sub__(self, other: 'Time') -> 'Time': - super().__sub__(other = other) - - return Time(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - - def __mul__(self, other: Union[float, int]) -> 'Time': - super().__mul__(other = other) - - if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {self.__class__.__name__} by a ' - f'{other.__class__.__name__}.') - - return Time(value = self.__value*other, unit = self.__unit) - - def __rmul__(self, other: Union[float, int]) -> 'Time': - super().__rmul__(other = other) - - if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a ' - f'{self.__class__.__name__}.') - - return Time(value = self.__value*other, unit = self.__unit) - - def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: - super().__truediv__(other = other) - - if not isinstance(other, Time) and not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') - - if isinstance(other, Time): - return self.__value/other.to(self.__unit).value - else: - return Time(value = self.__value/other, unit = self.__unit) - - def __eq__(self, other: 'Time') -> bool: - super().__eq__(other = other) - - if self.__unit == other.unit: - return self.__value == other.value - else: - return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE - - def __ne__(self, other: 'Time') -> bool: - super().__ne__(other = other) - - if self.__unit == other.unit: - return self.__value != other.value - else: - return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE - - def __gt__(self, other: 'Time') -> bool: - super().__gt__(other = other) - - if self.__unit == other.unit: - return self.__value > other.value - else: - return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE - - def __ge__(self, other: 'Time') -> bool: - super().__ge__(other = other) - - if self.__unit == other.unit: - return self.__value >= other.value - else: - return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE - - def __lt__(self, other: 'Time') -> bool: - super().__lt__(other = other) - - if self.__unit == other.unit: - return self.__value < other.value - else: - return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE - - def __le__(self, other: 'Time') -> bool: - super().__le__(other = other) - - if self.__unit == other.unit: - return self.__value <= other.value - else: - return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE - - @property - def value(self) -> Union[float, int]: - return self.__value - - @property - def unit(self) -> str: - return self.__unit - - def to(self, target_unit: str, inplace: bool = False) -> 'Time': - super().to(target_unit = target_unit, inplace = inplace) - - if target_unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - if target_unit != self.__unit: - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - else: - target_value = self.__value - - if inplace: - self.__value = target_value - self.__unit = target_unit - return self - else: - return Time(value = target_value, unit = target_unit) diff --git a/gearpy/units/time_interval.py b/gearpy/units/time_interval.py deleted file mode 100644 index 7c9271c..0000000 --- a/gearpy/units/time_interval.py +++ /dev/null @@ -1,67 +0,0 @@ -from .time import Time -from typing import Union - - -class TimeInterval(Time): - - def __init__(self, value: Union[float, int], unit: str): - super().__init__(value = value, unit = unit) - - if value <= 0: - raise ValueError("Parameter 'value' must be positive.") - - self.__value = value - self.__unit = unit - - def __add__(self, other: Union['TimeInterval', 'Time']) -> Union['TimeInterval', 'Time']: - super().__add__(other = other) - - if isinstance(other, TimeInterval): - return TimeInterval(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - else: - return Time(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - - def __sub__(self, other: Union['TimeInterval', 'Time']) -> Union['TimeInterval', 'Time']: - super().__sub__(other = other) - - if self.__value - other.to(self.__unit).value <= 0: - raise ValueError('Cannot perform the subtraction because the result is not positive.') - - if isinstance(other, TimeInterval): - return TimeInterval(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - else: - return Time(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - - def __mul__(self, other: Union[float, int]) -> 'TimeInterval': - super().__mul__(other = other) - - if other <= 0: - raise ValueError('Cannot perform a multiplication by a non-positive number.') - - return TimeInterval(value = self.__value*other, unit = self.__unit) - - def __rmul__(self, other: Union[float, int]) -> 'TimeInterval': - super().__rmul__(other = other) - - if other <= 0: - raise ValueError('Cannot perform a multiplication by a non-positive number.') - - return TimeInterval(value = self.__value*other, unit = self.__unit) - - def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: - super().__truediv__(other = other) - - if isinstance(other, Time): - return self.__value/other.to(self.__unit).value - else: - return TimeInterval(value = self.__value/other, unit = self.__unit) - - def to(self, target_unit: str, inplace: bool = False) -> 'TimeInterval': - converted = super().to(target_unit = target_unit, inplace = inplace) - - if inplace: - self.__value = converted.value - self.__unit = converted.unit - return self - else: - return TimeInterval(value = converted.value, unit = converted.unit) diff --git a/gearpy/units/torque.py b/gearpy/units/torque.py deleted file mode 100644 index da4c7e6..0000000 --- a/gearpy/units/torque.py +++ /dev/null @@ -1,145 +0,0 @@ -from .angular_acceleration import AngularAcceleration -from .inertia_moment import InertiaMoment -from math import fabs -from .settings import COMPARISON_TOLERANCE -from typing import Union -from .unit_base import UnitBase - - -class Torque(UnitBase): - - __UNITS = {'Nm': 1, - 'mNm': 1e-3, - 'kNm': 1e3, - 'kgfm': 9.80665, - 'kgfcm': 9.80665e-2} - - def __init__(self, value: Union[float, int], unit: str): - super().__init__(value = value, unit = unit) - - if unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - self.__value = value - self.__unit = unit - - def __repr__(self) -> str: - return f'{self.__value} {self.__unit}' - - def __add__(self, other: 'Torque') -> 'Torque': - super().__add__(other = other) - - return Torque(value = self.__value + other.to(self.__unit).value, unit = self.__unit) - - def __sub__(self, other: 'Torque') -> 'Torque': - super().__sub__(other = other) - - return Torque(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - - def __mul__(self, other: Union[float, int]) -> 'Torque': - super().__mul__(other = other) - - if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {self.__class__.__name__} by a ' - f'{other.__class__.__name__}.') - - return Torque(value = self.__value*other, unit = self.__unit) - - def __rmul__(self, other: Union[float, int]) -> 'Torque': - super().__rmul__(other = other) - - if not isinstance(other, float) and not isinstance(other, int): - raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a ' - f'{self.__class__.__name__}.') - - return Torque(value = self.__value*other, unit = self.__unit) - - def __truediv__(self, other: Union['Torque', 'InertiaMoment', float, int]) -> Union['Torque', 'AngularAcceleration', float]: - super().__truediv__(other = other) - - if not isinstance(other, Torque) and not isinstance(other, float) and not isinstance(other, int) \ - and not isinstance(other, InertiaMoment): - raise TypeError(f'It is not allowed to divide a {self.__class__.__name__} by a {other.__class__.__name__}.') - - if isinstance(other, Torque): - return self.__value/other.to(self.__unit).value - elif isinstance(other, InertiaMoment): - return AngularAcceleration(value = self.to('Nm').value/other.to('kgm^2').value, unit = 'rad/s^2') - else: - return Torque(value = self.__value/other, unit = self.__unit) - - def __eq__(self, other: 'Torque') -> bool: - super().__eq__(other = other) - - if self.__unit == other.unit: - return self.__value == other.value - else: - return fabs(self.__value - other.to(self.__unit).value) < COMPARISON_TOLERANCE - - def __ne__(self, other: 'Torque') -> bool: - super().__ne__(other = other) - - if self.__unit == other.unit: - return self.__value != other.value - else: - return fabs(self.__value - other.to(self.__unit).value) > COMPARISON_TOLERANCE - - def __gt__(self, other: 'Torque') -> bool: - super().__gt__(other = other) - - if self.__unit == other.unit: - return self.__value > other.value - else: - return self.__value - other.to(self.__unit).value > COMPARISON_TOLERANCE - - def __ge__(self, other: 'Torque') -> bool: - super().__ge__(other = other) - - if self.__unit == other.unit: - return self.__value >= other.value - else: - return self.__value - other.to(self.__unit).value >= -COMPARISON_TOLERANCE - - def __lt__(self, other: 'Torque') -> bool: - super().__lt__(other = other) - - if self.__unit == other.unit: - return self.__value < other.value - else: - return self.__value - other.to(self.__unit).value < -COMPARISON_TOLERANCE - - def __le__(self, other: 'Torque') -> bool: - super().__le__(other = other) - - if self.__unit == other.unit: - return self.__value <= other.value - else: - return self.__value - other.to(self.__unit).value <= COMPARISON_TOLERANCE - - @property - def value(self) -> Union[float, int]: - return self.__value - - @property - def unit(self) -> str: - return self.__unit - - def to(self, target_unit: str, inplace: bool = False) -> 'Torque': - super().to(target_unit = target_unit, inplace = inplace) - - if target_unit not in self.__UNITS.keys(): - raise KeyError(f"{self.__class__.__name__} unit '{target_unit}' not available. " - f"Available units are: {list(self.__UNITS.keys())}") - - if target_unit != self.__unit: - target_value = self.__value*self.__UNITS[self.__unit]/self.__UNITS[target_unit] - else: - target_value = self.__value - - if inplace: - self.__value = target_value - self.__unit = target_unit - return self - else: - return Torque(value = target_value, unit = target_unit) From 39f47fe9d4c2b07d857b631f71d047a685cb6b93 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sat, 14 Oct 2023 13:09:00 +0200 Subject: [PATCH 26/33] DEV: allow operation between UnitBase subclasses --- gearpy/units/unit_base.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gearpy/units/unit_base.py b/gearpy/units/unit_base.py index 8cdb032..f2169ec 100644 --- a/gearpy/units/unit_base.py +++ b/gearpy/units/unit_base.py @@ -19,12 +19,12 @@ def __repr__(self): ... @abstractmethod def __add__(self, other: 'UnitBase') -> None: - if not isinstance(other, self.__class__): + if not isinstance(other, self.__class__) and not issubclass(self.__class__, other.__class__): raise TypeError(f'It is not allowed to sum a {self.__class__.__name__} and a {other.__class__.__name__}.') @abstractmethod def __sub__(self, other: 'UnitBase') -> None: - if not isinstance(other, self.__class__): + if not isinstance(other, self.__class__) and not issubclass(self.__class__, other.__class__): raise TypeError(f'It is not allowed to subtract a {other.__class__.__name__} ' f'from a {self.__class__.__name__}.') @@ -48,32 +48,32 @@ def __truediv__(self, other: Union['UnitBase', float, int]) -> None: @abstractmethod def __eq__(self, other: 'UnitBase') -> None: - if not isinstance(other, self.__class__): + if not isinstance(other, self.__class__) and not issubclass(self.__class__, other.__class__): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @abstractmethod def __ne__(self, other: 'UnitBase') -> None: - if not isinstance(other, self.__class__): + if not isinstance(other, self.__class__) and not issubclass(self.__class__, other.__class__): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @abstractmethod def __gt__(self, other: 'UnitBase') -> None: - if not isinstance(other, self.__class__): + if not isinstance(other, self.__class__) and not issubclass(self.__class__, other.__class__): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @abstractmethod def __ge__(self, other: 'UnitBase') -> None: - if not isinstance(other, self.__class__): + if not isinstance(other, self.__class__) and not issubclass(self.__class__, other.__class__): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @abstractmethod def __lt__(self, other: 'UnitBase') -> None: - if not isinstance(other, self.__class__): + if not isinstance(other, self.__class__) and not issubclass(self.__class__, other.__class__): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @abstractmethod def __le__(self, other: 'UnitBase') -> None: - if not isinstance(other, self.__class__): + if not isinstance(other, self.__class__) and not issubclass(self.__class__, other.__class__): raise TypeError(f'Cannot compare {self.__class__.__name__} and {other.__class__.__name__}') @property From dc14d9dbb71171434c93050315e6fdf5d1efb5f8 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sat, 14 Oct 2023 13:09:57 +0200 Subject: [PATCH 27/33] DEV: allow mixed multiplication between Time and other UnitBase --- gearpy/units/concrete_units.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/gearpy/units/concrete_units.py b/gearpy/units/concrete_units.py index 35863bb..410e92d 100644 --- a/gearpy/units/concrete_units.py +++ b/gearpy/units/concrete_units.py @@ -743,23 +743,34 @@ def __sub__(self, other: 'Time') -> 'Time': return Time(value = self.__value - other.to(self.__unit).value, unit = self.__unit) - def __mul__(self, other: Union[float, int]) -> 'Time': + def __mul__(self, other: Union['AngularAcceleration', 'AngularSpeed', float, int]) -> Union['AngularPosition', 'AngularSpeed', 'Time']: super().__mul__(other = other) - if not isinstance(other, float) and not isinstance(other, int): + if not isinstance(other, AngularAcceleration) and not isinstance(other, AngularSpeed) \ + and not isinstance(other, float) and not isinstance(other, int): raise TypeError(f'It is not allowed to multiply a {self.__class__.__name__} by a ' f'{other.__class__.__name__}.') - return Time(value = self.__value*other, unit = self.__unit) + if isinstance(other, AngularAcceleration): + return AngularSpeed(value = self.to('sec').value*other.to('rad/s^2').value, unit = 'rad/s') + elif isinstance(other, AngularSpeed): + return AngularPosition(value = self.to('sec').value*other.to('rad/s').value, unit = 'rad') + else: + return Time(value = self.__value*other, unit = self.__unit) - def __rmul__(self, other: Union[float, int]) -> 'Time': + def __rmul__(self, other: Union['AngularAcceleration', 'AngularSpeed', float, int]) -> Union['AngularPosition', 'AngularSpeed', 'Time']: super().__rmul__(other = other) - if not isinstance(other, float) and not isinstance(other, int): + if not isinstance(other, AngularSpeed) and not isinstance(other, float) and not isinstance(other, int): raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a ' f'{self.__class__.__name__}.') - return Time(value = self.__value*other, unit = self.__unit) + if isinstance(other, AngularAcceleration): + return AngularSpeed(value = self.to('sec').value*other.to('rad/s^2').value, unit = 'rad/s') + elif isinstance(other, AngularSpeed): + return AngularPosition(value = self.to('sec').value*other.to('rad/s').value, unit = 'rad') + else: + return Time(value = self.__value*other, unit = self.__unit) def __truediv__(self, other: Union['Time', float, int]) -> Union['Time', float]: super().__truediv__(other = other) From cb039a519caea2e97469b5e84d85b0ae43884441 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sat, 14 Oct 2023 13:12:56 +0200 Subject: [PATCH 28/33] TST: add tests for UnitBase classes --- tests/conftest.py | 541 +++++++++--------- .../test_angular_acceleration/conftest.py | 113 ++++ .../test_angular_acceleration.py | 386 +++++++++++++ .../test_angular_position/conftest.py | 103 ++++ .../test_angular_position.py | 374 ++++++++++++ .../test_units/test_angular_speed/conftest.py | 112 ++++ .../test_angular_speed/test_angular_speed.py | 386 +++++++++++++ .../test_inertia_moment/conftest.py | 104 ++++ .../test_inertia_moment.py | 399 +++++++++++++ tests/test_units/test_time/conftest.py | 105 ++++ tests/test_units/test_time/test_time.py | 398 +++++++++++++ .../test_units/test_time_interval/conftest.py | 115 ++++ .../test_time_interval/test_time_interval.py | 413 +++++++++++++ tests/test_units/test_torque/conftest.py | 104 ++++ tests/test_units/test_torque/test_torque.py | 382 +++++++++++++ tox.ini | 1 + 16 files changed, 3768 insertions(+), 268 deletions(-) create mode 100644 tests/test_units/test_angular_acceleration/conftest.py create mode 100644 tests/test_units/test_angular_acceleration/test_angular_acceleration.py create mode 100644 tests/test_units/test_angular_position/conftest.py create mode 100644 tests/test_units/test_angular_position/test_angular_position.py create mode 100644 tests/test_units/test_angular_speed/conftest.py create mode 100644 tests/test_units/test_angular_speed/test_angular_speed.py create mode 100644 tests/test_units/test_inertia_moment/conftest.py create mode 100644 tests/test_units/test_inertia_moment/test_inertia_moment.py create mode 100644 tests/test_units/test_time/conftest.py create mode 100644 tests/test_units/test_time/test_time.py create mode 100644 tests/test_units/test_time_interval/conftest.py create mode 100644 tests/test_units/test_time_interval/test_time_interval.py create mode 100644 tests/test_units/test_torque/conftest.py create mode 100644 tests/test_units/test_torque/test_torque.py diff --git a/tests/conftest.py b/tests/conftest.py index 82b6a66..b21275f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,269 +1,274 @@ -from gearpy.gear import GearBase, SpurGear -from gearpy.mechanical_object import RotatingObject -from gearpy.motor import MotorBase, DCMotor -from gearpy.transmission import Transmission -from gearpy.utils import add_fixed_joint, add_gear_mating -from hypothesis.strategies import composite, text, integers, floats, lists +# from gearpy.gear import GearBase, SpurGear +# from gearpy.mechanical_object import RotatingObject +# from gearpy.motor import MotorBase, DCMotor +# from gearpy.transmission import Transmission +from gearpy.units import AngularAcceleration, AngularPosition, AngularSpeed, InertiaMoment, Torque, Time, TimeInterval +# from gearpy.utils import add_fixed_joint, add_gear_mating +# from hypothesis.strategies import composite, text, integers, floats, lists import numpy as np -from pytest import fixture -from typing import Callable - - -types_to_check = ['string', 2, 2.2, True, (0, 1), [0, 1], {0, 1}, {0: 1}, None, np.array([0])] - - -basic_dc_motor = DCMotor(name = 'name', inertia = 1, no_load_speed = 1, maximum_torque = 1) -basic_spur_gear = SpurGear(name = 'gear', n_teeth = 10, inertia = 1) -basic_rotating_objects = [basic_dc_motor, basic_spur_gear] - - -@composite -def dc_motors(draw): - name = draw(text(min_size = 1)) - inertia = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) - no_load_speed = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) - maximum_torque = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) - - return DCMotor(name = name, inertia = inertia, no_load_speed = no_load_speed, maximum_torque = maximum_torque) - - -@composite -def spur_gears(draw): - name = draw(text(min_size = 1)) - n_teeth = draw(integers(min_value = 1)) - inertia = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) - - return SpurGear(name = name, n_teeth = n_teeth, inertia = inertia) - - -@composite -def transmissions(draw): - motor = draw(dc_motors()) - gears = draw(lists(elements = spur_gears(), min_size = 1)) - - add_fixed_joint(master = motor, slave = gears[0]) - - for i in range(0, len(gears) - 1): - if i%2 == 0: - add_gear_mating(master = gears[i], slave = gears[i + 1], efficiency = 1) - else: - add_fixed_joint(master = gears[i], slave = gears[i + 1]) - - return Transmission(motor = motor) - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) - and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -def rotating_object_angle_type_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) - and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -def rotating_object_speed_type_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) - and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -def rotating_object_acceleration_type_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) - and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -def rotating_object_torque_type_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) - and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -def rotating_object_driving_torque_type_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) - and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -def rotating_object_load_torque_type_error(request): - return request.param - - -dc_motor_init_type_error_1 = [{'name': type_to_check, 'inertia': 1, 'no_load_speed': 1, 'maximum_torque': 1} - for type_to_check in types_to_check if not isinstance(type_to_check, str)] - -dc_motor_init_type_error_2 = [{'name': 'motor', 'inertia': type_to_check, 'no_load_speed': 1, 'maximum_torque': 1} - for type_to_check in types_to_check if not isinstance(type_to_check, float) - and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] - -dc_motor_init_type_error_3 = [{'name': 'motor', 'inertia': 1, 'no_load_speed': type_to_check, 'maximum_torque': 1} - for type_to_check in types_to_check if not isinstance(type_to_check, float) - and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] - -dc_motor_init_type_error_4 = [{'name': 'motor', 'inertia': 1, 'no_load_speed': 1, 'maximum_torque': type_to_check} - for type_to_check in types_to_check if not isinstance(type_to_check, float) - and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] - -@fixture(params = [*dc_motor_init_type_error_1, - *dc_motor_init_type_error_2, - *dc_motor_init_type_error_3, - *dc_motor_init_type_error_4]) -def dc_motor_init_type_error(request): - return request.param - - -@fixture(params = [{'name': '', 'inertia': 1, 'no_load_speed': 1, 'maximum_torque': 1}, - {'name': 'motor', 'inertia': -1, 'no_load_speed': 1, 'maximum_torque': 1}, - {'name': 'motor', 'inertia': 1, 'no_load_speed': -1, 'maximum_torque': 1}, - {'name': 'motor', 'inertia': 1, 'no_load_speed': 1, 'maximum_torque': -1}]) -def dc_motor_init_value_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) -def dc_motor_drives_type_error(request): - return request.param - - -@fixture(params = [{'name': 'gear', 'n_teeth': type_to_check, 'inertia': 1} for type_to_check in types_to_check - if not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -def spur_gear_init_type_error(request): - return request.param - - -@fixture(params = [{'name': '', 'n_teeth': 1, 'inertia': 1}, - {'name': 'gear', 'n_teeth': -1, 'inertia': 1}, - {'name': 'gear', 'n_teeth': 1, 'inertia': -1}]) -def spur_gear_init_value_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) -def spur_gear_driven_by_type_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) -def spur_gear_drives_type_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float)]) -def spur_gear_master_gear_ratio_type_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) - and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -def spur_gear_master_gear_efficiency_type_error(request): - return request.param - - -@fixture(params = [-1, 2]) -def spur_gear_master_gear_efficiency_value_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Callable)]) -def spur_gear_external_torque_type_error(request): - return request.param - - -add_gear_mating_type_error_1 = [{'gear 1': type_to_check, 'gear 2': basic_spur_gear, 'efficiency': 0.5} - for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] - -add_gear_mating_type_error_2 = [{'gear 1': basic_spur_gear, 'gear 2': type_to_check, 'efficiency': 0.5} - for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] - -add_gear_mating_type_error_3 = [{'gear 1': basic_spur_gear, 'gear 2': basic_spur_gear, 'efficiency': type_to_check} - for type_to_check in types_to_check if not isinstance(type_to_check, float) - and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] - -@fixture(params = [*add_gear_mating_type_error_1, - *add_gear_mating_type_error_2, - *add_gear_mating_type_error_3]) -def add_gear_mating_type_error(request): - return request.param - - -@fixture(params = [-1, 2]) -def add_gear_mating_value_error(request): - return request.param - - -add_fixed_joint_type_error_1 = [{'master': type_to_check, 'slave': basic_spur_gear} for type_to_check in types_to_check - if not isinstance(type_to_check, GearBase) and not isinstance(type_to_check, MotorBase)] - -add_fixed_joint_type_error_2 = [{'master': basic_spur_gear, 'slave': type_to_check} - for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] - -@fixture(params = [*add_fixed_joint_type_error_1, - *add_fixed_joint_type_error_2]) -def add_fixed_joint_type_error(request): - return request.param - - -@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, MotorBase)]) -def transmission_init_type_error(request): - return request.param - - -motor_transmission_solver_init_type_error = DCMotor(name = 'name', inertia = 1, no_load_speed = 1, maximum_torque = 1) -gear_transmission_solver_init_type_error = SpurGear(name = 'gear', n_teeth = 10, inertia = 1) -add_fixed_joint(master = motor_transmission_solver_init_type_error, slave = gear_transmission_solver_init_type_error) -transmission_solver_init_type_error = Transmission(motor = motor_transmission_solver_init_type_error) - -class TransmissionFake(Transmission): - - def __init__(self, chain: list): - self.__chain = chain - - @property - def chain(self): - return self.__chain - - @chain.setter - def chain(self, chain): - self.__chain = chain - -solver_init_type_error_1 = [{'time_discretization': type_to_check, 'simulation_time': 1, - 'transmission': transmission_solver_init_type_error} for type_to_check in types_to_check - if not isinstance(type_to_check, float) and not isinstance(type_to_check, int) - and not isinstance(type_to_check, bool)] - -solver_init_type_error_2 = [{'time_discretization': 1, 'simulation_time': type_to_check, - 'transmission': transmission_solver_init_type_error} for type_to_check in types_to_check - if not isinstance(type_to_check, float) and not isinstance(type_to_check, int) - and not isinstance(type_to_check, bool)] - -solver_init_type_error_3 = [{'time_discretization': 1, 'simulation_time': 5, - 'transmission': type_to_check} for type_to_check in types_to_check - if not isinstance(type_to_check, Transmission)] - -solver_init_type_error_4 = [{'time_discretization': 1, 'simulation_time': 5, - 'transmission': TransmissionFake([type_to_check, basic_spur_gear])} - for type_to_check in types_to_check if not isinstance(type_to_check, MotorBase)] - -solver_init_type_error_5 = [{'time_discretization': 1, 'simulation_time': 5, - 'transmission': TransmissionFake([basic_dc_motor, type_to_check])} - for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)] - -@fixture(params = [*solver_init_type_error_1, - *solver_init_type_error_2, - *solver_init_type_error_3, - *solver_init_type_error_4, - *solver_init_type_error_5]) -def solver_init_type_error(request): - return request.param - -motor_transmission_solver_init_value_error = DCMotor(name = 'name', inertia = 1, - no_load_speed = 1, maximum_torque = 1) -gear_transmission_solver_init_value_error = SpurGear(name = 'gear', n_teeth = 10, inertia = 1) -add_fixed_joint(master = motor_transmission_solver_init_value_error, slave = gear_transmission_solver_init_value_error) -transmission_solver_init_value_error = Transmission(motor = motor_transmission_solver_init_value_error) - -@fixture(params = [{'time_discretization': -1, 'simulation_time': 5, 'transmission': transmission_solver_init_value_error}, - {'time_discretization': 1, 'simulation_time': -1, 'transmission': transmission_solver_init_value_error}, - {'time_discretization': 6, 'simulation_time': 5, 'transmission': transmission_solver_init_value_error}, - {'time_discretization': 1, 'simulation_time': 5, 'transmission': TransmissionFake([])}]) -def solver_init_value_error(request): - return request.param +# from pytest import fixture +# from typing import Callable +# +# +# basic_dc_motor = DCMotor(name = 'name', inertia_moment = 1, no_load_speed = 1, maximum_torque = 1) +# basic_spur_gear = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = 1) +# basic_rotating_objects = [basic_dc_motor, basic_spur_gear] +# + + +types_to_check = ['string', 2, 2.2, True, (0, 1), [0, 1], {0, 1}, {0: 1}, None, np.array([0]), + AngularPosition(1, 'rad'), AngularSpeed(1, 'rad/s'), AngularAcceleration(1, 'rad/s^2'), + InertiaMoment(1, 'kgm^2'), Torque(1, 'Nm'), Time(1, 'sec'), TimeInterval(1, 'sec')] + + +# +# @composite +# def dc_motors(draw): +# name = draw(text(min_size = 1)) +# inertia = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) +# no_load_speed = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) +# maximum_torque = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) +# +# return DCMotor(name = name, inertia_moment = inertia, no_load_speed = no_load_speed, maximum_torque = maximum_torque) +# +# +# @composite +# def spur_gears(draw): +# name = draw(text(min_size = 1)) +# n_teeth = draw(integers(min_value = 1)) +# inertia = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) +# +# return SpurGear(name = name, n_teeth = n_teeth, inertia_moment = inertia) +# +# +# @composite +# def transmissions(draw): +# motor = draw(dc_motors()) +# gears = draw(lists(elements = spur_gears(), min_size = 1)) +# +# add_fixed_joint(master = motor, slave = gears[0]) +# +# for i in range(0, len(gears) - 1): +# if i%2 == 0: +# add_gear_mating(master = gears[i], slave = gears[i + 1], efficiency = 1) +# else: +# add_fixed_joint(master = gears[i], slave = gears[i + 1]) +# +# return Transmission(motor = motor) +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) +# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) +# def rotating_object_angle_type_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) +# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) +# def rotating_object_speed_type_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) +# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) +# def rotating_object_acceleration_type_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) +# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) +# def rotating_object_torque_type_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) +# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) +# def rotating_object_driving_torque_type_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) +# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) +# def rotating_object_load_torque_type_error(request): +# return request.param +# +# +# dc_motor_init_type_error_1 = [{'name': type_to_check, 'inertia_moment': 1, 'no_load_speed': 1, 'maximum_torque': 1} +# for type_to_check in types_to_check if not isinstance(type_to_check, str)] +# +# dc_motor_init_type_error_2 = [{'name': 'motor', 'inertia_moment': type_to_check, 'no_load_speed': 1, 'maximum_torque': 1} +# for type_to_check in types_to_check if not isinstance(type_to_check, float) +# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] +# +# dc_motor_init_type_error_3 = [{'name': 'motor', 'inertia_moment': 1, 'no_load_speed': type_to_check, 'maximum_torque': 1} +# for type_to_check in types_to_check if not isinstance(type_to_check, float) +# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] +# +# dc_motor_init_type_error_4 = [{'name': 'motor', 'inertia_moment': 1, 'no_load_speed': 1, 'maximum_torque': type_to_check} +# for type_to_check in types_to_check if not isinstance(type_to_check, float) +# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] +# +# @fixture(params = [*dc_motor_init_type_error_1, +# *dc_motor_init_type_error_2, +# *dc_motor_init_type_error_3, +# *dc_motor_init_type_error_4]) +# def dc_motor_init_type_error(request): +# return request.param +# +# +# @fixture(params = [{'name': '', 'inertia_moment': 1, 'no_load_speed': 1, 'maximum_torque': 1}, +# {'name': 'motor', 'inertia_moment': -1, 'no_load_speed': 1, 'maximum_torque': 1}, +# {'name': 'motor', 'inertia_moment': 1, 'no_load_speed': -1, 'maximum_torque': 1}, +# {'name': 'motor', 'inertia_moment': 1, 'no_load_speed': 1, 'maximum_torque': -1}]) +# def dc_motor_init_value_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) +# def dc_motor_drives_type_error(request): +# return request.param +# +# +# @fixture(params = [{'name': 'gear', 'n_teeth': type_to_check, 'inertia_moment': 1} for type_to_check in types_to_check +# if not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) +# def spur_gear_init_type_error(request): +# return request.param +# +# +# @fixture(params = [{'name': '', 'n_teeth': 1, 'inertia_moment': 1}, +# {'name': 'gear', 'n_teeth': -1, 'inertia_moment': 1}, +# {'name': 'gear', 'n_teeth': 1, 'inertia_moment': -1}]) +# def spur_gear_init_value_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) +# def spur_gear_driven_by_type_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) +# def spur_gear_drives_type_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float)]) +# def spur_gear_master_gear_ratio_type_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) +# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) +# def spur_gear_master_gear_efficiency_type_error(request): +# return request.param +# +# +# @fixture(params = [-1, 2]) +# def spur_gear_master_gear_efficiency_value_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Callable)]) +# def spur_gear_external_torque_type_error(request): +# return request.param +# +# +# add_gear_mating_type_error_1 = [{'gear 1': type_to_check, 'gear 2': basic_spur_gear, 'efficiency': 0.5} +# for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] +# +# add_gear_mating_type_error_2 = [{'gear 1': basic_spur_gear, 'gear 2': type_to_check, 'efficiency': 0.5} +# for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] +# +# add_gear_mating_type_error_3 = [{'gear 1': basic_spur_gear, 'gear 2': basic_spur_gear, 'efficiency': type_to_check} +# for type_to_check in types_to_check if not isinstance(type_to_check, float) +# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] +# +# @fixture(params = [*add_gear_mating_type_error_1, +# *add_gear_mating_type_error_2, +# *add_gear_mating_type_error_3]) +# def add_gear_mating_type_error(request): +# return request.param +# +# +# @fixture(params = [-1, 2]) +# def add_gear_mating_value_error(request): +# return request.param +# +# +# add_fixed_joint_type_error_1 = [{'master': type_to_check, 'slave': basic_spur_gear} for type_to_check in types_to_check +# if not isinstance(type_to_check, GearBase) and not isinstance(type_to_check, MotorBase)] +# +# add_fixed_joint_type_error_2 = [{'master': basic_spur_gear, 'slave': type_to_check} +# for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] +# +# @fixture(params = [*add_fixed_joint_type_error_1, +# *add_fixed_joint_type_error_2]) +# def add_fixed_joint_type_error(request): +# return request.param +# +# +# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, MotorBase)]) +# def transmission_init_type_error(request): +# return request.param +# +# +# motor_transmission_solver_init_type_error = DCMotor(name = 'name', inertia_moment = 1, no_load_speed = 1, maximum_torque = 1) +# gear_transmission_solver_init_type_error = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = 1) +# add_fixed_joint(master = motor_transmission_solver_init_type_error, slave = gear_transmission_solver_init_type_error) +# transmission_solver_init_type_error = Transmission(motor = motor_transmission_solver_init_type_error) +# +# class TransmissionFake(Transmission): +# +# def __init__(self, chain: list): +# self.__chain = chain +# +# @property +# def chain(self): +# return self.__chain +# +# @chain.setter +# def chain(self, chain): +# self.__chain = chain +# +# solver_init_type_error_1 = [{'time_discretization': type_to_check, 'simulation_time': 1, +# 'transmission': transmission_solver_init_type_error} for type_to_check in types_to_check +# if not isinstance(type_to_check, float) and not isinstance(type_to_check, int) +# and not isinstance(type_to_check, bool)] +# +# solver_init_type_error_2 = [{'time_discretization': 1, 'simulation_time': type_to_check, +# 'transmission': transmission_solver_init_type_error} for type_to_check in types_to_check +# if not isinstance(type_to_check, float) and not isinstance(type_to_check, int) +# and not isinstance(type_to_check, bool)] +# +# solver_init_type_error_3 = [{'time_discretization': 1, 'simulation_time': 5, +# 'transmission': type_to_check} for type_to_check in types_to_check +# if not isinstance(type_to_check, Transmission)] +# +# solver_init_type_error_4 = [{'time_discretization': 1, 'simulation_time': 5, +# 'transmission': TransmissionFake([type_to_check, basic_spur_gear])} +# for type_to_check in types_to_check if not isinstance(type_to_check, MotorBase)] +# +# solver_init_type_error_5 = [{'time_discretization': 1, 'simulation_time': 5, +# 'transmission': TransmissionFake([basic_dc_motor, type_to_check])} +# for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)] +# +# @fixture(params = [*solver_init_type_error_1, +# *solver_init_type_error_2, +# *solver_init_type_error_3, +# *solver_init_type_error_4, +# *solver_init_type_error_5]) +# def solver_init_type_error(request): +# return request.param +# +# motor_transmission_solver_init_value_error = DCMotor(name = 'name', inertia_moment = 1, +# no_load_speed = 1, maximum_torque = 1) +# gear_transmission_solver_init_value_error = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = 1) +# add_fixed_joint(master = motor_transmission_solver_init_value_error, slave = gear_transmission_solver_init_value_error) +# transmission_solver_init_value_error = Transmission(motor = motor_transmission_solver_init_value_error) +# +# @fixture(params = [{'time_discretization': -1, 'simulation_time': 5, 'transmission': transmission_solver_init_value_error}, +# {'time_discretization': 1, 'simulation_time': -1, 'transmission': transmission_solver_init_value_error}, +# {'time_discretization': 6, 'simulation_time': 5, 'transmission': transmission_solver_init_value_error}, +# {'time_discretization': 1, 'simulation_time': 5, 'transmission': TransmissionFake([])}]) +# def solver_init_value_error(request): +# return request.param diff --git a/tests/test_units/test_angular_acceleration/conftest.py b/tests/test_units/test_angular_acceleration/conftest.py new file mode 100644 index 0000000..3b96625 --- /dev/null +++ b/tests/test_units/test_angular_acceleration/conftest.py @@ -0,0 +1,113 @@ +from gearpy.units import AngularAcceleration, Time +from hypothesis.strategies import composite, floats, sampled_from +import numpy as np +from tests.conftest import types_to_check +from pytest import fixture + + +basic_angular_acceleration = AngularAcceleration(1, 'rad/s^2') + + +@composite +def angular_accelerations(draw): + value = draw(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) + unit = draw(sampled_from(elements = list(AngularAcceleration._AngularAcceleration__UNITS.keys()))) + + return AngularAcceleration(value = value, unit = unit) + +@composite +def times(draw): + value = draw(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) + unit = draw(sampled_from(elements = list(Time._Time__UNITS.keys()))) + + return Time(value = value, unit = unit) + + +angular_acceleration_init_type_error_1 = [{'value': type_to_check, 'unit': 'unit'} for type_to_check in types_to_check + if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int)] + +angular_acceleration_init_type_error_2 = [{'value': 1, 'unit': types_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, str)] + +@fixture(params = [*angular_acceleration_init_type_error_1, + *angular_acceleration_init_type_error_2]) +def angular_acceleration_init_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularAcceleration)]) +def angular_acceleration_add_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularAcceleration)]) +def angular_acceleration_sub_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, Time)]) +def angular_acceleration_mul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, np.ndarray) + and not isinstance(type_to_check, Time)]) +def angular_acceleration_rmul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, AngularAcceleration)]) +def angular_acceleration_truediv_type_error(request): + return request.param + + +@fixture(params = [0, 0.0, AngularAcceleration(0, 'rad/s^2')]) +def angular_acceleration_truediv_zero_division_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularAcceleration)]) +def angular_acceleration_eq_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularAcceleration)]) +def angular_acceleration_ne_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularAcceleration)]) +def angular_acceleration_gt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularAcceleration)]) +def angular_acceleration_ge_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularAcceleration)]) +def angular_acceleration_lt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularAcceleration)]) +def angular_acceleration_le_type_error(request): + return request.param + + +angular_acceleration_to_type_error_1 = [{'target_unit': type_to_check, 'inplace': True} + for type_to_check in types_to_check if not isinstance(type_to_check, str)] + +angular_acceleration_to_type_error_2 = [{'target_unit': 'target_unit', 'inplace': type_to_check} + for type_to_check in types_to_check if not isinstance(type_to_check, bool) + and not isinstance(type_to_check, int)] + +@fixture(params = [*angular_acceleration_to_type_error_1, + *angular_acceleration_to_type_error_2]) +def angular_acceleration_to_type_error(request): + return request.param \ No newline at end of file diff --git a/tests/test_units/test_angular_acceleration/test_angular_acceleration.py b/tests/test_units/test_angular_acceleration/test_angular_acceleration.py new file mode 100644 index 0000000..88c2005 --- /dev/null +++ b/tests/test_units/test_angular_acceleration/test_angular_acceleration.py @@ -0,0 +1,386 @@ +from gearpy.units import AngularAcceleration, AngularSpeed, Time +from hypothesis.strategies import floats, sampled_from, one_of, booleans +from hypothesis import given, settings +from tests.test_units.test_angular_acceleration.conftest import basic_angular_acceleration, angular_accelerations, times +from pytest import mark, raises + + +units_list = list(AngularAcceleration._AngularAcceleration__UNITS.keys()) + + +@mark.units +class TestAngularAccelerationInit: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + angular_acceleration = AngularAcceleration(value = value, unit = unit) + + assert angular_acceleration.value == value + assert angular_acceleration.unit == unit + + + @mark.error + def test_raises_type_error(self, angular_acceleration_init_type_error): + with raises(TypeError): + AngularAcceleration(**angular_acceleration_init_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + AngularAcceleration(value = 1, unit = fake_unit) + + +@mark.units +class TestAngularAccelerationRepr: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + angular_acceleration = AngularAcceleration(value = value, unit = unit) + + assert str(angular_acceleration) == f'{value} {unit}' + + + +@mark.units +class TestAngularAccelerationAdd: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + angular_acceleration_1 = AngularAcceleration(value = value_1, unit = unit_1) + angular_acceleration_2 = AngularAcceleration(value = value_2, unit = unit_2) + result = angular_acceleration_1 + angular_acceleration_2 + + assert isinstance(result, AngularAcceleration) + assert result.value == angular_acceleration_1.value + angular_acceleration_2.to(unit_1).value + assert result.unit == angular_acceleration_1.unit + + + @mark.error + def test_raises_type_error(self, angular_acceleration_add_type_error): + with raises(TypeError): + assert basic_angular_acceleration + angular_acceleration_add_type_error + + +@mark.units +class TestAngularAccelerationSub: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + angular_acceleration_1 = AngularAcceleration(value = value_1, unit = unit_1) + angular_acceleration_2 = AngularAcceleration(value = value_2, unit = unit_2) + result = angular_acceleration_1 - angular_acceleration_2 + + assert isinstance(result, AngularAcceleration) + assert result.value == angular_acceleration_1.value - angular_acceleration_2.to(unit_1).value + assert result.unit == angular_acceleration_1.unit + + + @mark.error + def test_raises_type_error(self, angular_acceleration_sub_type_error): + with raises(TypeError): + assert basic_angular_acceleration - angular_acceleration_sub_type_error + + +@mark.units +class TestAngularAccelerationMul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), + times())) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + angular_acceleration = AngularAcceleration(value = value, unit = unit) + result = angular_acceleration*multiplier + + if isinstance(multiplier, Time): + assert isinstance(result, AngularSpeed) + assert result.value == angular_acceleration.to('rad/s^2').value*multiplier.to('sec').value + assert result.unit == 'rad/s' + else: + assert isinstance(result, AngularAcceleration) + assert result.value == angular_acceleration.value*multiplier + assert result.unit == angular_acceleration.unit + + + @mark.error + def test_raises_type_error(self, angular_acceleration_mul_type_error): + with raises(TypeError): + assert basic_angular_acceleration*angular_acceleration_mul_type_error + + +@mark.units +class TestAngularAccelerationRmul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), + times())) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + angular_acceleration = AngularAcceleration(value = value, unit = unit) + result = multiplier*angular_acceleration + + if isinstance(multiplier, Time): + assert isinstance(result, AngularSpeed) + assert result.value == angular_acceleration.to('rad/s^2').value*multiplier.to('sec').value + assert result.unit == 'rad/s' + else: + assert isinstance(result, AngularAcceleration) + assert result.value == angular_acceleration.value*multiplier + assert result.unit == angular_acceleration.unit + + + @mark.error + def test_raises_type_error(self, angular_acceleration_rmul_type_error): + with raises(TypeError): + assert angular_acceleration_rmul_type_error*basic_angular_acceleration + + +@mark.units +class TestAngularAccelerationTruediv: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + divider = one_of(floats(allow_nan = False, allow_infinity = False), + angular_accelerations())) + @settings(max_examples = 100) + def test_method(self, value, unit, divider): + angular_acceleration = AngularAcceleration(value = value, unit = unit) + + if isinstance(divider, AngularAcceleration): + if abs(divider.value) >= 1e-300: + result = angular_acceleration/divider + assert isinstance(result, float) + assert result == angular_acceleration.value/divider.to(unit).value + else: + if divider != 0: + result = angular_acceleration/divider + assert isinstance(result, AngularAcceleration) + assert result.value == angular_acceleration.value/divider + assert result.unit == angular_acceleration.unit + + + @mark.error + def test_raises_type_error(self, angular_acceleration_truediv_type_error): + with raises(TypeError): + assert basic_angular_acceleration/angular_acceleration_truediv_type_error + + + @mark.error + def test_raises_zero_division_error(self, angular_acceleration_truediv_zero_division_error): + with raises(ZeroDivisionError): + assert basic_angular_acceleration/angular_acceleration_truediv_zero_division_error + + +@mark.units +class TestAngularAccelerationEq: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + angular_acceleration_1 = AngularAcceleration(value = value, unit = unit) + angular_acceleration_2 = AngularAcceleration(value = value, unit = unit) + + for target_unit in units_list: + assert angular_acceleration_1 == angular_acceleration_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_acceleration_eq_type_error): + with raises(TypeError): + assert basic_angular_acceleration == angular_acceleration_eq_type_error + + +@mark.units +class TestAngularAccelerationNe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + angular_acceleration_1 = AngularAcceleration(value = value, unit = unit) + angular_acceleration_2 = AngularAcceleration(value = value + gap, unit = unit) + + for target_unit in units_list: + assert angular_acceleration_1 != angular_acceleration_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_acceleration_ne_type_error): + with raises(TypeError): + assert basic_angular_acceleration != angular_acceleration_ne_type_error + + +@mark.units +class TestAngularAccelerationGt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + angular_acceleration_1 = AngularAcceleration(value = value + gap, unit = unit) + angular_acceleration_2 = AngularAcceleration(value = value, unit = unit) + + for target_unit in units_list: + assert angular_acceleration_1 > angular_acceleration_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_acceleration_gt_type_error): + with raises(TypeError): + assert basic_angular_acceleration > angular_acceleration_gt_type_error + + +@mark.units +class TestAngularAccelerationGe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + angular_acceleration_1 = AngularAcceleration(value = value + gap, unit = unit) + angular_acceleration_2 = AngularAcceleration(value = value, unit = unit) + + for target_unit in units_list: + assert angular_acceleration_1 >= angular_acceleration_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_acceleration_ge_type_error): + with raises(TypeError): + assert basic_angular_acceleration >= angular_acceleration_ge_type_error + + +@mark.units +class TestAngularAccelerationLt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + angular_acceleration_1 = AngularAcceleration(value = value, unit = unit) + angular_acceleration_2 = AngularAcceleration(value = value + gap, unit = unit) + + for target_unit in units_list: + assert angular_acceleration_1 < angular_acceleration_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_acceleration_lt_type_error): + with raises(TypeError): + assert basic_angular_acceleration < angular_acceleration_lt_type_error + + +@mark.units +class TestAngularAccelerationLe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + angular_acceleration_1 = AngularAcceleration(value = value, unit = unit) + angular_acceleration_2 = AngularAcceleration(value = value + gap, unit = unit) + + for target_unit in units_list: + assert angular_acceleration_1 <= angular_acceleration_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_acceleration_le_type_error): + with raises(TypeError): + assert basic_angular_acceleration <= angular_acceleration_le_type_error + + +@mark.units +class TestAngularAccelerationTo: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + inplace = booleans()) + @settings(max_examples = 100) + def test_method(self, value, unit, inplace): + if value != 0: + angular_acceleration = AngularAcceleration(value = value, unit = unit) + + for target_unit in units_list: + converted_acceleration = angular_acceleration.to(target_unit = target_unit, inplace = inplace) + + assert converted_acceleration.unit == target_unit + if target_unit != unit: + assert converted_acceleration.value != value + assert converted_acceleration.unit != unit + + if inplace: + assert converted_acceleration.value == angular_acceleration.value + assert converted_acceleration.unit == angular_acceleration.unit + else: + assert converted_acceleration.value != angular_acceleration.value + assert converted_acceleration.unit != angular_acceleration.unit + else: + assert converted_acceleration == angular_acceleration + + + @mark.error + def test_raises_type_error(self, angular_acceleration_to_type_error): + with raises(TypeError): + basic_angular_acceleration.to(**angular_acceleration_to_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + basic_angular_acceleration.to(fake_unit) diff --git a/tests/test_units/test_angular_position/conftest.py b/tests/test_units/test_angular_position/conftest.py new file mode 100644 index 0000000..7756dba --- /dev/null +++ b/tests/test_units/test_angular_position/conftest.py @@ -0,0 +1,103 @@ +from gearpy.units import AngularPosition +from hypothesis.strategies import composite, floats, sampled_from +import numpy as np +from tests.conftest import types_to_check +from pytest import fixture + + +basic_angular_position = AngularPosition(1, 'rad') + + +@composite +def angular_positions(draw): + value = draw(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) + unit = draw(sampled_from(elements = list(AngularPosition._AngularPosition__UNITS.keys()))) + + return AngularPosition(value = value, unit = unit) + + +angular_position_init_type_error_1 = [{'value': type_to_check, 'unit': 'unit'} for type_to_check in types_to_check + if not isinstance(type_to_check, float) and not isinstance(type_to_check, int)] + +angular_position_init_type_error_2 = [{'value': 1, 'unit': types_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, str)] + +@fixture(params = [*angular_position_init_type_error_1, + *angular_position_init_type_error_2]) +def angular_position_init_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularPosition)]) +def angular_position_add_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularPosition)]) +def angular_position_sub_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, float) and not isinstance(type_to_check, int)]) +def angular_position_mul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, np.ndarray)]) +def angular_position_rmul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, AngularPosition)]) +def angular_position_truediv_type_error(request): + return request.param + + +@fixture(params = [0, 0.0, AngularPosition(0, 'rad')]) +def angular_position_truediv_zero_division_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularPosition)]) +def angular_position_eq_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularPosition)]) +def angular_position_ne_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularPosition)]) +def angular_position_gt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularPosition)]) +def angular_position_ge_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularPosition)]) +def angular_position_lt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularPosition)]) +def angular_position_le_type_error(request): + return request.param + + +angular_position_to_type_error_1 = [{'target_unit': type_to_check, 'inplace': True} for type_to_check in types_to_check + if not isinstance(type_to_check, str)] + +angular_position_to_type_error_2 = [{'target_unit': 'target_unit', 'inplace': type_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, bool) and not isinstance(type_to_check, int)] + +@fixture(params = [*angular_position_to_type_error_1, + *angular_position_to_type_error_2]) +def angular_position_to_type_error(request): + return request.param diff --git a/tests/test_units/test_angular_position/test_angular_position.py b/tests/test_units/test_angular_position/test_angular_position.py new file mode 100644 index 0000000..d3f038d --- /dev/null +++ b/tests/test_units/test_angular_position/test_angular_position.py @@ -0,0 +1,374 @@ +from gearpy.units import AngularPosition +from hypothesis.strategies import floats, sampled_from, one_of, booleans +from hypothesis import given, settings +from tests.test_units.test_angular_position.conftest import basic_angular_position, angular_positions +from pytest import mark, raises + + +units_list = list(AngularPosition._AngularPosition__UNITS.keys()) + + +@mark.units +class TestAngularPositionInit: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + angular_position = AngularPosition(value = value, unit = unit) + + assert angular_position.value == value + assert angular_position.unit == unit + + + @mark.error + def test_raises_type_error(self, angular_position_init_type_error): + with raises(TypeError): + AngularPosition(**angular_position_init_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + AngularPosition(value = 1, unit = fake_unit) + + +@mark.units +class TestAngularPositionRepr: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + angular_position = AngularPosition(value = value, unit = unit) + + assert str(angular_position) == f'{value} {unit}' + + + +@mark.units +class TestAngularPositionAdd: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + angular_position_1 = AngularPosition(value = value_1, unit = unit_1) + angular_position_2 = AngularPosition(value = value_2, unit = unit_2) + result = angular_position_1 + angular_position_2 + + assert isinstance(result, AngularPosition) + assert result.value == angular_position_1.value + angular_position_2.to(unit_1).value + assert result.unit == angular_position_1.unit + + + @mark.error + def test_raises_type_error(self, angular_position_add_type_error): + with raises(TypeError): + assert basic_angular_position + angular_position_add_type_error + + +@mark.units +class TestAngularPositionSub: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + angular_position_1 = AngularPosition(value = value_1, unit = unit_1) + angular_position_2 = AngularPosition(value = value_2, unit = unit_2) + result = angular_position_1 - angular_position_2 + + assert isinstance(result, AngularPosition) + assert result.value == angular_position_1.value - angular_position_2.to(unit_1).value + assert result.unit == angular_position_1.unit + + + @mark.error + def test_raises_type_error(self, angular_position_sub_type_error): + with raises(TypeError): + assert basic_angular_position - angular_position_sub_type_error + + +@mark.units +class TestAngularPositionMul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + multiplier = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + angular_position = AngularPosition(value = value, unit = unit) + result = angular_position*multiplier + + assert isinstance(result, AngularPosition) + assert result.value == angular_position.value*multiplier + assert result.unit == angular_position.unit + + + @mark.error + def test_raises_type_error(self, angular_position_mul_type_error): + with raises(TypeError): + assert basic_angular_position*angular_position_mul_type_error + + +@mark.units +class TestAngularPositionRmul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + multiplier = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + angular_position = AngularPosition(value = value, unit = unit) + result = multiplier*angular_position + + assert isinstance(result, AngularPosition) + assert result.value == angular_position.value*multiplier + assert result.unit == angular_position.unit + + + @mark.error + def test_raises_type_error(self, angular_position_rmul_type_error): + with raises(TypeError): + assert angular_position_rmul_type_error*basic_angular_position + + +@mark.units +class TestAngularPositionTruediv: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + divider = one_of(floats(allow_nan = False, allow_infinity = False), + angular_positions())) + @settings(max_examples = 100) + def test_method(self, value, unit, divider): + angular_position = AngularPosition(value = value, unit = unit) + + if isinstance(divider, AngularPosition): + if abs(divider.value) >= 1e-300: + result = angular_position/divider + assert isinstance(result, float) + assert result == angular_position.value/divider.to(unit).value + else: + if divider != 0: + result = angular_position/divider + assert isinstance(result, AngularPosition) + assert result.value == angular_position.value/divider + assert result.unit == angular_position.unit + + + @mark.error + def test_raises_type_error(self, angular_position_truediv_type_error): + with raises(TypeError): + assert basic_angular_position/angular_position_truediv_type_error + + + @mark.error + def test_raises_zero_division_error(self, angular_position_truediv_zero_division_error): + with raises(ZeroDivisionError): + assert basic_angular_position/angular_position_truediv_zero_division_error + + +@mark.units +class TestAngularPositionEq: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + angular_position_1 = AngularPosition(value = value, unit = unit) + angular_position_2 = AngularPosition(value = value, unit = unit) + + for target_unit in units_list: + assert angular_position_1 == angular_position_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_position_eq_type_error): + with raises(TypeError): + assert basic_angular_position == angular_position_eq_type_error + + +@mark.units +class TestAngularPositionNe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + angular_position_1 = AngularPosition(value = value, unit = unit) + angular_position_2 = AngularPosition(value = value + gap, unit = unit) + + for target_unit in units_list: + assert angular_position_1 != angular_position_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_position_ne_type_error): + with raises(TypeError): + assert basic_angular_position != angular_position_ne_type_error + + +@mark.units +class TestAngularPositionGt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + angular_position_1 = AngularPosition(value = value + gap, unit = unit) + angular_position_2 = AngularPosition(value = value, unit = unit) + + for target_unit in units_list: + assert angular_position_1 > angular_position_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_position_gt_type_error): + with raises(TypeError): + assert basic_angular_position > angular_position_gt_type_error + + +@mark.units +class TestAngularPositionGe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + angular_position_1 = AngularPosition(value = value + gap, unit = unit) + angular_position_2 = AngularPosition(value = value, unit = unit) + + for target_unit in units_list: + assert angular_position_1 >= angular_position_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_position_ge_type_error): + with raises(TypeError): + assert basic_angular_position >= angular_position_ge_type_error + + +@mark.units +class TestAngularPositionLt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + angular_position_1 = AngularPosition(value = value, unit = unit) + angular_position_2 = AngularPosition(value = value + gap, unit = unit) + + for target_unit in units_list: + assert angular_position_1 < angular_position_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_position_lt_type_error): + with raises(TypeError): + assert basic_angular_position < angular_position_lt_type_error + + +@mark.units +class TestAngularPositionLe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + angular_position_1 = AngularPosition(value = value, unit = unit) + angular_position_2 = AngularPosition(value = value + gap, unit = unit) + + for target_unit in units_list: + assert angular_position_1 <= angular_position_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_position_le_type_error): + with raises(TypeError): + assert basic_angular_position <= angular_position_le_type_error + + +@mark.units +class TestAngularPositionTo: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + inplace = booleans()) + @settings(max_examples = 100) + def test_method(self, value, unit, inplace): + if value != 0: + angular_position = AngularPosition(value = value, unit = unit) + + for target_unit in units_list: + converted_position = angular_position.to(target_unit = target_unit, inplace = inplace) + + assert converted_position.unit == target_unit + if target_unit != unit: + assert converted_position.value != value + assert converted_position.unit != unit + + if inplace: + assert converted_position.value == angular_position.value + assert converted_position.unit == angular_position.unit + else: + assert converted_position.value != angular_position.value + assert converted_position.unit != angular_position.unit + else: + assert converted_position == angular_position + + + @mark.error + def test_raises_type_error(self, angular_position_to_type_error): + with raises(TypeError): + basic_angular_position.to(**angular_position_to_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + basic_angular_position.to(fake_unit) diff --git a/tests/test_units/test_angular_speed/conftest.py b/tests/test_units/test_angular_speed/conftest.py new file mode 100644 index 0000000..19c9b75 --- /dev/null +++ b/tests/test_units/test_angular_speed/conftest.py @@ -0,0 +1,112 @@ +from gearpy.units import AngularSpeed, Time +from hypothesis.strategies import composite, floats, sampled_from +import numpy as np +from tests.conftest import types_to_check +from pytest import fixture + + +basic_angular_speed = AngularSpeed(1, 'rad/s') + + +@composite +def angular_speeds(draw): + value = draw(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) + unit = draw(sampled_from(elements = list(AngularSpeed._AngularSpeed__UNITS.keys()))) + + return AngularSpeed(value = value, unit = unit) + + +@composite +def times(draw): + value = draw(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) + unit = draw(sampled_from(elements = list(Time._Time__UNITS.keys()))) + + return Time(value = value, unit = unit) + + +angular_speed_init_type_error_1 = [{'value': type_to_check, 'unit': 'unit'} for type_to_check in types_to_check + if not isinstance(type_to_check, float) and not isinstance(type_to_check, int)] + +angular_speed_init_type_error_2 = [{'value': 1, 'unit': types_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, str)] + +@fixture(params = [*angular_speed_init_type_error_1, + *angular_speed_init_type_error_2]) +def angular_speed_init_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularSpeed)]) +def angular_speed_add_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularSpeed)]) +def angular_speed_sub_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, Time)]) +def angular_speed_mul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, np.ndarray) + and not isinstance(type_to_check, Time)]) +def angular_speed_rmul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, AngularSpeed)]) +def angular_speed_truediv_type_error(request): + return request.param + + +@fixture(params = [0, 0.0, AngularSpeed(0, 'rad/s')]) +def angular_speed_truediv_zero_division_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularSpeed)]) +def angular_speed_eq_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularSpeed)]) +def angular_speed_ne_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularSpeed)]) +def angular_speed_gt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularSpeed)]) +def angular_speed_ge_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularSpeed)]) +def angular_speed_lt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularSpeed)]) +def angular_speed_le_type_error(request): + return request.param + + +angular_speed_to_type_error_1 = [{'target_unit': type_to_check, 'inplace': True} for type_to_check in types_to_check + if not isinstance(type_to_check, str)] + +angular_speed_to_type_error_2 = [{'target_unit': 'target_unit', 'inplace': type_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, bool) and not isinstance(type_to_check, int)] + +@fixture(params = [*angular_speed_to_type_error_1, + *angular_speed_to_type_error_2]) +def angular_speed_to_type_error(request): + return request.param diff --git a/tests/test_units/test_angular_speed/test_angular_speed.py b/tests/test_units/test_angular_speed/test_angular_speed.py new file mode 100644 index 0000000..79e7f15 --- /dev/null +++ b/tests/test_units/test_angular_speed/test_angular_speed.py @@ -0,0 +1,386 @@ +from gearpy.units import AngularPosition, AngularSpeed, Time +from hypothesis.strategies import floats, sampled_from, one_of, booleans +from hypothesis import given, settings +from tests.test_units.test_angular_speed.conftest import basic_angular_speed, angular_speeds, times +from pytest import mark, raises + + +units_list = list(AngularSpeed._AngularSpeed__UNITS.keys()) + + +@mark.units +class TestAngularSpeedInit: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + angular_speed = AngularSpeed(value = value, unit = unit) + + assert angular_speed.value == value + assert angular_speed.unit == unit + + + @mark.error + def test_raises_type_error(self, angular_speed_init_type_error): + with raises(TypeError): + AngularSpeed(**angular_speed_init_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + AngularSpeed(value = 1, unit = fake_unit) + + +@mark.units +class TestAngularSpeedRepr: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + angular_speed = AngularSpeed(value = value, unit = unit) + + assert str(angular_speed) == f'{value} {unit}' + + + +@mark.units +class TestAngularSpeedAdd: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + angular_speed_1 = AngularSpeed(value = value_1, unit = unit_1) + angular_speed_2 = AngularSpeed(value = value_2, unit = unit_2) + result = angular_speed_1 + angular_speed_2 + + assert isinstance(result, AngularSpeed) + assert result.value == angular_speed_1.value + angular_speed_2.to(unit_1).value + assert result.unit == angular_speed_1.unit + + + @mark.error + def test_raises_type_error(self, angular_speed_add_type_error): + with raises(TypeError): + assert basic_angular_speed + angular_speed_add_type_error + + +@mark.units +class TestAngularSpeedSub: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + angular_speed_1 = AngularSpeed(value = value_1, unit = unit_1) + angular_speed_2 = AngularSpeed(value = value_2, unit = unit_2) + result = angular_speed_1 - angular_speed_2 + + assert isinstance(result, AngularSpeed) + assert result.value == angular_speed_1.value - angular_speed_2.to(unit_1).value + assert result.unit == angular_speed_1.unit + + + @mark.error + def test_raises_type_error(self, angular_speed_sub_type_error): + with raises(TypeError): + assert basic_angular_speed - angular_speed_sub_type_error + + +@mark.units +class TestAngularSpeedMul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), + times())) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + angular_speed = AngularSpeed(value = value, unit = unit) + result = angular_speed*multiplier + + if isinstance(multiplier, Time): + assert isinstance(result, AngularPosition) + assert result.value == angular_speed.to('rad/s').value*multiplier.to('sec').value + assert result.unit == 'rad' + else: + assert isinstance(result, AngularSpeed) + assert result.value == angular_speed.value*multiplier + assert result.unit == angular_speed.unit + + + @mark.error + def test_raises_type_error(self, angular_speed_mul_type_error): + with raises(TypeError): + assert basic_angular_speed*angular_speed_mul_type_error + + +@mark.units +class TestAngularSpeedRmul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), + times())) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + angular_speed = AngularSpeed(value = value, unit = unit) + result = multiplier*angular_speed + + if isinstance(multiplier, Time): + assert isinstance(result, AngularPosition) + assert result.value == angular_speed.to('rad/s').value*multiplier.to('sec').value + assert result.unit == 'rad' + else: + assert isinstance(result, AngularSpeed) + assert result.value == angular_speed.value*multiplier + assert result.unit == angular_speed.unit + + + @mark.error + def test_raises_type_error(self, angular_speed_rmul_type_error): + with raises(TypeError): + assert angular_speed_rmul_type_error*basic_angular_speed + + +@mark.units +class TestAngularSpeedTruediv: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + divider = one_of(floats(allow_nan = False, allow_infinity = False), + angular_speeds())) + @settings(max_examples = 100) + def test_method(self, value, unit, divider): + angular_speed = AngularSpeed(value = value, unit = unit) + + if isinstance(divider, AngularSpeed): + if abs(divider.value) >= 1e-300: + result = angular_speed/divider + assert isinstance(result, float) + assert result == angular_speed.value/divider.to(unit).value + else: + if divider != 0: + result = angular_speed/divider + assert isinstance(result, AngularSpeed) + assert result.value == angular_speed.value/divider + assert result.unit == angular_speed.unit + + + @mark.error + def test_raises_type_error(self, angular_speed_truediv_type_error): + with raises(TypeError): + assert basic_angular_speed/angular_speed_truediv_type_error + + + @mark.error + def test_raises_zero_division_error(self, angular_speed_truediv_zero_division_error): + with raises(ZeroDivisionError): + assert basic_angular_speed/angular_speed_truediv_zero_division_error + + +@mark.units +class TestAngularSpeedEq: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + angular_speed_1 = AngularSpeed(value = value, unit = unit) + angular_speed_2 = AngularSpeed(value = value, unit = unit) + + for target_unit in units_list: + assert angular_speed_1 == angular_speed_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_speed_eq_type_error): + with raises(TypeError): + assert basic_angular_speed == angular_speed_eq_type_error + + +@mark.units +class TestAngularSpeedNe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + angular_speed_1 = AngularSpeed(value = value, unit = unit) + angular_speed_2 = AngularSpeed(value = value + gap, unit = unit) + + for target_unit in units_list: + assert angular_speed_1 != angular_speed_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_speed_ne_type_error): + with raises(TypeError): + assert basic_angular_speed != angular_speed_ne_type_error + + +@mark.units +class TestAngularSpeedGt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + angular_speed_1 = AngularSpeed(value = value + gap, unit = unit) + angular_speed_2 = AngularSpeed(value = value, unit = unit) + + for target_unit in units_list: + assert angular_speed_1 > angular_speed_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_speed_gt_type_error): + with raises(TypeError): + assert basic_angular_speed > angular_speed_gt_type_error + + +@mark.units +class TestAngularSpeedGe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + angular_speed_1 = AngularSpeed(value = value + gap, unit = unit) + angular_speed_2 = AngularSpeed(value = value, unit = unit) + + for target_unit in units_list: + assert angular_speed_1 >= angular_speed_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_speed_ge_type_error): + with raises(TypeError): + assert basic_angular_speed >= angular_speed_ge_type_error + + +@mark.units +class TestAngularSpeedLt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + angular_speed_1 = AngularSpeed(value = value, unit = unit) + angular_speed_2 = AngularSpeed(value = value + gap, unit = unit) + + for target_unit in units_list: + assert angular_speed_1 < angular_speed_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_speed_lt_type_error): + with raises(TypeError): + assert basic_angular_speed < angular_speed_lt_type_error + + +@mark.units +class TestAngularSpeedLe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + angular_speed_1 = AngularSpeed(value = value, unit = unit) + angular_speed_2 = AngularSpeed(value = value + gap, unit = unit) + + for target_unit in units_list: + assert angular_speed_1 <= angular_speed_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, angular_speed_le_type_error): + with raises(TypeError): + assert basic_angular_speed <= angular_speed_le_type_error + + +@mark.units +class TestAngularSpeedTo: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + inplace = booleans()) + @settings(max_examples = 100) + def test_method(self, value, unit, inplace): + if value != 0: + angular_speed = AngularSpeed(value = value, unit = unit) + + for target_unit in units_list: + converted_speed = angular_speed.to(target_unit = target_unit, inplace = inplace) + + assert converted_speed.unit == target_unit + if target_unit != unit: + assert converted_speed.value != value + assert converted_speed.unit != unit + + if inplace: + assert converted_speed.value == angular_speed.value + assert converted_speed.unit == angular_speed.unit + else: + assert converted_speed.value != angular_speed.value + assert converted_speed.unit != angular_speed.unit + else: + assert converted_speed == angular_speed + + + @mark.error + def test_raises_type_error(self, angular_speed_to_type_error): + with raises(TypeError): + basic_angular_speed.to(**angular_speed_to_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + basic_angular_speed.to(fake_unit) diff --git a/tests/test_units/test_inertia_moment/conftest.py b/tests/test_units/test_inertia_moment/conftest.py new file mode 100644 index 0000000..9771836 --- /dev/null +++ b/tests/test_units/test_inertia_moment/conftest.py @@ -0,0 +1,104 @@ +from gearpy.units import InertiaMoment +from hypothesis.strategies import composite, floats, sampled_from +import numpy as np +from tests.conftest import types_to_check +from pytest import fixture + + +basic_inertia_moment = InertiaMoment(1, 'kgm^2') + + +@composite +def inertia_moments(draw): + value = draw(floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = True, max_value = 1000)) + unit = draw(sampled_from(elements = list(InertiaMoment._InertiaMoment__UNITS.keys()))) + + return InertiaMoment(value = value, unit = unit) + + +inertia_moment_init_type_error_1 = [{'value': type_to_check, 'unit': 'unit'} for type_to_check in types_to_check + if not isinstance(type_to_check, float) and not isinstance(type_to_check, int)] + +inertia_moment_init_type_error_2 = [{'value': 1, 'unit': types_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, str)] + +@fixture(params = [*inertia_moment_init_type_error_1, + *inertia_moment_init_type_error_2]) +def inertia_moment_init_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, InertiaMoment)]) +def inertia_moment_add_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, InertiaMoment)]) +def inertia_moment_sub_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, float) and not isinstance(type_to_check, int)]) +def inertia_moment_mul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, np.ndarray)]) +def inertia_moment_rmul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, InertiaMoment)]) +def inertia_moment_truediv_type_error(request): + return request.param + + +@fixture(params = [0, 0.0]) +def inertia_moment_truediv_zero_division_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, InertiaMoment)]) +def inertia_moment_eq_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, InertiaMoment)]) +def inertia_moment_ne_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, InertiaMoment)]) +def inertia_moment_gt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, InertiaMoment)]) +def inertia_moment_ge_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, InertiaMoment)]) +def inertia_moment_lt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, InertiaMoment)]) +def inertia_moment_le_type_error(request): + return request.param + + +inertia_moment_to_type_error_1 = [{'target_unit': type_to_check, 'inplace': True} + for type_to_check in types_to_check if not isinstance(type_to_check, str)] + +inertia_moment_to_type_error_2 = [{'target_unit': 'target_unit', 'inplace': type_to_check} + for type_to_check in types_to_check if not isinstance(type_to_check, bool) + and not isinstance(type_to_check, int)] + +@fixture(params = [*inertia_moment_to_type_error_1, + *inertia_moment_to_type_error_2]) +def inertia_moment_to_type_error(request): + return request.param \ No newline at end of file diff --git a/tests/test_units/test_inertia_moment/test_inertia_moment.py b/tests/test_units/test_inertia_moment/test_inertia_moment.py new file mode 100644 index 0000000..28f6653 --- /dev/null +++ b/tests/test_units/test_inertia_moment/test_inertia_moment.py @@ -0,0 +1,399 @@ +from gearpy.units import InertiaMoment +from hypothesis.strategies import floats, sampled_from, one_of, booleans +from hypothesis import given, settings +from tests.test_units.test_inertia_moment.conftest import basic_inertia_moment, inertia_moments +from pytest import mark, raises + + +units_list = list(InertiaMoment._InertiaMoment__UNITS.keys()) + + +@mark.units +class TestInertiaMomentInit: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = True), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + inertia_moment = InertiaMoment(value = value, unit = unit) + + assert inertia_moment.value == value + assert inertia_moment.unit == unit + + + @mark.error + def test_raises_type_error(self, inertia_moment_init_type_error): + with raises(TypeError): + InertiaMoment(**inertia_moment_init_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + InertiaMoment(value = 1, unit = fake_unit) + + + @mark.error + def test_raises_value_error(self): + with raises(ValueError): + InertiaMoment(value = -1, unit = 'kgm^2') + + +@mark.units +class TestInertiaMomentRepr: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = True), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + inertia_moment = InertiaMoment(value = value, unit = unit) + + assert str(inertia_moment) == f'{value} {unit}' + + + +@mark.units +class TestInertiaMomentAdd: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + inertia_moment_1 = InertiaMoment(value = value_1, unit = unit_1) + inertia_moment_2 = InertiaMoment(value = value_2, unit = unit_2) + result = inertia_moment_1 + inertia_moment_2 + + assert isinstance(result, InertiaMoment) + assert result.value == inertia_moment_1.value + inertia_moment_2.to(unit_1).value + assert result.unit == inertia_moment_1.unit + + + @mark.error + def test_raises_type_error(self, inertia_moment_add_type_error): + with raises(TypeError): + assert basic_inertia_moment + inertia_moment_add_type_error + + +@mark.units +class TestInertiaMomentSub: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + inertia_moment_1 = InertiaMoment(value = value_1, unit = unit_1) + inertia_moment_2 = InertiaMoment(value = value_2, unit = unit_2) + if inertia_moment_1 > inertia_moment_2: + result = inertia_moment_1 - inertia_moment_2 + + assert isinstance(result, InertiaMoment) + assert result.value == inertia_moment_1.value - inertia_moment_2.to(unit_1).value + assert result.unit == inertia_moment_1.unit + + + @mark.error + def test_raises_type_error(self, inertia_moment_sub_type_error): + with raises(TypeError): + assert basic_inertia_moment - inertia_moment_sub_type_error + + + @mark.error + def test_raises_value_error(self): + with raises(ValueError): + assert basic_inertia_moment - InertiaMoment(basic_inertia_moment.value + 1, basic_inertia_moment.unit) + + +@mark.units +class TestInertiaMomentMul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit = sampled_from(elements = units_list), + multiplier = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + inertia_moment = InertiaMoment(value = value, unit = unit) + result = inertia_moment*multiplier + + assert isinstance(result, InertiaMoment) + assert result.value == inertia_moment.value*multiplier + assert result.unit == inertia_moment.unit + + + @mark.error + def test_raises_type_error(self, inertia_moment_mul_type_error): + with raises(TypeError): + assert basic_inertia_moment*inertia_moment_mul_type_error + + + @mark.error + def test_raises_value_error(self): + with raises(ValueError): + assert basic_inertia_moment*(-1) + + +@mark.units +class TestInertiaMomentRmul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit = sampled_from(elements = units_list), + multiplier = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + inertia_moment = InertiaMoment(value = value, unit = unit) + result = multiplier*inertia_moment + + assert isinstance(result, InertiaMoment) + assert result.value == inertia_moment.value*multiplier + assert result.unit == inertia_moment.unit + + + @mark.error + def test_raises_type_error(self, inertia_moment_rmul_type_error): + with raises(TypeError): + assert inertia_moment_rmul_type_error*basic_inertia_moment + + + @mark.error + def test_raises_value_error(self): + with raises(ValueError): + assert -1*basic_inertia_moment + + +@mark.units +class TestInertiaMomentTruediv: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit = sampled_from(elements = units_list), + divider = one_of(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + inertia_moments())) + @settings(max_examples = 100) + def test_method(self, value, unit, divider): + inertia_moment = InertiaMoment(value = value, unit = unit) + + if isinstance(divider, InertiaMoment): + if abs(divider.value) >= 1e-300: + result = inertia_moment/divider + assert isinstance(result, float) + assert result == inertia_moment.value/divider.to(unit).value + else: + if divider != 0: + result = inertia_moment/divider + assert isinstance(result, InertiaMoment) + assert result.value == inertia_moment.value/divider + assert result.unit == inertia_moment.unit + + + @mark.error + def test_raises_type_error(self, inertia_moment_truediv_type_error): + with raises(TypeError): + assert basic_inertia_moment/inertia_moment_truediv_type_error + + + @mark.error + def test_raises_zero_division_error(self, inertia_moment_truediv_zero_division_error): + with raises(ZeroDivisionError): + assert basic_inertia_moment/inertia_moment_truediv_zero_division_error + + +@mark.units +class TestInertiaMomentEq: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + inertia_moment_1 = InertiaMoment(value = value, unit = unit) + inertia_moment_2 = InertiaMoment(value = value, unit = unit) + + for target_unit in units_list: + assert inertia_moment_1 == inertia_moment_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, inertia_moment_eq_type_error): + with raises(TypeError): + assert basic_inertia_moment == inertia_moment_eq_type_error + + +@mark.units +class TestInertiaMomentNe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + inertia_moment_1 = InertiaMoment(value = value, unit = unit) + inertia_moment_2 = InertiaMoment(value = value + gap, unit = unit) + + for target_unit in units_list: + assert inertia_moment_1 != inertia_moment_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, inertia_moment_ne_type_error): + with raises(TypeError): + assert basic_inertia_moment != inertia_moment_ne_type_error + + +@mark.units +class TestInertiaMomentGt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + inertia_moment_1 = InertiaMoment(value = value + gap, unit = unit) + inertia_moment_2 = InertiaMoment(value = value, unit = unit) + + for target_unit in units_list: + assert inertia_moment_1 > inertia_moment_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, inertia_moment_gt_type_error): + with raises(TypeError): + assert basic_inertia_moment > inertia_moment_gt_type_error + + +@mark.units +class TestInertiaMomentGe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + inertia_moment_1 = InertiaMoment(value = value + gap, unit = unit) + inertia_moment_2 = InertiaMoment(value = value, unit = unit) + + for target_unit in units_list: + assert inertia_moment_1 >= inertia_moment_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, inertia_moment_ge_type_error): + with raises(TypeError): + assert basic_inertia_moment >= inertia_moment_ge_type_error + + +@mark.units +class TestInertiaMomentLt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + inertia_moment_1 = InertiaMoment(value = value, unit = unit) + inertia_moment_2 = InertiaMoment(value = value + gap, unit = unit) + + for target_unit in units_list: + assert inertia_moment_1 < inertia_moment_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, inertia_moment_lt_type_error): + with raises(TypeError): + assert basic_inertia_moment < inertia_moment_lt_type_error + + +@mark.units +class TestInertiaMomentLe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + inertia_moment_1 = InertiaMoment(value = value, unit = unit) + inertia_moment_2 = InertiaMoment(value = value + gap, unit = unit) + + for target_unit in units_list: + assert inertia_moment_1 <= inertia_moment_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, inertia_moment_le_type_error): + with raises(TypeError): + assert basic_inertia_moment <= inertia_moment_le_type_error + + +@mark.units +class TestInertiaMomentTo: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + inplace = booleans()) + @settings(max_examples = 100) + def test_method(self, value, unit, inplace): + if value != 0: + inertia_moment = InertiaMoment(value = value, unit = unit) + + for target_unit in units_list: + converted_inertia = inertia_moment.to(target_unit = target_unit, inplace = inplace) + + assert converted_inertia.unit == target_unit + if target_unit != unit: + assert converted_inertia.value != value + assert converted_inertia.unit != unit + + if inplace: + assert converted_inertia.value == inertia_moment.value + assert converted_inertia.unit == inertia_moment.unit + else: + assert converted_inertia.value != inertia_moment.value + assert converted_inertia.unit != inertia_moment.unit + else: + assert converted_inertia == inertia_moment + + + @mark.error + def test_raises_type_error(self, inertia_moment_to_type_error): + with raises(TypeError): + basic_inertia_moment.to(**inertia_moment_to_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + basic_inertia_moment.to(fake_unit) diff --git a/tests/test_units/test_time/conftest.py b/tests/test_units/test_time/conftest.py new file mode 100644 index 0000000..a34af47 --- /dev/null +++ b/tests/test_units/test_time/conftest.py @@ -0,0 +1,105 @@ +from gearpy.units import AngularAcceleration, AngularSpeed, Time +from hypothesis.strategies import composite, floats, sampled_from +import numpy as np +from tests.conftest import types_to_check +from pytest import fixture + + +basic_time = Time(1, 'sec') + + +@composite +def times(draw): + value = draw(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) + unit = draw(sampled_from(elements = list(Time._Time__UNITS.keys()))) + + return Time(value = value, unit = unit) + + +time_init_type_error_1 = [{'value': type_to_check, 'unit': 'unit'} for type_to_check in types_to_check + if not isinstance(type_to_check, float) and not isinstance(type_to_check, int)] + +time_init_type_error_2 = [{'value': 1, 'unit': types_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, str)] + +@fixture(params = [*time_init_type_error_1, + *time_init_type_error_2]) +def time_init_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Time)]) +def time_add_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Time)]) +def time_sub_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, float) and not isinstance(type_to_check, int) + and not isinstance(type_to_check, AngularSpeed) and not isinstance(type_to_check, AngularAcceleration)]) +def time_mul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, np.ndarray) + and not isinstance(type_to_check, AngularSpeed) and not isinstance(type_to_check, AngularAcceleration)]) +def time_rmul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, Time)]) +def time_truediv_type_error(request): + return request.param + + +@fixture(params = [0, 0.0, Time(0, 'sec')]) +def time_truediv_zero_division_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Time)]) +def time_eq_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Time)]) +def time_ne_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Time)]) +def time_gt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Time)]) +def time_ge_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Time)]) +def time_lt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Time)]) +def time_le_type_error(request): + return request.param + + +time_to_type_error_1 = [{'target_unit': type_to_check, 'inplace': True} + for type_to_check in types_to_check if not isinstance(type_to_check, str)] + +time_to_type_error_2 = [{'target_unit': 'target_unit', 'inplace': type_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, bool) and not isinstance(type_to_check, int)] + +@fixture(params = [*time_to_type_error_1, + *time_to_type_error_2]) +def time_to_type_error(request): + return request.param \ No newline at end of file diff --git a/tests/test_units/test_time/test_time.py b/tests/test_units/test_time/test_time.py new file mode 100644 index 0000000..3ba9b0a --- /dev/null +++ b/tests/test_units/test_time/test_time.py @@ -0,0 +1,398 @@ +from gearpy.units import AngularAcceleration, AngularPosition, AngularSpeed, Time +from hypothesis.strategies import floats, sampled_from, one_of, booleans +from hypothesis import given, settings +from tests.test_units.test_angular_speed.conftest import angular_speeds +from tests.test_units.test_angular_acceleration.conftest import angular_accelerations +from tests.test_units.test_time.conftest import basic_time, times +from pytest import mark, raises + + +units_list = list(Time._Time__UNITS.keys()) + + +@mark.units +class TestTimeInit: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + time = Time(value = value, unit = unit) + + assert time.value == value + assert time.unit == unit + + + @mark.error + def test_raises_type_error(self, time_init_type_error): + with raises(TypeError): + Time(**time_init_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + Time(value = 1, unit = fake_unit) + + +@mark.units +class TestTimeRepr: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + time = Time(value = value, unit = unit) + + assert str(time) == f'{value} {unit}' + + + +@mark.units +class TestTimeAdd: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + time_1 = Time(value = value_1, unit = unit_1) + time_2 = Time(value = value_2, unit = unit_2) + result = time_1 + time_2 + + assert isinstance(result, Time) + assert result.value == time_1.value + time_2.to(unit_1).value + assert result.unit == time_1.unit + + + @mark.error + def test_raises_type_error(self, time_add_type_error): + with raises(TypeError): + assert basic_time + time_add_type_error + + +@mark.units +class TestTimeSub: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + time_1 = Time(value = value_1, unit = unit_1) + time_2 = Time(value = value_2, unit = unit_2) + result = time_1 - time_2 + + assert isinstance(result, Time) + assert result.value == time_1.value - time_2.to(unit_1).value + assert result.unit == time_1.unit + + + @mark.error + def test_raises_type_error(self, time_sub_type_error): + with raises(TypeError): + assert basic_time - time_sub_type_error + + +@mark.units +class TestTimeMul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), + angular_speeds(), + angular_accelerations())) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + time = Time(value = value, unit = unit) + result = time*multiplier + + if isinstance(multiplier, AngularAcceleration): + assert isinstance(result, AngularSpeed) + assert result.value == time.to('sec').value*multiplier.to('rad/s^2').value + assert result.unit == 'rad/s' + elif isinstance(multiplier, AngularSpeed): + assert isinstance(result, AngularPosition) + assert result.value == time.to('sec').value*multiplier.to('rad/s').value + assert result.unit == 'rad' + else: + assert isinstance(result, Time) + assert result.value == time.value*multiplier + assert result.unit == time.unit + + + @mark.error + def test_raises_type_error(self, time_mul_type_error): + with raises(TypeError): + assert basic_time*time_mul_type_error + + +@mark.units +class TestTimeRmul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), + angular_speeds(), + angular_accelerations())) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + time = Time(value = value, unit = unit) + result = multiplier*time + + if isinstance(multiplier, AngularAcceleration): + assert isinstance(result, AngularSpeed) + assert result.value == time.to('sec').value*multiplier.to('rad/s^2').value + assert result.unit == 'rad/s' + elif isinstance(multiplier, AngularSpeed): + assert isinstance(result, AngularPosition) + assert result.value == time.to('sec').value*multiplier.to('rad/s').value + assert result.unit == 'rad' + else: + assert isinstance(result, Time) + assert result.value == time.value*multiplier + assert result.unit == time.unit + + + @mark.error + def test_raises_type_error(self, time_rmul_type_error): + with raises(TypeError): + assert time_rmul_type_error*basic_time + + +@mark.units +class TestTimeTruediv: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + divider = one_of(floats(allow_nan = False, allow_infinity = False), + times())) + @settings(max_examples = 100) + def test_method(self, value, unit, divider): + time = Time(value = value, unit = unit) + + if isinstance(divider, Time): + if abs(divider.value) >= 1e-300: + result = time/divider + assert isinstance(result, float) + assert result == time.value/divider.to(unit).value + else: + if divider != 0: + result = time/divider + assert isinstance(result, Time) + assert result.value == time.value/divider + assert result.unit == time.unit + + + @mark.error + def test_raises_type_error(self, time_truediv_type_error): + with raises(TypeError): + assert basic_time/time_truediv_type_error + + + @mark.error + def test_raises_zero_division_error(self, time_truediv_zero_division_error): + with raises(ZeroDivisionError): + assert basic_time/time_truediv_zero_division_error + + +@mark.units +class TestTimeEq: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + time_1 = Time(value = value, unit = unit) + time_2 = Time(value = value, unit = unit) + + for target_unit in units_list: + assert time_1 == time_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_eq_type_error): + with raises(TypeError): + assert basic_time == time_eq_type_error + + +@mark.units +class TestTimeNe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + time_1 = Time(value = value, unit = unit) + time_2 = Time(value = value + gap, unit = unit) + + for target_unit in units_list: + assert time_1 != time_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_ne_type_error): + with raises(TypeError): + assert basic_time != time_ne_type_error + + +@mark.units +class TestTimeGt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + time_1 = Time(value = value + gap, unit = unit) + time_2 = Time(value = value, unit = unit) + + for target_unit in units_list: + assert time_1 > time_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_gt_type_error): + with raises(TypeError): + assert basic_time > time_gt_type_error + + +@mark.units +class TestTimeGe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + time_1 = Time(value = value + gap, unit = unit) + time_2 = Time(value = value, unit = unit) + + for target_unit in units_list: + assert time_1 >= time_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_ge_type_error): + with raises(TypeError): + assert basic_time >= time_ge_type_error + + +@mark.units +class TestTimeLt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + time_1 = Time(value = value, unit = unit) + time_2 = Time(value = value + gap, unit = unit) + + for target_unit in units_list: + assert time_1 < time_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_lt_type_error): + with raises(TypeError): + assert basic_time < time_lt_type_error + + +@mark.units +class TestTimeLe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + time_1 = Time(value = value, unit = unit) + time_2 = Time(value = value + gap, unit = unit) + + for target_unit in units_list: + assert time_1 <= time_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_le_type_error): + with raises(TypeError): + assert basic_time <= time_le_type_error + + +@mark.units +class TestTimeTo: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + inplace = booleans()) + @settings(max_examples = 100) + def test_method(self, value, unit, inplace): + if value != 0: + time = Time(value = value, unit = unit) + + for target_unit in units_list: + converted_time = time.to(target_unit = target_unit, inplace = inplace) + + assert converted_time.unit == target_unit + if target_unit != unit: + assert converted_time.value != value + assert converted_time.unit != unit + + if inplace: + assert converted_time.value == time.value + assert converted_time.unit == time.unit + else: + assert converted_time.value != time.value + assert converted_time.unit != time.unit + else: + assert converted_time == time + + + @mark.error + def test_raises_type_error(self, time_to_type_error): + with raises(TypeError): + basic_time.to(**time_to_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + basic_time.to(fake_unit) diff --git a/tests/test_units/test_time_interval/conftest.py b/tests/test_units/test_time_interval/conftest.py new file mode 100644 index 0000000..3a83c46 --- /dev/null +++ b/tests/test_units/test_time_interval/conftest.py @@ -0,0 +1,115 @@ +from gearpy.units import AngularAcceleration, AngularSpeed, Time, TimeInterval +from hypothesis.strategies import composite, floats, sampled_from +import numpy as np +from tests.conftest import types_to_check +from pytest import fixture + + +basic_time_interval = TimeInterval(1, 'sec') + + +@composite +def time_intervals(draw): + value = draw(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) + unit = draw(sampled_from(elements = list(TimeInterval._Time__UNITS.keys()))) + + return TimeInterval(value = value, unit = unit) + + +time_interval_init_type_error_1 = [{'value': type_to_check, 'unit': 'unit'} for type_to_check in types_to_check + if not isinstance(type_to_check, float) and not isinstance(type_to_check, int)] + +time_interval_init_type_error_2 = [{'value': 1, 'unit': types_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, str)] + +@fixture(params = [*time_interval_init_type_error_1, + *time_interval_init_type_error_2]) +def time_interval_init_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, Time) and not isinstance(type_to_check, TimeInterval)]) +def time_interval_add_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, Time) and not isinstance(type_to_check, TimeInterval)]) +def time_interval_sub_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, float) and not isinstance(type_to_check, int) + and not isinstance(type_to_check, AngularSpeed) and not isinstance(type_to_check, AngularAcceleration)]) +def time_interval_mul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, np.ndarray) + and not isinstance(type_to_check, AngularSpeed) and not isinstance(type_to_check, AngularAcceleration)]) +def time_interval_rmul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, Time) + and not isinstance(type_to_check, TimeInterval)]) +def time_interval_truediv_type_error(request): + return request.param + + +@fixture(params = [0, 0.0]) +def time_interval_truediv_zero_division_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, Time) and not isinstance(type_to_check, TimeInterval)]) +def time_interval_eq_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, Time) and not isinstance(type_to_check, TimeInterval)]) +def time_interval_ne_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, Time) and not isinstance(type_to_check, TimeInterval)]) +def time_interval_gt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, Time) and not isinstance(type_to_check, TimeInterval)]) +def time_interval_ge_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, Time) and not isinstance(type_to_check, TimeInterval)]) +def time_interval_lt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, Time) and not isinstance(type_to_check, TimeInterval)]) +def time_interval_le_type_error(request): + return request.param + + +time_interval_to_type_error_1 = [{'target_unit': type_to_check, 'inplace': True} + for type_to_check in types_to_check if not isinstance(type_to_check, str)] + +time_interval_to_type_error_2 = [{'target_unit': 'target_unit', 'inplace': type_to_check} + for type_to_check in types_to_check if not isinstance(type_to_check, bool) + and not isinstance(type_to_check, int)] + +@fixture(params = [*time_interval_to_type_error_1, + *time_interval_to_type_error_2]) +def time_interval_to_type_error(request): + return request.param \ No newline at end of file diff --git a/tests/test_units/test_time_interval/test_time_interval.py b/tests/test_units/test_time_interval/test_time_interval.py new file mode 100644 index 0000000..2fe3621 --- /dev/null +++ b/tests/test_units/test_time_interval/test_time_interval.py @@ -0,0 +1,413 @@ +from gearpy.units import Time, TimeInterval +from hypothesis.strategies import floats, sampled_from, one_of, booleans +from hypothesis import given, settings +from tests.test_units.test_time_interval.conftest import basic_time_interval, time_intervals +from pytest import mark, raises + + +units_list = list(TimeInterval._Time__UNITS.keys()) + + +@mark.units +class TestTimeIntervalInit: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + time_interval = TimeInterval(value = value, unit = unit) + + assert time_interval.value == value + assert time_interval.unit == unit + + + @mark.error + def test_raises_type_error(self, time_interval_init_type_error): + with raises(TypeError): + TimeInterval(**time_interval_init_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + TimeInterval(value = 1, unit = fake_unit) + + + @mark.error + def test_raises_value_error(self): + with raises(ValueError): + TimeInterval(value = -1, unit = 'sec') + + +@mark.units +class TestTimeIntervalRepr: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + time_interval = TimeInterval(value = value, unit = unit) + + assert str(time_interval) == f'{value} {unit}' + + + +@mark.units +class TestTimeIntervalAdd: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + time_interval_1 = TimeInterval(value = value_1, unit = unit_1) + time_interval_2 = TimeInterval(value = value_2, unit = unit_2) + time = Time(value = value_2, unit = unit_2) + result_1 = time_interval_1 + time_interval_2 + result_2 = time_interval_1 + time + + assert isinstance(result_1, TimeInterval) + assert result_1.value == time_interval_1.value + time_interval_2.to(unit_1).value + assert result_1.unit == time_interval_1.unit + assert isinstance(result_2, Time) + assert result_2.value == time_interval_1.value + time.to(unit_1).value + assert result_2.unit == time_interval_1.unit + + + @mark.error + def test_raises_type_error(self, time_interval_add_type_error): + with raises(TypeError): + assert basic_time_interval + time_interval_add_type_error + + +@mark.units +class TestTimeIntervalSub: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + time_interval_1 = TimeInterval(value = value_1, unit = unit_1) + time_interval_2 = TimeInterval(value = value_2, unit = unit_2) + time = Time(value = value_2, unit = unit_2) + + if time_interval_1 > time_interval_2: + result_1 = time_interval_1 - time_interval_2 + + assert isinstance(result_1, TimeInterval) + assert result_1.value == time_interval_1.value - time_interval_2.to(unit_1).value + assert result_1.unit == time_interval_1.unit + + if time_interval_1 > time: + result_2 = time_interval_1 - time + + assert isinstance(result_2, Time) + assert result_2.value == time_interval_1.value + time.to(unit_1).value + assert result_2.unit == time_interval_1.unit + + + @mark.error + def test_raises_type_error(self, time_interval_sub_type_error): + with raises(TypeError): + assert basic_time_interval - time_interval_sub_type_error + + + @mark.error + def test_raises_value_error(self): + with raises(ValueError): + assert basic_time_interval - TimeInterval(basic_time_interval.value + 1, basic_time_interval.unit) + + +@mark.units +class TestTimeIntervalMul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit = sampled_from(elements = units_list), + multiplier = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, max_value = 1000)) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + time_interval = TimeInterval(value = value, unit = unit) + result = time_interval*multiplier + + assert isinstance(result, TimeInterval) + assert result.value == time_interval.value*multiplier + assert result.unit == time_interval.unit + + + @mark.error + def test_raises_type_error(self, time_interval_mul_type_error): + with raises(TypeError): + assert basic_time_interval*time_interval_mul_type_error + + + @mark.error + def test_raises_value_error(self): + with raises(ValueError): + assert basic_time_interval*(-1) + + +@mark.units +class TestTimeIntervalRmul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit = sampled_from(elements = units_list), + multiplier = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, max_value = 1000)) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + time_interval = TimeInterval(value = value, unit = unit) + result = multiplier*time_interval + + assert isinstance(result, TimeInterval) + assert result.value == time_interval.value*multiplier + assert result.unit == time_interval.unit + + + @mark.error + def test_raises_type_error(self, time_interval_rmul_type_error): + with raises(TypeError): + assert time_interval_rmul_type_error*basic_time_interval + + + @mark.error + def test_raises_value_error(self): + with raises(ValueError): + assert -1*basic_time_interval + + +@mark.units +class TestTimeIntervalTruediv: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + unit = sampled_from(elements = units_list), + divider = one_of(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + time_intervals())) + @settings(max_examples = 100) + def test_method(self, value, unit, divider): + time_interval = TimeInterval(value = value, unit = unit) + + if isinstance(divider, TimeInterval): + if abs(divider.value) >= 1e-300: + result = time_interval/divider + assert isinstance(result, float) + assert result == time_interval.value/divider.to(unit).value + else: + if divider != 0: + result = time_interval/divider + assert isinstance(result, TimeInterval) + assert result.value == time_interval.value/divider + assert result.unit == time_interval.unit + + + @mark.error + def test_raises_type_error(self, time_interval_truediv_type_error): + with raises(TypeError): + assert basic_time_interval/time_interval_truediv_type_error + + + @mark.error + def test_raises_zero_division_error(self, time_interval_truediv_zero_division_error): + with raises(ZeroDivisionError): + assert basic_time_interval/time_interval_truediv_zero_division_error + + +@mark.units +class TestTimeIntervalEq: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + time_interval_1 = TimeInterval(value = value, unit = unit) + time_interval_2 = TimeInterval(value = value, unit = unit) + + for target_unit in units_list: + assert time_interval_1 == time_interval_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_interval_eq_type_error): + with raises(TypeError): + assert basic_time_interval == time_interval_eq_type_error + + +@mark.units +class TestTimeIntervalNe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + time_interval_1 = TimeInterval(value = value, unit = unit) + time_interval_2 = TimeInterval(value = value + gap, unit = unit) + + for target_unit in units_list: + assert time_interval_1 != time_interval_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_interval_ne_type_error): + with raises(TypeError): + assert basic_time_interval != time_interval_ne_type_error + + +@mark.units +class TestTimeIntervalGt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + time_interval_1 = TimeInterval(value = value + gap, unit = unit) + time_interval_2 = TimeInterval(value = value, unit = unit) + + for target_unit in units_list: + assert time_interval_1 > time_interval_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_interval_gt_type_error): + with raises(TypeError): + assert basic_time_interval > time_interval_gt_type_error + + +@mark.units +class TestTimeIntervalGe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + time_interval_1 = TimeInterval(value = value + gap, unit = unit) + time_interval_2 = TimeInterval(value = value, unit = unit) + + for target_unit in units_list: + assert time_interval_1 >= time_interval_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_interval_ge_type_error): + with raises(TypeError): + assert basic_time_interval >= time_interval_ge_type_error + + +@mark.units +class TestTimeIntervalLt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + time_interval_1 = TimeInterval(value = value, unit = unit) + time_interval_2 = TimeInterval(value = value + gap, unit = unit) + + for target_unit in units_list: + assert time_interval_1 < time_interval_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_interval_lt_type_error): + with raises(TypeError): + assert basic_time_interval < time_interval_lt_type_error + + +@mark.units +class TestTimeIntervalLe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + time_interval_1 = TimeInterval(value = value, unit = unit) + time_interval_2 = TimeInterval(value = value + gap, unit = unit) + + for target_unit in units_list: + assert time_interval_1 <= time_interval_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, time_interval_le_type_error): + with raises(TypeError): + assert basic_time_interval <= time_interval_le_type_error + + +@mark.units +class TestTimeIntervalTo: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), + unit = sampled_from(elements = units_list), + inplace = booleans()) + @settings(max_examples = 100) + def test_method(self, value, unit, inplace): + if value != 0: + time_interval = TimeInterval(value = value, unit = unit) + + for target_unit in units_list: + converted_time_interval = time_interval.to(target_unit = target_unit, inplace = inplace) + + assert converted_time_interval.unit == target_unit + if target_unit != unit: + assert converted_time_interval.value != value + assert converted_time_interval.unit != unit + + if inplace: + assert converted_time_interval.value == time_interval.value + assert converted_time_interval.unit == time_interval.unit + else: + assert converted_time_interval.value != time_interval.value + assert converted_time_interval.unit != time_interval.unit + else: + assert converted_time_interval == time_interval + + + @mark.error + def test_raises_type_error(self, time_interval_to_type_error): + with raises(TypeError): + basic_time_interval.to(**time_interval_to_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + basic_time_interval.to(fake_unit) diff --git a/tests/test_units/test_torque/conftest.py b/tests/test_units/test_torque/conftest.py new file mode 100644 index 0000000..867ecf3 --- /dev/null +++ b/tests/test_units/test_torque/conftest.py @@ -0,0 +1,104 @@ +from gearpy.units import InertiaMoment, Torque +from hypothesis.strategies import composite, floats, sampled_from +import numpy as np +from tests.conftest import types_to_check +from pytest import fixture + + +basic_torque = Torque(1, 'Nm') + + +@composite +def torques(draw): + value = draw(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) + unit = draw(sampled_from(elements = list(Torque._Torque__UNITS.keys()))) + + return Torque(value = value, unit = unit) + + +torque_init_type_error_1 = [{'value': type_to_check, 'unit': 'unit'} for type_to_check in types_to_check + if not isinstance(type_to_check, float) and not isinstance(type_to_check, int)] + +torque_init_type_error_2 = [{'value': 1, 'unit': types_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, str)] + +@fixture(params = [*torque_init_type_error_1, + *torque_init_type_error_2]) +def torque_init_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Torque)]) +def torque_add_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Torque)]) +def torque_sub_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check + if not isinstance(type_to_check, float) and not isinstance(type_to_check, int)]) +def torque_mul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, np.ndarray)]) +def torque_rmul_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, InertiaMoment) + and not isinstance(type_to_check, Torque)]) +def torque_truediv_type_error(request): + return request.param + + +@fixture(params = [0, 0.0, Torque(0, 'Nm')]) +def torque_truediv_zero_division_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Torque)]) +def torque_eq_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Torque)]) +def torque_ne_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Torque)]) +def torque_gt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Torque)]) +def torque_ge_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Torque)]) +def torque_lt_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Torque)]) +def torque_le_type_error(request): + return request.param + + +torque_to_type_error_1 = [{'target_unit': type_to_check, 'inplace': True} + for type_to_check in types_to_check if not isinstance(type_to_check, str)] + +torque_to_type_error_2 = [{'target_unit': 'target_unit', 'inplace': type_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, bool) and not isinstance(type_to_check, int)] + +@fixture(params = [*torque_to_type_error_1, + *torque_to_type_error_2]) +def torque_to_type_error(request): + return request.param \ No newline at end of file diff --git a/tests/test_units/test_torque/test_torque.py b/tests/test_units/test_torque/test_torque.py new file mode 100644 index 0000000..a849386 --- /dev/null +++ b/tests/test_units/test_torque/test_torque.py @@ -0,0 +1,382 @@ +from gearpy.units import AngularAcceleration, InertiaMoment, Torque +from hypothesis.strategies import floats, sampled_from, one_of, booleans +from hypothesis import given, settings +from tests.test_units.test_inertia_moment.conftest import inertia_moments +from tests.test_units.test_torque.conftest import basic_torque, torques +from pytest import mark, raises + + +units_list = list(Torque._Torque__UNITS.keys()) + + +@mark.units +class TestTorqueInit: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + torque = Torque(value = value, unit = unit) + + assert torque.value == value + assert torque.unit == unit + + + @mark.error + def test_raises_type_error(self, torque_init_type_error): + with raises(TypeError): + Torque(**torque_init_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + Torque(value = 1, unit = fake_unit) + + +@mark.units +class TestTorqueRepr: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + torque = Torque(value = value, unit = unit) + + assert str(torque) == f'{value} {unit}' + + + +@mark.units +class TestTorqueAdd: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + torque_1 = Torque(value = value_1, unit = unit_1) + torque_2 = Torque(value = value_2, unit = unit_2) + result = torque_1 + torque_2 + + assert isinstance(result, Torque) + assert result.value == torque_1.value + torque_2.to(unit_1).value + assert result.unit == torque_1.unit + + + @mark.error + def test_raises_type_error(self, torque_add_type_error): + with raises(TypeError): + assert basic_torque + torque_add_type_error + + +@mark.units +class TestTorqueSub: + + + @mark.genuine + @given(value_1 = floats(allow_nan = False, allow_infinity = False), + unit_1 = sampled_from(elements = units_list), + value_2 = floats(allow_nan = False, allow_infinity = False), + unit_2 = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value_1, unit_1, value_2, unit_2): + torque_1 = Torque(value = value_1, unit = unit_1) + torque_2 = Torque(value = value_2, unit = unit_2) + result = torque_1 - torque_2 + + assert isinstance(result, Torque) + assert result.value == torque_1.value - torque_2.to(unit_1).value + assert result.unit == torque_1.unit + + + @mark.error + def test_raises_type_error(self, torque_sub_type_error): + with raises(TypeError): + assert basic_torque - torque_sub_type_error + + +@mark.units +class TestTorqueMul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + multiplier = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + torque = Torque(value = value, unit = unit) + result = torque*multiplier + + assert isinstance(result, Torque) + assert result.value == torque.value*multiplier + assert result.unit == torque.unit + + + @mark.error + def test_raises_type_error(self, torque_mul_type_error): + with raises(TypeError): + assert basic_torque*torque_mul_type_error + + +@mark.units +class TestTorqueRmul: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + multiplier = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) + @settings(max_examples = 100) + def test_method(self, value, unit, multiplier): + torque = Torque(value = value, unit = unit) + result = multiplier*torque + + assert isinstance(result, Torque) + assert result.value == torque.value*multiplier + assert result.unit == torque.unit + + + @mark.error + def test_raises_type_error(self, torque_rmul_type_error): + with raises(TypeError): + assert torque_rmul_type_error*basic_torque + + +@mark.units +class TestTorqueTruediv: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list), + divider = one_of(floats(allow_nan = False, allow_infinity = False), + torques(), + inertia_moments())) + @settings(max_examples = 100) + def test_method(self, value, unit, divider): + torque = Torque(value = value, unit = unit) + + if isinstance(divider, Torque): + if abs(divider.value) >= 1e-300: + result = torque/divider + assert isinstance(result, float) + assert result == torque.value/divider.to(unit).value + elif isinstance(divider, InertiaMoment): + if abs(divider.value) >= 1e-300: + result = torque/divider + assert isinstance(result, AngularAcceleration) + assert result.value == torque.to('Nm').value/divider.to('kgm^2').value + assert result.unit == 'rad/s^2' + else: + if divider != 0: + result = torque/divider + assert isinstance(result, Torque) + assert result.value == torque.value/divider + assert result.unit == torque.unit + + + @mark.error + def test_raises_type_error(self, torque_truediv_type_error): + with raises(TypeError): + assert basic_torque/torque_truediv_type_error + + + @mark.error + def test_raises_zero_division_error(self, torque_truediv_zero_division_error): + with raises(ZeroDivisionError): + assert basic_torque/torque_truediv_zero_division_error + + +@mark.units +class TestTorqueEq: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method(self, value, unit): + torque_1 = Torque(value = value, unit = unit) + torque_2 = Torque(value = value, unit = unit) + + for target_unit in units_list: + assert torque_1 == torque_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, torque_eq_type_error): + with raises(TypeError): + assert basic_torque == torque_eq_type_error + + +@mark.units +class TestTorqueNe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + torque_1 = Torque(value = value, unit = unit) + torque_2 = Torque(value = value + gap, unit = unit) + + for target_unit in units_list: + assert torque_1 != torque_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, torque_ne_type_error): + with raises(TypeError): + assert basic_torque != torque_ne_type_error + + +@mark.units +class TestTorqueGt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + torque_1 = Torque(value = value + gap, unit = unit) + torque_2 = Torque(value = value, unit = unit) + + for target_unit in units_list: + assert torque_1 > torque_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, torque_gt_type_error): + with raises(TypeError): + assert basic_torque > torque_gt_type_error + + +@mark.units +class TestTorqueGe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + torque_1 = Torque(value = value + gap, unit = unit) + torque_2 = Torque(value = value, unit = unit) + + for target_unit in units_list: + assert torque_1 >= torque_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, torque_ge_type_error): + with raises(TypeError): + assert basic_torque >= torque_ge_type_error + + +@mark.units +class TestTorqueLt: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + torque_1 = Torque(value = value, unit = unit) + torque_2 = Torque(value = value + gap, unit = unit) + + for target_unit in units_list: + assert torque_1 < torque_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, torque_lt_type_error): + with raises(TypeError): + assert basic_torque < torque_lt_type_error + + +@mark.units +class TestTorqueLe: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + @settings(max_examples = 100) + def test_method(self, value, unit, gap): + if value != 0: + torque_1 = Torque(value = value, unit = unit) + torque_2 = Torque(value = value + gap, unit = unit) + + for target_unit in units_list: + assert torque_1 <= torque_2.to(target_unit) + + + @mark.error + def test_raises_type_error(self, torque_le_type_error): + with raises(TypeError): + assert basic_torque <= torque_le_type_error + + +@mark.units +class TestTorqueTo: + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), + unit = sampled_from(elements = units_list), + inplace = booleans()) + @settings(max_examples = 100) + def test_method(self, value, unit, inplace): + if value != 0: + torque = Torque(value = value, unit = unit) + + for target_unit in units_list: + converted_torque = torque.to(target_unit = target_unit, inplace = inplace) + + assert converted_torque.unit == target_unit + if target_unit != unit: + assert converted_torque.value != value + assert converted_torque.unit != unit + + if inplace: + assert converted_torque.value == torque.value + assert converted_torque.unit == torque.unit + else: + assert converted_torque.value != torque.value + assert converted_torque.unit != torque.unit + else: + assert converted_torque == torque + + + @mark.error + def test_raises_type_error(self, torque_to_type_error): + with raises(TypeError): + basic_torque.to(**torque_to_type_error) + + + @mark.error + def test_raises_key_error(self): + fake_units = [f'fake {unit}' for unit in units_list] + for fake_unit in fake_units: + with raises(KeyError): + basic_torque.to(fake_unit) diff --git a/tox.ini b/tox.ini index b0a47c7..6cbe41c 100644 --- a/tox.ini +++ b/tox.ini @@ -26,6 +26,7 @@ markers = dc_motor: DCMotor tests solver: Solver tests transmission: Transmission tests + units: Units tests utils: Utilities functions tests genuine: Genuine method tests with no errors error: Error-raising tests From 21782c30401ffeddeec0bb495e17904b937cf620 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sat, 14 Oct 2023 15:31:15 +0200 Subject: [PATCH 29/33] TST: update RotatingObject tests --- tests/test_dc_motor.py | 80 ----------------- tests/test_gear/conftest.py | 73 ++++++++++++++++ tests/{ => test_gear}/test_spur_gear.py | 31 ++++--- tests/test_motor/conftest.py | 58 +++++++++++++ tests/test_motor/test_dc_motor.py | 80 +++++++++++++++++ tests/test_rotating_object/conftest.py | 38 +++++++++ .../test_rotating_object.py | 85 ++++++++++--------- 7 files changed, 310 insertions(+), 135 deletions(-) delete mode 100644 tests/test_dc_motor.py create mode 100644 tests/test_gear/conftest.py rename tests/{ => test_gear}/test_spur_gear.py (80%) create mode 100644 tests/test_motor/conftest.py create mode 100644 tests/test_motor/test_dc_motor.py create mode 100644 tests/test_rotating_object/conftest.py rename tests/{ => test_rotating_object}/test_rotating_object.py (57%) diff --git a/tests/test_dc_motor.py b/tests/test_dc_motor.py deleted file mode 100644 index 6978aa4..0000000 --- a/tests/test_dc_motor.py +++ /dev/null @@ -1,80 +0,0 @@ -from gearpy.gear import SpurGear -from gearpy.motor import DCMotor -from hypothesis import given, settings -from hypothesis.strategies import text, floats -from pytest import mark, raises -from tests.conftest import basic_dc_motor - - -@mark.dc_motor -class TestDCMotorInit: - - - @mark.genuine - @given(name = text(min_size = 1), - inertia = floats(min_value = 0, exclude_min = True), - no_load_speed = floats(min_value = 0, exclude_min = True), - maximum_torque = floats(min_value = 0, exclude_min = True)) - @settings(max_examples = 100) - def test_method(self, name, inertia, no_load_speed, maximum_torque): - motor = DCMotor(name = name, inertia = inertia, no_load_speed = no_load_speed, maximum_torque = maximum_torque) - - assert motor.name == name - assert motor.inertia == inertia - assert motor.no_load_speed == no_load_speed - assert motor.maximum_torque == maximum_torque - - - @mark.error - def test_raises_type_error(self, dc_motor_init_type_error): - with raises(TypeError): - DCMotor(name = dc_motor_init_type_error['name'], - inertia = dc_motor_init_type_error['inertia'], - no_load_speed = dc_motor_init_type_error['no_load_speed'], - maximum_torque = dc_motor_init_type_error['maximum_torque']) - - - @mark.error - def test_raises_value_error(self, dc_motor_init_value_error): - with raises(ValueError): - DCMotor(name = dc_motor_init_value_error['name'], - inertia = dc_motor_init_value_error['inertia'], - no_load_speed = dc_motor_init_value_error['no_load_speed'], - maximum_torque = dc_motor_init_value_error['maximum_torque']) - - -@mark.dc_motor -class TestDCMotorDrives: - - - @mark.genuine - def test_property(self): - gear = SpurGear(name = 'gear', n_teeth = 10, inertia = 1) - basic_dc_motor.drives = gear - - assert basic_dc_motor.drives == gear - - - @mark.error - def test_raises_type_error(self, dc_motor_drives_type_error): - with raises(TypeError): - basic_dc_motor.drives = dc_motor_drives_type_error - - -@mark.dc_motor -class TestDCMotorComputeTorque: - - - @mark.genuine - @given(name = text(min_size = 1), - inertia = floats(min_value = 0, exclude_min = True), - no_load_speed = floats(min_value = 0, exclude_min = True), - maximum_torque = floats(min_value = 0, exclude_min = True), - speed = floats(allow_nan = False, allow_infinity = False)) - @settings(max_examples = 100) - def test_method(self, name, inertia, no_load_speed, maximum_torque, speed): - motor = DCMotor(name = name, inertia = inertia, no_load_speed = no_load_speed, maximum_torque = maximum_torque) - motor.speed = speed - torque = motor.compute_torque() - - assert isinstance(torque, float) or isinstance(torque, int) diff --git a/tests/test_gear/conftest.py b/tests/test_gear/conftest.py new file mode 100644 index 0000000..6968e30 --- /dev/null +++ b/tests/test_gear/conftest.py @@ -0,0 +1,73 @@ +from gearpy.gear import SpurGear +from gearpy.mechanical_object import RotatingObject +from gearpy.units import InertiaMoment +from hypothesis.strategies import composite, text, integers +from pytest import fixture +from tests.conftest import types_to_check +from typing import Callable + + +basic_spur_gear = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = InertiaMoment(1, 'kgm^2')) + + +@composite +def spur_gears(draw): + name = draw(text(min_size = 1)) + n_teeth = draw(integers(min_value = 1)) + inertia = InertiaMoment(1, 'kgm^2') + + return SpurGear(name = name, n_teeth = n_teeth, inertia_moment = inertia) + + +spur_gear_init_type_error_1 = [{'name': type_to_check, 'n_teeth': 10, 'inertia_moment': InertiaMoment(1, 'kgm^2')} + for type_to_check in types_to_check if not isinstance(type_to_check, str)] + +spur_gear_init_type_error_2 = [{'name': 'gear', 'n_teeth': type_to_check, 'inertia_moment': InertiaMoment(1, 'kgm^2')} + for type_to_check in types_to_check if not isinstance(type_to_check, int) + and not isinstance(type_to_check, bool)] + +spur_gear_init_type_error_3 = [{'name': 'gear', 'n_teeth': 10, 'inertia_moment': type_to_check} + for type_to_check in types_to_check if not isinstance(type_to_check, InertiaMoment)] + +@fixture(params = [*spur_gear_init_type_error_1, + *spur_gear_init_type_error_2, + *spur_gear_init_type_error_3]) +def spur_gear_init_type_error(request): + return request.param + + +@fixture(params = [{'name': '', 'n_teeth': 1, 'inertia_moment': InertiaMoment(1, 'kgm^2')}, + {'name': 'gear', 'n_teeth': -1, 'inertia_moment': InertiaMoment(1, 'kgm^2')}]) +def spur_gear_init_value_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) +def spur_gear_driven_by_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) +def spur_gear_drives_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float)]) +def spur_gear_master_gear_ratio_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) +def spur_gear_master_gear_efficiency_type_error(request): + return request.param + + +@fixture(params = [-1, 2]) +def spur_gear_master_gear_efficiency_value_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Callable)]) +def spur_gear_external_torque_type_error(request): + return request.param diff --git a/tests/test_spur_gear.py b/tests/test_gear/test_spur_gear.py similarity index 80% rename from tests/test_spur_gear.py rename to tests/test_gear/test_spur_gear.py index a041e1b..20054b0 100644 --- a/tests/test_spur_gear.py +++ b/tests/test_gear/test_spur_gear.py @@ -1,9 +1,11 @@ from gearpy.gear import SpurGear from gearpy.motor import DCMotor +from gearpy.units import AngularSpeed, InertiaMoment, Torque from hypothesis import given, settings from hypothesis.strategies import text, floats, integers, functions from pytest import mark, raises -from tests.conftest import basic_spur_gear +from tests.test_gear.conftest import basic_spur_gear +from tests.test_units.test_inertia_moment.conftest import inertia_moments @mark.spur_gear @@ -13,30 +15,26 @@ class TestSpurGearInit: @mark.genuine @given(name = text(min_size = 1), n_teeth = integers(min_value = 1), - inertia = floats(min_value = 0, exclude_min = True)) + inertia_moment = inertia_moments()) @settings(max_examples = 100) - def test_method(self, name, n_teeth, inertia): - gear = SpurGear(name = name, n_teeth = n_teeth, inertia = inertia) + def test_method(self, name, n_teeth, inertia_moment): + gear = SpurGear(name = name, n_teeth = n_teeth, inertia_moment = inertia_moment) assert gear.name == name assert gear.n_teeth == n_teeth - assert gear.inertia == inertia + assert gear.inertia_moment == inertia_moment @mark.error def test_raises_type_error(self, spur_gear_init_type_error): with raises(TypeError): - SpurGear(name = spur_gear_init_type_error['name'], - n_teeth = spur_gear_init_type_error['n_teeth'], - inertia = spur_gear_init_type_error['inertia']) + SpurGear(**spur_gear_init_type_error) @mark.error def test_raises_value_error(self, spur_gear_init_value_error): with raises(ValueError): - SpurGear(name = spur_gear_init_value_error['name'], - n_teeth = spur_gear_init_value_error['n_teeth'], - inertia = spur_gear_init_value_error['inertia']) + SpurGear(**spur_gear_init_value_error) @mark.spur_gear @@ -45,8 +43,9 @@ class TestSpurGearDrivenBy: @mark.genuine def test_property(self): - motor = DCMotor(name = 'motor', inertia = 1, no_load_speed = 1, maximum_torque = 1) - gear = SpurGear(name = 'gear', n_teeth = 10, inertia = 1) + motor = DCMotor(name = 'motor', inertia_moment = InertiaMoment(1, 'kgm^2'), + no_load_speed = AngularSpeed(1000, 'rpm'), maximum_torque = Torque(1, 'Nm')) + gear = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = InertiaMoment(1, 'kgm^2')) for master in [motor, gear]: basic_spur_gear.driven_by = master @@ -66,7 +65,7 @@ class TestSpurGearDrives: @mark.genuine def test_property(self): - gear = SpurGear(name = 'gear', n_teeth = 10, inertia = 1) + gear = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = InertiaMoment(1, 'kgm^2')) basic_spur_gear.drives = gear assert basic_spur_gear.drives == gear @@ -106,6 +105,7 @@ def test_raises_value_error(self): @mark.spur_gear class TestSpurGearMasterGearEfficiency: + @mark.genuine @given(master_gear_efficiency = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False, max_value = 1, exclude_max = False)) @@ -115,6 +115,7 @@ def test_property(self, master_gear_efficiency): assert basic_spur_gear.master_gear_efficiency == master_gear_efficiency + @mark.error def test_raises_type_error(self, spur_gear_master_gear_efficiency_type_error): with raises(TypeError): @@ -130,6 +131,7 @@ def test_raises_value_error(self, spur_gear_master_gear_efficiency_value_error): @mark.spur_gear class TestSpurGearExternalTorque: + @mark.genuine @given(external_torque = functions()) @settings(max_examples = 100) @@ -138,6 +140,7 @@ def test_property(self, external_torque): assert basic_spur_gear.external_torque == external_torque + @mark.error def test_raises_type_error(self, spur_gear_external_torque_type_error): with raises(TypeError): diff --git a/tests/test_motor/conftest.py b/tests/test_motor/conftest.py new file mode 100644 index 0000000..b1314f5 --- /dev/null +++ b/tests/test_motor/conftest.py @@ -0,0 +1,58 @@ +from gearpy.mechanical_object import RotatingObject +from gearpy.motor import DCMotor +from gearpy.units import AngularSpeed, InertiaMoment, Torque +from hypothesis.strategies import composite, text, floats +from tests.conftest import types_to_check +from pytest import fixture + + +basic_dc_motor = DCMotor(name = 'name', + inertia_moment = InertiaMoment(1, 'kgm^2'), + no_load_speed = AngularSpeed(1000, 'rpm'), + maximum_torque = Torque(1, 'Nm')) + + +@composite +def dc_motors(draw): + name = draw(text(min_size = 1)) + inertia = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) + no_load_speed = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) + maximum_torque = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) + + return DCMotor(name = name, inertia_moment = inertia, no_load_speed = no_load_speed, maximum_torque = maximum_torque) + + +dc_motor_init_type_error_1 = [{'name': type_to_check, 'inertia_moment': InertiaMoment(1, 'kgm^2'), + 'no_load_speed': AngularSpeed(1000, 'rpm'), 'maximum_torque': Torque(1, 'Nm')} + for type_to_check in types_to_check if not isinstance(type_to_check, str)] + +dc_motor_init_type_error_2 = [{'name': 'motor', 'inertia_moment': type_to_check, + 'no_load_speed': AngularSpeed(1000, 'rpm'), 'maximum_torque': Torque(1, 'Nm')} + for type_to_check in types_to_check if not isinstance(type_to_check, InertiaMoment)] + +dc_motor_init_type_error_3 = [{'name': 'motor', 'inertia_moment': InertiaMoment(1, 'kgm^2'), + 'no_load_speed': type_to_check, 'maximum_torque': Torque(1, 'Nm')} + for type_to_check in types_to_check if not isinstance(type_to_check, AngularSpeed)] + +dc_motor_init_type_error_4 = [{'name': 'motor', 'inertia_moment': InertiaMoment(1, 'kgm^2'), + 'no_load_speed': AngularSpeed(1000, 'rpm'), 'maximum_torque': type_to_check} + for type_to_check in types_to_check if not isinstance(type_to_check, Torque)] + +@fixture(params = [*dc_motor_init_type_error_1, + *dc_motor_init_type_error_2, + *dc_motor_init_type_error_3, + *dc_motor_init_type_error_4]) +def dc_motor_init_type_error(request): + return request.param + + +@fixture(params = [{'name': '', 'inertia_moment': InertiaMoment(1, 'kgm^2'), 'no_load_speed': AngularSpeed(1000, 'rpm'), 'maximum_torque': Torque(1, 'Nm')}, + {'name': 'motor', 'inertia_moment': InertiaMoment(1, 'kgm^2'), 'no_load_speed': AngularSpeed(-1000, 'rpm'), 'maximum_torque': Torque(1, 'Nm')}, + {'name': 'motor', 'inertia_moment': InertiaMoment(1, 'kgm^2'), 'no_load_speed': AngularSpeed(1000, 'rpm'), 'maximum_torque': Torque(-1, 'Nm')}]) +def dc_motor_init_value_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) +def dc_motor_drives_type_error(request): + return request.param diff --git a/tests/test_motor/test_dc_motor.py b/tests/test_motor/test_dc_motor.py new file mode 100644 index 0000000..be3657c --- /dev/null +++ b/tests/test_motor/test_dc_motor.py @@ -0,0 +1,80 @@ +from gearpy.gear import SpurGear +from gearpy.motor import DCMotor +from gearpy.units import Torque +from hypothesis import given, settings +from hypothesis.strategies import text +from pytest import mark, raises +from tests.test_motor.conftest import basic_dc_motor +from tests.test_units.test_angular_speed.conftest import angular_speeds +from tests.test_units.test_inertia_moment.conftest import inertia_moments, basic_inertia_moment +from tests.test_units.test_torque.conftest import torques + + +@mark.dc_motor +class TestDCMotorInit: + + + @mark.genuine + @given(name = text(min_size = 1), + inertia_moment = inertia_moments(), + no_load_speed = angular_speeds(), + maximum_torque = torques()) + @settings(max_examples = 100) + def test_method(self, name, inertia_moment, no_load_speed, maximum_torque): + if no_load_speed.value > 0 and maximum_torque.value > 0: + motor = DCMotor(name = name, inertia_moment = inertia_moment, no_load_speed = no_load_speed, maximum_torque = maximum_torque) + + assert motor.name == name + assert motor.inertia_moment == inertia_moment + assert motor.no_load_speed == no_load_speed + assert motor.maximum_torque == maximum_torque + + + @mark.error + def test_raises_type_error(self, dc_motor_init_type_error): + with raises(TypeError): + DCMotor(**dc_motor_init_type_error) + + + @mark.error + def test_raises_value_error(self, dc_motor_init_value_error): + with raises(ValueError): + DCMotor(**dc_motor_init_value_error) + + +@mark.dc_motor +class TestDCMotorDrives: + + + @mark.genuine + def test_property(self): + gear = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = basic_inertia_moment) + basic_dc_motor.drives = gear + + assert basic_dc_motor.drives == gear + + + @mark.error + def test_raises_type_error(self, dc_motor_drives_type_error): + with raises(TypeError): + basic_dc_motor.drives = dc_motor_drives_type_error + + +@mark.dc_motor +class TestDCMotorComputeTorque: + + + @mark.genuine + @given(name = text(min_size = 1), + inertia_moment = inertia_moments(), + no_load_speed = angular_speeds(), + maximum_torque = torques(), + speed = angular_speeds()) + @settings(max_examples = 100) + def test_method(self, name, inertia_moment, no_load_speed, maximum_torque, speed): + if no_load_speed.value > 1e-10 and maximum_torque.value > 1e-10: + motor = DCMotor(name = name, inertia_moment = inertia_moment, no_load_speed = no_load_speed, maximum_torque = maximum_torque) + motor.angular_speed = speed + torque = motor.compute_torque() + + assert isinstance(torque, Torque) diff --git a/tests/test_rotating_object/conftest.py b/tests/test_rotating_object/conftest.py new file mode 100644 index 0000000..a3967c6 --- /dev/null +++ b/tests/test_rotating_object/conftest.py @@ -0,0 +1,38 @@ +from gearpy.units import AngularAcceleration, AngularPosition, AngularSpeed, Torque +from tests.conftest import types_to_check +from tests.test_gear.conftest import basic_spur_gear +from tests.test_motor.conftest import basic_dc_motor +from pytest import fixture + + +basic_rotating_objects = [basic_dc_motor, basic_spur_gear] + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularPosition)]) +def rotating_object_angular_position_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularSpeed)]) +def rotating_object_angular_speed_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, AngularAcceleration)]) +def rotating_object_angular_acceleration_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Torque)]) +def rotating_object_torque_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Torque)]) +def rotating_object_driving_torque_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Torque)]) +def rotating_object_load_torque_type_error(request): + return request.param diff --git a/tests/test_rotating_object.py b/tests/test_rotating_object/test_rotating_object.py similarity index 57% rename from tests/test_rotating_object.py rename to tests/test_rotating_object/test_rotating_object.py index 5d18ca7..948538d 100644 --- a/tests/test_rotating_object.py +++ b/tests/test_rotating_object/test_rotating_object.py @@ -1,70 +1,73 @@ from hypothesis import given, settings -from hypothesis.strategies import floats from pytest import mark, raises -from tests.conftest import basic_rotating_objects +from tests.test_rotating_object.conftest import basic_rotating_objects +from tests.test_units.test_angular_acceleration.conftest import angular_accelerations +from tests.test_units.test_angular_position.conftest import angular_positions +from tests.test_units.test_angular_speed.conftest import angular_speeds +from tests.test_units.test_torque.conftest import torques @mark.rotating_object -class TestRotatingObjectAngle: +class TestRotatingObjectAngularPosition: @mark.genuine - @given(angle = floats(allow_nan = False, allow_infinity = False)) + @given(angular_position = angular_positions()) @settings(max_examples = 100) - def test_property(self, angle): + def test_property(self, angular_position): for rotating_object in basic_rotating_objects: - rotating_object.angle = angle + rotating_object.angular_position = angular_position - assert rotating_object.angle == angle + assert rotating_object.angular_position == angular_position @mark.error - def test_raises_type_error(self, rotating_object_angle_type_error): + def test_raises_type_error(self, rotating_object_angular_position_type_error): for rotating_object in basic_rotating_objects: with raises(TypeError): - rotating_object.angle = rotating_object_angle_type_error + rotating_object.angular_position = rotating_object_angular_position_type_error @mark.rotating_object -class TestRotatingObjectSpeed: +class TestRotatingObjectAngularSpeed: @mark.genuine - @given(speed = floats(allow_nan = False, allow_infinity = False)) + @given(angular_speed = angular_speeds()) @settings(max_examples = 100) - def test_property(self, speed): + def test_property(self, angular_speed): for rotating_object in basic_rotating_objects: - rotating_object.speed = speed + rotating_object.angular_speed = angular_speed - assert rotating_object.speed == speed + assert rotating_object.angular_speed == angular_speed @mark.error - def test_raises_type_error(self, rotating_object_speed_type_error): + def test_raises_type_error(self, rotating_object_angular_speed_type_error): for rotating_object in basic_rotating_objects: with raises(TypeError): - rotating_object.speed = rotating_object_speed_type_error + rotating_object.angular_speed = rotating_object_angular_speed_type_error @mark.rotating_object -class TestRotatingObjectAcceleration: +class TestRotatingObjectAngularAcceleration: @mark.genuine - @given(acceleration = floats(allow_nan = False, allow_infinity = False)) + @given(angular_acceleration = angular_accelerations()) @settings(max_examples = 100) - def test_property(self, acceleration): + def test_property(self, angular_acceleration): for rotating_object in basic_rotating_objects: - rotating_object.acceleration = acceleration + rotating_object.angular_acceleration = angular_acceleration - assert rotating_object.acceleration == acceleration + assert rotating_object.angular_acceleration == angular_acceleration @mark.error - def test_raises_type_error(self, rotating_object_acceleration_type_error): + def test_raises_type_error(self, rotating_object_angular_acceleration_type_error): for rotating_object in basic_rotating_objects: with raises(TypeError): - rotating_object.acceleration = rotating_object_acceleration_type_error + rotating_object.angular_acceleration = rotating_object_angular_acceleration_type_error @mark.rotating_object @@ -72,7 +75,7 @@ class TestRotatingObjectTorque: @mark.genuine - @given(torque = floats(allow_nan = False, allow_infinity = False)) + @given(torque = torques()) @settings(max_examples = 100) def test_property(self, torque): for rotating_object in basic_rotating_objects: @@ -93,7 +96,7 @@ class TestRotatingObjectDrivingTorque: @mark.genuine - @given(driving_torque = floats(allow_nan = False, allow_infinity = False)) + @given(driving_torque = torques()) @settings(max_examples = 100) def test_property(self, driving_torque): for rotating_object in basic_rotating_objects: @@ -114,7 +117,7 @@ class TestRotatingObjectLoadTorque: @mark.genuine - @given(load_torque = floats(allow_nan = False, allow_infinity = False)) + @given(load_torque = torques()) @settings(max_examples = 100) def test_property(self, load_torque): for rotating_object in basic_rotating_objects: @@ -140,7 +143,7 @@ def test_property(self): time_variables = rotating_object.time_variables assert isinstance(time_variables, dict) - assert ['angle', 'speed', 'acceleration', + assert ['angular position', 'angular speed', 'angular acceleration', 'torque', 'driving torque', 'load torque'] == list(time_variables.keys()) assert all([value == [] for value in time_variables.values()]) @@ -150,17 +153,17 @@ class TestRotatingObjectUpdateTimeVariables: @mark.genuine - @given(angle = floats(allow_nan = False, allow_infinity = False), - speed = floats(allow_nan = False, allow_infinity = False), - acceleration = floats(allow_nan = False, allow_infinity = False), - torque = floats(allow_nan = False, allow_infinity = False), - driving_torque = floats(allow_nan = False, allow_infinity = False), - load_torque = floats(allow_nan = False, allow_infinity = False)) - def test_method(self, angle, speed, acceleration, torque, driving_torque, load_torque): + @given(angular_position = angular_positions(), + angular_speed = angular_speeds(), + angular_acceleration = angular_accelerations(), + torque = torques(), + driving_torque = torques(), + load_torque = torques()) + def test_method(self, angular_position, angular_speed, angular_acceleration, torque, driving_torque, load_torque): for rotating_object in basic_rotating_objects: - rotating_object.angle = angle - rotating_object.speed = speed - rotating_object.acceleration = acceleration + rotating_object.angular_position = angular_position + rotating_object.angular_speed = angular_speed + rotating_object.angular_acceleration = angular_acceleration rotating_object.torque = torque rotating_object.driving_torque = driving_torque rotating_object.load_torque = load_torque @@ -169,11 +172,11 @@ def test_method(self, angle, speed, acceleration, torque, driving_torque, load_t time_variables = rotating_object.time_variables assert isinstance(time_variables, dict) - assert ['angle', 'speed', 'acceleration', + assert ['angular position', 'angular speed', 'angular acceleration', 'torque', 'driving torque', 'load torque'] == list(time_variables.keys()) - assert time_variables['angle'][-1] == angle - assert time_variables['speed'][-1] == speed - assert time_variables['acceleration'][-1] == acceleration + assert time_variables['angular position'][-1] == angular_position + assert time_variables['angular speed'][-1] == angular_speed + assert time_variables['angular acceleration'][-1] == angular_acceleration assert time_variables['torque'][-1] == torque assert time_variables['driving torque'][-1] == driving_torque assert time_variables['load torque'][-1] == load_torque From 0042dac6f3c2c7b192f515016d72fa0a7c3cd05d Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sat, 14 Oct 2023 16:54:01 +0200 Subject: [PATCH 30/33] TST: update Transmission and Solver tests --- tests/conftest.py | 437 +++++++----------- tests/test_gear/conftest.py | 14 - tests/test_gear/test_spur_gear.py | 2 +- tests/test_motor/conftest.py | 18 - tests/test_motor/test_dc_motor.py | 2 +- tests/test_rotating_object/conftest.py | 3 +- tests/test_solver.py | 34 +- tests/test_transmission.py | 4 +- .../test_units/test_time_interval/conftest.py | 9 - .../test_time_interval/test_time_interval.py | 3 +- tests/test_utils.py | 12 +- 11 files changed, 201 insertions(+), 337 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index b21275f..cf842ab 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,19 +1,12 @@ -# from gearpy.gear import GearBase, SpurGear -# from gearpy.mechanical_object import RotatingObject -# from gearpy.motor import MotorBase, DCMotor -# from gearpy.transmission import Transmission +from gearpy.gear import GearBase, SpurGear +from gearpy.mechanical_object import RotatingObject +from gearpy.motor import MotorBase, DCMotor +from gearpy.transmission import Transmission from gearpy.units import AngularAcceleration, AngularPosition, AngularSpeed, InertiaMoment, Torque, Time, TimeInterval -# from gearpy.utils import add_fixed_joint, add_gear_mating -# from hypothesis.strategies import composite, text, integers, floats, lists +from gearpy.utils import add_fixed_joint, add_gear_mating +from hypothesis.strategies import composite, text, integers, floats, lists, sampled_from import numpy as np -# from pytest import fixture -# from typing import Callable -# -# -# basic_dc_motor = DCMotor(name = 'name', inertia_moment = 1, no_load_speed = 1, maximum_torque = 1) -# basic_spur_gear = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = 1) -# basic_rotating_objects = [basic_dc_motor, basic_spur_gear] -# +from pytest import fixture types_to_check = ['string', 2, 2.2, True, (0, 1), [0, 1], {0, 1}, {0: 1}, None, np.array([0]), @@ -21,254 +14,168 @@ InertiaMoment(1, 'kgm^2'), Torque(1, 'Nm'), Time(1, 'sec'), TimeInterval(1, 'sec')] -# -# @composite -# def dc_motors(draw): -# name = draw(text(min_size = 1)) -# inertia = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) -# no_load_speed = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) -# maximum_torque = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) -# -# return DCMotor(name = name, inertia_moment = inertia, no_load_speed = no_load_speed, maximum_torque = maximum_torque) -# -# -# @composite -# def spur_gears(draw): -# name = draw(text(min_size = 1)) -# n_teeth = draw(integers(min_value = 1)) -# inertia = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) -# -# return SpurGear(name = name, n_teeth = n_teeth, inertia_moment = inertia) -# -# -# @composite -# def transmissions(draw): -# motor = draw(dc_motors()) -# gears = draw(lists(elements = spur_gears(), min_size = 1)) -# -# add_fixed_joint(master = motor, slave = gears[0]) -# -# for i in range(0, len(gears) - 1): -# if i%2 == 0: -# add_gear_mating(master = gears[i], slave = gears[i + 1], efficiency = 1) -# else: -# add_fixed_joint(master = gears[i], slave = gears[i + 1]) -# -# return Transmission(motor = motor) -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) -# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -# def rotating_object_angle_type_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) -# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -# def rotating_object_speed_type_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) -# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -# def rotating_object_acceleration_type_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) -# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -# def rotating_object_torque_type_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) -# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -# def rotating_object_driving_torque_type_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) -# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -# def rotating_object_load_torque_type_error(request): -# return request.param -# -# -# dc_motor_init_type_error_1 = [{'name': type_to_check, 'inertia_moment': 1, 'no_load_speed': 1, 'maximum_torque': 1} -# for type_to_check in types_to_check if not isinstance(type_to_check, str)] -# -# dc_motor_init_type_error_2 = [{'name': 'motor', 'inertia_moment': type_to_check, 'no_load_speed': 1, 'maximum_torque': 1} -# for type_to_check in types_to_check if not isinstance(type_to_check, float) -# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] -# -# dc_motor_init_type_error_3 = [{'name': 'motor', 'inertia_moment': 1, 'no_load_speed': type_to_check, 'maximum_torque': 1} -# for type_to_check in types_to_check if not isinstance(type_to_check, float) -# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] -# -# dc_motor_init_type_error_4 = [{'name': 'motor', 'inertia_moment': 1, 'no_load_speed': 1, 'maximum_torque': type_to_check} -# for type_to_check in types_to_check if not isinstance(type_to_check, float) -# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] -# -# @fixture(params = [*dc_motor_init_type_error_1, -# *dc_motor_init_type_error_2, -# *dc_motor_init_type_error_3, -# *dc_motor_init_type_error_4]) -# def dc_motor_init_type_error(request): -# return request.param -# -# -# @fixture(params = [{'name': '', 'inertia_moment': 1, 'no_load_speed': 1, 'maximum_torque': 1}, -# {'name': 'motor', 'inertia_moment': -1, 'no_load_speed': 1, 'maximum_torque': 1}, -# {'name': 'motor', 'inertia_moment': 1, 'no_load_speed': -1, 'maximum_torque': 1}, -# {'name': 'motor', 'inertia_moment': 1, 'no_load_speed': 1, 'maximum_torque': -1}]) -# def dc_motor_init_value_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) -# def dc_motor_drives_type_error(request): -# return request.param -# -# -# @fixture(params = [{'name': 'gear', 'n_teeth': type_to_check, 'inertia_moment': 1} for type_to_check in types_to_check -# if not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -# def spur_gear_init_type_error(request): -# return request.param -# -# -# @fixture(params = [{'name': '', 'n_teeth': 1, 'inertia_moment': 1}, -# {'name': 'gear', 'n_teeth': -1, 'inertia_moment': 1}, -# {'name': 'gear', 'n_teeth': 1, 'inertia_moment': -1}]) -# def spur_gear_init_value_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) -# def spur_gear_driven_by_type_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)]) -# def spur_gear_drives_type_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float)]) -# def spur_gear_master_gear_ratio_type_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, float) -# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)]) -# def spur_gear_master_gear_efficiency_type_error(request): -# return request.param -# -# -# @fixture(params = [-1, 2]) -# def spur_gear_master_gear_efficiency_value_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, Callable)]) -# def spur_gear_external_torque_type_error(request): -# return request.param -# -# -# add_gear_mating_type_error_1 = [{'gear 1': type_to_check, 'gear 2': basic_spur_gear, 'efficiency': 0.5} -# for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] -# -# add_gear_mating_type_error_2 = [{'gear 1': basic_spur_gear, 'gear 2': type_to_check, 'efficiency': 0.5} -# for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] -# -# add_gear_mating_type_error_3 = [{'gear 1': basic_spur_gear, 'gear 2': basic_spur_gear, 'efficiency': type_to_check} -# for type_to_check in types_to_check if not isinstance(type_to_check, float) -# and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] -# -# @fixture(params = [*add_gear_mating_type_error_1, -# *add_gear_mating_type_error_2, -# *add_gear_mating_type_error_3]) -# def add_gear_mating_type_error(request): -# return request.param -# -# -# @fixture(params = [-1, 2]) -# def add_gear_mating_value_error(request): -# return request.param -# -# -# add_fixed_joint_type_error_1 = [{'master': type_to_check, 'slave': basic_spur_gear} for type_to_check in types_to_check -# if not isinstance(type_to_check, GearBase) and not isinstance(type_to_check, MotorBase)] -# -# add_fixed_joint_type_error_2 = [{'master': basic_spur_gear, 'slave': type_to_check} -# for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] -# -# @fixture(params = [*add_fixed_joint_type_error_1, -# *add_fixed_joint_type_error_2]) -# def add_fixed_joint_type_error(request): -# return request.param -# -# -# @fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, MotorBase)]) -# def transmission_init_type_error(request): -# return request.param -# -# -# motor_transmission_solver_init_type_error = DCMotor(name = 'name', inertia_moment = 1, no_load_speed = 1, maximum_torque = 1) -# gear_transmission_solver_init_type_error = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = 1) -# add_fixed_joint(master = motor_transmission_solver_init_type_error, slave = gear_transmission_solver_init_type_error) -# transmission_solver_init_type_error = Transmission(motor = motor_transmission_solver_init_type_error) -# -# class TransmissionFake(Transmission): -# -# def __init__(self, chain: list): -# self.__chain = chain -# -# @property -# def chain(self): -# return self.__chain -# -# @chain.setter -# def chain(self, chain): -# self.__chain = chain -# -# solver_init_type_error_1 = [{'time_discretization': type_to_check, 'simulation_time': 1, -# 'transmission': transmission_solver_init_type_error} for type_to_check in types_to_check -# if not isinstance(type_to_check, float) and not isinstance(type_to_check, int) -# and not isinstance(type_to_check, bool)] -# -# solver_init_type_error_2 = [{'time_discretization': 1, 'simulation_time': type_to_check, -# 'transmission': transmission_solver_init_type_error} for type_to_check in types_to_check -# if not isinstance(type_to_check, float) and not isinstance(type_to_check, int) -# and not isinstance(type_to_check, bool)] -# -# solver_init_type_error_3 = [{'time_discretization': 1, 'simulation_time': 5, -# 'transmission': type_to_check} for type_to_check in types_to_check -# if not isinstance(type_to_check, Transmission)] -# -# solver_init_type_error_4 = [{'time_discretization': 1, 'simulation_time': 5, -# 'transmission': TransmissionFake([type_to_check, basic_spur_gear])} -# for type_to_check in types_to_check if not isinstance(type_to_check, MotorBase)] -# -# solver_init_type_error_5 = [{'time_discretization': 1, 'simulation_time': 5, -# 'transmission': TransmissionFake([basic_dc_motor, type_to_check])} -# for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)] -# -# @fixture(params = [*solver_init_type_error_1, -# *solver_init_type_error_2, -# *solver_init_type_error_3, -# *solver_init_type_error_4, -# *solver_init_type_error_5]) -# def solver_init_type_error(request): -# return request.param -# -# motor_transmission_solver_init_value_error = DCMotor(name = 'name', inertia_moment = 1, -# no_load_speed = 1, maximum_torque = 1) -# gear_transmission_solver_init_value_error = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = 1) -# add_fixed_joint(master = motor_transmission_solver_init_value_error, slave = gear_transmission_solver_init_value_error) -# transmission_solver_init_value_error = Transmission(motor = motor_transmission_solver_init_value_error) -# -# @fixture(params = [{'time_discretization': -1, 'simulation_time': 5, 'transmission': transmission_solver_init_value_error}, -# {'time_discretization': 1, 'simulation_time': -1, 'transmission': transmission_solver_init_value_error}, -# {'time_discretization': 6, 'simulation_time': 5, 'transmission': transmission_solver_init_value_error}, -# {'time_discretization': 1, 'simulation_time': 5, 'transmission': TransmissionFake([])}]) -# def solver_init_value_error(request): -# return request.param +basic_spur_gear = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = InertiaMoment(1, 'kgm^2')) + +basic_dc_motor = DCMotor(name = 'name', + inertia_moment = InertiaMoment(1, 'kgm^2'), + no_load_speed = AngularSpeed(1000, 'rpm'), + maximum_torque = Torque(1, 'Nm')) + + +@composite +def spur_gears(draw): + name = draw(text(min_size = 1)) + + n_teeth = draw(integers(min_value = 1)) + + inertia_moment_units_list = list(InertiaMoment._InertiaMoment__UNITS.keys()) + inertia_moment_value = draw(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) + inertia_moment_unit = draw(sampled_from(elements = inertia_moment_units_list)) + + return SpurGear(name = name, + n_teeth = n_teeth, + inertia_moment = InertiaMoment(inertia_moment_value, inertia_moment_unit)) + + +@composite +def dc_motors(draw): + name = draw(text(min_size = 1)) + + inertia_moment_units_list = list(InertiaMoment._InertiaMoment__UNITS.keys()) + inertia_moment_value = draw(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) + inertia_moment_unit = draw(sampled_from(elements = inertia_moment_units_list)) + + no_load_speed_units_list = list(AngularSpeed._AngularSpeed__UNITS.keys()) + no_load_speed_value = draw(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) + no_load_speed_unit = draw(sampled_from(elements = no_load_speed_units_list)) + + maximum_torque_units_list = list(Torque._Torque__UNITS.keys()) + maximum_torque_value = draw(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) + maximum_torque_unit = draw(sampled_from(elements = maximum_torque_units_list)) + + return DCMotor(name = name, + inertia_moment = InertiaMoment(inertia_moment_value, inertia_moment_unit), + no_load_speed = AngularSpeed(no_load_speed_value, no_load_speed_unit), + maximum_torque = Torque(maximum_torque_value, maximum_torque_unit)) + + +@composite +def transmissions(draw): + motor = draw(dc_motors()) + gears = draw(lists(elements = spur_gears(), min_size = 1)) + + add_fixed_joint(master = motor, slave = gears[0]) + + for i in range(0, len(gears) - 1): + if i%2 == 0: + add_gear_mating(master = gears[i], slave = gears[i + 1], efficiency = 1) + else: + add_fixed_joint(master = gears[i], slave = gears[i + 1]) + + return Transmission(motor = motor) + + +@composite +def time_intervals(draw): + value = draw(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) + unit = draw(sampled_from(elements = list(TimeInterval._Time__UNITS.keys()))) + + return TimeInterval(value = value, unit = unit) + + +add_gear_mating_type_error_1 = [{'master': type_to_check, 'slave': basic_spur_gear, 'efficiency': 0.5} + for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] + +add_gear_mating_type_error_2 = [{'master': basic_spur_gear, 'slave': type_to_check, 'efficiency': 0.5} + for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] + +add_gear_mating_type_error_3 = [{'master': basic_spur_gear, 'slave': basic_spur_gear, 'efficiency': type_to_check} + for type_to_check in types_to_check if not isinstance(type_to_check, float) + and not isinstance(type_to_check, int) and not isinstance(type_to_check, bool)] + +@fixture(params = [*add_gear_mating_type_error_1, + *add_gear_mating_type_error_2, + *add_gear_mating_type_error_3]) +def add_gear_mating_type_error(request): + return request.param + + +@fixture(params = [-1, 2]) +def add_gear_mating_value_error(request): + return request.param + + +add_fixed_joint_type_error_1 = [{'master': type_to_check, 'slave': basic_spur_gear} for type_to_check in types_to_check + if not isinstance(type_to_check, GearBase) and not isinstance(type_to_check, MotorBase)] + +add_fixed_joint_type_error_2 = [{'master': basic_spur_gear, 'slave': type_to_check} + for type_to_check in types_to_check if not isinstance(type_to_check, GearBase)] + +@fixture(params = [*add_fixed_joint_type_error_1, + *add_fixed_joint_type_error_2]) +def add_fixed_joint_type_error(request): + return request.param + + +@fixture(params = [type_to_check for type_to_check in types_to_check if not isinstance(type_to_check, MotorBase)]) +def transmission_init_type_error(request): + return request.param + + +motor_transmission_solver_init_type_error = DCMotor(name = 'name', inertia_moment = InertiaMoment(1, 'kgm^2'), + no_load_speed = AngularSpeed(1000, 'rpm'), maximum_torque = Torque(1, 'Nm')) +gear_transmission_solver_init_type_error = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = InertiaMoment(1, 'kgm^2')) +add_fixed_joint(master = motor_transmission_solver_init_type_error, slave = gear_transmission_solver_init_type_error) +transmission_solver_init_type_error = Transmission(motor = motor_transmission_solver_init_type_error) + +class TransmissionFake(Transmission): + + def __init__(self, chain: list): + self.__chain = chain + + @property + def chain(self): + return self.__chain + + @chain.setter + def chain(self, chain): + self.__chain = chain + +solver_init_type_error_1 = [{'time_discretization': type_to_check, 'simulation_time': TimeInterval(5, 'sec'), + 'transmission': transmission_solver_init_type_error} for type_to_check in types_to_check + if not isinstance(type_to_check, TimeInterval)] + +solver_init_type_error_2 = [{'time_discretization': TimeInterval(1, 'sec'), 'simulation_time': type_to_check, + 'transmission': transmission_solver_init_type_error} for type_to_check in types_to_check + if not isinstance(type_to_check, TimeInterval)] + +solver_init_type_error_3 = [{'time_discretization': TimeInterval(1, 'sec'), 'simulation_time': TimeInterval(5, 'sec'), + 'transmission': type_to_check} for type_to_check in types_to_check + if not isinstance(type_to_check, Transmission)] + +solver_init_type_error_4 = [{'time_discretization': TimeInterval(1, 'sec'), 'simulation_time': TimeInterval(5, 'sec'), + 'transmission': TransmissionFake([type_to_check, basic_spur_gear])} + for type_to_check in types_to_check if not isinstance(type_to_check, MotorBase)] + +solver_init_type_error_5 = [{'time_discretization': TimeInterval(1, 'sec'), 'simulation_time': TimeInterval(5, 'sec'), + 'transmission': TransmissionFake([basic_dc_motor, type_to_check])} + for type_to_check in types_to_check if not isinstance(type_to_check, RotatingObject)] + +@fixture(params = [*solver_init_type_error_1, + *solver_init_type_error_2, + *solver_init_type_error_3, + *solver_init_type_error_4, + *solver_init_type_error_5]) +def solver_init_type_error(request): + return request.param + +motor_transmission_solver_init_value_error = DCMotor(name = 'name', inertia_moment = InertiaMoment(1, 'kgm^2'), + no_load_speed = AngularSpeed(1000, 'rpm'), maximum_torque = Torque(1, 'Nm')) +gear_transmission_solver_init_value_error = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = InertiaMoment(1, 'kgm^2')) +add_fixed_joint(master = motor_transmission_solver_init_value_error, slave = gear_transmission_solver_init_value_error) +transmission_solver_init_value_error = Transmission(motor = motor_transmission_solver_init_value_error) + +@fixture(params = [{'time_discretization': TimeInterval(5, 'sec'), 'simulation_time': TimeInterval(1, 'sec'), 'transmission': transmission_solver_init_value_error}, + {'time_discretization': TimeInterval(1, 'sec'), 'simulation_time': TimeInterval(5, 'sec'), 'transmission': TransmissionFake([])}]) +def solver_init_value_error(request): + return request.param diff --git a/tests/test_gear/conftest.py b/tests/test_gear/conftest.py index 6968e30..b71a2c1 100644 --- a/tests/test_gear/conftest.py +++ b/tests/test_gear/conftest.py @@ -1,24 +1,10 @@ -from gearpy.gear import SpurGear from gearpy.mechanical_object import RotatingObject from gearpy.units import InertiaMoment -from hypothesis.strategies import composite, text, integers from pytest import fixture from tests.conftest import types_to_check from typing import Callable -basic_spur_gear = SpurGear(name = 'gear', n_teeth = 10, inertia_moment = InertiaMoment(1, 'kgm^2')) - - -@composite -def spur_gears(draw): - name = draw(text(min_size = 1)) - n_teeth = draw(integers(min_value = 1)) - inertia = InertiaMoment(1, 'kgm^2') - - return SpurGear(name = name, n_teeth = n_teeth, inertia_moment = inertia) - - spur_gear_init_type_error_1 = [{'name': type_to_check, 'n_teeth': 10, 'inertia_moment': InertiaMoment(1, 'kgm^2')} for type_to_check in types_to_check if not isinstance(type_to_check, str)] diff --git a/tests/test_gear/test_spur_gear.py b/tests/test_gear/test_spur_gear.py index 20054b0..455f330 100644 --- a/tests/test_gear/test_spur_gear.py +++ b/tests/test_gear/test_spur_gear.py @@ -4,7 +4,7 @@ from hypothesis import given, settings from hypothesis.strategies import text, floats, integers, functions from pytest import mark, raises -from tests.test_gear.conftest import basic_spur_gear +from tests.conftest import basic_spur_gear from tests.test_units.test_inertia_moment.conftest import inertia_moments diff --git a/tests/test_motor/conftest.py b/tests/test_motor/conftest.py index b1314f5..80773c2 100644 --- a/tests/test_motor/conftest.py +++ b/tests/test_motor/conftest.py @@ -1,27 +1,9 @@ from gearpy.mechanical_object import RotatingObject -from gearpy.motor import DCMotor from gearpy.units import AngularSpeed, InertiaMoment, Torque -from hypothesis.strategies import composite, text, floats from tests.conftest import types_to_check from pytest import fixture -basic_dc_motor = DCMotor(name = 'name', - inertia_moment = InertiaMoment(1, 'kgm^2'), - no_load_speed = AngularSpeed(1000, 'rpm'), - maximum_torque = Torque(1, 'Nm')) - - -@composite -def dc_motors(draw): - name = draw(text(min_size = 1)) - inertia = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) - no_load_speed = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) - maximum_torque = draw(floats(min_value = 0, exclude_min = True, allow_nan = False, allow_infinity = False)) - - return DCMotor(name = name, inertia_moment = inertia, no_load_speed = no_load_speed, maximum_torque = maximum_torque) - - dc_motor_init_type_error_1 = [{'name': type_to_check, 'inertia_moment': InertiaMoment(1, 'kgm^2'), 'no_load_speed': AngularSpeed(1000, 'rpm'), 'maximum_torque': Torque(1, 'Nm')} for type_to_check in types_to_check if not isinstance(type_to_check, str)] diff --git a/tests/test_motor/test_dc_motor.py b/tests/test_motor/test_dc_motor.py index be3657c..439b46d 100644 --- a/tests/test_motor/test_dc_motor.py +++ b/tests/test_motor/test_dc_motor.py @@ -4,7 +4,7 @@ from hypothesis import given, settings from hypothesis.strategies import text from pytest import mark, raises -from tests.test_motor.conftest import basic_dc_motor +from tests.conftest import basic_dc_motor from tests.test_units.test_angular_speed.conftest import angular_speeds from tests.test_units.test_inertia_moment.conftest import inertia_moments, basic_inertia_moment from tests.test_units.test_torque.conftest import torques diff --git a/tests/test_rotating_object/conftest.py b/tests/test_rotating_object/conftest.py index a3967c6..85dcf87 100644 --- a/tests/test_rotating_object/conftest.py +++ b/tests/test_rotating_object/conftest.py @@ -1,7 +1,6 @@ from gearpy.units import AngularAcceleration, AngularPosition, AngularSpeed, Torque from tests.conftest import types_to_check -from tests.test_gear.conftest import basic_spur_gear -from tests.test_motor.conftest import basic_dc_motor +from tests.conftest import basic_spur_gear, basic_dc_motor from pytest import fixture diff --git a/tests/test_solver.py b/tests/test_solver.py index f6f5ab2..9dae17d 100644 --- a/tests/test_solver.py +++ b/tests/test_solver.py @@ -1,9 +1,12 @@ from gearpy.solver import Solver +from gearpy.units import Torque, Time from hypothesis import given, settings from hypothesis.strategies import floats, integers import numpy as np from pytest import mark, raises -from tests.conftest import transmissions +from tests.conftest import transmissions, time_intervals +from tests.test_units.test_angular_position.conftest import angular_positions +from tests.test_units.test_angular_speed.conftest import angular_speeds @mark.solver @@ -11,8 +14,7 @@ class TestSolverInit: @mark.genuine - @given(time_discretization = floats(min_value = 0, max_value = 1, exclude_min = True, - allow_nan = False, allow_infinity = False), + @given(time_discretization = time_intervals(), simulation_steps = integers(min_value = 2, max_value = 1000), transmission = transmissions()) @settings(max_examples = 100) @@ -25,23 +27,19 @@ def test_method(self, time_discretization, simulation_steps, transmission): assert solver.time_discretization == time_discretization assert solver.simulation_time == simulation_time assert solver.transmission_chain == transmission.chain - assert solver.time == [0] + assert solver.time == [Time(value = 0, unit = time_discretization.unit)] @mark.error def test_raises_type_error(self, solver_init_type_error): with raises(TypeError): - Solver(time_discretization = solver_init_type_error['time_discretization'], - simulation_time = solver_init_type_error['simulation_time'], - transmission = solver_init_type_error['transmission']) + Solver(**solver_init_type_error) @mark.error def test_raises_value_error(self, solver_init_value_error): with raises(ValueError): - Solver(time_discretization = solver_init_value_error['time_discretization'], - simulation_time = solver_init_value_error['simulation_time'], - transmission = solver_init_value_error['transmission']) + Solver(**solver_init_value_error) @mark.solver @@ -49,20 +47,20 @@ class TestSolverRun: @mark.genuine - @given(time_discretization = floats(min_value = 1e-10, max_value = 10, allow_nan = False, allow_infinity = False), + @given(time_discretization = time_intervals(), simulation_steps = floats(min_value = 5, max_value = 1000, allow_nan = False, allow_infinity = False), transmission = transmissions(), - initial_angle = floats(allow_nan = False, allow_infinity = False), - initial_speed = floats(allow_nan = False, allow_infinity = False)) + initial_angular_position = angular_positions(), + initial_angular_speed = angular_speeds()) @settings(max_examples = 100, deadline = None) - def test_method(self, time_discretization, simulation_steps, transmission, initial_angle, initial_speed): - transmission.chain[-1].angle = initial_angle - transmission.chain[-1].speed = initial_speed - transmission.chain[-1].external_torque = lambda time, angle, speed: 0.001 + def test_method(self, time_discretization, simulation_steps, transmission, initial_angular_position, initial_angular_speed): + transmission.chain[-1].angular_position = initial_angular_position + transmission.chain[-1].angular_speed = initial_angular_speed + transmission.chain[-1].external_torque = lambda time, angular_position, angular_speed: Torque(0.001, 'Nm') simulation_time = time_discretization*simulation_steps solver = Solver(time_discretization = time_discretization, simulation_time = simulation_time, transmission = transmission) solver.run() - assert len(solver.time) == len(np.arange(time_discretization, simulation_time, time_discretization)) + 1 + assert len(solver.time) == len(np.arange(time_discretization.value, simulation_time.value, time_discretization.value)) + 1 diff --git a/tests/test_transmission.py b/tests/test_transmission.py index 64ed95f..30ff854 100644 --- a/tests/test_transmission.py +++ b/tests/test_transmission.py @@ -1,5 +1,6 @@ from gearpy.motor import DCMotor from gearpy.transmission import Transmission +from gearpy.units import AngularSpeed, InertiaMoment, Torque from gearpy.utils import add_gear_mating, add_fixed_joint from hypothesis import given, settings from hypothesis.strategies import lists @@ -42,6 +43,7 @@ def test_raises_type_error(self, transmission_init_type_error): @mark.error def test_raises_value_error(self): - motor = DCMotor(name = 'motor', inertia = 1, no_load_speed = 1, maximum_torque = 1) + motor = DCMotor(name = 'motor', inertia_moment = InertiaMoment(1, 'kgm^2'), + no_load_speed = AngularSpeed(1000, 'rpm'), maximum_torque = Torque(1, 'Nm')) with raises(ValueError): Transmission(motor = motor) diff --git a/tests/test_units/test_time_interval/conftest.py b/tests/test_units/test_time_interval/conftest.py index 3a83c46..fda50bd 100644 --- a/tests/test_units/test_time_interval/conftest.py +++ b/tests/test_units/test_time_interval/conftest.py @@ -1,5 +1,4 @@ from gearpy.units import AngularAcceleration, AngularSpeed, Time, TimeInterval -from hypothesis.strategies import composite, floats, sampled_from import numpy as np from tests.conftest import types_to_check from pytest import fixture @@ -8,14 +7,6 @@ basic_time_interval = TimeInterval(1, 'sec') -@composite -def time_intervals(draw): - value = draw(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) - unit = draw(sampled_from(elements = list(TimeInterval._Time__UNITS.keys()))) - - return TimeInterval(value = value, unit = unit) - - time_interval_init_type_error_1 = [{'value': type_to_check, 'unit': 'unit'} for type_to_check in types_to_check if not isinstance(type_to_check, float) and not isinstance(type_to_check, int)] diff --git a/tests/test_units/test_time_interval/test_time_interval.py b/tests/test_units/test_time_interval/test_time_interval.py index 2fe3621..def7d76 100644 --- a/tests/test_units/test_time_interval/test_time_interval.py +++ b/tests/test_units/test_time_interval/test_time_interval.py @@ -1,7 +1,8 @@ from gearpy.units import Time, TimeInterval from hypothesis.strategies import floats, sampled_from, one_of, booleans from hypothesis import given, settings -from tests.test_units.test_time_interval.conftest import basic_time_interval, time_intervals +from tests.conftest import time_intervals +from tests.test_units.test_time_interval.conftest import basic_time_interval from pytest import mark, raises diff --git a/tests/test_utils.py b/tests/test_utils.py index df89689..279b797 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,4 +1,5 @@ from gearpy.gear import SpurGear +from gearpy.units import InertiaMoment from gearpy.utils import add_gear_mating, add_fixed_joint from hypothesis import given, settings from hypothesis.strategies import floats @@ -28,15 +29,13 @@ def test_function(self, gear_1, gear_2, efficiency): @mark.error def test_raises_type_error(self, add_gear_mating_type_error): with raises(TypeError): - add_gear_mating(master = add_gear_mating_type_error['gear 1'], - slave = add_gear_mating_type_error['gear 2'], - efficiency = add_gear_mating_type_error['efficiency']) + add_gear_mating(**add_gear_mating_type_error) @mark.error def test_raises_value_error(self, add_gear_mating_value_error): - gear_1 = SpurGear(name = 'gear 1', n_teeth = 10, inertia = 1) - gear_2 = SpurGear(name = 'gear 2', n_teeth = 20, inertia = 1) + gear_1 = SpurGear(name = 'gear 1', n_teeth = 10, inertia_moment = InertiaMoment(1, 'kgm^2')) + gear_2 = SpurGear(name = 'gear 2', n_teeth = 20, inertia_moment = InertiaMoment(1, 'kgm^2')) with raises(ValueError): add_gear_mating(master = gear_1, slave = gear_2, efficiency = add_gear_mating_value_error) @@ -59,5 +58,4 @@ def test_function(self, gear_1, gear_2): @mark.error def test_raises_type_error(self, add_fixed_joint_type_error): with raises(TypeError): - add_fixed_joint(master = add_fixed_joint_type_error['master'], - slave = add_fixed_joint_type_error['slave']) + add_fixed_joint(**add_fixed_joint_type_error) From b22cce75307d7124ec0707f518c9f24ecb972b7a Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sat, 14 Oct 2023 17:18:16 +0200 Subject: [PATCH 31/33] TST: add __rmul__ patch tests --- gearpy/units/concrete_units.py | 3 +- .../test_angular_acceleration.py | 19 ++++++++++ .../test_angular_speed/test_angular_speed.py | 19 ++++++++++ tests/test_units/test_time/test_time.py | 38 +++++++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/gearpy/units/concrete_units.py b/gearpy/units/concrete_units.py index 410e92d..70bfb17 100644 --- a/gearpy/units/concrete_units.py +++ b/gearpy/units/concrete_units.py @@ -761,7 +761,8 @@ def __mul__(self, other: Union['AngularAcceleration', 'AngularSpeed', float, int def __rmul__(self, other: Union['AngularAcceleration', 'AngularSpeed', float, int]) -> Union['AngularPosition', 'AngularSpeed', 'Time']: super().__rmul__(other = other) - if not isinstance(other, AngularSpeed) and not isinstance(other, float) and not isinstance(other, int): + if not isinstance(other, AngularAcceleration) and not isinstance(other, AngularSpeed) \ + and not isinstance(other, float) and not isinstance(other, int): raise TypeError(f'It is not allowed to multiply a {other.__class__.__name__} by a ' f'{self.__class__.__name__}.') diff --git a/tests/test_units/test_angular_acceleration/test_angular_acceleration.py b/tests/test_units/test_angular_acceleration/test_angular_acceleration.py index 88c2005..c6db39d 100644 --- a/tests/test_units/test_angular_acceleration/test_angular_acceleration.py +++ b/tests/test_units/test_angular_acceleration/test_angular_acceleration.py @@ -158,6 +158,25 @@ def test_method(self, value, unit, multiplier): assert result.unit == angular_acceleration.unit + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method_patch(self, value, unit): + angular_acceleration = AngularAcceleration(value = value, unit = unit) + + class FakeTime(Time): + + def __mul__(self, other: AngularAcceleration): return NotImplemented + + fake_multiplier = FakeTime(1, 'sec') + result = fake_multiplier*angular_acceleration + + assert isinstance(result, AngularSpeed) + assert result.value == angular_acceleration.to('rad/s^2').value*fake_multiplier.to('sec').value + assert result.unit == 'rad/s' + + @mark.error def test_raises_type_error(self, angular_acceleration_rmul_type_error): with raises(TypeError): diff --git a/tests/test_units/test_angular_speed/test_angular_speed.py b/tests/test_units/test_angular_speed/test_angular_speed.py index 79e7f15..e441dcd 100644 --- a/tests/test_units/test_angular_speed/test_angular_speed.py +++ b/tests/test_units/test_angular_speed/test_angular_speed.py @@ -158,6 +158,25 @@ def test_method(self, value, unit, multiplier): assert result.unit == angular_speed.unit + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method_patch(self, value, unit): + angular_speed = AngularSpeed(value = value, unit = unit) + + class FakeTime(Time): + + def __mul__(self, other: AngularSpeed): return NotImplemented + + fake_multiplier = FakeTime(1, 'sec') + result = fake_multiplier*angular_speed + + assert isinstance(result, AngularPosition) + assert result.value == angular_speed.to('rad/s').value*fake_multiplier.to('sec').value + assert result.unit == 'rad' + + @mark.error def test_raises_type_error(self, angular_speed_rmul_type_error): with raises(TypeError): diff --git a/tests/test_units/test_time/test_time.py b/tests/test_units/test_time/test_time.py index 3ba9b0a..7d0834b 100644 --- a/tests/test_units/test_time/test_time.py +++ b/tests/test_units/test_time/test_time.py @@ -170,6 +170,44 @@ def test_method(self, value, unit, multiplier): assert result.unit == time.unit + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method_patch_1(self, value, unit): + time = Time(value = value, unit = unit) + + class FakeAngularAcceleration(AngularAcceleration): + + def __mul__(self, other: Time): return NotImplemented + + fake_multiplier = FakeAngularAcceleration(1, 'rad/s^2') + result = fake_multiplier*time + + assert isinstance(result, AngularSpeed) + assert result.value == time.to('sec').value*fake_multiplier.to('rad/s^2').value + assert result.unit == 'rad/s' + + + @mark.genuine + @given(value = floats(allow_nan = False, allow_infinity = False), + unit = sampled_from(elements = units_list)) + @settings(max_examples = 100) + def test_method_patch_2(self, value, unit): + time = Time(value = value, unit = unit) + + class FakeAngularSpeed(AngularSpeed): + + def __mul__(self, other: Time): return NotImplemented + + fake_multiplier = FakeAngularSpeed(1, 'rad/s') + result = fake_multiplier*time + + assert isinstance(result, AngularPosition) + assert result.value == time.to('sec').value*fake_multiplier.to('rad/s').value + assert result.unit == 'rad' + + @mark.error def test_raises_type_error(self, time_rmul_type_error): with raises(TypeError): From e7f2a23893dec236830d4e61d0cb99e52df86bc8 Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sat, 14 Oct 2023 17:36:46 +0200 Subject: [PATCH 32/33] TST: limit hypothesis value range to avoid overflow approximation --- .../test_angular_acceleration.py | 22 +++++++------- .../test_angular_position.py | 20 ++++++------- .../test_angular_speed/test_angular_speed.py | 22 +++++++------- .../test_inertia_moment.py | 30 +++++++++---------- tests/test_units/test_time/test_time.py | 30 +++++++++---------- .../test_time_interval/test_time_interval.py | 14 ++++----- tests/test_units/test_torque/test_torque.py | 30 +++++++++---------- 7 files changed, 84 insertions(+), 84 deletions(-) diff --git a/tests/test_units/test_angular_acceleration/test_angular_acceleration.py b/tests/test_units/test_angular_acceleration/test_angular_acceleration.py index c6db39d..8dee305 100644 --- a/tests/test_units/test_angular_acceleration/test_angular_acceleration.py +++ b/tests/test_units/test_angular_acceleration/test_angular_acceleration.py @@ -13,7 +13,7 @@ class TestAngularAccelerationInit: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value, unit): @@ -42,7 +42,7 @@ class TestAngularAccelerationRepr: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value, unit): @@ -57,9 +57,9 @@ class TestAngularAccelerationAdd: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -83,9 +83,9 @@ class TestAngularAccelerationSub: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -109,7 +109,7 @@ class TestAngularAccelerationMul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), times())) @@ -139,7 +139,7 @@ class TestAngularAccelerationRmul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), times())) @@ -159,7 +159,7 @@ def test_method(self, value, unit, multiplier): @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method_patch(self, value, unit): @@ -188,9 +188,9 @@ class TestAngularAccelerationTruediv: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), - divider = one_of(floats(allow_nan = False, allow_infinity = False), + divider = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), angular_accelerations())) @settings(max_examples = 100) def test_method(self, value, unit, divider): diff --git a/tests/test_units/test_angular_position/test_angular_position.py b/tests/test_units/test_angular_position/test_angular_position.py index d3f038d..e24ef44 100644 --- a/tests/test_units/test_angular_position/test_angular_position.py +++ b/tests/test_units/test_angular_position/test_angular_position.py @@ -13,7 +13,7 @@ class TestAngularPositionInit: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value, unit): @@ -42,7 +42,7 @@ class TestAngularPositionRepr: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value, unit): @@ -57,9 +57,9 @@ class TestAngularPositionAdd: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -83,9 +83,9 @@ class TestAngularPositionSub: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -109,7 +109,7 @@ class TestAngularPositionMul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) @settings(max_examples = 100) @@ -133,7 +133,7 @@ class TestAngularPositionRmul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) @settings(max_examples = 100) @@ -157,9 +157,9 @@ class TestAngularPositionTruediv: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), - divider = one_of(floats(allow_nan = False, allow_infinity = False), + divider = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), angular_positions())) @settings(max_examples = 100) def test_method(self, value, unit, divider): diff --git a/tests/test_units/test_angular_speed/test_angular_speed.py b/tests/test_units/test_angular_speed/test_angular_speed.py index e441dcd..eba12f3 100644 --- a/tests/test_units/test_angular_speed/test_angular_speed.py +++ b/tests/test_units/test_angular_speed/test_angular_speed.py @@ -13,7 +13,7 @@ class TestAngularSpeedInit: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value, unit): @@ -42,7 +42,7 @@ class TestAngularSpeedRepr: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value, unit): @@ -57,9 +57,9 @@ class TestAngularSpeedAdd: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -83,9 +83,9 @@ class TestAngularSpeedSub: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -109,7 +109,7 @@ class TestAngularSpeedMul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), times())) @@ -139,7 +139,7 @@ class TestAngularSpeedRmul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), times())) @@ -159,7 +159,7 @@ def test_method(self, value, unit, multiplier): @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method_patch(self, value, unit): @@ -188,9 +188,9 @@ class TestAngularSpeedTruediv: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), - divider = one_of(floats(allow_nan = False, allow_infinity = False), + divider = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), angular_speeds())) @settings(max_examples = 100) def test_method(self, value, unit, divider): diff --git a/tests/test_units/test_inertia_moment/test_inertia_moment.py b/tests/test_units/test_inertia_moment/test_inertia_moment.py index 28f6653..d94f183 100644 --- a/tests/test_units/test_inertia_moment/test_inertia_moment.py +++ b/tests/test_units/test_inertia_moment/test_inertia_moment.py @@ -13,7 +13,7 @@ class TestInertiaMomentInit: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = True), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value, unit): @@ -48,7 +48,7 @@ class TestInertiaMomentRepr: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = True), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value, unit): @@ -63,9 +63,9 @@ class TestInertiaMomentAdd: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -89,9 +89,9 @@ class TestInertiaMomentSub: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -122,7 +122,7 @@ class TestInertiaMomentMul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) @@ -152,7 +152,7 @@ class TestInertiaMomentRmul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) @@ -182,9 +182,9 @@ class TestInertiaMomentTruediv: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - divider = one_of(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + divider = one_of(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), inertia_moments())) @settings(max_examples = 100) def test_method(self, value, unit, divider): @@ -244,7 +244,7 @@ class TestInertiaMomentNe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): inertia_moment_1 = InertiaMoment(value = value, unit = unit) @@ -267,7 +267,7 @@ class TestInertiaMomentGt: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): inertia_moment_1 = InertiaMoment(value = value + gap, unit = unit) @@ -290,7 +290,7 @@ class TestInertiaMomentGe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): inertia_moment_1 = InertiaMoment(value = value + gap, unit = unit) @@ -313,7 +313,7 @@ class TestInertiaMomentLt: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): if value != 0: @@ -337,7 +337,7 @@ class TestInertiaMomentLe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): if value != 0: diff --git a/tests/test_units/test_time/test_time.py b/tests/test_units/test_time/test_time.py index 7d0834b..b905af5 100644 --- a/tests/test_units/test_time/test_time.py +++ b/tests/test_units/test_time/test_time.py @@ -59,9 +59,9 @@ class TestTimeAdd: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -85,9 +85,9 @@ class TestTimeSub: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -111,7 +111,7 @@ class TestTimeMul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), angular_speeds(), @@ -146,7 +146,7 @@ class TestTimeRmul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), angular_speeds(), @@ -171,7 +171,7 @@ def test_method(self, value, unit, multiplier): @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method_patch_1(self, value, unit): @@ -190,7 +190,7 @@ def __mul__(self, other: Time): return NotImplemented @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method_patch_2(self, value, unit): @@ -219,9 +219,9 @@ class TestTimeTruediv: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), - divider = one_of(floats(allow_nan = False, allow_infinity = False), + divider = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), times())) @settings(max_examples = 100) def test_method(self, value, unit, divider): @@ -281,7 +281,7 @@ class TestTimeNe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): time_1 = Time(value = value, unit = unit) @@ -304,7 +304,7 @@ class TestTimeGt: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): time_1 = Time(value = value + gap, unit = unit) @@ -327,7 +327,7 @@ class TestTimeGe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): time_1 = Time(value = value + gap, unit = unit) @@ -350,7 +350,7 @@ class TestTimeLt: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): if value != 0: @@ -374,7 +374,7 @@ class TestTimeLe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): if value != 0: diff --git a/tests/test_units/test_time_interval/test_time_interval.py b/tests/test_units/test_time_interval/test_time_interval.py index def7d76..e737b4c 100644 --- a/tests/test_units/test_time_interval/test_time_interval.py +++ b/tests/test_units/test_time_interval/test_time_interval.py @@ -197,9 +197,9 @@ class TestTimeIntervalTruediv: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - divider = one_of(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True), + divider = one_of(floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), time_intervals())) @settings(max_examples = 100) def test_method(self, value, unit, divider): @@ -259,7 +259,7 @@ class TestTimeIntervalNe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): time_interval_1 = TimeInterval(value = value, unit = unit) @@ -282,7 +282,7 @@ class TestTimeIntervalGt: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): time_interval_1 = TimeInterval(value = value + gap, unit = unit) @@ -305,7 +305,7 @@ class TestTimeIntervalGe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): time_interval_1 = TimeInterval(value = value + gap, unit = unit) @@ -328,7 +328,7 @@ class TestTimeIntervalLt: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): if value != 0: @@ -352,7 +352,7 @@ class TestTimeIntervalLe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): if value != 0: diff --git a/tests/test_units/test_torque/test_torque.py b/tests/test_units/test_torque/test_torque.py index a849386..df6e4cd 100644 --- a/tests/test_units/test_torque/test_torque.py +++ b/tests/test_units/test_torque/test_torque.py @@ -14,7 +14,7 @@ class TestTorqueInit: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value, unit): @@ -43,7 +43,7 @@ class TestTorqueRepr: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value, unit): @@ -58,9 +58,9 @@ class TestTorqueAdd: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -84,9 +84,9 @@ class TestTorqueSub: @mark.genuine - @given(value_1 = floats(allow_nan = False, allow_infinity = False), + @given(value_1 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_1 = sampled_from(elements = units_list), - value_2 = floats(allow_nan = False, allow_infinity = False), + value_2 = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit_2 = sampled_from(elements = units_list)) @settings(max_examples = 100) def test_method(self, value_1, unit_1, value_2, unit_2): @@ -110,7 +110,7 @@ class TestTorqueMul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) @settings(max_examples = 100) @@ -134,7 +134,7 @@ class TestTorqueRmul: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), multiplier = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000)) @settings(max_examples = 100) @@ -158,9 +158,9 @@ class TestTorqueTruediv: @mark.genuine - @given(value = floats(allow_nan = False, allow_infinity = False), + @given(value = floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), unit = sampled_from(elements = units_list), - divider = one_of(floats(allow_nan = False, allow_infinity = False), + divider = one_of(floats(allow_nan = False, allow_infinity = False, min_value = -1000, max_value = 1000), torques(), inertia_moments())) @settings(max_examples = 100) @@ -227,7 +227,7 @@ class TestTorqueNe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): torque_1 = Torque(value = value, unit = unit) @@ -250,7 +250,7 @@ class TestTorqueGt: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): torque_1 = Torque(value = value + gap, unit = unit) @@ -273,7 +273,7 @@ class TestTorqueGe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): torque_1 = Torque(value = value + gap, unit = unit) @@ -296,7 +296,7 @@ class TestTorqueLt: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 1e-10, exclude_min = True, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): if value != 0: @@ -320,7 +320,7 @@ class TestTorqueLe: @mark.genuine @given(value = floats(allow_nan = False, allow_infinity = False, max_value = 1000, min_value = -1000), unit = sampled_from(elements = units_list), - gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False)) + gap = floats(allow_nan = False, allow_infinity = False, min_value = 0, exclude_min = False, max_value = 1000)) @settings(max_examples = 100) def test_method(self, value, unit, gap): if value != 0: From 1f7fd0408c909113fbc56f7761cc7b774111836e Mon Sep 17 00:00:00 2001 From: Andrea Blengino Date: Sat, 14 Oct 2023 18:16:26 +0200 Subject: [PATCH 33/33] DOC: complete module documentation structure --- .../gear/SpurGear/angular_acceleration.rst | 7 +++++++ .../source/gear/SpurGear/angular_position.rst | 7 +++++++ docs/source/gear/SpurGear/angular_speed.rst | 7 +++++++ docs/source/gear/SpurGear/driven_by.rst | 7 +++++++ docs/source/gear/SpurGear/drives.rst | 7 +++++++ docs/source/gear/SpurGear/driving_torque.rst | 7 +++++++ docs/source/gear/SpurGear/external_torque.rst | 7 +++++++ docs/source/gear/SpurGear/index.rst | 17 ++++++++++++++++ docs/source/gear/SpurGear/inertia_moment.rst | 7 +++++++ docs/source/gear/SpurGear/load_torque.rst | 7 +++++++ .../gear/SpurGear/master_gear_efficiency.rst | 7 +++++++ .../gear/SpurGear/master_gear_ratio.rst | 7 +++++++ docs/source/gear/SpurGear/n_teeth.rst | 7 +++++++ docs/source/gear/SpurGear/name.rst | 7 +++++++ docs/source/gear/SpurGear/time_variables.rst | 7 +++++++ docs/source/gear/SpurGear/torque.rst | 7 +++++++ .../gear/SpurGear/update_time_variables.rst | 7 +++++++ docs/source/gearpy.rst | 1 + .../motor/DCMotor/angular_acceleration.rst | 7 +++++++ .../source/motor/DCMotor/angular_position.rst | 7 +++++++ docs/source/motor/DCMotor/angular_speed.rst | 7 +++++++ docs/source/motor/DCMotor/compute_torque.rst | 7 +++++++ docs/source/motor/DCMotor/drives.rst | 7 +++++++ docs/source/motor/DCMotor/driving_torque.rst | 7 +++++++ docs/source/motor/DCMotor/index.rst | 13 ++++++++++++ docs/source/motor/DCMotor/inertia_moment.rst | 7 +++++++ docs/source/motor/DCMotor/load_torque.rst | 7 +++++++ docs/source/motor/DCMotor/name.rst | 7 +++++++ docs/source/motor/DCMotor/time_variables.rst | 7 +++++++ docs/source/motor/DCMotor/torque.rst | 7 +++++++ .../motor/DCMotor/update_time_variables.rst | 7 +++++++ docs/source/solver/Solver/index.rst | 2 ++ docs/source/solver/Solver/run.rst | 7 +++++++ .../transmission/Transmission/chain.rst | 7 +++++++ .../transmission/Transmission/index.rst | 2 ++ .../units/AngularAcceleration/index.rst | 18 +++++++++++++++++ docs/source/units/AngularAcceleration/to.rst | 7 +++++++ .../source/units/AngularAcceleration/unit.rst | 7 +++++++ .../units/AngularAcceleration/value.rst | 7 +++++++ docs/source/units/AngularPosition/index.rst | 18 +++++++++++++++++ docs/source/units/AngularPosition/to.rst | 7 +++++++ docs/source/units/AngularPosition/unit.rst | 7 +++++++ docs/source/units/AngularPosition/value.rst | 7 +++++++ docs/source/units/AngularSpeed/index.rst | 18 +++++++++++++++++ docs/source/units/AngularSpeed/to.rst | 7 +++++++ docs/source/units/AngularSpeed/unit.rst | 7 +++++++ docs/source/units/AngularSpeed/value.rst | 7 +++++++ docs/source/units/InertiaMoment/index.rst | 18 +++++++++++++++++ docs/source/units/InertiaMoment/to.rst | 7 +++++++ docs/source/units/InertiaMoment/unit.rst | 7 +++++++ docs/source/units/InertiaMoment/value.rst | 7 +++++++ docs/source/units/Time/index.rst | 18 +++++++++++++++++ docs/source/units/Time/to.rst | 7 +++++++ docs/source/units/Time/unit.rst | 7 +++++++ docs/source/units/Time/value.rst | 7 +++++++ docs/source/units/TimeInterval/index.rst | 18 +++++++++++++++++ docs/source/units/TimeInterval/to.rst | 7 +++++++ docs/source/units/TimeInterval/unit.rst | 7 +++++++ docs/source/units/TimeInterval/value.rst | 7 +++++++ docs/source/units/Torque/index.rst | 18 +++++++++++++++++ docs/source/units/Torque/to.rst | 7 +++++++ docs/source/units/Torque/unit.rst | 7 +++++++ docs/source/units/Torque/value.rst | 7 +++++++ docs/source/units/index.rst | 20 +++++++++++++++++++ docs/source/utils/add_fixed_joint.rst | 7 +++++++ docs/source/utils/add_gear_mating.rst | 7 +++++++ docs/source/utils/index.rst | 3 ++- 67 files changed, 554 insertions(+), 1 deletion(-) create mode 100644 docs/source/gear/SpurGear/angular_acceleration.rst create mode 100644 docs/source/gear/SpurGear/angular_position.rst create mode 100644 docs/source/gear/SpurGear/angular_speed.rst create mode 100644 docs/source/gear/SpurGear/driven_by.rst create mode 100644 docs/source/gear/SpurGear/drives.rst create mode 100644 docs/source/gear/SpurGear/driving_torque.rst create mode 100644 docs/source/gear/SpurGear/external_torque.rst create mode 100644 docs/source/gear/SpurGear/inertia_moment.rst create mode 100644 docs/source/gear/SpurGear/load_torque.rst create mode 100644 docs/source/gear/SpurGear/master_gear_efficiency.rst create mode 100644 docs/source/gear/SpurGear/master_gear_ratio.rst create mode 100644 docs/source/gear/SpurGear/n_teeth.rst create mode 100644 docs/source/gear/SpurGear/name.rst create mode 100644 docs/source/gear/SpurGear/time_variables.rst create mode 100644 docs/source/gear/SpurGear/torque.rst create mode 100644 docs/source/gear/SpurGear/update_time_variables.rst create mode 100644 docs/source/motor/DCMotor/angular_acceleration.rst create mode 100644 docs/source/motor/DCMotor/angular_position.rst create mode 100644 docs/source/motor/DCMotor/angular_speed.rst create mode 100644 docs/source/motor/DCMotor/compute_torque.rst create mode 100644 docs/source/motor/DCMotor/drives.rst create mode 100644 docs/source/motor/DCMotor/driving_torque.rst create mode 100644 docs/source/motor/DCMotor/inertia_moment.rst create mode 100644 docs/source/motor/DCMotor/load_torque.rst create mode 100644 docs/source/motor/DCMotor/name.rst create mode 100644 docs/source/motor/DCMotor/time_variables.rst create mode 100644 docs/source/motor/DCMotor/torque.rst create mode 100644 docs/source/motor/DCMotor/update_time_variables.rst create mode 100644 docs/source/solver/Solver/run.rst create mode 100644 docs/source/transmission/Transmission/chain.rst create mode 100644 docs/source/units/AngularAcceleration/index.rst create mode 100644 docs/source/units/AngularAcceleration/to.rst create mode 100644 docs/source/units/AngularAcceleration/unit.rst create mode 100644 docs/source/units/AngularAcceleration/value.rst create mode 100644 docs/source/units/AngularPosition/index.rst create mode 100644 docs/source/units/AngularPosition/to.rst create mode 100644 docs/source/units/AngularPosition/unit.rst create mode 100644 docs/source/units/AngularPosition/value.rst create mode 100644 docs/source/units/AngularSpeed/index.rst create mode 100644 docs/source/units/AngularSpeed/to.rst create mode 100644 docs/source/units/AngularSpeed/unit.rst create mode 100644 docs/source/units/AngularSpeed/value.rst create mode 100644 docs/source/units/InertiaMoment/index.rst create mode 100644 docs/source/units/InertiaMoment/to.rst create mode 100644 docs/source/units/InertiaMoment/unit.rst create mode 100644 docs/source/units/InertiaMoment/value.rst create mode 100644 docs/source/units/Time/index.rst create mode 100644 docs/source/units/Time/to.rst create mode 100644 docs/source/units/Time/unit.rst create mode 100644 docs/source/units/Time/value.rst create mode 100644 docs/source/units/TimeInterval/index.rst create mode 100644 docs/source/units/TimeInterval/to.rst create mode 100644 docs/source/units/TimeInterval/unit.rst create mode 100644 docs/source/units/TimeInterval/value.rst create mode 100644 docs/source/units/Torque/index.rst create mode 100644 docs/source/units/Torque/to.rst create mode 100644 docs/source/units/Torque/unit.rst create mode 100644 docs/source/units/Torque/value.rst create mode 100644 docs/source/units/index.rst create mode 100644 docs/source/utils/add_fixed_joint.rst create mode 100644 docs/source/utils/add_gear_mating.rst diff --git a/docs/source/gear/SpurGear/angular_acceleration.rst b/docs/source/gear/SpurGear/angular_acceleration.rst new file mode 100644 index 0000000..5b4044e --- /dev/null +++ b/docs/source/gear/SpurGear/angular_acceleration.rst @@ -0,0 +1,7 @@ +angular_acceleration +==================== + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.angular_acceleration diff --git a/docs/source/gear/SpurGear/angular_position.rst b/docs/source/gear/SpurGear/angular_position.rst new file mode 100644 index 0000000..a1fd430 --- /dev/null +++ b/docs/source/gear/SpurGear/angular_position.rst @@ -0,0 +1,7 @@ +angular_position +================ + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.angular_position diff --git a/docs/source/gear/SpurGear/angular_speed.rst b/docs/source/gear/SpurGear/angular_speed.rst new file mode 100644 index 0000000..bd12b97 --- /dev/null +++ b/docs/source/gear/SpurGear/angular_speed.rst @@ -0,0 +1,7 @@ +angular_speed +============= + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.angular_speed diff --git a/docs/source/gear/SpurGear/driven_by.rst b/docs/source/gear/SpurGear/driven_by.rst new file mode 100644 index 0000000..35cac07 --- /dev/null +++ b/docs/source/gear/SpurGear/driven_by.rst @@ -0,0 +1,7 @@ +driven_by +========= + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.driven_by diff --git a/docs/source/gear/SpurGear/drives.rst b/docs/source/gear/SpurGear/drives.rst new file mode 100644 index 0000000..ada8b11 --- /dev/null +++ b/docs/source/gear/SpurGear/drives.rst @@ -0,0 +1,7 @@ +drives +====== + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.drives diff --git a/docs/source/gear/SpurGear/driving_torque.rst b/docs/source/gear/SpurGear/driving_torque.rst new file mode 100644 index 0000000..5f1a208 --- /dev/null +++ b/docs/source/gear/SpurGear/driving_torque.rst @@ -0,0 +1,7 @@ +driving_torque +============== + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.driving_torque diff --git a/docs/source/gear/SpurGear/external_torque.rst b/docs/source/gear/SpurGear/external_torque.rst new file mode 100644 index 0000000..6672824 --- /dev/null +++ b/docs/source/gear/SpurGear/external_torque.rst @@ -0,0 +1,7 @@ +external_torque +=============== + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.driving_torque diff --git a/docs/source/gear/SpurGear/index.rst b/docs/source/gear/SpurGear/index.rst index f45c8a8..9384739 100644 --- a/docs/source/gear/SpurGear/index.rst +++ b/docs/source/gear/SpurGear/index.rst @@ -12,3 +12,20 @@ SpurGear .. toctree:: :hidden: + + angular_acceleration + angular_position + angular_speed + driven_by + drives + driving_torque + external_torque + inertia_moment + load_torque + master_gear_efficiency + master_gear_ratio + n_teeth + name + time_variables + torque + update_time_variables diff --git a/docs/source/gear/SpurGear/inertia_moment.rst b/docs/source/gear/SpurGear/inertia_moment.rst new file mode 100644 index 0000000..e1e0ca0 --- /dev/null +++ b/docs/source/gear/SpurGear/inertia_moment.rst @@ -0,0 +1,7 @@ +inertia_moment +============== + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.inertia_moment diff --git a/docs/source/gear/SpurGear/load_torque.rst b/docs/source/gear/SpurGear/load_torque.rst new file mode 100644 index 0000000..d88afda --- /dev/null +++ b/docs/source/gear/SpurGear/load_torque.rst @@ -0,0 +1,7 @@ +load_torque +=========== + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.load_torque diff --git a/docs/source/gear/SpurGear/master_gear_efficiency.rst b/docs/source/gear/SpurGear/master_gear_efficiency.rst new file mode 100644 index 0000000..771d454 --- /dev/null +++ b/docs/source/gear/SpurGear/master_gear_efficiency.rst @@ -0,0 +1,7 @@ +master_gear_efficiency +====================== + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.master_gear_efficiency diff --git a/docs/source/gear/SpurGear/master_gear_ratio.rst b/docs/source/gear/SpurGear/master_gear_ratio.rst new file mode 100644 index 0000000..f46d585 --- /dev/null +++ b/docs/source/gear/SpurGear/master_gear_ratio.rst @@ -0,0 +1,7 @@ +master_gear_ratio +================= + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.master_gear_ratio diff --git a/docs/source/gear/SpurGear/n_teeth.rst b/docs/source/gear/SpurGear/n_teeth.rst new file mode 100644 index 0000000..8203ac6 --- /dev/null +++ b/docs/source/gear/SpurGear/n_teeth.rst @@ -0,0 +1,7 @@ +n_teeth +======= + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.n_teeth diff --git a/docs/source/gear/SpurGear/name.rst b/docs/source/gear/SpurGear/name.rst new file mode 100644 index 0000000..c5b1841 --- /dev/null +++ b/docs/source/gear/SpurGear/name.rst @@ -0,0 +1,7 @@ +name +==== + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.name diff --git a/docs/source/gear/SpurGear/time_variables.rst b/docs/source/gear/SpurGear/time_variables.rst new file mode 100644 index 0000000..4203162 --- /dev/null +++ b/docs/source/gear/SpurGear/time_variables.rst @@ -0,0 +1,7 @@ +time_variables +============== + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.time_variables diff --git a/docs/source/gear/SpurGear/torque.rst b/docs/source/gear/SpurGear/torque.rst new file mode 100644 index 0000000..da048c6 --- /dev/null +++ b/docs/source/gear/SpurGear/torque.rst @@ -0,0 +1,7 @@ +torque +====== + + +.. currentmodule:: gearpy.gear.spur_gear + +.. autoproperty:: SpurGear.torque diff --git a/docs/source/gear/SpurGear/update_time_variables.rst b/docs/source/gear/SpurGear/update_time_variables.rst new file mode 100644 index 0000000..73a9185 --- /dev/null +++ b/docs/source/gear/SpurGear/update_time_variables.rst @@ -0,0 +1,7 @@ +update_time_variables +===================== + + +.. currentmodule:: gearpy.gear.spur_gear + +.. automethod:: SpurGear.update_time_variables diff --git a/docs/source/gearpy.rst b/docs/source/gearpy.rst index 103f5fa..c16cb85 100644 --- a/docs/source/gearpy.rst +++ b/docs/source/gearpy.rst @@ -9,4 +9,5 @@ gearpy motor/index solver/index transmission/index + units/index utils/index \ No newline at end of file diff --git a/docs/source/motor/DCMotor/angular_acceleration.rst b/docs/source/motor/DCMotor/angular_acceleration.rst new file mode 100644 index 0000000..9ccb018 --- /dev/null +++ b/docs/source/motor/DCMotor/angular_acceleration.rst @@ -0,0 +1,7 @@ +angular_acceleration +==================== + + +.. currentmodule:: gearpy.motor.dc_motor + +.. autoproperty:: DCMotor.angular_acceleration diff --git a/docs/source/motor/DCMotor/angular_position.rst b/docs/source/motor/DCMotor/angular_position.rst new file mode 100644 index 0000000..e015d79 --- /dev/null +++ b/docs/source/motor/DCMotor/angular_position.rst @@ -0,0 +1,7 @@ +angular_position +================ + + +.. currentmodule:: gearpy.motor.dc_motor + +.. autoproperty:: DCMotor.angular_position diff --git a/docs/source/motor/DCMotor/angular_speed.rst b/docs/source/motor/DCMotor/angular_speed.rst new file mode 100644 index 0000000..907e51e --- /dev/null +++ b/docs/source/motor/DCMotor/angular_speed.rst @@ -0,0 +1,7 @@ +angular_speed +============= + + +.. currentmodule:: gearpy.motor.dc_motor + +.. autoproperty:: DCMotor.angular_speed diff --git a/docs/source/motor/DCMotor/compute_torque.rst b/docs/source/motor/DCMotor/compute_torque.rst new file mode 100644 index 0000000..066ec0c --- /dev/null +++ b/docs/source/motor/DCMotor/compute_torque.rst @@ -0,0 +1,7 @@ +compute_torque +============== + + +.. currentmodule:: gearpy.motor.dc_motor + +.. automethod:: DCMotor.compute_torque diff --git a/docs/source/motor/DCMotor/drives.rst b/docs/source/motor/DCMotor/drives.rst new file mode 100644 index 0000000..e0b717e --- /dev/null +++ b/docs/source/motor/DCMotor/drives.rst @@ -0,0 +1,7 @@ +drives +====== + + +.. currentmodule:: gearpy.motor.dc_motor + +.. autoproperty:: DCMotor.drives diff --git a/docs/source/motor/DCMotor/driving_torque.rst b/docs/source/motor/DCMotor/driving_torque.rst new file mode 100644 index 0000000..2d949e7 --- /dev/null +++ b/docs/source/motor/DCMotor/driving_torque.rst @@ -0,0 +1,7 @@ +driving_torque +============== + + +.. currentmodule:: gearpy.motor.dc_motor + +.. autoproperty:: DCMotor.driving_torque diff --git a/docs/source/motor/DCMotor/index.rst b/docs/source/motor/DCMotor/index.rst index 584671b..88b82a9 100644 --- a/docs/source/motor/DCMotor/index.rst +++ b/docs/source/motor/DCMotor/index.rst @@ -12,3 +12,16 @@ DCMotor .. toctree:: :hidden: + + angular_acceleration + angular_position + angular_speed + compute_torque + drives + driving_torque + inertia_moment + load_torque + name + time_variables + torque + update_time_variables diff --git a/docs/source/motor/DCMotor/inertia_moment.rst b/docs/source/motor/DCMotor/inertia_moment.rst new file mode 100644 index 0000000..15b0c75 --- /dev/null +++ b/docs/source/motor/DCMotor/inertia_moment.rst @@ -0,0 +1,7 @@ +inertia_moment +============== + + +.. currentmodule:: gearpy.motor.dc_motor + +.. autoproperty:: DCMotor.inertia_moment diff --git a/docs/source/motor/DCMotor/load_torque.rst b/docs/source/motor/DCMotor/load_torque.rst new file mode 100644 index 0000000..dc6c298 --- /dev/null +++ b/docs/source/motor/DCMotor/load_torque.rst @@ -0,0 +1,7 @@ +load_torque +=========== + + +.. currentmodule:: gearpy.motor.dc_motor + +.. autoproperty:: DCMotor.load_torque diff --git a/docs/source/motor/DCMotor/name.rst b/docs/source/motor/DCMotor/name.rst new file mode 100644 index 0000000..df5faee --- /dev/null +++ b/docs/source/motor/DCMotor/name.rst @@ -0,0 +1,7 @@ +name +==== + + +.. currentmodule:: gearpy.motor.dc_motor + +.. autoproperty:: DCMotor.name diff --git a/docs/source/motor/DCMotor/time_variables.rst b/docs/source/motor/DCMotor/time_variables.rst new file mode 100644 index 0000000..00e70f0 --- /dev/null +++ b/docs/source/motor/DCMotor/time_variables.rst @@ -0,0 +1,7 @@ +time_variables +============== + + +.. currentmodule:: gearpy.motor.dc_motor + +.. autoproperty:: DCMotor.time_variables diff --git a/docs/source/motor/DCMotor/torque.rst b/docs/source/motor/DCMotor/torque.rst new file mode 100644 index 0000000..2b62fdb --- /dev/null +++ b/docs/source/motor/DCMotor/torque.rst @@ -0,0 +1,7 @@ +torque +====== + + +.. currentmodule:: gearpy.motor.dc_motor + +.. autoproperty:: DCMotor.torque diff --git a/docs/source/motor/DCMotor/update_time_variables.rst b/docs/source/motor/DCMotor/update_time_variables.rst new file mode 100644 index 0000000..1642de9 --- /dev/null +++ b/docs/source/motor/DCMotor/update_time_variables.rst @@ -0,0 +1,7 @@ +update_time_variables +===================== + + +.. currentmodule:: gearpy.motor.dc_motor + +.. automethod:: DCMotor.update_time_variables diff --git a/docs/source/solver/Solver/index.rst b/docs/source/solver/Solver/index.rst index 2aad9bc..e2b5ea5 100644 --- a/docs/source/solver/Solver/index.rst +++ b/docs/source/solver/Solver/index.rst @@ -12,3 +12,5 @@ Solver .. toctree:: :hidden: + + run diff --git a/docs/source/solver/Solver/run.rst b/docs/source/solver/Solver/run.rst new file mode 100644 index 0000000..7e0b620 --- /dev/null +++ b/docs/source/solver/Solver/run.rst @@ -0,0 +1,7 @@ +run +=== + + +.. currentmodule:: gearpy.solver.solver + +.. automethod:: Solver.run diff --git a/docs/source/transmission/Transmission/chain.rst b/docs/source/transmission/Transmission/chain.rst new file mode 100644 index 0000000..9c494e7 --- /dev/null +++ b/docs/source/transmission/Transmission/chain.rst @@ -0,0 +1,7 @@ +chain +===== + + +.. currentmodule:: gearpy.transmission.transmission + +.. autoproperty:: Transmission.chain diff --git a/docs/source/transmission/Transmission/index.rst b/docs/source/transmission/Transmission/index.rst index 416dc6c..ab46f85 100644 --- a/docs/source/transmission/Transmission/index.rst +++ b/docs/source/transmission/Transmission/index.rst @@ -12,3 +12,5 @@ Transmission .. toctree:: :hidden: + + chain diff --git a/docs/source/units/AngularAcceleration/index.rst b/docs/source/units/AngularAcceleration/index.rst new file mode 100644 index 0000000..bc592de --- /dev/null +++ b/docs/source/units/AngularAcceleration/index.rst @@ -0,0 +1,18 @@ +AngularAcceleration +=================== + + +.. currentmodule:: gearpy.units +.. autoclass:: gearpy.units.concrete_units.AngularAcceleration + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: + + to + unit + value diff --git a/docs/source/units/AngularAcceleration/to.rst b/docs/source/units/AngularAcceleration/to.rst new file mode 100644 index 0000000..4283900 --- /dev/null +++ b/docs/source/units/AngularAcceleration/to.rst @@ -0,0 +1,7 @@ +to +== + + +.. currentmodule:: gearpy.units.concrete_units + +.. automethod:: AngularAcceleration.to diff --git a/docs/source/units/AngularAcceleration/unit.rst b/docs/source/units/AngularAcceleration/unit.rst new file mode 100644 index 0000000..5b4158e --- /dev/null +++ b/docs/source/units/AngularAcceleration/unit.rst @@ -0,0 +1,7 @@ +unit +==== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: AngularAcceleration.unit diff --git a/docs/source/units/AngularAcceleration/value.rst b/docs/source/units/AngularAcceleration/value.rst new file mode 100644 index 0000000..0e5e0bd --- /dev/null +++ b/docs/source/units/AngularAcceleration/value.rst @@ -0,0 +1,7 @@ +value +===== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: AngularAcceleration.value diff --git a/docs/source/units/AngularPosition/index.rst b/docs/source/units/AngularPosition/index.rst new file mode 100644 index 0000000..3a0317d --- /dev/null +++ b/docs/source/units/AngularPosition/index.rst @@ -0,0 +1,18 @@ +AngularPosition +=============== + + +.. currentmodule:: gearpy.units +.. autoclass:: gearpy.units.concrete_units.AngularPosition + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: + + to + unit + value diff --git a/docs/source/units/AngularPosition/to.rst b/docs/source/units/AngularPosition/to.rst new file mode 100644 index 0000000..418a226 --- /dev/null +++ b/docs/source/units/AngularPosition/to.rst @@ -0,0 +1,7 @@ +to +== + + +.. currentmodule:: gearpy.units.concrete_units + +.. automethod:: AngularPosition.to diff --git a/docs/source/units/AngularPosition/unit.rst b/docs/source/units/AngularPosition/unit.rst new file mode 100644 index 0000000..e94ce47 --- /dev/null +++ b/docs/source/units/AngularPosition/unit.rst @@ -0,0 +1,7 @@ +unit +==== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: AngularPosition.unit diff --git a/docs/source/units/AngularPosition/value.rst b/docs/source/units/AngularPosition/value.rst new file mode 100644 index 0000000..88b8ae3 --- /dev/null +++ b/docs/source/units/AngularPosition/value.rst @@ -0,0 +1,7 @@ +value +===== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: AngularPosition.value diff --git a/docs/source/units/AngularSpeed/index.rst b/docs/source/units/AngularSpeed/index.rst new file mode 100644 index 0000000..0c44ed8 --- /dev/null +++ b/docs/source/units/AngularSpeed/index.rst @@ -0,0 +1,18 @@ +AngularSpeed +============ + + +.. currentmodule:: gearpy.units +.. autoclass:: gearpy.units.concrete_units.AngularSpeed + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: + + to + unit + value diff --git a/docs/source/units/AngularSpeed/to.rst b/docs/source/units/AngularSpeed/to.rst new file mode 100644 index 0000000..2bba839 --- /dev/null +++ b/docs/source/units/AngularSpeed/to.rst @@ -0,0 +1,7 @@ +to +== + + +.. currentmodule:: gearpy.units.concrete_units + +.. automethod:: AngularSpeed.to diff --git a/docs/source/units/AngularSpeed/unit.rst b/docs/source/units/AngularSpeed/unit.rst new file mode 100644 index 0000000..ad691e6 --- /dev/null +++ b/docs/source/units/AngularSpeed/unit.rst @@ -0,0 +1,7 @@ +unit +==== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: AngularSpeed.unit diff --git a/docs/source/units/AngularSpeed/value.rst b/docs/source/units/AngularSpeed/value.rst new file mode 100644 index 0000000..f41067c --- /dev/null +++ b/docs/source/units/AngularSpeed/value.rst @@ -0,0 +1,7 @@ +value +===== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: AngularSpeed.value diff --git a/docs/source/units/InertiaMoment/index.rst b/docs/source/units/InertiaMoment/index.rst new file mode 100644 index 0000000..50afd70 --- /dev/null +++ b/docs/source/units/InertiaMoment/index.rst @@ -0,0 +1,18 @@ +InertiaMoment +============= + + +.. currentmodule:: gearpy.units +.. autoclass:: gearpy.units.concrete_units.InertiaMoment + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: + + to + unit + value diff --git a/docs/source/units/InertiaMoment/to.rst b/docs/source/units/InertiaMoment/to.rst new file mode 100644 index 0000000..92499bd --- /dev/null +++ b/docs/source/units/InertiaMoment/to.rst @@ -0,0 +1,7 @@ +to +== + + +.. currentmodule:: gearpy.units.concrete_units + +.. automethod:: InertiaMoment.to diff --git a/docs/source/units/InertiaMoment/unit.rst b/docs/source/units/InertiaMoment/unit.rst new file mode 100644 index 0000000..240d09c --- /dev/null +++ b/docs/source/units/InertiaMoment/unit.rst @@ -0,0 +1,7 @@ +unit +==== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: InertiaMoment.unit diff --git a/docs/source/units/InertiaMoment/value.rst b/docs/source/units/InertiaMoment/value.rst new file mode 100644 index 0000000..c512d3d --- /dev/null +++ b/docs/source/units/InertiaMoment/value.rst @@ -0,0 +1,7 @@ +value +===== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: InertiaMoment.value diff --git a/docs/source/units/Time/index.rst b/docs/source/units/Time/index.rst new file mode 100644 index 0000000..f5ebcfa --- /dev/null +++ b/docs/source/units/Time/index.rst @@ -0,0 +1,18 @@ +Time +==== + + +.. currentmodule:: gearpy.units +.. autoclass:: gearpy.units.concrete_units.Time + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: + + to + unit + value diff --git a/docs/source/units/Time/to.rst b/docs/source/units/Time/to.rst new file mode 100644 index 0000000..6cb331e --- /dev/null +++ b/docs/source/units/Time/to.rst @@ -0,0 +1,7 @@ +to +== + + +.. currentmodule:: gearpy.units.concrete_units + +.. automethod:: Time.to diff --git a/docs/source/units/Time/unit.rst b/docs/source/units/Time/unit.rst new file mode 100644 index 0000000..8a9db29 --- /dev/null +++ b/docs/source/units/Time/unit.rst @@ -0,0 +1,7 @@ +unit +==== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: Time.unit diff --git a/docs/source/units/Time/value.rst b/docs/source/units/Time/value.rst new file mode 100644 index 0000000..8771b64 --- /dev/null +++ b/docs/source/units/Time/value.rst @@ -0,0 +1,7 @@ +value +===== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: Time.value diff --git a/docs/source/units/TimeInterval/index.rst b/docs/source/units/TimeInterval/index.rst new file mode 100644 index 0000000..4c5a651 --- /dev/null +++ b/docs/source/units/TimeInterval/index.rst @@ -0,0 +1,18 @@ +TimeInterval +============ + + +.. currentmodule:: gearpy.units +.. autoclass:: gearpy.units.concrete_units.TimeInterval + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: + + to + unit + value diff --git a/docs/source/units/TimeInterval/to.rst b/docs/source/units/TimeInterval/to.rst new file mode 100644 index 0000000..2354e67 --- /dev/null +++ b/docs/source/units/TimeInterval/to.rst @@ -0,0 +1,7 @@ +to +== + + +.. currentmodule:: gearpy.units.concrete_units + +.. automethod:: TimeInterval.to diff --git a/docs/source/units/TimeInterval/unit.rst b/docs/source/units/TimeInterval/unit.rst new file mode 100644 index 0000000..fead4d8 --- /dev/null +++ b/docs/source/units/TimeInterval/unit.rst @@ -0,0 +1,7 @@ +unit +==== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: TimeInterval.unit diff --git a/docs/source/units/TimeInterval/value.rst b/docs/source/units/TimeInterval/value.rst new file mode 100644 index 0000000..8ec820a --- /dev/null +++ b/docs/source/units/TimeInterval/value.rst @@ -0,0 +1,7 @@ +value +===== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: TimeInterval.value diff --git a/docs/source/units/Torque/index.rst b/docs/source/units/Torque/index.rst new file mode 100644 index 0000000..cfeeb09 --- /dev/null +++ b/docs/source/units/Torque/index.rst @@ -0,0 +1,18 @@ +Torque +====== + + +.. currentmodule:: gearpy.units +.. autoclass:: gearpy.units.concrete_units.Torque + :members: + :undoc-members: + :show-inheritance: + :no-index: + + +.. toctree:: + :hidden: + + to + unit + value diff --git a/docs/source/units/Torque/to.rst b/docs/source/units/Torque/to.rst new file mode 100644 index 0000000..ab2edbf --- /dev/null +++ b/docs/source/units/Torque/to.rst @@ -0,0 +1,7 @@ +to +== + + +.. currentmodule:: gearpy.units.concrete_units + +.. automethod:: Torque.to diff --git a/docs/source/units/Torque/unit.rst b/docs/source/units/Torque/unit.rst new file mode 100644 index 0000000..348e204 --- /dev/null +++ b/docs/source/units/Torque/unit.rst @@ -0,0 +1,7 @@ +unit +==== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: Torque.unit diff --git a/docs/source/units/Torque/value.rst b/docs/source/units/Torque/value.rst new file mode 100644 index 0000000..731aa9b --- /dev/null +++ b/docs/source/units/Torque/value.rst @@ -0,0 +1,7 @@ +value +===== + + +.. currentmodule:: gearpy.units.concrete_units + +.. autoproperty:: Torque.value diff --git a/docs/source/units/index.rst b/docs/source/units/index.rst new file mode 100644 index 0000000..41cc499 --- /dev/null +++ b/docs/source/units/index.rst @@ -0,0 +1,20 @@ +units +===== + + +.. automodule:: gearpy.units + :members: + :undoc-members: + :show-inheritance: + + +.. toctree:: + :hidden: + + AngularAcceleration/index + AngularPosition/index + AngularSpeed/index + InertiaMoment/index + Time/index + TimeInterval/index + Torque/index diff --git a/docs/source/utils/add_fixed_joint.rst b/docs/source/utils/add_fixed_joint.rst new file mode 100644 index 0000000..e623b23 --- /dev/null +++ b/docs/source/utils/add_fixed_joint.rst @@ -0,0 +1,7 @@ +add_fixed_joint +=============== + + +.. currentmodule:: gearpy.utils.relations + +.. autofunction:: add_fixed_joint diff --git a/docs/source/utils/add_gear_mating.rst b/docs/source/utils/add_gear_mating.rst new file mode 100644 index 0000000..cb7d9e3 --- /dev/null +++ b/docs/source/utils/add_gear_mating.rst @@ -0,0 +1,7 @@ +add_gear_mating +=============== + + +.. currentmodule:: gearpy.utils.relations + +.. autofunction:: add_gear_mating diff --git a/docs/source/utils/index.rst b/docs/source/utils/index.rst index f600723..e0b9b76 100644 --- a/docs/source/utils/index.rst +++ b/docs/source/utils/index.rst @@ -11,4 +11,5 @@ utils .. toctree:: :hidden: - + add_fixed_joint + add_gear_mating