Skip to content

Commit f4a94df

Browse files
committed
fix: steps is now use as a local variable accumulator instead of gloabal.
1 parent b6936c0 commit f4a94df

File tree

2 files changed

+51
-28
lines changed

2 files changed

+51
-28
lines changed

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

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
load_dotenv()
1010

1111
logger = logging.getLogger(__name__)
12-
steps = []
1312

1413

1514
def open_json_file(region: str) -> dict[str, Any]:
@@ -26,7 +25,9 @@ def open_json_file(region: str) -> dict[str, Any]:
2625
return data
2726

2827

29-
def unit_conversion_requests(number_of_requests: int, request_unit: str) -> int:
28+
def unit_conversion_requests(
29+
number_of_requests: int, request_unit: str, steps: list[str]
30+
) -> int:
3031
"""
3132
@brief Convert number of requests based on the unit provided. Assuming 730 hours in a month (30 days). Assuming 24 hours in a day.
3233
@param number_of_requests: The number of requests to convert.
@@ -82,7 +83,7 @@ def unit_conversion_requests(number_of_requests: int, request_unit: str) -> int:
8283
raise ValueError(f"Unknown request unit: {request_unit}")
8384

8485

85-
def unit_conversion_memory(memory: float, memory_unit: str) -> float:
86+
def unit_conversion_memory(memory: float, memory_unit: str, steps: list[str]) -> float:
8687
"""
8788
@brief Convert memory based on the unit provided.
8889
@param memory: amount of memory.
@@ -105,7 +106,7 @@ def unit_conversion_memory(memory: float, memory_unit: str) -> float:
105106

106107

107108
def unit_conversion_ephemeral_storage(
108-
ephemeral_storage_mb: float, storage_unit: str
109+
ephemeral_storage_mb: float, storage_unit: str, steps: list[str]
109110
) -> float:
110111
"""
111112
@brief Convert ephemeral storage based on the unit provided.
@@ -132,6 +133,7 @@ def calculate_tiered_cost(
132133
total_compute_gb_sec: float,
133134
tier_cost_factor: dict[str, float],
134135
overflow_rate: float,
136+
steps: list[str],
135137
) -> float:
136138
"""
137139
total_compute_gb_sec: total usage in GB‑seconds
@@ -183,6 +185,7 @@ def calc_monthly_compute_charges(
183185
duration_of_each_request_in_ms: int,
184186
memory_in_gb: float,
185187
tier_cost_factor: dict[str, float],
188+
steps: list[str],
186189
) -> tuple[float, float]:
187190
"""
188191
@brief Calculate the monthly compute charges based on requests per month, duration of each request in ms, and memory in GB.
@@ -214,13 +217,13 @@ def calc_monthly_compute_charges(
214217
# anything above 15 B GB‑sec
215218
overflow_rate = 0.0000133334
216219
monthly_compute_charges = calculate_tiered_cost(
217-
total_compute_gb_sec, tier_cost_factor, overflow_rate
220+
total_compute_gb_sec, tier_cost_factor, overflow_rate, steps
218221
)
219222
return total_compute_gb_sec, monthly_compute_charges
220223

221224

222225
def calc_monthly_request_charges(
223-
requests_per_month: float, requests_cost_factor: float
226+
requests_per_month: float, requests_cost_factor: float, steps: list[str]
224227
) -> float:
225228
res = float(requests_per_month) * float(requests_cost_factor)
226229
logger.debug(
@@ -236,6 +239,7 @@ def calc_monthly_ephemeral_storage_charges(
236239
storage_in_gb: float,
237240
ephemeral_storage_cost_factor: float,
238241
total_compute_gb_sec: float,
242+
steps: list[str],
239243
) -> float:
240244
billable_storage = max(0.0, float(storage_in_gb) - 0.5)
241245
gb_s = billable_storage * total_compute_gb_sec
@@ -322,8 +326,7 @@ def calculate(
322326
storage_unit=storage_unit,
323327
)
324328

325-
global steps
326-
steps = []
329+
steps: list[str] = []
327330

328331
logger.info("Starting cost calculation...")
329332

@@ -344,9 +347,13 @@ def calculate(
344347
if request_unit != "per month" or memory_unit != "GB" or storage_unit != "GB":
345348
logger.debug("Unit conversions:")
346349
steps.append("\nUnit conversions:")
347-
requests_per_month = unit_conversion_requests(number_of_requests, request_unit)
348-
memory_in_gb = unit_conversion_memory(memory, memory_unit)
349-
storage_in_gb = unit_conversion_ephemeral_storage(ephemeral_storage, storage_unit)
350+
requests_per_month = unit_conversion_requests(
351+
number_of_requests, request_unit, steps
352+
)
353+
memory_in_gb = unit_conversion_memory(memory, memory_unit, steps)
354+
storage_in_gb = unit_conversion_ephemeral_storage(
355+
ephemeral_storage, storage_unit, steps
356+
)
350357

351358
# Step 5
352359
logger.debug("Pricing calculations:")
@@ -356,16 +363,17 @@ def calculate(
356363
duration_of_each_request_in_ms,
357364
memory_in_gb,
358365
tier_cost_factor,
366+
steps,
359367
)
360368
logger.debug(f"Monthly compute charges: {monthly_compute_charges} USD")
361369
steps.append(f"Monthly compute charges: {monthly_compute_charges} USD\n")
362370
monthly_request_charges = calc_monthly_request_charges(
363-
requests_per_month, requests_cost_factor
371+
requests_per_month, requests_cost_factor, steps
364372
)
365373
logger.debug(f"Monthly request charges: {monthly_request_charges} USD")
366374
steps.append(f"Monthly request charges: {monthly_request_charges} USD\n")
367375
monthly_ephemeral_storage_charges = calc_monthly_ephemeral_storage_charges(
368-
storage_in_gb, ephemeral_storage_cost_factor, total_compute_gb_sec
376+
storage_in_gb, ephemeral_storage_cost_factor, total_compute_gb_sec, steps
369377
)
370378
logger.debug(
371379
f"Monthly ephemeral storage charges: {monthly_ephemeral_storage_charges} USD"

aws-lambda-calculator/tests/test_calculator_coverage.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,88 +29,103 @@ def test_open_json_file_invalid_region(self):
2929

3030
def test_unit_conversion_requests_per_second(self):
3131
"""Test request conversion for per second unit."""
32-
result = unit_conversion_requests(100, "per second")
32+
steps = []
33+
result = unit_conversion_requests(100, "per second", steps)
3334
expected = 100 * 60 * 60 * 730 # per second to per month
3435
assert result == expected
3536

3637
def test_unit_conversion_requests_per_minute(self):
3738
"""Test request conversion for per minute unit."""
38-
result = unit_conversion_requests(100, "per minute")
39+
steps = []
40+
result = unit_conversion_requests(100, "per minute", steps)
3941
expected = 100 * 60 * 730 # per minute to per month
4042
assert result == expected
4143

4244
def test_unit_conversion_requests_per_hour(self):
4345
"""Test request conversion for per hour unit."""
44-
result = unit_conversion_requests(100, "per hour")
46+
steps = []
47+
result = unit_conversion_requests(100, "per hour", steps)
4548
expected = 100 * 730 # per hour to per month
4649
assert result == expected
4750

4851
def test_unit_conversion_requests_per_day(self):
4952
"""Test request conversion for per day unit."""
50-
result = unit_conversion_requests(100, "per day")
53+
steps = []
54+
result = unit_conversion_requests(100, "per day", steps)
5155
expected = int(100 * (730 / 24)) # per day to per month
5256
assert result == expected
5357

5458
def test_unit_conversion_requests_per_month(self):
5559
"""Test request conversion for per month unit."""
56-
result = unit_conversion_requests(100, "per month")
60+
steps = []
61+
result = unit_conversion_requests(100, "per month", steps)
5762
assert result == 100
5863

5964
def test_unit_conversion_requests_million_per_month(self):
6065
"""Test request conversion for million per month unit."""
61-
result = unit_conversion_requests(5, "million per month")
66+
steps = []
67+
result = unit_conversion_requests(5, "million per month", steps)
6268
assert result == 5_000_000
6369

6470
def test_unit_conversion_requests_invalid_unit(self):
6571
"""Test request conversion with invalid unit."""
72+
steps = []
6673
with pytest.raises(ValueError, match="Unknown request unit"):
67-
unit_conversion_requests(100, "invalid-unit")
74+
unit_conversion_requests(100, "invalid-unit", steps)
6875

6976
def test_unit_conversion_memory_mb(self):
7077
"""Test memory conversion from MB."""
71-
result = unit_conversion_memory(1024, "MB")
78+
steps = []
79+
result = unit_conversion_memory(1024, "MB", steps)
7280
expected = 1024 * 0.0009765625 # MB to GB
7381
assert result == approx(expected)
7482

7583
def test_unit_conversion_memory_gb(self):
7684
"""Test memory conversion from GB."""
77-
result = unit_conversion_memory(2, "GB")
85+
steps = []
86+
result = unit_conversion_memory(2, "GB", steps)
7887
assert result == 2
7988

8089
def test_unit_conversion_memory_invalid_unit(self):
8190
"""Test memory conversion with invalid unit."""
91+
steps = []
8292
with pytest.raises(ValueError, match="Unknown memory unit"):
83-
unit_conversion_memory(1024, "invalid-unit")
93+
unit_conversion_memory(1024, "invalid-unit", steps)
8494

8595
def test_unit_conversion_ephemeral_storage_mb(self):
8696
"""Test ephemeral storage conversion from MB."""
87-
result = unit_conversion_ephemeral_storage(1024, "MB")
97+
steps = []
98+
result = unit_conversion_ephemeral_storage(1024, "MB", steps)
8899
expected = 1024 * 0.0009765625 # MB to GB
89100
assert result == approx(expected)
90101

91102
def test_unit_conversion_ephemeral_storage_gb(self):
92103
"""Test ephemeral storage conversion from GB."""
93-
result = unit_conversion_ephemeral_storage(2, "GB")
104+
steps = []
105+
result = unit_conversion_ephemeral_storage(2, "GB", steps)
94106
assert result == 2
95107

96108
def test_unit_conversion_ephemeral_storage_invalid_unit(self):
97109
"""Test ephemeral storage conversion with invalid unit."""
110+
steps = []
98111
with pytest.raises(ValueError, match="Unknown storage unit"):
99-
unit_conversion_ephemeral_storage(1024, "invalid-unit")
112+
unit_conversion_ephemeral_storage(1024, "invalid-unit", steps)
100113

101114
def test_calculate_tiered_cost_simple(self):
102115
"""Test tiered cost calculation with simple case."""
116+
steps = []
103117
tier_cost_factor = {"1000": "0.0000002083"}
104118
overflow_rate = 0.0000133334
105-
result = calculate_tiered_cost(500.0, tier_cost_factor, overflow_rate)
119+
result = calculate_tiered_cost(500.0, tier_cost_factor, overflow_rate, steps)
106120
expected = 500.0 * 0.0000002083
107121
assert result == approx(expected, abs=0.0001)
108122

109123
def test_calculate_tiered_cost_with_overflow(self):
110124
"""Test tiered cost calculation with overflow."""
125+
steps = []
111126
tier_cost_factor = {"1000": "0.0000002083"}
112127
overflow_rate = 0.0000133334
113-
result = calculate_tiered_cost(1500.0, tier_cost_factor, overflow_rate)
128+
result = calculate_tiered_cost(1500.0, tier_cost_factor, overflow_rate, steps)
114129
tier_cost = 1000.0 * 0.0000002083
115130
overflow_cost = 500.0 * overflow_rate
116131
expected = tier_cost + overflow_cost

0 commit comments

Comments
 (0)