Skip to content

Prevent unexpected alpha/beta returns from _calc_alpha_beta...#4

Merged
hbmartin merged 2 commits intomainfrom
prevent-unexpected-alpha-beta-array
Jul 18, 2025
Merged

Prevent unexpected alpha/beta returns from _calc_alpha_beta...#4
hbmartin merged 2 commits intomainfrom
prevent-unexpected-alpha-beta-array

Conversation

@hbmartin
Copy link
Copy Markdown
Owner

@hbmartin hbmartin commented Jul 18, 2025

User description

...by checking if an array has all equal elements and returning the scalar instead


PR Type

Bug fix, Enhancement


Description

  • Fix unexpected array returns from _calc_alpha_beta function

  • Add type hints and debug logging for array parameters

  • Return scalar values when all array elements are equal

  • Bump version to 0.2.0


Diagram Walkthrough

flowchart LR
  A["Array Parameters"] --> B["_calc_alpha_beta Function"]
  B --> C["Check All Elements Equal"]
  C --> D["Return Scalar Values"]
  C --> E["Return Array Values"]
  F["Debug Logging"] --> B
Loading

File Walkthrough

Relevant files
Bug fix
funcs.py
Fix array handling in _calc_alpha_beta function                   

betapert/funcs.py

  • Add type hints to _calc_alpha_beta function parameters and return type
  • Add logic to check if array parameters have all equal elements
  • Return scalar values instead of arrays when all elements are equal
  • Add debug logging for unexpected array parameters
+21/-1   
Tests
test_ppf_log_fallback.py
Add tests for _calc_alpha_beta array handling                       

tests/test_ppf_log_fallback.py

  • Add test for _calc_alpha_beta with array arguments having all equal
    elements
  • Add test for _calc_alpha_beta with array arguments having different
    elements
  • Verify scalar vs array return behavior based on input uniformity
+34/-0   
Configuration changes
pyproject.toml
Version bump to 0.2.0                                                                       

pyproject.toml

  • Bump version from 0.1.9 to 0.2.0
+1/-1     

Summary by CodeRabbit

  • New Features

    • Improved handling of array inputs for parameter calculation, with automatic conversion to scalars when all array elements are equal.
    • Enhanced debug messages for array input detection and warnings when array outputs are not uniform (visible only if debugging is enabled).
  • Tests

    • Added tests to verify correct behavior with array inputs, including scenarios with all-equal and non-equal elements.
  • Chores

    • Updated version number to 0.2.0.
    • Added new development dependencies for type checking and scientific computing support.

Important

Fix _calc_alpha_beta to return scalars for all-equal arrays, add type hints, logging, and tests, and update version to 0.2.0.

  • Behavior:
    • Fix _calc_alpha_beta in funcs.py to return scalars when all array elements are equal.
    • Add type hints and debug logging to _calc_alpha_beta.
  • Tests:
    • Add tests in test_ppf_log_fallback.py for _calc_alpha_beta with all-equal and non-equal array elements.
  • Configuration:
    • Update version to 0.2.0 in pyproject.toml.

This description was created by Ellipsis for 60d5e8f. You can customize this summary. It will automatically update as commits are pushed.

…ng if an array has all equal elements and returning the scalar instead
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Jul 18, 2025

Reviewer's Guide

This PR updates _calc_alpha_beta to collapse uniform-array outputs into scalars with optional debug logging, adds explicit type annotations, extends test coverage for the new behavior, and bumps the project version.

Class diagram for updated _calc_alpha_beta function

classDiagram
    class _calc_alpha_beta {
        +mini: np.float64 | np.ndarray | float | int
        +mode: np.float64 | np.ndarray | float | int
        +maxi: np.float64 | np.ndarray | float | int
        +lambd: np.float64 | np.ndarray | float | int
        +_calc_alpha_beta(mini, mode, maxi, lambd) -> tuple[np.float64 | np.ndarray | float | int, np.float64 | np.ndarray | float | int]
    }

    _calc_alpha_beta : checks if alpha and beta are arrays with all equal elements
    _calc_alpha_beta : returns scalar if arrays are uniform
    _calc_alpha_beta : emits debug logs if DEBUG is set and unexpected arrays are encountered
Loading

File-Level Changes

Change Details Files
Collapse uniform-array alpha and beta outputs to scalars with debug logging
  • Insert uniformity check on alpha and beta arrays to return scalar values when all elements match
  • Emit stderr debug messages for array parameters and unexpected arrays when DEBUG is enabled
betapert/funcs.py
Enhance _calc_alpha_beta with explicit type annotations
  • Define parameter and return types using numpy and built-in numeric types
betapert/funcs.py
Extend test coverage for _calc_alpha_beta behavior
  • Add test for scalar return when array inputs are all equal
  • Add test for array return and shape validation when inputs differ
tests/test_ppf_log_fallback.py
Bump package version to 0.2.0
  • Update version in pyproject.toml from 0.1.9 to 0.2.0
pyproject.toml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jul 18, 2025

Walkthrough

The _calc_alpha_beta function in betapert/funcs.py was enhanced with type annotations and new debug logic for handling numpy arrays. The function now conditionally returns scalar or array outputs based on input uniformity. Corresponding tests were added, and the project version in pyproject.toml was incremented to 0.2.0.

Changes

File(s) Change Summary
betapert/funcs.py Added type annotations, debug logic for numpy array inputs, and conditional scalar/array output in _calc_alpha_beta.
tests/test_ppf_log_fallback.py Added two tests for _calc_alpha_beta to verify array input handling and output type behavior.
pyproject.toml Updated project version from 0.1.9 to 0.2.0 and added dev dependencies ty and scipy-stubs.

Sequence Diagram(s)

sequenceDiagram
    participant Test as Test Method
    participant Funcs as _calc_alpha_beta
    participant Debug as Debug Logic

    Test->>Funcs: Call with (mini, mode, maxi, lambd)
    alt DEBUG enabled
        Funcs->>Debug: Check if inputs are numpy arrays
        Debug-->>Funcs: Write diagnostic if arrays detected
    end
    Funcs->>Funcs: Compute alpha, beta
    alt alpha and beta are arrays and all elements equal
        Funcs->>Test: Return first element as scalars
    else alpha and beta are arrays with differing elements
        alt DEBUG enabled
            Funcs->>Debug: Write warning to stderr
        end
        Funcs->>Test: Return arrays
    else
        Funcs->>Test: Return scalars
    end
Loading

Suggested labels

Review effort 3/5

Poem

With numbers that stretch, or numbers that shrink,
Now _calc_alpha_beta stops to think—
Are all these values the same, or a crowd?
It whispers a warning, sometimes out loud.
Tests hop along to check every case,
And a version bump marks this new rabbit race! 🐇


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d9ee844 and 60d5e8f.

⛔ Files ignored due to path filters (1)
  • poetry.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • betapert/funcs.py (2 hunks)
  • pyproject.toml (2 hunks)
  • tests/test_ppf_log_fallback.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • pyproject.toml
  • tests/test_ppf_log_fallback.py
  • betapert/funcs.py
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@qodo-code-review
Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Logic Error

The debug logging condition has incorrect boolean logic. The condition uses 'and' followed by 'or' without proper parentheses, which may not capture all intended array parameter cases correctly.

if DEBUG and (
    isinstance(mini, np.ndarray)
    and isinstance(mode, np.ndarray)
    or isinstance(maxi, np.ndarray)
    or isinstance(lambd, np.ndarray)
):
Missing Import

The code uses sys.stderr.write for debug logging but there's no visible import statement for the sys module, which could cause a NameError at runtime.

sys.stderr.write(
    f"CAB: unexpected array parameters: mini={mini}, mode={mode}, maxi={maxi}, lambd={lambd}\n"
)
Undefined Variable

The DEBUG variable is referenced but not defined in the visible code scope, which could lead to a NameError when the debug conditions are evaluated.

if DEBUG and (
    isinstance(mini, np.ndarray)

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @hbmartin, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refines the behavior of the _calc_alpha_beta function within the betapert library. The primary goal is to ensure that when array inputs to this function would logically result in scalar outputs (i.e., all elements of the resulting alpha and beta arrays are identical), the function correctly returns scalar values instead of arrays. This change improves the predictability and consistency of the function's output, and is supported by new comprehensive tests and a package version bump.

Highlights

  • _calc_alpha_beta behavior refinement: Modified the _calc_alpha_beta function to detect if the calculated alpha and beta are NumPy arrays where all elements are identical. If so, it now returns the scalar value (the first element) instead of the array, preventing unexpected array returns when a scalar is implied.
  • Type Hinting: Added explicit type hints to the _calc_alpha_beta function signature, improving code readability and maintainability by specifying expected input and output types (float, int, or NumPy arrays).
  • Test Coverage: Introduced new unit tests to specifically validate the updated behavior of _calc_alpha_beta, covering scenarios where array inputs result in either scalar or array outputs based on element equality.
  • Version Update: Incremented the package version in pyproject.toml from 0.1.9 to 0.2.0, indicating a new release with this functional improvement.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@openhands-ai
Copy link
Copy Markdown

openhands-ai Bot commented Jul 18, 2025

Looks like there are a few issues preventing this PR from being merged!

  • GitHub Actions are failing:
    • Pytest, ruff, and black

If you'd like me to help, just leave a comment, like

@OpenHands please fix the failing actions on PR #4

Feel free to include any additional details that might help me get this PR into a better state.

You can manage your notification settings

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @hbmartin - I've reviewed your changes - here's some feedback:

  • The DEBUG check for array inputs currently uses mixed and/or without full grouping—consider using all(isinstance(...)) or parentheses to ensure you only log when all four inputs are arrays.
  • Avoid writing debug messages directly to stderr; it would be better to use Python’s logging module with a dedicated logger to control verbosity in production.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The DEBUG check for array inputs currently uses mixed `and/or` without full grouping—consider using `all(isinstance(...))` or parentheses to ensure you only log when all four inputs are arrays.
- Avoid writing debug messages directly to stderr; it would be better to use Python’s logging module with a dedicated logger to control verbosity in production.

## Individual Comments

### Comment 1
<location> `betapert/funcs.py:107` </location>
<code_context>
     alpha = 1 + ((mode - mini) * lambd) / (maxi - mini)
     beta = 1 + ((maxi - mode) * lambd) / (maxi - mini)
+    # If alpha and beta are arrays and all elements are equal, return the scalar value
+    if DEBUG and (
+        isinstance(mini, np.ndarray)
+        and isinstance(mode, np.ndarray)
+        or isinstance(maxi, np.ndarray)
+        or isinstance(lambd, np.ndarray)
+    ):
+        sys.stderr.write(
</code_context>

<issue_to_address>
Logical grouping in the condition may not match intent.

Mixing 'and' and 'or' without parentheses can cause unintended logic. Add parentheses to clarify the intended evaluation order.
</issue_to_address>

### Comment 2
<location> `betapert/funcs.py:116` </location>
<code_context>
+        sys.stderr.write(
+            f"CAB: unexpected array parameters: mini={mini}, mode={mode}, maxi={maxi}, lambd={lambd}\n"
+        )
+    if isinstance(alpha, np.ndarray) and isinstance(beta, np.ndarray):
+        if np.all(alpha == alpha.flat[0]) and np.all(beta == beta.flat[0]):
+            return alpha[0], beta[0]
+        elif DEBUG:
</code_context>

<issue_to_address>
Returning alpha[0], beta[0] may not always yield scalars.

If alpha and beta are multi-dimensional arrays, alpha[0] and beta[0] may still be arrays. Use .item() to ensure scalars are returned.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
        if np.all(alpha == alpha.flat[0]) and np.all(beta == beta.flat[0]):
            return alpha[0], beta[0]
=======
        if np.all(alpha == alpha.flat[0]) and np.all(beta == beta.flat[0]):
            return alpha.item(), beta.item()
>>>>>>> REPLACE

</suggested_fix>

### Comment 3
<location> `betapert/funcs.py:86` </location>
<code_context>


-def _calc_alpha_beta(mini, mode, maxi, lambd):
+def _calc_alpha_beta(
+    mini: np.float64 | np.ndarray | float | int,
+    mode: np.float64 | np.ndarray | float | int,
</code_context>

<issue_to_address>
Consider extracting array handling and uniformity checks into a helper function and simplifying type hints to streamline the function.

```suggestion
Rather than sprinkling `DEBUG`‐branch logs and nested `isinstance` checks inside `_calc_alpha_beta`, you can:

1. Collapse the array-check into a single `any(...)` call.  
2. Extract the “uniform array → scalar” logic into a tiny helper that uses `np.squeeze`/`.item()`.  
3. Optionally simplify your type hints to `ArrayLike` from `numpy.typing`.

Example:

```python
from numpy.typing import ArrayLike

def _flatten_if_uniform(alpha: ArrayLike, beta: ArrayLike):
    # squeeze out singleton dims
    a0, b0 = np.squeeze(alpha), np.squeeze(beta)
    # if still 0-d arrays, convert to Python scalars
    return (a0.item(), b0.item()) if np.isscalar(a0) and np.isscalar(b0) else (alpha, beta)

def _calc_alpha_beta(
    mini: ArrayLike,
    mode: ArrayLike,
    maxi: ArrayLike,
    lambd: ArrayLike,
) -> tuple[ArrayLike, ArrayLike]:
    alpha = 1 + ((mode - mini) * lambd) / (maxi - mini)
    beta  = 1 + ((maxi - mode) * lambd) / (maxi - mini)

    if DEBUG and any(isinstance(x, np.ndarray) for x in (mini, mode, maxi, lambd)):
        sys.stderr.write(f"CAB: array params mini={mini}, mode={mode}, maxi={maxi}, lambd={lambd}\n")

    return _flatten_if_uniform(alpha, beta)
```

This keeps all functionality, collapses branching, and makes the core logic much tighter.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread betapert/funcs.py Outdated
Comment thread betapert/funcs.py Outdated
Comment on lines +117 to +118
if np.all(alpha == alpha.flat[0]) and np.all(beta == beta.flat[0]):
return alpha[0], beta[0]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Returning alpha[0], beta[0] may not always yield scalars.

If alpha and beta are multi-dimensional arrays, alpha[0] and beta[0] may still be arrays. Use .item() to ensure scalars are returned.

Suggested change
if np.all(alpha == alpha.flat[0]) and np.all(beta == beta.flat[0]):
return alpha[0], beta[0]
if np.all(alpha == alpha.flat[0]) and np.all(beta == beta.flat[0]):
return alpha.item(), beta.item()

Comment thread betapert/funcs.py


def _calc_alpha_beta(mini, mode, maxi, lambd):
def _calc_alpha_beta(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider extracting array handling and uniformity checks into a helper function and simplifying type hints to streamline the function.

Suggested change
def _calc_alpha_beta(
Rather than sprinkling `DEBUG`branch logs and nested `isinstance` checks inside `_calc_alpha_beta`, you can:
1. Collapse the array-check into a single `any(...)` call.
2. Extract theuniform arrayscalarlogic into a tiny helper that uses `np.squeeze`/`.item()`.
3. Optionally simplify your type hints to `ArrayLike` from `numpy.typing`.
Example:
```python
from numpy.typing import ArrayLike
def _flatten_if_uniform(alpha: ArrayLike, beta: ArrayLike):
# squeeze out singleton dims
a0, b0 = np.squeeze(alpha), np.squeeze(beta)
# if still 0-d arrays, convert to Python scalars
return (a0.item(), b0.item()) if np.isscalar(a0) and np.isscalar(b0) else (alpha, beta)
def _calc_alpha_beta(
mini: ArrayLike,
mode: ArrayLike,
maxi: ArrayLike,
lambd: ArrayLike,
) -> tuple[ArrayLike, ArrayLike]:
alpha = 1 + ((mode - mini) * lambd) / (maxi - mini)
beta = 1 + ((maxi - mode) * lambd) / (maxi - mini)
if DEBUG and any(isinstance(x, np.ndarray) for x in (mini, mode, maxi, lambd)):
sys.stderr.write(f"CAB: array params mini={mini}, mode={mode}, maxi={maxi}, lambd={lambd}\n")
return _flatten_if_uniform(alpha, beta)

This keeps all functionality, collapses branching, and makes the core logic much tighter.

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Jul 18, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix boolean operator precedence
Suggestion Impact:The suggestion identified a logic error in the boolean condition. The commit addressed this by completely refactoring the condition to use a more concise 'any()' function with a generator expression, which achieves the same logical intent as the suggested fix.

code diff:

+    if DEBUG and any(isinstance(x, np.ndarray) for x in (mini, mode, maxi, lambd)):
+        sys.stderr.write("CAB: unexpected arrays in method parameters\n")

The boolean logic is incorrect due to operator precedence. The and operator has
higher precedence than or, causing unexpected evaluation. Add parentheses to
group the isinstance checks properly.

betapert/funcs.py [107-112]

 if DEBUG and (
     isinstance(mini, np.ndarray)
-    and isinstance(mode, np.ndarray)
+    or isinstance(mode, np.ndarray)
     or isinstance(maxi, np.ndarray)
     or isinstance(lambd, np.ndarray)
 ):

[Suggestion processed]

Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies a logic error in a debug condition due to operator precedence, and the proposed fix correctly captures the likely intent of checking if any input is an array.

Low
General
Optimize array element access
Suggestion Impact:The suggestion was directly implemented - the code was changed from using alpha.flat[0] and beta.flat[0] to alpha[0] and beta[0] as recommended

code diff:

-        if np.all(alpha == alpha.flat[0]) and np.all(beta == beta.flat[0]):
+        if np.all(alpha == alpha[0]) and np.all(beta == beta[0]):

Using alpha.flat[0] can be inefficient for large arrays and may cause issues
with empty arrays. Use alpha.item() or alpha[0] for better performance and
safety when extracting scalar values.

betapert/funcs.py [116-118]

 if isinstance(alpha, np.ndarray) and isinstance(beta, np.ndarray):
-    if np.all(alpha == alpha.flat[0]) and np.all(beta == beta.flat[0]):
+    if np.all(alpha == alpha[0]) and np.all(beta == beta[0]):
         return alpha[0], beta[0]

[Suggestion processed]

Suggestion importance[1-10]: 4

__

Why: The suggestion correctly points out that using alpha[0] is a more direct and readable way to access the first element of a numpy array than alpha.flat[0], improving code clarity.

Low

No more code suggestions

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses an issue where _calc_alpha_beta could return arrays with identical elements instead of a scalar. The added logic to check for uniform arrays and return a scalar is a good fix, and the new tests validate this behavior correctly.

Comment thread betapert/funcs.py Outdated
Comment thread betapert/funcs.py
sys.stderr.write(
f"CAB: unexpected array parameters: mini={mini}, mode={mode}, maxi={maxi}, lambd={lambd}\n"
)
if isinstance(alpha, np.ndarray) and isinstance(beta, np.ndarray):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This check for isinstance(alpha, np.ndarray) and isinstance(beta, np.ndarray) is slightly redundant. Due to NumPy's broadcasting, if any of the input parameters is an array, both alpha and beta will be np.ndarrays. Checking only one of them is sufficient.

if isinstance(alpha, np.ndarray):

Comment thread tests/test_ppf_log_fallback.py Outdated
Comment thread tests/test_ppf_log_fallback.py Outdated
Copy link
Copy Markdown

@ellipsis-dev ellipsis-dev Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Changes requested ❌

Reviewed everything up to d9ee844 in 2 minutes and 4 seconds. Click for details.
  • Reviewed 95 lines of code in 3 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. betapert/funcs.py:87
  • Draft comment:
    The function signature and type annotations now allow array returns, but the docstring still mentions a tuple of floats. Update the docstring to reflect that scalars or arrays can be returned.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
2. betapert/funcs.py:113
  • Draft comment:
    Consider replacing sys.stderr.write debug prints with the logging module for better configurability and standardized logging.
  • Reason this comment was not posted:
    Confidence changes required: 50% <= threshold 50% None
3. tests/test_ppf_log_fallback.py:315
  • Draft comment:
    In the scalar fallback test, consider using np.isscalar(result_scalar) instead of isinstance(result_scalar, np.number) to more clearly check for a scalar value.
  • Reason this comment was not posted:
    Confidence changes required: 40% <= threshold 50% None

Workflow ID: wflow_Xq63lsCr7pJ3SbMm

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Comment thread betapert/funcs.py Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88bf638 and d9ee844.

📒 Files selected for processing (3)
  • betapert/funcs.py (2 hunks)
  • pyproject.toml (1 hunks)
  • tests/test_ppf_log_fallback.py (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Pytest, ruff, and black
tests/test_ppf_log_fallback.py

[error] 372-372: Ruff PLC0415: import should be at the top-level of a file.


[error] 372-373: Ruff I001: Import block is un-sorted or un-formatted. Organize imports.


[error] 373-373: Ruff PLC0415: import should be at the top-level of a file.


[error] 389-389: Ruff I001: Import block is un-sorted or un-formatted. Organize imports.


[error] 389-390: Ruff PLC0415: import should be at the top-level of a file.


[error] 390-390: Ruff PLC0415: import should be at the top-level of a file.

betapert/funcs.py

[error] 87-90: Ruff PYI041: Use float instead of int | float. Remove redundant type annotations in function parameters.


[error] 108-108: Ruff RUF021: Parenthesize a and b expressions when chaining and and or together to clarify precedence.


[error] 114-114: Ruff E501: Line too long (103 > 100).


[error] 114-114: Ruff COM812: Trailing comma missing.


[error] 119-119: Ruff RET505: Unnecessary elif after return statement. Remove unnecessary elif.

🔇 Additional comments (3)
pyproject.toml (1)

4-4: Version bump looks appropriate for the feature addition.

The minor version increment from 0.1.9 to 0.2.0 correctly reflects the addition of new conditional logic in _calc_alpha_beta function.

betapert/funcs.py (1)

104-121: The core logic for conditional scalar/array returns is well-implemented.

The implementation correctly identifies when alpha and beta arrays have uniform values and returns scalars in those cases, which addresses the PR objective of preventing unexpected array returns.

tests/test_ppf_log_fallback.py (1)

370-402: Test logic correctly validates the new conditional behavior.

Both tests properly verify that _calc_alpha_beta returns scalars when input arrays have uniform elements and returns arrays when elements differ, which aligns with the PR objective.

Comment thread betapert/funcs.py
Comment thread betapert/funcs.py
Comment thread betapert/funcs.py Outdated
Comment thread tests/test_ppf_log_fallback.py
Comment thread tests/test_ppf_log_fallback.py
@hbmartin hbmartin merged commit ab5f580 into main Jul 18, 2025
4 checks passed
@hbmartin hbmartin deleted the prevent-unexpected-alpha-beta-array branch July 18, 2025 17:12
Copy link
Copy Markdown

@ellipsis-dev ellipsis-dev Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed 60d5e8f in 2 minutes and 26 seconds. Click for details.
  • Reviewed 95 lines of code in 3 files
  • Skipped 1 files when reviewing.
  • Skipped posting 4 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. betapert/funcs.py:87
  • Draft comment:
    Type hints now exclude 'int'. If integer values are expected, consider including them (or document that ints will be accepted via implicit conversion).
  • Reason this comment was not posted:
    Confidence changes required: 50% <= threshold 50% None
2. betapert/funcs.py:110
  • Draft comment:
    Using alpha[0] assumes a 1D array. For multi-dimensional arrays, consider using alpha.flat[0] to ensure a true scalar is returned when all elements are equal.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% Looking at the code, this is inside _calc_alpha_beta which takes numpy arrays as input. The alpha/beta calculations are simple arithmetic operations that preserve array shape. For multi-dimensional arrays, both [0] and flat[0] would work - [0] gets the first element along the first axis, flat[0] gets the first element in flattened order. Since we're checking np.all(alpha == alpha[0]), we're already verifying all elements are equal, so the specific access method doesn't matter. The comment raises a valid point about multi-dimensional arrays behaving differently. Maybe there's an edge case where the array elements are equal but in different order between flattened and non-flattened views? Since np.all() is checking element-wise equality with alpha[0], if all elements are equal, they must be equal regardless of array shape or access method. The order doesn't matter when all elements are the same value. The comment suggests a change that would be functionally equivalent and not fix any real issues. The current code is correct as-is.
3. betapert/funcs.py:107
  • Draft comment:
    Rather than using sys.stderr.write for debug logging, consider using the logging module for better configurability and integration.
  • Reason this comment was not posted:
    Confidence changes required: 40% <= threshold 50% None
4. tests/test_ppf_log_fallback.py:315
  • Draft comment:
    Using isinstance(result_scalar, np.number) may not catch native Python floats. Consider using np.isscalar(result_scalar) to check for scalar values.
  • Reason this comment was not posted:
    Confidence changes required: 50% <= threshold 50% None

Workflow ID: wflow_kfzJIL4MpX26WF1C

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant