Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions physical_quantities/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ The first public release. This is a further tidy-up after the 0.2.0 extraction:

### Fixed

- A value that is a list, with a unit, is converted value by value: `{1, 2} km`, `1,2~\mathrm{km}` (LaTeX), `plus_minus 2 km` and `\pm 2~\mathrm{km}` give `standard_values` of 1000 and 2000 (or −2000 and 2000). Before, the unit factor multiplied the list as a whole, and `parse_quantity` raised `QuantityParseError`.
- The roentgen was converted as kelvin per kilogram; it is 2.58×10⁻⁴ C/kg (ampere·second per kilogram).
- The imperial pint was 0.00056826 m³; it is 0.00056826125 m³, so that 8 pints make a gallon.
- `nautical_miles` is recognised as the plural of `nautical_mile`. Before, only `nauticalmiles` was, and in natural mode `2 nautical_miles` parsed as 2 nautical_mile·second.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from lambdafeedback.expression_parsing import (
SympyParsingConfig,
create_expression_set,
parse_expression,
parse_expressions,
parse_latex,
Expand Down Expand Up @@ -85,6 +86,7 @@ def sympy_forms(
value_text: Any = value.content_string() if value is not None else None
if value_text is not None and params.is_latex:
value_text = parse_latex(value_text, params.symbols, params.simplify)
standard_values: tuple[Basic, ...] | None = None
standard_unit: Any = None
expanded_unit: Any = None
dimension: Basic = Integer(1)
Expand All @@ -99,10 +101,17 @@ def sympy_forms(
base_symbols = {symbol: 1 for symbol in standard_unit.free_symbols if str(symbol) in _BASE_UNIT_NAMES}
unit_factor = standard_unit.subs(base_symbols).simplify()
standard_unit = (standard_unit / unit_factor).simplify(rational=True)
value_text = f"({value_text})*({unit_factor})"
if len(create_expression_set(value_text, config.substitution_params)) > 1:
# A list ({1, 2}, 1,2 in LaTeX, or ±): the factor applies to each value, not to the list.
factored_values = tuple(value * unit_factor for value in parse_expressions(value_text, config))
standard_values = tuple(dict.fromkeys(factored_values))
else:
value_text = f"({value_text})*({unit_factor})"
dimension = parse_expression(substitute(expanded_unit_string, _BASE_UNIT_DIMENSIONS), config)
if standard_values is None and value_text is not None:
standard_values = parse_expressions(value_text, config)
return SympyForms(
standard_values=None if value_text is None else parse_expressions(value_text, config),
standard_values=standard_values,
standard_unit=standard_unit,
expanded_unit=expanded_unit,
dimension=dimension,
Expand Down
15 changes: 15 additions & 0 deletions physical_quantities/tests/test_regressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,21 @@ def test_latex_spacing_and_upright_units(self, expr, value, unit):
quantity = parse_quantity(expr, QuantityParams(is_latex=True))
assert (quantity.value.content_string(), quantity.unit.content_string()) == (value, unit)

@pytest.mark.parametrize(
"expr, is_latex, values",
[
("{1, 2} km", False, {1000, 2000}),
("plus_minus 2 km", False, {-2000, 2000}),
(r"1,2~\mathrm{km}", True, {1000, 2000}),
(r"\pm 2~\mathrm{km}", True, {-2000, 2000}),
],
)
def test_unit_factor_applies_to_each_value_of_a_list(self, expr, is_latex, values):
# The factor multiplied the list as a whole, "((1, 2))*(1000)", which raised.
quantity = parse_quantity(expr, QuantityParams(is_latex=is_latex))
assert set(quantity.standard_values) == values
assert str(quantity.standard_unit) == "metre"

@pytest.mark.parametrize("strictness", ["strict", "natural"])
@pytest.mark.parametrize(
"expr, unit",
Expand Down
Loading