-
Notifications
You must be signed in to change notification settings - Fork 3
Work on the SasData object definition #156
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
base: refactor_24
Are you sure you want to change the base?
Work on the SasData object definition #156
Conversation
Useful for testing.
We add the following ignore statements to pycodestyle - E501: Too many pieces of legacy code extend past the line length - W503: This PEP is now considered and anti-pattern and many formatters explicitly (e.g. ruff, black) explicitly ignore it. Reference to anti-pattern: https://peps.python.org/pep-0008/#should-a-line-break-before-or-after-a-binary-operator
Serialise sasdata
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.
Code Health Improved
(1 files improve in Code Health)
Gates Failed
New code is healthy
(1 new file with code health below 9.00)
Enforce critical code health rules
(1 file with Bumpy Road Ahead, Deep, Nested Complexity)
Gates Passed
1 Quality Gates Passed
See analysis details in CodeScene
Reason for failure
| New code is healthy | Violations | Code Health Impact | |
|---|---|---|---|
| abscissa.py | 3 rules | 10.00 → 8.64 | Suppress |
| Enforce critical code health rules | Violations | Code Health Impact | |
|---|---|---|---|
| abscissa.py | 2 critical rules | 10.00 → 8.64 | Suppress |
View Improvements
| File | Code Health Impact | Categories Improved |
|---|---|---|
| transforms.py | 9.39 → 10.00 | Deep, Nested Complexity |
Quality Gate Profile: The Bare Minimum
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.
31d7c10 to
78bcc6d
Compare
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.
Gates Failed
New code is healthy
(1 new file with code health below 9.00)
Enforce critical code health rules
(1 file with Bumpy Road Ahead, Deep, Nested Complexity)
Gates Passed
1 Quality Gates Passed
See analysis details in CodeScene
Reason for failure
| New code is healthy | Violations | Code Health Impact | |
|---|---|---|---|
| abscissa.py | 3 rules | 10.00 → 8.64 | Suppress |
| Enforce critical code health rules | Violations | Code Health Impact | |
|---|---|---|---|
| abscissa.py | 2 critical rules | 10.00 → 8.64 | Suppress |
Quality Gate Profile: The Bare Minimum
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.
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.
Gates Failed
New code is healthy
(1 new file with code health below 9.00)
Enforce critical code health rules
(1 file with Bumpy Road Ahead, Deep, Nested Complexity)
Gates Passed
1 Quality Gates Passed
See analysis details in CodeScene
Reason for failure
| New code is healthy | Violations | Code Health Impact | |
|---|---|---|---|
| abscissa.py | 3 rules | 10.00 → 8.64 | Suppress |
| Enforce critical code health rules | Violations | Code Health Impact | |
|---|---|---|---|
| abscissa.py | 2 critical rules | 10.00 → 8.64 | Suppress |
Quality Gate Profile: The Bare Minimum
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.
| def determine(axis_data: list[Quantity[ArrayLike]], ordinate_data: Quantity[ArrayLike]) -> "Abscissa": | ||
| """ Get an Abscissa object that fits the combination of axes and data""" | ||
|
|
||
| # Different posibilites: | ||
| # 1: axes_data[i].shape == axes_data[j].shape == ordinate_data.shape | ||
| # 1a: axis_data[i] is 1D => | ||
| # 1a-i: len(axes_data) == 1 => Grid type or Scatter type depending on sortedness | ||
| # 1a-ii: len(axes_data) != 1 => Scatter type | ||
| # 1b: axis_data[i] dimensionality matches len(axis_data) => Meshgrid type | ||
| # 1c: other => Error | ||
| # 2: (len(axes_data[0]), len(axes_data[1])... ) == ordinate_data.shape => Grid type | ||
| # 3: None of the above => Error | ||
|
|
||
| ordinate_shape = np.array(ordinate_data.value).shape | ||
| axis_arrays = [np.array(axis.value) for axis in axis_data] | ||
|
|
||
| # 1: | ||
| if all([axis.shape == ordinate_shape for axis in axis_arrays]): | ||
| # 1a: | ||
| if all([len(axis.shape)== 1 for axis in axis_arrays]): | ||
| # 1a-i: | ||
| if len(axis_arrays) == 1: | ||
| # Is it sorted | ||
| if is_increasing(axis_arrays[0]): | ||
| return GridAbscissa(axis_data) | ||
| else: | ||
| return ScatterAbscissa(axis_data) | ||
| # 1a-ii | ||
| else: | ||
| return ScatterAbscissa(axis_data) | ||
| # 1b | ||
| elif all([len(axis.shape) == len(axis_arrays) for axis in axis_arrays]): | ||
|
|
||
| return MeshgridAbscissa(axis_data) | ||
|
|
||
| else: | ||
| raise InterpretationError(Abscissa._determine_error_message(axis_arrays, ordinate_shape)) | ||
|
|
||
| elif all([len(axis.shape)== 1 for axis in axis_arrays]) and \ | ||
| tuple([axis.shape[0] for axis in axis_arrays]) == ordinate_shape: | ||
|
|
||
| # Require that they are sorted | ||
| if all([is_increasing(axis) for axis in axis_arrays]): | ||
|
|
||
| return GridAbscissa(axis_data) | ||
|
|
||
| else: | ||
| raise InterpretationError("Grid axes are not sorted") | ||
|
|
||
| else: | ||
| raise InterpretationError(Abscissa._determine_error_message(axis_arrays, ordinate_shape)) |
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.
❌ New issue: Complex Method
Abscissa.determine has a cyclomatic complexity of 24, threshold = 9
| def determine(axis_data: list[Quantity[ArrayLike]], ordinate_data: Quantity[ArrayLike]) -> "Abscissa": | ||
| """ Get an Abscissa object that fits the combination of axes and data""" | ||
|
|
||
| # Different posibilites: | ||
| # 1: axes_data[i].shape == axes_data[j].shape == ordinate_data.shape | ||
| # 1a: axis_data[i] is 1D => | ||
| # 1a-i: len(axes_data) == 1 => Grid type or Scatter type depending on sortedness | ||
| # 1a-ii: len(axes_data) != 1 => Scatter type | ||
| # 1b: axis_data[i] dimensionality matches len(axis_data) => Meshgrid type | ||
| # 1c: other => Error | ||
| # 2: (len(axes_data[0]), len(axes_data[1])... ) == ordinate_data.shape => Grid type | ||
| # 3: None of the above => Error | ||
|
|
||
| ordinate_shape = np.array(ordinate_data.value).shape | ||
| axis_arrays = [np.array(axis.value) for axis in axis_data] | ||
|
|
||
| # 1: | ||
| if all([axis.shape == ordinate_shape for axis in axis_arrays]): | ||
| # 1a: | ||
| if all([len(axis.shape)== 1 for axis in axis_arrays]): | ||
| # 1a-i: | ||
| if len(axis_arrays) == 1: | ||
| # Is it sorted | ||
| if is_increasing(axis_arrays[0]): | ||
| return GridAbscissa(axis_data) | ||
| else: | ||
| return ScatterAbscissa(axis_data) | ||
| # 1a-ii | ||
| else: | ||
| return ScatterAbscissa(axis_data) | ||
| # 1b | ||
| elif all([len(axis.shape) == len(axis_arrays) for axis in axis_arrays]): | ||
|
|
||
| return MeshgridAbscissa(axis_data) | ||
|
|
||
| else: | ||
| raise InterpretationError(Abscissa._determine_error_message(axis_arrays, ordinate_shape)) | ||
|
|
||
| elif all([len(axis.shape)== 1 for axis in axis_arrays]) and \ | ||
| tuple([axis.shape[0] for axis in axis_arrays]) == ordinate_shape: | ||
|
|
||
| # Require that they are sorted | ||
| if all([is_increasing(axis) for axis in axis_arrays]): | ||
|
|
||
| return GridAbscissa(axis_data) | ||
|
|
||
| else: | ||
| raise InterpretationError("Grid axes are not sorted") | ||
|
|
||
| else: | ||
| raise InterpretationError(Abscissa._determine_error_message(axis_arrays, ordinate_shape)) |
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.
❌ New issue: Bumpy Road Ahead
Abscissa.determine has 2 blocks with nested conditional logic. Any nesting of 2 or deeper is considered. Threshold is one single, nested block per function
| def determine(axis_data: list[Quantity[ArrayLike]], ordinate_data: Quantity[ArrayLike]) -> "Abscissa": | ||
| """ Get an Abscissa object that fits the combination of axes and data""" | ||
|
|
||
| # Different posibilites: | ||
| # 1: axes_data[i].shape == axes_data[j].shape == ordinate_data.shape | ||
| # 1a: axis_data[i] is 1D => | ||
| # 1a-i: len(axes_data) == 1 => Grid type or Scatter type depending on sortedness | ||
| # 1a-ii: len(axes_data) != 1 => Scatter type | ||
| # 1b: axis_data[i] dimensionality matches len(axis_data) => Meshgrid type | ||
| # 1c: other => Error | ||
| # 2: (len(axes_data[0]), len(axes_data[1])... ) == ordinate_data.shape => Grid type | ||
| # 3: None of the above => Error | ||
|
|
||
| ordinate_shape = np.array(ordinate_data.value).shape | ||
| axis_arrays = [np.array(axis.value) for axis in axis_data] | ||
|
|
||
| # 1: | ||
| if all([axis.shape == ordinate_shape for axis in axis_arrays]): | ||
| # 1a: | ||
| if all([len(axis.shape)== 1 for axis in axis_arrays]): | ||
| # 1a-i: | ||
| if len(axis_arrays) == 1: | ||
| # Is it sorted | ||
| if is_increasing(axis_arrays[0]): | ||
| return GridAbscissa(axis_data) | ||
| else: | ||
| return ScatterAbscissa(axis_data) | ||
| # 1a-ii | ||
| else: | ||
| return ScatterAbscissa(axis_data) | ||
| # 1b | ||
| elif all([len(axis.shape) == len(axis_arrays) for axis in axis_arrays]): | ||
|
|
||
| return MeshgridAbscissa(axis_data) | ||
|
|
||
| else: | ||
| raise InterpretationError(Abscissa._determine_error_message(axis_arrays, ordinate_shape)) | ||
|
|
||
| elif all([len(axis.shape)== 1 for axis in axis_arrays]) and \ | ||
| tuple([axis.shape[0] for axis in axis_arrays]) == ordinate_shape: | ||
|
|
||
| # Require that they are sorted | ||
| if all([is_increasing(axis) for axis in axis_arrays]): | ||
|
|
||
| return GridAbscissa(axis_data) | ||
|
|
||
| else: | ||
| raise InterpretationError("Grid axes are not sorted") | ||
|
|
||
| else: | ||
| raise InterpretationError(Abscissa._determine_error_message(axis_arrays, ordinate_shape)) |
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.
❌ New issue: Deep, Nested Complexity
Abscissa.determine has a nested complexity depth of 4, threshold = 4
6e3ba34 to
c010919
Compare
d4683bd to
3df6e01
Compare
b32dbfe to
6f3b4af
Compare
Reworked SasData classes
This introduces a new object, the Abscissa object, that describes how the axes data relates to ordinate data.