Skip to content
Open
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
5 changes: 1 addition & 4 deletions src/easyscience/variable/descriptor_number.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,16 +423,13 @@ def __rmul__(self, other: numbers.Number) -> DescriptorNumber:

def __truediv__(self, other: Union[DescriptorNumber, numbers.Number]) -> DescriptorNumber:
if isinstance(other, numbers.Number):
original_other = other
if other == 0:
raise ZeroDivisionError('Cannot divide by zero')
new_value = self.full_value / other
elif type(other) is DescriptorNumber:
original_other = other.value
if original_other == 0:
if other.value == 0:
raise ZeroDivisionError('Cannot divide by zero')
new_value = self.full_value / other.full_value
other.value = original_other
else:
return NotImplemented
descriptor_number = DescriptorNumber.from_scipp(name=self.name, full_value=new_value)
Expand Down
2 changes: 0 additions & 2 deletions src/easyscience/variable/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,6 @@ def __truediv__(self, other: Union[DescriptorNumber, Parameter, numbers.Number])
combinations = [self.min / other.min, self.max / other.max, self.min / other.max, self.max / other.min]
else:
combinations = [self.min / other.value, self.max / other.value]
other.value = other_value
else:
return NotImplemented
min_value = min(combinations)
Expand Down Expand Up @@ -926,7 +925,6 @@ def __rtruediv__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parame
parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value)
parameter._convert_unit(parameter._base_unit())
parameter.name = parameter.unique_name
self.value = original_self
return parameter

def __pow__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parameter:
Expand Down
45 changes: 45 additions & 0 deletions tests/unit_tests/variable/test_parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,51 @@ def test_dependent_parameter_return_is_descriptor_number(self):
assert dependent_parameter.min == 2*descriptor_number.value
assert dependent_parameter.max == 2*descriptor_number.value

def test_dependent_parameter_division_expression_order(self):
"""Test that division expressions work regardless of operand order.

This is a regression test for https://github.com/easyscience/corelib/issues/190
where 'a / b' would fail with an observer notification error while '1/b * a'
would work correctly.
"""
# When
angstrom = DescriptorNumber("angstrom", 1e-10, unit="m")
jump_length = Parameter(
name="jump_length",
value=float(1.0),
fixed=False,
unit="angstrom",
)

expression = "jump_length / angstrom"
dependency_map = {
"jump_length": jump_length,
"angstrom": angstrom,
}

# Calculate the expected result from direct division
expected_result = jump_length / angstrom
expected_value = expected_result.value

# Then - This should not raise an error
dependent_param = Parameter(name='a', value=1.0)
dependent_param.make_dependent_on(
dependency_expression=expression,
dependency_map=dependency_map,
)

# Expect - The dependent parameter should have the same value as the direct division
assert dependent_param.value == pytest.approx(expected_value)

# Also test the alternative expression that previously worked
expression_alt = "1/angstrom * jump_length"
dependent_param_alt = Parameter(name='b', value=1.0)
dependent_param_alt.make_dependent_on(
dependency_expression=expression_alt,
dependency_map=dependency_map,
)
assert dependent_param_alt.value == pytest.approx(expected_value)

def test_dependent_parameter_overwrite_dependency(self, normal_parameter: Parameter):
# When
dependent_parameter = Parameter.from_dependency(
Expand Down
Loading