-
Notifications
You must be signed in to change notification settings - Fork 1
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
Add a linspace class method #44
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
843da65
Add get_range_in_chunks
jeanconn b033266
Update ruff checking and pre-commit
jeanconn ba24bfa
Remove explicit CxoTime on at least one test
jeanconn a14f5b1
Update docstring
jeanconn 965e28c
Remove utils
jeanconn 1285848
Make a linspace class method
jeanconn b54e5af
Add requirement that num be positive and add num tests
jeanconn b50a3e7
Simplify linspace logic
jeanconn 59b866c
Update text and remove defunct comments
jeanconn 63bc3d2
First pass of test cleanup
jeanconn bcccd21
Remove stray comment
jeanconn 8a91bde
Change option check and add tests for it
jeanconn 566ee5f
Remove some more chunks references that Tom doesn't like
jeanconn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
import astropy.units as u | ||
import numpy as np | ||
import pytest | ||
|
||
from cxotime import CxoTime | ||
|
||
|
||
def run_linspace_step_test(start, stop, dt_max, expected_len, expected_values): | ||
"""General test function for CxoTime.linspace with step_max.""" | ||
|
||
result = CxoTime.linspace(start, stop, step_max=dt_max) | ||
|
||
# Confirm that the first interval duration matches the expected value | ||
assert abs(result[1] - result[0]) <= min( | ||
dt_max, abs(CxoTime(stop) - CxoTime(start)) | ||
) | ||
|
||
# Confirm that all the intervals are the same duration | ||
interval1 = result[1] - result[0] | ||
assert all(np.isclose((result[1:] - result[:-1]).sec, interval1.sec)) | ||
|
||
# Confirm that the time range is covered | ||
assert result[0] == start | ||
assert result[-1] == stop | ||
|
||
# And confirm that the result is as expected | ||
assert len(result) == expected_len | ||
assert np.allclose(CxoTime(result).secs, CxoTime(expected_values).secs) | ||
|
||
|
||
def test_linspace_step_with_zero_range(): | ||
"""Test that the result is correct when start==stop.""" | ||
run_linspace_step_test( | ||
"2000:001", "2000:001", 1 * u.day, 2, ["2000:001", "2000:001"] | ||
) | ||
|
||
|
||
def test_linspace_step_with_zero_range_and_bigger_step(): | ||
"""Test that the result is correct when the step is larger than the range.""" | ||
run_linspace_step_test( | ||
"2000:001", "2000:001", 1.5 * u.day, 2, ["2000:001", "2000:001"] | ||
) | ||
|
||
|
||
def test_linspace_step_with_float_range(): | ||
"""Test that the result is correct when the step is smaller than the range and more float-like.""" | ||
run_linspace_step_test( | ||
"2024:001", | ||
"2023:364", | ||
12.5 * u.hour, | ||
5, | ||
[ | ||
"2024:001:00:00:00.000", | ||
"2023:365:12:00:00.000", | ||
"2023:365:00:00:00.000", | ||
"2023:364:12:00:00.000", | ||
"2023:364:00:00:00.000", | ||
], | ||
) | ||
|
||
|
||
def test_linspace_step_odd_minutes(): | ||
"""Test that the result is correct when the step is just some weird float of minutes.""" | ||
run_linspace_step_test( | ||
"2020:020:00:12:00.000", | ||
"2020:020:00:13:00.000", | ||
23.5 * u.min, | ||
2, | ||
["2020:020:00:12:00.000", "2020:020:00:13:00.000"], | ||
) | ||
|
||
|
||
def test_linspace_negative_range(): | ||
"""Test that the result is correct when stop < start""" | ||
start = CxoTime("2000:005") | ||
stop = CxoTime("2000:001") | ||
dt_max = 24 * u.hour | ||
result = CxoTime.linspace(start, stop, step_max=dt_max) | ||
assert len(result) == 5 | ||
expected_values = ["2000:005", "2000:004", "2000:003", "2000:002", "2000:001"] | ||
assert np.all(result == CxoTime(expected_values)) | ||
|
||
|
||
def test_linspace_big_step(): | ||
"""Test that the result is correct when the step is larger than the range.""" | ||
start = CxoTime("2020:001") | ||
stop = CxoTime("2020:005") | ||
dt_max = 30 * u.day | ||
result = CxoTime.linspace(start, stop, step_max=dt_max) | ||
assert len(result) == 2 | ||
assert np.all(result == CxoTime(["2020:001", "2020:005"])) | ||
|
||
|
||
def test_linspace_zero_step(): | ||
"""Test that an error is raised if step_max is zero.""" | ||
start = CxoTime("2020:001") | ||
stop = CxoTime("2020:005") | ||
dt_max = 0 * u.day | ||
with pytest.raises(ValueError, match="step_max must be positive nonzero"): | ||
CxoTime.linspace(start, stop, step_max=dt_max) | ||
|
||
|
||
def test_linspace_negative_step(): | ||
"""Test that an error is raised if step_max is negative.""" | ||
start = CxoTime("2020:001") | ||
stop = CxoTime("2020:005") | ||
dt_max = -1 * u.day | ||
with pytest.raises(ValueError, match="step_max must be positive nonzero"): | ||
CxoTime.linspace(start, stop, step_max=dt_max) | ||
|
||
|
||
def test_linspace_num_0(): | ||
"""Test that an error is raised if num is zero.""" | ||
start = CxoTime("2000:001") | ||
stop = CxoTime("2000:005") | ||
num = 0 | ||
with pytest.raises(ValueError, match="num must be positive nonzero"): | ||
CxoTime.linspace(start, stop, num=num) | ||
|
||
|
||
def test_linspace_num_neg(): | ||
"""Test that an error is raised if num is negative.""" | ||
start = CxoTime("2000:001") | ||
stop = CxoTime("2000:005") | ||
num = -1 | ||
with pytest.raises(ValueError, match="num must be positive nonzero"): | ||
CxoTime.linspace(start, stop, num=num) | ||
|
||
|
||
def test_linspace_num_1(): | ||
start = CxoTime("2000:001") | ||
stop = CxoTime("2000:005") | ||
num = 2 | ||
result = CxoTime.linspace(start, stop, num=num) | ||
assert len(result) == num + 1 | ||
expected = ["2000:001", "2000:003", "2000:005"] | ||
assert np.all(result == CxoTime(expected)) | ||
|
||
|
||
def test_linspace_num_2(): | ||
start = "2000:001" | ||
stop = "2024:001" | ||
num = 12 | ||
result = CxoTime.linspace(start, stop, num=num) | ||
assert len(result) == num + 1 | ||
expected = [ | ||
"2000:001:00:00:00.000", | ||
"2001:365:12:00:00.417", | ||
"2004:001:00:00:00.833", | ||
"2005:365:12:00:01.250", | ||
"2008:001:00:00:00.667", | ||
"2009:365:12:00:00.083", | ||
"2012:001:00:00:00.500", | ||
"2013:365:11:59:59.917", | ||
"2015:365:23:59:59.333", | ||
"2017:365:11:59:58.750", | ||
"2019:365:23:59:59.167", | ||
"2021:365:11:59:59.583", | ||
"2024:001:00:00:00.000", | ||
] | ||
# There are very small numerical differences between the expected and actual values | ||
# so this test uses allclose instead of ==. | ||
assert np.allclose(CxoTime(result).secs, CxoTime(expected).secs) | ||
|
||
|
||
def test_linspace_num_3(): | ||
start = "2010:001" | ||
stop = "2011:001" | ||
num = 12 | ||
result = CxoTime.linspace(start, stop, num=num) | ||
assert len(result) == num + 1 | ||
expected = [ | ||
"2010:001:00:00:00.000", | ||
"2010:031:10:00:00.000", | ||
"2010:061:20:00:00.000", | ||
"2010:092:06:00:00.000", | ||
"2010:122:16:00:00.000", | ||
"2010:153:02:00:00.000", | ||
"2010:183:12:00:00.000", | ||
"2010:213:22:00:00.000", | ||
"2010:244:08:00:00.000", | ||
"2010:274:18:00:00.000", | ||
"2010:305:04:00:00.000", | ||
"2010:335:14:00:00.000", | ||
"2011:001:00:00:00.000", | ||
] | ||
# There are very small numerical differences between the expected and actual values | ||
# so this test uses allclose instead of ==. | ||
assert np.allclose(CxoTime(result).secs, CxoTime(expected).secs) | ||
|
||
|
||
def test_missing_args(): | ||
start = "2015:001" | ||
stop = "2015:002" | ||
with pytest.raises( | ||
ValueError, match="exactly one of num and step_max must be defined" | ||
): | ||
CxoTime.linspace(start, stop) | ||
|
||
|
||
def test_too_many_args(): | ||
start = "2015:001" | ||
stop = "2015:002" | ||
with pytest.raises( | ||
ValueError, match="exactly one of num and step_max must be defined" | ||
): | ||
CxoTime.linspace(start, stop, 1, 2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# Copied originally from pandas. This config requires ruff >= 0.2. | ||
target-version = "py311" | ||
|
||
# fix = true | ||
lint.unfixable = [] | ||
|
||
lint.select = [ | ||
"I", # isort | ||
"F", # pyflakes | ||
"E", "W", # pycodestyle | ||
"YTT", # flake8-2020 | ||
"B", # flake8-bugbear | ||
"Q", # flake8-quotes | ||
"T10", # flake8-debugger | ||
"INT", # flake8-gettext | ||
"PLC", "PLE", "PLR", "PLW", # pylint | ||
"PIE", # misc lints | ||
"PYI", # flake8-pyi | ||
"TID", # tidy imports | ||
"ISC", # implicit string concatenation | ||
"TCH", # type-checking imports | ||
"C4", # comprehensions | ||
"PGH" # pygrep-hooks | ||
] | ||
|
||
# Some additional rules that are useful | ||
lint.extend-select = [ | ||
"UP009", # UTF-8 encoding declaration is unnecessary | ||
"SIM118", # Use `key in dict` instead of `key in dict.keys()` | ||
"D205", # One blank line required between summary line and description | ||
"ARG001", # Unused function argument | ||
"RSE102", # Unnecessary parentheses on raised exception | ||
"PERF401", # Use a list comprehension to create a transformed list | ||
] | ||
|
||
lint.ignore = [ | ||
"ISC001", # Disable this for compatibility with ruff format | ||
"E402", # module level import not at top of file | ||
"E731", # do not assign a lambda expression, use a def | ||
"PLR2004", # Magic number | ||
"B028", # No explicit `stacklevel` keyword argument found | ||
"PLR0913", # Too many arguments to function call | ||
"PLR1730", # Checks for if statements that can be replaced with min() or max() calls | ||
] | ||
|
||
extend-exclude = [ | ||
"docs", | ||
] | ||
|
||
[lint.pycodestyle] | ||
max-line-length = 100 # E501 reports lines that exceed the length of 100. | ||
|
||
[lint.extend-per-file-ignores] | ||
"__init__.py" = ["E402", "F401", "F403"] | ||
# For tests: | ||
# - D205: Don't worry about test docstrings | ||
# - ARG001: Unused function argument false positives for some fixtures | ||
# - E501: Line-too-long | ||
"**/tests/test_*.py" = ["D205", "ARG001", "E501"] |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
You already have a test of this.
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.
I think I now have on "big step" test with a nonzero range and one big step with a zero range, but let me know if there's still a test you'd like to cut.