-
Couldn't load subscription status.
- Fork 20
Allow multiplying Quantity by float
#875
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
Changes from all commits
f78393f
7c754a6
a4e879a
7eaee36
5118985
9d45a46
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -544,31 +544,69 @@ def test_abs() -> None: | |
| assert abs(-pct) == Percentage.from_fraction(30) | ||
|
|
||
|
|
||
| def test_quantity_multiplied_with_precentage() -> None: | ||
| @pytest.mark.parametrize("quantity_ctor", _QUANTITY_CTORS + [Quantity]) | ||
| # Use a small amount to avoid long running tests, we have too many combinations | ||
| @hypothesis.settings(max_examples=10) | ||
| @hypothesis.given( | ||
| quantity_value=st.floats( | ||
| allow_infinity=False, | ||
| allow_nan=False, | ||
| allow_subnormal=False, | ||
| # We need to set this because otherwise constructors with big exponents will | ||
| # cause the value to be too big for the float type, and the test will fail. | ||
| max_value=1e298, | ||
| min_value=-1e298, | ||
| ), | ||
| percent=st.floats(allow_infinity=False, allow_nan=False, allow_subnormal=False), | ||
| ) | ||
| def test_quantity_multiplied_with_precentage( | ||
| quantity_ctor: type[Quantity], quantity_value: float, percent: float | ||
| ) -> None: | ||
| """Test the multiplication of all quantities with percentage.""" | ||
| percentage = Percentage.from_percent(50) | ||
| power = Power.from_watts(1000.0) | ||
| voltage = Voltage.from_volts(230.0) | ||
| current = Current.from_amperes(2) | ||
| energy = Energy.from_kilowatt_hours(12) | ||
| percentage_ = Percentage.from_percent(50) | ||
|
|
||
| assert power * percentage == Power.from_watts(500.0) | ||
| assert voltage * percentage == Voltage.from_volts(115.0) | ||
| assert current * percentage == Current.from_amperes(1) | ||
| assert energy * percentage == Energy.from_kilowatt_hours(6) | ||
| assert percentage_ * percentage == Percentage.from_percent(25) | ||
|
|
||
| power *= percentage | ||
| assert power == Power.from_watts(500.0) | ||
| voltage *= percentage | ||
| assert voltage == Voltage.from_volts(115.0) | ||
| current *= percentage | ||
| assert current == Current.from_amperes(1) | ||
| energy *= percentage | ||
| assert energy == Energy.from_kilowatt_hours(6) | ||
| percentage_ *= percentage | ||
| assert percentage_ == Percentage.from_percent(25) | ||
| percentage = Percentage.from_percent(percent) | ||
| quantity = quantity_ctor(quantity_value) | ||
| expected_value = quantity.base_value * (percent / 100.0) | ||
| print(f"{quantity=}, {percentage=}, {expected_value=}") | ||
|
|
||
| product = quantity * percentage | ||
| print(f"{product=}") | ||
| assert product.base_value == expected_value | ||
|
|
||
| quantity *= percentage | ||
| print(f"*{quantity=}") | ||
| assert quantity.base_value == expected_value | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need to retain the print statements? don't they pollute the test output when trying to debug something else? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They are useful when something fails. I guess if you are focusing on some other test you can always run There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well there's always: assert quantity.base_value == expected_value, f"{quantity=} * {percentage=} != {expected_value}! 🙀 " |
||
|
|
||
|
|
||
| @pytest.mark.parametrize("quantity_ctor", _QUANTITY_CTORS + [Quantity]) | ||
| # Use a small amount to avoid long running tests, we have too many combinations | ||
| @hypothesis.settings(max_examples=10) | ||
| @hypothesis.given( | ||
| quantity_value=st.floats( | ||
| allow_infinity=False, | ||
| allow_nan=False, | ||
| allow_subnormal=False, | ||
| # We need to set this because otherwise constructors with big exponents will | ||
| # cause the value to be too big for the float type, and the test will fail. | ||
| max_value=1e298, | ||
| min_value=-1e298, | ||
| ), | ||
| scalar=st.floats(allow_infinity=False, allow_nan=False, allow_subnormal=False), | ||
| ) | ||
| def test_quantity_multiplied_with_float( | ||
| quantity_ctor: type[Quantity], quantity_value: float, scalar: float | ||
| ) -> None: | ||
| """Test the multiplication of all quantities with a float.""" | ||
| quantity = quantity_ctor(quantity_value) | ||
| expected_value = quantity.base_value * scalar | ||
| print(f"{quantity=}, {expected_value=}") | ||
|
|
||
| product = quantity * scalar | ||
| print(f"{product=}") | ||
| assert product.base_value == expected_value | ||
|
|
||
| quantity *= scalar | ||
| print(f"*{quantity=}") | ||
| assert quantity.base_value == expected_value | ||
|
|
||
|
|
||
| def test_invalid_multiplications() -> None: | ||
|
|
@@ -602,12 +640,6 @@ def test_invalid_multiplications() -> None: | |
| with pytest.raises(TypeError): | ||
| energy *= quantity # type: ignore | ||
|
|
||
| for quantity in [power, voltage, current, energy, Percentage.from_percent(50)]: | ||
| with pytest.raises(TypeError): | ||
| _ = quantity * 200.0 # type: ignore | ||
| with pytest.raises(TypeError): | ||
| quantity *= 200.0 # type: ignore | ||
|
|
||
|
|
||
| # We can't use _QUANTITY_TYPES here, because it will break the tests, as hypothesis | ||
| # will generate more values, some of which are unsupported by the quantities. See the | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to add some more context, when Marenz was adding these, we had no idea what the issue was, because without these,
mypykept crashing. Looks like they've fixed that bug and now we are able to understand the issue.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I didn't get a crash (thankfully!) but I still had to do my research, because the error message is not very clear why is there a problem with doing that.