Skip to content

Commit 13d7d8f

Browse files
authored
Merge pull request #22 from open-resources/round_sig_fix
2 parents b4ad4f9 + 97c5416 commit 13d7d8f

File tree

2 files changed

+43
-19
lines changed

2 files changed

+43
-19
lines changed

src/problem_bank_helpers/problem_bank_helpers.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,27 @@ def sigfigs(x):
7979
return sigfigs('e'.join(n))
8080

8181

82-
# A function to rounding a number x keeping sig significant figures.
8382
def round_sig(x, sig):
83+
"""
84+
Round a number to a specified number of significant digits.
85+
86+
Args:
87+
x (float or int): The number to be rounded.
88+
sig (int): The number of significant digits.
89+
90+
Returns:
91+
float or int: The rounded number retaining the type of the input.
92+
"""
8493
from math import log10, floor
8594
if x == 0:
8695
y = 0
8796
else:
8897
y = sig - int(floor(log10(abs(x)))) - 1
8998
# avoid precision loss with floats
90-
x = Decimal(str(x))
91-
return float(round(x, y))
99+
decimal_x = round( Decimal(str(x)) , y )
100+
101+
return type(x)(decimal_x)
102+
92103

93104
# def round_sig(x, sig_figs = 3):
94105
# """A function that rounds to specific significant digits. Original from SO: https://stackoverflow.com/a/3413529/2217577; adapted by Jake Bobowski

tests/test_problem_bank_helpers_rounding.py

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,25 @@ def test_sigfigs(test_group, variables):
130130
pytest.fail(f"test group is not defined (got: '{test_group}')")
131131
assert (pbh.sigfigs(test_input) == correct_sigfigs), f"input: {test_input}, output: {pbh.sigfigs(test_input)}"
132132

133-
def test_sigfigs_floatinput_fail():
133+
def test_sigfigs_float_input_fail():
134134
with pytest.raises(Exception):
135135
pbh.sigfigs(float(1))
136136

137137

138138
# Test round_sig function
139+
def test_roundsig_int_returns_int():
140+
"""Test rounding an int with specified sigfigs"""
141+
assert isinstance(pbh.round_sig(123, 2), int)
142+
143+
def test_roundsig_with_float():
144+
"""Test rounding an float with specified sigfigs"""
145+
assert isinstance(pbh.round_sig(123.0, 2), float)
146+
147+
def test_roundsig_with_string_fail():
148+
"""Test rounding a string with specified sigfigs"""
149+
with pytest.raises(Exception):
150+
pbh.round_sig("123.0", 2)
151+
139152
@pytest.mark.parametrize('id, input, sigfigs, expected_result', [
140153
('id_positive float',3.14159, 3, 3.14), # Test rounding a positive float to 3 sigfigs
141154
('id_negative float',-2.71828, 3, -2.72), # Test rounding a negative float to 3 sigfigs
@@ -158,11 +171,22 @@ def test_sigfigs_floatinput_fail():
158171
],
159172
ids=idfn
160173
)
161-
def test_roundsig(id, input, sigfigs, expected_result):
174+
def test_roundsig_rigorous(id, input, sigfigs, expected_result):
162175
assert (pbh.round_sig(input, sigfigs) == expected_result)
163176

164177

165178
#test num_as_str function
179+
def test_num_as_str_default_dp():
180+
"""test default decimal places"""
181+
assert pbh.num_as_str(3.14159) == '3.14'
182+
183+
def test_num_as_str_invalid_args_kwargs():
184+
with pytest.raises(TypeError):
185+
pbh.num_as_str(123.45, 2, "args") # Function should not accept *args
186+
187+
with pytest.raises(TypeError):
188+
pbh.num_as_str(123.45, 2, digits_after_decimal=2) # Function should not accept **kwargs
189+
166190
@pytest.mark.parametrize('id, input, digits_after_decimal, expected_result', [
167191
('id_positive float',3.14159, 2, '3.14'), # Test rounding a positive float to 2 digits after decimal
168192
('id_negative float',-2.71828, 2, '-2.72'), # Test rounding a negative float to 2 digits after decimal
@@ -184,20 +208,9 @@ def test_roundsig(id, input, sigfigs, expected_result):
184208
],
185209
ids=idfn
186210
)
187-
def test_num_as_str(id, input, digits_after_decimal, expected_result):
211+
def test_num_as_str_rigorous(id, input, digits_after_decimal, expected_result):
188212
assert pbh.num_as_str(input, digits_after_decimal) == expected_result
189213

190-
def test_num_as_str_default_dp():
191-
"""test default decimal places"""
192-
assert pbh.num_as_str(3.14159) == '3.14'
193-
194-
def test_num_as_str_invalid_args_kwargs():
195-
with pytest.raises(TypeError):
196-
pbh.num_as_str(123.45, 2, "args") # Function should not accept *args
197-
198-
with pytest.raises(TypeError):
199-
pbh.num_as_str(123.45, 2, digits_after_decimal=2) # Function should not accept **kwargs
200-
201214

202215
# Test roundp function
203216
def test_roundp_with_overriden_sigfig_settings():
@@ -266,7 +279,7 @@ def test_roundp_notation_sci_dp():
266279
],
267280
ids=idfn
268281
)
269-
def test_roundp_rigorous_sigfig(id, input, sigfigs, expected_result):
282+
def test_roundp_rigorous(id, input, sigfigs, expected_result):
270283
assert pbh.roundp(input, sigfigs=sigfigs) == expected_result
271284

272285

@@ -317,5 +330,5 @@ def test_roundstr_with_decimal_sci_notation_dp():
317330
],
318331
ids=idfn
319332
)
320-
def test_roundstr_rigorous_sigfig(id, input, sigfigs, expected_result):
333+
def test_roundstr_rigorous(id, input, sigfigs, expected_result):
321334
assert pbh.round_str(input, sigfigs=sigfigs) == expected_result

0 commit comments

Comments
 (0)