Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: floordiv, mod, divmod #943 #946

Closed
wants to merge 2 commits into from

Conversation

westurner
Copy link
Contributor

@westurner westurner commented Dec 21, 2019

...

This is surely the wrong way to do this:
The hasattr(obj, 'dimensionless') check is probably not correct?

IDK how to get math.floor to return a quantity. Modifying __float__ to return a non-Quantity float results in further errors.

Why is floordiv returning 10.0 in TestQuantityBasicMath.test_nparray?

@pytest.mark.parametrize might make it easier to identify the test failures by creating named test cases for each combination. There's probably a historical or a technical reason for the current approach?

This is already beyond my level of comprehension of the pint internal API. I'd be grateful for any help or "just move" https://stackoverflow.com/questions/14947789/github-clone-from-pull-request

@westurner
Copy link
Contributor Author

The e.g. __divmod__ / __rdivmod__ variants could likely be solved with a decorator that swaps self and other and a proto-function?

@westurner
Copy link
Contributor Author

Here's the output from `pytest ./test_quantity.py`:
$ pytest test_quantity.py 
==================================================================== test session starts =====================================================================
platform linux -- Python 3.6.8, pytest-5.3.0, py-1.8.0, pluggy-0.12.0
rootdir: /home/wturner/-wrk/-ce37/woodworking/src/pint
collected 436 items                                                                                                                                          

test_quantity.py .....................................FFF............................................................................................. [ 30%]
...................................................................................................................................................... [ 64%]
...................................................................................................................................................... [ 99%]
...                                                                                                                                                    [100%]

========================================================================== FAILURES ==========================================================================
______________________________________________________________ TestQuantityBasicMath.test_float ______________________________________________________________

self = <pint.testsuite.test_quantity.TestQuantityBasicMath testMethod=test_float>

    def test_float(self):
>       self._test_numeric(1.0, self._test_not_inplace)

test_quantity.py:798: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test_quantity.py:794: in _test_numeric
    self._test_quantity_divmod()
test_quantity.py:785: in _test_quantity_divmod
    self._test_quantity_divmod_one("10*meter", 3)
test_quantity.py:752: in _test_quantity_divmod_one
    self.assertEqual(q, math.floor(q))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(3, 'meter')>

    def __float__(self):
        if self.dimensionless:
            return float(self._convert_magnitude_not_inplace(UnitsContainer()))
        # else: # ( for math.floor !? )
        #     return float(self._magnitude)
>       raise DimensionalityError(self._units, "dimensionless")
E       pint.errors.DimensionalityError: Cannot convert from 'meter' to 'dimensionless'

../quantity.py:669: DimensionalityError
____________________________________________________________ TestQuantityBasicMath.test_fraction _____________________________________________________________

self = <pint.testsuite.test_quantity.TestQuantityBasicMath testMethod=test_fraction>

    def test_fraction(self):
        import fractions
    
>       self._test_numeric(fractions.Fraction(1, 1), self._test_not_inplace)

test_quantity.py:803: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test_quantity.py:794: in _test_numeric
    self._test_quantity_divmod()
test_quantity.py:785: in _test_quantity_divmod
    self._test_quantity_divmod_one("10*meter", 3)
test_quantity.py:752: in _test_quantity_divmod_one
    self.assertEqual(q, math.floor(q))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(3, 'meter')>

    def __float__(self):
        if self.dimensionless:
            return float(self._convert_magnitude_not_inplace(UnitsContainer()))
        # else: # ( for math.floor !? )
        #     return float(self._magnitude)
>       raise DimensionalityError(self._units, "dimensionless")
E       pint.errors.DimensionalityError: Cannot convert from 'meter' to 'dimensionless'

../quantity.py:669: DimensionalityError
_____________________________________________________________ TestQuantityBasicMath.test_nparray _____________________________________________________________

self = <pint.testsuite.test_quantity.TestQuantityBasicMath testMethod=test_nparray>

    @helpers.requires_numpy()
    def test_nparray(self):
>       self._test_numeric(np.ones((1, 3)), self._test_inplace)

test_quantity.py:807: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test_quantity.py:792: in _test_numeric
    self._test_quantity_floordiv(unit, self._test_not_inplace)
test_quantity.py:725: in _test_quantity_floordiv
    func(op.ifloordiv, unit * 10, 3, 3 * unit, unit)
test_quantity.py:650: in _test_not_inplace
    self.assertQuantityAlmostEqual(value1, value1_cpy)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pint.testsuite.test_quantity.TestQuantityBasicMath testMethod=test_nparray>, first = array([[3., 3., 3.]]), second = array([[10., 10., 10.]])
rtol = 1e-07, atol = 0, msg = 'Comparing array([[3., 3., 3.]]) and array([[10., 10., 10.]]). '

    def assertQuantityAlmostEqual(self, first, second, rtol=1e-07, atol=0, msg=None):
        if msg is None:
            msg = "Comparing %r and %r. " % (first, second)
    
        m1, m2 = self._get_comparable_magnitudes(first, second, msg)
    
        if isinstance(m1, ndarray) or isinstance(m2, ndarray):
>           np.testing.assert_allclose(m1, m2, rtol=rtol, atol=atol, err_msg=msg)
E           AssertionError: 
E           Not equal to tolerance rtol=1e-07, atol=0
E           Comparing array([[3., 3., 3.]]) and array([[10., 10., 10.]]). 
E           Mismatch: 100%
E           Max absolute difference: 7.
E           Max relative difference: 0.7
E            x: array([[3., 3., 3.]])
E            y: array([[10., 10., 10.]])

__init__.py:114: AssertionError
====================================================================== warnings summary ======================================================================
pint/testsuite/test_quantity.py::TestQuantity::test_convert_numpy
  /home/wturner/-wrk/-ce37/woodworking/src/pint/pint/quantity.py:200: BehaviorChangeWarning: The way Pint handles NumPy operations has changed with the
  implementation of NEP 18. Unimplemented NumPy operations will now fail instead of making
  assumptions about units. Some functions, eg concat, will now return Quanties with units, where
  they returned ndarrays previously. See https://github.com/hgrecco/pint/pull/905.
  
  To hide this warning, wrap your first creation of an array Quantity with
  warnings.catch_warnings(), like the following:
  
  import numpy as np
  import warnings
  from pint import Quantity
  
  with warnings.catch_warnings():
      warnings.simplefilter("ignore")
      Quantity([])
  
  To disable the new behavior, see
  https://www.numpy.org/neps/nep-0018-array-function-protocol.html#implementation
  
    warnings.warn(array_function_change_msg, BehaviorChangeWarning)

pint/testsuite/test_quantity.py::TestCompareZero::test_equal_zero_NP
pint/testsuite/test_quantity.py::TestCompareZero::test_equal_zero_NP
  /home/wturner/-wrk/-ce37/woodworking/src/pint/pint/compat.py:143: DeprecationWarning: elementwise comparison failed; this will raise an error in the future.
    out = first == second

-- Docs: https://docs.pytest.org/en/latest/warnings.html
========================================================= 3 failed, 433 passed, 3 warnings in 5.58s ==========================================================
#  pytest test_quantity.py 

@westurner westurner changed the title WIP: __floordiv__, __mod__, __divmod__ #943 WIP: floordiv, mod, divmod #943 Dec 21, 2019
@jthielen
Copy link
Contributor

@westurner Now that #954 is merged, @pytest.mark.parametrize should be available to use here.

@westurner
Copy link
Contributor Author

westurner commented Dec 27, 2019

@hgrecco hgrecco added this to the 0.10 milestone Dec 27, 2019
@hgrecco
Copy link
Owner

hgrecco commented Dec 30, 2019

@westurner Any chance of getting this fixed in the upcoming days? It would be great to include this in 0.10

@westurner
Copy link
Contributor Author

westurner commented Dec 31, 2019 via email

@hgrecco hgrecco modified the milestones: 0.10, 0.11 Jan 7, 2020
@hgrecco hgrecco modified the milestones: 0.11, 0.12 Feb 19, 2020
@tecki
Copy link

tecki commented Jun 3, 2020

Please do not merge this PR. I is wrong, as I commented at the corresponding issue.

@hgrecco hgrecco mentioned this pull request Feb 24, 2022
21 tasks
@jules-ch
Copy link
Collaborator

Closing

@jules-ch jules-ch closed this Feb 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

floordiv (and divmod, modulo, math.floor) raise DimensionalityError
6 participants