Skip to content

Conversation

@zMynxx
Copy link
Contributor

@zMynxx zMynxx commented Oct 18, 2025

PR Type

Bug fix


Description

  • Remove global steps variable, convert to local parameter

  • Pass steps list as parameter to all functions that append to it

  • Update all function calls to include steps argument

  • Update test cases to initialize and pass steps parameter


Diagram Walkthrough

flowchart LR
  A["Global steps variable"] -->|Remove| B["Local steps list"]
  B -->|Pass as parameter| C["Unit conversion functions"]
  B -->|Pass as parameter| D["Pricing calculation functions"]
  C -->|Append to steps| E["Calculation flow"]
  D -->|Append to steps| E
Loading

File Walkthrough

Relevant files
Bug fix
calculator.py
Convert steps from global to local parameter                         

aws-lambda-calculator/src/aws_lambda_calculator/calculator.py

  • Remove global steps = [] declaration at module level
  • Add steps: list[str] parameter to unit_conversion_requests(),
    unit_conversion_memory(), unit_conversion_ephemeral_storage(),
    calculate_tiered_cost(), calc_monthly_compute_charges(),
    calc_monthly_request_charges(), and
    calc_monthly_ephemeral_storage_charges()
  • Initialize steps as local variable in calculate() function
  • Update all function calls to pass steps argument
+21/-13 
Tests
test_calculator_coverage.py
Update tests to pass steps parameter                                         

aws-lambda-calculator/tests/test_calculator_coverage.py

  • Initialize empty steps = [] list in each test method before calling
    functions
  • Update all function calls to include steps parameter in test
    assertions
  • Maintain test logic and expected values while adapting to new function
    signatures
+30/-15 

@codiumai-pr-agent-free
Copy link
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
- [ ] Create ticket/issue <!-- /create_ticket --create_ticket=true -->

</details></td></tr>
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
No custom compliance provided

Follow the guide to enable custom compliance check.

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@github-actions
Copy link
Contributor

github-actions bot commented Oct 18, 2025

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
565 552 98% 0% 🟢

New Files

No new covered files...

Modified Files

No covered modified files...

updated for commit: f4a94df by action🐍

@github-actions
Copy link
Contributor

github-actions bot commented Oct 18, 2025

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  aws-lambda-calculator/src/aws_lambda_calculator
  calculator.py 83
Project Total  

This report was generated by python-coverage-comment-action

@codiumai-pr-agent-free
Copy link
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Refactor to a class-based design

Refactor the procedural functions into a Calculator class to manage the steps
list as an instance variable. This change would eliminate the need to pass steps
as a parameter across multiple functions, leading to a cleaner design.

Examples:

aws-lambda-calculator/src/aws_lambda_calculator/calculator.py [296-377]
def calculate(
    region: str = "us-east-1",
    architecture: Literal["x86", "arm64"] = "x86",
    number_of_requests: int = 1000000,
    request_unit: Literal[
        "per second",
        "per minute",
        "per hour",
        "per day",
        "per month",

 ... (clipped 72 lines)

Solution Walkthrough:

Before:

def calculate(...):
    steps: list[str] = []
    ...
    requests_per_month = unit_conversion_requests(..., steps)
    ...
    monthly_charges = calc_monthly_compute_charges(..., steps)
    ...
    return CalculationResult(..., steps=steps)

def unit_conversion_requests(..., steps: list[str]):
    ...
    steps.append("some calculation step")
    ...

def calc_monthly_compute_charges(..., steps: list[str]):
    ...
    steps.append("another calculation step")
    ...

After:

class Calculator:
    def __init__(self):
        self.steps: list[str] = []

    def calculate(self, ...):
        ...
        requests_per_month = self._unit_conversion_requests(...)
        ...
        monthly_charges = self._calc_monthly_compute_charges(...)
        ...
        return CalculationResult(..., steps=self.steps)

    def _unit_conversion_requests(self, ...):
        ...
        self.steps.append("some calculation step")
        ...

    def _calc_monthly_compute_charges(self, ...):
        ...
        self.steps.append("another calculation step")
        ...
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a design weakness in passing the steps parameter through many functions and proposes a superior, object-oriented refactoring that would significantly improve the code's structure and maintainability.

High
Possible issue
Utilize the unused steps parameter

Utilize the unused steps parameter in calculate_tiered_cost by appending the
tiered and overflow cost calculation details to it for a complete calculation
breakdown.

aws-lambda-calculator/src/aws_lambda_calculator/calculator.py [132-180]

 def calculate_tiered_cost(
     total_compute_gb_sec: float,
     tier_cost_factor: dict[str, float],
     overflow_rate: float,
     steps: list[str],
 ) -> float:
     """
     total_compute_gb_sec: total usage in GB‑seconds
     tier_cost_factor: maps breakpoint (as string) → rate
     overflow_rate: per‑GB‑sec rate for usage beyond the highest breakpoint
     """
     # 1) parse & sort tiers by threshold (ascending)
     tiers = sorted(
         (int(thresh), float(rate)) for thresh, rate in tier_cost_factor.items()
     )
 
     total_cost = 0.0
     prev_threshold = 0.0
+    remaining_gb_sec = total_compute_gb_sec
 
     # 2) bill each tier up to its cap
     for threshold, rate in tiers:
-        if total_compute_gb_sec <= 0:
+        if remaining_gb_sec <= 0:
             break
 
         tier_cap = threshold - prev_threshold
-        usage_in_tier = min(total_compute_gb_sec, tier_cap)
+        usage_in_tier = min(remaining_gb_sec, tier_cap)
         cost_for_tier = usage_in_tier * rate
+        steps.append(
+            f"Tier {prev_threshold}-{threshold} GB-s: {usage_in_tier:.2f} GB-s * ${rate} = ${cost_for_tier:.10f}"
+        )
         total_cost += cost_for_tier
-        total_compute_gb_sec -= usage_in_tier
+        remaining_gb_sec -= usage_in_tier
         prev_threshold = threshold
 
     # 3) bill remaining usage at the overflow rate
-    if total_compute_gb_sec > 0:
-        overflow_cost = total_compute_gb_sec * overflow_rate
+    if remaining_gb_sec > 0:
+        overflow_cost = remaining_gb_sec * overflow_rate
+        steps.append(
+            f"Overflow (> {prev_threshold} GB-s): {remaining_gb_sec:.2f} GB-s * ${overflow_rate} = ${overflow_cost:.10f}"
+        )
         total_cost += overflow_cost
 
     return total_cost

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies that the steps parameter is unused in calculate_tiered_cost, which is an oversight given the PR's goal of logging calculation steps. Implementing this change makes the function's behavior consistent with other updated functions and completes the intended logging feature.

Medium
  • More

@sonarqubecloud
Copy link

@zMynxx zMynxx merged commit dae46fe into main Oct 18, 2025
14 checks passed
@zMynxx zMynxx deleted the fix/local-steps branch October 18, 2025 00:19
Comment on lines +28 to +30
def unit_conversion_requests(
number_of_requests: int, request_unit: str, steps: list[str]
) -> int:

Check notice

Code scanning / CodeQL

Explicit returns mixed with implicit (fall through) returns Note

Mixing implicit and explicit returns may indicate an error, as implicit returns always return None.

Copilot Autofix

AI 24 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.



def unit_conversion_memory(memory: float, memory_unit: str) -> float:
def unit_conversion_memory(memory: float, memory_unit: str, steps: list[str]) -> float:

Check notice

Code scanning / CodeQL

Explicit returns mixed with implicit (fall through) returns Note

Mixing implicit and explicit returns may indicate an error, as implicit returns always return None.

Copilot Autofix

AI 24 days ago

To fix the issue, we need to ensure that unit_conversion_memory never falls off the end of the function and implicitly returns None. The best way to do this is to add an explicit return at the end of the function, preferably return None, since if execution ever reaches the end without hitting one of the match cases, it most likely denotes an error or unexpected value for memory_unit. No changes in imports or other definitions are required, just a single line addition at the end of the function at line 106 in aws-lambda-calculator/src/aws_lambda_calculator/calculator.py.


Suggested changeset 1
aws-lambda-calculator/src/aws_lambda_calculator/calculator.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/aws-lambda-calculator/src/aws_lambda_calculator/calculator.py b/aws-lambda-calculator/src/aws_lambda_calculator/calculator.py
--- a/aws-lambda-calculator/src/aws_lambda_calculator/calculator.py
+++ b/aws-lambda-calculator/src/aws_lambda_calculator/calculator.py
@@ -103,8 +103,8 @@
             return memory
         case _:
             raise ValueError(f"Unknown memory unit: {memory_unit}")
+    return None
 
-
 def unit_conversion_ephemeral_storage(
     ephemeral_storage_mb: float, storage_unit: str, steps: list[str]
 ) -> float:
EOF
@@ -103,8 +103,8 @@
return memory
case _:
raise ValueError(f"Unknown memory unit: {memory_unit}")
return None


def unit_conversion_ephemeral_storage(
ephemeral_storage_mb: float, storage_unit: str, steps: list[str]
) -> float:
Copilot is powered by AI and may make mistakes. Always verify output.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR removes the module-level global steps and refactors it into a passed-in accumulator list, making the computation trace explicit and locally scoped.

  • Add steps: list[str] parameter to conversion and pricing functions; propagate through calculate and tests.
  • Remove global steps; initialize a local steps list in calculate.
  • Update tests to pass a local steps list into affected functions.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
aws-lambda-calculator/src/aws_lambda_calculator/calculator.py Removes global steps, adds steps parameter across functions, and wires it through calculate.
aws-lambda-calculator/tests/test_calculator_coverage.py Updates tests to pass a local steps list to affected APIs.
Comments suppressed due to low confidence (2)

aws-lambda-calculator/src/aws_lambda_calculator/calculator.py:141

  • The docstring is missing documentation for the new steps parameter; please add a brief description (e.g., 'steps: list collecting calculation trace lines').
def calculate_tiered_cost(
    total_compute_gb_sec: float,
    tier_cost_factor: dict[str, float],
    overflow_rate: float,
    steps: list[str],
) -> float:
    """
    total_compute_gb_sec: total usage in GB‑seconds
    tier_cost_factor: maps breakpoint (as string) → rate
    overflow_rate: per‑GB‑sec rate for usage beyond the highest breakpoint

aws-lambda-calculator/src/aws_lambda_calculator/calculator.py:141

  • Docstring parameter list for calculate_tiered_cost omits steps; include an entry (e.g., 'steps: accumulator for detailed trace messages') to keep documentation consistent with the signature.
    """
    total_compute_gb_sec: total usage in GB‑seconds
    tier_cost_factor: maps breakpoint (as string) → rate
    overflow_rate: per‑GB‑sec rate for usage beyond the highest breakpoint

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +28 to +30
def unit_conversion_requests(
number_of_requests: int, request_unit: str, steps: list[str]
) -> int:
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

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

[nitpick] Adding a required steps parameter is a breaking API change for external callers. Consider making it optional to preserve backward compatibility, e.g., steps: list[str] | None = None and only append when steps is not None; apply the same pattern to unit_conversion_memory and unit_conversion_ephemeral_storage.

Copilot uses AI. Check for mistakes.


def unit_conversion_memory(memory: float, memory_unit: str) -> float:
def unit_conversion_memory(memory: float, memory_unit: str, steps: list[str]) -> float:
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

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

[nitpick] Same breaking change concern: make steps optional (steps: list[str] | None = None) and guard appends to avoid forcing all callers to pass a list.

Copilot uses AI. Check for mistakes.
Comment on lines +109 to 110
ephemeral_storage_mb: float, storage_unit: str, steps: list[str]
) -> float:
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

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

[nitpick] Same breaking change concern: make steps optional and only append when provided, to avoid breaking existing consumers.

Copilot uses AI. Check for mistakes.
Comment on lines +226 to 227
requests_per_month: float, requests_cost_factor: float, steps: list[str]
) -> float:
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

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

[nitpick] Same as above: make steps optional to preserve backward compatibility with existing callers.

Copilot uses AI. Check for mistakes.
Comment on lines 239 to 243
storage_in_gb: float,
ephemeral_storage_cost_factor: float,
total_compute_gb_sec: float,
steps: list[str],
) -> float:
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

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

[nitpick] Same as above: make steps optional to avoid breaking changes; only append when steps is not None.

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +40
steps = []
result = unit_conversion_requests(100, "per minute", steps)
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

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

[nitpick] steps = [] is repeated across many tests; consider a pytest fixture (e.g., a steps() function returning a new list) to reduce duplication and make the intent clearer.

Copilot uses AI. Check for mistakes.
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