Skip to content

WIP: floordiv, mod, divmod #943#946

Closed
westurner wants to merge 2 commits into
hgrecco:masterfrom
westurner:issue943_floordiv_modulo
Closed

WIP: floordiv, mod, divmod #943#946
westurner wants to merge 2 commits into
hgrecco:masterfrom
westurner:issue943_floordiv_modulo

Conversation

@westurner

@westurner westurner commented Dec 21, 2019

Copy link
Copy Markdown
Contributor

...

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
Contributor

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

@westurner

westurner commented Dec 27, 2019

Copy link
Copy Markdown
Contributor Author

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

hgrecco commented Dec 30, 2019

Copy link
Copy Markdown
Owner

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

@westurner

westurner commented Dec 31, 2019 via email

Copy link
Copy Markdown
Contributor Author

@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

tecki commented Jun 3, 2020

Copy link
Copy Markdown

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
Copy Markdown
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