Skip to content

Seg-Transaction-Stats #153

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

Merged
merged 1 commit into from
Mar 25, 2025
Merged

Seg-Transaction-Stats #153

merged 1 commit into from
Mar 25, 2025

Conversation

mayurkmmt
Copy link
Collaborator

@mayurkmmt mayurkmmt commented Mar 25, 2025

User description

feat: added params to cal total row


PR Type

Enhancement, Tests


Description

  • Added calc_total parameter to include/exclude total row.

  • Updated _calc_seg_stats to handle calc_total logic.

  • Enhanced tests to validate calc_total functionality.

  • Added a new test to verify exclusion of total row.


Changes walkthrough 📝

Relevant files
Enhancement
segmentation.py
Add `calc_total` parameter and update aggregation logic   

pyretailscience/analysis/segmentation.py

  • Introduced calc_total parameter in SegTransactionStats.
  • Updated _calc_seg_stats to conditionally include total row.
  • Adjusted logic for segment and total metrics aggregation.
  • Improved error message for invalid data types.
  • +14/-5   
    Tests
    test_segmentation.py
    Add and update tests for `calc_total` functionality           

    tests/analysis/test_segmentation.py

  • Modified existing tests to include calc_total parameter.
  • Added a new test to verify exclusion of total row.
  • Enhanced test cases for multiple segment columns and extra
    aggregations.
  • Validated calc_total functionality across various scenarios.
  • +53/-7   

    Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • Summary by CodeRabbit

    • New Features

      • Introduced an optional parameter that allows users to control the inclusion of an aggregate total row with segmented metrics.
    • Documentation

      • Updated documentation to reflect the new parameter and its impact on aggregated results.
    • Tests

      • Enhanced test coverage to verify the behavior of the total row inclusion based on the new parameter.

    Copy link

    coderabbitai bot commented Mar 25, 2025

    Walkthrough

    This pull request introduces an optional calc_total parameter to the SegTransactionStats class and its _calc_seg_stats method. When set to True, the implementation calculates and unions a total row with the segmented metrics. Method signatures and documentation have been updated accordingly. The tests have been modified to instantiate the class with the new parameter and include a new test to verify that the total row is excluded when calc_total is False.

    Changes

    File Change Summary
    pyretailscience/analysis/segmentation.py Added an optional calc_total parameter (default True) to __init__ and _calc_seg_stats. Modified logic to calculate total metrics when enabled using ibis.union. Updated docstrings.
    tests/analysis/test_segmentation.py Updated test cases to instantiate SegTransactionStats with calc_total=True in multiple tests. Added a new test (test_excludes_total_row_when_calc_total_false) to verify behavior when calc_total is False.

    Sequence Diagram(s)

    sequenceDiagram
        participant C as Client
        participant S as SegTransactionStats
        participant M as _calc_seg_stats
    
        C->>S: Instantiate with calc_total (true/false)
        S->>M: Call _calc_seg_stats(calc_total)
        alt calc_total true
            M->>M: Calculate segment metrics
            M->>M: Calculate total metrics using ibis.union
            M-->>S: Return combined metrics
        else calc_total false
            M->>M: Calculate segment metrics only
            M-->>S: Return segment metrics only
        end
    
    Loading

    Possibly related PRs

    Suggested labels

    enhancement, Tests, Review effort [1-5]: 3

    Poem

    I'm a little rabbit, hopping through code,
    With calc_total added, metrics now explode.
    Union the totals, or leave them behind,
    In every branch, clarity we find.
    Hop along smoothly in this new mode!
    Cheers to changes in a bunny-coded ode!


    📜 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 bbccdb8 and af3dca1.

    ⛔ Files ignored due to path filters (1)
    • uv.lock is excluded by !**/*.lock
    📒 Files selected for processing (2)
    • pyretailscience/analysis/segmentation.py (7 hunks)
    • tests/analysis/test_segmentation.py (2 hunks)
    🚧 Files skipped from review as they are similar to previous changes (1)
    • pyretailscience/analysis/segmentation.py
    🔇 Additional comments (2)
    tests/analysis/test_segmentation.py (2)

    133-157: Well-implemented test case for the new calc_total parameter.

    This test properly validates that when calc_total=False is passed to SegTransactionStats, the total row is excluded from the results. The test has a clear structure with appropriate assertions.

    I notice that the customers_pct is set to 1.0 for both segments when there's no total row. This is a logical adjustment since percentages are now calculated relative to each segment itself rather than to a total.


    435-440: Good formatting improvement.

    Breaking the parameters onto separate lines makes this code more readable without changing functionality.

    ✨ Finishing Touches
    • 📝 Generate Docstrings

    🪧 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.
      • Generate unit testing code for this file.
      • 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 generate unit testing code for this file.
      • @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 generate unit testing code.
      • @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.

    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 resolve resolve all the CodeRabbit review comments.
    • @coderabbitai plan to trigger planning for file edits and PR creation.
    • @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.

    Copy link
    Contributor

    Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

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

    Parameter Order

    The calc_total parameter was added between existing parameters in _calc_seg_stats method, but it's generally better practice to add new optional parameters at the end to maintain backward compatibility.

    calc_total: bool = False,
    Docstring Inconsistency

    The docstring for _calc_seg_stats method lists parameters in a different order than they appear in the function signature, with calc_total appearing after extra_aggs in the docstring.

    calc_total (bool, optional): Whether to include the total row. Defaults to False.

    Copy link
    Contributor

    qodo-merge-pro bot commented Mar 25, 2025

    Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Missing customer percentage calculation

    The customers_pct calculation is missing in the mutate operation. When
    calc_total=False, the percentage calculation will be incorrect as it needs to be
    calculated relative to the total number of customers.

    pyretailscience/analysis/segmentation.py [324-339]

     # Calculate metrics for segments
     segment_metrics = data.group_by(segment_col).aggregate(**aggs)
     final_metrics = segment_metrics
     
     if calc_total:
         total_metrics = data.aggregate(**aggs).mutate({col: ibis.literal("Total") for col in segment_col})
         final_metrics = ibis.union(segment_metrics, total_metrics)
     
     total_customers = data[cols.customer_id].nunique()
     
     # Cross join with total_customers to make it available for percentage calculation
     final_metrics = final_metrics.mutate(
         **{
             cols.calc_spend_per_cust: ibis._[cols.agg_unit_spend] / ibis._[cols.agg_customer_id],
             cols.calc_spend_per_trans: ibis._[cols.agg_unit_spend] / ibis._[cols.agg_transaction_id],
             cols.calc_trans_per_cust: ibis._[cols.agg_transaction_id] / ibis._[cols.agg_customer_id].cast("float"),
    +        cols.customers_pct: ibis._[cols.agg_customer_id] / total_customers,
    • Apply this suggestion
    Suggestion importance[1-10]: 9

    __

    Why: The suggestion identifies a critical bug where the customers_pct calculation is missing in the mutate operation. Without this, percentage calculations would be incorrect when calc_total=False, affecting core functionality of the segmentation analysis.

    High
    • Update

    Copy link

    @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: 0

    🧹 Nitpick comments (1)
    pyretailscience/analysis/segmentation.py (1)

    324-331: Simplify the conditional logic

    The implementation could be simplified by avoiding the intermediate final_metrics assignment.

    # Calculate metrics for segments
    segment_metrics = data.group_by(segment_col).aggregate(**aggs)
    -final_metrics = segment_metrics
    -
    if calc_total:
        total_metrics = data.aggregate(**aggs).mutate({col: ibis.literal("Total") for col in segment_col})
    -   final_metrics = ibis.union(segment_metrics, total_metrics)
    +   segment_metrics = ibis.union(segment_metrics, total_metrics)
    
    total_customers = data[cols.customer_id].nunique()
    
    # Cross join with total_customers to make it available for percentage calculation
    -final_metrics = final_metrics.mutate(
    +segment_metrics = segment_metrics.mutate(

    This simplifies the code by avoiding the intermediate variable and makes the flow clearer.

    📜 Review details

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

    📥 Commits

    Reviewing files that changed from the base of the PR and between a12b64b and bbccdb8.

    ⛔ Files ignored due to path filters (1)
    • uv.lock is excluded by !**/*.lock
    📒 Files selected for processing (2)
    • pyretailscience/analysis/segmentation.py (7 hunks)
    • tests/analysis/test_segmentation.py (8 hunks)
    🧰 Additional context used
    🧬 Code Definitions (2)
    pyretailscience/analysis/segmentation.py (1)
    tests/analysis/test_revenue_tree.py (1)
    • cols (16-18)
    tests/analysis/test_segmentation.py (1)
    pyretailscience/analysis/segmentation.py (4)
    • SegTransactionStats (188-464)
    • df (145-149)
    • df (355-369)
    • df (567-571)
    🔇 Additional comments (14)
    tests/analysis/test_segmentation.py (9)

    54-55: LGTM - Parameter addition for calc_total

    The addition of calc_total=True ensures this test continues to work as expected with the total row included.


    84-88: LGTM - Parameter addition for calc_total

    The addition of calc_total=True ensures this test continues to include the total row in its assertions.


    112-116: LGTM - Parameter addition for calc_total

    The addition of calc_total=True ensures this test continues to include the total row in its assertions.


    139-145: LGTM - Parameter addition for calc_total

    The addition of calc_total=True ensures this test continues to include the total row in its assertions.


    147-171: Great addition of test for the new functionality

    This new test case properly verifies that when calc_total=False is passed, the total row is excluded from the results. The test has appropriate assertions checking that only segment rows (A, B) are present.


    377-377: LGTM - Parameter addition for calc_total

    The addition of calc_total=True ensures this test continues to include the total row in its assertions.


    421-421: LGTM - Parameter addition for calc_total

    The addition of calc_total=True ensures this test continues to include the total row in its assertions.


    449-455: LGTM - Parameter addition for calc_total

    The addition of calc_total=True ensures this test continues to include the total row for the extra_aggs functionality.


    468-472: LGTM - Parameter addition for calc_total

    The addition of calc_total=True ensures this test continues to include the total row for multiple extra_aggs tests.

    pyretailscience/analysis/segmentation.py (5)

    197-197: LGTM - Addition of the calc_total parameter

    The addition of the calc_total parameter with a default value of False is a good choice as it maintains backward compatibility with existing code that doesn't set this parameter explicitly.


    209-209: LGTM - Updated docstring

    The docstring has been appropriately updated to include documentation for the new parameter.


    249-249: LGTM - Updated method call

    The call to _calc_seg_stats has been updated to correctly pass the new calc_total parameter.


    284-284: LGTM - Addition of the calc_total parameter

    The calc_total parameter has been properly added to the static method with the same default value for consistency.


    293-294: LGTM - Updated docstring

    The docstring for the static method has been appropriately updated to include documentation for the new parameter.

    Copy link

    codecov bot commented Mar 25, 2025

    Codecov Report

    Attention: Patch coverage is 85.71429% with 1 line in your changes missing coverage. Please review.

    Files with missing lines Patch % Lines
    pyretailscience/analysis/segmentation.py 85.71% 1 Missing ⚠️
    Files with missing lines Coverage Δ
    pyretailscience/analysis/segmentation.py 76.47% <85.71%> (+0.35%) ⬆️
    🚀 New features to boost your workflow:
    • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

    @@ -194,6 +194,7 @@ def __init__(
    self,
    data: pd.DataFrame | ibis.Table,
    segment_col: str | list[str] = "segment_name",
    calc_total: bool = False,
    Copy link
    Contributor

    Choose a reason for hiding this comment

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

    Can you make this default to True please

    @mayurkmmt mayurkmmt force-pushed the feature/seg-transaction-stats branch from bbccdb8 to af3dca1 Compare March 25, 2025 10:48
    @mayurkmmt mayurkmmt merged commit 91edbf4 into main Mar 25, 2025
    3 checks passed
    @coderabbitai coderabbitai bot mentioned this pull request Mar 28, 2025
    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.

    2 participants